Alex Jamshedi
Jacie Unpingco
Alexander Thurber
DSK Final project
In this lab we learned how to apply FIR filters with the DSK board. We used the FIR filters to recover audio signals that had been corrupted with an added tone. In previous labs we have used FIR filters with MATLAB but transferring this theory to practice with the DSK was introduced in this lab. The goal of this lab was to recover a C major scale from a C major scale that had a high magnitude tone added to it. We knew that this could be done with a low pass FIR filter. The results shown in our frequency spectrum graphs show we were successfully able to crop out the unwanted tone. As we can see in Figure 1 the mixed signal has two peaks, one of those peaks represents the added tone that ideally needs to be removed. We can see by Figure 3 that we were able to remove the unwanted peak that represented the added tone, as we can now observe only one peak in the frequency spectrum. This shows our filter was appropriate for filtering out the unwanted tone from the C major scale.
Theory Questions:
1. Specify how you come up with the filter parameters and the coefficients in the report. Record the order, the type, and the cut off frequency (ies) of the filter and sketch the frequency response of the filter in your report.
For our mixed signal of our C-scale and noise signal, the C-scale was between 261 Hz and 524 Hz while our noise signal was at 1 kHz. Since our frequencies were so low, we chose to use a 40th order low pass filter with a cutoff frequency of 800 Hz. We had to choose a low order because if we didn’t then the filter would not work in the CCS program. To obtain the filter coefficients we first used our desired frequency divided by half of the sampling frequency to get a cut-off frequency for the filter. Then we used the function fir1 with the order of the filter and our cut-off frequency to get the coefficients of our filter.
2. Compare the spectrum of the recovered signal and the mixed signal. State your observations.
The mixed signal time and frequency domain responses are shown below in figures one and two. And the recovered time and frequency domain responses are shown in figures three and four on the next page.
Figure 1: Mixed time domain spectrum, C major scale added to unwanted signal tone
Figure 2: Mixed signal frequency spectrum, C major scale added to unwanted signal tone
Comparing the time domain responses, we see that for the mixed signal there is some modulation which results in the wave not looking like a perfect sine because there are two different signals being played at the same time. For the recovered signal though, that modulation is gone and we just see the sine wave for the major C-scale. As for the frequency responses, in the mixed signal we see the noise peak at 1000 Hz and in the recovered signal response we only see one peak for whichever note is being played at the time from the scale. This is what we expect because we don’t want to see the noise at 1000 Hz after the mixed signal is filtered.
Figure 3: Recovered signal time domain after filter
Figure 4: Recovered signal frequency spectrum after filter
DSK code:
#include "DSK6713_AIC23.h" //codec support
Uint32 fs=DSK6713_AIC23_FREQ_8KHZ; //set sampling rate
#define DSK6713_AIC23_INPUT_MIC 0x0015
#define DSK6713_AIC23_INPUT_LINE 0x0011
Uint16 inputsource=DSK6713_AIC23_INPUT_MIC;
#define LOOPLENGTH 32000
#define BUFFERLENGTH 256
#define N 41
int loopindex = 0; //table index
int bufindex = 0; //buffer index
short sine_table[LOOPLENGTH]={0, 2.742670e+02, 4.985890e+02, 6.476421e+02, 7.311156e+02, 7.839748e+02, 8.424666e+02…};
int out_buffer[BUFFERLENGTH]; //output buffer
int recover_buffer[BUFFERLENGTH]; //recover buffer
short gain = 10;
float x[N]; //filter delay line
float h[N]={-6.252251e-19, -8.456016e-04, -1.728314e-03, -2.323078e-03, -1.967575e-03, 1.678189e-18, 3.611989e-03, 7.730582e-03, 1.006126e-02, 7.980217e-03, -4.220270e-18, -1.275278e-02, -2.587620e-02, -3.246388e-02, -2.533159e-02, 6.762350e-18, 4.276904e-02, 9.608413e-02, 1.483175e-01, 1.864909e-01, 2.004867e-01, 1.864909e-01, 1.483175e-01, 9.608413e-02, 4.276904e-02, 6.762350e-18, -2.533159e-02, -3.246388e-02, -2.587620e-02, -1.275278e-02, -4.220270e-18, 7.980217e-03, 1.006126e-02, 7.730582e-03, 3.611989e-03, 1.678189e-18, -1.967575e-03, -2.323078e-03, -1.728314e-03, -8.456016e-04, -6.252251e-19};
interrupt void c_int11()
{
short out_sample;
short i;
float yn = 0.0;
out_sample = sine_table[loopindex++];
for (i=0 ; i<N ; i++) //calculate filter output
yn += h[N-i]*(float)sine_table[loopindex+i]*gain;
output_left_sample((short)(out_sample)); //output to codec
out_buffer[bufindex++] = out_sample; //store in buffer
recover_buffer[bufindex++] = yn;
loopindex++;
if (loopindex >= LOOPLENGTH) loopindex = 0; //check for end of table
if (bufindex >= BUFFERLENGTH) bufindex = 0; //check for end of buffer
return; //return from interrupt
}
void main()
{
comm_intr(); //init DSK, codec, McBSP
while(1); //infinite loop
}
Mixed signal MATLAB code:
%sinCscalenoise.m Generates C scale and noise
%Creates file sinCscalenoise.h
t1 = 0:1/8000:.5-(1/8000);
t2 = 0: 1/8000:4-(1/8000);
c = 1000*sin(2*pi*261*t1);
d = 1000*sin(2*pi*294*t1);
e = 1000*sin(2*pi*330*t1);
f = 1000*sin(2*pi*350*t1);
g = 1000*sin(2*pi*392*t1);
a = 1000*sin(2*pi*440*t1);
b = 1000*sin(2*pi*494*t1);
c2 = 1000*sin(2*pi*524*t1);
n = 1000*sin(2*pi*1000*t2);
x = [c d e f g a b c2];
mix = x+n;
fid = fopen('sinCscalenoise.h','w'); %open/create file
fprintf(fid,'short sinCscalenoise[32000]={'); %print array name,"={"
fprintf(fid,'%d, ' ,mix(1:31999)); %print points
fprintf(fid,'%d' ,mix(32000));
fprintf(fid,'};\n'); %print closing bracket
fclose(fid); %close file
Filter coefficient MATLAB code:
Wn = .2; % fc = 800
N = 40; % order of the filter
b = fir1(N,Wn); % creates filter coefficients
hn = b(1:41)
N=length(b); % length of the signal x
t=(1/8000)*(1:N); % define a time vector
ssf=(ceil(-N/2):ceil(N/2)-1)/((1/8000)*N); % frequency vector
fx=fft(b(1:N)); % do DFT/FFT
fxs=fftshift(fx); % shift it for plotting
plot(ssf,abs(fxs)) % plot magnitude spectrum
xlabel('Frequency (Hz)') % label the axes
ylabel('Magnitude')
title('Frequency Response of the Filter') % title
grid;
fid = fopen('filter.cof','w'); % open/create file
fprintf(fid,'short filter[41]={'); % print array name,"={"
fprintf(fid,'%d, ' ,b(1:40)); % print points
fprintf(fid,'%d' ,b(41));
fprintf(fid,'};\n'); % print closing bracket
fclose(fid); % close file