Check for errors in replaygain action.
[clinton/abcde.git] / abcde
diff --git a/abcde b/abcde
index 17ebeb1..9a5742f 100755 (executable)
--- a/abcde
+++ b/abcde
@@ -1,6 +1,6 @@
 #!/bin/sh
 # Copyright (c) 1998-2001 Robert Woodcock <rcw@debian.org>
-# Copyright (c) 2003-2004 Jesus Climent <jesus.climent@hispalinux.es>
+# Copyright (c) 2003-2005 Jesus Climent <jesus.climent@hispalinux.es>
 # This code is hereby licensed for public consumption under either the
 # GNU GPL v2 or greater, or Larry Wall's Artistic license - your choice.
 #
@@ -11,7 +11,7 @@
 # Copyright for this work is to expire January 1, 2010, after which it
 # shall be public domain.
 
-VERSION="2.3.99"
+VERSION="2.3.99-$Id$"
 
 usage ()
 {
@@ -31,6 +31,7 @@ echo "-d <device>"
 echo "       Specify CDROM device to grab"
 echo "-D     Debugging mode (equivalent to sh -x abcde)"
 echo "-e     Erase encoded track information from status file"
+#echo "-E     Set the encoding information for the tags"
 echo "-h     This help information"
 #echo "-i    Tag files while encoding, when possible (local only) -NWY-"
 echo "-j <#> Number of encoder processes to run at once (localhost)"
@@ -82,12 +83,17 @@ f_seq_row ()
 f_seq_line ()
 {
        i=$1
-       while [ $i -ne `expr $2 + 1` ]
-       do
-               printf $i" "
-               i=`expr $i + 1`
-       done
-       echo
+       if echo i | grep -q "[[:digit:]]" ; then
+               while [ $i -ne `expr $2 + 1` ]
+               do
+                       printf $i" "
+                       i=`expr $i + 1`
+               done
+               echo
+       else
+               echo "abcde: syntax error while processing track numbers" >&2
+               exit 1
+       fi
 }
 
 # Functions to replace the need of awk {print $1} and {print $NF}
@@ -161,6 +167,31 @@ checkerrors ()
        fi
 }
 
+# page [file]
+# Finds the right pager in the system to display a file
+page ()
+{
+       PAGEFILE="$1"
+       # Use the debian sensible-pager wrapper to pick the pager
+       # user has requested via their $PAGER environment variable
+       if [ -x "/usr/bin/sensible-pager" ]; then
+               /usr/bin/sensible-pager "$PAGEFILE"
+       elif [ -x "$PAGER" ]; then
+               # That failed, try to load the preferred editor, starting
+               # with their PAGER variable
+               $PAGER "$PAGEFILE"
+               # If that fails, check for less
+       elif [ -x /usr/bin/less ]; then
+               /usr/bin/less -f "$PAGEFILE"
+               # more should be on all UNIX systems
+       elif [ -x /bin/more ]; then
+               /bin/more "$PAGEFILE"
+       else
+               # No bananas, just cat the thing
+               cat "$PAGEFILE" >&2
+       fi
+}
+
 # run_command [blurb] [command...]
 # Runs a command, silently if necessary, and updates the status file
 run_command ()
@@ -183,7 +214,7 @@ run_command ()
                fi
        fi
        case "$1" in
-       normalize)
+       normalize|normalize-audio)
                if [ "$RETURN" = "2" ]; then
                        # File was already normalized.
                        RETURN=0
@@ -255,6 +286,81 @@ relpath ()
        echo $TO
 }
 
+# do_getcddbinfo
+# Finds an specific field from cddbinfo
+# 
+#      TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2 -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')
+#      TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2 -d= | tr -d \[:cntrl:\])
+#      TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+
+do_getcddbinfo()
+{
+       case $1 in
+       TRACKNAME1)
+               TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+               ;;
+       TRACKNAME)
+               TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+               ;;
+       esac
+}
+
+# do_gettracknum
+# Get the track number we are going to use for different actions
+do_gettracknum()
+{
+       if [ -n "$STARTTRACKNUMBER" ] ; then
+               # Get the trackpadding from the current track
+               CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c)
+               TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
+       else
+               TRACKNUM=${UTRACKNUM}
+       fi
+}
+
+do_replaygain()
+{
+       if checkstatus replaygain; then :; else
+               run_command "" echo "Adding reply-gain information..."
+               for OUTPUT in $( echo $OUTPUTTYPE | tr , \ )
+               # THE OUTPUT NEEDS TO BE CORRECTED WITH THE CONTAINER?
+               do
+                       OUTPUTFILES=""
+                       for UTRACKNUM in $TRACKQUEUE
+                       do
+                               CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
+                               do_getcddbinfo TRACKNAME
+                               splitvarious
+                               TRACKFILE=$(mungefilename "$TRACKNAME")
+                               ARTISTFILE=$(mungefilename "$TRACKARTIST")
+                               ALBUMFILE=$(mungefilename "$DALBUM")
+                               do_gettracknum
+                               if [ "$VARIOUSARTISTS" = "y" ]; then
+                                       OUTPUTFILE=$(eval echo $VAOUTPUTFORMAT)
+                               else
+                                       OUTPUTFILE=$(eval echo $OUTPUTFORMAT)
+                               fi
+                               OUTPUTFILES="$OUTPUTDIR/$OUTPUTFILE.$OUTPUT $OUTPUTFILES"
+                       done
+                       case "$OUTPUT" in
+                               flac);;
+                               ogg);;
+                               *);;
+                       esac
+                       if [ "$RETURN" = "0" ]; then
+                               run_command replaygain-$OUTPUT true
+                       else
+                               runcommand replaygain-$OUTPUT false
+                       fi
+               done
+               if checkerrors replaygain-.{3,4}; then
+                       run_command replaygain false
+               else
+                       run_command replaygain true
+               fi
+       fi
+}
+
 # This code splits the a Various Artist track name from one of the following
 # forms:
 #
