Extend Musicbrainz multi-artist support
[abcde.git] / abcde
diff --git a/abcde b/abcde
index b2da1f8..384954a 100755 (executable)
--- a/abcde
+++ b/abcde
@@ -2,8 +2,8 @@
 # Copyright (c) 1998-2001 Robert Woodcock <rcw@debian.org>
 # Copyright (c) 2003-2006 Jesus Climent <jesus.climent@hispalinux.es>
 # Copyright (c) 2009-2012 Colin Tuckley <colint@debian.org>
-# Copyright (c) 2012-     Steve McIntyre <93sam@@debian.org>
-# Copyright (c) 2015-     Andrew Strong <andrew.david.strong@gmail.com>
+# Copyright (c) 2012-2018 Steve McIntyre <93sam@@debian.org>
+# Copyright (c) 2015-2017 Andrew Strong <andrew.david.strong@gmail.com>
 # 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 @@
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-VERSION='2.7.1-UNRELEASED'
+VERSION='2.8.2-UNRELEASED'
 
 usage ()
 {
@@ -20,10 +20,12 @@ echo "Usage: abcde [options] [tracks]"
 echo "Options:"
 echo "-1     Encode the whole CD in a single file"
 echo "-a <action1[,action2]...>"
-echo "       Actions to perform:"
-echo "       cddb,read,getalbumart,normalize,encode,tag,move,replaygain,playlist,clean"
+echo "       Actions to perform, comma separated:"
+echo "       (cddb,read,getalbumart,embedalbumart,normalize,encode,"
+echo "       tag,move,replaygain,playlist,clean)"
 #echo "-A     Experimental actions (retag, transcode)"
 echo "-b     Enable batch normalization"
+echo "-B     Embed albumart (this also activates getalbumart)"
 echo "-c <file>"
 echo "       Specify a configuration file (overrides system and user config files)"
 echo "-C <discid#>"
@@ -47,9 +49,13 @@ echo "-m     Modify playlist to include CRLF endings, to comply with some player
 echo "-n     No lookup. Don't query CDDB, just create and use template"
 echo "-N     Noninteractive. Never prompt for anything"
 echo "-o <type1[,type2]...>"
-echo "       Output file type(s) (vorbis,mp3,flac,spx,mpc,wav,m4a,opus,wv,ape,mp2). Defaults to vorbis"
+echo "       Output file type(s), comma separated"
+echo "       (vorbis,mp3,flac,spx,mpc,wav,m4a,opus,mka,wv,ape,mp2,tta,aiff)."
+echo "       Defaults to vorbis"
 echo "-p     Pad track numbers with 0's (if less than 10 tracks)"
 echo "-P     Use UNIX pipes to read+encode without wav files"
+echo "-Q     CD lookup method(s), comma separated"
+echo "       (musicbrainz,cddb,cdtext). Defaults to musicbrainz".
 echo "-r <host1[,host2]...>"
 echo "       Also encode on these remote hosts"
 echo "-s <field>"
@@ -74,7 +80,7 @@ echo ""
 
 addstatus ()
 {
-       echo "$@" >> "$ABCDETEMPDIR/status"
+       echo "$@" >> "${ABCDETEMPDIR}/status"
 }
 
 # log [level] [message]
@@ -95,21 +101,21 @@ log ()
 f_seq_row ()
 {
        i=$1
-       while [ $i -ne `expr $2 + 1` ]
+       while [ $i -le $2 ]
        do
                echo $i
-               i=`expr $i + 1`
+               i=$(( $i + 1 ))
        done
 }
 
 f_seq_line ()
 {
        i=$1
-       if echo $i | grep "[[:digit:]]" > /dev/null 2>&1 ; then
-               while [ $i -ne `expr $2 + 1` ]
+       if echo "$i" | grep "[[:digit:]]" > /dev/null 2>&1 ; then
+               while [ $i -le $2 ]
                do
-                       printf $i" "
-                       i=`expr $i + 1`
+                       printf "%d " "$i"
+                       i=$(( $i + 1 ))
                done
                echo
        else
@@ -121,26 +127,26 @@ f_seq_line ()
 # Functions to replace the need of awk {print $1} and {print $NF}
 get_first()
 {
-if [ X"$1" = "X" ]; then
-       for first in `cat`; do
-               break
-       done
-else
-       first=$1
-fi
-echo $first
+       if [ X"$1" = "X" ]; then
+               for first in $(cat); do
+                       break
+               done
+       else
+               first=$1
+       fi
+       echo "$first"
 }
 
 get_last()
 {
-if [ X"$1" = "X" ]; then
-       for stdin in `cat`; do
-               last=$stdin
-       done
-else
-       for last in $@ ; do :; done
-fi
-echo $last
+       if [ X"$1" = "X" ]; then
+               for stdin in $(cat); do
+                       last=$stdin
+               done
+       else
+               for last in $@ ; do :; done
+       fi
+       echo "$last"
 }
 
 # checkstatus [blurb]
@@ -151,7 +157,7 @@ checkstatus ()
 {
        # Take the last line in the status file if there's multiple matches
        PATTERN="^$1(=.*)?$"
-       BLURB=$(grep -E $PATTERN "$ABCDETEMPDIR/status" | tail -n 1)
+       BLURB=$(grep -E "$PATTERN" "${ABCDETEMPDIR}/status" | tail -n 1)
 
        if [ -z "$BLURB" ]; then
                # No matches found
@@ -159,8 +165,8 @@ checkstatus ()
        else
                # Matches found
                # See if there's a = in it
-               if [ "$(echo $BLURB | grep -c =)" != "0" ]; then
-                       echo "$(echo $BLURB | cut -f2- -d=)"
+               if ( echo "$BLURB" | grep -q '=' ); then
+                       echo "$BLURB" | cut -f2- -d=
                fi
                return 0
        fi
@@ -173,12 +179,12 @@ checkstatus ()
 # Otherwise, returns "".
 checkwarnings ()
 {
-       if [ -e "$ABCDETEMPDIR/warnings" ]; then :; else
+       if [ -e "${ABCDETEMPDIR}/warnings" ]; then :; else
                return 1
        fi
        # Take the last line in the status file if there's multiple matches
        PATTERN="^$1(:.*)?$"
-       BLURB="$(grep -E $PATTERN "$ABCDETEMPDIR/warnings" | tail -n 1)"
+       BLURB=$(grep -E "$PATTERN" "${ABCDETEMPDIR}/warnings" | tail -n 1)
 
        if [ -z "$BLURB" ]; then
                # negative, we did not have a negative...
@@ -196,12 +202,12 @@ checkwarnings ()
 # Otherwise, returns "".
 checkerrors ()
 {
-       if [ -e "$ABCDETEMPDIR/errors" ]; then :; else
+       if [ -e "${ABCDETEMPDIR}/errors" ]; then :; else
                return 1
        fi
        # Take the last line in the status file if there's multiple matches
        PATTERN="^$1(:.*)?$"
-       BLURB="$(grep -E $PATTERN "$ABCDETEMPDIR/errors" | tail -n 1)"
+       BLURB=$(grep -E "$PATTERN" "${ABCDETEMPDIR}/errors" | tail -n 1)
 
        if [ -z "$BLURB" ]; then
                # negative, we did not have a negative...
@@ -213,26 +219,36 @@ checkerrors ()
 }
 
 # page [file]
-# Finds the right pager in the system to display a file
+# Display a file. If it's too long to fit the current terminal size,
+# find the right pager in the system and use it
 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"
+       local NUM_LINES=$(wc -l < "$PAGEFILE")
+
+       # Is the text long enough to need a pager?
+       if [ "$NUM_LINES" -ge $LINES ]; then
+               # Yes!
+               # 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 pager, 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
        else
-               # No bananas, just cat the thing
+               # No, just cat the thing
                cat "$PAGEFILE" >&2
        fi
 }
@@ -251,7 +267,7 @@ run_command ()
        else
                # Special case for SMP, since
                # encoder output is never displayed, don't mute echos
-               if [ -z "$BLURB" -a "$MAXPROCS" != "1" ]; then
+               if [ -z "$BLURB" ] && [ "$MAXPROCS" != "1" ]; then
                        "$@" >&2
                        RETURN=$?
                else
@@ -275,11 +291,11 @@ run_command ()
                if [ "$BLURB" ]; then
                        TWEAK="$BLURB: "
                fi
-               echo "${TWEAK}returned code $RETURN: $@" >> "$ABCDETEMPDIR/errors"
+               echo "${TWEAK}returned code $RETURN: $@" >> "${ABCDETEMPDIR}/errors"
                return $RETURN # Do not pass go, do not update the status file
        fi
        if [ "$BLURB" ]; then
-               echo $BLURB >> "$ABCDETEMPDIR/status"
+               echo "$BLURB" >> "${ABCDETEMPDIR}/status"
        fi
 }
 
@@ -329,17 +345,18 @@ relpath ()
                ;;
        esac
 
-       echo $TO
+       echo "$TO"
 }
 
 new_checkexec ()
 {
        if [ ! "$@" = "" ]; then
                # Cut off any command-line option we added in
-               X=$(echo $@ | cut -d' ' -f2)
-               if [ "$(which $X)" = "" ]; then
+               X=$(echo "$@" | cut -d' ' -f2)
+               WHICH=$(which "$X" 2>/dev/null)
+               if [ -z "$WHICH" ]; then
                        return 1
-               elif [ ! -x $(which $X) ]; then
+               elif [ ! -x "$WHICH" ]; then
                        return 2
                fi
        fi
@@ -350,21 +367,26 @@ checkexec ()
 {
        if [ ! "$@" = "" ]; then
                # Cut off any command-line option we added in
-               X=$(echo $@ | cut -d' ' -f2)
+               X=$(echo "$@" | cut -d' ' -f2)
                # Test for built-in abcde.function
-               [ "$X" != "${X#abcde.}" ] && type $X >/dev/null 2>&1 && return
-               if [ "$(which $X)" = "" ]; then
+               [ "$X" != "${X#abcde.}" ] && type "$X" >/dev/null 2>&1 && return
+               WHICH=$(which "$X" 2>/dev/null)
+               if [ -z "$WHICH" ]; then
                        log error "$X is not in your path." >&2
                        log info  "Define the full path to the executable if it exists on your system." >&2
-                       if [ -e /etc/debian_* ] ; then
+                       if [ -e /etc/debian_version ] ; then
                                case $X in
-                                       oggenc)         MISSING_PACKAGE=vorbis-tools ;;
-                                       lame|flac)      MISSING_PACKAGE=$X ;;
+                                       oggenc)
+                                               MISSING_PACKAGE=vorbis-tools
+                                               ;;
+                                       lame|flac|cd-discid|eject|mkcue|icedax|glyrc)
+                                               MISSING_PACKAGE=$X
+                                               ;;
                                esac
                                log info "Hint: sudo apt-get install $MISSING_PACKAGE" >&2
                        fi
                        exit 1
-               elif [ ! -x "$(which $X)" ]; then
+               elif [ ! -x "$WHICH" ]; then
                        log error "$X is not executable." >&2
                        exit 1
                fi
@@ -381,27 +403,26 @@ diffentries ()
        shift
        local CDDBDIFFCHOICE="$@"
        if [ ! X"$DIFF" = "X" ]; then
-               PARSECHOICE1=$(echo $CDDBDIFFCHOICE | cut -d"," -f1 | xargs printf %d 2>/dev/null)
-               PARSECHOICE2=$(echo $CDDBDIFFCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null)
-               if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBDIFFCHOICES ] || \
-                  [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBDIFFCHOICES ] || \
-                  [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then
-                       echo "Invalid diff range. Please select two comma-separated numbers between 1 and $CDDBDIFFCHOICES" >&2
+               PARSECHOICE1=$(echo "$CDDBDIFFCHOICE" | cut -d"," -f1 | xargs printf %d 2>/dev/null)
+               PARSECHOICE2=$(echo "$CDDBDIFFCHOICE" | cut -d"," -f2 | xargs printf %d 2>/dev/null)
+               if [ "$PARSECHOICE1" -lt 1 ] || [ "$PARSECHOICE1" -gt "$CDDBDIFFCHOICES" ] || \
+                  [ "$PARSECHOICE2" -lt 1 ] || [ "$PARSECHOICE2" -gt "$CDDBDIFFCHOICES" ] || \
+                  [ "$PARSECHOICE1" -eq "$PARSECHOICE2" ]; then
+                       echo "Invalid diff range." >&2
+                       echo "Please select two comma-separated numbers between 1 and $CDDBDIFFCHOICES" >&2
                else
                        # We parse the 2 choices to diff, store them in temporary files and diff them.
-                       for PARSECHOICE in $(echo $CDDBDIFFCHOICE | tr , \ ); do
-                               do_cddbparse "$ABCDETEMPDIR/$FILENAME.$PARSECHOICE" > "$ABCDETEMPDIR/$FILENAME.parsechoice.$PARSECHOICE"
+                       for PARSECHOICE in $(echo "$CDDBDIFFCHOICE" | tr , \ ); do
+                               do_cddbparse "${ABCDETEMPDIR}/$FILENAME.$PARSECHOICE" > "${ABCDETEMPDIR}/$FILENAME.parsechoice.$PARSECHOICE"
                        done
-                       echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..." > "$ABCDETEMPDIR/$FILENAME.diff"
-                       $DIFF $DIFFOPTS "$ABCDETEMPDIR/$FILENAME.parsechoice.$PARSECHOICE1" "$ABCDETEMPDIR/$FILENAME.parsechoice.$PARSECHOICE2" >> "$ABCDETEMPDIR/$FILENAME.diff"
-                       if [ $(cat "$ABCDETEMPDIR/$FILENAME.diff" | wc -l) -ge 24 ]; then
-                               page "$ABCDETEMPDIR/$FILENAME.diff"
-                       else
-                               cat "$ABCDETEMPDIR/$FILENAME.diff" >&2
-                       fi
+                       echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..." > "${ABCDETEMPDIR}/$FILENAME.diff"
+                       $DIFF $DIFFOPTS "${ABCDETEMPDIR}/$FILENAME.parsechoice.$PARSECHOICE1" \
+                                 "${ABCDETEMPDIR}/$FILENAME.parsechoice.$PARSECHOICE2" >> "${ABCDETEMPDIR}/$FILENAME.diff"
+                       page "${ABCDETEMPDIR}/$FILENAME.diff"
                fi
        else
-               echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBDIFFCHOICES." >&2
+               echo "The diff program was not found in your path." >&2
+               echo "Please choose a number between 0 and $CDDBDIFFCHOICES." >&2
        fi
 }
 
@@ -411,13 +432,13 @@ getcddbinfo()
 {
        case $1 in
        TRACKNAME1)
-               TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+               TRACKNAME="$(grep -a "^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/\ \+$//')"
+               TRACKNAME="$(grep -a "^TTITLE$CDDBTRACKNUM=" "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
                ;;
        TRACK-INFO)
-               grep ^EXTT$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\\n/\n/g'
+               grep -a "^EXTT$CDDBTRACKNUM=" "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\\n/\n/g'
                ;;
        esac
 }
@@ -428,10 +449,10 @@ gettracknum()
 {
        if [ -n "$STARTTRACKNUMBER" ] ; then
                # Get the trackpadding from the current track, also trim whitespace for MacOSX
-               CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c | tr -d ' ')
-               TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
+               CURRENTTRACKPADDING=$(echo -n "$UTRACKNUM" | wc -c | tr -d ' ')
+               TRACKNUM=$( printf %0."${CURRENTTRACKPADDING}"d $(("${UTRACKNUM}" + "${STARTTRACKNUMBER}" - "${FIRSTTRACK}")))
        else
-               TRACKNUM=${UTRACKNUM}
+               TRACKNUM="${UTRACKNUM}"
        fi
 }
 
@@ -468,7 +489,7 @@ makeids ()
        CDDBCKSUM=0
 
        COOKEDOFFSETS=""
-       for OFFSET in $(echo $OFFSETS)
+       for OFFSET in $OFFSETS
        do
                COOKEDOFFSETS="${COOKEDOFFSETS} $(($OFFSET + $LEADIN))"
 
@@ -482,28 +503,37 @@ makeids ()
 
        COOKEDOFFSETS="${COOKEDOFFSETS:1}"  # eat the leading space
 
-       PREGAP=$(($(echo $OFFSETS | cut -f1 -d' ')))
+       PREGAP=$(echo $OFFSETS | cut -f1 -d' ')
        TOTALTIME=$(( (($LEADOUT + $LEADIN + $PREGAP) / $CDFRAMES) - (($LEADIN + $PREGAP) / $CDFRAMES)))
 
-       case "$CDDBMETHOD" in
-               cddb)
-                       printf -v DISCID "%08lx" $(( ($CDDBCKSUM % 0xff) * 16777216 | $TOTALTIME * 256 | $TRACKS))
-                       ;;
-               musicbrainz)
+       vvecho "makeids: PREGAP $PREGAP, LEADIN $LEADIN, LEADOUT $LEADOUT"
+
+       # Calculate both the cddb discid *and* the musicbrainz discid
+       # now. We'll use the cddb discid for reference in most cases
+       # for consistency, but we also have the musicbrainz discid for
+       # when we need it
+       printf -v CDDBDISCID "%08lx" $(( ($CDDBCKSUM % 0xff) * 16777216 | $TOTALTIME * 256 | $TRACKS))
+       CDDBTRACKINFO="${CDDBDISCID} $((TRACKS)) ${COOKEDOFFSETS} $((($LEADOUT + $LEADIN + $IDMAGICNUM) / $CDFRAMES))"
+
+       case $CDDBMETHOD in
+               *musicbrainz*)
                        # FIXME: don't assume the first track is 1
-                       echo "dasd: 1 $TRACKS $LEADIN $LEADOUT $OFFSETS "
-                       DISCID=$($MUSICBRAINZ --command calcid --discinfo 1 $TRACKS $LEADIN $LEADOUT $OFFSETS)
+                       MBDISCID=$($MUSICBRAINZ --command calcid --discinfo 1 $TRACKS $LEADIN $(($PREGAP + $LEADOUT)) $OFFSETS)
+                       error=$?
+                       if [ $error != 0 ]; then
+                               log error "$MUSICBRAINZ failed to run; ABORT"
+                               exit $error
+                       fi
+                       MBTRACKINFO="${MBDISCID} $((TRACKS)) ${COOKEDOFFSETS} $((($LEADOUT + $LEADIN + $IDMAGICNUM) / $CDFRAMES))"
                        ;;
        esac
-
-       TRACKINFO="${DISCID} $((TRACKS)) ${COOKEDOFFSETS} $((($LEADOUT + $LEADIN + $IDMAGICNUM) / $CDFRAMES))"
 }
 
 do_replaygain()
 {
        if checkstatus replaygain; then :; else
                run_command "" echo "Adding replaygain information..."
-               for TMPOUTPUT in $( echo $OUTPUTTYPE | tr , \ )
+               for TMPOUTPUT in $( echo "$OUTPUTTYPE" | tr , \ )
                do
                        case $TMPOUTPUT in
                                vorbis|ogg)
@@ -523,12 +553,12 @@ do_replaygain()
                        REPLAYINDEX=0
                        for UTRACKNUM in $TRACKQUEUE
                        do
-                               CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
+                               CDDBTRACKNUM=$(expr "$UTRACKNUM" - 1) # Unpad
                                getcddbinfo TRACKNAME
                                splitvarious
-                               TRACKFILE="$(mungefilename "$TRACKNAME")"
-                               ARTISTFILE="$(mungefilename "$TRACKARTIST")"
-                               ALBUMFILE="$(mungefilename "$DALBUM")"
+                               TRACKFILE="$(mungetrackname "$TRACKNAME")"
+                               ARTISTFILE="$(mungeartistname "$TRACKARTIST")"
+                               ALBUMFILE="$(mungealbumname "$DALBUM")"
                                GENRE="$(mungegenre "$GENRE")"
                                YEAR=${CDYEAR:-$CDYEAR}
                                gettracknum
@@ -550,26 +580,25 @@ do_replaygain()
                        done
                        case "$OUTPUT" in
                                flac)
-                                       run_command replaygain-flac nice $ENCNICE $METAFLAC $FLACGAINOPTS "${OUTPUTFILES[@]}"
-                                       #run_command replaygain-flac true
+                                       run_command "replaygain-flac" nice $ENCNICE $METAFLAC $FLACGAINOPTS "${OUTPUTFILES[@]}"
                                        ;;
                                vorbis|ogg)
-                                       run_command replaygain-vorbis nice $ENCNICE $VORBISGAIN $VORBISGAINOPTS "${OUTPUTFILES[@]}"
+                                       run_command "replaygain-vorbis" nice $ENCNICE $VORBISGAIN $VORBISGAINOPTS "${OUTPUTFILES[@]}"
                                        ;;
                                mp3)
-                                       run_command replaygain-mp3 nice $ENCNICE $MP3GAIN $MP3GAINOPTS "${OUTPUTFILES[@]}"
+                                       run_command "replaygain-mp3" nice $ENCNICE $MP3GAIN $MP3GAINOPTS "${OUTPUTFILES[@]}"
                                        ;;
                                mpc)
-                                       run_command replaygain-mpc nice $ENCNICE $MPCGAIN "${OUTPUTFILES[@]}"
+                                       run_command "replaygain-mpc" nice $ENCNICE $MPCGAIN "${OUTPUTFILES[@]}"
                                        ;;
                                wv)
-                                       run_command replaygain-wv nice $ENCNICE $WVGAIN $WVGAINOPTS "${OUTPUTFILES[@]}"
+                                       run_command "replaygain-wv" nice $ENCNICE $WVGAIN $WVGAINOPTS "${OUTPUTFILES[@]}"
                                        ;;
                                *);;
                        esac
                done
                if checkerrors "replaygain-.{3,6}"; then :; else
-                       run_command replaygain true
+                       run_command "replaygain" true
                fi
        fi
 }
@@ -629,8 +658,8 @@ splitvarious ()
 }
 
 do_getgenreid () {
-local genre=$(echo "${@}" | tr '[A-Z]' '[a-z]')
-local id=""
+       local genre=$(echo "${@}" | tr 'A-Z' 'a-z')
+       local id=""
        case ${genre} in
                "blues")                 id=0 ;;
                "classic rock")          id=1 ;;
@@ -781,7 +810,7 @@ local id=""
                "jpop")                  id=146 ;;
                "synthpop")              id=147 ;;
                "rock/pop"|"rock / pop") id=148 ;;
-               *)                       return 1 ;;
+               *)                       id=255 ;;
        esac
 echo ${id}
 return 0
@@ -794,20 +823,18 @@ return 0
 # COMMENT, DALBUM, DARTIST, CDYEAR, CDGENRE
 do_tag ()
 {
-       COMMENTOUTPUT="$(eval echo ${COMMENT})"
+       COMMENTOUTPUT="$(eval echo "${COMMENT}")"
        if [ -z "$COMMENTOUTPUT" ]; then
                COMMENTOUTPUT="$(getcddbinfo TRACK-INFO)"
        fi
-       if [ "$CDDBMETHOD" = "cddb" ]; then
-               CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
-       fi
-       run_command '' echo "Tagging track $1 of $TRACKS: $TRACKNAME..."
+       CDDBDISCID=$(echo "$CDDBTRACKINFO" | cut -d' ' -f1)
+       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 "$STARTTRACKNUMBERTAG" ] ; then
                gettracknum
        fi
-       for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
+       for OUTPUT in $(echo "$OUTPUTTYPE" | tr , \ )
        do
                case "$OUTPUT" in
                mp3)
@@ -821,23 +848,33 @@ do_tag ()
 
                        case "$ID3SYNTAX" in
                                id3)
-                                       run_command tagtrack-$OUTPUT-$1 nice $ENCNICE \
+                                       run_command "tagtrack-$OUTPUT-$1" nice $ENCNICE \
                                                $TAGGER $TAGGEROPTS -c "$COMMENTOUTPUT" \
                                                -A "$DALBUM" -a "$TRACKARTIST" -t "$TRACKNAME" \
                                                -y "$CDYEAR" -g "$GENREID" \
                                                -T "${TRACKNUM:-$1}" \
-                                               "$ABCDETEMPDIR/track$1.$OUTPUT"
+                                               "${ABCDETEMPDIR}/track$1.$OUTPUT"
                                        ;;
                                id3v2)
                                        # FIXME # track numbers in mp3 come with 1/10, so we cannot
                                        # happily substitute them with $TRACKNUM
-                                       run_command tagtrack-$OUTPUT-$1 nice $ENCNICE \
+                                       run_command "tagtrack-$OUTPUT-$1" nice $ENCNICE \
                                                $TAGGER $TAGGEROPTS -c "$COMMENTOUTPUT" \
                                                -A "$DALBUM" -a "$TRACKARTIST" -t "$TRACKNAME" \
                                                -y "$CDYEAR" -g "$GENREID" \
                                                -T "${TRACKNUM:-$1}/$TRACKS" \
                                                ${TPE2:+--TPE2 "$TPE2"} \
-                                               "$ABCDETEMPDIR/track$1.$OUTPUT"
+                                               "${ABCDETEMPDIR}/track$1.$OUTPUT"
+                                       ;;
+                               id3tag)
+                                       # FIXME # track numbers in mp3 come with 1/10, so we cannot
+                                       # happily substitute them with $TRACKNUM
+                                       run_command "tagtrack-$OUTPUT-$1" nice $ENCNICE \
+                                               $TAGGER $TAGGEROPTS -c "$COMMENTOUTPUT" \
+                                               -A "$DALBUM" -a "$TRACKARTIST" -s "$TRACKNAME" \
+                                               -y "$CDYEAR" -g "$GENREID" \
+                                               -t "${TRACKNUM:-$1}" ${TRACKNUM:+-T "$TRACKS"} \
+                                               "${ABCDETEMPDIR}/track$1.$OUTPUT"
                                        ;;
                                eyed3*)
                                        # FIXME # track numbers in mp3 come with 1/10, so we cannot
@@ -860,13 +897,13 @@ do_tag ()
                                                        ${COMMENTOUTPUT:+--comment "$COMMENTOUTPUT"} \
                                                        );;
                                        esac
-                                       run_command tagtrack-$OUTPUT-$1 nice $ENCNICE $TAGGER $TAGGEROPTS \
+                                       run_command "tagtrack-$OUTPUT-$1" nice $ENCNICE $TAGGER $TAGGEROPTS \
                                                -A "$DALBUM" \
                                                -a "$TRACKARTIST" -t "$TRACKNAME" \
                                                -G "$GENREID" -n "${TRACKNUM:-$1}" \
                                                ${TRACKNUM:+-N "$TRACKS"} \
                                                "${addopts[@]}" \
-                                               "$ABCDETEMPDIR/track$1.$OUTPUT"
+                                               "${ABCDETEMPDIR}/track$1.$OUTPUT"
                                        ;;
                                *)
                                        log error "Internal error: ID3SYNTAX has an illegal value"
@@ -878,12 +915,14 @@ do_tag ()
                        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"
+                                       if [ -f "${ABCDETEMPDIR}/track$1.$OGGOUTPUTCONTAINER" ] && \
+                                                  [ ! -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/vorbis/doc/v-comment.html
+                                       # https://www.xiph.org/vorbis/doc/v-comment.html
 
                                        echo ARTIST="$TRACKARTIST"
                                        echo ALBUM="$DALBUM"
@@ -894,37 +933,45 @@ do_tag ()
                                        if [ -n "$CDGENRE" ]; then
                                                echo GENRE="$CDGENRE"
                                        fi
-                                       echo TRACKNUMBER=${TRACKNUM:-$1}
+                                       echo TRACKNUMBER="${TRACKNUM:-$1}"
                                        # TRACKTOTAL is not in the proposed, minimal list of standard field names from
-                                       # xiph.org: http://www.xiph.org/vorbis/doc/v-comment.html but is in common usage
+                                       # xiph.org: https://www.xiph.org/vorbis/doc/v-comment.html but is in common usage
                                        # and read by mediainfo, ffprobe, vlc, Aqualung, ogg123, Foobar. And now abcde :)
                                        # The tag is quietly ignored by  Audacious, MPlayer, mpv, XMMS....
                                        echo TRACKTOTAL="${TRACKS}"
                                        if [ -n "$DISCNUMBER" ]; then
                                                echo DISCNUMBER="$DISCNUMBER"
                                        fi
-                                       echo CDDB=$CDDBDISCID
+                                       echo CDDB="${CDDBDISCID}"
                                        if [ "$(eval echo ${COMMENT})" != "" ]; then
                                                case "$COMMENTOUTPUT" in
                                                        *=*) echo "$COMMENTOUTPUT";;
                                                        *)   echo COMMENT="$COMMENTOUTPUT";;
                                                esac
                                        fi
-                                       ) | run_command tagtrack-$OUTPUT-$1 nice $ENCNICE \
+                                       ) | run_command "tagtrack-$OUTPUT-$1" nice $ENCNICE \
                                                $VORBISCOMMENT $VORBISCOMMENTOPTS -w \
-                                               "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
+                                               "${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"
+                                       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"
+                                               mv "${ABCDETEMPDIR}/track$1.uncommented.$OGGOUTPUTCONTAINER" \
+                                                  "${ABCDETEMPDIR}/track$1.$OGGOUTPUTCONTAINER"
                                        fi
                                        ;;
                        esac
                        ;;
                opus)
