Skip to content

Commit

Permalink
Biquad cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiashienzsch committed Feb 24, 2024
1 parent 34bebab commit 9ee1e76
Showing 1 changed file with 60 additions and 47 deletions.
107 changes: 60 additions & 47 deletions lib/grit/audio/filter/biquad.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,8 @@ struct BiquadCoefficients
using value_type = Float;
using SampleType = Float;

[[nodiscard]] static constexpr auto makeBypass() -> etl::array<Float, 6>
{
return {Float(1), Float(0), Float(0), Float(1), Float(0), Float(0)};
}

[[nodiscard]] static constexpr auto makeLowPass(Float cutoff, Float Q, Float sampleRate) -> etl::array<Float, 6>
{
auto const omega0 = Float(2) * static_cast<Float>(etl::numbers::pi) * cutoff / sampleRate;
auto const d = Float(1) / Q;
auto const cos0 = etl::cos(omega0);
auto const sin0 = etl::sin(omega0);
auto const beta = Float(0.5) * ((Float(1) - (d * Float(0.5)) * sin0) / (Float(1) + (d * Float(0.5)) * sin0));
auto const gamma = (Float(0.5) + beta) * cos0;

auto const b0 = (Float(0.5) + beta - gamma) * Float(0.5);
auto const b1 = Float(0.5) + beta - gamma;
auto const b2 = b0;

auto const a0 = Float(1);
auto const a1 = Float(-2) * gamma;
auto const a2 = Float(2) * beta;

return {b0, b1, b2, a0, a1, a2};
}
[[nodiscard]] static constexpr auto makeBypass() -> etl::array<Float, 6>;
[[nodiscard]] static constexpr auto makeLowPass(Float cutoff, Float Q, Float sampleRate) -> etl::array<Float, 6>;
};

/// \brief 2nd order IIR filter using the transpose direct form 2 structure.
Expand All @@ -55,30 +33,10 @@ struct Biquad

constexpr Biquad() = default;

constexpr auto setCoefficients(etl::span<Float const, 6> coefficients) -> void
{
etl::copy(coefficients.begin(), coefficients.end(), _coefficients.begin());
}
constexpr auto setCoefficients(etl::span<Float const, 6> coefficients) -> void;
constexpr auto reset() -> void;

constexpr auto reset() -> void
{
_z[0] = Float(0);
_z[1] = Float(0);
}

[[nodiscard]] constexpr auto operator()(Float x) -> Float
{
auto const b0 = _coefficients[Index::B0];
auto const b1 = _coefficients[Index::B1];
auto const b2 = _coefficients[Index::B2];
auto const a1 = _coefficients[Index::A1];
auto const a2 = _coefficients[Index::A2];

auto const y = b0 * x + _z[0];
_z[0] = b1 * x - a1 * y + _z[1];
_z[1] = b2 * x - a2 * y;
return y;
}
[[nodiscard]] constexpr auto operator()(Float x) -> Float;

private:
enum Index
Expand All @@ -96,4 +54,59 @@ struct Biquad
etl::array<Float, 2> _z{};
};

template<etl::floating_point Float>
constexpr auto BiquadCoefficients<Float>::makeBypass() -> etl::array<Float, 6>
{
return {Float(1), Float(0), Float(0), Float(1), Float(0), Float(0)};
}

template<etl::floating_point Float>
constexpr auto BiquadCoefficients<Float>::makeLowPass(Float cutoff, Float Q, Float sampleRate) -> etl::array<Float, 6>
{
auto const omega0 = Float(2) * static_cast<Float>(etl::numbers::pi) * cutoff / sampleRate;
auto const d = Float(1) / Q;
auto const cos0 = etl::cos(omega0);
auto const sin0 = etl::sin(omega0);
auto const beta = Float(0.5) * ((Float(1) - (d * Float(0.5)) * sin0) / (Float(1) + (d * Float(0.5)) * sin0));
auto const gamma = (Float(0.5) + beta) * cos0;

auto const b0 = (Float(0.5) + beta - gamma) * Float(0.5);
auto const b1 = Float(0.5) + beta - gamma;
auto const b2 = b0;

auto const a0 = Float(1);
auto const a1 = Float(-2) * gamma;
auto const a2 = Float(2) * beta;

return {b0, b1, b2, a0, a1, a2};
}

template<etl::floating_point Float>
constexpr auto Biquad<Float>::setCoefficients(etl::span<Float const, 6> coefficients) -> void
{
etl::copy(coefficients.begin(), coefficients.end(), _coefficients.begin());
}

template<etl::floating_point Float>
constexpr auto Biquad<Float>::reset() -> void
{
_z[0] = Float(0);
_z[1] = Float(0);
}

template<etl::floating_point Float>
constexpr auto Biquad<Float>::operator()(Float x) -> Float
{
auto const b0 = _coefficients[Index::B0];
auto const b1 = _coefficients[Index::B1];
auto const b2 = _coefficients[Index::B2];
auto const a1 = _coefficients[Index::A1];
auto const a2 = _coefficients[Index::A2];

auto const y = b0 * x + _z[0];
_z[0] = b1 * x - a1 * y + _z[1];
_z[1] = b2 * x - a2 * y;
return y;
}

} // namespace grit

0 comments on commit 9ee1e76

Please sign in to comment.