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 fc5956a..080ed24 100755 (executable)
--- a/abcde
+++ b/abcde
@@ -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.7.2-UNRELEASED'
 
 usage ()
 {
@@ -47,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]...>"
@@ -356,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
@@ -781,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
@@ -839,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
@@ -926,6 +936,9 @@ do_tag ()
                opus)
                        run_command tagtrack-$OUTPUT-$1 true
                        ;;
+               mka)
+                       run_command tagtrack-$OUTPUT-$1 true
+                       ;;
                flac)
                        (
                        echo ARTIST="$TRACKARTIST"
@@ -972,6 +985,14 @@ do_tag ()
                        -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
                        ;;
@@ -990,8 +1011,27 @@ do_tag ()
                                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
                        ;;
+               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
                        ;;
@@ -1015,7 +1055,7 @@ do_nogap_encode ()
                case "$OUTPUT" in
                mp3)
                        case "$MP3ENCODERSYNTAX" in
-                       lame|toolame)
+                       lame)
                                (
                                cd "$ABCDETEMPDIR"
                                TRACKFILES=
@@ -1069,6 +1109,9 @@ do_encode ()
                        opus)
                                TEMPARG="PIPE_$OPUSENCODERSYNTAX"
                                ;;
+                       mka)
+                               TEMPARG="PIPE_$MKAENCODERSYNTAX"
+                               ;;
                        flac)
                                TEMPARG="PIPE_$FLACENCODERSYNTAX"
                                ;;
@@ -1081,6 +1124,9 @@ do_encode ()
                        wv)
                                TEMPARG="PIPE_$WVENCODERSYNTAX"
                                ;;
+                       tta)
+                               TEMPARG="PIPE_$TTAENCODERSYNTAX"
+                               ;;
                        aac)
                                TEMPARG="PIPE_$AACENCODERSYNTAX"
                                ;;
@@ -1103,6 +1149,9 @@ do_encode ()
                                opus)
                                        OUTPUT=$OPUSOUTPUTCONTAINER
                                        ;;
+                               mka)
+                                       OUTPUT=$MKAOUTPUTCONTAINER
+                                       ;;
                                flac)
                                        OUTPUT=$FLACOUTPUTCONTAINER
                                        ;;
@@ -1133,7 +1182,7 @@ do_encode ()
                                case "$2" in
                                %local*%)
                                        case "$MP3ENCODERSYNTAX" in
-                                       lame|toolame|gogo) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER $MP3ENCODEROPTS "$IN" "$OUT" ;;
+                                       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 ;;
@@ -1178,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*%)
@@ -1216,17 +1278,51 @@ do_encode ()
                                        $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
-                                       $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
                                ;;
+                       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).
@@ -1253,6 +1349,26 @@ do_encode ()
                                                        $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)
@@ -1491,6 +1607,9 @@ do_move ()
                                opus)
                                        OUTPUT=$OPUSOUTPUTCONTAINER
                                        ;;
+                               mka)
+                                       OUTPUT=$MKAOUTPUTCONTAINER
+                                       ;;
                                flac)
                                        OUTPUT=$FLACOUTPUTCONTAINER
                                        ;;
@@ -1575,6 +1694,9 @@ do_playlist ()
                        opus)
                                OUTPUT=$OPUSOUTPUTCONTAINER
                                ;;
+                       mka)
+                               OUTPUT=$MKAOUTPUTCONTAINER
+                               ;;
                        flac)
                                OUTPUT=$FLACOUTPUTCONTAINER
                                ;;
@@ -2335,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
@@ -2381,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"
 }
@@ -2585,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
@@ -2985,6 +3110,8 @@ 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)
@@ -3094,11 +3221,19 @@ do_getalbumart()
                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"
@@ -3145,7 +3280,6 @@ do_cdread ()
        if [ "$USEPIPES" = "y" ]; then
                TEMPARG="PIPERIPPER_$CDROMREADERSYNTAX"
                FILEARG="$( eval echo "\$$TEMPARG" )"
-               REDIR=""
                PIPE_MESSAGE="and encoding "
        else
                WAVDATA="$ABCDETEMPDIR/track$UTRACKNUM.wav"
@@ -3158,7 +3292,6 @@ do_cdread ()
                                FILEARG="$WAVDATA"
                                ;;
                esac
-               REDIR=">&2"
        fi
        if [ "$1" = "onetrack" ]; then
                echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2
@@ -3178,8 +3311,13 @@ do_cdread ()
                        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/}
@@ -3194,17 +3332,25 @@ 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"
                        else
                                # Write ripped audio data to stdout and redirect to $FILEARG.
