Ability to resize internal sound buffers

This commit is contained in:
Jeffrey Pfau 2014-07-21 00:14:48 -07:00
parent 10fc916425
commit e527220398
5 changed files with 53 additions and 6 deletions

View File

@ -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);
}
@ -70,6 +70,40 @@ void GBAAudioDeinit(struct GBAAudio* audio) {
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) {
audio->nextEvent -= cycles;
audio->eventDiff += cycles;
@ -670,7 +704,7 @@ static void _sample(struct GBAAudio* audio) {
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) {

View File

@ -218,10 +218,12 @@ struct GBAStereoSample {
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);

View File

@ -86,6 +86,11 @@ static THREAD_ENTRY _GBAThreadRun(void* context) {
#else
TlsSetValue(_contextKey, threadContext);
#endif
if (threadContext->audioBuffers) {
GBAAudioResizeBuffer(&gba.audio, threadContext->audioBuffers);
}
if (threadContext->renderer) {
GBAVideoAssociateRenderer(&gba.video, threadContext->renderer);
}
@ -551,6 +556,10 @@ void GBASyncLockAudio(struct GBASync* sync) {
MutexLock(&sync->audioBufferMutex);
}
void GBASyncUnlockAudio(struct GBASync* sync) {
MutexUnlock(&sync->audioBufferMutex);
}
void GBASyncConsumeAudio(struct GBASync* sync) {
ConditionWake(&sync->audioRequiredCond);
MutexUnlock(&sync->audioBufferMutex);

View File

@ -57,6 +57,7 @@ struct GBAThread {
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

View File

@ -121,7 +121,7 @@ static void GBAInit(struct ARMCore* cpu, struct ARMComponent* component) {
GBAVideoInit(&gba->video);
gba->audio.p = gba;
GBAAudioInit(&gba->audio);
GBAAudioInit(&gba->audio, GBA_AUDIO_SAMPLES);
GBAIOInit(gba);