我的低通滤波器有啥问题?
Posted
技术标签:
【中文标题】我的低通滤波器有啥问题?【英文标题】:What is wrong with my low pass filter?我的低通滤波器有什么问题? 【发布时间】:2011-03-03 15:09:51 【问题描述】:我有一系列 int 样本,范围从 32766 到 -32767。在尝试创建包络检测器的过程中,我编写了一个低通滤波器,但它似乎并没有起到作用。请记住,我正在尝试一次性过滤整个数组(无缓冲区)。
这不是流式传输的,而是应用于录制的音频以供以后播放。它是用 C 语言编写的。一个示例截止参数是 0.5。
void lopass(int *input, float cutoff, int *output)
float sample = 0;
for (int i=1 ; i < (1430529-10); i++) // we will go through all except the last 10 samples
for (int j = i; j < (i+10); j++) // only do this for a WINDOW of a hundred samples
float _in = (float)input[j];
float _out = (float)output[j-1];
sample = (cutoff * _in) + (32766 - (32766*cutoff)) * _out;
output[i] = (int)sample;
我想我会在 10 个样本的窗口上运行我的过滤语句。它不仅超级慢,而且它并没有真正做太多,但似乎降低了整体幅度。 \
如果您对如何正确执行此操作有任何建议或建议(或代码!),那就太好了!
【问题讨论】:
【参考方案1】:低通滤波器基本上是将多个值平均在一起的某种变体。这意味着至少在正常情况下,您的内部循环将累积一个值。很难从你的代码中猜出确切的意图,但你最终会得到一些非常一般的东西:
sample = 0;
for (int j=i; j<i+10; j++)
sample += input[j];
output[i] = sample / 10;
就目前而言,这个只是进行平均,没有指定截止 - 这意味着它有一个固定的(并且相当慢的)截止曲线。截止值仅由窗口中的样本数控制。
要控制截止,您不会(至少通常)将所有输入值乘以相同的数量——这基本上只会修改比例因子。相反,您获取要应用的截止曲线的一组样本(在您的情况下为 10 个),通过逆 FFT 运行它们,并获得一组 10 个系数。然后在循环中应用这些系数:
sample = 0;
for (j=0; j<10; j++)
sample += input[i+j] * coefficients[j];
output[i] = sample;
您窗口中的样本数量通常不是设计过程的输入,而是输出。首先指定截止频率(作为采样频率的一部分)和截止宽度,然后根据这些值计算必要的窗口大小。
计算系数有很多不同的技术。然而,不管你如何计算它们,你通常会得到这个一般顺序的东西——在窗口中累积样本的总和,每个样本乘以其各自的系数。
几年前,EE 时代在滤波器设计方面有相当不错的article。
【讨论】:
【参考方案2】:不知道它是否相关,但在您的代码中,内部循环什么都不做
for (j=???; j<???; j++)
sample = ???;
和
一样// for (j=???; j<???; j++)
sample = ???; // for last j
//
【讨论】:
【参考方案3】:过滤器中的算术看起来是错误的,正如@pmg 已经指出的那样,您没有正确存储输出值。应该是:
void lopass(int *input, float cutoff, int *output)
float sample = 0.0f;
output[0] = 0.0f;
for (int i = 1 ; i < (1430529 - 10); i++)
for (int j = i; j < (i + 10); j++)
float _in = (float)input[j];
float _out = (float)output[j-1];
sample = (cutoff * _in) + (1.0f - cutoff) * _out;
output[i] = (int)sample;
仍有一些小问题需要解决,但这至少应该可以作为一个相当粗糙的单极递归 (IIR) 滤波器。
【讨论】:
谢谢,我喜欢这篇文章。我再次写了一个小的改动,我用浮点数替换了整数输入和输出作为函数变量,因为它们被用作循环中的浮点数。然后我尝试了从 0 到 1 的截止值,但没有听到任何过滤效果,如果我在测试中将截止值设置为 -5 和 90,我只是听到了一些高端的添加。尽管如此,它让我意识到我将能够为我的程序设置一个过滤器,我非常高兴。【参考方案4】:这是一个损坏的移动窗口过滤器,内部循环中有 10 个样本(实际上您只使用了 10 个样本中的最后一个样本),当您在 cmets 中说您希望矩形过滤器窗口中有 100 个样本时。
第一个错误会使您的过滤器转换频率高出 10 倍。
【讨论】:
以上是关于我的低通滤波器有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章
具有 FFT 卷积的低通 FIR 滤波器 - 重叠相加,为啥以及如何