Buffer/Stream management for heavy FFTs
Buffer/Stream management for heavy FFTs
- Subject: Buffer/Stream management for heavy FFTs
- From: Giovanni Salerno <email@hidden>
- Date: Sat, 5 Mar 2005 11:02:18 +0100
Hi, AU developers!
I’m developing an AU plug-in effect that works in the frequency domain, computing short time Fourier trasforms.
At first stage, no “overlap and add” step was implemented: I’m just testing the behaviour of two FFT libraries (vecLib and FFTW).
My AU plug-in should compute FFTs large up to 2^15 points, but it starts to fail at 2^14: I ear periodical “cracks” (dropouts) in preview mode.
Because no dropouts were found if I let the plug-in process the audio (instead of previewing), I’m sure that the problem is a bad efficiency of my buffer/stream management or its incorrectness.
Here’s my stategy:
- accumulate samples in a buffer of size n
- do FFT forward
- do fitering. At the moment “do nothing”
- do FFT inverse
- copy buffer in a larger one (2 x n) where the output stream pointer of the AU pick processed samples up.
Anyone knows how to modify my strategy or let me know the right one to reach my computational specs?
Hey, guys! I know for sure that a DirectX plug-in did it on a PC, three years ago! I don’t want to believe that Mac+AU can’t do the same, today (G4@1,25GHz)!
Thanks, people!
Hope to hear from someone soon.
Giovanni
PS
Keyframes of my code:
<x-tad-bigger>MyUnit::MyUnit(AudioUnit component)
: AUEffectBase(component)
{
...
dimInBuffer = n; //size of accumulation buffer = FFT points
inBuffer = (</x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>*)malloc (dimInBuffer * </x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>));
inBufferCount = </x-tad-bigger><x-tad-bigger>0</x-tad-bigger><x-tad-bigger>;
tmpBuffer = (</x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>*)malloc (dimInBuffer * </x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>));
dimOutBuffer = </x-tad-bigger><x-tad-bigger>2</x-tad-bigger><x-tad-bigger>*n;
outBuffer = (</x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>*)malloc (dimOutBuffer * </x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>));
outBufferCount = </x-tad-bigger><x-tad-bigger>0</x-tad-bigger><x-tad-bigger>;
...
}
...</x-tad-bigger>
<x-tad-bigger>OSStatus MyUnit::ProcessBufferLists(AudioUnitRenderActionFlags &ioActionFlags,
</x-tad-bigger><x-tad-bigger>const</x-tad-bigger><x-tad-bigger> AudioBufferList &iBuffer,
AudioBufferList &oBuffer,
UInt32 inFramesToProcess)
{
...
UInt32 lenIn = iBuffer.mBuffers[</x-tad-bigger><x-tad-bigger>0</x-tad-bigger><x-tad-bigger>].mDataByteSize;
</x-tad-bigger><x-tad-bigger>if</x-tad-bigger><x-tad-bigger> ((dimInBuffer - inBufferCount)*</x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>) > lenIn) {
memcpy(&inBuffer[inBufferCount], iBuffer.mBuffers[</x-tad-bigger><x-tad-bigger>0</x-tad-bigger><x-tad-bigger>].mData, lenIn);
inBufferCount+=(lenIn/</x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>));
}
</x-tad-bigger><x-tad-bigger>else</x-tad-bigger><x-tad-bigger> {
UInt32 residue = lenIn/</x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>)-(dimInBuffer-inBufferCount);
memcpy(tmpBuffer, iBuffer.mBuffers[</x-tad-bigger><x-tad-bigger>0</x-tad-bigger><x-tad-bigger>].mData, lenIn);
memcpy(&inBuffer[inBufferCount], tmpBuffer, (dimInBuffer-inBufferCount)*</x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>));
memcpy(fftBuffer, inBuffer, dimInBuffer*</x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>));
memcpy(inBuffer, &tmpBuffer[dimInBuffer-inBufferCount], </x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>)*residue);
trasf.fft( fftBuffer, outFreq ); //FFT(FWD)
</x-tad-bigger><x-tad-bigger>if</x-tad-bigger><x-tad-bigger> (outBufferCount>=dimFftBuffer)
trasf.ifft( outFreq, outBuffer );//FFT(BWD)
</x-tad-bigger><x-tad-bigger> else</x-tad-bigger><x-tad-bigger>
trasf.ifft( outFreq, &outBuffer[dimOutBuffer/</x-tad-bigger><x-tad-bigger>2</x-tad-bigger><x-tad-bigger>] );//FFT(BWD)
inBufferCount = residue;
}
</x-tad-bigger><x-tad-bigger>...</x-tad-bigger><x-tad-bigger>
</x-tad-bigger><x-tad-bigger>if</x-tad-bigger><x-tad-bigger> ((dimOutBuffer - outBufferCount)*</x-tad-bigger><x-tad-bigger>0</x-tad-bigger><x-tad-bigger>].mDataByteSize)
outBufferCount = </x-tad-bigger><x-tad-bigger>0</x-tad-bigger><x-tad-bigger>;
oBuffer.mBuffers[</x-tad-bigger><x-tad-bigger>0</x-tad-bigger><x-tad-bigger>].mData = &outBuffer[outBufferCount];
...
outBufferCount+=oBuffer.mBuffers[</x-tad-bigger><x-tad-bigger>float</x-tad-bigger><x-tad-bigger>);
</x-tad-bigger><x-tad-bigger>return</x-tad-bigger><x-tad-bigger> noErr;
}</x-tad-bigger> _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden