Audio · interface

BeatMap

Offline rhythm analysis: where the kicks are in a whole track.

Explained in Your first game.

interface BeatMap
import 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:

  1. 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".
  2. 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.
  3. 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

NameTypeDescription
beatsreadonlyFloat32ArrayDetected kick onsets in seconds, ascending. These are the hits the analyser is sure about — deliberately not every beat in the track.
strengthreadonlyFloat32Array0–1 per detected beat, for weighting cuts and flashes.
bpmreadonlynumber
bpmConfidencereadonlynumber0–1. Low means the hits are real but irregular — a rubato passage.
energyreadonlyFloat32ArrayCoarse loudness envelope, for finding drops and quiet passages.
energyHzreadonlynumber
durationSecreadonlynumber