C语言实现FIR

#include <stdio.h>

#ifdef WIN32

    #include <conio.h>

#endif 

#define SAMPLE  double      /* define the type used for data samples */

void clear(int ntaps, SAMPLE z[])      

{

    int ii;

    for (ii = 0; ii < ntaps; ii++) {

        z[ii] = 0;

    }

}

SAMPLE fir_basic(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[])       

{

    int ii;

    SAMPLE accum;

    

    /* store input at the beginning of the delay line */

    z[0] = input;

    /* calc FIR */

    accum = 0;

    for (ii = 0; ii < ntaps; ii++) {

        accum += h[ii] * z[ii];

    }

    /* shift delay line */

    for (ii = ntaps - 2; ii >= 0; ii--) {

        z[ii + 1] = z[ii];

    }

    return accum;

}

SAMPLE fir_circular(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[],

                    int *p_state)         

{

    int ii, state;

    SAMPLE accum;

    state = *p_state;               /* copy the filter's state to a local */

    /* store input at the beginning of the delay line */

    z[state] = input;

    if (++state >= ntaps) {         /* incr state and check for wrap */

        state = 0;

    }

    /* calc FIR and shift data */

    accum = 0;

    for (ii = ntaps - 1; ii >= 0; ii--) {

        accum += h[ii] * z[state];

        if (++state >= ntaps) {     /* incr state and check for wrap */

            state = 0;

        }

    }

    *p_state = state;               /* return new state to caller */

    return accum;

}

SAMPLE fir_shuffle(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[])         

{

    int ii;

    SAMPLE accum;

    

    /* store input at the beginning of the delay line */

    z[0] = input;

    /* calc FIR and shift data */

    accum = h[ntaps - 1] * z[ntaps - 1];

    for (ii = ntaps - 2; ii >= 0; ii--) {

        accum += h[ii] * z[ii];

        z[ii + 1] = z[ii];

    }

    return accum;

}

SAMPLE fir_split(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[],

                 int *p_state)

{

    int ii, end_ntaps, state = *p_state;

    SAMPLE accum;

    SAMPLE const *p_h;

    SAMPLE *p_z;

    /* setup the filter */

    accum = 0;

    p_h = h;

    /* calculate the end part */

    p_z = z + state;

    *p_z = input;

    end_ntaps = ntaps - state;

    for (ii = 0; ii < end_ntaps; ii++) {

        accum += *p_h++ * *p_z++;

    }

    /* calculate the beginning part */

    p_z = z;

    for (ii = 0; ii < state; ii++) {

        accum += *p_h++ * *p_z++;

    }

    /* decrement the state, wrapping if below zero */

    if (--state < 0) {

        state += ntaps;

    }

    *p_state = state;       /* return new state to caller */

    return accum;

}

SAMPLE fir_double_z(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[],

            int *p_state)

{

    SAMPLE accum;

    int ii, state = *p_state;

    SAMPLE const *p_h, *p_z;

    /* store input at the beginning of the delay line as well as ntaps more */

    z[state] = z[state + ntaps] = input;

    /* calculate the filter */

    p_h = h;

    p_z = z + state;

    accum = 0;

    for (ii = 0; ii < ntaps; ii++) {

        accum += *p_h++ * *p_z++;

    }

    /* decrement state, wrapping if below zero */

    if (--state < 0) {

        state += ntaps;

    }

    *p_state = state;       /* return new state to caller */

    return accum;

}

SAMPLE fir_double_h(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[],

                    int *p_state)

{

    SAMPLE accum;

    int ii, state = *p_state;

    SAMPLE const *p_h, *p_z;

    /* store input at the beginning of the delay line */

    z[state] = input;

    /* calculate the filter */

    p_h = h + ntaps - state;

    p_z = z;

    accum = 0;

    for (ii = 0; ii < ntaps; ii++) {

        accum += *p_h++ * *p_z++;

    }

    /* decrement state, wrapping if below zero */

    if (--state < 0) {

        state += ntaps;

    }

    *p_state = state;       /* return new state to caller */

    return accum;

}

