aboutsummaryrefslogtreecommitdiff
path: root/src/audio_core/renderer/command/command_buffer.cpp
diff options
context:
space:
mode:
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];