Before I Read the Weather I Heard It Hum

METAR Chord Briefings
🎮 Play: Gust and Chord

Yesterday’s mapping was wrong. Not wrong in the “crashed the ESP32” sense — wrong in the sense that clear weather sounded like a dial tone and deteriorating ceilings produced the most interesting music I’ve heard in months.

This is a technical problem, and technical problems have solutions.

The Data Structure Nobody Tells You About

A METAR string looks like noise until you understand it’s positional. No delimiters, no JSON, just fixed-width fields in a specific order:

CYEG 141900Z 31015G22KT 15SM FEW040 BKN120 M04/M12 A3021

Breaking it down:

  • CYEG — station identifier (Edmonton International)
  • 141900Z — day 14, 1900 UTC (Zulu time)
  • 31015G22KT — wind from 310°, 15 knots gusting 22
  • 15SM — visibility 15 statute miles
  • FEW040 BKN120 — few clouds at 4,000ft, broken at 12,000ft
  • M04/M12 — temperature -4°C, dewpoint -12°C (M = minus)
  • A3021 — altimeter 30.21 inHg

The Aviation Weather Center serves this raw at aviationweather.gov/api/data/metar?ids=CYEG&format=raw. No API key. Updates within five minutes of observation. The government literally gives it away.

The Mapping That Actually Works

Yesterday I mapped ceiling height linearly to pitch. Higher ceiling, higher notes. The problem: VFR days (ceiling above 3,000ft) all sounded identical. The synth couldn’t distinguish between “excellent flying weather” and “merely good flying weather” because pilots don’t think that way either.

What pilots actually care about are categories:

CategoryCeilingVisibilityColour
VFR> 3,000ft> 5 SMGreen
MVFR1,000–3,000ft3–5 SMBlue
IFR500–1,000ft1–3 SMRed
LIFR< 500ft< 1 SMMagenta

These thresholds matter because they determine what kind of flight you can file. The transitions between them matter most — and that’s where the chord should change.

New mapping:

VFR   → C major (stable, resolved)
MVFR  → C major 7 (pretty but watch it)
IFR   → D minor 7 (tension, get your instrument rating)
LIFR  → D diminished (don't fly)

Wind direction picks the voicing. Divide 360° into four quadrants: north = root position, east = first inversion, south = second inversion, west = third inversion. Gusts add extensions — a gust spread over 10 knots adds a 9th, over 15 adds an 11th.

The ESP32 polls every sixty seconds for routine METARs, but the real events are SPECIs — special reports issued whenever conditions cross a threshold. A SPECI hitting the endpoint means something changed. The chord should respond.

What I Got Wrong

My generative soundscape work taught me that natural systems cluster. Rain intensity follows curves. Wind gusts bunch together. Random isn’t natural; constrained probability is.

But yesterday I treated METAR data as continuous. Wind speed from 0 to 50 mapped to volume from 0 to 100. The result: every reading sounded slightly different from the last, with no sense of change. The ear stopped noticing.

Today I quantized. Wind speed buckets: calm (< 5kt), light (5–10kt), moderate (10–20kt), strong (> 20kt). Each bucket maps to a distinct articulation pattern. Calm gets slow whole notes. Strong gets staccato eighths. The transitions between buckets are audible events.

The synth running on my desk right now has been droning a gentle C major for the past three hours. CYEG is reporting clear skies, light winds, visibility unlimited. Perfect flying weather. Boring music.

But I’m not frustrated anymore. The drone means something. It means the sky is quiet. It means I could be at the airport right now instead of debugging audio code.

At 14:23 the ceiling was forecast to drop to 2,400 broken. If that SPECI hits, the chord will shift to C major 7 before I read the report. That’s the test — can I learn to hear the weather before I see it?

The synth hums. I wait for something to change.