Рассчитывается КИХ фильтр так. Отклик в частотной области
представляет ступеньку, во временной области представляет
sinc-функцию. И если надо то наоборот. Значит наша задача не более
чем сгенерировать sinc-функцию. Коэффициенты КИХ фильтра её и
представляют. И вся фильтрация, т.е. фильтр будет представлять
собой банальную свертку с ней, т.е. к коэффициентами). Налабал
демо-код в дикой спешке, у меня нет времени писать красиво, завтра
с утра ехать запускать проект и я самозабанюсь на сахаре.
#include <math.h>
#define PI 3.14159265
#define KernelLen 51 // Длина ядра фильтра
float KERNEL[KernelLen]; // коэфф. фильтра, оно ж ядро
#define SignalLen 2000 // Длина сигнала
float InputSignal[SignalLen]; // Сигнал
float Output[SignalLen]; // Выходной сигнал
float Fcutoff = 0.003; // F среза, задается в диапазоне от 0 до 0.5 от F сэмплирования исх. сигнала
// Расчет ядра фильтра aka sinc-фунции
void CalcFIR(void)
{
// Расчет коэфф. фильтра.
for (int i = 0 ; i < KernelLen ; i++)
{
if ((i-KernelLen/2) == 0)
{
KERNEL[i] = 2*PI*Fcutoff;
}
else if ((i-KernelLen/2) != 0)
{
KERNEL[i] = sinf(2*PI*Fcutoff * (i-KernelLen/2)) / (i-KernelLen/2);
}
KERNEL[i] = KERNEL[i] * (0.42f - 0.5f*cosf(2*PI*i/KernelLen) + 0.08f*cosf(4*PI*i/KernelLen));
}
// Банальная нормализация полученного
float sum = 0.0f;
for (int i = 0; i<KernelLen; i++)
{
sum = sum + KERNEL[i];
}
for (int i = 0; i<KernelLen; i++)
{
KERNEL[i] = KERNEL[i] / sum;
}
}
Примитивная и медленная КИХ фильтрация предсталяет собой свертку "в лоб" с расчитанной sinc-функцией.
for( int j = KernelLen ; j < SignalLen-1; j++)
{
Output[j] = 0.0;
for (int i = 0; i < KernelLen; i++)
{
Output[j] = Output[j] + InputSignal[j-i] * KERNEL[i];
}
}
Но учти, так как sinc-функция обрезана (короткая), она даст вследствие эффекта Гиббса некоторую рябь.
Поэтому реально ядро фильтра представляет собой обрезанную SINC функцию просто поэлементно умноженную на оконные функции, ф-лы:
HAMMING[i] = 0.54 - 0.46 *cosf(2*PI * i / LENGTH );
BLACKMAN[i] = 0.42 - 0.5 cosf(2 * PI * i / LENGTH ) + 0.08 * cosf(4 * PI * i / LENGTH );
Фазовый отклик линейный.
https://en.wikipedia.org/wiki/Sinc_filter
Да, и судя по тому что ты писал выше, попробуй несколько раз фильтровать по сигналу одним и тем же фильтром, втч и БИХ что приводил выше.