-                       run_command tagtrack-$OUTPUT-$1 true
+                       run_command "tagtrack-$OUTPUT-$1" true
+                       ;;
+               mka)
+                       run_command "tagtrack-$OUTPUT-$1" true
+                       ;;
+               aiff)
+                       run_command "tagtrack-$OUTPUT-$1" true
                        ;;
                flac)
                        (
@@ -939,86 +986,101 @@ do_tag ()
                        fi
                        echo TRACKNUMBER="${TRACKNUM:-$1}"
                        # TRACKTOTAL is not in the proposed, minimal list of standard field names from
-                       # xiph.org: http://www.xiph.org/vorbis/doc/v-comment.html but is in common usage
+                       # xiph.org: https://www.xiph.org/vorbis/doc/v-comment.html but is in common usage
                        # and read by mediainfo, ffprobe, vlc, Aqualung, ogg123, Foobar. And now abcde :)
                        # The tag is quietly ignored by  Audacious, MPlayer, mpv, XMMS....
                        echo TRACKTOTAL="${TRACKS}"
                        if [ -n "$DISCNUMBER" ]; then
                                echo DISCNUMBER="$DISCNUMBER"
                        fi
-                       echo CDDB="$CDDBDISCID"
-                       if [ "$(eval echo ${COMMENT})" != "" ]; then
+                       echo CDDB="${CDDBDISCID}"
+                       if [ -n "$(eval echo "${COMMENT}")" ]; then
                                case "$COMMENTOUTPUT" in
                                        *=*) echo "$COMMENTOUTPUT";;
                                        *)   echo COMMENT="$COMMENTOUTPUT";;
                                esac
                        fi
-                       ) | run_command tagtrack-$OUTPUT-$1 nice $ENCNICE $METAFLAC $METAFLACOPTS ${IMPORTCUESHEET:+--import-cuesheet-from="$ABCDETEMPDIR/$CUEFILE"} \
-                       --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
+                       ) | run_command "tagtrack-$OUTPUT-$1" nice $ENCNICE $METAFLAC $METAFLACOPTS \
+                                                       ${IMPORTCUESHEET:+--import-cuesheet-from="${ABCDETEMPDIR}/$CUEFILE"} \
+                                                       --import-tags-from=- "${ABCDETEMPDIR}/track$1.$FLACOUTPUTCONTAINER"
                        ;;
                spx)
-                       run_command tagtrack-$OUTPUT-$1 true
+                       run_command "tagtrack-$OUTPUT-$1" true
                        ;;
                mpc)
-                       run_command tagtrack-$OUTPUT-$1 true
+                       run_command "tagtrack-$OUTPUT-$1" true
                        ;;
                wv)
-                       run_command tagtrack-$OUTPUT-$1 true
+                       run_command "tagtrack-$OUTPUT-$1" true
                        ;;
                ape)
                        # This tagging syntax is suitable for Robert Muth's application 'apetag', the Monkey's Audio 
                        # Console port (mac) used for encoding does not have the ability to tag.
-                       run_command tagtrack-$OUTPUT-$1 nice $ENCNICE "$APETAG" -i "$ABCDETEMPDIR/track$1.ape" -m overwrite \
-                       -p artist="$TRACKARTIST" -p album="$DALBUM" -p title="$TRACKNAME" -p track=${TRACKNUM:-$1} \
-                       -p year="$CDYEAR" -p genre="$CDGENRE" ${COMMENTOUTPUT:+-p comment="$COMMENTOUTPUT"} 
+                       run_command "tagtrack-$OUTPUT-$1" nice $ENCNICE "$APETAG" -i "${ABCDETEMPDIR}/track$1.ape" -m overwrite \
+                                               -p artist="$TRACKARTIST" -p album="$DALBUM" -p title="$TRACKNAME" -p track="${TRACKNUM:-$1}" \
+                                               -p year="$CDYEAR" -p genre="$CDGENRE" ${COMMENTOUTPUT:+-p comment="$COMMENTOUTPUT"} 
                        ;;
                mp2)
                        # Using Mutagen's mid3v2 for tagging with id3v2.4.0. Interesting enough vlc, MPlayer and XMMS ignore
-                       # these tags but they are read by Audacious, Xine, Aqualung, mediainfo, ffplay, ffprobe. Curious...
-                       run_command tagtrack-$OUTPUT-$1 nice $ENCNICE "$MID3V2" -A "$DALBUM" -a "$TRACKARTIST" -t "$TRACKNAME" \
-                       -y "$CDYEAR" -g "$CDGENRE" -T "${TRACKNUM:-$1}/$TRACKS" ${TPE2:+--TPE2 "$TPE2"} ${COMMENTOUTPUT:+--comment="$COMMENTOUTPUT"} \
-                       "$ABCDETEMPDIR/track$1.mp2"
+                       # these tags but they are read by Audacious, Xine, Aqualung, mediainfo, ffplay, ffprobe. FFmpeg does
+                       # not currently tag mp2 audio so twolame and FFmpeg will both use mid3v2...
+                       run_command "tagtrack-$OUTPUT-$1" nice $ENCNICE "$MID3V2" --verbose -A "$DALBUM" \
+                                               -a "$TRACKARTIST" -t "$TRACKNAME" -y "$CDYEAR" -g "$CDGENRE" \
+                                               -T "${TRACKNUM:-$1}/$TRACKS" ${TPE2:+--TPE2 "$TPE2"} \
+                                               ${COMMENTOUTPUT:+--comment="$COMMENTOUTPUT"} \
+                                               "${ABCDETEMPDIR}/track$1.mp2"
                        ;;
                aac)
-                       run_command tagtrack-$OUTPUT-$1 true
+                       run_command "tagtrack-$OUTPUT-$1" true
                        ;;
                m4a)
                        case "$AACENCODERSYNTAX" in
                                fdkaac)
                                        # We will use inline tagging...
-                                       run_command tagtrack-$OUTPUT-$1 true
+                                       run_command "tagtrack-$OUTPUT-$1" true
                                        ;;
                                neroAacEnc)
                                        # Tag post encode with neroAacTag...
-                                       run_command tagtrack-$OUTPUT-$1 nice $ENCNICE "$NEROAACTAG" "$ABCDETEMPDIR/track$1.m4a" \
-                                       -meta:artist="$TRACKARTIST" -meta:album="$DALBUM" -meta:title="$TRACKNAME" -meta:track=${TRACKNUM:-$1} \
-                                       -meta:year="$CDYEAR" -meta:genre="$CDGENRE" -meta:comment="$COMMENT"
+                                       run_command "tagtrack-$OUTPUT-$1" nice $ENCNICE "$NEROAACTAG" \
+                                                               "${ABCDETEMPDIR}/track$1.m4a" \
+                                                               -meta:artist="$TRACKARTIST" -meta:album="$DALBUM" \
+                                                               -meta:title="$TRACKNAME" -meta:track="${TRACKNUM:-$1}" \
+                                                               -meta:year="$CDYEAR" -meta:genre="$CDGENRE" -meta:comment="$COMMENT"
                                        ;;
                                faac)
-                                       run_command tagtrack-$OUTPUT-$1 true   
+                                       run_command "tagtrack-$OUTPUT-$1" true
                                        ;;
                                qaac)
-                                       run_command tagtrack-$OUTPUT-$1 true   
+                                       run_command "tagtrack-$OUTPUT-$1" true
                                        ;;
                                fhgaacenc)
                                        # Tag post encode with AtomicParsley. Note that previous problems with seg fault when using
                                        # 'overWrite' cannot be reproduced with newer versions: https://bitbucket.org/wez/atomicparsley
-                                       run_command tagtrack-$OUTPUT-$1 nice $ENCNICE "$ATOMICPARSLEY" "$ABCDETEMPDIR/track$1.m4a" \
-                                       --artist="$TRACKARTIST" --album="$DALBUM" --title="$TRACKNAME" --tracknum=${TRACKNUM:-$1} \
-                                       --year="$CDYEAR" --genre="$CDGENRE" --comment="$COMMENT" $ATOMICPARSLEYOPTS --overWrite
+                                       run_command "tagtrack-$OUTPUT-$1" nice $ENCNICE "$ATOMICPARSLEY" \
+                                                               "${ABCDETEMPDIR}/track$1.m4a" --artist="$TRACKARTIST" --album="$DALBUM" \
+                                                               --title="$TRACKNAME" --tracknum="${TRACKNUM:-$1}" \
+                                                               --year="$CDYEAR" --genre="$CDGENRE" --comment="$COMMENT" \
+                                                               $ATOMICPARSLEYOPTS --overWrite
                                        ;;
                                ffmpeg)
-                                       run_command tagtrack-$OUTPUT-$1 true   
+                                       run_command "tagtrack-$OUTPUT-$1" true
                                ;;
                        esac
                        ;;
+               tta)
+                       # We use mid3v2 tagging for True Audio:
+                       run_command "tagtrack-$OUTPUT-$1" nice $ENCNICE "$MID3V2" --verbose -A "$DALBUM" \
+                                               -a "$TRACKARTIST" -t "$TRACKNAME" -y "$CDYEAR" -g "$CDGENRE" \
+                                               -T "${TRACKNUM:-$1}/$TRACKS" ${TPE2:+--TPE2 "$TPE2"} \
+                                               ${COMMENTOUTPUT:+--comment="$COMMENTOUTPUT"} "${ABCDETEMPDIR}/track$1.tta"
+                       ;;
                wav)
-                       run_command tagtrack-$OUTPUT-$1 true
+                       run_command "tagtrack-$OUTPUT-$1" true
                        ;;
                esac
        done
        if checkerrors "tagtrack-(.{3,6})-$1"; then :; else
-               run_command tagtrack-$1 true
+               run_command "tagtrack-$1" true
        fi
 }
 
@@ -1030,30 +1092,29 @@ do_nogap_encode ()
        # The commands here don't go through run_command because they're never
        # supposed to be silenced
        echo "Encoding gapless MP3 tracks: $TRACKQUEUE"
-       for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
+       for OUTPUT in $(echo "$OUTPUTTYPE" | tr , \ )
        do
                case "$OUTPUT" in
                mp3)
                        case "$MP3ENCODERSYNTAX" in
                        lame)
                                (
-                               cd "$ABCDETEMPDIR"
-                               TRACKFILES=
-                               for UTRACKNUM in $TRACKQUEUE
-                               do
-                                       TRACKFILES="$TRACKFILES track$UTRACKNUM.wav"
-                               done
-                               nice $ENCNICE $MP3ENCODER $MP3ENCODEROPTS --nogap $TRACKFILES
-                               RETURN=$?
-                               if [ "$RETURN" != "0" ]; then
-                                       echo "nogap-encode: $ENCODER returned code $RETURN" >> errors
-                               else
-                                       for UTRACKNUM in $TRACKQUEUE
+                                       cd "${ABCDETEMPDIR}"
+                                       TRACKFILES=
+                                       for THISTRACKNUM in $TRACKQUEUE
                                        do
-                                               run_command encodetrack-$OUTPUT-$UTRACKNUM true
-                                               #run_command encodetrack-$UTRACKNUM true
+                                               TRACKFILES="$TRACKFILES track$THISTRACKNUM.wav"
                                        done
-                               fi
+                                       nice $ENCNICE $MP3ENCODER $MP3ENCODEROPTS --nogap $TRACKFILES
+                                       RETURN=$?
+                                       if [ "$RETURN" != "0" ]; then
+                                               echo "nogap-encode: $MP3ENCODER returned code $RETURN" >> "${ABCDETEMPDIR}/errors"
+                                       else
+                                               for THISTRACKNUM in $TRACKQUEUE
+                                               do
+                                                       run_command "encodetrack-$OUTPUT-$THISTRACKNUM" true
+                                               done
+                                       fi
                                )
                                ;;
                        esac
@@ -1089,6 +1150,12 @@ do_encode ()
                        opus)
                                TEMPARG="PIPE_$OPUSENCODERSYNTAX"
                                ;;
+                       mka)
+                               TEMPARG="PIPE_$MKAENCODERSYNTAX"
+                               ;;
+                       aiff)
+                               TEMPARG="PIPE_$AIFFENCODERSYNTAX"
+                               ;;
                        flac)
                                TEMPARG="PIPE_$FLACENCODERSYNTAX"
                                ;;
@@ -1101,6 +1168,9 @@ do_encode ()
                        wv)
                                TEMPARG="PIPE_$WVENCODERSYNTAX"
                                ;;
+                       tta)
+                               TEMPARG="PIPE_$TTAENCODERSYNTAX"
+                               ;;
                        aac)
                                TEMPARG="PIPE_$AACENCODERSYNTAX"
                                ;;
@@ -1110,11 +1180,11 @@ do_encode ()
                esac
                IN="$( eval echo "\$$TEMPARG" )"
        else
-               IN="$ABCDETEMPDIR/track$1.wav"
+               IN="${ABCDETEMPDIR}/track$1.wav"
        fi
        # We need IN to proceed, if we are not using pipes.
-       if [ -s "$IN" -o X"$USEPIPES" = "Xy" ] ; then
-               for TMPOUTPUT in $(echo $OUTPUTTYPE | tr , \ )
+       if [ -s "$IN" ] || [ X"$USEPIPES" = "Xy" ] ; then
+               for TMPOUTPUT in $(echo "$OUTPUTTYPE" | tr , \ )
                do
                        case "$TMPOUTPUT" in
                                vorbis|ogg)
@@ -1123,6 +1193,12 @@ do_encode ()
                                opus)
                                        OUTPUT=$OPUSOUTPUTCONTAINER
                                        ;;
+                               mka)
+                                       OUTPUT=$MKAOUTPUTCONTAINER
+                                       ;;
+                               aiff)
+                                       OUTPUT=$AIFFOUTPUTCONTAINER
+                                       ;;
                                flac)
                                        OUTPUT=$FLACOUTPUTCONTAINER
                                        ;;
@@ -1130,8 +1206,8 @@ do_encode ()
                                        OUTPUT=$TMPOUTPUT
                                        ;;
                        esac
-                       OUT="$ABCDETEMPDIR/track$1.$OUTPUT"
-                       if [ "$NOGAP" = "y" ] && checkstatus encodetrack-$OUTPUT-$1 ; then
+                       OUT="${ABCDETEMPDIR}/track$1.$OUTPUT"
+                       if [ "$NOGAP" = "y" ] && checkstatus "encodetrack-$OUTPUT-$1" ; then
                                continue
                        fi
                        if [ X"$USEPIPES" = "Xy" ]; then
@@ -1144,7 +1220,7 @@ do_encode ()
                                # bit the reading process.
                                EFFECTIVE_NICE=$READNICE
                        else
-                               run_command '' echo "Encoding track $1 of $TRACKS: $TRACKNAME..."
+                               run_command "" echo "Encoding track $1 of $TRACKS: $TRACKNAME..."
                                RUN_COMMAND="run_command encodetrack-$OUTPUT-$1"
                                EFFECTIVE_NICE=$ENCNICE
                        fi
@@ -1184,9 +1260,10 @@ do_encode ()
                                        opusenc)
                                        # Tag the file at encode time, as it can't be done after encoding.
                                                if [ "$DOTAG" = "y" ]; then
-                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $OPUSENCODER $OPUSENCODEROPTS --artist "$TRACKARTIST" \
-                                                       --album "$DALBUM" --title "$TRACKNAME" --genre "$CDGENRE" --date "$CDYEAR" --comment TRACKNUMBER="$1" \
-                                                       ${COMMENT:+--comment COMMENT="$COMMENT"} "$IN" "$OUT"
+                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $OPUSENCODER $OPUSENCODEROPTS \
+                                                                                --artist "$TRACKARTIST" --album "$DALBUM" --title "$TRACKNAME" \
+                                                                                --genre "$CDGENRE" --date "$CDYEAR" --comment TRACKNUMBER="$1" \
+                                                                                ${COMMENT:+--comment COMMENT="$COMMENT"} "$IN" "$OUT"
                                                else
                                                        $RUN_COMMAND nice $EFFECTIVE_NICE $OPUSENCODER $OPUSENCODEROPTS "$IN" "$OUT"
                                                fi
@@ -1198,6 +1275,36 @@ do_encode ()
                                        ;;
                                esac
                                ;;
+                       mka)
+                               case "$MKAENCODERSYNTAX" in
+                               ffmpeg)
+                                       if [ "$DOTAG" = "y" ]; then
+                                               $RUN_COMMAND nice $EFFECTIVE_NICE $MKAENCODER -i "$IN" $MKAENCODEROPTS \
+                                                                        -metadata artist="$TRACKARTIST" -metadata album="$DALBUM" \
+                                                                        -metadata title="$TRACKNAME" -metadata track="${TRACKNUM:-$1}" \
+                                                                        -metadata date="$CDYEAR" -metadata genre="$CDGENRE" \
+                                                                        -metadata comment="$COMMENT" "$OUT"
+                                       else
+                                               $RUN_COMMAND nice $EFFECTIVE_NICE $MKAENCODER -i "$IN" $MKAENCODEROPTS "$OUT"
+                                       fi
+                               ;;
+                               esac
+                               ;;
+                       aiff)
+                               case "$AIFFENCODERSYNTAX" in
+                               ffmpeg)
+                                       if [ "$DOTAG" = "y" ]; then
+                                               $RUN_COMMAND nice $EFFECTIVE_NICE $AIFFENCODER -i "$IN" $AIFFENCODEROPTS \
+                                                                        -metadata artist="$TRACKARTIST" -metadata album="$DALBUM" \
+                                                                        -metadata title="$TRACKNAME" -metadata track="${TRACKNUM:-$1}" \
+                                                                        -metadata date="$CDYEAR" -metadata genre="$CDGENRE" \
+                                                                        -metadata comment="$COMMENT" "$OUT"
+                                       else
+                                               $RUN_COMMAND nice $EFFECTIVE_NICE $AIFFENCODER -i "$IN" $AIFFENCODEROPTS "$OUT"
+                                       fi
+                               ;;
+                               esac
+                               ;;
                        flac)
                                case "$2" in
                                %local*%)
@@ -1213,7 +1320,7 @@ do_encode ()
                                esac
                                ;;
                        spx)
-                               if [ "$(eval echo ${COMMENT})" != "" ]; then
+                               if [ -n "$(eval echo "${COMMENT}")" ]; then
                                        case "$COMMENT" in
                                                *=*) ;;
                                                *)   COMMENT="COMMENT=$COMMENT" ;;
@@ -1221,8 +1328,9 @@ do_encode ()
                                fi
                                # Tag the file at encode time, as it can't be done after encoding.
                                if [ "$DOTAG" = "y" ]; then
-                                       $RUN_COMMAND nice $EFFECTIVE_NICE $SPEEXENCODER $SPEEXENCODEROPTS --author "$TRACKARTIST" --title "$TRACKNAME" \
-                                       ${COMMENT:+--comment "$COMMENT"} "$IN" "$OUT"
+                                       $RUN_COMMAND nice $EFFECTIVE_NICE $SPEEXENCODER $SPEEXENCODEROPTS \
+                                                                --author "$TRACKARTIST" --title "$TRACKNAME" \
+                                                                ${COMMENT:+--comment "$COMMENT"} "$IN" "$OUT"
                                else
                                        $RUN_COMMAND nice $EFFECTIVE_NICE $SPEEXENCODER $SPEEXENCODEROPTS "$IN" "$OUT"
                                fi
@@ -1230,27 +1338,44 @@ do_encode ()
                        mpc)
                                # Tag the file inline at encode time.
                                if [ "$DOTAG" = "y" ]; then
-                                       $RUN_COMMAND nice $EFFECTIVE_NICE $MPCENCODER $MPCENCODEROPTS --artist "$TRACKARTIST" --album "$DALBUM" \
-                                       --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" --year "$CDYEAR" ${COMMENT:+--comment "$COMMENT"} "$IN" "$OUT"
+                                       $RUN_COMMAND nice $EFFECTIVE_NICE $MPCENCODER $MPCENCODEROPTS \
+                                                                --artist "$TRACKARTIST" --album "$DALBUM" \
+                                                                --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" \
+                                                                --year "$CDYEAR" ${COMMENT:+--comment "$COMMENT"} "$IN" "$OUT"
                                else
                                        $RUN_COMMAND nice $EFFECTIVE_NICE $MPCENCODER $MPCENCODEROPTS "$IN" "$OUT"
                                fi
                                ;;
+                       tta)
+                               case "$TTAENCODERSYNTAX" in
+                               # tta is the newer version with a small syntax change...
+                                       tta)
+                                       $RUN_COMMAND nice $EFFECTIVE_NICE $TTAENCODER -e $TTAENCODEROPTS "$IN" "$OUT"
+                                       ;;
+                                       ttaenc)
+                                       $RUN_COMMAND nice $EFFECTIVE_NICE $TTAENCODER -e $TTAENCODEROPTS "$IN" -o "$OUT"
+                                       ;;
+                               esac
+                               ;;
                        wv)
                        case "$WVENCODERSYNTAX" in
                                wavpack)
                                        if [ "$DOTAG" = "y" ]; then
-                                               $RUN_COMMAND nice $EFFECTIVE_NICE $WVENCODER $WVENCODEROPTS -w Artist="$TRACKARTIST" -w Album="$DALBUM" \
-                                               -w Title="$TRACKNAME" -w Track="$1" -w Genre="$CDGENRE" -w Year="$CDYEAR" ${COMMENT:+-w Comment="$COMMENT"} "$IN" -o "$OUT"
+                                               $RUN_COMMAND nice $EFFECTIVE_NICE $WVENCODER $WVENCODEROPTS \
+                                                                        -w Artist="$TRACKARTIST" -w Album="$DALBUM" \
+                                                                        -w Title="$TRACKNAME" -w Track="$1" -w Genre="$CDGENRE" \
+                                                                        -w Year="$CDYEAR" ${COMMENT:+-w Comment="$COMMENT"} "$IN" -o "$OUT"
                                        else
                                                $RUN_COMMAND nice $EFFECTIVE_NICE $WVENCODER $WVENCODEROPTS "$IN" -o "$OUT"
                                        fi
                                ;;
                                ffmpeg)
                                        if [ "$DOTAG" = "y" ]; then
-                                               $RUN_COMMAND nice $EFFECTIVE_NICE $WVENCODER -i "$IN" $WVENCODEROPTS -metadata artist="$TRACKARTIST" \
-                                               -metadata album="$DALBUM" -metadata title="$TRACKNAME" -metadata track=${TRACKNUM:-$1} -metadata date="$CDYEAR" \
-                                               -metadata genre="$CDGENRE" -metadata comment="$COMMENT" "$OUT" 
+                                               $RUN_COMMAND nice $EFFECTIVE_NICE $WVENCODER -i "$IN" $WVENCODEROPTS \
+                                                                        -metadata artist="$TRACKARTIST" \
+                                                                        -metadata album="$DALBUM" -metadata title="$TRACKNAME" \
+                                                                        -metadata track="${TRACKNUM:-$1}" -metadata date="$CDYEAR" \
+                                                                        -metadata genre="$CDGENRE" -metadata comment="$COMMENT" "$OUT" 
                                        else 
                                                $RUN_COMMAND nice $EFFECTIVE_NICE $WVENCODER -i "$IN" $WVENCODEROPTS "$OUT"
                                        fi
@@ -1261,7 +1386,14 @@ do_encode ()
                                $RUN_COMMAND nice $EFFECTIVE_NICE $APENCODER "$IN" "$OUT" $APENCODEROPTS
                                ;;
                        mp2)
-                               $RUN_COMMAND nice $EFFECTIVE_NICE $MP2ENCODER $MP2ENCODEROPTS "$IN" "$OUT" 
+                               case "$MP2ENCODERSYNTAX" in
+                                       twolame)
+                                               $RUN_COMMAND nice $EFFECTIVE_NICE $MP2ENCODER $MP2ENCODEROPTS "$IN" "$OUT"
+                                               ;;
+                                       ffmpeg)
+                                               $RUN_COMMAND nice $EFFECTIVE_NICE $MP2ENCODER -i "$IN" $MP2ENCODEROPTS "$OUT" 
+                                               ;;
+                               esac
                                ;;
                        aac)
                                # aac container is only used to catch faac encoded files where faac 
@@ -1272,8 +1404,10 @@ do_encode ()
                                case "$AACENCODERSYNTAX" in
                                        faac)
                                                if [ "$DOTAG" = "y" ]; then
-                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS  --artist "$TRACKARTIST" --album "$DALBUM" \
-                                                       --title "$TRACKNAME" --track ${TRACKNUM:-$1} --year "$CDYEAR" --genre "$CDGENRE" --comment "$COMMENT" -o "$OUT" "$IN"
+                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS  \
+                                                                                --artist "$TRACKARTIST" --album "$DALBUM" \
+                                                                                --title "$TRACKNAME" --track "${TRACKNUM:-$1}" \
+                                                                                --year "$CDYEAR" --genre "$CDGENRE" --comment "$COMMENT" -o "$OUT" "$IN"
                                                else 
                                                        $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS -o "$OUT" "$IN"   
                                                fi
@@ -1283,16 +1417,20 @@ do_encode ()
                                                ;;
                                        fdkaac)      
                                                if [ "$DOTAG" = "y" ]; then
-                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS --artist "$TRACKARTIST" --album "$DALBUM" \
-                                                       --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" --date "$CDYEAR" --comment "$COMMENT" "$IN" -o "$OUT"
+                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS \
+                                                                                --artist "$TRACKARTIST" --album "$DALBUM" \
+                                                                                --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" \
+                                                                                --date "$CDYEAR" --comment "$COMMENT" "$IN" -o "$OUT"
                                                else
                                                        $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS "$IN" -o "$OUT"
                                                fi
                                                ;;
                                        qaac)
                                                if [ "$DOTAG" = "y" ]; then
-                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $WINE $AACENCODER $AACENCODEROPTS  --artist "$TRACKARTIST" --album "$DALBUM" \
-                                                       --title "$TRACKNAME" --track ${TRACKNUM:-$1} --date "$CDYEAR" --genre "$CDGENRE" --comment "$COMMENT" -o "$OUT" "$IN"
+                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $WINE $AACENCODER $AACENCODEROPTS \
+                                                                                --artist "$TRACKARTIST" --album "$DALBUM" \
+                                                                                --title "$TRACKNAME" --track "${TRACKNUM:-$1}" \
+                                                                                --date "$CDYEAR" --genre "$CDGENRE" --comment "$COMMENT" -o "$OUT" "$IN"
                                                else 
                                                        $RUN_COMMAND nice $EFFECTIVE_NICE $WINE $AACENCODER $AACENCODEROPTS -o "$OUT" "$IN"
                                                fi
@@ -1302,9 +1440,11 @@ do_encode ()
                                                ;;
                                        ffmpeg)
                                                if [ "$DOTAG" = "y" ]; then
-                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER -i "$IN" $AACENCODEROPTS -metadata artist="$TRACKARTIST" \
-                                                       -metadata album="$DALBUM" -metadata title="$TRACKNAME" -metadata track=${TRACKNUM:-$1} -metadata date="$CDYEAR" \
-                                                       -metadata genre="$CDGENRE" -metadata comment="$COMMENT" "$OUT" 
+                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER -i "$IN" \
+                                                                                $AACENCODEROPTS -metadata artist="$TRACKARTIST" \
+                                                                                -metadata album="$DALBUM" -metadata title="$TRACKNAME" \
+                                                                                -metadata track="${TRACKNUM:-$1}" -metadata date="$CDYEAR" \
+                                                                                -metadata genre="$CDGENRE" -metadata comment="$COMMENT" "$OUT" 
                                                else 
                                                        $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER -i "$IN"  $AACENCODEROPTS "$OUT"
                                                fi
@@ -1314,15 +1454,15 @@ do_encode ()
                        wav)
                                # In case of wav output we need nothing. Just keep the wavs.
                                # But we need the following to allow full logging and subsequent 
-                               # successful cleaning of $ABCDETEMPDIR.
-                               echo "encodetrack-$OUTPUT-$UTRACKNUM" >> "$ABCDETEMPDIR/status"
+                               # successful cleaning of ${ABCDETEMPDIR}.
+                               echo "encodetrack-$OUTPUT-$UTRACKNUM" >> "${ABCDETEMPDIR}/status"
                                ;;
                        esac
                        $RUN_COMMAND_PIPES
                done
                # Only remove .wav if the encoding succeeded
                if checkerrors "encodetrack-(.{3,6})-$1"; then :; else
-                       run_command encodetrack-$1 true
+                       run_command "encodetrack-$1" true
                        if [ ! "$KEEPWAVS" = "y" ] ; then
                                if [ ! "$KEEPWAVS" = "move" ] ; then
                                        rm -f "$IN"
@@ -1332,85 +1472,87 @@ do_encode ()
        else
                run_command "" echo "HEH! The file we were about to encode disappeared:"
                run_command "" echo ">> $IN"
-               run_command encodetrack-$1 false
+               run_command "encodetrack-$1" false
        fi
 }
 
 # do_preprocess [tracknumber]
 # variables used:
-# TRACKS, TRACKNAME, TRACKARTIST, DISTMP3, DISTMP3OPTS, {FOO}ENCODERSYNTAX, OUTPUTTYPE, ENCODEROPTS, DALBUM, DARTIST, ENCNICE, CDYEAR, CDGENRE, COMMENT
+# TRACKS, TRACKNAME, TRACKARTIST, DISTMP3, DISTMP3OPTS, {FOO}ENCODERSYNTAX,
+# OUTPUTTYPE, ENCODEROPTS, DALBUM, DARTIST, ENCNICE, CDYEAR, CDGENRE, COMMENT
 #do_preprocess ()
 #{
-#      IN="$ABCDETEMPDIR/track$1.wav"
+#      IN="${ABCDETEMPDIR}/track$1.wav"
 #      # We need IN to proceed.
 #      if [ -s "$IN" ] ; then
 #              for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
 #              do
