Warning:
This post was written in pre-docker era. Back in the time it was necessary to perform many things that are no longer required on modern devices (like installing Debian Chroot package which, expectedly, is no longer offered).
Modern devices with Docker support or equivalent features (FWIW, my choice is Linux Station from QNAP) are much more friendly towards linux enthusiasts
Previously we’ve covered ALSA setup and Debian chroot.
In this post I’ll describe how to set up PulseAudio in Debian chroot, so that it’s possible to stream any sound from linux-powered pc to a sound card connected to Synology NAS.
Installing PulseAudio
Although Synology already uses PulseAudio for sound playback in Synology AudioStation, an old version of PulseAudio is used for that purpose (2.1 as per DSM5.1). Debian chroot, on the other hand, provides PulseAudio 5.0.
Install PulseAudio and some dependencies and add pulse
user to audio
group
(chroot)# apt-get install pulseaudio pulseaudio-module-zeroconf dbus
(chroot)# gpasswd -a pulse audio
PulseAudio theory
Modes of operation
PulseAudio can operate in 2 modes: system mode and per-user mode.
Configuration file for per-user mode is /etc/pulse/default.pa
. If PulseAudio works in system mode, it reads from
/etc/pulse/system.pa
.
Although system mode worked pretty well for me, it is considered unsafe and is said to have bad performance.
I’ll describe modifications I made to configuration script. They may be applied to both default.pa
and system.pa
with the same effect.
Working with remote clients
When it comes to playing audio from remote clients, PulseAudio provides 2 options: RTP and native TCP protocol.
In case of RTP, client broadcasts a signal and capable receivers on network receive it. RTP is extensively used and is widely supported by applications, so theoretically not only PulseAudio clients can play, but any RTP sender that can send uncompressed (RTP provides plenty of options, but PulseAudio doesn’t support all) audio.
RTP can be easily enabled or disabled with paprefs
utility without even changing configuration.
I noticed 2 downsides of RTP:
- It gives noticeable delay when streaming from PC. Though it may be compensated manually in
pavucontrol
utility. - PulseAudio server died frequently for me when acted as RTP receiver.
Native TCP, on the other hand, is for PulseAudio clients only. It is as if PulseAudio client had been talking to a local PulseAudio server, only it is not local. Thus, no extensive support, no 3-rd party apps playing…
Also there’s 1 thing to keep in mind: native TCP is extremely sensitive to time synchronisation. Client and server must be almost perfectly in sync. To the extent, that even having different NTP servers on the client and server breaks playback completely.
As a benefit you’ll get perfectly synced audio and video when playing movies or youtube videos on your PC.
Also PulseAudio seems to support it much better and works without crashes for me.
PulseAudio server configuration
(chroot)# vi /etc/pulse/default.pa
- Devices auto-detection via udev never worked for me, no matter, how I tried, so I loaded audio drivers statically:
` load-module module-alsa-card device_id=0
` and removed auto-detection completely by removingmodule-udev-detect
andmodule-detect
- Anyone on group
audio
should be able to use PulseAudio` load-module module-native-protocol-unix auth-group=audio
` - Anyone on local network (192.168.0.1 through 192.168.0.255 in my case) should be able to use PulseAudio
` load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/24;
` - PulseAudio should be discoverable via zeroconf, so clients are not required to specify static IP
` load-module module-zeroconf-publish
`
That’s it. Also I cleaned up some modules I do not need, for example the one that corks audio, when phone stream is active, the one that displays information about playing application or pans notification sound depending on widget position on the screen (whoa, PulseAudio is a beast, really), bluetooth, etc..
### Automatically restore the volume of streams and devices
load-module module-device-restore
load-module module-stream-restore
load-module module-card-restore
### Should be after module-*-restore but before module-*-detect
load-module module-switch-on-port-available
### Load audio drivers statically
load-module module-alsa-card device_id=0
### Allow access for everyone in audio group
load-module module-native-protocol-unix auth-group=audio
### Allow access for everyone on local network
load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/24;
load-module module-zeroconf-publish
### Load the RTP receiver module (can be configured via paprefs)
#load-module module-rtp-recv
### Load the RTP sender module (can be configured via paprefs)
#load-module module-null-sink sink_name=rtp format=s16be channels=2 rate=44100 sink_properties="device.description='RTP Multicast Sink'"
#load-module module-rtp-send source=rtp.monitor
load-module module-default-device-restore
load-module module-rescue-streams
load-module module-always-sink
load-module module-intended-roles
load-module module-suspend-on-idle
If you do not need network streaming, remove module-zeroconf-publish
. It might be a good idea to keep
module-native-protocol-tcp
though, as it’ll let you to connect to PulseAudio from remote PC with pavucontrol
and
paprefs
:
(pc)$ PULSE_SERVER=<nas ip> pavucontrol
(pc)$ PULSE_SERVER=<nas ip> paprefs
Clients on the NAS
(chroot)# vi /etc/pulse/client.pa
We need all local applications to try to connect to local PulseAudio server only. Also I turned auto-spawn
off as I
intend to start PulseAudio manually from pulse
user
default-server = 127.0.0.1
autospawn = yes
Giving it a spin
Start all the systems PulseAudio depends on
(chroot)# service start dbus
(chroot)# service start avahi-daemon
(chroot)# su pulse -s /bin/bash -c 'pulseaudio -D'
If it doesn’t start, try examining its output
(chroot)# su pulse -s /bin/bash
(chroot)$ pulseaudio
Else, if it starts successfully, try playing some sound through it
(chroot)# aplay -D pulse /media/path/to/some.wav
Volume can be adjusted with alsamixer
(chroot)# alsamixer
Configure NTP
As I mentioned streaming via native TCP protocol won’t work if system clocks on NAS and your PC are our of sync. DSM6.0 has ntp installed, and by default it uses Google servers for time synchronization:
(nas)$ ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================
*time1.google.co 71.79.79.71 2 u 768 1024 377 126.551 1.670 1.470
+time2.google.co 71.79.79.71 2 u 684 1024 377 135.111 0.921 0.836
+time3.google.co 71.79.79.71 2 u 449 1024 377 31.924 0.433 1.520
+time4.google.co 71.79.79.71 2 u 561 1024 377 292.364 5.348 4.849
I just added the same servers to /etc/ntp.conf
on my pc and never had a problem with playback again:
(pc)# cat /etc/ntp.conf | grep server
server time1.google.com minpoll 6 maxpoll 10 iburst prefer
server time2.google.com minpoll 6 maxpoll 10 iburst prefer
server time3.google.com minpoll 6 maxpoll 10 iburst prefer
server time4.google.com minpoll 6 maxpoll 10 iburst prefer
PulseAudio client configuration
Just load module-zeroconf-discover
in your /etc/pulse/default.pa
:
(pc)# vi /etc/pulse/default.pa
Uncomment or add line and restart PulseAudio
load-module module-zeroconf-discover
After PulseAudio restart new tunnel sink should become available in PulseAudio
(pc)$ pacmd list-sinks
...
index: 2
name: <tunnel.sigma.local.alsa_output.0.analog-stereo>
driver: <module-tunnel.c>
flags: NETWORK HW_MUTE_CTRL HW_VOLUME_CTRL LATENCY
state: IDLE
suspend cause:
priority: 0
volume: front-left: 42185 / 64%, front-right: 42185 / 64%
balance 0.00
base volume: 65536 / 100%
volume steps: 65537
muted: no
current latency: 312.65 ms
max request: 0 KiB
max rewind: 0 KiB
monitor source: 3
sample spec: s16le 2ch 44100Hz
channel map: front-left,front-right
Stereo
used by: 0
linked by: 2
fixed latency: 250.00 ms
module: 24
properties:
device.description = "Audinst HUD-mini Analog Stereo on pulse@sigma"
tunnel.remote.server = "[2a02:a310:20:5f80:211:32ff:fe3d:74f5]:4713"
tunnel.remote.sink = "alsa_output.0.analog-stereo"
device.icon_name = "audio-card"
tunnel.remote_version = "29"
tunnel.remote.user = "pulse"
tunnel.remote.fqdn = "sigma"
tunnel.remote.description = "Audinst HUD-mini Analog Stereo"
...
This is how it looks in PulseAudio Volume Control utility
Starting PulseAudio on NAS automatically
We need to create startup scripts to run dbus
, avahi-daemon
and pulseaudio
itself. The approach was described in
the previous part.
Just refer to the git repo for details.