From 1342a5329e8e4af1be39a8ad2a09d29589d03c36 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 23 Feb 2025 16:40:41 +0100 Subject: [PATCH 1/2] Add fi._fb_comb() function, generic feed-back comb filter The next patch will add the users of the new funtion. --- filters.lib | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/filters.lib b/filters.lib index 147b538..04e07b2 100644 --- a/filters.lib +++ b/filters.lib @@ -247,6 +247,33 @@ declare ff_combfilter copyright "Copyright (C) 2003-2019 by Julius O. Smith III declare ff_combfilter license "MIT-style STK-4.3 license"; ffcombfilter(maxdel,del,g) = ff_comb(maxdel,del,1,g); +//---------------------`(fi.)_fb_comb`--------------------- +// A generic feed-back comb filter +// +// #### Usage +// +// ``` +// _ : _fb_comb(dop,N,b0,aN) : _ +// ``` +// +// Where +// +// * `dop`: delay operator, e.g. `@` or `de.fdelay4a(2048)` +// * `N`: current delay +// * `b0`: gain applied to input +// * `aN`: gain applied to delay-line output +// +// #### Example test program +// +// ``` +// process = _fb_comb(@,N,b0,aN); +// ``` +// implements the following difference equation: +// ``` +// y[n] = b0 x[n] + aN y[n - N] +// ``` +// -------------------------------------------------------- +_fb_comb(dop,N,b0,aN) = *(aN) + *(b0) ~ dop(N-1); //-----------------------`(fi.)fb_comb`----------------------- // Feed-Back Comb Filter (integer delay). From 9135fcc5c2854d0ff646e4152d7719c7f95482a0 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 23 Feb 2025 21:55:53 +0100 Subject: [PATCH 2/2] Reimplement fi.fb_comb() and fi.fb_fcomb() using fi._fb_comb() To ensure this patch is correct I used the following test-case maxdel = 10; N = 7.5; b0 = 1/2; aN = 1/3; maxerr = abs : max~_; // Old implementations before this patch o_fb_comb(maxdel,N,b0,aN) = (+ <: de.delay(maxdel,N-1),_) ~ *(-aN) : !,*(b0) : mem; o_fb_fcomb(maxdel,N,b0,aN) = (+ <: de.fdelay(maxdel,float(N)-1.0),_) ~ *(-aN) : !,*(b0) : mem; process = no.noise <: fi.fb_comb(maxdel,N,b0,aN) -o_fb_comb(maxdel,N,b0,aN), fi.fb_fcomb(maxdel,N,b0,aN) -o_fb_fcomb(maxdel,N,b0,aN) : par(i,2,maxerr); compiled with "-a plot.cpp". Result: $ ./test-plot -n 1000000 | tail -n 1 0 0 This patch makes the source code more understandable and the generated code more efficient. For example, the generated code for process = fi.fb_comb(15,10,1/3,1/4); before this patch: // class variables float fVec0[10]; float fRec0[2]; float fRec1[2]; int fSampleRate; void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { FAUSTFLOAT* input0 = inputs[0]; FAUSTFLOAT* output0 = outputs[0]; for (int i0 = 0; i0 < count; i0 = i0 + 1) { float fTemp0 = float(input0[i0]) - 0.25f * fRec0[1]; fVec0[0] = fTemp0; fRec0[0] = fVec0[9]; fRec1[0] = fTemp0; output0[i0] = FAUSTFLOAT(0.33333334f * fRec1[1]); for (int j0 = 9; j0 > 0; j0 = j0 - 1) { fVec0[j0] = fVec0[j0 - 1]; } fRec0[1] = fRec0[0]; fRec1[1] = fRec1[0]; } } after this patch: // class variables float fRec0[11]; int fSampleRate; void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { FAUSTFLOAT* input0 = inputs[0]; FAUSTFLOAT* output0 = outputs[0]; for (int i0 = 0; i0 < count; i0 = i0 + 1) { fRec0[0] = 0.33333334f * float(input0[i0]) - 0.25f * fRec0[10]; output0[i0] = FAUSTFLOAT(fRec0[1]); for (int j0 = 10; j0 > 0; j0 = j0 - 1) { fRec0[j0] = fRec0[j0 - 1]; } } } --- filters.lib | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/filters.lib b/filters.lib index 04e07b2..19f2565 100644 --- a/filters.lib +++ b/filters.lib @@ -272,6 +272,8 @@ ffcombfilter(maxdel,del,g) = ff_comb(maxdel,del,1,g); // ``` // y[n] = b0 x[n] + aN y[n - N] // ``` +// +// See more examples in `filters.lib` below. // -------------------------------------------------------- _fb_comb(dop,N,b0,aN) = *(aN) + *(b0) ~ dop(N-1); @@ -299,8 +301,7 @@ _fb_comb(dop,N,b0,aN) = *(aN) + *(b0) ~ dop(N-1); declare fb_comb author "Julius O. Smith III"; declare fb_comb copyright "Copyright (C) 2003-2019 by Julius O. Smith III "; declare fb_comb license "MIT-style STK-4.3 license"; -fb_comb(maxdel,N,b0,aN) = (+ <: de.delay(maxdel,N-1),_) ~ *(-aN) : !,*(b0) : mem; - +fb_comb(maxdel,N,b0,aN) = _fb_comb(de.delay(maxdel),N,b0,-aN) : mem; //-----------------------`(fi.)fb_fcomb`----------------------- // Feed-Back Comb Filter (floating point delay). @@ -326,7 +327,7 @@ fb_comb(maxdel,N,b0,aN) = (+ <: de.delay(maxdel,N-1),_) ~ *(-aN) : !,*(b0) : mem declare fb_fcomb author "Julius O. Smith III"; declare fb_fcomb copyright "Copyright (C) 2003-2019 by Julius O. Smith III "; declare fb_fcomb license "MIT-style STK-4.3 license"; -fb_fcomb(maxdel,N,b0,aN) = (+ <: de.fdelay(maxdel,float(N)-1.0),_) ~ *(-aN) : !,*(b0) : mem; +fb_fcomb(maxdel,N,b0,aN) = _fb_comb(de.fdelay(maxdel),N,b0,-aN) : mem; //-----------------------`(fi.)rev1`----------------------- // Special case of `fb_comb` (`rev1(maxdel,N,g)`).