Sound.cpp
00001 00002 // 00003 // SFML - Simple and Fast Multimedia Library 00004 // Copyright (C) 2007-2009 Laurent Gomila ([email protected]) 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/Sound.hpp> 00029 #include <SFML/Audio/SoundBuffer.hpp> 00030 #include <SFML/Audio/OpenAL.hpp> 00031 00032 00033 namespace sf 00034 { 00038 Sound::Sound() 00039 { 00040 ALCheck(alGenSources(1, &mySource)); 00041 ALCheck(alSourcei(mySource, AL_BUFFER, 0)); 00042 } 00043 00044 00048 Sound::Sound(const SoundBuffer& Buffer, bool Loop, float Pitch, float Volume, const Vector3f& Position) : 00049 myBuffer(NULL) 00050 { 00051 ALCheck(alGenSources(1, &mySource)); 00052 00053 SetBuffer(Buffer); 00054 SetLoop(Loop); 00055 SetPitch(Pitch); 00056 SetVolume(Volume); 00057 SetPosition(Position); 00058 } 00059 00060 00064 Sound::Sound(const Sound& Copy) : 00065 AudioResource(Copy), 00066 myBuffer(NULL) 00067 { 00068 ALCheck(alGenSources(1, &mySource)); 00069 00070 if (Copy.myBuffer) 00071 SetBuffer(*Copy.myBuffer); 00072 SetLoop(Copy.GetLoop()); 00073 SetPitch(Copy.GetPitch()); 00074 SetVolume(Copy.GetVolume()); 00075 SetPosition(Copy.GetPosition()); 00076 SetRelativeToListener(Copy.IsRelativeToListener()); 00077 SetMinDistance(Copy.GetMinDistance()); 00078 SetAttenuation(Copy.GetAttenuation()); 00079 } 00080 00081 00085 Sound::~Sound() 00086 { 00087 if (mySource) 00088 { 00089 if (myBuffer) 00090 { 00091 Stop(); 00092 ALCheck(alSourcei(mySource, AL_BUFFER, 0)); 00093 myBuffer->DetachSound(this); 00094 } 00095 ALCheck(alDeleteSources(1, &mySource)); 00096 } 00097 } 00098 00099 00103 void Sound::Play() 00104 { 00105 ALCheck(alSourcePlay(mySource)); 00106 } 00107 00108 00112 void Sound::Pause() 00113 { 00114 ALCheck(alSourcePause(mySource)); 00115 } 00116 00117 00121 void Sound::Stop() 00122 { 00123 ALCheck(alSourceStop(mySource)); 00124 } 00125 00126 00130 void Sound::SetBuffer(const SoundBuffer& Buffer) 00131 { 00132 // First detach from the previous buffer 00133 if (myBuffer) 00134 { 00135 Stop(); 00136 myBuffer->DetachSound(this); 00137 } 00138 00139 // Assign and use the new buffer 00140 myBuffer = &Buffer; 00141 myBuffer->AttachSound(this); 00142 ALCheck(alSourcei(mySource, AL_BUFFER, myBuffer->myBuffer)); 00143 } 00144 00145 00149 void Sound::SetLoop(bool Loop) 00150 { 00151 ALCheck(alSourcei(mySource, AL_LOOPING, Loop)); 00152 } 00153 00154 00158 void Sound::SetPitch(float Pitch) 00159 { 00160 ALCheck(alSourcef(mySource, AL_PITCH, Pitch)); 00161 } 00162 00163 00167 void Sound::SetVolume(float Volume) 00168 { 00169 ALCheck(alSourcef(mySource, AL_GAIN, Volume * 0.01f)); 00170 } 00171 00176 void Sound::SetPosition(float X, float Y, float Z) 00177 { 00178 ALCheck(alSource3f(mySource, AL_POSITION, X, Y, Z)); 00179 } 00180 00181 00186 void Sound::SetPosition(const Vector3f& Position) 00187 { 00188 SetPosition(Position.x, Position.y, Position.z); 00189 } 00190 00191 00197 void Sound::SetRelativeToListener(bool Relative) 00198 { 00199 ALCheck(alSourcei(mySource, AL_SOURCE_RELATIVE, Relative)); 00200 } 00201 00202 00208 void Sound::SetMinDistance(float MinDistance) 00209 { 00210 ALCheck(alSourcef(mySource, AL_REFERENCE_DISTANCE, MinDistance)); 00211 } 00212 00213 00219 void Sound::SetAttenuation(float Attenuation) 00220 { 00221 ALCheck(alSourcef(mySource, AL_ROLLOFF_FACTOR, Attenuation)); 00222 } 00223 00224 00228 void Sound::SetPlayingOffset(float TimeOffset) 00229 { 00230 ALCheck(alSourcef(mySource, AL_SEC_OFFSET, TimeOffset)); 00231 } 00232 00233 00237 const SoundBuffer* Sound::GetBuffer() const 00238 { 00239 return myBuffer; 00240 } 00241 00242 00246 bool Sound::GetLoop() const 00247 { 00248 ALint Loop; 00249 ALCheck(alGetSourcei(mySource, AL_LOOPING, &Loop)); 00250 00251 return Loop != 0; 00252 } 00253 00254 00258 float Sound::GetPitch() const 00259 { 00260 ALfloat Pitch; 00261 ALCheck(alGetSourcef(mySource, AL_PITCH, &Pitch)); 00262 00263 return Pitch; 00264 } 00265 00266 00270 float Sound::GetVolume() const 00271 { 00272 ALfloat Gain; 00273 ALCheck(alGetSourcef(mySource, AL_GAIN, &Gain)); 00274 00275 return Gain * 100.f; 00276 } 00277 00278 00282 Vector3f Sound::GetPosition() const 00283 { 00284 Vector3f Position; 00285 ALCheck(alGetSource3f(mySource, AL_POSITION, &Position.x, &Position.y, &Position.z)); 00286 00287 return Position; 00288 } 00289 00290 00295 bool Sound::IsRelativeToListener() const 00296 { 00297 ALint Relative; 00298 ALCheck(alGetSourcei(mySource, AL_SOURCE_RELATIVE, &Relative)); 00299 00300 return Relative != 0; 00301 } 00302 00303 00307 float Sound::GetMinDistance() const 00308 { 00309 ALfloat MinDistance; 00310 ALCheck(alGetSourcef(mySource, AL_REFERENCE_DISTANCE, &MinDistance)); 00311 00312 return MinDistance; 00313 } 00314 00315 00319 float Sound::GetAttenuation() const 00320 { 00321 ALfloat Attenuation; 00322 ALCheck(alGetSourcef(mySource, AL_ROLLOFF_FACTOR, &Attenuation)); 00323 00324 return Attenuation; 00325 } 00326 00327 00331 float Sound::GetPlayingOffset() const 00332 { 00333 ALfloat Seconds = 0.f; 00334 ALCheck(alGetSourcef(mySource, AL_SEC_OFFSET, &Seconds)); 00335 00336 return Seconds; 00337 } 00338 00339 00343 Sound::Status Sound::GetStatus() const 00344 { 00345 ALint State; 00346 ALCheck(alGetSourcei(mySource, AL_SOURCE_STATE, &State)); 00347 00348 switch (State) 00349 { 00350 case AL_INITIAL : 00351 case AL_STOPPED : return Stopped; 00352 case AL_PAUSED : return Paused; 00353 case AL_PLAYING : return Playing; 00354 } 00355 00356 return Stopped; 00357 } 00358 00359 00363 Sound& Sound::operator =(const Sound& Other) 00364 { 00365 // Here we don't use the copy-and-swap idiom, because it would mess up 00366 // the list of sound instances contained in the buffers 00367 00368 // Detach the sound instance from the previous buffer (if any) 00369 if (myBuffer) 00370 { 00371 Stop(); 00372 myBuffer->DetachSound(this); 00373 myBuffer = NULL; 00374 } 00375 00376 // Copy the sound attributes 00377 if (Other.myBuffer) 00378 SetBuffer(*Other.myBuffer); 00379 SetLoop(Other.GetLoop()); 00380 SetPitch(Other.GetPitch()); 00381 SetVolume(Other.GetVolume()); 00382 SetPosition(Other.GetPosition()); 00383 SetRelativeToListener(Other.IsRelativeToListener()); 00384 SetMinDistance(Other.GetMinDistance()); 00385 SetAttenuation(Other.GetAttenuation()); 00386 00387 return *this; 00388 } 00389 00390 00394 void Sound::ResetBuffer() 00395 { 00396 // First stop the sound in case it is playing 00397 Stop(); 00398 00399 // Detach the buffer 00400 ALCheck(alSourcei(mySource, AL_BUFFER, 0)); 00401 myBuffer = NULL; 00402 } 00403 00404 } // namespace sf
:: Copyright © 2007-2008 Laurent Gomila, all rights reserved :: Documentation generated by doxygen 1.5.2 ::