Show HN: Beatsync – perfect audio sync across multiple devices (github.com)
Hi HN! I made Beatsync, an open-source browser-based audio player that syncs audio with millisecond-level accuracy across many devices.
Try it live right now: https://www.beatsync.gg/
The idea is that with no additional hardware, you can turn any group of devices into a full surround sound system. MacBook speakers are particularly good.
Inspired by Network Time Protocol (NTP), I do clock synchronization over websockets and use the Web Audio API to keep audio latency under a few ms.
You can also drag devices around a virtual grid to simulate spatial audio — it changes the volume of each device depending on its distance to a virtual listening source!
I've been working on this project for the past couple of weeks. Would love to hear your thoughts and ideas!
134 comments
[ 4.2 ms ] story [ 138 ms ] threadFirst, I do clock synchronization with a central server so that all clients can agree on a time reference.
Then, instead of directly manipulating the hardware audio ring buffers (which browsers don't allow), I use the Web Audio API's scheduling system to play audio in the future at a specific start time, on all devices.
So a central server relays messages from clients, telling them when to start and which sample position in the buffer to start from.
https://www.w3.org/community/webtiming/
https://github.com/webtiming/timingobject
* open if you pay membership dues to the AES or buy the spec
I'm super jazzed seeing AES67 emerge.. although it not working great over wifi for lack of proper timing info hurts. Very understandable for professional gear, but there's nothing I love more than seeing professional, prosumer and consumer gear blend together!
PipeWire already has pretty decent support! There's a tracker where people report on with their hardware experiences trying it. Some really really interesting hardware shows up here (and elsewhere on the gitlab): https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/32...
they're doing a smarter thing by doing streaming. i don't do any streaming right now.
the upside is that beatsync works in the browser. just a link means no setup is required.
There are a ton of directions I can think about you taking it in.
The household application: this one is already pretty directly applicable. Have a bunch of wireless speakers and you should be able to make it sound really good from anywhere, yes? You would probably want support for static configurations, and there's a good chance each client isn't going to be able to run the full suite, but the server can probably still figure out what to send to each client based on timing data.
Relatedly, it would be nice to have a sense of "facing" for the point on the virtual grid and adjust 5.1 channels accordingly, automatically (especially left/right). [Oh, maybe this is already implicit in the grid - "up" is "forward"?]
The party application: this would be a cool trick that would take a lot more work. What if each device could locate itself in actual space automatically and figure out its sync accordingly as it moved? This might not be possible purely with software - especially with just the browser's access to sensors related to high-accuracy location based on, for example, wi-fi sources. However, it would be utterly magical to be able to install an app, join a host, and let your phone join a mob of other phones as individual speakers in everyone's pockets at a party and have positional audio "just work." The "wow" factor would be off the charts.
On a related note, it could be interesting to add a "jukebox" front-end - some way for clients to submit and negotiate tracks for the play queue.
Another idea - account for copper and optical cabling. The latency issue isn't restricted to the clocks that you can see. Adjusting audio timing for long audio cable runs matters a lot in large areas (say, a stadium or performance hall) but it can still matter in house-sized settings, too, depending on how speakers are wired. For a laptop speaker, there's no practical offset between the clock's time and the time as which sound plays, but if the audio output is connected to a cable run, it would be nice - and probably not very hard - to add some static timing offset for the physical layer associated with a particular output (or even channel). It might even be worth it to be able to calculate it for the user. (This speaker is 300 feet away from its output through X meters of copper; figure out my additional latency offset for me.)
An OSS app with the ability to sync everyone up over mobile or wifi, on Android or iOS with BYO headphones, would be incredible. This should be a thing :)
I've never seen in action and don't know how it works, but at least for the audio part it should be able to synchronize the phone with the cinema screen.
If I'm not mistaken, it's provided by this company: https://www.twavox.com/en/
I'm self hosting a web radio for my LAN at home. I set it up years ago, I'm not there so I can't check the details but I think it is: Icecast2 on an ARM small server with DeeFuzzer (sp?) to send my mp3s to the Icecast2 server. MPV or VLC to play music on my Linux laptop and Transistor from F-Droid (I believe)
0.3 microseconds. The period of a wave at 20kHz (very roughly the highest pitch we can hear) is 50 microseconds. So - more or less insignificant.
Cable latency is basically never an issue for audio. Latency due to speed of sound in air is what you see techs at stadiums and performance halls tuning.
To put things into proper units: speed of light in vacuum is approx 1.8 terafurlongs per fortnight, and electricity in wires has a pace of similar magnitude, and sound in normal atmospheric conditions shuffles along at approx 2.1 megafurlongs per fortnight.
Well, but its also just wrong. Its 12.5% to low. Thats why "about one foot" sounded absolutely wrong to me.
Do you suppose there exists some other reason for that, like maybe matching impedance on each cable, or is this likely one of those superstitions that audiophiles fall prey to?
The instant you start having wireless speakers (eg. bluetooth) or any sort of significant delay between commanding playback and the actual sound coming out, the latency becomes audible.
If you support mic input, you can allow the user to select a device as the "nexus" with mic recording on. Then you tell each device in your setup to "chirp" at the same exact time, but at different frequencies. Then you can derive the individual device's "local delay" and compensate.
This allows you to tune the surround setup to full accuracy for a given point in space, and it will take care of ring buffer differences, wireless transfers of non-teathered speakers, etc.
Someone brought up the idea of an internet radio, which I thought was cool. If you could see a list of all the rooms people are in and tune it to exactly what they're jamming to.
How can you guarantee that? NTP fails to guarantee that all clocks are synced inside a datacenter, let alone across an ocean (Did not read the code yet)
EDIT: The wording got me. "Guarantee" & "Perfect" in the post title, and "Millisecond-accurate synchronization" in the README. Cool project!
Going off on a tangent: Back in the days of Live Aid, they tried doing a transatlantic duet. Turns out it’s literally physically impossible because if A songs when they hear B, then B hears A at least 38ms too late, which is too much for the human body to handle and still make music.
That's assuming standard OS and hardware and drivers can manage latency with that degree of precision, which I have serious doubts about.
In a duet, your partner needs to hear you now and you need to hear them now. With pre-recorded audio, you can buffer into the future.
If you _don’t_ have real time communication, then you don’t really need to solve this problem. But the problem is fundamentally unsolvable because the speed of light (in a vacuum) is the speed of causality and, as I say, puts a hard cap on simultaneity. This tends to be regarded as obvious at interstellar distances but it affects us at transatlantic distances too.
Also latency demands on conversation are not nearly as tight as those on music performance. See ubiquitous video conferences.
Special relativity does indeed have something to say about simultaneity.
> Wolfram Alpha reckons New York to London is 19ms in a vacuum, more using fibre.
And this is not, in any respect, a limit on simultaneity. If the endpoints are moving at very very very quickly relative to each other, then there are complications. Otherwise you measure that 19ms or so and deal with it.
Do you have any interesting insight into that question?
But also, I don't really have an intuition for why the speed of travel is relevant here?
It's funny that I have a natural intuition that sound is slow over long distances, yet 1 ft/s still feels astonishingly slow. And yet while I know light travels 1ft/ns, it's still astonishing that it takes 30ms to travel from London to Sydney at that speed.
What I mean is that if you have multiple speakers around you, if any one is 1 foot closer or further than another, it'll be off by a millisecond already. Given that most people probably aren't going to have sub-foot positioning accuracy, sub-millisecond timing accuracy isn't critically important.
Most of the time, I think my synchronization algorithm is actually sub-1ms, but it can be worse depending on unstable network conditions.
However, it very much depends on what your expectations are, and how critical your listening is. If no one is looking for problems, it can be made to work well enough.
Last I heard safari was buggy and behind on web audio - did you run into any issues there?
Once that changes (at the very least, the macOS part), I can't wait to play with it!
Not a huge deal, but if I start playing from my Pixel 4, it staggers the startup between devices (either pixel is faster or vice versa).
If this starts working with spotify somehow, I'll be set for my weekends coding around the house!
Just to share a couple of similar/related projects in case useful for reference:
http://strobe.audio multi-room audio in Elixir
https://www.panaudia.com multi-user spatial audio mixing in Rust