Tuesday, May 12, 2015

USB audio disconnect woes in FreeBSD with fstat: tales of a voltage-sensitive Topping TP30

I have a very nice "class T" Tripath audio amplifier: the Topping TP30 (MK I -- hopefully they fixed the MKII) with a very convenient integrated USB audio card. However, this device is VERY sensitive to line voltage. For example, when plugged into the same circuit as, say, a refrigerator, the motor spark is enough to pop the speakers and cause the device to perform a USB reset.

In the case of FreeBSD, this causes everything to come to a miserable, grinding halt. dmesg gives me repeated warnings of failure:

pcm2: unregister: mixer busy
pcm2: Waiting for sound application to exit!
pcm2: unregister: mixer busy
pcm2: Waiting for sound application to exit!
pcm2: unregister: mixer busy
pcm2: Waiting for sound application to exit!
pcm2: unregister: mixer busy
pcm2: Waiting for sound application to exit!
pcm2: unregister: channel pcm2:virtual:dsp2.vp0 busy (pid 11413)
pcm2: Waiting for sound application to exit!
pcm2: unregister: channel pcm2:virtual:dsp2.vp0 busy (pid 11413)
pcm2: Waiting for sound application to exit!
pcm2: chn_write(): pcm2:virtual:dsp2.vp0: play interrupt timeout, channel dead

Before I realized that fstat worked on character devices, I had to manually fish around for processes to kill, in order to give the USB audio subsystem the breathing room required for it to reset the audio device. Interestingly enough: if a process that was holding onto the mixer releases the corresponding /dev/mixer device, but then restarts quickly enough and grabs control of the (now defunct) mixer, the sound card still won't reset.

Below, find the one-liner script that goes out and kills every process that holds the audio devices open. I have to execute this twice in a row to kill off XFCE's mixer process until the USB audio card has time to fully reset:

fstat /dev/dsp* /dev/mixer* /dev/audio* | tail -n +2 | awk '{print $3}' | xargs sh -c 'sudo kill -9 $0 $*'

4 comments:

Anonymous said...

YOU ARE A LIFESAVER!!! I unplugged my USB audio device and plugged it back in and all of a sudden my messages log was getting spammed with 'kernel: pcm7: Waiting for sound application to exit!'
This happened conveniently at a time where I was running some lengthy remote tasks in a terminal and didn't want to reboot. This is the only post I found on the internet with the solution. Thanks!!

Anonymous said...

Agreed, this just helped me when my DAC cut out due to a power supply issue.

/dev/audio didn't exist for me so I used the following:
fstat /dev/dsp* /dev/mixer* | tail -n +2 | awk '{print $3}' | xargs sh -c 'sudo kill -9 $0 $*'

Steve said...

Just a thought, you said it's very sensitive... plugging in refrigerator". When a electrical motor is powered up for a brief moment (~120th of a sec) it surgest maybe 20 X normal consumption. Which for me meant I needed to have over 5kW available to start it.

In other words the problem could be the wiring or circuit, that you share with the fridge, not your amp.

Anonymous said...

Wow! Thank you so much!

This issue occurred for me with a Monoprice Blackbird (it's named something like that anyways) KVM switch. Here is a devd rule to kill pulseaudio (the offending application in my setup).

`/usr/local/etc/devd/pulseaudio.conf`

```
notify 0 {
match "device-name" "pcm[0-9]+";
action "su myuser -c '/usr/local/bin/pulseaudio --kill ; /usr/local/bin/pulseaudio --

};
```

Killing all applications with open handles seems aggressive and likely to break things in very nonstandard ways. Although in principle I agree that the offending applications are at fault I think this will be more maintainable.

It is easily adapted to use your command though. Hope this helps someone else. Cheers.