aboutsummaryrefslogtreecommitdiff
path: root/src/audio_core/renderer/command/effect
diff options
context:
space:
mode:
authorunknown <sahyno1996@gmail.com>2025-10-12 17:03:14 +0200
committercrueter <crueter@eden-emu.dev>2025-10-12 17:03:14 +0200
commita3ef2cc1838a007a2f424e88212aa6f1eb93eab3 (patch)
tree6ab37fe23b6d30a33a352deb631866720d012ecb /src/audio_core/renderer/command/effect
parent1e1b8ad33face3f3409aec50818d2b4fda8e6a0d (diff)
[audio_core/hid] Audio REV12+15 support + HID fixes (#2719)
This fixes newer updates / games. Implements partial audio rev15, rev13, rev12 and HID issues on SDK20+ games. Credits to LotP (Ryubing) and Zephyron (Citron) for their research and implementation. Co-authored-by: Zephyron <zephyron@citron-emu.org> Co-authored-by: Shinmegumi <shinmegumi@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2719 Reviewed-by: MaranBr <maranbr@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Co-authored-by: unknown <sahyno1996@gmail.com> Co-committed-by: unknown <sahyno1996@gmail.com>
Diffstat (limited to 'src/audio_core/renderer/command/effect')
-rw-r--r--src/audio_core/renderer/command/effect/biquad_filter.cpp44
-rw-r--r--src/audio_core/renderer/command/effect/biquad_filter.h21
-rw-r--r--src/audio_core/renderer/command/effect/multi_tap_biquad_filter.cpp13
-rw-r--r--src/audio_core/renderer/command/effect/multi_tap_biquad_filter.h7
4 files changed, 81 insertions, 4 deletions
diff --git a/src/audio_core/renderer/command/effect/biquad_filter.cpp b/src/audio_core/renderer/command/effect/biquad_filter.cpp
index 539e0c6370..4ad3184079 100644
--- a/src/audio_core/renderer/command/effect/biquad_filter.cpp
+++ b/src/audio_core/renderer/command/effect/biquad_filter.cpp
@@ -52,6 +52,40 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
}
/**
+ * Biquad filter float implementation with native float coefficients.
+ */
+void ApplyBiquadFilterFloat2(std::span<s32> output, std::span<const s32> input,
+ std::array<f32, 3>& b, std::array<f32, 2>& a,
+ VoiceState::BiquadFilterState& state, const u32 sample_count) {
+ constexpr f64 min{std::numeric_limits<s32>::min()};
+ constexpr f64 max{std::numeric_limits<s32>::max()};
+
+ std::array<f64, 3> b_double{static_cast<f64>(b[0]), static_cast<f64>(b[1]),
+ static_cast<f64>(b[2])};
+ std::array<f64, 2> a_double{static_cast<f64>(a[0]), static_cast<f64>(a[1])};
+ std::array<f64, 4> s{Common::BitCast<f64>(state.s0), Common::BitCast<f64>(state.s1),
+ Common::BitCast<f64>(state.s2), Common::BitCast<f64>(state.s3)};
+
+ for (u32 i = 0; i < sample_count; i++) {
+ f64 in_sample{static_cast<f64>(input[i])};
+ auto sample{in_sample * b_double[0] + s[0] * b_double[1] + s[1] * b_double[2] +
+ s[2] * a_double[0] + s[3] * a_double[1]};
+
+ output[i] = static_cast<s32>(std::clamp(sample, min, max));
+
+ s[1] = s[0];
+ s[0] = in_sample;
+ s[3] = s[2];
+ s[2] = sample;
+ }
+
+ state.s0 = Common::BitCast<s64>(s[0]);
+ state.s1 = Common::BitCast<s64>(s[1]);
+ state.s2 = Common::BitCast<s64>(s[2]);
+ state.s3 = Common::BitCast<s64>(s[3]);
+}
+
+/**
* Biquad filter s32 implementation.
*
* @param output - Output container for filtered samples.
@@ -98,8 +132,14 @@ void BiquadFilterCommand::Process(const AudioRenderer::CommandListProcessor& pro
processor.mix_buffers.subspan(output * processor.sample_count, processor.sample_count)};
if (use_float_processing) {
- ApplyBiquadFilterFloat(output_buffer, input_buffer, biquad.b, biquad.a, *state_,
- processor.sample_count);
+ // REV15+: Use native float coefficients if available
+ if (use_float_coefficients) {
+ ApplyBiquadFilterFloat2(output_buffer, input_buffer, biquad_float.numerator,
+ biquad_float.denominator, *state_, processor.sample_count);
+ } else {
+ ApplyBiquadFilterFloat(output_buffer, input_buffer, biquad.b, biquad.a, *state_,
+ processor.sample_count);
+ }
} else {
ApplyBiquadFilterInt(output_buffer, input_buffer, biquad.b, biquad.a, *state_,
processor.sample_count);
diff --git a/src/audio_core/renderer/command/effect/biquad_filter.h b/src/audio_core/renderer/command/effect/biquad_filter.h
index 0e903930a6..0e1893e536 100644
--- a/src/audio_core/renderer/command/effect/biquad_filter.h
+++ b/src/audio_core/renderer/command/effect/biquad_filter.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -50,12 +53,16 @@ struct BiquadFilterCommand : ICommand {
s16 output;
/// Input parameters for biquad
VoiceInfo::BiquadFilterParameter biquad;
+ /// Input parameters for biquad (REV15+ native float)
+ VoiceInfo::BiquadFilterParameter2 biquad_float;
/// Biquad state, updated each call
CpuAddr state;
/// If true, reset the state
bool needs_init;
/// If true, use float processing rather than int
bool use_float_processing;
+ /// If true, use native float coefficients (REV15+)
+ bool use_float_coefficients;
};
/**
@@ -72,4 +79,18 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
std::array<s16, 3>& b, std::array<s16, 2>& a,
VoiceState::BiquadFilterState& state, const u32 sample_count);
+/**
+ * Biquad filter float implementation with native float coefficients (SDK REV15+).
+ *
+ * @param output - Output container for filtered samples.
+ * @param input - Input container for samples to be filtered.
+ * @param b - Feedforward coefficients (float).
+ * @param a - Feedback coefficients (float).
+ * @param state - State to track previous samples.
+ * @param sample_count - Number of samples to process.
+ */
+void ApplyBiquadFilterFloat2(std::span<s32> output, std::span<const s32> input,
+ std::array<f32, 3>& b, std::array<f32, 2>& a,
+ VoiceState::BiquadFilterState& state, const u32 sample_count);
+
} // namespace AudioCore::Renderer
diff --git a/src/audio_core/renderer/command/effect/multi_tap_biquad_filter.cpp b/src/audio_core/renderer/command/effect/multi_tap_biquad_filter.cpp
index 208bbeaf29..2dfbcf6145 100644
--- a/src/audio_core/renderer/command/effect/multi_tap_biquad_filter.cpp
+++ b/src/audio_core/renderer/command/effect/multi_tap_biquad_filter.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -33,8 +36,14 @@ void MultiTapBiquadFilterCommand::Process(const AudioRenderer::CommandListProces
*state = {};
}
- ApplyBiquadFilterFloat(output_buffer, input_buffer, biquads[i].b, biquads[i].a, *state,
- processor.sample_count);
+ // REV15+: Use native float coefficients if available
+ if (use_float_coefficients) {
+ ApplyBiquadFilterFloat2(output_buffer, input_buffer, biquads_float[i].numerator,
+ biquads_float[i].denominator, *state, processor.sample_count);
+ } else {
+ ApplyBiquadFilterFloat(output_buffer, input_buffer, biquads[i].b, biquads[i].a, *state,
+ processor.sample_count);
+ }
}
}
diff --git a/src/audio_core/renderer/command/effect/multi_tap_biquad_filter.h b/src/audio_core/renderer/command/effect/multi_tap_biquad_filter.h
index 50fce80b0c..35fa76f62d 100644
--- a/src/audio_core/renderer/command/effect/multi_tap_biquad_filter.h
+++ b/src/audio_core/renderer/command/effect/multi_tap_biquad_filter.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -49,12 +52,16 @@ struct MultiTapBiquadFilterCommand : ICommand {
s16 output;
/// Biquad parameters
std::array<VoiceInfo::BiquadFilterParameter, MaxBiquadFilters> biquads;
+ /// Biquad parameters (REV15+ native float)
+ std::array<VoiceInfo::BiquadFilterParameter2, MaxBiquadFilters> biquads_float;
/// Biquad states, updated each call
std::array<CpuAddr, MaxBiquadFilters> states;
/// If each biquad needs initialisation
std::array<bool, MaxBiquadFilters> needs_init;
/// Number of active biquads
u8 filter_tap_count;
+ /// If true, use native float coefficients (REV15+)
+ bool use_float_coefficients;
};
} // namespace AudioCore::Renderer