Real-time 与 FFTW 的脉冲响应卷积——结果听起来 IR 是对称的

Real-time impulse response convolution with FFTW -- result sounds like IR is symmetrical

出于研究目的,我正在使用 FFTW(以及用于声音传输的 PortAudio)和 overlap-add 卷积方法在 C++ 中构建一个 real-time 混响卷积引擎。它的大部分都在工作,但出现了一个非常奇特的效果。虽然我不明白为什么,但听起来脉冲响应变得非常对称:h[n] 变成了 h[n] + h[-n]。有谁知道按照我下面描述的方式执行 FFT 是否会产生这种效果?

基本上我的流程是这样的:

提前知道:

n > m 大约是 3 倍,但 FFT_SIZE 小得多(目前为 1024)

音频开始前在离线阶段完成的工作:

我将 x 分成 FFT_SIZE 长度的部分。因为我会将每个 window 与 h 进行卷积,所以我将每个 n+m - 1 样本复制到长度为 0 的填充缓冲区中,并执行前向 FFT,保存生成的复杂数组。 (我有 n/FFT_SIZE 个复杂的数组。)现在我正在使用没有重叠的矩形 windowing,一旦我解决了这个问题,如果它改进了,我将实施 Hamming。

我还在 0 填充到长度 n+m - 1 之后执行 h 的单个前向 FFT,并存储与其他大小相同的单个复数数组。

实时阶段

PortAudio 与大多数音频引擎一样,调用回调以定期用声音数据填充缓冲区 out。在我的回调中(根据设计要求 FFT_SIZE 音频样本,我每次 select 表示下一个 window 的复杂数组(因为一个回调调用对应于与一个相同的声音长度 window 用于 FFT)。

我将该数组与 FFT-ing h 生成的数组逐点相乘,然后执行 IFFT。生成的声音缓冲区 n+m-1 长,比 FFT_SIZE 大得多,所以我只将开头复制到 out 缓冲区并将其余部分添加到 overlap/carry 缓冲区(累积混响在将进位缓冲区的开头移动到 out 之后(因此 out 现在包含一个 window 的新 IFFT 数据添加到一个 window 之前计算的衰变尾巴的价值)。

关注现在

就像我之前提到的,这听起来好像脉冲响应没有被正确地进行 FFT,并且导致表现得好像它是对称的 - 反转然后添加到自身。我不确定我做错了什么,但我看不出这种影响是如何由我的携带问题产生的——尽管如果我是,我很高兴找到了这个错误!

我最好的猜测是我也应该以某种方式执行 h 的 windowing。但是,根据我读过的文献,您只需将 x 的每个 window 与整个 h 进行卷积并进行进位。也许这是错误的?

感谢您的帮助!

当 point-wise 乘以 2 个 FFT 向量时,您的算术似乎是错误的。复向量乘法必须考虑实部和虚部之间的叉积。例如re = re1*re2 - im1*im2; im = re1*im2 + re2*im1 等