使用FFTW的实时脉冲响应卷积 - 像IR一样的结果声音是对称的

时间:2016-01-13 06:51:26

标签: c++ audio signal-processing convolution fftw

出于研究目的,我正在使用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个复杂的数组。)现在我使用没有重叠的矩形窗口,如果我在解决这个问题后改进了东西就会实现Hamming。

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

在实时阶段

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

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

现在关注

就像我之前提到的那样,听起来好像脉冲响应不是正确的FFT,并且导致行为就好像是对称的 - 反转然后添加到自身。我不确定我做错了什么,但是我无法看到我的携带问题是如何产生这种效果的 - 虽然我是,但我很高兴发现了这个错误!

我最好的猜测是,我应该以{{1​​}}的方式进行窗口化。但是,根据我读过的文献,您只需将h的每个窗口与整个x进行卷积并执行进位。这可能是错的吗?

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

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