Don't discard all previous cddbdata if a sed on cd-text data errors out
[abcde.git] / abcde
diff --git a/abcde b/abcde
index d64436c..080ed24 100755 (executable)
--- a/abcde
+++ b/abcde
@@ -2,18 +2,16 @@
 # 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) 2012-     Steve McIntyre <93sam@@debian.org>
+# Copyright (c) 2015-     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.
 #
 # You should have received a copy of the GNU General Public License along
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-# Copyright for this work is to expire January 1, 2010, after which it
-# shall be public domain.
 
-VERSION='2.6.1-UNRELEASED'
+VERSION='2.7.2-UNRELEASED'
 
 usage ()
 {
@@ -23,7 +21,7 @@ echo "Options:"
 echo "-1     Encode the whole CD in a single file"
 echo "-a <action1[,action2]...>"
 echo "       Actions to perform:"
-echo "       cddb,read,normalize,encode,tag,move,replaygain,playlist,clean"
+echo "       cddb,read,getalbumart,normalize,encode,tag,move,replaygain,playlist,clean"
 #echo "-A     Experimental actions (retag, transcode)"
 echo "-b     Enable batch normalization"
 echo "-c <file>"
@@ -36,6 +34,7 @@ echo "-D     Debugging mode (equivalent to sh -x abcde)"
 echo "-e     Erase encoded track information from status file"
 echo "-f     Force operations that otherwise are considered harmful. Read \"man abcde\""
 echo "-g     Use \"lame --nogap\" for MP3 encoding. Disables low disk and pipes flags"
+echo "-G     Get album art by using the 'getalbumart' action"
 echo "-h     This help information"
 #echo "-i    Tag files while encoding, when possible (local only) -NWY-"
 echo "-j <#> Number of encoder processes to run at once (localhost)"
@@ -48,7 +47,7 @@ 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). Defaults to vorbis"
+echo "       Output file type(s) (vorbis,mp3,flac,spx,mpc,wav,m4a,opus,mka,wv,ape,mp2,tta). 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 "-r <host1[,host2]...>"
@@ -86,9 +85,9 @@ log ()
        BLURB="$1"
        shift
        case $BLURB in
-               error)   echo "[ERROR] abcde: $@" >&2 ;;
-               warning) echo "[WARNING] $@" >&2 ;;
-               info)    echo "[INFO] $@" ;;
+               error)   >&2 echo "[ERROR] abcde: $@" >&2 ;;
+               warning) >&2 echo "[WARNING] $@" >&2 ;;
+               info)    >&4 echo "[INFO] $@" ;;
        esac
 }
 
@@ -357,12 +356,12 @@ checkexec ()
                if [ "$(which $X)" = "" ]; 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_release ] ; then
+                       if [ -e /etc/debian_* ] ; then
                                case $X in
                                        oggenc)         MISSING_PACKAGE=vorbis-tools ;;
                                        lame|flac)      MISSING_PACKAGE=$X ;;
                                esac
-                               log info "Hint: apt-get install $MISSING_PACKAGE" >&2
+                               log info "Hint: sudo apt-get install $MISSING_PACKAGE" >&2
                        fi
                        exit 1
                elif [ ! -x "$(which $X)" ]; then
@@ -782,7 +781,7 @@ local id=""
                "jpop")                  id=146 ;;
                "synthpop")              id=147 ;;
                "rock/pop"|"rock / pop") id=148 ;;
-               *)                       return 1 ;;
+               *)                       id=255 ;;
        esac
 echo ${id}
 return 0
@@ -820,7 +819,6 @@ do_tag ()
                                TPE2="Various"
                        fi
 
-
                        case "$ID3SYNTAX" in
                                id3)
                                        run_command tagtrack-$OUTPUT-$1 nice $ENCNICE \
@@ -841,6 +839,16 @@ do_tag ()
                                                ${TPE2:+--TPE2 "$TPE2"} \
                                                "$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
                                        # happily substitute them with $TRACKNUM
@@ -863,7 +871,7 @@ do_tag ()
                                                        );;
                                        esac
                                        run_command tagtrack-$OUTPUT-$1 nice $ENCNICE $TAGGER $TAGGEROPTS \
-                                           -A "$DALBUM" \
+                                               -A "$DALBUM" \
                                                -a "$TRACKARTIST" -t "$TRACKNAME" \
                                                -G "$GENREID" -n "${TRACKNUM:-$1}" \
                                                ${TRACKNUM:+-N "$TRACKS"} \
@@ -885,7 +893,7 @@ do_tag ()
                                        fi
                                        (
                                        # These are from
-                                       # http://www.xiph.org/ogg/vorbis/doc/v-comment.html
+                                       # http://www.xiph.org/vorbis/doc/v-comment.html
 
                                        echo ARTIST="$TRACKARTIST"
                                        echo ALBUM="$DALBUM"
@@ -897,6 +905,11 @@ do_tag ()
                                                echo GENRE="$CDGENRE"
                                        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
+                                       # 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
@@ -923,7 +936,9 @@ do_tag ()
                opus)
                        run_command tagtrack-$OUTPUT-$1 true
                        ;;
-
+               mka)
+                       run_command tagtrack-$OUTPUT-$1 true
+                       ;;
                flac)
                        (
                        echo ARTIST="$TRACKARTIST"
@@ -936,6 +951,11 @@ do_tag ()
                                echo GENRE="$CDGENRE"
                        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
+                       # 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
@@ -946,7 +966,8 @@ do_tag ()
                                        *)   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
@@ -954,32 +975,62 @@ do_tag ()
                mpc)
                        run_command tagtrack-$OUTPUT-$1 true
                        ;;
-        wv)
-            run_command tagtrack-$OUTPUT-$1 true
+               wv)
+                       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.              Andrew.
-            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"} 
+               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"} 
                        ;;
+               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. 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
-               ;;
+                       ;;
                m4a)
-                 case "$AACENCODERSYNTAX" in
-                   fdkaac) # We will use inline tagging...
-                       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"
-                     ;;
-                  faac)
-                    run_command tagtrack-$OUTPUT-$1 true                   
+                       case "$AACENCODERSYNTAX" in
+                               fdkaac)
+                                       # We will use inline tagging...
+                                       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"
+                                       ;;
+                               faac)
+                                       run_command tagtrack-$OUTPUT-$1 true   
+                                       ;;
+                               qaac)
+                                       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
+                                       ;;
+                               ffmpeg)
+                                       run_command tagtrack-$OUTPUT-$1 true   
+                               ;;
+                       esac
                        ;;
-               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
@@ -989,7 +1040,6 @@ do_tag ()
        if checkerrors "tagtrack-(.{3,6})-$1"; then :; else
                run_command tagtrack-$1 true
        fi
-
 }
 
 # do_nogap_encode
@@ -1005,7 +1055,7 @@ do_nogap_encode ()
                case "$OUTPUT" in
                mp3)
                        case "$MP3ENCODERSYNTAX" in
-                       lame|toolame)
+                       lame)
                                (
                                cd "$ABCDETEMPDIR"
                                TRACKFILES=
@@ -1044,7 +1094,8 @@ do_nogap_encode ()
 # do_encode [tracknumber] [hostname]
 # If no hostname is specified, encode locally
 # 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_encode ()
 {
        if [ "$USEPIPES" = "y" ]; then
@@ -1058,6 +1109,9 @@ do_encode ()
                        opus)
                                TEMPARG="PIPE_$OPUSENCODERSYNTAX"
                                ;;
+                       mka)
+                               TEMPARG="PIPE_$MKAENCODERSYNTAX"
+                               ;;
                        flac)
                                TEMPARG="PIPE_$FLACENCODERSYNTAX"
                                ;;
@@ -1070,6 +1124,9 @@ do_encode ()
                        wv)
                                TEMPARG="PIPE_$WVENCODERSYNTAX"
                                ;;
+                       tta)
+                               TEMPARG="PIPE_$TTAENCODERSYNTAX"
+                               ;;
                        aac)
                                TEMPARG="PIPE_$AACENCODERSYNTAX"
                                ;;
@@ -1092,6 +1149,9 @@ do_encode ()
                                opus)
                                        OUTPUT=$OPUSOUTPUTCONTAINER
                                        ;;
+                               mka)
+                                       OUTPUT=$MKAOUTPUTCONTAINER
+                                       ;;
                                flac)
                                        OUTPUT=$FLACOUTPUTCONTAINER
                                        ;;
@@ -1107,7 +1167,7 @@ do_encode ()
                                RUN_COMMAND=""
                                # We need a way to store the creation of the files when using PIPES
                                RUN_COMMAND_PIPES="run_command encodetrack-$OUTPUT-$1 true"
-                               # When pipping it does not make sense to have a higher nice for
+                               # When piping it does not make sense to have a higher nice for
                                # reading than for encoding, since it will be hold by the
                                # encoding process. Setting an effective nice, to calm down a
                                # bit the reading process.
@@ -1122,8 +1182,8 @@ do_encode ()
                                case "$2" in
                                %local*%)
                                        case "$MP3ENCODERSYNTAX" in
-                                       lame|toolame|gogo) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER $MP3ENCODEROPTS "$IN" "$OUT" ;;
-                                       bladeenc) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER $MP3ENCODEROPTS -quit "$IN" ;;
+                                       lame|gogo) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER $MP3ENCODEROPTS "$IN" "$OUT" ;;
+                                       bladeenc) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER $MP3ENCODEROPTS -quit "$IN" "$OUT" ;;
                                        l3enc|xingmp3enc) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER "$IN" "$OUT" $MP3ENCODEROPTS ;;
                                        mp3enc) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER -if "$IN" -of "$OUT" $MP3ENCODEROPTS ;;
                                        esac
@@ -1151,14 +1211,15 @@ do_encode ()
                                %local*%)
                                        case "$OPUSENCODERSYNTAX" in
                                        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"
-                                           else
-                                             $RUN_COMMAND nice $EFFECTIVE_NICE $OPUSENCODER $OPUSENCODEROPTS "$IN" "$OUT"
-                                           fi
-                                             ;;
+                                       # 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"
+                                               else
+                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $OPUSENCODER $OPUSENCODEROPTS "$IN" "$OUT"
+                                               fi
+                                       ;;
                                        esac
                                        ;;
                                *)
@@ -1166,6 +1227,19 @@ 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
+                               ;;
                        flac)
                                case "$2" in
                                %local*%)
@@ -1189,66 +1263,119 @@ 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
                                ;;
                        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"
+                               # 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"
                                else
-                                $RUN_COMMAND nice $EFFECTIVE_NICE $MPCENCODER $MPCENCODEROPTS "$IN" "$OUT"
+                                       $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)
-                        if [ "$DOTAG" = "y" ]; then
-             # wavpack tagging is done inline using Apev2 tags:
-                               $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
+                       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"
+                                       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" 
+                                       else 
+                                               $RUN_COMMAND nice $EFFECTIVE_NICE $WVENCODER -i "$IN" $WVENCODEROPTS "$OUT"
+                                       fi
+                               ;;
+                       esac
                                ;;
                        ape)
-                         $RUN_COMMAND nice $EFFECTIVE_NICE $APENCODER "$IN" "$OUT" $APENCODEROPTS
-                        ;;
+                               $RUN_COMMAND nice $EFFECTIVE_NICE $APENCODER "$IN" "$OUT" $APENCODEROPTS
+                               ;;
+                       mp2)
+                               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 
-                       # is compiled without mp4 support (with libmp4v2).           Andrew.
-                         $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS -o "$OUT" "$IN"
-                        ;;
+                               # aac container is only used to catch faac encoded files where faac 
+                               # is compiled without mp4 support (with libmp4v2).
+                               $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS -o "$OUT" "$IN"
+                               ;;
                        m4a)