@@ -302,7 +408,7 @@ splitvarious ()
                        TRACKNAME=$(echo "$DTITLEARTIST" | cut -f1 -d~)
                        ;;
                esac
-       elif [ "$ONETRACK" = "y" ]; then
+       elif [ "$VARIOUSARTISTS" = "y" ] && [ "$ONETRACK" = "y" ]; then
                TRACKARTIST="Various"
        else
                TRACKARTIST="$DARTIST"
@@ -375,7 +481,7 @@ local id=""
                "gangsta")               id=59 ;;
                "top 40")                id=60 ;;
                "christian rap")         id=61 ;;
-               "pop/funk")              id=62 ;;
+               "pop/funk"|"pop / funk") id=62 ;;
                "jungle")                id=63 ;;
                "native american")       id=64 ;;
                "cabaret")               id=65 ;;
@@ -461,6 +567,7 @@ local id=""
                "anime")                 id=145 ;;
                "jpop")                  id=146 ;;
                "synthpop")              id=147 ;;
+               "rock/pop"|"rock / pop") id=148 ;;
                *)                       return 1 ;;
        esac
 echo ${id}
@@ -478,90 +585,112 @@ do_tag ()
        run_command '' echo "Tagging track $1 of $TRACKS: $TRACKNAME..."
        # If we want to start the tracks with a given number, we need to modify the
        # TRACKNUM value before evaluation
-       if [ -n "$STARTTRACKNUMBER" -a -n "$STARTTRACKNUMBERTAG" ] ; then
-               # Get the trackpadding from the current track
-               CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c)
-               TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
+#      if [ -n "$STARTTRACKNUMBER" -a -n "$STARTTRACKNUMBERTAG" ] ; then
+#              # Get the trackpadding from the current track
+#              CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c)
+#              TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
+#      fi
+       if [ -n "$STARTTRACKNUMBERTAG" ] ; then
+               do_gettracknum
        fi
        for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
        do
-       case "$OUTPUT" in
-       mp3)
-               # id3v2 v0.1.9 claims to have solved the -c bug, so we merge both id3 and id3v2
-               GENREID=$(do_getgenreid "${CDGENRE}")
-
-               # FIXME # track numbers in mp3 come with 1/10, so we cannot happily substitute them with $TRACKNUM
-               run_command tagtrack-$1 $TAGGER $TAGGEROPTS -c "$COMMENTOUTPUT" \
-                       -A "$DALBUM" -a "$TRACKARTIST" -t "$TRACKNAME" -y "$CDYEAR" \
-                       -g "$GENREID" -T "${TRACKNUM:-$1/$TRACKS}" \
-                       "$ABCDETEMPDIR/track$1.$OUTPUT"
-               ;;
-       vorbis|ogg)
-               case "$OGGENCODERSYNTAX" in
-                       vorbize|oggenc)
-                               # vorbiscomment can't do in-place modification, mv the file first
-                               if [ -f "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" -a ! -f "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" ]; then
-                                       mv "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER"
-                               fi
-                               (
-                               # These are from http://www.xiph.org/ogg/vorbis/doc/v-comment.html
-                               echo ARTIST="$TRACKARTIST"
-                               echo ALBUM="$DALBUM"
-                               echo TITLE="$TRACKNAME"
-                               if [ -n "$CDYEAR" ]; then
-                                       echo DATE="$CDYEAR"
-                               fi
-                               if [ -n "$CDGENRE" ]; then
-                                       echo GENRE="$CDGENRE"
-                               fi      
-                               echo TRACKNUMBER=${TRACKNUM:-$1}
-                               echo CDDB=$CDDBDISCID
-                               if [ "$(eval echo ${COMMENT})" != "" ]; then
-                                       case "$COMMENTOUTPUT" in
-                                               *=*) echo "$COMMENTOUTPUT";;
-                                               *)   echo COMMENT="$COMMENTOUTPUT";;
-                                       esac    
-                               fi
-                               ) | run_command tagtrack-$1 $VORBISCOMMENT $VORBISCOMMENTOPTS -w \
-                                       "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
-                               # Doublecheck that the commented file was created successfully before wiping the original
-                               if [ -f "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" ]; then
-                                       rm -f "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER"
-                               else
-                                       mv "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
-                               fi
-                               ;;
+               case "$OUTPUT" in
+               mp3)
+                       # id3v2 v0.1.9 claims to have solved the -c bug, so we merge both id3 and id3v2
+                       GENREID=$(do_getgenreid "${CDGENRE}")
+       
+                       case "$ID3SYNTAX" in
+                               id3);;
+                               eyed3)
+                                       # FIXME # track numbers in mp3 come with 1/10, so we cannot happily substitute them with $TRACKNUM
+                                       run_command tagtrack-$OUTPUT-$1 $TAGGER $TAGGEROPTS --commen=::"$COMMENTOUTPUT" \
+                                               -A "$DALBUM" -a "$TRACKARTIST" -t "$TRACKNAME" -Y "$CDYEAR" \
+                                               -G "$GENREID" -n "${TRACKNUM:-$1}" "${TRACKNUM:+-N $TRACKS}" \
+                                               "${ENCODING:+--set-encoding=$ENCODING}"
+                                               "$ABCDETEMPDIR/track$1.$OUTPUT"
+                                       ;;
+                               *)
+                                       # FIXME # track numbers in mp3 come with 1/10, so we cannot happily substitute them with $TRACKNUM
+                                       run_command tagtrack-$OUTPUT-$1 $TAGGER $TAGGEROPTS -c "$COMMENTOUTPUT" \
+                                               -A "$DALBUM" -a "$TRACKARTIST" -t "$TRACKNAME" -y "$CDYEAR" \
+                                               -g "$GENREID" -T "${TRACKNUM:-$1/$TRACKS}" \
+                                               "$ABCDETEMPDIR/track$1.$OUTPUT"
+                                       ;;
+                       esac
+                       ;;
+               vorbis|ogg)
+                       case "$OGGENCODERSYNTAX" in
+                               vorbize|oggenc)
+                                       # vorbiscomment can't do in-place modification, mv the file first
+                                       if [ -f "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" -a ! -f "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" ]; then
+                                               mv "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER"
+                                       fi
+                                       (
+                                       # These are from http://www.xiph.org/ogg/vorbis/doc/v-comment.html
+                                       echo ARTIST="$TRACKARTIST"
+                                       echo ALBUM="$DALBUM"
+                                       echo TITLE="$TRACKNAME"
+                                       if [ -n "$CDYEAR" ]; then
+                                               echo DATE="$CDYEAR"
+                                       fi
+                                       if [ -n "$CDGENRE" ]; then
+                                               echo GENRE="$CDGENRE"
+                                       fi      
+                                       echo TRACKNUMBER=${TRACKNUM:-$1}
+                                       echo CDDB=$CDDBDISCID
+                                       if [ "$(eval echo ${COMMENT})" != "" ]; then
+                                               case "$COMMENTOUTPUT" in
+                                                       *=*) echo "$COMMENTOUTPUT";;
+                                                       *)   echo COMMENT="$COMMENTOUTPUT";;
+                                               esac    
+                                       fi
+                                       ) | run_command tagtrack-$OUTPUT-$1 $VORBISCOMMENT $VORBISCOMMENTOPTS -w \
+                                               "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
+                                       # Doublecheck that the commented file was created successfully before wiping the original
+                                       if [ -f "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" ]; then
+                                               rm -f "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER"
+                                       else
+                                               mv "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
+                                       fi
+                                       ;;
+                       esac
+                       ;;
+               flac)
+                       (
+                       echo ARTIST="$TRACKARTIST"
+                       echo ALBUM="$DALBUM"
+                       echo TITLE="$TRACKNAME"
+                       if [ -n "$CDYEAR" ]; then
+                               echo DATE="$CDYEAR"
+                       fi
+                       if [ -n "$CDGENRE" ]; then
+                               echo GENRE="$CDGENRE"
+                       fi      
+                       echo TRACKNUMBER="${TRACKNUM:-$1}"
+                       echo CDDB="$CDDBDISCID"
+                       if [ "$(eval echo ${COMMENT})" != "" ]; then
+                               case "$COMMENTOUTPUT" in
+                                       *=*) echo "$COMMENTOUTPUT";;
+                                       *)   echo COMMENT="$COMMENTOUTPUT";;
+                               esac    
+                       fi
+                       ) | run_command tagtrack-$OUTPUT-$1 $METAFLAC $METAFLACOPTS --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
+                       ;;
+               spx)
+                       run_command tagtrack-$OUTPUT-$1 true
+                       ;;
+               mpc)
+                       run_command tagtrack-$OUTPUT-$1 true
+                       ;;
                esac
