Cyrinx: data over sound, measured
Your laptop already has a speaker. Your phone already has a microphone. Cyrinx uses exactly those, and nothing else, to move real data between the two through the air as sound. No Bluetooth, no Wi-Fi, no pairing, no network. You set the phone down next to the laptop, the laptop plays something that sounds like a burst of static, and bytes come out the other side.
It’s now open source under Apache-2.0, with a home at cyrinx.org and the code at github.com/dweekly/cyrinx.
What’s actually new here, and what isn’t
Data over sound is not a new idea, and I want to be upfront about that. Dial-up modems did it over a wire for decades. Projects like minimodem, ggwave, Quiet, Chirp, and Google’s Nearby Messages have all sent data acoustically, and the underlying signal-processing pieces Cyrinx leans on (OFDM, cyclic prefixes, pilot tracking, QAM, Viterbi error correction, CRC block checks) are textbook radio techniques borrowed for the audio band.
So the contribution isn’t the concept. It’s the measurement. Cyrinx is a careful, reproducible answer to a narrow question: with two ordinary consumer devices sitting a foot or two apart, how much real, verified throughput can you actually get through the air as sound, and where exactly does the physics stop you? Most of the work went into the diagnostic methodology and a catalog of the specific physical-layer defects that show up on real laptop and phone transducers, so the next person doesn’t have to rediscover them the expensive way.
The numbers
Every figure below is ordered, byte-verified goodput. A block only counts if it passes CRC and is byte-identical to what was transmitted, at the same position in the stream. Preambles, pilots, error-correction overhead, and inter-frame gaps all count against the total. The transmitting machine in every row is an M4 MacBook Pro.
| Link | Goodput | Decoded by |
|---|---|---|
| MacBook to Pixel 7a | 36.6 kbps | on-device Kotlin |
| MacBook to Pixel 7a | 39.3 kbps | the shipped C library itself |
| Pixel 7a to MacBook | 27.3 kbps | Python reference |
| MacBook to iPhone 17 Pro Max | 36.6 kbps | on-device Swift |
| iPhone to MacBook | 16.9 kbps | Python reference |
The asymmetry is real and worth noting: an iPhone speaker is band-limited to roughly 11 kHz of usable range, so it transmits a lot slower than it receives. These constants are also specific to this hardware. The gain-staging and geometry were tuned on my machine, and they have to be re-derived on any other Mac.
Graceful degradation matters more than the peak
The headline number is the fun part, but the part I’m actually proud of is what happens when conditions get bad. Move the phone into a reverberant spot in the keyboard well, or shadow it below the laptop, and a brittle modem just drops to zero. Cyrinx instead steps down: about 48 kbps in a clean placement, down to roughly 11 kbps when reflections get ugly, and all the way down to a floor measured in tens of bits per second in the worst shadowed positions. It gets slow, but it does not go silent. That floor comes from a two-microphone maximal-ratio combiner and a non-coherent multitone fallback, and there’s a golden-vector test where microphone zero alone fails to decode and the combiner still recovers the bytes exactly.
If you want the signal-processing story behind all of this, the 2x2 MIMO acoustic handshake post from May goes deep on the multipath, Doppler, and harmonic-distortion problems that make the audio channel so stubborn.
What ships
The core is portable C with a stable ABI, plus a Swift binding and a Kotlin decoder, all validated bit-for-bit against committed golden vectors so the Android, Apple, and reference paths stay in agreement. There’s a 25-page whitepaper in the repo that consolidates the channel measurements, the modem design, the defect catalog, and the negative findings (the dead ends, kept on purpose), and an arXiv version is on the way.
A fair warning: this is a research prototype, not a product. It works best at close range, the crypto envelope is experimental and unaudited, and plenty of the roadmap is still open. But the measurements are real and reproducible, and now the code is out there for anyone who wants to push it further.