From 29ecc552c248d7b17749422ca127a1b12e9adc26 Mon Sep 17 00:00:00 2001 From: LaurentGom Date: Thu, 26 Nov 2009 09:03:00 +0000 Subject: [PATCH] Fixed crashes at startup when using the audio module git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1289 4e206d99-4929-0410-ac5d-dfc041789085 --- src/SFML/Audio/ALCheck.cpp | 14 +++++++++++++ src/SFML/Audio/ALCheck.hpp | 6 ++++++ src/SFML/Audio/AudioDevice.cpp | 34 ++++++++++++++++++-------------- src/SFML/Audio/AudioDevice.hpp | 11 +---------- src/SFML/Audio/Listener.cpp | 12 +++++++++++ src/SFML/Audio/SoundBuffer.cpp | 2 ++ src/SFML/Audio/SoundRecorder.cpp | 2 +- src/SFML/Audio/SoundSource.cpp | 4 ++++ 8 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/SFML/Audio/ALCheck.cpp b/src/SFML/Audio/ALCheck.cpp index 03520950..fdfda895 100644 --- a/src/SFML/Audio/ALCheck.cpp +++ b/src/SFML/Audio/ALCheck.cpp @@ -26,6 +26,7 @@ // Headers //////////////////////////////////////////////////////////// #include +#include namespace sf @@ -88,6 +89,19 @@ void ALCheckError(const std::string& file, unsigned int line) << std::endl; } } + + +//////////////////////////////////////////////////////////// +/// Make sure that OpenAL is initialized +//////////////////////////////////////////////////////////// +void EnsureALInit() +{ + // The audio device is instanciated on demand rather than at global startup, + // which solves a lot of weird crashes and errors. + /// It is destroyed at global exit which is fine. + + static AudioDevice globalDevice; +} } // namespace priv diff --git a/src/SFML/Audio/ALCheck.hpp b/src/SFML/Audio/ALCheck.hpp index 7832845d..20148f2f 100644 --- a/src/SFML/Audio/ALCheck.hpp +++ b/src/SFML/Audio/ALCheck.hpp @@ -71,6 +71,12 @@ namespace priv //////////////////////////////////////////////////////////// void ALCheckError(const std::string& file, unsigned int line); +//////////////////////////////////////////////////////////// +/// Make sure that OpenAL is initialized +/// +//////////////////////////////////////////////////////////// +void EnsureALInit(); + } // namespace priv } // namespace sf diff --git a/src/SFML/Audio/AudioDevice.cpp b/src/SFML/Audio/AudioDevice.cpp index a396b921..4c16b200 100644 --- a/src/SFML/Audio/AudioDevice.cpp +++ b/src/SFML/Audio/AudioDevice.cpp @@ -26,20 +26,20 @@ // Headers //////////////////////////////////////////////////////////// #include +#include #include -#include #include //////////////////////////////////////////////////////////// // Private data //////////////////////////////////////////////////////////// -namespace +namespace { - sf::priv::AudioDevice globalDevice; + ALCdevice* audioDevice = NULL; + ALCcontext* audioContext = NULL; } - namespace sf { namespace priv @@ -48,17 +48,17 @@ namespace priv AudioDevice::AudioDevice() { // Create the device - myDevice = alcOpenDevice(NULL); + audioDevice = alcOpenDevice(NULL); - if (myDevice) + if (audioDevice) { // Create the context - myContext = alcCreateContext(myDevice, NULL); + audioContext = alcCreateContext(audioDevice, NULL); - if (myContext) + if (audioContext) { // Set the context as the current one (we'll only need one) - alcMakeContextCurrent(myContext); + alcMakeContextCurrent(audioContext); // Initialize the listener, located at the origin and looking along the Z axis Listener::SetPosition(0.f, 0.f, 0.f); @@ -81,28 +81,32 @@ AudioDevice::~AudioDevice() { // Destroy the context alcMakeContextCurrent(NULL); - if (myContext) - alcDestroyContext(myContext); + if (audioContext) + alcDestroyContext(audioContext); // Destroy the device - if (myDevice) - alcCloseDevice(myDevice); + if (audioDevice) + alcCloseDevice(audioDevice); } //////////////////////////////////////////////////////////// bool AudioDevice::IsExtensionSupported(const std::string& extension) { + EnsureALInit(); + if ((extension.length() > 2) && (extension.substr(0, 3) == "ALC")) - return alcIsExtensionPresent(globalDevice.myDevice, extension.c_str()) != AL_FALSE; + return alcIsExtensionPresent(audioDevice, extension.c_str()) != AL_FALSE; else return alIsExtensionPresent(extension.c_str()) != AL_FALSE; } //////////////////////////////////////////////////////////// -ALenum AudioDevice::GetFormatFromChannelsCount(unsigned int channelsCount) +int AudioDevice::GetFormatFromChannelsCount(unsigned int channelsCount) { + EnsureALInit(); + // Find the good format according to the number of channels switch (channelsCount) { diff --git a/src/SFML/Audio/AudioDevice.hpp b/src/SFML/Audio/AudioDevice.hpp index 0df6c8d7..334869f9 100644 --- a/src/SFML/Audio/AudioDevice.hpp +++ b/src/SFML/Audio/AudioDevice.hpp @@ -28,7 +28,6 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include #include #include @@ -81,15 +80,7 @@ public : /// \return Corresponding format /// //////////////////////////////////////////////////////////// - static ALenum GetFormatFromChannelsCount(unsigned int channelsCount); - -private : - - //////////////////////////////////////////////////////////// - // Member data - //////////////////////////////////////////////////////////// - ALCdevice* myDevice; ///< Audio device - ALCcontext* myContext; ///< Audio context + static int GetFormatFromChannelsCount(unsigned int channelsCount); }; } // namespace priv diff --git a/src/SFML/Audio/Listener.cpp b/src/SFML/Audio/Listener.cpp index c9bac558..9e2f9490 100644 --- a/src/SFML/Audio/Listener.cpp +++ b/src/SFML/Audio/Listener.cpp @@ -34,6 +34,8 @@ namespace sf //////////////////////////////////////////////////////////// void Listener::SetGlobalVolume(float volume) { + priv::EnsureALInit(); + ALCheck(alListenerf(AL_GAIN, volume * 0.01f)); } @@ -41,6 +43,8 @@ void Listener::SetGlobalVolume(float volume) //////////////////////////////////////////////////////////// float Listener::GetGlobalVolume() { + priv::EnsureALInit(); + float volume = 0.f; ALCheck(alGetListenerf(AL_GAIN, &volume)); @@ -51,6 +55,8 @@ float Listener::GetGlobalVolume() //////////////////////////////////////////////////////////// void Listener::SetPosition(float x, float y, float z) { + priv::EnsureALInit(); + ALCheck(alListener3f(AL_POSITION, x, y, z)); } @@ -65,6 +71,8 @@ void Listener::SetPosition(const Vector3f& position) //////////////////////////////////////////////////////////// Vector3f Listener::GetPosition() { + priv::EnsureALInit(); + Vector3f position; ALCheck(alGetListener3f(AL_POSITION, &position.x, &position.y, &position.z)); @@ -75,6 +83,8 @@ Vector3f Listener::GetPosition() //////////////////////////////////////////////////////////// void Listener::SetDirection(float x, float y, float z) { + priv::EnsureALInit(); + float orientation[] = {x, y, z, 0.f, 1.f, 0.f}; ALCheck(alListenerfv(AL_ORIENTATION, orientation)); } @@ -90,6 +100,8 @@ void Listener::SetDirection(const Vector3f& direction) //////////////////////////////////////////////////////////// Vector3f Listener::GetDirection() { + priv::EnsureALInit(); + float orientation[6]; ALCheck(alGetListenerfv(AL_ORIENTATION, orientation)); diff --git a/src/SFML/Audio/SoundBuffer.cpp b/src/SFML/Audio/SoundBuffer.cpp index 21306e04..ec498e8a 100644 --- a/src/SFML/Audio/SoundBuffer.cpp +++ b/src/SFML/Audio/SoundBuffer.cpp @@ -40,6 +40,8 @@ SoundBuffer::SoundBuffer() : myBuffer (0), myDuration(0.f) { + priv::EnsureALInit(); + // Create the buffer ALCheck(alGenBuffers(1, &myBuffer)); } diff --git a/src/SFML/Audio/SoundRecorder.cpp b/src/SFML/Audio/SoundRecorder.cpp index 796eda65..37a3c254 100644 --- a/src/SFML/Audio/SoundRecorder.cpp +++ b/src/SFML/Audio/SoundRecorder.cpp @@ -47,7 +47,7 @@ SoundRecorder::SoundRecorder() : mySampleRate (0), myIsCapturing(false) { - + priv::EnsureALInit(); } diff --git a/src/SFML/Audio/SoundSource.cpp b/src/SFML/Audio/SoundSource.cpp index a6c5de6a..cd52e87b 100644 --- a/src/SFML/Audio/SoundSource.cpp +++ b/src/SFML/Audio/SoundSource.cpp @@ -34,6 +34,8 @@ namespace sf //////////////////////////////////////////////////////////// SoundSource::SoundSource() { + priv::EnsureALInit(); + ALCheck(alGenSources(1, &mySource)); ALCheck(alSourcei(mySource, AL_BUFFER, 0)); } @@ -42,6 +44,8 @@ SoundSource::SoundSource() //////////////////////////////////////////////////////////// SoundSource::SoundSource(const SoundSource& copy) { + priv::EnsureALInit(); + ALCheck(alGenSources(1, &mySource)); ALCheck(alSourcei(mySource, AL_BUFFER, 0));