My audio toolchain

A Tech article with View Comments posted 29 December 2006.

I try to manage the audio I’ve accumulated over the years in the easiest possible way, so I’ve developed this routine using Ubuntu that some people might find useful.

When I get a new CD, I rip using SoundJuicer. I have a decent stereo system, and I don’t want the artifacts from mp3 or ogg compression, so I rip it to FLAC (Free Lossless Audio Compression). You do that in SoundJuicer by selecting “Edit > Preferences” and using settings like these:

SoundJuicer Preferences

Make sure that all of the track titles and such are correct, then extract the CD. You can use RhythmBox to play your music – it will read your music’s id3 tags and everything is hunky-dorey. You might be thinking “this isn’t rocket science – so what?” But we’re only half done.

I use a laptop regularly, and even though my speakers are nice (for laptop speakers), I can’t reproduce anything approaching CD-quality music. My laptop’s hard drive is also pretty small. Why carry around that extra audio data? So sudo aptitude install vorbis-tools installs oggenc, a transcoder from FLAC to ogg-vorbis (an mp3-like format that is much better sounding for the size of files produced).

Then just open a terminal, cd to the folder with your .flac files, and run oggenc *.flac. A minute or two later, you’ve got good-sounding .ogg files that are one-tenth the size of the flac files and have preserved all of the ooey-gooey metadata from the flac files.

Then just copy the flac files to a spare hard drive (maybe a computer powering the stereo?) and keep the ogg files to listen on the laptop.

Phantom Traffic Jams

A Tech article with View Comments posted 27 December 2006.
Tags:

Apparently I’m not the only person to have contemplated why inexplicable traffic jams occur – you know, the ones that have no apparent cause whatsoever? I had always suspected that it was due to some temporary slowdown which had become amplified, much like turbulence in a pipe of flowing fluid will persist long after the disturbance ends.

The engineer in me asks: Is there anything that can be done to mitigate this problem? Every solution I can think of has one (or more) of these problems:

  1. Requires every car to be outfitted with a special hardware
  2. Requires special hardware on every major highway
  3. Requires the cooperation of every driver

Is it possible that a single driver (you or me) could overcome by some strategy any part of this without cooperation from other drivers? Anyone have a better idea that doesn’t fall prey to the above problems?

Dynamic CSS/JS/HTML in Template Toolkit wrappers

A Tech article with View Comments posted 19 December 2006.
Tags: ,

I’ve been asked about this a few times on #tt, so I thought I’d provide it for future Googlers. If you’re looking to optionally include certain files in a Template Toolkit wrapper, it’s very easy. You just provide the file names as a parameter to the WRAPPER call.

First, the wrapper file itself, wrapper.tt:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>[% title %]</title>
<body>
[% IF includes %]
    <div id="sidebar">
    [% FOREACH include_file = includes %]
        [% INCLUDE $include_file %]
    [% END %]
    </div>
    <div id="content">
[% ELSE %]
    <div id="wide_content">
[% END %]

[% content %]</div>

</body>
</html>

And then you call the file like this:

[% WRAPPER wrapper.tt
    title = 'My Title'
    includes = [
        'includedfile1.tt',
        'includedfile2.tt'
    ]
%]

<h1>Content for middle</h1>

[% END %]

It’s pretty straightforward to adapt this to CSS or JS files, or whatever you need to customize in the wrapper.

Debugging long-running perl programs in Debian

A Tech article with View Comments posted 15 December 2006.
Tags: , , ,

One of the slicker ways I’ve seen of trying to figure out what Perl is doing in a long-running process is defining a signal handler, like so:

use Carp ();
$SIG{‘USR2′} = sub {
Carp::confess(“Caught SIGUSR2: Dumping stacktrace and dieing:”);
};

It works great, dumping the current stacktrace to STDERR. But if you’re stuck in a loop inside the perl interpreter, that user-level signal is never handled, and you don’t get anything. Foiled again! You’re going to have to use (gasp!) the GNU debugger (gdb).

While the advice offered in Debugging mod_perl and Debugging mod_perl C internals is useful, most of the magic with gdb doesn’t work unless you are running a perl with debugging symbols on. How do you get that in Debian-based distributions?

sudo aptitude install perl-debug

Then run the process:

/usr/bin/debugperl path/to/program.pl

Attach gdb:

gdb

attach Process ID

Define the curinfo gdb macro. (see Analyzing the Core File.) If you see “my_perl” in a gdb backtrace, you’re running threaded perl, otherwise use the unthreaded version of curinfo.

(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0xb7f78751 in accept () from /lib/tls/i686/cmov/libpthread.so.0
#2 0×081502de in Perl_pp_accept (my_perl=0×81c1008) at pp_sys.c:2565
#3 0×080d10b3 in Perl_runops_debug (my_perl=0×81c1008) at dump.c:1452
#4 0×08065c9b in S_run_body (my_perl=0×81c1008, oldscope=1) at perl.c:1995
#5 0×08065703 in perl_run (my_perl=0×81c1008) at perl.c:1919
#6 0×0805febd in main (argc=3, argv=0xbfccac44, env=0xbfccac54)
at perlmain.c:98

Looks like we’re running threaded perl, so define curinfo:

(gdb) define curinfo
Type commands for definition of “curinfo”.
End with a line saying just “end”.
> printf “%d:%s\n”, my_perl->Tcurcop->cop_line, \
my_perl->Tcurcop->cop_file
> end

Then use it:

(gdb) curinfo
196:/usr/local/share/perl/5.8.7/Catalyst/Engine/HTTP.pm
(gdb)

That’s what line was executing and what file you were in. It’s worth mentioning that this was not a buggy application, just an ordinary Catalyst application waiting for a connection. Not too exciting for ordinary perl debugging (much easier to run the process as perl -d), but when you’ve got an infinite loop in the perl interpreter (for example, an infinite loop in a regex), this can help point you in the right direction.

Scientific proof that students procrastinate

A Tech article with View Comments posted 4 December 2006.
Tags: , , ,

SAG2 load average 03 Dec 2006

This graph, from our new release of SAGrader at work, is proof positive that students wait until the last possible moment to complete their assignments. This is the average load on the server for an assignment that was due at 11:00pm on Sunday, December 3. And, happily, we weathered the onslaught with nary a hiccup!

Pictures of the snow

A Family article with View Comments posted 1 December 2006.
Tags: ,

Perfect line of snow at the garage door.Neighbor's car buried in snowMy thunderbird buried in the snowA look back at the house.Down the street - whiteout!Jennifer peeking out the front window

Nasty Winter Storm

A Family article with View Comments posted 1 December 2006.
Tags:

Just woke up to the results of a nasty winter storm here in mid-Missouri. Local TV is reporting 11 inches of snow, drifting to 2 feet. It’s really quite spectacular – I’ll try to post some pictures after sunrise. According to the National Weather Service, MODOT has suspended plowing operations, and parts of I-70 are closed. Good thing Jennifer and I don’t have to go into work!