Distributed audio player on odroid

Post Reply
kibergus
Posts: 401
Joined: Sat Feb 23, 2013 11:23 pm
languages_spoken: english, russian
ODROIDs: U2 X2
Has thanked: 0
Been thanked: 0
Contact:

Distributed audio player on odroid

Unread post by kibergus » Mon Jun 03, 2013 5:37 pm

Image
The idea is to have high quality music player capable to play music in several rooms syncronously and with no fans or hard drives that produce noise.
Beside that I want to use the same speakers as main audio output of my PC. the article is quite big because I want to provide explanations which solutions are possible and why one or another solution should be selected.

Hardware:
HiFi speakers and amplifier - 1x There is no need to have more than one amplifier per room, so I want all my devices to use it.
USB sound card - 1x
Ethernet network - good old reliable and predictable ethernet is the best solution if you can afford extra cables. This is required to use the same speakers to output sound from other computers located in the room.
NAS (network attached storage) - you have to store music somewhere. Flash cards are good, but they are not big enough to store a lot of loseless music. So you need a HDD, which are noisy creatures, so you probably wouldn't like to have it in audio player. A good solution is a NAS located somewhere in the furthest corner of your flat/house.
There is another advantage that NAS can have gigabit ethernet which would allow you to move data to/from it much faster than if you connect HDD to odroid.

Software:
File share
My NAS allows NFS access. This is linux native network file system and it should be prefered to SMB if possible. To make system mount network share automatically add folowing line to fstab:

Code: Select all

<NAS domain>:<share path>                       <mount path>     nfs     bg,hard 0 0
And add to /etc/network/interfaces

Code: Select all

auto eth0
iface eth0 inet dhcp
Without these lines network interface would be brought up by network manager after X11 startup. This happens too late and NFS shares are not mounted.

Syncronous playback:
There are not many applications capable to synchronously playback audio on several computers. Our ear is very sensetive and even a slight shift would result in "echo" effect. Actually there are to audio subsystems which can do that: jack and PulseAudio. People say that squeezebox works good too. Beside that I've tried mplayer and vlc, but could not get good enough synchronization. Vlc can syncronization is more than enough for video if you use RTP multicast stream, but audio has a notisable "echo". And with video on demand there is no syncronization at all: every client receives his own stream. Mplayer just lags a lot when udp synchronization is active.
So, if you don't need synchronous video playback, than jack or PulseAudio is your choice because they are very flexible. If you want video playback too... Notify me please if you find a working solution.

Jack vs PulseAudio:
After a lot of googling it occurred that these subsystems are not competitors. They were written for different purposes. I don't need very low latency and high flexibility for listening music. I need low CPU usage and I don't want to load my network when nothing is played back. All flexibility I need is just switching on and off predefined outputs for predefined stream. So for this use case PulseAudio is a preferred solution.

PulseAudio:
Hint:First of all, if system time on devices would differ much, problems are expected. So you must install ntpd.

There are several ways to configure synchronous playback with pulseaudio. You can use module-combine-sink with module-tunnel-sink or you can use rtp broadcasting. I've chosen module-combine-sink because it provides lesser latency. But there is a chance that rtp would work over WiFi, while module-tunnel-sink does not.

Another thing that you have to decide is to run PulseAudio in system mode or as per-session daemon. Later is a prefered one mostly because of security considerations, such as users able to disconnect or redirect each others audio streams. But if you want headless device you need system mode. And this security issue, actually this is exactly what I want: common sound server for trusted users.
If you use system mode do not forget to add needed users to <b>pulse-access</b> user group. Configuration files are located in /etc/pulse/. For system mode it is system.pa and for user mode it is default.pa.

Output devices:
Theese are devices that are connected to amplifiers and output audio streams. You need to allow remote access, so enable module-native-protocol-tcp:

Code: Select all

load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16
Input devices:
On device which would generate audio stream you need to configure remote sinks. For every output device (excepting local outputs) add folowing line

Code: Select all

load-module module-tunnel-sink server=<output device address>
Now we need to be able to switch outputs on and off dinamically. PulseAudio streams data even to muted channels. But it does not send send data to suspended sinks. So we create intermideate sinks for every output which we can suspend independently:

Code: Select all

load-module module-combine-sink sink_name=kitchen_mpd slaves=tunnel-sink.u2k.home
load-module module-combine-sink sink_name=hall_mpd slaves=alsa_output.usb-ESI_Audiotechnik_GmbH_Dr._DAC_nano-01-nano.analog-stereo
And, finally, we combine all that sinks in-to one:

Code: Select all