-               ;;
-       flac)
-               (
-               echo ARTIST="$TRACKARTIST"
-               echo ALBUM="$DALBUM"
-               echo TITLE="$TRACKNAME"
-               if [ -n "$CDYEAR" ]; then
-                       echo DATE="$CDYEAR"
-               fi
-               if [ -n "$CDGENRE" ]; then
-                       echo GENRE="$CDGENRE"
-               fi      
-               echo TRACKNUMBER=${TRACKNUM:-$1}
-               echo CDDB=$CDDBDISCID
-               if [ "$(eval echo ${COMMENT})" != "" ]; then
-                       case "$COMMENTOUTPUT" in
-                               *=*) echo "$COMMENTOUTPUT";;
-                               *)   echo COMMENT="$COMMENTOUTPUT";;
-                       esac    
-               fi
-               ) | run_command tagtrack-$1 $METAFLAC $METAFLACOPTS --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
-               ;;
-       spx)
-               run_command tagtrack-$1 true
-               ;;
-       mpc)
-               run_command tagtrack-$1 true
-               ;;
-       esac
        done
+       if checkerrors "tagtrack-(.{3,4})-$1"; then
+               run_command tagtrack-$1 false
+       else
+               run_command tagtrack-$1 true
+       fi
+
 }
 
 # do_batch_encode
@@ -583,7 +712,7 @@ do_batch_encode ()
                        do
                                TRACKFILES="$TRACKFILES track$UTRACKNUM.wav"
                        done
-                       nice $ENCNICE $MP3ENCODER $MP3ENCODEROPTS --nogap $TRACKFILES
+                       nice $ENCNICE $MP3ENCODER $MP3ENCODEROPTS `[ "$MP3ENCODER" = "lame" ] && echo "--nogap"` $TRACKFILES
                        RETURN=$?
                        if [ "$RETURN" != "0" ]; then
                                echo "batch-encode: $ENCODER returned code $RETURN" >> errors
@@ -626,7 +755,7 @@ do_encode ()
                                TEMPARG="PIPE_$MPPENCODER"
                                ;;
                esac
-               IN=${!TEMPARG}
+               IN="$( eval echo "\$$TEMPARG" )"
        else
                IN="$ABCDETEMPDIR/track$1.wav"
                case "$OUTPUT" in
@@ -748,10 +877,8 @@ do_encode ()
                        fi
                fi
        else
-               if [ "$(checkstatus encode-output)" = "loud" ]; then
-                       echo "HEH! The file we were about to encode disappeared:"
-                       echo ">> $IN"
-               fi
+               run_command "" echo "HEH! The file we were about to encode disappeared:"
+               run_command "" echo ">> $IN"
                run_command encodetrack-$1 false
        fi
 }
@@ -929,14 +1056,6 @@ do_move ()
 {
        for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
        do
-               case $OUTPUT in
-                       vorbis|ogg)
-                               OUTPUT=$OGGOUTPUTCONTAINER
-                               ;;
-                       flac)
-                               OUTPUT=$FLACOUTPUTCONTAINER
-                               ;;
-               esac
                # Create ALBUMFILE, ARTISTFILE, TRACKFILE
                # Munge filenames as follows:
                # ' ' -> '_'
@@ -951,13 +1070,14 @@ do_move ()
                YEAR=$(echo $CDYEAR)
                # If we want to start the tracks with a given number, we need to modify the
                # TRACKNUM value before evaluation
-               if [ -n "$STARTTRACKNUMBER" ] ; then
-                       # Get the trackpadding from the current track
-                       CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c)
-                       TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
-               else
-                       TRACKNUM=${UTRACKNUM}
-               fi
+       #       if [ -n "$STARTTRACKNUMBER" ] ; then
+       #               # Get the trackpadding from the current track
+       #               CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c)
+       #               TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
+       #       else
+       #               TRACKNUM=${UTRACKNUM}
+       #       fi
+               do_gettracknum
                # Supported variables for OUTPUTFORMAT are GENRE, ALBUMFILE, ARTISTFILE,
                # TRACKFILE, and TRACKNUM.
                if [ "$VARIOUSARTISTS" = "y" ]; then
@@ -965,34 +1085,43 @@ do_move ()
                        else
                        OUTPUTFILE=$(eval echo $OUTPUTFORMAT)
                fi
