Реализация FIR-фильтра в C-программировании

Может кто-нибудь сказать мне, как реализовать FIR-фильтр с использованием языка программирования C.

 UmNyobe21 февр. 2013 г., 09:45
 com.prehensible16 нояб. 2014 г., 00:12
вы можете проверить musicdsp.org для фильтров, таких как списки бесплатных кодов, начиная с 2000 года. "
 com.prehensible25 мая 2015 г., 05:48
fircoef.h» может быть полезным поиск в Google

Ответы на вопрос(4)

Разработка КИХ-фильтраНЕ простая тема, но реализация уже разработанного фильтра (при условии, что у вас уже есть коэффициенты FIR) isn 'Тоже плохо. Алгоритм называетсясвертка, Вот'Наивная реализация ...

void convolve (double *p_coeffs, int p_coeffs_n,
               double *p_in, double *p_out, int n)
{
  int i, j, k;
  double tmp;

  for (k = 0; k < n; k++)  //  position in output
  {
    tmp = 0;

    for (i = 0; i < p_coeffs_n; i++)  //  position in coefficients array
    {
      j = k - i;  //  position in input

      if (j >= 0)  //  bounds check for input buffer
      {
        tmp += p_coeffs [k] * p_in [j];
      }
    }

    p_out [i] = tmp;
  }
}

По сути, свертка делает скользящее средневзвешенное значение входного сигнала. Весами являются коэффициенты фильтра, которые, как предполагается, суммируются до 1,0. Если веса суммируются с чем-то отличным от 1,0, вы получаете некоторое усиление / ослабление, а также фильтрацию.

Кстати - этоВозможно, эта функция имеет массив коэффициентов в обратном направлении - у меня нетпроверил дважды, и этоНекоторое время назад я думал об этих вещах.

Для расчета коэффициентов КИХ для конкретного фильтраЗа этим стоит немало математики - вам действительно нужна хорошая книга по цифровой обработке сигналов.Вот этот доступен бесплатно для PDF, но яЯ не уверен, насколько это хорошо. я имеюRorabaugh а такжеOrfandisоба опубликованы в середине девяностых, но эти вещи недействительно устареет.

 D X21 февр. 2013 г., 13:52
Это не работает, я попробовал. Я запутался.
 D X21 февр. 2013 г., 10:44
хорошо, позвольте мне попробовать. Но я также пытаюсь сделать это со структурами, поэтому я думаю, что это сделает код более громоздким.
 D X21 февр. 2013 г., 10:11
Да, у меня уже есть коэффициенты фильтра. Его легко сгенерировать, если у вас есть стоп-полоса и спецификация полосы пропускания. Еще один вопрос, есть ли у вас какие-либо идеи, как я могу применять FIR-фильтры в каскаде. Например, предположим, что у меня есть входные данные x (n) и мне нужен выходной сигнал y (n), поэтому моя общая передаточная функция будет блоком из 3 небольших блоков FIR-фильтра, т.е. (H (z) = Y (z) * X (z) * A (z)). Моя настоящая проблема заключается в том, как объединить все эти три фильтра вместе в каскад, чтобы получить вывод y (n). Дайте мне лишь приблизительную идею, псевдокод или, если у вас есть код, вставьте его.
 Steve31421 февр. 2013 г., 10:36
Если вы думаете об этом, комбинированный фильтр должен быть эквивалентен последовательности фильтров. Такой же "*" оператор используется для обоих, так чтодействительно простоассоциативность свертки, Просто убедитесь, что вы учитываете большее количество коэффициентов (суммируйте входные размеры).
 Steve31421 февр. 2013 г., 10:17
Вы можете в основном: (1) создать единый фильтр для всей передаточной функции или (2) повторно вызвать функцию свертки, один раз для каждого фильтра в каскаде. Насколько я могу вспомнить, (1) оказывается также сверткой (для каждой пары фильтров вместе), но я 'Я должен был вернуться к моим учебникам, чтобы быть уверенным.
 D X21 февр. 2013 г., 10:21
Можете ли вы проверить это, потому что я потратил много времени на обдумывание этого, но не смогне выходи с решением. Было бы здорово, если бы вы могли помочь мне с этим :)
 Steve31421 февр. 2013 г., 10:42
@D X - ОК, но я уже предоставил (по общему признанию наивную) функцию свертки. Все, что вам нужно сделать, это выделить и инициализировать буферывызов вещь.
 D X21 февр. 2013 г., 10:40
Я уже это понимаю. Я имею в виду, что это легко понять теоретически, но сложно программировать.

что этот фрагмент кода не работает для меня (Visual Studio 2005).

В конце концов я нашел, что вопросы о свертке имеют отличный ответ:

1d линейная свертка в коде ANSI C?

Для тех, кто неt знаю, что свертка - это та же операция, что и для КИХ-фильтрации:ядро» импульсный отклик КИХ-фильтра, а сигнал - входной сигнал.

