I've been looking through the code for the AudioFilterStateVariable (...\Arduino\hardware\teensy\avr\libraries\Audio\filter_variable.cpp), trying to understand the filter better.
the part that does the state variable filter ("Chamberlin Filter") looks like it has the filter coded twice (sort of).
// now do the state variable filter as normal, using fmult
input = (*in++) << 12;
lowpass = lowpass + MULT(fmult, bandpass);
highpass = ((input + inputprev)>>1) - lowpass - MULT(damp, bandpass);
inputprev = input;
bandpass = bandpass + MULT(fmult, highpass);
lowpasstmp = lowpass;
bandpasstmp = bandpass;
highpasstmp = highpass;
lowpass = lowpass + MULT(fmult, bandpass);
highpass = input - lowpass - MULT(damp, bandpass);
bandpass = bandpass + MULT(fmult, highpass);
lowpasstmp = signed_saturate_rshift(lowpass+lowpasstmp, 16, 13);
bandpasstmp = signed_saturate_rshift(bandpass+bandpasstmp, 16, 13);
highpasstmp = signed_saturate_rshift(highpass+highpasstmp, 16, 13);
*lp++ = lowpasstmp;
*bp++ = bandpasstmp;
*hp++ = highpasstmp;
is was expecting something more like...
input = (*in++) << 12;
lowpass = lowpass_delayed + MULT(fmult, bandpass_delayed);
highpass = input - lowpass - MULT(damp, bandpass_delayed);
bandpass = bandpass_delayd + MULT(fmult, highpass);
bandpass_delayed = bandpass;
lowpass_delayed = lowpass;
*lp++ = signed_saturate_rshift(lowpass, 16, 12);
*bp++ = signed_saturate_rshift(bandpass, 16, 12);
*hp++ = signed_saturate_rshift(highpass, 16, 12);
It looks like there is a two sample box car filter on the input ( ((input + inputprev)>>1) ) and an averaging of the two "instances" of the filtering ( signed_saturate_rshift(lowpass+lowpasstmp, 16, 13) ).
Can anyone tell me the reasoning behind the design?
the part that does the state variable filter ("Chamberlin Filter") looks like it has the filter coded twice (sort of).
// now do the state variable filter as normal, using fmult
input = (*in++) << 12;
lowpass = lowpass + MULT(fmult, bandpass);
highpass = ((input + inputprev)>>1) - lowpass - MULT(damp, bandpass);
inputprev = input;
bandpass = bandpass + MULT(fmult, highpass);
lowpasstmp = lowpass;
bandpasstmp = bandpass;
highpasstmp = highpass;
lowpass = lowpass + MULT(fmult, bandpass);
highpass = input - lowpass - MULT(damp, bandpass);
bandpass = bandpass + MULT(fmult, highpass);
lowpasstmp = signed_saturate_rshift(lowpass+lowpasstmp, 16, 13);
bandpasstmp = signed_saturate_rshift(bandpass+bandpasstmp, 16, 13);
highpasstmp = signed_saturate_rshift(highpass+highpasstmp, 16, 13);
*lp++ = lowpasstmp;
*bp++ = bandpasstmp;
*hp++ = highpasstmp;
is was expecting something more like...
input = (*in++) << 12;
lowpass = lowpass_delayed + MULT(fmult, bandpass_delayed);
highpass = input - lowpass - MULT(damp, bandpass_delayed);
bandpass = bandpass_delayd + MULT(fmult, highpass);
bandpass_delayed = bandpass;
lowpass_delayed = lowpass;
*lp++ = signed_saturate_rshift(lowpass, 16, 12);
*bp++ = signed_saturate_rshift(bandpass, 16, 12);
*hp++ = signed_saturate_rshift(highpass, 16, 12);
It looks like there is a two sample box car filter on the input ( ((input + inputprev)>>1) ) and an averaging of the two "instances" of the filtering ( signed_saturate_rshift(lowpass+lowpasstmp, 16, 13) ).
Can anyone tell me the reasoning behind the design?