SFML logo
  • Main Page
  • Namespaces
  • Classes
  • Files
  • File List

SoundBuffer.cpp

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/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 
00036 namespace sf
00037 {
00041 SoundBuffer::SoundBuffer() :
00042 myBuffer  (0),
00043 myDuration(0.f)
00044 {
00045     // Create the buffer
00046     ALCheck(alGenBuffers(1, &myBuffer));
00047 }
00048 
00049 
00053 SoundBuffer::SoundBuffer(const SoundBuffer& Copy) :
00054 AudioResource        (Copy),
00055 Resource<SoundBuffer>(Copy),
00056 myBuffer             (0),
00057 mySamples            (Copy.mySamples),
00058 myDuration           (Copy.myDuration)
00059 {
00060     // Create the buffer
00061     ALCheck(alGenBuffers(1, &myBuffer));
00062 
00063     // Update the internal buffer with the new samples
00064     Update(Copy.GetChannelsCount(), Copy.GetSampleRate());
00065 }
00066 
00067 
00071 SoundBuffer::~SoundBuffer()
00072 {
00073     if (myBuffer)
00074         ALCheck(alDeleteBuffers(1, &myBuffer));
00075 }
00076 
00077 
00081 bool SoundBuffer::LoadFromFile(const std::string& Filename)
00082 {
00083     // Create the sound file
00084     std::auto_ptr<priv::SoundFile> File(priv::SoundFile::CreateRead(Filename));
00085 
00086     // Open the sound file
00087     if (File.get())
00088     {
00089         // Get the sound parameters
00090         std::size_t  NbSamples     = File->GetSamplesCount();
00091         unsigned int ChannelsCount = File->GetChannelsCount();
00092         unsigned int SampleRate    = File->GetSampleRate();
00093 
00094         // Read the samples from the opened file
00095         mySamples.resize(NbSamples);
00096         if (File->Read(&mySamples[0], NbSamples) == NbSamples)
00097         {
00098             // Update the internal buffer with the new samples
00099             return Update(ChannelsCount, SampleRate);
00100         }
00101         else
00102         {
00103             // Error...
00104             std::cerr << "Failed to read audio data from file \"" << Filename << "\"" << std::endl;
00105 
00106             return false;
00107         }
00108     }
00109     else
00110     {
00111         // Error...
00112         std::cerr << "Failed to load sound buffer from file \"" << Filename << "\"" << std::endl;
00113 
00114         return false;
00115     }
00116 }
00117 
00118 
00122 bool SoundBuffer::LoadFromMemory(const char* Data, std::size_t SizeInBytes)
00123 {
00124     // Create the sound file
00125     std::auto_ptr<priv::SoundFile> File(priv::SoundFile::CreateRead(Data, SizeInBytes));
00126 
00127     // Open the sound file
00128     if (File.get())
00129     {
00130         // Get the sound parameters
00131         std::size_t  NbSamples     = File->GetSamplesCount();
00132         unsigned int ChannelsCount = File->GetChannelsCount();
00133         unsigned int SampleRate    = File->GetSampleRate();
00134 
00135         // Read the samples from the opened file
00136         mySamples.resize(NbSamples);
00137         if (File->Read(&mySamples[0], NbSamples) == NbSamples)
00138         {
00139             // Update the internal buffer with the new samples
00140             return Update(ChannelsCount, SampleRate);
00141         }
00142         else
00143         {
00144             // Error...
00145             std::cerr << "Failed to read audio data from file in memory" << std::endl;
00146 
00147             return false;
00148         }
00149     }
00150     else
00151     {
00152         // Error...
00153         std::cerr << "Failed to load sound buffer from file in memory" << std::endl;
00154 
00155         return false;
00156     }
00157 }
00158 
00159 
00164 bool SoundBuffer::LoadFromSamples(const Int16* Samples, std::size_t SamplesCount, unsigned int ChannelsCount, unsigned int SampleRate)
00165 {
00166     if (Samples && SamplesCount && ChannelsCount && SampleRate)
00167     {
00168         // Copy the new audio samples
00169         mySamples.assign(Samples, Samples + SamplesCount);
00170 
00171         // Update the internal buffer with the new samples
00172         return Update(ChannelsCount, SampleRate);
00173     }
00174     else
00175     {
00176         // Error...
00177         std::cerr << "Failed to load sound buffer from memory ("
00178                   << "Samples : "        << Samples       << ", "
00179                   << "Samples count : "  << SamplesCount  << ", "
00180                   << "Channels count : " << ChannelsCount << ", "
00181                   << "Sample rate : "    << SampleRate    << ")"
00182                   << std::endl;
00183 
00184         return false;
00185     }
00186 }
00187 
00188 
00192 bool SoundBuffer::SaveToFile(const std::string& Filename) const
00193 {
00194     // Create the sound file in write mode
00195     std::auto_ptr<priv::SoundFile> File(priv::SoundFile::CreateWrite(Filename, GetChannelsCount(), GetSampleRate()));
00196     if (File.get())
00197     {
00198         // Write the samples to the opened file
00199         File->Write(&mySamples[0], mySamples.size());
00200 
00201         return true;
00202     }
00203     else
00204     {
00205         // Error...
00206         std::cerr << "Failed to save sound buffer to file \"" << Filename << "\"" << std::endl;
00207 
00208         return false;
00209     }
00210 }
00211 
00212 
00216 const Int16* SoundBuffer::GetSamples() const
00217 {
00218     return mySamples.empty() ? NULL : &mySamples[0];
00219 }
00220 
00221 
00225 std::size_t SoundBuffer::GetSamplesCount() const
00226 {
00227     return mySamples.size();
00228 }
00229 
00230 
00234 unsigned int SoundBuffer::GetSampleRate() const
00235 {
00236     ALint SampleRate;
00237     ALCheck(alGetBufferi(myBuffer, AL_FREQUENCY, &SampleRate));
00238 
00239     return SampleRate;
00240 }
00241 
00242 
00246 unsigned int SoundBuffer::GetChannelsCount() const
00247 {
00248     ALint ChannelsCount;
00249     ALCheck(alGetBufferi(myBuffer, AL_CHANNELS, &ChannelsCount));
00250 
00251     return ChannelsCount;
00252 }
00253 
00254 
00258 float SoundBuffer::GetDuration() const
00259 {
00260     return myDuration;
00261 }
00262 
00263 
00267 SoundBuffer& SoundBuffer::operator =(const SoundBuffer& Other)
00268 {
00269     SoundBuffer Temp(Other);
00270 
00271     mySamples.swap(Temp.mySamples);
00272     std::swap(myBuffer,   Temp.myBuffer);
00273     std::swap(myDuration, Temp.myDuration);
00274 
00275     return *this;
00276 }
00277 
00278 
00282 bool SoundBuffer::Update(unsigned int ChannelsCount, unsigned int SampleRate)
00283 {
00284     // Check parameters
00285     if (!SampleRate || !ChannelsCount || mySamples.empty())
00286         return false;
00287 
00288     // Find the good format according to the number of channels
00289     ALenum Format = priv::AudioDevice::GetInstance().GetFormatFromChannelsCount(ChannelsCount);
00290 
00291     // Check if the format is valid
00292     if (Format == 0)
00293     {
00294         std::cerr << "Unsupported number of channels (" << ChannelsCount << ")" << std::endl;
00295         return false;
00296     }
00297 
00298     // Fill the buffer
00299     ALsizei Size = static_cast<ALsizei>(mySamples.size()) * sizeof(Int16);
00300     ALCheck(alBufferData(myBuffer, Format, &mySamples[0], Size, SampleRate));
00301 
00302     // Compute the duration
00303     myDuration = static_cast<float>(mySamples.size()) / SampleRate / ChannelsCount;
00304 
00305     return true;
00306 }
00307 
00308 } // namespace sf

 ::  Copyright © 2007-2008 Laurent Gomila, all rights reserved  ::  Documentation generated by doxygen 1.5.2  ::