Thank you for your replies and suggestions. I got rid of any windowing and taken Sebastian's sugegstion. I have been advised by others to do just that and aparrently it works! I have adjusted my code to the sugegsted method (which actually is what it was before I got carried away with the Windowing theory). However I get clicks/pops at the end of each frame block processed. This results in buzzing. I have added the code of my processing with comments bellow in case anybody can spot a problem.
Regarding the spectrum multiplication. I am using Apple's vDSP library's function zvmulD(). In the documentation it is described as "Complex Vector Multiply." On of the function arguments is the "conjugate." The documentation says "Assign conjugate flag 'conjugate' a value of 1 for normal multiplication or -1 for multiplication by conjugated values of input 1." I have tried both, and both give different waveforms and both still have the clicks/pops. I am new to FFTs and DSP in general so is it normal multiplication I need for my scenario or multiplication by conjugated values of input 1? While both give clicks and pops, perhaps this may shed some light on the overall problem with the pops in the signal.
Thanks a lot!
// Store 512 incoming audio samples into array
for(UInt32 j = 0; j < 512; j++)
{
speakerTempBuffer[j] = audioData[j];
}
// Zero-pad the second half of the array
for(int a = 512; a < 1024; a++)
{
speakerTempBuffer[a] = 0.0;
}
// Convert to Split Double Complex
ctozD((DOUBLE_COMPLEX *) speakerTempBuffer, 2, &speakersSplitDoubleComplex, 1, nOver2);
// FFT
fft_zripD(fft1024Setup, &speakersSplitDoubleComplex, stride, log2n, kFFTDirection_Forward);
// Multiplication of the spectrum with the spectrum of an HRTF impulse response
zvmulD(&speakersSplitDoubleComplex, stride, &HRTF_0Degree0ElevationSplitDoubleComplex, stride, &speakersSplitDoubleComplex, stride, log2n, 1);
// Inverse FFT the result
fft_zripD(fft1024Setup, &speakersSplitDoubleComplex, stride, log2n, kFFTDirection_Inverse);
// Scale the result
vsmulD(speakersSplitDoubleComplex.realp, 1, &scale, speakersSplitDoubleComplex.realp, 1, nOver2);
vsmulD(speakersSplitDoubleComplex.imagp, 1, &scale, speakersSplitDoubleComplex.imagp, 1, nOver2);
// Convert to real array
ztocD(&speakersSplitDoubleComplex, 1, (DOUBLE_COMPLEX *) speakerTempBuffer, 2, nOver2);
// Add over lap
for(int a = 0; a < overlapSize; a++)
{
speakerTempBuffer[a] += overLap[a];
}
// Update over laps
for(int a = 512; a < 1023; a++)
{
overLap[a - 512] = speakerTempBuffer[a];
}
// Store result to ouput stream
for(UInt32 j = 0; j < 512; j++)
{
audioData[j] = (float) speakerTempBuffer[j];
}