Jun 10 2008

My Studio

Well, I’ve spent two days doing actual work in my studio and I can now confidently report my settings for the benefit of Linux-running MacBook users (and other related hoodlums).

I won’t go into the detail that I did in the previous posts, most of which is still relevant.

I pass the option position_fix=3 to the module snd-hda-intel. I did this by creating /etc/modprobe.d/local, containing:
options snd-hda-intel position_fix=3

then running sudo update-initramfs -uk all.

I set up my Gnome session to run QJackCtl, which is in turn configured to start JACK on startup. My JACK settings (from ~/.jackdrc) are:
/usr/bin/jackd -R -t2000 -dalsa -dhw:0 -r48000 -p1024 -n2 -s

JACK is extremely stable. I’ve had 2, maybe 3 xruns through two days of work, and those were when starting up applications, not when actually using them.

Now, since we have only one audio device and JACK has monopolized it, and we want to hear other than JACK, we need more configuration. Here is my ~/.asoundrc:

# Set the default device to PulseAudio for all well-behaved ALSA applications
pcm.!default {
        type plug
        slave.pcm "pulse"
}
ctl.!default {
        type plug
        slave.pcm "pulse"
}

# This device can come in handy, but I mostly don't use it.
pcm.jack {
        type plug
        slave {
                pcm {
                        type jack
                        playback_ports {
                                0 alsa_pcm:playback_1
                                1 alsa_pcm:playback_2
                        }
                        capture_ports {
                                0 alsa_pcm:capture_1
                                1 alsa_pcm:capture_2
                        }
                }
                rate 48000
        }
}
ctl.jack {
        type hw
        card 0
}

# The acutal PulseAudio device
pcm.pulse {
        type pulse
}
ctl.pulse {
        type pulse
}

Now all well-behaved ALSA programs will use the default ALSA device, i.e.
PulseAudio. PulseAudio needs to be configured now to use JACK. You’ll need to
get the pulseaudio-module-jack package, which probably means you’ll need to
build it yourself. I show you how to do that and how to configure PulseAudio in
a previous
post
.
Incidentally you need to do the same for libasound2-plugins if you want to
use the JACK plugin for ALSA as in my asoundrc above.

Now we have a bit of a chicken and egg problem. PulseAudio starts when you log
in, and so does JACK (by way of QJackCtl in your Gnome session). But PulseAudio
will fail to start if JACK isn’t already running. What’s more, if you decided
you wanted to restart JACK for whatever reason, you’d have to restart
PulseAudio too. So here’s how I solved it. I leave ESD enabled in the Gnome
sound settings, knowing that it will fail to start (and I won’t get the really
cool Ubuntu Studio startup ditty, but oh well). It needs to be checked if you
want Gnome to make nifty system sounds. Now, in QJackCtl setup, on the options
tab, check the box for “Execute script after Startup” and put “pulseaudio -D
in the box. Now PulseAudio will start whenever JACK starts, and it will
stop/crash/whatever whenever JACK stops.

Now, you need to install libflashsupport to get Flash working with
PulseAudio. Even so you might find occasional sites that crash it.

That about covers it. If you do much work with audio applications using
complicated JACK graphs, don’t overlook the power of QJackCtl’s patchbay, which
will automatically hook things up. I have a patch that will connect Aeolus to
system output 3&4 (headphones/external speakers), and hook my MIDI keyboard to
Aeolus. So all I have to do is start Aeolus and pull some stops and I’m ready
to play.

Which reminds me, there’s still the annoying thing about JACK having 8 outputs
(for surround sound) and the internal speakers are on outputs 1&2, and the
headphone jack is outputs 3&4. If you’re not getting sound from a JACK app and
you think you should be, that’s the first thing to check. Someday I plan to
figure out the .asoundrc magic needed to set up JACK so that it’s a regular
stereo device sending sound to both the internal speakers and headphones. If
you know how, please enlighten us in the comments. I know it can be done, I
just haven’t put in the time to figure it out and test it.


Dec 15 2007

A Patchwork Quilt

“Patches welcome!”

