FIR Digital Filter Design
FIR Fractional Delay Filter Design
Use of a Transition BandSearch Spectral Audio Signal Processing
Would you like to be notified by email when Julius Orion Smith III publishes a new entry into his blog?
We close this appendix with a slightly more advanced example of fractional-delay FIR filter design. In addition to working with unwrapped phase and enforcing odd symmetry as illustrated above, we will employ a transition band near half the sampling rate over which the desired frequency response will be tapered to zero. Such a transition band should be used whenever there is an inherent discontinuity at half the sampling rate. In return for giving up on the extreme high-frequency portion of the spectrum, we will obtain much better performance at lower (more audible) frequencies.
In this example, the desired frequency response is
% Example matlab program for fractional-delay FIR design N = 64; % FFT size (power of 2) = 2* FIR length power = N/4 + 0.4;% Spectrum will be raised to this power tw = round(N/10); % Transition width, passband to fs/2, % in FFT bins (to reduce time-aliasing) fs = 1; % Sampling frequency T = 1/fs; % Sampling period f = (0:N-1)/N; % Frequency axis w = 2*pi*f; % rad/sec S = exp(-j*w*T); % Frequency response of a unit delay No2 = N/2; Nspec = No2+1; % Index of fs/2 in all spectrum arrays Sh = S(1:Nspec); % Drop negative frequencies Sm = abs(Sh); Sp = angle(Sh); Spu = unwrap(Sp); % unwrap phase if Spu(1) ~= 0, error('DC phase should be zero'); end % Apply spectral modification separately to mag and phase Stm = Sm .^ power; Stpu = Spu * power; Stu = Stm .* exp(j*Stpu); % Reassemble complex spectrum % Apply transition-band weighting xndx = Nspec-tw:Nspec; % Indices spanning transition band ramp = 1:-1/tw:0; % Simple linear ramp to 0 sinramp = sin(ramp*0.5*pi/ramp(1)).^2; % Half-Hanning Stu(xndx) = Stu(xndx) .* sinramp; % Stu(xndx) = Stu(xndx) .* ramp; % Compare linear ramp % Append negative-frequency spectrum: Stu = [Stu,conj(Stu(No2:-1:2))]; stu = ifft(Stu); % here is our FIR filter stu = real(stu); % remove imaginary round-off error |
Figure B.31 shows the final impulse response designed by the program in Fig.B.30. The point of symmetry between the ``pre-ring'' and ``post-ring'' is marked with a vertical dashed line. This is a good point at which to estimate time aliasing as the signal energy near that point divided by the total signal energy. Some matlab for this is as follows:
% Estimate time aliasing due to use of a finite IFFT size % with this nonlinear spectral transformation. nh = N/32; % half of measurement interval ta = stu(tfndx-nh:tfndx+nh); % signal near fold-time taerr = norm(ta)/norm(stu); disp(sprintf(... 'Estimated time-aliasing energy bound = %0.2f%%',... taerr*100));This code can be appended to that in Fig.B.30. In the present example, the time aliasing estimate was
Figure B.32 shows the final amplitude response and group delay of the designed FIR filter. The transition band can be clearly seen at the right of the amplitude response. Some matlab for measuring the average delay versus frequency not including the transition band is as follows:
% Measure group delay of causal portion of impulse response: gdel = grpdelay(stu(1:No2),1,Nspec); pbendx = (Nspec - tw); % Passband edge index meangd = mean(gdel(1:pbendx)); % Measure in passband only disp(sprintf('Expected group delay = %0.2f samples',power)); disp(sprintf(... 'Measured mean group delay = %0.2f samples',meangd));This code can be appended to that in Fig.B.30. In the present example, the measured group delay was
Thus, we conclude that FIR fractional delay filters of very high quality can be designed simply using phase unwrapping and a transition band near half the sampling rate. The quality also goes up, of course, as the FIR filter length is increased (N in Fig.B.30). Such ``nonparametric'' methods can be highly effective for the design of a wide variety of FIR filters with comparatively ``exotic'' desired frequency-responses.
