/*---------------------------------------------------------------------- File: fir.c Description: Perform 128-tap fir filtering on codec input. Input: Right channel of line-in Output: Right channel = original signal Left channel = filtered signal -----------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #define SAMPLING_RATE 44100 extern int inicodec (int sampling_rate); short R_in[128]; // Input samples R_in[0] most recent, R_in[127] oldest. short h[]= // Impulse response of FIR filter. { -2, 10, 14, 7, -7, -17, -13 , 3, 19, 21, 4, -21, -32, -16, 18 , 43, 34, -8, -51, -56, -11, 53, 81 , 41, -44, -104, -81, 19, 119, 129, 24 , -119, -178, -88, 95, 222, 171, -41, -248 , -266, -50, 244, 366, 181, -195, -457, -353 , 85, 522, 568, 109, -540, -831, -424, 474 , 1163, 953, -245, -1661, -2042, -463, 2940, 6859 , 9469, 9469, 6859, 2940, -463, -2042, -1661, -245 , 953, 1163, 474, -424, -831, -540, 109, 568 , 522, 85, -353, -457, -195, 181, 366, 244 , -50, -266, -248, -41, 171, 222, 95, -88 , -178, -119, 24, 129, 119, 19, -81, -104 , -44, 41, 81, 53, -11, -56, -51, -8 , 34, 43, 18, -16, -32, -21, 4, 21 , 19, 3, -13, -17, -7, 7, 14, 10 , -2 }; #pragma CODE_SECTION (fir_filter, ".iprog") // Put routine in internal memory. short fir_filter (short input) { int i; short output; int acc=0; int prod; R_in[0] = input; // Update most recent sample. acc = 0; // Zero accumulator. for (i=0; i<128; i++) // 128 taps { prod = (h[i]*R_in[i]); // perform Q.15 multiplication acc = acc + prod; // Update 32-bit accumulator, catering } // for temporary overflow. output = (short) (acc>>15); // Cast output to 16-bits. for (i=127; i>0; i--) // Shift delay samples. R_in[i]=R_in[i-1]; return output; } #pragma CODE_SECTION (isr_rint0, ".iprog") // Put routine in internal memory. interrupt void isr_rint0 (void) { int sample; short output; sample = MCBSP0_DRR; sample &= 0xffff; output = fir_filter ((short) sample); sample |= (((int)output)<<16); MCBSP0_DXR = sample; return; } void Init_Interrupts () { intr_reset(); // Reset the interrupt system, // disable all interrupts. INTR_CLR_FLAG (CPU_INT15); // Clear previous interrupt request INTR_ENABLE (CPU_INT15); // Enable cpu interrupt line 15 intr_map(CPU_INT15,ISN_RINT0); // Link receive interrupt of serial // port 0 to interrupt line 15. intr_hook (isr_rint0,CPU_INT15); // Assign the interrupt service routine } void main(void) { evm_init(); // Initialise EVM board. inicodec (SAMPLING_RATE); // Initialise codec, adjust sampling rate. Init_Interrupts (); // Initialise interrupts and hook isr. INTR_GLOBAL_ENABLE(); // Enable global interrupt. for (;;); // Main loop, does nothing. }