From 3035f43428b15dbc75dff150646dd97425f91ec4 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Fri, 19 Oct 2018 23:53:01 +0300 Subject: [PATCH] Emulation of DAC charging, Fixes #46, #85, #88 and #89 --- Core/apu.c | 24 +++++++++++++++--------- Core/apu.h | 9 +++++++-- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/Core/apu.c b/Core/apu.c index 6041c25e..1bdc2750 100644 --- a/Core/apu.c +++ b/Core/apu.c @@ -75,9 +75,19 @@ static void render(GB_gameboy_t *gb, bool no_downsampling, GB_sample_t *dest) gb->apu_output.dac_discharge[i] -= ((double) DAC_DECAY_SPEED) / gb->apu_output.sample_rate; if (gb->apu_output.dac_discharge[i] < 0) { multiplier = 0; + gb->apu_output.dac_discharge[i] = 0; } else { - multiplier *= pow(0.05, 1 - gb->apu_output.dac_discharge[i]) * (gb->apu_output.dac_discharge[i]); + multiplier *= gb->apu_output.dac_discharge[i]; + } + } + else { + gb->apu_output.dac_discharge[i] += ((double) DAC_ATTACK_SPEED) / gb->apu_output.sample_rate; + if (gb->apu_output.dac_discharge[i] > 1) { + gb->apu_output.dac_discharge[i] = 1; + } + else { + multiplier *= gb->apu_output.dac_discharge[i]; } } @@ -797,9 +807,10 @@ void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value) gb->apu.wave_channel.length_enabled = false; } /* Note that we don't change the sample just yet! This was verified on hardware. */ - /* Todo: The first sample *is not* skipped on the DMG, this is a bug introduced - on the CGB. It appears that the bug was fixed on the AGB, but it's not reflected - by PCM434. */ + /* Todo: The first sample might *not* beskipped on the DMG, this could be a bug + introduced on the CGB. It appears that the bug was fixed on the AGB, but it's + not reflected by PCM34. This should be probably verified as this could just + mean differences in the DACs. */ /* Todo: Similar issues may apply to the other channels on the DMG/AGB, test, verify and fix if needed */ } @@ -939,11 +950,6 @@ void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value) } } gb->io_registers[reg] = value; - for (unsigned i = 0; i < GB_N_CHANNELS; i++) { - if (is_DAC_enabled(gb, i)) { - gb->apu_output.dac_discharge[i] = 1.0; - } - } } size_t GB_apu_get_current_buffer_length(GB_gameboy_t *gb) diff --git a/Core/apu.h b/Core/apu.h index f6c456aa..baa56a43 100644 --- a/Core/apu.h +++ b/Core/apu.h @@ -8,8 +8,13 @@ #ifdef GB_INTERNAL /* Speed = 1 / Length (in seconds) */ -/* Todo: Measure this and find the actual curve shape*/ -#define DAC_DECAY_SPEED 50 +/* Todo: Measure these and find the actual curve shapes. + They are known to be incorrect (Some analog test ROM sound different), + but are good enough approximations to fix Cannon Fodder's terrible audio. + It also varies by model. */ +#define DAC_DECAY_SPEED (1000000) +#define DAC_ATTACK_SPEED 1000 + /* Divides nicely and never overflows with 4 channels and 8 (1-8) volume levels */ #ifdef WIIU