Ability to resize internal sound buffers
Jeffrey Pfau jeffrey@endrift.com
Mon, 21 Jul 2014 00:14:48 -0700
5 files changed,
53 insertions(+),
6 deletions(-)
M
src/gba/gba-audio.c
→
src/gba/gba-audio.c
@@ -20,9 +20,9 @@ static int32_t _updateChannel4(struct GBAAudioChannel4* ch);
static int _applyBias(struct GBAAudio* audio, int sample); static void _sample(struct GBAAudio* audio); -void GBAAudioInit(struct GBAAudio* audio) { - CircleBufferInit(&audio->left, GBA_AUDIO_SAMPLES * sizeof(int32_t)); - CircleBufferInit(&audio->right, GBA_AUDIO_SAMPLES * sizeof(int32_t)); +void GBAAudioInit(struct GBAAudio* audio, size_t samples) { + CircleBufferInit(&audio->left, samples * sizeof(int32_t)); + CircleBufferInit(&audio->right, samples * sizeof(int32_t)); CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE); CircleBufferInit(&audio->chB.fifo, GBA_AUDIO_FIFO_SIZE); }@@ -68,6 +68,40 @@ CircleBufferDeinit(&audio->left);
CircleBufferDeinit(&audio->right); CircleBufferDeinit(&audio->chA.fifo); CircleBufferDeinit(&audio->chB.fifo); +} + +void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples) { + if (samples >= GBA_AUDIO_SAMPLES) { + return; + } + + GBASyncLockAudio(audio->p->sync); + int32_t buffer[GBA_AUDIO_SAMPLES]; + int32_t dummy; + size_t read; + size_t i; + + read = CircleBufferDump(&audio->left, buffer, sizeof(buffer)); + CircleBufferDeinit(&audio->left); + CircleBufferInit(&audio->left, samples * sizeof(int32_t)); + for (i = 0; i * sizeof(int32_t) < read; ++i) { + if (!CircleBufferWrite32(&audio->left, buffer[i])) { + CircleBufferRead32(&audio->left, &dummy); + CircleBufferWrite32(&audio->left, buffer[i]); + } + } + + read = CircleBufferDump(&audio->right, buffer, sizeof(buffer)); + CircleBufferDeinit(&audio->right); + CircleBufferInit(&audio->right, samples * sizeof(int32_t)); + for (i = 0; i * sizeof(int32_t) < read; ++i) { + if (!CircleBufferWrite32(&audio->right, buffer[i])) { + CircleBufferRead32(&audio->right, &dummy); + CircleBufferWrite32(&audio->right, buffer[i]); + } + } + + GBASyncUnlockAudio(audio->p->sync); } int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles) {@@ -670,7 +704,7 @@ GBASyncLockAudio(audio->p->sync);
CircleBufferWrite32(&audio->left, sampleLeft); CircleBufferWrite32(&audio->right, sampleRight); unsigned produced = CircleBufferSize(&audio->left); - GBASyncProduceAudio(audio->p->sync, produced >= GBA_AUDIO_SAMPLES * 3); + GBASyncProduceAudio(audio->p->sync, produced >= CircleBufferCapacity(&audio->left) / sizeof(int32_t) * 3); } void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state) {
M
src/gba/gba-audio.h
→
src/gba/gba-audio.h
@@ -218,9 +218,11 @@ int16_t left;
int16_t right; }; -void GBAAudioInit(struct GBAAudio* audio); +void GBAAudioInit(struct GBAAudio* audio, size_t samples); void GBAAudioReset(struct GBAAudio* audio); void GBAAudioDeinit(struct GBAAudio* audio); + +void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples); int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles); void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info);
M
src/gba/gba-thread.c
→
src/gba/gba-thread.c
@@ -86,6 +86,11 @@ pthread_setspecific(_contextKey, threadContext);
#else TlsSetValue(_contextKey, threadContext); #endif + + if (threadContext->audioBuffers) { + GBAAudioResizeBuffer(&gba.audio, threadContext->audioBuffers); + } + if (threadContext->renderer) { GBAVideoAssociateRenderer(&gba.video, threadContext->renderer); }@@ -549,6 +554,10 @@ }
void GBASyncLockAudio(struct GBASync* sync) { MutexLock(&sync->audioBufferMutex); +} + +void GBASyncUnlockAudio(struct GBASync* sync) { + MutexUnlock(&sync->audioBufferMutex); } void GBASyncConsumeAudio(struct GBASync* sync) {
M
src/gba/gba-thread.h
→
src/gba/gba-thread.h
@@ -57,6 +57,7 @@ const char* fname;
int activeKeys; int frameskip; float fpsTarget; + size_t audioBuffers; // Threading state Thread thread;@@ -106,6 +107,7 @@ bool GBASyncDrawingFrame(struct GBASync* sync);
void GBASyncProduceAudio(struct GBASync* sync, int wait); void GBASyncLockAudio(struct GBASync* sync); +void GBASyncUnlockAudio(struct GBASync* sync); void GBASyncConsumeAudio(struct GBASync* sync); #endif
M
src/gba/gba.c
→
src/gba/gba.c
@@ -121,7 +121,7 @@ gba->video.p = gba;
GBAVideoInit(&gba->video); gba->audio.p = gba; - GBAAudioInit(&gba->audio); + GBAAudioInit(&gba->audio, GBA_AUDIO_SAMPLES); GBAIOInit(gba);