FastLED 3.9.15
Loading...
Searching...
No Matches

◆ computeFeatures()

void fl::audio::detector::Percussion::computeFeatures ( const fft::Bins & fft)
private

Definition at line 146 of file percussion.cpp.hpp.

146 {
147 auto bins = fft.raw();
148 int n = static_cast<int>(bins.size());
149 if (n < 16) {
150 mBassToTotal = 0.0f;
151 mTrebleToTotal = 0.0f;
152 mClickRatio = 0.0f;
153 mTrebleFlatness = 0.0f;
154 mMidToTreble = 0.0f;
155 mSubBassProxy = 0.0f;
156 return;
157 }
158
159 // Frequency-based band boundaries (range-agnostic).
160 // Bass: fmin–300 Hz (kick body, sub-bass)
161 // Mid: 300–2000 Hz (snare body, tom)
162 // Treble: 2000+ Hz (click transients, hi-hat, cymbals)
163 // Click: 1500–4500 Hz (kick beater attack, snare crack)
164 int bassCutBin = fl::max(1, fft.freqToBin(300.0f));
165 int trebleCutBin = fl::max(bassCutBin + 1, fft.freqToBin(2000.0f));
166 int clickLoBin = fl::max(bassCutBin, fft.freqToBin(1500.0f));
167 int clickHiBin = fl::min(n - 1, fft.freqToBin(4500.0f));
168
169 float bassSum = 0.0f;
170 for (int i = 0; i <= bassCutBin; ++i) bassSum += bins[i];
171
172 float midSum = 0.0f;
173 for (int i = bassCutBin + 1; i < trebleCutBin; ++i) midSum += bins[i];
174
175 float trebleSum = 0.0f;
176 for (int i = trebleCutBin; i < n; ++i) trebleSum += bins[i];
177
178 // Click band: 1500–4500 Hz (kick click, snare crack)
179 float clickBandSum = 0.0f;
180 for (int i = clickLoBin; i <= clickHiBin; ++i) clickBandSum += bins[i];
181
182 // Upper-mid for click ratio denominator
183 float upperMidSum = midSum;
184
185 float total = bassSum + midSum + trebleSum;
186
187 // Bass/Total ratio
188 mBassToTotal = (total > 1e-6f) ? bassSum / total : 0.0f;
189
190 // Treble/Total ratio
191 mTrebleToTotal = (total > 1e-6f) ? trebleSum / total : 0.0f;
192
193 // Click ratio: treble click band vs upper-mid notch region
194 mClickRatio = (upperMidSum > 1e-6f) ? clickBandSum / upperMidSum : 0.0f;
195
196 // Mid/Treble ratio
197 mMidToTreble = (trebleSum > 1e-6f) ? midSum / trebleSum : 0.0f;
198
199 // Sub-bass proxy: lowest bin / first mid bin
200 int firstMidBin = bassCutBin + 1;
201 mSubBassProxy = (firstMidBin < n && bins[firstMidBin] > 1e-6f)
202 ? bins[0] / bins[firstMidBin]
203 : 0.0f;
204
205 // Treble flatness: geometric_mean / arithmetic_mean of treble bins
206 int trebleBinCount = n - trebleCutBin;
207 float trebleArithMean = (trebleBinCount > 0) ? trebleSum / static_cast<float>(trebleBinCount) : 0.0f;
208 if (trebleArithMean > 1e-6f) {
209 float sumLog = 0.0f;
210 int validCount = 0;
211 for (int i = trebleCutBin; i < n; ++i) {
212 if (bins[i] > 1e-6f) {
213 sumLog += fl::logf(bins[i]);
214 ++validCount;
215 }
216 }
217 if (validCount > 0) {
218 float geoMean = fl::expf(sumLog / static_cast<float>(validCount));
219 mTrebleFlatness = geoMean / trebleArithMean;
220 } else {
221 mTrebleFlatness = 0.0f;
222 }
223 } else {
224 mTrebleFlatness = 0.0f;
225 }
226}
AudioAnalyzeFFT1024 fft
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NOEXCEPT
Definition math.h:71
constexpr common_type_t< T, U > max(T a, U b) FL_NOEXCEPT
Definition math.h:75
float expf(float value) FL_NOEXCEPT
Definition math.h:398
float logf(float value) FL_NOEXCEPT
Definition math.h:418

References fl::expf(), fl::logf(), fl::max(), mBassToTotal, mClickRatio, fl::min(), mMidToTreble, mSubBassProxy, mTrebleFlatness, and mTrebleToTotal.

Referenced by update().

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