Fire & Forget bash script for Ogg and MP3 ReplayGain tagging

24 08 2009

I love music, and always want more. (Check out MagnaTune, AmieStreet and EMusic for fabulous, non-Apple music stores, and Jamendo for an amazing collection of free Creative Commons licensed music). From these sites I have a ton of music in both MP3 and Ogg Vorbis formats.

The more music you have, the more likely it is you’ll want to replay-gain it, probably in album mode – that is, make it so that all albums appear to be at the same volume when playing. Differences between songs in an album are preserved, so Princess Leia’s theme will be soft and delicate, while the Imperial March will blast you out of your seat. But you won’t have to constantly adjust the volume between albums any more, just because John Williams records proper music and the latest Britney Spears album is loudness-compressed to hell and back. Read the link above to see what I’m talking about, and how it works.

There are a lot of graphical tools to do this on Windows, look for example at the excellent Foobar music player. There is at least one for Linux too, the ExFalso tool included with the QuodLibet music player, installable under Ubuntu with a simple sudo aptitude install exfalso.

But when you have thousands of songs, spread over hundreds of directories, this can become quite a chore. Scripting to the rescue! It’s a slight bit tricky though, since on the command line you have to use mp3gain -a -k *.mp3 to adjust MP3 files, and vorbisgain -a -f *.ogg to do the same for Ogg files. And on top of that, mp3gain only writes APE tags, not ID3 tags which are recognized by many more players.

Luckily I found a good solution at http://zuttobenkyou.wordpress.com/2009/03/26/adding-replay-gain-in-linux-automatically/. There is a bash script that will go recursively through your folders, looking for music files, and also a Python script called by the former script that will copy mp3gain’s APE tags to an ID3v2 tag section in the file. The only problem I had with this setup was that it would only work on MP3 files, while I wanted to have the script work on both formats, so I could just fire and forget the script.

I created my own bash script that looks like this:

