Back to index

libsfml  1.6+dfsg2
SoundFileDefault.cpp
Go to the documentation of this file.
00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #include <SFML/Audio/SoundFileDefault.hpp>
00029 #include <iostream>
00030 #include <string.h>
00031 
00032 
00033 namespace sf
00034 {
00035 namespace priv
00036 {
00040 SoundFileDefault::SoundFileDefault() :
00041 myFile(NULL)
00042 {
00043 
00044 }
00045 
00046 
00050 SoundFileDefault::~SoundFileDefault()
00051 {
00052     if (myFile)
00053         sf_close(myFile);
00054 }
00055 
00056 
00060 bool SoundFileDefault::IsFileSupported(const std::string& Filename, bool Read)
00061 {
00062     if (Read)
00063     {
00064         // Open the sound file
00065         SF_INFO FileInfos;
00066         SNDFILE* File = sf_open(Filename.c_str(), SFM_READ, &FileInfos);
00067 
00068         if (File)
00069         {
00070             sf_close(File);
00071             return true;
00072         }
00073         else
00074         {
00075             return false;
00076         }
00077     }
00078     else
00079     {
00080         // Check the extension
00081         return GetFormatFromFilename(Filename) != -1;
00082     }
00083 }
00084 
00085 
00089 bool SoundFileDefault::IsFileSupported(const char* Data, std::size_t SizeInBytes)
00090 {
00091     // Define the I/O custom functions for reading from memory
00092     SF_VIRTUAL_IO VirtualIO;
00093     VirtualIO.get_filelen = &SoundFileDefault::MemoryGetLength;
00094     VirtualIO.read        = &SoundFileDefault::MemoryRead;
00095     VirtualIO.seek        = &SoundFileDefault::MemorySeek;
00096     VirtualIO.tell        = &SoundFileDefault::MemoryTell;
00097     VirtualIO.write       = &SoundFileDefault::MemoryWrite;
00098 
00099     // Initialize the memory data
00100     MemoryInfos Memory;
00101     Memory.DataStart = Data;
00102     Memory.DataPtr   = Data;
00103     Memory.TotalSize = SizeInBytes;
00104 
00105     // Open the sound file
00106     SF_INFO FileInfos;
00107     SNDFILE* File = sf_open_virtual(&VirtualIO, SFM_READ, &FileInfos, &Memory);
00108 
00109     if (File)
00110     {
00111         sf_close(File);
00112         return true;
00113     }
00114     else
00115     {
00116         return false;
00117     }
00118 }
00119 
00120 
00124 bool SoundFileDefault::OpenRead(const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate)
00125 {
00126     // If the file is already opened, first close it
00127     if (myFile)
00128         sf_close(myFile);
00129 
00130     // Open the sound file
00131     SF_INFO FileInfos;
00132     myFile = sf_open(Filename.c_str(), SFM_READ, &FileInfos);
00133     if (!myFile)
00134     {
00135         std::cerr << "Failed to read sound file \"" << Filename << "\"" << std::endl;
00136         return false;
00137     }
00138 
00139     // Set the sound parameters
00140     ChannelsCount = FileInfos.channels;
00141     SampleRate    = FileInfos.samplerate;
00142     NbSamples     = static_cast<std::size_t>(FileInfos.frames) * ChannelsCount;
00143 
00144     return true;
00145 }
00146 
00147 
00151 bool SoundFileDefault::OpenRead(const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate)
00152 {
00153     // If the file is already opened, first close it
00154     if (myFile)
00155         sf_close(myFile);
00156 
00157     // Define the I/O custom functions for reading from memory
00158     SF_VIRTUAL_IO VirtualIO;
00159     VirtualIO.get_filelen = &SoundFileDefault::MemoryGetLength;
00160     VirtualIO.read        = &SoundFileDefault::MemoryRead;
00161     VirtualIO.seek        = &SoundFileDefault::MemorySeek;
00162     VirtualIO.tell        = &SoundFileDefault::MemoryTell;
00163     VirtualIO.write       = &SoundFileDefault::MemoryWrite;
00164 
00165     // Initialize the memory data
00166     myMemory.DataStart = Data;
00167     myMemory.DataPtr   = Data;
00168     myMemory.TotalSize = SizeInBytes;
00169 
00170     // Open the sound file
00171     SF_INFO FileInfos;
00172     myFile = sf_open_virtual(&VirtualIO, SFM_READ, &FileInfos, &myMemory);
00173     if (!myFile)
00174     {
00175         std::cerr << "Failed to read sound file from memory" << std::endl;
00176         return false;
00177     }
00178 
00179     // Set the sound parameters
00180     ChannelsCount = FileInfos.channels;
00181     SampleRate    = FileInfos.samplerate;
00182     NbSamples     = static_cast<std::size_t>(FileInfos.frames) * ChannelsCount;
00183 
00184     return true;
00185 }
00186 
00187 
00191 bool SoundFileDefault::OpenWrite(const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate)
00192 {
00193     // If the file is already opened, first close it
00194     if (myFile)
00195         sf_close(myFile);
00196 
00197     // Find the right format according to the file extension
00198     int Format = GetFormatFromFilename(Filename);
00199     if (Format == -1)
00200     {
00201         // Error : unrecognized extension
00202         std::cerr << "Failed to create sound file \"" << Filename << "\" : unknown format" << std::endl;
00203         return false;
00204     }
00205 
00206     // Fill the sound infos with parameters
00207     SF_INFO FileInfos;
00208     FileInfos.channels   = ChannelsCount;
00209     FileInfos.samplerate = SampleRate;
00210     FileInfos.format     = Format | SF_FORMAT_PCM_16;
00211 
00212     // Open the sound file for writing
00213     myFile = sf_open(Filename.c_str(), SFM_WRITE, &FileInfos);
00214     if (!myFile)
00215     {
00216         std::cerr << "Failed to create sound file \"" << Filename << "\"" << std::endl;
00217         return false;
00218     }
00219 
00220     return true;
00221 }
00222 
00223 
00227 std::size_t SoundFileDefault::Read(Int16* Data, std::size_t NbSamples)
00228 {
00229     if (myFile && Data && NbSamples)
00230         return static_cast<std::size_t>(sf_read_short(myFile, Data, NbSamples));
00231     else
00232         return 0;
00233 }
00234 
00235 
00239 void SoundFileDefault::Write(const Int16* Data, std::size_t NbSamples)
00240 {
00241     if (myFile && Data && NbSamples)
00242         sf_write_short(myFile, Data, NbSamples);
00243 }
00244 
00245 
00250 int SoundFileDefault::GetFormatFromFilename(const std::string& Filename)
00251 {
00252     // Extract the extension
00253     std::string Ext = "wav";
00254     std::string::size_type Pos = Filename.find_last_of(".");
00255     if (Pos != std::string::npos)
00256         Ext = Filename.substr(Pos + 1);
00257 
00258     // Match every supported extension with its format constant
00259     if (Ext == "wav"  || Ext == "WAV" ) return SF_FORMAT_WAV;
00260     if (Ext == "aif"  || Ext == "AIF" ) return SF_FORMAT_AIFF;
00261     if (Ext == "aiff" || Ext == "AIFF") return SF_FORMAT_AIFF;
00262     if (Ext == "au"   || Ext == "AU"  ) return SF_FORMAT_AU;
00263     if (Ext == "raw"  || Ext == "RAW" ) return SF_FORMAT_RAW;
00264     if (Ext == "paf"  || Ext == "PAF" ) return SF_FORMAT_PAF;
00265     if (Ext == "svx"  || Ext == "SVX" ) return SF_FORMAT_SVX;
00266     if (Ext == "voc"  || Ext == "VOC" ) return SF_FORMAT_VOC;
00267     if (Ext == "sf"   || Ext == "SF"  ) return SF_FORMAT_IRCAM;
00268     if (Ext == "w64"  || Ext == "W64" ) return SF_FORMAT_W64;
00269     if (Ext == "mat4" || Ext == "MAT4") return SF_FORMAT_MAT4;
00270     if (Ext == "mat5" || Ext == "MAT5") return SF_FORMAT_MAT5;
00271     if (Ext == "pvf"  || Ext == "PVF" ) return SF_FORMAT_PVF;
00272     if (Ext == "htk"  || Ext == "HTK" ) return SF_FORMAT_HTK;
00273     if (Ext == "caf"  || Ext == "CAF" ) return SF_FORMAT_CAF;
00274     if (Ext == "nist" || Ext == "NIST") return SF_FORMAT_NIST; // SUPPORTED ?
00275     if (Ext == "sds"  || Ext == "SDS" ) return SF_FORMAT_SDS;  // SUPPORTED ?
00276     if (Ext == "avr"  || Ext == "AVR" ) return SF_FORMAT_AVR;  // SUPPORTED ?
00277     if (Ext == "sd2"  || Ext == "SD2" ) return SF_FORMAT_SD2;  // SUPPORTED ?
00278     if (Ext == "flac" || Ext == "FLAC") return SF_FORMAT_FLAC; // SUPPORTED ?
00279 
00280     return -1;
00281 }
00282 
00283 
00288 sf_count_t SoundFileDefault::MemoryGetLength(void* UserData)
00289 {
00290     MemoryInfos* Memory = static_cast<MemoryInfos*>(UserData);
00291 
00292     return Memory->TotalSize;
00293 }
00294 sf_count_t SoundFileDefault::MemoryRead(void* Ptr, sf_count_t Count, void* UserData)
00295 {
00296     MemoryInfos* Memory = static_cast<MemoryInfos*>(UserData);
00297 
00298     sf_count_t Position = Memory->DataPtr - Memory->DataStart;
00299     if (Position + Count >= Memory->TotalSize)
00300         Count = Memory->TotalSize - Position;
00301 
00302     memcpy(Ptr, Memory->DataPtr, static_cast<std::size_t>(Count));
00303 
00304     Memory->DataPtr += Count;
00305 
00306     return Count;
00307 }
00308 sf_count_t SoundFileDefault::MemorySeek(sf_count_t Offset, int Whence, void* UserData)
00309 {
00310     MemoryInfos* Memory = static_cast<MemoryInfos*>(UserData);
00311 
00312     sf_count_t Position = 0;
00313     switch (Whence)
00314     {
00315         case SEEK_SET :
00316             Position = Offset;
00317             break;
00318         case SEEK_CUR :
00319             Position = Memory->DataPtr - Memory->DataStart + Offset;
00320             break;
00321         case SEEK_END :
00322             Position = Memory->TotalSize - Offset;
00323             break;
00324         default :
00325             Position = 0;
00326             break;
00327     }
00328 
00329     if (Position >= Memory->TotalSize)
00330         Position = Memory->TotalSize - 1;
00331     else if (Position < 0)
00332         Position = 0;
00333 
00334     Memory->DataPtr = Memory->DataStart + Position;
00335 
00336     return Position;
00337 }
00338 sf_count_t SoundFileDefault::MemoryTell(void* UserData)
00339 {
00340     MemoryInfos* Memory = static_cast<MemoryInfos*>(UserData);
00341 
00342     return Memory->DataPtr - Memory->DataStart;
00343 }
00344 sf_count_t SoundFileDefault::MemoryWrite(const void*, sf_count_t, void*)
00345 {
00346     return 0;
00347 }
00348 
00349 
00350 } // namespace priv
00351 
00352 } // namespace sf