Skip to content

Instantly share code, notes, and snippets.

@r0b0
Last active September 6, 2024 14:10
Show Gist options
  • Save r0b0/8606332f68ed4af5f9b3ff37724c605f to your computer and use it in GitHub Desktop.
Save r0b0/8606332f68ed4af5f9b3ff37724c605f to your computer and use it in GitHub Desktop.
Using raspberry pi as a sound server with Raspberry PI OS 12 bookworm with HDMI output

Running a sound server on a raspberry pi

Disabling headphones output

bcm2835 headphones are selected as default in alsa, I wanted to disable it completely:

# /etc/modprobe.d/blacklist-snd_bcm2835.conf
blacklist snd_bcm2835

VC4 audio

Raspberry pi os 12 bookworm defaults to the vc4 driver for hdmi audio. After disabling the headphones, there is one alsa device:

root# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: vc4hdmi [vc4-hdmi], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

The vc4 driver does not support sound mixing - not even via alsa dmix - see raspberrypi/linux#4951 We need to use software mixing

PulseAudio server

We cannot use the default per-user PulseAudio because the first user would block the underlying audio device. We have to use the discouraged server-wide PulseAudio service - see https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/SystemWide/

# /etc/systemd/system/pulseaudio.service
[Unit]
Description=Sound Service
After=sound.target

[Service]
# Note that notify will only work if --daemonize=no
Type=notify
ExecStart=/usr/bin/pulseaudio --daemonize=no --exit-idle-time=-1 --disallow-exit=true --system --disallow-module-loading
ExecStartPre=/usr/bin/sleep 3  # XXX: not sure why this is needed
Restart=always

[Install]
WantedBy=default.target

Remove all users (except pulse) from the audio group - add them to pulse-access group instead:

# /etc/group
audio:x:29:pulse
pulse-access:x:117:librespot,mpd,pi

Mask all per-user PulseAudio systemd services:

root# systemctl --global mask pulseaudio.socket
pi$ systemctl --user mask pulseaudio

mpd

Set mpd to use PulseAudio as output:

# /etc/mpd.conf
audio_output {
    type            "pulse"
    name            "My Pulse Output"
}

Change dependencies of the mpd systemd service to include PulseAudio:

root# systemctl edit mpd
[Unit]
After=network.target sound.target pulseaudio.service

librespot

Spotify server - see https://github.com/librespot-org/librespot/

# /etc/systemd/system/librespot.service
[Unit]
Description=librespot spotify connect server
After=network-online.target pulseaudio.service
Wants=network-online.target pulseaudio.service

[Service]
ExecStart=/usr/local/bin/librespot -c /var/cache/librespot -n %H -b 320
Environment=RUST_LOG=warn
User=librespot
SupplementaryGroups=pulse-access
ExecReload=/bin/kill $MAINPID
KillMode=process
RuntimeMaxSec=86400
RestartSec=5s
StartLimitBurst=5

[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment