synchronizing mp3 playback

Background

Once upon a time, we thought a killer app for hall parties would be an MP3 player synchronizer. We actually wrote one, as part of our p2p network, P4. It plugged into Winamp and synched its playback with other P4 users on the network. This allowed lots of computers to sync up and play the same songs, at the same time, as if they were tuned to the same radio station. It sounded like one giant stereo with lots and lots of speakers.

We had considered alternatives. First, we tried tuning lots of computers to the same streaming MP3 server. Unfortunately, they ended up out of sync due to buffering. Another low-tech alternative was to yell “Play!” and have everyone try to start an MP3 at the same time. We actually tried this, and quickly verified that it’s more or less impossible.

In the end, P4‘s syncher worked, but it was brittle and not at all easy to use. I tried again without P2P, and ended up with a solid synching engine, but couldn’t find a player with low enough plugin latency. When the sync plugin says “seek here!”, it needs to happen within 50ms or so, all the way from the player down through the sound card driver. Winamp can do this, but not iTunes, nor any *nix players we found.

Beyond that, our real world tests found that players have different playback rates. The differences are small; by the end of the average three minute song, two different players have only skewed by a few seconds at most. Still, the human ear can detect skew as low as a few dozen milliseconds, so to counteract this, all players need to re-sync often. This is doable, but if seeking a player results in a noticeable skip or other artifact, that’s a problem.

Still, if you’re interested, feel free to check out the source in the p4sync project on github. It comes with the sync engine, plugin framework, and working plugins for the *nix music players XMMS, Zinf, and MPD. Drop me a line if you have any questions!

Related Work

The “synchronizing audio over a network” question on Stack Overflow has a number of good links, including Tom Blank of Microsoft Research’s paper An Internet Protocol Sound System.

The NetSync Winamp plugin attempts to solve the synchronization problem too. However, it’s low-tech; it’s the network equivalent of shouting “Play!” and hoping everyone presses the button at the same time. Because of this, its sync quality is often in the mid to high hundreds of milliseconds, which is unacceptable.

The BASS Network Player, from K* Software, takes a different approach. It’s a self-contained MP3 player, with network synchronization built in. When I’ve managed to get it working, its sync quality seems to be better than NetSync’s. However, it can be very flaky and difficult to use.

Also, it’s not a plugin for your normal MP3 player. This is a noticeable drawback, since it lacks most of the features (usability, playlist management, plugins, different file formats, visualizations, etc.) that we’ve come to expect from MP3 players.

Slim Devices, best known for the Squeezebox, a dedicated set-top box MP3 player, recently released the software that powers it under the GPL. It’s called SlimServer, and one of its touted features is the ability to synchronize MP3 streams on multiple clients. It’s somewhat non-trivial to install, so I haven’t fully evaluated it yet…but it looks promising.

Finally, Media Player Puppeteer claims to synchronize iTunes over a network, and allows for remote control. On the plus side, it syncs playlists and songs fairly well. However, like the others, its sync quality is unacceptable. Even with only two computers, when we tested, we heard a noticeable echo. MPP also requires iTunes, Windows, and the .NET framework, which limits its target audience severely.

Challenges

Network latency. MP3 streaming technologies (such as ShoutCast) already exist. However, they assume that a central server will be broadcasting a stream of music to many computers that are geographically disparate. Its goal is to maintain an uninterrupted stream of music flowing to each computer. As a result, it pushes out music as fast as possible and stores the extra music in a buffer to ensure continutity. It assumes each user will experience latency (lag), so the buffer ensures that no user runs out of music to listening to. Unfortunately, this buffering almost guarantees that no two users listening to the same stream will be in sync.

Playback rate. The syncher used Winamp v.2.x as its mp3 player. By using Winamp’s API, we were able to determine that different computers play mp3’s at noticably different rates! This means, if you are able to start synchonized playback between two computers, they may well skew out of sync midway through the song, and you’ll hear a noticeable echo.

Player API latency. We also noticed that there was an occasional delay, as large as hundreds of milliseconds, between when we told Winamp to seek and when it actually seeked. Worse, this delay was highly variable. Needless to say, if our goal is accurate synchronization, this is deadly. We’re not sure if the delay was caused by Windows’ IPC, Winamp, or unavoidable hardware delays like the hard drive controller. We haven’t tested any other players to see if they experience similar delays.

Solution

The key insight is, synchronizing computers within milliseconds over a best-effort network is a hard problem. I doubt any of the p4sync developers is smart enough to solve it from scratch. Luckily, computer science researchers back in the ’80s figured out how to do it, and designed NTP. Since then, most people have piggybacked over NTP for their synchronization needs.

So, just like everyone else, we cheat and use NTP (actually SNTP) to solve the hard problem. Who am I to look a gift horse in the mouth?

Seriously, though, there’s only one trick to p4sync, and that is how it uses NTP. One host acts as the p4sync server. The other p4sync clients synchronize their system clocks to the server’s clock, using SNTP. When the server starts playing a song, it records the time, to the millisecond. The clients then retrieve that timestamp, calculate the difference between current time from that timestamp, and seek forward that far into the song.

It’s really all quite simple. No, really.

We use existing, tried-and-true technologies for everything except the music synching. We use libmsntp for synching system clocks. The server timestamp and the current song and playlist are sent over HTTP, using http-tiny and libwebserver. The MP3 players are existing players with large installed bases, initially Windows Media Player, Winamp, iTunes, and XMMS. So, most of the p4sync code is nothing more than glue.

Party Structure

Each party needs exactly one host. The rest of the computers are guests.

The host is the server. It is the authoritative source of the currently playing song, as well as determines the speed at which to play it.

Each guest is responsible for downloading the songs in the playlist of the party as well as playing back the songs. Guests ask the host which song to play, and when that song started playing.

The official time is determined by the host’s system clock, which guests sync to using SNTP. This means that any network lag will be compensated by knowing the true time. If a guest is playing a song too slowly, it can periodically skip ahead every now and then to re-sync.

Future plans

  • Investigate methods to guarantee that MP3s play back at a constant rate, regardless of player or host.

  • Distribute playlists and songs from the host to the guests.

  • Automatic host discovery, possible using Bonjour (formerly Rendezvous, aka ZeroConf).

History

p4sync used to be hosted at SourceForge. Snarfed has its own web space and subversion repository, though, so SourceForge ended up being redundant. We’ve closed the project there, but we definitely appreciated their hospitality. So long, SourceForge, and thanks for all the fish!

46 thoughts on “synchronizing mp3 playback

  1. Hi, I have been keeping tabs on this report. Thanks for the great info. I like vlc player for local multicast streaming, because my roomates use ibooks, and I use a self built pc. Of course it eventually falls out of sync in the hundreds of a second range as you describe. Pretty annoying. I look forward to more info on how to minimize this sync gap. Thanks! -bjorn

  2. Great work guys keepit up :) I will definatly be interested in a final version. will it be freeware???

    – DonkyBoY

  3. thanks! if and when we make an official release, it will definitely be free, both as in beer and as in freedom.

    development has slowed down some, though, since the plugin latency in the vast majority of players is too high. when a plugin says “seek here!”, it needs to actually happen, from the player down through the sound card driver, in under 100ms at a bare minimum. winamp can do this, but not itunes, nor any *nix players i’ve found. :/

    still, we might come back to it. until then, you’re welcome to try out the latest version! it come with the core sync library and experimental plugins for xmms, zinf, and mpd, available for most *nix platforms.

  4. I was excited to find this page, but worried when I noticed there was no posting date, and downright disappointed to hear that development has stalled. I have exactly the problem you describe: Two computers in disparate parts of the house, which I want to be able to play synchronized music from my own library or tune to an Internet radio station. I have a local Shoutcast server to feed a common stream, and my local network latency is low enough that via remote access, I can kick off playback on both machines nearly simultaneously. Unfortunately, drift is dramatic: One the order of 5 seconds an hour! Within five minutes, I can already hear a distinct echo.

    I’ll download it and check it out, but does your latest version make any attempt to keep two playback machines in sync, or does it only try to synch the initial start of playback?

    Thanks, Jim

    – Jim

  5. hi jim! absolutely, it continuously syncs the players, not just at the beginning. as i mentioned in the “playback rate” section, we noticed the skew that you noticed too, so we had to account for it.

  6. Any chance of an alpha yet, guys? I’m really interested in seeing this work. I’ve tried muxing with Shoutcast, running two instances of Winamp on the server (one to run shoutcast, the other to client) and simultaneously listening on a remote machine. It works to within 250ms I’d say if you stop and start the stream to reset both clients but it’s still noticeable.

    Thanks!

    – FSL

  7. sure! as i mentioned a few comments above, you’re welcome to try out what we have right now. it has the core sync library and plugins for xmms, zinf, and mpd, available for most *nix platforms.

    sadly, though, due to the IPC latency in most players, development is on hold indefinitely.

  8. Sorry to hear that development is on hold. This is a cool concept, and I’d love to see it working.

    One of my best memories from college was synching up gregorian chant over the network with my roomate, then playing Unreal Tournament. We’d fill the whole apartment with the sounds of chanting and headshots. I can’t remember what tool we used back then, but the echo was significant.

    Good times.

    Bob

  9. I’m no programer, but could you use some fuzzy logic to steer the timing back to perfect sync. Get it to play slightly faster or slower as needed instead of seeking a hundredth here or there. I.e. Client says oops, Im starting to get ahead of the server, better slow it down 4 notches, Oops now I’m starting to get behind better speed it up 2 notches, etc.

    Or, If you know what the ultimate deviation of the client and server was by the end of the track couldn’t you have the client learn the diffference and adjust the playback speed to suite. Then the more files you play the more accurate it becomes. You could create a log of playback rates for different bit rates etc.

    Also, I looked at your latest version, but I have no idea how to try this with say winamp, you might post a laymans guide to plugging it in and running it. FWIW, if you got it working in just one player many would be happy.

    – Humanzee

  10. I tooo agree if you can get it to work with just 1 player, like winamp you would make many many people happy, and I would pay for a working version of a winamp plugin that can do this

    Alex

  11. I tooo agree if you can get it to work with just 1 player, like winamp you would make many many people happy, and I would pay for a working version of a winamp plugin that can do this

    Alex

  12. It is good to see that someone picks up where others stop. As the author of NetSync I know how hard these problems are.

    I don’t work on NetSync anymore, and I’ve also learned on College about realtime computersystems. What NetSync, P4 or any other plugins are trying to accive is quite impossible if you don’t use a realtime OS in both ends. But you can get pretty near.

    If someone wants to redo the NetSync I would recommend to use UDP diagrams and continiously update the slaves with the current playback position and try to “sync it” as good as you can. It would be quicker than the orginal that uses TCP.

    Cheers,
    Lars Werner
    http://lars.werner.no

  13. I just learned about SpectrumLab, which is ham radio software with some incredible features. One is the ability to calibrate your soundcard’s sample rate clock, when fed a precise reference via the line-in jack. Some of their techniques might be relevant here.

    One more effect to consider is network latency, particularly over wireless. Don’t just send one packet and expect it to arrive immediately. Send a thousand, and take the one with the lowest apparent latency. (Since packets can’t travel back in time, that’s guaranteed to be the one that’s closest to reality.) If your round-trip times are consistently under a millisecond I guess it doesn’t matter, but most wireless networks clock in much higher, particularly if they’re running accelerator modes, which, ironically enough, improve throughput at the expense of latency.

    I’m fascinated by the existence of this software, and will download and play with it later. I’d love to sync several copies of Winamp around the house, and I’m not opposed to soldering hand-picked crystals into old SoundBlasters for each machine if that’s what it takes to minimize drift. ;)

  14. Hey guys I am happy to find you all. This is my situation: exact copies of music cds on two different hard drives in two different computers (the computers and hard drives are twins). I want to use one of the computers to play left channel stereo, the other right channel. Clearly there are timing issues, but no network latency issue. Nice to know that others have experimented with solutions that might be applicable.

  15. Like everyone else, im happy to find someone that has not just blown this off as impossible. Is this the only known project like this?

  16. Hello,

    I ended up doing the same thing you did with the clock sync…but…like you I found that the latency for winamp to start playing or seek is what ruined everything. Had accuracy down to 5 milliseconds at incredible worse between the comps, but, didn’t do any good cause of winamp.

    I think the best bet would be to make an audio output plugin where you could precisely control when a sample is played. Doing it this way, syncing could probably be done every 100 or so milliseconds if you wanted without noticing. Too bad you use c and I use delphi :-\

    Lol, as I’m typing this, I hear my amd computer running ahead of the two pentiums as it plays this synced mp3 with the software I made. wtf is up with that anyways?

    Good luck!
    brandon D0T irwin @gm ail dot com

  17. Awesome, this is the only live tread i can find on this topic.  My aim is to have kickass flat parties with synched up music playing from a terminal pc in every room, but I don’t want to install a separate audio network (with an amp at EVERY terminal would be so expensive) when we already have a LAN in. 

    A progress update would be cool, especially since this tread seems to be the last port of call for our problem :(

  18. Hey guys, this project sounds very good indeed!  In my searches i’ve found some hardware related stuff that can sync music, but what you guys are doing is basically what i’m looking for because it is free software… You mentioned something about seeing a work in progress version??…  I would be willing to bug test to the extent of my comoputer knowledge.  My flat mate funs a mac and I run windows…

  19. I found a solution that works well for me. I bought a dLO TransPod for my car and mired an extra power supply to the extension arm. Now I attach the TransPod to the extension arm (which is bolted to my desk) and plug a patch cord into the speaker jack on the comp and into the input on the TransPod. All the radios in my house can play the same music with zero lag. It works very well and has decent range. The only downside is that you cna’t change the song from any room other than the one with the computer in it. The sound quality is just as good as a real radio station so it leaves a little to be desired when played through my home theatre system. If anyone wants some more info, email me at FletcherTBomb@aol.com. I’d be happy to send you pics. This is only an interim solution until someone makes sync software work.

  20. What about pinging each node on the net and say each has <5ms like a LAN. From there send out a signal to each based on some calculation (“I’m 1ms round trip so I’ll start at THIS point, I’m 3ms so I’ll start at THIS point”) to start the song. Obviously the host would be the last to start playing relative to the latency of all the others. Again, introducing anomalies like other nodes putting loads on the net would interfere with this “perfect” LAN, but lets say it was isolated for this reason. Given a common 100/1000 type network, it would seem that this is a software  problem more than anything . FWIW, I’m not a software engineer by any means.

  21. Holy fuck. I thought sites had protection for double posting, let alone quadruple posting! Sorry!

  22. I really apprechiate the work going into this project, but its very sad to hear, that you stopped development before reaching a working winamp plugin. I would love to see that, especially because you wrote, that the winamp api calls are fast enough.

  23. I too would pay money for this type of a plugin for winamp.  I’m sure a LOT of people would.  Look at how popular things like Sonos and Squeezebox are becoming.

  24. Damn I was really looking forward to using this, I tried NetSync but i just couldnt get it work in a practicle sense, I could somtimes get it to sync correctly but most of the time there was a noticable echo, plus like I said its not practicle to use during a party. Wish you were still developing it Lars Werner.

    Any chance of a revisit to this project?

  25. The solution to the problem is VLC. Create a stream with the –control netsync option and stream to a multicast IP ( i used 239.255.1.1).

    For server:
    “<path to vlc.exe>” -vvv “<path to playlist file>” –sout udp:239.255.1.1 –control netsync –netsync-master

    For client:
    “<path to vlc.exe>” udp://@239.255.1.1 –control netsync –netsync-master-ip <ip address of server>

    (keep quotes, remove <>) run two copys of vlc on the master if you want to hear the stream on that machine (run 1 client and 1 server). I just made two batch files with that info in for easy access.

    Streaming quality is excelent and delay is only really noticeable if you listen hard for it.

  26. Nice try, Ryan.  The truth is you’ll NEVER be able to get this to work unless you remove the network and API latency issues.  There needs to be a calibration tool that thoroughly determines API latency, THEN you need to have the MP3 downloaded (can be pre-cached from the server or network share) to remove network latency altogether.  Network latency (especially on wireless networks) can never be overcome although I’ve come very close using gigabit based Ethernet.

    FYI:  Slimserver has all the same issues.  It’s close, but still unacceptable.  VLC is a fantastic tool, but the results are still unacceptable by my standards

    Don’t give up, guys!  It’s only a matter of time… I think the best solution will be one that uses combined SNTP and real-time MP3 analysis/sync.

  27. uh, bradbeard, try reading the whole article. it makes the same obversations, and comes to the same conclusion. the source in the tarball even includes an SNTP library i wrote for use in this project.

  28. Maulik / Ryan–

    I was recently looking into how to stream the same music to multiple players on a floor (or in our case, wing). With surprising results, I found that there was enough bandwidth to do the following in VLC:

    vlc -vvv –ttl 1 –sout-all –sout-keep –sout=#rtp{mux=ts,dst=224.30.68.1,port=1234} playlist.m3u

    I experimented a little bit with some other methods, but found this was the easiest. I was also able to make a batch file for windows users so they can just drop their sound/playlist file onto an icon and have it start playing:

    vlc -vvv –ttl 1 –sout-all –sout-keep –sout=#rtp{mux=ts,dst=224.30.68.1,port=1234} %1

    Essentially the same thing, with a %1 in place of the playlist.m3u to accept the command line argument.

    Although the sound quality can deteriorate, we’ve found that on fast networks it doesn’t seem to have any trouble.

  29. I have used airtunes (airport express) and found that there is a noticeable delay right off the bat.  I did not measure it, but it is audibly clear seconds into a song on a snare or kick beat.  Aside from this, they do not tend to play nicely with non-apple hardware.

  30. This task is huge. Look into what audio technicians use to sync audio at a dedicated workstation, then consider the implications of doing that over a network. (of course, they need to sync down to the sample.) I think the best solution would be some kind of dedicated hardware that sent a sync signal. But if we could manage to get less than 5ms (preferably <3ms) at the worst using network software then that’d do the trick for most user’s listening and watching habbits. I’m going to dig into this for my home network by the way. Thanks!

  31. @Jason, thanks for the interest! unfortunately, it’s not really very usable for end users. if you’re adventurous and don’t mind building from source, though, you’re welcome to download it!

    also see P4, the more modern platform rewrite without the music-specific parts.

  32. I mean seriously I am considering just installing a whole house audio system…. It would be less trouble maybe.. lol

  33. It is now 2012 and this is still badly needed. I’m going to try p4 as a plugin for mpd. My setup: mpd as host and wireless squeezebox (via icecast) as guest. The delay is somewhere between 3-5 seconds right now. If this solves my problem I’ll post results!

  34. I am the developer of one of the original programs here for winamp, winamp netsync

    just to update, we did later evolve the program to accomodate for ping time sync to improve synchronization which worked out quite well actually

    anyway, I am still using it today, in some respects and the site lives on at phear.com/netsync (download link currently broken, working to fix it, as i am traveling now)

Leave a Reply

Your email address will not be published.