Upgraded to libsndfile 1.0.19

Removed stb_vorbis

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1071 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
laurentgom 2009-04-07 12:11:11 +00:00
parent 392eb219f2
commit 137ef64f2a
21 changed files with 937 additions and 7156 deletions

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_workspace_file>
<Workspace title="SFML workspace">
<Project filename="sfml-system.cbp" active="1" />
<Project filename="sfml-system.cbp" />
<Project filename="sfml-window.cbp" />
<Project filename="sfml-network.cbp" />
<Project filename="sfml-graphics.cbp" />
<Project filename="sfml-audio.cbp" />
<Project filename="sfml-audio.cbp" active="1" />
<Project filename="sfml-main.cbp" />
<Project filename="..\..\samples\build\codeblocks\ftp.cbp" />
<Project filename="..\..\samples\build\codeblocks\opengl.cbp" />

View File

@ -129,16 +129,8 @@
<Unit filename="..\..\src\SFML\Audio\SoundBufferRecorder.cpp" />
<Unit filename="..\..\src\SFML\Audio\SoundFile.cpp" />
<Unit filename="..\..\src\SFML\Audio\SoundFile.hpp" />
<Unit filename="..\..\src\SFML\Audio\SoundFileDefault.cpp" />
<Unit filename="..\..\src\SFML\Audio\SoundFileDefault.hpp" />
<Unit filename="..\..\src\SFML\Audio\SoundFileOgg.cpp" />
<Unit filename="..\..\src\SFML\Audio\SoundFileOgg.hpp" />
<Unit filename="..\..\src\SFML\Audio\SoundRecorder.cpp" />
<Unit filename="..\..\src\SFML\Audio\SoundStream.cpp" />
<Unit filename="..\..\src\SFML\Audio\stb_vorbis\stb_vorbis.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="..\..\src\SFML\Audio\stb_vorbis\stb_vorbis.h" />
<Extensions>
<code_completion />
<envvars />

View File

@ -343,52 +343,6 @@
<References>
</References>
<Files>
<Filter
Name="stb_vorbis"
>
<File
RelativePath="..\..\src\SFML\Audio\stb_vorbis\stb_vorbis.c"
>
<FileConfiguration
Name="Debug DLL|Win32"
>
<Tool
Name="VCCLCompilerTool"
WarningLevel="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release DLL|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
WarningLevel="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug static|Win32"
>
<Tool
Name="VCCLCompilerTool"
WarningLevel="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
WarningLevel="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\SFML\Audio\stb_vorbis\stb_vorbis.h"
>
</File>
</Filter>
<File
RelativePath="..\..\src\SFML\Audio\AudioDevice.cpp"
>
@ -457,22 +411,6 @@
RelativePath="..\..\src\SFML\Audio\SoundFile.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Audio\SoundFileDefault.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Audio\SoundFileDefault.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Audio\SoundFileOgg.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Audio\SoundFileOgg.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Audio\SoundRecorder.cpp"
>

View File

@ -339,52 +339,6 @@
<References>
</References>
<Files>
<Filter
Name="stb_vorbis"
>
<File
RelativePath="..\..\src\SFML\Audio\stb_vorbis\stb_vorbis.c"
>
<FileConfiguration
Name="Debug DLL|Win32"
>
<Tool
Name="VCCLCompilerTool"
WarningLevel="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release DLL|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
WarningLevel="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug static|Win32"
>
<Tool
Name="VCCLCompilerTool"
WarningLevel="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release static|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
WarningLevel="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\SFML\Audio\stb_vorbis\stb_vorbis.h"
>
</File>
</Filter>
<File
RelativePath="..\..\src\SFML\Audio\AudioDevice.cpp"
>
@ -453,22 +407,6 @@
RelativePath="..\..\src\SFML\Audio\SoundFile.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Audio\SoundFileDefault.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Audio\SoundFileDefault.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Audio\SoundFileOgg.cpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Audio\SoundFileOgg.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Audio\SoundRecorder.cpp"
>

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,7 +1,5 @@
SRC = $(wildcard *.cpp)
SRCVORBIS = $(wildcard ./stb_vorbis/*.c)
OBJ = $(SRC:.cpp=.o)
OBJVORBIS = $(SRCVORBIS:.c=.o)
SRC = $(wildcard *.cpp)
OBJ = $(SRC:.cpp=.o)
ifeq ($(STATIC), yes)
LIB = libsfml-audio-s.a
@ -15,22 +13,19 @@ endif
all: $(LIB)
libsfml-audio-s.a: $(OBJ) $(OBJVORBIS)
$(AR) $(ARFLAGS) $(LIBNAME) $(OBJ) $(OBJVORBIS)
libsfml-audio-s.a: $(OBJ)
$(AR) $(ARFLAGS) $(LIBNAME) $(OBJ)
libsfml-audio.so: $(OBJ) $(OBJVORBIS)
$(CPP) $(LDFLAGS) -Wl,-soname,$(LIB).$(VERSION) -o $(LIBNAME) $(OBJ) $(OBJVORBIS) -lsndfile -lopenal
$(CPP) $(LDFLAGS) -Wl,-soname,$(LIB).$(VERSION) -o $(LIBNAME) $(OBJ) -lsndfile -lopenal
$(OBJ): %.o: %.cpp
$(CPP) -o $@ -c $< $(CFLAGS)
$(OBJVORBIS): %.o: %.c
$(CC) -o $@ -c $< $(CFLAGSEXT)
.PHONY: clean mrproper
clean:
@rm -rf $(OBJ) $(OBJVORBIS)
@rm -rf $(OBJ)
mrproper: clean
@rm -rf $(LIBNAME)

View File

@ -38,7 +38,7 @@ namespace sf
/// Construct the music with a buffer size
////////////////////////////////////////////////////////////
Music::Music(std::size_t BufferSize) :
myFile (NULL),
myFile (new priv::SoundFile),
myDuration(0.f),
mySamples (BufferSize)
{
@ -67,9 +67,7 @@ bool Music::OpenFromFile(const std::string& Filename)
Stop();
// Create the sound file implementation, and open it in read mode
delete myFile;
myFile = priv::SoundFile::CreateRead(Filename);
if (!myFile)
if (!myFile->OpenRead(Filename))
{
std::cerr << "Failed to open \"" << Filename << "\" for reading" << std::endl;
return false;
@ -94,9 +92,7 @@ bool Music::OpenFromMemory(const char* Data, std::size_t SizeInBytes)
Stop();
// Create the sound file implementation, and open it in read mode
delete myFile;
myFile = priv::SoundFile::CreateRead(Data, SizeInBytes);
if (!myFile)
if (!myFile->OpenRead(Data, SizeInBytes))
{
std::cerr << "Failed to open music from memory for reading" << std::endl;
return false;

View File

@ -80,37 +80,29 @@ SoundBuffer::~SoundBuffer()
////////////////////////////////////////////////////////////
bool SoundBuffer::LoadFromFile(const std::string& Filename)
{
// Create the sound file
std::auto_ptr<priv::SoundFile> File(priv::SoundFile::CreateRead(Filename));
// Open the sound file
if (File.get())
priv::SoundFile File;
if (File.OpenRead(Filename))
{
// Get the sound parameters
std::size_t NbSamples = File->GetSamplesCount();
unsigned int ChannelsCount = File->GetChannelsCount();
unsigned int SampleRate = File->GetSampleRate();
std::size_t NbSamples = File.GetSamplesCount();
unsigned int ChannelsCount = File.GetChannelsCount();
unsigned int SampleRate = File.GetSampleRate();
// Read the samples from the opened file
mySamples.resize(NbSamples);
if (File->Read(&mySamples[0], NbSamples) == NbSamples)
if (File.Read(&mySamples[0], NbSamples) == NbSamples)
{
// Update the internal buffer with the new samples
return Update(ChannelsCount, SampleRate);
}
else
{
// Error...
std::cerr << "Failed to read audio data from file \"" << Filename << "\"" << std::endl;
return false;
}
}
else
{
// Error...
std::cerr << "Failed to load sound buffer from file \"" << Filename << "\"" << std::endl;
return false;
}
}
@ -121,37 +113,29 @@ bool SoundBuffer::LoadFromFile(const std::string& Filename)
////////////////////////////////////////////////////////////
bool SoundBuffer::LoadFromMemory(const char* Data, std::size_t SizeInBytes)
{
// Create the sound file
std::auto_ptr<priv::SoundFile> File(priv::SoundFile::CreateRead(Data, SizeInBytes));
// Open the sound file
if (File.get())
priv::SoundFile File;
if (File.OpenRead(Data, SizeInBytes))
{
// Get the sound parameters
std::size_t NbSamples = File->GetSamplesCount();
unsigned int ChannelsCount = File->GetChannelsCount();
unsigned int SampleRate = File->GetSampleRate();
std::size_t NbSamples = File.GetSamplesCount();
unsigned int ChannelsCount = File.GetChannelsCount();
unsigned int SampleRate = File.GetSampleRate();
// Read the samples from the opened file
mySamples.resize(NbSamples);
if (File->Read(&mySamples[0], NbSamples) == NbSamples)
if (File.Read(&mySamples[0], NbSamples) == NbSamples)
{
// Update the internal buffer with the new samples
return Update(ChannelsCount, SampleRate);
}
else
{
// Error...
std::cerr << "Failed to read audio data from file in memory" << std::endl;
return false;
}
}
else
{
// Error...
std::cerr << "Failed to load sound buffer from file in memory" << std::endl;
return false;
}
}
@ -192,19 +176,16 @@ bool SoundBuffer::LoadFromSamples(const Int16* Samples, std::size_t SamplesCount
bool SoundBuffer::SaveToFile(const std::string& Filename) const
{
// Create the sound file in write mode
std::auto_ptr<priv::SoundFile> File(priv::SoundFile::CreateWrite(Filename, GetChannelsCount(), GetSampleRate()));
if (File.get())
priv::SoundFile File;
if (File.OpenWrite(Filename, GetChannelsCount(), GetSampleRate()))
{
// Write the samples to the opened file
File->Write(&mySamples[0], mySamples.size());
File.Write(&mySamples[0], mySamples.size());
return true;
}
else
{
// Error...
std::cerr << "Failed to save sound buffer to file \"" << Filename << "\"" << std::endl;
return false;
}
}

View File

@ -26,126 +26,19 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Audio/SoundFile.hpp>
#include <SFML/Audio/SoundFileDefault.hpp>
#include <SFML/Audio/SoundFileOgg.hpp>
#include <iostream>
#include <string.h>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Create a new sound from a file, for reading
////////////////////////////////////////////////////////////
SoundFile* SoundFile::CreateRead(const std::string& Filename)
{
// Create the file according to its type
SoundFile* File = NULL;
if (SoundFileOgg::IsFileSupported(Filename, true)) File = new SoundFileOgg;
else if (SoundFileDefault::IsFileSupported(Filename, true)) File = new SoundFileDefault;
// Open it for reading
if (File)
{
std::size_t SamplesCount;
unsigned int ChannelsCount;
unsigned int SampleRate;
if (File->OpenRead(Filename, SamplesCount, ChannelsCount, SampleRate))
{
File->myFilename = Filename;
File->myData = NULL;
File->mySize = 0;
File->myNbSamples = SamplesCount;
File->myChannelsCount = ChannelsCount;
File->mySampleRate = SampleRate;
}
else
{
delete File;
File = NULL;
}
}
return File;
}
////////////////////////////////////////////////////////////
/// Create a new sound from a file in memory, for reading
////////////////////////////////////////////////////////////
SoundFile* SoundFile::CreateRead(const char* Data, std::size_t SizeInMemory)
{
// Create the file according to its type
SoundFile* File = NULL;
if (SoundFileOgg::IsFileSupported(Data, SizeInMemory)) File = new SoundFileOgg;
else if (SoundFileDefault::IsFileSupported(Data, SizeInMemory)) File = new SoundFileDefault;
// Open it for reading
if (File)
{
std::size_t SamplesCount;
unsigned int ChannelsCount;
unsigned int SampleRate;
if (File->OpenRead(Data, SizeInMemory, SamplesCount, ChannelsCount, SampleRate))
{
File->myFilename = "";
File->myData = Data;
File->mySize = SizeInMemory;
File->myNbSamples = SamplesCount;
File->myChannelsCount = ChannelsCount;
File->mySampleRate = SampleRate;
}
else
{
delete File;
File = NULL;
}
}
return File;
}
////////////////////////////////////////////////////////////
/// Create a new sound from a file, for writing
////////////////////////////////////////////////////////////
SoundFile* SoundFile::CreateWrite(const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate)
{
// Create the file according to its type
SoundFile* File = NULL;
if (SoundFileOgg::IsFileSupported(Filename, false)) File = new SoundFileOgg;
else if (SoundFileDefault::IsFileSupported(Filename, false)) File = new SoundFileDefault;
// Open it for writing
if (File)
{
if (File->OpenWrite(Filename, ChannelsCount, SampleRate))
{
File->myFilename = "";
File->myData = NULL;
File->mySize = 0;
File->myNbSamples = 0;
File->myChannelsCount = ChannelsCount;
File->mySampleRate = SampleRate;
}
else
{
delete File;
File = NULL;
}
}
return File;
}
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
SoundFile::SoundFile() :
myFile (NULL),
myNbSamples (0),
myChannelsCount(0),
mySampleRate (0)
@ -155,11 +48,12 @@ mySampleRate (0)
////////////////////////////////////////////////////////////
/// Virtual destructor
/// Destructor
////////////////////////////////////////////////////////////
SoundFile::~SoundFile()
{
// Nothing to do
if (myFile)
sf_close(myFile);
}
@ -198,12 +92,12 @@ bool SoundFile::Restart()
if (myData)
{
// Reopen from memory
return OpenRead(myData, mySize, myNbSamples, myChannelsCount, mySampleRate);
return OpenRead(myData, mySize);
}
else if (myFilename != "")
{
// Reopen from file
return OpenRead(myFilename, myNbSamples, myChannelsCount, mySampleRate);
return OpenRead(myFilename);
}
else
{
@ -217,53 +111,257 @@ bool SoundFile::Restart()
////////////////////////////////////////////////////////////
/// Open the sound file for reading
////////////////////////////////////////////////////////////
bool SoundFile::OpenRead(const std::string& Filename, std::size_t&, unsigned int&, unsigned int&)
bool SoundFile::OpenRead(const std::string& Filename)
{
std::cerr << "Failed to open sound file \"" << Filename << "\", format is not supported by SFML" << std::endl;
// If the file is already opened, first close it
if (myFile)
sf_close(myFile);
return false;
// Open the sound file
SF_INFO FileInfos;
myFile = sf_open(Filename.c_str(), SFM_READ, &FileInfos);
if (!myFile)
{
std::cerr << "Failed to read sound file \"" << Filename << "\" (" << sf_strerror(myFile) << ")" << std::endl;
return false;
}
// Set the sound parameters
myChannelsCount = FileInfos.channels;
mySampleRate = FileInfos.samplerate;
myNbSamples = static_cast<std::size_t>(FileInfos.frames) * myChannelsCount;
myFilename = Filename;
myData = NULL;
mySize = 0;
return true;
}
////////////////////////////////////////////////////////////
/// Open the sound file in memory for reading
////////////////////////////////////////////////////////////
bool SoundFile::OpenRead(const char*, std::size_t, std::size_t&, unsigned int&, unsigned int&)
bool SoundFile::OpenRead(const char* Data, std::size_t SizeInBytes)
{
std::cerr << "Failed to open sound file from memory, format is not supported by SFML" << std::endl;
// If the file is already opened, first close it
if (myFile)
sf_close(myFile);
return false;
// Define the I/O custom functions for reading from memory
SF_VIRTUAL_IO VirtualIO;
VirtualIO.get_filelen = &SoundFile::MemoryGetLength;
VirtualIO.read = &SoundFile::MemoryRead;
VirtualIO.seek = &SoundFile::MemorySeek;
VirtualIO.tell = &SoundFile::MemoryTell;
VirtualIO.write = &SoundFile::MemoryWrite;
// Initialize the memory data
myMemory.DataStart = Data;
myMemory.DataPtr = Data;
myMemory.TotalSize = SizeInBytes;
// Open the sound file
SF_INFO FileInfos;
myFile = sf_open_virtual(&VirtualIO, SFM_READ, &FileInfos, &myMemory);
if (!myFile)
{
std::cerr << "Failed to read sound file from memory (" << sf_strerror(myFile) << ")" << std::endl;
return false;
}
// Set the sound parameters
myChannelsCount = FileInfos.channels;
mySampleRate = FileInfos.samplerate;
myNbSamples = static_cast<std::size_t>(FileInfos.frames) * myChannelsCount;
myFilename = "";
myData = Data;
mySize = SizeInBytes;
return true;
}
////////////////////////////////////////////////////////////
/// Open the sound file for writing
////////////////////////////////////////////////////////////
bool SoundFile::OpenWrite(const std::string& Filename, unsigned int, unsigned int)
bool SoundFile::OpenWrite(const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate)
{
std::cerr << "Failed to open sound file \"" << Filename << "\", format is not supported by SFML" << std::endl;
// If the file is already opened, first close it
if (myFile)
sf_close(myFile);
return false;
// Find the right format according to the file extension
int Format = GetFormatFromFilename(Filename);
if (Format == -1)
{
// Error : unrecognized extension
std::cerr << "Failed to create sound file \"" << Filename << "\" (unknown format)" << std::endl;
return false;
}
// Fill the sound infos with parameters
SF_INFO FileInfos;
FileInfos.channels = ChannelsCount;
FileInfos.samplerate = SampleRate;
FileInfos.format = Format | (Format == SF_FORMAT_OGG ? SF_FORMAT_VORBIS : SF_FORMAT_PCM_16);
// Open the sound file for writing
myFile = sf_open(Filename.c_str(), SFM_WRITE, &FileInfos);
if (!myFile)
{
std::cerr << "Failed to create sound file \"" << Filename << "\" (" << sf_strerror(myFile) << ")" << std::endl;
return false;
}
// Set the sound parameters
myChannelsCount = ChannelsCount;
mySampleRate = SampleRate;
myNbSamples = 0;
myFilename = "";
myData = NULL;
mySize = 0;
return true;
}
////////////////////////////////////////////////////////////
/// Read samples from the loaded sound
////////////////////////////////////////////////////////////
std::size_t SoundFile::Read(Int16*, std::size_t)
std::size_t SoundFile::Read(Int16* Data, std::size_t NbSamples)
{
std::cerr << "Failed to read from sound file (not supported)" << std::endl;
return 0;
if (myFile && Data && NbSamples)
return static_cast<std::size_t>(sf_read_short(myFile, Data, NbSamples));
else
return 0;
}
////////////////////////////////////////////////////////////
/// Write samples to the file
////////////////////////////////////////////////////////////
void SoundFile::Write(const Int16*, std::size_t)
void SoundFile::Write(const Int16* Data, std::size_t NbSamples)
{
std::cerr << "Failed to write to sound file (not supported)" << std::endl;
if (myFile && Data && NbSamples)
{
// Write small chunks instead of everything at once,
// to avoid a stack overflow in libsndfile (happens only with OGG format)
while (NbSamples > 0)
{
std::size_t Count = NbSamples > 10000 ? 10000 : NbSamples;
sf_write_short(myFile, Data, Count);
Data += Count;
NbSamples -= Count;
}
}
}
////////////////////////////////////////////////////////////
/// Get the internal format of an audio file according to
/// its filename extension
////////////////////////////////////////////////////////////
int SoundFile::GetFormatFromFilename(const std::string& Filename)
{
// Extract the extension
std::string Ext = "wav";
std::string::size_type Pos = Filename.find_last_of(".");
if (Pos != std::string::npos)
Ext = Filename.substr(Pos + 1);
// Match every supported extension with its format constant
if (Ext == "wav" || Ext == "WAV" ) return SF_FORMAT_WAV;
if (Ext == "aif" || Ext == "AIF" ) return SF_FORMAT_AIFF;
if (Ext == "aiff" || Ext == "AIFF") return SF_FORMAT_AIFF;
if (Ext == "au" || Ext == "AU" ) return SF_FORMAT_AU;
if (Ext == "raw" || Ext == "RAW" ) return SF_FORMAT_RAW;
if (Ext == "paf" || Ext == "PAF" ) return SF_FORMAT_PAF;
if (Ext == "svx" || Ext == "SVX" ) return SF_FORMAT_SVX;
if (Ext == "nist" || Ext == "NIST") return SF_FORMAT_NIST;
if (Ext == "voc" || Ext == "VOC" ) return SF_FORMAT_VOC;
if (Ext == "sf" || Ext == "SF" ) return SF_FORMAT_IRCAM;
if (Ext == "w64" || Ext == "W64" ) return SF_FORMAT_W64;
if (Ext == "mat4" || Ext == "MAT4") return SF_FORMAT_MAT4;
if (Ext == "mat5" || Ext == "MAT5") return SF_FORMAT_MAT5;
if (Ext == "pvf" || Ext == "PVF" ) return SF_FORMAT_PVF;
if (Ext == "xi" || Ext == "XI" ) return SF_FORMAT_XI;
if (Ext == "htk" || Ext == "HTK" ) return SF_FORMAT_HTK;
if (Ext == "sds" || Ext == "SDS" ) return SF_FORMAT_SDS;
if (Ext == "avr" || Ext == "AVR" ) return SF_FORMAT_AVR;
if (Ext == "sd2" || Ext == "SD2" ) return SF_FORMAT_SD2;
if (Ext == "flac" || Ext == "FLAC") return SF_FORMAT_FLAC;
if (Ext == "caf" || Ext == "CAF" ) return SF_FORMAT_CAF;
if (Ext == "wve" || Ext == "WVE" ) return SF_FORMAT_WVE;
if (Ext == "ogg" || Ext == "OGG") return SF_FORMAT_OGG;
if (Ext == "mpc2k" || Ext == "MPC2K") return SF_FORMAT_MPC2K;
if (Ext == "rf64" || Ext == "RF64") return SF_FORMAT_RF64;
return -1;
}
////////////////////////////////////////////////////////////
/// Functions for implementing custom read and write to memory files
////////////////////////////////////////////////////////////
sf_count_t SoundFile::MemoryGetLength(void* UserData)
{
MemoryInfos* Memory = static_cast<MemoryInfos*>(UserData);
return Memory->TotalSize;
}
sf_count_t SoundFile::MemoryRead(void* Ptr, sf_count_t Count, void* UserData)
{
MemoryInfos* Memory = static_cast<MemoryInfos*>(UserData);
sf_count_t Position = Memory->DataPtr - Memory->DataStart;
if (Position + Count >= Memory->TotalSize)
Count = Memory->TotalSize - Position;
memcpy(Ptr, Memory->DataPtr, static_cast<std::size_t>(Count));
Memory->DataPtr += Count;
return Count;
}
sf_count_t SoundFile::MemorySeek(sf_count_t Offset, int Whence, void* UserData)
{
MemoryInfos* Memory = static_cast<MemoryInfos*>(UserData);
sf_count_t Position = 0;
switch (Whence)
{
case SEEK_SET :
Position = Offset;
break;
case SEEK_CUR :
Position = Memory->DataPtr - Memory->DataStart + Offset;
break;
case SEEK_END :
Position = Memory->TotalSize - Offset;
break;
default :
Position = 0;
break;
}
if (Position >= Memory->TotalSize)
Position = Memory->TotalSize - 1;
else if (Position < 0)
Position = 0;
Memory->DataPtr = Memory->DataStart + Position;
return Position;
}
sf_count_t SoundFile::MemoryTell(void* UserData)
{
MemoryInfos* Memory = static_cast<MemoryInfos*>(UserData);
return Memory->DataPtr - Memory->DataStart;
}
sf_count_t SoundFile::MemoryWrite(const void*, sf_count_t, void*)
{
return 0;
}
} // namespace priv

View File

@ -29,6 +29,7 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/NonCopyable.hpp>
#include <sndfile.h>
#include <string>
@ -37,57 +38,24 @@ namespace sf
namespace priv
{
////////////////////////////////////////////////////////////
/// SoundFile is the abstract base class for loading
/// and saving different sound file formats
/// SoundFile is used to load and save various sampled
/// sound file formats
////////////////////////////////////////////////////////////
class SoundFile : NonCopyable
{
public :
////////////////////////////////////////////////////////////
/// Create a new sound from a file, for reading
///
/// \param Filename : Path of sound file
/// \param NbSamples : Number of samples in the file
/// \param ChannelsCount : Number of channels in the loaded sound
/// \param SampleRate : Sample rate of the loaded sound
///
/// \return Pointer to the new sound file (NULL if failed)
/// Default constructor
///
////////////////////////////////////////////////////////////
static SoundFile* CreateRead(const std::string& Filename);
SoundFile();
////////////////////////////////////////////////////////////
/// Create a new sound from a file in memory, for reading
///
/// \param Data : Pointer to the file data in memory
/// \param SizeInBytes : Size of the data to load, in bytes
/// \param NbSamples : Number of samples in the file
/// \param ChannelsCount : Number of channels in the loaded sound
/// \param SampleRate : Sample rate of the loaded sound
///
/// \return Pointer to the new sound file (NULL if failed)
/// Destructor
///
////////////////////////////////////////////////////////////
static SoundFile* CreateRead(const char* Data, std::size_t SizeInBytes);
////////////////////////////////////////////////////////////
/// Create a new sound from a file, for writing
///
/// \param Filename : Path of sound file
/// \param ChannelsCount : Number of channels in the sound
/// \param SampleRate : Sample rate of the sound
///
/// \return Pointer to the new sound file (NULL if failed)
///
////////////////////////////////////////////////////////////
static SoundFile* CreateWrite(const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate);
////////////////////////////////////////////////////////////
/// Virtual destructor
///
////////////////////////////////////////////////////////////
virtual ~SoundFile();
~SoundFile();
////////////////////////////////////////////////////////////
/// Get the total number of samples in the file
@ -121,62 +89,26 @@ public :
////////////////////////////////////////////////////////////
bool Restart();
////////////////////////////////////////////////////////////
/// Read samples from the loaded sound
///
/// \param Data : Pointer to the samples array to fill
/// \param NbSamples : Number of samples to read
///
/// \return Number of samples read
///
////////////////////////////////////////////////////////////
virtual std::size_t Read(Int16* Data, std::size_t NbSamples);
////////////////////////////////////////////////////////////
/// Write samples to the file
///
/// \param Data : Pointer to the samples array to write
/// \param NbSamples : Number of samples to write
///
////////////////////////////////////////////////////////////
virtual void Write(const Int16* Data, std::size_t NbSamples);
protected :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
SoundFile();
private :
////////////////////////////////////////////////////////////
/// Open the sound file for reading
///
/// \param Filename : Path of sound file to load
/// \param NbSamples : Number of samples in the file
/// \param ChannelsCount : Number of channels in the loaded sound
/// \param SampleRate : Sample rate of the loaded sound
/// \param Filename : Path of sound file to load
///
/// \return True if the file was successfully opened
///
////////////////////////////////////////////////////////////
virtual bool OpenRead(const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate);
bool OpenRead(const std::string& Filename);
////////////////////////////////////////////////////////////
/// Open the sound file in memory for reading
///
/// \param Data : Pointer to the file data in memory
/// \param SizeInBytes : Size of the data to load, in bytes
/// \param NbSamples : Number of samples in the file
/// \param ChannelsCount : Number of channels in the loaded sound
/// \param SampleRate : Sample rate of the loaded sound
/// \param Data : Pointer to the file data in memory
/// \param SizeInBytes : Size of the data to load, in bytes
///
/// \return True if the file was successfully opened
///
////////////////////////////////////////////////////////////
virtual bool OpenRead(const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate);
bool OpenRead(const char* Data, std::size_t SizeInBytes);
////////////////////////////////////////////////////////////
/// Open the sound file for writing
@ -188,11 +120,66 @@ private :
/// \return True if the file was successfully opened
///
////////////////////////////////////////////////////////////
virtual bool OpenWrite(const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate);
bool OpenWrite(const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate);
////////////////////////////////////////////////////////////
/// Read samples from the loaded sound
///
/// \param Data : Pointer to the samples array to fill
/// \param NbSamples : Number of samples to read
///
/// \return Number of samples read
///
////////////////////////////////////////////////////////////
std::size_t Read(Int16* Data, std::size_t NbSamples);
////////////////////////////////////////////////////////////
/// Write samples to the file
///
/// \param Data : Pointer to the samples array to write
/// \param NbSamples : Number of samples to write
///
////////////////////////////////////////////////////////////
void Write(const Int16* Data, std::size_t NbSamples);
private :
////////////////////////////////////////////////////////////
/// Get the internal format of an audio file according to
/// its filename extension
///
/// \param Filename : Filename to check
///
/// \return Internal format matching the filename (-1 if no match)
///
////////////////////////////////////////////////////////////
static int GetFormatFromFilename(const std::string& Filename);
////////////////////////////////////////////////////////////
/// Functions for implementing custom read and write to memory files
///
////////////////////////////////////////////////////////////
static sf_count_t MemoryGetLength(void* UserData);
static sf_count_t MemoryRead(void* Ptr, sf_count_t Count, void* UserData);
static sf_count_t MemorySeek(sf_count_t Offset, int Whence, void* UserData);
static sf_count_t MemoryTell(void* UserData);
static sf_count_t MemoryWrite(const void* Ptr, sf_count_t Count, void* UserData);
////////////////////////////////////////////////////////////
/// Structure holding data related to memory operations
////////////////////////////////////////////////////////////
struct MemoryInfos
{
const char* DataStart; ///< Pointer to the begining of the data
const char* DataPtr; ///< Pointer to the current read / write position
sf_count_t TotalSize; ///< Total size of the data, in bytes
};
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SNDFILE* myFile; ///< File descriptor
MemoryInfos myMemory; ///< Memory read / write data
std::size_t myNbSamples; ///< Total number of samples in the file
unsigned int myChannelsCount; ///< Number of channels used by the sound
unsigned int mySampleRate; ///< Number of samples per second

View File

@ -1,352 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Audio/SoundFileDefault.hpp>
#include <iostream>
#include <string.h>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
SoundFileDefault::SoundFileDefault() :
myFile(NULL)
{
}
////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
SoundFileDefault::~SoundFileDefault()
{
if (myFile)
sf_close(myFile);
}
////////////////////////////////////////////////////////////
/// Check if a given file is supported by this loader
////////////////////////////////////////////////////////////
bool SoundFileDefault::IsFileSupported(const std::string& Filename, bool Read)
{
if (Read)
{
// Open the sound file
SF_INFO FileInfos;
SNDFILE* File = sf_open(Filename.c_str(), SFM_READ, &FileInfos);
if (File)
{
sf_close(File);
return true;
}
else
{
return false;
}
}
else
{
// Check the extension
return GetFormatFromFilename(Filename) != -1;
}
}
////////////////////////////////////////////////////////////
/// Check if a given file in memory is supported by this loader
////////////////////////////////////////////////////////////
bool SoundFileDefault::IsFileSupported(const char* Data, std::size_t SizeInBytes)
{
// Define the I/O custom functions for reading from memory
SF_VIRTUAL_IO VirtualIO;
VirtualIO.get_filelen = &SoundFileDefault::MemoryGetLength;
VirtualIO.read = &SoundFileDefault::MemoryRead;
VirtualIO.seek = &SoundFileDefault::MemorySeek;
VirtualIO.tell = &SoundFileDefault::MemoryTell;
VirtualIO.write = &SoundFileDefault::MemoryWrite;
// Initialize the memory data
MemoryInfos Memory;
Memory.DataStart = Data;
Memory.DataPtr = Data;
Memory.TotalSize = SizeInBytes;
// Open the sound file
SF_INFO FileInfos;
SNDFILE* File = sf_open_virtual(&VirtualIO, SFM_READ, &FileInfos, &Memory);
if (File)
{
sf_close(File);
return true;
}
else
{
return false;
}
}
////////////////////////////////////////////////////////////
/// Open the sound file for reading
////////////////////////////////////////////////////////////
bool SoundFileDefault::OpenRead(const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate)
{
// If the file is already opened, first close it
if (myFile)
sf_close(myFile);
// Open the sound file
SF_INFO FileInfos;
myFile = sf_open(Filename.c_str(), SFM_READ, &FileInfos);
if (!myFile)
{
std::cerr << "Failed to read sound file \"" << Filename << "\"" << std::endl;
return false;
}
// Set the sound parameters
ChannelsCount = FileInfos.channels;
SampleRate = FileInfos.samplerate;
NbSamples = static_cast<std::size_t>(FileInfos.frames) * ChannelsCount;
return true;
}
////////////////////////////////////////////////////////////
/// /see sf::SoundFile::OpenRead
////////////////////////////////////////////////////////////
bool SoundFileDefault::OpenRead(const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate)
{
// If the file is already opened, first close it
if (myFile)
sf_close(myFile);
// Define the I/O custom functions for reading from memory
SF_VIRTUAL_IO VirtualIO;
VirtualIO.get_filelen = &SoundFileDefault::MemoryGetLength;
VirtualIO.read = &SoundFileDefault::MemoryRead;
VirtualIO.seek = &SoundFileDefault::MemorySeek;
VirtualIO.tell = &SoundFileDefault::MemoryTell;
VirtualIO.write = &SoundFileDefault::MemoryWrite;
// Initialize the memory data
myMemory.DataStart = Data;
myMemory.DataPtr = Data;
myMemory.TotalSize = SizeInBytes;
// Open the sound file
SF_INFO FileInfos;
myFile = sf_open_virtual(&VirtualIO, SFM_READ, &FileInfos, &myMemory);
if (!myFile)
{
std::cerr << "Failed to read sound file from memory" << std::endl;
return false;
}
// Set the sound parameters
ChannelsCount = FileInfos.channels;
SampleRate = FileInfos.samplerate;
NbSamples = static_cast<std::size_t>(FileInfos.frames) * ChannelsCount;
return true;
}
////////////////////////////////////////////////////////////
/// Open the sound file for writing
////////////////////////////////////////////////////////////
bool SoundFileDefault::OpenWrite(const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate)
{
// If the file is already opened, first close it
if (myFile)
sf_close(myFile);
// Find the right format according to the file extension
int Format = GetFormatFromFilename(Filename);
if (Format == -1)
{
// Error : unrecognized extension
std::cerr << "Failed to create sound file \"" << Filename << "\" : unknown format" << std::endl;
return false;
}
// Fill the sound infos with parameters
SF_INFO FileInfos;
FileInfos.channels = ChannelsCount;
FileInfos.samplerate = SampleRate;
FileInfos.format = Format | SF_FORMAT_PCM_16;
// Open the sound file for writing
myFile = sf_open(Filename.c_str(), SFM_WRITE, &FileInfos);
if (!myFile)
{
std::cerr << "Failed to create sound file \"" << Filename << "\"" << std::endl;
return false;
}
return true;
}
////////////////////////////////////////////////////////////
/// Read samples from the loaded sound
////////////////////////////////////////////////////////////
std::size_t SoundFileDefault::Read(Int16* Data, std::size_t NbSamples)
{
if (myFile && Data && NbSamples)
return static_cast<std::size_t>(sf_read_short(myFile, Data, NbSamples));
else
return 0;
}
////////////////////////////////////////////////////////////
/// Write samples to the file
////////////////////////////////////////////////////////////
void SoundFileDefault::Write(const Int16* Data, std::size_t NbSamples)
{
if (myFile && Data && NbSamples)
sf_write_short(myFile, Data, NbSamples);
}
////////////////////////////////////////////////////////////
/// Get the internal format of an audio file according to
/// its filename extension
////////////////////////////////////////////////////////////
int SoundFileDefault::GetFormatFromFilename(const std::string& Filename)
{
// Extract the extension
std::string Ext = "wav";
std::string::size_type Pos = Filename.find_last_of(".");
if (Pos != std::string::npos)
Ext = Filename.substr(Pos + 1);
// Match every supported extension with its format constant
if (Ext == "wav" || Ext == "WAV" ) return SF_FORMAT_WAV;
if (Ext == "aif" || Ext == "AIF" ) return SF_FORMAT_AIFF;
if (Ext == "aiff" || Ext == "AIFF") return SF_FORMAT_AIFF;
if (Ext == "au" || Ext == "AU" ) return SF_FORMAT_AU;
if (Ext == "raw" || Ext == "RAW" ) return SF_FORMAT_RAW;
if (Ext == "paf" || Ext == "PAF" ) return SF_FORMAT_PAF;
if (Ext == "svx" || Ext == "SVX" ) return SF_FORMAT_SVX;
if (Ext == "voc" || Ext == "VOC" ) return SF_FORMAT_VOC;
if (Ext == "sf" || Ext == "SF" ) return SF_FORMAT_IRCAM;
if (Ext == "w64" || Ext == "W64" ) return SF_FORMAT_W64;
if (Ext == "mat4" || Ext == "MAT4") return SF_FORMAT_MAT4;
if (Ext == "mat5" || Ext == "MAT5") return SF_FORMAT_MAT5;
if (Ext == "pvf" || Ext == "PVF" ) return SF_FORMAT_PVF;
if (Ext == "htk" || Ext == "HTK" ) return SF_FORMAT_HTK;
if (Ext == "caf" || Ext == "CAF" ) return SF_FORMAT_CAF;
if (Ext == "nist" || Ext == "NIST") return SF_FORMAT_NIST; // SUPPORTED ?
if (Ext == "sds" || Ext == "SDS" ) return SF_FORMAT_SDS; // SUPPORTED ?
if (Ext == "avr" || Ext == "AVR" ) return SF_FORMAT_AVR; // SUPPORTED ?
if (Ext == "sd2" || Ext == "SD2" ) return SF_FORMAT_SD2; // SUPPORTED ?
if (Ext == "flac" || Ext == "FLAC") return SF_FORMAT_FLAC; // SUPPORTED ?
return -1;
}
////////////////////////////////////////////////////////////
/// Functions for implementing custom read and write to memory files
///
////////////////////////////////////////////////////////////
sf_count_t SoundFileDefault::MemoryGetLength(void* UserData)
{
MemoryInfos* Memory = static_cast<MemoryInfos*>(UserData);
return Memory->TotalSize;
}
sf_count_t SoundFileDefault::MemoryRead(void* Ptr, sf_count_t Count, void* UserData)
{
MemoryInfos* Memory = static_cast<MemoryInfos*>(UserData);
sf_count_t Position = Memory->DataPtr - Memory->DataStart;
if (Position + Count >= Memory->TotalSize)
Count = Memory->TotalSize - Position;
memcpy(Ptr, Memory->DataPtr, static_cast<std::size_t>(Count));
Memory->DataPtr += Count;
return Count;
}
sf_count_t SoundFileDefault::MemorySeek(sf_count_t Offset, int Whence, void* UserData)
{
MemoryInfos* Memory = static_cast<MemoryInfos*>(UserData);
sf_count_t Position = 0;
switch (Whence)
{
case SEEK_SET :
Position = Offset;
break;
case SEEK_CUR :
Position = Memory->DataPtr - Memory->DataStart + Offset;
break;
case SEEK_END :
Position = Memory->TotalSize - Offset;
break;
default :
Position = 0;
break;
}
if (Position >= Memory->TotalSize)
Position = Memory->TotalSize - 1;
else if (Position < 0)
Position = 0;
Memory->DataPtr = Memory->DataStart + Position;
return Position;
}
sf_count_t SoundFileDefault::MemoryTell(void* UserData)
{
MemoryInfos* Memory = static_cast<MemoryInfos*>(UserData);
return Memory->DataPtr - Memory->DataStart;
}
sf_count_t SoundFileDefault::MemoryWrite(const void*, sf_count_t, void*)
{
return 0;
}
} // namespace priv
} // namespace sf

View File

@ -1,156 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOUNDFILEDEFAULT_HPP
#define SFML_SOUNDFILEDEFAULT_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Audio/SoundFile.hpp>
#include <sndfile.h>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Specialization of SoundFile that can handle a lot of
/// sound formats (see libsndfile homepage for a complete list)
////////////////////////////////////////////////////////////
class SoundFileDefault : public SoundFile
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
SoundFileDefault();
////////////////////////////////////////////////////////////
/// Destructor
///
////////////////////////////////////////////////////////////
~SoundFileDefault();
////////////////////////////////////////////////////////////
/// Check if a given file is supported by this loader
///
/// \param Filename : Path of the file to check
/// \param Read : Is the file opened for reading or writing ?
///
/// \param return True if the loader can handle this file
///
////////////////////////////////////////////////////////////
static bool IsFileSupported(const std::string& Filename, bool Read);
////////////////////////////////////////////////////////////
/// Check if a given file in memory is supported by this loader
///
/// \param Data : Pointer to the file data in memory
/// \param SizeInBytes : Size of the data to load, in bytes
///
/// \param return True if the loader can handle this file
///
////////////////////////////////////////////////////////////
static bool IsFileSupported(const char* Data, std::size_t SizeInBytes);
////////////////////////////////////////////////////////////
/// /see sf::SoundFile::Read
///
////////////////////////////////////////////////////////////
virtual std::size_t Read(Int16* Data, std::size_t NbSamples);
////////////////////////////////////////////////////////////
/// /see sf::SoundFile::Write
///
////////////////////////////////////////////////////////////
virtual void Write(const Int16* Data, std::size_t NbSamples);
private :
////////////////////////////////////////////////////////////
/// /see sf::SoundFile::OpenRead
///
////////////////////////////////////////////////////////////
virtual bool OpenRead(const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate);
////////////////////////////////////////////////////////////
/// /see sf::SoundFile::OpenRead
///
////////////////////////////////////////////////////////////
virtual bool OpenRead(const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate);
////////////////////////////////////////////////////////////
/// /see sf::SoundFile::OpenWrite
///
////////////////////////////////////////////////////////////
virtual bool OpenWrite(const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate);
////////////////////////////////////////////////////////////
/// Get the internal format of an audio file according to
/// its filename extension
///
/// \param Filename : Filename to check
///
/// \return Internal format matching the filename (-1 if no match)
///
////////////////////////////////////////////////////////////
static int GetFormatFromFilename(const std::string& Filename);
////////////////////////////////////////////////////////////
/// Functions for implementing custom read and write to memory files
///
////////////////////////////////////////////////////////////
static sf_count_t MemoryGetLength(void* UserData);
static sf_count_t MemoryRead(void* Ptr, sf_count_t Count, void* UserData);
static sf_count_t MemorySeek(sf_count_t Offset, int Whence, void* UserData);
static sf_count_t MemoryTell(void* UserData);
static sf_count_t MemoryWrite(const void* Ptr, sf_count_t Count, void* UserData);
////////////////////////////////////////////////////////////
/// Structure holding data related to memory operations
////////////////////////////////////////////////////////////
struct MemoryInfos
{
const char* DataStart; ///< Pointer to the begining of the data
const char* DataPtr; ///< Pointer to the current read / write position
sf_count_t TotalSize; ///< Total size of the data, in bytes
};
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SNDFILE* myFile; ///< File descriptor
MemoryInfos myMemory; ///< Memory read / write data
};
} // namespace priv
} // namespace sf
#endif // SFML_SOUNDFILEDEFAULT_HPP

View File

@ -1,182 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Audio/SoundFileOgg.hpp>
#include <SFML/Audio/stb_vorbis/stb_vorbis.h>
#include <iostream>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
SoundFileOgg::SoundFileOgg() :
myStream (NULL),
myChannelsCount(0)
{
}
////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
SoundFileOgg::~SoundFileOgg()
{
if (myStream)
stb_vorbis_close(myStream);
}
////////////////////////////////////////////////////////////
/// Check if a given file is supported by this loader
////////////////////////////////////////////////////////////
bool SoundFileOgg::IsFileSupported(const std::string& Filename, bool Read)
{
if (Read)
{
// Open the vorbis stream
stb_vorbis* Stream = stb_vorbis_open_filename(const_cast<char*>(Filename.c_str()), NULL, NULL);
if (Stream)
{
stb_vorbis_close(Stream);
return true;
}
else
{
return false;
}
}
else
{
// No support for writing ogg files yet...
return false;
}
}
////////////////////////////////////////////////////////////
/// Check if a given file in memory is supported by this loader
////////////////////////////////////////////////////////////
bool SoundFileOgg::IsFileSupported(const char* Data, std::size_t SizeInBytes)
{
// Open the vorbis stream
unsigned char* Buffer = reinterpret_cast<unsigned char*>(const_cast<char*>(Data));
int Length = static_cast<int>(SizeInBytes);
stb_vorbis* Stream = stb_vorbis_open_memory(Buffer, Length, NULL, NULL);
if (Stream)
{
stb_vorbis_close(Stream);
return true;
}
else
{
return false;
}
}
////////////////////////////////////////////////////////////
/// Open the sound file for reading
////////////////////////////////////////////////////////////
bool SoundFileOgg::OpenRead(const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate)
{
// Close the file if already opened
if (myStream)
stb_vorbis_close(myStream);
// Open the vorbis stream
myStream = stb_vorbis_open_filename(const_cast<char*>(Filename.c_str()), NULL, NULL);
if (myStream == NULL)
{
std::cerr << "Failed to read sound file \"" << Filename << "\" (cannot open the file)" << std::endl;
return false;
}
// Get the music parameters
stb_vorbis_info Infos = stb_vorbis_get_info(myStream);
ChannelsCount = myChannelsCount = Infos.channels;
SampleRate = Infos.sample_rate;
NbSamples = static_cast<std::size_t>(stb_vorbis_stream_length_in_samples(myStream) * ChannelsCount);
return true;
}
////////////////////////////////////////////////////////////
/// /see sf::SoundFile::OpenRead
////////////////////////////////////////////////////////////
bool SoundFileOgg::OpenRead(const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate)
{
// Close the file if already opened
if (myStream)
stb_vorbis_close(myStream);
// Open the vorbis stream
unsigned char* Buffer = reinterpret_cast<unsigned char*>(const_cast<char*>(Data));
int Length = static_cast<int>(SizeInBytes);
myStream = stb_vorbis_open_memory(Buffer, Length, NULL, NULL);
if (myStream == NULL)
{
std::cerr << "Failed to read sound file from memory (cannot open the file)" << std::endl;
return false;
}
// Get the music parameters
stb_vorbis_info Infos = stb_vorbis_get_info(myStream);
ChannelsCount = myChannelsCount = Infos.channels;
SampleRate = Infos.sample_rate;
NbSamples = static_cast<std::size_t>(stb_vorbis_stream_length_in_samples(myStream) * ChannelsCount);
return true;
}
////////////////////////////////////////////////////////////
/// Read samples from the loaded sound
////////////////////////////////////////////////////////////
std::size_t SoundFileOgg::Read(Int16* Data, std::size_t NbSamples)
{
if (myStream && Data && NbSamples)
{
int Read = stb_vorbis_get_samples_short_interleaved(myStream, myChannelsCount, Data, static_cast<int>(NbSamples));
return static_cast<std::size_t>(Read * myChannelsCount);
}
else
{
return 0;
}
}
} // namespace priv
} // namespace sf

View File

@ -1,114 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOUNDFILEOGG_HPP
#define SFML_SOUNDFILEOGG_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Audio/SoundFile.hpp>
struct stb_vorbis;
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Specialization of SoundFile that handles ogg-vorbis files (.ogg)
/// (does not support variable bitrate / channels and writing)
////////////////////////////////////////////////////////////
class SoundFileOgg : public SoundFile
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
SoundFileOgg();
////////////////////////////////////////////////////////////
/// Destructor
///
////////////////////////////////////////////////////////////
~SoundFileOgg();
////////////////////////////////////////////////////////////
/// Check if a given file is supported by this loader
///
/// \param Filename : Path of the file to check
/// \param Read : Is the file opened for reading or writing ?
///
/// \param return True if the loader can handle this file
///
////////////////////////////////////////////////////////////
static bool IsFileSupported(const std::string& Filename, bool Read);
////////////////////////////////////////////////////////////
/// Check if a given file in memory is supported by this loader
///
/// \param Data : Pointer to the file data in memory
/// \param SizeInBytes : Size of the data to load, in bytes
///
/// \param return True if the loader can handle this file
///
////////////////////////////////////////////////////////////
static bool IsFileSupported(const char* Data, std::size_t SizeInBytes);
////////////////////////////////////////////////////////////
/// /see sf::SoundFile::Read
///
////////////////////////////////////////////////////////////
virtual std::size_t Read(Int16* Data, std::size_t NbSamples);
private :
////////////////////////////////////////////////////////////
/// /see sf::SoundFile::OpenRead
///
////////////////////////////////////////////////////////////
virtual bool OpenRead(const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate);
////////////////////////////////////////////////////////////
/// /see sf::SoundFile::OpenRead
///
////////////////////////////////////////////////////////////
virtual bool OpenRead(const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
stb_vorbis* myStream; ///< Vorbis stream
unsigned int myChannelsCount; ///< Number of channels (1 = mono, 2 = stereo)
};
} // namespace priv
} // namespace sf
#endif // SFML_SOUNDFILEOGG_HPP

File diff suppressed because it is too large Load Diff

View File

@ -1,357 +0,0 @@
// Ogg Vorbis I audio decoder -- version 0.99994
//
// Written in April 2007 by Sean Barrett, sponsored by RAD Game Tools.
//
// Placed in the public domain April 2007 by the author: no copyright is
// claimed, and you may use it for any purpose you like.
//
// No warranty for any purpose is expressed or implied by the author (nor
// by RAD Game Tools). Report bugs and send enhancements to the author.
//
// Get the latest version and other information at:
// http://nothings.org/stb_vorbis/
// Todo:
//
// - seeking (note you can seek yourself using the pushdata API)
//
// Limitations:
//
// - floor 0 not supported (used in old ogg vorbis files)
// - lossless sample-truncation at beginning ignored
// - cannot concatenate multiple vorbis streams
// - sample positions are 32-bit, limiting seekable 192Khz
// files to around 6 hours (Ogg supports 64-bit)
//
// All of these limitations may be removed in future versions.
//////////////////////////////////////////////////////////////////////////////
//
// HEADER BEGINS HERE
//
#ifndef STB_VORBIS_INCLUDE_STB_VORBIS_H
#define STB_VORBIS_INCLUDE_STB_VORBIS_H
#if defined(STB_VORBIS_NO_CRT) && !defined(STB_VORBIS_NO_STDIO)
#define STB_VORBIS_NO_STDIO 1
#endif
#ifndef STB_VORBIS_NO_STDIO
#include <stdio.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/////////// THREAD SAFETY
// Individual stb_vorbis* handles are not thread-safe; you cannot decode from
// them from multiple threads at the same time. However, you can have multiple
// stb_vorbis* handles and decode from them independently in multiple thrads.
/////////// MEMORY ALLOCATION
// normally stb_vorbis uses malloc() to allocate memory at startup,
// and alloca() to allocate temporary memory during a frame on the
// stack. (Memory consumption will depend on the amount of setup
// data in the file and how you set the compile flags for speed
// vs. size. In my test files the maximal-size usage is ~150KB.)
//
// You can modify the wrapper functions in the source (setup_malloc,
// setup_temp_malloc, temp_malloc) to change this behavior, or you
// can use a simpler allocation model: you pass in a buffer from
// which stb_vorbis will allocate _all_ its memory (including the
// temp memory). "open" may fail with a VORBIS_outofmem if you
// do not pass in enough data; there is no way to determine how
// much you do need except to succeed (at which point you can
// query get_info to find the exact amount required. yes I know
// this is lame).
//
// If you pass in a non-NULL buffer of the type below, allocation
// will occur from it as described above. Otherwise just pass NULL
// to use malloc()/alloca()
typedef struct
{
char *alloc_buffer;
int alloc_buffer_length_in_bytes;
} stb_vorbis_alloc;
/////////// FUNCTIONS USEABLE WITH ALL INPUT MODES
typedef struct stb_vorbis stb_vorbis;
typedef struct
{
unsigned int sample_rate;
int channels;
unsigned int setup_memory_required;
unsigned int setup_temp_memory_required;
unsigned int temp_memory_required;
int max_frame_size;
} stb_vorbis_info;
// get general information about the file
extern stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f);
// get the last error detected (clears it, too)
extern int stb_vorbis_get_error(stb_vorbis *f);
// close an ogg vorbis file and free all memory in use
extern void stb_vorbis_close(stb_vorbis *f);
// this function returns the offset (in samples) from the beginning of the
// file that will be returned by the next decode, if it is known, or -1
// otherwise. after a flush_pushdata() call, this may take a while before
// it becomes valid again.
// NOT WORKING YET after a seek with PULLDATA API
extern int stb_vorbis_get_sample_offset(stb_vorbis *f);
// returns the current seek point within the file, or offset from the beginning
// of the memory buffer. In pushdata mode it returns 0.
extern unsigned int stb_vorbis_get_file_offset(stb_vorbis *f);
/////////// PUSHDATA API
#ifndef STB_VORBIS_NO_PUSHDATA_API
// this API allows you to get blocks of data from any source and hand
// them to stb_vorbis. you have to buffer them; stb_vorbis will tell
// you how much it used, and you have to give it the rest next time;
// and stb_vorbis may not have enough data to work with and you will
// need to give it the same data again PLUS more. Note that the Vorbis
// specification does not bound the size of an individual frame.
extern stb_vorbis *stb_vorbis_open_pushdata(
unsigned char *datablock, int datablock_length_in_bytes,
int *datablock_memory_consumed_in_bytes,
int *error,
stb_vorbis_alloc *alloc_buffer);
// create a vorbis decoder by passing in the initial data block containing
// the ogg&vorbis headers (you don't need to do parse them, just provide
// the first N bytes of the file--you're told if it's not enough, see below)
// on success, returns an stb_vorbis *, does not set error, returns the amount of
// data parsed/consumed on this call in *datablock_memory_consumed_in_bytes;
// on failure, returns NULL on error and sets *error, does not change *datablock_memory_consumed
// if returns NULL and *error is VORBIS_need_more_data, then the input block was
// incomplete and you need to pass in a larger block from the start of the file
extern int stb_vorbis_decode_frame_pushdata(
stb_vorbis *f, unsigned char *datablock, int datablock_length_in_bytes,
int *channels, // place to write number of float * buffers
float ***output, // place to write float ** array of float * buffers
int *samples // place to write number of output samples
);
// decode a frame of audio sample data if possible from the passed-in data block
//
// return value: number of bytes we used from datablock
// possible cases:
// 0 bytes used, 0 samples output (need more data)
// N bytes used, 0 samples output (resynching the stream, keep going)
// N bytes used, M samples output (one frame of data)
// note that after opening a file, you will ALWAYS get one N-bytes,0-sample
// frame, because Vorbis always "discards" the first frame.
//
// Note that on resynch, stb_vorbis will rarely consume all of the buffer,
// instead only datablock_length_in_bytes-3 or less. This is because it wants
// to avoid missing parts of a page header if they cross a datablock boundary,
// without writing state-machiney code to record a partial detection.
//
// The number of channels returned are stored in *channels (which can be
// NULL--it is always the same as the number of channels reported by
// get_info). *output will contain an array of float* buffers, one per
// channel. In other words, (*output)[0][0] contains the first sample from
// the first channel, and (*output)[1][0] contains the first sample from
// the second channel.
extern void stb_vorbis_flush_pushdata(stb_vorbis *f);
// inform stb_vorbis that your next datablock will not be contiguous with
// previous ones (e.g. you've seeked in the data); future attempts to decode
// frames will cause stb_vorbis to resynchronize (as noted above), and
// once it sees a valid Ogg page (typically 4-8KB, as large as 64KB), it
// will begin decoding the _next_ frame.
//
// if you want to seek using pushdata, you need to seek in your file, then
// call stb_vorbis_flush_pushdata(), then start calling decoding, then once
// decoding is returning you data, call stb_vorbis_get_sample_offset, and
// if you don't like the result, seek your file again and repeat.
#endif
////////// PULLING INPUT API
#ifndef STB_VORBIS_NO_PULLDATA_API
// This API assumes stb_vorbis is allowed to pull data from a source--
// either a block of memory containing the _entire_ vorbis stream, or a
// FILE * that you or it create, or possibly some other reading mechanism
// if you go modify the source to replace the FILE * case with some kind
// of callback to your code. (But if you don't support seeking, you may
// just want to go ahead and use pushdata.)
#if !defined(STB_VORBIS_NO_STDIO) && !defined(STB_VORBIS_NO_INTEGER_CONVERSION)
extern int stb_vorbis_decode_filename(char *filename, int *channels, short **output);
#endif
extern int stb_vorbis_decode_memory(unsigned char *mem, int len, int *channels, short **output);
// decode an entire file and output the data interleaved into a malloc()ed
// buffer stored in *output. The return value is the number of samples
// decoded, or -1 if the file could not be opened or was not an ogg vorbis file.
// When you're done with it, just free() the pointer returned in *output.
extern stb_vorbis * stb_vorbis_open_memory(unsigned char *data, int len,
int *error, stb_vorbis_alloc *alloc_buffer);
// create an ogg vorbis decoder from an ogg vorbis stream in memory (note
// this must be the entire stream!). on failure, returns NULL and sets *error
#ifndef STB_VORBIS_NO_STDIO
extern stb_vorbis * stb_vorbis_open_filename(char *filename,
int *error, stb_vorbis_alloc *alloc_buffer);
// create an ogg vorbis decoder from a filename via fopen(). on failure,
// returns NULL and sets *error (possibly to VORBIS_file_open_failure).
extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close,
int *error, stb_vorbis_alloc *alloc_buffer);
// create an ogg vorbis decoder from an open FILE *, looking for a stream at
// the _current_ seek point (ftell). on failure, returns NULL and sets *error.
// note that stb_vorbis must "own" this stream; if you seek it in between
// calls to stb_vorbis, it will become confused. Morever, if you attempt to
// perform stb_vorbis_seek_*() operations on this file, it will assume it
// owns the _entire_ rest of the file after the start point. Use the next
// function, stb_vorbis_open_file_section(), to limit it.
extern stb_vorbis * stb_vorbis_open_file_section(FILE *f, int close_handle_on_close,
int *error, stb_vorbis_alloc *alloc_buffer, unsigned int len);
// create an ogg vorbis decoder from an open FILE *, looking for a stream at
// the _current_ seek point (ftell); the stream will be of length 'len' bytes.
// on failure, returns NULL and sets *error. note that stb_vorbis must "own"
// this stream; if you seek it in between calls to stb_vorbis, it will become
// confused.
#endif
extern int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number);
extern int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number);
// NOT WORKING YET
// these functions seek in the Vorbis file to (approximately) 'sample_number'.
// after calling seek_frame(), the next call to get_frame_*() will include
// the specified sample. after calling stb_vorbis_seek(), the next call to
// stb_vorbis_get_samples_* will start with the specified sample. If you
// do not need to seek to EXACTLY the target sample when using get_samples_*,
// you can also use seek_frame().
extern void stb_vorbis_seek_start(stb_vorbis *f);
// this function is equivalent to stb_vorbis_seek(f,0), but it
// actually works
extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f);
extern float stb_vorbis_stream_length_in_seconds(stb_vorbis *f);
// these functions return the total length of the vorbis stream
extern int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output);
// decode the next frame and return the number of samples. the number of
// channels returned are stored in *channels (which can be NULL--it is always
// the same as the number of channels reported by get_info). *output will
// contain an array of float* buffers, one per channel. These outputs will
// be overwritten on the next call to stb_vorbis_get_frame_*.
//
// You generally should not intermix calls to stb_vorbis_get_frame_*()
// and stb_vorbis_get_samples_*(), since the latter calls the former.
#ifndef STB_VORBIS_NO_INTEGER_CONVERSION
extern int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts);
extern int stb_vorbis_get_frame_short (stb_vorbis *f, int num_c, short **buffer, int num_samples);
#endif
// decode the next frame and return the number of samples per channel. the
// data is coerced to the number of channels you request according to the
// channel coercion rules (see below). You must pass in the size of your
// buffer(s) so that stb_vorbis will not overwrite the end of the buffer.
// The maximum buffer size needed can be gotten from get_info(); however,
// the Vorbis I specification implies an absolute maximum of 4096 samples
// per channel. Note that for interleaved data, you pass in the number of
// shorts (the size of your array), but the return value is the number of
// samples per channel, not the total number of samples.
// Channel coercion rules:
// Let M be the number of channels requested, and N the number of channels present,
// and Cn be the nth channel; let stereo L be the sum of all L and center channels,
// and stereo R be the sum of all R and center channels (channel assignment from the
// vorbis spec).
// M N output
// 1 k sum(Ck) for all k
// 2 * stereo L, stereo R
// k l k > l, the first l channels, then 0s
// k l k <= l, the first k channels
// Note that this is not _good_ surround etc. mixing at all! It's just so
// you get something useful.
extern int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats);
extern int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples);
// gets num_samples samples, not necessarily on a frame boundary--this requires
// buffering so you have to supply the buffers. DOES NOT APPLY THE COERCION RULES.
// Returns the number of samples stored per channel; it may be less than requested
// at the end of the file. If there are no more samples in the file, returns 0.
#ifndef STB_VORBIS_NO_INTEGER_CONVERSION
extern int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts);
extern int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int num_samples);
#endif
// gets num_samples samples, not necessarily on a frame boundary--this requires
// buffering so you have to supply the buffers. Applies the coercion rules above
// to produce 'channels' channels. Returns the number of samples stored per channel;
// it may be less than requested at the end of the file. If there are no more
// samples in the file, returns 0.
#endif
//////// ERROR CODES
enum STBVorbisError
{
VORBIS__no_error,
VORBIS_need_more_data=1, // not a real error
VORBIS_invalid_api_mixing, // can't mix API modes
VORBIS_outofmem, // not enough memory
VORBIS_feature_not_supported, // uses floor 0
VORBIS_too_many_channels, // STB_VORBIS_MAX_CHANNELS is too small
VORBIS_file_open_failure, // fopen() failed
VORBIS_seek_without_length, // can't seek in unknown-length file
VORBIS_unexpected_eof=10, // file is truncated?
VORBIS_seek_invalid, // seek past EOF
// decoding errors (corrupt/invalid stream) -- you probably
// don't care about the exact details of these
// vorbis errors:
VORBIS_invalid_setup=20,
VORBIS_invalid_stream,
// ogg errors:
VORBIS_missing_capture_pattern=30,
VORBIS_invalid_stream_structure_version,
VORBIS_continued_packet_flag_invalid,
VORBIS_incorrect_stream_serial_number,
VORBIS_invalid_first_page,
VORBIS_bad_packet_type,
VORBIS_cant_find_last_page,
VORBIS_seek_failed
};
#ifdef __cplusplus
}
#endif
#endif // STB_VORBIS_INCLUDE_STB_VORBIS_H
//
// HEADER ENDS HERE
//
//////////////////////////////////////////////////////////////////////////////