-                               # $REDIR can be ignored. Progress is written to stderr by default.
+                               # 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)
@@ -3212,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
@@ -3362,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
@@ -3405,7 +3564,6 @@ CDPARANOIACDROMBUS="d"
 # program paths - defaults to checking your $PATH
 # mp3
 LAME=lame
-TOOLAME=toolame
 GOGO=gogo
 BLADEENC=bladeenc
 L3ENC=l3enc
@@ -3423,22 +3581,41 @@ 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
 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
 NEROAACTAG=neroAacTag
+ATOMICPARSLEY=AtomicParsley
 
+WINE=wine
 CDPARANOIA=cdparanoia
 CD_PARANOIA=cd-paranoia
 CDDA2WAV=icedax
@@ -3473,7 +3650,6 @@ DISPLAYCMD=display
 # Options for programs called from abcde
 # mp3
 LAMEOPTS=
-TOOLAMEOPTS=
 GOGOOPTS=
 BLADEENCOPTS=
 L3ENCOPTS=
@@ -3497,20 +3673,29 @@ 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.
 APENCOPTS='-c4000'
+# mp2
+TWOLAMENCOPTS=
 # m4a
 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=
@@ -3545,7 +3730,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: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 libcdio pird"
@@ -3571,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
@@ -4003,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
@@ -4040,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
@@ -4063,11 +4255,22 @@ 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
                        [ "$DOTAG" = "n" ]
@@ -4078,6 +4281,9 @@ do
                        [ "$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
@@ -4097,10 +4303,6 @@ case "$MP3ENCODERSYNTAX" in
                MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$LAMEOPTS}"
                MP3ENCODER="$LAME"
                ;;
-       toolame)
-               MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$TOOLAMEOPTS}"
-               MP3ENCODER="$TOOLAME"
-               ;;
        gogo)
                MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$GOGOOPTS}"
                MP3ENCODER="$GOGO"
@@ -4138,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}"
@@ -4170,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
@@ -4180,8 +4409,18 @@ 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
-               # Some elaborate 'if' work to keep backward compatability for those
+               # 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)
@@ -4211,6 +4450,33 @@ case "$AACENCODERSYNTAX" in
                        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
 
 # and which tagger
@@ -4225,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
@@ -4351,6 +4622,11 @@ 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.
@@ -4368,6 +4644,8 @@ if [ "$USEPIPES" = "y" ]; then
                        PIPEENCODERSVARCHECK="PIPE_$OGGENCODERSYNTAX" ;;
                opus)
                        PIPEENCODERSVARCHECK="PIPE_$OPUSENCODERSYNTAX" ;;
+               mka)
+                       PIPEENCODERSVARCHECK="PIPE_$MKAENCODERSYNTAX" ;;
                flac)
                        PIPEENCODERSVARCHECK="PIPE_$FLACENCODERSYNTAX" ;;
                spx)
@@ -4376,6 +4654,8 @@ if [ "$USEPIPES" = "y" ]; then
                        PIPEENCODERSVARCHECK="PIPE_$MPCENCODERSYNTAX" ;;
                wv)
                        PIPEENCODERSVARCHECK="PIPE_$WVENCODERSYNTAX" ;;
+               tta)
+                       PIPEENCODERSVARCHECK="PIPE_$TTAENCODERSYNTAX" ;;
                m4a)
                        PIPEENCODERSVARCHECK="PIPE_$AACENCODERSYNTAX" ;;
                aac)
@@ -4399,8 +4679,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 \
+       $OGGENCODER $OPUSENCODER $MKAENCODER $FLACENCODER $SPEEXENCODER $MPCENCODER \
+       $AACENCODER $WVENCODER $CDDBTOOL $APENCODER $MP2ENCODER $TTAENCODER \
        ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \
        ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
        ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
@@ -4409,7 +4689,8 @@ for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
        ${NEEDMPCGAIN+$MPCGAIN} ${NEEDCUEREADER+$CUEREADER} \
        ${NEEDWVGAIN+WVGAIN} ${NEEDAPETAG+$APETAG} \
        ${NEEDCUE2DISCID+$CUE2DISCID} ${NEEDNEROAACTAG+$NEROAACTAG} \
-       ${NEEDGLYRC+$GLYRC}
+       ${NEEDGLYRC+$GLYRC} ${NEEDWINE+$WINE} ${NEEDATOMICPARSLEY+$ATOMICPARSLEY} \
+       ${NEEDMID3V2+$MID3V2}
 do
        checkexec "$X"
 done
@@ -4648,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
@@ -4683,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