vDSP distortion/buzzing
vDSP distortion/buzzing
- Subject: vDSP distortion/buzzing
- From: Aristotel Digenis <email@hidden>
- Date: Sat, 17 Jul 2004 01:52:16 +0100
Greetings!
Earlier in the week I was having trouble using Apple's vBigDSP class for
FFTs. Thank you to John and Stephen for suggesting how to fix it and
suggesting to use vDSP instead of vBigDSP. Since then I have been
reading its documentation and going through the example code for
implementing the FFT. Unfortunately, I have run into difficulties. I
have spent since Tuesday trying to figure this out, and gone over it
with a friend to see perhaps a fresh view might spot the problem. But no
luck and as time for my project deadline is approaching, I am left with
no choice but to ask for help here. :-)
Bellow is a cut down of the processing I am trying to do. The code
compiles, and runs. It appears to be applying the processing but there
is also a buzz/distortion that is present in the signal. It is based on
the example code which is part of the Accelerate framework. In fact it
is practically a copy, which is what makes the problem even more
frustrating.
I have an array of doubles[512] which make up the impulse response of an
HRTF. In the constructor I convert that array to a Double Complex type,
then use ctozD() to convert it to an odd-even Split Double Complex type.
That then is use with fft_zripD() to convert the HRTF to the frequency
domain.
In ProcessBufferLists() incoming data is stored into an array[size 512].
Once 512 samples have been stored on the temporary buffer, they are
converted to the frequency domain in the same manner the HRTF samples
were. The 512 frequency domain samples of the incoming audio signal are
multiplied with the 512 frequency domain samples. The results are
converted back to the time domain, back to normal array from Double
Complex Split. Lastly the results are assigned to the output stream.
In ProcessBufferLists() I have used an int bufferCount (set to value "0"
in the constructor) to keep track of how many samples of the incoming
audio signal has been added to the temporary array.Once 512 samples have
been reached and processed bufferCount is set back to "0'. If the length
of frames that ProcessBufferLists() is called for is complete without
512 samples having been processed, then the next time
ProcessBufferLists() is called, bufferCount is used to continue adding
to the temporary buffers where they last left off.
I tried to comment out portions of the processing to locate the error.
If i get rid of the FFT and inverse FFT processes, and the
multiplication of the frequency spectrum, i still get the
buzz/distortion. It appears that the distortion is a result of
converting real arrays into Double Complex Splits. I cannot possibly see
what the problem is. I have repeatedly double checked it with the
example code of the Accelerate framework and have come to no conclusion.
I would greatly appreciate anybody who is familiar with vDSP to have a
look at the cut-down and simplified version of my processing. Perhaps
its possible to spot he error more easily when you not having looked at
it for days continuously.
Thank you in advance! 8-)
Aristotel
PS: For those interested, the plug in is a 3rd order Ambisonic decoder
to binaural and it will be available online freely ASAP.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// BBinaural::BBinaural
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BBinaural::BBinaural(AudioUnit component) : AUEffectBase(component)
{
log2n = 9;
n = 1 << log2n;
nOver2 = n / 2;
stride = 1;
fft512Setup = create_fftsetupD(log2n, kFFTRadix2);
scale = (float) 1.0 / (2 * n);
bufferCount = 0;
//// HRTF_0Degree0ElevationSplitDoubleComplex declared in header
HRTF_0Degree0ElevationSplitDoubleComplex.realp = (double*)
malloc(nOver2 * sizeof(double));
HRTF_0Degree0ElevationSplitDoubleComplex.imagp = (double*)
malloc(nOver2 * sizeof(double));
//// Convert real data array to Double Complex Split
ctozD((DOUBLE_COMPLEX *) front0elevation0, 2,
&HRTF_0Degree0ElevationSplitDoubleComplex, 1, nOver2);
//// Convert the HRTF inpulse response to frequency domain
fft_zripD(fft512Setup, &HRTF_0Degree0ElevationSplitDoubleComplex,
stride, log2n, kFFTDirection_Forward);
//// DOUBLE_COMPLEX_SPLIT speakersSplitDoubleComplex declared in
header
speakersSplitDoubleComplex.realp = (double*) malloc(nOver2 *
sizeof(double));
speakersSplitDoubleComplex.imagp = (double*) malloc(nOver2 *
sizeof(double));
//// double array declared in header, now initialized
for(int a = 0; a < 512; a++)
{
speakerTempBuffer[a] = 0.0f;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// BBinaural::ProcessBufferLists
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSStatus BBinaural::ProcessBufferLists(AudioUnitRenderActionFlags&
iFlags, const AudioBufferList& inBufferList, AudioBufferList&
outBufferList, UInt32 iFrames)
{
float* audioData = (float*) inBufferList.mBuffers[0].mData;
for(UInt32 j = 0; j < iFrames; j++)
{
audioData[j] = audioData[j];
if(bufferCount < 512)
{
speakerTempBuffer[bufferCount] = audioData[j];
bufferCount++;
}
if(bufferCount == 512)
{
//// Split the 512 samples into odd-even complex double array
ctozD((DOUBLE_COMPLEX *) speakerTempBuffer, 2,
&speakersSplitDoubleComplex, 1, nOver2);
//// Convert the 512 samples to frequency domain
fft_zripD(fft512Setup, &speakersSplitDoubleComplex, stride,
log2n, kFFTDirection_Forward);
//// Multiply the frequency spectrum of the input with
the spectrum of the HRTF
zvmulD(&speakersSplitDoubleComplex, stride,
&HRTF_0Degree0ElevationSplitDoubleComplex, stride,
&speakersSplitDoubleComplex, stride, log2n, 1);
//// Convert the 512 samples to time domain
fft_zripD(fft512Setup, &speakersSplitDoubleComplex, stride,
log2n, kFFTDirection_Inverse);
//// Split the 512 samples into properly ordered array
ztocD(&speakersSplitDoubleComplex, 1, (DOUBLE_COMPLEX *)
speakerTempBuffer, 2, nOver2);
//// Place 512 samples into audioData
for(int a = 0; a < (int) log2n; a++)
{
audioData[a] = speakerTempBuffer[a];
}
//// Reset this counter so that the next 512 samples can
be stored at the beginning of the speakerTempBuffer array
bufferCount = 0;
}
}
outBufferList.mBuffers[0].mData = audioData;
return noErr;
}
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.