all repos — mgba @ 45501658b5b9492996141149ade4ad29aa14ffd4

mGBA Game Boy Advance Emulator

Sync to audio by default
Jeffrey Pfau jeffrey@endrift.com
Sat, 05 Oct 2013 02:52:57 -0700
commit

45501658b5b9492996141149ade4ad29aa14ffd4

parent

4ef6a70731ab6d4602d7b2ae5a42b26565055513

M src/gba/gba-audio.csrc/gba/gba-audio.c

@@ -2,8 +2,9 @@ #include "gba-audio.h"

#include "gba.h" #include "gba-io.h" +#include "gba-thread.h" -const unsigned GBA_AUDIO_SAMPLES = 1024; +const unsigned GBA_AUDIO_SAMPLES = 512; const unsigned GBA_AUDIO_FIFO_SIZE = 8 * sizeof(int32_t); static void _sample(struct GBAAudio* audio);

@@ -176,6 +177,9 @@ sampleRight += audio->chB.sample;

} pthread_mutex_lock(&audio->bufferMutex); + while (CircleBufferSize(&audio->left) + (GBA_AUDIO_SAMPLES * 2 / 5) >= audio->left.capacity) { + GBASyncProduceAudio(audio->p->sync, &audio->bufferMutex); + } CircleBufferWrite32(&audio->left, sampleLeft); CircleBufferWrite32(&audio->right, sampleRight); pthread_mutex_unlock(&audio->bufferMutex);
M src/gba/gba-thread.csrc/gba/gba-thread.c

@@ -92,6 +92,8 @@

pthread_mutex_init(&threadContext->sync.videoFrameMutex, 0); pthread_cond_init(&threadContext->sync.videoFrameAvailableCond, 0); pthread_cond_init(&threadContext->sync.videoFrameRequiredCond, 0); + pthread_cond_init(&threadContext->sync.audioAvailableCond, 0); + pthread_cond_init(&threadContext->sync.audioRequiredCond, 0); pthread_mutex_lock(&threadContext->startMutex); threadContext->activeKeys = 0;

@@ -119,6 +121,11 @@ pthread_cond_broadcast(&threadContext->sync.videoFrameAvailableCond);

pthread_cond_destroy(&threadContext->sync.videoFrameAvailableCond); pthread_cond_broadcast(&threadContext->sync.videoFrameRequiredCond); pthread_cond_destroy(&threadContext->sync.videoFrameRequiredCond); + + pthread_cond_broadcast(&threadContext->sync.audioAvailableCond); + pthread_cond_destroy(&threadContext->sync.audioAvailableCond); + pthread_cond_broadcast(&threadContext->sync.audioRequiredCond); + pthread_cond_destroy(&threadContext->sync.audioRequiredCond); } struct GBAThread* GBAThreadGetContext(void) {

@@ -163,3 +170,14 @@

int GBASyncDrawingFrame(struct GBASync* sync) { return sync->videoFrameSkip <= 0; } + +void GBASyncProduceAudio(struct GBASync* sync, pthread_mutex_t* mutex) { + pthread_cond_broadcast(&sync->audioAvailableCond); + if (&sync->audioWait) { + pthread_cond_wait(&sync->audioRequiredCond, mutex); + } +} + +void GBASyncConsumeAudio(struct GBASync* sync) { + pthread_cond_broadcast(&sync->audioRequiredCond); +}
M src/gba/gba-thread.hsrc/gba/gba-thread.h

@@ -30,6 +30,10 @@ int videoFrameSkip;

pthread_mutex_t videoFrameMutex; pthread_cond_t videoFrameAvailableCond; pthread_cond_t videoFrameRequiredCond; + + int audioWait; + pthread_cond_t audioAvailableCond; + pthread_cond_t audioRequiredCond; } sync; };

@@ -41,5 +45,8 @@ void GBASyncPostFrame(struct GBASync* sync);

void GBASyncWaitFrameStart(struct GBASync* sync, int frameskip); void GBASyncWaitFrameEnd(struct GBASync* sync); int GBASyncDrawingFrame(struct GBASync* sync); + +void GBASyncProduceAudio(struct GBASync* sync, pthread_mutex_t* mutex); +void GBASyncConsumeAudio(struct GBASync* sync); #endif
M src/gl-main.csrc/gl-main.c

@@ -72,6 +72,8 @@ context.fname = fname;

context.useDebugger = 1; context.renderer = &renderer.d.d; context.frameskip = 0; + context.sync.videoFrameWait = 0; + context.sync.audioWait = 1; GBAThreadStart(&context); renderer.audio.audio = &context.gba->audio;
M src/sdl/sdl-audio.csrc/sdl/sdl-audio.c

@@ -1,6 +1,7 @@

#include "sdl-audio.h" #include "gba.h" +#include "gba-thread.h" static void _GBASDLAudioCallback(void* context, Uint8* data, int len);

@@ -67,6 +68,7 @@ audioContext->drift -= 1.f;

} ssamples[i] = audioContext->currentSample; } + GBASyncConsumeAudio(audioContext->audio->p->sync); pthread_mutex_unlock(&audioContext->audio->bufferMutex); } }
M src/sdl/sdl-events.csrc/sdl/sdl-events.c

@@ -52,7 +52,7 @@ case SDLK_RIGHT:

key = GBA_KEY_RIGHT; break; case SDLK_TAB: - context->sync.videoFrameWait = !context->sync.videoFrameWait; + context->sync.audioWait = !context->sync.audioWait; return; default: return;