2014-12-15 2 views
1

저는 C에서 FIR 로우 패스 필터를 구현하고 있습니다. 출력을 계산하는 데 사용되는 MATLAB에서 생성 된 일부 계수를 얻었습니다. 오디오는 Zynq Zedboard에서 나오며 실시간으로 출력됩니다. 응용 프로그램을 실행하면 많은 잡음이 발생합니다. 하지만 신호가 어떻게 왜곡되는지 모르겠습니다. 처리 된 샘플을 유지하기 위해 오디오 버퍼가 필요합니까? 아니면 그냥 진절머리 나는 코드가 있습니까? 나는 내 코드의 거의 모든 요소를 ​​분석하지만, 여기에 FIR 로우 패스 필터 in 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

전나무 필터의 공식입니다 ... 주위에 내 머리를 얻을 수 없습니다

Y

하나의 출력을 계산하려면, 마지막 44 입력 샘플이 필요하고, 다음과 같이 곱셈과 곱셈이 필요합니다. [n] = b0 * x [n] + b1 * x [n-1] 그것을 필터 계수로 누적하십시오. 입력 샘플을 저장하기 위해 크기가 44 인 링 버퍼를 사용하는 것이 좋습니다. 링 버퍼를 할당하고 0으로 초기화하십시오.

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]); 
} 
관련 문제