Reputation: 99
I've worked out the coefficients for a 2nd order low-pass and highpass butterworth filter.
The coefficients are as follows. I'm implementing this C.
float cutoff = 600.00f * M_PI * 2;
float c = 2.0f / sampleRate;
float q = sqrt(2.0f)/2.0f;
g_a1LP = (2.0f * pow(c, 2.0f) - (2.0f * pow(cutoff, 2.0f))) / (pow(c, 2.0f) + ((cutoff*c)/q) + pow(cutoff, 2.0f));
g_a2LP = -(pow(c, 2.0f) + pow(cutoff, 2.0f) - (cutoff*c)/q ) / (pow(c, 2.0f) + ((cutoff*c)/q) + pow(cutoff, 2.0f));
g_b0LP = 1.0f;
g_b1LP = 2.0f;
g_b2LP = 1.0f;
g_a1HP = (2.0f - (2.0f * pow(cutoff, 2.0f))/ pow(c, 2.0f)) / (1.0f + (2.0f/sqrt(2.0f)) * (1.0f/c) * cutoff + (pow(cutoff, 2.0f) / pow(c, 2.0f)));
g_a2HP = -(1.0f - (2.0f/sqrt(2.0f) * 1.0f/c * cutoff) + pow(cutoff, 2.0f)/pow(c, 2.0f)) / (1.0f + (2.0f/sqrt(2.0f)) * (1.0f/c) * cutoff + (pow(cutoff, 2.0f) / pow(c, 2.0f)));
g_b0HP = 1.0;
g_b1HP = -2.0;
g_b2HP = 1.0;
I now have to make a 4th order Linkwitz-Riley crossover. I know that this is two butterworth's cascaded. I'm not too sure how I should go about this. Do I just multiply the coefficients together? Am I on the right track? If anyone is bothered, do my coefficients look ok? They plotted fine in matlab.
Upvotes: 2
Views: 6567
Reputation: 214
RawBean is right in his comment...
First of all, in order to create Linkwitz Riley filter (the same applies to both lowpass or highpass), you have to cascade two identical filters, like Aporee mentions. Now, this in conjunction with RawBean's comment means that you have to convolve the coefficients. This can be done separately for the numerator and the denominator and the final results will correspond to the numerator and the denominator coefficients of the Linkwitz-Riley coefficients you are seeking.
If you have a look at Aporee's example the convolution function is used to calculate the final coefficients. You could very well use this code snippet to get your coefficients and if the implementation will be a static crossover filter you can even hardcode them.
Upvotes: 0
Reputation: 41
In order to create a 4th order high-pass (resp. low-pass) Linkwitz-Riley filter, you have to cascade 2 identical second order high-pass (resp. low-pass) Butterworth filters.
With the filters polynomial, it means :
Butterworth filter :
h = b0 + b1.X + b2.X**2 / a0 + a1.X + a2.X**2
Linkwitz-Riley filter :
h' = h**2
So if your implementation allows it, you can simply square the Butterworth filter.
If you want to have the Linkwitz-Riley digital filter coefficients, you can :
Find them by developing the following equation :
(b0 + b1.X + b2.X**2) ** 2 = (b0' + b1'.X + b2'.X**2 + b3'.X**3 + b4'.X**4)
It will give you 5 coefficients b0' ... b4' as functions of b0 ... b3 (and similarly a0' ... a4' as functions of a0 ... a3), that you can implement into your code.
Use Matlab or Python
Here is an example function in Python using scipy.signal, which returns the numerator and denominator Linkwitz-Riley coefficients for digital filter.
import scipy.signal as sig
def linkril(filter_order, w_center, btype='lowpass', analog=False):
butter_order = int(filter_order / 2.)
numbut, denbut = sig.butter(butter_order, w_center,
btype = btype, analog=analog)
num = np.convolve(numbut, numbut)
den = np.convolve(denbut, denbut)
return(num, den)
Upvotes: 4
Reputation: 462
Why not using
They propose to do such operation in 2 lines of code in Python
from scipy.signal import butter
# generate the coefficients (discrete time) of a 4 order butterworth bandpass filter, where low cutoff frequency is 0.3 the Nyquist frequency and the high cutoff is 0.4 the Nyquist frequency
butter(4, [0.3, 0.4], 'band')
This will output the following coefficients:
>>> (array([ 4.16599204e-04, 0.00000000e+00, -1.66639682e-03,
3.25816475e-19, 2.49959523e-03, -3.25816475e-19,
-1.66639682e-03, 0.00000000e+00, 4.16599204e-04]), array([ 1. , -3.30057727, 7.28008314, -10.20570426,
10.95189946, -8.30658348, 4.82226759, -1.77664475, 0.43826514]))
Upvotes: 3