| 302 | } |
| 303 | |
| 304 | float TempoAnalyzer::calculateIntervalScore(u32 interval) { |
| 305 | float bpm = 60000.0f / static_cast<float>(interval); |
| 306 | |
| 307 | // All BPM values within the valid range score equally |
| 308 | if (bpm >= mMinBPM && bpm <= mMaxBPM) { |
| 309 | return 1.0f; |
| 310 | } |
| 311 | |
| 312 | // Outside the range, penalize based on distance from nearest boundary |
| 313 | float distOutside; |
| 314 | if (bpm < mMinBPM) { |
| 315 | distOutside = mMinBPM - bpm; |
| 316 | } else { |
| 317 | distOutside = bpm - mMaxBPM; |
| 318 | } |
| 319 | float range = mMaxBPM - mMinBPM; |
| 320 | float normalizedDist = distOutside / range; |
| 321 | return fl::max(0.1f, 1.0f - normalizedDist); |
| 322 | } |
| 323 | |
| 324 | float TempoAnalyzer::calculateTempoConfidence(const TempoHypothesis& hyp) { |
| 325 | // Confidence based on: |
no test coverage detected