diff --git a/src/core/save_state_version.h b/src/core/save_state_version.h index faf4e0f27..ccff222be 100644 --- a/src/core/save_state_version.h +++ b/src/core/save_state_version.h @@ -2,4 +2,4 @@ #include "types.h" static constexpr u32 SAVE_STATE_MAGIC = 0x43435544; -static constexpr u32 SAVE_STATE_VERSION = 11; +static constexpr u32 SAVE_STATE_VERSION = 12; diff --git a/src/core/spu.cpp b/src/core/spu.cpp index f0896b055..2082abe21 100644 --- a/src/core/spu.cpp +++ b/src/core/spu.cpp @@ -72,8 +72,6 @@ void SPU::Reset() v.has_samples = false; } - m_voice_key_on_off_delay.fill(0); - m_ram.fill(0); UpdateEventInterval(); } @@ -130,8 +128,6 @@ bool SPU::DoState(StateWrapper& sw) sw.Do(&v.has_samples); } - sw.Do(&m_voice_key_on_off_delay); - sw.DoBytes(m_ram.data(), RAM_SIZE); if (sw.IsReading()) @@ -280,15 +276,6 @@ void SPU::WriteRegister(u32 offset, u16 value) Log_DebugPrintf("SPU key on low <- 0x%04X", ZeroExtend32(value)); m_tick_event->InvokeEarly(); m_key_on_register = (m_key_on_register & 0xFFFF0000) | ZeroExtend32(value); - - u16 bits = value; - for (u32 i = 0; i < 16; i++) - { - if (bits & 0x01) - VoiceKeyOn(i); - - bits >>= 1; - } } break; @@ -297,15 +284,6 @@ void SPU::WriteRegister(u32 offset, u16 value) Log_DebugPrintf("SPU key on high <- 0x%04X", ZeroExtend32(value)); m_tick_event->InvokeEarly(); m_key_on_register = (m_key_on_register & 0x0000FFFF) | (ZeroExtend32(value) << 16); - - u16 bits = value; - for (u32 i = 16; i < NUM_VOICES; i++) - { - if (bits & 0x01) - VoiceKeyOn(i); - - bits >>= 1; - } } break; @@ -313,16 +291,7 @@ void SPU::WriteRegister(u32 offset, u16 value) { Log_DebugPrintf("SPU key off low <- 0x%04X", ZeroExtend32(value)); m_tick_event->InvokeEarly(); - m_key_on_register = (m_key_on_register & 0xFFFF0000) | ZeroExtend32(value); - - u16 bits = value; - for (u32 i = 0; i < 16; i++) - { - if (bits & 0x01) - VoiceKeyOff(i); - - bits >>= 1; - } + m_key_off_register = (m_key_off_register & 0xFFFF0000) | ZeroExtend32(value); } break; @@ -330,16 +299,7 @@ void SPU::WriteRegister(u32 offset, u16 value) { Log_DebugPrintf("SPU key off high <- 0x%04X", ZeroExtend32(value)); m_tick_event->InvokeEarly(); - m_key_on_register = (m_key_on_register & 0x0000FFFF) | (ZeroExtend32(value) << 16); - - u16 bits = value; - for (u32 i = 16; i < NUM_VOICES; i++) - { - if (bits & 0x01) - VoiceKeyOff(i); - - bits >>= 1; - } + m_key_off_register = (m_key_off_register & 0x0000FFFF) | (ZeroExtend32(value) << 16); } break; @@ -508,6 +468,7 @@ u16 SPU::ReadVoiceRegister(u32 offset) m_tick_event->InvokeEarly(); } + Log_TracePrintf("Read voice %u register %u -> 0x%02X", voice_index, reg_index, voice.regs.index[reg_index]); return voice.regs.index[reg_index]; } @@ -710,29 +671,39 @@ void SPU::Execute(TickCount ticks) s32 right_sum = 0; s32 reverb_in_left = 0; s32 reverb_in_right = 0; - if (m_SPUCNT.enable) + + u32 key_on_register = m_key_on_register; + m_key_on_register = 0; + u32 key_off_register = m_key_off_register; + m_key_off_register = 0; + u32 reverb_on_register = m_reverb_on_register; + + for (u32 voice = 0; voice < NUM_VOICES; voice++) { - u32 reverb_on = m_reverb_on_register; + const auto [left, right] = SampleVoice(voice); + left_sum += left; + right_sum += right; - for (u32 voice = 0; voice < NUM_VOICES; voice++) + if (reverb_on_register & 1u) { - const auto [left, right] = SampleVoice(voice); - left_sum += left; - right_sum += right; - - if (reverb_on & 1u) - { - reverb_in_left += left; - reverb_in_right += right; - } - reverb_on >>= 1; + reverb_in_left += left; + reverb_in_right += right; } + reverb_on_register >>= 1; - if (!m_SPUCNT.mute_n) - { - left_sum = 0; - right_sum = 0; - } + if (key_off_register & 1u) + m_voices[voice].KeyOff(); + key_off_register >>= 1; + + if (key_on_register & 1u) + m_voices[voice].KeyOn(); + key_on_register >>= 1; + } + + if (!m_SPUCNT.mute_n) + { + left_sum = 0; + right_sum = 0; } // Update noise once per frame. @@ -802,15 +773,6 @@ void SPU::Execute(TickCount ticks) output_stream->EndWrite(frames_in_this_batch); remaining_frames -= frames_in_this_batch; } - - for (u32 i = 0; i < NUM_VOICES; i++) - { - const u32 delay = static_cast(m_voice_key_on_off_delay[i]); - if (delay == 0) - continue; - - m_voice_key_on_off_delay[i] -= static_cast(std::min(delay, static_cast(ticks))); - } } void SPU::UpdateEventInterval() @@ -1300,36 +1262,6 @@ std::tuple SPU::SampleVoice(u32 voice_index) return std::make_tuple(left, right); } -void SPU::VoiceKeyOn(u32 voice_index) -{ - Log_DebugPrintf("Voice %u key on", voice_index); - - if (m_voice_key_on_off_delay[voice_index] > 0) - { - Log_DevPrintf("Ignoring key on for voice %u due to only %u ticks passed since last write", voice_index, - m_voice_key_on_off_delay[voice_index]); - return; - } - - m_voices[voice_index].KeyOn(); - m_voice_key_on_off_delay[voice_index] = MINIMUM_TICKS_BETWEEN_KEY_ON_OFF; -} - -void SPU::VoiceKeyOff(u32 voice_index) -{ - Log_DebugPrintf("Voice %u key off", voice_index); - - if (m_voice_key_on_off_delay[voice_index] > 0) - { - Log_DevPrintf("Ignoring key off for voice %u due to only %u ticks passed since last write", voice_index, - m_voice_key_on_off_delay[voice_index]); - return; - } - - m_voices[voice_index].KeyOff(); - m_voice_key_on_off_delay[voice_index] = MINIMUM_TICKS_BETWEEN_KEY_ON_OFF; -} - void SPU::UpdateNoise() { // Dr Hell's noise waveform, implementation borrowed from pcsx-r. diff --git a/src/core/spu.h b/src/core/spu.h index 47e7da036..e107c83c0 100644 --- a/src/core/spu.h +++ b/src/core/spu.h @@ -362,8 +362,6 @@ private: void ReadADPCMBlock(u16 address, ADPCMBlock* block); std::tuple SampleVoice(u32 voice_index); - void VoiceKeyOn(u32 voice_index); - void VoiceKeyOff(u32 voice_index); void UpdateNoise(); @@ -419,7 +417,6 @@ private: s16 m_reverb_right_output = 0; std::array m_voices{}; - std::array m_voice_key_on_off_delay{}; std::array m_ram{}; InlineFIFOQueue m_cd_audio_buffer;