Real Time Audio Signal Processing TMS320C54X Assembly Code and Report
Real Time Audio Signal Processing TMS320C54X Assembly Code and Report
This report covers all the aspects of the project. It explains how things were executed and accomplished. The layout of the report is as follows:
1. 2. 3. 4. 5. 6.
MATLAB Filter Design and Analysis Filter Coefficients MATLAB Code C5416 DSK Program Results Using Simulated audio signal Conclusion and Comments
-50
-100
500
1000
3000
3500
4000
0 Phase (degrees)
-2000
-4000
-6000
500
1000
3000
3500
4000
49
48.5
48
47.5
100
200
300 samples
400
500
600
2 Imaginary Part 97
-2
-4
-20
-40
-60
500
1000
3000
3500
4000
500
1000
3000
3500
4000
100
200
300 samples
400
500
600
Pole-Zero Plot of IIR Filter 1 0.8 0.6 0.4 Imaginary Part 0.2 0 -0.2 -0.4 -0.6 -0.8 -1 -1 -0.5 0 Real Part 0.5 1
Filter Coefficients
The filter coefficients of our desired filters designed in MATLAB were converted to Q.15 using MATLAB. The function to convert them into Q15 Hex numbers, which were written down in the fir_coeff.dat file. These coefficients are listed below. FIR Coefficients 98 coefficients of FIR filter in Q.15 form
.word -13 .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word -75 -36 116 -50 -94 131 5 331 -57 -333 328 124 -476 234 .word .word .word .word -154 116 85 -200
.word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word
-356 -889 1207 148 -1795 1407 1508 -4109 1515 17251 17251 1515 -4109 1508 1407 -1795 148 1207 -889 -356 942
.word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word
-338 -548 650 21 -564 367 234 -476 124 328 -333 -57 331 -178 -167 271 -40 -210 181 60 -200
.word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word .word
85 116 -154 5 131 -94 -50 116 -36 -75 82 8 -76 44 43 -203 -13
IIR Filter Coefficient The IIR coefficients were converted to Q15 hex numbers and then converted to decimal format that was given to the main file. The decimal numbers were represented in signed 16-bit numbers. The coefficients are shown below in all the formats.
; IIR Filter coefficients (sequential locations) b0 .word 9598 ;257Eh ;b0 = 0.2929 b1 .word -11282 ;D3EEh ;b1 = -0.3343 b2 .word 9598 ;257Eh ;b2 = 0.2929 a1 .word -11282 ;D3EEh ;a1 = -0.3343 a2 .word -13572 ;CAFCh ;a2 = -0.4412
MATLAB Code
This is the code that I used to design the 2400Hz cutoff frequency low pass FIR Filter and 1200Hz Notch IIR filter. The magnitude and phase response, group delay and Pole-zero plot were seen for both the designed filters. An audio file named male.wav is passed to the system and two single frequency tones are superimposed on it. These frequencies are 3500Hz in order to test the Low Pass filter and 1200Hz in order to test the IIR filter. The frequency domain analysis was done for the system.
% **************************************************** % Design & Analysis of Filters % ****************************************************
% ******************* % FIR Filter % ******************* Fs = 8000; f = [0.3*Fs 0.32*Fs]; a = [1 0]; dev = [0.01 0.01]; % % % % Sampling frequency Cutoff frequencies Desired amplitudes deviations in the pass & stop bands
%Parks-McClellan optimal FIR filter order estimation [n,fo,ao] = firpmord(f,a,dev,Fs) b = firpm(n,fo,ao); % Filter Coeeficients % Ploting the Low Pass FIR Filter figure; freqz(b,1,512,Fs); title('Lowpass Filter with Cutoff Frequency 2400Hz'); % Group Delay
figure; plot(grpdelay(b,a)); title('Group Delay of FIR Filter');xlabel('samples'); % Pole-Zero Plot figure;zplane(b,1);title('Pole-Zero Plot of FIR Filter');
% ******************* % IIR Filter % ******************* wo=0.15*Fs/(0.5*Fs); % Notch Frequency bw=wo/.4; [bi,ai] = iirnotch(wo,bw); % Ploting the Low Pass FIR Filter figure; freqz(bi,ai,512,Fs); title('Notch Filter with Notch Frequency 1200Hz'); % Group Delay figure;plot(grpdelay(bi,ai)); title('Group Delay of IIR Filter');xlabel('samples'); % Pole-Zero Plot figure;zplane(bi,ai);title('Pole-Zero Plot of IIR Filter');
% ******************************************************* % Creating Input Signals % ******************************************************* w = [1:(3*Fs)]; [input,fs]=wavread('male.wav'); % sound file passed n=[1:length(input)]; % Add sinosoids with frequency f1=1200Hz and f2=2800Hz input=input'+0.04*sin(2*pi*.35*n)+0.05*sin(2*pi*n*.1507); % input=awgn(input,25); fft_input = abs((fft(input))); % Plot Input figure; plot((w(1:1.5*Fs)*(Fs/2))/(1.5*Fs),fft_input(1:1.5*Fs)); axis([1 4000 1 100]); title('Input Signal'); xlabel('Frequency (Hz)'); ylabel('Magnitude') % Play Input input = input(1:(3*Fs)); sound(input,Fs);
% *********************************************************** % Filtering of the input % *********************************************************** input = input(1:(3*Fs)); % just pick 3 seconds of the signal
% ******************* % LPF Output % ******************* % Generate Output fir_output = filter(b,1,input); fft_fir_output = abs((fft(fir_output))); % Plot Output figure; plot((w(1:1.5*Fs)*(Fs/2))/(1.5*Fs),fft_fir_output(1:1.5*Fs)); axis([1 4000 1 100]); title('Output of FIR Filter (Low-Pass)'); xlabel('Frequency (Hz)'); ylabel('Magnitude') % Play Output pause(3) sound(fir_output,Fs);
% **************************** % Notch Filter Output % **************************** % Generate Output iir_output = filter(bi,ai,fir_output); fft_iir_output = abs((fft(iir_output))); % Plot Output figure; plot((w(1:1.5*Fs)*(Fs/2))/(1.5*Fs),fft_iir_output(1:1.5*Fs)); axis([1 4000 1 100]); title('Output of IIR Filter (Notch)'); xlabel('Frequency (Hz)'); ylabel('Magnitude') % Play Output pause(3) sound(iir_output,Fs);
C5416.m File This code was used to record the sound coming out of the C5416 DSK board. The frequency response of the unprocessed input signal, the FIR output signal and the final output after the IIR filter were plotted using this code.
% ******************************************** % C5416 Sound Output Analysis % ******************************************** Fs=8000; input_board = wavrecord(3*Fs,Fs); fir_output_board = wavrecord(3*Fs,Fs);
iir_output_board = wavrecord(3*Fs,Fs);
% ******************************************************** % Frequency Response Using a Simulated Signal % ******************************************************** % Generate FFt of input_board fft_input_board = abs((fft(input_board))); % Plot input_board figure; plot((w(1:1.5*Fs)*(Fs/2))/(1.5*Fs),fft_input_board(1:1.5*Fs),'r'); axis([1 4000 1 100]); title('input board Signal'); xlabel('Frequency (Hz)'); ylabel('Magnitude') % Play Input sound(input_board,Fs)
% ******************* % LPF Output % ******************* % Generate FFT of Output fft_fir_output_board = abs((fft(fir_output_board))); % Plot Output figure; plot((w(1:1.5*Fs)*(Fs/2))/(1.5*Fs),fft_fir_output_board(1:1.5*Fs),'r'); axis([1 4000 1 100]); title('Output of FIR Filter (Low-Pass)'); xlabel('Frequency (Hz)'); ylabel('Magnitude') % Play Output pause(3) sound(fir_output_board,Fs);
% **************************** % Notch Filter Output % **************************** % Generate FFT of Output fft_iir_output_board = abs((fft(iir_output_board))); % Plot Output figure; plot((w(1:1.5*Fs)*(Fs/2))/(1.5*Fs),fft_iir_output_board(1:1.5*Fs),'r'); axis([1 4000 1 100]); title('Output of IIR Filter (Notch)'); xlabel('Frequency (Hz)'); ylabel('Magnitude')
.set
The samples received and transmitted are 16-bits each. This is achieved by changing the values of the transmit and receive control registers (RCR1, RCR2, XCR1, XCR2) in the file initMcBSP.asm:
; Receive Control Register 1 (0000 0000 0100 0000) ; ; ; ; VAL_RCR1 Bit15 = 0: Reserved Bit14-8 = 0000000: 1 word per frame Bit7-5 = 010: 16 bit receive word Bit4-0 = 00000: Reserved 0040h
.set
; Receive Control Register 2 (0000 0000 0100 0001) ; ; ; ; ; ; VAL_RCR2 Bit15 = 0: Single phase frame Bit14-8 = 00h: 1 word per frame Bit7-5 = 010: 16 bit receive word Bit4-3 = 00: No companding Bit2 = 0: Receive frame sync pulses not ignored Bit1-0 = 01: 1-bit data delay 0041h
.set
; Bit14-8 = 00h: 1 word per frame ; Bit7-5 = 010: 16 bit transmit word ; Bit4-0 = 0h: Reserved VAL_XCR1 .set 0040h
; Transmit Control Register 2 (0000 0000 0100 0000) ; ; ; ; ; ; VAL_XCR2 Bit15 = 0: Single phase frame Bit14-8 = 00h: 1 word per frame Bit7-5 = 010: 16 bit transmit word Bit4-3 = 00: No companding Bit2 = 0: Transmit frame sync pulses not ignored Bit1-0 = 00: 0-bit data delay 0040h
.set
The main file of the project is as shown below. It waits for the receive interrupt and when a sample is received it calls an FIR filter whose coefficients are already loaded in a circular buffer. After the FIR filter the sample is in Register A. It then calls the IIR filter and the sample is processed upon.
************************************************************************ * * This program reads an input signal from the ADC , Passes it through a Lowpass FIR *filter and then that output through a IIR Notch Filter. It then writes the sample to * the DAC on the DSK5416 board. * ************************************************************************ .include .ref .ref .ref .def .def .def .def VAL_SP OutSamples .set .bss .bss .bss .sect .include .set "regs.asm" initC5416 initMcBSP2 initPCM3002 _c_int00 brint2_isr sample_receive sample_transmit 0x0500 y,1,1 CoefBuf, 99, 1 SampleBuf, 99, 1 "FIRcoeff" "coff_fir.dat" 98 ; initial stack address ; Allocate space for y(n)s ; Memory for coeff circular buffer ; Memory for sample circular buffer ; Filter coeff (seq locations) ; Number of filter taps N - 1
FIRcoeff Nm1
; Intermediate variables (sequential locations) wn .word 0 wnm1 .word 0 wnm2 .word 0 ; IIR Filter coefficients (sequential locations) b0 .word 9598
b1 b2 a1 a2
= = = =
* The entry-point for the program _c_int00: stm ssbx call call call stm orm stm orm stm orm STM ST CALL ssbx rsbx wait_main: idle b nop nop nop #VAL_SP, SP INTM initC5416 initMcBSP2 initPCM3002 #SPCR1, MCBSP2_SPSA #0001h, MCBSP2_SPSD #SPCR2, MCBSP2_SPSA #0001h, MCBSP2_SPSD #0FFFFh, IFR #040h, IMR #OutSamples, AR6 #0, *AR6 fir_init SXM INTM 1 wait_main ; Define the stack ; Disable all interrupts ; Init the DSP processor ; Init the McBSP2 port ; Init the DSK CODEC ; Enable McBSP2 receiver ; Enable McBSP2 transmitter ; Clear pending interrupts ; Unmask McBSP2 RX int ; Clear output sample buffer ; AR6 points to OutSample buffer ; Init for filter calculations ; Select sign extension mode ; Enable all interrupts ; Wait for an RX interrupt
* Interrupt service routine for McBSP2 Receiver brint2_isr: call call (integer) call STH call rete STH sample_receive fir_filter A,1,*AR6 iir_filter A,1,*AR6 sample_transmit ; Receive the sample ; Call FIR filter routine, ; Store filtered sample ; Call IIR filter routine ; Store filtered sample (integer) ; Transmit the sample
* This procedure receives a 16-bit value from the ADC * Return with A (LSBs) = 16 bit received sample sample_receive: ld ldm ret * This procedure sends a 16-bit value in A (LSBs) to the DAC. sample_transmit: stlm ret * * * * * * * ---------------------------------------------------------------------------------FIR Filter Initialization Routine This routine sets AR2 as the pointer for the sample circular buffer, and AR3 as the pointer for coefficient circular buffer. BK = Number of filter taps - 1. AR0 = 1 = circular buffer pointer increment ---------------------------------------------------------------------------------ST ST STM RPT MVPD RPT ST STM ret nop nop nop * * * * * * * -------------------------------------------------------------------------------FIR Filter Routine Enter with A = the current sample x(n) - an integer, AR2 pointing to the location for the current sample x(n), and AR3 pointing to the q15 coefficient h(N-1). Exit with A = y(n) as q15 number. -------------------------------------------------------------------------------#CoefBuf,AR3 #SampleBuf,AR2 #Nm1,BK #Nm1 #FIRcoeff, *AR3+% #Nm1 - 1 #0h,*AR2+% #1,AR0 ; AR3 is the CB Coeff Pointer ; AR2 is the CB sample pointer ; BK = number of filter taps ; Place coeff in circular buffer ; Clear circular sample buffer ; AR0 = 1 = CB pointer increment A, MCBSP2_DXR1 ; Transmit 16 bits #0, A MCBSP2_DRR1, A ; Retrieve 16 bits
fir_init:
fir_filter: STL RPTZ MAC ret nop nop nop A, *AR2+0% A, #Nm1 - 1 *AR3+0%,*AR2+0%,A ; Place x(n)in the sample buffer ; A = 0 ; A = filtered sum (q15)
;--------------------------------------------------------------------------------; IIR Filter Subroutine ; Enter with A = x(n) as q15 number ; Exit with A = y(n) as q15 number
;w(n)=x(n)+ a1.w(n-1)+ a2.w(n-2) STM #a2,AR2 STM #wnm2, AR3 MAC *AR2-,*AR3-,A MAC *AR2-,*AR3-,A STH A,1,*AR3 ; ; ; ; ; ; ; AR2 points to a2 AR3 points to w(n-2) A = x(n)+ a2.w(n-2) AR2 points to a1 & AR3 to w(n-1) A = x(n)+ a1.w(n-1)+ a2.w(n-2) AR2 points to b2 & AR3 to w(n) Save w(n)
;y(n)=b0.w(n)+ b1.w(n-1)+ b2.w(n-2) LD #0,A STM #wnm2,AR3 MAC *AR2-,*AR3-,A DELAY *AR3 MAC *AR2-,*AR3-,A DELAY *AR3 MAC *AR2,*AR3,A popm popm RET .end AR3 AR2 ; Return ; A = 0 ; AR3 points to w(n-2) ; A = b2.w(n-2) ; AR2 points to b1 & AR3 to w(n-1) ; w(n-1) -> w(n-2) ; A = b1.w(n-1)+ b2.w(n-2) ; AR2 points to b0 & AR3 to w(n) ; w(n) -> w(n-1) ; A = b0.w(n)+ b1.w(n-1)+ b2.w(n-2)
Input Signal 1000 900 800 700 600 Magnitude 500 400 300 200 100 0
500
1000
3000
3500
4000
500
400 Magnitude
300
200
100
500
1000
3000
3500
4000
500
1000
3000
3500
4000
50
40 Magnitude
30
20
10
500
1000
3000
3500
4000
50
40 Magnitude
30
20
10
500
1000
3000
3500
4000
500
1000
3000
3500
4000