From f054d9e48ccac09c112837f7dd17914e8f7c2a3d Mon Sep 17 00:00:00 2001 From: Josef Date: Fri, 11 Jul 2025 10:38:34 +0200 Subject: [PATCH] AllPass Added --- Runtime/Math/Biquad.cs | 123 +++++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 48 deletions(-) diff --git a/Runtime/Math/Biquad.cs b/Runtime/Math/Biquad.cs index 5aa57a9..275fdba 100644 --- a/Runtime/Math/Biquad.cs +++ b/Runtime/Math/Biquad.cs @@ -10,17 +10,18 @@ namespace Rokojori Peak, LowShelf, HighShelf, - Notch + Notch, + AllPass } public class Biquad { - public float a0 = 0; + public float b0 = 0; + public float b1 = 0; + public float b2 = 0; public float a1 = 0; public float a2 = 0; - public float a3 = 0; - public float a4 = 0; public float x1 = 0; public float x2 = 0; @@ -29,11 +30,11 @@ namespace Rokojori float process( float inputSample ) { - var result = this.a0 * inputSample + - this.a1 * this.x1 + - this.a2 * this.x2 - - this.a3 * this.y1 - - this.a4 * this.y2; + var result = this.b0 * inputSample + + this.b1 * this.x1 + + this.b2 * this.x2 - + this.a1 * this.y1 - + this.a2 * this.y2; this.x2 = this.x1; this.x1 = inputSample; @@ -44,41 +45,52 @@ namespace Rokojori return result; } + public static Biquad Create( BiquadType filterType, float gainDB, float frequency, float bandwidth, float sampleRate ) { - var filter = new Biquad(); - float A= 0, omega= 0, sn= 0, cs= 0, alpha= 0, beta = 0; - float a0= 0, a1= 0, a2= 0, b0= 0, b1= 0, b2 = 0; + var A = 0f; + var omega = 0f; + var sin = 0f; + var cos = 0f; + var alpha = 0f; + var beta = 0f; - var M_LN2 = 0.69314718055994530942f; + var a0 = 0f; + var a1 = 0f; + var a2 = 0f; + var b0 = 0f; + var b1 = 0f; + var b2 = 0f; - A = Mathf.Pow( 10, gainDB / 40 ); - omega = 2 * Mathf.Pi * frequency / sampleRate; - sn = Mathf.Sin( omega ); - cs = Mathf.Cos( omega ); - alpha = ( sn * Mathf.Sinh( M_LN2 / 2 * bandwidth * omega / sn ) ); + var ln2 = 0.69314718055994530942f; + + A = Mathf.Pow( 10f, gainDB / 40f ); + omega = 2f * Mathf.Pi * frequency / sampleRate; + sin = Mathf.Sin( omega ); + cos = Mathf.Cos( omega ); + alpha = ( sin * Mathf.Sinh( ln2 / 2f * bandwidth * omega / sin ) ); beta = Mathf.Sqrt(A + A); switch ( filterType ) { case BiquadType.LowPass: { - b0 = (1 - cs) /2; - b1 = 1 - cs; - b2 = (1 - cs) /2; + b0 = (1 - cos) /2; + b1 = 1 - cos; + b2 = (1 - cos) /2; a0 = 1 + alpha; - a1 = -2 * cs; + a1 = -2 * cos; a2 = 1 - alpha; } break; case BiquadType.HighPass: { - b0 = (1 + cs) /2; - b1 = -(1 + cs); - b2 = (1 + cs) /2; + b0 = (1 + cos) /2; + b1 = -(1 + cos); + b2 = (1 + cos) /2; a0 = 1 + alpha; - a1 = -2 * cs; + a1 = -2 * cos; a2 = 1 - alpha; } break; @@ -89,7 +101,7 @@ namespace Rokojori b1 = 0; b2 = -alpha; a0 = 1 + alpha; - a1 = -2 * cs; + a1 = -2 * cos; a2 = 1 - alpha; } break; @@ -97,10 +109,10 @@ namespace Rokojori case BiquadType.Notch: { b0 = 1; - b1 = -2 * cs; + b1 = -2 * cos; b2 = 1; a0 = 1 + alpha; - a1 = -2 * cs; + a1 = -2 * cos; a2 = 1 - alpha; } break; @@ -108,43 +120,58 @@ namespace Rokojori case BiquadType.Peak: { b0 = 1 + (alpha * A); - b1 = -2 * cs; + b1 = -2 * cos; b2 = 1 - (alpha * A); a0 = 1 + (alpha /A); - a1 = -2 * cs; + a1 = -2 * cos; a2 = 1 - (alpha /A); } break; case BiquadType.LowShelf: { - b0 = A * ((A + 1) - (A - 1) * cs + beta * sn); - b1 = 2 * A * ((A - 1) - (A + 1) * cs); - b2 = A * ((A + 1) - (A - 1) * cs - beta * sn); - a0 = (A + 1) + (A - 1) * cs + beta * sn; - a1 = -2 * ((A - 1) + (A + 1) * cs); - a2 = (A + 1) + (A - 1) * cs - beta * sn; + b0 = A * ((A + 1) - (A - 1) * cos + beta * sin); + b1 = 2 * A * ((A - 1) - (A + 1) * cos); + b2 = A * ((A + 1) - (A - 1) * cos - beta * sin); + a0 = (A + 1) + (A - 1) * cos + beta * sin; + a1 = -2 * ((A - 1) + (A + 1) * cos); + a2 = (A + 1) + (A - 1) * cos - beta * sin; } break; case BiquadType.HighShelf: { - b0 = A * ((A + 1) + (A - 1) * cs + beta * sn); - b1 = -2 * A * ((A - 1) + (A + 1) * cs); - b2 = A * ((A + 1) + (A - 1) * cs - beta * sn); - a0 = (A + 1) - (A - 1) * cs + beta * sn; - a1 = 2 * ((A - 1) - (A + 1) * cs); - a2 = (A + 1) - (A - 1) * cs - beta * sn; + b0 = A * ((A + 1) + (A - 1) * cos + beta * sin); + b1 = -2 * A * ((A - 1) + (A + 1) * cos); + b2 = A * ((A + 1) + (A - 1) * cos - beta * sin); + a0 = (A + 1) - (A - 1) * cos + beta * sin; + a1 = 2 * ((A - 1) - (A + 1) * cos); + a2 = (A + 1) - (A - 1) * cos - beta * sin; + } + break; + + case BiquadType.AllPass: + { + var allPassAlpha = cos / ( 2.0f * bandwidth ); + b0 = 1.0f - allPassAlpha; + b1 = -2.0f * cos; + b2 = 1.0f + allPassAlpha; + a0 = 1.0f + allPassAlpha; + a1 = -2.0f * cos; + a2 = 1.0f - allPassAlpha; + } break; } - filter.a0 = b0 / a0; - filter.a1 = b1 / a0; - filter.a2 = b2 / a0; - filter.a3 = a1 / a0; - filter.a4 = a2 / a0; + var filter = new Biquad(); + + filter.b0 = b0 / a0; + filter.b1 = b1 / a0; + filter.b2 = b2 / a0; + filter.a1 = a1 / a0; + filter.a2 = a2 / a0; filter.x1 = filter.x2 = 0; filter.y1 = filter.y2 = 0;