-               # Check that the directory for OUTPUTFILE exists, if it doesn't, create it
-               OUTPUTFILEDIR=$(dirname "$OUTPUTDIR/$OUTPUTFILE")
-               # mkdir -p shouldn't return an error if the directory already exists
-               mkdir -p "$OUTPUTFILEDIR"
-               # Silence the Moving output since it overlaps with encoding processes...
-               #run_command '' vecho "Moving track$1.$OUTPUT to $OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
-               run_command movetrack-$1 mv "$ABCDETEMPDIR/track$1.$OUTPUT" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
-               # Lets move the cue file
-               if CUEFILE=$(checkstatus cuefile) >/dev/null ; then 
-                       if [ -r "$ABCDETEMPDIR/$CUEFILE" ]; then
-                               if checkstatus movecue-$OUTPUT; then :; else
-                                       # Silence the Copying output since it overlaps with encoding processes...
-                                       #run_command '' vecho "Copying cue file to its destination directory..."
-                                       if checkstatus onetrack >/dev/null ; then
-                                               case $OUTPUT in
-                                                       # NOTE: Creating a cue file with the 3-char-extension files is to comply with
-                                                       # http://brianvictor.tripod.com/mp3cue.htm#details
-                                                       [a-z0-9][a-z0-9][a-z0-9])
-                                                               run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.cue"
-                                                               ;;
-                                                       *)
-                                                               run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT.cue"
-                                                               ;;
-                                               esac
-                                       else
-                                               run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTFILEDIR/$CUEFILE"
+               if checkerrors "tagtrack-$OUTPUT-$1"; then :; else
+                       # Once we know the specific output was successful, we can change the OUTPUT to the value containing the container
+                       case $OUTPUT in
+                               vorbis|ogg)
+                                       OUTPUT=$OGGOUTPUTCONTAINER
+                                       ;;
+                               flac)
+                                       OUTPUT=$FLACOUTPUTCONTAINER
+                                       ;;
+                       esac
+                       # Check that the directory for OUTPUTFILE exists, if it doesn't, create it
+                       OUTPUTFILEDIR=$(dirname "$OUTPUTDIR/$OUTPUTFILE")
+                       # mkdir -p shouldn't return an error if the directory already exists
+                       mkdir -p "$OUTPUTFILEDIR"
+                       run_command movetrack-$1 mv "$ABCDETEMPDIR/track$1.$OUTPUT" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
+                       # Lets move the cue file
+                       if CUEFILE=$(checkstatus cuefile) >/dev/null ; then 
+                               if [ -r "$ABCDETEMPDIR/$CUEFILE" ]; then
+                                       if checkstatus movecue-$OUTPUT; then :; else
+                                               # Silence the Copying output since it overlaps with encoding processes...
+                                               #run_command '' vecho "Copying cue file to its destination directory..."
+                                               if checkstatus onetrack >/dev/null ; then
+                                                       case $OUTPUT in
+                                                               # NOTE: Creating a cue file with the 3-char-extension files is to comply with
+                                                               # http://brianvictor.tripod.com/mp3cue.htm#details
+                                                               [a-z0-9][a-z0-9][a-z0-9])
+                                                                       run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.cue"
+                                                                       ;;
+                                                               *)
+                                                                       run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT.cue"
+                                                                       ;;
+                                                       esac
+                                               else
+                                                       run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTFILEDIR/$CUEFILE"
+                                               fi
+                                               echo movecue-$OUTPUT >> "$ABCDETEMPDIR/status"
                                        fi
-                                       echo movecue-$OUTPUT >> "$ABCDETEMPDIR/status"
                                fi
                        fi
                fi
@@ -1048,19 +1177,22 @@ do_playlist ()
                        do
                                # Shares some code with do_move since the filenames have to match
                                CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
-                               TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2 -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')
+                               #TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2 -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')
+                               do_getcddbinfo TRACKNAME
                                splitvarious
                                TRACKFILE=$(mungefilename "$TRACKNAME")
                                ARTISTFILE=$(mungefilename "$TRACKARTIST")
+                               ALBUMFILE=$(mungefilename "$DALBUM")
                                # If we want to start the tracks with a given number, we need to modify the
                                # TRACKNUM value before evaluation
-                               if [ -n "$STARTTRACKNUMBER" ] ; then
-                                       # Get the trackpadding from the current track
-                                       CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c)
-                                       TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
-                               else
-                                       TRACKNUM=${UTRACKNUM}
-                               fi
+                       #       if [ -n "$STARTTRACKNUMBER" ] ; then
+                       #               # Get the trackpadding from the current track
+                       #               CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c)
+                       #               TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
+                       #       else
+                       #               TRACKNUM=${UTRACKNUM}
+                       #       fi
+                               do_gettracknum
                                if [ "$VARIOUSARTISTS" = "y" ]; then
                                        OUTPUTFILE=$(eval echo $VAOUTPUTFORMAT)
                                else
@@ -1271,8 +1403,13 @@ do_discid ()
                if checkstatus cuefile > /dev/null 2>&1 ; then :; else
                        CUEFILE=cue-$(echo "$TRACKINFO" | cut -f1 -d' ').txt
                        vecho "Creating cue file..."
-                       $MKCUE $MKCUEOPTS > "$ABCDETEMPDIR/$CUEFILE"
-                       echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status"
+                       if $CUEREADER $CUEREADEROPTS > "$ABCDETEMPDIR/$CUEFILE"; then
+                               echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status"
+                       else
+                               echo "abcde: reading the CUE sheet with mkcue is still considered experimental"
+                               echo "abcde: and there was a problem with the CD reading. abcde will continue,"
+                               echo "abcde: but consider reporting the problem to the abcde author"
+                       fi
                fi
        fi
        # If we got the CDPARANOIA status and it is not recorded, save it now
