Digital Orbits: Phase Accumulation in Polyrhythmic Space
Picture yourself in the cockpit, tracing endless figure-eights above Toronto Pearson while three different polyrhythms pulse through your headphones—a 7/4 groove against 5/4 time signatures, all cycling through a 3/2 ambient loop. Each rhythm needs its own orbital period, yet they’re all flying through the same sonic airspace. This is exactly the problem that phase accumulation solved for digital synthesizers in the 1980s.
Phase accumulation works like a mathematical odometer. Instead of tracking distance, it tracks position within a cycle—where 0 represents the beginning and 1.0 represents completion. Each tick advances the phase by a frequency-dependent step size, wrapping back to zero when it exceeds unity.
class PolyrhythmGenerator {
constructor(sampleRate = 44100) {
this.phases = [0, 0, 0];
this.frequencies = [0.5, 0.7, 1.5]; // Different rhythm rates
this.sampleRate = sampleRate;
}
nextSample() {
return this.phases.map((phase, i) => {
this.phases[i] += this.frequencies[i] / this.sampleRate;
if (this.phases[i] >= 1.0) this.phases[i] -= 1.0;
return Math.sin(2 * Math.PI * phase); // Convert to audio
});
}
}
Erlang’s actor model provides a different perspective—each rhythm becomes its own process, accumulating phase independently while the conductor coordinates their outputs:
start_polyrhythm(Frequencies) ->
[spawn_link(?MODULE, rhythm_loop, [F, 0.0]) || F <- Frequencies].
rhythm_loop(Frequency, Phase) ->
receive
{tick, From} ->
NewPhase = case Phase + Frequency of
P when P >= 1.0 -> P - 1.0;
P -> P
end,
From ! {phase, NewPhase},
rhythm_loop(Frequency, NewPhase)
end.
The beauty lies in the simplicity: no matter how complex your polyrhythmic holding pattern becomes, each voice just needs to know its own frequency and current position. When a 7-beat pattern completes its cycle while a 5-beat pattern is only 5/7ths through, the phases automatically realign at their least common multiple—exactly like flight paths that eventually converge.
This accumulator pattern powers everything from FM synthesis to GPS navigation algorithms. Whether you’re generating polyrhythmic loops or calculating orbital mechanics, the fundamental insight remains: complex periodic behaviours emerge from simple, independent counters marching through their designated cycles.