FastLED 3.10.8
Loading...
Searching...
No Matches

◆ runLogRebin()

void fl::audio::fft::Context::runLogRebin ( span< const i16 > buffer,
Bins * out )
inlineprivate

Definition at line 247 of file fft_impl.cpp.hpp.

247 {
248 out->setParams(mFmin, mFmax, mSampleRate);
249 const int N = mInputSamples;
250 const int bands = mTotalBands;
251 const int numRawBins = N / 2 + 1;
252
253 // Use thread-local scratch buffers to avoid stack overflow on
254 // ESP32 tasks with limited stack (~4-8 KB).
255 FftScratch &s = scratch();
256 s.windowed.resize(N);
257 s.fftOut.resize(N);
258 s.re.resize(numRawBins);
259 s.im.resize(numRawBins);
260 s.mag.resize(numRawBins);
261 s.rawBinsI.resize(bands);
262
263 applyWindow(buffer.data(), mWindowBuf.data(), s.windowed.data(), N);
264 fl_fft_real_forward(mFftrCfg, mInputSamples, s.windowed.data(), s.fftOut.data());
265
266 // Deinterleave AoS → SoA and batch-compute magnitudes
267 deinterleave(s.fftOut.data(), s.re.data(), s.im.data(), numRawBins);
268 batchMag(s.re.data(), s.im.data(), s.mag.data(), numRawBins);
269
270 // Linear bins (same as other paths)
271 computeLinearBins(s.mag.data(), N, out);
272
273 // Group FFT bins into log-spaced output bins (integer accumulation)
274 fl::memset(s.rawBinsI.data(), 0, sizeof(u32) * bands);
275 logRebinRange(s.mag.data(), N, static_cast<float>(mSampleRate),
276 0, bands, s.rawBinsI.data(), mLogBinLut);
277
278 // Store raw magnitudes (dB computed lazily by Bins::db())
279 fl::vector<float> &rawBins = out->raw_mut();
280 rawBins.resize(bands);
281 for (int i = 0; i < bands; ++i) {
282 rawBins[i] = static_cast<float>(s.rawBinsI[i]);
283 }
284
285 // Store bin-width normalization factors so consumers can optionally
286 // normalize (e.g. for equalization display). Raw output is unchanged.
287 out->setNormFactors(mLogBinNormFactors);
288 }
static void batchMag(const kiss_fft_scalar *re, const kiss_fft_scalar *im, u16 *mag, int n) FL_NO_EXCEPT
void computeLinearBins(const u16 *mag, int, Bins *out) FL_NO_EXCEPT
void logRebinRange(const u16 *mag, int fftN, float fs, int binStart, int binEnd, u32 *rawBinsI, const fl::vector< u8 > &lut) FL_NO_EXCEPT
fl::vector< alpha16 > mWindowBuf
static FftScratch & scratch() FL_NO_EXCEPT
static void deinterleave(const kiss_fft_cpx *cpx, kiss_fft_scalar *re, kiss_fft_scalar *im, int n) FL_NO_EXCEPT
static void applyWindow(const kiss_fft_scalar *samples, const alpha16 *win, kiss_fft_scalar *out, int N) FL_NO_EXCEPT
fl::vector< u8 > mLogBinLut
fl::vector< float > mLogBinNormFactors
void resize(fl::size n) FL_NO_EXCEPT
Definition vector.h:593
void fl_fft_real_forward(kiss_fftr_cfg cfg, int N, const kiss_fft_scalar *in, kiss_fft_cpx *out) FL_NO_EXCEPT
Forward real-to-complex FFT.
FASTLED_FORCE_INLINE void * memset(void *s, int c, size_t n) FL_NO_EXCEPT
Definition cstring.h:148

References applyWindow(), batchMag(), computeLinearBins(), fl::vector< T >::data(), deinterleave(), fl::audio::fft::Context::FftScratch::fftOut, fl::audio::fft::fl_fft_real_forward(), fl::FL_NO_EXCEPT, fl::audio::fft::Context::FftScratch::im, logRebinRange(), fl::audio::fft::Context::FftScratch::mag, fl::memset(), mFftrCfg, mFmax, mFmin, mInputSamples, mLogBinLut, mLogBinNormFactors, mSampleRate, mTotalBands, mWindowBuf, fl::audio::fft::Context::FftScratch::rawBinsI, fl::audio::fft::Context::FftScratch::re, fl::vector< T >::resize(), scratch(), and fl::audio::fft::Context::FftScratch::windowed.

Referenced by run().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: