# 2-way crossover by using MATLAB's $\tt butter()$ and $\tt filter()$

I am trying to do a 2-way crossover audio filter in MATLAB in two ways:

1. using crossoverFilter() from Audio System Toolbox
2. using standard MATLAB functions butter() and filter()

In 2nd case I used parallel combination of two butter filters connected in series. However, that produced slightly different output than the crossoverFilter.

Is there an error in my butter/filter usage? I even tried negating high pass output, as it is expected that there will always be a phase difference of $180^\circ$ between the outputs of a second order low-pass filter and a high-pass filter having the same crossover frequency. But that didn't help.

Init1:

crossFilt = crossoverFilter(...
'NumCrossovers', 1,...    % Number of magnitude response band crossings.
'CrossoverFrequencies', crossover_frequency,...
'CrossoverSlopes', 12,... % Second-order filters have 12 dB/octave slope.
'SampleRate', sampling_frequency);


Execute1:

[out1_lowpass,out1_highpass] = step(crossFilt,in_pcm);


Init2:

[B_highpass, A_highpass] = butter( 2, crossover_frequency/sampling_frequency*2, 'high' );
[B_lowpass,  A_lowpass ] = butter( 2, crossover_frequency/sampling_frequency*2, 'low'  );


Execute2:

[out2_lowpass,  state_lowpass_1st ] = filter( B_lowpass,  A_lowpass,  in_pcm,        state_lowpass_1st);
[out2_lowpass,  state_lowpass_2nd ] = filter( B_lowpass,  A_lowpass,  out2_lowpass,  state_lowpass_2nd);

[out2_highpass, state_highpass_1st] = filter( B_highpass, A_highpass, in_pcm,        state_highpass_1st);
[out2_highpass, state_highpass_2nd] = filter( B_highpass, A_highpass, out2_highpass, state_highpass_2nd);

• can you show exactly how you designed your crossover? what order, crossover frequency, and transfer function you used in filter()? – robert bristow-johnson Mar 22 '17 at 0:16
• @robertbristow-johnson Added some code, does that help. – Danijel Mar 22 '17 at 6:48

OK, figured it out.

The above example has one problem in this line:

'CrossoverSlopes', 12,... % Second-order filters have 12 dB/octave slope.


Cascading any order Butterworth filter produces 2x that order Linkwitz-Riley. So, cascading two 2nd order Butterworth filters creates a LR-4 design! This means the crossover slope is 24 dB/octave, not 12.

Changing the above line to:

'CrossoverSlopes', 24,...


makes the output from crossoverFilter() the same as "manual" setup.

More theory at Linkwitz-Riley Crossovers: A Primer.