00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024
00026
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
00046 ALCheck(alGenBuffers(1, &myBuffer));
00047 }
00048
00049
00053 SoundBuffer::SoundBuffer(const SoundBuffer& Copy) :
00054 AudioResource(Copy),
00055 myBuffer (0),
00056 mySamples (Copy.mySamples),
00057 myDuration (Copy.myDuration)
00058 {
00059
00060 ALCheck(alGenBuffers(1, &myBuffer));
00061
00062
00063 Update(Copy.GetChannelsCount(), Copy.GetSampleRate());
00064 }
00065
00066
00070 SoundBuffer::~SoundBuffer()
00071 {
00072 if (myBuffer)
00073 ALCheck(alDeleteBuffers(1, &myBuffer));
00074 }
00075
00076
00080 bool SoundBuffer::LoadFromFile(const std::string& Filename)
00081 {
00082
00083 std::auto_ptr<priv::SoundFile> File(priv::SoundFile::Create(Filename));
00084
00085
00086 std::size_t NbSamples;
00087 unsigned int ChannelsCount, SampleRate;
00088 if (File->OpenRead(Filename, NbSamples, ChannelsCount, SampleRate))
00089 {
00090
00091 mySamples.resize(NbSamples);
00092 if (File->Read(&mySamples[0], NbSamples) == NbSamples)
00093 {
00094
00095 return Update(ChannelsCount, SampleRate);
00096 }
00097 else
00098 {
00099
00100 std::cerr << "Failed to read audio data from file \"" << Filename << "\"" << std::endl;
00101
00102 return false;
00103 }
00104 }
00105 else
00106 {
00107
00108 std::cerr << "Failed to load sound buffer from file \"" << Filename << "\"" << std::endl;
00109
00110 return false;
00111 }
00112 }
00113
00114
00118 bool SoundBuffer::LoadFromMemory(const Int16* Samples, std::size_t SamplesCount, unsigned int ChannelsCount, unsigned int SampleRate)
00119 {
00120 if (Samples && SamplesCount && ChannelsCount && SampleRate)
00121 {
00122
00123 mySamples.assign(Samples, Samples + SamplesCount);
00124
00125
00126 return Update(ChannelsCount, SampleRate);
00127 }
00128 else
00129 {
00130
00131 std::cerr << "Failed to load sound buffer from memory ("
00132 << "Samples : " << Samples << ", "
00133 << "Samples count : " << SamplesCount << ", "
00134 << "Channels count : " << ChannelsCount << ", "
00135 << "Sample rate : " << SampleRate << ")"
00136 << std::endl;
00137
00138 return false;
00139 }
00140 }
00141
00142
00146 bool SoundBuffer::SaveToFile(const std::string& Filename) const
00147 {
00148
00149 std::auto_ptr<priv::SoundFile> File(priv::SoundFile::Create(Filename));
00150
00151
00152 if (File->OpenWrite(Filename, GetChannelsCount(), GetSampleRate()))
00153 {
00154
00155 File->Write(&mySamples[0], mySamples.size());
00156
00157 return true;
00158 }
00159 else
00160 {
00161
00162 std::cerr << "Failed to save sound buffer to file \"" << Filename << "\"" << std::endl;
00163
00164 return false;
00165 }
00166 }
00167
00168
00172 const Int16* SoundBuffer::GetSamples() const
00173 {
00174 return mySamples.empty() ? NULL : &mySamples[0];
00175 }
00176
00177
00181 std::size_t SoundBuffer::GetSamplesCount() const
00182 {
00183 return mySamples.size();
00184 }
00185
00186
00190 unsigned int SoundBuffer::GetSampleRate() const
00191 {
00192 ALint SampleRate;
00193 ALCheck(alGetBufferi(myBuffer, AL_FREQUENCY, &SampleRate));
00194
00195 return SampleRate;
00196 }
00197
00198
00202 unsigned int SoundBuffer::GetChannelsCount() const
00203 {
00204 ALint ChannelsCount;
00205 ALCheck(alGetBufferi(myBuffer, AL_CHANNELS, &ChannelsCount));
00206
00207 return ChannelsCount;
00208 }
00209
00210
00214 float SoundBuffer::GetDuration() const
00215 {
00216 return myDuration;
00217 }
00218
00219
00223 SoundBuffer& SoundBuffer::operator =(const SoundBuffer& Other)
00224 {
00225 SoundBuffer Temp(Other);
00226
00227 mySamples.swap(Temp.mySamples);
00228 std::swap(myBuffer, Temp.myBuffer);
00229 std::swap(myDuration, Temp.myDuration);
00230
00231 return *this;
00232 }
00233
00234
00238 bool SoundBuffer::Update(unsigned int ChannelsCount, unsigned int SampleRate)
00239 {
00240
00241 if (!SampleRate || !ChannelsCount || mySamples.empty())
00242 return false;
00243
00244
00245 ALenum Format = priv::AudioDevice::GetInstance().GetFormatFromChannelsCount(ChannelsCount);
00246
00247
00248 if (Format == 0)
00249 {
00250 std::cerr << "Unsupported number of channels (" << ChannelsCount << ")" << std::endl;
00251 return false;
00252 }
00253
00254
00255 ALsizei Size = static_cast<ALsizei>(mySamples.size()) * sizeof(Int16);
00256 ALCheck(alBufferData(myBuffer, Format, &mySamples[0], Size, SampleRate));
00257
00258
00259 myDuration = static_cast<float>(mySamples.size()) / SampleRate / ChannelsCount;
00260
00261 return true;
00262 }
00263
00264 }