SoundBuffer.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007 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/SoundBuffer.hpp>
00029 #include <SFML/Audio/SoundFile.hpp>
00030 #include <SFML/Audio/AudioDevice.hpp>
00031 #include <SFML/Audio/OpenAL.hpp>
00032 #include <iostream>
00033 #include <memory>
00034 
00035 
00039 sfSoundBuffer::sfSoundBuffer() :
00040 myBuffer  (0),
00041 myDuration(0.f)
00042 {
00043     // Create the buffer
00044     sfALCheck(alGenBuffers(1, &myBuffer));
00045 }
00046 
00047 
00051 sfSoundBuffer::sfSoundBuffer(const sfSoundBuffer& Copy) :
00052 myBuffer  (0),
00053 mySamples (Copy.mySamples),
00054 myDuration(Copy.myDuration)
00055 {
00056     // Create the buffer
00057     sfALCheck(alGenBuffers(1, &myBuffer));
00058 
00059     // Update the internal buffer with the new samples
00060     Update(Copy.GetChannelsCount(), Copy.GetSampleRate());
00061 }
00062 
00063 
00067 sfSoundBuffer::~sfSoundBuffer()
00068 {
00069     DestroyAudioResources();
00070 }
00071 
00072 
00076 bool sfSoundBuffer::LoadFromFile(const std::string& Filename)
00077 {
00078     // Create the sound file
00079     std::auto_ptr<sf_private::sfSoundFile> File(sf_private::sfSoundFile::Create(Filename));
00080 
00081     // Open the sound file
00082     std::size_t  NbSamples;
00083     unsigned int ChannelsCount, SampleRate;
00084     if (File->OpenRead(Filename, NbSamples, ChannelsCount, SampleRate))
00085     {
00086         // Read the samples from the opened file
00087         mySamples.resize(NbSamples);
00088         if (File->Read(&mySamples[0], NbSamples) == NbSamples)
00089         {
00090             // Update the internal buffer with the new samples
00091             return Update(ChannelsCount, SampleRate);
00092         }
00093         else
00094         {
00095             // Error...
00096             std::cerr << "Failed to read audio data from file \"" << Filename << "\"" << std::endl;
00097 
00098             return false;
00099         }
00100     }
00101     else
00102     {
00103         // Error...
00104         std::cerr << "Failed to load sound buffer from file \"" << Filename << "\"" << std::endl;
00105 
00106         return false;
00107     }
00108 }
00109 
00110 
00114 bool sfSoundBuffer::LoadFromMemory(const sfInt16* Samples, std::size_t SamplesCount, unsigned int ChannelsCount, unsigned int SampleRate)
00115 {
00116     if (Samples && SamplesCount && ChannelsCount && SampleRate)
00117     {
00118         // Copy the new audio samples
00119         mySamples.assign(Samples, Samples + SamplesCount);
00120 
00121         // Update the internal buffer with the new samples
00122         return Update(ChannelsCount, SampleRate);
00123     }
00124     else
00125     {
00126         // Error...
00127         std::cerr << "Failed to load sound buffer from memory ("
00128                   << "Samples : "        << Samples       << ", "
00129                   << "Samples count : "  << SamplesCount  << ", "
00130                   << "Channels count : " << ChannelsCount << ", "
00131                   << "Sample rate : "    << SampleRate    << ")"
00132                   << std::endl;
00133 
00134         return false;
00135     }
00136 }
00137 
00138 
00142 bool sfSoundBuffer::SaveToFile(const std::string& Filename) const
00143 {
00144     // Create the sound file
00145     std::auto_ptr<sf_private::sfSoundFile> File(sf_private::sfSoundFile::Create(Filename));
00146 
00147     // Open a sound file
00148     if (File->OpenWrite(Filename, GetChannelsCount(), GetSampleRate()))
00149     {
00150         // Write the samples to the opened file
00151         File->Write(&mySamples[0], mySamples.size());
00152 
00153         return true;
00154     }
00155     else
00156     {
00157         // Error...
00158         std::cerr << "Failed to save sound buffer to file \"" << Filename << "\"" << std::endl;
00159 
00160         return false;
00161     }
00162 }
00163 
00164 
00168 const sfInt16* sfSoundBuffer::GetSamples() const
00169 {
00170     return mySamples.empty() ? NULL : &mySamples[0];
00171 }
00172 
00173 
00177 std::size_t sfSoundBuffer::GetSamplesCount() const
00178 {
00179     return mySamples.size();
00180 }
00181 
00182 
00186 unsigned int sfSoundBuffer::GetSampleRate() const
00187 {
00188     ALint SampleRate;
00189     sfALCheck(alGetBufferi(myBuffer, AL_FREQUENCY, &SampleRate));
00190 
00191     return SampleRate;
00192 }
00193 
00194 
00198 unsigned int sfSoundBuffer::GetChannelsCount() const
00199 {
00200     ALint ChannelsCount;
00201     sfALCheck(alGetBufferi(myBuffer, AL_CHANNELS, &ChannelsCount));
00202 
00203     return ChannelsCount;
00204 }
00205 
00206 
00210 float sfSoundBuffer::GetDuration() const
00211 {
00212     return myDuration;
00213 }
00214 
00215 
00219 sfSoundBuffer& sfSoundBuffer::operator =(const sfSoundBuffer& Other)
00220 {
00221     sfSoundBuffer Temp(Other);
00222 
00223     mySamples.swap(Temp.mySamples);
00224     std::swap(myBuffer,   Temp.myBuffer);
00225     std::swap(myDuration, Temp.myDuration);
00226 
00227     return *this;
00228 }
00229 
00230 
00234 bool sfSoundBuffer::Update(unsigned int ChannelsCount, unsigned int SampleRate)
00235 {
00236     // Check parameters
00237     if (!SampleRate || !ChannelsCount || mySamples.empty())
00238         return false;
00239 
00240     // Find the good format according to the number of channels
00241     ALenum Format = sf_private::sfAudioDevice::GetInstance().GetFormatFromChannelsCount(ChannelsCount);
00242 
00243     // Check if the format is valid
00244     if (Format == 0)
00245     {
00246         std::cerr << "Unsupported number of channels (" << ChannelsCount << ")" << std::endl;
00247         return false;
00248     }
00249 
00250     // Fill the buffer
00251     ALsizei Size = static_cast<ALsizei>(mySamples.size()) * sizeof(sfInt16);
00252     sfALCheck(alBufferData(myBuffer, Format, &mySamples[0], Size, SampleRate));
00253 
00254     // Compute the duration
00255     myDuration = static_cast<float>(mySamples.size()) / SampleRate / ChannelsCount;
00256 
00257     return true;
00258 }
00259 
00260 
00264 void sfSoundBuffer::DestroyAudioResources()
00265 {
00266     if (myBuffer)
00267     {
00268         sfALCheck(alDeleteBuffers(1, &myBuffer));
00269         myBuffer = 0;
00270     }
00271 }