I would like to lowpass filter a long pcm wav file. I designed a 20 order butterworth lowpass filter in Octave and transform the zero pole gain data to a series of second order sections. Then I am applying these SOS filters to each processing block on the long audio. The script is like this:
clear all; close all;
[y, fs, bit] = wavread('sweep.wav');
# design butter
[z, p, k] = butter(20, 1200 / (fs / 2), 'low');
[sos, k] = zp2sos(z, p, k);
# frame index
framesPerBuffer = 512;
currentFrame = 1;
# final condition buffer
zbuf(2) = 0;
while currentFrame + framesPerBuffer < size(y, 1)
# read one frame
data = y(currentFrame:currentFrame + framesPerBuffer - 1, 1);
for i = 1:size(sos, 1)
data = filter(sos(i, 1:3), sos(i, 4:6), data);
end
y(currentFrame:currentFrame + framesPerBuffer - 1, 1) = data;
currentFrame += framesPerBuffer;
end
# apply gain to filtered signal
y = y * k;
The "sweep.wav" input is a mono pcm file with 48kHz sample rate and 16 bit depth with duration of 40 seconds. It is a step sweep signal with each sine tone duration about 1 second, frequency range from 200-12000 Hz. The overall wave shape is like this:
After the filtering process above the output signal has the wavform of this:
Since butterworth filter has the flat passband/stopband, the waveform is clearly not correct. When I listen to the filtered wave it is like a filtered wav plus some low frequency modulation.
I have also tried to add final condition z buffer for the filter function but it is still perform bad. Is there anything wrong for me filter process? How can I get the correct filtered data out of this long PCM? Thank you very much!