Sunday, October 21, 2012

Turning off the screen saver in Ubuntu

TL;DR: xset s off

“That's easy,” I could hear you think when you read the title. Well, it took me hours to figure it out. It drove me crazy that I'd have to get up and move the mouse every 10 minutes while watching a movie¹, and I couldn't figure out how to disable this behaviour. And when something takes that much effort, I blog about it so that other people might find the solution more easily.

Of course you can easily disable the screen saver through the control panel thing. But I'm not using the Gnome panel, so I never know how to get to that GUI in the first place. Also, you may find, like me, that it just does not work and your screen will still turn black after 10 minutes.

From the console, you can disable the screen saver with:

$ gsettings set org.gnome.desktop.screensaver idle-activation-enabled false

This probably does the same thing as the check box in the GUI. But for me, it wasn't enough: the screen would still blank after 10 minutes!

As it turns out, this is a default built into Xorg itself. Try this:

$ xset q
...
Screen Saver:
  prefer blanking:  yes    allow exposures:  yes
  timeout:  600    cycle:  600
...

Yep, that's the problem. Once you've found it, the solution is simple:

$ xset s off
$ xset q
...
Screen Saver:
  prefer blanking:  yes    allow exposures:  yes
  timeout:  0    cycle:  600
...

This only works until the X server is restarted; put xset s off in your .xsession file to make this change permanent.


¹ At least for some movies. mplayer disables the screensaver automatically, but Flash doesn't.

Sunday, July 15, 2012

Switching default PulseAudio device when USB microphone is plugged in

I have a PlayStation Eye for a USB webcam and microphone, which is supposed to be supported by Linux. Unfortunately the microphone won't work until I unplug it and plug it in again after boot.

But the unplugging causes PulseAudio to change its default device back to my on-board sound card, which doesn't have a microphone plugged into it. It won't change the default back to the Eye on its own. Here's a workaround, which took me several hours to develop, and isn't for the faint of heart. But it works now, dammit.

All we need to do is nudge PulseAudio a little via a udev event. First, install the daemon package:

sudo apt-get install daemon

Then create a new file /etc/udev/rules.d/99-pseye.rules with the following content (all on one line!):

SUBSYSTEMS=="usb", ATTR{idVendor}=="1415", ATTR{idProduct}=="2000", RUN+="/usr/bin/daemon -- /bin/su thomas -c 'sleep 1 && /usr/bin/pacmd set-default-source alsa_input.usb-OmniVision_Technologies__Inc._USB_Camera-B4.04.27.1-01-CameraB404271.input-4-channels'"

OmniVision is apparently the manufacturer of this camera. Reports around the internet have slightly different version numbers; type pacmd list-sources and use the name of your particular device (which shows up as name: <...>). You also want to replace thomas by your own username; this is used to find the running pulseaudio daemon.

There shouldn't be any need to restart the udev daemon, but if you find otherwise, do sudo restart udev.

The daemon command is needed because we need to delay the pacmd command a bit; if we run it right away, PulseAudio hasn't picked up the new device yet. The trouble is that udev tries very hard to wait for completion of all child processes of the RUN command before firing its events into userland, so PulseAudio will always get its event only after our script has already finished and failed. Even various combinations of & and nohup wouldn't convince udev not to wait, but daemon does the trick.

If this doesn't work, here are some debugging methods that I used. Try adding -o/tmp/daemon.log after /usr/bin/daemon and inspect the output. To watch udev events happen in real time, use udevadm monitor. Another good source of information is /var/log/syslog; do tail -f /var/log/syslog | grep pacmd to filter it. Also check the output of pacmd dump to see whether the set-default-source command has taken hold.

Oh, and the upstream PulseAudio people in all their wisdom decided (bug report) that 4-channel microphones like this one don't deserve to have a default profile, resulting in the message Failed to find a working profile in /var/log/syslog. The result is that PulseAudio will retry loading, and retry, and retry … causing brief and hard to debug system freezes once every minute or so. To make the microphone work at all in Ubuntu 12.04 (bug report), you also have to add the following at the end of /usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf:

[Mapping input-4-channels]
device-strings = hw:%f
channel-map = front-left,front-right,rear-left,rear-right
description = 4 Channels Input
direction = input
priority = 5

[Profile input:mic-array]
description = Microphone Array
input-mappings = input-4-channels
priority = 2
skip-probe = yes

Then type pulseaudio -k to reload the daemon (it will be restarted on demand). Yes, this will be overwritten on upgrades. I've found no way to work around that yet.