site  contact  subhomenews

Automatic detection of audio device

December 29, 2021 — BarryK

What I want is when plugin a USB audio device, that it will be detected, and if it is a sink device launch the Multiple Sound Card Wizard. Yes, I will explain that, but also want to point out a serious potential bug that still exists in woof-CE built pups.

Firstly, the automatic detection. I have this "5H" USB audio adaptor, purchased January 2020:

https://bkhome.org/news/202001/usb-sound-stereo-adapter.html

img1

EasyOS has inherited a udev-based detection system from the Puppy days, /etc/udev/rules.d/88-puppy-autodetect.rules, which detects certain hardware plugged in and launches /usr/sbin/pupautodetect.

I have added detection of an audio sink device, these lines inserted into 88-puppy-autodetect.rules:

ACTION=="add", SUBSYSTEM=="sound", ENV{DEVTYPE}=="pcm", RUN+="/usr/sbin/pupautodetect pcm"
ACTION=="remove", SUBSYSTEM=="sound", ENV{DEVTYPE}=="pcm", RUN+="/usr/sbin/pupautodetect pcm"

Now, plugin my audio adaptor and Multiple Sound Card Wizard automatically runs:

img2

After unplugging the adaptor, again mscw runs:

img3

This is great, can plugin the audio adaptor and immediately test it, adjust levels and choose it as default audio output. Ditto when remove it, can go back to inbuilt audio output.

Note, bluetooth audio is different, handled in another way.

Back in 2020, I experienced some weirdness, cannot recall exactly what it was, but determined that it was caused by the application launched from a udev rule running too long. The problem is discussed here:

https://unix.stackexchange.com/questions/56243/how-to-run-long-time-process-on-udev-event

I posted to my blog about it in December 2020 and brought it to the attention of Puppy developers:

https://bkhome.org/news/202012/how-to-run-long-time-process-on-udev-event.html

I have just now looked at woof-CE testing branch on github, and see nobody took any notice of my warning.

As explained in the stackexchange post, simply appending "&" to long processes, as woof-CE does in /usr/sbin/pupautodetect, does not detach the long process, and is going to result in udev getting upset, and as is suggested in the stackexchange post, udev may kill the long process.

Can't recall, I think maybe, the weirdness I experienced was udev actually stopped working.

In EasyOS, /usr/sbin/pupautodetect is now just this:

#!/bin/ash
#20201021 scripts called from udev rule must exit quickly.
#ref: https://bkhome.org/news/202009/detach-child-process-from-parent.html
#20201208 setsid not working when call from udev rule. "&" or "disown" do NOT detach the process.
# ref: https://unix.stackexchange.com/questions/56243/how-to-run-long-time-process-on-udev-event
# busybox cttyhack does detach process.
#20211229 need paths.

cttyhack /bin/ash /usr/sbin/pupautodetect-run $@ &

The real work is now done in /usr/sbin/pupautodetect-run:

#!/bin/ash
#Barry Kauler, Oct. 2011
#called via udev /etc/udev/rules.d/88-puppy-autodetect.rules
#111007 first release.
#111010 maybe wait until delayedrun has done its stuff.
#161008 ubuntu 16.01, /usr/bin/Xorg now a script, actual Xorg is at /usr/lib/xorg/
#20201205 now have /usr/sbin/pupmtp, handles MTP device (Media Transfer Protocol).
#20201208 workaround to prevent both pupmtp and pupcamera running.
#20201215 if called from udev rule, LANG will not be set.
#20211206 remove /root/my-applications
#20211229 /etc/udev/rules.d/88-puppy-autodetect.rules detects plugged in audio pcm (sink) device.

[ ! $1 ] && exit
export PATH='/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin'
export DISPLAY=':0'

[ "`pidof X`" ] || [ "`pidof Xorg`" ] || exit #161008

#20211229 detect already running...
#ref: https://stackoverflow.com/questions/16807876/how-to-check-if-another-instance-of-my-shell-script-is-running
lockdir="/tmp/pupautodetectrunlock${1}"
mkdir ${lockdir} || exit

#20201215 if called from udev rule, LANG will not be set...
eval $(grep '^LANG=.*' /etc/profile)
export LANG

#111010 maybe wait until delayedrun has done its stuff...
EXCNT=0
while [ ! -f /tmp/delayedrun_finished_flag ];do #see /usr/sbin/delayedrun.
sleep 2
EXCNT=$(($EXCNT + 1))
[ $EXCNT -gt 10 ] && break #precaution
done

case $1 in
camera)
pupcamera &
;;
android-device) #20201205
sleep 2 #20201208 do not run pupmtp if running pupcamera
pidof pupcamera >/dev/null
if [ $? -ne 0 ];then
pupmtp &
fi
;;
pcm) #20211229 audio device
sleep 2
pidof pulseaudio >/dev/null
if [ $? -eq 0 ];then
pidof mscw >/dev/null
if [ $? -ne 0 ];then
mscw &
fi
fi
;;
esac

rm -rf ${lockdir} #20211229
###end###

I will inform them again about this.  

Tags: easy