为什么我的过滤器的循环方向会改变我的结果?

Why does the loop direction of my filter change my result?

我设计了一个简单的双通道滤波器来去除给定频率的一些噪声。

#include "../include/Filter.h"

void Filter(int DataIn, int* DataOut, bool Enable)
{
    static coef_t Coefficients[] = {
            0.0076925293, -0.039817952, 0.018740745, 0.013075141, -0.052312399,
            0.052374545, 0.017044802, -0.14227364, 0.26541378, 0.68194015, 0.26541378,
            -0.14227364, 0.017044802, 0.052374545, -0.052312399, 0.013075141, 0.018740745,
            -0.039817952, 0.0076925293
    };

    static data_t ShiftRegRight[LENGTH];
    static data_t ShiftRegLeft[LENGTH];

    acc_t AccRight = 0x00;
    acc_t AccLeft = 0x00;

    if(Enable == true)
    {
        Shift_Accum_Loop: for(int i = (LENGTH - 1); i >= 0; i--)
        {
            if(i == 0)
            {
                ShiftRegRight[0] = DataIn & 0x0000FFFF;
                ShiftRegLeft[0] = (DataIn & 0xFFFF0000) >> 0x10;
            }
            else
            {
                ShiftRegRight[i] = ShiftRegRight[i - 1];
                ShiftRegLeft[i] = ShiftRegLeft[i - 1];
            }

            AccRight += ShiftRegRight[i] * Coefficients[i];
            AccLeft += ShiftRegLeft[i] * Coefficients[i];
        }

        *DataOut = ((AccLeft.range() >> 0x20) << 0x10) | (AccRight.range() >> 0x20);
    }
    else
    {
        *DataOut = DataIn;
    }
}

此滤波器在给定测试信号上产生以下输出:

0, 0, 0
1, 28377, 218
2, 0, 64405
3, 0, 531
4, 0, 370
5, 37159, 63833
6, 0, 2616
7, 37159, 65269
8, 0, 62257
9, 0, 8484
10, 0, 17494
11, 28377, 8750
12, 0, 62919
13, 28377, 58754
14, 0, 50948
15, 0, 48035
16, 0, 52449
17, 37159, 56833
18, 0, 0
19, 37159, 8484
20, 0, 14216
21, 0, 16968
22, 0, 14216
...

测试信号是用测试台生成的:

#include <math.h>
#include <stdio.h>

#include "../include/Filter.h"

#define SAMPLES                 48000
#define FREQ_RIGHT_1            8000
#define FREQ_RIGHT_2            10000
#define FREQ_LEFT_1             50

FILE* File;

int main(void)
{
    int Output;
    int StreamData;
    uint16_t RightChannel = 0x00;
    uint16_t LeftChannel = 0x00;

    File = fopen("Result.log", "w");
    for(int i = 0x00; i < SAMPLES; i++)
    {
        // Generate the input data
        RightChannel = 32767 * sin(2 * M_PI * i / (SAMPLES / FREQ_RIGHT_1)) * sin(2 * M_PI * i / (SAMPLES / FREQ_RIGHT_2));
        StreamData = (LeftChannel << 0x10) | RightChannel;

        // Execute the function with latest input
        Filter(StreamData, &Output, true);

        // Write the simulation results
        fprintf(File, "%i, %d, %d\n", i, StreamData, Output);
    }

    fclose(File);
}

那么,当我将 Filter 中的 for 循环从递减计数循环更改为递增计数循环时,为什么会得到不同的输出?

if(Enable == true)
{
    Shift_Accum_Loop: for(int i = 0; i < (LENGTH - 1); i++)
    {
        if(i == 0)
        {
            ...

0, 0, 0
1, 28377, 27073
2, 0, 0
3, 0, 0
4, 0, 0
5, 37159, 38462
6, 0, 0
7, 37159, 38462
8, 0, 0
9, 0, 0
10, 0, 0
11, 28377, 27073

这有什么区别?在这两种情况下,循环确实从 0 计数到 (LENGTH - 1),并且过滤器是对称的。为什么计数方向对结果有影响?

if(i == 0)
        {
            ShiftRegRight[0] = DataIn & 0x0000FFFF;
            ShiftRegLeft[0] = (DataIn & 0xFFFF0000) >> 0x10;
        }
        else
        {
            ShiftRegRight[i] = ShiftRegRight[i - 1];
            ShiftRegLeft[i] = ShiftRegLeft[i - 1];
        }

当你倒数时 i==0 最后计算为真。

当你向上计数时 i==0 首先评估为真。