Making ‘find’ simpler on linux

The “find” command, which searches directories for files, is great but requires a lot of options to perform a simple search. Usually I want to search the current directory for a specific file name, but doing that requires all this typing:

find ./ -iname "*my_search_term*"

What I would like to be able to is just type:
f my search term

and have it match files that look like that. Here’s a little bash script I call “find.sh” that does it:

#!/bin/bash
args=`echo "$*" | sed -e "s/ /*/g"`
eval find ./ -iname \"*$args*\"

then just put the following in your ~/.bashrc
alias f="/location/to/find.sh"

This script takes the arguments, converts spaces to wildcards, then does a case-insensitive search of the current directory. So “f foo bar” gets translated to find ./ -iname "*foo*bar*"

Adventures in not actually frying my USB bus

Well, that was exciting. I had an unplanned adventure in technical troubleshooting today.

The symptom: USB isn’t working properly. Low-speed 1.1 devices work, but USB 2.0 appears busted. Rebooting doesn’t fix the problem. Trying other kernels doesn’t fix the problem. The problem also exists in Windows. All googling indicates possible hardware failure. Shit.

I really didn’t want to call tech support, so I actually ran the Dell Diagnostic help tree that comes with their installation of windows. Some of the questions are obvious, like, are the ports physically damaged, but as you drill down it makes a very helpful suggestion: Try running the diagnostics program that came with your computer!

In my case, Dell has a program that will burn a bootable CD. That CD will test the entire system, including the USB subsystem. Interestingly, the diagnostic came back clean. How can USB be busted if the tests are ok?

Ultimately, I have no idea, because when I rebooted into Windows the problem was gone. Booting back into linux, the problem was fixed there too. And here I thought I would have to replace the motherboard because of a burnt-out usb system.

The first moral of the story: It is possible for linux to fuck up USB so bad, a reboot and power-cycle won’t fix it.

The second moral of the story: It’s really nice to have windows around when you want to see if a problem is linux-specific, or hardware-specific. (The same goes the other way. If you have windows installed, it’s nice to have a linux installation, or at least a boot disc, so you can try stuff out.)

The third moral of the story: Even if you think you are technically able, don’t jump to the conclusion that a problem is fucked hardware. Go through the motions of troubleshooting the problem, and who knows, it might actually be fixable without mailing your part in for service. I was this close to calling Dell, and there would have been no need.

Edit:
Hrm. Well, the usb died again. This time the dell diagnostic didn’t bring it back. Time to call tech support

Edit 2:
Double hrm. Spent an hour on the phone and screen sharing with Dell tech support, who proved completely immune to my evidence that this was a hardware issue, not a software issue. They installed some driver and the problem went away, but I think it’s just like last time — it randomly fixed itself and the problem still remains. The best part was when the tech support person suddenly decided to become a sales rep and asked me why I hadn’t bought dell’s extra Accidental Protection Plan or some shitty tuneup software. Way to put progressbar time to good use, assholes.

More Audio 4 DJ tricks

In my DJ setup, I use the JACK sound server to link my mixing program to a bunch of fun effects. It is possible to get JACK to perform at extremely low latencies (~6ms and less) but it’s hard to get all the options just right. For the benefit of others who don’t want to go through the same trial and error I did, here is the command line I’m using to launch jack:

jackd -R -P 99 -p128 --timeout 4500 -d alsa -d AUDIO4DJ -p $size -n $periods -i 4 -o 4 -r 44100

Here’s what all that means:

  • -R: Realtime mode
  • -P 99: Realtime Priority value (maxed out)
  • -p 128: max jack ports
  • –timeout 4500: client timeout in ms. This is very important, because Mixxx might hang for longer than the default 500ms when it’s loading tracks. If that happens, JACK kicks out Mixxx and playback stops
  • -d alsa: Use ALSA backend

