Trying to demonstrate group delay but not seeing any in dsp.BiquadFilter.
3 views (last 30 days)
In the following code I am using part of the parametric equalizer example to show group delay in signals. I have generated a 2 channel signal of 40Hz @ -3.02dB FS on channel 1 and a signal of 200Hz @ -3.02dB FS on channel 2. In the plot ax1 is the magnitude response from 20-300Hz, and ax2 is the group delay over the same frequency range. In ax3 is the input signal, and ax4 shows the output signal after the filter has been applied. You can see the 3dB increase in the 40Hz signal. But... I don't see the ~244 sample delay in the 40Hz output. If I look closely at the 200Hz signal I can see the approximately -1 sample delay in the output.
Fs = 44.1e3;
Samples = [0:10*Fs];
yInput(Samples+1,1) = 1/sqrt(2)*sin(2*pi*40*Samples/Fs);
yInput(Samples+1,2) = 1/sqrt(2)*sin(2*pi*200*Samples/Fs);
F0 = 40; N = 2; Q1 = 2; G = 3;
Wo = F0/(Fs/2); BW1 = Wo/Q1;
[B1,A1] = designParamEQ(N,G,Wo,BW1);
BQ1 = dsp.BiquadFilter('SOSMatrix',[B1.',[1,A1.']]);
% hfvt = fvtool(BQ1,'Fs',Fs,'FrequencyScale','Log');
% set(hfvt, 'OverlayedAnalysis', 'grpdelay');
yOutput = BQ1(yInput);
% determine magnitude and group delay
[h,fh] = freqz(BQ1,Fs,'whole',Fs);
[d,fd] = grpdelay(BQ1,Fs,'whole',Fs);
MagnitudeAt40Hz = 20*log10(abs(h(41))), DelayAt40Hz = d(41)
MagnitudeAt200Hz = 20*log10(abs(h(201))), DelayAt200Hz = d(201)
ax1 = nexttile; semilogx(ax1,fh(21:301),20*log10(abs(h(21:301))));
xlim([20 300]); xlabel('Freq (Hz)'); ylabel('Magnitude'); grid on;
ax2 = nexttile; semilogx(ax2,fd(21:301),d(21:301));
xlim([20 300]); xlabel('Freq (Hz)'); ylabel('Group Delay'); grid on;
ax3 = nexttile; plot(yInput(43350:44850,:));
xlim([0 1500]); xticks(0:250:1500); xlabel('Time (samples)'); ylabel('Input Waveform'); grid on;
ax4 = nexttile; plot(yOutput(43350:44850,:));
xlim([0 1500]); xticks(0:250:1500); xlabel('Time (samples)'); ylabel('Output Waveform'); grid on;
What am I doing wrong here? Shouldn't the blue trace be shifted 244 samples to the right in the Output Waveform?
Paul on 13 Jan 2022
I thought group delay shifts the low frequency envelope of the signal and phase delay (phase / frequency) shifts the high frequency carrier of the signal. That is
u[n] = s[n]*cos(w0*n) -> y[n] = s[n - grpdelay]*cos(w0*(n - phasedelay)
But the example code doesn't include the low frequency envelope on the input sine wave. Because the phase of the filter is nearly exactly zero at 40 Hz and pretty close to zero at 200 Hz, the phase delay at those frequencies is also essentially zero, so we basically see zero phase shift in both outputs relative to the inputs.