450 {
451
452
453
454
455
456
457
458
459
460 float formantScore;
461 if (formantRatio < 0.12f) {
462 formantScore = formantRatio / 0.12f * 0.30f;
463 } else {
464
465 float dist =
fl::abs(formantRatio - 0.5f);
466 formantScore =
fl::max(0.30f, 1.0f - dist / 0.70f);
467 }
468
469
470
471
472 float flatnessScore;
473 if (spectralFlatness < 0.20f) {
474
475 flatnessScore = spectralFlatness / 0.20f * 0.3f;
476 } else if (spectralFlatness <= 0.65f) {
477
478 float dist =
fl::abs(spectralFlatness - 0.43f);
479 flatnessScore =
fl::max(0.0f, 1.0f - dist / 0.22f);
480 } else {
481
482 flatnessScore =
fl::max(0.0f, 1.0f - (spectralFlatness - 0.65f) / 0.10f);
483 }
484
485
486
487 float densityScore;
488 if (harmonicDensity < 2.5f) {
489
490 densityScore = harmonicDensity / 2.5f * 0.3f;
491 } else if (harmonicDensity <= 12.5f) {
492
493 densityScore = 0.3f + (harmonicDensity - 2.5f) / 10.0f * 0.7f;
494 } else {
495
496 densityScore =
fl::max(0.0f, 1.0f - (harmonicDensity - 12.5f) / 3.5f);
497 }
498
499
500
501
502 float spectralFluxScore;
503 if (spectralFlux < 0.01f) {
504 spectralFluxScore = 0.0f;
505 } else if (spectralFlux < 0.15f) {
506 spectralFluxScore = (spectralFlux - 0.01f) / 0.14f;
507 } else {
508 spectralFluxScore = 1.0f;
509 }
510
511
512
513
514 float weightedAvg = 0.33f * formantScore
515 + 0.35f * flatnessScore
516 + 0.12f * densityScore
517 + 0.10f * spectralFluxScore;
518
519
520
521
522
523
524 float totalBoost = 1.0f;
525
526
527
528
529 if (spectralVariance > 0.01f) {
530 float varianceBoost = 1.0f + 0.40f * (spectralVariance - 0.74f) / 0.76f;
531 varianceBoost =
fl::clamp(varianceBoost, 0.90f, 1.25f);
532 totalBoost *= varianceBoost;
533 }
534
535
536
538 float periodicPenalty = 1.0f - 0.25f * (0.15f -
mEnvelopeJitter) / 0.15f;
539 totalBoost *= periodicPenalty;
540 }
541
542
543
546 jitterBoost =
fl::clamp(jitterBoost, 1.0f, 1.15f);
547 totalBoost *= jitterBoost;
548 }
549
550
553 acfBoost =
fl::clamp(acfBoost, 1.0f, 1.25f);
554 totalBoost *= acfBoost;
555 }
556
557
558
561 totalBoost *= zcPenalty;
562 }
563
564
566 float zcBoost;
570 zcBoost = 1.0f;
571 } else {
573 }
574 zcBoost =
fl::clamp(zcBoost, 0.80f, 1.20f);
575 totalBoost *= zcBoost;
576 }
577
578
582 float combinedBoost = 1.0f + 1.5f * minExcess;
583 combinedBoost =
fl::clamp(combinedBoost, 1.0f, 1.20f);
584 totalBoost *= combinedBoost;
585 }
586
587
588 totalBoost =
fl::clamp(totalBoost, 0.50f, 1.60f);
589 weightedAvg *= totalBoost;
590
591
592 float formantMultiplier;
593 if (formantScore < 0.40f) {
594 formantMultiplier = formantScore * 2.5f;
595 } else {
596 formantMultiplier = 1.0f + 0.40f * (formantScore - 0.40f);
597 }
598
599
602}
float mAutocorrelationIrregularity
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) 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
constexpr enable_if< is_fixed_point< T >::value, T >::type clamp(T x, T lo, T hi) FL_NOEXCEPT