-#                      #OUT="$ABCDETEMPDIR/track$1.$OUTPUT"
-#                      run_command '' echo "Pre-processing track $1 of $TRACKS..."
+#                      #OUT="${ABCDETEMPDIR}/track$1.$OUTPUT"
+#                      run_command "" echo "Pre-processing track $1 of $TRACKS..."
 #                      case "$POSTPROCESSFORMAT" in
 #                      all|wav*)
-#                              run_command preprocess-$OUTPUT-$1 nice $PRENICE $WAV_PRE $IF $OF ;;
+#                              run_command "preprocess-$OUTPUT-$1" nice $PRENICE $WAV_PRE $IF $OF ;;
 #                      mp3)
-#                              run_command preprocess-$OUTPUT-$1 nice $PRENICE $MP3_PRE $IF $OF ;;
+#                              run_command "preprocess-$OUTPUT-$1" nice $PRENICE $MP3_PRE $IF $OF ;;
 #                      ogg)
-#                              run_command preprocess-$OUTPUT-$1 nice $PRENICE $OGG_PRE $IF $OF ;;
+#                              run_command "preprocess-$OUTPUT-$1" nice $PRENICE $OGG_PRE $IF $OF ;;
 #                      flac)
-#                              run_command preprocess-$OUTPUT-$1 nice $PRENICE $FLAC_PRE $IF $OF ;;
+#                              run_command "preprocess-$OUTPUT-$1" nice $PRENICE $FLAC_PRE $IF $OF ;;
 #                      spx)
-#                              run_command preprocess-$OUTPUT-$1 nice $PRENICE $SPX_PRE $IF $OF ;;
+#                              run_command "preprocess-$OUTPUT-$1" nice $PRENICE $SPX_PRE $IF $OF ;;
 #                      esac
 #              done
 #              # Only remove .wav if the encoding succeeded
 #              if checkerrors "preprocess-(.{3,4})-$1"; then
-#                      run_command preprocess-$1 false
+#                      run_command "preprocess-$1" false
 #              else
-#                      run_command preprocess-$1 true
+#                      run_command "preprocess-$1" true
 #              fi
 #      else
 #              if [ "$(checkstatus encode-output)" = "loud" ]; then
 #                      echo "HEH! The file we were about to pre-process disappeared:"
 #                      echo ">> $IN"
 #              fi
-#              run_command preprocess-$1 false
+#              run_command "preprocess-$1" false
 #      fi
 #}
 
 
 # do_postprocess [tracknumber]
 # variables used:
-# TRACKS, TRACKNAME, TRACKARTIST, DISTMP3, DISTMP3OPTS, {FOO}ENCODERSYNTAX, OUTPUTTYPE, ENCODEROPTS, DALBUM, DARTIST, ENCNICE, CDYEAR, CDGENRE, COMMENT
+# TRACKS, TRACKNAME, TRACKARTIST, DISTMP3, DISTMP3OPTS, {FOO}ENCODERSYNTAX, OUTPUTTYPE, ENCODEROPTS, 
+# DALBUM, DARTIST, ENCNICE, CDYEAR, CDGENRE, COMMENT
 #do_postprocess ()
 #{
 #      for POSTPROCESSFORMAT in $(echo $POSTPROCESSFORMATS | tr , \ )
 #      do
-#              IN="$ABCDETEMPDIR/track$1.$POSTPROCESSFORMAT"
+#              IN="${ABCDETEMPDIR}/track$1.$POSTPROCESSFORMAT"
 #              # We need IN to proceed.
 #              if [ -s "$IN" ] ; then
-#                      #OUT="$ABCDETEMPDIR/track$1.$OUTPUT"
-#                      run_command '' echo "Post-processing track $1 of $TRACKS..."
+#                      #OUT="${ABCDETEMPDIR}/track$1.$OUTPUT"
+#                      run_command "" echo "Post-processing track $1 of $TRACKS..."
 #                      case "$POSTPROCESSFORMAT" in
 #                              mp3)
-#                                      run_command postprocess-$OUTPUT-$1 nice $POSTNICE $MP3_POST $IF $OF ;;
+#                                      run_command "postprocess-$OUTPUT-$1" nice $POSTNICE $MP3_POST $IF $OF ;;
 #                              ogg)
-#                                      run_command postprocess-$OUTPUT-$1 nice $POSTNICE $OGG_POST $IF $OF ;;
+#                                      run_command "postprocess-$OUTPUT-$1" nice $POSTNICE $OGG_POST $IF $OF ;;
 #                              flac)
-#                                      run_command postprocess-$OUTPUT-$1 nice $POSTNICE $FLAC_POST $IF $OF ;;
+#                                      run_command "postprocess-$OUTPUT-$1" nice $POSTNICE $FLAC_POST $IF $OF ;;
 #                              spx)
-#                                      run_command postprocess-$OUTPUT-$1 nice $POSTNICE $SPX_POST $IF $OF ;;
+#                                      run_command "postprocess-$OUTPUT-$1" nice $POSTNICE $SPX_POST $IF $OF ;;
 #                      esac
 #                      # Only remove .wav if the encoding succeeded
 #                      if checkerrors "postprocess-(.{3,4})-$1"; then
-#                              run_command postprocess-$1 false
+#                              run_command "postprocess-$1" false
 #                      else
-#                              run_command postprocess-$1 true
+#                              run_command "postprocess-$1" true
 #                      fi
 #              else
 #                      if [ "$(checkstatus encode-output)" = "loud" ]; then
 #                              echo "HEH! The file we were about to post-process disappeared:"
 #                              echo ">> $IN"
 #                      fi
-#                      run_command postprocess-$1 false
+#                      run_command "postprocess-$1" false
 #              fi
 #      done
 #}
@@ -1432,22 +1574,22 @@ do_batch_gain ()
        # The commands here don't go through run_command because they're never supposed to be silenced
        echo "Batch analizing gain in tracks: $TRACKQUEUE"
        (
-       cd "$ABCDETEMPDIR"
+       cd "${ABCDETEMPDIR}"
        BLURB=
        TRACKFILES=
        for UTRACKNUM in $TRACKQUEUE
        do
-               MP3FILES="$TRACKFILES track$UTRACKNUM.mp3"
+               TRACKFILES="$TRACKFILES track$UTRACKNUM.mp3"
        done
        # FIXME # Hard-coded batch option!
        $NORMALIZER -b $NORMALIZEROPTS $TRACKFILES
        RETURN=$?
        if [ "$RETURN" != "0" ]; then
-               echo "batch-normalize: $NORMALIZER returned code $RETURN" >> errors
+               echo "batch-normalize: $NORMALIZER returned code $RETURN" >> "${ABCDETEMPDIR}/errors"
        else
                for UTRACKNUM in $TRACKQUEUE
                do
-                       echo normalizetrack-$UTRACKNUM >> status
+                       echo "normalizetrack-$UTRACKNUM" >> "${ABCDETEMPDIR}/status"
                done
        fi
        )
@@ -1461,7 +1603,7 @@ do_batch_normalize ()
        # The commands here don't go through run_command because they're never supposed to be silenced
        echo "Batch normalizing tracks: $TRACKQUEUE"
        (
-       cd "$ABCDETEMPDIR"
+       cd "${ABCDETEMPDIR}"
        BLURB=
        TRACKFILES=
        for UTRACKNUM in $TRACKQUEUE
@@ -1472,11 +1614,11 @@ do_batch_normalize ()
        $NORMALIZER -b $NORMALIZEROPTS $TRACKFILES
        RETURN=$?
        if [ "$RETURN" != "0" ]; then
-               echo "batch-normalize: $NORMALIZER returned code $RETURN" >> errors
+               echo "batch-normalize: $NORMALIZER returned code $RETURN" >> "${ABCDETEMPDIR}/errors"
        else
                for UTRACKNUM in $TRACKQUEUE
                do
-                       echo normalizetrack-$UTRACKNUM >> status
+                       echo "normalizetrack-$UTRACKNUM" >> "${ABCDETEMPDIR}/status"
                done
        fi
        )
@@ -1487,16 +1629,16 @@ do_batch_normalize ()
 # TRACKS, TRACKNAME, NORMALIZER, NORMALIZEROPTS
 do_normalize ()
 {
-       IN="$ABCDETEMPDIR/track$1.wav"
+       IN="${ABCDETEMPDIR}/track$1.wav"
        if [ -e "$IN" ] ; then
-               run_command '' echo "Normalizing track $1 of $TRACKS: $TRACKNAME..."
-               run_command normalizetrack-$1 $NORMALIZER $NORMALIZEROPTS "$IN"
+               run_command "" echo "Normalizing track $1 of $TRACKS: $TRACKNAME..."
+               run_command "normalizetrack-$1" $NORMALIZER $NORMALIZEROPTS "$IN"
        else
                if [ "$(checkstatus encode-output)" = "loud" ]; then
                        echo "HEH! The file we were about to normalize disappeared:"
                        echo ">> $IN"
                fi
-               run_command normalizetrack-$1 false "File $IN was not found"
+               run_command "normalizetrack-$1" false "File $IN was not found"
        fi
 }
 
@@ -1507,16 +1649,16 @@ do_normalize ()
 # TRACKNUM, TRACKNAME, TRACKARTIST, DALBUM, OUTPUTFORMAT, CDGENRE, CDYEAR
 do_move ()
 {
-       for TMPOUTPUT in $(echo $OUTPUTTYPE | tr , \ )
+       for TMPOUTPUT in $(echo "$OUTPUTTYPE" | tr , \ )
        do
                # For now, set OUTPUT as TMPOUTPUT, and then change it once we have
                # defined the OUTPUTFILE:
                OUTPUT="$TMPOUTPUT"
 
                # Create ALBUMFILE, ARTISTFILE, TRACKFILE
-               ALBUMFILE="$(mungefilename "$DALBUM")"
-               ARTISTFILE="$(mungefilename "$TRACKARTIST")"
-               TRACKFILE="$(mungefilename "$TRACKNAME")"
+               ALBUMFILE="$(mungealbumname "$DALBUM")"
+               ARTISTFILE="$(mungeartistname "$TRACKARTIST")"
+               TRACKFILE="$(mungetrackname "$TRACKNAME")"
                GENRE="$(mungegenre "$GENRE")"
                YEAR=${CDYEAR:-$CDYEAR}
                # If we want to start the tracks with a given number, we need to modify
@@ -1547,6 +1689,12 @@ do_move ()
                                opus)
                                        OUTPUT=$OPUSOUTPUTCONTAINER
                                        ;;
+                               mka)
+                                       OUTPUT=$MKAOUTPUTCONTAINER
+                                       ;;
+                               aiff)
+                                       OUTPUT=$AIFFOUTPUTCONTAINER
+                                       ;;
                                flac)
                                        OUTPUT=$FLACOUTPUTCONTAINER
                                        ;;
@@ -1564,27 +1712,27 @@ do_move ()
                                        else
                                                # 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"
-                                               if checkstatus movetrack-output-$OUTPUT; then :; else
-                                                       run_command movetrack-output-$OUTPUT true
+                                               run_command "movetrack-$1" mv "${ABCDETEMPDIR}/track$1.$OUTPUT" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
+                                               if checkstatus "movetrack-output-$OUTPUT"; then :; else
+                                                       run_command "movetrack-output-$OUTPUT" true
                                                fi
                                        fi
                                        ;;
                                *)
                                        # 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"
-                                       if checkstatus movetrack-output-$OUTPUT; then :; else
-                                               run_command movetrack-output-$OUTPUT true
+                                       run_command "movetrack-$1" mv "${ABCDETEMPDIR}/track$1.$OUTPUT" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
+                                       if checkstatus "movetrack-output-$OUTPUT"; then :; else
+                                               run_command "movetrack-output-$OUTPUT" true
                                        fi
                                        ;;
                        esac
                        # Lets move the cue file
                        if CUEFILE=$(checkstatus cuefile) >/dev/null ; then
-                               if [ -r "$ABCDETEMPDIR/$CUEFILE" ]; then
-                                       if checkstatus movecue-$OUTPUT; then :; else
+                               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..."
+                                               #run_command "" vecho "Copying cue file to its destination directory..."
                                                if checkstatus onetrack >/dev/null ; then
                                                        case $OUTPUT in
                                                                wav)
@@ -1592,22 +1740,22 @@ do_move ()
                                                                                # We dont have the dir, since it was not created before.
                                                                                :
                                                                        else
-                                                                               run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.cue"
+                                                                               run_command "movecue-$OUTPUT" cp "${ABCDETEMPDIR}/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.cue"
                                                                        fi
                                                                        ;;
                                                                # 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.cue"
                                                                        ;;
                                                                *)
-                                                                       run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT.cue"
+                                                                       run_command "movecue-$OUTPUT" cp "${ABCDETEMPDIR}/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT.cue"
                                                                        ;;
                                                        esac
                                                else
-                                                       run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTFILEDIR/$CUEFILE"
+                                                       run_command "movecue-$OUTPUT" cp "${ABCDETEMPDIR}/$CUEFILE" "$OUTPUTFILEDIR/$CUEFILE"
                                                fi
-                                               echo movecue-$OUTPUT >> "$ABCDETEMPDIR/status"
+                                               echo "movecue-$OUTPUT" >> "${ABCDETEMPDIR}/status"
                                        fi
                                fi
                        fi
@@ -1622,7 +1770,7 @@ do_move ()
 # VARIOUSARTISTS, OUTPUTDIR
 do_playlist ()
 {
-       for TMPOUTPUT in $(echo $OUTPUTTYPE | tr , \ )
+       for TMPOUTPUT in $(echo "$OUTPUTTYPE" | tr , \ )
        do
                case $TMPOUTPUT in
                        vorbis|ogg)
@@ -1631,6 +1779,12 @@ do_playlist ()
                        opus)
                                OUTPUT=$OPUSOUTPUTCONTAINER
                                ;;
+                       mka)
+                               OUTPUT=$MKAOUTPUTCONTAINER
+                               ;;
+                       aiff)
+                               OUTPUT=$AIFFOUTPUTCONTAINER
+                               ;;
                        flac)
                                OUTPUT=$FLACOUTPUTCONTAINER
                                ;;
@@ -1641,8 +1795,8 @@ do_playlist ()
                # Create a playlist file for the playlist data to go into.
                # We used to wipe it out if it existed. Now we request permission if interactive.
                for LASTTRACK in $TRACKQUEUE; do :; done
-               ALBUMFILE="$(mungefilename "$DALBUM")"
-               ARTISTFILE="$(mungefilename "$DARTIST")"
+               ALBUMFILE="$(mungealbumname "$DALBUM")"
+               ARTISTFILE="$(mungeartistname "$DARTIST")"
                GENRE="$(mungegenre "$GENRE")"
                YEAR=${CDYEAR:-$CDYEAR}
                if [ "$VARIOUSARTISTS" = "y" ] ; then
@@ -1668,22 +1822,22 @@ do_playlist ()
                                ERASEPLAYLIST=e
                        fi
                        # Once we erase the playlist, we use append to create the new one.
-                       [ "$ERASEPLAYLIST" = "e" -o "$ERASEPLAYLIST" = "E" ] && rm -f "$OUTPUTDIR/$PLAYLISTFILE" && ERASEPLAYLIST=a
+                       [ "$ERASEPLAYLIST" = "e" ] || [ "$ERASEPLAYLIST" = "E" ] && rm -f "$OUTPUTDIR/$PLAYLISTFILE" && ERASEPLAYLIST=a
                else
                        # The playlist does not exist, so we can safelly use append to create the new list
                        ERASEPLAYLIST=a
                fi
-               if [ "$ERASEPLAYLIST" = "a" -o "$ERASEPLAYLIST" = "A" ]; then
+               if [ "$ERASEPLAYLIST" = "a" ] || [ "$ERASEPLAYLIST" = "A" ]; then
                        touch "$OUTPUTDIR/$PLAYLISTFILE"
                        for UTRACKNUM in $TRACKQUEUE
                        do
                                # Shares some code with do_move since the filenames have to match
-                               CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
+                               CDDBTRACKNUM=$(expr $UTRACKNUM - 1) # Unpad
                                getcddbinfo TRACKNAME
                                splitvarious
-                               TRACKFILE="$(mungefilename "$TRACKNAME")"
-                               ARTISTFILE="$(mungefilename "$TRACKARTIST")"
-                               ALBUMFILE="$(mungefilename "$DALBUM")"
+                               TRACKFILE="$(mungetrackname "$TRACKNAME")"
+                               ARTISTFILE="$(mungeartistname "$TRACKARTIST")"
+                               ALBUMFILE="$(mungealbumname "$DALBUM")"
                                # If we want to start the tracks with a given number, we need to modify the
                                # TRACKNUM value before evaluation
                                gettracknum
@@ -1694,13 +1848,13 @@ do_playlist ()
                                fi
                                if [ "$VARIOUSARTISTS" = "y" ]; then
                                        if [ "$VAPLAYLISTDATAPREFIX" ] ; then
-                                               echo ${VAPLAYLISTDATAPREFIX}$OUTPUTFILE.$OUTPUT >> "$OUTPUTDIR/$PLAYLISTFILE"
+                                               echo "${VAPLAYLISTDATAPREFIX}$OUTPUTFILE.$OUTPUT" >> "$OUTPUTDIR/$PLAYLISTFILE"
                                        else
                                                relpath "$PLAYLISTFILE", "$OUTPUTFILE.$OUTPUT" >> "$OUTPUTDIR/$PLAYLISTFILE"
                                        fi
                                else
                                        if [ "$PLAYLISTDATAPREFIX" ]; then
-                                               echo ${PLAYLISTDATAPREFIX}$OUTPUTFILE.$OUTPUT >> "$OUTPUTDIR/$PLAYLISTFILE"
+                                               echo "${PLAYLISTDATAPREFIX}$OUTPUTFILE.$OUTPUT" >> "$OUTPUTDIR/$PLAYLISTFILE"
                                        else
                                                relpath "$PLAYLISTFILE", "$OUTPUTFILE.$OUTPUT" >> "$OUTPUTDIR/$PLAYLISTFILE"
                                        fi
@@ -1710,11 +1864,11 @@ do_playlist ()
                ## this will convert the playlist to have CRLF line-endings, if specified
                ## (some hardware players insist on CRLF endings)
                if [ "$DOSPLAYLIST" = "y" ]; then
-                       awk '{sub("\r$",""); printf "%s\r\n", $0}' "$OUTPUTDIR/$PLAYLISTFILE" > "$ABCDETEMPDIR/PLAYLISTFILE.tmp"
-#                      mv -f "$ABCDETEMPDIR/PLAYLISTFILE.tmp" "$OUTPUTDIR/$PLAYLISTFILE"
-                       cat "$ABCDETEMPDIR/PLAYLISTFILE.tmp" | sed 's/\//\\/' > "$OUTPUTDIR/$PLAYLISTFILE"
+                       awk '{sub("\r$",""); printf "%s\r\n", $0}' "$OUTPUTDIR/$PLAYLISTFILE" > "${ABCDETEMPDIR}/PLAYLISTFILE.tmp"
+#                      mv -f "${ABCDETEMPDIR}/PLAYLISTFILE.tmp" "$OUTPUTDIR/$PLAYLISTFILE"
+                       cat "${ABCDETEMPDIR}/PLAYLISTFILE.tmp" | sed 's/\//\\/' > "$OUTPUTDIR/$PLAYLISTFILE"
                fi
-               echo "playlistcomplete" >> "$ABCDETEMPDIR/status"
+               echo "playlistcomplete" >> "${ABCDETEMPDIR}/status"
        done
 }
 
@@ -1728,24 +1882,24 @@ abcde.cue2discid () {
        cddb_sum () {
                val=$1
                ret=0
-               while [ $val -gt 0 ] ; do
-                       ret=$(( $ret + ( $val % 10) ))
-                       val=$(( $val / 10 ))
+               while [ "$val" -gt 0 ] ; do
+                       ret=$(( "$ret" + ( "$val" % 10) ))
+                       val=$(( "$val" / 10 ))
                done
-               echo $ret
+               echo "$ret"
        }
 
        msf2lba () {
                OIFS="$IFS"
                IFS=":"
-               set -- $1
+               set -- "$1"
                IFS="$OIFS"
                local first second third
-               first=$(expr ${1} + 0 )
-               second=$(expr ${2} + 0 )
-               third=$(expr ${3} + 0 )
+               first=$(( $1 + 0 ))
+               second=$(( $2 + 0 ))
+               third=$(( $3 + 0 ))
 
-               echo $(( ((($first * 60) + $second) * 75) + $third ))
+               echo $(( ((("$first" * 60) + "$second") * 75) + "$third" ))
        }
 
        OFFSET=150
@@ -1756,26 +1910,26 @@ abcde.cue2discid () {
        N=0
 
        while read line ; do
-               set -- $line
+               set -- "$line"
                case "$1" in
                TRACK)  i=$(( i + 1 ))
                        ;;
                INDEX)  if [ "$2" -eq 1 ] ; then
-                               LBA=$(msf2lba $3)
-                               START=$(( $LBA + $PREGAP + $OFFSET ))
+                               LBA=$(msf2lba "$3")
+                               START=$(( "$LBA" + "$PREGAP" + "$OFFSET" ))
                                eval TRACK$i=$START
-                               X=$(cddb_sum $(( $START / 75 )) )
-                               N=$(( $N + $X ))
+                               X=$(cddb_sum $(( "$START" / 75 )) )
+                               N=$(( "$N" + "$X" ))
                        fi
                        ;;
-               PREGAP) PREGAP=$(msf2lba $2)
+               PREGAP) PREGAP=$(msf2lba "$2")
                        ;;
                REM)    case "$2" in
                        FLAC__lead-out)
-                               LEADOUT=$(( $4 / 588 ))
+                               LEADOUT=$(( "$4" / 588 ))
                                ;;
                        FLAC__lead-in)
-                               LEADIN=$(( $3 / 588 ))
+                               LEADIN=$(( "$3" / 588 ))
                                ;;
                        esac
                        ;;
@@ -1784,16 +1938,16 @@ abcde.cue2discid () {
        done
 
        TRACKS=$i
-       LEADOUT=$(( $LEADOUT + $LEADIN ))
+       LEADOUT=$(( "$LEADOUT" + "$LEADIN" ))
 
-       LENGTH=$(( $LEADOUT/75 - $TRACK1/75 ))
-       DISCID=$(( ( $N % 255 ) * 2**24 | $LENGTH * 2**8 | $TRACKS ))
-       printf "%08x %i" $DISCID $TRACKS
+       LENGTH=$(( "$LEADOUT"/75 - "$TRACK1"/75 ))
+       CDDBDISCID=$(( ( "$N" % 255 ) * 2**24 | "$LENGTH" * 2**8 | "$TRACKS" ))
+       printf "%08x %i" "${CDDBDISCID}" "$TRACKS"
 
        j=1
-       while [ $j -le $TRACKS ] ; do
+       while [ $j -le "$TRACKS" ] ; do
                eval echo -n "\" \$TRACK$j\""
-               j=$((j+1))
+               j=$(( $j + 1))
        done
        echo " $(( $LEADOUT / 75 ))"
 }
@@ -1819,7 +1973,7 @@ abcde.cue2discid () {
 #   Remaining track index values offset by <pregap value>
 #
 # Variables used:
-# TRACKINFO
+# CDDBTRACKINFO
 abcde.mkcue () {
 
        echomsf () {
@@ -1830,16 +1984,16 @@ abcde.mkcue () {
        local i OFFSET LBA
        local CUEWAVFILE
 
-       if [ "$1" = --wholedisc ] ; then
+       if [ "$1" = --wholedisk ] ; then
                MODE=INDEX
        else
                MODE=PREGAP
        fi
 
        vecho "One track is $ONETRACK"
-       TRACKFILE="$(mungefilename "$TRACKNAME")"
-       ARTISTFILE="$(mungefilename "$TRACKARTIST")"
-       ALBUMFILE="$(mungefilename "$DALBUM")"
+       TRACKFILE="$(mungetrackname "$TRACKNAME")"
+       ARTISTFILE="$(mungeartistname "$TRACKARTIST")"
+       ALBUMFILE="$(mungealbumname "$DALBUM")"
        if [ "$ONETRACK" = "y" ]; then
                if [ "$VARIOUSARTISTS" = "y" ]; then
                        CUEWAVFILE="$(eval echo \""$VAONETRACKOUTPUTFORMAT"\" | sed -e 's@^.*/@@').$OUTPUT"
@@ -1851,52 +2005,47 @@ abcde.mkcue () {
                CUEWAVFILE="dummy.wav"
        fi
 
-       set -- $TRACKINFO
+       set -- "$CDDBTRACKINFO"
 
-       DISCID=$1
-       TRACKS=$2
+       DISCID="$1"
+       TRACKS="$2"
        shift 2
 
-       echo REM DISCID $DISCID
+       echo "REM DISCID $DISCID"
        echo FILE \""$CUEWAVFILE"\" WAVE
 
-       if [ $1 -ne 150 ] && [ $MODE = "PREGAP" ] ; then
-               OFFSET=$1
+       if [ "$1" -ne 150 ] && [ "$MODE" = "PREGAP" ] ; then
+               OFFSET="$1"
        else
-               OFFSET=150
+               OFFSET="150"
        fi
 
        i=1
        while [ $i -le "$TRACKS" ] ; do
                LBA=$(( $1 - $OFFSET ))
                printf "  TRACK %02i AUDIO\n" $i
-               if [ $i -eq 1 -a $1 -ne 150 ] ; then
-                       if [ $MODE = PREGAP ] ; then
-                               echomsf "    PREGAP " $(($OFFSET-150))
+               if [ "$i" -eq 1 ] && [ "$1" -ne 150 ] ; then
+                       if [ "$MODE" = PREGAP ] ; then
+                               echomsf "    PREGAP " $(($"OFFSET" - 150))
                        else
                                echo    "    INDEX 00 00:00:00"
                        fi
                fi
-               echomsf "    INDEX 01 " $LBA
-               i=$(($i+1))
+               echomsf "    INDEX 01 " "$LBA"
+               i=$(( $i + 1))
                shift
        done
 }
 
 # do_discid
-# This essentially the start of things
+# This is essentially the start of things
 do_discid ()
 {
-       # Query the CD to get the track info, unless the user specified -C
-       # or we are using some actions which do not need the CDDB data at all
-       #if [ ! X"$EXPACTIONS" = "X" ]; then
-       #       :
-       #elif [ -z "$DISCID" ]; then
-       if [ -z "$DISCID" ]; then
+       if [ -z "${CDDBDISCID}" ]; then
                vecho -n "Getting CD track info... "
                # In OSX, unmount the disc before a query
                if [ "$OSFLAVOUR" = "OSX" ]; then
-                       diskutil unmount ${CDROM#/dev/}
+                       diskutil unmount "${CDROM#/dev/}"
                fi
                case "$CDROMREADERSYNTAX" in
                        flac)
@@ -1926,7 +2075,7 @@ do_discid ()
                                                ;;
                                                *)
                                                        #vecho "Using external python cue2discid implementation..."
-                                                       TRACKINFO=$($METAFLAC $METAFLACOPTS --export-cuesheet-to=- "$CDROM" | $CUE2DISCID)
+                                                       CDDBTRACKINFO=$($METAFLAC $METAFLACOPTS --export-cuesheet-to=- "$CDROM" | $CUE2DISCID)
                                                ;;
                                        esac
                                else
@@ -1934,26 +2083,42 @@ do_discid ()
                                        exit 1
                                fi
                                ;;
-#                      cdparanoia|debug)
-#                              CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -Q --verbose 2>&1 )"
-#                              RET=$?
-#                              if [ ! "$RET" = "0" ];then
-#                                      log warning "something went wrong while querying the CD... Maybe a DATA CD?"
-#                              fi
-#
-#                              TRACKS="$(echo "$CDPARANOIAOUTPUT" | grep -E '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ')"
-#                              CDPARANOIAAUDIOTRACKS="$TRACKS"
-#
-#                              LEADOUT="$(echo "$CDPARANOIAOUTPUT" | grep -Eo '^TOTAL[[:space:]]+([[:digit:]]+)' | get_last)"
-#                              OFFSETS="$(echo "$CDPARANOIAOUTPUT" | sed -n -e's/^ .* \([0-9]\+\) \[.*/\1/p')"
-#                              makeids
-#                              ;;
+                       cdparanoia|debug)
+                               CDPARANOIAOUTPUT="$( $CDROMREADER -"$CDPARANOIACDROMBUS" "$CDROM" -Q --verbose 2>&1 )"
+                               RET=$?
+                               if [ ! "$RET" = "0" ];then
+                                       log warning "something went wrong while querying the CD... Maybe a DATA CD or the CD is not loaded?"
+                               fi
+
+                               TRACKS="$(echo "$CDPARANOIAOUTPUT" | grep -E '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ')"
+                               CDPARANOIAAUDIOTRACKS="$TRACKS"
+
+                               LEADOUT="$(echo "$CDPARANOIAOUTPUT" | grep -Eo '^TOTAL[[:space:]]+([[:digit:]]+)' | get_last)"
+                               OFFSETS="$(echo "$CDPARANOIAOUTPUT" | sed -n -e's/^ .* \([0-9]\+\) \[.*/\1/p')"
+                               makeids
+                               ;;
                        *)
+                               # Calculate the cddb discid in all
+                               # cases now. We'll use the cddb discid
+                               # for reference in most cases for
+                               # consistency. Also calculate the
+                               # musicbrainz discid if we need it.
+                               CDDBTRACKINFO=$($CDDISCID "$CDROM")
+                               if [ "$CDDISCID_NEEDS_PAUSE"x = "y"x ]; then
+                                       sleep 6
+                               fi
+                               CDDBDISCID=$(echo "$CDDBTRACKINFO" | cut -d' ' -f1)
                                case "$CDDBMETHOD" in
-                                       cddb) TRACKINFO=$($CDDISCID "$CDROM") ;;
-                                       musicbrainz) TRACKINFO=$($MUSICBRAINZ --command id --device "$CDROM") ;;
+                                       *musicbrainz*)
+                                               MBTRACKINFO=$($MUSICBRAINZ --command id --device "$CDROM")
+                                               error=$?
+                                               if [ $error != 0 ]; then
+                                                       log error "$MUSICBRAINZ failed to run; ABORT"
+                                                       exit $error
+                                               fi
+                                               MBDISCID=$(echo "$MBTRACKINFO" | cut -d' ' -f1)
+                                               ;;
                                esac
