From 5a6ec5595bcda83a30b87d4cabc86505c111e9b8 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Wed, 8 Jun 2022 00:11:46 +0200 Subject: [PATCH] Remove duplicate biquad module This was moved elsewhere, but I guess another copy got saved and I didn't notice. --- plugins/crossover/src/biquad.rs | 198 -------------------------------- 1 file changed, 198 deletions(-) delete mode 100644 plugins/crossover/src/biquad.rs diff --git a/plugins/crossover/src/biquad.rs b/plugins/crossover/src/biquad.rs deleted file mode 100644 index d238acd9..00000000 --- a/plugins/crossover/src/biquad.rs +++ /dev/null @@ -1,198 +0,0 @@ -// Crossover: clean crossovers as a multi-out plugin -// Copyright (C) 2022 Robbert van der Helm -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use nih_plug::debug::*; - -use std::f32::consts; -use std::ops::{Add, Mul, Sub}; -use std::simd::f32x2; - -pub const NEUTRAL_Q: f32 = std::f32::consts::FRAC_1_SQRT_2; - -/// A simple biquad filter with functions for generating coefficients for second order low-pass and -/// high-pass filters. Since these filters have 3 dB of attenuation at the center frequency, we'll -/// two of them in series to get 6 dB of attenutation at the crossover point for the LR24 -/// crossovers. -/// -/// Based on . -/// -/// The type parameter T should be either an `f32` or a SIMD type. -#[derive(Clone, Copy, Debug)] -pub struct Biquad { - pub coefficients: BiquadCoefficients, - s1: T, - s2: T, -} - -/// The coefficients `[b0, b1, b2, a1, a2]` for [`Biquad`]. These coefficients are all -/// prenormalized, i.e. they have been divided by `a0`. -/// -/// The type parameter T should be either an `f32` or a SIMD type. -#[derive(Clone, Copy, Debug)] -pub struct BiquadCoefficients { - b0: T, - b1: T, - b2: T, - a1: T, - a2: T, -} - -/// Either an `f32` or some SIMD vector type of `f32`s that can be used with our biquads. -pub trait SimdType: - Mul + Sub + Add + Copy + Sized -{ - fn from_f32(value: f32) -> Self; -} - -impl Default for Biquad { - /// Before setting constants the filter should just act as an identity function. - fn default() -> Self { - Self { - coefficients: BiquadCoefficients::identity(), - s1: T::from_f32(0.0), - s2: T::from_f32(0.0), - } - } -} - -impl Biquad { - /// Process a single sample. - pub fn process(&mut self, sample: T) -> T { - let result = self.coefficients.b0 * sample + self.s1; - - self.s1 = self.coefficients.b1 * sample - self.coefficients.a1 * result + self.s2; - self.s2 = self.coefficients.b2 * sample - self.coefficients.a2 * result; - - result - } - - /// Reset the state to zero, useful after making making large, non-interpolatable changes to the - /// filter coefficients. - pub fn reset(&mut self) { - self.s1 = T::from_f32(0.0); - self.s2 = T::from_f32(0.0); - } -} - -impl BiquadCoefficients { - /// Convert scalar coefficients into the correct vector type. - pub fn from_f32s(scalar: BiquadCoefficients) -> Self { - Self { - b0: T::from_f32(scalar.b0), - b1: T::from_f32(scalar.b1), - b2: T::from_f32(scalar.b2), - a1: T::from_f32(scalar.a1), - a2: T::from_f32(scalar.a2), - } - } - - /// Filter coefficients that would cause the sound to be passed through as is. - pub fn identity() -> Self { - Self::from_f32s(BiquadCoefficients { - b0: 1.0, - b1: 0.0, - b2: 0.0, - a1: 0.0, - a2: 0.0, - }) - } - - /// Compute the coefficients for a low-pass filter. - /// - /// Based on . - pub fn lowpass(sample_rate: f32, frequency: f32, q: f32) -> Self { - nih_debug_assert!(sample_rate > 0.0); - nih_debug_assert!(frequency > 0.0); - nih_debug_assert!(frequency < sample_rate / 2.0); - nih_debug_assert!(q > 0.0); - - let omega0 = consts::TAU * (frequency / sample_rate); - let cos_omega0 = omega0.cos(); - let alpha = omega0.sin() / (2.0 * q); - - // We'll prenormalize everything with a0 - let a0 = 1.0 + alpha; - let b0 = ((1.0 - cos_omega0) / 2.0) / a0; - let b1 = (1.0 - cos_omega0) / a0; - let b2 = ((1.0 - cos_omega0) / 2.0) / a0; - let a1 = (-2.0 * cos_omega0) / a0; - let a2 = (1.0 - alpha) / a0; - - Self::from_f32s(BiquadCoefficients { b0, b1, b2, a1, a2 }) - } - - /// Compute the coefficients for a high-pass filter. - /// - /// Based on . - pub fn highpass(sample_rate: f32, frequency: f32, q: f32) -> Self { - nih_debug_assert!(sample_rate > 0.0); - nih_debug_assert!(frequency > 0.0); - nih_debug_assert!(frequency < sample_rate / 2.0); - nih_debug_assert!(q > 0.0); - - let omega0 = consts::TAU * (frequency / sample_rate); - let cos_omega0 = omega0.cos(); - let alpha = omega0.sin() / (2.0 * q); - - // We'll prenormalize everything with a0 - let a0 = 1.0 + alpha; - let b0 = ((1.0 + cos_omega0) / 2.0) / a0; - let b1 = -(1.0 + cos_omega0) / a0; - let b2 = ((1.0 + cos_omega0) / 2.0) / a0; - let a1 = (-2.0 * cos_omega0) / a0; - let a2 = (1.0 - alpha) / a0; - - Self::from_f32s(BiquadCoefficients { b0, b1, b2, a1, a2 }) - } - - /// Compute the coefficients for an all-pass filter. - /// - /// Based on . - pub fn allpass(sample_rate: f32, frequency: f32, q: f32) -> Self { - nih_debug_assert!(sample_rate > 0.0); - nih_debug_assert!(frequency > 0.0); - nih_debug_assert!(frequency < sample_rate / 2.0); - nih_debug_assert!(q > 0.0); - - let omega0 = consts::TAU * (frequency / sample_rate); - let cos_omega0 = omega0.cos(); - let alpha = omega0.sin() / (2.0 * q); - - // We'll prenormalize everything with a0 - let a0 = 1.0 + alpha; - let b0 = (1.0 - alpha) / a0; - let b1 = (-2.0 * cos_omega0) / a0; - let b2 = (1.0 + alpha) / a0; - let a1 = (-2.0 * cos_omega0) / a0; - let a2 = (1.0 - alpha) / a0; - - Self::from_f32s(BiquadCoefficients { b0, b1, b2, a1, a2 }) - } -} - -impl SimdType for f32 { - #[inline(always)] - fn from_f32(value: f32) -> Self { - value - } -} - -impl SimdType for f32x2 { - #[inline(always)] - fn from_f32(value: f32) -> Self { - f32x2::splat(value) - } -}