I have 5 'negative peaking' biquads that will change center frequency while maintaining a constant Q and A (amplitude reduction) on a realtime microcontroller (ARM cortex-m4) with a codec over i2s controlled by i2c system operating at 96kHz. I am concerned (with concerns raised by my oscilloscope) that I am going to be hosed by divisions and sine/cosine. What can I do to speed things up?
Using RBJ's EQ cookbook, a peak filter takes the following coefficients:
w0 = 2*pi*f0/Fs;
A = sqrt(10^(dBgain/40));
alpha = (sin(w0)/(2*Q));
b0 = 1 + alpha*A;
b1 = -2*cos(w0);
b2 = 1 - alpha*A;
a0 = 1 + alpha/A;
a1 = -2*cos(w0);
a2 = 1 - alpha/A;
Furthermore, the feedback coefficients will take the form c0 = b0/a0 c1 = b1/a0 c2 = b2/a0 and the feedforward coefficients: c3 = a1 / a0; c4 = a2 / a0;
Expanding these divisions:
c0 = (1 + (sin(w0)/(2*Q))*A)/(1 + (sin(w0)/(2*Q))/A);
c1 = -2*cos(w0) / (1 + sin(w0)/(2*Q)/A);
c2 = (1 - (sin(w0)/(2*Q))*A)/(1 + (sin(w0)/(2*Q))/A);
c3 = c1;
c4 = (1 - (sin(w0)/(2*Q))/A) / (1 + (sin(w0)/(2*Q))/A);
Using simplify() in MATLAB with symbolic variables w0, Q, and A, we obtain:
c0 = (2AQ + A^2*sin(w0))/(2AQ+sin(w0))
c1 = -(4AQ*cos(w0))/(sin(w0) + 2AQ)
c2 = -(A^2*sin(w0) - 2AQ)/(2AQ + sin(w0));
c3 = c1;
c4 = -(sin(w0)- 2AQ)/(2AQ + sin(w0));
If Q and A are constant, no problem, these can be computed ahead of time. What will kill me are the divisions and the sine/cosine computations.
What tricks or processes can be used to speed up the calculation or if at all, further simplify or approximate the filter coefficients?