-                               ;;
                esac
                # Make sure there's a CD in there by checking cd-discid's return code
                if [ ! "$?" = "0" ]; then
@@ -1968,12 +2133,12 @@ do_discid ()
                fi
                # In OSX, remount the disc again
                if [ "$OSFLAVOUR" = "OSX" ]; then
-                       diskutil mount ${CDROM#/dev/}
+                       diskutil mount "${CDROM#/dev/}"
                fi
                WEHAVEACD=y
-               DISCID=$(echo $TRACKINFO | cut -f1 -d' ')
+               CDDBDISCID=$(echo "$CDDBTRACKINFO" | cut -f1 -d' ')
        else
-               TRACKINFO=$(cat "$WAVOUTPUTDIR/abcde.$DISCID/discid")
+               CDDBTRACKINFO=$(cat "$WAVOUTPUTDIR/abcde.${CDDBDISCID}/cddbdiscid")
        fi
 
        # Get a full enumeration of tracks, sort it, and put it in the TRACKQUEUE.
@@ -1988,14 +2153,14 @@ do_discid ()
                TRACKNUMPADDING=2
        fi
 
-       ABCDETEMPDIR="$WAVOUTPUTDIR/abcde.$(echo $TRACKINFO | cut -f1 -d' ')"
+       ABCDETEMPDIR="$WAVOUTPUTDIR/abcde.$(echo "$CDDBTRACKINFO" | cut -f1 -d' ')"
        if [ -z "$TRACKQUEUE" ]; then
                if [ ! "$STRIPDATATRACKS" = "n" ]; then
                        case "$CDROMREADERSYNTAX" in
                                cdparanoia|libcdio|debug)
                                        if [ "$WEHAVEACD" = "y" ]; then
                                                vecho "Querying the CD for audio tracks..."
-                                               CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -Q --verbose 2>&1 )"
+                                               CDPARANOIAOUTPUT="$( $CDROMREADER -"$CDPARANOIACDROMBUS" "$CDROM" -Q --verbose 2>&1 )"
                                                RET=$?
                                                if [ ! "$RET" = "0" ];then
                                                        log warning "something went wrong while querying the CD... Maybe a DATA CD?"
@@ -2004,19 +2169,19 @@ do_discid ()
                                                CDPARANOIAAUDIOTRACKS="$TRACKS"
                                        else
                                                # Previous versions of abcde would store the tracks on a file, instead of the status record.
-                                               if [ -f "$ABCDETEMPDIR/cdparanoia-audio-tracks" ]; then
-                                                       echo cdparanoia-audio-tracks=$( cat "$ABCDETEMPDIR/cdparanoia-audio-tracks" ) >> "$ABCDETEMPDIR/status"
-                                                       rm -f "$ABCDETEMPDIR/cdparanoia-audio-tracks"
+                                               if [ -f "${ABCDETEMPDIR}/cdparanoia-audio-tracks" ]; then
+                                                       echo "cdparanoia-audio-tracks=$( cat "${ABCDETEMPDIR}/cdparanoia-audio-tracks" )" >> "${ABCDETEMPDIR}/status"
+                                                       rm -f "${ABCDETEMPDIR}/cdparanoia-audio-tracks"
                                                fi
-                                               if [ -f "$ABCDETEMPDIR/status" ] && TRACKS=$(checkstatus cdparanoia-audio-tracks); then :; else
-                                                       TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
+                                               if [ -f "${ABCDETEMPDIR}/status" ] && TRACKS=$(checkstatus cdparanoia-audio-tracks); then :; else
+                                                       TRACKS=$(echo "$CDDBTRACKINFO" | cut -f2 -d' ')
                                                fi
                                        fi
                                        ;;
-                               *)      TRACKS=$(echo $TRACKINFO | cut -f2 -d' ') ;;
+                               *)      TRACKS=$(echo "$CDDBTRACKINFO" | cut -f2 -d' ') ;;
                        esac
                else
-                       TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
+                       TRACKS=$(echo "$CDDBTRACKINFO" | cut -f2 -d' ')
                fi
                if echo "$TRACKS" | grep "[[:digit:]]" > /dev/null 2>&1 ;then :;else
                        log info "The disc does not contain any tracks. Giving up..."
@@ -2024,32 +2189,34 @@ do_discid ()
                fi
                echo -n "Grabbing entire CD - tracks: "
                if [ ! "$PADTRACKS" = "y" ] ; then
-                       TRACKNUMPADDING=$(echo -n $TRACKS | wc -c | tr -d ' ')
+                       TRACKNUMPADDING=$(echo -n "$TRACKS" | wc -c | tr -d ' ')
                fi
+
                TRACKS=$(printf "%0.${TRACKNUMPADDING}d" $TRACKS)
                X=0
                while [ "$X" -ne "$TRACKS" ]
                do
-                       X=$(printf "%0.${TRACKNUMPADDING}d" $(expr $X + 1))
-                       TRACKQUEUE=$(echo $TRACKQUEUE $X)
+                       PT=$(printf "%0.${TRACKNUMPADDING}d" $(($X + 1)))
+                       TRACKQUEUE="$TRACKQUEUE $PT"
+                       X=$(($X + 1))
                done
-               echo $TRACKQUEUE
+               echo "$TRACKQUEUE"
        else
-               TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
+               TRACKS=$(echo "$CDDBTRACKINFO" | cut -f2 -d' ')
                # User-supplied track queue.
                # Weed out non-numbers, whitespace, then sort and weed out duplicates
-               TRACKQUEUE=$(echo $TRACKQUEUE | sed 's-[^0-9 ]--g' | tr ' ' '\n' | grep -v ^$ | sort -n | uniq | tr '\n' ' ' | sed 's- $--g')
+               TRACKQUEUE=$(echo "$TRACKQUEUE" | sed 's-[^0-9 ]--g' | tr ' ' '\n' | grep -v ^$ | sort -n | uniq | tr '\n' ' ' | sed 's- $--g')
                # Once cleaned, obtain the highest value in the trackqueue for number padding
                for LASTTRACK in $TRACKQUEUE; do :; done
                if [ ! "$PADTRACKS" = "y" ] ; then
-                       TRACKNUMPADDING=$(echo -n $LASTTRACK | wc -c | tr -d ' ')
+                       TRACKNUMPADDING=$(echo -n "$LASTTRACK" | wc -c | tr -d ' ')
                fi
                # Now we normalize the trackqueue
                for TRACK in $TRACKQUEUE ; do
-                       TRACKNUM=$(printf %0.${TRACKNUMPADDING}d $(expr ${TRACK} + 0 ))
-                       PADTRACKQUEUE=$(echo $PADTRACKQUEUE $TRACKNUM)
+                       TRACKNUM=$(printf "%0.${TRACKNUMPADDING}d" $(($TRACK + 0)))
+                       PADTRACKQUEUE="$PADTRACKQUEUE $TRACKNUM"
                done
-               TRACKQUEUE=$PADTRACKQUEUE
+               TRACKQUEUE="$PADTRACKQUEUE"
                echo Grabbing tracks: "$TRACKQUEUE"
        fi
 
@@ -2058,31 +2225,31 @@ do_discid ()
        # We have the discid, create a temp directory after it to store all the temp
        # info
 
-       if [ -e "$ABCDETEMPDIR" ]; then
-               echo -n "abcde: attempting to resume from $ABCDETEMPDIR"
+       if [ -e "${ABCDETEMPDIR}" ]; then
+               echo -n "abcde: attempting to resume from ${ABCDETEMPDIR}"
                # It already exists, see if it's a directory
-               if [ ! -d "$ABCDETEMPDIR" ]; then
+               if [ ! -d "${ABCDETEMPDIR}" ]; then
                        # This is a file/socket/fifo/device/etc, not a directory
                        # Complain and exit
                        echo >&2
-                       echo "abcde: file $ABCDETEMPDIR already exists and does not belong to abcde." >&2
+                       echo "abcde: file ${ABCDETEMPDIR} already exists and does not belong to abcde." >&2
                        echo "Please investigate, remove it, and rerun abcde." >&2
                        exit 1
                fi
                echo -n .
                # It's a directory, let's see if it's writable by us
-               if [ ! -r "$ABCDETEMPDIR" ] || [ ! -w "$ABCDETEMPDIR" ] || [ ! -x "$ABCDETEMPDIR" ]; then
+               if [ ! -r "${ABCDETEMPDIR}" ] || [ ! -w "${ABCDETEMPDIR}" ] || [ ! -x "${ABCDETEMPDIR}" ]; then
                        # Nope, complain and exit
                        echo >&2
-                       echo "abcde: directory $ABCDETEMPDIR already exists and is not writeable." >&2
+                       echo "abcde: directory ${ABCDETEMPDIR} already exists and is not writeable." >&2
                        echo "Please investigate, remove it, and rerun abcde." >&2
                        exit 1
                fi
                echo .
                # See if it's populated
-               if [ ! -f "$ABCDETEMPDIR/discid" ]; then
+               if [ ! -f "${ABCDETEMPDIR}/cddbdiscid" ]; then
                        # Wipe and start fresh
-                       echo "abcde: $ABCDETEMPDIR/discid not found. Abcde must remove and recreate" >&2
+                       echo "abcde: ${ABCDETEMPDIR}/cddbdiscid not found. Abcde must remove and recreate" >&2
                        echo -n "this directory to continue. Continue [y/N]? " >&2
                        if [ "$INTERACTIVE" = "y" ]; then
                                read ANSWER
@@ -2093,54 +2260,54 @@ do_discid ()
                        if [ "$ANSWER" != "y" ]; then
                                exit 1
                        fi
-                       rm -rf "$ABCDETEMPDIR" || exit 1
-                       mkdir -p "$ABCDETEMPDIR"
+                       rm -rf "${ABCDETEMPDIR}" || exit 1
+                       mkdir -p "${ABCDETEMPDIR}"
                        if [ "$?" -gt "0" ]; then
                                # Directory already exists or could not be created
-                               echo "abcde: Temp directory $ABCDETEMPDIR could not be created." >&2
+                               echo "abcde: Temp directory ${ABCDETEMPDIR} could not be created." >&2
                                exit 1
                        fi
                else
                        # Everything is fine. Check for ^encodetracklocation-
                        # and encode-output entries in the status file and
                        # remove them. These are not relevant across sessions.
-                       if [ -f "$ABCDETEMPDIR/status" ]; then
-                               mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
-                               grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
-                                       | grep -v ^encode-output > "$ABCDETEMPDIR/status"
+                       if [ -f "${ABCDETEMPDIR}/status" ]; then
+                               mv "${ABCDETEMPDIR}/status" "${ABCDETEMPDIR}/status.old"
+                               grep -v ^encodetracklocation- < "${ABCDETEMPDIR}/status.old" \
+                                       | grep -v ^encode-output > "${ABCDETEMPDIR}/status"
                        fi
                        # Remove old error messages
-                       if [ -f "$ABCDETEMPDIR/errors" ]; then
-                               rm -f "$ABCDETEMPDIR/errors"
+                       if [ -f "${ABCDETEMPDIR}/errors" ]; then
+                               rm -f "${ABCDETEMPDIR}/errors"
                        fi
                fi
        else
                # We are starting from scratch
-               mkdir -p "$ABCDETEMPDIR"
+               mkdir -p "${ABCDETEMPDIR}"
                if [ "$?" -gt "0" ]; then
                        # Directory already exists or could not be created
-                       echo "abcde: Temp directory $ABCDETEMPDIR could not be created." >&2
+                       echo "abcde: Temp directory ${ABCDETEMPDIR} could not be created." >&2
                        exit 1
                fi
-               cat /dev/null > "$ABCDETEMPDIR/status"
+               cat /dev/null > "${ABCDETEMPDIR}/status"
                # Store the abcde version in the status file.
-               echo "abcde-version=$VERSION" >> "$ABCDETEMPDIR/status"
+               echo "abcde-version=$VERSION" >> "${ABCDETEMPDIR}/status"
        fi
-       if [ X"$DOCUE" = "Xy" -a X"$WEHAVEACD" = "Xy" ]; then
+       if [ X"$DOCUE" = "Xy" ] && [ X"$WEHAVEACD" = "Xy" ]; then
                if checkstatus cuefile > /dev/null 2>&1 ; then :; else
-                       CUEFILE=cue-$(echo "$TRACKINFO" | cut -f1 -d' ').txt
+                       CUEFILE=cue-$(echo "$CDDBTRACKINFO" | cut -f1 -d' ').txt
                        vecho "Creating cue file..."
-                       case $CDROMREADERSYNTAX in
+                       case "$CDROMREADERSYNTAX" in
                                flac)
-                                       if $METAFLAC --export-cuesheet-to=- "$CDROM" > "$ABCDETEMPDIR/$CUEFILE"; then
-                                               echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status"
+                                       if $METAFLAC --export-cuesheet-to=- "$CDROM" > "${ABCDETEMPDIR}/$CUEFILE"; then
+                                               echo "cuefile=$CUEFILE" >> "${ABCDETEMPDIR}/status"
                                        else
                                                log warning "the input flac file does not contain a cuesheet."
                                        fi
                                        ;;
                                *)
-                                       if $CUEREADER $CUEREADEROPTS > "$ABCDETEMPDIR/$CUEFILE"; then
-                                               echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status"
+                                       if $CUEREADER $CUEREADEROPTS > "${ABCDETEMPDIR}/$CUEFILE"; then
+                                               echo "cuefile=$CUEFILE" >> "${ABCDETEMPDIR}/status"
                                        else
                                                log warning "reading the CUE sheet is still considered experimental"
                                                log warning "and there was a problem with the CD reading. abcde will continue,"
@@ -2153,22 +2320,24 @@ do_discid ()
        # If we got the CDPARANOIA status and it is not recorded, save it now
        if [ -n "$CDPARANOIAAUDIOTRACKS" ]; then
                if checkstatus cdparanoia-audio-tracks > /dev/null 2>&1; then :; else
-                       echo cdparanoia-audio-tracks=$CDPARANOIAAUDIOTRACKS >> "$ABCDETEMPDIR/status"
+                       echo "cdparanoia-audio-tracks=$CDPARANOIAAUDIOTRACKS" >> "${ABCDETEMPDIR}/status"
                fi
        fi
 
-       # Create the discid file
-       echo "$TRACKINFO" > "$ABCDETEMPDIR/discid"
-       if checkstatus cddbmethod > /dev/null 2>&1 ; then :; else
-               echo "cddbmethod=$CDDBMETHOD" >> "$ABCDETEMPDIR/status"
-       fi
+       # Create the discid files
+       echo "$CDDBTRACKINFO" > "${ABCDETEMPDIR}/cddbdiscid"
+       case "$CDDBMETHOD" in
+               *musicbrainz*)
+                       echo "$MBTRACKINFO" > "${ABCDETEMPDIR}/mbdiscid"
+                       ;;
+       esac
 }
 
 # do_cleancue
 # Create a proper CUE file based on the CUE file we created before.
 do_cleancue()
 {
-       if CUEFILE_IN="$ABCDETEMPDIR"/$(checkstatus cuefile); then
+       if CUEFILE_IN="${ABCDETEMPDIR}"/$(checkstatus cuefile); then
                CUEFILE_OUT=$CUEFILE_IN.out
                ### FIXME ### checkstatus cddb
                if [ -e "$CDDBDATA" ]; then
@@ -2189,7 +2358,7 @@ do_cleancue()
 #                              echo "$line" >> "$CUEFILE_OUT"
 #                              if echo "$line" | grep "^[[:space:]]*TRACK" > /dev/null 2>&1 ; then
                                        eval track="\$TRACK$n"
-                                       n=$(expr $n + 1)
+                                       n=$(( $n + 1 ))
                                        echo "    TITLE \"$track\"" >> "$CUEFILE_OUT"
                                # When making a single-track rip, put the
                                # actual file name into the file declaration
@@ -2198,9 +2367,9 @@ do_cleancue()
                                elif [ "$ONETRACK" = "y" ] &&
                                                echo "$line" | grep '^FILE "dummy.wav" WAVE' > /dev/null 2>&1 ; then
 
-                                       TRACKFILE="$(mungefilename "$TRACKNAME")"
-                                       ARTISTFILE="$(mungefilename "$TRACKARTIST")"
-                                       ALBUMFILE="$(mungefilename "$DALBUM")"
+                                       TRACKFILE="$(mungetrackname "$TRACKNAME")"
+                                       ARTISTFILE="$(mungeartistname "$TRACKARTIST")"
+                                       ALBUMFILE="$(mungealbumname "$DALBUM")"
 
                                        if [ "$VARIOUSARTISTS" = "y" ]; then
                                                OUTPUTFILE="$(eval echo \""$VAONETRACKOUTPUTFORMAT"\" | sed -e 's@^.*/@@').$OUTPUT"
@@ -2216,7 +2385,7 @@ do_cleancue()
                        done
                        IFS="$OIFS"
                        mv "$CUEFILE_OUT" "$CUEFILE_IN"
-                       echo "cleancuefile" >> "$ABCDETEMPDIR/status"
+                       echo "cleancuefile" >> "${ABCDETEMPDIR}/status"
                fi
        fi
 }
@@ -2231,15 +2400,15 @@ do_cddbparse ()
        if [ "$ONETRACK" = "y" ]; then
                vecho "ONETRACK mode selected: displaying only the title of the CD..."
        fi
-       echo "---- $(grep DTITLE "${CDDBPARSEFILE}" | cut '-d=' -f2- | tr -d \\r\\n ) ----"
+       echo "---- $(grep -a DTITLE "${CDDBPARSEFILE}" | cut '-d=' -f2- | tr -d \\r\\n ) ----"
        if [ X"$SHOWCDDBYEAR" = "Xy" ]; then
-               PARSEDYEAR=$(grep DYEAR "${CDDBPARSEFILE}" | cut '-d=' -f2-)
+               PARSEDYEAR=$(grep -a DYEAR "${CDDBPARSEFILE}" | cut '-d=' -f2-)
                if [ ! X"$PARSEDYEAR" = "X" ]; then
                        echo "Year: $PARSEDYEAR"
                fi
        fi
        if [ X"$SHOWCDDBGENRE" = "Xy" ]; then
-               PARSEDGENRE=$(grep DGENRE "${CDDBPARSEFILE}" | cut '-d=' -f2-)
+               PARSEDGENRE=$(grep -a DGENRE "${CDDBPARSEFILE}" | cut '-d=' -f2-)
                if [ ! X"$PARSEDGENRE" = "X" ]; then
                        echo "Genre: $PARSEDGENRE"
                fi
@@ -2247,23 +2416,23 @@ do_cddbparse ()
        if [ ! "$ONETRACK" = "y" ]; then
                for TRACK in $(f_seq_row 1 $TRACKS)
                do
-                       echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "${CDDBPARSEFILE}" | cut -f2- -d= | tr -d \\r\\n)"
+                       echo "$TRACK": "$(grep -a ^TTITLE$(($TRACK - 1))= "${CDDBPARSEFILE}" | cut -f2- -d= | tr -d \\r\\n)"
                done
        fi
 }
 
-# do_localcddb
+# do_localcddb_read
 # Check for a local CDDB file, and report success
-do_localcddb ()
+do_localcddb_read ()
 {
        if checkstatus cddb-readcomplete && checkstatus cddb-choice >/dev/null; then :; else
 
                CDDBLOCALSTATUS="notfound"
-               CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
+               CDDBDISCID=$(echo "$CDDBTRACKINFO" | cut -d' ' -f1)
                USELOCALRESP="y"
 
                if [ "$CDDBLOCALRECURSIVE" = "y" ]; then
-                       CDDBLOCALRESULTS="$(find ${CDDBLOCALDIR} -name "${CDDBDISCID}" -type f 2> /dev/null)"
+                       CDDBLOCALRESULTS="$(find "${CDDBLOCALDIR}" -name "${CDDBDISCID}" -type f 2> /dev/null)"
                        if [ ! "${CDDBLOCALRESULTS}" = "" ]; then
                                if   (( $(echo "${CDDBLOCALRESULTS}" | wc -l) == 1 )); then
                                        CDDBLOCALFILE="${CDDBLOCALRESULTS}"
@@ -2284,12 +2453,12 @@ do_localcddb ()
                # If the user has selected to check a local CDDB repo, we proceed with it
                case $CDDBLOCALMATCH in
                        multiple)
-                               echo "Processing multiple matching CDDB entries..." > "$ABCDETEMPDIR/cddblocalchoices"
+                               echo "Processing multiple matching CDDB entries..." > "${ABCDETEMPDIR}/cddblocalchoices"
                                X=0
                                echo "$CDDBLOCALRESULTS" | while read RESULT ; do
-                                       X=$(expr $X + 1)
+                                       X=$(( $X + 1 ))
                                        # List out disc title/author and contents
-                                       CDDBLOCALREAD="$ABCDETEMPDIR/cddblocalread.$X"
+                                       CDDBLOCALREAD="${ABCDETEMPDIR}/cddblocalread.$X"
                                        cat "$RESULT" > "${CDDBLOCALREAD}"
                                        {
                                                echo -n "#$X: "
@@ -2297,20 +2466,16 @@ do_localcddb ()
                                                echo ""
                                                ##FIXME## QUICK HACK !!!!
                                                if [ ! "$INTERACTIVE" = "y" ]; then break ; fi
-                                       } >> "$ABCDETEMPDIR/cddblocalchoices"
+                                       } >> "${ABCDETEMPDIR}/cddblocalchoices"
                                done
-                               if [ $(cat "$ABCDETEMPDIR/cddblocalchoices" | wc -l) -ge 24 ] && [ "$INTERACTIVE" = "y" ]; then
-                                       page "$ABCDETEMPDIR/cddblocalchoices"
-                               else
-                                       # It's all going to fit in one page, cat it
-                                       cat "$ABCDETEMPDIR/cddblocalchoices" >&2
-                               fi
+                               page "${ABCDETEMPDIR}/cddblocalchoices"
                                CDDBLOCALCHOICES=$( echo "$CDDBLOCALRESULTS" | wc -l )
                                # Setting the choice to an impossible integer to avoid errors in the numeric comparisons
                                CDDBLOCALCHOICENUM=-1
                                if [ "$INTERACTIVE" = "y" ]; then
-                                       while [ $CDDBLOCALCHOICENUM -lt 0 ] || [ $CDDBLOCALCHOICENUM -gt $CDDBLOCALCHOICES ]; do
-                                               echo -n "Locally cached CDDB entries found. Which one would you like to use (0 for none)? [0-$CDDBLOCALCHOICES]: " >&2
+                                       while [ "$CDDBLOCALCHOICENUM" -lt 0 ] || [ "$CDDBLOCALCHOICENUM" -gt "$CDDBLOCALCHOICES" ]; do
+                                               echo "Locally cached CDDB entries found." >&2
+                                               echo -n "Which one would you like to use (0 for none)? [0-$CDDBLOCALCHOICES]: " >&2
                                                read CDDBLOCALCHOICE
                                                [ x"$CDDBLOCALCHOICE" = "x" ] && CDDBLOCALCHOICE="1"
                                                # FIXME # Introduce diff's
@@ -2319,25 +2484,23 @@ do_localcddb ()
                                                elif echo $CDDBLOCALCHOICE | grep -E "[[:space:]]*[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
                                                        # Make sure we get a valid choice
                                                        CDDBLOCALCHOICENUM=$(echo $CDDBLOCALCHOICE | xargs printf %d 2>/dev/null)
-                                                       if [ $CDDBLOCALCHOICENUM -lt 0 ] || [ $CDDBLOCALCHOICENUM -gt $CDDBLOCALCHOICES ]; then
+                                                       if [ "$CDDBLOCALCHOICENUM" -lt 0 ] || [ "$CDDBLOCALCHOICENUM" -gt "$CDDBLOCALCHOICES" ]; then
                                                                echo "Invalid selection. Please choose a number between 0 and $CDDBLOCALCHOICES." >&2
                                                        fi
                                                fi
                                        done
                                else
-                                       ### FIXME ###
-                                       #echo "Selected ..."
-                                       CDDBLOCALRESP=y
                                        CDDBLOCALCHOICENUM=1
                                fi
                                if [ ! "$CDDBLOCALCHOICENUM" = "0" ]; then
                                        #echo "Using local copy of CDDB data"
-                                       echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "$ABCDETEMPDIR/cddbread.1"
-                                       cat "$ABCDETEMPDIR/cddblocalread.$CDDBLOCALCHOICENUM" >> "$ABCDETEMPDIR/cddbread.1"
-                                       echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB
-                                       echo cddb-readcomplete >> "$ABCDETEMPDIR/status"
-                                       do_cddbparse "$ABCDETEMPDIR/cddbread.1" > "$ABCDETEMPDIR/cddbchoices"
-                                       echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
+                                       echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "${ABCDETEMPDIR}/cddbread.1"
+                                       cat "${ABCDETEMPDIR}/cddblocalread.$CDDBLOCALCHOICENUM" >> "${ABCDETEMPDIR}/cddbread.1"
+                                       echo "local" > "${ABCDETEMPDIR}/datasource.1"
+                                       echo 999 > "${ABCDETEMPDIR}/cddbquery" # Assuming 999 isn't used by CDDB
+                                       echo cddb-readcomplete >> "${ABCDETEMPDIR}/status"
+                                       do_cddbparse "${ABCDETEMPDIR}/cddbread.1" > "${ABCDETEMPDIR}/cddbchoices"
+                                       echo cddb-choice=1 >> "${ABCDETEMPDIR}/status"
                                        CDDBLOCALSTATUS="found"
                                else
                                        #echo "Not using local copy of CDDB data"
@@ -2364,12 +2527,13 @@ do_localcddb ()
                                fi
                                if [ "$USELOCALRESP" = "y" ]; then
                                        #echo "Using local copy of CDDB data"
-                                       echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "$ABCDETEMPDIR/cddbread.1"
-                                       cat "${CDDBLOCALFILE}" >> "$ABCDETEMPDIR/cddbread.1"
-                                       echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB
-                                       echo cddb-readcomplete >> "$ABCDETEMPDIR/status"
-                                       do_cddbparse "${CDDBLOCALFILE}" > "$ABCDETEMPDIR/cddbchoices"
-                                       echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
+                                       echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "${ABCDETEMPDIR}/cddbread.1"
+                                       cat "${CDDBLOCALFILE}" >> "${ABCDETEMPDIR}/cddbread.1"
+                                       echo "local" > "${ABCDETEMPDIR}/datasource.1"
+                                       echo 999 > "${ABCDETEMPDIR}/cddbquery" # Assuming 999 isn't used by CDDB
+                                       echo cddb-readcomplete >> "${ABCDETEMPDIR}/status"
+                                       do_cddbparse "${CDDBLOCALFILE}" > "${ABCDETEMPDIR}/cddbchoices"
+                                       echo cddb-choice=1 >> "${ABCDETEMPDIR}/status"
                                        CDDBLOCALSTATUS="single"
                                else
                                        #echo "Not using local copy of CDDB data"
@@ -2383,9 +2547,9 @@ do_localcddb ()
        fi
 }
 
-# do_cdtext
+# do_cdtext_read
 # Try to read CD-Text from the drive using icedax / cdda2wav
