使用FFTW进行实时脉冲响应卷积 - 结果听起来像IR是对称的

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

本文关键字:听起来 结果 IR 对称 卷积 FFTW 实时 响应 脉冲 使用      更新时间:2023-10-16

出于研究目的,我正在使用FFTW(和用于声音传递的PortAudio)和用于卷积的重叠添加方法构建C++的实时混响卷积引擎。其中大部分都在工作,但发生了非常奇特的效果。虽然我不明白为什么,但听起来好像脉冲反应变得对称:原来h[n]的东西变成了h[n] + h[-n]。有谁知道以我下面描述的方式执行 FFT 是否会产生这种效果?

基本上,我的流程如下:

事先知道:

  • h,脉冲响应m样本长
  • x,声音n采样长
  • FFT_SIZE,分区大小/窗口大小
n > m 3倍

左右,但FFT_SIZE要小得多(目前为1024)

音频开始之前在脱机阶段完成的工作:

我把x分成FFT_SIZE长度的部分。因为我将使用h卷积每个窗口,所以我将每个窗口复制到长度n+m - 1样本的 0 填充缓冲区中,并执行前向 FFT,从而保存生成的复杂数组。(我有n/FFT_SIZE复杂的数组。目前,我正在使用没有重叠的矩形窗口,如果在解决此问题后可以改善事情,将实施汉明。

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

在实时阶段

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

执行这个数组与我通过 FFT-ing h 制作的数组逐点乘法,并执行 IFFT。生成的声音缓冲区n+m-1长,比FFT_SIZE大得多,因此我只将开头复制到out缓冲区中,并将其余部分添加到重叠/进位缓冲区(每次回调调用都会累积混响尾音)在将进位缓冲区的开头移动到out后(因此out现在包含一个窗口的新 IFFT'd 数据添加到一个窗口的先前计算的衰减尾巴中)。

现在的担忧

就像我之前提到的,听起来脉冲响应在某种程度上没有被正确FFT,并导致它表现得好像它是对称的 - 颠倒然后添加到自身。我不确定我做错了什么,但我看不出我的携带问题是如何产生这种效果的——尽管如果我是,我很高兴发现了这个错误!

我最好的猜测是,不知何故我也应该对h执行窗口化。然而,根据我读过的文献,你只是将每个x窗口与整个h卷入并做携带。这也许是错误的吗?

感谢您的帮助!

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