Sound.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007 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 
00036 sfSound::sfSound(const sfSoundBuffer* Buffer, bool Loop, float Pitch, float Volume, float X, float Y, float Z) :
00037 myBuffer(Buffer)
00038 {
00039     sfALCheck(alGenSources(1, &mySource));
00040 
00041     sfALCheck(alSourcei (mySource, AL_BUFFER,   myBuffer ? myBuffer->myBuffer : 0));
00042     sfALCheck(alSourcei (mySource, AL_LOOPING,  Loop));
00043     sfALCheck(alSourcef (mySource, AL_PITCH,    Pitch));
00044     sfALCheck(alSourcef (mySource, AL_GAIN,     Volume * 0.01f));
00045     sfALCheck(alSource3f(mySource, AL_POSITION, X, Y, Z));
00046 
00047     // Seems to fix the bug of mono sounds not being played due to spacialization,
00048     // although the listener and the sound are at the same position
00049     sfALCheck(alSourcef (mySource, AL_ROLLOFF_FACTOR, 0.99f));
00050 }
00051 
00052 
00056 sfSound::sfSound(const sfSound& Copy) :
00057 myBuffer(Copy.myBuffer)
00058 {
00059     sfALCheck(alGenSources(1, &mySource));
00060 
00061     sfALCheck(alSourcei(mySource, AL_BUFFER,  myBuffer ? myBuffer->myBuffer : 0));
00062     sfALCheck(alSourcei(mySource, AL_LOOPING, Copy.GetLoop()));
00063     sfALCheck(alSourcef(mySource, AL_PITCH,   Copy.GetPitch()));
00064     sfALCheck(alSourcef(mySource, AL_GAIN,    Copy.GetVolume() * 0.01f));
00065 
00066     float X, Y, Z;
00067     Copy.GetPosition(X, Y, Z);
00068     sfALCheck(alSource3f(mySource, AL_POSITION, X, Y, Z));
00069 
00070     // Seems to fix the bug of mono sounds not being played due to spacialization,
00071     // although the listener and the sound are at the same position
00072     sfALCheck(alSourcef (mySource, AL_ROLLOFF_FACTOR, 0.99f));
00073 }
00074 
00075 
00079 sfSound::~sfSound()
00080 {
00081     Stop();
00082     DestroyAudioResources();
00083 }
00084 
00085 
00089 void sfSound::Play()
00090 {
00091     sfALCheck(alSourcePlay(mySource));
00092 }
00093 
00094 
00098 void sfSound::Pause()
00099 {
00100     sfALCheck(alSourcePause(mySource));
00101 }
00102 
00103 
00107 void sfSound::Stop()
00108 {
00109     sfALCheck(alSourceStop(mySource));
00110 }
00111 
00112 
00116 void sfSound::SetBuffer(const sfSoundBuffer* Buffer)
00117 {
00118     myBuffer = Buffer;
00119     sfALCheck(alSourcei(mySource, AL_BUFFER, myBuffer ? myBuffer->myBuffer : 0));
00120 }
00121 
00122 
00126 void sfSound::SetLoop(bool Loop)
00127 {
00128     sfALCheck(alSourcei(mySource, AL_LOOPING, Loop));
00129 }
00130 
00131 
00135 void sfSound::SetPitch(float Pitch)
00136 {
00137     sfALCheck(alSourcef(mySource, AL_PITCH, Pitch));
00138 }
00139 
00140 
00144 void sfSound::SetVolume(float Volume)
00145 {
00146     sfALCheck(alSourcef(mySource, AL_GAIN, Volume * 0.01f));
00147 }
00148 
00149 
00153 void sfSound::SetPosition(float X, float Y, float Z)
00154 {
00155     sfALCheck(alSource3f(mySource, AL_POSITION, X, Y, Z));
00156 }
00157 
00158 
00162 const sfSoundBuffer* sfSound::GetBuffer() const
00163 {
00164     return myBuffer;
00165 }
00166 
00167 
00171 bool sfSound::GetLoop() const
00172 {
00173     ALint Loop;
00174     sfALCheck(alGetSourcei(mySource, AL_LOOPING, &Loop));
00175 
00176     return Loop != 0;
00177 }
00178 
00179 
00183 float sfSound::GetPitch() const
00184 {
00185     ALfloat Pitch;
00186     sfALCheck(alGetSourcef(mySource, AL_PITCH, &Pitch));
00187 
00188     return Pitch;
00189 }
00190 
00191 
00195 float sfSound::GetVolume() const
00196 {
00197     ALfloat Gain;
00198     sfALCheck(alGetSourcef(mySource, AL_GAIN, &Gain));
00199 
00200     return Gain * 100.f;
00201 }
00202 
00203 
00207 void sfSound::GetPosition(float& X, float& Y, float& Z) const
00208 {
00209     sfALCheck(alGetSource3f(mySource, AL_POSITION, &X, &Y, &Z));
00210 }
00211 
00212 
00216 sfSound::Status sfSound::GetStatus() const
00217 {
00218     ALint State;
00219     sfALCheck(alGetSourcei(mySource, AL_SOURCE_STATE, &State));
00220 
00221     switch (State)
00222     {
00223         case AL_INITIAL :
00224         case AL_STOPPED : return Stopped;
00225         case AL_PAUSED :  return Paused;
00226         case AL_PLAYING : return Playing;
00227     }
00228 
00229     return Stopped;
00230 }
00231 
00232 
00236 float sfSound::GetPlayingOffset() const
00237 {
00238     ALfloat Seconds = 0.f;
00239     sfALCheck(alGetSourcef(mySource, AL_SEC_OFFSET, &Seconds));
00240 
00241     return Seconds;
00242 }
00243 
00244 
00248 sfSound& sfSound::operator =(const sfSound& Other)
00249 {
00250     sfSound Temp(Other);
00251 
00252     std::swap(mySource, Temp.mySource);
00253     std::swap(myBuffer, Temp.myBuffer);
00254 
00255     return *this;
00256 }
00257 
00258 
00262 void sfSound::DestroyAudioResources()
00263 {
00264     if (mySource)
00265     {
00266         sfALCheck(alSourcei(mySource, AL_BUFFER, 0));
00267         sfALCheck(alDeleteSources(1, &mySource));
00268         mySource = 0;
00269     }
00270 }