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 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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue