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 ::