How to resample MP3 audio files on Linux using LAME

August 10, 2008 by Linerd
Filed under: HowTo, Ubuntu, bash, lame, linux, mp3 

If you're like me, you're not willing to shell out several hundred dollars to buy an 80GB iPOD to carry and store your music collection. In my case, I chose the 4GB Sansa e260 as my music player. Having ripped my music at high bitrates for improved quality, I soon became dissatisfied with the capacity of my player. At that point, I decided to do some experimenting with LAME's different encoding options in order to determine what settings gave me the minimum file size while providing acceptable sound quality. For me, LAME's variable bit rate preset 5 provides a good compromise between sound quality and file size.

After determining my optimal file quality, I basically had two choices:

  1. Rip all of my CD's using these new settings, or
  2. Figure out a way to re-encode my existing files to the new bitrate.

Well, it turns out that LAME provides an easy option to resample mp3's without having to convert back to .wav first.

I'm using Ubuntu Linux, so these instructions should work for most Debian based Linux Distro's. The first step is to make sure that you have the required packages installed on your system. The packages you'll need for this process are lame and python-mutagen (which contains mid3v2). You can add them using one of the available graphical package managers, or from the terminal using apt-get.

sudo apt-get install lame python-mutagen

The LAME program doesn't provide a graphical interface, so we'll have to work in the terminal. Here's the basic command to resample a song.

lame -V5 --vbr-new --resample 44.1 song.mp3 song-resampled.mp3

This command does a great job of resampling and likely shrinking your mp3 file, but there are two drawbacks:

  1. Due to a bug (or missing feature) in the LAME code, the id3 tags are not copied into the resampled file. This means that it will show up in your player as Unknown Song by Unknown Artist.
  2. It's a pain to type this command hundreds of times to resample all of your music.

Because of the two problems above, I decided to write a script to automate the process. I actually ended up writing two scripts. The first script, mp3shrink, acts as the main program. It reads all of the mp3 files in a directory and feeds them to the second script, cptag, for resampling and copying the id3 tags.

I suggest placing the scripts in your private bin directory(~/bin). If you don't have one, just create it with:

cd
mkdir bin

So, here's the mp3shrink script. Copy the text and paste it into a text editor and save it as /home/myID/bin/mp3shrink.

#!/bin/bash
#
#mp3shrink - A script to resample all mp3 files in a
# directory.  This script calls the cptag script which
# must also be in the user's path. cptag depends upon
# lame and mid3v2 (mid3v2 can be found in the
# python-mutagen package).
#
# It is suggested that both the mp3shink and cptag
# scripts be placed in the user's private bin (~/bin).
######################################################

# List mp3's in current directory.
ls *.mp3 > mp3_list
ls *.MP3 >> mp3_list

# Parse the mp3_list and replace spaces with escaped spaces.
sed -i 's: :\\ :g' mp3_list

# Check if resample directory exists and create it if it doesn't.
if
   test -e ./resample
then
   echo "resample directory/file already exists - delete it? (Y/n)"
   read reply
   if
     [ "$reply" != "n" ]
   then
     rm -r resample
     mkdir resample
   else
     exit
   fi
else
   mkdir resample
fi

# Resample each mp3 and write tags using the cptag script
cat mp3_list |while read song
do
   echo "$song"
   cptag "$song"
done

#clean up
if
   test -e mp3_list
then
   rm mp3_list
fi
if
   test -e tag2.txt
then
   rm tag2.txt
fi
exit

OK, here's cptag. Paste the following text and save as /home/myID/bin/cptag.

#!/bin/bash
#
#cptag - A script to resample mp3 files with LAME and
#        copy id3v2 tags from the old file to the new one.
#
#####################

# Read id3 tags and write to file
mid3v2 -l "$1" > tag2.txt

# Resample music file

lame -V5 --vbr-new --resample 44.1 "$1" "resample/$1"

# Set value of variable 'title'
if
   grep TIT2= tag2.txt > /dev/null  #Test if title tag exists
then
   title=`grep TIT2= tag2.txt | sed "s:TIT2=::"`
   echo $title
else
   echo "Title tag does not exist."
fi

# Set value of variable 'album'
if
   grep TALB= tag2.txt > /dev/null  #Test if album tag exists
then
   album=`grep TALB= tag2.txt | sed "s:TALB=::"`
   echo $album
else
   echo "Album tag does not exist."
fi

# Set value of variable 'artist'
if
   grep TPE1= tag2.txt > /dev/null  #Test if artist tag exists
then
   artist=`grep TPE1= tag2.txt | sed "s:TPE1=::"`
   echo $artist
else
   echo "Artist tag does not exist."
fi

# Set value of variable 'track'
if
   grep TRCK= tag2.txt > /dev/null  # Test if track tag exists
then
   track=`grep TRCK= tag2.txt | sed "s:TRCK=::"`
   echo $track
else
   echo "Track tag does not exist."
fi

# Set value of variable 'genre'
if
   grep TCON= tag2.txt > /dev/null  # Test if genre tag exists
then
   genre=`grep TCON= tag2.txt | sed "s:TCON=::"`
   echo $genre
else
   echo "Genre tag does not exist."
fi

# Write tags to file
mid3v2 -t "$title" -A "$album" -a "$artist" -T "$track" -g "$genre" "resample/$1"

exit

Now, you'll need to make sure that the files are executable.

cd ~/bin
chmod u+x mp3shrink
chmod u+x cptag

You're now set to resample your music!

Just cd to the directory with your music files and type:

mp3shrink

The script will place your resampled mp3's in a sub-directory called resample.

Comments

5 Responses to “How to resample MP3 audio files on Linux using LAME”

  1. queen says:

    Thank you!!!

  2. Gerwin says:

    THE script I was looking for! But too bad the id3 tag is not written at least id3info does not show them ...

  3. AAM says:

    Thanks for the useful script. There were two parts that didn't work immediately for me:

    1. the chmod call didn't set the files to executable, so I used the Properties GUI to switch executable on

    2. the mp3shrink script needed cptag to be changed to ~/bin/cptag for it to work.

    But excellent nevertheless!

  4. Luca says:

    Hi,
    your script is great! Only a minor flaw i saw is with uncommon characters, such as Norwegian ones:
    with titles like this:

    TIT2=Inn I Evighetens Mørke (Part 1)

    grep returns a message like :
    Binary file matches

    which clutters all tags in the track.

    I have worked around it by adding the "--binary-files=text" to all grep commands in cptag, i.e.:

    # Set value of variable 'title'
    if
    grep --binary-files=text TIT2= tag2.txt > /dev/null #Test if title tag exists
    then
    title=`grep --binary-files=text TIT2= tag2.txt | sed "s:TIT2=::"`
    echo $title
    else
    echo "Title tag does not exist."
    fi

    Hope it helps.

    • Linerd says:

      Thanks for the tip. My scripts usually get to the point where they work for me and then I'm done.

      It looks like grep gets confused by the special characters and thinks the file is a binary file. So your modification forces grep to interpret the file as a text file. Good job figuring that out.

      Thanks for sharing your solution. Hopefully it will help someone else out there.

Leave a Reply