Audio · interface
BeatMap
Offline rhythm analysis: where the kicks are in a whole track.
Explained in Your first game.
interface BeatMapimport type { BeatMap } from '@driftengine/audio';In depth
Computed once, ahead of time, from decoded samples. That is the important difference from a live detector, and it buys three things a live one cannot:
- Cuts land on the beat. A real-time detector necessarily fires after the transient it is detecting, and by a varying amount. Offline we can look ahead — pick the peak of the onset curve and then walk back to where the transient actually began, which is a fixed reference rather than "whenever the level happened to cross a threshold".
- Determinism. Two people watching the same shared run see the same
edit, and the same run watched twice is identical. Nothing here reads a
clock or
Math.random. - Structure. Choosing where to spend the best shot needs to see the whole track. Real-time analysis by definition cannot.
The detection is ported from a production kick detector, whose central idea is whitening: in bass-led electronic music the low end is dominated by a sustained 808, so raw low energy is loud all the time and useless. Subtract a weighted bassline/mud/low-mid mask from the kick band and take the difference between a fast and a slow envelope, and only the transient survives.
Properties
| Name | Type | Description |
|---|---|---|
beatsreadonly | Float32Array | Detected kick onsets in seconds, ascending. These are the hits the analyser is sure about — deliberately not every beat in the track. |
strengthreadonly | Float32Array | 0–1 per detected beat, for weighting cuts and flashes. |
bpmreadonly | number | |
bpmConfidencereadonly | number | 0–1. Low means the hits are real but irregular — a rubato passage. |
energyreadonly | Float32Array | Coarse loudness envelope, for finding drops and quiet passages. |
energyHzreadonly | number | |
durationSecreadonly | number |