Introducing Bark! Low-latency multi-receiver live-sync lossless audio streaming for local networks. It's like Sonos, but open source, so nobody can brick your devices remotely. It's also written in Rust :)

https://github.com/haileys/bark

It sends 48khz uncompressed float32 data over UDP multicast. It can achieve playback sync to within hundreds of microseconds in ideal conditions, and usually to within a millisecond.

I've been working on it in my spare time over the past week, and I'm pretty happy with how it's shaped up. I have three receivers setup and it works remarkably well at keeping everything in sync as I walk around my house. For now it only really works on Linux, and supports Pipewire (and Pulse in theory), but there's no huge impediment to making it truly cross-platform.

It also features a fancy live stats subcommand, which can used on any computer in the same multicast domain to watch the status of the stream cluster:

GitHub - haileys/bark: live sync audio streaming for local networks

live sync audio streaming for local networks. Contribute to haileys/bark development by creating an account on GitHub.

GitHub
I realised I forgot to put a link in the original post lol so I have edited it, but here is the link in case: https://github.com/haileys/bark
GitHub - haileys/bark: live sync audio streaming for local networks

live sync audio streaming for local networks. Contribute to haileys/bark development by creating an account on GitHub.

GitHub
@hailey have you seen Roon Labs RAAT - it is quite popular in hifi circles and has pretty good list of supported network streamers/dacs/amplifiers. Would be nice to have compatible opensource implementation https://help.roonlabs.com/portal/en/kb/articles/raat
Roon Advanced Audio Transport (RAAT)

What is RAAT? RAAT (Roon Advanced Audio Transport) is the backbone of Roon's audio distribution technology. It is designed to support a wide range of software and hardware applications without format support restrictions or quality compromises. It ...

Roon Labs Help Center

it is so so so cool to hear some music playing in my lounge room, and then on my desktop run `systemctl --user start bark-receive`, and hear the exact same thing out of my computer speakers.

The stream source is hooked to line-in on the lounge room server, so it can cast to the network anything playing from my cheap little spotify/airplay/bluetooth/etc stream box, or the Apple TV, or my FM radio even.

The latency added by Bark is basically imperceptible too!

@hailey next level: Hack sonos to install Bark in it. (IMO, it seems possible unless they blown up secure boot fuses)

Anyway, Thanks for the software.

I'll try to cross compile it into mips-unknown-linux-musleabi and run it in my old smart speaker (ReSpeaker gen1)

@hailey this does sound like an ideal solution for multi room audio. Thank you!

Have you tried it on a raspberry pi? If so does it work okay on the pi?

@martin I have not, but I imagine it would work fine! it doesn't use that much CPU on the mac minis I have it running on right now

@hailey I'll have a play and let you know!

It's hard to believe there isn't a standard already defined for this purpose... Thanks again for coming up with it!

@martin @hailey @astraluma and I played with it a bit a few weeks ago and it just barely works on a Pi 4, consuming about 50% CPU. Anything less was pegged at 100% CPU and you could watch the drift increase.

@agmlego @martin @hailey the Pi3 was close; I think some optimization would allow it. But ones, twos, and zeros were right out as the software stands.

Other SBCs might also work, but you're going to want similar or better single core performance.

@hailey is that all ethernet devices? How does wifi do? How big is the jitter buffer/input latency? The project sound exactly what i was searching earlier! Thanks for sharing!
@dunkelstern @hailey Wifi does _terribly_ since it'll be stuck at 6 Mbit/sec max
@hailey this looks fantastic! Is there a repo where I can have a go / experiment / contribute?
@jk yes sorry I forgot to link it lol! Here it is: https://github.com/haileys/bark
GitHub - haileys/bark: live sync audio streaming for local networks

live sync audio streaming for local networks. Contribute to haileys/bark development by creating an account on GitHub.

GitHub
@hailey this looks really great! what are you using for your devices?
@jaxter184 other than my desktop, the receivers are a couple of old 2012-ish mac minis I had lying around which I installed arch linux on for this
@hailey @jaxter184 UDP should make it fairly easy to whip up a microcontroller receiver
@tommythorn @hailey yeah, i originally asked because i had vague desires to make a PoE AES67 speaker, but i got bogged down in the research. just a little ESP32 with regular UDP messages seems much more reasonable.
@jaxter184 @hailey The #RISCV based, #Rust focused ESP32-C3-RUST-1 dev kit should be coming from @adafruit in a few days. That ought to be a good target (not that I will have time to pursue this).
@tommythorn @adafruit is the ESP32-C3 not already available? I'm pretty sure ive had one laying around somewhere for like a year at least
@jaxter184 @adafruit The chip, yes. This dev board is fairly recent AFAIU.

@jaxter184 @hailey @adafruit The board arrived and it *literally* took me 9 min from I sat down with the board until I had read the instructions [1], installed the software, and run the Hello World. This is great.

Slightly puzzled about the SHA-256 checksum warnings that show up.

[1] https://esp-rs.github.io/no_std-training/

Introduction - Embedded Rust (no_std) on Espressif

Embedded Rust (no_std) on Espressif training material

128Mb Ox64 SBC - PINE STORE

