📄 fastconvo.c
字号:
//FastConvo.c FIR filter implemented using overlap-add fast convolution
#include <math.h>
#include "coeffs.h" //time domain FIR coefficients
#define PI 3.14159265358979
#define PTS 256 //number of points for FFT
#define SQRT_PTS 16 //used in twiddle factor calc.
#define RADIX 2 //passed to TI FFT routines
#define DELTA (2*PI)/PTS
typedef struct Complex_tag {float real, imag;} COMPLEX ;
#pragma DATA_ALIGN(W, sizeof(COMPLEX))
#pragma DATA_ALIGN(samples, sizeof(COMPLEX))
#pragma DATA_ALIGN(h, sizeof(COMPLEX))
COMPLEX W[PTS/RADIX] ; //twiddle factor array
COMPLEX samples[PTS]; //processing buffer
COMPLEX h[PTS]; //FIR filter coefficients
short buffercount = 0; //buffer count for iobuffer samples
float iobuffer[PTS/2]; //primary input/output buffer
float overlap[PTS/2]; //intermediate result buffer
short i; //index variable
short flag = 0; //set to indicate iobuffer full
float a, b; //variables used in complex multiply
short NUMCOEFFS = sizeof(coeffs)/sizeof(float);
short iTwid[SQRT_PTS] ; //PTS/2 + 1 > sqrt(PTS)
interrupt void c_int11(void) //ISR
{
output_sample((int)(iobuffer[buffercount]));
iobuffer[buffercount++] = (float)(input_sample());
if (buffercount >= PTS/2) //for overlap-add method iobuffer
{ //is half size of FFT used
buffercount = 0;
flag = 1;
}
}
main()
{ //set up array of twiddle factors
digitrev_index(iTwid, PTS/RADIX, RADIX);
for(i = 0 ; i < PTS/RADIX ; i++)
{
W[i].real = cos(DELTA*i);
W[i].imag = sin(DELTA*i);
}
bitrev(W, iTwid, PTS/RADIX); //bit reverse order W
for (i = 0 ; i<PTS ; i++) //initialise PTS element
{ //of COMPLEX to hold real-valued
h[i].real = 0.0; //time domain FIR filter coefficients
h[i].imag = 0.0;
}
for (i = 0 ; i < NUMCOEFFS ; i++)
{ //read FIR filter coeffs
h[i].real = coeffs[i]; //NUMCOEFFS should be less than PTS/2
}
cfftr2_dit(h,W,PTS); //transform filter coeffs
comm_intr(); //initialise DSK, codec, McBSP
while(1) //frame processing infinite loop
{
while (flag == 0); //wait for iobuffer full
flag = 0;
for (i = 0 ; i<PTS/2 ; i++) //iobuffer into first half of
{ //samples buffer
samples[i].real = iobuffer[i];
iobuffer[i] = overlap[i]; //previously processed output
} //to iobuffer
for (i = 0 ; i<PTS/2 ; i++)
{ //second half of samples to overlap
overlap[i] = samples[i+PTS/2].real;
samples[i+PTS/2].real = 0.0;//zero-pad input from iobuffer
}
for (i=0 ; i<PTS ; i++)
samples[i].imag = 0.0; //init imag parts in samples buffer
cfftr2_dit(samples,W,PTS); //complex FFT function from TI
for (i=0 ; i<PTS ; i++) //frequency-domain representation
{ //complex multiply samples by h
a = samples[i].real;
b = samples[i].imag;
samples[i].real = h[i].real*a - h[i].imag*b;
samples[i].imag = h[i].real*b + h[i].imag*a;
}
icfftr2_dif(samples,W,PTS); //inverse FFT function from TI
for (i=0 ; i<PTS ; i++)
samples[i].real /= PTS;
for (i=0 ; i<PTS/2 ; i++) //add first half of samples
overlap[i] += samples[i].real; //to overlap
} //end of while(1)
} //end of main()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -