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 
00033 namespace sf
00034 {
00038 Sound::Sound(const SoundBuffer* Buffer, bool Loop, float Pitch, float Volume, float X, float Y, float Z) :
00039 myBuffer(Buffer)
00040 {
00041     ALCheck(alGenSources(1, &mySource));
00042 
00043     ALCheck(alSourcei (mySource, AL_BUFFER,   myBuffer ? myBuffer->myBuffer : 0));
00044     ALCheck(alSourcei (mySource, AL_LOOPING,  Loop));
00045     ALCheck(alSourcef (mySource, AL_PITCH,    Pitch));
00046     ALCheck(alSourcef (mySource, AL_GAIN,     Volume * 0.01f));
00047     ALCheck(alSource3f(mySource, AL_POSITION, X, Y, Z));
00048 
00049     // Seems to fix the bug of mono sounds not being played due to spacialization,
00050     // although the listener and the sound are at the same position
00051     ALCheck(alSourcef (mySource, AL_ROLLOFF_FACTOR, 0.99f));
00052 }
00053 
00054 
00058 Sound::Sound(const Sound& Copy) :
00059 AudioResource(Copy),
00060 myBuffer     (Copy.myBuffer)
00061 {
00062     ALCheck(alGenSources(1, &mySource));
00063 
00064     ALCheck(alSourcei(mySource, AL_BUFFER,  myBuffer ? myBuffer->myBuffer : 0));
00065     ALCheck(alSourcei(mySource, AL_LOOPING, Copy.GetLoop()));
00066     ALCheck(alSourcef(mySource, AL_PITCH,   Copy.GetPitch()));
00067     ALCheck(alSourcef(mySource, AL_GAIN,    Copy.GetVolume() * 0.01f));
00068 
00069     float X, Y, Z;
00070     Copy.GetPosition(X, Y, Z);
00071     ALCheck(alSource3f(mySource, AL_POSITION, X, Y, Z));
00072 
00073     // Seems to fix the bug of mono sounds not being played due to spacialization,
00074     // although the listener and the sound are at the same position
00075     ALCheck(alSourcef (mySource, AL_ROLLOFF_FACTOR, 0.99f));
00076 }
00077 
00078 
00082 Sound::~Sound()
00083 {
00084     if (mySource)
00085     {
00086         Stop();
00087         ALCheck(alSourcei(mySource, AL_BUFFER, 0));
00088         ALCheck(alDeleteSources(1, &mySource));
00089     }
00090 }
00091 
00092 
00096 void Sound::Play()
00097 {
00098     ALCheck(alSourcePlay(mySource));
00099 }
00100 
00101 
00105 void Sound::Pause()
00106 {
00107     ALCheck(alSourcePause(mySource));
00108 }
00109 
00110 
00114 void Sound::Stop()
00115 {
00116     ALCheck(alSourceStop(mySource));
00117 }
00118 
00119 
00123 void Sound::SetBuffer(const SoundBuffer* Buffer)
00124 {
00125     myBuffer = Buffer;
00126     ALCheck(alSourcei(mySource, AL_BUFFER, myBuffer ? myBuffer->myBuffer : 0));
00127 }
00128 
00129 
00133 void Sound::SetLoop(bool Loop)
00134 {
00135     ALCheck(alSourcei(mySource, AL_LOOPING, Loop));
00136 }
00137 
00138 
00142 void Sound::SetPitch(float Pitch)
00143 {
00144     ALCheck(alSourcef(mySource, AL_PITCH, Pitch));
00145 }
00146 
00147 
00151 void Sound::SetVolume(float Volume)
00152 {
00153     ALCheck(alSourcef(mySource, AL_GAIN, Volume * 0.01f));
00154 }
00155 
00156 
00160 void Sound::SetPosition(float X, float Y, float Z)
00161 {
00162     ALCheck(alSource3f(mySource, AL_POSITION, X, Y, Z));
00163 }
00164 
00165 
00169 const SoundBuffer* Sound::GetBuffer() const
00170 {
00171     return myBuffer;
00172 }
00173 
00174 
00178 bool Sound::GetLoop() const
00179 {
00180     ALint Loop;
00181     ALCheck(alGetSourcei(mySource, AL_LOOPING, &Loop));
00182 
00183     return Loop != 0;
00184 }
00185 
00186 
00190 float Sound::GetPitch() const
00191 {
00192     ALfloat Pitch;
00193     ALCheck(alGetSourcef(mySource, AL_PITCH, &Pitch));
00194 
00195     return Pitch;
00196 }
00197 
00198 
00202 float Sound::GetVolume() const
00203 {
00204     ALfloat Gain;
00205     ALCheck(alGetSourcef(mySource, AL_GAIN, &Gain));
00206 
00207     return Gain * 100.f;
00208 }
00209 
00210 
00214 void Sound::GetPosition(float& X, float& Y, float& Z) const
00215 {
00216     ALCheck(alGetSource3f(mySource, AL_POSITION, &X, &Y, &Z));
00217 }
00218 
00219 
00223 Sound::Status Sound::GetStatus() const
00224 {
00225     ALint State;
00226     ALCheck(alGetSourcei(mySource, AL_SOURCE_STATE, &State));
00227 
00228     switch (State)
00229     {
00230         case AL_INITIAL :
00231         case AL_STOPPED : return Stopped;
00232         case AL_PAUSED :  return Paused;
00233         case AL_PLAYING : return Playing;
00234     }
00235 
00236     return Stopped;
00237 }
00238 
00239 
00243 float Sound::GetPlayingOffset() const
00244 {
00245     ALfloat Seconds = 0.f;
00246     ALCheck(alGetSourcef(mySource, AL_SEC_OFFSET, &Seconds));
00247 
00248     return Seconds;
00249 }
00250 
00251 
00255 Sound& Sound::operator =(const Sound& Other)
00256 {
00257     Sound Temp(Other);
00258 
00259     std::swap(mySource, Temp.mySource);
00260     std::swap(myBuffer, Temp.myBuffer);
00261 
00262     return *this;
00263 }
00264 
00265 } // namespace sf