1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
| double i1, i2, o1, o2; /* temporary variables */
double a0, a1, a2; /* coefficients */
double b0, b1, b2; /* coefficients */
double f; /* last Frequency used */
double q; /* last Q used */
double g; /* last Gain used */
long t; /* last Type used /
static int maxfilterunits=10;
double FilterCell(long Unit, double Input, double Frequency, double Q, double Gain, int Type)
{
/* --------------------------------------------------------------- */
double Output=0,S,omega,A,sn,cs,alpha,beta,temp1,temp2,temp3,temp4;
/* -- check if frequency, Q, gain or type has changed.. and, if so, update coefficients */
if ( ( Frequency != f ) || ( Q != q ) || ( Gain != g ) || ( Type != t ) ) {
f = Frequency; q = Q; g = Gain; t = Type; /* remember last frequency, q, gain and type */
switch (Type) {
case 0: /* no filtering */
b0 = Math.pow( 10.0, Gain / 20.0 ); /* convert from dB to linear */
break;
case 1: /* lowpass */
Gain = Math.pow( 10.0, Gain / 20.0 ); /* convert from dB to linear */
omega = ( Math.PI*2 * Frequency ) / 44100;
sn = Math.sin( omega ); cs = Math.cos( omega );
alpha = sn / ( 2.0 * Q );
a0 = 1.0 / ( 1.0 + alpha );
a1 = ( -2.0 * cs ) * a0;
a2 = ( 1.0 - alpha ) * a0;
b1 = ( 1.0 - cs ) * a0 * Gain;
b0 = b1 * 0.5;
break;
case 2: /* highpass */
Gain = Math.pow( 10.0, Gain / 20.0 ); /* convert from dB to linear */
omega = ( Math.PI*2 * Frequency ) / 44100;
sn = Math.sin( omega ); cs = Math.cos( omega );
alpha = sn / ( 2.0 * Q );
a0 = 1.0 / ( 1.0 + alpha );
a1 = ( -2.0 * cs ) * a0;
a2 = ( 1.0 - alpha ) * a0;
b1 = -( 1.0 + cs ) * a0 * Gain;
b0 = -b1 * 0.5;
break;
case 3: /* bandpass */
Gain = Math.pow( 10.0, Gain / 20.0 ); /* convert from dB to linear */
omega = ( Math.PI*2 * Frequency ) / 44100;
sn =Math.sin( omega ); cs = Math.cos( omega );
alpha = sn / ( 2.0 * Q );
a0 = 1.0 / ( 1.0 + alpha );
a1 = ( -2.0 * cs ) * a0;
a2 = ( 1.0 - alpha ) * a0;
b0 = alpha * a0 * Gain;
break;
case 4: /* notch */
Gain = Math.pow( 10.0, Gain / 20.0 ); /* convert from dB to linear */
omega = ( Math.PI*2 * Frequency ) / 44100;
sn = Math.sin( omega ); cs = Math.cos( omega );
alpha = sn / ( 2.0 * Q );
a0 = 1.0 / ( 1.0 + alpha );
a1 = ( -2.0 * cs ) * a0;
a2 = ( 1.0 - alpha ) * a0;
b0 = a0 * Gain;
b1 = a1 * Gain;
break;
case 5: /* lowshelf */
/* "shelf slope" 1.0 = max slope, because neither Q nor bandwidth is used in */
/* those filters (note: true only for lowshelf and highshelf, not peaking). */
S = 1.0; /* used only by lowshelf and highshelf */
A = Math.pow( 10.0 , ( Gain / 40.0 ) ); /* Gain is expressed in dB */
omega = ( Math.PI*2 * Frequency ) / 44100;
sn = Math.sin( omega ); cs = Math.cos( omega );
temp1 = A + 1.0; temp2 = A - 1.0; temp3 = temp1 * cs; temp4 = temp2 * cs;
beta = sn * Math.sqrt( ( A * A + 1.0 ) / S - temp2 * temp2 );
a0 = 1.0 / ( temp1 + temp4 + beta );
a1 = ( -2.0 * ( temp2 + temp3 ) ) * a0;
a2 = ( temp1 + temp4 - beta ) * a0;
b0 = ( A * ( temp1 - temp4 + beta ) ) * a0;
b1 = ( 2.0 * A * ( temp2 - temp3 ) ) * a0;
b2 = ( A * ( temp1 - temp4 - beta ) ) * a0;
break;
case 6: /* highshelf */
/* "shelf slope" 1.0 = max slope, because neither Q nor bandwidth is used in */
/* those filters (note: true only for lowshelf and highshelf, not peaking). */
S = 1.0; /* used only by lowshelf and highshelf */
A = Math.pow( 10.0, ( Gain / 40.0 ) ); /* Gain is expressed in dB */
omega = ( Math.PI*2 * Frequency ) / 44100;
sn = Math.sin( omega ); cs = Math.cos( omega );
temp1 = A + 1.0; temp2 = A - 1.0; temp3 = temp1 * cs; temp4 = temp2 * cs;
beta = sn * Math.sqrt( ( A * A + 1.0 ) / S - temp2 * temp2 );
a0 = 1.0 / ( temp1 - temp4 + beta );
a1 = ( 2.0 * ( temp2 - temp3 ) ) * a0;
a2 = ( temp1 - temp4 - beta ) * a0;
b0 = ( A * ( temp1 + temp4 + beta ) ) * a0;
b1 = ( -2.0 * A * ( temp2 + temp3 ) ) * a0;
b2 = ( A * ( temp1 + temp4 - beta ) ) * a0;
break;
case 7: /* peaking */
A = Math.pow( 10.0, ( Gain / 40.0 ) ); /* Gain is expressed in dB */
omega = ( Math.PI*2 * Frequency ) / 44100;
sn = Math.sin( omega ); cs = Math.cos( omega );
alpha = sn / ( 2.0 * Q );
temp1 = alpha * A;
temp2 = alpha / A;
a0 = 1.0 / ( 1.0 + temp2 );
a1 = ( -2.0 * cs ) * a0;
a2 = ( 1.0 - temp2 ) * a0;
b0 = ( 1.0 + temp1 ) * a0;
b2 = ( 1.0 - temp1 ) * a0;
break;
}
}
/* -- filter loop: if you don't change the parameters of the filter dynamically, ~only this code will be executed. */
switch (Type) {
case 0: /* no filtering */
Output = b0*Input;
Output = Input;
break;
case 1: /* lowpass */
case 2: /* highpass */
Output = b0*Input + b1*i1 + b0*i2 - a1*o1 - a2*o2;
break;
case 3: /* bandpass */
Output = b0*Input - b0*i2 - a1*o1 - a2*o2;
break;
case 4: /* notch */
Output = b0*Input + b1*i1 + b0*i2 - a1*o1 - a2*o2;
break;
case 5: /* low shelving */
case 6: /* high shelving */
Output = b0*Input + b1*i1 + b2*i2 - a1*o1 - a2*o2;
break;
case 7: /* peaking */
Output = b0*Input + a1*i1 + b2*i2 - a1*o1 - a2*o2;
break;
}
o2=o1; o1=Output; i2=i1; i1=Input; /* update variables for recursion */
return(Output);
} |
Partager