int main(void)

{

    #define NTAPS 6

    static const SAMPLE h[NTAPS] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };

    static SAMPLE h2[2 * NTAPS];

    static SAMPLE z[2 * NTAPS];

    #define IMP_SIZE (3 * NTAPS)

    static SAMPLE imp[IMP_SIZE];

    SAMPLE output;

    int ii, state;

    /* make impulse input signal */

    clear(IMP_SIZE, imp);

    imp[5] = 1.0;

    /* create a SAMPLEd h */

    for (ii = 0; ii < NTAPS; ii++) {

        h2[ii] = h2[ii + NTAPS] = h[ii];

    }

    /* test FIR algorithms */

    printf("Testing fir_basic:/n   ");

    clear(NTAPS, z);

    for (ii = 0; ii < IMP_SIZE; ii++) {

        output = fir_basic(imp[ii], NTAPS, h, z);

        printf("%3.1lf ", (double) output);

    }   

    printf("/n/n");

    printf("Testing fir_shuffle:/n   ");

    clear(NTAPS, z);

    state = 0;

    for (ii = 0; ii < IMP_SIZE; ii++) {

        output = fir_shuffle(imp[ii], NTAPS, h, z);

        printf("%3.1lf ", (double) output);

    }   

    printf("/n/n");

    printf("Testing fir_circular:/n   ");

    clear(NTAPS, z);

    state = 0;

    for (ii = 0; ii < IMP_SIZE; ii++) {

        output = fir_circular(imp[ii], NTAPS, h, z, &state);

        printf("%3.1lf ", (double) output);

    }   

    printf("/n/n");

    printf("Testing fir_split:/n   ");

    clear(NTAPS, z);

    state = 0;

    for (ii = 0; ii < IMP_SIZE; ii++) {

        output = fir_split(imp[ii], NTAPS, h, z, &state);

        printf("%3.1lf ", (double) output);

    }   

    printf("/n/n");

    printf("Testing fir_double_z:/n   ");

    clear(2 * NTAPS, z);

    state = 0;

    for (ii = 0; ii < IMP_SIZE; ii++) {

        output = fir_double_z(imp[ii], NTAPS, h, z, &state);

        printf("%3.1lf ", (double) output);

    }   

    printf("/n/n");

    printf("Testing fir_double_h:/n   ");

    clear(NTAPS, z);

    state = 0;

    for (ii = 0; ii < IMP_SIZE; ii++) {

        output = fir_double_h(imp[ii], NTAPS, h2, z, &state);

        printf("%3.1lf ", (double) output);

    }   

    #ifdef WIN32

        printf("/n/nHit any key to continue.");

        getch();

    #endif

    return 0;

}

