Compute bin-width normalization factors for LOG_REBIN. Counts how many FFT bins map to each output bin via the LUT, then stores 1/count as the normalization factor. Bins with 0 FFT bins get factor 1.0 (no scaling).
| 969 | // then stores 1/count as the normalization factor. Bins with 0 FFT bins |
| 970 | // get factor 1.0 (no scaling). |
| 971 | void computeLogRebinNormFactors(fl::vector<float>& normFactors, |
| 972 | const fl::vector<u8>& lut, |
| 973 | int fftN, float fs, |
| 974 | int binStart, int binEnd) { |
| 975 | int bands = binEnd - binStart; |
| 976 | normFactors.resize(binEnd); |
| 977 | for (int i = 0; i < binEnd; ++i) { |
| 978 | normFactors[i] = 1.0f; |
| 979 | } |
| 980 | |
| 981 | // Count FFT bins mapping to each output bin using same bounds as logRebinRange |
| 982 | const int numRawBins = fftN / 2 + 1; |
| 983 | const u16x16 rawBinHz(fs / static_cast<float>(fftN)); |
| 984 | const u16x16 halfBin = rawBinHz >> 1; |
| 985 | const u16x16 loEdge(mLogBinEdges[binStart]); |
| 986 | const u16x16 hiEdge(mLogBinEdges[binEnd]); |
| 987 | |
| 988 | int kStart = 0; |
| 989 | if (loEdge > halfBin) { |
| 990 | kStart = static_cast<int>( |
| 991 | u16x16::ceil((loEdge - halfBin) / rawBinHz).to_int()); |
| 992 | } |
| 993 | int kEnd = static_cast<int>( |
| 994 | u16x16::ceil((hiEdge + halfBin) / rawBinHz).to_int()); |
| 995 | if (kEnd > numRawBins) kEnd = numRawBins; |
| 996 | |
| 997 | FASTLED_STACK_ARRAY(float, counts, binEnd); |
| 998 | for (int k = kStart; k < kEnd; ++k) { |
| 999 | counts[lut[k]] += 1.0f; |
| 1000 | } |
| 1001 | |
| 1002 | for (int i = binStart; i < binEnd; ++i) { |
| 1003 | normFactors[i] = (counts[i] > 0.0f) ? 1.0f / counts[i] : 1.0f; |
| 1004 | } |
| 1005 | (void)bands; |
| 1006 | } |
| 1007 | |
| 1008 | // LOG_REBIN helper: group FFT bins into CQ output bins [binStart, binEnd) |
| 1009 | // Uses pre-computed LUT for O(1) bin mapping per FFT bin. |