ECE 3551 MICROCOMPUTER SYSTEMS 1 Lab 5—Learn to process audio data OBJECTIVE: Learn how to process audio data in ADSP-BF533 EZ-Kit Lite. Learn how to design Finite Impulse Response (fir) filters with MATLAB fdatool. Learn how to implement digital fir filter in DSP using: 32-bit floating point emulation 16-bit integer arithmetic 16-bit fractional arithmetic Learn how to control the audio input/output. Create the Project 1. Before power on the board, make sure that switch SW9 pin1,pin2, pin3, pin4, pin5 and pin6 are turned on., which means all pins in SW9 must be on. 1 2 3 4 5 6 2. Copy the project of “u:\ece3551\labs\lab5”. the previous completed Lab #3 to your u-drive Modify the Project In this lab, you need to learn how to filter audio data and compare the original audio and the filtered audio. In this Lab exercise only stereo input 1 and stereo output 1 will be used. Duplicating the input & controlling the output: Read the data from the input and save it’s copy: one is the original data and another will be the filtered data. PF8 & PF9 is used to control which data is sent to output: In the beginning, LED4 & LED5 are off, and the original data is send to output. So what is heard is the original audio. When PF8 is pressed: The LED4 should turn on, and The low-pass filtered data is send to output. What is heard therefore is filtered audio. By pushing PF8 again, the LED4 should turn off, and the original data is send to output; what is heard is the original audio again. When PF9 is pressed: The LED5 should turn on, and The high-pass filtered data is send to output. What is heard therefore is high-pass filtered audio. By pushing PF9 again, the LED5 should turn off, and the original data is send to output; what is heard is the original audio again. Designing FIR Filters: MATLAB exports FIR filters as a number of coefficients representing that are used to implement moving average (MA) of the input weighted by those coefficients. The general relationship of output and input given with a difference equation of the form: M yn k xn k k 0 Note that this difference equation is equivalent to z transfer function of filter of the form: H z Y z 1 1 X z 1 1 z 2 z 2 M z M Again, note that z-1 denotes unit delay D operator and z-2, denotes 2 unit delays, i.e, D2, etc. Y(z) is z-transform of the output, X(z) is z-transform of the input, M is the order of the filter. Contrasting FIR filter with IIR filter covered in the previous LAB one has to observe that the output is dependent only on the input for FIR filter (Moving Average part). Thus FIR filter as know in the literature as MA filters. For IIR filter the output is dependent on the input (Moving Average part of the filter) as well as the current and past values of the output (Auto Regressive part of the filter). IIR filters are known in literature as ARMA filters. For more information see PPT lecture notes Discrete-Time Signal Processing Framework2.ppt under: http://my.fit.edu/~vkepuska/ece3551/ Note that impulse response of the filter is equal to its coefficients as shown below. y0 0 y1 1 yn 0 n 1 n 1 M n M 1, n n0 0 n n0 n n0 0 otherwise yM M yk 0, k M This realization is indicated in the term Finite Impulse Response of the filter type. The block diagram realization of a filter with M sections is given below: x[n-1] x[n] x[n-2] D β0 D D β1 x[n-M] βM β2 y[n] Example of a fourth-order IIR filter realized by cascading of two bi-quads. Implementation Algorithm Implementation algorithm is straight forward realization of the difference equation presented above: yn 0 xn 1 xn 1 i xn 1 M xn M and n={0,1,2,…} is a time index. H(z) and the difference equation presented above denotes direct form realization of the filter. Note that as any rational function H(z) can be implemented in various other forms that are equivalent (assuming infinite precision representation and arithmetic) transforming original transfer function into other forms namely: Y z H z X z 1 M i 0 i z i M 1 1 a z M 1 i i 0 i 0 Ai 1 ai z 1 Use MATLAB to design 2 types of filters: 1. Low-Pass FIR Filter with following properties: i. ii. iii. iv. v. vi. vii. Response Type = Lowpass Design Method = FIR Window Filter Order (i.e., Number of Filter Coefficients) = 100 Sampling Frequencey Fs = 48000 Hz Cutoff Frequency Fc = 5000 Hz Window = Chebyshev Sidelobe atten. = 80 This Figure depicts default output of the MATLAB fdatool. Exporting the result into a C file following the procedure depicted below from the fdatool (version 7) toolbar: Targets->Generate C Header File o Select Single Precision float should give you the following result: Low-Pass Filter /* * Filter Coefficients (C Source) generated by the Filter Design and Analysis Tool * * Generated by MATLAB(R) 7.0.4 and the Signal Processing Toolbox 6.3. * * Generated on: 09-Mar-2007 10:56:17 * */ /* * Discrete-Time FIR Filter (real) * ------------------------------* Filter Structure : Direct-Form FIR * Filter Length : 101 * Stable : Yes * Linear Phase : Yes (Type 1) */ /* General type conversion for MATLAB generated C-code #include "tmwtypes.h" /* * Expected path to tmwtypes.h * C:\Program Files\MATLAB704\extern\include\tmwtypes.h */ */ /* * Warning - Filter coefficients were truncated to fit specified data type. * The resulting response may not match generated theoretical response. * Use the Filter Design & Analysis Tool to design accurate * single-precision filter coefficients. */ const int BL = 101; const real32_T B[101] = { 2.08284564e-005,1.305201204e-005,-3.947098765e-020, -2.830013e-005,-6.275059422e-005, -8.177757991e-005,-5.905532817e-005,2.021048203e-005,0.0001413606078,0.0002525068703, 0.0002776836918,0.0001528497232,-0.000127544612,-0.000478173024,-0.0007313149981, -0.0006988272653,-0.000272744277,0.0004794355773, 0.00128239661, 0.00172587065, 0.001439732034,0.0003093931591,-0.001373724663,-0.002930190181, -0.00352320238, -0.002544731367,2.92407023e-018, 0.003311318578, 0.005969046615, 0.006471042521, 0.00396144297,-0.001167825307,-0.007134978659, -0.01127221063, -0.01108935289, -0.005519220605, 0.004207141232, 0.006951973774, 0.01455503237, 0.02075315639, 0.01868703589, -0.0117982002, -0.03092020005, -0.04149967432, -0.03530054167, -0.007966354489, 0.0387298055, 0.0965513736, 0.1526996791, 0.193448782, 0.2083333284, 0.193448782, 0.1526996791, 0.0965513736, 0.0387298055, -0.007966354489, -0.03530054167, -0.04149967432, -0.03092020005, -0.0117982002, 0.006951973774, 0.01868703589, 0.02075315639, 0.01455503237, 0.004207141232, -0.005519220605, -0.01108935289, -0.01127221063,-0.007134978659,-0.001167825307, 0.00396144297, 0.006471042521, 0.005969046615, 0.003311318578,2.92407023e-018, -0.002544731367, -0.00352320238,-0.002930190181,-0.001373724663,0.0003093931591, 0.001439732034, 0.00172587065, 0.00128239661,0.0004794355773,-0.000272744277, -0.0006988272653,-0.0007313149981,-0.000478173024,-0.000127544612,0.0001528497232, 0.0002776836918,0.0002525068703,0.0001413606078,2.021048203e-005,-5.905532817e-005, -8.177757991e-005,-6.275059422e-005, -2.830013e-005,-3.947098765e-020,1.305201204e-005, 2.08284564e-005 }; Use the same design to generate the output coefficients for two other data types, 16-bit integer and fractional (fract16) data types using export feature of Target menu of the fdatool. 2. High-Pass FIR Filter with following properties: Response Type = Highpass Design Method = FIR Window Filter Order (i.e., Number of Filter Coefficients) = 100 Sampling Frequencey Fs = 48000 Hz Cutoff Frequency Fc = 1500 Hz Window = Chebyshev Sidelobe atten. = 80 Exporting Filter coefficients: The MATLAB should generate the following Filter Coefficients: /* * Filter Coefficients (C Source) generated by the Filter Design and Analysis Tool * * Generated by MATLAB(R) 7.0.4 and the Signal Processing Toolbox 6.3. * * Generated on: 09-Mar-2007 11:02:20 * */ /* * Discrete-Time FIR Filter (real) * ------------------------------* Filter Structure : Direct-Form FIR * Filter Length : 101 * Stable : Yes * Linear Phase : Yes (Type 1) */ /* General type conversion for MATLAB generated C-code */ #include "tmwtypes.h" /* * Expected path to tmwtypes.h * C:\Program Files\MATLAB704\extern\include\tmwtypes.h */ /* * Warning - Filter coefficients were truncated to fit specified data type. * The resulting response may not match generated theoretical response. * Use the Filter Design & Analysis Tool to design accurate * single-precision filter coefficients. */ const int BL = 101; const real32_T B[101] = { 8.251880899e-006,4.182790235e-006,-2.013020406e-019,-9.069368389e-006,-2.486072117e-005, -4.917652768e-005,-8.351684664e-005,-0.0001287435152,-0.0001846965461,-0.0002497920359, -0.0003206415277,-0.000391740934,-0.0004552827741,-0.0005011465983,-0.0005171177909, -0.0004893754376,-0.0004032729485,-0.0002444141428,-5.440312295e-018,0.0003396060492, 0.0007791773533, 0.001316897571, 0.001942740055, 0.00263710157, 0.003369838931, 0.004099857528, 0.004775369074, 0.005334918387, 0.00570921693, 0.005823784508, 0.005602326244, 0.004970718641, 0.003861422418, 0.002218075097,-2.66584777e-017, -0.002813674044,-0.006220574956, -0.01019261219, -0.01467469707, -0.01958484575, -0.02481574006, -0.0302377902, -0.03570356965, -0.04105348513, -0.04612238333, -0.05074676126, -0.0547722131, -0.05806067586, -0.06049702317, -0.06199470535, 0.9375, -0.06199470535, -0.06049702317, -0.05806067586, -0.0547722131, -0.05074676126, -0.04612238333, -0.04105348513, -0.03570356965, -0.0302377902, -0.02481574006, -0.01958484575, -0.01467469707, -0.01019261219,-0.006220574956, -0.002813674044,-2.66584777e-017, 0.002218075097, 0.003861422418, 0.004970718641, 0.005602326244, 0.005823784508, 0.00570921693, 0.005334918387, 0.004775369074, 0.004099857528, 0.003369838931, 0.00263710157, 0.001942740055, 0.001316897571, 0.0007791773533,0.0003396060492,-5.440312295e-018,-0.0002444141428,-0.0004032729485, -0.0004893754376,-0.0005171177909,-0.0005011465983,-0.0004552827741,-0.000391740934, -0.0003206415277,-0.0002497920359,-0.0001846965461,-0.0001287435152,-8.351684664e-005, -4.917652768e-005,-2.486072117e-005,-9.069368389e-006,-2.013020406e-019, 4.182790235e-006,8.251880899e-006 }; Useful hints ADI VisualDSP++ Blackfin library While you are encouraged to implement your own fir, ADI VisualDSP++ Blackfin library provides several functions that implement fir filters. The following is taken from “VisualDSP++ 4.5 C/C++ Compiler and Library Manual for Blackfin Processors”, page 4-95. fir - finite impulse response filter Synopsis #include <filter.h> void fir_fr16(const fract16 input[], fract16 output[], int length, fir_state_fr16 *filter_state); The function uses the following structure to maintain the state of the filter. typedef struct { fract16 *h, /* filter coefficients */ fract16 *d, /* start of delay line */ fract16 *p, /* read/write pointer */ int k; /* number of coefficients */ int l; /* interpolation/decimation index */ } fir_state_fr16; Description The fir_fr16 function implements a finite impulse response (FIR) filter. The function generates the filtered response of the input data input and stores the result in the output vector output. The number of input samples and the length of the output vector are specified by the argument length. The function maintains the filter state in the structured variable filter_state, which must be declared and initialized before calling the function. The macro fir_init, defined in the filter.h header file, is available to initialize the structure. It is defined as: #define fir_init(state, coeffs, delay, ncoeffs. index) \ (state).h = (coeffs); \ (state).d = (delay); \ (state).p = (delay); \ (state).k = (ncoeffs); \ (state).l = (index) The characteristics of the filter (passband, stopband, and so on) are dependent upon the number of filter coefficients and their values. A pointer to the coefficients should be stored in filter_state->h, and filter_state->k should be set to the number of coefficients. Each filter should have its own delay line which is a vector of type fract16 and whose length is equal to the number of coefficients. The vector should be initially cleared to zero and should not otherwise be modified by the user program. The structure member filter_state->d should be set to the start of the delay line, and the function uses filter_state->p to keep track of its current position within the vector. The structure member filter_state->l is not used by fir_fr16. This field is normally set to an interpolation/decimation index before calling either the fir_interp_fr16 or fir_decima_fr16 functions. Algorithm k 1 y[i] h[ j ] * x[i j ] j 0 Where x is the input signal, y is the output, h are the filter coefficients, k is the number of filter coefficients. Practical Recommendations The data from the input are 24bits long, that’s why the original program use integer to store the data. To filter the data, first left shift 8 bits of the data, make it 16 bits each. After filtering, right shift the filtered data before send it to the output. The FIR example provided by Analog Devices is used to filter a block of data (the number of data input is required must be even). See page 4-95 in VisualDSP++ 4.5 C/C++ Compiler and Library Manual for fir_fr16 library function. The alternative is to implement yourself the filtering function which will enhance your understanding of digital filtering. If you chose to implement your own filtering function the following expression must be coded: N y[n] w[k ] * x[n k ] k 0 Where, n is time index, x[n ] is the input signal, w[k ] are the filter coefficients, N +1 is the number of filter coefficients, and y[n] is the output filtered signal. How to implement the digital filter in BF-533 This lab requires real-time data processing, which means in each sampling interval, you must get two filtered samples (left and right channels). Otherwise, the output will be distorted. In DSP, data movement in memory is very time consuming. To avoid data movement, a circular buffer is used to store the input data. Go to http://en.wikipedia.org/wiki/Ring_buffer for more information about circular buffer. (The buffer size should be equal to the number of coefficients, 101 in our example) Try debugging model first in simulator mode, and then use the release model to compile your program, which will show you best possible real-time performance. Lab report and the complete VisualDSP++ project is needed for this lab. Specifically I would like you to pay attention to the difference in the sound quality when applying IIR low-pass filters compared to high-pass filters and among various implementations. Describe your observations and make an attempt to explain why you are hearing/noticing this difference if any. Contrast this implementation with IIR filters. What are advantages of iir and what are advantages of fir filters. What are potential disadvantages of iir and fir filters?