Summary
Provisioning a Raspberry Pi 5 with --audio-device hdmi (-a hdmi) produces no HDMI audio. Two independent, Pi 5-specific defects in the provisioning path are responsible:
- The
hdmi case writes the firmware-KMS overlay dtoverlay=vc4-fkms-v3d, which does not expose an HDMI audio device on Pi 5.
- Even once the HDMI audio cards appear, CamillaDSP is configured to play to a raw
device: "hw:0", but the Pi 5 vc4-hdmi ALSA device accepts only IEC958_SUBFRAME_LE — a format CamillaDSP cannot emit — so playback dies with EINVAL.
Scope: the current hdmi provisioning path is confirmed working on Pi 4. This fix should change behavior only for Pi 5. Ideally the provisioning scripts detect the board model and apply the correct overlay + playback device automatically, leaving the Pi 4 path untouched.
Environment
- Board: Raspberry Pi 5 (
bcm2712)
- OS: DietPi (aarch64)
- Audio path:
Snapclient → hw:Loopback,0 → [kernel loopback] → hw:Loopback,1 → CamillaDSP → <playback> → HDMI
- CamillaDSP v3.0.1
Root cause 1 — wrong overlay (firmware KMS vs full KMS)
os/dietpi/lib/config.sh → configure_audio_device() hdmi case sets:
set_config_line /boot/firmware/config.txt 'dtoverlay' 'dtoverlay=vc4-fkms-v3d'
On Pi 4 firmware-KMS drives HDMI audio via snd_bcm2835 and works. On Pi 5 there is no snd_bcm2835; firmware-KMS binds firmwarekms (video only) and no HDMI audio card is enumerated. aplay -l shows only the loopback:
card 7: Loopback [Loopback], device 0: ...
dmesg confirms bound firmwarekms. Pi 5 requires full KMS (dtoverlay=vc4-kms-v3d), after which two HDMI audio cards enumerate:
card 0: vc4hdmi0 [vc4-hdmi-0]
card 1: vc4hdmi1 [vc4-hdmi-1]
card 7: Loopback [Loopback]
The legacy hdmi_force_hotplug / hdmi_drive / hdmi_group / hdmi_mode / hdmi_force_edid_audio lines and the vc4.force_hotplug=3 cmdline param are ignored under KMS on Pi 5 and are Pi 4-era firmware settings.
Root cause 2 — playback device must go through the plug layer on Pi 5
After switching to full KMS, CamillaDSP still fails:
ERROR [src/bin.rs:293] Playback error: ALSA function 'snd_pcm_hw_params_set_format' failed with error 'Invalid argument (22)'
The device opens fine — it's the format that's rejected. aplay -D hw:0 --dump-hw-params shows the vc4-hdmi device advertises exactly one format:
FORMAT: IEC958_SUBFRAME_LE
Available formats:
- IEC958_SUBFRAME_LE
IEC958_SUBFRAME_LE is the S/PDIF/AES3 wire framing (audio bits + preamble + validity/user/channel-status/parity), not linear PCM. CamillaDSP's ALSA output formats are linear only (S16LE/S24LE/S24LE3/S32LE/FLOAT), so no format: value can match a raw hw: device — every linear format returns EINVAL (S16/S24/S24_3/S32 all rejected as root). The PCM→IEC958 encapsulation has to happen in ALSA's iec958/plug layer.
Playing to plughw:0 (which pulls in the iec958 converter automatically) works from root:
$ sudo speaker-test -D plughw:0 -c 2 -r 48000 -F S16_LE -t sine -l 1
... period_size = 12000 / buffer_size = 48000 / Front Left / Front Right (plays)
Notes:
- This is not a resampling penalty — rate/channels already match (48000/2ch);
plug does only the mandatory framing conversion (negligible CPU, no quality loss).
hw:0 remains correct for the I2S DACs (DigiAMP+/DAC+/HiFiBerry), which take linear PCM directly — the plug device is HDMI-only.
hw:1 (second HDMI port) returned audio open error: Unknown error 524 (-ENOTSUPP); only HDMI0 (hw:0, port nearest USB-C) had a usable audio sink on the test unit.
- The direct
iec958:CARD=vc4hdmi0,DEV=0 PCM returned -22 (needs explicit AES params); plughw:0 fills those in, so it's the pragmatic target.
Manual workaround (validated on the affected unit — not a code change)
# 1) full KMS so the HDMI audio cards enumerate
sudo sed -i 's/^dtoverlay=vc4-fkms-v3d/dtoverlay=vc4-kms-v3d/' /boot/firmware/config.txt
sudo reboot
# 2) route CamillaDSP playback through the plug/iec958 layer
sudo sed -i 's|device: "hw:0"|device: "plughw:0"|' /etc/camilladsp/config.yml
sudo systemctl restart camilladsp
Proposed fix (auto-detect board, Pi 5 only)
Detect the board at provisioning time, e.g.:
grep -q "Raspberry Pi 5" /proc/device-tree/model
Then, for --audio-device hdmi:
|
Pi 4 (unchanged, confirmed working) |
Pi 5 |
| overlay |
vc4-fkms-v3d + legacy hdmi_* |
vc4-kms-v3d + dtparam=audio=on (drop legacy hdmi_* / vc4.force_hotplug) |
| CamillaDSP playback device |
hw:0 |
plughw:0 |
| CamillaDSP playback format |
S16LE |
S16LE |
Non-HDMI audio devices (DigiAMP+/DAC+/HiFiBerry) are unaffected on both boards (hw:0, linear PCM).
Implementation sketch:
os/dietpi/lib/config.sh: branch configure_audio_device()'s hdmi case on board model; add a camilladsp_playback_device() helper (returns plughw:0 for Pi 5 HDMI, hw:0 otherwise) alongside the existing camilladsp_playback_format().
audera/cli/conf.py render_camilladsp(): the playback device: is currently hardcoded to hw:0; add a playback_device parameter.
audera/cli/commands.py: thread playback_device through _emit_conf / player_conf / streamer_conf.
audera/cli/audera.py: add --playback-device (default hw:0) to both conf parsers.
os/dietpi/{player,streamer}/automation/setup.sh: pass --playback-device "$(camilladsp_playback_device "$AUDIO_DEVICE")".
Docs to update
docs/adrs/003-camilladsp-signal-chain-configuration.md — Decision 5 (playback device hw:0) and Decision 6 (HDMI format) need a Pi 5 HDMI exception: plughw:0 because vc4-hdmi accepts only IEC958_SUBFRAME_LE.
docs/adrs/001-raspberry-pi-hardware-assumptions.md — note Pi 5 HDMI (full KMS, vc4hdmi cards, no snd_bcm2835).
docs/dev/PROVISION.md — the -a hdmi description referencing vc4-fkms-v3d needs the Pi 5 / full-KMS path.
Acceptance criteria
Summary
Provisioning a Raspberry Pi 5 with
--audio-device hdmi(-a hdmi) produces no HDMI audio. Two independent, Pi 5-specific defects in the provisioning path are responsible:hdmicase writes the firmware-KMS overlaydtoverlay=vc4-fkms-v3d, which does not expose an HDMI audio device on Pi 5.device: "hw:0", but the Pi 5 vc4-hdmi ALSA device accepts onlyIEC958_SUBFRAME_LE— a format CamillaDSP cannot emit — so playback dies withEINVAL.Environment
bcm2712)Snapclient → hw:Loopback,0 → [kernel loopback] → hw:Loopback,1 → CamillaDSP → <playback> → HDMIRoot cause 1 — wrong overlay (firmware KMS vs full KMS)
os/dietpi/lib/config.sh→configure_audio_device()hdmicase sets:On Pi 4 firmware-KMS drives HDMI audio via
snd_bcm2835and works. On Pi 5 there is nosnd_bcm2835; firmware-KMS bindsfirmwarekms(video only) and no HDMI audio card is enumerated.aplay -lshows only the loopback:dmesgconfirmsbound firmwarekms. Pi 5 requires full KMS (dtoverlay=vc4-kms-v3d), after which two HDMI audio cards enumerate:The legacy
hdmi_force_hotplug/hdmi_drive/hdmi_group/hdmi_mode/hdmi_force_edid_audiolines and thevc4.force_hotplug=3cmdline param are ignored under KMS on Pi 5 and are Pi 4-era firmware settings.Root cause 2 — playback device must go through the plug layer on Pi 5
After switching to full KMS, CamillaDSP still fails:
The device opens fine — it's the format that's rejected.
aplay -D hw:0 --dump-hw-paramsshows the vc4-hdmi device advertises exactly one format:IEC958_SUBFRAME_LEis the S/PDIF/AES3 wire framing (audio bits + preamble + validity/user/channel-status/parity), not linear PCM. CamillaDSP's ALSA output formats are linear only (S16LE/S24LE/S24LE3/S32LE/FLOAT), so noformat:value can match a rawhw:device — every linear format returnsEINVAL(S16/S24/S24_3/S32all rejected as root). The PCM→IEC958 encapsulation has to happen in ALSA'siec958/pluglayer.Playing to
plughw:0(which pulls in theiec958converter automatically) works from root:Notes:
plugdoes only the mandatory framing conversion (negligible CPU, no quality loss).hw:0remains correct for the I2S DACs (DigiAMP+/DAC+/HiFiBerry), which take linear PCM directly — the plug device is HDMI-only.hw:1(second HDMI port) returnedaudio open error: Unknown error 524(-ENOTSUPP); only HDMI0 (hw:0, port nearest USB-C) had a usable audio sink on the test unit.iec958:CARD=vc4hdmi0,DEV=0PCM returned-22(needs explicit AES params);plughw:0fills those in, so it's the pragmatic target.Manual workaround (validated on the affected unit — not a code change)
Proposed fix (auto-detect board, Pi 5 only)
Detect the board at provisioning time, e.g.:
grep -q "Raspberry Pi 5" /proc/device-tree/modelThen, for
--audio-device hdmi:vc4-fkms-v3d+ legacyhdmi_*vc4-kms-v3d+dtparam=audio=on(drop legacyhdmi_*/vc4.force_hotplug)hw:0plughw:0S16LES16LENon-HDMI audio devices (DigiAMP+/DAC+/HiFiBerry) are unaffected on both boards (
hw:0, linear PCM).Implementation sketch:
os/dietpi/lib/config.sh: branchconfigure_audio_device()'shdmicase on board model; add acamilladsp_playback_device()helper (returnsplughw:0for Pi 5 HDMI,hw:0otherwise) alongside the existingcamilladsp_playback_format().audera/cli/conf.pyrender_camilladsp(): the playbackdevice:is currently hardcoded tohw:0; add aplayback_deviceparameter.audera/cli/commands.py: threadplayback_devicethrough_emit_conf/player_conf/streamer_conf.audera/cli/audera.py: add--playback-device(defaulthw:0) to bothconfparsers.os/dietpi/{player,streamer}/automation/setup.sh: pass--playback-device "$(camilladsp_playback_device "$AUDIO_DEVICE")".Docs to update
docs/adrs/003-camilladsp-signal-chain-configuration.md— Decision 5 (playback devicehw:0) and Decision 6 (HDMI format) need a Pi 5 HDMI exception:plughw:0because vc4-hdmi accepts onlyIEC958_SUBFRAME_LE.docs/adrs/001-raspberry-pi-hardware-assumptions.md— note Pi 5 HDMI (full KMS, vc4hdmi cards, nosnd_bcm2835).docs/dev/PROVISION.md— the-a hdmidescription referencingvc4-fkms-v3dneeds the Pi 5 / full-KMS path.Acceptance criteria
-a hdmiyields enumeratedvc4hdmi0/vc4hdmi1cards and a stable (non-crash-looping)camilladsp.service.-a hdmibehavior is unchanged (stillvc4-fkms-v3d+hw:0).