# Notes on PFFFT We strongly recommend to **read this file** before using PFFFT and to **always wrap** the original C library within a C++ wrapper. [Example of PFFFT wrapper](https://cs.chromium.org/chromium/src/third_party/webrtc/modules/audio_processing/utility/pffft_wrapper.h). ## Scratch buffer The caller can optionally provide a scratch buffer. When not provided, VLA is used to provide a thread-safe option. However, it is recommended to write a C++ wrapper which allocates its own scratch buffer. Note that the scratch buffer has the same memory alignment requirements of the input and output vectors. ## Output layout PFFFT computes the forward transform with two possible output layouts: 1. ordered 2. unordered ### Ordered layout Calling `pffft_transform_ordered` produces an array of **interleaved real and imaginary parts**. The last Fourier coefficient is purely real and stored in the imaginary part of the DC component (which is also purely real). ### Unordered layout Calling `pffft_transform` produces an array with a more complex structure, but in a more efficient way than `pffft_transform_ordered`. Below, the output produced by Matlab and that produced by PFFFT are compared. The comparison is made for a 32 point transform of a 16 sample buffer. A 32 point transform has been chosen as this is the minimum supported by PFFFT. Important notes: - In Matlab the DC (Matlab index 1 [R1, I1]]) and Nyquist (Matlab index 17 [R17, I17]) values are not repeated as complex conjugates. - In PFFFT the Nyquist real and imaginary parts ([R17, I17]) are omitted entirely. - In PFFFT the final 8 values (4 real and 4 imaginary) are not in the same order as all of the others. - In PFFFT all imaginary parts are stored as negatives (like second half in Matlab). ``` +-------+-----------+-------+-------+ | Index | Matlab | Index | PFFFT | +-------+-----------+-------+-------+ | 1 | R1 + I1 | 0 | R1 | | 2 | R2+ I2 | 1 | R2 | | 3 | R3 + I3 | 2 | R3 | | 4 | R4 + I4 | 3 | R4 | | 5 | R5 + I5 | 4 | -I1 | | 6 | R6 + I6 | 5 | -I2 | | 7 | R7 + I7 | 6 | -I3 | | 8 | R8 + I8 | 7 | -I4 | | 9 | R9 + I9 | 8 | R5 | | 10 | R10 + I10 | 9 | R6 | | 11 | R11 + I11 | 10 | R7 | | 12 | R12 + I12 | 11 | R8 | | 13 | R13 + I13 | 12 | -I5 | | 14 | R14 + I14 | 13 | -I6 | | 15 | R15 + I15 | 14 | -I7 | | 16 | R16 + I16 | 15 | -I8 | | 17 | R17 + I17 | 16 | R9 | | 18 | R16 - I16 | 17 | R10 | | 19 | R15 - I15 | 18 | R11 | | 20 | R14 - I14 | 19 | R12 | | 21 | R13 - I13 | 20 | -I9 | | 22 | R12 - I12 | 21 | -I10 | | 23 | R11 - I11 | 22 | -I11 | | 24 | R10 - I10 | 23 | -I12 | | 25 | R9 - I9 | 24 | R13 | | 26 | R8 - I8 | 25 | R16 | | 27 | R7 - I7 | 26 | R15 | | 28 | R6 - I6 | 27 | R14 | | 29 | R5 - I5 | 28 | -I13 | | 30 | R4 - I4 | 29 | -I16 | | 31 | R3 - I3 | 30 | -I15 | | 32 | R2 - I2 | 31 | -I14 | +-------+-----------+-------+-------+ ```