SGN-16006 Bachelor s Laboratory Course in Signal Processing Signal processor assignment (June 2, 2014) Setup the environment for first time use Use the following procedure to start Code composer studio for the first time. Using your own account instead of the below ccs-user account is possible but a lot more difficult. Follow the assignment website for more up-to-date information: http://www.cs.tut.fi/~hehu/sgn-16006/ Steps when running CCS first time. 1. Go to TC303 and log into the computer with your TUT account. 2. Find Code Composer Studio from start menu ancd right-click the program while pressing shift button. 3. Choose "Run as different user" 4. Enter account information as follows Username:.\ccs-user Password: Koodi42orja 5. The program asks for a path for your workbench. This can be e.g., a memory stick, or a folder you have created, e.g., c:\temp\<your account>. 6. Untick "do not ask again", so the next user will not use your workbench. 7. On the first run, the program asks for a license file. Choose "Activate license" and "Specify a license file". A valid license file is stored at C:\Apps\TI\license\. Background This assignment implements real-time digital filters in a signal processor. The assignment is done using Texas Instruments DSP TMS320C6713, that can be found in the classroom TC303. See the timetable in front of the classroom to see when there is no teaching. The instructor for this assignment is lecturer Heikki Huttunen (Heikki.Huttunen@tut.fi). The device is inside the white box by the computers, and in addition to the processor, it consists of all required peripherals, such as memory, I/O and power supply. The devices in class TC303 represent TI s C6000 series, which are the most powerful ones intended for multimedia applications. The processors feature also floating point arithmetic
on hardware, which means that you can freely use float data type. The programming is done using C, and no assembly language is required. Follow the assignment website for bug fixes etc: http://www.cs.tut.fi/~hehu/sgn-16006/ Setup and use The computers are used in many courses, and there s a good chance that the setup is messed up. Thus, perform the following initial checks to make sure everything is installed as it should. Initialization. Check that there s a wire from the computer s audio output into the input of the DSP card. Then check that the connector labeled OUT is connected to computer speakers. Finally, check that there s a USB connection between the white box and the computer, and that the card is powered up (green led). Push the reset button to make sure that there s nothing running in the card. Software. The programming and control of the card is done using software called Code Composer Studio 4.2, which can be found from the desktop. It has been installed on computers 4 and 5 in TC303 (will be in other computers later) and the icon below should be on the desktop. As a basis for programming, use the template that is at http://www.cs.tut.fi/kurssit/sgn-11000/ti-tyo.zip Unzip the file for example to the directory P:\My Documents\TI\. Note: always use the short path (P:\...) instead of the long UNC path (\\homeserver$\hehu\whatever\). CCS does not support UNC filenames. Compile and check. Start Code Composer Studio. At the first time the software asks for the default directory for storing project data. Choose e.g., P:\My Documents\TI\ and mark it as the default location. After this, a black welcome screen opens. On the top right corner there is text "start using CCS"; click the icon next to this text. After this, a desktop like the one below opens.
Open the project template you have downloaded (in directory P:\My Documents\TI\). The opening is done from menus: Project Import Existing CCS/CCE Eclipse Project. A dialog opens asking the location of the new project. Enter the location (e.g., P:\My Documents\TI\Loop_Intr\) into the text box "Select search-directory". If all was correct, CCS finds the template and the dialog should look like below. After this, there is a project tree at the left edge of the desktop (see below). The code to be modified is now in file Loop_intr.c. Open this file, and check that a function called interrupt void c_int11() is defined there. The board will call this function every time a new sample is ready for processing.
The project template simply copies the input to the output. Check that it actually works like this. You can compile the program by right-clicking on the open project(loop_intr), and a context menu like the one below opens. The compilation starts by selecting "Build Project" (or shortcut Ctrl-B). If the compilation was successful, the bottom of the desktop should look like below. you can run the program by choosing the Debug-button (see below) and choose "Debug Active Project".
This opens the debug view that looks like below. At the debug screen, the program has started already, but stopped at the first instruction (beginning of "main()"). To run further, click the "play button at the top of the screen (or shortcut F8). The process tree should after this read "Thread [main] (Running)". Play a file on the computer (internet radio or some samples of Windows Media Player). You should hear the sound from the speakers. If you do, push the red "stop" button (or shortcut Ctrl-Alt-T), and you return to the C/C++ view. Debugging. The compiled has two modes: Debug and Release. The former is used when problems arise, because in Debug mode you can follow the program run line by line. This option makes the program flow slower, and in general you should work in release mode. The selection is made by right-clicking the context menu as shown below.
The basic idea of the Debug mode is that it is possible to monitor the program flow. The program can be halted at any row by clicking the right mouse button at the row and choosing "New Breakpoint Breakpoint". The breakpoint is indicated by a red circle on the left. When the program is run, it halts when entering this row for the first time. At that point you can for example see the values of all variables simply by moving the mouse on top of the variable in the code. This is illustrated in the figure below, where the mouse is set on top of variable rightsample. The most important functions of the debug mode are as follows: <F6>: move one step forward <F5>: enter the function <F8>: run until the next breakpoint More functions available in the Target-menu.
Assignment 1 In this assignment you should implement an FIR highpass filter by editing the file Loop_intr.c. In the beginning of the file you can find the declaration interrupt void c_int11() This function is called every time a new input sample is ready for processing. The most recent sample is fetched using the command input_both_channels(&leftsample, &rightsample); The filtering operation needs the previous inputs, as well. These are stored already in the program into the buffer short inputbuffer[bufferlength]; In the current version, there is the following line outputsample = inputsample; This line copies the input directly to the output. In place of this you should write the FIR filter implementation, which is basically a simple for loop. This is done as follows. 1. Design a FIR highpass filter in Matlab using the command fir1. The cutoff frequency is defined by f c = 2500 + 200n, where n is the last digit of your student number. In case of many members, choose the smallest last digit of all members. Prior to designing the filter, give the following command for better accuracy: format long. The filter order should be 18. 2. Copy the coefficients into the file Loop_intr.c where you define the array float h[] = {0.001201261290430, 0.002048894418557,... etc. }; 3. Replace the above mentioned line (outputsample = inputsample) by something like this: sum = 0.0; /* sum is a float */ for (k = 0; k < N; k++) /* k is an integer */ { sum = sum + something; } outputsample = (short) sum;
The expression "something" has to be replaced by something more intelligent. The definition of a 18th order FIR is 18 y(n) = h(k)x(n k). k=0 Note, however, that you may not be able to access x(n k) if n k < 0. In these cases the n k th sample can be found at index n - k + bufferlength (due to circular buffering). 4. Compile and run. Play the sample file of Windows media player (or similar). You should hear a highpass filtered version of the test file. Common problems Write C, not C++. For example, the variables can only be defined in the beginning of a program block. Remember to compile and upload after changing the code. Be careful with the indexing. Do not try to access x(n k) with k > n. If the coefficients are wrong, you won t probably hear a thing. When you have successfully implemented the task, copy the file into the name t1.c and add into the final zip package to be returned. Add into the written report: Description of what you have done, and the frequency response of the designed filter. The program code of the function void c_int11(). Comment the result and any problems you might have encountered. Assignment 2 Implement an IIR filter with frequency response similar to that of the FIR filter of assignment 1. This means that the stopband and passband ripples should be the same as earlier. The transition band width of the FIR filter can be found using the formula for the Hamming window: f = 3.3 N. The center of the transition band should be the same as earlier. Use the elliptic filter design functions of Matlab: ellipord and ellip. Note that Matlab tends to design better IIR filters than the corresponding FIR filter. This is illustrated in the figure below: the transition band of the IIR filter is narrower.
In practise it is not possible to implement an IIR filter of an order higher than 2. Therefore, higher order filters should b divided into second order sections. There is a command for doing this in Matlab: tf2sos. Considet the 4th order filter: H(z) = 0.5702 2.2627z 1 + 3.3851z 2 2.2627z 3 + 0.5702z 4 1 2.8767 + 3.2538z 2 1.6844z 3 + 0.3410z 4. This is divided into 2nd order sections as follows. >> tf2sos(a,b) ans = 0.5702-1.1377 0.5702 1.0000-1.1851 0.4031 1.0000-1.9730 1.0000 1.0000-1.6916 0.8460 The resulting matrix represents two 2nd order filters: H 1 (z) = 0.5702 1.1377z 1 + 0.5702z 2 1 1.1851 + 0.4031z 2 1 1.9730 + z 2 H 2 (z) = 1 1.6916 + 0.8460z 2, The flowgraph of the implementation is shown below. x(n) w(n) y(n)
1209 Hz 1336 Hz 1477 Hz 697 Hz 1 2 3 770 Hz 4 5 6 852 Hz 7 8 9 941 Hz 0 # Table 1: DTMF-frequencies (dual tone multiple frequency). For example, pressing 5 generates the tone: x(n) = sin(2π 770 n/f s ) + sin(2π 1336 n/f s ). Note that you have to store the signal w(n) of the above figure. Store the implementation into a file called t2.c. Add into the written report: Description of what you have done, and the frequency responses of the designed filters. The program code of the function void c_int11(). Comment the result and any problems you might have encountered. Assignment 3 In PSTN telephone networks, the dialed number is transmitted using so called DTMF signals. A table of frequencies used is shown as table 1. The frequencies are chosen such that they interfere with each other as little as possible. In this assignment you should implement a program that recognizes the vertical set of frequencies: 697 Hz,...,941 Hz. When one or more of these are detected, the corresponding LEDs placed on the board should be lit. The detection is based on calculating the correlation between the inputbuffer and the following two signals: The correlations are defined by c 697 (n) = cos(2π 697 n/f s ), s 697 (n) = sin(2π 697 n/f s ). c cos (697) = c sin (697) = N 1 c 697 (n) x(n), n=0 N 1 s 697 (n) x(n). n=0 Additionally, we need an estimate of the signal power in order to normalize for changes in volume. This can be obtained from the signal variance: N 1 var = x(n) 2. n=0
These quantities are used to construct a detector for each frequency. For example, the presence of the 697 Hz component can be tested using the quantity: w 697 = c2 cos(697) + c 2 sin (697) var The quantity should have a large value when the 697 Hz component is present. Calculate the numbers w 697, w 770, w 852, and w 941 every time you reach the end of buffer. Based on these, determine whether the tone is present by comparing the value with a threshold T 0. Set the threshold experimentally to make the detection as robust and reliable as you can. Based on the decisions, light the LEDs using the function: void setledstatus(int lednumber, int newstatus) defined in c6713dskinit.c. Test the implementation by generating suitable test tones in Matlab and playing them into the board. For example, the test for 697 Hz can be tested with the following lines in Matlab. f = 697; % This is the studied frequency n = 1:8192; x = cos(2*pi*n*f / 8192); soundsc(x); Also the chirp signal can be used for testing: t = 0:1/2000:5; x = chirp(t, 0, 5, 1000); soundsc(x, 2000); The above lines should flash the leds one at a time. Below are a few points of advice. The longer your window is, the better is the separation of frequencies. Experiments indicate that 200 samples should separate the given frequencies rather well. The method can become computationally heavy if you do not take care of efficiency. For example, the cosines and sines should be calculated into a lookup table at startup. Calculate the correlations only when reaching the end of buffer, i.e., not at every iteration. Add into the written report: Description of what you have done. The program code of the function void c_int11(). The Matlab function used for testing. Comment the result and any problems you might have encountered.
Assignment 4 Another method for detecting the DTMF frequencies is to use the Goertzel-algorithm. In this assignment we implement this method for the task of the previous assignment. The method uses an unstable IIR filter, which amplifies the selected frequencies without limit. This does not become a problem, because the filter state is initialized every time the end of buffer is reached. Goertzel-algorithm is an effeicient method for calculating the quantity N 1 X(e iω ) = x(n)e iωn n=0 which is the discrete-time Fourier transform (DTFT) of x(n) at the frequency ω = 2πf/F s. The filter definition is as follows. When detecting the frequency f with sampling frequency F s, the Goertzel filter is y(n) = x(n) + 2 cos(2πf/f s )y(n 1) y(n 2), (1) where y(n) is the filter output and x(n) its input. For example, when detecting the frequency 697 Hz from the signal x(n), the filter becomes or, in approximate terms, y(n) = x(n) + 2 cos(2π 697/24000)y(n 1) y(n 2), y(n) = x(n) + 1.9668y(n 1) y(n 2). The pole-zero plot and the amplitude response of the filter are shown in the figures below. 1 70 0.8 60 0.6 50 Imaginary Part 0.4 0.2 0 0.2 0.4 2 Amplitude response (db) 40 30 20 10 0.6 0 0.8 1 1 0.5 0 0.5 1 Real Part 10 20 0 697 2000 4000 6000 8000 10000 12000 Frequency / Hz The Goertzel filter of Equation (1) is not directly the indicator used for turing on the leds. Instead, it can be shown that the terms y(n 1) and y(n 2) give the DTFT with the rule: X(e iω ) = (y(n 1) e 2πiω y(n 2))e 2πiω(N 1) Since we re interested only in the DTFT magnitude, the equation simplifies to: X(e iω ) 2 = y(n 2) 2 + y(n 1) 2 2 cos(2πω)y(n 2)y(N 1). (2)
More information about the Goertzel algorithm is available at Wikipedia: http://en.wikipedia.org/wiki/goertzel_algorithm. The pseudo code of the Goertzel algorithm is in our case as follows. Denote the detected frequency by f and the sampling frequency by F s. The buffer length is N and the threshold for turning on the led is T 0. 1. Initialize n = 0 and y( 2) = y( 1) = 0. 2. If n < N: (a) Calculate y(n) using Eq. (1). (b) Increment n = n + 1 and return to 2. 3. If n = N: (a) Calculate X(e iω ) 2 using Eq. (2). (b) If X(eiω ) 2 var > T 0, turn led on; else turn led off. (c) Increment n = n + 1 and return to 1. Example. Below is a figure of the output of the filter (1) when f = 697 Hz. In this case x(n) consists only of the frequency 697 Hz. The signal is filtered until the end of buffer (N = 200), and the last two points of output are used for calculating X(e iω ) 2 : X(e iω ) 2 ( 536) 2 + ( 512) 2 2 cos(2π 697/24000) ( 536) ( 512) 968.8. 400 200 0 200 400 y(n 1) y(n 2) 0 50 100 150 200 250 If the parameter f = 941 Hz, the result is as shown below. From the output signal one can calculate X(e iω ) 2 : X(e iω ) 2 ( 5.1) 2 + ( 3.2) 2 2 cos(2π 941/24000) ( 5.1) ( 3.2) 4.6. Obviously, the result is a lot smaller than that of the 697 Hz case, which indicates that 697 Hz is present and 941 is not. 400 200 y(n 2) y(n 1) 0 200 400 0 50 100 150 200 250 Using the Goertzel algorithm, implement a detector similar to assignment 3. Add into the written report:
Description of what you have done. The program code of the function void c_int11(). Comment the result and any problems you might have encountered. Returning the report and implementation Return the written report in PDF format. Create a zip archive containing the files of the five assignments and return that as well. Send the package to Heikki.Huttunen@tut.fi The deadline is Fri. 15th of August, 2014.