From 08ad5aad5322c8ebd1d68330408a4f979b4df474 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Fri, 27 Mar 2020 01:42:43 +1000 Subject: [PATCH] SPU: Run muted voices when IRQ is enabled Fixes SPU timeout in Casper. We can still optimize for most games where interrupts are not used by completely ignoring muted voices in those. --- src/core/spu.cpp | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/core/spu.cpp b/src/core/spu.cpp index d8ba9104e..7dfd67120 100644 --- a/src/core/spu.cpp +++ b/src/core/spu.cpp @@ -1225,7 +1225,7 @@ void SPU::ReadADPCMBlock(u16 address, ADPCMBlock* block) std::tuple SPU::SampleVoice(u32 voice_index) { Voice& voice = m_voices[voice_index]; - if (!voice.IsOn()) + if (!voice.IsOn() && !m_SPUCNT.irq9_enable) { voice.last_volume = 0; return {}; @@ -1245,18 +1245,28 @@ std::tuple SPU::SampleVoice(u32 voice_index) } } - // interpolate/sample and apply ADSR volume - s16 sample; - if (IsVoiceNoiseEnabled(voice_index)) - sample = GetVoiceNoiseLevel(); - else - sample = voice.Interpolate(); + // skip interpolation when the volume is muted anyway + s32 volume; + if (voice.regs.adsr_volume != 0) + { + // interpolate/sample and apply ADSR volume + s16 sample; + if (IsVoiceNoiseEnabled(voice_index)) + sample = GetVoiceNoiseLevel(); + else + sample = voice.Interpolate(); + + volume = ApplyVolume(sample, voice.regs.adsr_volume); + } + else + { + volume = 0; + } - const s32 volume = ApplyVolume(sample, voice.regs.adsr_volume); - // if (voice_index == 3 || voice_index == 4) - // Log_WarningPrintf("voice %u %d", voice_index, volume); voice.last_volume = volume; - voice.TickADSR(); + + if (voice.adsr_phase != ADSRPhase::Off) + voice.TickADSR(); // Pitch modulation u16 step = voice.regs.adpcm_sample_rate;