584 {
585
586
587
588
589 int numOctaves =
static_cast<int>(
floorf(
log2f(fmax / fmin)));
590 if (numOctaves < 1)
591 numOctaves = 1;
592
593
594 float logRatio =
logf(fmax / fmin);
596 for (int i = 0; i < bands; i++) {
597 centerFreqs[i] =
598 fmin *
599 expf(logRatio *
static_cast<float>(i) /
600 static_cast<float>(bands - 1));
601 }
602
603
605 for (int i = 0; i < bands; i++) {
607 static_cast<int>(
floorf(
log2f(centerFreqs[i] / fmin)));
610 if (
oct >= numOctaves)
611 oct = numOctaves - 1;
613 }
614
615
618 for (
int oct = 0;
oct < numOctaves;
oct++) {
619 int first = -1, last = -1;
620 for (int i = 0; i < bands; i++) {
621 if (binOctave[i] ==
oct) {
622 if (first < 0)
623 first = i;
624 last = i;
625 }
626 }
627
630 oi.kernels = nullptr;
631 if (first < 0) {
632 oi.firstBin = 0;
633 oi.numBins = 0;
634 continue;
635 }
636
637 oi.firstBin = first;
638 oi.numBins = last - first + 1;
641 }
642
643
644
645 int decimExp = numOctaves - 1 -
oct;
646 float effectiveFs =
647 static_cast<float>(sr) /
648 static_cast<float>(1 << decimExp);
649
650 oi.cfg.samples = samples;
651 oi.cfg.bands = oi.numBins;
652 oi.cfg.fmin = centerFreqs[first];
653 oi.cfg.fmax = (oi.numBins > 1) ? centerFreqs[last]
654 : centerFreqs[first] * 2.0f;
655 oi.cfg.fs = effectiveFs;
657
659 }
660
661
664
668 const float mainLobeHz = 4.0f * static_cast<float>(sr) /
669 static_cast<float>(samples);
670
671
672
673 FL_ASSERT(bands <= 0xFFFF,
"CQ_OCTAVE band count exceeds u16 index range");
676 int firstNearby = 0;
677 int lastNearby = 0;
678 for (int i = 0; i < bands; ++i) {
679 while (centerFreqs[i] - centerFreqs[firstNearby] > mainLobeHz) {
680 ++firstNearby;
681 }
682 if (lastNearby < i) lastNearby = i;
683 while (lastNearby + 1 < bands &&
684 centerFreqs[lastNearby + 1] - centerFreqs[i] <= mainLobeHz) {
685 ++lastNearby;
686 }
689 }
690
691
692 }
#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