2014-12-15 3 views
1

Я внедряю фильтр низких частот FIR в C. Получил некоторые коэффициенты, сгенерированные в MATLAB, которые я использую для вычисления вывода. Аудиосигнал происходит от Zynq Zedboard и находится в режиме реального времени. Если я запускаю приложение, я получаю много шума. Но я не знаю, как искажается сигнал. Нужен ли звуковой буфер для хранения обработанных образцов? Или у меня просто дерьмовый код? Я проанализировал практически все элементы в моем коде, но не могу получить мою голову вокруг него ...FIR Фильтр нижних частот в C

Вот вызов функции

#define FILTER_LEN_LP 44 
int32_t coeffsLPF[ FILTER_LEN_LP ] = 
{ 
    87, 76, 106, 143, 185, 234, 289, 349, 
    414, 483, 555, 628, 701, 773, 842, 907, 
    966, 1017, 1060, 1093, 1115, 1126, 1126, 
    1115, 1093, 1060, 1017, 966, 907, 842, 773, 
    701, 628, 555, 483, 414, 349, 289, 234, 185, 
    143, 106, 76, 87 
}; 

void low_pass_filter(){ 

    int k = 0; 
    int filter_length = FILTER_LEN_LP; 
    int32_t *coeffp; // pointer to coefficients 
    int32_t in_left; 

    while (!XUartPs_IsReceiveData(UART_BASEADDR)) { 
     int32_t out_left; 
     int32_t acc; // accumulator 

     in_left = Xil_In32(I2S_DATA_RX_L_REG); 

     //printf("%d\r\n", in_left); 

     coeffp = coeffsLPF; 

     acc = 1 << 14 ; 
     for (k = 0; k < filter_length; k++) 
     { 
      acc += (int32_t)(*coeffp++) * (int32_t)(in_left); 
     } 

     //printf("%d\r\n", acc); 

     //printf("\r\n"); 

     // saturate the result 
     // 32768^2 
     if (acc > 1073741823) 
     { 
      acc = 1073741823; 
     } else if (acc < -1073741824){ 
      acc = -1073741824; 
     } 

     out_left = (int32_t) (acc >> 13); 

     //xil_printf("%d\n\r", out_left); 

     //in_right = Xil_In32(I2S_DATA_RX_R_REG); 
     Xil_Out32(I2S_DATA_TX_L_REG, out_left); 

     //Xil_Out32(I2S_DATA_TX_R_REG, in_right); 

    } 

// break 
if(XUartPs_ReadReg(UART_BASEADDR, XUARTPS_FIFO_OFFSET) == 'q') menu(); 

else low_pass_filter(); 

} 

ответ

0

Формула для FIR фильтра:

у [n] = b0 * x [n] + b1 * x [n-1] + b2 * x [n-2] ...

Чтобы вычислить один выход, вам нужны последние 44 входных пробора и умножьте и накапливают его с коэффициентами фильтра. Моей рекомендацией было бы использовать кольцевой буфер размером 44 для хранения входных выборок. Выделите кольцевой буфер и инициализируйте его нулем.

ring_buffer[FILTER_LEN_LP] = {0}; 
rb_index = 0; 

, а затем используйте следующий примерный код для хранения ваших входных выборок и расчета выходных данных.

ring_buffer[rb_idx] = Xil_In32(I2S_DATA_RX_L_REG); 
rb_idx = (rb_idx + 1) % filter_length; 
for (k=0; k<filter_length; k++) { 
    acc += (int32_t)(*coeffp++) * (int32_t)(ring_buffer[(k+rb_idx)%filter_length]); 
} 
Смежные вопросы