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

回眸只為那壹抹淺笑 提交于 2020-01-06 20:01:58

问题


For research purposes I am building a real-time reverb convolution engine in C++ using FFTW (and PortAudio for the sound delivery) with the overlap-add method for convolution. Most of it is working, but a very peculiar effect occurs. Though I can't see why, it sounds very much as if the impulse response becomes symmetrical: what was h[n] becomes h[n] + h[-n]. Does anyone know if performing FFT in the way I describe below would have this effect?

Basically, my process is as follows:

Known in advance:

  • h, an impulse response m samples long
  • x, a sound n samples long
  • FFT_SIZE, a partition size/window size

n > m by a factor of 3 ish but FFT_SIZE is much smaller (1024 at the moment)

Work done in an offline phase before audio starts:

I split x into portions of FFT_SIZE length. Because I will convolve each window with h, I copy each one into a 0-padded buffer of length n+m - 1 samples, and perform a forward FFT, saving the resulting complex array. (I have n/FFT_SIZE complex arrays.) For now I am using rectangular windowing with no overlap, will implement Hamming if it improves things once I resolve this issue.

I furthermore perform a single forward FFT of h after 0-padding to length n+m - 1, and store this single complex array of same size as the others.

During the real time phase

PortAudio like most audio engines invokes callbacks to fill a buffer out with sound data at regular intervals. In my callback (which by design requests FFT_SIZE samples of audio, I select the complex array representing the next window each time (since one callback invocation corresponds to same sound length as one window for FFT).

I perform pointwise multiplication of this array with the one I made by FFT-ing h, and perform IFFT. Resulting sound buffer is n+m-1 long, much bigger than FFT_SIZE, so I copy only the beginning into the out buffer and add the rest to a overlap/carry buffer (which accumulates reverb tail sound with each callback invocation) after moving the beginning of the carry buffer to out (so out now contains one window's worth of new IFFT'd data added to one window's worth of previously calculated decay tail).

The concern now

Like I mentioned before, it sounds like somehow the impulse response is not being FFT'd correctly, and is resulting in behaving as if it was symmetrical -- reversed and then added to itself. I'm not sure what I'm doing wrong, but I can't see how this effect can be produced by a problem with my carrying -- though if I am, i'd be glad to have found the bug!

My best guess is that somehow I'm supposed to perform windowing of has well. However, based on the literature I've read, you just convolve each window of x with the whole h and do the carry. Is this wrong perhaps?

Thanks for your help!


回答1:


Your arithmetic when point-wise multiplying the 2 FFT vectors appears to be wrong. Complex vector multiplication has to take into account the cross product between the real and imaginary components. e.g. re = re1*re2 - im1*im2; im = re1*im2 + re2*im1 , etc.



来源:https://stackoverflow.com/questions/34760137/real-time-impulse-response-convolution-with-fftw-result-sounds-like-ir-is-sym

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!