FastLED 3.10.9
Loading...
Searching...
No Matches

◆ fastDb()

static float fl::audio::fft::Context::fastDb ( u32 x)
inlinestaticprivate

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

359 {
360 if (x == 0) return 0.0f;
361
362 // Find highest set bit (integer part of log2)
363 int msb = 0;
364 {
365 u32 v = x;
366 if (v >= 0x10000u) { v >>= 16; msb += 16; }
367 if (v >= 0x100u) { v >>= 8; msb += 8; }
368 if (v >= 0x10u) { v >>= 4; msb += 4; }
369 if (v >= 0x4u) { v >>= 2; msb += 2; }
370 if (v >= 0x2u) { msb += 1; }
371 }
372
373 // Normalized mantissa in [0, 1) as u16x16
374 u32 t_raw;
375 if (msb >= 16) {
376 t_raw = (x >> (msb - 16)) - 65536u;
377 } else {
378 t_raw = (x << (16 - msb)) - 65536u;
379 }
380 u16x16 t = u16x16::from_raw(t_raw);
381
382 // log2(1+t) ~= t + 0.345 * t * (1-t) [max error ~0.008]
383 // 22610 = 0.345 * 65536 (from_raw preserves exact original constant)
384 static constexpr u16x16 one(1.0f);
385 static constexpr u16x16 kCorrection = u16x16::from_raw(22610u);
386 u16x16 complement = one - t;
387 u16x16 prod = t * complement;
388 u16x16 correction = prod * kCorrection;
389 u16x16 frac = t + correction;
390
391 // log2(x) = msb + frac, assembled as u16x16
392 u16x16 log2_val = u16x16::from_raw(
393 (static_cast<u32>(msb) << 16) + frac.raw());
394
395 // 20*log10(x) = 6.02060 * log2(x)
396#if FASTLED_FFT_PRECISION == FASTLED_FFT_FIXED16
397 // 394593 = 6.02060 * 65536 (from_raw preserves exact original constant)
398 static constexpr u16x16 kDbScale = u16x16::from_raw(394593u);
399 u16x16 db = log2_val * kDbScale;
400 return db.to_float();
401#else
402 return 6.02060f * log2_val.to_float();
403#endif
404 }
static constexpr FASTLED_FORCE_INLINE u16x16 from_raw(u32 raw) FL_NO_EXCEPT
Definition u16x16.h:54

References fl::FL_NO_EXCEPT, fl::u16x16::from_raw(), fl::u16x16::raw(), fl::t, fl::u16x16::to_float(), and fl::x.

+ Here is the call graph for this function: