On Mon, Jan 23, 2012 at 1:17 AM, Clemens Ladisch <cladisch@xxxxxxxxxxxxxx>
Jeffrey Barish wrote:AFAIK PulseAudio can be configured to do this automatically, even when
> A USB DAC may or may not be connected to my system. When it is
> connected, sound should come out the USB DAC. When it is not
> connected, sound should come out the internal DAC.
a stream is currently being played.
> The solution that I implemented uses udev to detect when the USB DAC
> is connected/disconnected. udev runs a script when it detects
> a change. The script writes ~/.asoundrc
> So, what is different about restarting the daemon from the commandMaybe ~ points to another user's home directory, or you're using a udev
> line versus restarting it from the script.
event that happens before the USB sound device is registered.
Yes, I am aware that pulseaudio can do what I want automatically. However, it is only recent versions of pulseaudio that have this capability. I am running Ubuntu 10.10. The version of pulseaudio that runs on this platform does not have this capability. I can't upgrade the OS, so I tried, but failed, to make pulseaudio from source. I would rather not introduce another dependency anyway. It seemed as if I could solve the problem using alsa alone, but now I am wondering.
The ~ theory is a good thought. Unfortunately, I misled you. I used ~ as a shorthand when composing the message. The actual code uses a full path. In any case, I know that the correct .asoundrc file is being updated because I see the new contents and because the sound does actually switch when I disconnect the USB DAC.
Your second suggestion is also interesting. I described two changes I made to test that theory. First, I removed the numeric prefix from the name of the rules file so that it runs after all the rules in /lib/udev/rules.d. I figured that allowing all other rules to run first would provide an opportunity for the USB DAC to be registered by the time my script runs. Then, in case I was wrong about the effect of that change, I inserted a 2-second delay before restarting my daemon. I figured that the delay would provide ample time for the registration to take place. Does anyone know these tests to be invalid? When you talk about the USB DAC being "registered", do you mean by udev, or something else? If I do "cat /proc/asound/cards" in my script, I see both cards even when udev runs the script.
Your suggestion did point out another difference. When my script runs under udev, it is owned by root. When I restart the daemon from the command line, I would be me except that I use sudo. To make the two situations as similar as possible, I tried running the udev script itself from the command line using sudo (rather than simply restarting the daemon using sudo):
sudo ACTION="" udev-script.sh
When activated this way, the script runs exactly the same commands that it runs when activated by udev, and the commands in the script all produce the same output (except that the pid of the daemon changes). However, when run by udev the script does not switch the sound to the USB DAC and when run from the command line, it does. I can't think of any difference, though, as in both cases the script runs as root.
Here's something new:
If I set up the system to use the USB DAC -- sound is actually come out the USB DAC -- and then I disconnect the USB DAC while playing, I get the error message
Cannot connect to server socket err = No such file or directory
Cannot connect to server socket
jack server is not running or cannot be started
I don't know what these messages mean, but I'm wondering: Is it possible that if alsa sees these messages when it first tries to connect the USB DAC under udev, it decides that something is wrong with the USB DAC and refuses to abandon the internal DAC? Maybe by the time I run the script from the command line, whatever it is that causes these error messages to be produced has settled, so alsa proceeds with the switch.
As far as I know, I am not running jack. ps aux | grep jack lists nothing even when sound is coming out the USB DAC. But something seems to think that I should be running jack. Maybe that something is interfering with the switch.