Tool/software: Code Composer Studio
I write an IIR HPF in C language as bellow:
void iir_2nd_filter(int *d_x, int *d_y, int *x, int *y, int factor1, int factor2, int ch_offset, int step, int nbytes) { int i; y[ch_offset] = (x[ch_offset] - d_x[1]) - (d_x[1] - d_x[0]) + d_y[1] +((d_y[1]>>10)*factor1 - (d_y[0]>>10)*factor2); y[step + ch_offset] = (x[step + ch_offset] - x[ch_offset]) - (x[ch_offset] - d_x[1]) + y[ch_offset] +((y[ch_offset]>>10)*factor1 - (d_y[1]>>10)*factor2); nbytes = nbytes/4; for(i=step*2+ch_offset; i<nbytes; i+=step) { y[i] = (x[i] - x[i-step]) - (x[i-step] - x[i-(step<<1)]) + y[i-step] + ((y[i-step]>>10)*factor1 - (y[i-(step<<1)]>>10)*factor2); } d_x[0] = x[i-(step<<1)]; d_x[1] = x[i-step]; d_y[0] = y[i-(step<<1)]; d_y[1] = y[i-step]; }
And then write the same function in Linear Assembly:
;extern void iir_2nd_Assembly(int *d_x, int *d_y, int *x, int *y, ; int factor1, int factor2, int ch_offset, int step, int nbytes); .global iir_2nd_Assembly ;二阶IIR高通滤波器 iir_2nd_Assembly: .cproc d_x, d_y, x, y, factor1, factor2, ch_offset, step, nbytes ;线性汇编程序开始 ; 变量声明 .reg xn,xn1,xn2,yn,yn1 .reg sum,tmp1,tmp2 SHL ch_offset, 2, ch_offset ;ch_offset = ch_offset*4 SHL step, 2, step ;step = step*4 LDW *d_x++, xn ;xn = x[n] LDW *d_x, xn1 ;xn1 = x[n+1] LDW *d_y++, yn ;yn = y[n] LDW *d_y, yn1 ;yn1 = y[n+1] ADD x, ch_offset, x ; LDW *x, xn2 ;xn2 = x[n+2] SUB xn2, xn1, tmp1 ;tmp1 = xn2 - xn1 SUB xn1, xn, tmp2 ;tmp2 = xn1 - xn SUB tmp1, tmp2, sum ;sum = tmp1 - tmp2 = (xn2-xn1) - (xn1-xn) ADD sum, yn1, sum ;sum = (xn2-xn1) - (xn1-xn) + yn1 SHR yn1, 10, tmp1 ;tmp1 = yn1>>10 MPY32 tmp1, factor1, tmp1 ;tmp1 = factor1*tmp1 = (yn1>>10)*factor1 SHR yn, 10, tmp2 ;tmp2 = yn>>10 MPY32 tmp2, factor2, tmp2 ;tmp2 = factor2*tmp2 = (yn>>10)*factor2 MV yn1, yn ;yn = yn1 SUB tmp1, tmp2, tmp1 ;tmp1 = tmp1 - tmp2 = (yn1>>10)*factor1 - (yn>>10)*factor2 ADD sum, tmp1, yn1 ;yn1 = sum + tmp1 = (xn2-xn1) - (xn1-xn) + yn1 ; + ((yn1>>10)*factor1 - (yn>>10)*factor2) ADD y, ch_offset, y STW yn1, *y ;y[n+2] = yn1 MV xn1, xn ;xn = x[n+1] MV xn2, xn1 ;xn1 = x[n+2] SHR nbytes, 2, nbytes ;nbytes = nbytes/4 [nbytes] SUB nbytes, 1, nbytes ;nbytes -= 1 LOOP3: .trip 1 ;for循环起始位置 ADD x, step, x LDW *x, xn2 ;xn2 = x[n+2] SUB xn2, xn1, tmp1 ;tmp1 = xn2 - xn1 SUB xn1, xn, tmp2 ;tmp2 = xn1 - xn SUB tmp1, tmp2, sum ;sum = tmp1 - tmp2 = (xn2-xn1) - (xn1-xn) ADD sum, yn1, sum ;sum = (xn2-xn1) - (xn1-xn) + yn1 SHR yn1, 10, tmp1 ;tmp1 = yn1>>10 MPY32 tmp1, factor1, tmp1 ;tmp1 = factor1*tmp1 = (yn1>>10)*factor1 SHR yn, 10, tmp2 ;tmp2 = yn>>10 MPY32 tmp2, factor2, tmp2 ;tmp2 = factor2*tmp2 = (yn>>10)*factor2 MV yn1, yn ;yn = yn1 SUB tmp1, tmp2, tmp1 ;tmp1 = tmp1 - tmp2 = (yn1>>10)*factor1 - (yn>>10)*factor2 ADD sum, tmp1, yn1 ;yn1 = sum + tmp1 = (xn2-xn1) - (xn1-xn) + yn1 ; + ((yn1>>10)*factor1 - (yn>>10)*factor2) ADD y, step, y STW yn1, *y ;y[n+2] = yn1 MV xn1, xn ;xn = x[n+1] MV xn2, xn1 ;xn1 = x[n+2] [nbytes] SUB nbytes, 1, nbytes ; nbytes -= 1 [nbytes] B LOOP3 ; if (nbytes!=0) goto loop ;for循环结束位置 STW xn1, *d_x-- STW xn, *d_x STW yn1, *d_y-- STW yn, *d_y .endproc ; 线性汇编程序结束
the two function are called in C file as bellow:
#define Tn 1024
int IIR_In[Tn+4]; int IIR_Out[Tn+4]; int delay_x[2] = {0,0}; int delay_y[2] = {0,0};
extern void iir_2nd_Assembly(int *d_x, int *d_y, int *x, int *y,
int factor1, int factor2, int ch_offset, int step, int nbytes);
int iir_lowcut_test(void) { unsigned int bytes_read = 0, bytes_writed = 0; int res = FR_OK; res = f_open(&rec_file_ch1,"FileIn.wav", FA_READ); res |= f_lseek(&rec_file_ch1, 44); //pionte to the first data if (FR_OK != res) { return res; } res |= rec_wav_file_create("FileOut.wav", &rec_file_ch2, 48000, 32, 1); if (FR_OK != res) { return res; } while(!f_eof(&rec_file_ch1)) { res = f_read(&rec_file_ch1, IIR_In, Tn*4, &bytes_read); #if 1 iir_2nd_filter(delay_x, delay_y, IIR_In, IIR_Out, 967, 969, 0, 1, Tn*4); #else iir_2nd_Assembly(delay_x, delay_y, IIR_In, IIR_Out, 967, 969, 0, 1, Tn*4); #endif res |= f_write(&rec_file_ch2, IIR_Out, Tn*4, &bytes_writed); if (FR_OK != res) { break; } } f_close(&rec_file_ch1); rec_wav_file_close(&rec_file_ch2); return res; }
Note: FileIn.wav is a audio file with ONE channel, 48kHz/32bit.
967 and 969, are the IIR HPF parameters for Fs = 48kHz, Fc = 300Hz.
In the function iir_lowcut_test(),Calling for iir_2nd_filter() and iir_2nd_Assembly() have the same result.
BUT, there is ERR occur when I call iir_2nd_Assembly() in a SWI thread, while call iir_2nd_filter() is all right.
IS there any restrictions on calling linear assembly functions in C?