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:
parent
392eb219f2
commit
137ef64f2a
@ -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" />
|
||||
|
@ -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 />
|
||||
|
@ -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"
|
||||
>
|
||||
|
@ -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.
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
@ -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
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
Loading…
Reference in New Issue
Block a user