SFML - Simple and Fast Multimedia Library
Main Page
Namespaces
Classes
Files
File List
SoundBuffer.cpp00001
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/Sound.hpp>
00031 #include <SFML/Audio/AudioDevice.hpp>
00032 #include <SFML/Audio/OpenAL.hpp>
00033 #include <iostream>
00034 #include <memory>
00035
00036
00037 namespace sf
00038 {
00042 SoundBuffer::SoundBuffer() :
00043 myBuffer (0),
00044 myDuration(0.f)
00045 {
00046 // Create the buffer
00047 ALCheck(alGenBuffers(1, &myBuffer));
00048 }
00049
00050
00054 SoundBuffer::SoundBuffer(const SoundBuffer& Copy) :
00055 AudioResource (Copy),
00056 Resource<SoundBuffer>(Copy),
00057 myBuffer (0),
00058 mySamples (Copy.mySamples),
00059 myDuration (Copy.myDuration),
00060 mySounds () // don't copy the attached sounds
00061 {
00062 // Create the buffer
00063 ALCheck(alGenBuffers(1, &myBuffer));
00064
00065 // Update the internal buffer with the new samples
00066 Update(Copy.GetChannelsCount(), Copy.GetSampleRate());
00067 }
00068
00069
00073 SoundBuffer::~SoundBuffer()
00074 {
00075 // First detach the buffer from the sounds that use it (to avoid OpenAL errors)
00076 for (SoundList::const_iterator it = mySounds.begin(); it != mySounds.end(); ++it)
00077 (*it)->ResetBuffer();
00078
00079 // Destroy the buffer
00080 if (myBuffer)
00081 ALCheck(alDeleteBuffers(1, &myBuffer));
00082 }
00083
00084
00088 bool SoundBuffer::LoadFromFile(const std::string& Filename)
00089 {
00090 // Create the sound file
00091 std::auto_ptr<priv::SoundFile> File(priv::SoundFile::CreateRead(Filename));
00092
00093 // Open the sound file
00094 if (File.get())
00095 {
00096 // Get the sound parameters
00097 std::size_t NbSamples = File->GetSamplesCount();
00098 unsigned int ChannelsCount = File->GetChannelsCount();
00099 unsigned int SampleRate = File->GetSampleRate();
00100
00101 // Read the samples from the opened file
00102 mySamples.resize(NbSamples);
00103 if (File->Read(&mySamples[0], NbSamples) == NbSamples)
00104 {
00105 // Update the internal buffer with the new samples
00106 return Update(ChannelsCount, SampleRate);
00107 }
00108 else
00109 {
00110 // Error...
00111 std::cerr << "Failed to read audio data from file \"" << Filename << "\"" << std::endl;
00112
00113 return false;
00114 }
00115 }
00116 else
00117 {
00118 // Error...
00119 std::cerr << "Failed to load sound buffer from file \"" << Filename << "\"" << std::endl;
00120
00121 return false;
00122 }
00123 }
00124
00125
00129 bool SoundBuffer::LoadFromMemory(const char* Data, std::size_t SizeInBytes)
00130 {
00131 // Create the sound file
00132 std::auto_ptr<priv::SoundFile> File(priv::SoundFile::CreateRead(Data, SizeInBytes));
00133
00134 // Open the sound file
00135 if (File.get())
00136 {
00137 // Get the sound parameters
00138 std::size_t NbSamples = File->GetSamplesCount();
00139 unsigned int ChannelsCount = File->GetChannelsCount();
00140 unsigned int SampleRate = File->GetSampleRate();
00141
00142 // Read the samples from the opened file
00143 mySamples.resize(NbSamples);
00144 if (File->Read(&mySamples[0], NbSamples) == NbSamples)
00145 {
00146 // Update the internal buffer with the new samples
00147 return Update(ChannelsCount, SampleRate);
00148 }
00149 else
00150 {
00151 // Error...
00152 std::cerr << "Failed to read audio data from file in memory" << std::endl;
00153
00154 return false;
00155 }
00156 }
00157 else
00158 {
00159 // Error...
00160 std::cerr << "Failed to load sound buffer from file in memory" << std::endl;
00161
00162 return false;
00163 }
00164 }
00165
00166
00171 bool SoundBuffer::LoadFromSamples(const Int16* Samples, std::size_t SamplesCount, unsigned int ChannelsCount, unsigned int SampleRate)
00172 {
00173 if (Samples && SamplesCount && ChannelsCount && SampleRate)
00174 {
00175 // Copy the new audio samples
00176 mySamples.assign(Samples, Samples + SamplesCount);
00177
00178 // Update the internal buffer with the new samples
00179 return Update(ChannelsCount, SampleRate);
00180 }
00181 else
00182 {
00183 // Error...
00184 std::cerr << "Failed to load sound buffer from memory ("
00185 << "Samples : " << Samples << ", "
00186 << "Samples count : " << SamplesCount << ", "
00187 << "Channels count : " << ChannelsCount << ", "
00188 << "Sample rate : " << SampleRate << ")"
00189 << std::endl;
00190
00191 return false;
00192 }
00193 }
00194
00195
00199 bool SoundBuffer::SaveToFile(const std::string& Filename) const
00200 {
00201 // Create the sound file in write mode
00202 std::auto_ptr<priv::SoundFile> File(priv::SoundFile::CreateWrite(Filename, GetChannelsCount(), GetSampleRate()));
00203 if (File.get())
00204 {
00205 // Write the samples to the opened file
00206 File->Write(&mySamples[0], mySamples.size());
00207
00208 return true;
00209 }
00210 else
00211 {
00212 // Error...
00213 std::cerr << "Failed to save sound buffer to file \"" << Filename << "\"" << std::endl;
00214
00215 return false;
00216 }
00217 }
00218
00219
00223 const Int16* SoundBuffer::GetSamples() const
00224 {
00225 return mySamples.empty() ? NULL : &mySamples[0];
00226 }
00227
00228
00232 std::size_t SoundBuffer::GetSamplesCount() const
00233 {
00234 return mySamples.size();
00235 }
00236
00237
00241 unsigned int SoundBuffer::GetSampleRate() const
00242 {
00243 ALint SampleRate;
00244 ALCheck(alGetBufferi(myBuffer, AL_FREQUENCY, &SampleRate));
00245
00246 return SampleRate;
00247 }
00248
00249
00253 unsigned int SoundBuffer::GetChannelsCount() const
00254 {
00255 ALint ChannelsCount;
00256 ALCheck(alGetBufferi(myBuffer, AL_CHANNELS, &ChannelsCount));
00257
00258 return ChannelsCount;
00259 }
00260
00261
00265 float SoundBuffer::GetDuration() const
00266 {
00267 return myDuration;
00268 }
00269
00270
00274 SoundBuffer& SoundBuffer::operator =(const SoundBuffer& Other)
00275 {
00276 SoundBuffer Temp(Other);
00277
00278 std::swap(mySamples, Temp.mySamples);
00279 std::swap(myBuffer, Temp.myBuffer);
00280 std::swap(myDuration, Temp.myDuration);
00281 std::swap(mySounds, Temp.mySounds); // swap sounds too, so that they are detached when Temp is destroyed
00282
00283 return *this;
00284 }
00285
00286
00290 bool SoundBuffer::Update(unsigned int ChannelsCount, unsigned int SampleRate)
00291 {
00292 // Check parameters
00293 if (!SampleRate || !ChannelsCount || mySamples.empty())
00294 return false;
00295
00296 // Find the good format according to the number of channels
00297 ALenum Format = priv::AudioDevice::GetInstance().GetFormatFromChannelsCount(ChannelsCount);
00298
00299 // Check if the format is valid
00300 if (Format == 0)
00301 {
00302 std::cerr << "Unsupported number of channels (" << ChannelsCount << ")" << std::endl;
00303 return false;
00304 }
00305
00306 // Fill the buffer
00307 ALsizei Size = static_cast<ALsizei>(mySamples.size()) * sizeof(Int16);
00308 ALCheck(alBufferData(myBuffer, Format, &mySamples[0], Size, SampleRate));
00309
00310 // Compute the duration
00311 myDuration = static_cast<float>(mySamples.size()) / SampleRate / ChannelsCount;
00312
00313 return true;
00314 }
00315
00316
00320 void SoundBuffer::AttachSound(Sound* Instance) const
00321 {
00322 mySounds.insert(Instance);
00323 }
00324
00325
00329 void SoundBuffer::DetachSound(Sound* Instance) const
00330 {
00331 mySounds.erase(Instance);
00332 }
00333
00334 } // namespace sf
:: Copyright © 2007-2008 Laurent Gomila, all rights reserved ::
Documentation generated by doxygen 1.5.2 ::
Wyszukiwarka
Podobne podstrony:
SoundBufferRecorder?pp sourceSoundBufferRecorder 8hpp sourcesource30Matrix3?pp sourceThread?pp sourcearm biquad ?scade ?1 ?st q31? sourcearm conv ?2? sourcearm mat mult q15? sourceResource 8inl sourcearm fir lattice init q31? sourcearm fir ?cimate ?st q15? sourcesource11arm correlate ?st q15? sourceconnector?s sourcesource8register? sourcewięcej podobnych podstron