Thread safe.

PS: The OpenAL is a mess.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4710 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
ayuanx 2009-12-18 19:52:04 +00:00
parent 97090337e3
commit 7b6a0f9b72
4 changed files with 48 additions and 39 deletions

View File

@ -49,16 +49,13 @@ void AOSound::SoundLoop()
while (!threadData) while (!threadData)
{ {
soundCriticalSection.Enter();
m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2); m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2);
soundCriticalSection.Enter();
ao_play(device, (char*)realtimeBuffer, numBytesToRender); ao_play(device, (char*)realtimeBuffer, numBytesToRender);
soundCriticalSection.Leave(); soundCriticalSection.Leave();
if (! threadData) soundSyncEvent.Wait();
soundSyncEvent.Wait();
} }
ao_close(device);
device = NULL;
} }
void *soundThread(void *args) void *soundThread(void *args)
@ -84,19 +81,23 @@ void AOSound::Update()
void AOSound::Stop() void AOSound::Stop()
{ {
soundCriticalSection.Enter();
threadData = 1; threadData = 1;
soundSyncEvent.Set(); soundSyncEvent.Set();
soundCriticalSection.Leave();
delete thread; soundCriticalSection.Enter();
delete thread;
thread = NULL; thread = NULL;
ao_shutdown();
ao_close(device);
device = NULL;
soundCriticalSection.Leave();
soundSyncEvent.Shutdown(); soundSyncEvent.Shutdown();
} }
AOSound::~AOSound() { AOSound::~AOSound()
// FIXME: crashes dolphin {
// ao_shutdown();
} }
#endif #endif

View File

