SlimStreamer: Multiroom Streamer That Does Not Resample

Hello Volumio Community

Let me introduce my pet project, I have been working for while. SlimStreamer is an audio streamer that captures PCM data from ALSA in a transparent to applications way and sends it over to Squeezebox players through SlimProto protocol. Moreover, while capturing, original sampling rate is preserved and PCM stream does not get resampled to a predefined frequency. Other solutions (like AirPlay, SnapCast, …) use predefined sample rate, so original PCM stream is resampled in case sample rate does not match.

In other words, you can use any Linux software that outputs audio to the default ALSA device (MPD, Mopidy, Spotify client, …) and SlimStreamer will capture it and redirect to connected Squeezebox players (for example squeezelite) in a transparent way.

I am still working on supporting SlimProto (it is still missing). However most tricky part, PCM capture in a bit-perfect way, is working fine, also single-threaded asynchronous TCP server is done.

Few more details:
-> SlimStreamer is written in C++17 (one should read it is very fast and lightweight)
-> It uses two ALSA plugins: SlimPlexor and Loopback
-> SlimStreamer’s source code is in Public Domain (Unlicensed)

Any comments / feedback about whether you find it relevant / interesting / useful are much appreciated :wink:

Hi!
If I understand, you send the output to a Loopback device and the Loopback output to Slimplexor ?
path :
volumio->loopback->slimplexor
or I 'm missing something ?

Not really. PCM path:
MPD (or any other app) → ALSA default device → ALSA I/O plugin SlimPlexor (it is used to direct PCM to a proper Loopback device) → ALSA loopback device → ALSA loopback plugin → SlimStreamer → Squeezebox player

There are several Loopback devices (one per sample rate) and SlimStreamer tries to reads from all of them simultaneously, however only one is used at a time. This is done to avoid resampling on PCM path as original sample rate is never known in advance.

github page contains a diagram, check it out. Also please ‘Star’ me on github if you like it :wink:

Niiiiiiice project! Kudos!
Want to try it… but… can we have a simpler receiver other than Squeezzebox?

Hello michelangelo

I use squeezelite as a ‘reference’ player. However the aim is that any player capable of talking SlimProto can be used as a ‘destination’. So one can use Pi Model A / Zero with a decent DAC and run just squeezelite as a single player software; on the server side one can use any music software with any bells-and-whistles (Volumio + MPD, Mopidy, ShairPlay, Clementine, …) that outputs to a default ALSA device. The whole beauty is that synchronized streaming would be done ‘transparently’ to the original application playing music.

Current development status is that squeezelite can eatable connectivity with SlimStreamer so it is only PCM streaming and synchronization functionality is missing (actual synchronization is done by a player, so it is not a big deal on server side). I also validated bit-perfect PCM stream capturing functionality by directing it to a WAV file and it works as expected.

You can support me by promoting SlimStreamer project among DIY community (as I wrote this software is in Public Domain, so no string attached) and 'star’ing it on github :wink:

Sounds promising! It’s waaaaaaaay above my head, but if I can help, I will. :slight_smile:

Streaming without having to resample solves a lot of the multiroom issues, also a systemwide solution would help decrease complexity.
Only the player would remain, preferably a switch between master/slave in Volumio, but that’s just my two cents. That way you can use it as a slave or stand-alone instance.

This is what I am looking for since “ages”!

Thank you, guys. Your comments are really important for me to understand if the approach I am taking relevant for the rest of Volumio & DIY community. You are right, SlimStreamer & SlimPlexor took A LOT of engineering, I can talk to hours about all the challenges I faced. But it is very exciting as I rediscovered C++17 and it would be even more rewarding if the community finds it relevant as well :wink:

Waow, that looks very interresting (and also way above me) and exciting as the promises solve many of the synced multiroom complexity. I look forward to test something, especially in a Volumio configuration.

This kind of projects reminds me how much I enjoy the FFOS & DIY communities :wink:

Kudos mate !

-j

Hello guys

Let me share the latest update on SlimStreamer - It works!!!
All the way: regular app plays to a default ALSA device, SlimPlexor captures and passes to SlimStreamer, which delivers to squeezelite, which plays to a different ALSA device.
Having send that, there are still many ‘rough corners’: numerous hardcoded values, for now it works only for 44.1 kHz playback, no synchronisation yet…
I already started preparing instructions how to build and use it by regular users. As soon as I make it work for all (regular) sampling rates, I will release alpha version…

Stay tuned :wink:

Great news! I’m psyched to try this.

Keep us posted :slight_smile:

Hi

Finally I feel like the project is ready for alpha testing! Please check out instructions how to build and setup SlimPlexor. It is the first (and relatively tricky) part to start with. Let me know how it goes for you. I will publish instructions for building SlimStreamer within few days (it is way easier to set it up compared to SlimPlexor).

Thanks for your patience and support.

Wow! Can’t wait to try it, but I must admit… I must finish some other plugins first… :stuck_out_tongue:

Btw, how do we connect to the SlimStreamer? Is that by setting the host in the arguments of SqueezeLite? Or is there some other way of managing that?

Nice job!

Thanks, Saiyato :slight_smile: Yes, squeezelite connects to SlimStreamer by using ‘-s slimstreamerhost:3484’ parameter. Managed to get it working for all sampling rates so working on build instructions for SLimStreamer now. SlimStreamer’s functionality still missing two important pieces: it streams using raw PCM data which is a lot of data to send - it needs to encode to some lossless format on the fly, synchronization is missing. Despite that it is ready for alpha testing (as soon as I publish build instructions) :wink:

Hello Volumio Community

Let me share a great news - SlimStreamer is available for alpha testing! Please find instructions how to build it on the front page. Can’t wait for anyone trying it out providing feedback. Please note, you need to build and setup SlimPlexor and then SlimStreamer to make it work all the way :wink:

Hello Volumio Community

Quick update: I have just prepared Alpha release with compiled binaries, so no need to compile anything (for amd64 and armhf architectures). Anyone willing to give it a try?

I’ll certainly give it a try, I’m on my phone now, so I’ll check your GitHub tomorrow on the PC and see if I’ll succeed :slight_smile: psyched to try it!

Hello Volumio Community

I have just released a new version of SlimStreamer. It contains few important bug fixes and some improvements. You can download compiled binaries (Raspberry PI and Intel64) from github. Looking forward for your feedback :wink:

Awesome, I’m still working on getting the plug-in to work nicely for ALSA. It’s more a challenge of understanding how and why it works than really executing the commands.

But I’ll try to install the slim server this weekend :wink:

And document what I did along the road, so I might actually be able to make it a plugin.

Just a quick question though, I know squeezelite can play the stream, but can’t MPD do so too? I mean it should be just a stream right? Or am I mixing up stuff now?

Hello Saiyato

If you could tell me which steps puzzled you while setting up SlimPlexor, I could try to explain what’s happening by doing those steps. Also let me know if you see how I can make the description more user-friendly (I am thinking about creating kind of setup.py for setting thing up).

MPD can act as a source for streaming audio, the chain would be like this: MPD → ALSA default device (on server) → SlimPlexor → SlimStreamer → Squeezelite → ALSA (on client that does the playback). MPD cannot act as a player for a stream from SlimStreamer, because MPD uses actual files (MP3, FLAC, …) to play music (theoretically it is possible to do hacks like receive stream in Squeezelite, then direct to a pipe and feed this pipe to a MPD, but I see no point in that).

Let me know if you have any questions…