Interactive LAME-ifyer to convert WAV or AIFF files to MP3
I wrote this as a bash script because I wanted to accomplish two things that I didn't find in any of the prebuilt GUI tools I've seen for OS X: First, I wanted to enable accurate ReplayGain, and second, I wanted to avoid clipping in the output, which requires iteratively encoding to home in on the best scale factor to avoid clipping while keeping the audio otherwise at its highest fidelity. I present what I call semilame semiautomatic LAME:
#!/usr/local/bin/bash SDIR=$PWD # Assumes xxx/Artist/Album hierarchy TDIR=${PWD}/../../Out # Assumes xxx/Out hierarchy CUT="/usr/bin/cut" # Set the correct path LAME="/usr/local/bin/lame" # Set the correct path for fn in $(/bin/ls -1 *.aif *.aiff *.aifc 2>/dev/null); do clear # Start with a clear screen, for goodness sake # First try to parse the filename; set other defaults appropriately FName="${fn/\.aifc/}" g_Track=$(echo $FName | $CUT -d÷ -f 1) g_Artist=${u_Artist:=$(echo $FName | $CUT -d÷ -f 2 | sed -e 's,_,\ ,g')} g_Title=$(echo $FName | $CUT -d÷ -f 3 | sed -e 's,_,\ ,g') # N.B. Expected format: TRACK÷Artist÷Title.aifc # with spaces converted to underscores. # Album name is picked up from $PWD. # Adjust to your needs! g_Album=${u_Album:=$(pwd | sed -E -e 's,(.*)/(.*)$,\2,')} g_Scale="1" if [[ $u_Qual ]]; then g_Qual=$u_Qual # Keep what we had from the last encoding else g_Qual="2" fi # Now prompt for user input for corrections BOLD="\033[1m" # Set to "" if your term doesn't support bold NORM="\033[0m" # Set to "" if your term doesn't support bold echo -e "${BOLD}FILENAME: ${NORM}====== « ${BOLD}$fn${NORM} »\n" echo -e "${BOLD}Track: ${NORM}[${BOLD}${g_Track}${NORM}]: \c" read u_Track echo -e "${BOLD}Total Tracks: ${NORM}[${BOLD}${g_Total}${NORM}]: \c" read u_Total echo -e "${BOLD}Artist: ${NORM}[${BOLD}${g_Artist}${NORM}]: \c" read u_Artist echo -e "${BOLD}Title: ${NORM}[${BOLD}${g_Title}${NORM}]: \c" read u_Title echo -e "${BOLD}Album: ${NORM}[${BOLD}${g_Album}${NORM}]: \c" read u_Album echo -e "${BOLD}Year: ${NORM}[${BOLD}${g_Year}${NORM}]: \c" read u_Year echo -e "${BOLD}Quality Level: ${NORM}[${BOLD}${g_Qual}${NORM}]: \c" read u_Qual # Compare u_* values with g_* values if [[ -z $u_Track ]]; then u_Track=$g_Track fi if [[ -z $u_Total ]]; then u_Total=$g_Total elif [[ -z $g_Total ]]; then g_Total=$u_Total fi if [[ -z $u_Artist ]]; then u_Artist=$g_Artist fi if [[ -z $u_Title ]]; then u_Title=$g_Title fi if [[ -z $u_Album ]]; then u_Album=$g_Album fi if [[ -z $u_Year ]]; then u_Year=$g_Year elif [[ -z $g_Year ]]; then g_Year=$u_Year fi if [[ -z $u_Qual ]]; then u_Qual=$g_Qual elif [[ -z $g_Qual ]]; then g_Qual=$u_Qual fi u_Scale=$g_Scale # while loop = each interation through the track while [[ $u_Scale != "0" ]]; do echo -e "${BOLD}Scale: ${NORM}[${BOLD}${g_Scale}${NORM}]: \c" read u_Scale if [[ $u_Scale == "0" ]]; then g_Scale=1 continue fi if [[ -z $u_Scale ]]; then u_Scale=$g_Scale elif [[ -z $g_Scale ]]; then g_Scale=$u_Scale fi g_Scale=$u_Scale # At this point, the real values should all be in the u_* variables. # The g_* variables are simply placeholders for the next round # through the loop, for the ones that aren't auto guessed. # Construct the lame command and run it. Adjust to your liking. LAMEOPTS="--replaygain-accurate --clipdetect --big-endian --nohist --id3v2-only --vbr-new -V $u_Qual -q $u_Qual --temporal-masking 1 --ignore-tag-errors " # LAMEARGS is constructed separately because it changes with each file. LAMEARGS="--tt $u_Title --tl $u_Album" if [[ -n $u_Artist ]]; then LAMEARGS="$LAMEARGS --ta ${u_Artist}" fi if [[ -n $u_Total ]]; then LAMEARGS="$LAMEARGS --tn ${u_Track}/${u_Total}" else LAMEARGS="$LAMEARGS --tn ${u_Track}" fi if [[ -n $u_Year ]]; then LAMEARGS="$LAMEARGS --ty $u_Year" fi if [[ -n $u_Scale ]]; then LAMEARGS="$LAMEARGS --scale $u_Scale" fi OLDIFS=$IFS IFS=' ' LAMELINE="${LAME} ${LAMEOPTS} ${LAMEARGS} $fn ${TDIR}/${fn/aifc/mp3}" $LAMELINE # Restore IFS IFS=$OLDIFS echo -e "Set Scale to ${BOLD}0${NORM} to continue.\n" done done