Skip to content

02 · Visualising the warp

The integral t(β)=0β60/BPM(b)db is the whole subject. Drawing both sides of it side by side makes the equality literal:

  • Left chart: 60/BPM(b) — seconds per beat. The shaded region from 0 to the cursor is the area under the integrand on that interval.
  • Right chart: t(β) — the warp map itself. The y-value at the cursor IS that shaded area.

Move the cursor and watch both numbers — beatsToSeconds(β) and the trapezoidal area under 60/BPM — track each other to numerical-noise tolerance for the closed-form regimes and exactly for the curved one (where they share the same quadrature).

Open the full-screen standalone demo ↗

What to notice

  • In constant mode the left chart is a flat line; the shaded rectangle is literally β(60/K).
  • In piecewise mode the left chart is a step function; the shaded "area so far" is the running sum of completed rectangles plus a partial one. Drag the orange dots in the right chart to call pin() and watch downstream beats shift in time while pinned beats stay fixed (a drag that would make time non-monotonic is rejected and snaps back).
  • In linear ramp mode the left chart bends — 60/BPM is a reciprocal-of-line, not a line — and the right chart's logarithmic shape is visible directly.
  • In curved mode there is no formula; the right chart is the trapezoidal sum evaluated at every β.

warp-marker.js

"What does it mean to pin a sample to a beat?"

A warp marker is a single fact: "the audio at THIS second is musically THAT beat." Written as { beat, second }. Pinning = asserting one such fact and letting the segments on either side rescale to keep the assertion true.

Crucially, pinning a marker does NOT set a tempo. It sets a (beat, second) point on the warp map. Tempo is whatever slope the neighbouring markers now imply -- so moving ONE marker changes the derived tempo of the TWO segments touching it, and (because the map is cumulative) shifts every beat after it in absolute seconds. Pinning is local; drift is global.