From 2e43d9578b37347d1d9b1faa89a4f7eefc65722c Mon Sep 17 00:00:00 2001 From: Collecting Date: Tue, 13 Jan 2026 17:36:23 +0000 Subject: [PATCH] revert b5a82bcfdc41dfb8fc865103ac6da670c07cf43b revert fix(audio): biquad filter effect parameter version 2 handling Fix ParameterVersion2 structure layout to match actual format: - Add padding and use f32 for coefficients (was incorrectly using s16) - Update state field offset from 0x17 to 0x25 Update command generation to: - Read from correct structure based on version - Convert float coefficients to fixed-point Q2.14 when using version 2 Signed-off-by: Zephyron --- .../renderer/command/command_buffer.cpp | 43 ++++--------------- .../renderer/command/command_generator.cpp | 39 ++++------------- .../renderer/effect/biquad_filter.cpp | 25 +---------- .../renderer/effect/biquad_filter.h | 11 ++--- 4 files changed, 22 insertions(+), 96 deletions(-) diff --git a/src/audio_core/renderer/command/command_buffer.cpp b/src/audio_core/renderer/command/command_buffer.cpp index 026832c57..7ec373f75 100644 --- a/src/audio_core/renderer/command/command_buffer.cpp +++ b/src/audio_core/renderer/command/command_buffer.cpp @@ -1,5 +1,4 @@ // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "audio_core/renderer/behavior/behavior_info.h" @@ -258,45 +257,19 @@ void CommandBuffer::GenerateBiquadFilterCommand(const s32 node_id, EffectInfoBas const bool use_float_processing) { auto& cmd{GenerateStart(node_id)}; + const auto& parameter{ + *reinterpret_cast(effect_info.GetParameter())}; const auto state{reinterpret_cast( effect_info.GetStateBuffer() + channel * sizeof(VoiceState::BiquadFilterState))}; - // Check which parameter version is being used - if (behavior->IsEffectInfoVersion2Supported()) { - const auto& parameter{ - *reinterpret_cast(effect_info.GetParameter())}; + cmd.input = buffer_offset + parameter.inputs[channel]; + cmd.output = buffer_offset + parameter.outputs[channel]; - cmd.input = buffer_offset + parameter.inputs[channel]; - cmd.output = buffer_offset + parameter.outputs[channel]; + cmd.biquad.b = parameter.b; + cmd.biquad.a = parameter.a; - // Convert float coefficients to fixed-point Q2.14 format (multiply by 16384) - constexpr f32 fixed_point_scale = 16384.0f; - cmd.biquad.b[0] = static_cast( - std::clamp(parameter.b[0] * fixed_point_scale, -32768.0f, 32767.0f)); - cmd.biquad.b[1] = static_cast( - std::clamp(parameter.b[1] * fixed_point_scale, -32768.0f, 32767.0f)); - cmd.biquad.b[2] = static_cast( - std::clamp(parameter.b[2] * fixed_point_scale, -32768.0f, 32767.0f)); - cmd.biquad.a[0] = static_cast( - std::clamp(parameter.a[0] * fixed_point_scale, -32768.0f, 32767.0f)); - cmd.biquad.a[1] = static_cast( - std::clamp(parameter.a[1] * fixed_point_scale, -32768.0f, 32767.0f)); - - // Effects use legacy fixed-point format - cmd.use_float_coefficients = false; - } else { - const auto& parameter{ - *reinterpret_cast(effect_info.GetParameter())}; - - cmd.input = buffer_offset + parameter.inputs[channel]; - cmd.output = buffer_offset + parameter.outputs[channel]; - - cmd.biquad.b = parameter.b; - cmd.biquad.a = parameter.a; - - // Effects use legacy fixed-point format - cmd.use_float_coefficients = false; - } + // Effects use legacy fixed-point format + cmd.use_float_coefficients = false; cmd.state = memory_pool->Translate(CpuAddr(state), MaxBiquadFilters * sizeof(VoiceState::BiquadFilterState)); diff --git a/src/audio_core/renderer/command/command_generator.cpp b/src/audio_core/renderer/command/command_generator.cpp index 8196b2ee2..46db1fe99 100644 --- a/src/audio_core/renderer/command/command_generator.cpp +++ b/src/audio_core/renderer/command/command_generator.cpp @@ -1,5 +1,4 @@ // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "audio_core/common/audio_renderer_parameter.h" @@ -362,33 +361,12 @@ void CommandGenerator::GenerateAuxCommand(const s16 buffer_offset, EffectInfoBas void CommandGenerator::GenerateBiquadFilterEffectCommand(const s16 buffer_offset, EffectInfoBase& effect_info, const s32 node_id) { - EffectInfoBase::ParameterState 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; - } - state = parameter->state; - channel_count = parameter->channel_count; - } else { - const auto* parameter = reinterpret_cast( - effect_info.GetParameter()); - if (!parameter) { - LOG_ERROR(Service_Audio, "Biquad filter parameter is null"); - return; - } - state = parameter->state; - channel_count = parameter->channel_count; - } - + const auto& parameter{ + *reinterpret_cast(effect_info.GetParameter())}; if (effect_info.IsEnabled()) { bool needs_init{false}; - switch (state) { + switch (parameter.state) { case EffectInfoBase::ParameterState::Initialized: needs_init = true; break; @@ -397,23 +375,22 @@ void CommandGenerator::GenerateBiquadFilterEffectCommand(const s16 buffer_offset if (render_context.behavior->IsBiquadFilterEffectStateClearBugFixed()) { needs_init = false; } else { - needs_init = state == EffectInfoBase::ParameterState::Updating; + needs_init = parameter.state == EffectInfoBase::ParameterState::Updating; } break; default: - LOG_ERROR(Service_Audio, "Invalid biquad parameter state {}, treating as uninitialized", - static_cast(state)); - needs_init = true; + LOG_ERROR(Service_Audio, "Invalid biquad parameter state {}", + static_cast(parameter.state)); break; } - for (s8 channel = 0; channel < channel_count; channel++) { + for (s8 channel = 0; channel < parameter.channel_count; channel++) { command_buffer.GenerateBiquadFilterCommand( node_id, effect_info, buffer_offset, channel, needs_init, render_context.behavior->UseBiquadFilterFloatProcessing()); } } else { - for (s8 channel = 0; channel < channel_count; channel++) { + for (s8 channel = 0; channel < parameter.channel_count; channel++) { command_buffer.GenerateCopyMixBufferCommand(node_id, effect_info, buffer_offset, channel); } diff --git a/src/audio_core/renderer/effect/biquad_filter.cpp b/src/audio_core/renderer/effect/biquad_filter.cpp index 6f06eb482..08161d840 100644 --- a/src/audio_core/renderer/effect/biquad_filter.cpp +++ b/src/audio_core/renderer/effect/biquad_filter.cpp @@ -1,5 +1,4 @@ // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "audio_core/renderer/effect/biquad_filter.h" @@ -41,28 +40,8 @@ void BiquadFilterInfo::UpdateForCommandGeneration() { usage_state = UsageState::Disabled; } - // Determine which version structure is being used - // Version 1: state at offset 0x17, structure size ~24 bytes - // Version 2: state at offset 0x25, structure size ~40 bytes - auto params_v1{reinterpret_cast(parameter.data())}; - auto params_v2{reinterpret_cast(parameter.data())}; - - // Check which state location contains a valid ParameterState value (0-2) - // Valid states: Initialized (0), Updating (1), Updated (2) - const auto state_v1_raw = *reinterpret_cast(¶ms_v1->state); - const auto state_v2_raw = *reinterpret_cast(¶ms_v2->state); - - if (state_v1_raw <= 2) { - // Version 1 location has valid state, update there - params_v1->state = ParameterState::Updated; - } else if (state_v2_raw <= 2) { - // Version 2 location has valid state, update there - params_v2->state = ParameterState::Updated; - } else { - // Neither looks valid, update both (one will be wrong but command generator handles it) - params_v1->state = ParameterState::Updated; - params_v2->state = ParameterState::Updated; - } + auto params{reinterpret_cast(parameter.data())}; + params->state = ParameterState::Updated; } void BiquadFilterInfo::InitializeResultState(EffectResultState& result_state) {} diff --git a/src/audio_core/renderer/effect/biquad_filter.h b/src/audio_core/renderer/effect/biquad_filter.h index f77ef9266..5a22899ab 100644 --- a/src/audio_core/renderer/effect/biquad_filter.h +++ b/src/audio_core/renderer/effect/biquad_filter.h @@ -1,5 +1,4 @@ // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -28,12 +27,10 @@ public: struct ParameterVersion2 { /* 0x00 */ std::array inputs; /* 0x06 */ std::array outputs; - /* 0x0C */ u32 padding; - /* 0x10 */ std::array b; - /* 0x1C */ std::array a; - /* 0x24 */ s8 channel_count; - /* 0x25 */ ParameterState state; - /* 0x26 */ u16 reserved; + /* 0x0C */ std::array b; + /* 0x12 */ std::array a; + /* 0x16 */ s8 channel_count; + /* 0x17 */ ParameterState state; }; static_assert(sizeof(ParameterVersion2) <= sizeof(EffectInfoBase::InParameterVersion2), "BiquadFilterInfo::ParameterVersion2 has the wrong size!");