Fixed-Point Lowpass Filtering Using Embedded MATLAB™ MEX
This is a demonstration of some aspects of the Embedded MATLAB™ C-MEX generation (emlmex). You will generate a C-MEX function from M code, run the generated C-MEX function, and display the results.
Contents
- Description of the Demonstration
- Copy Required File
- Inspect the Weighted Average Function
- Create the Lowpass Coefficients
- Create the Chirp Input Signal
- Run the Filter with Floating-Point Data Types
- Define Fixed-Point Parameters
- Compile the M-File into a MEX File
- Run the Filter with Fixed-Point Data Types
- Plot the Results
- Clean up Temporary Files
Description of the Demonstration
In this example, you take the weighted average of a signal. By choosing the weights, or coefficients, in a certain way, you can average out only high frequencies and retain low frequencies. Because you are allowing the low frequencies to pass through without modification, this is called a "lowpass filter". A filter of this kind can be used to remove high-frequency hiss from a telephone, for example. A different choice of coefficients would allow you to filter out different frequency bands.
Copy Required File
There is an M-file that is needed to run this demonstration. Copy it to a temporary directory. This step requires write-permission to the system's temporary directory.
emlmexdir = [tempdir filesep 'emlmexdir']; if ~exist(emlmexdir,'dir') mkdir(emlmexdir); end emlmexsrc = ... fullfile(matlabroot,'toolbox','fixedpoint','fidemos','emlmexfilter.m'); copyfile(emlmexsrc,emlmexdir,'f');
Inspect the Weighted Average Function
The function that performs the weighted average is in file emlmexfilter.m:
type(fullfile(emlmexdir,'emlmexfilter.m'))
function [y,z] = emlmexfilter(b, x, y, z)
%EMLMEXFILTER Filter used in EMLMEXBASICSDEMO.
% Copyright 1984-2008 The MathWorks, Inc.
%#eml
for k=1:length(x);
z = [x(k);z(1:end-1)];
y(k) = b*z;
end
The following variables are use in this function:
- b is a row-vector of filter coefficients.
- x is the input signal vector.
- y is the output signal vector of the same size as x.
- z is a column vector of the filter states of the same size as b.
The state vector z allows you to start and stop the filter over multiple sections, for example, if the data is being streamed into the function over time.
So that you can see the effect of the filter, you use a chirp signal for the input x. If played, this chirp sounds like a bird's chirp, going from low frequency to high frequency. In the plot of the output, you can see the low frequencies passing through unchanged (but delayed a little bit), and the higher frequencies are attenuated.
Create the Lowpass Coefficients
Create FIR filter coefficients using Signal Processing Toolbox™.
% [L,fo,mo,w] = firpmord([1500 2000],[1 0], [0.01 01.], 8000 ); % b = firpm(L,fo,mo,w);
b = [ -0.0204578867332896
0.0086603954613574
0.1068667619076360
-0.2187706460534480
0.0730546552429822
0.3153037876114750
0.4649509557016000
0.3153037876114750
0.0730546552429822
-0.2187706460534480
0.1068667619076360
0.0086603954613574
-0.0204578867332896]';
stem(b)
title('Filter coefficients')
Create the Chirp Input Signal
Fs = 256; % Sampling frequency Ts = 1/Fs; % Sample time t = 0:Ts:1-Ts; % Time vector from 0 to 1 second f1 = Fs/2; % Target frequency of chirp set to Nyquist gain = (1-2^-15); % Scale the input to be in the range [-1, +1) x0 = gain * sin(pi*f1*t.^2); % Linear chirp from 0 to Fs/2 Hz in 1 second. z0 = zeros(length(b),1); y0 = zeros(size(x0));
Run the Filter with Floating-Point Data Types
emlcurdir = pwd; cd(emlmexdir); yfl = emlmexfilter(b, x0, y0, z0);
Define Fixed-Point Parameters
Define fixed-point parameters with 12-bit word length and 32-bit accumulator.
reset(fipref); bfi = fi(b, 1, 12); xfi = fi(x0, 1, 12); zfi = fi(z0, numerictype(xfi)); yfi = fi(y0, 1, 12, 10); F = fimath('ProductMode', 'KeepLSB', ... 'ProductWordLength', 32,... 'SumMode', 'KeepLSB', ... 'SumWordLength', 32,... 'OverFlowMode', 'wrap',... 'Roundmode', 'nearest'); bfi.fimath = F; xfi.fimath = F; zfi.fimath = F; yfi.fimath = F;
Compile the M-File into a MEX File
emlmex emlmexfilter -eg {bfi, xfi, yfi, zfi} -o emlmexfilterx
Run the Filter with Fixed-Point Data Types
yfi2 = emlmexfilterx(bfi, xfi, yfi, zfi);
Plot the Results
t = 1:length(x0); subplot(3,1,[1 2]); plot(t,x0,'c',t,yfl,'o-',t,yfi2,'s-');legend('Input','Floating point','Fixed Point') subplot(3,1,3);plot(double(yfi2(:))-yfl(:),'r');ylabel('Error') figure(gcf)
Clean up Temporary Files
cd(emlcurdir); clear emlmexfilterx; status = rmdir(emlmexdir,'s');
Store
