LISNR · 2018–2024
Data over sound, from embedded C++ to the browser
LISNR transmits data as inaudible high-frequency audio. I built the portable C++ SDK that ran it on payment terminals and conference hardware, the low-latency audio stacks on iOS and Android, and then the WebAssembly port that brought the whole thing to a browser tab.
- Role
- Embedded Engineer → Lead Software Engineer → Technical Advisor
- Stack
- Ultrasonic audio running in a browser with no plugin or install
- WebAssembly binary reduced by 20% while adding capability
- SDK ported to third-party hardware including payment terminals and conference systems
The problem
Sending data as sound sounds simple until you try it. The signal has to survive real rooms — reflections, background noise, cheap speakers, microphones with wildly different frequency responses — and it has to do so at frequencies people cannot hear, which is exactly where consumer audio hardware is least predictable.
Then it has to run everywhere: embedded terminals, phones, and eventually browsers.
Embedded and mobile
I built the high-frequency audio SDK in C++11, designed for portability from the start, and ported it onto third-party hardware including Equinox payment terminals and the Bose Videobar.
On phones, the work was latency. Audio stacks on iOS and Android have different buffer models, different threading rules and different ideas about when to hand you samples, and getting under the latency budget on both meant treating each platform on its own terms rather than averaging them. I was the platform SME for those optimisations.
I also designed a peer-to-peer payment protocol over high-frequency audio, including the signal training sequences that make a transaction work offline — no network on either device, which is the point.
Testing was automated end to end with XCTest and gtest, because a signal-processing regression is invisible until someone’s payment fails.
Then: the browser
The harder and more interesting piece was getting it into a browser tab with no plugin and no install.
That meant WebAssembly, and it meant rebuilding the audio stack against the Web Audio API so that browser behaviour matched what the native iOS and Android SDKs already did — because the product promise is that it works, not that it works differently per platform.
Binary size matters a great deal when the thing has to download before a user will wait for it. I cut the WebAssembly binary by 20% while the capability was still growing.
I also built React Native wrappers over the iOS and Android libraries so product teams could ship cross-platform without waiting on native work, containerised the CI/CD pipelines with Docker and GitLab CI, and led the engineering team through SCRUM for two years before moving to an advisory role.