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

◆ detectEnhancedBeats()

void fl::audio::Reactive::detectEnhancedBeats ( fl::u32 currentTimeMs)
private

Definition at line 648 of file audio_reactive.cpp.hpp.

648 {
649 // Reset beat flags
650 mCurrentData.bassBeatDetected = false;
651 mCurrentData.midBeatDetected = false;
652 mCurrentData.trebleBeatDetected = false;
653
654 // Skip if enhanced beat detection is disabled
655 if (!mConfig.enableSpectralFlux && !mConfig.enableMultiBand &&
656 !mConfig.enableMusicalBeatDetection && !mConfig.enableMultiBandBeats) {
657 return;
658 }
659
660 // Need minimum time since last beat for enhanced detection too
661 if (currentTimeMs - mLastBeatTime < BEAT_COOLDOWN) {
662 return;
663 }
664
665 // Spectral flux-based onset detection (preliminary)
666 bool onsetDetected = false;
667 float onsetStrength = 0.0f;
668
669 if (mConfig.enableSpectralFlux && mSpectralFluxDetector) {
670 onsetDetected = mSpectralFluxDetector->detectOnset(
671 mCurrentData.frequencyBins
672 );
673
674 // Use already-computed spectral flux for onset strength.
675 // Do NOT call calculateSpectralFlux() again — detectOnset() already
676 // updated the detector's internal state, so a second call would see
677 // current == previous and return 0.
678 if (onsetDetected) {
679 onsetStrength = mCurrentData.spectralFlux;
680 }
681 }
682
683 // Phase 3: Musical beat detection - validates onsets as true musical beats
684 if (mConfig.enableMusicalBeatDetection) {
685 mMusicalBeatDetector->processSample(onsetDetected, onsetStrength);
686
687 if (mMusicalBeatDetector->isBeat()) {
688 // This is a validated musical beat, not just a random onset
689 mCurrentData.beatDetected = true;
690 mLastBeatTime = currentTimeMs;
691 }
692 } else if (onsetDetected) {
693 // Fall back to simple onset detection if musical beat detection disabled
694 mCurrentData.beatDetected = true;
695 mLastBeatTime = currentTimeMs;
696 }
697
698 // Phase 3: Multi-band beat detection - per-frequency beat tracking
699 if (mConfig.enableMultiBandBeats) {
700 mMultiBandBeatDetector->detectBeats(mCurrentData.frequencyBins);
701
702 mCurrentData.bassBeatDetected = mMultiBandBeatDetector->isBassBeat();
703 mCurrentData.midBeatDetected = mMultiBandBeatDetector->isMidBeat();
704 mCurrentData.trebleBeatDetected = mMultiBandBeatDetector->isTrebleBeat();
705 } else if (mConfig.enableMultiBand) {
706 // Fall back to simple threshold-based detection if multi-band disabled
707 // Bass beat detection (bins 0-1)
708 if (mCurrentData.bassEnergy > mConfig.bassThreshold) {
709 mCurrentData.bassBeatDetected = true;
710 }
711
712 // Mid beat detection (bins 6-7)
713 if (mCurrentData.midEnergy > mConfig.midThreshold) {
714 mCurrentData.midBeatDetected = true;
715 }
716
717 // Treble beat detection (bins 14-15)
718 if (mCurrentData.trebleEnergy > mConfig.trebleThreshold) {
719 mCurrentData.trebleBeatDetected = true;
720 }
721 }
722}
fl::unique_ptr< SpectralFluxDetector > mSpectralFluxDetector
fl::unique_ptr< detector::MultiBandBeat > mMultiBandBeatDetector
ReactiveConfig mConfig
fl::unique_ptr< detector::MusicalBeat > mMusicalBeatDetector
static constexpr fl::u32 BEAT_COOLDOWN

References BEAT_COOLDOWN, mConfig, mCurrentData, mLastBeatTime, mMultiBandBeatDetector, mMusicalBeatDetector, and mSpectralFluxDetector.

Referenced by processSample().

+ Here is the caller graph for this function: