aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormusil <tmusil@users.sourceforge.net>2008-12-11 19:43:26 +0000
committermusil <tmusil@users.sourceforge.net>2008-12-11 19:43:26 +0000
commitf880e7082f1ee1bc081ca98c031eb959a355e576 (patch)
treef04e59455a0660526053a4e63d2deed1b3f45b9d
parent150c23c7abdc3b915ff3763d639768e081af7759 (diff)
single or double precision for filter~
svn path=/trunk/externals/iemlib/; revision=10446
-rw-r--r--iemlib1/src/filter~.c1413
1 files changed, 1115 insertions, 298 deletions
diff --git a/iemlib1/src/filter~.c b/iemlib1/src/filter~.c
index cd90fb5..c26b4c8 100644
--- a/iemlib1/src/filter~.c
+++ b/iemlib1/src/filter~.c
@@ -1,7 +1,7 @@
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
-iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */
+iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2008 */
#include "m_pd.h"
@@ -10,40 +10,82 @@ iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006
/* ---------- filter~ - slow dynamic filter-kernel 1. and 2. order ----------- */
+/* ---------- with double precision option ----------------------------------- */
+
+typedef struct _float_filter_para_tilde
+{
+ t_float wn1;// old wn of biquad recursion
+ t_float wn2;// two times old wn of biquad recursion
+ t_float a0;// wn factor of numerator term of biquad recursion
+ t_float a1;// wn1 factor of numerator term of biquad recursion
+ t_float a2;// wn2 factor of numerator term of biquad recursion
+ t_float b1;// wn1 factor of denominator term of biquad recursion
+ t_float b2;// wn2 factor of denominator term of biquad recursion
+ t_float pi_over_sr;// pi/samplerate
+ t_float cur_f;// current frequency
+ t_float cur_l;// current bilinear transformed frequency
+ t_float cur_a;// current damping
+ t_float cur_b;// current freqency shifting factor
+ t_float delta_f;// frequency ratio from previous to current frequency
+ t_float delta_a;// damping ratio from previous to current damping
+ t_float delta_b;// freqency shift ratio from previous to current freqency shift
+ t_float end_f;// destination frequency
+ t_float end_a;// destination damping
+ t_float end_b;// destination freqency shift
+ t_float ticks_per_interpol_time;// dsp ticks per interpolation time intervall
+ t_float rcp_ticks;// reciprocal number of dsp ticks within intervall
+ t_float interpol_time;// interpolation time
+ int ticks;// number of dsp ticks within intervall
+ int counter_f;// number of dsp ticks to compute new frequency
+ int counter_a;// number of dsp ticks to compute new damping
+ int counter_b;// number of dsp ticks to compute new frequency shift
+ int inlet3_is_Q1_or_damping0;// if flag is HIGH, the third inlet (Q) has to be inverted to damping
+ int filter_function_is_highpass;// flag is HIGH if filter has highpass characteristic
+ int filter_function_is_first_order;// flag is HIGH if filter is first order
+ int event_mask;// a three bit mask: Bit 0 is HIGH during frequency ramp, Bit 1 is HIGH during damping ramp, Bit 2 is HIGH during frequency shift ramp
+ void (*calc)();
+} t_float_filter_para_tilde;
+
+typedef struct _double_filter_para_tilde
+{
+ double wn1;// old wn of biquad recursion
+ double wn2;// two times old wn of biquad recursion
+ double a0;// wn factor of numerator term of biquad recursion
+ double a1;// wn1 factor of numerator term of biquad recursion
+ double a2;// wn2 factor of numerator term of biquad recursion
+ double b1;// wn1 factor of denominator term of biquad recursion
+ double b2;// wn2 factor of denominator term of biquad recursion
+ double pi_over_sr;// pi/samplerate
+ double cur_f;// current frequency
+ double cur_l;// current bilinear transformed frequency
+ double cur_a;// current damping
+ double cur_b;// current freqency shifting factor
+ double delta_f;// frequency ratio from previous to current frequency
+ double delta_a;// damping ratio from previous to current damping
+ double delta_b;// freqency shift ratio from previous to current freqency shift
+ double end_f;// destination frequency
+ double end_a;// destination damping
+ double end_b;// destination freqency shift
+ double ticks_per_interpol_time;// dsp ticks per interpolation time intervall
+ double rcp_ticks;// reciprocal number of dsp ticks within intervall
+ double interpol_time;// interpolation time
+ int ticks;// number of dsp ticks within intervall
+ int counter_f;// number of dsp ticks to compute new frequency
+ int counter_a;// number of dsp ticks to compute new damping
+ int counter_b;// number of dsp ticks to compute new frequency shift
+ int inlet3_is_Q1_or_damping0;// if flag is HIGH, the third inlet (Q) has to be inverted to damping
+ int filter_function_is_highpass;// flag is HIGH if filter has highpass characteristic
+ int filter_function_is_first_order;// flag is HIGH if filter is first order
+ int event_mask;// a three bit mask: Bit 0 is HIGH during frequency ramp, Bit 1 is HIGH during damping ramp, Bit 2 is HIGH during frequency shift ramp
+ void (*calc)();
+} t_double_filter_para_tilde;
typedef struct _filter_tilde
{
t_object x_obj;
- t_float wn1;
- t_float wn2;
- t_float a0;
- t_float a1;
- t_float a2;
- t_float b1;
- t_float b2;
- t_float sr;
- t_float cur_f;
- t_float cur_l;
- t_float cur_a;
- t_float cur_b;
- t_float delta_f;
- t_float delta_a;
- t_float delta_b;
- t_float end_f;
- t_float end_a;
- t_float end_b;
- t_float ticks_per_interpol_time;
- t_float rcp_ticks;
- t_float interpol_time;
- int ticks;
- int counter_f;
- int counter_a;
- int counter_b;
- int inv;
- int hp;
- int first_order;
- int event_mask;
- void (*calc)();
+ t_float_filter_para_tilde fp;
+ t_double_filter_para_tilde dp;
+ int precision_d1_f0;
void *x_debug_outlet;
t_atom x_at[5];
t_float x_msi;
@@ -51,12 +93,12 @@ typedef struct _filter_tilde
static t_class *filter_tilde_class;
-static void filter_tilde_snafu(t_filter_tilde *x)
+static void filter_tilde_snafu(t_float_filter_para_tilde *x)
{
}
-static void filter_tilde_lp1(t_filter_tilde *x)
+static void filter_tilde_lp1(t_float_filter_para_tilde *x)
{
t_float al;
@@ -66,7 +108,7 @@ static void filter_tilde_lp1(t_filter_tilde *x)
x->b1 = (al - 1.0f)*x->a0;
}
-static void filter_tilde_lp2(t_filter_tilde *x)
+static void filter_tilde_lp2(t_float_filter_para_tilde *x)
{
t_float l, al, bl2, rcp;
@@ -81,7 +123,7 @@ static void filter_tilde_lp2(t_filter_tilde *x)
x->b2 = rcp*(al - bl2);
}
-static void filter_tilde_hp1(t_filter_tilde *x)
+static void filter_tilde_hp1(t_float_filter_para_tilde *x)
{
t_float al, rcp;
@@ -92,7 +134,7 @@ static void filter_tilde_hp1(t_filter_tilde *x)
x->b1 = rcp*(al - 1.0f);
}
-static void filter_tilde_hp2(t_filter_tilde *x)
+static void filter_tilde_hp2(t_float_filter_para_tilde *x)
{
t_float l, al, bl2, rcp;
@@ -107,7 +149,7 @@ static void filter_tilde_hp2(t_filter_tilde *x)
x->b2 = rcp*(al - bl2);
}
-static void filter_tilde_rp2(t_filter_tilde *x)
+static void filter_tilde_rp2(t_float_filter_para_tilde *x)
{
t_float l, al, l2, rcp;
@@ -121,7 +163,7 @@ static void filter_tilde_rp2(t_filter_tilde *x)
x->b2 = rcp*(al - l2);
}
-static void filter_tilde_bp2(t_filter_tilde *x)
+static void filter_tilde_bp2(t_float_filter_para_tilde *x)
{
t_float l, al, l2, rcp;
@@ -135,7 +177,7 @@ static void filter_tilde_bp2(t_filter_tilde *x)
x->b2 = rcp*(al - l2);
}
-static void filter_tilde_bs2(t_filter_tilde *x)
+static void filter_tilde_bs2(t_float_filter_para_tilde *x)
{
t_float l, al, l2, rcp;
@@ -150,7 +192,7 @@ static void filter_tilde_bs2(t_filter_tilde *x)
x->b2 = rcp*(al - l2);
}
-static void filter_tilde_rpw2(t_filter_tilde *x)
+static void filter_tilde_rpw2(t_float_filter_para_tilde *x)
{
t_float l, al, l2, rcp;
@@ -164,7 +206,7 @@ static void filter_tilde_rpw2(t_filter_tilde *x)
x->b2 = rcp*(al - l2);
}
-static void filter_tilde_bpw2(t_filter_tilde *x)
+static void filter_tilde_bpw2(t_float_filter_para_tilde *x)
{
t_float l, al, l2, rcp;
@@ -178,7 +220,7 @@ static void filter_tilde_bpw2(t_filter_tilde *x)
x->b2 = rcp*(al - l2);
}
-static void filter_tilde_bsw2(t_filter_tilde *x)
+static void filter_tilde_bsw2(t_float_filter_para_tilde *x)
{
t_float l, al, l2, rcp;
@@ -193,7 +235,7 @@ static void filter_tilde_bsw2(t_filter_tilde *x)
x->b2 = rcp*(al - l2);
}
-static void filter_tilde_ap1(t_filter_tilde *x)
+static void filter_tilde_ap1(t_float_filter_para_tilde *x)
{
t_float al;
@@ -202,7 +244,7 @@ static void filter_tilde_ap1(t_filter_tilde *x)
x->b1 = -x->a0;
}
-static void filter_tilde_ap2(t_filter_tilde *x)
+static void filter_tilde_ap2(t_float_filter_para_tilde *x)
{
t_float l, al, bl2, rcp;
@@ -230,7 +272,167 @@ t_float l, al, l2, rcp;
x->b2 = rcp*(l2 - al);
}*/
-static void filter_tilde_dsp_tick(t_filter_tilde *x)
+static void filter_tilde_dlp1(t_double_filter_para_tilde *x)
+{
+ double al;
+
+ al = x->cur_a * x->cur_l;
+ x->a0 = 1.0/(1.0 + al);
+ x->a1 = x->a0;
+ x->b1 = (al - 1.0)*x->a0;
+}
+
+static void filter_tilde_dlp2(t_double_filter_para_tilde *x)
+{
+ double l, al, bl2, rcp;
+
+ l = x->cur_l;
+ al = l*x->cur_a;
+ bl2 = l*l*x->cur_b + 1.0;
+ rcp = 1.0/(al + bl2);
+ x->a0 = rcp;
+ x->a1 = 2.0*rcp;
+ x->a2 = x->a0;
+ x->b1 = rcp*2.0*(bl2 - 2.0);
+ x->b2 = rcp*(al - bl2);
+}
+
+static void filter_tilde_dhp1(t_double_filter_para_tilde *x)
+{
+ double al, rcp;
+
+ al = x->cur_a * x->cur_l;
+ rcp = 1.0/(1.0 + al);
+ x->a0 = rcp*al;
+ x->a1 = -x->a0;
+ x->b1 = rcp*(al - 1.0);
+}
+
+static void filter_tilde_dhp2(t_double_filter_para_tilde *x)
+{
+ double l, al, bl2, rcp;
+
+ l = x->cur_l;
+ bl2 = l*l*x->cur_b + 1.0;
+ al = l*x->cur_a;
+ rcp = 1.0/(al + bl2);
+ x->a0 = rcp*(bl2 - 1.0);
+ x->a1 = -2.0*x->a0;
+ x->a2 = x->a0;
+ x->b1 = rcp*2.0*(bl2 - 2.0);
+ x->b2 = rcp*(al - bl2);
+}
+
+static void filter_tilde_drp2(t_double_filter_para_tilde *x)
+{
+ double l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0;
+ al = l*x->cur_a;
+ rcp = 1.0/(al + l2);
+ x->a0 = rcp*l;
+ x->a2 = -x->a0;
+ x->b1 = rcp*2.0*(l2 - 2.0);
+ x->b2 = rcp*(al - l2);
+}
+
+static void filter_tilde_dbp2(t_double_filter_para_tilde *x)
+{
+ double l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0;
+ al = l*x->cur_a;
+ rcp = 1.0/(al + l2);
+ x->a0 = rcp*al;
+ x->a2 = -x->a0;
+ x->b1 = rcp*2.0*(l2 - 2.0);
+ x->b2 = rcp*(al - l2);
+}
+
+static void filter_tilde_dbs2(t_double_filter_para_tilde *x)
+{
+ double l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0;
+ al = l*x->cur_a;
+ rcp = 1.0/(al + l2);
+ x->a0 = rcp*l2;
+ x->a1 = rcp*2.0*(2.0 - l2);
+ x->a2 = x->a0;
+ x->b1 = -x->a1;
+ x->b2 = rcp*(al - l2);
+}
+
+static void filter_tilde_drpw2(t_double_filter_para_tilde *x)
+{
+ double l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0;
+ al = l*x->cur_a/x->cur_f;
+ rcp = 1.0/(al + l2);
+ x->a0 = rcp*l;
+ x->a2 = -x->a0;
+ x->b1 = rcp*2.0*(l2 - 2.0);
+ x->b2 = rcp*(al - l2);
+}
+
+static void filter_tilde_dbpw2(t_double_filter_para_tilde *x)
+{
+ double l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0;
+ al = l*x->cur_a/x->cur_f;
+ rcp = 1.0/(al + l2);
+ x->a0 = rcp*al;
+ x->a2 = -x->a0;
+ x->b1 = rcp*2.0*(l2 - 2.0);
+ x->b2 = rcp*(al - l2);
+}
+
+static void filter_tilde_dbsw2(t_double_filter_para_tilde *x)
+{
+ double l, al, l2, rcp;
+
+ l = x->cur_l;
+ l2 = l*l + 1.0;
+ al = l*x->cur_a/x->cur_f;
+ rcp = 1.0/(al + l2);
+ x->a0 = rcp*l2;
+ x->a1 = rcp*2.0*(2.0 - l2);
+ x->a2 = x->a0;
+ x->b1 = -x->a1;
+ x->b2 = rcp*(al - l2);
+}
+
+static void filter_tilde_dap1(t_double_filter_para_tilde *x)
+{
+ double al;
+
+ al = x->cur_a * x->cur_l;
+ x->a0 = (1.0 - al)/(1.0 + al);
+ x->b1 = -x->a0;
+}
+
+static void filter_tilde_dap2(t_double_filter_para_tilde *x)
+{
+ double l, al, bl2, rcp;
+
+ l = x->cur_l;
+ bl2 = l*l*x->cur_b + 1.0;
+ al = l*x->cur_a;
+ rcp = 1.0/(al + bl2);
+ x->a1 = rcp*2.0*(2.0 - bl2);
+ x->a0 = rcp*(bl2 - al);
+ x->b1 = -x->a1;
+ x->b2 = -x->a0;
+}
+
+static void filter_tilde_dsp_tick(t_float_filter_para_tilde *x)
{
if(x->event_mask)
{
@@ -249,7 +451,7 @@ static void filter_tilde_dsp_tick(t_filter_tilde *x)
x->counter_f--;
x->cur_f *= x->delta_f;
}
- l = x->cur_f * x->sr;
+ l = x->cur_f * x->pi_over_sr;
if(l < 1.0e-20f)
x->cur_l = 1.0e20f;
else if(l > 1.57079632f)
@@ -293,7 +495,7 @@ static void filter_tilde_dsp_tick(t_filter_tilde *x)
(*(x->calc))(x);
/* stability check */
- if(x->first_order)
+ if(x->filter_function_is_first_order)
{
if(x->b1 <= -0.9999998f)
x->b1 = -0.9999998f;
@@ -322,6 +524,103 @@ static void filter_tilde_dsp_tick(t_filter_tilde *x)
x->b2 = 0.9999998f + x->b1;
}
}
+ //post("float a0=%f, a1=%f, a2=%f, b1=%f, b2=%f", x->a0, x->a1, x->a2, x->b1, x->b2);
+ }
+}
+
+static void filter_tilde_dsp_dtick(t_double_filter_para_tilde *x)
+{
+ if(x->event_mask)
+ {
+ if(x->counter_f)
+ {
+ double l, si, co;
+
+ if(x->counter_f <= 1)
+ {
+ x->cur_f = x->end_f;
+ x->counter_f = 0;
+ x->event_mask &= 6;/*set event_mask_bit 0 = 0*/
+ }
+ else
+ {
+ x->counter_f--;
+ x->cur_f *= x->delta_f;
+ }
+ l = x->cur_f * x->pi_over_sr;
+ if(l < 1.0e-20)
+ x->cur_l = 1.0e20;
+ else if(l > 1.57079632)
+ x->cur_l = 0.0;
+ else
+ {
+ si = sin(l);
+ co = cos(l);
+ x->cur_l = co/si;
+ }
+ }
+ if(x->counter_a)
+ {
+ if(x->counter_a <= 1)
+ {
+ x->cur_a = x->end_a;
+ x->counter_a = 0;
+ x->event_mask &= 5;/*set event_mask_bit 1 = 0*/
+ }
+ else
+ {
+ x->counter_a--;
+ x->cur_a *= x->delta_a;
+ }
+ }
+ if(x->counter_b)
+ {
+ if(x->counter_b <= 1)
+ {
+ x->cur_b = x->end_b;
+ x->counter_b = 0;
+ x->event_mask &= 3;/*set event_mask_bit 2 = 0*/
+ }
+ else
+ {
+ x->counter_b--;
+ x->cur_b *= x->delta_b;
+ }
+ }
+
+ (*(x->calc))(x);
+
+ /* stability check */
+ if(x->filter_function_is_first_order)
+ {
+ if(x->b1 <= -0.9999998)
+ x->b1 = -0.9999998;
+ else if(x->b1 >= 0.9999998)
+ x->b1 = 0.9999998;
+ }
+ else
+ {
+ double discriminant = x->b1 * x->b1 + 4.0 * x->b2;
+
+ if(x->b1 <= -1.9999996)
+ x->b1 = -1.9999996;
+ else if(x->b1 >= 1.9999996)
+ x->b1 = 1.9999996;
+
+ if(x->b2 <= -0.9999998)
+ x->b2 = -0.9999998;
+ else if(x->b2 >= 0.9999998)
+ x->b2 = 0.9999998;
+
+ if(discriminant >= 0.0)
+ {
+ if(0.9999998 - x->b1 - x->b2 < 0.0)
+ x->b2 = 0.9999998 - x->b1;
+ if(0.9999998 + x->b1 - x->b2 < 0.0)
+ x->b2 = 0.9999998 + x->b1;
+ }
+ }
+ //post("double a0=%f, a1=%f, a2=%f, b1=%f, b2=%f", (t_float)x->a0, (t_float)x->a1, (t_float)x->a2, (t_float)x->b1, (t_float)x->b2);
}
}
@@ -331,11 +630,11 @@ static t_int *filter_tilde_perform_2o(t_int *w)
t_float *out = (float *)(w[2]);
t_filter_tilde *x = (t_filter_tilde *)(w[3]);
int i, n = (t_int)(w[4]);
- t_float wn0, wn1=x->wn1, wn2=x->wn2;
- t_float a0=x->a0, a1=x->a1, a2=x->a2;
- t_float b1=x->b1, b2=x->b2;
+ t_float wn0, wn1=x->fp.wn1, wn2=x->fp.wn2;
+ t_float a0=x->fp.a0, a1=x->fp.a1, a2=x->fp.a2;
+ t_float b1=x->fp.b1, b2=x->fp.b2;
- filter_tilde_dsp_tick(x);
+ filter_tilde_dsp_tick(&x->fp);
for(i=0; i<n; i++)
{
wn0 = *in++ + b1*wn1 + b2*wn2;
@@ -349,8 +648,8 @@ static t_int *filter_tilde_perform_2o(t_int *w)
if(IEM_DENORMAL(wn1))
wn1 = 0.0f;
- x->wn1 = wn1;
- x->wn2 = wn2;
+ x->fp.wn1 = wn1;
+ x->fp.wn2 = wn2;
return(w+5);
}
/* yn0 = *out;
@@ -371,12 +670,12 @@ static t_int *filter_tilde_perf8_2o(t_int *w)
t_filter_tilde *x = (t_filter_tilde *)(w[3]);
int i, n = (t_int)(w[4]);
t_float wn[10];
- t_float a0=x->a0, a1=x->a1, a2=x->a2;
- t_float b1=x->b1, b2=x->b2;
+ t_float a0=x->fp.a0, a1=x->fp.a1, a2=x->fp.a2;
+ t_float b1=x->fp.b1, b2=x->fp.b2;
- filter_tilde_dsp_tick(x);
- wn[0] = x->wn2;
- wn[1] = x->wn1;
+ filter_tilde_dsp_tick(&x->fp);
+ wn[0] = x->fp.wn2;
+ wn[1] = x->fp.wn1;
for(i=0; i<n; i+=8, in+=8, out+=8)
{
wn[2] = in[0] + b1*wn[1] + b2*wn[0];
@@ -404,8 +703,8 @@ static t_int *filter_tilde_perf8_2o(t_int *w)
if(IEM_DENORMAL(wn[1]))
wn[1] = 0.0f;
- x->wn1 = wn[1];
- x->wn2 = wn[0];
+ x->fp.wn1 = wn[1];
+ x->fp.wn2 = wn[0];
return(w+5);
}
@@ -415,11 +714,11 @@ static t_int *filter_tilde_perform_1o(t_int *w)
t_float *out = (float *)(w[2]);
t_filter_tilde *x = (t_filter_tilde *)(w[3]);
int i, n = (t_int)(w[4]);
- t_float wn0, wn1=x->wn1;
- t_float a0=x->a0, a1=x->a1;
- t_float b1=x->b1;
+ t_float wn0, wn1=x->fp.wn1;
+ t_float a0=x->fp.a0, a1=x->fp.a1;
+ t_float b1=x->fp.b1;
- filter_tilde_dsp_tick(x);
+ filter_tilde_dsp_tick(&x->fp);
for(i=0; i<n; i++)
{
wn0 = *in++ + b1*wn1;
@@ -430,7 +729,7 @@ static t_int *filter_tilde_perform_1o(t_int *w)
if(IEM_DENORMAL(wn1))
wn1 = 0.0f;
- x->wn1 = wn1;
+ x->fp.wn1 = wn1;
return(w+5);
}
@@ -441,11 +740,11 @@ static t_int *filter_tilde_perf8_1o(t_int *w)
t_filter_tilde *x = (t_filter_tilde *)(w[3]);
int i, n = (t_int)(w[4]);
t_float wn[9];
- t_float a0=x->a0, a1=x->a1;
- t_float b1=x->b1;
+ t_float a0=x->fp.a0, a1=x->fp.a1;
+ t_float b1=x->fp.b1;
- filter_tilde_dsp_tick(x);
- wn[0] = x->wn1;
+ filter_tilde_dsp_tick(&x->fp);
+ wn[0] = x->fp.wn1;
for(i=0; i<n; i+=8, in+=8, out+=8)
{
wn[1] = in[0] + b1*wn[0];
@@ -470,330 +769,849 @@ static t_int *filter_tilde_perf8_1o(t_int *w)
if(IEM_DENORMAL(wn[0]))
wn[0] = 0.0f;
- x->wn1 = wn[0];
+ x->fp.wn1 = wn[0];
return(w+5);
}
-static void filter_tilde_ft4(t_filter_tilde *x, t_floatarg t)
+static t_int *filter_tilde_dperform_2o(t_int *w)
{
- int i = (int)((x->ticks_per_interpol_time)*t+0.49999f);
+ t_float *in = (t_float *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_filter_tilde *x = (t_filter_tilde *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ double wn0, wn1=x->dp.wn1, wn2=x->dp.wn2;
+ double a0=x->dp.a0, a1=x->dp.a1, a2=x->dp.a2;
+ double b1=x->dp.b1, b2=x->dp.b2;
- x->interpol_time = t;
- if(i <= 0)
- {
- x->ticks = 1;
- x->rcp_ticks = 1.0;
- }
- else
+ filter_tilde_dsp_dtick(&x->dp);
+ for(i=0; i<n; i++)
{
- x->ticks = i;
- x->rcp_ticks = 1.0 / (t_float)i;
+ wn0 = (double)(*in++) + b1*wn1 + b2*wn2;
+ *out++ = (t_float)(a0*wn0 + a1*wn1 + a2*wn2);
+ wn2 = wn1;
+ wn1 = wn0;
}
+ /* NAN protect */
+ // if(IEM_DENORMAL(wn2))
+ // wn2 = 0.0f;
+ // if(IEM_DENORMAL(wn1))
+ // wn1 = 0.0f;
+
+ x->dp.wn1 = wn1;
+ x->dp.wn2 = wn2;
+ return(w+5);
}
+/* yn0 = *out;
+xn0 = *in;
+*************
+yn0 = a0*xn0 + a1*xn1 + a2*xn2 + b1*yn1 + b2*yn2;
+yn2 = yn1;
+yn1 = yn0;
+xn2 = xn1;
+xn1 = xn0;
+*************************
+y/x = (a0 + a1*z-1 + a2*z-2)/(1 - b1*z-1 - b2*z-2);*/
-static void filter_tilde_ft3(t_filter_tilde *x, t_floatarg b)
+static t_int *filter_tilde_dperf8_2o(t_int *w)
{
- if(b <= 0.0f)
- b = 0.000001f;
- if(x->hp)
- b = 1.0 / b;
- if(b != x->cur_b)
+ t_float *in = (t_float *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_filter_tilde *x = (t_filter_tilde *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ double wn[10];
+ double a0=x->dp.a0, a1=x->dp.a1, a2=x->dp.a2;
+ double b1=x->dp.b1, b2=x->dp.b2;
+
+ filter_tilde_dsp_dtick(&x->dp);
+ wn[0] = x->dp.wn2;
+ wn[1] = x->dp.wn1;
+ for(i=0; i<n; i+=8, in+=8, out+=8)
{
- x->end_b = b;
- x->counter_b = x->ticks;
- x->delta_b = exp(log(b/x->cur_b)*x->rcp_ticks);
- x->event_mask |= 4;/*set event_mask_bit 2 = 1*/
+ wn[2] = (double)(in[0]) + b1*wn[1] + b2*wn[0];
+ out[0] = (t_float)(a0*wn[2] + a1*wn[1] + a2*wn[0]);
+ wn[3] = (double)(in[1]) + b1*wn[2] + b2*wn[1];
+ out[1] = (t_float)(a0*wn[3] + a1*wn[2] + a2*wn[1]);
+ wn[4] = (double)(in[2]) + b1*wn[3] + b2*wn[2];
+ out[2] = (t_float)(a0*wn[4] + a1*wn[3] + a2*wn[2]);
+ wn[5] = (double)(in[3]) + b1*wn[4] + b2*wn[3];
+ out[3] = (t_float)(a0*wn[5] + a1*wn[4] + a2*wn[3]);
+ wn[6] = (double)(in[4]) + b1*wn[5] + b2*wn[4];
+ out[4] = (t_float)(a0*wn[6] + a1*wn[5] + a2*wn[4]);
+ wn[7] = (double)(in[5]) + b1*wn[6] + b2*wn[5];
+ out[5] = (t_float)(a0*wn[7] + a1*wn[6] + a2*wn[5]);
+ wn[8] = (double)(in[6]) + b1*wn[7] + b2*wn[6];
+ out[6] = (t_float)(a0*wn[8] + a1*wn[7] + a2*wn[6]);
+ wn[9] = (double)(in[7]) + b1*wn[8] + b2*wn[7];
+ out[7] = (t_float)(a0*wn[9] + a1*wn[8] + a2*wn[7]);
+ wn[0] = wn[8];
+ wn[1] = wn[9];
}
+ /* NAN protect */
+ // if(IEM_DENORMAL(wn[0]))
+ // wn[0] = 0.0f;
+ // if(IEM_DENORMAL(wn[1]))
+ // wn[1] = 0.0f;
+
+ /*BIGORSMALL:
+ tabfudge union double long[2]
+ if((long[0]&0x7c000000==0x0x40000000)||(long[0]&0x7c000000==0x0x3c000000))
+ double=0.0;
+
+ erstes bit ist signum
+ die naechsten 11 bit sind exponent
+ +2.0 ist 0x400
+ +4.0 ist 0x401
+ -4.0 ist 0xC01
+ ca. +8.0e+019 ist Sprung von 0x43F auf 0x440 0100.0011.1111 - 0100.0100.0000
+ ca. -8.0e+019 ist Sprung von 0xC3F auf 0xC40 1100.0011.1111 - 1100.0100.0000
+ ca. +8.0e-019 ist Sprung von 0x3C0 auf 0x3BF 0011.1100.0000 - 0011.1011.1111
+ ca. -8.0e-019 ist Sprung von 0xBC0 auf 0xBBF 1011.1100.0000 - 1011.1011.1111
+
+ 0100.0100.0000
+ 0100.0011.1111
+ 0011.1100.0000
+ 0011.1011.1111
+
+ mask = 0x7c
+
+ 100.01
+ 100.00}\
+ 011.11}/
+ 011.10
+
+
+ */
+
+ x->dp.wn1 = wn[1];
+ x->dp.wn2 = wn[0];
+ return(w+5);
}
-static void filter_tilde_ft2(t_filter_tilde *x, t_floatarg a)
+static t_int *filter_tilde_dperform_1o(t_int *w)
{
- if(a <= 0.0f)
- a = 0.000001f;
- if(x->inv)
- a = 1.0f / a;
- if(x->hp)
- a /= x->cur_b;
- if(a != x->cur_a)
+ t_float *in = (t_float *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_filter_tilde *x = (t_filter_tilde *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ double wn0, wn1=x->dp.wn1;
+ double a0=x->dp.a0, a1=x->dp.a1;
+ double b1=x->dp.b1;
+
+ filter_tilde_dsp_dtick(&x->dp);
+ for(i=0; i<n; i++)
{
- x->end_a = a;
- x->counter_a = x->ticks;
- x->delta_a = exp(log(a/x->cur_a)*x->rcp_ticks);
- x->event_mask |= 2;/*set event_mask_bit 1 = 1*/
+ wn0 = (double)(*in++) + b1*wn1;
+ *out++ = (t_float)(a0*wn0 + a1*wn1);
+ wn1 = wn0;
}
+ /* NAN protect */
+ // if(IEM_DENORMAL(wn1))
+ // wn1 = 0.0f;
+
+ x->dp.wn1 = wn1;
+ return(w+5);
}
-static void filter_tilde_ft1(t_filter_tilde *x, t_floatarg f)
+static t_int *filter_tilde_dperf8_1o(t_int *w)
{
- if(f <= 0.0f)
- f = 0.000001f;
- if(f != x->cur_f)
+ t_float *in = (t_float *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_filter_tilde *x = (t_filter_tilde *)(w[3]);
+ int i, n = (t_int)(w[4]);
+ double wn[9];
+ double a0=x->dp.a0, a1=x->dp.a1;
+ double b1=x->dp.b1;
+
+ filter_tilde_dsp_dtick(&x->dp);
+ wn[0] = x->dp.wn1;
+ for(i=0; i<n; i+=8, in+=8, out+=8)
{
- x->end_f = f;
- x->counter_f = x->ticks;
- x->delta_f = exp(log(f/x->cur_f)*x->rcp_ticks);
- x->event_mask |= 1;/*set event_mask_bit 0 = 1*/
+ wn[1] = (double)(in[0]) + b1*wn[0];
+ out[0] = (t_float)(a0*wn[1] + a1*wn[0]);
+ wn[2] = (double)(in[1]) + b1*wn[1];
+ out[1] = (t_float)(a0*wn[2] + a1*wn[1]);
+ wn[3] = (double)(in[2]) + b1*wn[2];
+ out[2] = (t_float)(a0*wn[3] + a1*wn[2]);
+ wn[4] = (double)(in[3]) + b1*wn[3];
+ out[3] = (t_float)(a0*wn[4] + a1*wn[3]);
+ wn[5] = (double)(in[4]) + b1*wn[4];
+ out[4] = (t_float)(a0*wn[5] + a1*wn[4]);
+ wn[6] = (double)(in[5]) + b1*wn[5];
+ out[5] = (t_float)(a0*wn[6] + a1*wn[5]);
+ wn[7] = (double)(in[6]) + b1*wn[6];
+ out[6] = (t_float)(a0*wn[7] + a1*wn[6]);
+ wn[8] = (double)(in[7]) + b1*wn[7];
+ out[7] = (t_float)(a0*wn[8] + a1*wn[7]);
+ wn[0] = wn[8];
}
+ /* NAN protect */
+ // if(IEM_DENORMAL(wn[0]))
+ // wn[0] = 0.0f;
+
+ x->dp.wn1 = wn[0];
+ return(w+5);
}
-static void filter_tilde_print(t_filter_tilde *x)
-{
- // post("fb1 = %g, fb2 = %g, ff1 = %g, ff2 = %g, ff3 = %g", x->b1, x->b2, x->a0, x->a1, x->a2);
- x->x_at[0].a_w.w_float = x->b1;
- x->x_at[1].a_w.w_float = x->b2;
- x->x_at[2].a_w.w_float = x->a0;
- x->x_at[3].a_w.w_float = x->a1;
- x->x_at[4].a_w.w_float = x->a2;
- outlet_list(x->x_debug_outlet, &s_list, 5, x->x_at);
-}
-
-static void filter_tilde_dsp(t_filter_tilde *x, t_signal **sp)
+static void filter_tilde_ft4(t_filter_tilde *x, t_float t)
{
- t_float si, co, f;
- int i, n=(int)sp[0]->s_n;
-
- x->sr = 3.14159265358979323846f / (t_float)(sp[0]->s_sr);
- x->ticks_per_interpol_time = 0.001f * (t_float)(sp[0]->s_sr) / (t_float)n;
- i = (int)((x->ticks_per_interpol_time)*(x->interpol_time)+0.49999f);
- if(i <= 0)
+ if(x->precision_d1_f0)
{
- x->ticks = 1;
- x->rcp_ticks = 1.0f;
+ double dt=(double)t;
+ int di = (int)((x->dp.ticks_per_interpol_time)*dt+0.49999);
+
+ x->dp.interpol_time = dt;
+ if(di <= 0)
+ {
+ x->dp.ticks = 1;
+ x->dp.rcp_ticks = 1.0;
+ }
+ else
+ {
+ x->dp.ticks = di;
+ x->dp.rcp_ticks = 1.0 / (double)di;
+ }
}
else
{
- x->ticks = i;
- x->rcp_ticks = 1.0f / (t_float)i;
+ int i = (int)((x->fp.ticks_per_interpol_time)*t+0.49999f);
+
+ x->fp.interpol_time = t;
+ if(i <= 0)
+ {
+ x->fp.ticks = 1;
+ x->fp.rcp_ticks = 1.0;
+ }
+ else
+ {
+ x->fp.ticks = i;
+ x->fp.rcp_ticks = 1.0 / (t_float)i;
+ }
+ }
+}
+
+static void filter_tilde_ft3(t_filter_tilde *x, t_float b)
+{
+ if(x->precision_d1_f0)
+ {
+ double db=(double)b;
+
+ if(db <= 0.0)
+ db = 0.000001;
+ if(x->dp.filter_function_is_highpass)
+ db = 1.0 / db;
+ if(db != x->dp.cur_b)
+ {
+ x->dp.end_b = db;
+ x->dp.counter_b = x->dp.ticks;
+ x->dp.delta_b = exp(log(db/x->dp.cur_b)*x->dp.rcp_ticks);
+ x->dp.event_mask |= 4;/*set event_mask_bit 2 = 1*/
+ }
}
- f = x->cur_f * x->sr;
- if(f < 1.0e-20f)
- x->cur_l = 1.0e20f;
- else if(f > 1.57079632f)
- x->cur_l = 0.0f;
else
{
- si = sin(f);
- co = cos(f);
- x->cur_l = co/si;
+ if(b <= 0.0f)
+ b = 0.000001f;
+ if(x->fp.filter_function_is_highpass)
+ b = 1.0f / b;
+ if(b != x->fp.cur_b)
+ {
+ x->fp.end_b = b;
+ x->fp.counter_b = x->fp.ticks;
+ x->fp.delta_b = exp(log(b/x->fp.cur_b)*x->fp.rcp_ticks);
+ x->fp.event_mask |= 4;/*set event_mask_bit 2 = 1*/
+ }
}
- if(x->first_order)
+}
+
+static void filter_tilde_ft2(t_filter_tilde *x, t_float a)
+{
+ if(x->precision_d1_f0)
{
- if(n&7)
- dsp_add(filter_tilde_perform_1o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
- else
- dsp_add(filter_tilde_perf8_1o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ double da=(double)a;
+
+ if(da <= 0.0)
+ da = 0.000001;
+ if(x->dp.inlet3_is_Q1_or_damping0)
+ da = 1.0 / da;
+ if(x->dp.filter_function_is_highpass)
+ da /= x->dp.cur_b;
+ if(da != x->dp.cur_a)
+ {
+ x->dp.end_a = da;
+ x->dp.counter_a = x->dp.ticks;
+ x->dp.delta_a = exp(log(da/x->dp.cur_a)*x->dp.rcp_ticks);
+ x->dp.event_mask |= 2;/*set event_mask_bit 1 = 1*/
+ }
}
else
{
- if(n&7)
- dsp_add(filter_tilde_perform_2o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
- else
- dsp_add(filter_tilde_perf8_2o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ if(a <= 0.0f)
+ a = 0.000001f;
+ if(x->fp.inlet3_is_Q1_or_damping0)
+ a = 1.0f / a;
+ if(x->fp.filter_function_is_highpass)
+ a /= x->fp.cur_b;
+ if(a != x->fp.cur_a)
+ {
+ x->fp.end_a = a;
+ x->fp.counter_a = x->fp.ticks;
+ x->fp.delta_a = exp(log(a/x->fp.cur_a)*x->fp.rcp_ticks);
+ x->fp.event_mask |= 2;/*set event_mask_bit 1 = 1*/
+ }
}
}
-static void *filter_tilde_new(t_symbol *s, int argc, t_atom *argv)
+static void filter_tilde_ft1(t_filter_tilde *x, t_float f)
{
- t_filter_tilde *x = (t_filter_tilde *)pd_new(filter_tilde_class);
- int i;
- t_float si, co, f=0.0f, a=0.0f, b=0.0f, interpol=0.0f;
- t_symbol *filt_typ=gensym("");
-
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2"));
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft3"));
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft4"));
- outlet_new(&x->x_obj, &s_signal);
- x->x_debug_outlet = outlet_new(&x->x_obj, &s_list);
- x->x_msi = 0.0f;
-
- x->x_at[0].a_type = A_FLOAT;
- x->x_at[1].a_type = A_FLOAT;
- x->x_at[2].a_type = A_FLOAT;
- x->x_at[3].a_type = A_FLOAT;
- x->x_at[4].a_type = A_FLOAT;
-
- x->event_mask = 1;
- x->counter_f = 1;
- x->counter_a = 0;
- x->counter_b = 0;
- x->delta_f = 0.0f;
- x->delta_a = 0.0f;
- x->delta_b = 0.0f;
- x->interpol_time = 0.0f;
- x->wn1 = 0.0f;
- x->wn2 = 0.0f;
- x->a0 = 0.0f;
- x->a1 = 0.0f;
- x->a2 = 0.0f;
- x->b1 = 0.0f;
- x->b2 = 0.0f;
- x->sr = 3.14159265358979323846f / 44100.0f;
- x->calc = filter_tilde_snafu;
- x->first_order = 0;
- if((argc == 5)&&IS_A_FLOAT(argv,4)&&IS_A_FLOAT(argv,3)&&IS_A_FLOAT(argv,2)&&IS_A_FLOAT(argv,1)&&IS_A_SYMBOL(argv,0))
+ if(x->precision_d1_f0)
{
- filt_typ = atom_getsymbolarg(0, argc, argv);
- f = (t_float)atom_getfloatarg(1, argc, argv);
- a = (t_float)atom_getfloatarg(2, argc, argv);
- b = (t_float)atom_getfloatarg(3, argc, argv);
- interpol = (t_float)atom_getfloatarg(4, argc, argv);
+ double df=(double)f;
+
+ if(df <= 0.0)
+ df = 0.000001;
+ if(df != x->dp.cur_f)
+ {
+ x->dp.end_f = df;
+ x->dp.counter_f = x->dp.ticks;
+ x->dp.delta_f = exp(log(df/x->dp.cur_f)*x->dp.rcp_ticks);
+ x->dp.event_mask |= 1;/*set event_mask_bit 0 = 1*/
+ }
}
- x->cur_f = f;
- f *= x->sr;
- if(f < 1.0e-20f)
- x->cur_l = 1.0e20f;
- else if(f > 1.57079632f)
- x->cur_l = 0.0f;
else
{
- si = sin(f);
- co = cos(f);
- x->cur_l = co/si;
+ if(f <= 0.0f)
+ f = 0.000001f;
+ if(f != x->fp.cur_f)
+ {
+ x->fp.end_f = f;
+ x->fp.counter_f = x->fp.ticks;
+ x->fp.delta_f = exp(log(f/x->fp.cur_f)*x->fp.rcp_ticks);
+ x->fp.event_mask |= 1;/*set event_mask_bit 0 = 1*/
+ }
}
- if(a <= 0.0f)
- a = 0.000001f;
- if(b <= 0.0f)
- b = 0.000001f;
- x->cur_b = b;
-
- if(interpol <= 0.0f)
- interpol = 0.0f;
- x->interpol_time = interpol;
- x->ticks_per_interpol_time = 0.001f * 44100.0f / 64.0f;
- i = (int)((x->ticks_per_interpol_time)*(x->interpol_time)+0.49999f);
- if(i <= 0)
+}
+
+static void filter_tilde_print(t_filter_tilde *x)
+{
+ // post("fb1 = %g, fb2 = %g, ff1 = %g, ff2 = %g, ff3 = %g", x->b1, x->b2, x->a0, x->a1, x->a2);
+ if(x->precision_d1_f0)
{
- x->ticks = 1;
- x->rcp_ticks = 1.0f;
+ x->x_at[0].a_w.w_float = (t_float)x->dp.b1;
+ x->x_at[1].a_w.w_float = (t_float)x->dp.b2;
+ x->x_at[2].a_w.w_float = (t_float)x->dp.a0;
+ x->x_at[3].a_w.w_float = (t_float)x->dp.a1;
+ x->x_at[4].a_w.w_float = (t_float)x->dp.a2;
}
else
{
- x->ticks = i;
- x->rcp_ticks = 1.0f / (t_float)i;
+ x->x_at[0].a_w.w_float = x->fp.b1;
+ x->x_at[1].a_w.w_float = x->fp.b2;
+ x->x_at[2].a_w.w_float = x->fp.a0;
+ x->x_at[3].a_w.w_float = x->fp.a1;
+ x->x_at[4].a_w.w_float = x->fp.a2;
}
+ outlet_list(x->x_debug_outlet, &s_list, 5, x->x_at);
+}
+
+static void filter_tilde_dsp(t_filter_tilde *x, t_signal **sp)
+{
+ int i, n=(int)sp[0]->s_n;
- x->calc = filter_tilde_snafu;
-
- x->cur_a = 1.0f/a; /*a was Q*/
- x->inv = 1;
- x->hp = 0;
-
- if(filt_typ->s_name)
+ if(x->precision_d1_f0)
{
- if(filt_typ == gensym("ap1"))
+ double si, co, f;
+
+ x->dp.pi_over_sr = 3.14159265358979323846 / (double)(sp[0]->s_sr);
+ x->dp.ticks_per_interpol_time = 0.001 * (double)(sp[0]->s_sr) / (double)n;
+ i = (int)((x->dp.ticks_per_interpol_time)*(x->dp.interpol_time)+0.49999);
+ if(i <= 0)
{
- x->calc = filter_tilde_ap1;
- x->a1 = 1.0f;
- x->first_order = 1;
+ x->dp.ticks = 1;
+ x->dp.rcp_ticks = 1.0;
}
- else if(filt_typ == gensym("ap2"))
+ else
{
- x->calc = filter_tilde_ap2;
- x->a2 = 1.0f;
+ x->dp.ticks = i;
+ x->dp.rcp_ticks = 1.0 / (double)i;
}
- else if(filt_typ == gensym("ap1c"))
+ f = x->dp.cur_f * x->dp.pi_over_sr;
+ if(f < 1.0e-20)
+ x->dp.cur_l = 1.0e20;
+ else if(f > 1.57079632)
+ x->dp.cur_l = 0.0;
+ else
{
- x->calc = filter_tilde_ap1;
- x->a1 = 1.0f;
- x->inv = 0;
- x->cur_a = a; /*a was damping*/
- x->first_order = 1;
+ si = sin(f);
+ co = cos(f);
+ x->dp.cur_l = co/si;
}
- else if(filt_typ == gensym("ap2c"))
+ if(x->dp.filter_function_is_first_order)
{
- x->calc = filter_tilde_ap2;
- x->a2 = 1.0f;
- x->inv = 0;
- x->cur_a = a; /*a was damping*/
+ if(n&7)
+ dsp_add(filter_tilde_dperform_1o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ else
+ dsp_add(filter_tilde_dperf8_1o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
}
- else if(filt_typ == gensym("bpq2"))
+ else
{
- x->calc = filter_tilde_bp2;
+ if(n&7)
+ dsp_add(filter_tilde_dperform_2o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ else
+ dsp_add(filter_tilde_dperf8_2o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
}
- else if(filt_typ == gensym("rbpq2"))
+ }
+ else
+ {
+ t_float si, co, f;
+
+ x->fp.pi_over_sr = 3.14159265358979323846f / (t_float)(sp[0]->s_sr);
+ x->fp.ticks_per_interpol_time = 0.001f * (t_float)(sp[0]->s_sr) / (t_float)n;
+ i = (int)((x->fp.ticks_per_interpol_time)*(x->fp.interpol_time)+0.49999f);
+ if(i <= 0)
{
- x->calc = filter_tilde_rp2;
+ x->fp.ticks = 1;
+ x->fp.rcp_ticks = 1.0f;
}
- else if(filt_typ == gensym("bsq2"))
+ else
{
- x->calc = filter_tilde_bs2;
+ x->fp.ticks = i;
+ x->fp.rcp_ticks = 1.0f / (t_float)i;
}
- else if(filt_typ == gensym("bpw2"))
+ f = x->fp.cur_f * x->fp.pi_over_sr;
+ if(f < 1.0e-20f)
+ x->fp.cur_l = 1.0e20f;
+ else if(f > 1.57079632f)
+ x->fp.cur_l = 0.0f;
+ else
{
- x->calc = filter_tilde_bpw2;
- x->inv = 0;
- x->cur_a = a; /*a was bw*/
+ si = sin(f);
+ co = cos(f);
+ x->fp.cur_l = co/si;
}
- else if(filt_typ == gensym("rbpw2"))
+ if(x->fp.filter_function_is_first_order)
{
- x->calc = filter_tilde_rpw2;
- x->inv = 0;
- x->cur_a = a; /*a was bw*/
+ if(n&7)
+ dsp_add(filter_tilde_perform_1o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ else
+ dsp_add(filter_tilde_perf8_1o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
}
- else if(filt_typ == gensym("bsw2"))
+ else
{
- x->calc = filter_tilde_bsw2;
- x->inv = 0;
- x->cur_a = a; /*a was bw*/
+ if(n&7)
+ dsp_add(filter_tilde_perform_2o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
+ else
+ dsp_add(filter_tilde_perf8_2o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n);
}
- else if(filt_typ == gensym("hp1"))
+ }
+}
+
+static void *filter_tilde_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_filter_tilde *x = (t_filter_tilde *)pd_new(filter_tilde_class);
+ int i;
+ t_symbol *filt_typ=gensym("");
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft3"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft4"));
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_debug_outlet = outlet_new(&x->x_obj, &s_list);
+ x->x_msi = 0.0f;
+
+ x->x_at[0].a_type = A_FLOAT;
+ x->x_at[1].a_type = A_FLOAT;
+ x->x_at[2].a_type = A_FLOAT;
+ x->x_at[3].a_type = A_FLOAT;
+ x->x_at[4].a_type = A_FLOAT;
+
+ x->dp.delta_f = 0.0;
+ x->dp.delta_a = 0.0;
+ x->dp.delta_b = 0.0;
+ x->dp.interpol_time = 0.0;
+ x->dp.wn1 = 0.0;
+ x->dp.wn2 = 0.0;
+ x->dp.a0 = 0.0;
+ x->dp.a1 = 0.0;
+ x->dp.a2 = 0.0;
+ x->dp.b1 = 0.0;
+ x->dp.b2 = 0.0;
+ x->dp.pi_over_sr = 3.14159265358979323846 / 44100.0;
+ x->dp.event_mask = 1;
+ x->dp.counter_f = 1;
+ x->dp.counter_a = 0;
+ x->dp.counter_b = 0;
+ x->dp.filter_function_is_first_order = 0;
+
+ x->fp.delta_f = 0.0f;
+ x->fp.delta_a = 0.0f;
+ x->fp.delta_b = 0.0f;
+ x->fp.interpol_time = 0.0f;
+ x->fp.wn1 = 0.0f;
+ x->fp.wn2 = 0.0f;
+ x->fp.a0 = 0.0f;
+ x->fp.a1 = 0.0f;
+ x->fp.a2 = 0.0f;
+ x->fp.b1 = 0.0f;
+ x->fp.b2 = 0.0f;
+ x->fp.pi_over_sr = 3.14159265358979323846f / 44100.0f;
+ x->fp.event_mask = 1;
+ x->fp.counter_f = 1;
+ x->fp.counter_a = 0;
+ x->fp.counter_b = 0;
+ x->fp.filter_function_is_first_order = 0;
+
+ if((argc >= 1) && IS_A_SYMBOL(argv,0))
+ filt_typ = atom_getsymbolarg(0, argc, argv);
+
+ if(filt_typ->s_name[0] == 'd')
+ x->precision_d1_f0 = 1;
+ else
+ x->precision_d1_f0 = 0;
+
+ if(x->precision_d1_f0)
+ {
+ double si, co, f=0.0, a=0.0, b=0.0, interpol=0.0;
+
+ if((argc >= 5) && IS_A_FLOAT(argv,4) && IS_A_FLOAT(argv,3) && IS_A_FLOAT(argv,2) && IS_A_FLOAT(argv,1))
{
- x->calc = filter_tilde_hp1;
- x->first_order = 1;
+ f = (double)atom_getfloatarg(1, argc, argv);
+ a = (double)atom_getfloatarg(2, argc, argv);
+ b = (double)atom_getfloatarg(3, argc, argv);
+ interpol = (double)atom_getfloatarg(4, argc, argv);
}
- else if(filt_typ == gensym("hp2"))
+ x->dp.cur_f = f;
+ f *= x->dp.pi_over_sr;
+ if(f < 1.0e-20)
+ x->dp.cur_l = 1.0e20;
+ else if(f > 1.57079632)
+ x->dp.cur_l = 0.0;
+ else
{
- x->calc = filter_tilde_hp2;
+ si = sin(f);
+ co = cos(f);
+ x->dp.cur_l = co/si;
}
- else if(filt_typ == gensym("lp1"))
+ if(a <= 0.0)
+ a = 0.000001;
+ if(b <= 0.0)
+ b = 0.000001;
+
+ if(interpol <= 0.0)
+ interpol = 0.0;
+ x->dp.interpol_time = interpol;
+ x->dp.ticks_per_interpol_time = 0.001 * 44100.0 / 64.0;
+ i = (int)((x->dp.ticks_per_interpol_time)*(x->dp.interpol_time)+0.49999);
+ if(i <= 0)
{
- x->calc = filter_tilde_lp1;
- x->first_order = 1;
+ x->dp.ticks = 1;
+ x->dp.rcp_ticks = 1.0;
}
- else if(filt_typ == gensym("lp2"))
+ else
{
- x->calc = filter_tilde_lp2;
+ x->dp.ticks = i;
+ x->dp.rcp_ticks = 1.0 / (double)i;
}
- else if(filt_typ == gensym("hp1c"))
+
+ x->dp.cur_b = b;
+ x->dp.cur_a = 1.0/a; /*"a" is default Q*/
+ x->dp.inlet3_is_Q1_or_damping0 = 1;
+ x->dp.filter_function_is_highpass = 0;
+ x->dp.calc = filter_tilde_snafu;
+
+ if(filt_typ->s_name)
{
- x->calc = filter_tilde_hp1;
- x->cur_a = 1.0f / a;
- x->first_order = 1;
+ if(filt_typ == gensym("dap1"))
+ {
+ x->dp.calc = filter_tilde_dap1;
+ x->dp.a1 = 1.0;
+ x->dp.filter_function_is_first_order = 1;
+ }
+ else if(filt_typ == gensym("dap2"))
+ {
+ x->dp.calc = filter_tilde_dap2;
+ x->dp.a2 = 1.0;
+ }
+ else if(filt_typ == gensym("dap1c"))
+ {
+ x->dp.calc = filter_tilde_dap1;
+ x->dp.a1 = 1.0;
+ x->dp.inlet3_is_Q1_or_damping0 = 0;
+ x->dp.cur_a = a; /*"a" was damping*/
+ x->dp.filter_function_is_first_order = 1;
+ }
+ else if(filt_typ == gensym("dap2c"))
+ {
+ x->dp.calc = filter_tilde_dap2;
+ x->dp.a2 = 1.0;
+ x->dp.inlet3_is_Q1_or_damping0 = 0;
+ x->dp.cur_a = a; /*"a" was damping*/
+ }
+ else if(filt_typ == gensym("dbpq2"))
+ {
+ x->dp.calc = filter_tilde_dbp2;
+ }
+ else if(filt_typ == gensym("drbpq2"))
+ {
+ x->dp.calc = filter_tilde_drp2;
+ }
+ else if(filt_typ == gensym("dbsq2"))
+ {
+ x->dp.calc = filter_tilde_dbs2;
+ }
+ else if(filt_typ == gensym("dbpw2"))
+ {
+ x->dp.calc = filter_tilde_dbpw2;
+ x->dp.inlet3_is_Q1_or_damping0 = 0;
+ x->dp.cur_a = a; /*"a" was bw*/
+ }
+ else if(filt_typ == gensym("drbpw2"))
+ {
+ x->dp.calc = filter_tilde_drpw2;
+ x->dp.inlet3_is_Q1_or_damping0 = 0;
+ x->dp.cur_a = a; /*"a" was bw*/
+ }
+ else if(filt_typ == gensym("dbsw2"))
+ {
+ x->dp.calc = filter_tilde_dbsw2;
+ x->dp.inlet3_is_Q1_or_damping0 = 0;
+ x->dp.cur_a = a; /*"a" was bw*/
+ }
+ else if(filt_typ == gensym("dhp1"))
+ {
+ x->dp.calc = filter_tilde_dhp1;
+ x->dp.filter_function_is_first_order = 1;
+ }
+ else if(filt_typ == gensym("dhp2"))
+ {
+ x->dp.calc = filter_tilde_dhp2;
+ }
+ else if(filt_typ == gensym("dlp1"))
+ {
+ x->dp.calc = filter_tilde_dlp1;
+ x->dp.filter_function_is_first_order = 1;
+ }
+ else if(filt_typ == gensym("dlp2"))
+ {
+ x->dp.calc = filter_tilde_dlp2;
+ }
+ else if(filt_typ == gensym("dhp1c"))
+ {
+ x->dp.calc = filter_tilde_dhp1;
+ x->dp.cur_a = 1.0 / a;
+ x->dp.filter_function_is_first_order = 1;
+ }
+ else if(filt_typ == gensym("dhp2c"))
+ {
+ x->dp.calc = filter_tilde_dhp2;
+ x->dp.inlet3_is_Q1_or_damping0 = 0;
+ x->dp.cur_a = a / b;
+ x->dp.cur_b = 1.0 / b;
+ x->dp.filter_function_is_highpass = 1;
+ }
+ else if(filt_typ == gensym("dlp1c"))
+ {
+ x->dp.calc = filter_tilde_dlp1;
+ x->dp.inlet3_is_Q1_or_damping0 = 0;
+ x->dp.cur_a = a; /*"a" was damping*/
+ x->dp.filter_function_is_first_order = 1;
+ }
+ else if(filt_typ == gensym("dlp2c"))
+ {
+ x->dp.calc = filter_tilde_dlp2;
+ x->dp.inlet3_is_Q1_or_damping0 = 0;
+ x->dp.cur_a = a; /*"a" was damping*/
+ }
+ else
+ {
+ post("filter~-Error: 1. initial-arguments: <sym> kind: \
+lp1, lp2, hp1, hp2, \
+lp1c, lp2c, hp1c, hp2c, \
+ap1, ap2, ap1c, ap2c, \
+bpq2, rbpq2, bsq2, \
+bpw2, rbpw2, bsw2, \
+dlp1, dlp2, dhp1, dhp2, \
+dlp1c, dlp2c, dhp1c, dhp2c, \
+dap1, dap2, dap1c, dap2c, \
+dbpq2, drbpq2, dbsq2, \
+dbpw2, drbpw2, dbsw2 !");
+ }
+ x->dp.end_f = x->dp.cur_f;
+ x->dp.end_a = x->dp.cur_a;
+ x->dp.end_b = x->dp.cur_b;
}
- else if(filt_typ == gensym("hp2c"))
+ }
+ else
+ {
+ t_float si, co, f=0.0f, a=0.0f, b=0.0f, interpol=0.0f;
+
+ if((argc >= 5) && IS_A_FLOAT(argv,4) && IS_A_FLOAT(argv,3) && IS_A_FLOAT(argv,2) && IS_A_FLOAT(argv,1))
{
- x->calc = filter_tilde_hp2;
- x->inv = 0;
- x->cur_a = a / b;
- x->cur_b = 1.0f / b;
- x->hp = 1;
+ f = (t_float)atom_getfloatarg(1, argc, argv);
+ a = (t_float)atom_getfloatarg(2, argc, argv);
+ b = (t_float)atom_getfloatarg(3, argc, argv);
+ interpol = (t_float)atom_getfloatarg(4, argc, argv);
}
- else if(filt_typ == gensym("lp1c"))
+ x->fp.cur_f = f;
+ f *= x->fp.pi_over_sr;
+ if(f < 1.0e-20f)
+ x->fp.cur_l = 1.0e20f;
+ else if(f > 1.57079632f)
+ x->fp.cur_l = 0.0f;
+ else
{
- x->calc = filter_tilde_lp1;
- x->inv = 0;
- x->cur_a = a; /*a was damping*/
- x->first_order = 1;
+ si = sin(f);
+ co = cos(f);
+ x->fp.cur_l = co/si;
}
- else if(filt_typ == gensym("lp2c"))
+ if(a <= 0.0f)
+ a = 0.000001f;
+ if(b <= 0.0f)
+ b = 0.000001f;
+
+ if(interpol <= 0.0f)
+ interpol = 0.0f;
+ x->fp.interpol_time = interpol;
+ x->fp.ticks_per_interpol_time = 0.001f * 44100.0f / 64.0f;
+ i = (int)((x->fp.ticks_per_interpol_time)*(x->fp.interpol_time)+0.49999f);
+ if(i <= 0)
{
- x->calc = filter_tilde_lp2;
- x->inv = 0;
- x->cur_a = a; /*a was damping*/
+ x->fp.ticks = 1;
+ x->fp.rcp_ticks = 1.0f;
}
else
{
- post("filter~-Error: 1. initial-arguments: <sym> kind: \
+ x->fp.ticks = i;
+ x->fp.rcp_ticks = 1.0f / (t_float)i;
+ }
+
+ x->fp.cur_b = b;
+ x->fp.cur_a = 1.0f/a; /*"a" is default Q*/
+ x->fp.inlet3_is_Q1_or_damping0 = 1;
+ x->fp.filter_function_is_highpass = 0;
+ x->fp.calc = filter_tilde_snafu;
+
+ if(filt_typ->s_name)
+ {
+ if(filt_typ == gensym("ap1"))
+ {
+ x->fp.calc = filter_tilde_ap1;
+ x->fp.a1 = 1.0f;
+ x->fp.filter_function_is_first_order = 1;
+ }
+ else if(filt_typ == gensym("ap2"))
+ {
+ x->fp.calc = filter_tilde_ap2;
+ x->fp.a2 = 1.0f;
+ }
+ else if(filt_typ == gensym("ap1c"))
+ {
+ x->fp.calc = filter_tilde_ap1;
+ x->fp.a1 = 1.0f;
+ x->fp.inlet3_is_Q1_or_damping0 = 0;
+ x->fp.cur_a = a; /*"a" was damping*/
+ x->fp.filter_function_is_first_order = 1;
+ }
+ else if(filt_typ == gensym("ap2c"))
+ {
+ x->fp.calc = filter_tilde_ap2;
+ x->fp.a2 = 1.0f;
+ x->fp.inlet3_is_Q1_or_damping0 = 0;
+ x->fp.cur_a = a; /*"a" was damping*/
+ }
+ else if(filt_typ == gensym("bpq2"))
+ {
+ x->fp.calc = filter_tilde_bp2;
+ }
+ else if(filt_typ == gensym("rbpq2"))
+ {
+ x->fp.calc = filter_tilde_rp2;
+ }
+ else if(filt_typ == gensym("bsq2"))
+ {
+ x->fp.calc = filter_tilde_bs2;
+ }
+ else if(filt_typ == gensym("bpw2"))
+ {
+ x->fp.calc = filter_tilde_bpw2;
+ x->fp.inlet3_is_Q1_or_damping0 = 0;
+ x->fp.cur_a = a; /*"a" was bw*/
+ }
+ else if(filt_typ == gensym("rbpw2"))
+ {
+ x->fp.calc = filter_tilde_rpw2;
+ x->fp.inlet3_is_Q1_or_damping0 = 0;
+ x->fp.cur_a = a; /*"a" was bw*/
+ }
+ else if(filt_typ == gensym("bsw2"))
+ {
+ x->fp.calc = filter_tilde_bsw2;
+ x->fp.inlet3_is_Q1_or_damping0 = 0;
+ x->fp.cur_a = a; /*"a" was bw*/
+ }
+ else if(filt_typ == gensym("hp1"))
+ {
+ x->fp.calc = filter_tilde_hp1;
+ x->fp.filter_function_is_first_order = 1;
+ }
+ else if(filt_typ == gensym("hp2"))
+ {
+ x->fp.calc = filter_tilde_hp2;
+ }
+ else if(filt_typ == gensym("lp1"))
+ {
+ x->fp.calc = filter_tilde_lp1;
+ x->fp.filter_function_is_first_order = 1;
+ }
+ else if(filt_typ == gensym("lp2"))
+ {
+ x->fp.calc = filter_tilde_lp2;
+ }
+ else if(filt_typ == gensym("hp1c"))
+ {
+ x->fp.calc = filter_tilde_hp1;
+ x->fp.cur_a = 1.0f / a;
+ x->fp.filter_function_is_first_order = 1;
+ }
+ else if(filt_typ == gensym("hp2c"))
+ {
+ x->fp.calc = filter_tilde_hp2;
+ x->fp.inlet3_is_Q1_or_damping0 = 0;
+ x->fp.cur_a = a / b;
+ x->fp.cur_b = 1.0f / b;
+ x->fp.filter_function_is_highpass = 1;
+ }
+ else if(filt_typ == gensym("lp1c"))
+ {
+ x->fp.calc = filter_tilde_lp1;
+ x->fp.inlet3_is_Q1_or_damping0 = 0;
+ x->fp.cur_a = a; /*"a" was damping*/
+ x->fp.filter_function_is_first_order = 1;
+ }
+ else if(filt_typ == gensym("lp2c"))
+ {
+ x->fp.calc = filter_tilde_lp2;
+ x->fp.inlet3_is_Q1_or_damping0 = 0;
+ x->fp.cur_a = a; /*"a" was damping*/
+ }
+ else
+ {
+ post("filter~-Error: 1. initial-arguments: <sym> kind: \
lp1, lp2, hp1, hp2, \
lp1c, lp2c, hp1c, hp2c, \
ap1, ap2, ap1c, ap2c, \
bpq2, rbpq2, bsq2, \
-bpw2, rbpw2, bsw2!");
+bpw2, rbpw2, bsw2, \
+dlp1, dlp2, dhp1, dhp2, \
+dlp1c, dlp2c, dhp1c, dhp2c, \
+dap1, dap2, dap1c, dap2c, \
+dbpq2, drbpq2, dbsq2, \
+dbpw2, drbpw2, dbsw2 !");
+ }
+ x->fp.end_f = x->fp.cur_f;
+ x->fp.end_a = x->fp.cur_a;
+ x->fp.end_b = x->fp.cur_b;
}
- x->end_f = x->cur_f;
- x->end_a = x->cur_a;
- x->end_b = x->cur_b;
}
return (x);
}
@@ -809,5 +1627,4 @@ void filter_tilde_setup(void)
class_addmethod(filter_tilde_class, (t_method)filter_tilde_ft3, gensym("ft3"), A_FLOAT, 0);
class_addmethod(filter_tilde_class, (t_method)filter_tilde_ft4, gensym("ft4"), A_FLOAT, 0);
class_addmethod(filter_tilde_class, (t_method)filter_tilde_print, gensym("print"), 0);
-// class_sethelpsymbol(filter_tilde_class, gensym("iemhelp/help-filter~"));
}