Skip to content

Commit

Permalink
audiosettings: add helper service to set ALSA defaults on RPI
Browse files Browse the repository at this point in the history
Added a helper method that installs a `systemd` service meant to automatically configure ALSA with the HDMI 0 port when using the ARM `vc4hdmi` RPI driver. The service will run once then disable itself.

Since the default ALSA configuration on RaspiOS goes through the analog output (Heaphones) when the `vc4-kms-v3d` overlay is present, if we want to configure the HDMI output by default there needs to be an additional configuration.  The additional configuration needs also to be applied when only one audio output is present, since the ALSA config is a bit more involved.

There are a couple of reasons for which is a service:
 - the `vc4hdmi` device index can be different depending on the Pi model. Pi0(w)/Pi400 has no analog output by default and CM models may not have it also)
 - the card name can also be different (Pi4 with 2 devices vs Pi3/Pi2/Pi1 with 1 device)

Note that the service will configure the 1st HDMI port/device, on Pi models with multiple HDMI ports (Pi4/Pi 400/Pi5/CM4) the user will still need to use the Audio settings dialog to change it if they want to. There may be a way to detect which HDMI port is active and has audio, but that's not implemented.
  • Loading branch information
cmitu committed Oct 5, 2023
1 parent 083362d commit e39d31c
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
30 changes: 30 additions & 0 deletions scriptmodules/supplementary/audiosettings.sh
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,36 @@ function _bcm2835_alsa_internal_audiosettings() {
fi
}

# Adds a service to generate the ALSA configuration on HDMI 0 for a vc4-hdmi device (RPI configured with 'vc4-kms-v3d').
# The service will disable itself afterwards, but can be enabled if re-running the configuration is desired.
# If the RetroPie ALSA configuration is found, the service will not overwrite it.
function alsa_defaults_service_audiosettings() {
local service="retropie-alsa-config.service"

mkdir -p "$md_inst"
cp -f "$md_data/alsa-defaults.sh" "$md_inst"
cat << EOF > "/usr/lib/systemd/system/$service"
[Unit]
Description=Configure ALSA default card on HDMI 0
ConditionPathExists=!/etc/alsa/conf.d/99-retropie.conf
Before=getty.target
After=sound.target
[Service]
Type=oneshot
TimeoutSec=120
ExecStart=$md_inst/alsa-defaults.sh
ExecStartPost=/usr/bin/systemctl disable $service
[Install]
WantedBy=multi-user.target
EOF
# remove the RetroPie ALSA config file so it's created on next boot by the service
rm -f /etc/alsa/conf.d/99-retropie.conf
systemctl -q enable $service
printMsgs "console" "Installed the ALSA configuration service ($service)"

}
# configure the default ALSA soundcard based on chosen card index and type
function _asoundrc_save_audiosettings() {
[[ -z "$1" ]] && return
Expand Down
61 changes: 61 additions & 0 deletions scriptmodules/supplementary/audiosettings/alsa-defaults.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/sh

# Sets the default ALSA audio card to the 1st vc4-hdmi device found
# The ALSA configuration is written to '/etc/alsa/conf.d/99-retropie.conf'

CONF_FILE=/etc/alsa/conf.d/99-retropie.conf

# test if we don't already have the audio configured
if [ -f "$CONF_FILE" ]; then
echo RetroPie audio card configuration already present, skipping configuration
exit 0
fi

# test if we have any `vc4-hdmi` cards present, otherwise exit
card_index="$(grep vc4hdmi /proc/asound/cards | cut -d' ' -f 2 | head -n1)"
card_name="$(cat /proc/asound/card"${card_index}"/id)"
if [ -z "$card_index" ]; then
echo No vc4-hdmi audio devices present, skipping configuration
fi

echo "Found a vc4-hdmi sound card on slot $card_index, configuring it"

tmpfile="$(mktemp)"
cat << EOF > "$tmpfile"
pcm.hdmi${card_index} {
type asym
playback.pcm {
type plug
slave.pcm "hdmi:${card_name}"
}
}
ctl.!default {
type hw
card $card_index
}
pcm.softvolume {
type softvol
slave.pcm "hdmi${card_index}"
control.name "HDMI Playback Volume"
control.card ${card_index}
}
pcm.softmute {
type softvol
slave.pcm "softvolume"
control.name "HDMI Playback Switch"
control.card ${card_index}
resolution 2
}
pcm.!default {
type plug
slave.pcm "softmute"
}
EOF
mv -f "$tmpfile" "$CONF_FILE" || {
echo "Failed to save configuration file $CONF_FILE!"
exit 1
}
chmod 0644 "$CONF_FILE"
echo "ALSA configuration saved in $CONF_FILE"

0 comments on commit e39d31c

Please sign in to comment.