583 {
584
585
586
587
588 int numOctaves =
static_cast<int>(
floorf(
log2f(fmax / fmin)));
589 if (numOctaves < 1)
590 numOctaves = 1;
591
592
593 float logRatio =
logf(fmax / fmin);
595 for (int i = 0; i < bands; i++) {
596 centerFreqs[i] =
597 fmin *
598 expf(logRatio *
static_cast<float>(i) /
599 static_cast<float>(bands - 1));
600 }
601
602
604 for (int i = 0; i < bands; i++) {
606 static_cast<int>(
floorf(
log2f(centerFreqs[i] / fmin)));
609 if (
oct >= numOctaves)
610 oct = numOctaves - 1;
612 }
613
614
617 for (
int oct = 0;
oct < numOctaves;
oct++) {
618 int first = -1, last = -1;
619 for (int i = 0; i < bands; i++) {
620 if (binOctave[i] ==
oct) {
621 if (first < 0)
622 first = i;
623 last = i;
624 }
625 }
626
629 oi.kernels = nullptr;
630 if (first < 0) {
631 oi.firstBin = 0;
632 oi.numBins = 0;
633 continue;
634 }
635
636 oi.firstBin = first;
637 oi.numBins = last - first + 1;
640 }
641
642
643
644 int decimExp = numOctaves - 1 -
oct;
645 float effectiveFs =
646 static_cast<float>(sr) /
647 static_cast<float>(1 << decimExp);
648
649 oi.cfg.samples = samples;
650 oi.cfg.bands = oi.numBins;
651 oi.cfg.fmin = centerFreqs[first];
652 oi.cfg.fmax = (oi.numBins > 1) ? centerFreqs[last]
653 : centerFreqs[first] * 2.0f;
654 oi.cfg.fs = effectiveFs;
656
658 }
659
660
663
667 const float mainLobeHz = 4.0f * static_cast<float>(sr) /
668 static_cast<float>(samples);
669
670
671
672 FL_ASSERT(bands <= 0xFFFF,
"CQ_OCTAVE band count exceeds u16 index range");
675 int firstNearby = 0;
676 int lastNearby = 0;
677 for (int i = 0; i < bands; ++i) {
678 while (centerFreqs[i] - centerFreqs[firstNearby] > mainLobeHz) {
679 ++firstNearby;
680 }
681 if (lastNearby < i) lastNearby = i;
682 while (lastNearby + 1 < bands &&
683 centerFreqs[lastNearby + 1] - centerFreqs[i] <= mainLobeHz) {
684 ++lastNearby;
685 }
688 }
689
690
691 }
#define FASTLED_STACK_ARRAY(TYPE, NAME, SIZE)
Stack-allocated array with automatic zero-initialization.
#define FL_ASSERT(x, MSG)
fl::vector< kiss_fft_scalar > mWorkBuf
void buildLinearBinLut(fl::vector< u8 > &lut, int fftN) FL_NO_EXCEPT
fl::vector< alpha16 > mWindowBuf
fl::vector< u8 > mLinearBinLut
fl::vector< u16 > mCoverageLast
void initLogRebin() FL_NO_EXCEPT
fl::vector< u16 > mCoverageFirst
fl::vector< OctaveInfo > mOctaves
fl::vector< kiss_fft_cpx > mFftOut
static void computeWindow(fl::vector< alpha16 > &win, int N, Window type) FL_NO_EXCEPT
struct sparse_arr * generate_kernels(struct cq_kernel_cfg cfg)
float logf(float value) FL_NO_EXCEPT
float log2f(float value) FL_NO_EXCEPT
FASTLED_FORCE_INLINE void * memset(void *s, int c, size_t n) FL_NO_EXCEPT
float floorf(float value) FL_NO_EXCEPT
float expf(float value) FL_NO_EXCEPT