谁能告诉我如何实现用c语言编程的FIR滤波器。
Answer 1:
设计的FIR滤波器不是一个简单的话题,但实施一个已经设计的滤波器(假设你已经拥有了FIR系数)是不是太糟糕。 该算法被称为卷积 。 这里有一个天真的实现...
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之外的东西,你得到一些放大/衰减以及过滤。
顺便说一句 - 这是可能的这种功能具有系数阵列向后 - 我没有双重检查,它是因为我想这些事情了一会儿。
对于如何计算FIR系数为特定的过滤器,还有背后的数学相当数量的 - 你真的需要数字信号处理一本好书。 这一个是免费提供的PDF,但我不知道它有多好。 我有Rorabaugh和Orfandis ,都发表在90年代中期,但这些事情没有真正得到过时。
Answer 2:
要合并多个过滤器:
开始与一个单位脉冲(具有在第一位置的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;
}
Answer 3:
我发现这个代码片段并没有为我(Visual Studio 2005中)工作。
我最终找到有一个伟大的回答卷积问题:
在ANSI C代码1D线性卷积?
对于那些谁也不知道 - 卷积是完全一样的操作,FIR滤波 - 在“内核”是FIR滤波器脉冲响应和信号的输入信号。
我希望这有助于一些谁在寻找FIR代码可怜虫:-)
Answer 4:
请参阅此链接两个FIR和IIR C代码和FIR和IIR滤波器的例子。
http://www.iowahills.com/A7ExampleCodePage.html
文章来源: FIR filter implementation in C programming