internal static void ValidateBiquad(Biquad expected, Biquad actual, double error) { Assert.AreEqual(expected.B0, actual.B0, error); Assert.AreEqual(expected.B1, actual.B1, error); Assert.AreEqual(expected.B2, actual.B2, error); Assert.AreEqual(expected.A1, actual.A1, error); Assert.AreEqual(expected.A2, actual.A2, error); }
public BiquadPlugin() { Samplerate = 48000; DevInfo = new DeviceInfo(); ParameterInfo = new Parameter[5]; PortInfo = new Port[2]; BiquadL = new Biquad(Biquad.FilterType.LowPass, 48000); BiquadR = new Biquad(Biquad.FilterType.LowPass, 48000); }
private Biquad CreateBiquad(FilterType type, double f0, double gainInDB, double q, TimeDirection timeDirection) { Biquad biquad = new Biquad(); biquad.F0 = f0; biquad.GainInDB = gainInDB; biquad.Q = q; biquad.TimeDirection = timeDirection; biquad.Type = type; return(biquad); }
/// <summary> /// Construct a fourth order filter from two Biquad elements /// </summary> public Hpf() { // 2 kHz filter bq1 = new Biquad(1.0, -1.973416440674660, 1.0, -1.450197273018358, 0.596145071222633); bq2 = new Biquad(1.0, -1.994429119281506, 1.0, -1.880440530016805, 0.946873330944877); g = 0.654717549190572; // 1 kHz filter //bq1 = new Biquad(1.0, -1.993377987075336, 1.0, -1.727679913361968, 0.769204050974404); //bq2 = new Biquad(1.0, -1.998617772299150, 1.0, -1.955947061007005, 0.972849469079112); //g = 0.766814731321591; }
public EqProcessor(MixingConfig config, double samplerate) { this.config = config; this.samplerate = samplerate; filters = Enumerable.Range(0, 6) .Select(_ => { var b = new Biquad { Frequency = 100, Slope = 1.0, GainDB = 0, Q = 1, Samplerate = samplerate, Type = Biquad.FilterType.Peak }; b.Update(); return(b); }) .ToArray(); filters[0].Frequency = config.Eq1FreqTransformed; filters[0].Q = config.Eq1QTransformed; filters[0].GainDB = config.Eq1GainDbTransformed; filters[1].Frequency = config.Eq2FreqTransformed; filters[1].Q = config.Eq2QTransformed; filters[1].GainDB = config.Eq2GainDbTransformed; filters[2].Frequency = config.Eq3FreqTransformed; filters[2].Q = config.Eq3QTransformed; filters[2].GainDB = config.Eq3GainDbTransformed; filters[3].Frequency = config.Eq4FreqTransformed; filters[3].Q = config.Eq4QTransformed; filters[3].GainDB = config.Eq4GainDbTransformed; filters[4].Frequency = config.Eq5FreqTransformed; filters[4].Q = config.Eq5QTransformed; filters[4].GainDB = config.Eq5GainDbTransformed; filters[5].Frequency = config.Eq6FreqTransformed; filters[5].Q = config.Eq6QTransformed; filters[5].GainDB = config.Eq6GainDbTransformed; foreach (var f in filters) { f.Update(); } }
public void ImpulseResponseTest() { var impulseResponse = new double[] { 0.65471754919057201, -0.41719110093654077, -0.29887670227185281, -0.17887455470804403, -0.07495271913491164, 0.00420364664357312, 0.05661585665848813, 0.08464252576943176, 0.09295574981587507, 0.08701260448316661, 0.07203835103345660, 0.05245619317269765, 0.03165979792384682, 0.01201734200381667, -0.00499199754056533, -0.01858620452338062, -0.02848579851610977, -0.03474661966479594, -0.03763251723486896, -0.03752819499746086, -0.03488535222082659 }; var bq1 = new Biquad(1.0, -1.973416440674660, 1.0, -1.450197273018358, 0.596145071222633); var bq2 = new Biquad(1.0, -1.994429119281506, 1.0, -1.880440530016805, 0.946873330944877); var g = 0.654717549190572; var input = 1.0; for (var i = 0; i < 20; i++) { var output = g * bq2.Filter(bq1.Filter(input)); // This should be near enough :D Assert.IsTrue(Math.Abs(output - impulseResponse[i]) < 0.00000000000001); input = 0.0; } }
public DelayLine(int bufferSize, int samplerate) { delay = new ModulatedDelay(bufferSize, 10000); diffuser = new AllpassDiffuser(bufferSize, samplerate) { ModulationEnabled = false }; tempBuffer = new double[bufferSize]; filterOutputBuffer = new double[bufferSize]; lowPass = new Lp1(samplerate); lowShelf = new Biquad(Biquad.FilterType.LowShelf, samplerate) { Slope = 1.0, GainDB = -20, Frequency = 20 }; highShelf = new Biquad(Biquad.FilterType.HighShelf, samplerate) { Slope = 1.0, GainDB = -20, Frequency = 19000 }; lowPass.CutoffHz = 1000; lowShelf.Update(); highShelf.Update(); Samplerate = samplerate; }
public double[][] ProcessOutputStage() { var len = timeSignal[0].Length; var stereoSignal = timeSignal; var gain = Utils.DB2gain(outputStage.GainTransformed); var pan = outputStage.PanTransformed; var leftPan = pan <= 0 ? 1.0 : 1 - Math.Abs(pan); var rightPan = pan >= 0 ? 1.0 : 1 - Math.Abs(pan); var leftInvert = outputStage.InvertPhaseLeft ? -1 : 1; var rightInvert = outputStage.InvertPhaseRight ? -1 : 1; var leftDelay = (int)(outputStage.DelayMillisLTransformed / 1000.0 * samplerate); var rightDelay = (int)(outputStage.DelayMillisRTransformed / 1000.0 * samplerate); var windowLen = outputStage.WindowLengthTransformed; var windowType = outputStage.WindowMethodTransformed; var low12db = outputStage.LowCut12dB; var high12db = outputStage.HighCut12dB; var lp1Left = new ZeroLp1(); var lp1Right = new ZeroLp1(); var hp1Left = new ZeroHp1(); var hp1Right = new ZeroHp1(); lp1Left.SetFc(outputStage.HighCutLeftTransformed / (samplerate / 2)); lp1Right.SetFc(outputStage.HighCutRightTransformed / (samplerate / 2)); hp1Left.SetFc(outputStage.LowCutLeftTransformed / (samplerate / 2)); hp1Right.SetFc(outputStage.LowCutRightTransformed / (samplerate / 2)); var lp2Left = new Biquad { Q = 0.707, Type = Biquad.FilterType.LowPass, Gain = 1, Samplerate = samplerate }; var lp2Right = new Biquad { Q = 0.707, Type = Biquad.FilterType.LowPass, Gain = 1, Samplerate = samplerate }; var hp2Left = new Biquad { Q = 0.707, Type = Biquad.FilterType.HighPass, Gain = 1, Samplerate = samplerate }; var hp2Right = new Biquad { Q = 0.707, Type = Biquad.FilterType.HighPass, Gain = 1, Samplerate = samplerate }; lp2Left.Frequency = outputStage.HighCutLeftTransformed; lp2Right.Frequency = outputStage.HighCutRightTransformed; hp2Left.Frequency = outputStage.LowCutLeftTransformed; hp2Right.Frequency = outputStage.LowCutRightTransformed; lp2Left.Update(); lp2Right.Update(); hp2Left.Update(); hp2Right.Update(); var outputLeft = new double[len]; var outputRight = new double[len]; for (int i = 0; i < stereoSignal[0].Length; i++) { var lSample = stereoSignal[0][i] * gain * leftPan * leftInvert; var rSample = stereoSignal[1][i] * gain * rightPan * rightInvert; if (high12db) { lSample = lp2Left.Process(lSample); rSample = lp2Right.Process(rSample); } else { lSample = lp1Left.Process(lSample); rSample = lp1Right.Process(rSample); } if (low12db) { lSample = hp2Left.Process(lSample); rSample = hp2Right.Process(rSample); } else { lSample = hp1Left.Process(lSample); rSample = hp1Right.Process(rSample); } if (i + leftDelay < len) { outputLeft[i + leftDelay] = lSample; } if (i + rightDelay < len) { outputRight[i + rightDelay] = rSample; } } for (int i = 0; i < len; i++) { var window = GetWindow(i, impulseLength, windowLen, windowType); outputLeft[i] *= window; outputRight[i] *= window; } return(new[] { outputLeft, outputRight }); }