-                        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"                                
-                else                    
-                  $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS -o "$OUT" "$IN"        
-                fi
-                          ;;
-                          neroAacEnc)
-                   $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS -if "$IN" -of "$OUT"
-                          ;;
-                        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"
-                           else
-                    $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS "$IN" -o "$OUT"      
-                           fi
-                ;;
-                         esac  
+                               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"
+                                               else 
+                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS -o "$OUT" "$IN"   
+                                               fi
+                                               ;;
+                                       neroAacEnc)
+                                               $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS -if "$IN" -of "$OUT"
+                                               ;;
+                                       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"
+                                               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"
+                                               else 
+                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $WINE $AACENCODER $AACENCODEROPTS -o "$OUT" "$IN"
+                                               fi
+                                               ;;
+                                       fhgaacenc)
+                                               $RUN_COMMAND nice $EFFECTIVE_NICE $WINE $AACENCODER $AACENCODEROPTS "$IN" "$OUT"
+                                               ;;
+                                       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" 
+                                               else 
+                                                       $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER -i "$IN"  $AACENCODEROPTS "$OUT"
+                                               fi
+                                               ;;
+                                       esac
                                ;;
                        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. Andrew.
-             echo "encodetrack-$OUTPUT-$UTRACKNUM" >> "$ABCDETEMPDIR/status"
+                               # successful cleaning of $ABCDETEMPDIR.
+                               echo "encodetrack-$OUTPUT-$UTRACKNUM" >> "$ABCDETEMPDIR/status"
                                ;;
                        esac
                        $RUN_COMMAND_PIPES
@@ -1447,12 +1574,6 @@ do_move ()
                OUTPUT="$TMPOUTPUT"
 
                # Create ALBUMFILE, ARTISTFILE, TRACKFILE
-               # Munge filenames as follows:
-               # ' ' -> '_'
-               # '/' -> '_'
-               # ''' -> ''
-               # '?' -> ''
-               # Eat control characters
                ALBUMFILE="$(mungefilename "$DALBUM")"
                ARTISTFILE="$(mungefilename "$TRACKARTIST")"
                TRACKFILE="$(mungefilename "$TRACKNAME")"
@@ -1486,6 +1607,9 @@ do_move ()
                                opus)
                                        OUTPUT=$OPUSOUTPUTCONTAINER
                                        ;;
+                               mka)
+                                       OUTPUT=$MKAOUTPUTCONTAINER
+                                       ;;
                                flac)
                                        OUTPUT=$FLACOUTPUTCONTAINER
                                        ;;
@@ -1570,6 +1694,9 @@ do_playlist ()
                        opus)
                                OUTPUT=$OPUSOUTPUTCONTAINER
                                ;;
+                       mka)
+                               OUTPUT=$MKAOUTPUTCONTAINER
+                               ;;
                        flac)
                                OUTPUT=$FLACOUTPUTCONTAINER
                                ;;
@@ -1931,7 +2058,7 @@ do_discid ()
        if [ -z "$TRACKQUEUE" ]; then
                if [ ! "$STRIPDATATRACKS" = "n" ]; then
                        case "$CDROMREADERSYNTAX" in
-                               cdparanoia|debug)
+                               cdparanoia|libcdio|debug)
                                        if [ "$WEHAVEACD" = "y" ]; then
                                                vecho "Querying the CD for audio tracks..."
                                                CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -Q --verbose 2>&1 )"
@@ -2330,7 +2457,7 @@ do_cdtext ()
                CDTEXT_READER=icedax
        elif new_checkexec cdda2wav; then
                CDTEXT_READER=cdda2wav
-    else
+       else
                # Didn't find either, bail
                return 0
        fi
@@ -2376,11 +2503,12 @@ do_cdtext ()
                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"
+               sed "s~^TTITLE${TRACKM1}=.*~TTITLE${TRACKM1}=${TITLE}~" "$ABCDETEMPDIR/cddbread.1" > "$ABCDETEMPDIR/cddbread.new" && \
+                       mv -f "$ABCDETEMPDIR/cddbread.new" "$ABCDETEMPDIR/cddbread.1"
        done
-       sed "s~^DTITLE=.*~DTITLE=${ATITLE}~" "$ABCDETEMPDIR/cddbread.1" > "$ABCDETEMPDIR/cddbread.new"
-    mv -f "$ABCDETEMPDIR/cddbread.new" "$ABCDETEMPDIR/cddbread.1"
+       sed "s~^DTITLE=.*~DTITLE=${ATITLE}~" "$ABCDETEMPDIR/cddbread.1" > "$ABCDETEMPDIR/cddbread.new" && \
+               mv -f "$ABCDETEMPDIR/cddbread.new" "$ABCDETEMPDIR/cddbread.1"
+       rm -f "$ABCDETEMPDIR/cddbread.new" # In case a sed error occurred
        echo >> "$ABCDETEMPDIR/cddbchoices"
        echo "cdtext-readcomplete" >> "$ABCDETEMPDIR/status"
 }
@@ -2580,12 +2708,14 @@ do_cddbread ()
                        done
                        echo >> "$ABCDETEMPDIR/cddbchoices"
                        ;;
-               202|403|409|503)
-                       # No match
+               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:
                        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" ;;
+                       500|503) echo "CDDB unavailable." >> "$ABCDETEMPDIR/cddbchoices" ;;
                        esac
                        $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
                        # List out disc title/author and contents of template
@@ -2973,6 +3103,150 @@ do_cddbedit ()
        echo "cddb-edit" >> "$ABCDETEMPDIR/status"
 }
 
