Compare commits

...

2 Commits

Author SHA1 Message Date
David Marcec
4008695e4c Implement biquad filter for audio renderer effects 2020-09-20 14:36:44 +10:00
David Marcec
997d1e2ad9 audio_renderer: Fix biquad filter
Originally the biquad filter was disabled due to issues with crackling before.
2020-09-20 13:34:46 +10:00
3 changed files with 43 additions and 14 deletions

View File

@@ -270,11 +270,9 @@ void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voic
}
// Generate biquad filter
// GenerateBiquadFilterCommand(mix_buffer_count, biquad_filter,
// dsp_state.biquad_filter_state,
// mix_buffer_count + channel, mix_buffer_count +
// channel, worker_params.sample_count,
// voice_info.GetInParams().node_id);
GenerateBiquadFilterCommand(mix_buffer_count, biquad_filter, dsp_state.biquad_filter_state,
mix_buffer_count + channel, mix_buffer_count + channel,
worker_params.sample_count, voice_info.GetInParams().node_id);
}
}
@@ -302,8 +300,9 @@ void AudioCore::CommandGenerator::GenerateBiquadFilterCommand(
for (int i = 0; i < sample_count; ++i) {
const auto sample = static_cast<s64>(input[i]);
const auto f = (sample * n0 + s0 + 0x4000) >> 15;
const auto y = std::clamp(f, int32_min, int32_max);
const auto f = (sample * n0 + s0 + 0x2000) >> 14;
const auto y = static_cast<s64>(std::clamp(f, int32_min, int32_max));
s0 = sample * n1 + y * d0 + s1;
s1 = sample * n2 + y * d1;
output[i] = static_cast<s32>(y);
@@ -389,18 +388,33 @@ void CommandGenerator::GenerateI3dl2ReverbEffectCommand(s32 mix_buffer_offset, E
void CommandGenerator::GenerateBiquadFilterEffectCommand(s32 mix_buffer_offset, EffectBase* info,
bool enabled) {
if (!enabled) {
return;
}
const auto& params = dynamic_cast<EffectBiquadFilter*>(info)->GetParams();
auto* effect = dynamic_cast<EffectBiquadFilter*>(info);
const auto& params = effect->GetParams();
const auto channel_count = params.channel_count;
for (s32 i = 0; i < channel_count; i++) {
// TODO(ogniK): Actually implement biquad filter
if (params.input[i] != params.output[i]) {
if (!enabled) {
for (s32 i = 0; i < channel_count; i++) {
const auto* input = GetMixBuffer(mix_buffer_offset + params.input[i]);
auto* output = GetMixBuffer(mix_buffer_offset + params.output[i]);
ApplyMix<1>(output, input, 32768, worker_params.sample_count);
}
} else {
const BiquadFilterParameter filter_params{
.enabled = true,
.numerator = params.numerator,
.denominator = params.denominator,
};
auto& states = effect->GetState();
const auto need_init = params.status == ParameterStatus::Initialized ||
params.status == ParameterStatus::Updating;
for (s32 i = 0; i < channel_count; i++) {
if (need_init) {
states[i].fill(0);
}
GenerateBiquadFilterCommand(mix_buffer_offset, filter_params, states[i],
params.input[i], params.output[i],
worker_params.sample_count, 0);
}
}
}

View File

@@ -150,6 +150,14 @@ void EffectBiquadFilter::UpdateForCommandGeneration() {
GetParams().status = ParameterStatus::Updated;
}
const EffectBiquadFilter::StateType& EffectBiquadFilter::GetState() const {
return state;
}
EffectBiquadFilter::StateType& EffectBiquadFilter::GetState() {
return state;
}
EffectAuxInfo::EffectAuxInfo() : EffectGeneric::EffectGeneric(EffectType::Aux) {}
EffectAuxInfo::~EffectAuxInfo() = default;

View File

@@ -244,11 +244,18 @@ private:
class EffectBiquadFilter : public EffectGeneric<BiquadFilterParams> {
public:
using StateType = std::array<std::array<s64, 2>, AudioCommon::MAX_CHANNEL_COUNT>;
explicit EffectBiquadFilter();
~EffectBiquadFilter();
void Update(EffectInfo::InParams& in_params) override;
void UpdateForCommandGeneration() override;
const StateType& GetState() const;
StateType& GetState();
private:
StateType state{};
};
class EffectAuxInfo : public EffectGeneric<AuxInfo> {