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.
This commit is contained in:
Connor McLaughlin 2020-03-27 01:42:43 +10:00
parent 54abd37daa
commit 08ad5aad53

View file

@ -1225,7 +1225,7 @@ void SPU::ReadADPCMBlock(u16 address, ADPCMBlock* block)
std::tuple<s32, s32> SPU::SampleVoice(u32 voice_index) std::tuple<s32, s32> SPU::SampleVoice(u32 voice_index)
{ {
Voice& voice = m_voices[voice_index]; Voice& voice = m_voices[voice_index];
if (!voice.IsOn()) if (!voice.IsOn() && !m_SPUCNT.irq9_enable)
{ {
voice.last_volume = 0; voice.last_volume = 0;
return {}; return {};
@ -1245,18 +1245,28 @@ std::tuple<s32, s32> SPU::SampleVoice(u32 voice_index)
} }
} }
// interpolate/sample and apply ADSR volume // skip interpolation when the volume is muted anyway
s16 sample; s32 volume;
if (IsVoiceNoiseEnabled(voice_index)) if (voice.regs.adsr_volume != 0)
sample = GetVoiceNoiseLevel(); {
else // interpolate/sample and apply ADSR volume
sample = voice.Interpolate(); 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.last_volume = volume;
voice.TickADSR();
if (voice.adsr_phase != ADSRPhase::Off)
voice.TickADSR();
// Pitch modulation // Pitch modulation
u16 step = voice.regs.adpcm_sample_rate; u16 step = voice.regs.adpcm_sample_rate;