📖 What Pearson does

Chapter 13 builds circuits that lock the frequency of one oscillator to a multiple or fraction of another. The big chip is the 4046 PLL (phase-locked loop). Sub-projects:

  • The 4046 VCO. A voltage-controlled oscillator.
  • Portamento, glide, and glissando. Slowly sliding between two pitches.
  • VCO switching. Switching between multiple VCOs.
  • Sample and hold. Freezing a changing control voltage to a constant.
  • LFO multiplication. Using a PLL to make a slow LFO.
  • Audio-frequency multiplication. Using a PLL to make a fast oscillator.

🎓 Background: PLLs in software

PLLs are analog circuits that lock an oscillator’s phase to a reference signal. They are how analog synths tune their oscillators to other instruments or to a master clock. In software, a PLL is just a frequency-locked loop — a control algorithm that adjusts an oscillator’s frequency until its phase matches a reference.

Our firmware does not implement PLLs explicitly. The closest analog is the jam-sync feature (F-031): when sync-in is enabled, the sequencer advances on each incoming sync pulse, which keeps it phase-locked to the master device. There is no “fractional” sync — one pulse is one step. Pearson’s PLL multipliers and dividers are not implemented.

Portamento (smoothly sliding between two pitches) is approximated by AMY’s slew_time field, which can be set on a per-event basis. We have not wired this to a UART verb.

🔧 Try it on the device

Exercise 1: jam-sync as a simple PLL.

If you have another PO-33 (real or otherwise) running, connect a cable from its sync OUT to our device’s sync IN. Long-press FX for 2 seconds to enable sync-in listening:

> sync_in_toggle

Now when you press play on our device, it will wait for sync pulses from the master. Each pulse advances one step. That is a PLL with multiplier 1.

Exercise 2: pitch glide via FX.

The PO-33 has a punch-in effect called PORTAMENTO (when fully implemented). Set it:

> fx PORTAMENTO
> note 9 60
> note 9 72

The note should slide from C4 to C5 rather than jumping. (As of v0.6, the PORTAMENTO case in apply_fx() is a no-op.)

🛠 Code reference

  • Sync-in listener — main/system/sync.c. sync_in_task(). Blocked on a semaphore; wakes per pulse; calls sequencer_tick().
  • Sync-in toggle — main/ui/input.c, end-of-drain polling block. Long-press FX for 2 seconds toggles sequencer_set_sync_in_active().

🚫 What we can’t simulate

  • The 4046 PLL chip. No analog here. PLL math in software is trivial (an integer-N counter), but the analog version has subtle behaviour (lock range, capture range, hold range) that no digital emulator captures without effort.
  • VCO switching. No equivalent.
  • Sample and hold. Could be done in software but is not.