FIR Filter with size(kernel) > size(buffer)

DSP, Plug-in and Host development discussion.
KVRer
18 posts since 19 Mar, 2019

Post Wed Mar 17, 2021 8:33 am

Hello. So I've been starting again with audio coding and decided to start with FIR filters.
I have a nice code that produces the windowed filter kernels properly.

However I have problem in a situation where the filter kernel (lets say nK) is larger than the audio buffer (lets say nFrames). I've tried to simulate the behaviour with matlab as it's easier to debug:

This is the main loop. x1 is the input signal with three sine frequencies.

for i=1:nFrames:length(x1)
startIndx=i;
in=x1(i:(i-1)+nFrames);
in_test=in-x1(i:i-1+nFrames);

[out,xPrev]=process_myFIR_v2(in,xPrev,nFrames,h, length(h));
y1(i:(i-1)+nFrames)=out;

end

Then I take the FFT's and compare the results with MATLAB's own filter(B,A,y) command.
The loop works just fine in cases where nK<=nFrames, as I said earlier. The problem obviously lies somewhere in process_myFIR_v2() function.
When FIR loop is calculating the previous values:
if (i < j)
tmp = tmp+kernel(j)*xPrev(j-i); - I am using 'inverted' previous x-vector 'xPrev' so that xPrev(index=0) gives the "most recent" value and xPrev(k-1) gives the latest required value for the kernel.

So this works in cases nK<nFrames - so the problem is in my pushback loop, where I'm pushing the most recent 'xPrev' values as follows:

xPrev(nF+1:nK-nF-1) = xPrev(1:nK-nF).

So the code looks like this:
%% Write the xPrev vector
if (kernelSize-1<=nFrames)
for k=1:1:kernelSize-1
xP(k)=x(nFrames-k+1);
end
else
% Pushback the previous xPrev to the end before inputting x to 1:nf
% Try using temporary storage 'xP2'
prevSize=kernelSize-1;
xP2=zeros(1,prevSize-nFrames);
for k=1:prevSize-nFrames
xP2(k)=xP(k);
end

% Write the input buffer to xPrev, inverted.
for n=1:1:nFrames
xP(n)=x(nFrames-n+1); % Copies input to first part of xPrev, reversed
end

% Insert temporary buffer xP2
for k=1:prevSize-nFrames
xP(nFrames+k)=xP2(k);
end

end

Unfortunately MATLAB uses the horrible indexing system starting from '1' so everything gets confusing when working with c++ in conjunction.
If anyone is willing to help, I'd much appreciate that.

EDIT:

Here's the filter frequency response when nK=296 (order of filter) and I'm using nFrames=200.
Figure(5) shows the filtered signal with my code and figure(6) is the MATLAB filter() function filtered signal (no previous values required etc). Samplerate is 24kHz
You do not have the required permissions to view the files attached to this post.

KVRian
1379 posts since 26 Apr, 2004 from UK

Post Wed Mar 17, 2021 1:15 pm

You need a temporary buffer the same length as nFrames. Start by making it like that, copy in a circular buffer the new buffer and make the FIR output.
Then once you have something that works, you can "optimize". Create nFrames/nk rounded up buffers. Each time you get a new buffer, rotate the past buffers and copy the new one in your list. Apply the FIR.
Just basic algorithm. Return to the basics first.
The end.

KVRer

Topic Starter

18 posts since 19 Mar, 2019

Post Wed Mar 17, 2021 11:44 pm

Miles1981 wrote:
Wed Mar 17, 2021 1:15 pm
You need a temporary buffer the same length as nFrames. Start by making it like that, copy in a circular buffer the new buffer and make the FIR output.
Then once you have something that works, you can "optimize". Create nFrames/nk rounded up buffers. Each time you get a new buffer, rotate the past buffers and copy the new one in your list. Apply the FIR.
Just basic algorithm. Return to the basics first.
The end.
Thank you. I got it working now!

User avatar
KVRer
12 posts since 13 Apr, 2021 from Paris, France

Post Tue Apr 13, 2021 3:08 pm

Hi Miles, talking about optimize buffers, we're looking for an expert on the subject, in the form of a consulting mission. Would you be interested?
Miles1981 wrote:
Wed Mar 17, 2021 1:15 pm
You need a temporary buffer the same length as nFrames. Start by making it like that, copy in a circular buffer the new buffer and make the FIR output.
Then once you have something that works, you can "optimize". Create nFrames/nk rounded up buffers. Each time you get a new buffer, rotate the past buffers and copy the new one in your list. Apply the FIR.
Just basic algorithm. Return to the basics first.
The end.

Return to “DSP and Plug-in Development”