175 {
176
177
178 const auto& bins = broadFft.raw();
179 const int n = static_cast<int>(bins.size());
180 if (n == 0) {
184 return;
185 }
186
187
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) {
199 sumRaw += mag;
200 ++flatnessCount;
201 }
202 if (mag > peak) peak = mag;
203 }
204
205
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 {
212 }
213
214
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
226 for (int i = 0; i < n; ++i) {
227 const float mag = bins[i];
228 if (mag >= densityThreshold) ++densityCount;
229 float norm = mag * invSum;
231 if (hasPrev) {
233 flux += diff * diff;
234 }
235 }
236
240 } else {
242 }
243}
fl::vector< float > mFluxNormBins
fl::vector< float > mPrevBins
void swap(T &a, T &b) FL_NOEXCEPT
float sqrtf(float value) FL_NOEXCEPT
float expf(float value) FL_NOEXCEPT
float fast_logf_approx(float x) FL_NOEXCEPT