From 25a1d2b50842e767ddefb6447ccda0793cae73a4 Mon Sep 17 00:00:00 2001 From: John Date: Sun, 28 Dec 2025 06:21:30 +0100 Subject: [PATCH] EdenEmulator-13-39-06.patch Credit: Forrest Mark X --- .../renderer/command/command_buffer.cpp | 36 +++++++++++------ .../renderer/command/command_generator.cpp | 40 ++++++++++++------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/audio_core/renderer/command/command_buffer.cpp b/src/audio_core/renderer/command/command_buffer.cpp index 804aba438d..8ee00e873d 100644 --- a/src/audio_core/renderer/command/command_buffer.cpp +++ b/src/audio_core/renderer/command/command_buffer.cpp @@ -271,24 +271,34 @@ void CommandBuffer::GenerateBiquadFilterCommand(const s32 node_id, EffectInfoBas const auto state{reinterpret_cast( effect_info.GetStateBuffer() + channel * sizeof(VoiceState::BiquadFilterState))}; + // This is a simple fix for Metroid Prime Remastered as it can throw the emulator both a v1 and v2 parameter. I wasn't sure a proper way to use this so did a simple heuristic check. + // This should mostly work as since the binary data is misaligned state and channel_count should almost always be a corrupted value + bool is_version2_active = false; if (behavior->IsEffectInfoVersion2Supported()) { - const auto& p{ + const auto& p2{ *reinterpret_cast(effect_info.GetParameter())}; - if (!IsChannelCountValid(p.channel_count) || channel < 0 || channel >= p.channel_count) { - return; - } + if (p2.state <= EffectInfoBase::ParameterState::Updated && + p2.channel_count > 0) { + is_version2_active = true; - cmd.input = buffer_offset + p.inputs[channel]; - cmd.output = buffer_offset + p.outputs[channel]; + if (!IsChannelCountValid(p2.channel_count) || channel < 0 || channel >= p2.channel_count) { + return; + } - // Convert float coefficients to Q2.14 fixed-point as expected by the legacy DSP path. - cmd.biquad.b[0] = ToQ14Clamped(p.b[0]); - cmd.biquad.b[1] = ToQ14Clamped(p.b[1]); - cmd.biquad.b[2] = ToQ14Clamped(p.b[2]); - cmd.biquad.a[0] = ToQ14Clamped(p.a[0]); - cmd.biquad.a[1] = ToQ14Clamped(p.a[1]); - } else { + cmd.input = buffer_offset + p2.inputs[channel]; + cmd.output = buffer_offset + p2.outputs[channel]; + + // Convert float coefficients to Q2.14 fixed-point as expected by the legacy DSP path. + cmd.biquad.b[0] = ToQ14Clamped(p2.b[0]); + cmd.biquad.b[1] = ToQ14Clamped(p2.b[1]); + cmd.biquad.b[2] = ToQ14Clamped(p2.b[2]); + cmd.biquad.a[0] = ToQ14Clamped(p2.a[0]); + cmd.biquad.a[1] = ToQ14Clamped(p2.a[1]); + } + } + + if (!is_version2_active) { const auto& p{ *reinterpret_cast(effect_info.GetParameter())}; diff --git a/src/audio_core/renderer/command/command_generator.cpp b/src/audio_core/renderer/command/command_generator.cpp index bec6abbaf9..b150d48c75 100644 --- a/src/audio_core/renderer/command/command_generator.cpp +++ b/src/audio_core/renderer/command/command_generator.cpp @@ -367,23 +367,33 @@ void CommandGenerator::GenerateBiquadFilterEffectCommand(const s16 buffer_offset EffectInfoBase::ParameterState param_state{}; s8 channel_count = 0; - if (render_context.behavior->IsEffectInfoVersion2Supported()) { - const auto* parameter = - reinterpret_cast(effect_info.GetParameter()); - if (!parameter) { - LOG_ERROR(Service_Audio, "Biquad filter parameter is null"); - return; + const void* raw_data = effect_info.GetParameter(); + if (!raw_data) { + LOG_ERROR(Service_Audio, "Biquad filter parameter is null"); + return; + } + + // This is a simple fix for Metroid Prime Remastered as it can throw the emulator both a v1 and v2 parameter. I wasn't sure a proper way to use this so did a simple heuristic check. + // This should mostly work as since the binary data is misaligned state and channel_count should almost always be a corrupted value + bool is_version2_active = false; + if (render_context.behavior->IsEffectInfoVersion2Supported() ) { + const auto* parameter_v2 = + reinterpret_cast(raw_data); + + if (parameter_v2->state <= EffectInfoBase::ParameterState::Updated && + parameter_v2->channel_count > 0) { + is_version2_active = true; + + state = parameter_v2->state; + channel_count = parameter_v2->channel_count; } - param_state = parameter->state; - channel_count = parameter->channel_count; - } else { + } + + if (!is_version2_active) { const auto* parameter = - reinterpret_cast(effect_info.GetParameter()); - if (!parameter) { - LOG_ERROR(Service_Audio, "Biquad filter parameter is null"); - return; - } - param_state = parameter->state; + reinterpret_cast(raw_data); + + state = parameter->state; channel_count = parameter->channel_count; }