1. fir_basic: 实现基本的FIR滤波器

  2. fir_circular: 说明环行buffer是如何实现FIR的。

  3. fir_shuffle: 一些TI的处理器上使用的shuffle down技巧

  4. fir_split: FIR滤波器展开为两块,避免使用环行缓存。

  5. fir_double_z: 使用双精度的延迟线,使可以使用一个flat buffer

  6. fir_double_h: 使用双精度的系数,使可以使用一个flat buffer。 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 以下是一个简单的C语言实现FIR滤波器的示例代码: ```c #include <stdio.h> #define N 5 // FIR滤波器的阶数 float h[N] = {0.2, 0.3, 0.5, 0.3, 0.2}; // FIR滤波器的系数 int main() { float input[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 输入信号 float output[10] = {0}; // 输出信号 for (int n = 0; n < 10; n++) { for (int i = 0; i < N; i++) { if (n - i >= 0) { output[n] += h[i] * input[n - i]; } } } // 输出结果 for (int n = 0; n < 10; n++) { printf("output[%d] = %f\n", n, output[n]); } return 0; } ``` 该代码中定义了一个5阶的FIR滤波器,输入信号为长度为10的一维数组。通过嵌套循环计算每个输出样本的值,最终输出结果。在实际应用中,FIR滤波器的系数需要根据具体的应用场景进行设计和调整。 ### 回答2: FIR(Finite Impulse Response)滤波器是一类数字滤波器,其输出仅取决于有限数量的输入样本。下面是一个用C语言实现的简单FIR滤波器示例。 首先,我们需要定义FIR滤波器的参数。常见的参数包括滤波器的长度(N)、滤波器系数数组(h[])和输入输出缓冲区。 ```c #define N 10 // 滤波器长度 float h[N] = {0.1, 0.2, 0.1, 0.2, 0.1, 0.2, 0.1, 0.2, 0.1, 0.2}; // 滤波器系数 float buffer[N] = {0}; // 输入输出缓冲区 ``` 然后,我们可以编写一个函数来实现FIR滤波器的操作。 ```c float fir_filter(float input) { float output = 0; // 将新的输入值存入缓冲区 for (int i = N - 1; i >= 1; i--) { buffer[i] = buffer[i - 1]; } buffer[0] = input; // 计算输出值 for (int i = 0; i < N; i++) { output += h[i] * buffer[i]; } return output; } ``` 在主函数中,我们可以使用该函数来进行滤波操作。 ```c int main() { // 输入信号示例 float input_signal[] = {0.5, 1.0, 0.8, 0.3, 0.9}; // 滤波后的输出信号 float output_signal[5] = {0}; // 对输入信号进行滤波操作 for (int i = 0; i < 5; i++) { output_signal[i] = fir_filter(input_signal[i]); } // 输出滤波后的信号 for (int i = 0; i < 5; i++) { printf("Output signal[%d] = %f\n", i, output_signal[i]); } return 0; } ``` 以上就是一个简单的使用C语言实现FIR滤波器的示例。根据具体的需求,你可以根据示例进行修改和完善。 ### 回答3: FIR滤波器,又称为有限脉冲响应滤波器,是一种常见的数字滤波器。下面以C语言为例,简要介绍如何实现一个FIR滤波器的示例。 首先,需要定义FIR滤波器的系数数组,这些系数用于对输入信号进行滤波处理。可以通过手动设定系数,或者使用窗函数等方法生成。 假设我们定义一个长度为N的系数数组coeff[N],并且有一个输入信号数组inputSignal[N],我们的目标是对输入信号进行滤波处理,得到输出信号outputSignal[N]。 接下来,我们可以使用如下的代码来实现FIR滤波器的处理过程: ```c #define N 10 // FIR滤波器的系数长度 float coeff[N] = {0.1, 0.2, 0.3, 0.4, 0.3, 0.2, 0.1, -0.1, -0.2, -0.3}; // 举例设定的系数数组 void FIRFilter(float* inputSignal, float* outputSignal, int signalLength) { int i, j; // 初始化输出信号为0 for(i = 0; i < signalLength; i++) { outputSignal[i] = 0; } // 实现FIR滤波器的过程 for(i = N-1; i < signalLength; i++) { for(j = 0; j < N; j++) { outputSignal[i] += inputSignal[i-j] * coeff[j]; } } } ``` 上述代码中,定义了一个FIRFilter函数,接收输入信号数组inputSignal、输出信号数组outputSignal以及信号的长度signalLength作为参数。其中,内部通过两个循环实现了滑动窗口的累加操作,滤波的结果存放在输出信号数组outputSignal中。 在使用上述代码时,我们只需要将输入信号和输出信号的数组传入FIRFilter函数即可完成滤波过程,得到滤波后的输出信号。 当然,这只是一个简单的FIR滤波器示例,实际上FIR滤波器还有很多优化的方法,例如使用快速傅里叶变换(FFT)来加速计算,或者采用流水线处理等技术来提高运算效率。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值