I'm working on a virtual bass system and the signal flow is as follows

enter image description here

Where NLD denotes the nonlinear device which introduces both odd and even harmonics, and z^-D is to compensate the group delay caused by the LPF and BPF.

When the lowpass filtered signal pass through the NLD, I need to filter out the higher frequency component because harmonics with too high order is not wanted. However the NLD also introduces a DC offset so I need a DC blocker. That's why I need a BPF after the NLD.

My problem is that when an input signal passes through my virtual bass algorithm, it usually contains a few blocks of silence at the very beginning. These samples with value of zero are still zero after the LPF, but will be converted to the DC offset by the NLD, let's say 0.65 for example. Now I have a step function to feed in the BPF but my BPF has a step response like this

enter image description here

This is definitely audible although it only has a small period of time. Here's my BPF design:

Fs = 44100;
f1 = 50;
f2 = 600;
w1 = f1*2/Fs;
w2 = f2*2/Fs;
[b, a] = butter(1, [w1, w2], 'bandpass');

Is there any other type of BPF which has a low step response? Please tell me how can I avoid it. Thank you!


2 Answers 2


The step response of your BPF has a fast decay, so you may eliminate it by setting the filter states. Have a look at the difference equation of your biquad BPF:

$$ y[n] = 0.0377 x[n] + 0 x[n-1] - 0.0377 x[n-2] + 1.9240 y[n-1] - 0.9246 y[n-2] $$

Since $b_0=-b_2$ and we have $x[n] = 0.65$ for all $n\geq 0$, if we set $x[n-1]=x[n-2] = 0.65$ and $y[n-1]=y[n-2]=0$, we get a zero step response $y[n]=0$ for all $n\geq 0$.

So if you are implementing the biquad filter with direct form I, just initialize your filter states as [0.65, 0.65, 0, 0].

If you are using transposed direct form II, you may use a filter states [-b0*0.65, -b0*0.65].

x = ones(2*Fs, 1) * 0.65;
z = [-b(1)*0.65, -b(1)*0.65];
[y, z] = filter(b, a, x, z);
figure; stem(y)
  • 1
    $\begingroup$ One more thing, you are compensating the group delay and it's better to use Bessel filter which has a relatively flat group delay within passband. $\endgroup$
    – ZR Han
    Commented Nov 18, 2021 at 7:09
  • $\begingroup$ Thank you! I haven't ever thought it this way and it does solve my problem! $\endgroup$
    – DSP novice
    Commented Nov 19, 2021 at 1:52

but will be converted to the DC offset by the NLD,

That is generally a bad idea. DC offsets are a problem in any audio and it would be hard to justify through any physical model. I would take a serious look at the algorithm and try to understand WHY it is necessary to have a DC offset for 0 input. If you absolutely have to have it, I would follow the NLD with a DC blocking filter that you can initialize with the DC offset for zero input.

Please tell me how can I avoid it.

If you absolutely have to do it this way, you need to initialize the state of the filter properly. The procedure of how to do this depends on the specific filter topology as described by ZR Han. A simpler alternative would be

% find the steady state for a unit step
[~,zi] = filter(b,a,ones(10000,1));
%  filter with initialized state
output = filter(b,a,input,zi*DCOffset);

where DCOffset is the output of your NLD for 0 input. If you do frame based processing, make sure that the filter state is preserved across frames.

  • $\begingroup$ Thank you! I'll checked the article which introduces the NLD. $\endgroup$
    – DSP novice
    Commented Nov 19, 2021 at 2:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.