Daniel Nouri's Blog

tr -cs "[:alpha:]" " " < /dev/urandom

PulseAudio through Jack on Jaunty

written by nouri, on Jun 9, 2009 1:11:00 AM.

From the PulseAudio page on the archlinux wiki:

PulseAudio provides module-jack-source and module-jack-sink which allow PulseAudio to be run as a sound server above the JACK daemon.

What this means is that you can have JACK running at all times and still have sound (both in and out) with applications that aren't JACK- aware. Think of recording the sound of YouTube videos straight into Ardour, or passing your voice through LADSPA effects before sending it to Skype.

However, since this setup doesn't work so well with suspend, and because there's still the rare application that won't even work with PulseAudio (let alone, JACK), I wrote this little script that'll do two things: When called with no argument, it'll kill any existing PulseAudio daemon, start JACK (by means of QJackCtl) and then start the PulseAudio daemon again with a configuration file that loads its module-jack-source and module-jack-sink modules. I put this configuration file into $HOME/etc/pulsejack.pa. The PulseAudio page on the archlinux wiki has instructions on how to create such a configuration file. So here's my shell script:

#!/bin/sh

start() {
    echo "Starting..."
    /usr/bin/pulseaudio -k && echo "Killed pulseaudio"
    eval "/usr/bin/qjackctl.bin -s &" && echo "Started qjackctl"
    sleep 3;
    /usr/bin/pulseaudio -DnF /home/daniel/etc/pulsejack.pa && echo "Started pulseaudio"
}

stop() {
    echo "Stopping..."
    /usr/bin/pulseaudio -k && echo "Killed pulseaudio"
    /usr/bin/killall jackd && echo "Killed jackd"
    /usr/bin/killall qjackctl.bin && echo "Killed qjackctl"
    sleep 1;
    /usr/bin/pulse-session && echo "Started pulse-session"
}

case $1 in
    stop)
        stop;
    ;;
    *)
        start;
    ;;
esac

You can see that there's another function stop that'll kill the JACK daemon and start up PulseAudio with its default configuration file (which lives in /etc/pulse/default.pa).

Now this worked rather well, until I upgraded to Ubuntu 9.04 (Jaunty Jackalope) today. Because suddenly, whatever I tried, PulseAudio seemed to start automatically just before JACK could take control over my audio device, and so JACK died with:

the playback device "hw:0" is already in use. Please stop the
application using it and run JACK again

After a bit of Googling I found out that there's a configuration switch called autospawn in /etc/pulse/client.conf that needs to be set to autospawn = no to turn off this behaviour. With this, my script started to work again.

Further pointers:

New blog (software)

written by nouri, on Mar 15, 2009 2:06:00 AM.

I have a new blog now. This one's running Zine. I'm redirecting the old RSS and Atom feeds to Zine's Atom feed. I hope that this doesn't blow up someone's RSS reader. I decided not to import the posts from the old Atom feed (which Zine allows you to), because I'd lose comments. That's why the old blog will just stay online for the time being.

So update your bookmarks and readers and whatnot!

I decided to switch from my old blog running PyBlosxom for a couple of reasons:

  • I'm trying something new
  • PyBlosxom doesn't do tags (or: more than one category)
  • It doesn't do threaded comments
  • PyBlosxom's code is somewhat messy

Now what I really like about PyBlosxom though is its ability to render your blog from a bunch of files on the filesystem. You have a couple of folders, which represent your categories, and a couple of text files in those; your blog posts. Zine uses a technology called SQL database instead (wink), which is alienating in comparison.

The second thing I like about PyBlosxom is that those text files can use the reStructuredText format, which is my favourite markup language. Zine doesn't do this out of the box. There's this rst plugin floating around, but it didn't really work for me. And so I decided that instead of debugging this obscure reST-0.2.plugin file, and to warm up to Zine, I'd write a little reStructuredText plug-in myself.

You can get the plug-in here. If you have trouble like me to install it through Zine's admin interface, try restarting your Zine after installation. Here's the code for those who like code:

import docutils.core
from zine.i18n import _
from zine.parsers import BaseParser
from zine.utils.zeml import parse_html

class RSTParser(BaseParser):
    """A reStructured Text parser."""

    name = _(u'reStructured Text')
    settings = dict(file_insertion_enabled=0,
                    raw_enabled=0,
                    output_encoding='unicode',
                    input_encoding='unicode',
                    initial_header_level=4)

    def parse(self, input_data, reason):
        parts = docutils.core.publish_parts(
            input_data, writer_name='html',
            settings_overrides=self.settings)
        return parse_html(parts['html_body'])

def setup(app, plugin):
    app.add_parser('restructuredtext', RSTParser)

(The clever programmers see that it's still lacking support for Pygments.)

Update: There is Pygments support now, and I've changed the link to point to the updated version.

You can see that it's easy enough to extend Zine with a plug-in like this. (There's only a metadata file that you also need to put into your module.) But, I'm somewhat irritated that Zine's not using setuptools eggs and entry points for distribution and installation. Zine seems to have a general aversion to setuptools; to install Zine itself, one is advised to ./configure && make install.