aboutsummaryrefslogtreecommitdiff
path: root/src/audio_core/renderer/command/command_buffer.cpp
diff options
context:
space:
mode:
authorMaufeat <sahyno1996@gmail.com>2025-12-13 19:44:41 +0100
committercrueter <crueter@eden-emu.dev>2025-12-13 19:44:41 +0100
commit06b83a58a6d60063cd5fad934aa7f3a75f0ce040 (patch)
tree21f7d62f6940bd6cfe79ce60504884fb357ff1b6 /src/audio_core/renderer/command/command_buffer.cpp
parent1e06c6f752c3b257783347a705dbcae293f618db (diff)
[audio] correct biquad filter v2 parameters (#3142)
We had the same struct for v1 and v2 - this was tested only with MP4, should output correct sounds now and boot it. Co-authored-by: MaranBr <maranbr@outlook.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3142 Reviewed-by: MaranBr <maranbr@eden-emu.dev> Reviewed-by: crueter <crueter@eden-emu.dev> Co-authored-by: Maufeat <sahyno1996@gmail.com> Co-committed-by: Maufeat <sahyno1996@gmail.com>
Diffstat (limited to 'src/audio_core/renderer/command/command_buffer.cpp')
-rw-r--r--src/audio_core/renderer/command/command_buffer.cpp56
1 files changed, 49 insertions, 7 deletions
diff --git a/src/audio_core/renderer/command/command_buffer.cpp b/src/audio_core/renderer/command/command_buffer.cpp
index a0a574fc64..804aba438d 100644
--- a/src/audio_core/renderer/command/command_buffer.cpp
+++ b/src/audio_core/renderer/command/command_buffer.cpp
@@ -21,6 +21,15 @@
namespace AudioCore::Renderer {
+namespace {
+constexpr f32 BiquadParameterFixedScaleQ14 = 16384.0f; // 1 << 14
+
+[[nodiscard]] inline s16 ToQ14Clamped(f32 v) {
+ const f32 scaled = std::clamp(v * BiquadParameterFixedScaleQ14, -32768.0f, 32767.0f);
+ return static_cast<s16>(scaled);
+}
+} // namespace
+
template <typename T, CommandId Id>
T& CommandBuffer::GenerateStart(const s32 node_id) {
if (size + sizeof(T) >= command_list.size_bytes()) {
@@ -259,18 +268,42 @@ void CommandBuffer::GenerateBiquadFilterCommand(const s32 node_id, EffectInfoBas
const bool use_float_processing) {
auto& cmd{GenerateStart<BiquadFilterCommand, CommandId::BiquadFilter>(node_id)};
- const auto& parameter{
- *reinterpret_cast<BiquadFilterInfo::ParameterVersion1*>(effect_info.GetParameter())};
const auto state{reinterpret_cast<VoiceState::BiquadFilterState*>(
effect_info.GetStateBuffer() + channel * sizeof(VoiceState::BiquadFilterState))};
- cmd.input = buffer_offset + parameter.inputs[channel];
- cmd.output = buffer_offset + parameter.outputs[channel];
+ if (behavior->IsEffectInfoVersion2Supported()) {
+ const auto& p{
+ *reinterpret_cast<BiquadFilterInfo::ParameterVersion2*>(effect_info.GetParameter())};
- cmd.biquad.b = parameter.b;
- cmd.biquad.a = parameter.a;
+ if (!IsChannelCountValid(p.channel_count) || channel < 0 || channel >= p.channel_count) {
+ return;
+ }
+
+ cmd.input = buffer_offset + p.inputs[channel];
+ cmd.output = buffer_offset + p.outputs[channel];
+
+ // 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 {
+ const auto& p{
+ *reinterpret_cast<BiquadFilterInfo::ParameterVersion1*>(effect_info.GetParameter())};
- // Effects use legacy fixed-point format
+ if (!IsChannelCountValid(p.channel_count) || channel < 0 || channel >= p.channel_count) {
+ return;
+ }
+
+ cmd.input = buffer_offset + p.inputs[channel];
+ cmd.output = buffer_offset + p.outputs[channel];
+
+ cmd.biquad.b = p.b;
+ cmd.biquad.a = p.a;
+ }
+
+ // Effects always use the fixed-point coefficient path on the DSP.
cmd.use_float_coefficients = false;
cmd.state = memory_pool->Translate(CpuAddr(state),
@@ -595,6 +628,15 @@ void CommandBuffer::GenerateCopyMixBufferCommand(const s32 node_id, EffectInfoBa
const s16 buffer_offset, const s8 channel) {
auto& cmd{GenerateStart<CopyMixBufferCommand, CommandId::CopyMixBuffer>(node_id)};
+ if (behavior->IsEffectInfoVersion2Supported()) {
+ const auto& parameter_v2{
+ *reinterpret_cast<BiquadFilterInfo::ParameterVersion2*>(effect_info.GetParameter())};
+ cmd.input_index = buffer_offset + parameter_v2.inputs[channel];
+ cmd.output_index = buffer_offset + parameter_v2.outputs[channel];
+ GenerateEnd<CopyMixBufferCommand>(cmd);
+ return;
+ }
+
const auto& parameter{
*reinterpret_cast<BiquadFilterInfo::ParameterVersion1*>(effect_info.GetParameter())};
cmd.input_index = buffer_offset + parameter.inputs[channel];