(Note, after this argument, the rest of the arguments are ALSA-specific

  • -d AUDIO4DJ: use the AUDIO4DJ alsa device (see my previous post)
  • -p $size -n $periods: These two options are what determines the size of the sound buffer. The first number is the frame size, in bytes (I think). The second is the number of frames. Multiply the two together to get the total size. With a special realtime kernel, I can set this to 64 and 4 (total: 256, or about 6ms). With a standard kernel, it has to be 128 and 3 (total: 384, 9ms). The idea is you want to get the total multiplied number as small as possible without inducing the dreaded XRUN, which happens when your computer can’t feed audio to the sound card fast enough.
  • -i 4 -o 4: 4 inputs, 4 outputs
  • -r 44100: CD-rate audio

Yeah, I know, if I just bought a mac and Traktor or Serato I wouldn’t have to deal with this shit, but I’m cheap and can’t resist a challenge.

Native Instruments Audio 4 DJ on linux

The Native Instruments Audio4DJ is a professional-quality USB soundcard for DJing that is also supported under linux. Like mode devices that are “supported” under linux, however, it can be tricky to set up correctly. In my case, I need the device to work with the JACK sound server, and I needed to do a little extra work.

The first trick is setting up ALSA so that JACK works happily with the card. The problem is that the drivers don’t supply any regular mixer controls for the Audio4DJ, which makes jackd unhappy. So when creating a .asoundrc, it’s necessary to substitute the internal soundcard as the mixer elements for that device. Putting this text in ~/.asoundrc does the trick:

pcm.AUDIO4DJ {
    type multi;
    # bind hardware devices
    slaves.a.pcm "hw:1,0,0";
    slaves.a.channels 2;
    slaves.b.pcm "hw:1,0,1";
    slaves.b.channels 2;
    # bind channels to virtual device;
    bindings.0.slave a;
    bindings.0.channel 0;
    bindings.1.slave a;
    bindings.1.channel 1;
    bindings.2.slave b;
    bindings.2.channel 0;
    bindings.3.slave b;
    bindings.3.channel 1;
}

# JACK will be unhappy if there is no mixer to talk to, so we set
# this to card 0. This could be any device but 0 is easy. 
#note that audio4dj is actually card 1 -- we are faking mixer elements so JACK is happy:

ctl.AUDIO4DJ {
        type hw;
        card 0;
}

The second question is how to change the input mode of the Audio4DJ from phono to line and back. Normally this type of setting would be found in the alsamixer program, but for some reason it’s hidden away. This script makes it easy:

#!/bin/bash

if [ "$1"x == "x" ] ; then
	echo "$0 [phono|line|timecode]"
	exit 1
fi

dev=`aplay -l  | grep Audio4DJ | grep "device 0" | cut -d\  -f 2 | cut -d: -f 1`
if [ "$dev"x == "x" ] ; then
	echo "Audio 4 DJ not connected"
	exit 1
fi

result=0
if [ "$1" == "phono" ] ; then
	amixer -c $dev cset numid=1 2 > /dev/null
	result=$?
elif [ "$1" == "line" ] ; then
	amixer -c $dev cset numid=1 1 > /dev/null
	result=$?
elif [ "$1" == "timecode" ] ; then
	amixer -c $dev cset numid=1 0 > /dev/null
	result=$?
else
	echo "$0 [phono|line|timecode]"
	exit 1
fi

if [ $result -ne 0 ] ; then
	echo "Error setting Audio 4 DJ input"
	exit $result
fi

Synchronizing baseball radio with TV part 2: the new season

Last year, I wrote a post about using linux and JACK to delay baseball radio broadcasts by 7 seconds in order to bring it into sync with the TV broadcast. Well, today’s broadcast is on FOX, so that provided all the encouragement I needed to get my setup working again. I have since upgraded my laptop, so I was expecting to spend another seven innings getting JACK to work again.

Luckily it was much easier this year. All I had to do was start JACK like this:
pasuspender qjackctl

On modern versions of linux, there’s a system program called “pulseaudio” that normally takes care of all the sound on the system. JACK isn’t compatible with pulseaudio, so it’s necessary to disable pulseaudio while jack is running. Thankfully there’s a little program called “pasuspender” that disables pulseaudio while a specified program is running. So the command above disables pulseaudio while jack is running.

After that, I just had to reproduce the various connections in the screenshot I posted and it all worked. No special kernels, no editing of security files. Phew.

How to watch post-season baseball without wanting to stab yourself in the face

You want to watch the post season, but you can’t stand the awful, brain-dead commentary. What do you do? Well, if you use linux, you can spend 7 innings out of nine trying to get jack audio to work — which, when it finally does work, does the job well:

Using jack to delay audio

For those who aren’t familiar with JACK, it’s a “professional”-quality audio library that’s designed for low-latency audio routing and mixing. It’s great if you want to easily pipe audio from one application to another. In this case, I want to take the baseball AM radio broadcast, feed it into my laptop, delay it 7 seconds, and then output it.

So, you can see in the “Connections” window (using the program qjackctl) that the system input is tied to a program called jack-rack, and then jack-rack is fed back to the system output. Jack-rack is a program that supports many interesting audio plugins, like echos, flanges, pitch changes… and delays. Here, I have a seven second delay turned on.

And that’s it. All the difficulty with JACK is getting it to work without stuttering or skipping, which required that I install a “realtime”-quality kernel, edit files in /etc/security, and tweak all sorts of stupid options. As I say, it took me 7 innings of Game 6.

But now it’s working, and I can enjoy game 7 with good commentary from the very beginning!

(It occurs to me I should have gotten this working sooner in the season, but I had forgotten just how bad the national announcers were)

edit: Ah yes, why the delay at all? Because the HD feed is delayed by 7 seconds compared to the radio broadcast. I probably should have mentioned that.

Starting a user-controlled streaming radio station

The dream:
I want a streaming radio station for my company that itunes can tune in to, where anyone at work can upload tracks and add them to the playlist.

The ingredients:

Explanation:
MusicPD is an awesome music server that I’ve talked about before, and it would be perfect for setting up my little radio station. Users would be able to add files to the playlist from any browser, and mpd now supports shoutcast, which should make turning it into a streaming station easy.

However, right now mpd only supports shoutcast streaming in OGG Vorbis format, and iTunes can’t play OGG. Since everyone in the office is on iTunes, I need some way of getting mpd to spit out mp3 to icecast.

Enter JACK! Jack is a “pro-audio” subsystem for connecting applications, kind of like shell pipes for audio. It can be kind of daunting to work with, but in this case it’s best to just think of it as glue connecting one program with another.

For instance, mpd has a JACK output plugin, and there’s another program, Darkice, that has a JACK input and sends audio to icecast. I can link mpd and darkice with jack, and that should solve my mp3 problem.

So, to review:
mpd (links via JACK to) darkice (which encodes mp3s for) icecast (which streams to) itunes

The Wrinkle:
Make it work on a mac server. At work we don’t have a recent machine running linux that’s up all the time and that isn’t mission-critical, so I have to make due with one of the mac workstations. Luckily macports will do a lot of the heavy lifting.

A Note:
This took a lot of building, installing, and configuration that I don’t have space to cover here. I’m trying to record everything I did that was abnormal or not obvious. If you’re comfortable installing software on unix and you know how to configure a program based on the examples and READMEs, there should be enough information here to reproduce my work.

Getting the software:

  1. Install macports on the mac
  2. Install the following ports: apache2 faac faad2 flac id3lib mad lame libid3tag libvorbis speex
  3. Install this port: php5 +apache2 +macosx +pear
  4. Install the following by source: curl, jack (do not use “jackosx”, build it from source), icecast, darkice, mpd
  5. Apply my patch to mpd/src/audioOutputs/audioOutput_jack.c to make it work on mac osx.

Details:

JACK:
Built with these options: ./configure --prefix=/opt/local --with-default-tmpdir=/tmp
I just start JACK with jackd -d dummy -r 44100

If I don’t specify a default tmpdir, jack crashes complaining it can’t stat /dev/shm. I don’t need to use a real audio device in jack because I’m not outputting the audio to the speakers.

Icecast:
built with ./configure --prefix=/opt/local
No special configuration needed other than what’s specific to my site.

Darkice:
Built with ./configure --prefix=/opt/local/ --with-lame-prefix=/opt/local/ --with-vorbis-prefix=/opt/local/ --with-faac-prefix=/opt/local/ --with-jack-prefix=/opt/local/
I probably didn’t need all those options, but heck, it works.
I set up the configuration file so that the audio device is jack (no quotes).

MusicPD:
built with ./configure --prefix=/opt/local --with-faad=/opt/local --with-libFLAC=/opt/local --with-mad=/opt/local --with-libvorbis=/opt/local/ --with-id3tag=/opt/local
I set up the configuration file to use jack as a device. I need to tell mpd to connect to darkice when it starts up, but darkice picks its port names based on its pid, so it’s always different. What I did is create mpd.conf.in, with this as the device config:

audio_output {
type "jack"
name "MPDJack"
ports "darkice-REPLACEME:left,darkice-REPLACEME:right"
}

Then I run a script to actually start mpd:
#!/bin/bash
pid=`jack_lsp | grep darkice | cut -d '-' -f 2 | cut -d ':' -f 1 | uniq`
cat mpd.conf.in | eval sed -e 's/REPLACEME/$pid/g;' > mpd.conf
mpd ./mpd.conf

Putting it all together:
Once all of those pieces are in place, I can start the radio station by starting the various programs in this order:

  • Jack first,
  • then icecast,
  • then darkice, (-v 10 for debugging)
  • and finally mpd. (--verbose --stdout --no-daemon for debugging)

That’s it. I can control the mpd server and it plays music. If I run jack_lsp -c -p I can see mpd is connected to darkice. I can tune in to the icecast stream from itunes and hear it. With simple mac file sharing, users can connect to the server and drop music in the database. Then mpd can either rescan every hour or so with cron, or when the user clicks “update db” in pitchfork.

Setting up pitchfork is left as an exercise for the reader.

Linux Tip: How to clear some room

I’ve been running out of disk space on my laptop. Multiple development environments, vmware images, my music collection, and especially my camera RAW originals take a heavy toll. Most data on a computer is already highly-compressed, but the whole idea behind RAW files is that they are not compressed — they represent the original image sensor data. So, here’s a one-liner I used for freeing up some disk space. (I have an Olympus camera, whose raw file format has the ORF extension.)

find ~/Documents/images/photos/raw -name "*.ORF" | xargs -n 1 bzip2

Just using standard bzip compression reduces each file by about 50%. And, since I had 10 gigs of raw files, that translates into 5 gigs of space I’ve freed up.

Ubuntu Fonts

An update was recently pushed to ubuntu that updates fontconfig, one of the programs involved in rendering text on the desktop.

DOWNLOAD THIS UPDATE!

I’m not sure what they did, but my fonts look noticably clearer, better defined, and sharp. It’s really quite beautiful. Also, the various options in the font dialog (specifically the hinting levels) finally work, so I can see the difference. I don’t know who is responsible for finally getting this right, but thank you!