It’s a common exclamation in the open source world. In many ways, it’s at the very center of the open source development model, especially the bazaar style. Sometimes flippant, sometimes derisive, sometimes earnest, sometimes pleading, always at least half true.

You may be familiar with how to use diff to create a patch. Just to quickly recap, you make a copy of the original file(s), make your change(s), and use diff to make a patch. Not too hard, but there’s lots of intricacies to get wrong, or if not wrong then against the cultural grain. You need to make a level 1 patch, you need to make a unified diff, etc. The human overhead in making copies of files and constructing diff command lines is significant, so some smart people naturally wrote scripts to automate it. Andrew Morton was one of these smart people and wrote a set of patch scripts for working on the Linux kernel. Then Andreas Grünbacher tweaked them, generalized them, and released them as Quilt.

Quilt makes patch management much simpler. I won’t go into all its capabilities or usage, for that I recommend the excellent paper How to Survive with Many Patches or an Introduction to Quilt. I will give you a use case and show you how quilt applies.

I contribute in a small way to the project FlightGear. I don’t have CVS access, so any contributions I make are in the form of bug reports or sending patches to the development list. Let’s take the use case of fixing a compilation bug on my platform (OS X Leopard), from the beginning.

First I download the tarball and extract it somewhere. Quilt happily works over
any directory structure, it could be CVS or any other VCS, or just an extracted
tarball, or whatever.

Next I try to build it and notice that it fails to build. Now I know there’s a patch to be made, so I tell quilt about it:

~/fg/FlightGear-0.9.11-pre2$ quilt new leopard.diff
Patch leopard.diff is now on top

Now, I edit the file in question and fix the bug. Quilt needs to know ahead of time which file(s) I’m going to edit so it can make copies of the originals and create the diffs. So whenever you’re constructing a patch, you use quilt edit foo instead of $EDITOR foo. You might alias qvim='quilt edit'.

~/fg/FlightGear-0.9.11-pre2$ quilt edit foo

Lather, rinse, repeat until you’ve created a totally tubular bugfix. Then, tell quilt to update the patch file (which is stored in patches/) with

~/fg/FlightGear-0.9.11-pre2$ quilt refresh

Finally, submit the patch from patches/ however your project likes to get patch submissions. Since I use gMail for this list, I usually just type quilt diff and copy & paste it into the message. For another project or a one-off patch I’d probably use mutt -a patches/leopard.diff foo@example.com. Quilt also has facilities for sending patches by mail.

Later you may want to start a new patch for a new feature, or a different bug. Just quilt new and begin working on it. If you at some point want to unapply a certain patch, or all of them, you want quilt pop. Likewise you can quilt push. You can import other people’s patches, edit and refresh your patch until you get it just right, etc. Quilt is a powerful but easy-to-use tool for all your contribute-to-open-source-software-without-commit-access needs.

As an afterword, let me describe how I used to try to do this in general and for FlightGear in specific. In general, I’d just make a copy of the original source tree whenever I remembered to do so which is almost never. When I forgot, I’d have to move the modified one somewhere else and untar a fresh copy. It was error prone and wasteful but it worked for the single-patch use case. On large projects that I want to contribute to more than once, like FlightGear, I used to go through all sorts of gyrations trying to make a bridge from CVS to some distributed VCS using Tailor, and then try to generate meaningful diffs from my sister repositories and somehow manage to merge things back in that were changed. This is especially annoying for changes you manage to get committed, which all of a sudden are conflicts (depending on how smart the merger is and whether they modified your patch or applied it as-is). Then, I ran into the very annoying disadvantage that several other people were doing the same thing, with the same VCSes, and yet we couldn’t interoperate because we had all set up our own tailor scripts and the repositories were completely independent even though semantically they were just branches of the same thing. It got very complicated and had very few benefits in real life. I finally came to the conclusion that what I was doing was generating and applying patches to the canonical sources, and when I finally figured that out it became apparent that using Quilt was the right thing to do. I can still keep the quilt stuff in revision control. Sometimes I use Mercurial Queues (based on Quilt) instead for more integration, but Quilt is usually sufficient.

I encourage you to give Quilt a try next time you need to make a patch. You won’t be sorry.