+# do_getalbumart
+# try to download CD cover
+do_getalbumart()
+{
+       # set variables
+       ALBUMFILE="$(mungefilename "$DALBUM")"
+       ARTISTFILE="$(mungefilename "$DARTIST")"
+       GENRE="$(mungegenre "$GENRE")"
+       YEAR=${CDYEAR:-$CDYEAR}
+       # have we got a musicbrainz mbid or amazon asin?
+       case "$CDDBMETHOD" in
+               musicbrainz)
+                       # try musicbrainz mbid
+                       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"
+                               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)")
+                                               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"
+                                               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")
+                                                       if [ "$FILESIZE" -lt 1024 ]; then
+                                                               rm "$ABCDETEMPDIR/$ALBUMARTFILE"
+                                                               vecho "could not download cover from amazon" >&2
+                                                       fi
+                                               fi
+                                       else
+                                               vecho "no amazon ID found" >&2
+                                       fi
+                               fi
+                       else
+                               vecho "no musicbrainz ID found" >&2
+                       fi
+                       ;;
+       esac
+       # use glyrc
+       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
+               if [ $? -ne 0 ]; then
+                       vecho "could not download cover with glyrc" >&2
+               else
+                       ALBUMARTURL="glyrc"
+               fi
+       fi
+       if [ "$INTERACTIVE" = "y" ]; then
+               if [ -s "$ABCDETEMPDIR/$ALBUMARTFILE" ]; then
+                       # display properties of coverart when identify is available
+                       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 &
+                       fi
+               else
+                       # nothing downloaded yet
+                       vecho "automatic album art downloading failed" >&2
+               fi
+               # see if the user can find a better album art manually
+               echo -n "Do you want to enter URL or local path for the album art [y/N]? " >&2
+               read YESNO
+               while [ "$YESNO" != "y" ] && [ "$YESNO" != "n" ] && [ "$YESNO" != "Y" ] && \
+                       [ "$YESNO" != "N" ] && [ "$YESNO" != "" ]
+               do
+                       echo -n 'Invalid selection. Please answer "y" or "n": ' >&2
+                       read YESNO
+               done
+               if [ "$YESNO" = "y" ] || [ "$YESNO" = "Y" ]; then
+                       echo -n "Enter URL or local path (ENTER to cancel) :" >&2
+                       read ALBUMARTURL
+                       if [ ! -z "$ALBUMARTURL" ]; then
+                               if [[ ${ALBUMARTURL} =~ (https?|ftp|file)://.* ]]; 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
+                                       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"
+                       else
+                               rm -f "$ABCDETEMPDIR/$ALBUMARTFILE"
+                               vecho "sorry, cannot convert $ALBUMARTURLTYPE to $ALBUMARTTYPE without ImageMagick convert" >&2
+                       fi
+               fi
+       fi
+       # copy to target directories
+       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"
+               done
+               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"
+       fi
+}
+
 # do_cdread [tracknumber]
 # do_cdread onetrack [firsttrack] [lasttrack]
 #
@@ -2990,7 +3264,7 @@ do_cdread ()
                UTRACKNUM=$FIRSTTRACK
                case "$CDROMREADERSYNTAX" in
                        flac) READTRACKNUMS="$FIRSTTRACK.1-$(($LASTTRACK + 1)).0" ;;
-                       cdparanoia)
+                       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" ;;
@@ -3006,23 +3280,18 @@ do_cdread ()
        if [ "$USEPIPES" = "y" ]; then
                TEMPARG="PIPERIPPER_$CDROMREADERSYNTAX"
                FILEARG="$( eval echo "\$$TEMPARG" )"
-               REDIR=""
                PIPE_MESSAGE="and encoding "
        else
                WAVDATA="$ABCDETEMPDIR/track$UTRACKNUM.wav"
                case "$CDROMREADERSYNTAX" in
-               ## FIXME ## Find the cases for dagrab and flac, to avoid exceptions
+               ## FIXME ## Find the cases for flac, to avoid exceptions
                        flac)
                                FILEARG="--output-name=$WAVDATA"
                                ;;
-                       dagrab)
-                               FILEARG="-f $WAVDATA"
-                               ;;
                        *)
                                FILEARG="$WAVDATA"
                                ;;
                esac
-               REDIR=">&2"
        fi
        if [ "$1" = "onetrack" ]; then
                echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2
@@ -3041,9 +3310,14 @@ do_cdread ()
                        # 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" ;;
-               cdparanoia)
-                       nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR ;;
-               cdda2wav | icedax)
+               cdparanoia|libcdio)
+                       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/}
@@ -3058,11 +3332,25 @@ do_cdread ()
                                        CDDA2WAVCDROM="$CDROMID"
                                fi
                        fi
-                       nice $READNICE $CDROMREADER -D $CDDA2WAVCDROM -t ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR ;;
-               ## FIXME ## We have an exception for dagrab, since it uses -f
-               ## FIXME ## Shall we just use -f $FILEARG ??
-               dagrab) nice $READNICE $CDROMREADER -d "$CDROM" -v $UTRACKNUM "$FILEARG" $REDIR;;
-               pird) nice $READNICE $CDROMREADER -j ${READTRACKNUMS:-$UTRACKNUM} "$CDROM" "$FILEARG" $REDIR ;;
+                       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"
+                       else
+                               # Write ripped audio data to stdout and redirect to $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)
@@ -3070,11 +3358,21 @@ do_cdread ()
                        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
@@ -3122,7 +3420,7 @@ vecho ()
 if [ x"$EXTRAVERBOSE" != "x" ] && [ $EXTRAVERBOSE -gt 0 ] ; then
        case $1 in
                warning) shift ; log warning "$@" ;;
-               *) echo "$@" ;;
+               *) >&4 echo "$@" ;;
        esac
 fi
 }
@@ -3135,7 +3433,7 @@ vvecho ()
 if [ x"$EXTRAVERBOSE" != "x" ] && [ $EXTRAVERBOSE -gt 1 ] ; then
        case $1 in
                warning) shift ; log warning "$@" ;;
-               *) echo "$@" ;;
+               *) >&4 echo "$@" ;;
        esac
 fi
 }
@@ -3148,9 +3446,9 @@ decho ()
 if [ x"$DEBUG" != "x" ]; then
        if echo $1 | grep "^\[" > /dev/null 2>&1 ; then
                DEBUGECHO=$(echo "$@" | tr -d '[]')
-               echo "[DEBUG] $DEBUGECHO: `eval echo \\$${DEBUGECHO}`"
+               echo >&4 "[DEBUG] $DEBUGECHO: `eval echo \\$${DEBUGECHO}`"
        else
-               echo "[DEBUG] $1"
+               echo >&4 "[DEBUG] $1"
        fi
 fi
 }
@@ -3159,8 +3457,7 @@ fi
 # Custom filename munging:
 mungefilename ()
 {
-       #echo "$@" | sed s,:,\ -,g | tr \ /\* __+ | tr -d \'\"\?\[:cntrl:\]
-       echo "$@" | sed s,:,\ -,g | tr \ / __ | tr -d \'\"\?\[:cntrl:\]
+       echo "$@" | sed -e 's/^\.*//' -e 's/ /_/g' | tr -d ":><|*/\"'?[:cntrl:]"
 }
 
 # Custom genre munging:
@@ -3221,11 +3518,14 @@ ENCODERSYNTAX=default
 MP3ENCODERSYNTAX=default
 OGGENCODERSYNTAX=default
 OPUSENCODERSYNTAX=default
+MKAENCODERSYNTAX=default
 FLACENCODERSYNTAX=default
 SPEEXENCODERSYNTAX=default
 MPCENCODERSYNTAX=default
 WVENCODERSYNTAX=default
+TTAENCODERSYNTAX=default
 APENCODERSYNTAX=default
+MP2ENCODERSYNTAX=default
 AACENCODERSYNTAX=default
 NORMALIZERSYNTAX=default
 CUEREADERSYNTAX=default
@@ -3264,7 +3564,6 @@ CDPARANOIACDROMBUS="d"
 # program paths - defaults to checking your $PATH
 # mp3
 LAME=lame
-TOOLAME=toolame
 GOGO=gogo
 BLADEENC=bladeenc
 L3ENC=l3enc
@@ -3282,23 +3581,43 @@ SPEEXENC=speexenc
 # mpc (Musepack)
 MPCENC=mpcenc
 # wv (wavpack)
+# WVENC is retained in abcde 2.7.1 for backwards compatibility
+# 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
+# mp2
+TWOLAME=twolame
 # m4a
-AACENC=faac
+FAAC=faac
+NEROAACENC=neroAacEnc
+FDKAAC=fdkaac
+# Note that the qaac PATH will almost always require adjustment
+# as it is a Windows application being run through Wine. More
+# detailed notes in the sample abcde.conf file in the abcde tarball.
+QAAC=qaac
+FHGAACENC=fhgaacenc
+# The path to 'avconv' rather than 'ffmpeg'can be used here:
+FFMPEG=ffmpeg
 
 ID3=id3
 ID3V2=id3v2
+MID3V2=mid3v2
 EYED3=eyeD3
+ID3TAG=id3tag
 VORBISCOMMENT=vorbiscomment
 METAFLAC=metaflac
-AACTAG=faac
 NEROAACTAG=neroAacTag
-FDKAAC=fdkaac
+ATOMICPARSLEY=AtomicParsley
 
+WINE=wine
 CDPARANOIA=cdparanoia
+CD_PARANOIA=cd-paranoia
 CDDA2WAV=icedax
 DAGRAB=dagrab
 CDDAFS=cp
@@ -3323,11 +3642,14 @@ MKCUE=mkcue
 MKTOC=cdrdao
 DIFF=diff
 CUE2DISCID=builtin
+GLYRC=glyrc
+IDENTIFY=identify
+CONVERT=convert
+DISPLAYCMD=display
 
 # Options for programs called from abcde
 # mp3
 LAMEOPTS=
-TOOLAMEOPTS=
 GOGOOPTS=
 BLADEENCOPTS=
 L3ENCOPTS=
@@ -3351,17 +3673,31 @@ SPEEXENCOPTS=
 # mpc
 MPCENCOPTS=
 # wv
-WVENCOPTS=
+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.                                 Andrew.
+# so we set one here.
 APENCOPTS='-c4000'
+# mp2
+TWOLAMENCOPTS=
 # m4a
-AACENCOPTS=
+FAACENCOPTS=
+NEROACENCOPTS=
+# fdkaac chokes without either a bitrate or bitrate-mode specified so 
+# we set bitrate here.
+FDKAACENCOPTS='--bitrate 192k'
+QAACENCOPTS=
+FHGAACENCOPTS=
+FFMPEGENCOPTS=
 
 ID3OPTS=
+ID3TAGOPTS=
 EYED3OPTS=""
+ATOMICPARSLEYOPTS=
 CDPARANOIAOPTS=
+PIRDOPTS=
 CDDA2WAVOPTS=
 DAGRABOPTS=
 CDDAFSOPTS="-f"
@@ -3376,6 +3712,15 @@ MKTOCOPTS=""
 VORBISCOMMENTOPTS="-R"
 METAFLACOPTS="--no-utf8-convert"
 DIFFOPTS=
+GLYRCOPTS=
+IDENTIFYOPTS=
+CONVERTOPTS=
+DISPLAYCMDOPTS="-resize 512x512 -title abcde_album_art"
+
+# Defaults for album art downloads
+ALBUMARTFILE="cover.jpg"
+ALBUMARTTYPE="JPEG"
+ALBUMARTALWAYSCONVERT="n"
 
 # Default to one process if -j isn't specified
 MAXPROCS=1
@@ -3385,10 +3730,13 @@ 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:toolame,mp3:lame,mp3:bladeenc,spx:speex,m4a:faac:opus
+DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:lame,mp3:bladeenc,spx:speex,m4a:faac:opus
 
 # List of preferred cdromreaders - by default, run whichever we have in the path
-DEFAULT_CDROMREADERS="cdparanoia icedax cdda2wav pird"
+DEFAULT_CDROMREADERS="cdparanoia icedax cdda2wav libcdio pird"
+
+# fd for when `vecho` and `log info` called with redirected stdout
+exec 4>&1
 
 # Assume fetch if under FreeBSD. curl is used for Mac OS X. wget is used for
 # Linux/OpenBSD. ftp is user for NetBSD.
@@ -3408,7 +3756,7 @@ elif [ X$(uname) = "XDarwin" ] ; then
        # 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
+       HTTPGET=ftp
        MD5SUM=md5
        OSFLAVOUR=OBSD
 elif [ X$(uname) = "XNetBSD" ] ; then
@@ -3468,7 +3816,7 @@ fi
 if [ "$CDROM" = "" ] ; then
        if [ -e /dev/cdroms/cdrom0 ]; then
                CDROM=/dev/cdroms/cdrom0
-       elif [ "$OSFLAVOUR" = "OSX" ] && [[ $(diskutil list) =~ CD_part.*(disk.)$'\n' ]]; then
+       elif [ "$OSFLAVOUR" = "OSX" ] && [[ $(diskutil list) =~ CD_part[^/]*(disk.)$'\n' ]]; then
                CDROM=/dev/${BASH_REMATCH[1]}
        elif [ -e /dev/cdrom ]; then
                CDROM=/dev/cdrom
@@ -3496,7 +3844,7 @@ case "$EXTRAVERBOSE" in
 esac
 
 # Parse command line options
-while getopts 1a:bc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:UvVxX:w:W:z opt ; do
+while getopts 1a:bc:C:d:DefgGhj:klLmMnNo:pPr:s:S:t:T:UvVxX:w:W:z opt ; do
        case "$opt" in
                1) ONETRACK=y ;;
                a) ACTIONS="$OPTARG" ;;
@@ -3511,6 +3859,7 @@ while getopts 1a:bc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:UvVxX:w:W:z opt ; do
                E) ENCODING="$OPTARG" ;;
                f) FORCE=y ;;
                g) NOGAP=y ;;
+               G) GETALBUMART=y ;;
                i) INLINETAG=y ;;
                j) MAXPROCS="$OPTARG" ;;
                k) KEEPWAVS=y ;;
@@ -3606,7 +3955,7 @@ if [ "$ONETRACK" = "y" ]; then
        # FIXME # remove check as soon as we find out about the other readers
        case "$CDROMREADERSYNTAX" in
                flac) ;;
-               cdparanoia) ;;
+               cdparanoia | libcdio) ;;
                cdda2wav | icedax) ;;
                pird) ;;
                *) log error "$CDROMREADERSYNTAX does not support ONETRACK mode"
@@ -3679,6 +4028,7 @@ do
                replaygain) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOREPLAYGAIN=y;;
                playlist) DOCDDB=y; DOPLAYLIST=y;;
                clean) DOCLEAN=y;;
+               getalbumart) GETALBUMART=y;;
        esac
 done
 
@@ -3795,6 +4145,12 @@ case "$CDROMREADERSYNTAX" in
                CDROMREADER="$CDPARANOIA"
                CDROMREADEROPTS="$CDPARANOIAOPTS"
                ;;
+       libcdio)
+               # GNU's libcdio package will use cd-paranoia but I believe will be happy with
+               # the standard cdparanoia options. If I am wrong this will need to be fixed :).
+               CDROMREADER="$CD_PARANOIA"
+               CDROMREADEROPTS="$CDPARANOIAOPTS"
+               ;;
        cdda2wav | icedax)
                CDROMREADER="$CDDA2WAV"
                CDROMREADEROPTS="$CDDA2WAVOPTS"
@@ -3832,12 +4188,15 @@ 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- )" ;;
                        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- )" ;;
                esac
        done
@@ -3869,6 +4228,10 @@ do
                        [ "$OPUSENCODERSYNTAX" = "default" ] && OPUSENCODERSYNTAX=opusenc
                        OPUSOUTPUTCONTAINER=opus
                        ;;
+               mka)
+                       [ "$MKAENCODERSYNTAX" = "default" ] && MKAENCODERSYNTAX=ffmpeg
+                       MKAOUTPUTCONTAINER=mka
+                       ;;
                mp3)
                        [ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame
                        [ "$DOTAG" = "y" ] && NEEDTAGGER=y
@@ -3892,20 +4255,35 @@ do
                        [ "$WVENCODERSYNTAX" = "default" ] && WVENCODERSYNTAX=wavpack
                        [ "$DOTAG" = "y" ]
                        [ "$DOREPLAYGAIN" = "y" ] && NEEDWVGAIN=y
+                       [ "$WVENCODERSYNTAX" = "ffmpeg" ] && DOREPLAYGAIN=n
                        ;;
                ape)
                        [ "$APENCODERSYNTAX" = "default" ] && APENCODERSYNTAX=mac
                        [ "$DOTAG" = "y" ] && NEEDAPETAG=y
                        ;;
+               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
+                       [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac
                        [ "$DOTAG" = "n" ]
                # Neither Faac nor AtomicParsley can tag the .aac files which are used for faac
                # compiled without libmp4v2... Andrew.
-                       ;;      
+                       ;;
                m4a)
                        [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac
                        [ "$DOTAG" = "y" ] && CHECKFAACBUILD=y
+                       [ "$AACENCODERSYNTAX" = "neroAacEnc" ] && NEEDNEROAACTAG=y
+                       [ "$AACENCODERSYNTAX" = "qaac" ] && NEEDWINE=y
+                       [ "$AACENCODERSYNTAX" = "fhgaacenc" ] && NEEDWINE=y && NEEDATOMICPARSLEY=y
+                       [ "$AACENCODERSYNTAX" = "ffmpeg" ] && [ "$DOTAG" = "y" ]
                        ;;
                wav)
                        if [ "$KEEPWAVS" = "y" ]; then
@@ -3925,10 +4303,6 @@ case "$MP3ENCODERSYNTAX" in
                MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$LAMEOPTS}"
                MP3ENCODER="$LAME"
                ;;
-       toolame)
-               MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$TOOLAMEOPTS}"
-               MP3ENCODER="$TOOLAME"
-               ;;
        gogo)
                MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$GOGOOPTS}"
                MP3ENCODER="$GOGO"
@@ -3966,6 +4340,12 @@ case "$OPUSENCODERSYNTAX" in
                OPUSENCODER="$OPUSENC"
                ;;
 esac
+case "$MKAENCODERSYNTAX" in
+       ffmpeg)
+               MKAENCODEROPTS="${MKAENCODEROPTSCLI:-$FFMPEGENCOPTS}"
+               MKAENCODER="$FFMPEG"
+               ;;
+esac
 case "$FLACENCODERSYNTAX" in
        flac)
                FLACENCODEROPTS="${FLACENCODEROPTSCLI:-$FLACOPTS}"
@@ -3998,8 +4378,29 @@ case "$MPCENCODERSYNTAX" in
 esac
 case "$WVENCODERSYNTAX" in
        wavpack)
