I see this occasionally. Linkwitz-Riley crossovers are not linear-phase, unless explicitly implemented as symmetric FIR filters.... why not standard complementary linear-phase filters, like simple LR's?
Sure, of course.I see this occasionally. Linkwitz-Riley crossovers are not linear-phase, unless explicitly implemented as symmetric FIR filters.
I'm hoping anyone following this thread would automatically associate complementary linear-phase LR's, with symmetric FIR.
But then again, never hurts to be totally explicit, huh? 🙂
I do have to say, having analyzed lots and lots of different MDS crossover configurations: a linear-phase 4th-order Linkwitz-Riley response is very hard to beat for the compromize between transition band slopes and impulse response duration.... complementary linear-phase LR's ...
An analog or IIR lowpass has a more or less constant group-delay within its pas pand while the "constant" group-delay region of a higpass lies below its passband..
There is quite some effort needed to EQ those to flat group-delay so it isn't impossible....
The following is a second order Bessel highpass filter (1kHz cutoff) whose phase has been cleaned out all the way to 20kHz. The blue trace is the uncompensated filter.But the group delay of the HPF is not a "delay",...
Code:
%HIGHPASS
freq1 = 1000;
Q = 1/sqrt(3);
wc = 2*pi*freq1; % Cutoff frequency
hpf = tf([1,0,0],[1, wc/Q, wc*wc]); % analogue highpass transfer function
%ALLPASS1
freq = 3000;
Q = 1;
wc = 2*pi*freq;
apf1 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
%ALLPASS2
freq = 5500;
Q = 1.8;
wc = 2*pi*freq;
apf2 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
%ALLPASS3
freq = 8500;
Q = 2.6;
wc = 2*pi*freq;
apf3 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
%ALLPASS4
freq = 11000;
Q = 3.9;
wc = 2*pi*freq;
apf4 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
%ALLPASS5
freq = 14000;
Q = 5;
wc = 2*pi*freq;
apf5 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
%ALLPASS6
freq = 17000;
Q = 6.3;
wc = 2*pi*freq;
apf6 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
%ALLPASS7
freq = 19500;
Q = 9;
wc = 2*pi*freq;
apf7 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
apf = apf1*apf2*apf3*apf4*apf5*apf6*apf7;
% DISPLAY
options = bodeoptions; % bode plot
options.FreqUnits = 'Hz';
options.XLim = [10,20000];
options.YLim = [-2700,0];
options.grid = 'On';
options.Freqscale ='Linear';
options.MagVisible = 'Off';
options.PhaseWrapping = 'Off';
options.PhaseMatching = 'On';
figure(1)
bode(-hpf,-hpf*apf,options);
@newvirus2008 , how did you determine the parameters for those allpass filters, and if you plot the group delay, how close is it to equiripple?
Yep, that's my take on phase audibility too. Seems recent research is leaning towards the lower the frequency, the more likely the audibility.
I tried listening to LR4-style phase rotations at 100 Hz and 250 Hz: the latter could be heard as a flattening of the crack of a snare drum, whereas removing 100 Hz phase rotation made bass guitar and kick drum more distinct. The 250 Hz seemed more noticeable, however.
That could be part of the reason why full-range fans consider their speakers more lively than big multiway systems. I heard it myself at an early BAF, where a recording was so compelling I had to find out what was making that lovely sound. Perhaps it wasn't the flattest frequency response but the thing was there.
hpf = tf([1,0,0],[1, wc/Q, wc*wc]); % analogue highpass transfer function
Isn't that a low pass?
I did a manual, and I coudn't find anything in MATLAB that shows the GD of a 'tf' object (if you know, please help). It'd be nice to see the GD and what adjustments need to be made to get it to equiripple. The target GD ripple would also tell the user the number of biquads needed for the job....how did you determine the parameters for those allpass filters, and if you plot the group delay, how close is it to equiripple?
The numerator and denominator vectors carry the coefficients in the order of decreasing power (of 's') giving a highpass transfer. A lowpass would have to be tf ( [wc*wc] , [1, wc/Q, wc*wc] ) or tf ( [0, 0, wc*wc] , [1, wc/Q, wc*wc] ) ...Isn't that a low pass?
Figured the GD, new tunings below. Again this was manual, by hand but your curve fitting software might do better like maybe smaller allpass for same GD ripple etc..... if you plot the group delay, how close is it to equiripple?
Code:
f = 1:10:22000;
%HIGHPASS
freq1 = 1000;
Q1 = 1/sqrt(3);
wc = 2*pi*freq1; % Cutoff frequency
hpf = tf([1,0,0],[1, wc/Q1, wc*wc]); % analogue lowpass transfer function
[num, den] = tfdata(hpf,'v');
h = freqs(num,den,2*pi*f);
gd = -diff(unwrap(angle(h)))./diff(2*pi*f);
%ALLPASS1
freq = 2600;
Q = 1.1;
wc = 2*pi*freq; % Cutoff frequency
apf1 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
[num, den] = tfdata(apf1,'v');
h = freqs(num,den,2*pi*f);
gd = gd-diff(unwrap(angle(h)))./diff(2*pi*f);
%ALLPASS2
freq = 4650;
Q = 1.95;
wc = 2*pi*freq; % Cutoff frequency
apf2 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
[num, den] = tfdata(apf2,'v');
h = freqs(num,den,2*pi*f);
gd = gd-diff(unwrap(angle(h)))./diff(2*pi*f);
%ALLPASS3
freq = 6800;
Q = 2.75;
wc = 2*pi*freq; % Cutoff frequency
apf3 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
[num, den] = tfdata(apf3,'v');
h = freqs(num,den,2*pi*f);
gd = gd-diff(unwrap(angle(h)))./diff(2*pi*f);
%ALLPASS4
freq = 9050;
Q = 3.6;
wc = 2*pi*freq; % Cutoff frequency
apf4 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
[num, den] = tfdata(apf4,'v');
h = freqs(num,den,2*pi*f);
gd = gd-diff(unwrap(angle(h)))./diff(2*pi*f);
%ALLPASS5
freq = 11300;
Q = 4.7;
wc = 2*pi*freq; % Cutoff frequency
apf5 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
[num, den] = tfdata(apf5,'v');
h = freqs(num,den,2*pi*f);
gd = gd-diff(unwrap(angle(h)))./diff(2*pi*f);
%ALLPASS6
freq = 13500;
Q = 5.5;
wc = 2*pi*freq; % Cutoff frequency
apf6 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
[num, den] = tfdata(apf6,'v');
h = freqs(num,den,2*pi*f);
gd = gd-diff(unwrap(angle(h)))./diff(2*pi*f);
%ALLPASS7
freq = 15700;
Q = 6.5;
wc = 2*pi*freq; % Cutoff frequency
apf7 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
[num, den] = tfdata(apf7,'v');
h = freqs(num,den,2*pi*f);
gd = gd-diff(unwrap(angle(h)))./diff(2*pi*f);
%ALLPASS8
freq = 17850;
Q = 7.6;
wc = 2*pi*freq; % Cutoff frequency
apf8 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
[num, den] = tfdata(apf8,'v');
h = freqs(num,den,2*pi*f);
gd = gd-diff(unwrap(angle(h)))./diff(2*pi*f);
%ALLPASS9
freq = 19800;
Q = 10;
wc = 2*pi*freq; % Cutoff frequency
apf9 = tf([1, -wc/Q, wc*wc],[1, wc/Q, wc*wc]); % analogue allpass transfer function
[num, den] = tfdata(apf9,'v');
h = freqs(num,den,2*pi*f);
gd = gd-diff(unwrap(angle(h)))./diff(2*pi*f);
apf = apf1*apf2*apf3*apf4*apf5*apf6*apf7*apf8*apf9;
% DISPLAY
options = bodeoptions; % bode plot
options.FreqUnits = 'Hz';
options.XLim = [10,20000];
options.YLim = [-3250,0];
options.grid = 'On';
options.Freqscale ='Linear';
options.MagVisible = 'Off';
options.PhaseWrapping = 'Off';
options.PhaseMatching = 'On';
figure(1)
bode(-hpf,-hpf*apf,options);
gd(length(f))= 0;
figure(2)
plot(f,gd*1000);
Xlim([1,22000]);
Ylim([0,1]);
grid on; grid minor;
XLabel('Frequency (Hz)');
YLabel('Group delay (ms)');
OK, didn't understand the notation.The numerator and denominator vectors carry the coefficients in the order of decreasing power (of 's') giving a highpass transfer. A lowpass would have to be tf ( [wc*wc] , [1, wc/Q, wc*wc] ) or tf ( [0, 0, wc*wc] , [1, wc/Q, wc*wc] ) ...
Nice work!... this was manual, by hand ...
The curve-fitting script requires that one specify the desired phase values, so for constant group delay one has to compute the desired constant-slope phase, and then subtract the existing filter phase from it. It's harder to explain than to do, though it is tedious.
I don't think that there's any direct method. You could use tf2zp() to find the zeroes and poles, use those to determine the transfer function polynomials, then use grpdelay() to compute the group delay.I coudn't find anything in MATLAB that shows the GD of a 'tf' object (if you know, please help)
EDIT: tf2sos() is an alternative; it will return second-order sections.
For the handful of MDS crossovers I compared against linear-phase LR4s, I thought the LR4s were compelling both for straightforward simplicity, and for ease of implementation.I do have to say, having analyzed lots and lots of different MDS crossover configurations: a linear-phase 4th-order Linkwitz-Riley response is very hard to beat for the compromize between transition band slopes and impulse response duration.
Given my DIYs are usually 4-5 way, both of those comparative factors become even more important for me.
Sometimes, I'm not sure why I stay curious about IIR, LoL and sigh.
That said, right now I'm playing with straight IIR EQs using them as mag and phase flattening prior to lin-phase xovers in a FIR file.
(as opposed to just embedding the min-phase flattening EQ's into the FIR file)
Clearly helps with low-frequency work given tap count limitations and a desire to reduce latency.
I've found an auto-IIR filter generator, much like REW's auto-EQ, but that has considerably greater capability. It allows over a hundred discrete EQ's to be used with whatever chosen level of smoothing. Generates a set of biquads, for import into a qsys DSP which can handle up to 256 biquads per channel.
If desired, the auto-IIR can flatten mag and phase with a precision that rivals FIR's effective impulse inversion !
I'd like to see some guru come up with an auto-IIR generator that can both flatten in-band response and also match acoustic xover targets.
Iow, like FIR can do, but all via IIR. Would be a killer home run I think (for folks who want to stay away from FIR haha)
Be careful, @mark100 , it is possible to have too much of a good thing.It allows over a hundred discrete EQ's to be used ...
Using the phase linearisation allpass chain from post #809, I've calculated two MDS crossovers in the continuous s-domain, one each, using the HPF and then the LPF as the basis filter. Note that the filters have been squared to the 4th order and are therefore not Bessel (Q = 0.577) anymore. However, I believe the results would be more or less the same with another kind of filter.My question was whether anyone had done a subtractive delay crossover with a defined HPF and the LP derived from that, as described above. The dual of Lipshitz & Vanderkooy, similar to Berchin's but continuous time.
Hope that helps.
As I've said in the past, "Filtering is filtering; whether analog or digital is merely a detail of implementation."I've calculated two MDS crossovers in the continuous s-domain ...
The basic subtractive crossover construction is straight forward.
TF(HP,LP)= exp(jwTd) - TF(LP,HP), where TF(A,,B) means either A or B.
As @gberchin said, how it's implemented is irrelevant.
In the case where the "base" filer, (on the right of the equation) is linear phase, the "subtractive" filter will also be linear phase provided that Q of the base filter is less than or equal to 0.707... and it matters not whether the base filter is HP or LP. The summed response will be linear phase. For Q greater than 0.707.... the subtractive filter will have a notched response in the stop band and it's phase will flip 180 degrees at the notch, but the summed response will remain linear phase.
However, it may be of interest that that if the base filter (the one on the left) is linear phase with Butterworth amplitude, (LP or HP), and Td is the delay of that filter, the subtractive filter, (HP or LP) will roll off at twice the the rate of the base filter.
I have attached a paper I wrote back in 2002 on the subject of SD filters based on linear phase base filters for those interested.
But it should be recognized that removing nonlinear GD from filter is not the ultimate goal. You stll have to deal with the GD inherent to the drivers due to their minimum phase behavior.
TF(HP,LP)= exp(jwTd) - TF(LP,HP), where TF(A,,B) means either A or B.
As @gberchin said, how it's implemented is irrelevant.
In the case where the "base" filer, (on the right of the equation) is linear phase, the "subtractive" filter will also be linear phase provided that Q of the base filter is less than or equal to 0.707... and it matters not whether the base filter is HP or LP. The summed response will be linear phase. For Q greater than 0.707.... the subtractive filter will have a notched response in the stop band and it's phase will flip 180 degrees at the notch, but the summed response will remain linear phase.
However, it may be of interest that that if the base filter (the one on the left) is linear phase with Butterworth amplitude, (LP or HP), and Td is the delay of that filter, the subtractive filter, (HP or LP) will roll off at twice the the rate of the base filter.
I have attached a paper I wrote back in 2002 on the subject of SD filters based on linear phase base filters for those interested.
But it should be recognized that removing nonlinear GD from filter is not the ultimate goal. You stll have to deal with the GD inherent to the drivers due to their minimum phase behavior.
Attachments
Now that is very interesting! For my paper I only studied linear-phase Linkwitz-Riley responses, because LR is so prevalent in the current audio world. Your observation opens-up a whole new world of possibilities.However, it may be of interest that that if the base filter (the one on the left) is linear phase with Butterworth amplitude, (LP or HP), and Td is the delay of that filter, the subtractive filter, (HP or LP) will roll off at twice the the rate of the base filter.
Yes. It remains to be seen whether it's better to separate the driver compensation from the crossover response, and design each separately, or to try to incorporate both into one overall filter design.But it should be recognized that removing nonlinear GD from filter is not the ultimate goal. You stll have to deal with the GD inherent to the drivers due to their minimum phase behavior.
Hello,
Please ignore post #815 above as there was an error in my script. Both HP and LP work well as the basis filter as long as their group delays are matched to that of the delay line. Sorry for the mistake.
Now, if what I'm getting is what it really is, then it
Please ignore post #815 above as there was an error in my script. Both HP and LP work well as the basis filter as long as their group delays are matched to that of the delay line. Sorry for the mistake.
What if the base filter is HP and not linear phase and we do an MDS using the pure delay ? Would you get the LPF output as usual ? I'm asking this because I do not seem to get anything that resembles an LPF, in either continuous (below) or discrete (post# 783) domain.In the case where the "base" filer, (on the right of the equation) is linear phase, the "subtractive" filter will also be linear phase provided that Q of the base filter is less than or equal to 0.707... and it matters not whether the base filter is HP or LP. The summed response will be linear phase.
Now, if what I'm getting is what it really is, then it
- clearly violates the conventional wisdom that either filter, HP or LP, could be used as the base filter.
- makes @Dave Zan 's question about MDS crossovers more relevant.
- probably needs to be included in @gberchin 's MDS paper.
Last edited:
To be honest, development of the basic MDS concept has advanced so much in just the last year or so that I haven't been able to keep up with it all. I suspect that diyAudio has been responsible for advancing the state of the art more in that time than in the nearly fifty years since Golden proposed it in 1975.probably needs to be included in @gberchin 's MDS paper.
- Home
- Loudspeakers
- Multi-Way
- Why not IIR filters + a global phase linearization by FIR