# Filtering and decimating input as sections in multiple stages

What would be my options to decimate a large input signal available only in sections (or blocks) due to DMA type of interface? The FIR should be about order of 18 only and the total decimation factor of 8. I've made a quick MATLAB function to illustrate this issue.

function decimFilt(varargin)
% Multi-Stage Block-By-Block Decimation Filtering

%% Check input args
enPlot = false;
if nargin>0
enPlot = varargin{1};
end
%%

%% Definitions

% Sample rate and period
fs = 44.440e6;
ts = 1/fs;

% Input
N = 38400;              % Nbr of samples
B = 12;                 % Nbr of blocks
f1 = 0.0125*fs;
f2 = 0.25*fs;
n = (0:ts:N*ts-ts).';
x = sin(2*pi*f1*n) + ...
sin(2*pi*f2*n+pi/6) + ...
0.25*randn(size(n));
%%

%% Filter design
O = 18;
b = fir1(O,0.125);      % Linear-phase FIR filter.
%%

%% Filter and decimate entire signal in one block (REFERENCE).
m = 2;
%   1. stage
[yRef,Z1rf] = decFirFilt(b,x,m);
%   2. stage
[yRef,Z2rf] = decFirFilt(b,yRef,m);
%   2. stage
[yRef,Z3rf] = decFirFilt(b,yRef,m);
%%

%% Filtering and decimating the data as sections (BLOCK-BY-BLOCK)
xBlock = reshape(x,[N/B B]);
%   1. stage
y1m = zeros(N/(m*B),B);
Z1mf = zeros(O,B+1);        % Note! State vector needed per stage!
%   2. stage
y2m = zeros(N/(m*m*B),B);
Z2mf = zeros(O,B+1);        % Note! State vector needed per stage!
%   3. stage
y3m = zeros(N/(m*m*m*B),B);
Z3mf = zeros(O,B+1);        % Note! State vector needed per stage!
for i=1:B,
% Load previous section final condition to the initial condition
Zi = Z1mf(:,i);
[y1m(:,i),Z1mf(:,i+1)] = decFirFiltCond(b,xBlock(:,i),m,Zi);
% Load previous section final condition to the initial condition
Zi = Z2mf(:,i);
[y2m(:,i),Z2mf(:,i+1)] = decFirFiltCond(b,y1m(:,i),m,Zi);
% Load previous section final condition to the initial condition
Zi = Z3mf(:,i);
[y3m(:,i),Z3mf(:,i+1)] = decFirFiltCond(b,y2m(:,i),m,Zi);
end
%%

%% Results
% Plot
if enPlot
figure, ...
stem(yRef,'bo'), grid on, hold on, ...
stem(y3m(:),'kx')
end

% MSE results
mse = mean(abs(y3m(:) - yRef).^2);
fprintf('decimFilt\n MSE:%.4e\n', mse)
%%

end

%% Internal functions
% Decimation filter
function [y, z] = decFirFilt(b, x, m)
[yUnDec, z] = filter(b,1,x);
y = yUnDec(1:m:end);
end

% Decimation filter with  access to initial and final conditions of the delays.
function [y, zo] = decFirFiltCond(b, x, m, zi)
[yUnDec, zo] = filter(b,1,x,zi);
y = yUnDec(1:m:end);
end
%%


I'm guessing some polyphase FIR or FFT-based overlap-add or -save implementations could also be used? What I've calculated the FFT-based overlap-add or -save would not be more efficient for this problem?

• One issue I forgot is that in above it seems that I'm required to save the state vector per stage of the multi-stage decimation FIR filter. – Petri Sep 2 '14 at 6:52
• FFT-based would most likely not be worthwhile thinking about, correct. Should it be multi-stage? What requirement is it on the filter? I doubt you would save that much if you have a filter order of 18 and 8 times decimation. Polyphase-filtering in one go would give you 10/8 = 1.25 multiplications per output sample (assuming linear-phase, you can indeed share multiplications even in polyphase) and any savings would be marginal if even obtainable. The block issue is not obvious to me. Can't you still save the 18 most recent sample from the previous block? – Oscar Sep 2 '14 at 16:51
• Which is what I realize that you do (save the states). I'd say go for one stage polyphase decimation. Even if you split it into multiple stages, assuming that each stage does some filtering there will be at least one multiplication per stage, including the final, easily going beyond the 1.25 multiplications obtained for a single stage result. If you can use CIC-type filters, there will be only additions, and in that case you may be able to at least reduce the number of multiplications. – Oscar Sep 3 '14 at 10:50
• Thanks. I'll try that one stage polyphase with a longer filter and see if could be the answer. Plus, I need to study if that CIC is a option. – Petri Sep 3 '14 at 11:42
• Ok, if you go with a longer filter what I said may not be true anymore. I was especially for that low filter order-decimation factor ratio that single stage was probably the best choice, longer filter leads to at least some possibilities to savings by multiple stages. – Oscar Sep 9 '14 at 20:31