@@ -1332,14 +1469,14 @@ do_cddbparse ()
        echo "---- $(grep DTITLE "${CDDBPARSEFILE}" | cut '-d=' -f2- | tr -d \\r\\n ) ----"
        if [ X"$SHOWCDDBYEAR" = "Xy" ]; then
                PARSEDYEAR=$(grep DYEAR "${CDDBPARSEFILE}" | cut '-d=' -f2-)
-               if [ X"$PARSEDYEAR" = "X" ]; then
-                       echo "YEAR=$PARSEDYEAR"
+               if [ X"$PARSEDYEAR" = "X" ]; then
+                       echo "Year: $PARSEDYEAR"
                fi
        fi
        if [ X"$SHOWCDDBGENRE" = "Xy" ]; then
                PARSEDGENRE=$(grep DGENRE "${CDDBPARSEFILE}" | cut '-d=' -f2-)
-               if [ X"$PARSEDGENRE" = "X" ]; then
-                       echo "GENRE=$PARSEDGENRE"
+               if [ X"$PARSEDGENRE" = "X" ]; then
+                       echo "Genre: $PARSEDGENRE"
                fi
        fi
        if [ ! "$ONETRACK" = "y" ]; then
@@ -1595,30 +1732,15 @@ do_cddbedit ()
                                else
                                        # The user has a choice to make, display the info in a pager if necessary
                                        if [ $(cat "$ABCDETEMPDIR/cddbchoices" | wc -l) -ge 24 ]; then
-                                               # Use the debian sensible-pager wrapper to pick the pager
-                                               # user has requested via their $PAGER environment variable
-                                               if [ -x "/usr/bin/sensible-pager" ]; then
-                                                       /usr/bin/sensible-pager "$ABCDETEMPDIR/cddbchoices"
-                                               elif [ -x "$PAGER" ]; then
-                                                       # That failed, try to load the preferred editor, starting
-                                                       # with their PAGER variable
-                                                       $PAGER "$ABCDETEMPDIR/cddbchoices"
-                                                       # If that fails, check for less
-                                               elif [ -x /usr/bin/less ]; then
-                                                       /usr/bin/less -f "$ABCDETEMPDIR/cddbchoices"
-                                                       # more should be on all UNIX systems
-                                               elif [ -x /bin/more ]; then
-                                                       /bin/more "$ABCDETEMPDIR/cddbchoices"
-                                               else
-                                                       # No bananas, just cat the thing
-                                                       cat "$ABCDETEMPDIR/cddbchoices" >&2
-                                               fi
+                                               page "$ABCDETEMPDIR/cddbchoices"
                                        else
                                                # It's all going to fit in one page, cat it
                                                cat "$ABCDETEMPDIR/cddbchoices" >&2
                                        fi
                                        
                                        CDDBCHOICENUM=""
