mirror of https://github.com/mgba-emu/mgba.git
Ability to resize internal sound buffers
This commit is contained in:
parent
10fc916425
commit
e527220398
|
@ -20,9 +20,9 @@ static int32_t _updateChannel4(struct GBAAudioChannel4* ch);
|
||||||
static int _applyBias(struct GBAAudio* audio, int sample);
|
static int _applyBias(struct GBAAudio* audio, int sample);
|
||||||
static void _sample(struct GBAAudio* audio);
|
static void _sample(struct GBAAudio* audio);
|
||||||
|
|
||||||
void GBAAudioInit(struct GBAAudio* audio) {
|
void GBAAudioInit(struct GBAAudio* audio, size_t samples) {
|
||||||
CircleBufferInit(&audio->left, GBA_AUDIO_SAMPLES * sizeof(int32_t));
|
CircleBufferInit(&audio->left, samples * sizeof(int32_t));
|
||||||
CircleBufferInit(&audio->right, GBA_AUDIO_SAMPLES * sizeof(int32_t));
|
CircleBufferInit(&audio->right, samples * sizeof(int32_t));
|
||||||
CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE);
|
CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE);
|
||||||
CircleBufferInit(&audio->chB.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);
|
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) {
|
int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles) {
|
||||||
audio->nextEvent -= cycles;
|
audio->nextEvent -= cycles;
|
||||||
audio->eventDiff += cycles;
|
audio->eventDiff += cycles;
|
||||||
|
@ -670,7 +704,7 @@ static void _sample(struct GBAAudio* audio) {
|
||||||
CircleBufferWrite32(&audio->left, sampleLeft);
|
CircleBufferWrite32(&audio->left, sampleLeft);
|
||||||
CircleBufferWrite32(&audio->right, sampleRight);
|
CircleBufferWrite32(&audio->right, sampleRight);
|
||||||
unsigned produced = CircleBufferSize(&audio->left);
|
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) {
|
void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state) {
|
||||||
|
|
|
@ -218,10 +218,12 @@ struct GBAStereoSample {
|
||||||
int16_t right;
|
int16_t right;
|
||||||
};
|
};
|
||||||
|
|
||||||
void GBAAudioInit(struct GBAAudio* audio);
|
void GBAAudioInit(struct GBAAudio* audio, size_t samples);
|
||||||
void GBAAudioReset(struct GBAAudio* audio);
|
void GBAAudioReset(struct GBAAudio* audio);
|
||||||
void GBAAudioDeinit(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);
|
int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles);
|
||||||
void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info);
|
void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info);
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,11 @@ static THREAD_ENTRY _GBAThreadRun(void* context) {
|
||||||
#else
|
#else
|
||||||
TlsSetValue(_contextKey, threadContext);
|
TlsSetValue(_contextKey, threadContext);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (threadContext->audioBuffers) {
|
||||||
|
GBAAudioResizeBuffer(&gba.audio, threadContext->audioBuffers);
|
||||||
|
}
|
||||||
|
|
||||||
if (threadContext->renderer) {
|
if (threadContext->renderer) {
|
||||||
GBAVideoAssociateRenderer(&gba.video, threadContext->renderer);
|
GBAVideoAssociateRenderer(&gba.video, threadContext->renderer);
|
||||||
}
|
}
|
||||||
|
@ -551,6 +556,10 @@ void GBASyncLockAudio(struct GBASync* sync) {
|
||||||
MutexLock(&sync->audioBufferMutex);
|
MutexLock(&sync->audioBufferMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GBASyncUnlockAudio(struct GBASync* sync) {
|
||||||
|
MutexUnlock(&sync->audioBufferMutex);
|
||||||
|
}
|
||||||
|
|
||||||
void GBASyncConsumeAudio(struct GBASync* sync) {
|
void GBASyncConsumeAudio(struct GBASync* sync) {
|
||||||
ConditionWake(&sync->audioRequiredCond);
|
ConditionWake(&sync->audioRequiredCond);
|
||||||
MutexUnlock(&sync->audioBufferMutex);
|
MutexUnlock(&sync->audioBufferMutex);
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct GBAThread {
|
||||||
int activeKeys;
|
int activeKeys;
|
||||||
int frameskip;
|
int frameskip;
|
||||||
float fpsTarget;
|
float fpsTarget;
|
||||||
|
size_t audioBuffers;
|
||||||
|
|
||||||
// Threading state
|
// Threading state
|
||||||
Thread thread;
|
Thread thread;
|
||||||
|
@ -106,6 +107,7 @@ bool GBASyncDrawingFrame(struct GBASync* sync);
|
||||||
|
|
||||||
void GBASyncProduceAudio(struct GBASync* sync, int wait);
|
void GBASyncProduceAudio(struct GBASync* sync, int wait);
|
||||||
void GBASyncLockAudio(struct GBASync* sync);
|
void GBASyncLockAudio(struct GBASync* sync);
|
||||||
|
void GBASyncUnlockAudio(struct GBASync* sync);
|
||||||
void GBASyncConsumeAudio(struct GBASync* sync);
|
void GBASyncConsumeAudio(struct GBASync* sync);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -121,7 +121,7 @@ static void GBAInit(struct ARMCore* cpu, struct ARMComponent* component) {
|
||||||
GBAVideoInit(&gba->video);
|
GBAVideoInit(&gba->video);
|
||||||
|
|
||||||
gba->audio.p = gba;
|
gba->audio.p = gba;
|
||||||
GBAAudioInit(&gba->audio);
|
GBAAudioInit(&gba->audio, GBA_AUDIO_SAMPLES);
|
||||||
|
|
||||||
GBAIOInit(gba);
|
GBAIOInit(gba);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue