The Math Forum

Search All of the Math Forum:

Views expressed in these public forums are not endorsed by NCTM or The Math Forum.

Math Forum » Discussions » Software » comp.soft-sys.matlab

Notice: We are no longer accepting new posts, but the forums will continue to be readable.

Topic: zero phase low pass filter - filtfilt and IFIR
Replies: 9   Last Post: May 15, 2013 4:25 AM

Advanced Search

Back to Topic List Back to Topic List Jump to Tree View Jump to Tree View   Messages: [ Previous | Next ]
Wayne King

Posts: 2,961
Registered: 4/1/09
Re: zero phase low pass filter - filtfilt and IFIR
Posted: Dec 13, 2009 8:56 AM
  Click to see the message monospaced in plain text Plain Text   Click to reply to this topic Reply

"Yow" <> wrote in message <hg2pps$g4c$>...
> hi,
> i try the following, not much difference, the voice signal still have clear delay (lagging) effect. Any further idea to remove the delay effect ?
> [x, Fs] = wavread('c:\wav\sample.wav');
> h=fdesign.lowpass('Fp,Fst,Ap,Ast',1000,1010,0.1,1,Fs);
> d=design(h,'equiripple'); %Lowpass FIR filter
> disp(d);
> [y,y_tail]=filter(d.Numerator,1,x);
> disp(['ok2']);
> gd = (numel(d.Numerator)-1)/2;
> disp(['ok3']);
> disp(size(y));
> disp(size(y_tail));
> len_y = length(y);
> len_y_tail = length(y_tail);
> df=length(y)-length(y_tail);
> disp(df);
> if (df >0)
> disp(sprintf('3.1 = %d', df));
> for k=len_y_tail:len_y
> %disp(sprintf('bk = %d', k));
> y_tail(k) = 0;
> disp(sprintf('k = %d', k));
> end
> end
> %Then you obtain the whole y by concatenating y and y_tail
> y = [y, y_tail.'];
> disp(['ok4']);
> y_nodelay = y(floor(gd)+(1:numel(x)));
> disp(['ok5']);
> wavwrite(y_nodelay, 'c:\wav\filter\sample_new.wav');
> disp(['ok6']);
> regards,
> yow

Hi Yow, and others,
Yes, it is true that filtfilt() does not currently accept filter objects as inputs, but you can still take advantage of the flexibility and strength of fdesign.<response> and simply extract the filter coefficients to use in filtfilt(). This is straightforward in the case of an FIR filter:

Hd = fdesign.lowpass('Fp,Fst,Ap,Ast',1000,1200,0.5,60,10000);
D = design(Hd,'equiripple');
% Now you can call filtfilt() with the numerator coefficients
Y = filtfilt(D.Numerator,1,randn(1024,1));

In the case of an IIR filter, it's a bit trickier since those are implemented as biquad filters. You can use sos2tf() to extract the filter coefficients, but in this case I caution you to be careful because the higher the order of the IIR filter, the more numerical problems due to round off may occur in the SOS to transfer function conversion.
For example:
% Notice I pick a fairly low order filter here
Hd = fdesign.lowpass('N,F3dB',8,1000,10000);
D = design(Hd,'butter');
[B,A]= sos2tf(D.sosMatrix,D.ScaleValues);

% You can up the filter order, but again always view your resulting transfer function
% to see if it has been affected by numerical problems
Hd = fdesign.lowpass('N,F3dB',15,1000,10000);
D = design(Hd,'butter');
[B,A]= sos2tf(D.sosMatrix,D.ScaleValues);
fvtool(B,A) % still looks fine
y = filtfilt(B,A,randn(1024,1));

The above procedure should allow you to use filtfilt() and still take advantage of fdesign.<response> and their associated design methods.

Hope that helps,

Point your RSS reader here for a feed of the latest messages in this topic.

[Privacy Policy] [Terms of Use]

© The Math Forum at NCTM 1994-2018. All Rights Reserved.