Back to index

libsfml  1.6+dfsg2
Sound.cpp
Go to the documentation of this file.
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/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