home/ atoms/ adaptive-threshold-beat-detection

Robust beat detection uses a decaying cutoff plus a hold window to debounce triggers

A fixed amplitude threshold double-triggers on sustained loud passages and misses beats as levels drift. The workshop’s beat_detect_amplitude demo fixes this with a dynamic cutoff: a beat fires only when the current level exceeds BOTH a fixed floor (beatThreshold) and a moving beatCutoff; on firing, beatCutoff is raised above the current level (level*1.2) so the next frame cannot immediately re-trigger. A frame counter enforces a minimum gap (beatHoldFrames) before another beat is allowed, after which beatCutoff decays each frame (×beatDecayRate ≈ 0.98) back toward zero so future beats can register. This hold-and-decay envelope is the browser analogue of onset-detection debouncing.

Examples

beatThreshold=0.11; if (level>beatCutoff && level>beatThreshold) { onBeat(); beatCutoff=level1.2; framesSinceLastBeat=0; } else if (framesSinceLastBeat>beatHoldFrames) { beatCutoff=beatDecayRate; } else { framesSinceLastBeat++; }

Assessment

Explain why raising beatCutoff on each detected beat and decaying it over held frames prevents double-triggering; contrast this with a single fixed threshold.

“if (level > beatCutoff && level > beatThreshold)”