snowday

Blog

Scratching with a spring, and landing on the beat

How tapespin works · October 13, 2026 · 5 min read

Drag the record and the audio follows your hand, forwards and backwards. Let go and it spins back up and lands on the beat. This essay is about how a hand on a screen becomes tape speed, and how the return is arranged so the track comes back in step.

The hand is a position, not a speed

When you touch the record, the engine notes where the read head is. From then on the editor tells the engine where your hand is relative to the grab, in samples of tape. One turn of the record is one bar of the song when the host gives a tempo, so half a turn back is half a bar of audio back.

The engine does not move the read head to that position directly. The hand position arrives at screen rate, in steps, and jumping from step to step would make every step audible. Instead the head is pulled toward the hand by a spring:

speed += w*w * (target - position) - 2*w * speed

with w set for a twelve-millisecond spring. The first term pulls toward the hand. The second is damping, set to exactly the critical value: the fastest return that never overshoots. Back and forth returns to the same spot. The tests move a hand in ten-millisecond steps and check that speed changes by less than two thousandths per sample, and that a grab from full speed stops the reel over about ten milliseconds, not instantly.

Speed is what the spring produces, and speed is pitch. Pull backwards and the speed goes negative. Scratch speed is capped at six times normal. Hold still and the reel stops under your hand and the output fades to silence.

Reading backwards

Negative speed means the read head walks backwards through the ring buffer, playing the last twenty seconds of the track in reverse. There are two walls: the head cannot pass the write head, because that audio has not arrived yet, so pushed up against live it can only follow live at normal speed; and it cannot go back past the oldest audio in the ring, where it stalls.

Letting go is a release

When the hand leaves the record, the engine does not treat it as a special case. It is a release, the same call a tape stop uses when you let go of a hold, starting from whatever speed the hand left the reel at. From a backwards fling, the speed rises through zero and on up to normal in one motion. The tests fling the record backwards, let go, and check that the speed rises without a dip and with no step at the release.

One difference from a hold. A parked, silent reel restarts on live audio. A hand that lets go restarts from where it left the tape: what you were scratching, spun up.

Landing on the beat

A spin-up ends with a cut to the live track. Where that cut falls is a choice, and Snap makes it. While the song plays, the engine picks the grid line nearest to now plus the wanted spin-up length and resizes the ramp to end exactly there. Released at beat 3.1 with a 0.8-beat spin-up on a quarter-note grid, the nearest line to 3.9 is beat 4, so the ramp runs 0.9 beats. A line closer than half the wanted length is skipped, so a late release cannot turn into a near-instant jump: released at 3.7, the ramp runs to beat 5 instead. Snap runs from a sixteenth to a bar, and starts out on the quarter.

The cut is timed to finish, not start, on the line. The crossfade to live begins fifteen milliseconds early, so live audio is fully in on the grid line and not before.

That puts the live side of the cut on the beat. A second option, Lock, lines up the tape side too. With Auto off and a Bezier or Platter ramp, Lock asks that the tape end a whole number of grid units (a sixteenth to a quarter note) behind live at the moment of the cut. From a parked stop the engine simulates the coming spin-up to find how much lag it will build, then parks the tape just short enough of a whole unit behind live that the ramp delivers it to one. From a moving tape, with a Bezier ramp, it adjusts the Ease out handle instead.

Why bother? The cut joins two copies of the same music: the slowed tape, behind, and the live track. If they are a whole number of beats or subdivisions apart, their beats line up across the join. The sound changes, but the pulse does not stumble. Lock is off by default and does nothing with Auto on.

The quiet part

A stopped head holds one sample value. On its own that is a constant offset in the output, DC, and when the head moves again the offset would break off into a click. So the output gain follows speed, fading out below six percent of normal and in above it. A held scratch is silent; a stop is silent. The tests run a click detector over every scenario, looking for any jump larger than a sine at twice normal speed could make, and expect none.

Written from the engine source, tapespin 0.1.0.