Visualizations
039 / 500

039 · Retro

Modem Handshake

The dial-up screech, modulated and decoded live: DTMF, FSK and 16-QAM.

Two simulated modems share one telephone line sampled at 9600 Hz: dial tone, DTMF digits, ringback, the 2100 Hz answer tone with its phase reversals, V.21 FSK capability menus at 300 baud, QPSK training and finally V.22bis-style 16-QAM at 600 baud on two carriers at once (1200 Hz for the caller, 2400 Hz for the answerer). Everything shown is decoded from that one signal: Goertzel filters find the digits, quadrature discriminators and a UART state machine turn FSK back into text, and each QAM receiver mixes down, applies a root raised cosine matched filter, tracks the drifting carrier with a decision-directed phase-locked loop and an AGC, undoes the differential quadrant code and the self-synchronizing scrambler, and reframes the bytes. The spectrogram shows the screech is structured data, and the IQ plot shows each symbol landing on the constellation. Add noise and the clusters smear, the bit error rate climbs and the far end echoes back garbled text.

Try it. Type to transmit (each key is sent as it is typed, Enter ends a line and the BBS answers), and the far end echoes what it decoded. Drag up or down on the IQ plot, use the arrow keys or the NOISE buttons to change the line noise, click 1200 or 2400 (or press left and right) to switch which carrier the big plot shows, and press Escape to hang up and redial. Click once for sound.

  • DTMF and Goertzel filters
  • FSK demodulation
  • 16-QAM with RRC matched filter
  • Decision-directed PLL
  • Self-synchronizing scrambler
  • Spectrogram (FFT)

View the source · one module, plus a small shared runtime for sizing, the animation loop and input

Build your own

Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.

Build a dial-up modem line monitor with JavaScript, the HTML canvas element and the Web Audio API. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.

Start simple:
- Generate a telephone line signal yourself, one sample at a time at 9600 samples per second, in a ring buffer. Advance it by the elapsed time every animation frame.
- Script a short call: half a second of dial tone (350 Hz plus 440 Hz), then the digits of a phone number as DTMF tone pairs (row frequencies 697, 770, 852, 941 Hz; column frequencies 1209, 1336, 1477 Hz), 100 ms each with short gaps, then a 2100 Hz answer tone.
- Draw a scrolling spectrogram: every 160 samples, take a Hann-windowed 512-point FFT (write the FFT yourself), convert the bins up to 4 kHz to decibels and paint one column of an offscreen canvas, then draw it scaled up so time scrolls left.
- Decode the digits back out of the signal with the Goertzel algorithm on the eight DTMF frequencies, and print them in a green terminal font as they are recognized.

Once that works, make it beautiful and make it talk:
- Add a QPSK or 16-QAM data phase: map bits to constellation points, shape them with a raised cosine pulse and modulate a 1800 Hz carrier. In the receiver, mix back down, low-pass filter, sample once per symbol and plot the points on an IQ scatter with fading phosphor trails.
- Add a noise slider (Gaussian noise) and watch the constellation clusters smear as the signal-to-noise ratio drops.
- Style it like a beige 1980s terminal: green phosphor, scanlines, a vignette and a row of red modem status lights.
- Play the line through a ScriptProcessor or AudioWorklet after the first click, never before.

Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as FSK text with start and stop bits, a phase-locked loop to recover a drifting carrier, or a scrambler and bit error counter.
PreviousChecker ShadowSquares A and B are the exact same gray. Move the light and the shadow keeps lying. NextBandit CasinoEpsilon-greedy, UCB1 and Thompson sampling race to find the best slot machine.

Related visualizations

  • Modular SynthSound A eurorack case with a working signal graph and patch cables that sag and swing.
  • FM SynthesisSound A four-operator FM synth whose sidebands land exactly where Bessel functions say.
  • Oscilloscope MusicRetro A phosphor XY scope draws a 4D tesseract, knots and text from the stereo sound you hear.
  • CRT MonitorRetro An emulated electron beam, decaying phosphors and a shadow mask, under a 7x loupe.
  • MoireIllusions Two sheets of fine lines beat into giant ghosts, and hide a secret message.
  • Perceptual CodecSound Watch a psychoacoustic model decide which parts of the music you will never miss.
  • Dither LabRetro Seven dithering algorithms race on a moving scene in 1-bit, handheld green, CGA and EGA.
  • TeletextRetro A working teletext decoder: mosaic graphics, carousel pages and hidden answers.
  • DatamoshRetro A real motion-compensated codec, fed a broken stream until the video melts.

Use ← and → to move between demos. While the canvas has focus, keys go to the demo instead.

← More from Emergent Mind Labs