GBA Serialize: Fix audio serialization for desynced FIFOs
Vicki Pfau vi@endrift.com
Fri, 24 Jan 2020 21:51:15 -0800
3 files changed,
21 insertions(+),
8 deletions(-)
M
CHANGES
→
CHANGES
@@ -5,6 +5,7 @@ - ARM: Fix STR storing PC after address calculation
- GBA DMA: Linger last DMA on bus (fixes mgba.io/i/301 and mgba.io/i/1320) - GBA Memory: Misaligned SRAM writes are ignored - GBA Serialize: Fix serializing DMA transfer register + - GBA Serialize: Fix audio serialization for desynced FIFOs Other fixes: - Qt: Only dynamically reset video scale if a game is running - Qt: Fix race condition with proxied video events
M
include/mgba/internal/gba/serialize.h
→
include/mgba/internal/gba/serialize.h
@@ -66,9 +66,10 @@ * | 0x00188 - 0x0018B: Next event
* 0x0018C - 0x001AB: Audio FIFO 1 * 0x001AC - 0x001CB: Audio FIFO 2 * 0x001CC - 0x001DF: Audio miscellaneous state - * | 0x001CC - 0x001D3: Reserved + * | 0x001CC - 0x001CF: FIFO 1 size + * | 0x001D0 - 0x001D3: Reserved * | 0x001D4 - 0x001D7: Next sample - * | 0x001D8 - 0x001DB: FIFO size + * | 0x001D8 - 0x001DB: FIFO 2 size * | TODO: Fix this, they're in big-endian order, but field is little-endian * | 0x001DC - 0x001DC: Channel 1 envelope state * | bits 0 - 3: Current volume@@ -170,7 +171,8 @@ * | bits 4 - 8: GB Player transmit position
* | bits 9 - 23: Reserved * 0x002C4 - 0x002C7: Game Boy Player next event * 0x002C8 - 0x002CB: Current DMA transfer word - * 0x002CC - 0x002DF: Reserved (leave zero) + * 0x002CC - 0x002CF: Last DMA transfer PC + * 0x002D0 - 0x002DF: Reserved (leave zero) * 0x002E0 - 0x002EF: Savedata state * | 0x002E0 - 0x002E0: Savedata type * | 0x002E1 - 0x002E1: Savedata command (see savedata.h)@@ -256,9 +258,10 @@ struct {
struct GBSerializedPSGState psg; uint8_t fifoA[32]; uint8_t fifoB[32]; - int32_t reserved[2]; + uint32_t fifoSizeA; + int32_t reserved; int32_t nextSample; - uint32_t fifoSize; + uint32_t fifoSizeB; GBSerializedAudioFlags flags; } audio;
M
src/gba/audio.c
→
src/gba/audio.c
@@ -348,7 +348,9 @@
CircleBufferDump(&audio->chA.fifo, state->audio.fifoA, sizeof(state->audio.fifoA)); CircleBufferDump(&audio->chB.fifo, state->audio.fifoB, sizeof(state->audio.fifoB)); uint32_t fifoSize = CircleBufferSize(&audio->chA.fifo); - STORE_32(fifoSize, 0, &state->audio.fifoSize); + STORE_32(fifoSize, 0, &state->audio.fifoSizeA); + fifoSize = CircleBufferSize(&audio->chB.fifo); + STORE_32(fifoSize, 0, &state->audio.fifoSizeB); STORE_32(audio->sampleEvent.when - mTimingCurrentTime(&audio->p->timing), 0, &state->audio.nextSample); }@@ -358,13 +360,20 @@
CircleBufferClear(&audio->chA.fifo); CircleBufferClear(&audio->chB.fifo); uint32_t fifoSize; - LOAD_32(fifoSize, 0, &state->audio.fifoSize); - if (state->audio.fifoSize > CircleBufferCapacity(&audio->chA.fifo)) { + LOAD_32(fifoSize, 0, &state->audio.fifoSizeA); + if (fifoSize > CircleBufferCapacity(&audio->chA.fifo)) { fifoSize = CircleBufferCapacity(&audio->chA.fifo); } size_t i; for (i = 0; i < fifoSize; ++i) { CircleBufferWrite8(&audio->chA.fifo, state->audio.fifoA[i]); + } + + LOAD_32(fifoSize, 0, &state->audio.fifoSizeB); + if (fifoSize > CircleBufferCapacity(&audio->chB.fifo)) { + fifoSize = CircleBufferCapacity(&audio->chB.fifo); + } + for (i = 0; i < fifoSize; ++i) { CircleBufferWrite8(&audio->chB.fifo, state->audio.fifoB[i]); }