CORE 64-bit 480MHz RV64 C906 32-bit 320MHz RV32 E907 32-bit 150MHz RV32 E902 MEMORY 728KB internal SRAM 64MB internal PSRAM 128Mb (16MB) XSPI Flash microSD slot I/O INTERFACE UART I2C SPI I2S CAMERA INTERFACE MIPI-CSI 2 lanes COMMUNICATION 802.11 b/g/n 2.4GHz Wifi BLE 5.0 Zigbee USB 10/100Mbps Ethernet thru optional add-on board EXPANSION 40 pins Breadboard friendly form factor PACKAGE CONTENTS 128Mb Ox64 board Device Warranty: 30 Days  

PINE STORE
@shine @jaxter184 @hailey I’m super unhappy with the level of documentation for my other Buffalo (sic) boards. I’d not touch that.
@tommythorn @jaxter184 @hailey It's still waiting on my desk for me to have spoons to do anything with it :/ But it's true I'll trust ESP way more.
@hailey that’s super neat. I really wish there was better AES67 & PTP support in Linux, because all this stuff done closed-source in a pro audio could come across to open source and consumer network stuff so easily. One day I’ll have time to work on it.
@s0 I borrowed some ideas from PTP in this at least!! :)
@hailey nice :) I use MoOde Audio on a raspberry pi at home for a web interface to play back audio on my Hifi, this seems like something that would be great to add into that project for multi-zone audio, instead of relying on reverse-engineerings of airplay and Sonos protocols with so many layers of subtle bugs and compatibility problems…
@s0 @hailey Linuxptp and Pipewire-aes67/gstreamer work reasonably well, you might want to take a closer look at it
@dickenhobelix @hailey a year ago I couldn't get linuxptp to work at all, but I admit I haven't tried again recently.
@s0 @hailey I use it for several projects at work, and it's probably the most mature PTP stack I have encountered so far. Fiddly to parameterize, but it works quite well. Get in touch if you have any specific questions
@dickenhobelix @hailey that's very good to hear. I also work a fair bit with Dante & AES67 at work and have various projects where interop with regular audio stack would be great.

@s0 @hailey Dante is...well, special. Also Audinates's AES67 Implementation has had several Issues when I looked at it several years ago. But then I changed my employer and did not have access to the stacks, documentation and devices... Maybe stuff has improved since back then.

If you care about Interop, I'd recommend to also have a look at Milan (that's basically an Interop Layer for AVB). Though, I am absolutely biased, because I coauthored some of the specs back in the day...

@dickenhobelix @s0 Is there a particularly good guide or other documentation you'd recommend to learning how to configure it properly for any given site? It looks great to learn from, and I think lifting its best ideas into bark's userland stack could be a cool idea

@hailey @s0 One of the best resources that immediately comes to mind is Maciek's talk at netdev 0x16 https://youtu.be/Hs7oRukMuak

The difficult thing about linuxptp is that you need to have quite a bit of knowledge about IEEE1588 or IEEE802.1as to tweak all of knobs correctly. It's a good stack, but not quite user friendly

Netdev 0x16 - Introduction to time synchronization

YouTube
@hailey @s0 Ah, and one more important thing: until v4 linuxptp released new versions only ever 4 years or so, which is why most distros have terribly old versions with a few annoying bugs. Make sure to use at least v4 (they release bi quarterly starting with v4 afaik, but I don't know how long it will take Debian to pick up the latest versions). Most convenient way is to build from source...
@hailey I haven’t looked at the source but surely sending audio from macOS should be easy enough. It doesn’t have to be integrated with macOS audio to be useful (could pipe directly from mp1g123 say)
@hailey @tperfitt This reminds me of the (closed source, commercial) Skaa tech - https://www.skaastore.com/pages/aboutskaa or (very pricy) Dante - https://www.audinate.com/meet-dante/what-is-dante. Very cool to see an OSS take on this! How well does this perform on wireless?
What is SKAA?

SKAA is wireless technology which lets you share your audio, wirelessly, anywhere. Unlike Bluetooth or Wi-Fi, SKAA was built FOR audio! SKAA does not need a network to run! You can use almost ANY speaker and make it SKAA wireless!

SKAAstore™
@bruienne @tperfitt it is surprisingly ok on wifi! I wouldn’t rely on it, it’s too unreliable a transport, but it does work a lot better than I thought
@hailey Sounds a bit like snapcast, which I've been using for multiroom audio for a year or so. (Snapcast was kind of hard to set up, but that may have been more about my devices and network.) Is Bark comparable, or aiming for something different?
@joelvanderwerf I tried snapcast but it kept segfaulting on me so I just wrote my own!
@hailey Thank you for doing this!
@hailey why did you choose f32?

I don't know @halley's specific answer, but f32 seems like a very reasonable choice (24 bits of precision, half the size of f64). i16 would be in adequate for some things and i32 would require a fixed point convention so you might as well use f32 anyway.

@dgoodlad @hailey

@hailey you did this in a WEEK!?
@hailey This is cool. I’ve been looking at this stuff (along with AES67, Livewire, Dante, and friends.
@andrewharvey I briefly looked at that stuff but in classic programmer fashion it didn’t make immediate sense to me so I just wrote my own lol

@hailey Nice!

I've done that with VLC in the past, but it wasn't ideal.

@hailey this looks interesting.

How do you deal with long-term clock drift between your receivers? Is there some logic to resample the audio to match the clocks or do you wait until the buffer over/underflows and then jump?

@electronic_eel yes it uses the speex-dsp resampler and it will slew to resync for small offsets, and jump for large discontinuous offsets!

@hailey nice!

do you have plans on integrating it somehow with mpd?

I'd be especially interested in a way to use mpd to select on which devices I want to output audio. mpd has the concept of "audio_output" and most mpd clients allow you to control them.