Introduction
Filters can be used to shape the signal spectrum in a desired way or to perform mathematical operations such as differentiation and integration.
Compensating for Delay Introduced by Filtering
Digital filters introduce delay in your signal. Depending on the filter characteristics, the delay can be constant over all frequencies, or it can vary with frequency. The type of delay determines the actions you have to take to compensate for it. The grpdelay function allows you to look at the filter delay as a function of frequency. Looking at the output of this function allows you to identify if the delay of the filter is constant or if it varies with frequency (i.e. if it is frequency-dependent).
Filter delay that is constant over all frequencies can be easily compensated for by shifting the signal in time. FIR filters usually have constant delay. On the other hand, delay that varies with frequency causes phase distortion and can alter a signal waveform significantly. Compensating for frequency-dependent delay is not as trivial as for the constant delay case. IIR filters introduce frequency-dependent delay.
Compensating for Constant Filter Delay
As mentioned before, you can measure the group of delay of the filter to verify that it is a constant function of frequency. You can use the grpdelay function to measure the filter delay, D, and compensate for this delay by appending D zeros to the input signal and shifting the output signal in time by D samples.
Consider a noisy electrocardiogram signal that you want to filter to remove high frequency noise above 75 Hz. You want to apply an FIR lowpass filter and compensate for the filter delay so that the noisy and filtered signals are aligned correctly and can be plotted on top of each other for comparison.
Fs = 500; % sample rate in Hz N = 500; % number of signal samples rng default; x = ecg(N)'+0.25*randn(N,1); % noisy waveform t = (0:N-1)/Fs; % time vector % Design a 70th order lowpass FIR filter with cutoff frequency of 75 Hz. Fnorm = 75/(Fs/2); % Normalized frequency df = designfilt('lowpassfir','FilterOrder',70,'CutoffFrequency',Fnorm);
Plot the group delay of the filter to verify that it is constant across all frequencies indicating that the filter is linear phase. Use the group delay to measure the delay of the filter.
grpdelay(df,2048,Fs) % plot group delay D = mean(grpdelay(df)) % filter delay in samples
D = 35
Before filtering, append D zeros at the end of the input data vector, x. This ensures that all the useful samples are flushed out of the filter, and that the input signal and the delay-compensated output signal have the same length. Filter the data and compensate for the delay by shifting the output signal by D samples. This last step effectively removes the filter transient.
y = filter(df,[x; zeros(D,1)]); % Append D zeros to the input data y = y(D+1:end); % Shift data to compensate for delay
Compensating for Frequency-Dependent Delay
Frequency-dependent delay causes phase distortion in the signal. Compensating for this type of delay is not as trivial as for the constant delay case. If your application allows off-line processing, you can remove the frequency-dependent delay by implementing zero-phase filtering using the filtfilt function. filtfilt performs zero-phase filtering by processing the input data in both the forward and reverse directions. The main effect is that you obtain zero-phase distortion, i.e., you filter data with an equivalent filter that has a constant delay of 0 samples. Other effects are that you get a filter transfer function which equals the squared magnitude of the original filter transfer function, and a filter order that is double the order of the original filter.
% Design a 7th order lowpass IIR elliptic filter with cutoff frequency of 75 Hz. Fnorm = 75/(Fs/2); % Normalized frequency df = designfilt('lowpassiir',... 'PassbandFrequency',Fnorm,... 'FilterOrder',7,... 'PassbandRipple',1,... 'StopbandAttenuation',60);
grpdelay(df,2048,'half',Fs)
Filter the data and look at the effects of each filter implementation on the time signal.
y1 = filter(df,x); % non-linear phase filter - no delay compensation y2 = filtfilt(df,x); % zero-phase implementation - delay compensation
Notice how zero-phase filtering effectively removes the filter delay.
Zero-phase filtering is a great tool if your application allows for the non-causal forward/backward filtering operations, and for the change of the filter response to the square of the original response.
Filters that introduce constant delay are linear phase filters. Filters that introduce frequency-dependent delay are non-linear phase filters.
Removing Unwanted Spectral Content from a Signal
Filters are commonly used to remove unwanted spectral content from a signal. You can choose from a variety of filters to do this. You choose a lowpass filter when you want to remove high frequency content, or a highpass filter when you want to remove low frequency content. You can also choose a bandpass filter to remove low and high frequency content while leaving an intermediate band of frequencies intact. You choose a bandstop filter when you want to remove frequencies over a given band.
Consider an audio signal that has a power-line hum and white noise. The power-line hum is caused by a 60 Hz tone. White noise is a signal that exists across all the audio bandwidth.
Plot the power spectrum of the signal. The red triangular marker shows the strong 60 Hz tone interfering with the audio signal.
[P,F] = pwelch(y,ones(8192,1),8192/2,8192,Fs,'power');
You can first remove as much white noise spectral content as possible using a lowpass filter. The passband of the filter should be set to a value that offers a good trade-off between noise reduction and audio degradation due to loss of high frequency content. Applying the lowpass filter before removing the 60 Hz hum is very convenient since you will be able to downsample the band-limited signal. The lower rate signal will allow you to design a sharper and narrower 60 Hz bandstop filter with a smaller filter order.
Design a lowpass filter with passband frequency of 1 kHz, and stopband frequency of 1.4 kHz. Choose a minimum order design.
Fp = 1e3; % Passband frequency in Hz Fst = 1.4e3; % Stopband frequency in Hz Ap = 1; % Passband ripple in dB Ast = 95; % Stopband attenuation in dB % Design the filter df = designfilt('lowpassfir','PassbandFrequency',Fp,... 'StopbandFrequency',Fst,'PassbandRipple',Ap,... 'StopbandAttenuation',Ast,'SampleRate',Fs);
% Filter the data and compensate for delay D = mean(grpdelay(df)); % filter delay ylp = filter(df,[y; zeros(D,1)]);
ylp = ylp(D+1:end);
Look at the spectrum of the lowpass filtered signal. Note how the frequency content above 1400 Hz has been removed.
[Plp,Flp] = pwelch(ylp,ones(8192,1),8192/2,8192,Fs,'power');
From the power spectrum plot above, you can see that the maximum non-negligible frequency content of the lowpass filtered signal is at 1400 Hz. By the sampling theorem, a sample frequency of 2*1400 = 2800 Hz would suffice to represent the signal correctly, you however, are using a sample rate of 44100 Hz which is a waste since you will need to process more samples than those necessary. You can downsample the signal to reduce the sample rate and reduce the computational load by reducing the number of samples that you need to process. A lower sample rate will also allow you to design a sharper and narrower bandstop filter, needed to remove the 60 Hz noise, with a smaller filter order.
Downsample the lowpass filtered signal by a factor of 10 to obtain a sample rate of Fs/10 = 4.41 kHz. Plot the spectrum of the signal before and after downsampling.
Fs = Fs/10; yds = downsample(ylp,10); [Pds,Fds] = pwelch(yds,ones(8192,1),8192/2,8192,Fs,'power');
Now remove the 60 Hz tone using an IIR bandstop filter. Let the stopband have a width of 4 Hz centered at 60 Hz. We choose an IIR filter to achieve a sharp frequency notch, small passband ripple, and a relatively low order. Process the data using filtfilt to avoid phase distortion.
% Design the filter df = designfilt('bandstopiir','PassbandFrequency1',55,... 'StopbandFrequency1',58,'StopbandFrequency2',62,... 'PassbandFrequency2',65,'PassbandRipple1',1,... 'StopbandAttenuation',60,'PassbandRipple2',1,... 'SampleRate',Fs,'DesignMethod','ellip');
Perform zero-phase filtering to avoid distortion.
ybs = filtfilt(df,yds);
Finally, upsample the signal to bring it back to the original audio sample rate of 44.1 kHz which is compatible with audio soundcards.
yf = interp(ybs,10); Fs = Fs*10;
Take a final look at the spectrum of the original and processed signals. Notice how the high frequency noise floor and the 60 Hz tone have been attenuated by the filters.
Reference,
1. MathWorks