Я надеюсь, что это поможет бедному соку, который искал код FIR :-)

 Dennis Meng15 июн. 2014 г., 07:05
Возможно, вы захотите извлечь соответствующие части этого другого вопроса здесь (в случае, если этот другой вопрос когда-либо будет удален). Это также дает вам возможность указать на биты, которые вы нашли полезными :)

Начните с импульса единицы (сигнал с 1 в первой позиции и 0 везде). Примените первый фильтр. Примените второй фильтр. Продолжайте, пока все фильтры не будут применены. Результат показывает, как объединенные фильтры сворачивают единичный импульс (при условии, что массив достаточно длинный, чтобы данные не были потеряны), поэтому значения в нем являются коэффициентами для одного фильтра, который является составом других фильтров.

Вот пример кода:

#include <stdio.h>
#include <string.h>


#define NumberOf(a) (sizeof (a) / sizeof *(a))


/*  Convolve Signal with Filter.

    Signal must contain OutputLength + FilterLength - 1 elements.  Conversely,
    if there are N elements in Signal, OutputLength may be at most
    N+1-FilterLength.
*/
static void convolve(
    float *Signal,
    float *Filter, size_t FilterLength,
    float *Output, size_t OutputLength)
{
    for (size_t i = 0; i < OutputLength; ++i)
    {
        double sum = 0;
        for (size_t j = 0; j < FilterLength; ++j)
            sum += Signal[i+j] * Filter[FilterLength - 1 - j];
        Output[i] = sum;
    }
}


int main(void)
{
    //  Define a length for buffers that is long enough for this demonstration.
    #define LongEnough  128


    //  Define some sample filters.
    float Filter0[] = { 1, 2, -1 };
    float Filter1[] = { 1, 5, 7, 5, 1 };

    size_t Filter0Length = NumberOf(Filter0);
    size_t Filter1Length = NumberOf(Filter1);


    //  Define a unit impulse positioned so it captures all of the filters.
    size_t UnitImpulsePosition = Filter0Length - 1 + Filter1Length - 1;
    float UnitImpulse[LongEnough];
    memset(UnitImpulse, 0, sizeof UnitImpulse);
    UnitImpulse[UnitImpulsePosition] = 1;


    //  Calculate a filter that is Filter0 and Filter1 combined.
    float CombinedFilter[LongEnough];

    //  Set N to number of inputs that must be used.
    size_t N = UnitImpulsePosition + 1 + Filter0Length - 1 + Filter1Length - 1;

    //  Subtract to find number of outputs of first convolution, then convolve.
    N -= Filter0Length - 1;
    convolve(UnitImpulse,    Filter0, Filter0Length, CombinedFilter, N);

    //  Subtract to find number of outputs of second convolution, then convolve.
    N -= Filter1Length - 1;
    convolve(CombinedFilter, Filter1, Filter1Length, CombinedFilter, N);

    //  Remember size of resulting filter.
    size_t CombinedFilterLength = N;

    //  Display filter.
    for (size_t i = 0; i < CombinedFilterLength; ++i)
        printf("CombinedFilter[%zu] = %g.\n", i, CombinedFilter[i]);


    //  Define two identical signals.
    float Buffer0[LongEnough];
    float Buffer1[LongEnough];
    for (size_t i = 0; i < LongEnough; ++i)
    {
        Buffer0[i] = i;
        Buffer1[i] = i;
    }


    //  Convolve Buffer0 by using the two filters separately.

    //  Start with buffer length.
    N = LongEnough;

    //  Subtract to find number of outputs of first convolution, then convolve.
    N -= Filter0Length - 1;
    convolve(Buffer0, Filter0, Filter0Length, Buffer0, N);

    //  Subtract to find number of outputs of second convolution, then convolve.
    N -= Filter1Length - 1;
    convolve(Buffer0, Filter1, Filter1Length, Buffer0, N);

    //  Remember the length of the result.
    size_t ResultLength = N;


    //  Convolve Buffer1 with the combined filter.
    convolve(Buffer1, CombinedFilter, CombinedFilterLength, Buffer1, ResultLength);


    //  Show the contents of Buffer0 and Buffer1, and their differences.
    for (size_t i = 0; i < ResultLength; ++i)
    {
        printf("Buffer0[%zu] = %g.  Buffer1[%zu] = %g.  Difference = %g.\n",
            i, Buffer0[i], i, Buffer1[i], Buffer0[i] - Buffer1[i]);
    }

    return 0;
}
</string.h></stdio.h>
 g00dy10 авг. 2013 г., 01:01
С тех пор'не статья вStackOverflowПожалуйста, вставьте соответствующие части (если ссылка или сайт не работает), кроме того, это 'только ссылка "Ответ" и это нене считать здесь.

Ваш ответ на вопрос