295 {
296
297
298
299 const int n = static_cast<int>(pcm.size());
300 if (n < 44) {
303 return;
304 }
305
306 const float normFactor = 1.0f / 32768.0f;
308 const int winSize = 2 * halfWin + 1;
309 const float invWinSize = 1.0f / static_cast<float>(winSize);
310
311
312 float windowSum = 0.0f;
313 for (int j = 0; j < winSize && j < n; ++j) {
314 windowSum +=
fl::abs(
static_cast<float>(pcm[j])) * normFactor;
315 }
316
317
318 float sumEnv = 0.0f;
319 float sumDev = 0.0f;
320 int count = 0;
321 float sumPeaks = 0.0f;
322 float sumSqPeaks = 0.0f;
323 int numCycles = 0;
324 float currentPeak = 0.0f;
325 bool wasPositive = pcm[halfWin] >= 0;
326
327
328 int prevCrossing = -1;
329 int numIntervals = 0;
330 float sumIntervals = 0.0f;
331 float sumSqIntervals = 0.0f;
332
333 for (int i = halfWin; i < n - halfWin; ++i) {
334 float absVal =
fl::abs(
static_cast<float>(pcm[i])) * normFactor;
335 float smoothed = windowSum * invWinSize;
336
337 sumEnv += smoothed;
338 sumDev +=
fl::abs(absVal - smoothed);
339 ++count;
340
341
342 currentPeak =
fl::max(currentPeak, absVal);
343 bool isPositive = pcm[i] >= 0;
344 if (isPositive != wasPositive) {
345
346 if (currentPeak > 0.01f) {
347 sumPeaks += currentPeak;
348 sumSqPeaks += currentPeak * currentPeak;
349 ++numCycles;
350 }
351 currentPeak = 0.0f;
352
353
354 if (prevCrossing >= 0) {
355 float interval = static_cast<float>(i - prevCrossing);
356 sumIntervals += interval;
357 sumSqIntervals += interval * interval;
358 ++numIntervals;
359 }
360 prevCrossing = i;
361 }
362 wasPositive = isPositive;
363
364
365 if (i + 1 < n - halfWin) {
366 windowSum -=
fl::abs(
static_cast<float>(pcm[i - halfWin])) * normFactor;
367 windowSum +=
fl::abs(
static_cast<float>(pcm[i + halfWin + 1])) * normFactor;
368 }
369 }
370
371
372 if (sumEnv < 1e-6f || count == 0) {
374 } else {
375 float envelopeJitter = (sumDev / static_cast<float>(count))
376 / (sumEnv / static_cast<float>(count));
377
378 float shimmer = 0.0f;
379 if (numCycles >= 3) {
380 float meanPeak = sumPeaks / static_cast<float>(numCycles);
381 if (meanPeak > 0.01f) {
382 float variance = sumSqPeaks / static_cast<float>(numCycles)
383 - meanPeak * meanPeak;
384 if (variance < 0.0f) variance = 0.0f;
385 shimmer =
fl::sqrtf(variance) / meanPeak;
386 }
387 }
389 }
390
391
392 if (numIntervals < 2) {
394 } else {
395 float mean = sumIntervals / static_cast<float>(numIntervals);
396 if (mean < 1e-6f) {
398 } else {
399 float variance = sumSqIntervals / static_cast<float>(numIntervals)
400 - mean * mean;
401 if (variance < 0.0f) variance = 0.0f;
403 }
404 }
405}
float sqrtf(float value) FL_NOEXCEPT
constexpr common_type_t< T, U > max(T a, U b) FL_NOEXCEPT
constexpr enable_if< is_fixed_point< T >::value, T >::type abs(T x) FL_NOEXCEPT