+                                       # Setting the choice to an impossible integer to avoid errors in the numeric comparisons
+                                       CDCHOICENUM=-1
                                        # I'll take CDDB read #3 for $400, Alex
                                        while [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; do
                                                echo -n "Which entry would you like abcde to use (0 for none)? [0-$CDDBCHOICES]: " >&2
@@ -1626,14 +1748,26 @@ do_cddbedit ()
                                                [ X"$CDDBCHOICE" = "X" ] && CDDBCHOICE=1
                                                if echo $CDDBCHOICE | egrep -q "[[:digit:]]+,[[:digit:]]+" ; then
                                                        if [ ! X"$DIFF" = "X" ]; then
-                                                               # We parse the 2 choices to diff, store them in temporary files and diff them.
-                                                               for PARSECHOICE in $(echo $CDDBCHOICE | tr , \ ); do
-                                                                       do_cddbparse "$ABCDETEMPDIR/cddbread.$PARSECHOICE" > "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE"
-                                                               done
                                                                PARSECHOICE1=$(echo $CDDBCHOICE | cut -d"," -f1)
                                                                PARSECHOICE2=$(echo $CDDBCHOICE | cut -d"," -f2)
-                                                               echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..."
-                                                               $DIFF $DIFFOPTS "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE1" "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE2"
+                                                               if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBCHOICES ] || \
+                                                                  [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBCHOICES ] || \
+                                                                  [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then 
+                                                                       echo "Invalid diff range. Please select two coma-separated numbers between 1 and $CDDBCHOICES" >&2
+                                                               else
+
+                                                                       # We parse the 2 choices to diff, store them in temporary files and diff them.
+                                                                       for PARSECHOICE in $(echo $CDDBCHOICE | tr , \ ); do
+                                                                               do_cddbparse "$ABCDETEMPDIR/cddbread.$PARSECHOICE" > "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE"
+                                                                       done
+                                                                       echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..." > "$ABCDETEMPDIR/cddbread.diff"
+                                                                       $DIFF $DIFFOPTS "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE1" "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE2" >> "$ABCDETEMPDIR/cddbread.diff"
+                                                                       if [ $(cat "$ABCDETEMPDIR/cddbread.diff" | wc -l) -ge 24 ]; then
+                                                                               page "$ABCDETEMPDIR/cddbread.diff"
+                                                                       else
+                                                                               cat "$ABCDETEMPDIR/cddbread.diff" >&2
+                                                                       fi
+                                                               fi
                                                        else
                                                                echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBCHOICES." >&2
                                                        fi
@@ -1850,7 +1984,7 @@ do_cddbedit ()
        echo "variousartiststyle=$VARIOUSARTISTSTYLE" >> "$ABCDETEMPDIR/status"
 
        if [ "$EDITCDDB" = "y" ] && [ "$UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE" = "y" ]; then
-               if [ $CDDBDATAMD5SUM != "" ]  && [ $CDDBDATAMD5SUM != $($MD5SUM "$CDDBDATA" | cut -d " " -f 1) ]; then
+               if [ "$CDDBDATAMD5SUM" != "" ]  && [ "$CDDBDATAMD5SUM" != "$($MD5SUM "$CDDBDATA" | cut -d " " -f 1)" ]; then
                        # This works but does not have the necessary error checking
                        # yet. If you are familiar with the CDDB spec
                        # (see http://www.freedb.org/src/latest/DBFORMAT) 
@@ -1915,7 +2049,7 @@ do_cdread ()
        CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
        if [ "$USEPIPES" = "y" ]; then
                TEMPARG="PIPE_$CDROMREADERSYNTAX"
-               FILEARG="${!TEMPARG}"
+               FILEARG="$( eval echo "\$$TEMPARG" )"
                REDIR=""
                PIPE_MESSAGE="and encoding "
        else
@@ -1935,7 +2069,8 @@ do_cdread ()
                echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2
        else
                if [ -r "$CDDBDATA" ]; then
-                       TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2 -d= | tr -d \[:cntrl:\])
+                       #TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2 -d= | tr -d \[:cntrl:\])
+                       do_getcddbinfo TRACKNAME
                        echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM: $TRACKNAME..." >&2
                else
                        echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM..." >&2
@@ -2083,6 +2218,7 @@ FLACENCODERSYNTAX=default
 SPEEXENCODERSYNTAX=default
 MPPENCODERSYNTAX=default
 NORMALIZERSYNTAX=default
+CUEREADERSYNTAX=default
 
 OUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${TRACKNUM}.${TRACKFILE}'
 # Use the following VAOUTPUTFORMAT to revert to 2.0.x VA format:
@@ -2132,6 +2268,7 @@ MPPENC=mppenc
 
 ID3=id3
 ID3V2=id3v2
+EYED3=eyeD3
 CDPARANOIA=cdparanoia
 CDDA2WAV=cdda2wav
 DAGRAB=dagrab
@@ -2199,6 +2336,7 @@ DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:lame,mp3:bladeenc,spx:speex
 # Let's use these checkings to determine the OS flavour, which will be used later
 if [ X$(uname) = "XFreeBSD" ] ; then
        HTTPGET=fetch
+       MD5SUM=md5
        NEEDCDROMID=y
        OSFLAVOUR=FBSD
 elif [ X$(uname) = "XDarwin" ] ; then
@@ -2210,6 +2348,9 @@ elif [ X$(uname) = "XDarwin" ] ; then
 elif [ X$(uname) = "XOpenBSD" ] ; then
        HTTPGET=wget
        MD5SUM=md5
+elif [ X$(uname) = "XNetBSD" ] ; then
+       HTTPGET=ftp
+       MD5SUM=md5
 else
        HTTPGET=wget
 fi
@@ -2245,6 +2386,7 @@ if [ "$HTTPGETOPTS" = "" ] ; then
                wget) HTTPGETOPTS="-q -O -";;
                curl) HTTPGETOPTS="-f -s";;
                fetch)HTTPGETOPTS="-q -o -";;
+               ftp)  HTTPGETOPTS="-q -o -";;
                *) echo "abcde warning: HTTPGET in non-standard and HTTPGETOPTS are not defined." >&2 ;;
        esac
 fi
@@ -2268,11 +2410,11 @@ fi
 
 # Parse command line options
 #while getopts 1a:A:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:t:T:vVxw:W: opt ; do
-while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:vVxw:W: opt ; do
+while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:t:T:vVxw:W: opt ; do
        case "$opt" in
                1) ONETRACK=y ;;
                a) ACTIONS="$OPTARG" ;;
-               A) EXPACTIONS="$OPTARG";;
+               A) EXPACTIONS="$OPTARG" ;;
                b) BATCH=y ;;
                c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else echo "abcde error: config file \"$OPTARG\" cannot be found." >&2 ; exit 1 ; fi ;;
                C) DISCID="${OPTARG#abcde.}" ;;
