问题
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 responsem
samples longx
, a soundn
samples longFFT_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 h
as 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