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

◆ computeBroadSpectralFeatures()

void fl::audio::detector::Vocal::computeBroadSpectralFeatures ( const fft::Bins & broadFft)
private

Definition at line 175 of file vocal.cpp.hpp.

175 {
176 // Broad spectral features from low-res wide FFT (16 bins, 174.6-4698.3 Hz).
177 // Computes flatness, harmonic density, and spectral flux.
178 const auto& bins = broadFft.raw();
179 const int n = static_cast<int>(bins.size());
180 if (n == 0) {
181 mSpectralFlatness = 0.0f;
182 mHarmonicDensity = 0.0f;
183 mSpectralFlux = 0.0f;
184 return;
185 }
186
187 // === PASS 1: Flatness + density peak + magnitudeSum ===
188 float magnitudeSum = 0.0f;
189 float sumLn = 0.0f;
190 float sumRaw = 0.0f;
191 int flatnessCount = 0;
192 float peak = 0.0f;
193
194 for (int i = 0; i < n; ++i) {
195 const float mag = bins[i];
196 magnitudeSum += mag;
197 if (mag > 1e-6f) {
198 sumLn += fast_logf_approx(mag);
199 sumRaw += mag;
200 ++flatnessCount;
201 }
202 if (mag > peak) peak = mag;
203 }
204
205 // --- Flatness result ---
206 if (flatnessCount >= 2) {
207 float geometricMean = fl::expf(sumLn / static_cast<float>(flatnessCount));
208 float arithmeticMean = sumRaw / static_cast<float>(flatnessCount);
209 mSpectralFlatness = (arithmeticMean < 1e-6f) ? 0.0f : geometricMean / arithmeticMean;
210 } else {
211 mSpectralFlatness = 0.0f;
212 }
213
214 // === PASS 2: Density count + spectral flux ===
215 mHarmonicDensity = 0.0f;
216 mSpectralFlux = 0.0f;
217
218 if (magnitudeSum >= 1e-6f) {
219 const float densityThreshold = peak * 0.1f;
220 const float invSum = 1.0f / magnitudeSum;
221 const bool hasPrev = (mPrevBins.size() == static_cast<fl::size>(n));
222 int densityCount = 0;
223 float flux = 0.0f;
224
225 mFluxNormBins.resize(n);
226 for (int i = 0; i < n; ++i) {
227 const float mag = bins[i];
228 if (mag >= densityThreshold) ++densityCount;
229 float norm = mag * invSum;
230 mFluxNormBins[i] = norm;
231 if (hasPrev) {
232 float diff = norm - mPrevBins[i];
233 flux += diff * diff;
234 }
235 }
236
237 mHarmonicDensity = static_cast<float>(densityCount);
238 mSpectralFlux = hasPrev ? fl::sqrtf(flux) : 0.0f;
240 } else {
241 mPrevBins.clear();
242 }
243}
fl::vector< float > mFluxNormBins
Definition vocal.h:73
fl::vector< float > mPrevBins
Definition vocal.h:72
void swap(T &a, T &b) FL_NOEXCEPT
Definition s16x16x4.h:877
float sqrtf(float value) FL_NOEXCEPT
Definition math.h:453
float expf(float value) FL_NOEXCEPT
Definition math.h:398
float fast_logf_approx(float x) FL_NOEXCEPT
Definition math.h:406

References fl::expf(), fl::fast_logf_approx(), mFluxNormBins, mHarmonicDensity, mPrevBins, mSpectralFlatness, mSpectralFlux, fl::audio::fft::Bins::raw(), fl::sqrtf(), and fl::fl::swap().

Referenced by update().

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