@@ -2281,6 +2423,7 @@ while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:vVxw:W: opt ; do
                e) ERASEENCODEDSTATUS=y ;;
                h) usage; exit ;;
                e) ERASEENCODEDSTATUS=y ;;
+               E) ENCODING="$OPTARG" ;;
 #              f) FORCECDDBUSELOCAL=y ;;
                i) INLINETAG=y ;;
                j) MAXPROCS="$OPTARG" ;;
@@ -2371,6 +2514,7 @@ DOENCODE=n
 DOPOSTPROCESS=n
 DOTAG=n
 DOMOVE=n
+DOREPLAYGAIN=n
 DOPLAYLIST=n
 DOCLEAN=n
 
@@ -2385,11 +2529,17 @@ do
 #              postprocess) DOPREPROCESS=y; DOENCODE=y; DOREAD=y;;
                tag) DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
                move) DOMOVE=y; DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
+               replaygain) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOREPLAYGAIN=y;;
                playlist) DOCDDB=y; DOPLAYLIST=y;;
                clean) DOCLEAN=y;;
        esac
 done
 
+if [ "$DONORMALIZE" = "y" ] && [ "$DOREPLAYGAIN" = "y" ]; then
+       # FIXME # should we abort on error or just inform the user?
+       :
+fi
+
 for SHOWCDDBFIELD in $(echo $SHOWCDDBFIELDS | tr , \ ); do
        case $SHOWCDDBFIELD in
                y*|Y*) SHOWCDDBYEAR="y";;
@@ -2617,6 +2767,14 @@ else
        TAGGEROPTS="$ID3V2OPTS"
 fi
 
+# Options for mkcue
+case "$CUEREADERSYNTAX" in
+       default|mkcue)
+               CUEREADEROPTS="${CDROM}"
+               CUEREADER="$MKCUE"
+               ;;
+esac
+
 # Check if both OGGEOUTPUTCONTAINER and FLACOUTPUTCONTAINER are the same, and differentiante them
 if [ X"$OGGOUTPUTCONTAINER" = "Xogg" ] && [ X"$FLACOUTPUTCONTAINER" = "Xogg" ]; then
        echo "abcde error: FLAC on an Ogg container is not yet supported" >&2
@@ -2652,8 +2810,8 @@ fi
 if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then
        NEEDHTTPGET=y
 fi
-if [ "$CUEFILE" = "y" ]; then
-       NEEDMKCUE=y
+if [ "$MAKECUEFILE" = "y" ]; then
+       NEEDCUEREADER=y
 fi
 
 if [ X"$CDSPEEDVALUE" != "X" ]; then
@@ -2689,13 +2847,13 @@ if [ "$USEPIPES" = "y" ]; then
                mpc)
                        PIPEENCODERSVARCHECK="PIPE_$MPPENCODER" ;;
        esac
-       if [ ! -n "${!PIPERIPPERSVARCHECK}" ] ; then
+       if [ ! -n "$( eval echo "\$$PIPERIPPERSVARCHECK" )" ] ; then
                echo "abcde error: no support for pipes with given ripper" >&2
                echo "read the USEPIPES file from the source tarball to help" >&2
                echo "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz" >&2
                exit 1;
        fi
-       if [ ! -n "${!PIPEENCODERSVARCHECK}" ] ; then
+       if [ ! -n "$( eval echo "\$$PIPEENCODERSVARCHECK" )" ] ; then
                echo "abcde error: no support for pipes with given encoder" >&2
                echo "read the USEPIPES file from the source tarball to help" >&2
                echo "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz" >&2
@@ -2710,7 +2868,7 @@ for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
        ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
        ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
        ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} \
-       ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMKCUE+$MKCUE}
+       ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDCUEREADER+$CUEREADER}
 do
        # Cut off the command-line options we just added in
        X=$(echo $X | cut -d' ' -f2)
@@ -2735,7 +2893,7 @@ fi
 
 # Here it used to say:
 # One thousand lines in, we can start doing stuff with things
-# Well, right now we are at line 2695 ;)
+# Well, right now we are at line 2736 ;)
 
 # Export needed things so they can be read in this subshell
 export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS
@@ -3004,7 +3162,8 @@ do
 #                      TRACKNUM=$(printf %0.${TRACKNUMPADDING}d $(expr ${UTRACKNUM} + 0))
                        TRACKNUM=$UTRACKNUM
                        CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
-                       TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+                       #TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+                       do_getcddbinfo TRACKNAME
                        splitvarious
                fi
        fi
@@ -3075,6 +3234,9 @@ if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
 fi
 # If the above didn't catch the stragglers, this will
 wait
+if [ "$DOREPLAYGAIN" = "y" ]; then
+       do_replaygain
+fi
 # Check to see if run_command logged any errors
 if [ -f "$ABCDETEMPDIR/errors" ]; then
        echo "The following commands failed to run:"