#!/bin/bash
originaldir=$(pwd)
#echo $originaldir
find -type d -print0 | while read -d $'' dir ; do
  echo -n $dir
  files=$(ls "$dir"/*.ogg 2> /dev/null | wc -l)
  if [ "$files" != "0" ]
  then
    echo " ...ogg!"
    cd "$dir"
    vorbisgain -a -f *.ogg
    cd "$originaldir"
  else
    files=$(ls "$dir"/*.mp3 2> /dev/null | wc -l)
    if [ "$files" != "0" ]
    then
      echo " ...mp3!"
      cd "$dir"
      mp3gain -a -k *.mp3
      rg-ape-to-id3.py *.mp3
      cd "$originaldir"
    else
      echo
    fi
  fi
done

I saved this somewhere in my $PATH with the name allgain.sh.
Then I took the Shinobu’s python script shown at the link above and saved it next to the bash script, with the name rg-ape-to-id3.py. Now I can simply go to the root folder of my music library and run allgain.sh. After a while, all my music files will be tagged and ready to go.

Thanks to Shinobu for the original script and the Python code!





Downmixing Super-Separated Stereo Files with Sox

17 04 2009

I have a bunch of MP3s here with old Amiga MOD-music in them. If you don’t know what that is, you are missing out on a great chapter of computer music from the early 90s. Read more at Wikipedia.

There are many programs for playing the old MOD files, just see the Wiki entry. There is one problem though: If you have these tracks not as MOD, but alreadys converted to MP3 or something like that, you might find that they sound a bit weird, especially with headphones. You’ll hear some of the instruments only on the left, and some only on the right. The Amiga had 4 audio channels, 2 left, 2 right, and there was no overlap between them. If you just have speakers standing somewhere that usually isn’t a problem, but nowadays many people use headphones, and in that case it really sounds weird.

One could simply downmix them to mono now, but that wouldn’t sound very nice either. What we really want is to create a balanced mix, with left and right fully present on the left and right, but a bit of each channels sound mixed into the other channel. Personally, I found a mix of about 70% toward the “other side” to sound quite nice.

This can more or less quickly be done with any kind of sound editor like Audacity, but if you have more than two or three such files, it quickly becomes tedious. Luckily, there are command line tools that easily lend themselves for batching. One of them is Sox, the “Swiss Army-knife of sound conversion.” To quickly go through several directories worth of tracks, I wrote a small bash script that looks like this:

#!/bin/bash
target="adjusted"
mkdir $target
for file in "$@"
do
  tmpfile="$target/$file.tmp.wav"
  oggfile="$target/$file.ogg"
  sox "$file" "adjusted/$file.tmp.wav" mixer 1,0.7,0.7,1
  oggenc -q 5 -o "adjusted/$file.ogg" "adjusted/$file.tmp.wav"
  rm "$tmpfile"
done

I then simply change into the directory containing the files, say “downmix.sh *.mp3” and a few moments later I have a subdirectory “adjusted” that contains fresh ogg files with the properly downmixed tracks.

If you just want to use this, go ahead, install the packages sox and libsox-fmt-all on your Ubuntu machines, and copy&paste the above script into a file called “downmix.sh”, chmod u+x it, and you’re ready to go. If you want to know what it actually does, read on for a quick overview.

The script iterates over all arguments, so you could call it with “downmix.sh file1 file2 file3” or “downmix.sh *.mp3“, which is really the same thing, since the latter gets expanded by bash to the former. Sox is called for each file to decode it into a WAV file, while using the mixer effect to, well, mix the audio channels. The argument for this effect is a comma-separated list of relative values that tell it how to mix. 0 means “no sound”, 1 means “100%”. The first number is left input on left output, the second is left input on right output. #3 is right input on left output and finally #4 is right input on right output. My choice of 1,0.7,0.7,1 therefore keeps the left channel on 100% and adds it with 70% volume to the right output channel too, thus moving it perceptually much closer to the center. The latter two parameters do the same with the right channel – it’s sent with 70% of its volume to the left output, and then with its full strength to the right output.

Now I finally can listen to some of my favorite music properly with headphones.





Putting CapsLock to good use

27 01 2009

One of the most useless keys on any computer keyboard is CapsLock. It might be useful IF YOU ARE PRONE TO YELLING AND USING LOTS OF !!!!!11!!!!!, but in that case I don’t want to read anything you write :-)

One can put CapsLock to a better use by remapping it to produce a different signal. What signal that may be is up to your personal needs. Personally, I have it remapped as AltGr (right Alt key). On a German keyboard you have to rather awkwardly press AltGr+7,8,9,0 to get the braces and brackets {, [, ], } we developers need so often. With the remapping, I can comfortably press the CapsLock key with my left hand and the key for the brace I need with the right.

How is it done? For Linux (or anything with X windows, probably), you just create a file called .Xmodmap (note the dot in front!) with the following contents:

keycode 66 = ISO_Level3_Shift NoSymbol

After logging out and back in, Xmodmap might ask you to confirm you really want the remapping, and then You’ll have CapsLock working as AltGr.

For Windows, you need to edit the registry:

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,38,e0,3a,00,00,00,00,00

For convenience, you can copy&paste the above text into a file called “caps2ralt.reg”, double click it, and Windows will automatically import the setting into its registry. One reboot later you too will have your CapsLock uselessness fixed. (The registry is a fragile and horrible piece of cruft, it may have a nervous breakdown any time you touch it. You edit it at your own risk!)





Showing the current Git branch in your bash prompt

2 12 2008

I came across a neat way of always being aware of what Git branch you’re working on: just show it in your bash prompt. I like the idea, but the way it’s shown gives you a completely new prompt, overwriting your existing configuration. I changed it a bit and came up with this:

function parse_git_branch_and_add_brackets {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\[\1\]/'
}
PS1="$PS1\[33[0;31m\]\$(parse_git_branch_and_add_brackets)\[33[0m\]\$ "

This will take your original bash prompt and add the [branch] information to the end, like this:

calle@gutenbook:~/dev/git/ddt[master]$

Useful!





Slowly understanding monads

3 07 2008

Since I am still in the process of learning Scala and the new functional concepts it brings to the Java world, I so far remain somewhat fuzzy about the whole concept of Monads. One problem is likely that my computer science studies at university were actually called “Applied Computer Science & Media“, which means there was a lot of media and not as much computer science as I would have liked. Hence, I’m a bit weak on some of the theoretical aspects. Nonetheless, I’m very interested in it all. But so far, while I think I have understood some parts of what is said about Monads, I haven’t really had the feeling that I got it all in my head.

But a new blog post by Eric Torreborre helped to understand a bit more. In Everyday Monads he sheds some light by using clear, understandable and useful examples. I am well aware that this is nowhere near a complete definition or explanation of monads, but it certainly helped. For the first time I really had this “lightbulb going off” feeling for this topic. Thanks, Eric!





Hauppauge WinTV Nova-TD on Ubuntu 8.04 Hardy

11 06 2008

The Hauppauge WinTV Nova-TD USB DVB-T receiver is recognized out-of-the-box by Ubuntu 8.04 Hardy, and the proper /dev/dvb devices are created as is said in Case 1 of this page at linuxtv.org. However, Kaffeine did not find any channels when scanning. Two things helped:

  1. This receiver has two tuners and thus two antenna sockets. /dev/dvb/adapter0 is the one on the side of the stick. If possible, use that one, since it is the first one checked. For some reason, the other tuner wasn’t always checked, which might have something to do with point 2 as well. With adapter0, I managed to get some channels, but not all. One bouquet of channels was in a different frequency range, and only produced warning messages on the console about a frequency being out of range.
  2. Get the latest drivers and build them yourself according to Case 2 of said linuxtv.org page. It really is easy:
    • Grab the headers and build tools.
    • Check out the latest driver source.
    • make && sudo make install
    • Reboot.

    If that sounds daunting, don’t worry. It is well described on linuxtv.org and really isn’t that hard. Afterwards, I was able to tune in to all channels that should be available at this location.





How to get Firefox and Eclipse to look nice on Linux/Ubuntu

29 05 2008

After installing Ubuntu Hardy on my new laptop, I noticed a few slight problems. Firefox would sometimes display ugly large fonts, no matter what I set up in its preferences.

It turns out something is weird with the DPI settings – probably something in Ubuntu, but I’m not sure. Anyway, after some googling I found out how to just override the DPI detection and set it to a good value. Go to about:config and set layout.css.dpi to 96 (or whatever your display’s DPI is – I found 96 to be good on a normal laptop screen). And all of a sudden, fonts look nice.

Something very similar was happening in the Javadoc viewer of Eclipse. The fonts were much too large, and curiously didn’t respond to preference changes in Eclipse either. Of course, on Linux Eclipse just uses Mozilla’s rendering engine to display Javadoc, since Javadoc is basically HTML. But Eclipse provides no interface to set preferences on the embedded Mozilla. Again, Google to the rescue. The “profile” used by Eclipse’s embedded Mozilla is at ~/.mozilla/eclipse. And if you know your way around these profiles, you can now do basically anything. To apply the above setting, simply append this to the file prefs.js:

user_pref("layout.css.dpi", 96);

And lo and behold, the Javadoc view is no longer an eyesore.