Я разработал простой двухканальный фильтр для удаления шума на заданной частоте.
#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);
}
Итак, почему я получаю другой результат, когда я меняю цикл for
в Filter
с цикла обратного счета на цикл восходящего счета?
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)
, и фильтр является симметричным. Почему направление счета влияет на результат?
Shift_Accum_Loop
? Вы планируете использоватьgoto
? Тогда не надо. Если у вас есть это в качестве комментария к циклу, то, пожалуйста, напишите вместо этого правильный комментарий, в котором объясняется, что делает цикл и почему цикл делает это именно так. - person Some programmer dude   schedule 20.05.2020ShiftRegRight[i] = ShiftRegRight[i - 1];
, и о том, какими могут быть начальные значения массиваShiftRegRight
. - person Some programmer dude   schedule 20.05.2020goto
или чего-то в этом роде. - person Kampi   schedule 20.05.2020