46 float ibiSeconds =
static_cast<float>(ibiFrames *
mConfig.samplesPerFrame) /
47 static_cast<float>(
mConfig.sampleRate);
100 float avgFrames =
static_cast<float>(sum) /
static_cast<float>(
mIBIHistory.size());
101 return (avgFrames *
static_cast<float>(
mConfig.samplesPerFrame)) /
102 static_cast<float>(
mConfig.sampleRate);
115 mStats.validatedBeats = 0;
116 mStats.rejectedOnsets = 0;
130 float expectedFrames = (expectedIBI *
static_cast<float>(
mConfig.sampleRate)) /
131 static_cast<float>(
mConfig.samplesPerFrame);
137 float tolerance = 0.25f;
138 float minExpected = expectedFrames * (1.0f - tolerance);
139 float maxExpected = expectedFrames * (1.0f + tolerance);
143 float actualIBI = (actualFrames *
static_cast<float>(
mConfig.samplesPerFrame)) /
144 static_cast<float>(
mConfig.sampleRate);
149 return (actualFrames >= minExpected) && (actualFrames <= maxExpected);
166 float cv = (avgIBI > 0.0f) ? (stdDev / avgIBI) : 1.0f;
172 float confidence =
fl::max(0.0f, 1.0f - (cv * 2.0f));
175 float ibiDiff =
fl::abs(currentIBI - avgIBI);
176 float ibiError = (avgIBI > 0.0f) ? (ibiDiff / avgIBI) : 1.0f;
177 float ibiBonus =
fl::max(0.0f, 1.0f - (ibiError * 4.0f));
180 return (confidence * 0.7f) + (ibiBonus * 0.3f);
190 if (avgIBI <= 0.0f) {
194 float instantaneousBPM = 60.0f / avgIBI;
200 float alpha =
mConfig.bpmSmoothingAlpha;
213 float bpm = 60.0f / ibi;
229 float mean =
static_cast<float>(sum) /
static_cast<float>(
mIBIHistory.size());
232 float variance = 0.0f;
234 float diff =
static_cast<float>(
mIBIHistory[i]) - mean;
235 variance += diff * diff;
237 variance /=
static_cast<float>(
mIBIHistory.size());
240 float stdDevFrames =
fl::sqrt(variance);
241 return (stdDevFrames *
static_cast<float>(
mConfig.samplesPerFrame)) /
242 static_cast<float>(
mConfig.sampleRate);
deque< u32 > mIBIHistory
Inter-beat interval history (in frames)
float mAverageIBI
Average inter-beat interval (in frames)
MusicalBeat() FL_NOEXCEPT
void processSample(bool onsetDetected, float onsetStrength)
Process one audio frame.
bool isValidIBI(float ibi) const
Check if IBI is within valid BPM range.
float calculateBeatConfidence(float currentIBI)
Calculate beat confidence based on rhythmic consistency.
float getBeatConfidence() const
Get beat confidence for the last detected beat.
bool mBeatDetected
Last beat was detected.
float mCurrentBPM
Current BPM estimate (smoothed)
bool isBeat() const
Check if a musical beat was detected in the last frame.
float mLastBeatConfidence
Last beat confidence score.
void reset()
Reset internal state (clear history, reset BPM)
~MusicalBeat() FL_NOEXCEPT
u32 mCurrentFrame
Current frame counter.
void configure(const MusicalBeatDetectorConfig &config)
Configure the beat detector.
float getAverageIBI() const
Get inter-beat interval (IBI) statistics.
u32 mLastBeatFrame
Last beat timestamp (in frames)
bool validateBeat(float onsetStrength)
Validate if an onset is a true musical beat.
float getBPM() const
Get current BPM estimate.
void updateBPMEstimate()
Update BPM estimate from inter-beat intervals.
float calculateIBIStdDev() const
Calculate standard deviation of IBI history.
MusicalBeatDetectorConfig mConfig
Configuration for musical beat detection.
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 sqrt(T x) FL_NOEXCEPT
constexpr enable_if< is_fixed_point< T >::value, T >::type abs(T x) FL_NOEXCEPT
Base definition for an LED controller.