6dB/oct butterworth crossover doesn't have flat response

Started by jungledmnc August 17, 2017
Hi folks,

sorry if I'll be asking a dumb question :). I'd like to build a 6dB/oct
crossover (with variable number of bands and crossover points). First
order butterworth LP and HP filters seem to be working fine and provide
nearly flat magnitude response IF the crossover point isn't high enough,
hence close to the nyquist, then it starts forming something that looks
like a high-shelf of +6dB. 

I assume this is caused by the filter shape not being accurate enough
close to nyquist, correct? (seems that oversampling avoids the problem a
bit)

I'm asking since this is a bit of a surprise to me, since higher order
crossovers I have implemented don't seem to "care" about sampling rate and
are always perfectly flat, so I'm not sure if I didn't mess something up.

If my assumption is correct, is there a way to mitigate the problem? It's
not such a big deal, but still...

Thanks a lot as always!
jungledmnc
---------------------------------------
Posted through http://www.DSPRelated.com
>Hi folks, > >sorry if I'll be asking a dumb question :). I'd like to build a 6dB/oct >crossover (with variable number of bands and crossover points). First >order butterworth LP and HP filters seem to be working fine and provide >nearly flat magnitude response IF the crossover point isn't high enough, >hence close to the nyquist, then it starts forming something that looks >like a high-shelf of +6dB. > >I assume this is caused by the filter shape not being accurate enough >close to nyquist, correct? (seems that oversampling avoids the problem a >bit) > > ... >If my assumption is correct, is there a way to mitigate the problem?
It's
>not such a big deal, but still... > >Thanks a lot as always! >jungledmnc >--------------------------------------- >Posted through http://www.DSPRelated.com
I quickly made a tweaked 1st order LPF (MZT) implementation you could try. It's not perfect but at least improved magnitude response. Here are the Octave code and couple comparison plots: % OCTAVE PACKAGES ----------------------------------- pkg load signal % --------------------------------------------------- fs=44100; fc=3000; Q=0.7071; % Analog -------------------------------------------- w0 = 2*pi*fc; Analogb = 1; Analoga = [1 w0]; % BLT ----------------------------------------------- w0 = 2*pi*fc/fs; BLTb0 = sin(w0); BLTb1 = sin(w0); BLTa0 = cos(w0) + sin(w0) + 1; BLTa1 = sin(w0) - cos(w0) - 1; BLTa = [BLTa0 BLTa1]; BLTb = [BLTb0 BLTb1]; % MZT ----------------------------------------------- p1 = exp(-1.0/(fs*(1/(2 * pi * fc)))); % pole z1 = 0.0; % zero MZTb0 = 1.0; MZTb1 = -z1 MZTa0 = 1.0; MZTa1 = -p1; MZTa = [MZTa0 MZTa1]; MZTb = [MZTb0 MZTb1]; % MZT (tweaked) ------------------------------------- p1 = exp(-1.0/(fs*(1/(2 * pi * fc)))); % pole z1 = atan(-7.5*pi/180); % zero MZTob0 = 1.0; MZTob1 = -z1 MZToa0 = 1.0; MZToa1 = -p1; MZToa = [MZToa0 MZToa1]; MZTob = [MZTob0 MZTob1]; % IIM ----------------------------------------------- w0=2*pi*(fc/fs); Q=1/Q; aa = [Q/w0 1] p = roots(aa) % analog poles IIMa0=1; IIMa1=-exp(p(1)); IIMb0 = 1.0; IIMb1 = 0; IIMa = [IIMa0 IIMa1]; IIMb = [IIMb0 IIMb1]; % plot ---------------------------------------------- Analog = tf(Analogb, Analoga); Analog = Analog/dcgain(Analog); BLT=tf(BLTb, BLTa, 1/fs); BLT=BLT/dcgain(BLT); MZT=tf(MZTb, MZTa, 1/fs); MZT=MZT/dcgain(MZT); MZTo=tf(MZTob, MZToa, 1/fs); MZTo=MZTo/dcgain(MZTo); IIM=tf(IIMb, IIMa, 1/fs); IIM=IIM/dcgain(IIM); wmin = 2 * pi * 20; % 20Hz wmax = 2 * pi * ((fs/2.0) - (fs/2 - 20000)); bode(Analog, 'r', BLT, 'c', MZT, 'b', MZTo, '--', IIM, 'k', {wmin, wmax}); legend('Analog', 'BLT', 'MZT', 'MZT optimized', 'IIM'); Comparison between tweaked MZT and few other fc=300Hz https://s11.postimg.org/im2wdswhv/1storder_LPFcomparison300.png fc=3000Hz https://s11.postimg.org/i6rmksakj/1storder_LPFcomparison.png fc=10000Hz https://s11.postimg.org/umocej3wj/1storder_LPFcomparison10k.png --------------------------------------- Posted through http://www.DSPRelated.com
Thank you! Now, I'm not an Octave/Matlab user, but I'd deal with it. But
for now I found an interesting thing - it is actually enough to perform a
gain on the high band. That makes me thing that maybe I indeed have
something wrong, on the other hand the gain depends on the sampling
frequency, so I'm a bit puzzled. Anyways with a well chosen gain I can get
nearly flat magnitude response. I'd just like to figure out a formula for
the gain and know actually how is that possible :).
---------------------------------------
Posted through http://www.DSPRelated.com
Thank you again! The improved MZT version actually helps a lot!
---------------------------------------
Posted through http://www.DSPRelated.com
>Thank you again! The improved MZT version actually helps a lot! >--------------------------------------- >Posted through http://www.DSPRelated.com
Thanks. My tweaking method was not complete (in this case fc was not within calculation of the z1) but only showed what you can to do to tweak MZT (and IIM) based filters. If you want better results for magnitude response correction and you just need coefficients for your project then here's Octave/Matlab code for MZTi https://www.kvraudio.com/forum/viewtopic.php?p=5072902#p5072902 --------------------------------------- Posted through http://www.DSPRelated.com
>>Thank you again! The improved MZT version actually helps a lot! >>--------------------------------------- >>Posted through http://www.DSPRelated.com > >Thanks. My tweaking method was not complete (in this case fc was not >within calculation of the z1) but only showed what you can to do to
tweak
>MZT (and IIM) based filters. > >If you want better results for magnitude response correction and you
just
>need coefficients for your project then here's Octave/Matlab code for
MZTi
> > >https://www.kvraudio.com/forum/viewtopic.php?pP72902#p5072902 >--------------------------------------- >Posted through http://www.DSPRelated.com
Hmm... I forgot that MZTi implementation behind the link is for 2nd order LP filter ... --------------------------------------- Posted through http://www.DSPRelated.com
I was actually quite surprised you set the z1 to constant, but anyways the
idea is there, that's the main thing ;).
---------------------------------------
Posted through http://www.DSPRelated.com
>I was actually quite surprised you set the z1 to constant, but >anyways
the idea is there, that's the main thing ;). It worked good enough as a constant there so didn't go for finding the best fit formula .... BTW, if you want coefficients to give even more accurate magnitude responses for 6dB/oct LPF ... I'd recommend MIM (Magnitude Invariance Method) method. I plotted 1st - 4th order filters against analog prototype filter ... : Responses: https://s11.postimg.org/llgdiq2v7/mimplots.png Errors: https://s11.postimg.org/ybklvtatf/MIMerrors.png --------------------------------------- Posted through http://www.DSPRelated.com
>Responses: >https://s11.postimg.org/llgdiq2v7/mimplots.png > >Errors: >https://s11.postimg.org/ybklvtatf/MIMerrors.png
Something wrong with the images ... here are new ones: http://postimg.org/image/y1twb98s9/ http://postimg.org/image/sc92d7d89/ --------------------------------------- Posted through http://www.DSPRelated.com