Skip to main content

Udev and Pulse

To use a USB DAC (digital-analog audio converter) in Sailfish OS it is necessary to set up udev to respond to the device being plugged in and turn off the internal sound card.

You need to become root:

devel-su 

create a udev rule to deal with the usb dac and activate the pulse usbaudio config.

echo 'ATTRS{id}=="mtsndcard", ENV{PULSE_IGNORE}="1"' > /etc/udev/rules.d/89-pulseaudio-usb.rules
cd /etc/pulse/xpolicy.conf.d
mv usbaudio.conf.disabled usbaudio.conf

exit to normal user and execute

pactl load-module module-udev-detect

The last command should be done at system boot through pulse. It MAY work on your phone as is. Sadly on volla phones (gigaset GS5/rephone) it does not. This solution does:

as root:

devel-su

modify the udev rules file

vi /etc/udev/rules.d/89-pulseaudio-usb.rules

with the following

ATTRS{id}=="mtsndcard", ENV{PULSE_IGNORE}="1"
ACTION=="add", SUBSYSTEM=="sound", RUN+="/usr/local/bin/udev-create-flag"
ACTION=="change", SUBSYSTEM=="sound", RUN+="/usr/local/bin/udev-create-flag"

Create a flag file

vi /usr/local/bin/udev-create-flag

 with contents

#!/bin/sh
# called by udev (runs as root)
# write a flag in the user's runtime dir so the user service notices it
USER="defaultuser"
FLAG="/run/user/$(id -u "$USER")/usb-dac-connected.flag"
mkdir -p "$(dirname "$FLAG")"
touch "$FLAG"

 make it executable and create the script to trigger the dac (or set volume, for instance)

chmod 755 /usr/local/bin/udev-create-flag
vi /usr/local/bin/set-usb-dac-volume.sh

with content this version is NOT setting volume, just making sure the dac is seen

#!/bin/sh
sleep 2
/usr/bin/pactl load-module module-udev-detect

for setting volume add

# !!! update sink name to yours - it contains unique serial number !!! `pactl list sinks|grep Name`
# someone could improve this to autotdetec script
sleep 2
pactl set-sink-volume alsa_output.usb-Apple__Inc._USB-C_to_3.5mm_Headphone_Jack_Adapter_DWH504202DRL1MQAF-00.analog-stereo 100%

make it executable

 chmod 755 /usr/local/bin/set-usb-dac-volume.sh

Now create the systemd triggers (these are prompted by the udev create flag script)

vi /home/defaultuser/.config/systemd/user/usb-dac-volume.path

with contents

[Unit]
Description=Watch for USB DAC flag
[Path]
PathExists=/run/user/%U/usb-dac-connected.flag
Unit=usb-dac-volume.service
[Install]
WantedBy=default.target
vi /home/defaultuser/.config/systemd/user/usb-dac-volume.service

with contents

[Unit]
Description=Run USB DAC volume script when flag present
After=default.target
[Service]
Type=oneshot
Environment=XDG_RUNTIME_DIR=%t
ExecStart=/usr/local/bin/set-usb-dac-volume.sh
ExecStartPost=/bin/rm -f /run/user/%U/usb-dac-connected.flag
TimeoutStartSec=60
[Install]
WantedBy=default.target

and enable

systemctl --user daemon-reload
systemctl --user enable --now usb-dac-volume.path

You should now have automatic switching between internal and usb dacs.

Article discussion: USB DAC playback on Sailfish OS Forum