Monitoring Audio Levels with PulseAudio

I'm working on driving an analog VU meter from my Raspberry Pi using whatever audio is going out the Pi's sound outputs. The de facto Linux sound system, PulseAudio, allows any sound output (or "sink" in PulseAudio's nonclementure) to be monitored. In PulseAudio land, each sink has a corresponding "source" called the monitor source which can be read just like any other other PulseAudio input such as a microphone. In fact, to help with volume meter style applications, PulseAudio even allows you to ask for peak level measurements, which means you can sample the monitor sink at a low frequency, with low CPU utilisation, but still produce a useful volume display. When this feature is used, each sample read indicates the peak level since the last sample.


posted: Sun, 10 Feb 2013 22:05 | permalink | comments

Tiling addiction

So I have this problem ... Well it's not really a problem - I can stop whenever I want, really I can. My problem is that I have a thing for tiling window managers (WMs) [1]. I love the efficient window management, keyboard focussed operation, extensive customisability and lightweight feel that most tiling WMs offer. For the X Window System [2] there's an awful lot to choose from, and I've been obsessed for some time now with finding a great tiling WM that works for me and then configuring it to perfection.


posted: Sun, 30 Sep 2012 21:15 | permalink | comments

A little thing about cron

Here's something I just learned the hard way.

If you edit a crontab with "crontab -e", cron won't reload the updated crontab immediately. Changes will be read at 1 second past the next minute boundary. For example, if you change the crontab at 10:54:32, cron will reload it at 10:55:01. This means if you're trying to test how something runs under cron and you're impatient so you set that thing to run at the next minute, you won't see it run!

I spent a good half hour chasing my tail on this one. Set the test entry to run 2 minutes ahead instead.

Tags: ,
posted: Tue, 12 Jan 2010 13:20 | permalink | comments

Setting PYTHON_EGG_CACHE when deploying Python apps using FastCGI

I recently sorted out an issue with the IMAPClient Trac instance that's been bugging me for a while.

The problem was that whenever the web server logs were rotated logrotate would restart Lighttpd. The web server restart would in turn restart the Trac (FastCGI) processes. Unfortunately, the Trac processes would fail to start with the following error.

pkg_resources.ExtractionError: Can't extract file(s) to egg cache

The following error occurred while trying to extract file(s) to the Python egg

  [Errno 13] Permission denied: '/root/.python-eggs'

The Python egg cache directory is currently set to:


Bang, no IMAPClient web site (the rest of the site was ok). To band-aid the problem when it happened (and I noticed!) I issue a sudo /etc/init.d/lighttpd restart and everything would be fine again.

After some investigation I found that running /etc/init.d/lighttpd restart as root always triggered the problem where-as restarting using sudo always worked. My guess is that restarting when logged in as root was leaving $HOME at /root even after Lighttpd had dropped to its unprivileged user account. The unprivileged user isn't allowed to write to /root so Trac blows up. setuptools seems to use $HOME instead of looking up the actual home directory of the current user.

The fix for me was to set the PYTHON_EGG_CACHE environment variable for the FastCGI processes to somewhere they are allowed to write to. This is done with the bin-environment option if you're using Lighttpd like me.

I imagine similar problems can happen with any Python app deployed using FastCGI.

posted: Thu, 19 Nov 2009 17:48 | permalink | comments

Problem installing Trac under Lighttpd+FastCGI

I just finished configuring a Trac instance for IMAPClient. To keep page response times tolerable I'm using FastCGI.

It turns out there's a little gotcha when you serve an app at the root (ie. "/") using FastCGI with Lighttpd. It passes the wrong SCRIPT_NAME and PATH_INFO to the app causing unexpected behaviour. The problem isn't there if the app is served from a prefix (eg. "/trac").

The problem is apparently fixed somewhere in Lighttpd 1.5 but I'm on 1.4.13 as shipped with Debian.

With Trac there is a workaround. If you modify Trac's FastCGI runner ( to correct the SCRIPT_NAME and PATH_INFO environment variables before the rest of the app sees them, the problem is solved. Here's what my now looks like (header comments removed):

import pkg_resources

from trac import __version__ as VERSION
from trac.web.main import dispatch_request

from os import environ
import _fcgi

def application(environ, start_request):
    environ['PATH_INFO'] = environ['SCRIPT_NAME'] + environ['PATH_INFO']
    environ['SCRIPT_NAME'] = ''
    return dispatch_request(environ, start_request)

def run():

if __name__ == '__main__':
    pkg_resources.require('Trac==%s' % VERSION)

Figuring this out cost me lots of time. Hopefully this information helps someone else out.

Relevant links:

posted: Fri, 28 Aug 2009 01:46 | permalink | comments

Vaio BZ11 article updated

I've just updated the Linux on the Vaio BZ11 article on this site. It now includes details for Ubuntu Intrepid Ibex: the webcam now just works, wireless is easy to get functioning. I've also clarfied the information on suspend and resume.

posted: Sun, 11 Jan 2009 18:11 | permalink | comments

Upgrading iPhone firmware using VMWare on Linux

Well that was a bit scary. I've just updated the firmware on my iPhone to 2.2 (the horrors!). Actually, this normally shouldn't be too much of a trial. The difference here is that I did it from Windows running inside VMWare on a Linux host.

I initially tried the naive approach of applying the update normally using iTunes (but running inside VMWware). Don't do this! The host (Linux) USB subsystem gets in the way leaving you with a somewhat useless iPhone in "recovery mode". It seems that the iPhone firmware upgrade procedure does something tricky with USB that doesn't play nicely with VMWare running on Linux.

To workaround the issue, some USB modules have to not be loaded on the Linux host during the upgrade. Extending the tips on Stephen Laniel's blog I created a blacklist file for modprobe that prevents certain USB modules from loading. Just unloading the modules manually isn't enough. The iPhone reconnects to the USB bus at least once during the upgrade process causing udev to reload the modules you've manually unloaded.

So before attempting the upgrade, create a file named something like /etc/modprobe.d/blacklist-usb with the following contents:

blacklist snd_usb_audio
blacklist usbhid
blacklist ehci_hcd

I'm not sure if ehci_hcd needs to be disabled, but I did this in my case.

Reload udev so that it knows about the new modprobe config file:

sudo /etc/init.d/udev reload

Now make sure these modules aren't already loaded:

sudo /sbin/modprobe -r snd_usb_audio
sudo /sbin/modprobe -r usbhid
sudo /sbin/modprobe -r usbhid

Now go back to VMWare, cross your fingers and attempt the firmware upgrade using iTunes. Things should progress along slowly.

You might find that at one point during the upgrade that iTunes sits there with a dialog saying "Preparing iPhone for upgrade". If this goes on for several minutes it could be that the iPhone isn't connected to VMWare anymore. iTunes is just waiting for the device to appear. If this happens, reattach the iPhone to VMWare using the "Removable Devices" option on VMWare's VM menu. It's a good idea to occasionally check that the iPhone is connected to VMWare during the upgrade.

Once the upgrade is complete you can remove the modprobe config file and reload VMWare:

sudo rm /etc/modprobe.d/blacklist-usb
sudo /etc/init.d/udev reload

For the record, this was done using iTunes 8 running on Vista running inside VMware Workstation 6.5.0 build-118166 on Ubuntu Intrepid (8.10).

Tags: ,
posted: Wed, 31 Dec 2008 11:07 | permalink | comments

Linux on the Sony Vaio VGN-BZ11

I've just posted an article on my experiences with Linux on my shiny new Sony Vaio VGN-BZ11XN notebook. Hopefully it's useful to other Linux users who own or are considering purchasing this laptop.

Questions, updates and feedback most definitely welcome.

posted: Wed, 24 Sep 2008 23:13 | permalink | comments

Slides online for Python on the Openmoko Neo Freerunner

PyCon UK was fantastic. Many thanks to the organisers for such a great event.

As promised at the end of the talk, I've just put the slides and code online for my Python on Openmoko presentation. I'm hoping this stuff is useful to anyone looking to develop Python apps for Openmoko phone.

posted: Mon, 15 Sep 2008 21:52 | permalink | comments

Neo Freerunner: first impressions

I finally got my hands on my Neo Freerunner two weeks ago and have been playing with it when time allows (so much so that I haven't given myself time to blog about it).

Overall, the hardware is great. The first thing you notice is that the unit feels very solid and the quality of the display is excellent; bright and high resolution. I've had success with wifi, GPS, the SD card slot and basic GSM usage. I haven't had a change to try out the accelerometers yet, mainly due to a (surprising) lack of software that uses them.


posted: Tue, 29 Jul 2008 22:46 | permalink | comments

OpenMoko release

The OpenMoko Freerunner has been released! This is big news for people who'd like an open and free phone (running Linux) with some interesting hardware: GSM, GPRS data, WiFi, GPS, accelerometers, USB host support, accelerated graphics, SD card slot and much more. The software is still a work in progress so the phone is primarily for developers at this stage

The UK distributor has been swamped by the amount of people interested in buying one. This is certainly an encouraging for the potential success of the project. I'm on the list to get one in the next batch, fingers crossed.

posted: Fri, 27 Jun 2008 11:13 | permalink | comments

Time saviour

Virtualisation is so damn useful. I'm currently trying to figure out why the new kernel update at work doesn't boot[1]. Thanks to VMWare, after each failed boot I can quickly revert to the previous state before the update. No messing around trying to restore the old kernel or reinstall the system [2].

posted: Mon, 30 Apr 2007 10:49 | permalink | comments retired

A long time ago, I wrote a little script called that takes the URLs from the US-CERT Summary Bulletin Feed, parsed the HTML summary pages and generated a feed of containing each item individually. I needed something like this for work as I need to keep track security vulnerabilities for all things Linux. The script has been broken for some time because the HTML of summary pages has changed.

Today I finally got around to looking at the problem and found that the HTML of the summary pages is now so bad that it is very difficult to extract useful data from. The HTML looks fine when rendered but it is full of incorrectly escaped text, missing tags and bizarre formatting. Whoever is responsible for generating that HTML shouldn't have their jobs.

So, I'm retiring I've updated my Code page to reflect this.

As an alternative, there's some reasonable RSS feeds from the National Vulnerability Database that provide similar functionality.

Tags: ,
posted: Wed, 21 Mar 2007 16:59 | permalink | comments

ssh-agent-applet 0.1

I've finally managed to do the first release of ssh-agent-applet. I've actually been using it for some time on my own PC but it needed a bit of love and documentation to make it easier to install.

From the README:

ssh-agent-applet is a Gnome applet that allows you to conveniently keep your ssh key(s) on external media. This means that if your computer is cracked or stolen, the attacker will not have a copy of private ssh key(s).
Using ssh-agent-applet, your keys are loaded into ssh-agent as soon as you insert your "key drive" into a USB port. The drive is automatically unmounted once the key loaded so you can remove it from the USB port immediately.

For developers, ssh-agent-applet is a reasonable example of how to write Gnome applets in Python and how to interface with HAL from Python using DBUS. The HAL/DBUS interactions are non-trivial and go beyond what most documentation covers. It took a fair amount of experimentation to get some of this stuff working. Hopefully the applet or at least its' code is of use to other people.

Downloads can be found on my Code page.

The next thing to do is organise a better build/install system, probably using autoconf. As discussed previously, the current system is a little fragile.

posted: Tue, 13 Feb 2007 14:33 | permalink | comments

USB Sniffing / Optus 3G and Linux

I'm living at my brother's new place while I'm in Australia. He doesn't have an internet connection (no home computer) and doesn't have a home phone (just uses mobile). To work around this obvious lack of connectivity I've borrowed an Optus branded GlobeTrotter 3G Quad PCMCIA card. The card is supplied as part of the Optus Wireless Connect package.

The Windows drivers and software worked immediately on my laptop but I rarely use Windows so was keen to get it working under my Linux distro.

I spent many hours trying the configurations described at the PHARscape site (and others). PPP negotiation would start but an IP address would never be allocated. I figured there was something different about the Optus 3G network but was using the Optus Access Point Name (APN) documented on the net ("internet").

I ended up sniffing the USB traffic to and from the card under Windows by using the excellent SnoopyPro USB sniffer. I captured the URBs the Windows drivers sent to first serial port endpoint on the card and then used strings on the capture file under Linux. The AT commands used by the Windows drivers magically appeared.

It turns out that I was using the wrong APN; I should have been using "connect" instead of "internet". Once the pppd chat script was updated things started working. Fantastic!

More details on the specifics of the pppd configuration I'm using can be found on the wiki.

posted: Mon, 13 Nov 2006 06:41 | permalink | comments