0
$\begingroup$

I have been trying to find a solution to my FFT convolution problem but everything that I have found while searching hasn't been helping me.

I have a working forward and backward FFT function, that I have tested with perfect results. A wav file that I ran through the forward FFT came out with a result of a frequency domain data, ran this domain data backwards again and back came a nice sounding waveform.

Here's the problem; I have now tried to put forward FFT to a pre-recorded piano sound (wav) a file with only one note and no dead silence. Then I've done the same to an IR-file (wav) of a room reverb, took the results from these two forward FFTs and tried to convolve them with the following code (the res_ir buffer has been scaled to have values between -1 to +1 before this):

long bufSize = 1024*62;
mFFT->runFFT(res, bufSize);
mFFT->runFFT(res_ir, bufSize);

double a=0;
double b=0;
double c=0;
double d=0;
for (int i=0;i<bufSize;i++)
{
     a=res[i].re();
     b=res[i].im();
     c=res_ir[i].re();
     d=res_ir[i].im();

    res[i].mRe = (a*c - b*d) * (gain);
    res[i].mIm = (a*d + b*c) * (gain);
}
mFFT->runIFFT(res, bufSize,true);

I'm not looping through the complete wave file but just the size of one really big FFT buffer (1024*62), this to make it easier for me to follow and to eliminate extra possible bugs or errors keeping the problem down in size.

the result I'm getting is just the IR wav sound shaped somewhat like the piano file, but it sounds like the "starter gun" from the IR file (no piano sound at all).

Here's an image if the results (starting from above, first is the IR wav with the starter gun, second is the piano wav and last is the result from this):

wave files for this question

Someone who can help me find what or where to dig for answer to this problem?

$\endgroup$
  • $\begingroup$ Can you post the magnitude of the FFT of each? I'm thinking that the starter gun FFT has a zero (or close to it) at the frequency of the piano. That might explain why you can't hear the piano. Also, there is the circular convolution issue, but that would probably not cause you to not hear the piano. $\endgroup$ – Peter K. Feb 15 '15 at 19:21
1
$\begingroup$

Your code performs the circular convolution. Circ Convolution gives an array equal to max( len(a) , len(b) ) Convolution will return an array of length = len(a) + len(b) - 1 // a, b > 0 If you think about it, adding a reverb makes a sound longer. That's the equation ^^ that describes by how much. What you're hearing is the end of the reverb played over the start. Keep in mind in a musical setting, often the original sound is mixed in with the reverb sound.

I zero padding your data before FFTing it.

long bufSize = 1024*62;
for(int i=bufSize; i<2*bufSize; ++i) res[i].mRe = res[i].mIm = res_ir[i].mRe = res_ir[i].mIm = 0;
mFFT->runFFT(res, bufSize);
mFFT->runFFT(res_ir, bufSize);

double a=0;
double b=0;
double c=0;
double d=0;
for (int i=0;i<bufSize*2;i++)
{
    a=res[i].re();
    b=res[i].im();
    c=res_ir[i].re();
    d=res_ir[i].im();

    res[i].mRe = (a*c - b*d) * (gain);
    res[i].mIm = 0;
}

That gets rid of the 'wrapping' effect of circular convolution at least. Also, the imaginary part is zero because the convolution of two real signals is real.

$\endgroup$
  • $\begingroup$ The original FFT will need to be twice as long, too. Just zero-padding in the FFT domain will not give the desired results. $\endgroup$ – Peter K. Feb 15 '15 at 19:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.