SPU: Force all voices off when SPUCNT.15=0
This commit is contained in:
parent
8c6cb877eb
commit
8605620c24
|
@ -439,6 +439,14 @@ void SPU::WriteRegister(u32 offset, u16 value)
|
||||||
m_transfer_fifo.Clear();
|
m_transfer_fifo.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!new_value.enable && m_SPUCNT.enable)
|
||||||
|
{
|
||||||
|
// Mute all voices.
|
||||||
|
// Interestingly, hardware tests found this seems to happen immediately, not on the next 44100hz cycle.
|
||||||
|
for (u32 i = 0; i < NUM_VOICES; i++)
|
||||||
|
m_voices[i].ForceOff();
|
||||||
|
}
|
||||||
|
|
||||||
m_SPUCNT.bits = new_value.bits;
|
m_SPUCNT.bits = new_value.bits;
|
||||||
m_SPUSTAT.mode = m_SPUCNT.mode.GetValue();
|
m_SPUSTAT.mode = m_SPUCNT.mode.GetValue();
|
||||||
|
|
||||||
|
@ -1047,6 +1055,15 @@ void SPU::Voice::KeyOff()
|
||||||
SetADSRPhase(ADSRPhase::Release);
|
SetADSRPhase(ADSRPhase::Release);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SPU::Voice::ForceOff()
|
||||||
|
{
|
||||||
|
if (adsr_phase == ADSRPhase::Off)
|
||||||
|
return;
|
||||||
|
|
||||||
|
regs.adsr_volume = 0;
|
||||||
|
SetADSRPhase(ADSRPhase::Off);
|
||||||
|
}
|
||||||
|
|
||||||
SPU::ADSRPhase SPU::GetNextADSRPhase(ADSRPhase phase)
|
SPU::ADSRPhase SPU::GetNextADSRPhase(ADSRPhase phase)
|
||||||
{
|
{
|
||||||
switch (phase)
|
switch (phase)
|
||||||
|
@ -1461,8 +1478,7 @@ std::tuple<s32, s32> SPU::SampleVoice(u32 voice_index)
|
||||||
{
|
{
|
||||||
Log_TracePrintf("Voice %u loop end+mute @ 0x%08X", voice_index, ZeroExtend32(voice.current_address));
|
Log_TracePrintf("Voice %u loop end+mute @ 0x%08X", voice_index, ZeroExtend32(voice.current_address));
|
||||||
m_endx_register |= (u32(1) << voice_index);
|
m_endx_register |= (u32(1) << voice_index);
|
||||||
voice.regs.adsr_volume = 0;
|
voice.ForceOff();
|
||||||
voice.SetADSRPhase(ADSRPhase::Off);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -270,6 +270,7 @@ private:
|
||||||
|
|
||||||
void KeyOn();
|
void KeyOn();
|
||||||
void KeyOff();
|
void KeyOff();
|
||||||
|
void ForceOff();
|
||||||
|
|
||||||
void DecodeBlock(const ADPCMBlock& block);
|
void DecodeBlock(const ADPCMBlock& block);
|
||||||
s16 SampleBlock(s32 index) const;
|
s16 SampleBlock(s32 index) const;
|
||||||
|
|
Loading…
Reference in New Issue