-do_cdtext ()
+do_cdtext_read ()
 {
        if new_checkexec icedax; then
                CDTEXT_READER=icedax
@@ -2396,12 +2560,16 @@ do_cdtext ()
                return 0
        fi
 
+       vecho "Obtaining CD-Text results..."
+       local SOURCE_WORKDIR="${ABCDETEMPDIR}/data-cdtext"
+       mkdir -p "${SOURCE_WORKDIR}"
+
        if [ "$OSFLAVOUR" = "OSX" ] ; then
                # Hei, we have to unmount the device before running anything like cdda2wav/icedax in OSX
-               diskutil unmount ${CDROM#/dev/}
+               diskutil unmount "${CDROM#/dev/}"
                # Also, in OSX the cdrom device for cdda2wav/icedax changes...
                CDDA2WAVCDROM="IODVDServices"
-       elif [ "$OSFLAVOUR" = "FBSD" ] ; then
+       elif [ "$OSFLAVOUR" = "FBSD" ] || [ "$OSFLAVOUR" = "IRIX" ]; then
                CDDA2WAVCDROM="$CDROMID"
        else
                if [ "$CDROMID" = "" ]; then
@@ -2412,143 +2580,128 @@ do_cdtext ()
        fi
 
        # Do we have CD-Text on the disc (and can the drive read it?)
-       ${CDTEXT_READER} -J -N -D ${CDDA2WAVCDROM} > "$ABCDETEMPDIR/cd-text" 2>&1
-       grep -q '^CD-Text: detected' "$ABCDETEMPDIR/cd-text"
+       (
+               cd "${SOURCE_WORKDIR}" && rm -f audio.* audio_*
+               ${CDTEXT_READER} -J -v titles -D "${CDDA2WAVCDROM}" > "${SOURCE_WORKDIR}/cd-text" 2>&1
+       )
+       grep -a -q '^CD-Text: detected' "${SOURCE_WORKDIR}/cd-text"
        ERRORCODE=$?
        if [ $ERRORCODE -ne 0 ]; then
                # No CD-Text found, bail
                return 0
        fi
 
-       rm -f "$ABCDETEMPDIR/cddbchoices"
-       CDDBCHOICES=1
+       NUM_CDDB_MATCHES=$(($NUM_CDDB_MATCHES + 1))
        # Make an empty template
-       $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.1"
-       echo -n "Retrieved 1 CD-Text match..." >> "$ABCDETEMPDIR/cddbchoices"
-       echo "done." >> "$ABCDETEMPDIR/cddbchoices"
-       echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
-       echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
-       ATITLE=$(grep -e '^Album title:' "${ABCDETEMPDIR}/cd-text" | cut -c14- )
-       echo "200 none ${ATITLE}" >> "$ABCDETEMPDIR/cddbquery"
-       # List out disc title/author and contents
-       echo ---- ${ATITLE} ---- >> "$ABCDETEMPDIR/cddbchoices"
-       for TRACK in $(f_seq_row 1 $TRACKS)
-       do
-               TRACKM1=$(($TRACK - 1))
-               TITLE="$(grep -E ^Track\ +$TRACK: "$ABCDETEMPDIR/cd-text" | tr -d \\r\\n | sed 's~^Track ..: .~~g;'"s~'$~~g")"
-               echo "$TRACK: $TITLE" >> "$ABCDETEMPDIR/cddbchoices"
-               sed "s~^TTITLE${TRACKM1}=.*~TTITLE${TRACKM1}=${TITLE}~" "$ABCDETEMPDIR/cddbread.1" > "$ABCDETEMPDIR/cddbread.new"
-        mv -f "$ABCDETEMPDIR/cddbread.new" "$ABCDETEMPDIR/cddbread.1"
+       $CDDBTOOL template "$(cat "${ABCDETEMPDIR}/cddbdiscid")" > "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}"
+       echo "cddb-read-${NUM_CDDB_MATCHES}-complete" >> "${ABCDETEMPDIR}/status"
+       rm -f "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}"
+
+       # XXX FIXME - this is a hack and should be replaced by proper
+       # character set tracking for the CDDB data we have.
+       if [ "$CDDBPROTO" -ge 6 ]; then
+               # convert to Unicode
+               iconv -f iso-8859-1 -t utf-8 <"${SOURCE_WORKDIR}/audio.cddb" >"${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}"
+       else
+               # copy verbatim, assuming CD-TEXT is in ISO-8859-1 format
+               # apparently icedax/cdda2wav have no support for 16-bit
+               # characters yet, either
+               cp -p "${SOURCE_WORKDIR}/audio.cddb" "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}"
+       fi
+
+       CDDBDISCID=$(echo "$CDDBTRACKINFO" | cut -d' ' -f1)
+       ATITLE=$(grep -a -e '^DTITLE=' "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}" | cut -c8- | tr -d \\r\\n)
+       echo "CD-Text" > "${SOURCE_WORKDIR}/datasource.${NUM_CDDB_MATCHES}"
+       echo "none ${CDDBDISCID} ${ATITLE}" >> "${SOURCE_WORKDIR}/cddbquery.${NUM_CDDB_MATCHES}"
+
+       ( cd "${SOURCE_WORKDIR}" && rm -f audio_* audio.* )
+       for file in ${SOURCE_WORKDIR}/cddbread.* ${SOURCE_WORKDIR}/cddbquery.* ${SOURCE_WORKDIR}/datasource.*; do
+               if [ -f "$file" ]; then
+                       cp "$file" "${ABCDETEMPDIR}"
+               fi
        done
-       sed "s~^DTITLE=.*~DTITLE=${ATITLE}~" "$ABCDETEMPDIR/cddbread.1" > "$ABCDETEMPDIR/cddbread.new"
-    mv -f "$ABCDETEMPDIR/cddbread.new" "$ABCDETEMPDIR/cddbread.1"
-       echo >> "$ABCDETEMPDIR/cddbchoices"
-       echo "cdtext-readcomplete" >> "$ABCDETEMPDIR/status"
+       echo "cdtext-readcomplete" >> "${ABCDETEMPDIR}/status"
 }
 
-# do_musicbrainz
+# do_musicbrainz_read
 # Work with the musicbrainz WS API, then transform the results here so
 # they look (very) like the results from CDDB. Maybe not the best way
 # to go, but it Works For Me (TM)
-
-do_musicbrainz ()
+#
+# List out all the matches individually into $SOURCE_WORKDIR/cddbread.X
+#
+do_musicbrainz_read ()
 {
        if checkstatus musicbrainz-readcomplete; then :; else
                vecho "Obtaining Musicbrainz results..."
                # If MB is to be used, interpret the query results and read all
                # the available entries.
-               rm -f "$ABCDETEMPDIR/cddbchoices"
-               CDDBCHOICES=1 # Overridden by multiple matches
-               MBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
-               ${MUSICBRAINZ} --command data --discid "$MBDISCID" --workdir "$ABCDETEMPDIR"
+               CDDBDISCID=$(echo "$CDDBTRACKINFO" | cut -d' ' -f1)
+               MBDISCID=$(echo "$MBTRACKINFO" | cut -d' ' -f1)
+               local SOURCE_WORKDIR="${ABCDETEMPDIR}/data-musicbrainz"
+               mkdir -p "${SOURCE_WORKDIR}"
+               ${MUSICBRAINZ} --command data --discid "${MBDISCID}" --workdir "${SOURCE_WORKDIR}" --start ${NUM_CDDB_MATCHES}
+               error=$?
+               if [ $error != 0 ]; then
+                       log error "$MUSICBRAINZ failed to run; ABORT"
+                       exit $error
+               fi
 
+               # Check for no matches.
                # The helper script will write disc matches out to
                # cddbread.*. Count how many we have
-               if [ ! -f "${ABCDETEMPDIR}/cddbread.1" ] ; then
-                       # No matches. Use the normal cddb template for the user to
-                       # fill in
-                       echo "No Musicbrainz match." >> "$ABCDETEMPDIR/cddbchoices"
-                       $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
-                       # List out disc title/author and contents of template
-                       echo ---- Unknown Artist / Unknown Album ---- >> "$ABCDETEMPDIR/cddbchoices"
-                       UNKNOWNDISK=y
-                       for TRACK in $(f_seq_row 1 $TRACKS)
-                       do
-                               echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.0" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
+               NUM_RESPONSES=$(echo "${SOURCE_WORKDIR}"/cddbread.* | wc -w)
+               if [ "$NUM_RESPONSES" -gt 0 ] ; then
+                       # One or more exact matches
+                       i=1
+                       while [ $i -le "$NUM_RESPONSES" ]; do
+                               NUM_CDDB_MATCHES=$(($NUM_CDDB_MATCHES + 1))
+                               i=$(($i + 1))
+                               echo cddb-read-${NUM_CDDB_MATCHES}-complete >> "${ABCDETEMPDIR}/status"
+                               ATITLE=$(grep -a -e '^DTITLE=' "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}" | cut -c8- | tr -d \\r\\n)
+                               echo "none ${CDDBDISCID} ${ATITLE}" >> "${SOURCE_WORKDIR}/cddbquery.${NUM_CDDB_MATCHES}"
+                               echo "Musicbrainz" > "${SOURCE_WORKDIR}/datasource.${NUM_CDDB_MATCHES}"
+                               cp -f "${SOURCE_WORKDIR}/"*."${NUM_CDDB_MATCHES}" "${ABCDETEMPDIR}"
                        done
-                       echo >> "$ABCDETEMPDIR/cddbchoices"
-                       echo cddb-read-0-complete >> "$ABCDETEMPDIR/status"
-                       echo cddb-choice=0 >> "$ABCDETEMPDIR/status"
-                       echo 503 > "$ABCDETEMPDIR/cddbquery"
-               else
-                       # We have some matches
-                       NUM_RESPONSES=$(echo "${ABCDETEMPDIR}"/cddbread.* | wc -w)
-                       if [ "$NUM_RESPONSES" -eq 1 ] ; then
-                               # One exact match
-                               echo -n "Retrieved 1 Musicbrainz match..." >> "$ABCDETEMPDIR/cddbchoices"
-                               echo "done." >> "$ABCDETEMPDIR/cddbchoices"
-                               echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
-                               echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
-                               ATITLE=$(grep -e '^DTITLE=' "${ABCDETEMPDIR}/cddbread.1" | cut -c8- )
-                               echo "200 none ${ATITLE}" >> "$ABCDETEMPDIR/cddbquery"
-                               # List out disc title/author and contents
-                               echo ---- ${ATITLE} ---- >> "$ABCDETEMPDIR/cddbchoices"
-                               for TRACK in $(f_seq_row 1 $TRACKS)
-                               do
-                                       echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
-                               done
-                               echo >> "$ABCDETEMPDIR/cddbchoices"
-                       else
-                               echo "210 Found exact matches, list follows (until terminating .)" > "$ABCDETEMPDIR/cddbquery"
-                               echo "Multiple Musicbrainz matches:" >> "$ABCDETEMPDIR/cddbchoices"
-                               for file in "$ABCDETEMPDIR"/cddbread.*
-                               do
-                                       X=$(echo $file | sed 's/^.*cddbread\.//g')
-                                       echo cddb-read-$X-complete >> "$ABCDETEMPDIR/status"
-                                       ATITLE=$(grep -e '^DTITLE=' "${ABCDETEMPDIR}"/cddbread.$X | cut -c8- )
-                                       echo "none ${ATITLE}" >> "$ABCDETEMPDIR/cddbquery"
-                                       # List out disc title/author and contents
-                                       echo "#$X: ---- ${ATITLE} ----" >> "$ABCDETEMPDIR/cddbchoices"
-                                       for TRACK in $(f_seq_row 1 $TRACKS)
-                                       do
-                                               echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.$X" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
-                                       done
-                                       echo >> "$ABCDETEMPDIR/cddbchoices"
-                               done
-                               echo "." >> "$ABCDETEMPDIR/cddbquery"
-                       fi
                fi
-               echo "musicbrainz-readcomplete" >> "$ABCDETEMPDIR/status"
+               echo "musicbrainz-readcomplete" >> "${ABCDETEMPDIR}/status"
        fi
 }
 
-# do_cddbstat
-do_cddbstat ()
+# do_cddb_read
+do_cddb_read ()
 {
+       local SOURCE_WORKDIR="${ABCDETEMPDIR}/data-cddb"
+       mkdir -p "${SOURCE_WORKDIR}"
+
+       ###########
+       # cddbstat
+       ###########
+
        # Perform CDDB protocol version check if it hasn't already been done
        if checkstatus cddb-statcomplete; then :; else
                if [ "$CDDBAVAIL" = "n" ]; then
                        ERRORCODE=no_query
-                       echo 503 > "$ABCDETEMPDIR/cddbstat"
+                       echo 503 > "${SOURCE_WORKDIR}/cddbstat"
                else
                        rc=1
-                       CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
-                       CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
-                       while test $rc -eq 1 -a $CDDBPROTO -ge 3; do
+                       CDDBUSER=$(echo "$HELLOINFO" | cut -f1 -d'@')
+                       CDDBHOST=$(echo "$HELLOINFO" | cut -f2- -d'@')
+                       while [ $rc -eq 1 ] && [ "$CDDBPROTO" -ge 3 ]; do
                                vecho "Checking CDDB server status..."
-                               $CDDBTOOL stat $CDDBURL $CDDBUSER $CDDBHOST $CDDBPROTO > "$ABCDETEMPDIR/cddbstat"
-                               RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbstat" | cut -f1 -d' ')
+                               $CDDBTOOL stat "$CDDBURL" "$CDDBUSER" "$CDDBHOST" "$CDDBPROTO" > "${SOURCE_WORKDIR}/cddbstat"
+                               RESPONSECODE=$(head -n 1 "${SOURCE_WORKDIR}/cddbstat" | cut -f1 -d' ')
                                case "$RESPONSECODE" in
                                210)    # 210 OK, status information follows (until terminating `.')
                                        rc=0
                                        ;;
                                501)  # 501 Illegal CDDB protocol level: <n>.
-                                       CDDBPROTO=`expr $CDDBPROTO - 1`
+                                       CDDBPROTO=$(($CDDBPROTO - 1))
                                        ;;
                                *)      # Try a cddb query, since freedb2.org doesn't support the stat or ver commands
                                        # FreeDB TESTCD disc-id is used for query
-                                       $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST 03015501 1 296 344 > "$ABCDETEMPDIR/cddbstat"
-                                       RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbstat" | cut -f1 -d' ')
+                                       $CDDBTOOL query "$CDDBURL" "$CDDBPROTO" "$CDDBUSER" "$CDDBHOST" 03015501 1 296 344 > "${SOURCE_WORKDIR}/cddbstat"
+                                       RESPONSECODE=$(head -n 1 "${SOURCE_WORKDIR}/cddbstat" | cut -f1 -d' ')
                                        case "$RESPONSECODE" in
                                                2??)    # Server responded, everything seems OK
                                                        rc=0
@@ -2560,150 +2713,116 @@ do_cddbstat ()
                                        ;;
                                esac
                        done
-                       if test $rc -eq 1; then
+                       if [ $rc -eq 1 ]; then
                                CDDBAVAIL="n"
                        fi
                fi
-               echo cddb-statcomplete >> "$ABCDETEMPDIR/status"
+               echo cddb-statcomplete >> "${ABCDETEMPDIR}/status"
        fi
-}
 
+       ###########
+       # cddbquery
+       ###########
 
-# do_cddbquery
-do_cddbquery ()
-{
-       CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
+       CDDBDISCID=$(echo "$CDDBTRACKINFO" | cut -d' ' -f1)
        CDDBLOCALFILE="${CDDBLOCALDIR}/${CDDBDISCID}"
 
        # Perform CDDB query if it hasn't already been done
        if checkstatus cddb-querycomplete; then :; else
                if [ "$CDDBAVAIL" = "n" ]; then
                        ERRORCODE=no_query
-                       echo 503 > "$ABCDETEMPDIR/cddbquery"
+                       echo 503 > "${SOURCE_WORKDIR}/cddbquery"
                # The default CDDBLOCALSTATUS is "notfound"
                # This part will be triggered if the user CDDB repo does not
                # contain the entry, or if we are not trying to use the repo.
                else
                        vecho "Querying the CDDB server..."
-                       CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
-                       CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
-                       $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $TRACKINFO > "$ABCDETEMPDIR/cddbquery"
+                       CDDBUSER=$(echo "$HELLOINFO" | cut -f1 -d'@')
+                       CDDBHOST=$(echo "$HELLOINFO" | cut -f2- -d'@')
+                       $CDDBTOOL query "$CDDBURL" "$CDDBPROTO" "$CDDBUSER" "$CDDBHOST" "$CDDBTRACKINFO" > "${SOURCE_WORKDIR}/cddbquery"
                        ERRORCODE=$?
                        case $ERRORCODE in
                                0)  # success
                                ;;
                                12|13|14)
-                                       # no match found in database,
-                                       # wget/fetch error, or user requested not to use CDDB
-                                       # Make up an error code (503) that abcde
-                                       # will recognize in do_cddbread
+                                       # no match found in database, wget/fetch error,
+                                       # or user requested not to use CDDB. Make up an
+                                       # error code (503) that abcde will recognize later
                                        # and compensate by making a template
-                                       echo 503 > "$ABCDETEMPDIR/cddbquery"
+                                       echo 503 > "${SOURCE_WORKDIR}/cddbquery"
                                ;;
                                *) # strange and unknown error
-                                       echo ERRORCODE=$ERRORCODE
+                                       echo "ERRORCODE=$ERRORCODE"
                                        echo "abcde: $CDDBTOOL returned unknown error code"
                                ;;
                        esac
                fi
-               echo cddb-querycomplete >> "$ABCDETEMPDIR/status"
+               echo cddb-querycomplete >> "${ABCDETEMPDIR}/status"
        fi
-}
 
-# do_cddbread
-do_cddbread ()
-{
+       ###########
+       # cddbread
+       ###########
+
        # If it's not to be used, generate a template.
        # Then, display it (or them) and let the user choose/edit it
        if checkstatus cddb-readcomplete; then :; else
+               RESPONSECODE=$(head -n 1 "${SOURCE_WORKDIR}/cddbquery" | cut -f1 -d' ')
                vecho "Obtaining CDDB results..."
-               # If CDDB is to be used, interpret the query results and read all
-               # the available entries.
-               rm -f "$ABCDETEMPDIR/cddbchoices"
-               CDDBCHOICES=1 # Overridden by multiple matches
-               RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbquery" | cut -f1 -d' ')
                case "$RESPONSECODE" in
                200)
                        # One exact match, retrieve it
                        # 200 [section] [discid] [artist] / [title]
-                       if checkstatus cddb-read-1-complete; then :; else
-                               echo -n "Retrieving 1 CDDB match..." >> "$ABCDETEMPDIR/cddbchoices"
-                               $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(cut -f2,3 -d' ' "$ABCDETEMPDIR/cddbquery") > "$ABCDETEMPDIR/cddbread.1"
-                               echo "done." >> "$ABCDETEMPDIR/cddbchoices"
-                               echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
-                               echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
-                       fi
-                       # List out disc title/author and contents
-                       echo ---- "$(cut '-d ' -f4- "$ABCDETEMPDIR/cddbquery")" ---- >> "$ABCDETEMPDIR/cddbchoices"
-                       for TRACK in $(f_seq_row 1 $TRACKS)
-                       do
-                               echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
-                       done
-                       echo >> "$ABCDETEMPDIR/cddbchoices"
+                       NUM_CDDB_MATCHES=$(($NUM_CDDB_MATCHES + 1))
+                       $CDDBTOOL read "$CDDBURL" "$CDDBPROTO" "$CDDBUSER" "$CDDBHOST" \
+                                         $(cut -f2,3 -d' ' "${SOURCE_WORKDIR}/cddbquery") \
+                                         > "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}"
+                       cat "${SOURCE_WORKDIR}/cddbquery" | cut -f2- -d' ' > "${SOURCE_WORKDIR}/cddbquery.${NUM_CDDB_MATCHES}"
+                       echo "cddb" > "${SOURCE_WORKDIR}/datasource.${NUM_CDDB_MATCHES}"
+                       echo "cddb-read-${NUM_CDDB_MATCHES}-complete" >> "${ABCDETEMPDIR}/status"
                        ;;
-               202|403|409|503)
-                       # No match
-                       case "$RESPONSECODE" in
-                       202) echo "No CDDB match." >> "$ABCDETEMPDIR/cddbchoices" ;;
-                       403|409) echo "CDDB entry is corrupt, or the handshake failed." >> "$ABCDETEMPDIR/cddbchoices" ;;
-                       503) echo "CDDB unavailable." >> "$ABCDETEMPDIR/cddbchoices" ;;
-                       esac
-                       $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
-                       # List out disc title/author and contents of template
-                       echo ---- Unknown Artist / Unknown Album ---- >> "$ABCDETEMPDIR/cddbchoices"
-                       UNKNOWNDISK=y
-                       for TRACK in $(f_seq_row 1 $TRACKS)
-                       do
-                               echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.0" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
-                       done
-                       echo >> "$ABCDETEMPDIR/cddbchoices"
-                       echo cddb-read-0-complete >> "$ABCDETEMPDIR/status"
-                       echo cddb-choice=0 >> "$ABCDETEMPDIR/status"
+               202|403|409|500|503)
+                       # TODO: Explain these error codes a little more accurately:
+                       # http://ftp.freedb.org/pub/freedb/misc/freedb_CDDB_protcoldoc.zip
+                       # No match response:
                        ;;
                210|211)
                        # Multiple exact, (possibly multiple) inexact matches
-                       IN=
-                       if [ "$RESPONSECODE" = "211" ]; then IN=in; fi
-                       if [ "$(wc -l < "$ABCDETEMPDIR/cddbquery" | tr -d ' ')" -eq 3 ]; then
-                               echo "One ${IN}exact match:" >> "$ABCDETEMPDIR/cddbchoices"
-                               tail -n +2 "$ABCDETEMPDIR/cddbquery" | head -n 1 >> "$ABCDETEMPDIR/cddbchoices"
-                                                       echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
-                       else
-                               echo "Multiple ${IN}exact matches:" >> "$ABCDETEMPDIR/cddbchoices"
-                       fi
                        vecho -n "Retrieving multiple matches... "
-                       grep -v ^[.]$ "$ABCDETEMPDIR/cddbquery" | ( X=0
-                       read DISCINFO # eat top line
-                       while read DISCINFO
-                       do
-                               X=$(expr $X + 1)
-                               if checkstatus cddb-read-$X-complete; then :; else
-                                       $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(echo $DISCINFO | cut -f1,2 -d' ') > "$ABCDETEMPDIR/cddbread.$X"
-                                       echo cddb-read-$X-complete >> "$ABCDETEMPDIR/status"
-                               fi
-                               # List out disc title/author and contents
-                               echo \#$X: ---- "$DISCINFO" ---- >> "$ABCDETEMPDIR/cddbchoices"
-                               for TRACK in $(f_seq_row 1 $TRACKS)
+                       grep -v '^[.]$' "${SOURCE_WORKDIR}/cddbquery" | (
+                               # IN A SUB-SHELL - VARIABLES MODIFIED
+                               # HERE DO NOT PERSIST IN THE PARENT
+                               read DISCINFO # eat top line
+                               while read DISCINFO
                                do
-                                       echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.$X" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
-                               done
-                               echo >> "$ABCDETEMPDIR/cddbchoices"
-                       done )
+                                       NUM_CDDB_MATCHES=$(($NUM_CDDB_MATCHES + 1))
+                                       if checkstatus "cddb-read-${NUM_CDDB_MATCHES}-complete"; then :; else
+                                               $CDDBTOOL read "$CDDBURL" "$CDDBPROTO" "$CDDBUSER" "$CDDBHOST" \
+                                                                 $(echo "$DISCINFO" | cut -f1,2 -d' ') \
+                                                                 > "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}"
+                                               echo "$DISCINFO" > "${SOURCE_WORKDIR}/cddbquery.${NUM_CDDB_MATCHES}"
+                                               echo "cddb" > "${SOURCE_WORKDIR}/datasource.${NUM_CDDB_MATCHES}"
+                                               echo "cddb-read-${NUM_CDDB_MATCHES}-complete" >> "${ABCDETEMPDIR}/status"
+                                       fi
+                               done )
+                       # Need to re-count the entries here to be able
+                       # to incrememnt $NUM_CDDB_MATCHES in the
+                       # parent
+                       NUM_CDDB_MATCHES=$(($NUM_CDDB_MATCHES + $(echo "${SOURCE_WORKDIR}/datasource.*" | wc -w)))
                        vecho "done."
-                       CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
                        ;;
                999)
                        # Using local copy.
-                       for TRACK in $(f_seq_row 1 $TRACKS)
-                       do
-                               echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
-                       done
-                       echo >> "$ABCDETEMPDIR/cddbchoices"
-                       echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
-                       echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
+                       NUM_CDDB_MATCHES=$(($NUM_CDDB_MATCHES + 1))
+                       echo "cddb-read-${NUM_CDDB_MATCHES}-complete" >> "${ABCDETEMPDIR}/status"
                        ;;
                esac
-               echo "cddb-readcomplete" >> "$ABCDETEMPDIR/status"
+               echo "cddb-readcomplete" >> "${ABCDETEMPDIR}/status"
+               for file in ${SOURCE_WORKDIR}/cddbread.* ${SOURCE_WORKDIR}/cddbquery.* ${SOURCE_WORKDIR}/datasource.*; do
+                       if [ -f "$file" ]; then
+                               cp "$file" "${ABCDETEMPDIR}"
+                       fi
+               done
        fi
 }
 
@@ -2711,7 +2830,7 @@ do_cddbread ()
 do_cddbedit ()
 {
        if checkstatus cddb-edit >/dev/null; then
-               CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
+               CDDBDATA="${ABCDETEMPDIR}/cddbread.$(checkstatus cddb-choice)"
                VARIOUSARTISTS="$(checkstatus variousartists)"
                VARIOUSARTISTSTYLE="$(checkstatus variousartiststyle)"
                return 0
@@ -2720,105 +2839,94 @@ do_cddbedit ()
                # We should show the CDDB results both when we are not using the local CDDB repo
                # or when we are using it but we could not find a proper match
                if [ "$CDDBUSELOCAL" = "y" ] && [ "$CDDBLOCALSTATUS" = "notfound" ] || [ ! "$CDDBUSELOCAL" = "y" ]; then
-                       # Display the $ABCDETEMPDIR/cddbchoices file created above
-                       # Pick a pager so that if the tracks overflow the screen the user can still view everything
-                       if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
-                               CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
+                       # Display the ${ABCDETEMPDIR}/cddbchoices file created above
+                       if [ -r "${ABCDETEMPDIR}/cddbchoices" ]; then
                                CHOICE=$(checkstatus cddb-choice)
                                if [ -n "$CHOICE" ] ; then
-                                       case $CDDBCHOICES in
-                                               -1) if head -1 "$ABCDETEMPDIR/cddbquery" | grep "^$" > /dev/null 2>&1 ; then
-                                                               log error "CDDB query failed!"
-                                                               exit 1
-                                                       else
-                                                               cat "$ABCDETEMPDIR/cddbchoices"
-                                                       fi
-                                                       ;;
-                                               1) cat "$ABCDETEMPDIR/cddbchoices" ;;
+                                       case $NUM_CDDB_MATCHES in
+                                               1) cat "${ABCDETEMPDIR}/cddbchoices" ;;
                                                *)
-                                               echo "Selected: #$CHOICE"
-                                               do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
+                                               ATITLE=$(grep -a ^DTITLE= "${ABCDETEMPDIR}/cddbread.$CHOICE" | cut -f2- -d= | tr -d \\r\\n)
+                                               SOURCE=$(cat "${ABCDETEMPDIR}/datasource.$CHOICE")
+                                               echo "Selected: #$CDCHOICENUM ($SOURCE) ($ATITLE)"
+                                               do_cddbparse "${ABCDETEMPDIR}/cddbread.$CHOICE"
                                                ;;
                                        esac
                                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
-                                               page "$ABCDETEMPDIR/cddbchoices"
-                                       else
-                                               # It's all going to fit in one page, cat it
-                                               cat "$ABCDETEMPDIR/cddbchoices" >&2
-                                       fi
-
+                                       page "${ABCDETEMPDIR}/cddbchoices"
                                        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
+                                       while [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $NUM_CDDB_MATCHES ]; do
+                                               echo -n "Which entry would you like abcde to use (0 for none)? [0-$NUM_CDDB_MATCHES]: " >&2
                                                read CDDBCHOICE
                                                [ X"$CDDBCHOICE" = "X" ] && CDDBCHOICE=1
                                                if echo $CDDBCHOICE | grep -E "[[:space:]]*[[:digit:]]+,[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
                                                        if [ ! X"$DIFF" = "X" ]; then
                                                                PARSECHOICE1=$(echo $CDDBCHOICE | cut -d"," -f1 | xargs printf %d 2>/dev/null)
                                                                PARSECHOICE2=$(echo $CDDBCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null)
-                                                               if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBCHOICES ] || \
-                                                                  [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBCHOICES ] || \
-                                                                  [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then
-                                                                       echo "Invalid diff range. Please select two comma-separated numbers between 1 and $CDDBCHOICES" >&2
+                                                               if [ "$PARSECHOICE1" -lt 1 ] || [ "$PARSECHOICE1" -gt "$NUM_CDDB_MATCHES" ] || \
+                                                                  [ "$PARSECHOICE2" -lt 1 ] || [ "$PARSECHOICE2" -gt "$NUM_CDDB_MATCHES" ] || \
+                                                                  [ "$PARSECHOICE1" -eq "$PARSECHOICE2" ]; then
+                                                                       echo "Invalid diff range." >&2
+                                                                       echo "Please select two comma-separated numbers between 1 and $NUM_CDDB_MATCHES" >&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"
+                                                                               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
+                                                                       echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..." \
+                                                                                > "${ABCDETEMPDIR}/cddbread.diff"
+                                                                       $DIFF $DIFFOPTS "${ABCDETEMPDIR}/cddbread.parsechoice.$PARSECHOICE1" \
+                                                                                 "${ABCDETEMPDIR}/cddbread.parsechoice.$PARSECHOICE2" \
+                                                                                 >> "${ABCDETEMPDIR}/cddbread.diff"
+                                                                       page "${ABCDETEMPDIR}/cddbread.diff"
                                                                fi
                                                        else
-                                                               echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBCHOICES." >&2
+                                                               echo "The diff program was not found in your path." >&2
+                                                               echo "Please choose a number between 0 and $NUM_CDDB_MATCHES." >&2
                                                        fi
                                                elif echo $CDDBCHOICE | grep -E "[[:space:]]*[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
                                                        # Make sure we get a valid choice
                                                        CDCHOICENUM=$(echo $CDDBCHOICE | xargs printf %d 2>/dev/null)
-                                                       if [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; then
-                                                               echo "Invalid selection. Please choose a number between 0 and $CDDBCHOICES." >&2
+                                                       if [ "$CDCHOICENUM" -lt 0 ] || [ "$CDCHOICENUM" -gt "$NUM_CDDB_MATCHES" ]; then
+                                                               echo "Invalid selection. Please choose a number between 0 and $NUM_CDDB_MATCHES." >&2
                                                        fi
                                                fi
                                        done
                                        if [ "$CDCHOICENUM" = "0" ]; then
                                                vecho "Creating empty CDDB template..."
                                                UNKNOWNDISK=y
-                                               $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
+                                               $CDDBTOOL template $(cat "${ABCDETEMPDIR}/cddbdiscid") > "${ABCDETEMPDIR}/cddbread.0"
+                                               echo "template" > "${ABCDETEMPDIR}/datasource.0"
                                        else
-                                               echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
-                                               do_cddbparse "$ABCDETEMPDIR/cddbread.$CDCHOICENUM"
+                                               ATITLE=$(grep -a ^DTITLE= "${ABCDETEMPDIR}/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n)
+                                               SOURCE=$(cat "${ABCDETEMPDIR}/datasource.$CDCHOICENUM")
+                                               echo "Selected: #$CDCHOICENUM ($SOURCE) ($ATITLE)" >&2
                                        fi
-                                       echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
+                                       do_cddbparse "${ABCDETEMPDIR}/cddbread.$CDCHOICENUM"
+                                       echo "cddb-choice=$CDCHOICENUM" >> "${ABCDETEMPDIR}/status"
                                fi
                        fi
                else
                        # We need some code to show the selected option when local repository is selected and we have found a match
                        vecho "Using cached CDDB match..." >&2
-                       # Display the $ABCDETEMPDIR/cddbchoices file created above
-                       # Pick a pager so that if the tracks overflow the screen the user can still view everything
-                       if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
-                               CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
+                       # Display the ${ABCDETEMPDIR}/cddbchoices file created above
+                       if [ -r "${ABCDETEMPDIR}/cddbchoices" ]; then
                                CHOICE=$(checkstatus cddb-choice)
                                if [ "$USELOCALRESP" = "y" ]; then :; else
                                        if [ -n "$CHOICE" ] ; then
-                                               case $CDDBCHOICES in
+                                               case $NUM_CDDB_MATCHES in
                                                        0)
                                                        UNKNOWNDISK=y
                                                        echo "Selected template."
                                                        ;;
-                                                       1) cat "$ABCDETEMPDIR/cddbchoices" ;;
+                                                       1) cat "${ABCDETEMPDIR}/cddbchoices" ;;
                                                        *)
                                                        echo "Selected: #$CHOICE"
