ALSA Multiroom Audio

Hi,

I ran across an interesting article that described a simple system for distributing audio using a combination of ALSA loopback and the trx transmit/receive utility. trx: Realtime audio over IP

Trx uses the Opus codec and RTP/UDP protocol. My initial tests were unsuccessful due to the receiver module segfaulting shortly after receiving data. Here is a link to the trx sources, precompiled binaries for tx and rx and a generic test for anyone that is interested in trying to debug the segfault.
moode/other/trx at develop * moode-player/moode * GitHub

If trx can be made to work reliably then it may be possible to use it as the basis for a multiroom audio system. Something like below as a start.

Code:
   Host A
     |
     |
    MPD
     |
     |
ALSA Loopback
   |    |
   |    |
   |    +-> Local playback
   |                                     Host B - Remote playback
   +-> Tx: Opus encode -> RTP -> |     | Rx: RTP -> Opus decode -> ALSA out
                                         Host C - Remote playback
                       -> RTP -> |     | Rx: RTP -> Opus decode -> ALSA out
There are also some missing pieces.

- Volume control for remote playback
- User Interface for config and operation
- Clock sync between Sending and Receiving hosts
- Duplicating the RTP stream to multiple remote hosts

-Tim
 
I though that project was only for network based x-overs but I see that its fundamentally an audio distribution system that could be used as the basis for multi-room audio.

I'd certainly be interested in looking at what it would take to integrate and adapt it for use in moOde including developing configuration and operational UI's but the terms stated at the linked page don't seem to be compatible with moOde software which is GPLv3 FOSS and can be used commercially.

GSASysCon - A bash-script-based streaming audio system controller
"Licensed under GPLv3 for personal use. Others please contact me at: [email protected]"

-Tim
 
Hi,

I ran across an interesting article that described a simple system for distributing audio using a combination of ALSA loopback and the trx transmit/receive utility. trx: Realtime audio over IP

Trx uses the Opus codec and RTP/UDP protocol. My initial tests were unsuccessful due to the receiver module segfaulting shortly after receiving data. Here is a link to the trx sources, precompiled binaries for tx and rx and a generic test for anyone that is interested in trying to debug the segfault.
moode/other/trx at develop * moode-player/moode * GitHub

If trx can be made to work reliably then it may be possible to use it as the basis for a multiroom audio system. Something like below as a start.

Code:
   Host A
     |
     |
    MPD
     |
     |
ALSA Loopback
   |    |
   |    |
   |    +-> Local playback
   |                                     Host B - Remote playback
   +-> Tx: Opus encode -> RTP -> |     | Rx: RTP -> Opus decode -> ALSA out
                                         Host C - Remote playback
                       -> RTP -> |     | Rx: RTP -> Opus decode -> ALSA out
There are also some missing pieces.

- Volume control for remote playback
- User Interface for config and operation
- Clock sync between Sending and Receiving hosts
- Duplicating the RTP stream to multiple remote hosts

-Tim

Tim,

There is no need to encode - just send the audio directly from ALSA. There is plenty of bandwidth even over WiFi to send CD quality or better audio, up to 24bit/96k. Despite the claims of that web page, it cannot be strictly "realtime" as there will always be some buffering. End to end latencies well under 100msec is certainly possible, however.

To address your concerns:
Volume control for remote playback - just do it at the source.
User Interface for config and operation - I do this all with text files. This could be wrapped in a GUI interface at any time.
Clock sync between Sending and Receiving hosts - Gstreamer handles this very well when the audio is sent as RTP
Duplicating the RTP stream to multiple remote hosts - Gstreamer also does this extremely easily. See the element "multiudpsink"

When you have multiple clients you may need to tweak the playback latency for each one slightly, and trim the playback volume (this is done one time when setting up the system) so that when switching from system to system the volume level is about the same. Controlling volume at the source is the best approach IMHO.

For serious work and app coding, Gstreamer has a C++ API, plus you can use other code generators to build Gstreamer apps. There is also a command line version that is mostly intended to test things out, but I have been able to use that to build a relatively full featured LAN-streaming system that can have any number of clients and includes source-side volume control via amixer.

For input, you can use the loopback as you have outlined above, or get it from Pulse Audio. I have found that the latest PA, when configured to have high quality audio, is actually very good sounding. See for instance:
Enable High Quality Audio on Linux - Gamunu Balagalla - Medium

I used the command line version when building GSASysCon, as that was easiest for me, but you will want to use the C++ API or a helper program to create your code. I'm happy to give you some general guidance about using Gstreamer and how to build pipelines to accomplish your goals. I found Gstreamer to be a little opaque but perhaps the extent of documentation and online help has improved over the past couple of years.
 
Last edited:

I understand this is just one link of the many on the subject but just a note - the recommendation in the last section to reconfigure alsa is a nonsense - PA and other alsa clients will compete for the hw device, making the setup very unreliable. Either everything through PA, or disabling the given soundcard in PA and accessing directly (one client at a time, of course).
 
I understand this is just one link of the many on the subject but just a note - the recommendation in the last section to reconfigure alsa is a nonsense - PA and other alsa clients will compete for the hw device, making the setup very unreliable. Either everything through PA, or disabling the given soundcard in PA and accessing directly (one client at a time, of course).

You are right about that - there is no need to modify your alsa config in any way.

Here's what I did in a recent setup. This used a laptop as the source, and an USB pro audio interface as the "DAC" and "ADC".

First, I installed pavucontrol so that I could easily configure pulse audio. Within pavucontrol I disabled the pro audio interface. Then I set up a Gstreamer pipeline to use as its source the alsasrc element with "device=pulse". This seemed to work better than using Gstreamer's pulsesrc element. The rest of the pipeline implemented a crossover and then sent the audio to the local (USB) audio device outputs. This could just as easily have been sent via RTP in UDP to another device over my LAN but for this application I only needed local sinks.

When the above Gstreamer pipeline is launched, a new "monitor" device appears in pavucontrol. The "monitor" contains a copy of all the audio that is being sent to pulse audio from applications. This is similar to what you would obtain if you used dmix and snd-aloop, but it's done automatically by pulse. Since pulse audio is often the default (and sometimes only) audio output option for some applications like Firefox, this means you will always be able to grab the audio. With the "audiophile" pulse audio system configuration mods you will have control over the audio quality and can insure it is high quality. The monitor includes its own volume control, so I set the source app volume level set to 100% and controlled the playback volume via pavucontrol.