【问题标题】:FIR Low Pass Filter in CC语言中的FIR低通滤波器
【发布时间】:2014-12-15 15:18:58
【问题描述】:

我正在用 C 语言实现 FIR 低通滤波器。在 MATLAB 中生成了一些系数,我用它来计算输出。 音频来自 Zynq Zedboard,并且是实时的。 如果我运行应用程序,我会收到很多噪音。但我不知道信号是如何失真的.. 我需要一个音频缓冲区来保存处理过的样本吗?还是我只有蹩脚的代码?我几乎分析了代码中的所有元素,但无法理解它......

这里是函数调用

#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();

}

【问题讨论】:

    标签: c filter


    【解决方案1】:

    FIR 滤波器的公式为:

    y[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]);
    }
    

    【讨论】:

      猜你喜欢
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      • 2015-03-05
      • 2018-04-22
      • 1970-01-01
      • 2015-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多