具有FFT卷积的低通FIR滤波器 - 重叠添加,原因和方式

时间:2012-04-04 17:05:16

标签: c++ filter fft convolution vst

首先,抱歉没有在此处发布代码。出于某种原因,当我试图输入我在此页面上的代码时,所有代码都搞乱了upp,无论如何发布它可能太多了,无法接受。这是我的代码:http://pastebin.com/bmMRehbd

现在从我所说的,我无法从这段代码中获得好结果的原因是因为我没有使用重叠添加。我试图在互联网上阅读几个来源,为什么我需要使用重叠添加,但我无法理解它。似乎实际过滤器工作,导致任何高于给定截止值的东西,确实是截止的。

我应该提到这是为vst2-sdk工作的代码。

有人可以告诉我为什么我需要添加它以及如何在给定代码中实现重叠添加代码?

我还应该提一下,当涉及到算法和数学时,我真的很蠢。我是那些需要在视觉上抓住我正在做的事情的人之一。那个或者用代码解释的东西:),然后我指的是实际的重叠。

Overlad add theory:http://en.wikipedia.org/wiki/Overlap%E2%80%93add_method

感谢您提供的所有帮助!

4 个答案:

答案 0 :(得分:4)

当你通过对两个输入信号的离散傅立叶变换的乘积进行离散傅立叶变换进行卷积(使用有限脉冲响应滤波器)时,你实际上是在实现循环卷积。我在此称之为“在频域中计算的卷积”。 (如果你不知道循环卷积是什么,look at this link。它基本上是一个卷积,你假设这个域是圆形的,即从两侧移动信号使它“环绕”到另一边。域名。)

您通常希望通过对大信号使用快速傅里叶变换来执行卷积,因为它在计算上更有效。

重叠add(和它的堂兄重叠保存)是解决频域中完成的卷积实际上是圆形卷积的事实的方法,但实际上我们很少想要进行循环卷积,但通常是线性卷积。

重叠添加通过输入信号的“零填充”块然后适当地使用圆形卷积的部分(在频域中完成)来实现。重叠保存仅通过保持与线性卷积相对应的信号部分并抛弃被循环移位“损坏”的部分来实现。

以下是维基百科对这两种方法的两个链接。

Overlap-add:这个人有一个很好的数字来解释正在发生的事情。

Overlap-save

This book by Orfanidis explains it well. See section 9.9.2.这不是信号处理的“事实上的”标准,但它写得非常好,在我看来比其他书籍更好。

答案 1 :(得分:3)

需要使用overlap-add方法来处理每个fft缓冲区的边界。问题是FFT域中的乘法导致时域中的循环卷积。这意味着在执行IFFT之后,帧结束时的结果会在帧的开头环绕并破坏输出样本。

以这种方式思考可能更容易:假设您有一个长度为N的过滤器。使用M输入样本对此过滤器进行线性卷积实际上会返回M+N-1个输出样本。但是,在FFT域中完成的循环卷积会产生相同数量的输入和输出样本M。来自线性卷积的额外N-1个样本已“缠绕”并损坏了第一个N-1输出样本。

这是一个例子(matlab或octave):

a = [1,2,3,4,5,6];
b = [1,2,1];
conv(a,b)  %linear convolution

    1    4    8   12   16   20   17    6

ifft(fft(a,6).*fft(b,6))  %circular convolution

    18   10    8   12   16   20

请注意,最后2个样本已经缠绕并添加到圆形情况下的前2个样本中。

重叠 - 添加/重叠 - 保存方法基本上是处理此环绕的方法。由于循环卷积返回的输入样本数量少于输入样本数量,因此需要重叠FFT缓冲区。

答案 2 :(得分:0)

首先,要了解时域中的卷积等效于频域中的乘法。在卷积中,您大约为O(n * m),其中n是FIR长度,m是要过滤的样本数。在频域中,使用FFT,运行O(n * log n)。对于足够大的n,在进行频域时,滤波的成本要低得多。然而,如果n相对较小,则益处降低到在时域中过滤更简单的程度。这个断点是主观的,然而,图50到100是你可以切换的点。

答案 3 :(得分:0)

是的,就改变频率响应而言,卷积滤波器将“起作用”。但是频域中的这种乘法也会在一端污染来自另一端的数据的时域数据,反之亦然。重叠添加/保存扩展了FFT大小并切断了“污染”端,然后使用该结束数据来固定后续FFT窗口的开头。