@ -101,8 +101,8 @@ void DSound::SoundLoop()
{ {
currentPos = 0; currentPos = 0;
lastPos = 0; lastPos = 0;
dsBuffer->Play(0, 0, DSBPLAY_LOOPING);
HRESULT hr = dsBuffer->Play(0, 0, DSBPLAY_LOOPING);
while (!threadData) while (!threadData)
{ {
// No blocking inside the csection // No blocking inside the csection
@ -119,19 +119,15 @@ void DSound::SoundLoop()
totalRenderedBytes += numBytesToRender; totalRenderedBytes += numBytesToRender;
lastPos = currentPos; lastPos = currentPos;
} }
soundCriticalSection.Leave(); soundCriticalSection.Leave();
if (threadData)
break;
soundSyncEvent.Wait(); soundSyncEvent.Wait();
} }
dsBuffer->Stop();
} }
bool DSound::Start() bool DSound::Start()
{ {
soundSyncEvent.Init(); soundSyncEvent.Init();
if (FAILED(DirectSoundCreate8(0, &ds, 0))) if (FAILED(DirectSoundCreate8(0, &ds, 0)))
return false; return false;
if (g_dspInitialize.hWnd) if (g_dspInitialize.hWnd)
@ -170,6 +166,8 @@ void DSound::Update()
void DSound::Clear(bool mute) void DSound::Clear(bool mute)
{ {
m_muted = mute; m_muted = mute;
soundCriticalSection.Enter();
if (m_muted) if (m_muted)
{ {
dsBuffer->Stop(); dsBuffer->Stop();
@ -178,21 +176,23 @@ void DSound::Clear(bool mute)
{ {
dsBuffer->Play(0, 0, DSBPLAY_LOOPING); dsBuffer->Play(0, 0, DSBPLAY_LOOPING);
} }
soundCriticalSection.Leave();
} }
void DSound::Stop() void DSound::Stop()
{ {
soundCriticalSection.Enter();
threadData = 1; threadData = 1;
// kick the thread if it's waiting // kick the thread if it's waiting
soundSyncEvent.Set(); soundSyncEvent.Set();
soundCriticalSection.Leave();
delete thread;
soundCriticalSection.Enter();
delete thread;
thread = NULL;
dsBuffer->Stop();
dsBuffer->Release(); dsBuffer->Release();
ds->Release(); ds->Release();
soundCriticalSection.Leave();
soundSyncEvent.Shutdown(); soundSyncEvent.Shutdown();
thread = NULL;
} }

View File

@ -31,6 +31,9 @@ bool OpenALStream::Start()
bool bReturn = false; bool bReturn = false;
g_uiSource = 0; g_uiSource = 0;
g_uiBuffers = NULL;
soundSyncEvent.Init();
pDeviceList = new ALDeviceList(); pDeviceList = new ALDeviceList();
if ((pDeviceList) && (pDeviceList->GetNumDevices())) if ((pDeviceList) && (pDeviceList->GetNumDevices()))
@ -68,22 +71,30 @@ void OpenALStream::Stop()
ALCcontext *pContext; ALCcontext *pContext;
ALCdevice *pDevice; ALCdevice *pDevice;
soundCriticalSection.Enter();
threadData = 1; threadData = 1;
// kick the thread if it's waiting // kick the thread if it's waiting
soundSyncEvent.Set(); soundSyncEvent.Set();
soundCriticalSection.Leave();
soundCriticalSection.Enter();
delete thread; delete thread;
thread = NULL;
alSourceStop(g_uiSource);
alSourcei(g_uiSource, AL_BUFFER, 0);
// Clean up buffers and sources
alDeleteSources(1, &g_uiSource);
alDeleteBuffers(AUDIO_NUMBUFFERS, g_uiBuffers);
pContext = alcGetCurrentContext(); pContext = alcGetCurrentContext();
pDevice = alcGetContextsDevice(pContext); pDevice = alcGetContextsDevice(pContext);
alcMakeContextCurrent(NULL); alcMakeContextCurrent(NULL);
alcDestroyContext(pContext); alcDestroyContext(pContext);
alcCloseDevice(pDevice); alcCloseDevice(pDevice);
soundCriticalSection.Leave();
soundSyncEvent.Shutdown(); soundSyncEvent.Shutdown();
thread = NULL;
} }
void OpenALStream::Update() void OpenALStream::Update()
@ -97,6 +108,8 @@ void OpenALStream::Update()
void OpenALStream::Clear(bool mute) void OpenALStream::Clear(bool mute)
{ {
m_muted = mute; m_muted = mute;
soundCriticalSection.Enter();
if(m_muted) if(m_muted)
{ {
alSourceStop(g_uiSource); alSourceStop(g_uiSource);
@ -105,6 +118,7 @@ void OpenALStream::Clear(bool mute)
{ {
alSourcePlay(g_uiSource); alSourcePlay(g_uiSource);
} }
soundCriticalSection.Leave();
} }
THREAD_RETURN OpenALStream::ThreadFunc(void* args) THREAD_RETURN OpenALStream::ThreadFunc(void* args)
@ -115,8 +129,8 @@ THREAD_RETURN OpenALStream::ThreadFunc(void* args)
void OpenALStream::SoundLoop() void OpenALStream::SoundLoop()
{ {
ALuint uiBuffers[AUDIO_NUMBUFFERS] = {0}; ALuint uiBuffers[AUDIO_NUMBUFFERS] = {0};
ALuint uiSource = 0; ALuint uiSource = 0;
ALenum err; ALenum err;
u32 ulFrequency = m_mixer->GetSampleRate(); u32 ulFrequency = m_mixer->GetSampleRate();
// Generate some AL Buffers for streaming // Generate some AL Buffers for streaming
@ -135,19 +149,19 @@ void OpenALStream::SoundLoop()
//*/ //*/
g_uiSource = uiSource; g_uiSource = uiSource;
g_uiBuffers = (ALuint *)uiBuffers;
alSourcePlay(uiSource); alSourcePlay(uiSource);
err = alGetError(); err = alGetError();
while (!threadData) while (!threadData)
{ {
soundCriticalSection.Enter();
int numBytesToRender = 32768; //ya, this is a hack, we need real data count int numBytesToRender = 32768; //ya, this is a hack, we need real data count
/*int numBytesRender =*/ m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2); /*int numBytesRender =*/ m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2);
soundCriticalSection.Leave();
//if (numBytesRender) //here need debug //if (numBytesRender) //here need debug
{ {
soundCriticalSection.Enter();
ALint iBuffersProcessed = 0; ALint iBuffersProcessed = 0;
alGetSourcei(uiSource, AL_BUFFERS_PROCESSED, &iBuffersProcessed); alGetSourcei(uiSource, AL_BUFFERS_PROCESSED, &iBuffersProcessed);
@ -170,18 +184,11 @@ void OpenALStream::SoundLoop()
} }
alSourceQueueBuffers(uiSource, 1, &uiTempBuffer); alSourceQueueBuffers(uiSource, 1, &uiTempBuffer);
} }
soundCriticalSection.Leave();
} }
if (!threadData) soundSyncEvent.Wait();
soundSyncEvent.Wait();
} }
alSourceStop(uiSource);
alSourcei(uiSource, AL_BUFFER, 0);
// Clean up buffers and sources
alDeleteSources(1, &uiSource);
alDeleteBuffers(AUDIO_NUMBUFFERS, (ALuint *)uiBuffers);
} }
#endif //HAVE_OPENAL #endif //HAVE_OPENAL

View File

@ -61,7 +61,8 @@ private:
Common::Event soundSyncEvent; Common::Event soundSyncEvent;
short realtimeBuffer[OAL_BUFFER_SIZE]; short realtimeBuffer[OAL_BUFFER_SIZE];
ALuint g_uiSource; ALuint g_uiSource;
ALuint *g_uiBuffers;
#else #else
public: public:
OpenALStream(CMixer *mixer, void *hWnd = NULL): SoundStream(mixer) {} OpenALStream(CMixer *mixer, void *hWnd = NULL): SoundStream(mixer) {}