diff --git a/build/codeblocks/sfml-audio.cbp b/build/codeblocks/sfml-audio.cbp index dfc628210..141bd866b 100644 --- a/build/codeblocks/sfml-audio.cbp +++ b/build/codeblocks/sfml-audio.cbp @@ -116,6 +116,7 @@ + @@ -129,6 +130,7 @@ + diff --git a/build/vc2005/sfml-audio.vcproj b/build/vc2005/sfml-audio.vcproj index cc292f9ce..0746b04fa 100644 --- a/build/vc2005/sfml-audio.vcproj +++ b/build/vc2005/sfml-audio.vcproj @@ -415,6 +415,14 @@ RelativePath="..\..\include\SFML\Audio\SoundRecorder.hpp" > + + + + diff --git a/build/vc2008/sfml-audio.vcproj b/build/vc2008/sfml-audio.vcproj index b666b50a1..f36e3465c 100644 --- a/build/vc2008/sfml-audio.vcproj +++ b/build/vc2008/sfml-audio.vcproj @@ -415,6 +415,14 @@ RelativePath="..\..\include\SFML\Audio\SoundRecorder.hpp" > + + + + diff --git a/include/SFML/Audio/Sound.hpp b/include/SFML/Audio/Sound.hpp index 5b11871a5..cdfd07830 100644 --- a/include/SFML/Audio/Sound.hpp +++ b/include/SFML/Audio/Sound.hpp @@ -28,9 +28,8 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include +#include #include -#include #include @@ -39,231 +38,153 @@ namespace sf class SoundBuffer; //////////////////////////////////////////////////////////// -/// Sound defines the properties of a sound such as position, -/// volume, pitch, etc. +/// \brief Regular sound that can be played in the audio environment +/// //////////////////////////////////////////////////////////// -class SFML_API Sound +class SFML_API Sound : public SoundSource { public : //////////////////////////////////////////////////////////// - /// Enumeration of the sound states - //////////////////////////////////////////////////////////// - enum Status - { - Stopped, ///< Sound is not playing - Paused, ///< Sound is paused - Playing ///< Sound is playing - }; - - //////////////////////////////////////////////////////////// - /// Default constructor + /// \brief Default constructor /// //////////////////////////////////////////////////////////// Sound(); //////////////////////////////////////////////////////////// - /// Construct the sound from its parameters + /// \brief Construct the sound with parameters /// - /// \param buffer : Sound buffer to play - /// \param loop : Loop flag - /// \param pitch : Value of the pitch - /// \param volume : Volume - /// \param position : Position + /// \param buffer Sound buffer containing the audio data to play with the sound + /// \param loop Should the sound loop? + /// \param pitch Pitch of the sound + /// \param volume Volume of the sound, in the range [0, 100] + /// \param position 3D position of the sound source in the audio scene /// //////////////////////////////////////////////////////////// Sound(const SoundBuffer& buffer, bool loop = false, float pitch = 1.f, float volume = 100.f, const Vector3f& position = Vector3f(0, 0, 0)); //////////////////////////////////////////////////////////// - /// Copy constructor + /// \brief Copy constructor /// - /// \param copy : Instance to copy + /// \param copy Instance to copy /// //////////////////////////////////////////////////////////// Sound(const Sound& copy); //////////////////////////////////////////////////////////// - /// Destructor + /// \brief Destructor /// //////////////////////////////////////////////////////////// ~Sound(); //////////////////////////////////////////////////////////// - /// Play the sound + /// \brief Start or resume playing the sound + /// + /// This function starts the sound if it was stopped, resumes + /// it if it was paused, and does nothing it is it already playing. + /// This function uses its own thread so that it doesn't block + /// the rest of the program while the sound is played. + /// + /// \see Pause, Stop /// //////////////////////////////////////////////////////////// void Play(); //////////////////////////////////////////////////////////// - /// Pause the sound + /// \brief Pause the sound + /// + /// This function pauses the sound if it was playing, + /// otherwise (sound already paused or stopped) it has no effect. + /// + /// \see Play, Stop /// //////////////////////////////////////////////////////////// void Pause(); //////////////////////////////////////////////////////////// - /// Stop the sound + /// \brief Stop playing the sound + /// + /// This function stops the sound if it was playing or paused, + /// and does nothing if it was already stopped. + /// It also resets the playing position (unlike Pause()). + /// + /// \see Play, Pause /// //////////////////////////////////////////////////////////// void Stop(); //////////////////////////////////////////////////////////// - /// Set the source buffer + /// \brief Set the source buffer containing the audio data to play /// - /// \param buffer : New sound buffer to bind to the sound + /// It is important to note that the sound buffer is not copied, + /// thus the sf::SoundBuffer instance must remain alive as long + /// as it is attached to the sound. + /// + /// \param buffer Sound buffer to attach to the sound + /// + /// \see GetBuffer /// //////////////////////////////////////////////////////////// void SetBuffer(const SoundBuffer& buffer); //////////////////////////////////////////////////////////// - /// Set the sound loop state. - /// This parameter is disabled by default + /// \brief Set whether or not the sound should loop after reaching the end /// - /// \param loop : True to play in loop, false to play once + /// If set, the sound will restart from beginning after + /// reaching the end and so on, until it is stopped or + /// SetLoop(false) is called. + /// The default looping state for sound is false. + /// + /// \param loop True to play in loop, false to play once + /// + /// \see GetLoop /// //////////////////////////////////////////////////////////// void SetLoop(bool loop); //////////////////////////////////////////////////////////// - /// Set the sound pitch. - /// The default pitch is 1 + /// \brief Change the current playing position of the sound /// - /// \param pitch : New pitch + /// The playing position can be changed when the sound is + /// either paused or playing. /// - //////////////////////////////////////////////////////////// - void SetPitch(float pitch); - - //////////////////////////////////////////////////////////// - /// Set the sound volume. - /// The default volume is 100 + /// \param timeOffset New playing position, in seconds /// - /// \param volume : Volume (in range [0, 100]) - /// - //////////////////////////////////////////////////////////// - void SetVolume(float volume); - - //////////////////////////////////////////////////////////// - /// Set the sound position (take 3 values). - /// The default position is (0, 0, 0) - /// - /// \param x, y, z : Position of the sound in the world - /// - //////////////////////////////////////////////////////////// - void SetPosition(float x, float y, float z); - - //////////////////////////////////////////////////////////// - /// Set the sound position (take a 3D vector). - /// The default position is (0, 0, 0) - /// - /// \param position : Position of the sound in the world - /// - //////////////////////////////////////////////////////////// - void SetPosition(const Vector3f& position); - - //////////////////////////////////////////////////////////// - /// Make the sound's position relative to the listener's - /// position, or absolute. - /// The default value is false (absolute) - /// - /// \param relative : True to set the position relative, false to set it absolute - /// - //////////////////////////////////////////////////////////// - void SetRelativeToListener(bool relative); - - //////////////////////////////////////////////////////////// - /// Set the minimum distance - closer than this distance, - /// the listener will hear the sound at its maximum volume. - /// The default minimum distance is 1.0 - /// - /// \param distance : New minimum distance for the sound - /// - //////////////////////////////////////////////////////////// - void SetMinDistance(float distance); - - //////////////////////////////////////////////////////////// - /// Set the attenuation factor - the higher the attenuation, the - /// more the sound will be attenuated with distance from listener. - /// The default attenuation factor 1.0 - /// - /// \param attenuation : New attenuation factor for the sound - /// - //////////////////////////////////////////////////////////// - void SetAttenuation(float attenuation); - - //////////////////////////////////////////////////////////// - /// Set the current playing position of the sound - /// - /// \param timeOffset : New playing position, expressed in seconds + /// \see GetPlayingOffset /// //////////////////////////////////////////////////////////// void SetPlayingOffset(float timeOffset); //////////////////////////////////////////////////////////// - /// Get the source buffer + /// \brief Get the audio buffer attached to the sound /// - /// \return Sound buffer bound to the sound (can be NULL) + /// \return Sound buffer attached to the sound (can be NULL) /// //////////////////////////////////////////////////////////// const SoundBuffer* GetBuffer() const; //////////////////////////////////////////////////////////// - /// Tell whether or not the sound is looping + /// \brief Tell whether or not the sound is in loop mode /// /// \return True if the sound is looping, false otherwise /// + /// \see SetLoop + /// //////////////////////////////////////////////////////////// bool GetLoop() const; //////////////////////////////////////////////////////////// - /// Get the pitch + /// \brief Get the current playing position of the sound /// - /// \return Pitch value + /// \return Current playing position, in seconds + /// + /// \see SetPlayingOffset /// //////////////////////////////////////////////////////////// - float GetPitch() const; + float GetPlayingOffset() const; //////////////////////////////////////////////////////////// - /// Get the volume - /// - /// \return Volume value (in range [1, 100]) - /// - //////////////////////////////////////////////////////////// - float GetVolume() const; - - //////////////////////////////////////////////////////////// - /// Get the sound position - /// - /// \return Position of the sound in the world - /// - //////////////////////////////////////////////////////////// - Vector3f GetPosition() const; - - //////////////////////////////////////////////////////////// - /// Tell if the sound's position is relative to the listener's - /// position, or if it's absolute - /// - /// \return True if the position is relative, false if it's absolute - /// - //////////////////////////////////////////////////////////// - bool IsRelativeToListener() const; - - //////////////////////////////////////////////////////////// - /// Get the minimum distance - /// - /// \return Minimum distance for the sound - /// - //////////////////////////////////////////////////////////// - float GetMinDistance() const; - - //////////////////////////////////////////////////////////// - /// Get the attenuation factor - /// - /// \return Attenuation factor of the sound - /// - //////////////////////////////////////////////////////////// - float GetAttenuation() const; - - //////////////////////////////////////////////////////////// - /// Get the status of the sound (stopped, paused, playing) + /// \brief Get the current status of the sound (stopped, paused, playing) /// /// \return Current status of the sound /// @@ -271,31 +192,20 @@ public : Status GetStatus() const; //////////////////////////////////////////////////////////// - /// Get the current playing position of the sound + /// \brief Overload of assignment operator /// - /// \return Current playing position, expressed in seconds + /// \param right Instance to assign + /// + /// \return Reference to self /// //////////////////////////////////////////////////////////// - float GetPlayingOffset() const; - - //////////////////////////////////////////////////////////// - /// Assignment operator - /// - /// \param Other : Instance to assign - /// - /// \return Reference to the sound - /// - //////////////////////////////////////////////////////////// - Sound& operator =(const Sound& other); + Sound& operator =(const Sound& right); private : - friend class SoundStream; - //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - unsigned int mySource; ///< OpenAL source identifier ResourcePtr myBuffer; ///< Sound buffer bound to the source }; @@ -303,3 +213,40 @@ private : #endif // SFML_SOUND_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::Sound +/// +/// sf::Sound is the class to use to play sounds. +/// It provides: +/// \li Control (play, pause, stop) +/// \li Ability to modify output parameters in real-time (pitch, volume, ...) +/// \li 3D spatial features (position, attenuation, ...). +/// +/// sf::Sound is perfect for playing short sounds that can +/// fit in memory and require no latency, like foot steps or +/// gun shots. For longer sounds, like background musics +/// or long speeches, rather see sf::Music (which is based +/// on streaming). +/// +/// In order to work, a sound must be given a buffer of audio +/// data to play. Audio data (samples) is stored in sf::SoundBuffer, +/// and attached to a sound with the SetBuffer() function. +/// The buffer object attached to a sound must remain alive +/// as long as the sound uses it. Note that multiple sounds +/// can use the same sound buffer at the same time. +/// +/// Usage example: +/// \code +/// sf::SoundBuffer buffer; +/// buffer.LoadFromFile("sound.wav"); +/// +/// sf::Sound sound; +/// sound.SetBuffer(buffer); +/// sound.Play(); +/// \endcode +/// +/// \see sf::SoundBuffer, sf::Music +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Audio/SoundSource.hpp b/include/SFML/Audio/SoundSource.hpp new file mode 100644 index 000000000..6c149a5f0 --- /dev/null +++ b/include/SFML/Audio/SoundSource.hpp @@ -0,0 +1,285 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_SOUNDSOURCE_HPP +#define SFML_SOUNDSOURCE_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// \brief Base class defining a sound's properties +/// +//////////////////////////////////////////////////////////// +class SFML_API SoundSource +{ +public : + + //////////////////////////////////////////////////////////// + /// \brief Enumeration of the sound source states + /// + //////////////////////////////////////////////////////////// + enum Status + { + Stopped, ///< Sound is not playing + Paused, ///< Sound is paused + Playing ///< Sound is playing + }; + + //////////////////////////////////////////////////////////// + /// \brief Copy constructor + /// + /// \param copy Instance to copy + /// + //////////////////////////////////////////////////////////// + SoundSource(const SoundSource& copy); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + //////////////////////////////////////////////////////////// + virtual ~SoundSource(); + + //////////////////////////////////////////////////////////// + /// \brief Set the pitch of the sound + /// + /// The pitch represents the perceived fundamental frequency + /// of a sound; thus you can make a sound more acute or grave + /// by changing its pitch. A side effect of changing the pitch + /// is to modify the playing speed of the sound as well. + /// The default value for the pitch is 1. + /// + /// \param pitch New pitch to apply to the sound + /// + /// \see GetPitch + /// + //////////////////////////////////////////////////////////// + void SetPitch(float pitch); + + //////////////////////////////////////////////////////////// + /// \brief Set the volume of the sound + /// + /// The volume is a value between 0 (mute) and 100 (full volume). + /// The default value for the volume is 100. + /// + /// \param volume Volume of the sound + /// + /// \see GetVolume + /// + //////////////////////////////////////////////////////////// + void SetVolume(float volume); + + //////////////////////////////////////////////////////////// + /// \brief Set the 3D position of the sound in the audio scene + /// + /// Only sounds with one channel (mono sounds) can be + /// spatialized. + /// The default position of a sound is (0, 0, 0). + /// + /// \param x X coordinate of the position of the sound in the scene + /// \param y Y coordinate of the position of the sound in the scene + /// \param z Z coordinate of the position of the sound in the scene + /// + /// \see GetPosition + /// + //////////////////////////////////////////////////////////// + void SetPosition(float x, float y, float z); + + //////////////////////////////////////////////////////////// + /// \brief Set the 3D position of the sound in the audio scene + /// + /// Only sounds with one channel (mono sounds) can be + /// spatialized. + /// The default position of a sound is (0, 0, 0). + /// + /// \param position Position of the sound in the scene + /// + /// \see GetPosition + /// + //////////////////////////////////////////////////////////// + void SetPosition(const Vector3f& position); + + //////////////////////////////////////////////////////////// + /// \brief Make the sound's position relative to the listener or absolute + /// + /// Making a sound relative to the listener will ensure that it will always + /// be played the same way regardless the position of the listener. + /// This can be useful for non-spatialized sounds, sounds that are + /// produced by the listener, or sounds attached to it. + /// The default value is false (position is absolute). + /// + /// \param relative True to set the position relative, false to set it absolute + /// + /// \see IsRelativeToListener + /// + //////////////////////////////////////////////////////////// + void SetRelativeToListener(bool relative); + + //////////////////////////////////////////////////////////// + /// \brief Set the minimum distance of the sound + /// + /// The "minimum distance" of a sound is the maximum + /// distance at which it is heard at its maximum volume. Further + /// than the minimum distance, it will start to fade out according + /// to its attenuation factor. A value of 0 ("inside the head + /// of the listener") is an invalid value and is forbidden. + /// The default value of the minimum distance is 1. + /// + /// \param distance New minimum distance of the sound + /// + /// \see GetMinDistance, SetAttenuation + /// + //////////////////////////////////////////////////////////// + void SetMinDistance(float distance); + + //////////////////////////////////////////////////////////// + /// \brief Set the attenuation factor of the sound + /// + /// The attenuation is a multiplicative factor which makes + /// the sound more or less loud according to its distance + /// from the listener. An attenuation of 0 will produce a + /// non-attenuated sound, i.e. its volume will always be the same + /// whether it is heard from near or from far. On the other hand, + /// an attenuation value such as 100 will make the sound fade out + /// very quickly as it gets further from the listener. + /// The default value of the attenuation is 1. + /// + /// \param attenuation New attenuation factor of the sound + /// + /// \see GetAttenuation, SetMinDistance + /// + //////////////////////////////////////////////////////////// + void SetAttenuation(float attenuation); + + //////////////////////////////////////////////////////////// + /// \brief Get the pitch of the sound + /// + /// \return Pitch of the sound + /// + /// \see SetPitch + /// + //////////////////////////////////////////////////////////// + float GetPitch() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the volume of the sound + /// + /// \return Volume of the sound, in the range [0, 100] + /// + /// \see SetVolume + /// + //////////////////////////////////////////////////////////// + float GetVolume() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the 3D position of the sound in the audio scene + /// + /// \return Position of the sound + /// + /// \see SetPosition + /// + //////////////////////////////////////////////////////////// + Vector3f GetPosition() const; + + //////////////////////////////////////////////////////////// + /// \brief Tell whether the sound's position is relative to the + /// listener or is absolute + /// + /// \return True if the position is relative, false if it's absolute + /// + /// \see SetRelativeToListener + /// + //////////////////////////////////////////////////////////// + bool IsRelativeToListener() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the minimum distance of the sound + /// + /// \return Minimum distance of the sound + /// + /// \see SetMinDistance, GetAttenuation + /// + //////////////////////////////////////////////////////////// + float GetMinDistance() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the attenuation factor of the sound + /// + /// \return Attenuation factor of the sound + /// + /// \see SetAttenuation, GetMinDistance + /// + //////////////////////////////////////////////////////////// + float GetAttenuation() const; + +protected : + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// This constructor is meant ot be called by derived classes only. + /// + //////////////////////////////////////////////////////////// + SoundSource(); + + //////////////////////////////////////////////////////////// + /// \brief Get the current status of the sound (stopped, paused, playing) + /// + /// \return Current status of the sound + /// + //////////////////////////////////////////////////////////// + Status GetStatus() const; + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + unsigned int mySource; ///< OpenAL source identifier +}; + +} // namespace sf + + +#endif // SFML_SOUNDSOURCE_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::SoundSource +/// +/// sf::SoundSource is not meant to be used directly, it +/// only serves as a common base for all audio objects +/// that can live in the audio environment. +/// +/// It defines several properties for the sound: pitch, +/// volume, position, attenuation, etc. All of them can be +/// changed at any time with no impact on performances. +/// +/// \see sf::Sound, sf::SoundStream +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Audio/SoundStream.hpp b/include/SFML/Audio/SoundStream.hpp index 9f01f0e0c..ef6ba7a5b 100644 --- a/include/SFML/Audio/SoundStream.hpp +++ b/include/SFML/Audio/SoundStream.hpp @@ -28,7 +28,7 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include +#include #include #include @@ -39,28 +39,10 @@ namespace sf /// \brief Abstract base class for streamed audio sources /// //////////////////////////////////////////////////////////// -class SFML_API SoundStream : private Thread, private Sound +class SFML_API SoundStream : public SoundSource, private Thread { public : - using Sound::Status; - using Sound::Stopped; - using Sound::Paused; - using Sound::Playing; - using Sound::Pause; - using Sound::SetPitch; - using Sound::SetVolume; - using Sound::SetPosition; - using Sound::SetRelativeToListener; - using Sound::SetMinDistance; - using Sound::SetAttenuation; - using Sound::GetPitch; - using Sound::GetVolume; - using Sound::GetPosition; - using Sound::IsRelativeToListener; - using Sound::GetMinDistance; - using Sound::GetAttenuation; - //////////////////////////////////////////////////////////// /// \brief Structure defining a chunk of audio data to stream /// @@ -90,6 +72,17 @@ public : //////////////////////////////////////////////////////////// void Play(); + //////////////////////////////////////////////////////////// + /// \brief Pause the audio stream + /// + /// This function pauses the stream if it was playing, + /// otherwise (stream already paused or stopped) it has no effect. + /// + /// \see Play, Stop + /// + //////////////////////////////////////////////////////////// + void Pause(); + //////////////////////////////////////////////////////////// /// \brief Stop playing the audio stream /// @@ -172,7 +165,7 @@ public : //////////////////////////////////////////////////////////// /// \brief Tell whether or not the stream is in loop mode /// - /// \return True if the music is looping, false otherwise + /// \return True if the stream is looping, false otherwise /// /// \see SetLoop /// diff --git a/src/SFML/Audio/AudioDevice.cpp b/src/SFML/Audio/AudioDevice.cpp index d9b3ee447..a396b9215 100644 --- a/src/SFML/Audio/AudioDevice.cpp +++ b/src/SFML/Audio/AudioDevice.cpp @@ -91,34 +91,29 @@ AudioDevice::~AudioDevice() //////////////////////////////////////////////////////////// -AudioDevice& AudioDevice::GetInstance() +bool AudioDevice::IsExtensionSupported(const std::string& extension) { - return globalDevice; + if ((extension.length() > 2) && (extension.substr(0, 3) == "ALC")) + return alcIsExtensionPresent(globalDevice.myDevice, extension.c_str()) != AL_FALSE; + else + return alIsExtensionPresent(extension.c_str()) != AL_FALSE; } //////////////////////////////////////////////////////////// -ALCdevice* AudioDevice::GetDevice() const -{ - return myDevice; -} - - -//////////////////////////////////////////////////////////// -ALenum AudioDevice::GetFormatFromChannelsCount(unsigned int channelsCount) const +ALenum AudioDevice::GetFormatFromChannelsCount(unsigned int channelsCount) { // Find the good format according to the number of channels switch (channelsCount) { - case 1 : return AL_FORMAT_MONO16; - case 2 : return AL_FORMAT_STEREO16; - case 4 : return alGetEnumValue("AL_FORMAT_QUAD16"); - case 6 : return alGetEnumValue("AL_FORMAT_51CHN16"); - case 7 : return alGetEnumValue("AL_FORMAT_61CHN16"); - case 8 : return alGetEnumValue("AL_FORMAT_71CHN16"); + case 1 : return AL_FORMAT_MONO16; + case 2 : return AL_FORMAT_STEREO16; + case 4 : return alGetEnumValue("AL_FORMAT_QUAD16"); + case 6 : return alGetEnumValue("AL_FORMAT_51CHN16"); + case 7 : return alGetEnumValue("AL_FORMAT_61CHN16"); + case 8 : return alGetEnumValue("AL_FORMAT_71CHN16"); + default : return 0; } - - return 0; } } // namespace priv diff --git a/src/SFML/Audio/AudioDevice.hpp b/src/SFML/Audio/AudioDevice.hpp index 18a478326..0df6c8d72 100644 --- a/src/SFML/Audio/AudioDevice.hpp +++ b/src/SFML/Audio/AudioDevice.hpp @@ -60,20 +60,18 @@ public : ~AudioDevice(); //////////////////////////////////////////////////////////// - /// \brief Get the unique instance of the class + /// \brief Check if an OpenAL extension is supported /// - /// \return Unique instance of the class + /// This functions automatically finds whether it + /// is an AL or ALC extension, and calls the corresponding + /// function. + /// + /// \param extension Name of the extension to test + /// + /// \return True if the extension is supported, false if not /// //////////////////////////////////////////////////////////// - static AudioDevice& GetInstance(); - - //////////////////////////////////////////////////////////// - /// \brief Get the OpenAL audio device - /// - /// \return OpenAL device (cannot be NULL) - /// - //////////////////////////////////////////////////////////// - ALCdevice* GetDevice() const; + static bool IsExtensionSupported(const std::string& extension); //////////////////////////////////////////////////////////// /// \brief Get the OpenAL format that matches the given number of channels @@ -83,7 +81,7 @@ public : /// \return Corresponding format /// //////////////////////////////////////////////////////////// - ALenum GetFormatFromChannelsCount(unsigned int channelsCount) const; + static ALenum GetFormatFromChannelsCount(unsigned int channelsCount); private : diff --git a/src/SFML/Audio/Sound.cpp b/src/SFML/Audio/Sound.cpp index 91b8594dc..86baca43f 100644 --- a/src/SFML/Audio/Sound.cpp +++ b/src/SFML/Audio/Sound.cpp @@ -35,8 +35,6 @@ namespace sf //////////////////////////////////////////////////////////// Sound::Sound() { - ALCheck(alGenSources(1, &mySource)); - ALCheck(alSourcei(mySource, AL_BUFFER, 0)); } @@ -44,8 +42,6 @@ Sound::Sound() Sound::Sound(const SoundBuffer& buffer, bool loop, float pitch, float volume, const Vector3f& position) : myBuffer(NULL) { - ALCheck(alGenSources(1, &mySource)); - SetBuffer(buffer); SetLoop(loop); SetPitch(pitch); @@ -56,34 +52,19 @@ myBuffer(NULL) //////////////////////////////////////////////////////////// Sound::Sound(const Sound& copy) : -myBuffer(NULL) +SoundSource(copy), +myBuffer (NULL) { - ALCheck(alGenSources(1, &mySource)); - if (copy.myBuffer) SetBuffer(*copy.myBuffer); SetLoop(copy.GetLoop()); - SetPitch(copy.GetPitch()); - SetVolume(copy.GetVolume()); - SetPosition(copy.GetPosition()); - SetRelativeToListener(copy.IsRelativeToListener()); - SetMinDistance(copy.GetMinDistance()); - SetAttenuation(copy.GetAttenuation()); } //////////////////////////////////////////////////////////// Sound::~Sound() { - if (mySource) - { - if (myBuffer) - { - Stop(); - ALCheck(alSourcei(mySource, AL_BUFFER, 0)); - } - ALCheck(alDeleteSources(1, &mySource)); - } + Stop(); } @@ -123,54 +104,6 @@ void Sound::SetLoop(bool Loop) } -//////////////////////////////////////////////////////////// -void Sound::SetPitch(float pitch) -{ - ALCheck(alSourcef(mySource, AL_PITCH, pitch)); -} - - -//////////////////////////////////////////////////////////// -void Sound::SetVolume(float volume) -{ - ALCheck(alSourcef(mySource, AL_GAIN, volume * 0.01f)); -} - -//////////////////////////////////////////////////////////// -void Sound::SetPosition(float x, float y, float z) -{ - ALCheck(alSource3f(mySource, AL_POSITION, x, y, z)); -} - - -//////////////////////////////////////////////////////////// -void Sound::SetPosition(const Vector3f& position) -{ - SetPosition(position.x, position.y, position.z); -} - - -//////////////////////////////////////////////////////////// -void Sound::SetRelativeToListener(bool relative) -{ - ALCheck(alSourcei(mySource, AL_SOURCE_RELATIVE, relative)); -} - - -//////////////////////////////////////////////////////////// -void Sound::SetMinDistance(float distance) -{ - ALCheck(alSourcef(mySource, AL_REFERENCE_DISTANCE, distance)); -} - - -//////////////////////////////////////////////////////////// -void Sound::SetAttenuation(float attenuation) -{ - ALCheck(alSourcef(mySource, AL_ROLLOFF_FACTOR, attenuation)); -} - - //////////////////////////////////////////////////////////// void Sound::SetPlayingOffset(float timeOffset) { @@ -195,66 +128,6 @@ bool Sound::GetLoop() const } -//////////////////////////////////////////////////////////// -float Sound::GetPitch() const -{ - ALfloat pitch; - ALCheck(alGetSourcef(mySource, AL_PITCH, &pitch)); - - return pitch; -} - - -//////////////////////////////////////////////////////////// -float Sound::GetVolume() const -{ - ALfloat gain; - ALCheck(alGetSourcef(mySource, AL_GAIN, &gain)); - - return gain * 100.f; -} - - -//////////////////////////////////////////////////////////// -Vector3f Sound::GetPosition() const -{ - Vector3f position; - ALCheck(alGetSource3f(mySource, AL_POSITION, &position.x, &position.y, &position.z)); - - return position; -} - - -//////////////////////////////////////////////////////////// -bool Sound::IsRelativeToListener() const -{ - ALint relative; - ALCheck(alGetSourcei(mySource, AL_SOURCE_RELATIVE, &relative)); - - return relative != 0; -} - - -//////////////////////////////////////////////////////////// -float Sound::GetMinDistance() const -{ - ALfloat distance; - ALCheck(alGetSourcef(mySource, AL_REFERENCE_DISTANCE, &distance)); - - return distance; -} - - -//////////////////////////////////////////////////////////// -float Sound::GetAttenuation() const -{ - ALfloat attenuation; - ALCheck(alGetSourcef(mySource, AL_ROLLOFF_FACTOR, &attenuation)); - - return attenuation; -} - - //////////////////////////////////////////////////////////// float Sound::GetPlayingOffset() const { @@ -268,25 +141,14 @@ float Sound::GetPlayingOffset() const //////////////////////////////////////////////////////////// Sound::Status Sound::GetStatus() const { - ALint status; - ALCheck(alGetSourcei(mySource, AL_SOURCE_STATE, &status)); - - switch (status) - { - case AL_INITIAL : - case AL_STOPPED : return Stopped; - case AL_PAUSED : return Paused; - case AL_PLAYING : return Playing; - } - - return Stopped; + return SoundSource::GetStatus(); } //////////////////////////////////////////////////////////// -Sound& Sound::operator =(const Sound& other) +Sound& Sound::operator =(const Sound& right) { - Sound temp(other); + Sound temp(right); std::swap(mySource, temp.mySource); std::swap(myBuffer, temp.myBuffer); diff --git a/src/SFML/Audio/SoundBuffer.cpp b/src/SFML/Audio/SoundBuffer.cpp index 1db65f7f9..21306e043 100644 --- a/src/SFML/Audio/SoundBuffer.cpp +++ b/src/SFML/Audio/SoundBuffer.cpp @@ -237,7 +237,7 @@ bool SoundBuffer::Update(unsigned int channelsCount, unsigned int sampleRate) return false; // Find the good format according to the number of channels - ALenum format = priv::AudioDevice::GetInstance().GetFormatFromChannelsCount(channelsCount); + ALenum format = priv::AudioDevice::GetFormatFromChannelsCount(channelsCount); // Check if the format is valid if (format == 0) diff --git a/src/SFML/Audio/SoundFile.hpp b/src/SFML/Audio/SoundFile.hpp index 55529547e..2fa50d3b9 100644 --- a/src/SFML/Audio/SoundFile.hpp +++ b/src/SFML/Audio/SoundFile.hpp @@ -167,11 +167,11 @@ private : private : - static sf_count_t GetLength(void* UserData); - static sf_count_t Read(void* Ptr, sf_count_t Count, void* UserData); - static sf_count_t Seek(sf_count_t Offset, int Whence, void* UserData); - static sf_count_t Tell(void* UserData); - static sf_count_t Write(const void* Ptr, sf_count_t Count, void* UserData); + static sf_count_t GetLength(void* userData); + static sf_count_t Read(void* ptr, sf_count_t count, void* userData); + static sf_count_t Seek(sf_count_t offset, int whence, void* userData); + static sf_count_t Tell(void* userData); + static sf_count_t Write(const void* ptr, sf_count_t count, void* userData); const char* myDataStart; const char* myDataPtr; diff --git a/src/SFML/Audio/SoundRecorder.cpp b/src/SFML/Audio/SoundRecorder.cpp index 134c4a3c4..714aa651f 100644 --- a/src/SFML/Audio/SoundRecorder.cpp +++ b/src/SFML/Audio/SoundRecorder.cpp @@ -83,7 +83,7 @@ void SoundRecorder::Start(unsigned int sampleRate) return; } - // Clear the sample array + // Clear the array of samples mySamples.clear(); // Store the sample rate @@ -121,9 +121,7 @@ unsigned int SoundRecorder::GetSampleRate() const //////////////////////////////////////////////////////////// bool SoundRecorder::CanCapture() { - ALCdevice* device = priv::AudioDevice::GetInstance().GetDevice(); - - return alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") != AL_FALSE; + return priv::AudioDevice::IsExtensionSupported("ALC_EXT_CAPTURE"); } diff --git a/src/SFML/Audio/SoundSource.cpp b/src/SFML/Audio/SoundSource.cpp new file mode 100644 index 000000000..a6c5de6ad --- /dev/null +++ b/src/SFML/Audio/SoundSource.cpp @@ -0,0 +1,190 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +SoundSource::SoundSource() +{ + ALCheck(alGenSources(1, &mySource)); + ALCheck(alSourcei(mySource, AL_BUFFER, 0)); +} + + +//////////////////////////////////////////////////////////// +SoundSource::SoundSource(const SoundSource& copy) +{ + ALCheck(alGenSources(1, &mySource)); + ALCheck(alSourcei(mySource, AL_BUFFER, 0)); + + SetPitch(copy.GetPitch()); + SetVolume(copy.GetVolume()); + SetPosition(copy.GetPosition()); + SetRelativeToListener(copy.IsRelativeToListener()); + SetMinDistance(copy.GetMinDistance()); + SetAttenuation(copy.GetAttenuation()); +} + + +//////////////////////////////////////////////////////////// +SoundSource::~SoundSource() +{ + ALCheck(alSourcei(mySource, AL_BUFFER, 0)); + ALCheck(alDeleteSources(1, &mySource)); +} + + +//////////////////////////////////////////////////////////// +void SoundSource::SetPitch(float pitch) +{ + ALCheck(alSourcef(mySource, AL_PITCH, pitch)); +} + + +//////////////////////////////////////////////////////////// +void SoundSource::SetVolume(float volume) +{ + ALCheck(alSourcef(mySource, AL_GAIN, volume * 0.01f)); +} + +//////////////////////////////////////////////////////////// +void SoundSource::SetPosition(float x, float y, float z) +{ + ALCheck(alSource3f(mySource, AL_POSITION, x, y, z)); +} + + +//////////////////////////////////////////////////////////// +void SoundSource::SetPosition(const Vector3f& position) +{ + SetPosition(position.x, position.y, position.z); +} + + +//////////////////////////////////////////////////////////// +void SoundSource::SetRelativeToListener(bool relative) +{ + ALCheck(alSourcei(mySource, AL_SOURCE_RELATIVE, relative)); +} + + +//////////////////////////////////////////////////////////// +void SoundSource::SetMinDistance(float distance) +{ + ALCheck(alSourcef(mySource, AL_REFERENCE_DISTANCE, distance)); +} + + +//////////////////////////////////////////////////////////// +void SoundSource::SetAttenuation(float attenuation) +{ + ALCheck(alSourcef(mySource, AL_ROLLOFF_FACTOR, attenuation)); +} + + +//////////////////////////////////////////////////////////// +float SoundSource::GetPitch() const +{ + ALfloat pitch; + ALCheck(alGetSourcef(mySource, AL_PITCH, &pitch)); + + return pitch; +} + + +//////////////////////////////////////////////////////////// +float SoundSource::GetVolume() const +{ + ALfloat gain; + ALCheck(alGetSourcef(mySource, AL_GAIN, &gain)); + + return gain * 100.f; +} + + +//////////////////////////////////////////////////////////// +Vector3f SoundSource::GetPosition() const +{ + Vector3f position; + ALCheck(alGetSource3f(mySource, AL_POSITION, &position.x, &position.y, &position.z)); + + return position; +} + + +//////////////////////////////////////////////////////////// +bool SoundSource::IsRelativeToListener() const +{ + ALint relative; + ALCheck(alGetSourcei(mySource, AL_SOURCE_RELATIVE, &relative)); + + return relative != 0; +} + + +//////////////////////////////////////////////////////////// +float SoundSource::GetMinDistance() const +{ + ALfloat distance; + ALCheck(alGetSourcef(mySource, AL_REFERENCE_DISTANCE, &distance)); + + return distance; +} + + +//////////////////////////////////////////////////////////// +float SoundSource::GetAttenuation() const +{ + ALfloat attenuation; + ALCheck(alGetSourcef(mySource, AL_ROLLOFF_FACTOR, &attenuation)); + + return attenuation; +} + + +//////////////////////////////////////////////////////////// +SoundSource::Status SoundSource::GetStatus() const +{ + ALint status; + ALCheck(alGetSourcei(mySource, AL_SOURCE_STATE, &status)); + + switch (status) + { + case AL_INITIAL : + case AL_STOPPED : return Stopped; + case AL_PAUSED : return Paused; + case AL_PLAYING : return Playing; + } + + return Stopped; +} + +} // namespace sf diff --git a/src/SFML/Audio/SoundStream.cpp b/src/SFML/Audio/SoundStream.cpp index b968192fb..b1ffe87ed 100644 --- a/src/SFML/Audio/SoundStream.cpp +++ b/src/SFML/Audio/SoundStream.cpp @@ -61,7 +61,7 @@ void SoundStream::Initialize(unsigned int channelsCount, unsigned int sampleRate mySampleRate = sampleRate; // Deduce the format from the number of channels - myFormat = priv::AudioDevice::GetInstance().GetFormatFromChannelsCount(channelsCount); + myFormat = priv::AudioDevice::GetFormatFromChannelsCount(channelsCount); // Check if the format is valid if (myFormat == 0) @@ -79,14 +79,14 @@ void SoundStream::Play() // Check if the sound parameters have been set if (myFormat == 0) { - std::cerr << "Failed to play audio stream : sound parameters have not been initialized (call Initialize first)" << std::endl; + std::cerr << "Failed to play audio stream: sound parameters have not been initialized (call Initialize first)" << std::endl; return; } // If the sound is already playing (probably paused), just resume it if (myIsStreaming) { - Sound::Play(); + ALCheck(alSourcePlay(mySource)); return; } @@ -100,6 +100,13 @@ void SoundStream::Play() } +//////////////////////////////////////////////////////////// +void SoundStream::Pause() +{ + ALCheck(alSourcePause(mySource)); +} + + //////////////////////////////////////////////////////////// void SoundStream::Stop() { @@ -124,9 +131,9 @@ unsigned int SoundStream::GetSampleRate() const //////////////////////////////////////////////////////////// -Sound::Status SoundStream::GetStatus() const +SoundStream::Status SoundStream::GetStatus() const { - Status status = Sound::GetStatus(); + Status status = SoundSource::GetStatus(); // To compensate for the lag between Play() and alSourcePlay() if ((status == Stopped) && myIsStreaming) @@ -155,7 +162,10 @@ void SoundStream::SetPlayingOffset(float timeOffset) //////////////////////////////////////////////////////////// float SoundStream::GetPlayingOffset() const { - return Sound::GetPlayingOffset() + static_cast(mySamplesProcessed) / mySampleRate / myChannelsCount; + ALfloat seconds = 0.f; + ALCheck(alGetSourcef(mySource, AL_SEC_OFFSET, &seconds)); + + return seconds + static_cast(mySamplesProcessed) / mySampleRate / myChannelsCount; } @@ -184,17 +194,17 @@ void SoundStream::Run() bool requestStop = FillQueue(); // Play the sound - Sound::Play(); + ALCheck(alSourcePlay(mySource)); while (myIsStreaming) { - // The stream has been interrupted ! - if (Sound::GetStatus() == Stopped) + // The stream has been interrupted! + if (SoundSource::GetStatus() == Stopped) { if (!requestStop) { // Just continue - Sound::Play(); + ALCheck(alSourcePlay(mySource)); } else { @@ -205,13 +215,13 @@ void SoundStream::Run() // Get the number of buffers that have been processed (ie. ready for reuse) ALint nbProcessed; - ALCheck(alGetSourcei(Sound::mySource, AL_BUFFERS_PROCESSED, &nbProcessed)); + ALCheck(alGetSourcei(mySource, AL_BUFFERS_PROCESSED, &nbProcessed)); while (nbProcessed--) { // Pop the first unused buffer from the queue ALuint buffer; - ALCheck(alSourceUnqueueBuffers(Sound::mySource, 1, &buffer)); + ALCheck(alSourceUnqueueBuffers(mySource, 1, &buffer)); // Retrieve its size and add it to the samples count if (buffer == endBuffer) @@ -250,18 +260,18 @@ void SoundStream::Run() } // Leave some time for the other threads if the stream is still playing - if (Sound::GetStatus() != Stopped) + if (SoundSource::GetStatus() != Stopped) Sleep(0.1f); } // Stop the playback - Sound::Stop(); + ALCheck(alSourceStop(mySource)); // Unqueue any buffer left in the queue ClearQueue(); // Delete the buffers - ALCheck(alSourcei(Sound::mySource, AL_BUFFER, 0)); + ALCheck(alSourcei(mySource, AL_BUFFER, 0)); ALCheck(alDeleteBuffers(BuffersCount, myBuffers)); } @@ -284,7 +294,7 @@ bool SoundStream::FillAndPushBuffer(unsigned int buffer) ALCheck(alBufferData(buffer, myFormat, data.Samples, size, mySampleRate)); // Push it into the sound queue - ALCheck(alSourceQueueBuffers(Sound::mySource, 1, &buffer)); + ALCheck(alSourceQueueBuffers(mySource, 1, &buffer)); } return requestStop; @@ -311,12 +321,12 @@ void SoundStream::ClearQueue() { // Get the number of buffers still in the queue ALint nbQueued; - ALCheck(alGetSourcei(Sound::mySource, AL_BUFFERS_QUEUED, &nbQueued)); + ALCheck(alGetSourcei(mySource, AL_BUFFERS_QUEUED, &nbQueued)); // Unqueue them all ALuint buffer; for (ALint i = 0; i < nbQueued; ++i) - ALCheck(alSourceUnqueueBuffers(Sound::mySource, 1, &buffer)); + ALCheck(alSourceUnqueueBuffers(mySource, 1, &buffer)); } } // namespace sf