//low pass filter (LP12)
//taken mostly from lmms base code (it's GPL so it's good!)

typedef struct
{
	float lp0, bp0, hp0, last0;
}filter_data;

float rca, rcb, rcc, rcq; //coeffcients 

float bound ( float min, float x, float max )
{
	if( x < min )
		return min;
	else if ( x > max )
		return max;
	else
		return x;
}

void calculateFilterCoeffs( float freq, float q )
{
	freq = bound(0.1f, freq, SAMPLE_RATE);	

	float sr = 1.0f / SAMPLE_RATE * 0.25f;
	float f = 1.0f / (freq * 2 * PI);

	rca = 1.0f - sr / ( f + sr );
	rcb = 1.0f - rca;
	rcc = f / ( f + sr );
	rcq = q * 0.25f;
}

float updateFilter ( float in0, filter_data * fd ) 
{
	float lp, bp, hp, in;
	int n;
	for( n=4; n !=0; --n )
	{
		in = in0 + fd->bp0 * rcq;
		in = bound( -1.0f, in, 1.0f );

		lp = in * rcb + fd->lp0 * rca;
		lp = bound ( -1.0f, lp, 1.0f );

		hp = rcc * ( fd->hp0 + in - fd->last0);
		hp = bound ( -1.0, hp, 1.0f );

		bp = hp * rcb + fd->bp0 * rca;
		bp = bound( -1.0f, bp, 1.0f );

		fd->last0 = in;
		fd->lp0 = lp;
		fd->hp0 = hp;
		fd->bp0 = bp;
	}
	return lp;
}
