FFTW execute in real-time callback

Hello,
I don’t know if this is the place where this question belongs but I hope that there is someone here using FFTW for real-time audio analysis in Juce.

Did anyone use it and know if fftw_execute(plan) is guaranteed not to allocate memory when called? I’m porting code written for rt analysis in Puredata with many dft and dct computations and some of the fft go on without problems while, when executing a dct plan it seems like the library is trying to allocate memory.

During plugin initialization:

std::vector fftwInputVector(SIZE_A);
std::vector bfccVector(SIZE_B);
fftwf_complex *fftwOut = (fftwf_complex *)fftwf_alloc_complex(SIZE_A * 0.5 + 1);
...
float* fftwIn = &(fftwInputVector[0]);
this->fftwPlan = fftwf_plan_dft_r2c_1d(SIZE_A, fftwIn, this->fftwOut, FFTW_ESTIMATE);
...
float* bfcc = &(bfccVector[0]);
this->fftwDctPlan = fftwf_plan_r2r_1d(SIZE_B, fftwIn, bfcc, FFTW_REDFT10, FFTW_ESTIMATE);
...

In the audio callback:

fftwf_execute(this->fftwPlan); // No problem at all
...
fftwf_execute(this->fftwDctPlan); // Seems to allocate memory

Stacktrace when catching SIGXCPU on Xenomai (Juce plugin on Elk Audio Os):

    Thread 11 "sushi_b64" hit Catchpoint 1 (signal SIGXCPU), __GI___mmap64 (offset=<optimized out>, fd=-1, flags=16418, prot=0, len=134217728, addr=<optimized out>)
    at ../sysdeps/unix/sysv/linux/mmap64.c:52
52	../sysdeps/unix/sysv/linux/mmap64.c: No such file or directory.
(gdb) bt
#0  __GI___mmap64 (offset=<optimized out>, fd=-1, flags=16418, prot=0, len=134217728, addr=<optimized out>) at ../sysdeps/unix/sysv/linux/mmap64.c:52
#1  __GI___mmap64 (addr=addr@entry=0x0, len=len@entry=134217728, prot=prot@entry=0, flags=flags@entry=16418, fd=fd@entry=-1, offset=offset@entry=0)
    at ../sysdeps/unix/sysv/linux/mmap64.c:40
#2  0x0000007ff77169c4 in new_heap (size=135168, size@entry=2824, top_pad=<optimized out>) at arena.c:487
#3  0x0000007ff7717548 in _int_new_arena (size=576) at arena.c:911
#4  arena_get2 (avoid_arena=0x0, size=576) at arena.c:911
#5  arena_get2 (size=576, avoid_arena=0x0) at arena.c:872
#6  0x0000007ff7719e2c in tcache_init () at malloc.c:2994
#7  0x0000007ff771abc8 in tcache_init () at malloc.c:3050
#8  __GI___libc_malloc (bytes=200) at malloc.c:3050
#9  0x0000007ff43c5ec8 in fftwf_malloc_plain () from /usr/lib/libfftw3f.so.3
#10 0x0000007ff4443bf4 in ?? () from /usr/lib/libfftw3f.so.3
#11 0x0000007feec44e24 in DemoProcessor::computeFeatureVector() () from /home/mind/GuitarTimbreClassifier/Demo-guitarTimbreClassifier.so
#12 0x0000007feec454e0 in DemoProcessor::onsetDetectedRoutine() () from /home/mind/GuitarTimbreClassifier/Demo-guitarTimbreClassifier.so
#13 0x0000007feec46848 in DemoProcessor::processBlock(juce::AudioBuffer<float>&, juce::MidiBuffer&) () from /home/mind/GuitarTimbreClassifier/Demo-guitarTimbreClassifier.so
#14 0x0000007fee9134cc in void JuceVSTWrapper::internalProcessReplacing<float>(float**, float**, int, JuceVSTWrapper::VstTempBuffers<float>&) ()
from /home/mind/GuitarTimbreClassifier/Demo-guitarTimbreClassifier.so

This issue doesn’t come up when commenting the second fftwf_execute.
Thanks.

Hi,
FFTW creator confirmed that there is currently no REDFT implementation that does not allocate memory on execution (in their library ofc).

If you came up with the same issue, his solution is to stick to a fixed size dct transform (if possible) and use their code generator to produce a piece of C code that does not allocate memory.
If you’re in need of a dct transform of generic size, fftw cannot provide a solution right now.

1 Like