-                                                       do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
+                                                       do_cddbparse "${ABCDETEMPDIR}/cddbread.$CHOICE"
                                                        ;;
                                                esac
                                        fi
@@ -2828,22 +2936,22 @@ do_cddbedit ()
        else
                # We're noninteractive - pick the first choice.
                # But in case we run a previous instance and selected a choice, use it.
-               if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
+               if [ -r "${ABCDETEMPDIR}/cddbchoices" ]; then
                        # Show the choice if we are not using the locally stored one
                        # or when the local search failed to find a match.
                        PREVIOUSCHOICE=$(checkstatus cddb-choice)
                        if [ "$CDDBUSELOCAL" = "y" ] && [ "$CDDBLOCALSTATUS" = "notfound" ] || [ ! "$CDDBUSELOCAL" = "y" ]; then
                                #if [ "$PREVIOUSCHOICE" ]; then
-                                       cat "$ABCDETEMPDIR/cddbchoices"
+                                       cat "${ABCDETEMPDIR}/cddbchoices"
                                #fi
                        fi
                        if [ ! -z "$PREVIOUSCHOICE" ] ; then
                                CDCHOICENUM=$PREVIOUSCHOICE
                        else
                                CDCHOICENUM=1
-                               echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
+                               echo "cddb-choice=$CDCHOICENUM" >> "${ABCDETEMPDIR}/status"
                        fi
-                       echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
+                       echo "Selected: #$CDCHOICENUM ($(grep -a ^DTITLE= "${ABCDETEMPDIR}/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
                fi
        fi
 
@@ -2852,7 +2960,8 @@ do_cddbedit ()
                echo "abcde: internal error: cddb-choice not recorded." >&2
                exit 1
        fi
-       CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
+       CDDBDATA="${ABCDETEMPDIR}/cddbread.$(checkstatus cddb-choice)"
+       CDDBSOURCE=$(cat "${ABCDETEMPDIR}/datasource.$(checkstatus cddb-choice)")
        echo -n "Edit selected CDDB data " >&2
        if [ "$INTERACTIVE" = "y" ]; then
                if [ "$UNKNOWNDISK" = "y" ]; then
@@ -2875,10 +2984,10 @@ do_cddbedit ()
                if [ -x "/usr/bin/sensible-editor" ]; then
                        /usr/bin/sensible-editor "$CDDBDATA"
                elif [ -n "$EDITOR" ]; then
-                       if [ -x $(which "${EDITOR%%\ *}") ]; then
+                       if [ -x "$(which "${EDITOR%%\ *}")" ]; then
                                # That failed, try to load the preferred editor, starting
                                # with their EDITOR variable
-                               eval $(echo "$EDITOR") \"$CDDBDATA\"
+                               $EDITOR "$CDDBDATA"
                        fi
                # If that fails, check for a vi
                elif which vi >/dev/null 2>&1; then
@@ -2911,7 +3020,7 @@ do_cddbedit ()
 
        # Some heuristics first. Look at Disc Title, and if it starts with
        # "Various", then we'll assume Various Artists
-       if [ "$(grep ^DTITLE= "$CDDBDATA" | cut -f2- -d= | grep -Eci '^(various|soundtrack|varios|sonora|ost)')" != "0" ]; then
+       if [ "$(grep -a ^DTITLE= "$CDDBDATA" | cut -f2- -d= | grep -aEci '^(various|soundtrack|varios|sonora|ost)')" != "0" ]; then
                echo "Looks like a Multi-Artist CD" >&2
                VARIOUSARTISTS=y
        else
@@ -2927,14 +3036,14 @@ do_cddbedit ()
                # Set a default
                DEFAULTSTYLE=1
                # Need NUMTRACKS before cddb-tool will return it:
-               NUMTRACKS=$(grep -E '^TTITLE[0-9]+=' "$CDDBDATA" | wc -l)
-               if [ "$(grep -c "^TTITLE.*\/" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
+               NUMTRACKS=$(grep -a -E '^TTITLE[0-9]+=' "$CDDBDATA" | wc -l)
+               if [ "$(grep -ac "^TTITLE.*\/" "$CDDBDATA")" -gt "$(( $NUMTRACKS / 2 ))" ]; then
                        # More than 1/2 tracks contain a "/", so guess forward
                        DEFAULTSTYLE=1
-               elif [ "$(grep -c "^TTITLE.*\-" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
+               elif [ "$(grep -ac "^TTITLE.*\-" "$CDDBDATA")" -gt "$(( $NUMTRACKS / 2 ))" ]; then
                        # More than 1/2 contain a "-", so guess forward-dash
                        DEFAULTSTYLE=2
-               elif [ "$(grep -c "^TTITLE.*(.*)" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
+               elif [ "$(grep -ac "^TTITLE.*(.*)" "$CDDBDATA")" -gt "$(( $NUMTRACKS / 2 ))" ]; then
                        # More than 1/2 contain something in parens, so guess trailing-paren
                        DEFAULTSTYLE=6
                fi
@@ -2955,14 +3064,14 @@ do_cddbedit ()
                fi
                VARIOUSARTISTSTYLE=$(echo 0$VARIOUSARTISTSTYLE | xargs printf %d)
                # If they press Enter, then the default style (0) was chosen
-               while [ $VARIOUSARTISTSTYLE -lt 0 ] || [ $VARIOUSARTISTSTYLE -gt 7 ]; do
+               while [ "$VARIOUSARTISTSTYLE" -lt 0 ] || [ "$VARIOUSARTISTSTYLE" -gt 7 ]; do
                        echo "Invalid selection. Please choose a number between 1 and 7."
                        echo -n "Selection [1-7]: "
                        read VARIOUSARTISTSTYLE
-                       VARIOUSARTISTSTYLE=$(echo 0$VARIOUSARTISTSTYLE | xargs printf %d)
+                       VARIOUSARTISTSTYLE=$(echo "0$VARIOUSARTISTSTYLE" | xargs printf "%d")
                done
                if [ "$VARIOUSARTISTSTYLE" = "0" ]; then
-                       VARIOUSARTISTSTYLE=$DEFAULTSTYLE
+                       VARIOUSARTISTSTYLE="$DEFAULTSTYLE"
                fi
                vecho "Selected: $VARIOUSARTISTSTYLE"
                case "$VARIOUSARTISTSTYLE" in
@@ -2990,10 +3099,10 @@ do_cddbedit ()
                esac
        fi
 
-       echo "variousartists=$VARIOUSARTISTS" >> "$ABCDETEMPDIR/status"
-       echo "variousartiststyle=$VARIOUSARTISTSTYLE" >> "$ABCDETEMPDIR/status"
+       echo "variousartists=$VARIOUSARTISTS" >> "${ABCDETEMPDIR}/status"
+       echo "variousartiststyle=$VARIOUSARTISTSTYLE" >> "${ABCDETEMPDIR}/status"
 
-       if [ "$EDITCDDB" = "y" ] && [ "$CDDBMETHOD" = "cddb" ] && [ "$UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE" = "y" ]; then
+       if [ "$EDITCDDB" = "y" ] && [ "$CDDBSOURCE" = "cddb" ] && [ "$UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE" = "y" ]; 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
@@ -3016,7 +3125,7 @@ do_cddbedit ()
                                done
                                if [ "$YESNO" = "y" ] || [ "$YESNO" = "Y" ]; then
                                        echo -n "Sending..."
-                                       $CDDBTOOL send "$CDDBDATA" $CDDBSUBMIT
+                                       $CDDBTOOL send "$CDDBDATA" "$CDDBSUBMIT"
                                        echo "done."
                                fi
                        fi
@@ -3027,11 +3136,13 @@ do_cddbedit ()
        # Cache edited CDDB entry in the user's cddb dir
        if [ "$CDDBCOPYLOCAL" = "y" ]; then
                # Make sure the cache directory exists
-               mkdir -p $CDDBLOCALDIR
-               cat "$CDDBDATA" | tail -n $(expr $(cat "$CDDBDATA" | wc -l ) - 1 ) > ${CDDBLOCALDIR}/$(echo "$TRACKINFO" | cut -d' ' -f1)
+               mkdir -p "$CDDBLOCALDIR"
+               NUM_LINES=$(( $(wc -l < "$CDDBDATA") - 1 ))
+               OUTPUT_FILE="$(echo "$CDDBTRACKINFO" | cut -d' ' -f1)"
+               tail -n "$NUM_LINES" < "$CDDBDATA" > "${CDDBLOCALDIR}/${OUTPUT_FILE}"
        fi
 
-       echo "cddb-edit" >> "$ABCDETEMPDIR/status"
+       echo "cddb-edit" >> "${ABCDETEMPDIR}/status"
 }
 
 # do_getalbumart
@@ -3039,35 +3150,37 @@ do_cddbedit ()
 do_getalbumart()
 {
        # set variables
-       ALBUMFILE="$(mungefilename "$DALBUM")"
-       ARTISTFILE="$(mungefilename "$DARTIST")"
+       ALBUMFILE="$(mungealbumname "$DALBUM")"
+       ARTISTFILE="$(mungeartistname "$DARTIST")"
+       GENRE="$(mungegenre "$GENRE")"
+       YEAR=${CDYEAR:-$CDYEAR}
        # have we got a musicbrainz mbid or amazon asin?
        case "$CDDBMETHOD" in
-               musicbrainz)
+               *musicbrainz*)
                        # try musicbrainz mbid
-                       if [ -s "$ABCDETEMPDIR/mbid.$(checkstatus cddb-choice)" ]; then
-                               MBID=$(cat "$ABCDETEMPDIR/mbid.$(checkstatus cddb-choice)")
+                       if [ -s "${ABCDETEMPDIR}/mbid.$(checkstatus cddb-choice)" ]; then
+                               MBID=$(cat "${ABCDETEMPDIR}/mbid.$(checkstatus cddb-choice)")
                                vecho "trying to get cover from coverartarchive.orq with musicbrainz mbid $MBID" >&2
                                ALBUMARTURL="http://coverartarchive.org/release/$MBID/front"
                                vecho "cover URL: $ALBUMARTURL" >&2
-                               $HTTPGET "$ALBUMARTURL" > "$ABCDETEMPDIR/$ALBUMARTFILE"
+                               $HTTPGET "$ALBUMARTURL" > "${ABCDETEMPDIR}/$ALBUMARTFILE"
                                if [ $? -ne 0 ]; then
                                        vecho "could not download cover from musicbrainz" >&2
                                        # try amazon asin
-                                       if [ -s "$ABCDETEMPDIR/asin.$(checkstatus cddb-choice)" ]; then
-                                               ASIN=$(cat "$ABCDETEMPDIR/asin.$(checkstatus cddb-choice)")
+                                       if [ -s "${ABCDETEMPDIR}/asin.$(checkstatus cddb-choice)" ]; then
+                                               ASIN=$(cat "${ABCDETEMPDIR}/asin.$(checkstatus cddb-choice)")
                                                vecho "trying to get cover from amazon.com with asin $ASIN" >&2
                                                ALBUMARTURL="http://ec1.images-amazon.com/images/P/$ASIN.01.LZZZZZZZZ.jpg"
                                                vecho "cover URL: $ALBUMARTURL" >&2
-                                               $HTTPGET "$ALBUMARTURL" > "$ABCDETEMPDIR/$ALBUMARTFILE"
+                                               $HTTPGET "$ALBUMARTURL" > "${ABCDETEMPDIR}/$ALBUMARTFILE"
                                                if [ $? -ne 0 ]; then
                                                        vecho "could not download cover from amazon" >&2
                                                else
                                                        # Check that size is reasonable; sometimes when there is no cover image
                                                        # on amazon.com a 1x1 pixel gif image will be downloaded instead:
-                                                       FILESIZE=$(wc -c < "$ABCDETEMPDIR/$ALBUMARTFILE")
+                                                       FILESIZE=$(wc -c < "${ABCDETEMPDIR}/$ALBUMARTFILE")
                                                        if [ "$FILESIZE" -lt 1024 ]; then
-                                                               rm "$ABCDETEMPDIR/$ALBUMARTFILE"
+                                                               rm "${ABCDETEMPDIR}/$ALBUMARTFILE"
                                                                vecho "could not download cover from amazon" >&2
                                                        fi
                                                fi
@@ -3081,9 +3194,9 @@ do_getalbumart()
                        ;;
        esac
        # use glyrc
-       if [ ! -s "$ABCDETEMPDIR/$ALBUMARTFILE" ]; then
+       if [ ! -s "${ABCDETEMPDIR}/$ALBUMARTFILE" ]; then
                vecho "trying to get cover with glyrc for $ARTISTFILE / $ALBUMFILE" >&2
-               $GLYRC cover --artist "$ARTISTFILE" --album "$ALBUMFILE" --write "$ABCDETEMPDIR/$ALBUMARTFILE" $GLYRCOPTS
+               $GLYRC cover --artist "$ARTISTFILE" --album "$ALBUMFILE" --write "${ABCDETEMPDIR}/$ALBUMARTFILE" $GLYRCOPTS
                if [ $? -ne 0 ]; then
                        vecho "could not download cover with glyrc" >&2
                else
@@ -3091,14 +3204,14 @@ do_getalbumart()
                fi
        fi
        if [ "$INTERACTIVE" = "y" ]; then
-               if [ -s "$ABCDETEMPDIR/$ALBUMARTFILE" ]; then
+               if [ -s "${ABCDETEMPDIR}/$ALBUMARTFILE" ]; then
                        # display properties of coverart when identify is available
-                       if new_checkexec $IDENTIFY; then
-                               $IDENTIFY $IDENTIFYOPTS "$ABCDETEMPDIR/$ALBUMARTFILE" >&2
+                       if new_checkexec "$IDENTIFY"; then
+                               $IDENTIFY $IDENTIFYOPTS "${ABCDETEMPDIR}/$ALBUMARTFILE" >&2
                        fi
                        # display coverart when DISPLAY is set and display command is available
-                       if new_checkexec $DISPLAYCMD && [ "$DISPLAY" != "" ]; then
-                               $DISPLAYCMD $DISPLAYCMDOPTS "$ABCDETEMPDIR/$ALBUMARTFILE" >&2 &
+                       if new_checkexec "$DISPLAYCMD" && [ "$DISPLAY" != "" ]; then
+                               $DISPLAYCMD $DISPLAYCMDOPTS "${ABCDETEMPDIR}/$ALBUMARTFILE" >&2 &
                        fi
                else
                        # nothing downloaded yet
@@ -3118,54 +3231,211 @@ do_getalbumart()
                        read ALBUMARTURL
                        if [ ! -z "$ALBUMARTURL" ]; then
                                if [[ ${ALBUMARTURL} =~ (https?|ftp|file)://.* ]]; then
-                                       $HTTPGET "$ALBUMARTURL" > "$ABCDETEMPDIR/$ALBUMARTFILE"
-                                       if [ ! -s "$ABCDETEMPDIR/$ALBUMARTFILE" ]; then
+                                       $HTTPGET "$ALBUMARTURL" > "${ABCDETEMPDIR}/$ALBUMARTFILE"
+                                       if [ ! -s "${ABCDETEMPDIR}/$ALBUMARTFILE" ]; then
                                                vecho "unable to download $ALBUMARTURL" >&2
                                        fi
                                else # it's a local path
-                                       cp "$ALBUMARTURL" "$ABCDETEMPDIR/$ALBUMARTFILE"
-                                       if [ ! -s "$ABCDETEMPDIR/$ALBUMARTFILE" ]; then
-                                               vecho "unable to copy $ALBUMARTURL to $ABCDETEMPDIR/$ALBUMARTFILE" >&2
+                                       cp "$ALBUMARTURL" "${ABCDETEMPDIR}/$ALBUMARTFILE"
+                                       if [ ! -s "${ABCDETEMPDIR}/$ALBUMARTFILE" ]; then
+                                               vecho "unable to copy $ALBUMARTURL to ${ABCDETEMPDIR}/$ALBUMARTFILE" >&2
                                        fi
                                fi
                        fi
                fi
        fi
        # convert to ALBUMARTTYPE if ImageMagick is available, if not assume correct type
-       if [ -s "$ABCDETEMPDIR/$ALBUMARTFILE" ] && new_checkexec $IDENTIFY; then
-               ALBUMARTURLTYPE=$($IDENTIFY "$ABCDETEMPDIR/$ALBUMARTFILE" | cut -d' ' -f2)
-               if [ "$ALBUMARTURLTYPE" != "$ALBUMARTTYPE" -o "$ALBUMARTALWAYSCONVERT" = "y" ]; then
-                       if new_checkexec $CONVERT; then
-                               mv "$ABCDETEMPDIR/$ALBUMARTFILE" "$ABCDETEMPDIR/$ALBUMARTFILE.tmp"
-                               $CONVERT "$ABCDETEMPDIR/$ALBUMARTFILE.tmp" $CONVERTOPTS "$ABCDETEMPDIR/$ALBUMARTFILE"
-                               rm -f "$ABCDETEMPDIR/$ALBUMARTFILE.tmp"
+       if [ -s "${ABCDETEMPDIR}/$ALBUMARTFILE" ] && new_checkexec "$IDENTIFY"; then
+               ALBUMARTURLTYPE=$($IDENTIFY "${ABCDETEMPDIR}/$ALBUMARTFILE" | cut -d' ' -f2)
+               if [ "$ALBUMARTURLTYPE" != "$ALBUMARTTYPE" ] || [ "$ALBUMARTALWAYSCONVERT" = "y" ]; then
+                       if new_checkexec "$CONVERT"; then
+                               mv "${ABCDETEMPDIR}/$ALBUMARTFILE" "${ABCDETEMPDIR}/$ALBUMARTFILE.tmp"
+                               $CONVERT "${ABCDETEMPDIR}/$ALBUMARTFILE.tmp" $CONVERTOPTS "${ABCDETEMPDIR}/$ALBUMARTFILE"
+                               rm -f "${ABCDETEMPDIR}/$ALBUMARTFILE.tmp"
                        else
-                               rm -f "$ABCDETEMPDIR/$ALBUMARTFILE"
-                               vecho "sorry, cannot convert $ALBUMARTURLTYPE to $ALBUMARTTYPE without ImageMagick convert" >&2
+                               rm -f "${ABCDETEMPDIR}/$ALBUMARTFILE"
+                               vecho "sorry, cannot convert $ALBUMARTURLTYPE to $ALBUMARTTYPE" >&2
+                               vecho "without ImageMagick convert" >&2
                        fi
                fi
        fi
        # copy to target directories
-       if [ -s "$ABCDETEMPDIR/$ALBUMARTFILE" ]; then
-               for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
+       if [ -s "${ABCDETEMPDIR}/$ALBUMARTFILE" ]; then
+               for OUTPUT in $(echo "$OUTPUTTYPE" | tr , \ )
                do
                        # put cover in the same place as the album
+                       if [ "$ONETRACK" = "y" ] ; then
+                               if [ "$VARIOUSARTISTS" = "y" ] ; then
+                                       ALBUMARTDIR="$(eval echo "$VAONETRACKOUTPUTFORMAT")"
+                               else
+                                       ALBUMARTDIR="$(eval echo "$ONETRACKOUTPUTFORMAT")"
+                       fi
+               else
                        if [ "$VARIOUSARTISTS" = "y" ] ; then
                                ALBUMARTDIR="$(eval echo "$VAOUTPUTFORMAT")"
                        else
                                ALBUMARTDIR="$(eval echo "$OUTPUTFORMAT")"
                        fi
+               fi
                        FINALALBUMARTDIR="$(dirname "$OUTPUTDIR/$ALBUMARTDIR")"
                        vecho "copying cover to target directory $FINALALBUMARTDIR" >&2
                        mkdir -p "$FINALALBUMARTDIR"
-                       cp "$ABCDETEMPDIR/$ALBUMARTFILE" "$FINALALBUMARTDIR"
+                       cp "${ABCDETEMPDIR}/$ALBUMARTFILE" "$FINALALBUMARTDIR"
                done
-               rm -f "$ABCDETEMPDIR/$ALBUMARTFILE"
-               echo "get-album-art=$ALBUMARTURL" >> "$ABCDETEMPDIR/status"
+               rm -f "${ABCDETEMPDIR}/$ALBUMARTFILE"
+               echo "get-album-art=$ALBUMARTURL" >> "${ABCDETEMPDIR}/status"
        else
                log warning "could not get cover"
-               echo "get-album-art=none" >> "$ABCDETEMPDIR/status"
+               echo "get-album-art=none" >> "${ABCDETEMPDIR}/status"
+       fi
+}
+
+# Optionally embed the albumart downloaded by the getalbumart fuction.
+# FIXME: It would be nice to have this also selectable from within the
+# FIXME: getalbumart function itself. Andrew
+do_embedalbumart()
+{
+       # Set variables:
+       ALBUMFILE="$(mungealbumname "$DALBUM")"
+       ARTISTFILE="$(mungeartistname "$DARTIST")"
+       GENRE="$(mungegenre "$GENRE")"
+       YEAR=${CDYEAR:-$CDYEAR}
+
+       # Allow for multiple output formats:
+       for OUTPUT in $(echo "$OUTPUTTYPE" | tr , \ )
+       do
+               # Find the output directory for multi track encodes:
+               if [ "$ONETRACK" != "y" ] ; then
+                       if [ "$VARIOUSARTISTS" = "y" ] ; then
+                               FINDPATH="$(eval echo "$VAOUTPUTFORMAT")"
+                       else
+                               FINDPATH="$(eval echo "$OUTPUTFORMAT")"
+                       fi
+               fi
+               # Find the output directory for single track encodes:
+               if [ "$ONETRACK" = "y" ] ; then
+                       if [ "$VARIOUSARTISTS" = "y" ] ; then
+                               FINDPATH="$(eval echo "$VAONETRACKOUTPUTFORMAT")"
+                               else
+                               FINDPATH="$(eval echo "$ONETRACKOUTPUTFORMAT")"
+                       fi
+               fi
+
+       FINALDIR="$(dirname "$OUTPUTDIR/$FINDPATH")"
+       cd "$FINALDIR"
+
+# Instructions for each format, feel free to add more. It would be nice to
+# make the backup directory selectable and perhaps also have an option for
+# the bold to simply have the image deleted. Work for another day... Andrew.
+       if [ -e "$ALBUMARTFILE" ] ; then
+               case  "$OUTPUT" in
+                       mp3)
+                               for i in *.mp3
+                               do
+                               "$EYED3" --add-image "$ALBUMARTFILE":FRONT_COVER "$i"
+                               done
+                               mkdir "$FINALDIR"/albumart_backup
+                               mv "$ALBUMARTFILE" "$FINALDIR"/albumart_backup
+                               vecho "Successfully embedded the album art into your $OUTPUT tracks" >&2
+                       ;;
+                       flac)
+                               for i in *.flac
+                               do 
+                               "$METAFLAC" --import-picture-from="$ALBUMARTFILE" "$i"
+                               done
+                               mkdir "$FINALDIR"/albumart_backup
+                               mv "$ALBUMARTFILE" "$FINALDIR"/albumart_backup
+                               vecho "Successfully embedded the album art into your $OUTPUT tracks" >&2
+                       ;;
+                       m4a)
+                               for i in *.m4a
+                               do
+                               "$ATOMICPARSLEY" "$i" --artwork "$ALBUMARTFILE" --overWrite 
+                               done
+                               mkdir "$FINALDIR"/albumart_backup
+                               mv "$ALBUMARTFILE" "$FINALDIR"/albumart_backup
+                               vecho "Successfully embedded the album art into your $OUTPUT tracks" >&2
+                               ;;
+                       wv)
+                               for i in *.wv
+                               do
+                               "$WVTAG" --write-binary-tag "Cover Art (Front)=@$ALBUMARTFILE" "$i"
+                               done
+                               mkdir "$FINALDIR"/albumart_backup
+                               mv "$ALBUMARTFILE" "$FINALDIR"/albumart_backup
+                               vecho "Successfully embedded the album art into your $OUTPUT tracks" >&2
+                               ;;
+                       ogg)
+                       # ----------------
+                       # This technique is drawn from 2 sources (the first link being the primary source):
+                       #       1. https://github.com/biapy/howto.biapy.com/blob/master/various/mussync-tools
+                       #       2. https://github.com/acabal/scripts/blob/master/ogg-cover-art
+                       # In abcde a few steps are used in this sequence:
+                       #
+                       #       1. Create a 'legal' header for the cover art image
+                       #       2. Makes a copy of the existing tags
+                       #       3. base64 the cover art image
+                       #       4. Copy the original tags + the base64 image back to the original ogg file
+                       #
+                       # Might need some fine tuning but it is a start for abcde 2.8.2         Andrew.
+                       # FIXME: I am not sure if there is a maximum size for images converted in this
+                       # way, but this could be perhaps handled by CONVERTOPTS called from do_getalbumart.
+                       # ----------------
+                       # First some variables we can reuse:
+                       # Use MIMETYPECOVER to allow use of either png or the more common jpeg:
+                       MIMETYPECOVER=$(file -b --mime-type "$ALBUMARTFILE")
+                       EXPORTTAGS="${ABCDETEMPDIR}/export_ogg_tags"
+                       BUILDHEADER="${ABCDETEMPDIR}/build_header"
+                       # Now build the header, gory details are here:
+                       # https://xiph.org/flac/format.html#metadata_block_picture
+                               # Picture Type:
+                               printf "0: %.8x" 3 | xxd -r -g0 > "$BUILDHEADER"
+                               # Mime type length
+                               printf "0: %.8x" $(echo -n "$MIMETYPECOVER" | wc -c) | xxd -r -g0 >> "$BUILDHEADER"
+                               # Mime type:
+                               echo -n "$MIMETYPECOVER" >> "$BUILDHEADER"
+                               # Description length. FIXME: I have used 'Cover Image' but I am not sure
+                               # if this is better left as an empty field.      Andrew
+                               printf "0: %.8x" $(echo -n "Cover Image" | wc -c) | xxd -r -g0 >> "$BUILDHEADER"
+                               # Description:
+                               echo -n "Cover Image" >> "$BUILDHEADER"
+                               # Picture width:
+                               printf "0: %.8x" 0 | xxd -r -g0  >> "$BUILDHEADER"
+                               # Picture height:
+                               printf "0: %.8x" 0 | xxd -r -g0 >> "$BUILDHEADER"
+                               # Picture color depth:
+                               printf "0: %.8x" 0 | xxd -r -g0 >> "$BUILDHEADER"
+                               # Picture color count:
+                               printf "0: %.8x" 0 | xxd -r -g0 >> "$BUILDHEADER"
+                               # Image file size:
+                               printf "0: %.8x" $(wc -c "$ALBUMARTFILE" | cut --delimiter=' ' --fields=1) | xxd -r -g0 >> "$BUILDHEADER"
+                               # cat the image file:
+                               cat "$ALBUMARTFILE" >> "$BUILDHEADER"
+                       # Now process each ogg file by first exporting the original tags then
+                       # appending the cover image and finally copying the whole thing back
+                       # to the original image:
+                       for i in *.ogg
+                       do
+                               # Make a backup of the existing tags:
+                               "$VORBISCOMMENT" --list --raw "$i" > "EXPORTTAGS"
+                               # base64 the file and then mix it all together with the exported tags:
+                               echo "metadata_block_picture=$(base64 --wrap=0 < "$BUILDHEADER")" >> "EXPORTTAGS"
+                               # Update the original ogg file with exported tags and the appended base64'd image:
+                               "$VORBISCOMMENT" --write --raw --commentfile "EXPORTTAGS" "$i"
+                               # Delete the EXPORTTAGS file ready to be recreated for the next file in the loop,
+                               # note that the header file BUILDHEADER will be reused for each file in the loop:
+                               rm "EXPORTTAGS"
+                       done
+                       mkdir "$FINALDIR"/albumart_backup
+                       mv "$ALBUMARTFILE" "$FINALDIR"/albumart_backup
+                       vecho "Successfully embedded the album art into your $OUTPUT tracks" >&2
+                       ;;
+                       *) vecho "Sorry, abcde does not embed album art for the $OUTPUT container..." >&2
+               esac
+       else
+       vecho "Suitable cover image not found, no embedding done..." >&2
        fi
+done
 }
 
 # do_cdread [tracknumber]
@@ -3184,11 +3454,13 @@ do_cdread ()
                LASTTRACK=$(expr $3 + 0)
                UTRACKNUM=$FIRSTTRACK
                case "$CDROMREADERSYNTAX" in
-                       flac) READTRACKNUMS="$FIRSTTRACK.1-$(($LASTTRACK + 1)).0" ;;
+                       flac) READTRACKNUMS="-" ;;
                        cdparanoia|libcdio)
                                #XX FIXME XX
-                               # Add a variable to check if tracks are provided in command line and if not, use "0-" to rip the tracks
-                               READTRACKNUMS="$FIRSTTRACK-$LASTTRACK" ;;
+                               # Add a variable to check if tracks are provided in command line and if not, rip the whole CD
+                               # We must make sure to rip from sector 0, both lines below work
+                               # READTRACKNUMS="-- -$LASTTRACK" ;;
+                               READTRACKNUMS="[.0]-" ;;
                        cdda2wav | icedax) READTRACKNUMS="$FIRSTTRACK+$LASTTRACK" ;;
                        pird) READTRACKNUMS="$FIRSTTRACK..$LASTTRACK" ;;
                        *) echo "abcde error: $CDROMREADERSYNTAX does not support ONETRACK mode"
@@ -3197,14 +3469,13 @@ do_cdread ()
        else
                UTRACKNUM=$1
        fi
-       CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
+       CDDBTRACKNUM=$(expr $UTRACKNUM - 1) # Unpad
        if [ "$USEPIPES" = "y" ]; then
                TEMPARG="PIPERIPPER_$CDROMREADERSYNTAX"
                FILEARG="$( eval echo "\$$TEMPARG" )"
-               REDIR=""
                PIPE_MESSAGE="and encoding "
        else
-               WAVDATA="$ABCDETEMPDIR/track$UTRACKNUM.wav"
+               WAVDATA="${ABCDETEMPDIR}/track$UTRACKNUM.wav"
                case "$CDROMREADERSYNTAX" in
                ## FIXME ## Find the cases for flac, to avoid exceptions
                        flac)
@@ -3214,7 +3485,6 @@ do_cdread ()
                                FILEARG="$WAVDATA"
                                ;;
                esac
-               REDIR=">&2"
        fi
        if [ "$1" = "onetrack" ]; then
                echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2
@@ -3231,17 +3501,22 @@ do_cdread ()
                ### FIXME ### Shall we just use -o $FILEARG ??
                flac)
                        # Avoid problems with math expressions by unpadding the given UTRACKNUM
-                       STRIPTRACKNUM=$(expr $UTRACKNUM + 0)
-                       nice $READNICE $FLAC -d -f --cue=${READTRACKNUMS:-$STRIPTRACKNUM.1-$(($STRIPTRACKNUM + 1)).0} "$FILEARG" "$CDROM" ;;
+                       STRIPTRACKNUM=$(expr $UTRACKNUM + 0 )
+                       nice $READNICE $FLAC -d -f --cue="${READTRACKNUMS:-$STRIPTRACKNUM.1-$(($STRIPTRACKNUM + 1)).0}" "$FILEARG" "$CDROM" ;;
                cdparanoia|libcdio)
-                       nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR ;;
-               cdda2wav | icedax)
+                       if [ "$USEPIPES" = "y" ]; then
+                               nice $READNICE $CDROMREADER -"$CDPARANOIACDROMBUS" "$CDROM" "${READTRACKNUMS:-$UTRACKNUM}" "$FILEARG"
+                       else
+                               nice $READNICE $CDROMREADER -"$CDPARANOIACDROMBUS" "$CDROM" "${READTRACKNUMS:-$UTRACKNUM}" "$FILEARG" >&2
+                       fi
+                        ;;
+               cdda2wav|icedax)
                        if [ "$OSFLAVOUR" = "OSX" ] ; then
                                # Hei, we have to unmount the device before running anything like cdda2wav/icedax in OSX
-                               diskutil unmount ${CDROM#/dev/}
+                               diskutil unmount "${CDROM#/dev/}"
                                # Also, in OSX the cdrom device for cdda2wav/icedax changes...
                                CDDA2WAVCDROM="IODVDServices"
-                       elif [ "$OSFLAVOUR" = "FBSD" ] ; then
+                       elif [ "$OSFLAVOUR" = "FBSD" ] || [ "$OSFLAVOUR" = "IRIX" ]; then
                                CDDA2WAVCDROM="$CDROMID"
                        else
                                if [ "$CDROMID" = "" ]; then
@@ -3250,53 +3525,71 @@ do_cdread ()
                                        CDDA2WAVCDROM="$CDROMID"
                                fi
                        fi
-                       nice $READNICE $CDROMREADER -D $CDDA2WAVCDROM -t ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR ;;
-               dagrab) nice $READNICE $CDROMREADER -d "$CDROM" -f "$FILEARG" -v $UTRACKNUM >&2 ;;
+                       if [ "$USEPIPES" = "y" ]; then
+                               nice $READNICE $CDROMREADER -D "$CDDA2WAVCDROM" -t "${READTRACKNUMS:-$UTRACKNUM}" "$FILEARG"
+                       else
+                               nice $READNICE $CDROMREADER -D "$CDDA2WAVCDROM" -t "${READTRACKNUMS:-$UTRACKNUM}" "$FILEARG" >&2
+                       fi
+               ;;
+               dagrab)
+                                       # I cannot get USEPIPES to work with dagrab so just this:
+                               nice $READNICE $CDROMREADER -d "$CDROM" -f "$FILEARG" -v "$UTRACKNUM" >&2
+               ;;
                pird)
                        if [ "$USEPIPES" = "y" ]; then
-                               nice $READNICE $CDROMREADER -j ${READTRACKNUMS:-$UTRACKNUM} "$CDROM" "$FILEARG"
+                               nice $READNICE $CDROMREADER -j "${READTRACKNUMS:-$UTRACKNUM}" "$CDROM" "$FILEARG"
                        else
                                # Write ripped audio data to stdout and redirect to $FILEARG.
-                               # $REDIR can be ignored. Progress is written to stderr by default.
-                               nice $READNICE $CDROMREADER -j ${READTRACKNUMS:-$UTRACKNUM} "$CDROM" "$PIPERIPPER_pird" > "$FILEARG"
+                               # Progress is written to stderr by default and thus >&2 is not required.
+                               nice $READNICE $CDROMREADER -j "${READTRACKNUMS:-$UTRACKNUM}" "$CDROM" "$PIPERIPPER_pird" > "$FILEARG"
                        fi
-                       ;;
+               ;;
                cddafs)
                        # Find the track's mounted path
-                       REALTRACKNUM=$(expr $UTRACKNUM + 0)
+                       REALTRACKNUM=$(expr $UTRACKNUM + 0) # Unpad
                        FILEPATH=$(mount | grep "$CDROM on" | sed 's/^[^ ]* on \(.*\) (.*/\1/')
                        FILEPATH=$(find "$FILEPATH" | grep "/$REALTRACKNUM ");
                        # If the file exists, copy it
                        if [ -e "$FILEPATH" ] ; then
-                               nice $READNICE $CDROMREADER "$FILEPATH" "$FILEARG" $REDIR
+                               if [ "$USEPIPES" = "y" ]; then
+                                       nice $READNICE $CDROMREADER "$FILEPATH" "$FILEARG"
+                               else
+                               nice $READNICE $CDROMREADER "$FILEPATH" "$FILEARG" >&2
+                       fi
                        else
                                false
                        fi ;;
-               debug) nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -w $UTRACKNUM-[:1] "$FILEARG" $REDIR ;;
+               debug)
+                       if [ "$USEPIPES" = "y" ]; then
+                               nice $READNICE $CDROMREADER -"$CDPARANOIACDROMBUS" "$CDROM" -w "$UTRACKNUM-[:1]" "$FILEARG"
+                       else
+                               nice $READNICE $CDROMREADER -"$CDPARANOIACDROMBUS" "$CDROM" -w "$UTRACKNUM-[:1]" "$FILEARG" >&2
+                       fi
+               ;;
        esac
        RETURN=$?
        # If we get some error or we get some missing wav
        # (as long as we dont use pipes)
-       if [ "$RETURN" != "0" -o \( ! -s "$WAVDATA" -a X"$USEPIPES" != "Xy" \) ]; then
+       if [ "$RETURN" != "0" ] || ( [ ! -s "$WAVDATA" ] && [ X"$USEPIPES" != "Xy" ] ); then
                # Thank goodness errors is only machine-parseable up to the
                # first colon, otherwise this woulda sucked
-               if [ "$RETURN" = "0" -a ! -s "$WAVDATA" ]; then
+               if [ "$RETURN" = "0" ] || [ ! -s "$WAVDATA" ]; then
                        RETURN=73 # fake a return code as cdparanoia return 0 also on aborted reads
                fi
                if [ "$USEPIPES" = "y" ]; then
-                       echo "readencodetrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
+                       echo "readencodetrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "${ABCDETEMPDIR}/errors"
                else
-                       echo "readtrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
+                       echo "readtrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "${ABCDETEMPDIR}/errors"
                fi
                return $RETURN
        else
                if [ "$USEPIPES" = "y" ]; then
-                       echo readencodetrack-$UTRACKNUM >> "$ABCDETEMPDIR/status"
+                       echo "readencodetrack-$UTRACKNUM" >> "${ABCDETEMPDIR}/status"
                else
-                       echo readtrack-$UTRACKNUM >> "$ABCDETEMPDIR/status"
+                       echo "readtrack-$UTRACKNUM" >> "${ABCDETEMPDIR}/status"
                fi
                if [ "$1" = "onetrack" ]; then
-                       echo onetrack >> "$ABCDETEMPDIR/status"
+                       echo onetrack >> "${ABCDETEMPDIR}/status"
                fi
        fi
 }
@@ -3317,7 +3610,7 @@ do_cdspeed ()
 # vecho outputs a message if EXTRAVERBOSE is 1 or more
 vecho ()
 {
-if [ x"$EXTRAVERBOSE" != "x" ] && [ $EXTRAVERBOSE -gt 0 ] ; then
+if [ x"$EXTRAVERBOSE" != "x" ] && [ "$EXTRAVERBOSE" -gt 0 ] ; then
        case $1 in
                warning) shift ; log warning "$@" ;;
                *) >&4 echo "$@" ;;
@@ -3330,7 +3623,7 @@ fi
 # vvecho outputs a message if EXTRAVERBOSE is 2 or more
 vvecho ()
 {
-if [ x"$EXTRAVERBOSE" != "x" ] && [ $EXTRAVERBOSE -gt 1 ] ; then
+if [ x"$EXTRAVERBOSE" != "x" ] && [ "$EXTRAVERBOSE" -gt 1 ] ; then
        case $1 in
                warning) shift ; log warning "$@" ;;
                *) >&4 echo "$@" ;;
@@ -3344,9 +3637,9 @@ fi
 decho ()
 {
 if [ x"$DEBUG" != "x" ]; then
-       if echo $1 | grep "^\[" > /dev/null 2>&1 ; then
+       if echo "$1" | grep "^\[" > /dev/null 2>&1 ; then
                DEBUGECHO=$(echo "$@" | tr -d '[]')
-               echo >&4 "[DEBUG] $DEBUGECHO: `eval echo \\$${DEBUGECHO}`"
+               echo >&4 "[DEBUG] $DEBUGECHO: $(eval echo \\$${DEBUGECHO})"
        else
                echo >&4 "[DEBUG] $1"
        fi
@@ -3360,10 +3653,28 @@ mungefilename ()
        echo "$@" | sed -e 's/^\.*//' -e 's/ /_/g' | tr -d ":><|*/\"'?[:cntrl:]"
 }
 
+# Custom filename munging specific to track names:
+mungetrackname ()
+{
+       mungefilename "$@"
+}
+
+# Custom filename munging specific to artist names:
+mungeartistname ()
+{
+       mungefilename "$@"
+}
+
+# Custom filename munging specific to album names:
+mungealbumname ()
+{
+       mungefilename "$@"
+}
+
 # Custom genre munging:
 mungegenre ()
 {
-       echo $CDGENRE | tr "[:upper:]" "[:lower:]"
+       echo "$CDGENRE" | tr "[:upper:]" "[:lower:]"
 }
 
 # pre_read
@@ -3396,8 +3707,8 @@ post_encode ()
 # Builtin defaults
 
 # CDDB
-# Defaults to FreeDB, but musicbrainz can be used too, via the abcde-musicbrainz-tool script
-CDDBMETHOD=cddb
+# Currently three supported options ("musicbrainz", "cddb" for freedb.org and "cdtext")
+CDDBMETHOD=musicbrainz
 CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"
 CDDBSUBMIT=freedb-submit@freedb.org
 CDDBPROTO=6
@@ -3418,10 +3729,13 @@ ENCODERSYNTAX=default
 MP3ENCODERSYNTAX=default
 OGGENCODERSYNTAX=default
 OPUSENCODERSYNTAX=default
+MKAENCODERSYNTAX=default
+AIFFENCODERSYNTAX=default
 FLACENCODERSYNTAX=default
 SPEEXENCODERSYNTAX=default
 MPCENCODERSYNTAX=default
 WVENCODERSYNTAX=default
+TTAENCODERSYNTAX=default
 APENCODERSYNTAX=default
 MP2ENCODERSYNTAX=default
 AACENCODERSYNTAX=default
@@ -3483,6 +3797,9 @@ MPCENC=mpcenc
 # with abcde 2.7:
 WVENC=wavpack
 WAVPACK=wavpack
+# True Audio: 'tta' is the newer version, 'ttaenc' is the older version:
+TTA=tta
+TTAENC=ttaenc
 # ape
 APENC=mac
 APETAG=apetag
@@ -3504,25 +3821,27 @@ ID3=id3
 ID3V2=id3v2
 MID3V2=mid3v2
 EYED3=eyeD3
+ID3TAG=id3tag
 VORBISCOMMENT=vorbiscomment
 METAFLAC=metaflac
 NEROAACTAG=neroAacTag
 ATOMICPARSLEY=AtomicParsley
+WVTAG=wvtag
 
 WINE=wine
 CDPARANOIA=cdparanoia
-CD_PARANOIA=cd-paranoia
+CD_PARANOIA="cd-paranoia"
 CDDA2WAV=icedax
 DAGRAB=dagrab
 CDDAFS=cp
 PIRD=pird
-CDDISCID=cd-discid
+CDDISCID="cd-discid"
 CDDBTOOL=cddb-tool
 MUSICBRAINZ=abcde-musicbrainz-tool
 EJECT=eject
 MD5SUM=md5sum
 DISTMP3=distmp3
-NORMALIZE=normalize-audio
+NORMALIZE="normalize-audio"
 CDSPEED=eject
 VORBISGAIN=vorbisgain
 MP3GAIN=mp3gain
@@ -3541,7 +3860,13 @@ IDENTIFY=identify
 CONVERT=convert
 DISPLAYCMD=display
 
-# Options for programs called from abcde
+# Options for programs called from abcde:
+#
+# aiff
+# These options needed by FFmpeg for tagging and selection of id3v2 version:
+#  1. '-write_id3v2 1' allows id3v2 tagging while '-write_id3v2 0' disables tagging
+#  2. '-id3v2_version 4' gives version id3v2.4 while '3' gives id3v2.3 
+AIFFENCOPTS="-write_id3v2 1 -id3v2_version 4"
 # mp3
 LAMEOPTS=
 GOGOOPTS=
@@ -3568,6 +3893,8 @@ SPEEXENCOPTS=
 MPCENCOPTS=
 # wv
 WAVPACKENCOPTS=
+# True Audio has no useful options but it is here anyway :)
+TTAENCOPTS=
 # ape
 # Monkey's Audio Console (mac) chokes without a mode setting
 # so we set one here.
@@ -3585,6 +3912,7 @@ FHGAACENCOPTS=
 FFMPEGENCOPTS=
 
 ID3OPTS=
+ID3TAGOPTS=
 EYED3OPTS=""
 ATOMICPARSLEYOPTS=
 CDPARANOIAOPTS=
@@ -3621,7 +3949,7 @@ ACTIONS=cddb,read,encode,tag,move,clean
 
 # This option is basically for Debian package dependencies:
 # List of preferred outputs - by default, run with whatever we have in the path
-DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:lame,mp3:bladeenc,spx:speex,m4a:faac:opus
+DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:lame,mp3:bladeenc,spx:speex,m4a:fdkaac:opus
 
 # List of preferred cdromreaders - by default, run whichever we have in the path
 DEFAULT_CDROMREADERS="cdparanoia icedax cdda2wav libcdio pird"
@@ -3633,31 +3961,41 @@ exec 4>&1
 # Linux/OpenBSD. ftp is user for NetBSD.
 # Let's use these checkings to determine the OS flavour, which will be used
 # later
-if [ X$(uname) = "XFreeBSD" ] ; then
+UNAME="$(uname)"
+if [ X"$UNAME" = "XFreeBSD" ] ; then
        HTTPGET=fetch
        MD5SUM=md5
        NEEDCDROMID=y
        OSFLAVOUR=FBSD
-elif [ X$(uname) = "XDarwin" ] ; then
+elif [ X"$UNAME" = "XDarwin" ] ; then
        HTTPGET=curl
+       # By default md5sum is not installed, use md5 instead:
+       MD5SUM=md5
        OSFLAVOUR=OSX
        # We should have diskutil in OSX, but let's be sure...
        NEEDDISKUTIL=y
        CDROMREADERSYNTAX=cddafs
        # We won't find the eject program in OSX, and doing checkexec will fail further below...
        unset EJECT
-elif [ X$(uname) = "XOpenBSD" ] ; then
-       HTTPGET=wget
+elif [ X"$UNAME" = "XOpenBSD" ] ; then
+       HTTPGET=ftp
        MD5SUM=md5
        OSFLAVOUR=OBSD
-elif [ X$(uname) = "XNetBSD" ] ; then
+elif [ X"$UNAME" = "XNetBSD" ] ; then
        HTTPGET=ftp
        MD5SUM=md5
        OSFLAVOUR=NBSD
-elif [ X$(uname) = "SunOS" ] ; then
+elif [ X"$UNAME" = X"SunOS" ] ; then
        HTTPGET=""
        MD5SUM=md5
        OSFLAVOUR=SunOS
+elif [ X"$UNAME" = X"IRIX64" ] ; then
+       HTTPGET="wget"
+       OSFLAVOUR=IRIX
+       NEEDCDROMID=y
+       # Apparently necessary - see
+       # https://abcde.einval.com/bugzilla/show_bug.cgi?id=29
+       CDDISCID_NEEDS_PAUSE=y
 else
        HTTPGET=wget
 fi
@@ -3671,6 +4009,12 @@ CDDBAVAIL=y
 GREP_OPTIONS=""
 GREP_COLOR=""
 
+# Length of the terminal *should* be in $LINES. If it's not, guess at
+# a reasonable number instead
+if [ -z "$LINES" ]; then
+       LINES=24
+fi
+
 if [ -z "$OUTPUTDIR" ]; then
        OUTPUTDIR=$(pwd)
 fi
@@ -3684,8 +4028,8 @@ if [ -r /etc/abcde.conf ]; then
        . /etc/abcde.conf
 fi
 # Load user preference defaults
-if [ -r $HOME/.abcde.conf ]; then
-       . $HOME/.abcde.conf
+if [ -r "$HOME/.abcde.conf" ]; then
+       . "$HOME/.abcde.conf"
 fi
 
 # By this time, we need some HTTPGETOPTS already defined.
@@ -3694,7 +4038,7 @@ fi
 if [ "$HTTPGETOPTS" = "" ] ; then
        case $HTTPGET in
                wget) HTTPGETOPTS="-q -nv -e timestamping=off -O -";;
-               curl) HTTPGETOPTS="-f -s";;
+               curl) HTTPGETOPTS="-f -s -L";;
                fetch)HTTPGETOPTS="-q -o -";;
                ftp)  HTTPGETOPTS="-a -V -o - ";;
                *) log warning "HTTPGET in non-standard and HTTPGETOPTS are not defined." ;;
@@ -3735,14 +4079,21 @@ case "$EXTRAVERBOSE" in
 esac
 
 # Parse command line options
-while getopts 1a:bc:C:d:DefgGhj:klLmMnNo:pPr:s:S:t:T:UvVxX:w:W:z opt ; do
+while getopts 1a:bBc:C:d:DefgGhj:klLmMnNo:pPQ:r:s:S:t:T:UvVxX:w:W:z opt ; do
        case "$opt" in
                1) ONETRACK=y ;;
                a) ACTIONS="$OPTARG" ;;
                A) EXPACTIONS="$OPTARG" ;;
                b) BATCHNORM=y ;;
-               c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else log error "config file \"$OPTARG\" cannot be found." ; exit 1 ; fi ;;
-               C) DISCID="$( echo ${OPTARG#abcde.} | tr -d /)" ;;
+               B) GETALBUMART=y ; EMBEDALBUMART=y ;;
+               c) if [ -e "$OPTARG" ]; then
+                          . "$OPTARG"
+                  else
+                          log error "config file \"$OPTARG\" cannot be found."
+                          exit 1
+                  fi
+                  ;;
+               C) CDDBDISCID="$( echo "${OPTARG#abcde.}" | tr -d /)" ;;
                d) CDROM="$OPTARG" ;;
                D) set -x ;;
                h) usage; exit ;;
@@ -3763,6 +4114,7 @@ while getopts 1a:bc:C:d:DefgGhj:klLmMnNo:pPr:s:S:t:T:UvVxX:w:W:z opt ; do
                o) OUTPUTTYPE="$OPTARG" ;;
                p) PADTRACKS=y ;;
                P) USEPIPES=y ;;
+               Q) CDDBMETHOD="$OPTARG" ;;
                r) REMOTEHOSTS="$OPTARG" ;;
                R) CDDBLOCALRECURSIVE=y ;;
                s) SHOWCDDBFIELDS="$OPTARG" ;;
@@ -3780,8 +4132,8 @@ while getopts 1a:bc:C:d:DefgGhj:klLmMnNo:pPr:s:S:t:T:UvVxX:w:W:z opt ; do
                x) EJECTCD="y" ;;
                X) CUE2DISCID="$OPTARG" ;;
                w) COMMENT="$OPTARG" ;;
-               W) if echo $OPTARG | grep "[[:digit:]]" > /dev/null 2>&1 ; then
-                        STARTTRACKNUMBER="${OPTARG}$(printf %02d ${STARTTRACKNUMBER:-01})"
+               W) if echo "$OPTARG" | grep "[[:digit:]]" > /dev/null 2>&1 ; then
+                        STARTTRACKNUMBER="${OPTARG}$(printf "%02d" "${STARTTRACKNUMBER:-01}")"
                         STARTTRACKNUMBERTAG="y"
                         COMMENT="CD${OPTARG}"
                         DISCNUMBER="${OPTARG}"
@@ -3823,14 +4175,14 @@ if echo "$CDROM" | grep -i '.flac$' > /dev/null 2>&1 ; then
        EJECTCD=n
 fi
 
-# If the user provided a DISCID, disable eject
-if [ -n "$DISCID" ] || [ "$CDROMREADERSYNTAX" = "flac" ]; then EJECTCD=n ; fi
+# If the user provided a CDDBDISCID, disable eject
+if [ -n "${CDDBDISCID}" ] || [ "$CDROMREADERSYNTAX" = "flac" ]; then EJECTCD=n ; fi
 
 # Check the available cd rippers in the system, from the ones we know.
 if [ "$CDROMREADERSYNTAX" = "" ]; then
        for DEFAULT_CDROMREADER in $DEFAULT_CDROMREADERS; do
-               if new_checkexec $DEFAULT_CDROMREADER; then
-                       CDROMREADERSYNTAX=$DEFAULT_CDROMREADER
+               if new_checkexec "$DEFAULT_CDROMREADER"; then
+                       CDROMREADERSYNTAX="$DEFAULT_CDROMREADER"
                        break
                fi
        done
@@ -3875,7 +4227,7 @@ else
                else
                        RSTART=${1%%-*}
                        REND=${1##*-}
-                       while [ ${RSTART:=1} -le ${REND:=0} ] ; do
+                       while [ "${RSTART:=1}" -le "${REND:=0}" ] ; do
                                TRACKQUEUE="$TRACKQUEUE $RSTART"
                                RSTART=$(( $RSTART + 1 ))
                        done
@@ -3903,7 +4255,7 @@ DOCLEAN=n
 ## FIXME ## Lets keep compatibility with -M
 [ "$DOCUE" != "y" ] && DOCUE=n
 
-for ACTION in $(echo $ACTIONS | tr , \ )
+for ACTION in $(echo "$ACTIONS" | tr , \ )
 do
        case $ACTION in
                default) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOCLEAN=y;;
@@ -3920,6 +4272,7 @@ do
                playlist) DOCDDB=y; DOPLAYLIST=y;;
                clean) DOCLEAN=y;;
                getalbumart) GETALBUMART=y;;
+               embedalbumart) GETALBUMART=y; EMBEDALBUMART=y;;
        esac
 done
 
@@ -3928,7 +4281,7 @@ if [ "$DONORMALIZE" = "y" ] && [ "$DOREPLAYGAIN" = "y" ]; then
        log warning "selected both normalize and replaygain actions"
 fi
 
-for SHOWCDDBFIELD in $(echo $SHOWCDDBFIELDS | tr , \ ); do
+for SHOWCDDBFIELD in $(echo "$SHOWCDDBFIELDS" | tr , \ ); do
        case $SHOWCDDBFIELD in
                y*|Y*) SHOWCDDBYEAR="y";;
                g*|G*) SHOWCDDBGENRE="y";;
@@ -3938,15 +4291,20 @@ done
 
 # At this point a CDROM has to be defined, so we check it exists.
 if [ X"$CDROM" != "X" ] ; then
-       if ( [ "$CDROMREADERSYNTAX" = "cdda2wav" ] || [ "$CDROMREADERSYNTAX" = "icedax" ] ) && [ "$NEEDCDROMID" = "y" ] ; then
-               if [ "$OSFLAVOUR" = "FBSD" ]; then
-                       if echo "$CDROMID" | grep "^[0-9],[0-9],[0-9]$" >/dev/null 2>&1 ; then :; else
+       if [ "$NEEDCDROMID" = "y" ] ; then
+               if [ "$CDROMREADERSYNTAX" = "cdda2wav" ] || [ "$CDROMREADERSYNTAX" = "icedax" ]; then
+                       if [ "$OSFLAVOUR" = "IRIX" ]; then
+                               if [ -z "$CDROMID" ]; then
+                                       CDROMID="$(echo "$CDROM" | sed -e 's;/dev/scsi/sc\([0-9]*\)d\([0-9]*\)l\([0-9]*\)$;\1,\2,\3;')"
+                               fi
+                       fi
+                       if ! echo "$CDROMID" | grep "^[0-9],[0-9],[0-9]$" >/dev/null 2>&1 ; then
                                log error "CDROMID not in the right format for $CDROMREADERSYNTAX"
                                log error "Use \"cdrecord -scanbus\" to obtain an adequate ID and set CDROMID accordingly"
                                exit 1
                        fi
                fi
-       elif [ ! -e "$CDROM" -a X"$DOREAD" = "Xy" ]; then
+       elif [ ! -e "$CDROM" ] && [ X"$DOREAD" = "Xy" ]; then
                log error "CDROM device cannot be found."
                exit 1
        fi
@@ -3963,7 +4321,8 @@ fi
 # - lowdisk algorithm
 # - anything else?
 if [ X"$USEPIPES" = "Xy" ]; then
-       if [ $(echo "$OUTPUTTYPE" | tr , \  | wc -w ) -gt 1 ]; then
+       NUM_OUTPUT_TYPES="$(echo "$OUTPUTTYPE" | tr , \  | wc -w )"
+       if [ "$NUM_OUTPUT_TYPES" -gt 1 ]; then
                log error "Unix pipes not compatible with multiple outputs"
                exit 1
        fi
@@ -4015,9 +4374,9 @@ fi
 # Check the encoding format from the ones available in the system, if nothing has been configured.
 if [ X"$OUTPUTTYPE" = "X" ]; then
        for DEFAULT_OUTPUT in $( echo "$DEFAULT_OUTPUT_BINARIES" | tr , \ ); do
-               DEFAULT_OUTPUT_FORMAT="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 1)"
-               DEFAULT_OUTPUT_BINARY="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 2)"
-               if [ -x $(which $DEFAULT_OUTPUT_BINARY) ] ; then
+               DEFAULT_OUTPUT_FORMAT="$(echo "$DEFAULT_OUTPUT" | cut -d ":" -f 1)"
+               DEFAULT_OUTPUT_BINARY="$(echo "$DEFAULT_OUTPUT" | cut -d ":" -f 2)"
+               if [ -x "$(which "$DEFAULT_OUTPUT_BINARY")" ] ; then
                        OUTPUTTYPE=$DEFAULT_OUTPUT_FORMAT
                        vecho "No default output type defined. Autoselecting $OUTPUTTYPE..." >&2
                        break
@@ -4079,11 +4438,14 @@ case "$OUTPUTTYPE" in *:*)
                case "$OUTPUT" in
                        vorbis:*|ogg:*) OGGENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
                        opus:*) OPUSENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
+                       mka:*)  MKAENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
+                       aiff:*) AIFFENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
                        mp3:*)  MP3ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
                        flac:*) FLACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
                        spx:*)  SPEEXENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
                        mpc:*)  MPCENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
                        wv:*)   WVENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
+                       tta:*)  TTAENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
                        ape:*)  APENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
                        mp2:*)  MP2ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
                        m4a:*|aac:*)  AACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
@@ -4100,11 +4462,11 @@ case "$OUTPUTTYPE" in *:*)
 esac
 
 # If nothing has been specified, use oggenc for oggs and lame for mp3s and flac
-# for flacs and speexenc for speex and mpcenc for mpcs and faac for m4as and
+# for flacs and speexenc for speex and mpcenc for mpcs and fdkaac for m4as and
 # wavpack for wvs...
 
 # Getting ready for multiple output changes
-for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
+for OUTPUT in $(echo "$OUTPUTTYPE" | tr , \ )
 do
        case $OUTPUT in
                vorbis|ogg)
@@ -4117,16 +4479,26 @@ do
                        [ "$OPUSENCODERSYNTAX" = "default" ] && OPUSENCODERSYNTAX=opusenc
                        OPUSOUTPUTCONTAINER=opus
                        ;;
+               mka)
+                       [ "$MKAENCODERSYNTAX" = "default" ] && MKAENCODERSYNTAX=ffmpeg
+                       MKAOUTPUTCONTAINER=mka
+                       ;;
+               aiff)
+                       [ "$AIFFENCODERSYNTAX" = "default" ] && AIFFENCODERSYNTAX=ffmpeg
+                       AIFFOUTPUTCONTAINER=aiff
+                       ;;
                mp3)
                        [ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame
                        [ "$DOTAG" = "y" ] && NEEDTAGGER=y
                        [ "$DOREPLAYGAIN" = "y" ] && NEEDMP3GAIN=y
+                       [ "$EMBEDALBUMART" = "y" ] && NEEDEYED3=y
                        ;;
                flac)
                        [ "$FLACENCODERSYNTAX" = "default" ] && FLACENCODERSYNTAX=flac
                        [ "$DOTAG" = "y" ] && NEEDMETAFLAC=y
                        [ "$DOREPLAYGAIN" = "y" ] && NEEDMETAFLAC=y
                        [ "$ONETRACK" = "y" ] && [ "$DOCUE" = "y" ] && NEEDMETAFLAC=y
+                       [ "$EMBEDALBUMART" = "y" ] && NEEDMETAFLAC=y
                        ;;
                spx)
                        [ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc
@@ -4141,6 +4513,7 @@ do
                        [ "$DOTAG" = "y" ]
                        [ "$DOREPLAYGAIN" = "y" ] && NEEDWVGAIN=y
                        [ "$WVENCODERSYNTAX" = "ffmpeg" ] && DOREPLAYGAIN=n
+                       [ "$EMBEDALBUMART" = "y" ] && NEEDWVTAG=y
                        ;;
                ape)
                        [ "$APENCODERSYNTAX" = "default" ] && APENCODERSYNTAX=mac
@@ -4149,6 +4522,12 @@ do
                mp2)
                        [ "$MP2ENCODERSYNTAX" = "default" ] && MP2ENCODERSYNTAX=twolame
                        [ "$DOTAG" = "y" ] && NEEDMID3V2=y
+                       [ "$MP2ENCODERSYNTAX" = "ffmpeg" ] && [ "$DOTAG" = "y" ]  && NEEDMID3V2=y
+                       ;;
+               tta)
+                       [ "$TTAENCODERSYNTAX" = "default" ] && TTAENCODERSYNTAX=tta
+                       [ "$DOTAG" = "y" ] && NEEDMID3V2=y
+                       [ "$TTAENCODERSYNTAX" = "ttaenc" ] && [ "$DOTAG" = "y" ] && NEEDMID3V2=y
                        ;;
                aac)
                        [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac
@@ -4157,12 +4536,13 @@ do
                # compiled without libmp4v2... Andrew.
                        ;;
                m4a)
-                       [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac
-                       [ "$DOTAG" = "y" ] && CHECKFAACBUILD=y
+                       [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=fdkaac
+                       [ "$AACENCODERSYNTAX" = "faac" ] && [ "$DOTAG" = "y" ] && CHECKFAACBUILD=y      
                        [ "$AACENCODERSYNTAX" = "neroAacEnc" ] && NEEDNEROAACTAG=y
                        [ "$AACENCODERSYNTAX" = "qaac" ] && NEEDWINE=y
                        [ "$AACENCODERSYNTAX" = "fhgaacenc" ] && NEEDWINE=y && NEEDATOMICPARSLEY=y
-                       [ "$AACENCODERSYNTAX" = "ffmpeg" ] &&  [ "$DOTAG" = "y" ]
+                       [ "$AACENCODERSYNTAX" = "ffmpeg" ] && [ "$DOTAG" = "y" ]
+                       [ "$EMBEDALBUMART" = "y" ] && NEEDATOMICPARSLEY=y
                        ;;
                wav)
                        if [ "$KEEPWAVS" = "y" ]; then
@@ -4219,6 +4599,18 @@ case "$OPUSENCODERSYNTAX" in
                OPUSENCODER="$OPUSENC"
                ;;
 esac
+case "$MKAENCODERSYNTAX" in
+       ffmpeg)
+               MKAENCODEROPTS="${MKAENCODEROPTSCLI:-$FFMPEGENCOPTS}"
+               MKAENCODER="$FFMPEG"
+               ;;
+esac
+case "$AIFFENCODERSYNTAX" in
+       ffmpeg)
+               AIFFENCODEROPTS="${AIFFENCODEROPTSCLI:-$AIFFENCOPTS}"
+               AIFFENCODER="$FFMPEG"
+               ;;
+esac
 case "$FLACENCODERSYNTAX" in
        flac)
                FLACENCODEROPTS="${FLACENCODEROPTSCLI:-$FLACOPTS}"
@@ -4266,6 +4658,16 @@ case "$WVENCODERSYNTAX" in
                WVENCODER="$FFMPEG"
                ;;
 esac
+case "$TTAENCODERSYNTAX" in
+       tta)
+               TTAENCODEROPTS="${TTAENCODEROPTSCLI:-$TTAENCOPTS}"
+               TTAENCODER="$TTA"
+               ;;
+       ttaenc)
+               TTAENCODEROPTS="${TTAENCODEROPTSCLI:-$TTAENCOPTS}"
+               TTAENCODER="$TTAENC"
+               ;;
+esac
 case "$APENCODERSYNTAX" in
        mac)
                APENCODEROPTS="${APENCODEROPTSCLI:-$APENCOPTS}"
@@ -4277,6 +4679,10 @@ case "$MP2ENCODERSYNTAX" in
                MP2ENCODEROPTS="${MP2ENCODEROPTSCLI:-$TWOLAMENCOPTS}"
                MP2ENCODER="$TWOLAME"
                ;;
+       ffmpeg)
+               MP2ENCODEROPTS="${MP2ENCODEROPTSCLI:-$FFMPEGENCOPTS}"
+               MP2ENCODER="$FFMPEG"
+               ;;
 esac
 case "$AACENCODERSYNTAX" in
                # Some elaborate 'if' work to keep backward compatibility for those
@@ -4350,6 +4756,11 @@ case "$ID3TAGV" in
                ID3SYNTAX=id3v2
                TAGGEROPTS="$ID3V2OPTS"
                ;;
+       id3tag)
+               TAGGER="$ID3TAG"
+               ID3SYNTAX=id3tag
+               TAGGEROPTS="$ID3TAGOPTS"
+               ;;
        id3v2.4)
                TAGGER="$EYED3"
                # Note that eyeD3 is set to tag in utf-16 (below). This causes
@@ -4388,6 +4799,10 @@ case "$CUEREADERSYNTAX" in
                CUEREADEROPTS="${CDROM}"
                CUEREADER="$MKCUE"
                ;;
+       abcde.mkcue)
+               CUEREADEROPTS="$MKCUEOPTS ${CDROM}"
+               CUEREADER="$MKCUE"
+               ;;
 esac
 
 # which information retrieval tool are we using?
@@ -4403,7 +4818,8 @@ if [ X"$OGGOUTPUTCONTAINER" = "Xogg" ] && [ X"$FLACOUTPUTCONTAINER" = "Xogg" ];
        exit 1
        OGGOUTPUTCONTAINER=ogg.ogg
        FLACOUTPUTCONTAINER=flac.ogg
-       vecho warning "modified file endings due to conflicting transport layers in Ogg/Vorbis and Ogg/FLAC"
+       vecho warning "modified file endings due to conflicting transport"
+       vecho warning "layers in Ogg/Vorbis and Ogg/FLAC"
 fi
 
 # Clean up nice options (either use '-n NICELEVEL or -NICELEVEL')
@@ -4429,11 +4845,11 @@ if [ "$EJECTCD" = "y" ]; then
        NEEDEJECT=y
 fi
 if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then
-       if [ "$CDDBMETHOD" = "cddb" ]; then
-               NEEDHTTPGET=y
-       elif [ "$CDDBMETHOD" = "musicbrainz" ]; then
-               :
-       fi
+       # Need an http tool to be able to do CDDB
+       case $CDDBMETHOD in
+               *cddb*)
+                       NEEDHTTPGET=y;;
+       esac
 fi
 if [ "$DOCUE" = "y" ]; then
        NEEDCUEREADER=y
@@ -4479,6 +4895,8 @@ PIPE_faac="-"
 PIPE_qaac="-"
 PIPE_fhgaacenc="-"
 PIPE_ffmpeg="-"
+PIPE_tta="-"
+PIPE_ttaenc="-"
 # Both neroAacEnc and fdkaac seem to manage without the addition of
 # the 'ignorelength' option in PIPE_$AACENCODERSYNTAX when piping
 # in this manner.                                           Andrew.
@@ -4496,6 +4914,10 @@ if [ "$USEPIPES" = "y" ]; then
                        PIPEENCODERSVARCHECK="PIPE_$OGGENCODERSYNTAX" ;;
                opus)
                        PIPEENCODERSVARCHECK="PIPE_$OPUSENCODERSYNTAX" ;;
+               mka)
+                       PIPEENCODERSVARCHECK="PIPE_$MKAENCODERSYNTAX" ;;
+               aiff)
+                       PIPEENCODERSVARCHECK="PIPE_$AIFFENCODERSYNTAX" ;;
                flac)
                        PIPEENCODERSVARCHECK="PIPE_$FLACENCODERSYNTAX" ;;
                spx)
@@ -4504,6 +4926,8 @@ if [ "$USEPIPES" = "y" ]; then
                        PIPEENCODERSVARCHECK="PIPE_$MPCENCODERSYNTAX" ;;
                wv)
                        PIPEENCODERSVARCHECK="PIPE_$WVENCODERSYNTAX" ;;
+               tta)
+                       PIPEENCODERSVARCHECK="PIPE_$TTAENCODERSYNTAX" ;;
                m4a)
                        PIPEENCODERSVARCHECK="PIPE_$AACENCODERSYNTAX" ;;
                aac)
@@ -4527,8 +4951,8 @@ fi
 
 # Make sure a buncha things exist
 for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
-       $OGGENCODER $OPUSENCODER $FLACENCODER $SPEEXENCODER $MPCENCODER \
-       $AACENCODER $WVENCODER $CDDBTOOL $APENCODER $MP2ENCODER \
+       $OGGENCODER $OPUSENCODER $MKAENCODER $FLACENCODER $SPEEXENCODER $MPCENCODER \
+       $AACENCODER $WVENCODER $CDDBTOOL $APENCODER $MP2ENCODER $TTAENCODER $AIFFENCODER \
        ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \
        ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
        ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
@@ -4538,7 +4962,7 @@ for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
        ${NEEDWVGAIN+WVGAIN} ${NEEDAPETAG+$APETAG} \
        ${NEEDCUE2DISCID+$CUE2DISCID} ${NEEDNEROAACTAG+$NEROAACTAG} \
        ${NEEDGLYRC+$GLYRC} ${NEEDWINE+$WINE} ${NEEDATOMICPARSLEY+$ATOMICPARSLEY} \
-       ${NEEDMID3V2+$MID3V2}
+       ${NEEDMID3V2+$MID3V2} ${NEEDEYED3+$EYED3} ${NEEDWVTAG+$WVTAG}
 do
        checkexec "$X"
 done
@@ -4554,7 +4978,8 @@ if [ "$CHECKFAACBUILD" = "y" ] && [ "$AACENCODERSYNTAX" = "faac" ] ; then
        if faac --help 2>&1 | grep -q -F 'MP4 support unavailable.'; then 
                echo "WARNING: Your copy of Faac does not have mp4 support"
                echo "WARNING: Encoding untagged files to aac..."
-               OUTPUTTYPE=aac
+               # Replace m4a with aac for single and multi-output encodes:
+               OUTPUTTYPE=$(echo "$OUTPUTTYPE" | sed 's/m4a/aac/')
        else
                echo "Using Faac to Tag AAC Tracks..."
        fi
@@ -4562,7 +4987,7 @@ fi
 
 # And last but not least, check if we can diff between files. We do not abort,
 # since diffing is not critical...
-if [ -x $(which $DIFF) ]; then :; else
+if [ -x "$(which "$DIFF")" ]; then :; else
        vecho warning "Disabling diff since we cannot find it in the \$PATH..."
        DIFF=""
 fi
@@ -4570,8 +4995,8 @@ fi
 ## Now that we have metaflac, check if we need cue2discid
 #case $CDROMREADERSYNTAX in
 #      flac)
-#              TRACKINFO=$($METAFLAC --show-tag=CDDB $CDROM | cut -d"=" -f2 | grep -E "[a-f0-9]{8}")
-#              if [ "$TRACKINFO" = "" ]; then
+#              CDDBTRACKINFO=$($METAFLAC --show-tag=CDDB $CDROM | cut -d"=" -f2 | grep -E "[a-f0-9]{8}")
+#              if [ "$CDDBTRACKINFO" = "" ]; then
 #                      checkexec ${NEEDCUE2DISCID+$CUE2DISCID}
 #              fi
 #              ;;
@@ -4584,10 +5009,22 @@ HTTPGET="$HTTPGET $HTTPGETOPTS"
 # Here it used to say:
 # One thousand lines in, we can start doing stuff with things
 # Well, right now we are at line 3737 ;)
+# Hey, for grins, as of 2016-08-30 this is now line 4814! -GR
 
 # Export needed things so they can be read in this subshell
-export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS
-export CDROM CDDBDATA REMOTEHOSTS MAXPROCS HTTPGET MD5SUM
+export CDDBTOOL        # Path and options for the tool to query CDDB
+export ABCDETEMPDIR    # Path to the tmpdir for this rip
+export TRACKQUEUE      # 0-padded list of tracks to be processed
+export LOWDISK         # Are we using the low-diskspace algorithm?
+export EJECTCD         # Should we eject the CD when we're finished ripping?
+export EJECT           # The commend to use to eject the CD, if we have one
+export EJECTOPTS       # Options to that command
+export CDROM           # Device path for the CD device
+export CDDBDATA        # The filename we're using for CD lookup data
+export REMOTEHOSTS     # List of remote hosts for parallel encoding, if given
+export MAXPROCS        # The number of *local* encodes to do in parallel
+export HTTPGET         # Program to use to grab files via http
+export MD5SUM          # Program to calculate MD5 checksums
 
 if [ "$DOREAD" = "y" ]; then
        # User-definable function to set some things. Use it for
@@ -4607,29 +5044,93 @@ if [ "$DOCDDB" = "y" ]; then
        # start with a sane default:
        CDDBLOCALSTATUS=notfound
        if [ $CDDBUSELOCAL = "y" ]; then
-               do_localcddb
+               do_localcddb_read
        fi
        if checkstatus cddb-choice > /dev/null; then
                :
        else
+               NUM_CDDB_MATCHES=0
                if [ "$CDDBLOCALSTATUS" = "notfound" ] ; then
-                       case "$CDDBMETHOD" in
+                       idx=0
+                       for CDDBMETHCHOICE in $(echo "$CDDBMETHOD"  | tr -d '    ' | tr , ' ')
+                       do
+                               addstatus "Lookup method $idx: $CDDBMETHCHOICE"
+                               idx=$(($idx + 1))
+                               vecho "Found $NUM_CDDB_MATCHES matches so far"
+                               vecho "Trying lookup method ${CDDBMETHCHOICE}"
+
+                               # Run all the desired data acquisition methods, in the order
+                               # specified by the user. Each will use its own temporary
+                               # subdirectory, then copy the cddbread.* etc. files up into
+                               # ${ABCDETEMPDIR}
+                               case "$CDDBMETHCHOICE" in
                                cddb)
-                                       do_cddbstat
-                                       do_cddbquery
-                                       do_cddbread
+                                       do_cddb_read
                                        ;;
                                musicbrainz)
-                                       do_musicbrainz
+                                       do_musicbrainz_read
                                        ;;
-                       esac
-               fi
-               CHOICE=$(checkstatus cddb-choice)
-               if [ "$CHOICE" = 0 ] ; then
-                       # We don't have any information at all; try to fall back
-                       # to CD-Text for basic information
-                       vecho "No CDDB information found, trying cdtext from the CD"
-                       do_cdtext
+                               cdtext)
+                                       do_cdtext_read
+                                       ;;
+                               *)
+                                       echo "Unknown lookup method $CDDBMETHCHOICE. Aborting." >&2
+                                       exit 1
+                                       ;;
+                               esac
+
+                       done
+
+                       rm -f "${ABCDETEMPDIR}/cddbchoices"
+                       CDDBDISCID=$(echo "$CDDBTRACKINFO" | cut -d' ' -f1)
+
+                       if [ $NUM_CDDB_MATCHES = 0 ]; then
+                               # If we got no matches, we need to
+                               # generate a blank CDDB template.
+                               vecho "Unable to find any matches, generating unknown template."
+                               echo "No lookup matches." >> "${ABCDETEMPDIR}/cddbchoices"
+                               $CDDBTOOL template $(cat "${ABCDETEMPDIR}/cddbdiscid") > "${ABCDETEMPDIR}/cddbread.0"
+                               echo "template" > "${ABCDETEMPDIR}/datasource.0"
+                               # List out disc title/author and contents of template
+                               echo ---- Unknown Artist / Unknown Album ---- >> "${ABCDETEMPDIR}/cddbchoices"
+                               UNKNOWNDISK=y
+                               for TRACK in $(f_seq_row 1 $TRACKS)
+                               do
+                                       echo "$TRACK:" "$(grep -a ^TTITLE$(($TRACK - 1))= "${ABCDETEMPDIR}/cddbread.0" | cut -f2- -d= | tr -d \\r\\n)" >> "${ABCDETEMPDIR}/cddbchoices"
+                               done
+                               echo >> "${ABCDETEMPDIR}/cddbchoices"
+                               echo cddb-read-0-complete >> "${ABCDETEMPDIR}/status"
+                               echo cddb-choice=0 >> "${ABCDETEMPDIR}/status"
+                               echo 503 > "${ABCDETEMPDIR}/cddbquery"
+                       else
+                               # We have matches; create the cddbchoices and cddbquery
+                               # files from all the inputs we have
+                               if [ $NUM_CDDB_MATCHES = 1 ]; then
+                                       echo "Retrieved 1 match..." >> "${ABCDETEMPDIR}/cddbchoices"
+                                       echo -n "200 " > "${ABCDETEMPDIR}/cddbquery"
+                                       cat "${ABCDETEMPDIR}/cddbquery.1" >> "${ABCDETEMPDIR}/cddbquery"
+                               else
+                                       echo "Retrieved $NUM_CDDB_MATCHES matches..." >> "${ABCDETEMPDIR}/cddbchoices"
+                                       echo "210 Found exact matches, list follows (until terminating .)" > "${ABCDETEMPDIR}/cddbquery"
+                                       for X in $(f_seq_row 1 $NUM_CDDB_MATCHES)
+                                       do
+                                               cat "${ABCDETEMPDIR}/cddbquery.$X" >> "${ABCDETEMPDIR}/cddbquery"
+                                       done
+                                       echo "." >> "${ABCDETEMPDIR}/cddbquery"
+                               fi
+
+                               for X in $(f_seq_row 1 $NUM_CDDB_MATCHES)
+                               do
+                                       ATITLE=$(grep -a -e '^DTITLE=' "${ABCDETEMPDIR}/cddbread.$X" | cut -c8- | tr -d \\r\\n)
+                                       SOURCE=$(cat "${ABCDETEMPDIR}/datasource.$X")
+                                       echo "#$X ($SOURCE): ---- ${ATITLE} ----" >> "${ABCDETEMPDIR}/cddbchoices"
+                    for TRACK in $(f_seq_row 1 $TRACKS)
+                                       do
+                        echo "$TRACK:" "$(grep -a ^TTITLE$(($TRACK - 1))= "${ABCDETEMPDIR}/cddbread.$X" | cut -f2- -d= | tr -d \\r\\n)" >> "${ABCDETEMPDIR}/cddbchoices"
+                                       done
+                    echo >> "${ABCDETEMPDIR}/cddbchoices"
+                               done
+                       fi
                fi
        fi
        do_cddbedit
@@ -4652,10 +5153,10 @@ fi
 FIRSTTRACK=$( get_first $TRACKQUEUE )
 LASTTRACK=$( get_last $TRACKQUEUE )
 
-if [ -f "$ABCDETEMPDIR/status" ] && [ X"$ERASEENCODEDSTATUS" = "Xy" ]; then
-       mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
-       grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
-               | grep -v ^encode-output > "$ABCDETEMPDIR/status"
+if [ -f "${ABCDETEMPDIR}/status" ] && [ X"$ERASEENCODEDSTATUS" = "Xy" ]; then
+       mv "${ABCDETEMPDIR}/status" "${ABCDETEMPDIR}/status.old"
+       grep -v ^encodetracklocation- < "${ABCDETEMPDIR}/status.old" \
+               | grep -v ^encode-output > "${ABCDETEMPDIR}/status"
 fi
 
 if checkstatus onetrack ; then ONETRACK=y ; fi
@@ -4685,17 +5186,17 @@ fi
 # For the lowdisk option, only one program is running at once so the encoder
 # can be unsilenced right away.
 if [ "$LOWDISK" = "y" ] || [ "$ONETRACK" = "y" ]; then
-       echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
+       echo "encode-output=loud" >> "${ABCDETEMPDIR}/status"
 fi
 
 if [ "$ONETRACK" = "y" ]; then
-       TRACKS="$FIRSTTRACK"
+       TRACKS=$FIRSTTRACK
        if [ "$USEPIPES" = "y" ]; then
-               if checkstatus readencodetrack-$FIRSTTRACK; then :; else
+               if checkstatus "readencodetrack-$FIRSTTRACK"; then :; else
                        do_cdread onetrack $FIRSTTRACK $LASTTRACK | do_encode $FIRSTTRACK %local0% > /dev/null 2>&1
                fi
        else
-               if checkstatus readtrack-$FIRSTTRACK; then :; else
+               if checkstatus "readtrack-$FIRSTTRACK"; then :; else
                        do_cdread onetrack $FIRSTTRACK $LASTTRACK
                fi
        fi
@@ -4704,12 +5205,12 @@ else
        do
                if [ "$DOREAD" = "y" ]; then
                        if [ "$USEPIPES" = "y" ]; then
-                               if checkstatus readencodetrack-$UTRACKNUM; then :; else
+                               if checkstatus "readencodetrack-$UTRACKNUM"; then :; else
                                        # Read, pipe, shut up!
                                        do_cdread $UTRACKNUM | do_encode $UTRACKNUM %local0% > /dev/null 2>&1
                                fi
                        else
-                               if checkstatus readtrack-$UTRACKNUM; then :; else
+                               if checkstatus "readtrack-$UTRACKNUM"; then :; else
                                        do_cdread $UTRACKNUM
                                fi
                                if [ "$?" != "0" ]; then
@@ -4726,14 +5227,14 @@ else
                        # If we are not reading, set the encode output to loud already, so
                        # that we can see the output of the first track.
                        if [ "$MAXPROCS" = "1" ] && [ ! "$DOREAD" = "y" ]; then
-                               echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
+                               echo "encode-output=loud" >> "${ABCDETEMPDIR}/status"
                        fi
                        echo NEXTTRACK # Get the encoder machine churning again
                        if [ "$DOREAD" = "y" ]; then
                                if [ "$LOWDISK" = "y" ] && [ "$DOENCODE" = "y" ]; then
-                                       until checkstatus encodetrack-$UTRACKNUM
+                                       until checkstatus "encodetrack-$UTRACKNUM"
                                        do
-                                               if checkerrors encodetrack-$UTRACKNUM; then
+                                               if checkerrors "encodetrack-$UTRACKNUM"; then
                                                        break
                                                fi
                                                sleep 2
@@ -4747,7 +5248,7 @@ fi
 # Now that we're done the encoding can be loud again -
 # if we're not using SMP.
 if [ "$MAXPROCS" = "1" ]; then
-       echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
+       echo "encode-output=loud" >> "${ABCDETEMPDIR}/status"
 fi
 
 # All tracks read, start encoding.
@@ -4765,19 +5266,19 @@ if [ "$EJECTCD" = "y" ]; then
        # CD tray. If not, we do not eject the CD, since it might be so that the
        # user ejected it manually.
        #CURRENTTRACKINFO=$($CDDISCID $CDROM)
-       #if if [ "$?" != "1" ] && [ "$CURRENTTRACKINFO" = "$TRACKINFO" ] ; then
+       #if if [ "$?" != "1" ] && [ "$CURRENTTRACKINFO" = "$CDDBTRACKINFO" ] ; then
        # More FreeBSD bits.
-       if [ X"$(uname)" = X"FreeBSD" ] ; then
+       if [ X"$UNAME" = X"FreeBSD" ] ; then
                # FreeBSD eject uses the EJECT environment variable to name the CDROM
                # but in this script EJECT is in the envionment and names the program
                eject=$EJECT
                unset EJECT
                # The FreeBSD eject needs "adc0" not "/dev/adc0c"
-               cd="$(echo $CDROM | sed -e 's=.*/==;s=[a-h]$==;')"
+               cd="$(echo "$CDROM" | sed -e 's=.*/==;s=[a-h]$==;')"
                $eject $EJECTOPTS $cd
-       elif [ X"$(uname)" = X"Darwin" ] ; then
-               diskutil eject ${CDROM#/dev/} 0
-       elif [ -x $(which $EJECT) ]; then
+       elif [ X"$UNAME" = X"Darwin" ] ; then
+               diskutil eject "${CDROM#/dev/}" 0
+       elif [ -x "$(which "$EJECT")" ]; then
                $EJECT $EJECTOPTS "$CDROM"
        fi
        #fi
@@ -4796,7 +5297,7 @@ fi
 #              PREPROCEED=
 #              until [ $PREPROCEED ]
 #              do
-#                      if checkstatus readtrack-$PRETRACKNUM; then PREPROCEED=y; break; fi
+#                      if checkstatus "readtrack-$PRETRACKNUM"; then PREPROCEED=y; break; fi
 #                      # all locations are working, wait and try again later
 #                      if [ ! $PREPROCEED ]; then sleep 3; fi
 #              done
@@ -4812,24 +5313,25 @@ fi
 #BACK
 if [ "$BATCHNORM" = "y" ] || [ "$NOGAP" = "y" ]; then
        read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
-       if [ "$GOAHEAD" = "NO" ]; then break; fi
-       for LASTTRACK in $TRACKQUEUE; do :; done
-       if checkstatus readtrack-$LASTTRACK; then
-               if [ "$DONORMALIZE" = "y" ] && [ "$BATCHNORM" = "y" ]; then
-                       if checkstatus normalizetrack-$LASTTRACK; then :; else do_batch_normalize; fi
-                       if checkerrors batch-normalize; then exit 1; fi
-               fi
-               if [ "$DOENCODE" = "y" ] && [ "$NOGAP" = "y" ]; then
-                       if [ "$DONORMALIZE" = "y" ]; then
-                               for UTRACKNUM in $TRACKQUEUE
-                               do
-                                       if checkstatus readtrack-$UTRACKNUM; then
-                                               if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
-                                       fi
-                               done
+       if [ "$GOAHEAD" != "NO" ]; then
+               for LASTTRACK in $TRACKQUEUE; do :; done
+               if checkstatus "readtrack-$LASTTRACK"; then
+                       if [ "$DONORMALIZE" = "y" ] && [ "$BATCHNORM" = "y" ]; then
+                               if checkstatus "normalizetrack-$LASTTRACK"; then :; else do_batch_normalize; fi
+                               if checkerrors batch-normalize; then exit 1; fi
+                       fi
+                       if [ "$DOENCODE" = "y" ] && [ "$NOGAP" = "y" ]; then
+                               if [ "$DONORMALIZE" = "y" ]; then
+                                       for UTRACKNUM in $TRACKQUEUE
+                                       do
+                                               if checkstatus "readtrack-$UTRACKNUM"; then
+                                                       if checkstatus "normalizetrack-$UTRACKNUM"; then :; else do_normalize "$UTRACKNUM"; fi
+                                               fi
+                &nbs