Keeping Time · Part 3 of 7
Three Sounds in Every Tick
Hold a mechanical watch to your ear and you hear a tick. Record it with a contact microphone and slow it down, and every tick turns out to be three. They are the three things the last article described happening while the lever is in contact, and since the model already knows when each of them happens, Tick Again places each sound at that moment rather than playing a recording of a tick on a timer.
Unlock, impulse, drop
The first sound is the unlock: the jewel on the balance’s roller strikes the fork, and the pallet slides off the locking face of the escape tooth that was holding the train. The second is the impulse: the freed tooth pushes across the pallet’s sloped face, which is what gives the balance its push. The third is the drop: the escape wheel, now released, falls the small distance onto the other pallet and locks. Unlock as the window opens, impulse at the rest point, drop as it closes.
let t = Double(k) / bps + (k % 2 != 0 ? beatError / 1000 : 0)
let parts: [(Double, Sound.Kind)] = [(-w, .unlock), (0, .impulse), (w, .drop)]Here w is the half window from the last article, so for C1 at full swing the three sounds land at minus 6.14, zero and plus 6.14 milliseconds from the beat. The line above adds one more thing: every odd beat, every tock, can come a little late. That delay is the beat error, a watch whose balance does not rest exactly on the lever’s centre line, and it is stored in milliseconds because that is how a watchmaker reads it.
Ringing, not samples
Each of the three is a small piece of steel or ruby striking another, and what you hear is the parts ringing afterwards. So the sound of each is built the same way: as a handful of resonant modes, each with a frequency, a ring time over which it dies away by 60 decibels, and a gain. The impulse, for example, rings at 3,300, 5,100, 7,400 and 1,750 hertz, the longest of them for 20 milliseconds. Each mode is a two-pole resonator whose pole radius is chosen so it decays over exactly its ring time:
for m in modes {
// A pole radius that falls 60 dB over the mode's ring time.
let r = pow(0.001, 1 / (m.ring * sampleRate))
a1.append(2 * r * cos(2 * .pi * m.frequency / sampleRate))
a2.append(-r * r)
// Normalized so that a unit impulse rings at about the mode's gain.
gain.append(m.gain * sin(2 * .pi * m.frequency / sampleRate))
}What strikes the resonators is not a perfect impulse but a six-sample burst of decaying noise, because a real strike never is one. The modes themselves are marked in the source for review against recordings. They are a stand-in: the plan is to record each sound from a real movement with a contact microphone, and a recording dropped into the app’s sounds folder under a voice’s name replaces the synthesized one with no code change. The timing, which is the part the model actually knows, stays the same either way.
Before you read on
Of the three, which is loudest?
The impulse. It is the one moment real force passes between the train and the balance, the push that keeps it swinging. The bench mixes the unlock at 0.45, the impulse at 1 and the drop at 0.75, and a test checks that the synthesized impulse really is louder than the unlock.
On time to the sample
A tick is a few milliseconds long. A screen refreshes every 8 or 16, so a sound started from the drawing code would land up to a frame late, and differently late each time; at five beats a second the ear would hear the jitter at once. So the audio runs on its own clock. A single AVAudioSourceNode renders the ticking, and each time the system asks it for a buffer it works out from the audio timestamp which sounds fall inside that buffer and starts each one at the exact sample. The bench publishes the watch’s state once a frame (its running time, its pace, its amplitude, its beat error) and the audio thread places the ticks from that.
Two other things come through that path. Loudness follows the swing: a watch running down at half its amplitude ticks more quietly, as a real one does. So does the spacing: a short swing takes longer through the lift, and the three sounds of each tick spread apart with it. And a watch in a shut case sounds like one. With the movement cased and the back closed, the mix passes through a one-pole low-pass filter that at 48 kilohertz rolls off above about one and a half kilohertz, which dulls exactly the high metallic ring that makes an open movement sound so bright.
What the tests hold
- Every voice rings, and every voice dies: its last ten milliseconds are a hundredth as loud as its start.
- The impulse is louder than the unlock, and the case snapping shut is still ringing, fifty milliseconds in, ten times louder than a drop.
- Two seconds of C1 ticking with a beat error of two milliseconds, mixed as the bench mixes it, has its loudest peaks a fifth of a second apart within four milliseconds. The test also writes the result out as a WAV file, so the sound can be checked by ear as well as by number.
Those peaks, and when each one comes against a perfect clock, are exactly what a watchmaker’s timegrapher listens to. That is the next article.