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
This commit is contained in:
LaurentGom 2009-11-26 09:03:00 +00:00
parent 5669793e9e
commit 29ecc552c2
8 changed files with 59 additions and 26 deletions

View File

@ -26,6 +26,7 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Audio/ALCheck.hpp> #include <SFML/Audio/ALCheck.hpp>
#include <SFML/Audio/AudioDevice.hpp>
namespace sf namespace sf
@ -89,6 +90,19 @@ void ALCheckError(const std::string& file, unsigned int line)
} }
} }
////////////////////////////////////////////////////////////
/// 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 } // namespace priv
} // namespace sf } // namespace sf

View File

@ -71,6 +71,12 @@ namespace priv
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void ALCheckError(const std::string& file, unsigned int line); void ALCheckError(const std::string& file, unsigned int line);
////////////////////////////////////////////////////////////
/// Make sure that OpenAL is initialized
///
////////////////////////////////////////////////////////////
void EnsureALInit();
} // namespace priv } // namespace priv
} // namespace sf } // namespace sf

View File

@ -26,8 +26,8 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Audio/AudioDevice.hpp> #include <SFML/Audio/AudioDevice.hpp>
#include <SFML/Audio/ALCheck.hpp>
#include <SFML/Audio/Listener.hpp> #include <SFML/Audio/Listener.hpp>
#include <algorithm>
#include <iostream> #include <iostream>
@ -36,10 +36,10 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
namespace namespace
{ {
sf::priv::AudioDevice globalDevice; ALCdevice* audioDevice = NULL;
ALCcontext* audioContext = NULL;
} }
namespace sf namespace sf
{ {
namespace priv namespace priv
@ -48,17 +48,17 @@ namespace priv
AudioDevice::AudioDevice() AudioDevice::AudioDevice()
{ {
// Create the device // Create the device
myDevice = alcOpenDevice(NULL); audioDevice = alcOpenDevice(NULL);
if (myDevice) if (audioDevice)
{ {
// Create the context // 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) // 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 // Initialize the listener, located at the origin and looking along the Z axis
Listener::SetPosition(0.f, 0.f, 0.f); Listener::SetPosition(0.f, 0.f, 0.f);
@ -81,28 +81,32 @@ AudioDevice::~AudioDevice()
{ {
// Destroy the context // Destroy the context
alcMakeContextCurrent(NULL); alcMakeContextCurrent(NULL);
if (myContext) if (audioContext)
alcDestroyContext(myContext); alcDestroyContext(audioContext);
// Destroy the device // Destroy the device
if (myDevice) if (audioDevice)
alcCloseDevice(myDevice); alcCloseDevice(audioDevice);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool AudioDevice::IsExtensionSupported(const std::string& extension) bool AudioDevice::IsExtensionSupported(const std::string& extension)
{ {
EnsureALInit();
if ((extension.length() > 2) && (extension.substr(0, 3) == "ALC")) 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 else
return alIsExtensionPresent(extension.c_str()) != AL_FALSE; 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 // Find the good format according to the number of channels
switch (channelsCount) switch (channelsCount)
{ {

View File

@ -28,7 +28,6 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Audio/ALCheck.hpp>
#include <set> #include <set>
#include <string> #include <string>
@ -81,15 +80,7 @@ public :
/// \return Corresponding format /// \return Corresponding format
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
static ALenum GetFormatFromChannelsCount(unsigned int channelsCount); static int GetFormatFromChannelsCount(unsigned int channelsCount);
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
ALCdevice* myDevice; ///< Audio device
ALCcontext* myContext; ///< Audio context
}; };
} // namespace priv } // namespace priv

View File

@ -34,6 +34,8 @@ namespace sf
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Listener::SetGlobalVolume(float volume) void Listener::SetGlobalVolume(float volume)
{ {
priv::EnsureALInit();
ALCheck(alListenerf(AL_GAIN, volume * 0.01f)); ALCheck(alListenerf(AL_GAIN, volume * 0.01f));
} }
@ -41,6 +43,8 @@ void Listener::SetGlobalVolume(float volume)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
float Listener::GetGlobalVolume() float Listener::GetGlobalVolume()
{ {
priv::EnsureALInit();
float volume = 0.f; float volume = 0.f;
ALCheck(alGetListenerf(AL_GAIN, &volume)); ALCheck(alGetListenerf(AL_GAIN, &volume));
@ -51,6 +55,8 @@ float Listener::GetGlobalVolume()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Listener::SetPosition(float x, float y, float z) void Listener::SetPosition(float x, float y, float z)
{ {
priv::EnsureALInit();
ALCheck(alListener3f(AL_POSITION, x, y, z)); ALCheck(alListener3f(AL_POSITION, x, y, z));
} }
@ -65,6 +71,8 @@ void Listener::SetPosition(const Vector3f& position)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Vector3f Listener::GetPosition() Vector3f Listener::GetPosition()
{ {
priv::EnsureALInit();
Vector3f position; Vector3f position;
ALCheck(alGetListener3f(AL_POSITION, &position.x, &position.y, &position.z)); 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) void Listener::SetDirection(float x, float y, float z)
{ {
priv::EnsureALInit();
float orientation[] = {x, y, z, 0.f, 1.f, 0.f}; float orientation[] = {x, y, z, 0.f, 1.f, 0.f};
ALCheck(alListenerfv(AL_ORIENTATION, orientation)); ALCheck(alListenerfv(AL_ORIENTATION, orientation));
} }
@ -90,6 +100,8 @@ void Listener::SetDirection(const Vector3f& direction)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Vector3f Listener::GetDirection() Vector3f Listener::GetDirection()
{ {
priv::EnsureALInit();
float orientation[6]; float orientation[6];
ALCheck(alGetListenerfv(AL_ORIENTATION, orientation)); ALCheck(alGetListenerfv(AL_ORIENTATION, orientation));

View File

@ -40,6 +40,8 @@ SoundBuffer::SoundBuffer() :
myBuffer (0), myBuffer (0),
myDuration(0.f) myDuration(0.f)
{ {
priv::EnsureALInit();
// Create the buffer // Create the buffer
ALCheck(alGenBuffers(1, &myBuffer)); ALCheck(alGenBuffers(1, &myBuffer));
} }

View File

@ -47,7 +47,7 @@ SoundRecorder::SoundRecorder() :
mySampleRate (0), mySampleRate (0),
myIsCapturing(false) myIsCapturing(false)
{ {
priv::EnsureALInit();
} }

View File

@ -34,6 +34,8 @@ namespace sf
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
SoundSource::SoundSource() SoundSource::SoundSource()
{ {
priv::EnsureALInit();
ALCheck(alGenSources(1, &mySource)); ALCheck(alGenSources(1, &mySource));
ALCheck(alSourcei(mySource, AL_BUFFER, 0)); ALCheck(alSourcei(mySource, AL_BUFFER, 0));
} }
@ -42,6 +44,8 @@ SoundSource::SoundSource()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
SoundSource::SoundSource(const SoundSource& copy) SoundSource::SoundSource(const SoundSource& copy)
{ {
priv::EnsureALInit();
ALCheck(alGenSources(1, &mySource)); ALCheck(alGenSources(1, &mySource));
ALCheck(alSourcei(mySource, AL_BUFFER, 0)); ALCheck(alSourcei(mySource, AL_BUFFER, 0));