-               WVENCODEROPTS="${WVENCODEROPTSCLI:-$WVENCOPTS}"
-               WVENCODER="$WVENC"
+               # Syntax changed slightly between abcde 2.7 and abcde 2.7.1,
+               # and in the interests of backward compatibility:
+               if [ -z "$WAVPACKENCOPTS" ] && [ -n "$WVENCOPTS" ]; then
+                       WVENCODEROPTS="${WVENCODEROPTSCLI:-$WVENCOPTS}"
+                       WVENCODER="$WAVPACK"
+               else
+                       WVENCODEROPTS="${WVENCODEROPTSCLI:-$WAVPACKENCOPTS}"
+                       WVENCODER="$WAVPACK"
+               fi
+               ;;
+       ffmpeg)
+               WVENCODEROPTS="${WVENCODEROPTSCLI:-$FFMPEGENCOPTS}"
+               WVENCODER="$FFMPEG"
+               ;;
+esac
+case "$TTAENCODERSYNTAX" in
+       tta)
+               TTAENCODEROPTS="${TTAENCODEROPTSCLI:-$TTAENCOPTS}"
+               TTAENCODER="$TTA"
+               ;;
+       ttaenc)
+               TTAENCODEROPTS="${TTAENCODEROPTSCLI:-$TTAENCOPTS}"
+               TTAENCODER="$TTAENC"
                ;;
 esac
 case "$APENCODERSYNTAX" in
@@ -4008,10 +4409,73 @@ case "$APENCODERSYNTAX" in
                APENCODER="$APENC"
                ;;
 esac
+case "$MP2ENCODERSYNTAX" in
+       twolame)
+               MP2ENCODEROPTS="${MP2ENCODEROPTSCLI:-$TWOLAMENCOPTS}"
+               MP2ENCODER="$TWOLAME"
+               ;;
+       ffmpeg)
+               MP2ENCODEROPTS="${MP2ENCODEROPTSCLI:-$FFMPEGENCOPTS}"
+               MP2ENCODER="$FFMPEG"
+               ;;
+esac
 case "$AACENCODERSYNTAX" in
-       faac|neroAacEnc|fdkaac)
-               AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
-               AACENCODER="$AACENC"
+               # Some elaborate 'if' work to keep backward compatibility for those
+               # who don't realise that AACENCOPTS does not work with abcde from
+               # version 2.7 onwards.
+       faac)
+               if [ -z "$FAACENCOPTS" ] && [ -n "$AACENCOPTS" ]; then
+                       AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
+                       AACENCODER="$FAAC"
+               else
+                       AACENCODEROPTS="${AACENCODEROPTSCLI:-$FAACENCOPTS}"
+                       AACENCODER="$FAAC"
+               fi
+               ;;
+       neroAacEnc)
+               if [ -z "$NEROAACENCOPTS" ] && [ -n "$AACENCOPTS" ]; then
+                       AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
+                       AACENCODER="$NEROAACENC"
+               else        
+                       AACENCODEROPTS="${AACENCODEROPTSCLI:-$NEROAACENCOPTS}"
+                       AACENCODER="$NEROAACENC"
+               fi
+               ;;
+       fdkaac)
+               if [ -z "$FDKAACENCOPTS" ] && [ -n "$AACENCOPTS" ]; then
+                       AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
+                       AACENCODER="$FDKAAC"
+               else
+                       AACENCODEROPTS="${AACENCODEROPTSCLI:-$FDKAACENCOPTS}"
+                       AACENCODER="$FDKAAC"
+               fi
+               ;;
+       qaac)
+               if [ -z "$QAACENCOPTS" ] && [ -n "$AACENCOPTS" ]; then
+                       AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
+                       AACENCODER="$QAAC"
+               else
+                       AACENCODEROPTS="${AACENCODEROPTSCLI:-$QAACENCOPTS}"
+                       AACENCODER="$QAAC"
+               fi
+               ;;
+       fhgaacenc)
+               if [ -z "$FHGAACENCOPTS" ] && [ -n "$AACENCOPTS" ]; then
+                       AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
+                       AACENCODER="$FHGAACENC"
+               else
+                       AACENCODEROPTS="${AACENCODEROPTSCLI:-$FHGAACENCOPTS}"
+                       AACENCODER="$FHGAACENC"
+               fi
+               ;;
+       ffmpeg)
+               if [ -z "$FFMPEGENCOPTS" ] && [ -n "$AACENCOPTS" ]; then
+                       AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
+                       AACENCODER="$FFMPEG"
+               else
+                       AACENCODEROPTS="${AACENCODEROPTSCLI:-$FFMPEGENCOPTS}"
+                       AACENCODER="$FFMPEG"
+               fi
                ;;
 esac
 
@@ -4027,6 +4491,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
@@ -4118,7 +4587,7 @@ fi
 
 if [ X"$CDSPEEDVALUE" != "X" ] && [ "$DOREAD" = "y" ]; then
        case "$CDROMREADERSYNTAX" in
-               cdparanoia|debug) CDROMREADEROPTS="$CDPARANOIAOPTS -S $CDSPEEDVALUE" ;;
+               cdparanoia|libcdio|debug) CDROMREADEROPTS="$CDPARANOIAOPTS -S $CDSPEEDVALUE" ;;
                pird) CDROMREADEROPTS="$PIRDOPTS -s $CDSPEEDVALUE" ;;
                ### FIXME ### translate "cue2discid" from python to bash
                flac) NEEDMETAFLAC=y ; NEEDCUE2DISCID=y ; CDSPEEDVALUE="" ;;
@@ -4126,10 +4595,16 @@ if [ X"$CDSPEEDVALUE" != "X" ] && [ "$DOREAD" = "y" ]; then
        esac
 fi
 
+if [ "$GETALBUMART" = "y" ]; then
+       NEEDHTTPGET="y"
+       NEEDGLYRC="y"
+fi
+
 ###USEPIPESSUPPORT###
 
 # Rippers with USEPIPE support
 PIPERIPPER_cdparanoia="-"
+PIPERIPPER_libcdio="-"
 # Note that by default in abcde cdda2wav redirects to icedax.        
 PIPERIPPER_cdda2wav="-"
 PIPERIPPER_debug="-"
@@ -4139,13 +4614,24 @@ PIPERIPPER_pird="-"
 # Encoders with USEPIPE support
 PIPE_mp3enc="-sti"
 PIPE_lame="-"
-PIPE_bladeenc="-"
+PIPE_bladeenc="stdin"
 PIPE_oggenc="-"
 PIPE_opusenc="-"
 PIPE_flac="-"
 PIPE_speexenc="-"
 PIPE_mpcenc="-"
 PIPE_wavpack="-"
