diff --git a/CHANGES b/CHANGES index 06bae47db..eff4d6570 100644 --- a/CHANGES +++ b/CHANGES @@ -40,6 +40,8 @@ Emulation fixes: - GB Memory: Better emulate 0xFEA0 region on DMG, MGB and AGB - GB Printer: Reset printer buffer index after printing - GB Video: Fix mode 0 window edge case (fixes mgba.io/i/1519) + - GBA Audio: Fix channel 4 aliasing (fixes mgba.io/i/1265) + - GB Audio: Improve channel 4 supersampling Other fixes: - Qt: Fix some Qt display driver race conditions - Core: Improved lockstep driver reliability (Le Hoang Quyen) diff --git a/src/gb/audio.c b/src/gb/audio.c index 666ab42b8..b36cc3776 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -37,7 +37,7 @@ static bool _updateSweep(struct GBAudioSquareChannel* sweep, bool initial); static void _updateSquareSample(struct GBAudioSquareChannel* ch); static int32_t _updateSquareChannel(struct GBAudioSquareChannel* ch); -static int8_t _coalesceNoiseChannel(struct GBAudioNoiseChannel* ch); +static int16_t _coalesceNoiseChannel(struct GBAudioNoiseChannel* ch); static void _updateFrame(struct mTiming* timing, void* user, uint32_t cyclesLate); static void _updateChannel1(struct mTiming* timing, void* user, uint32_t cyclesLate); @@ -632,8 +632,11 @@ void GBAudioSamplePSG(struct GBAudio* audio, int16_t* left, int16_t* right) { } } + sampleLeft <<= 3; + sampleRight <<= 3; + if (!audio->forceDisableCh[3]) { - int8_t sample = _coalesceNoiseChannel(&audio->ch4); + int16_t sample = audio->style == GB_AUDIO_GBA ? (audio->ch4.sample << 3) : _coalesceNoiseChannel(&audio->ch4); if (audio->ch4Left) { sampleLeft += sample; } @@ -643,9 +646,6 @@ void GBAudioSamplePSG(struct GBAudio* audio, int16_t* left, int16_t* right) { } } - sampleLeft <<= 3; - sampleRight <<= 3; - *left = sampleLeft * (1 + audio->volumeLeft); *right = sampleRight * (1 + audio->volumeRight); } @@ -768,12 +768,12 @@ static int32_t _updateSquareChannel(struct GBAudioSquareChannel* ch) { } } -static int8_t _coalesceNoiseChannel(struct GBAudioNoiseChannel* ch) { +static int16_t _coalesceNoiseChannel(struct GBAudioNoiseChannel* ch) { if (!ch->nSamples) { return ch->sample; } // TODO keep track of timing - int8_t sample = ch->samples / ch->nSamples; + int16_t sample = (ch->samples << 3) / ch->nSamples; ch->nSamples = 0; ch->samples = 0; return sample;