load-module module-combine-sink sink_name=mpd_sink slaves=kitchen_mpd,hall_mpd
Now you can restart pulseaudio and switch particular sinks with commands like

Code: Select all

# Switch off
pactl suspend-sink hall_mpd 1
# Switch on
pactl suspend-sink hall_mpd 0
Congratulations. Now we have configurable sink, which syncronously streams to several output devices over network.

Music playback:
Now it is time to connect something to that distributed audio output. MPD is a good candidate because it can be remotely controlled and you can find a client for nearly any platform. Basic configuration is simple:

Code: Select all

audio_output {
        type            "pulse"
        name            "Pulse"
        server          "u2.home"               # optional
        sink            "mpd_sink"
}
But if we have multiple outputs it would be good to control them through MPD interface. I've prepared a little hack to make this possible. I created special dummy outputs which execute arbitrary commands when they are switched on and off. Then I've configured them to execute proper pactl commands and hid original (the first) pulse sink. Proposed patch is attached. Sink should be configured like this:

Code: Select all

audio_output {
        type            "exec"
        name            "Зал"
        enable          "pactl suspend-sink hall_mpd 0"
        disable         "pactl suspend-sink hall_mpd 1"
}

audio_output {
        type            "exec"
        name            "Кухня"
        enable          "/usr/bin/pactl suspend-sink kitchen_mpd 0"
        disable         "/usr/bin/pactl suspend-sink kitchen_mpd 1"
}
Issues:
The main problem which I am encountering now is reliability. If network connection fails PulseAudio removes remote sinks and does not recreate them. You have to restart it manually.
Another problem is that sink and outout states are not syncronized initially. So output statuses in MPD may differ from actual state.

timmoss
Posts: 1
Joined: Mon Mar 17, 2014 7:32 pm
languages_spoken: english
Has thanked: 0
Been thanked: 0
Contact:

Re: Distributed audio player on odroid

Unread post by timmoss » Mon Mar 17, 2014 7:50 pm

An interesting project and I wound be interested to know how it all worked. Incidentally, I have been using squeezebox for sometime now, the standard LMS server and squeezelite as client with 3 or 4 clients connected at any one time. Synchronization works very well, although accuracy is dependent on audio buffer size. Only problems I have had are rpi based, such as buffer underruns due to the shared usb / Ethernet bus structure, especially using 96k/24bit with an async dac and slow db lookups probably due to the same. I intend to swap to Odroid as this looks far more suited to this type of use. Btw squeezebox has some other nice features such as Sox interrogation for transcoding on the fly and internet radio, iplayer integration and a very active support network.

Ask the best with your project.

kibergus
Posts: 401
Joined: Sat Feb 23, 2013 11:23 pm
languages_spoken: english, russian
ODROIDs: U2 X2
Has thanked: 0
Been thanked: 0
Contact:

Re: Distributed audio player on odroid

Unread post by kibergus » Mon Mar 17, 2014 8:14 pm

I think, that you can use squeezebox on odroid too. Pulse audio works for me quite good, but not without issues.
1) You have to ensure, that only one instance of pulse audio works at the same time. I use system instance (because I don't want to depend on X11 and user session), but sometimes user instance of pulse audio was automatically launched. This resulted in strange floating bugs: sometimes audio works and sometimes not.
2) Synchronization is not perfect. Sometimes it is wery good and sometimes I have to stop and start playback manually to get it in sync.

So this recipe works for me, but I can't say that it is perfect.

taratsatsoin
Posts: 70
Joined: Tue Dec 31, 2013 6:13 pm
languages_spoken: english, french
ODROIDs: U3 soon :)
Has thanked: 0
Been thanked: 0
Contact:

Re: Distributed audio player on odroid

Unread post by taratsatsoin » Tue Mar 18, 2014 2:42 am

i tried the same at home and the only solution i found viable was to include a "follow me" option that i was not able to finish.
it is meant to decrease or to stop the sound in the main room (where the music starts most of the time) and to detects when you are moving and where you are in order to start or increase the sound in other room.
i started this with a rpi and gpio (movment sensors) that i still need to buy xD

if the idea can be useful for you :)

Akanksha
Posts: 1
Joined: Wed Sep 04, 2019 7:08 pm
languages_spoken: english
Has thanked: 0
Been thanked: 0
Contact:

Re: Distributed audio player on odroid

Unread post by Akanksha » Wed Sep 04, 2019 7:14 pm

How to make mplayer as rtp streaming server. I have installed live555 but no able to stream from mplayer. Please tell me the mplayer command for streaming data

Post Reply

Return to “Projects”

Who is online

Users browsing this forum: No registered users and 1 guest