+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.
+PIPE_neroAacEnc="-"
+PIPE_fdkaac="-"
 
 # Figure out if we can use pipes with the ripper/encoder combination
 # exit otherwise
@@ -4158,37 +4644,43 @@ if [ "$USEPIPES" = "y" ]; then
                        PIPEENCODERSVARCHECK="PIPE_$OGGENCODERSYNTAX" ;;
                opus)
                        PIPEENCODERSVARCHECK="PIPE_$OPUSENCODERSYNTAX" ;;
+               mka)
+                       PIPEENCODERSVARCHECK="PIPE_$MKAENCODERSYNTAX" ;;
                flac)
                        PIPEENCODERSVARCHECK="PIPE_$FLACENCODERSYNTAX" ;;
                spx)
-                       PIPEENCODERSVARCHECK="PIPE_$SPEEXENCODER" ;;
+                       PIPEENCODERSVARCHECK="PIPE_$SPEEXENCODERSYNTAX" ;;
                mpc)
-                       PIPEENCODERSVARCHECK="PIPE_$MPCENCODER" ;;
+                       PIPEENCODERSVARCHECK="PIPE_$MPCENCODERSYNTAX" ;;
                wv)
-                       PIPEENCODERSVARCHECK="PIPE_$WVENCODER" ;;
+                       PIPEENCODERSVARCHECK="PIPE_$WVENCODERSYNTAX" ;;
+               tta)
+                       PIPEENCODERSVARCHECK="PIPE_$TTAENCODERSYNTAX" ;;
+               m4a)
+                       PIPEENCODERSVARCHECK="PIPE_$AACENCODERSYNTAX" ;;
+               aac)
+                       PIPEENCODERSVARCHECK="PIPE_$AACENCODERSYNTAX" ;;
        esac
        decho "PIPERIPPERSVARCHECK: $( eval echo "\$$PIPERIPPERSVARCHECK" )"
        if [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "$" ] || \
           [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "" ] ; then
                log error "no support for pipes with given ripper"
-               log error "read the USEPIPES file from the source tarball to get help."
-               log error "On a Debian system, it is under /usr/share/doc/abcde/USEPIPES.gz"
+               log error "read the FAQ file from the source tarball to get help."
                exit 1;
        fi
        decho "PIPEENCODERSVARCHECK: $( eval echo "\$$PIPEENCODERSVARCHECK" )"
        if [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "$" ] || \
           [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "" ] ; then
                log error "no support for pipes with given encoder"
-               log error "read the USEPIPES file from the source tarball to help"
-               log error "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz"
+               log error "read the FAQ file from the source tarball to get help"
                exit 1;
        fi
 fi
 
 # Make sure a buncha things exist
 for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
-       $OGGENCODER $OPUSENCODER $FLACENCODER $SPEEXENCODER $MPCENCODER \
-       $AACENCODER $WVENCODER $CDDBTOOL $APENCODER \
+       $OGGENCODER $OPUSENCODER $MKAENCODER $FLACENCODER $SPEEXENCODER $MPCENCODER \
+       $AACENCODER $WVENCODER $CDDBTOOL $APENCODER $MP2ENCODER $TTAENCODER \
        ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \
        ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
        ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
@@ -4196,7 +4688,9 @@ for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
        ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMP3GAIN+$MP3GAIN} \
        ${NEEDMPCGAIN+$MPCGAIN} ${NEEDCUEREADER+$CUEREADER} \
        ${NEEDWVGAIN+WVGAIN} ${NEEDAPETAG+$APETAG} \
-       ${NEEDCUE2DISCID+$CUE2DISCID}
+       ${NEEDCUE2DISCID+$CUE2DISCID} ${NEEDNEROAACTAG+$NEROAACTAG} \
+       ${NEEDGLYRC+$GLYRC} ${NEEDWINE+$WINE} ${NEEDATOMICPARSLEY+$ATOMICPARSLEY} \
+       ${NEEDMID3V2+$MID3V2}
 do
        checkexec "$X"
 done
@@ -4205,16 +4699,17 @@ done
 # for the mp4 container and no tagging capability. (AtomicParsley also cannot tag
 # these files). The resulting files are actually ADTS streams which belong in an 
 # aac container and with some version sniffing this is all cleaned up below. If
-# faac is compiled with libmp4v2 inline tagging occurs with faac.         Andrew. 
+# faac is compiled with libmp4v2 inline tagging occurs with faac.
 
+# FIXME: Should this be in this location? (Better incorporated into the checks above.)
 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
-  else
-   echo "Using Faac to Tag AAC Tracks..."
-  fi
+       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
+       else
+               echo "Using Faac to Tag AAC Tracks..."
+       fi
 fi
 
 # And last but not least, check if we can diff between files. We do not abort,
@@ -4298,7 +4793,7 @@ fi
 
 if [ X"$CDSPEEDVALUE" != "X" ]; then
        case "$CDROMREADERSYNTAX" in
-               cdparanoia|debug) ;;
+               cdparanoia|libcdio|debug) ;;
                pird) ;;
                flac) ;;
                *) do_cdspeed ;;
@@ -4335,6 +4830,10 @@ if [ ! "$ONETRACK" = "y" ]; then
        fi
 fi
 
+if [ "$GETALBUMART" = "y" ]; then
+       do_getalbumart
+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
@@ -4430,7 +4929,7 @@ if [ "$EJECTCD" = "y" ]; then
                $eject $EJECTOPTS $cd
        elif [ X"$(uname)" = X"Darwin" ] ; then
                diskutil eject ${CDROM#/dev/} 0
-    elif [ -x $(which $EJECT) ]; then
+       elif [ -x $(which $EJECT) ]; then
                $EJECT $EJECTOPTS "$CDROM"
        fi
        #fi
@@ -4465,24 +4964,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
+                                       done
+                               fi
+                               if checkstatus encodetrack-$LASTTRACK; then :; else do_nogap_encode; fi
+                               if checkerrors nogap-encode; then exit 1; fi
                        fi
-                       if checkstatus encodetrack-$LASTTRACK; then :; else do_nogap_encode; fi
-                       if checkerrors nogap-encode; then exit 1; fi
                fi
        fi
 fi