From d9f13c57c0b107d9570d04bef4789c74acdeb8ae Mon Sep 17 00:00:00 2001 From: rogerman Date: Mon, 9 Jul 2012 23:58:05 +0000 Subject: [PATCH] Cocoa Port: - Make sound processing thread-safe. Fixes bug #3538263. < http://sourceforge.net/tracker/?func=detail&aid=3538263&group_id=164579&atid=832291 > --- desmume/src/cocoa/cocoa_output.mm | 3 ++ desmume/src/cocoa/sndOSX.cpp | 62 ++++++++++++++++++++++++++++++- desmume/src/cocoa/sndOSX.h | 7 +++- 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/desmume/src/cocoa/cocoa_output.mm b/desmume/src/cocoa/cocoa_output.mm index 275764cc8..12ff0f34f 100644 --- a/desmume/src/cocoa/cocoa_output.mm +++ b/desmume/src/cocoa/cocoa_output.mm @@ -20,6 +20,7 @@ #import "cocoa_globals.h" #import "cocoa_videofilter.h" #import "cocoa_util.h" +#include "sndOSX.h" #include @@ -214,6 +215,8 @@ GPU3DInterface *core3DList[] = { SPU_ChangeSoundCore(SNDCORE_DUMMY, 0); } + mutexAudioEmulateCore = self.mutexProducer; + pthread_mutex_unlock(self.mutexProducer); // Force the volume back to it's original setting. diff --git a/desmume/src/cocoa/sndOSX.cpp b/desmume/src/cocoa/sndOSX.cpp index b1e97e036..20c017ebc 100644 --- a/desmume/src/cocoa/sndOSX.cpp +++ b/desmume/src/cocoa/sndOSX.cpp @@ -24,6 +24,8 @@ // Global sound playback manager static CoreAudioSound *coreAudioPlaybackManager = NULL; +static pthread_mutex_t *mutexAudioSampleReadWrite = NULL; +pthread_mutex_t *mutexAudioEmulateCore = NULL; // Sound interface to the SPU SoundInterface_struct SNDOSX = { @@ -36,7 +38,9 @@ SoundInterface_struct SNDOSX = { SNDOSXMuteAudio, SNDOSXUnMuteAudio, SNDOSXSetVolume, - SNDOSXClearBuffer + SNDOSXClearBuffer, + SNDOSXFetchSamples, + SNDOSXPostProcessSamples }; SoundInterface_struct *SNDCoreList[] = { @@ -58,6 +62,12 @@ int SNDOSXInit(int buffer_size) coreAudioPlaybackManager = new CoreAudioSound(buffer_size / SPU_SAMPLE_SIZE, SPU_SAMPLE_SIZE); } + if (mutexAudioSampleReadWrite == NULL) + { + mutexAudioSampleReadWrite = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); + pthread_mutex_init(mutexAudioSampleReadWrite, NULL); + } + coreAudioPlaybackManager->start(); return 0; @@ -67,6 +77,13 @@ void SNDOSXDeInit() { delete coreAudioPlaybackManager; coreAudioPlaybackManager = NULL; + + if (mutexAudioSampleReadWrite != NULL) + { + pthread_mutex_destroy(mutexAudioSampleReadWrite); + free(mutexAudioSampleReadWrite); + mutexAudioSampleReadWrite = NULL; + } } int SNDOSXReset() @@ -138,3 +155,46 @@ void SNDOSXClearBuffer() coreAudioPlaybackManager->clearBuffer(); } } + +void SNDOSXFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) +{ + if (mutexAudioSampleReadWrite == NULL) + { + return; + } + + pthread_mutex_lock(mutexAudioSampleReadWrite); + SPU_DefaultFetchSamples(sampleBuffer, sampleCount, synchMode, theSynchronizer); + pthread_mutex_unlock(mutexAudioSampleReadWrite); +} + +size_t SNDOSXPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) +{ + size_t processedSampleCount = 0; + + switch (synchMode) + { + case ESynchMode_DualSynchAsynch: + if (mutexAudioEmulateCore != NULL) + { + pthread_mutex_lock(mutexAudioEmulateCore); + processedSampleCount = SPU_DefaultPostProcessSamples(postProcessBuffer, requestedSampleCount, synchMode, theSynchronizer); + pthread_mutex_unlock(mutexAudioEmulateCore); + } + break; + + case ESynchMode_Synchronous: + if (mutexAudioSampleReadWrite != NULL) + { + pthread_mutex_lock(mutexAudioSampleReadWrite); + processedSampleCount = SPU_DefaultPostProcessSamples(postProcessBuffer, requestedSampleCount, synchMode, theSynchronizer); + pthread_mutex_unlock(mutexAudioSampleReadWrite); + } + break; + + default: + break; + } + + return processedSampleCount; +} diff --git a/desmume/src/cocoa/sndOSX.h b/desmume/src/cocoa/sndOSX.h index 3b2d9758c..31cfe1812 100644 --- a/desmume/src/cocoa/sndOSX.h +++ b/desmume/src/cocoa/sndOSX.h @@ -19,12 +19,13 @@ #ifndef _OSXSOUNDINTERFACE_ #define _OSXSOUNDINTERFACE_ +#include #include "../SPU.h" #define SNDCORE_OSX 58325 //hopefully this is unique number -// Sound interface to the SPU -extern SoundInterface_struct SNDOSX; +extern SoundInterface_struct SNDOSX; // Sound interface to the SPU +extern pthread_mutex_t *mutexAudioEmulateCore; // Mutex for the emulation core - used when mixing audio in Dual Synch/Asynch mode in post-process // Core Audio functions for the sound interface int SNDOSXInit(int buffer_size); @@ -36,5 +37,7 @@ void SNDOSXMuteAudio(); void SNDOSXUnMuteAudio(); void SNDOSXSetVolume(int volume); void SNDOSXClearBuffer(); +void SNDOSXFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer); +size_t SNDOSXPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer); #endif // _OSXSOUNDINTERFACE_