My workaround
After some fidling with the FFT, this are my findings:
1) The RFFT does not work or at least I did not manage to make it work. This is not a big deal since you can use the regular FFT with zero imaginary inputs.
2) I still don't know the purpose of the fft_permute function. Neither with or without, do I get a logical sorting of the computed frequencies. Anyway I still call it in my code although it might also work without it.
3) What I did is to dynamicaly build an array of frequency indexes, in increasing order. I have a loop where I feed the FFT a single sinusoid at a time and search for the non null result. I have placed this code in the initialisation of my effect. There might be a simple way that I missed but still, if anyone is interested:
@init
// The fft_permute does not work as expected. Workaround: we build arrays containing the correct frequency indexes ("reals" for real results and "imaginaries" for imaginary results)
width = 1024; // window width
origin = 0;
reals = origin; memset (reals, -1, width); origin += width;
imaginaries = origin; memset (imaginaries, -1, width); origin += width;
temporaries = origin;
// DC
sample = 0; loop (width, temporaries [sample] = 1; temporaries [sample + 1] = 0; sample += 2; ); // constant
fft (temporaries, width);
fft_permute (temporaries, width);
found = 0;
index = 0;
while
(
abs (temporaries [index]) > 0.0001 ?
(
reals [0] = index;
imaginaries [0] = index + 1;
found = 1;
);
index += 1;
!found && index < 2 * width;
);
// cos waves
frequency = 1;
loop
(
width - 1,
sample = 0; loop (width, temporaries [2 * sample] = cos (frequency * 2 * $pi * sample / width); temporaries [2 * sample + 1] = 0; sample += 1; ); // cosine
fft (temporaries, width);
fft_permute (temporaries, width);
found = 0;
index = 0;
while
(
abs (temporaries [index]) > 0.0001 ?
(
reals [frequency] = index;
imaginaries [frequency] = index + 1;
found = 1;
);
index += 1;
!found && index < 2 * width;
);
frequency += 1;
);
// check
fftfailure = -1;
frequency = 0;
loop
(
width,
reals [frequency] == -1 ?
(
fftfailure = frequency;
):
(
reals [frequency] % 2 != 0 ?
(
fftfailure = frequency;
);
);
frequency += 1;
);
|