diff --git a/CHANGES b/CHANGES index 1a5b76075..0a1020f42 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,7 @@ Emulation fixes: - GB Audio: Fix channels 1/2 staying muted if restarted after long silence - GB I/O: Read back proper SVBK value after writing 0 (fixes mgba.io/i/2921) - GB SIO: Disabling SIO should cancel pending transfers (fixes mgba.io/i/2537) + - GBA Audio: Fix sample timing drifting when changing sample interval - GBA BIOS: Fix clobbering registers with word-sized CpuSet Other fixes: - mGUI: Fix cases where an older save state screenshot would be shown (fixes mgba.io/i/2183) diff --git a/src/gba/audio.c b/src/gba/audio.c index f6e13d5c0..08e188184 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -253,11 +253,16 @@ void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) { } void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value) { + GBAAudioSample(audio, mTimingCurrentTime(&audio->p->timing)); audio->soundbias = value; int32_t oldSampleInterval = audio->sampleInterval; audio->sampleInterval = 0x200 >> GBARegisterSOUNDBIASGetResolution(value); - if (oldSampleInterval != audio->sampleInterval && audio->p->stream && audio->p->stream->audioRateChanged) { - audio->p->stream->audioRateChanged(audio->p->stream, GBA_ARM7TDMI_FREQUENCY / audio->sampleInterval); + if (oldSampleInterval != audio->sampleInterval) { + audio->lastSample += oldSampleInterval * audio->sampleIndex; + audio->sampleIndex = 0; + if (audio->p->stream && audio->p->stream->audioRateChanged) { + audio->p->stream->audioRateChanged(audio->p->stream, GBA_ARM7TDMI_FREQUENCY / audio->sampleInterval); + } } }