Browse Source

[audio_core] Better biquad filter logic (#3235)

This removes all redundant code and improves the logic of the biquad filter.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3235
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
pull/3243/head
MaranBr 2 days ago
committed by crueter
parent
commit
55646657e1
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 30
      src/audio_core/renderer/command/command_buffer.cpp
  2. 70
      src/audio_core/renderer/command/command_generator.cpp

30
src/audio_core/renderer/command/command_buffer.cpp

@ -275,28 +275,24 @@ void CommandBuffer::GenerateBiquadFilterCommand(const s32 node_id, EffectInfoBas
const auto& parameter{
*reinterpret_cast<BiquadFilterInfo::ParameterVersion2*>(effect_info.GetParameter())};
if (parameter.state <= EffectInfoBase::ParameterState::Updated && IsChannelCountValid(parameter.channel_count) && channel >= 0 && channel < parameter.channel_count) {
cmd.input = buffer_offset + parameter.inputs[channel];
cmd.output = buffer_offset + parameter.outputs[channel];
// Convert float coefficients to Q2.14 fixed-point as expected by the legacy DSP path.
cmd.biquad.b[0] = ToQ14Clamped(parameter.b[0]);
cmd.biquad.b[1] = ToQ14Clamped(parameter.b[1]);
cmd.biquad.b[2] = ToQ14Clamped(parameter.b[2]);
cmd.biquad.a[0] = ToQ14Clamped(parameter.a[0]);
cmd.biquad.a[1] = ToQ14Clamped(parameter.a[1]);
}
cmd.input = buffer_offset + parameter.inputs[channel];
cmd.output = buffer_offset + parameter.outputs[channel];
// Convert float coefficients to Q2.14 fixed-point as expected by the legacy DSP path.
cmd.biquad.b[0] = ToQ14Clamped(parameter.b[0]);
cmd.biquad.b[1] = ToQ14Clamped(parameter.b[1]);
cmd.biquad.b[2] = ToQ14Clamped(parameter.b[2]);
cmd.biquad.a[0] = ToQ14Clamped(parameter.a[0]);
cmd.biquad.a[1] = ToQ14Clamped(parameter.a[1]);
} else {
const auto& parameter{
*reinterpret_cast<BiquadFilterInfo::ParameterVersion1*>(effect_info.GetParameter())};
if (IsChannelCountValid(parameter.channel_count) && channel >= 0 && channel < parameter.channel_count) {
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;
}
cmd.biquad.b = parameter.b;
cmd.biquad.a = parameter.a;
}
// Effects always use the fixed-point coefficient path on the DSP.

70
src/audio_core/renderer/command/command_generator.cpp

@ -370,63 +370,43 @@ void CommandGenerator::GenerateBiquadFilterEffectCommand(const s16 buffer_offset
if (render_context.behavior->IsEffectInfoVersion2Supported()) {
const auto* parameter =
reinterpret_cast<const BiquadFilterInfo::ParameterVersion2*>(effect_info.GetParameter());
if (!parameter) {
LOG_ERROR(Service_Audio, "Biquad filter parameter is null");
return;
}
if (parameter->state <= EffectInfoBase::ParameterState::Updated) {
param_state = parameter->state;
channel_count = parameter->channel_count;
}
param_state = parameter->state;
channel_count = parameter->channel_count;
} else {
const auto* parameter =
reinterpret_cast<const BiquadFilterInfo::ParameterVersion1*>(effect_info.GetParameter());
if (!parameter) {
LOG_ERROR(Service_Audio, "Biquad filter parameter is null");
return;
}
param_state = parameter->state;
channel_count = parameter->channel_count;
}
if (channel_count <= 0) {
return;
}
if (channel_count > 0 && param_state <= EffectInfoBase::ParameterState::Updated) {
if (effect_info.IsEnabled()) {
bool needs_init{false};
if (effect_info.IsEnabled()) {
bool needs_init{false};
switch (param_state) {
case EffectInfoBase::ParameterState::Initialized:
needs_init = true;
break;
case EffectInfoBase::ParameterState::Updating:
case EffectInfoBase::ParameterState::Updated:
if (render_context.behavior->IsBiquadFilterEffectStateClearBugFixed()) {
switch (param_state) {
case EffectInfoBase::ParameterState::Initialized:
needs_init = true;
break;
case EffectInfoBase::ParameterState::Updating:
needs_init = !render_context.behavior->IsBiquadFilterEffectStateClearBugFixed();
break;
case EffectInfoBase::ParameterState::Updated:
needs_init = false;
} else {
needs_init = param_state == EffectInfoBase::ParameterState::Updating;
break;
}
break;
default:
LOG_ERROR(Service_Audio,
"Invalid biquad parameter state {}, treating as uninitialized",
static_cast<u32>(param_state));
needs_init = true;
break;
}
const bool use_float_processing =
render_context.behavior->UseBiquadFilterFloatProcessing();
const bool use_float_processing =
render_context.behavior->UseBiquadFilterFloatProcessing();
for (s8 channel = 0; channel < channel_count; channel++) {
command_buffer.GenerateBiquadFilterCommand(node_id, effect_info, buffer_offset, channel,
needs_init, use_float_processing);
}
} else {
for (s8 channel = 0; channel < channel_count; channel++) {
command_buffer.GenerateCopyMixBufferCommand(node_id, effect_info, buffer_offset,
channel);
for (s8 channel = 0; channel < channel_count; channel++) {
command_buffer.GenerateBiquadFilterCommand(node_id, effect_info, buffer_offset, channel,
needs_init, use_float_processing);
}
} else {
for (s8 channel = 0; channel < channel_count; channel++) {
command_buffer.GenerateCopyMixBufferCommand(node_id, effect_info, buffer_offset,
channel);
}
}
}
}

Loading…
Cancel
Save