具有 FFT 卷积的低通 FIR 滤波器 - 重叠相加,为啥以及如何

Posted

技术标签:

【中文标题】具有 FFT 卷积的低通 FIR 滤波器 - 重叠相加,为啥以及如何【英文标题】:Lowpass FIR Filter with FFT Convolution - Overlap add, why and how具有 FFT 卷积的低通 FIR 滤波器 - 重叠相加,为什么以及如何 【发布时间】:2012-04-04 17:05:16 【问题描述】:

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

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

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

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

我还应该提到,我在算法和数学方面非常愚蠢。我是那些需要从视觉上掌握我正在做的事情的人之一。那或得到代码解释的东西:),然后我的意思是实际的重叠。

叠加理论:http://en.wikipedia.org/wiki/Overlap%E2%80%93add_method

感谢您提供的所有帮助!

【问题讨论】:

“重叠加法”是指融合乘法累加吗? en.wikipedia.org/wiki/Overlap%E2%80%93add_method 我的意思是我猜 :) 【参考方案1】:

需要使用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】:

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

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

重叠添加(及其表亲重叠保存)是解决在频域中完成的卷积实际上是循环卷积这一事实的方法,但实际上我们很少想做循环卷积,而是通常更喜欢线性卷积。

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

这里有两个来自 Wikipedia 的链接,用于这两种方法。

Overlap-add : 这个图很好地解释了发生了什么。

Overlap-save

【讨论】:

是的,问题是我无法理解他们在***文章中告诉我的算法,我无法使其适合我的代码。我至少尝试了那么多:) 我所见过的最好的参考书是我在罗格斯大学时奥法尼迪斯的一本书。 Here's a link to the .pdf 第 9.9.2 节解释得非常好。 对不起,如果有人付钱给我或成绩取决于它,我只会为此编写代码。这并不简单,需要考虑案例和数组大小等。不过那本书应该有助于理解。 虽然 pdf 非常棒,但它几乎告诉了我在***链接上已经尝试理解的内容。我会尝试在这篇论文中继续阅读它,看看我是否可以从不同的角度看到它,但在那之前,至少感谢你提供了一个超级棒的新学习资源! 有一件事让我很困惑。如果我处理让我们说 1024 个数据样本,然后将其放入数组中。该数组和过滤器数组的大小不应该是 1024 吗?或者过滤器数组应该是大小的两倍(2048)?【参考方案3】:

首先要明白,时域中的卷积等价于频域中的乘法。在卷积中,您大致处于 O(n*m) 的位置,其中 n 是 FIR 长度,m 是要过滤的样本数。在频域中,使用 FFT,您正在运行 O(n * log n)。对于足够大的 n,在频域中进行滤波的成本要低得多。但是,如果 n 相对较小,则收益会降低到在时域中更易于过滤的程度。这个断点是主观的,但是,图 50 到 100 是您可以切换的点。

【讨论】:

我可能太愚蠢了,但算法并不适合我。如果你能以某种方式将你所说的转换成代码,那么我也许能够理解它:) 这是对通过频域进行卷积的解释,而不是对为什么需要重叠相加的解释。【参考方案4】:

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

【讨论】:

以上是关于具有 FFT 卷积的低通 FIR 滤波器 - 重叠相加,为啥以及如何的主要内容,如果未能解决你的问题,请参考以下文章

使用 fft 的 Matlab 低通滤波器

iOS Accelerate低通FFT滤波器镜像结果

使用 FIR 滤波器过滤光谱

滤波器实现

FIR IIR数字滤波器特点简介

用MATLAB设计对信号进行频谱分析和滤波处理的程序