No description
  • JavaScript 100%
Find a file
2026-08-12 11:05:38 +02:00
4.119-2026-03-24-pi Fix HDMI audio on single-HDMI-port Raspberry Pi boards 2026-08-12 11:05:38 +02:00
README.md Fix HDMI audio on single-HDMI-port Raspberry Pi boards 2026-08-12 11:05:38 +02:00

Volumio — HDMI audio patch for Raspberry Pi boards with a single HDMI port

Patch for Volumio 4 restoring HDMI audio on Raspberry Pi boards with a single HDMI port (Pi 3, Pi Zero), where the ALSA card is named vc4hdmi without a numeric suffix.

Tested on Raspberry Pi 3 Model B Plus Rev 1.3, Volumio 4.119 (2026-03-24), kernel 6.12.74-v7+.

Symptom

With vc4-hdmi selected as output, MPD dies as soon as you press play:

mpd.service: Main process exited, code=killed, status=6/ABRT

In /var/log/mpd.log:

ALSA lib ./src/pcm_volumioswitch.c:189:(_snd_pcm_volumioswitch_hw_params)
  PCM volumioMultiRoomServer unable to set sample format to FLOAT_LE for target volumioOutput
mpd: pcm.c:728: snd_pcm_name: Assertion `pcm' failed.

The MPD crash also brings down the HDMI link, so the monitor drops to "No Signal" at the exact moment you press play — which makes the problem look like a video issue.

Cause

In alsa_controller/index.js, the function generating /etc/asound.conf has two bugs in the same block.

1. The HDMI condition ignores single-port boards.

if ( card  === 'vc4hdmi0' || card === 'vc4hdmi1' ) {

On Pi 4 the cards are vc4hdmi0 and vc4hdmi1; on Pi 3 it is vc4hdmi, which matches neither. The branch never runs, so the chain ends on type hw pointing at a device that accepts only IEC958_SUBFRAME_LEvolumioswitch then fails and MPD aborts.

2. When the branch does run, it emits invalid ALSA.

asoundcontent += 'pcm.volumioOutput {\n';
asoundcontent += '    type plug\n';           // <-- type
asoundcontent += '    slave.pcm "volumioHw"\n';
if ( ... ) {
    asoundcontent += '    type "iec958"\n';   // <-- type again

The generated block declares type twice. Merely adding vc4hdmi to the condition does not fix anything: you get a malformed block and MPD still crashes.

Dropping the duplicate type and keeping slave.format "IEC958_SUBFRAME_LE" is not enough either: plug converts between PCM formats, but IEC958_SUBFRAME_LE is not a PCM format — it is a packed S/PDIF frame, which only the ALSA hdmi: device produces natively.

Fix

pcm.volumioOutput goes back to being a plain plug, and pcm.volumioHw targets the hdmi: device instead of raw hardware when the card is a vc4hdmi one:

asoundcontent += 'pcm.volumioHw {\n';
if ( card === 'vc4hdmi0' || card === 'vc4hdmi1' || card === 'vc4hdmi' ) {
  asoundcontent += '    type plug\n';
  asoundcontent += '    slave.pcm "hdmi:CARD=' + card + ',DEV=0"\n';
} else {
  ... // unchanged for every other card
}

Resulting asound.conf:

pcm.volumioOutput {
    type plug
    slave.pcm "volumioHw"
}

pcm.volumioHw {
    type plug
    slave.pcm "hdmi:CARD=vc4hdmi,DEV=0"
}

The non-HDMI path is untouched, so USB and I2S DACs are unaffected.

Applying

cd / && sudo patch -p1 < /path/to/4.119-2026-03-24-pi/vc4hdmi-alsa.patch
sudo systemctl restart volumio

If patch is unavailable, copy the file from patched/ directly.

Then, under Settings → Playback Options, switch the output away and back to vc4-hdmi: Volumio only rewrites asound.conf when the generated content differs, so the regeneration has to be forced.

Verify:

grep -A 4 "pcm.volumioHw" /etc/asound.conf   # should show type plug + hdmi:CARD=...
tail -5 /var/log/mpd.log                     # no assertion after pressing play

Must be reapplied after every update

/volumio lives in the read-only squashfs image and is replaced by every Volumio update. /data survives, so keeping a copy of the patched file there is worthwhile.

Layout

4.119-2026-03-24-pi/
├── src/      … tree holding the pristine file, at its real path
├── patched/  … same tree, patched file
└── vc4hdmi-alsa.patch

One directory per Volumio version: when a new release ships, create a new tree and check that the hunk still applies.