# 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-2016 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.8.2-UNRELEASED'
usage ()
{
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,embedalbumart,normalize,encode,tag,move,replaygain,playlist,clean"
#echo "-A Experimental actions (retag, transcode)"
echo "-b Enable batch normalization"
+echo "-B Embed albumart (this also activates getalbumart)"
echo "-c <file>"
echo " Specify a configuration file (overrides system and user config files)"
echo "-C <discid#>"
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)"
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,aiff). Defaults to vorbis"
echo "-p Pad track numbers with 0's (if less than 10 tracks)"
echo "-P Use UNIX pipes to read+encode without wav files"
+echo "-Q Select CDDBMETHOD method(s) from the command line. Choose from any/all of musicbrainz,cddb,cdtext. Defaults to musicbrainz".
echo "-r <host1[,host2]...>"
echo " Also encode on these remote hosts"
echo "-s <field>"
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
}
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
{
case $1 in
TRACKNAME1)
- TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+ TRACKNAME="$(grep -a ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
;;
TRACKNAME)
- TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
+ TRACKNAME="$(grep -a ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
;;
TRACK-INFO)
- grep ^EXTT$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\\n/\n/g'
+ grep -a ^EXTT$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\\n/\n/g'
;;
esac
}
PREGAP=$(($(echo $OFFSETS | cut -f1 -d' ')))
TOTALTIME=$(( (($LEADOUT + $LEADIN + $PREGAP) / $CDFRAMES) - (($LEADIN + $PREGAP) / $CDFRAMES)))
- case "$CDDBMETHOD" in
- cddb)
- printf -v DISCID "%08lx" $(( ($CDDBCKSUM % 0xff) * 16777216 | $TOTALTIME * 256 | $TRACKS))
- ;;
- musicbrainz)
+ # Calculate both the cddb discid *and* the musicbrainz discid
+ # now. We'll use the cddb discid for reference in most cases
+ # for consistency, but we also have the musicbrainz discid for
+ # when we need it
+ printf -v CDDBDISCID "%08lx" $(( ($CDDBCKSUM % 0xff) * 16777216 | $TOTALTIME * 256 | $TRACKS))
+ CDDBTRACKINFO="${CDDBDISCID} $((TRACKS)) ${COOKEDOFFSETS} $((($LEADOUT + $LEADIN + $IDMAGICNUM) / $CDFRAMES))"
+
+ case $CDDBMETHOD in
+ *musicbrainz*)
# FIXME: don't assume the first track is 1
- echo "dasd: 1 $TRACKS $LEADIN $LEADOUT $OFFSETS "
- DISCID=$($MUSICBRAINZ --command calcid --discinfo 1 $TRACKS $LEADIN $LEADOUT $OFFSETS)
+ MBDISCID=$($MUSICBRAINZ --command calcid --discinfo 1 $TRACKS $LEADIN $LEADOUT $OFFSETS)
+ MBTRACKINFO="${MBDISCID} $((TRACKS)) ${COOKEDOFFSETS} $((($LEADOUT + $LEADIN + $IDMAGICNUM) / $CDFRAMES))"
;;
esac
-
- TRACKINFO="${DISCID} $((TRACKS)) ${COOKEDOFFSETS} $((($LEADOUT + $LEADIN + $IDMAGICNUM) / $CDFRAMES))"
}
do_replaygain()
CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
getcddbinfo TRACKNAME
splitvarious
- TRACKFILE="$(mungefilename "$TRACKNAME")"
- ARTISTFILE="$(mungefilename "$TRACKARTIST")"
- ALBUMFILE="$(mungefilename "$DALBUM")"
+ TRACKFILE="$(mungetrackname "$TRACKNAME")"
+ ARTISTFILE="$(mungeartistname "$TRACKARTIST")"
+ ALBUMFILE="$(mungealbumname "$DALBUM")"
GENRE="$(mungegenre "$GENRE")"
YEAR=${CDYEAR:-$CDYEAR}
gettracknum
}
do_getgenreid () {
-local genre=$(echo "${@}" | tr '[A-Z]' '[a-z]')
-local id=""
+ local genre=$(echo "${@}" | tr '[A-Z]' '[a-z]')
+ local id=""
case ${genre} in
"blues") id=0 ;;
"classic rock") id=1 ;;
"jpop") id=146 ;;
"synthpop") id=147 ;;
"rock/pop"|"rock / pop") id=148 ;;
- *) return 1 ;;
+ *) id=255 ;;
esac
echo ${id}
return 0
if [ -z "$COMMENTOUTPUT" ]; then
COMMENTOUTPUT="$(getcddbinfo TRACK-INFO)"
fi
- if [ "$CDDBMETHOD" = "cddb" ]; then
- CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
- fi
+ CDDBDISCID=$(echo $CDDBTRACKINFO | cut -d' ' -f1)
run_command '' echo "Tagging track $1 of $TRACKS: $TRACKNAME..."
# If we want to start the tracks with a given number, we need to modify the
# TRACKNUM value before evaluation
TPE2="Various"
fi
-
case "$ID3SYNTAX" in
id3)
run_command tagtrack-$OUTPUT-$1 nice $ENCNICE \
${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
);;
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"} \
fi
(
# These are from
- # http://www.xiph.org/ogg/vorbis/doc/v-comment.html
+ # https://www.xiph.org/vorbis/doc/v-comment.html
echo ARTIST="$TRACKARTIST"
echo ALBUM="$DALBUM"
echo GENRE="$CDGENRE"
fi
echo TRACKNUMBER=${TRACKNUM:-$1}
+ # TRACKTOTAL is not in the proposed, minimal list of standard field names from
+ # xiph.org: https://www.xiph.org/vorbis/doc/v-comment.html but is in common usage
+ # and read by mediainfo, ffprobe, vlc, Aqualung, ogg123, Foobar. And now abcde :)
+ # The tag is quietly ignored by Audacious, MPlayer, mpv, XMMS....
+ echo TRACKTOTAL="${TRACKS}"
if [ -n "$DISCNUMBER" ]; then
echo DISCNUMBER="$DISCNUMBER"
fi
opus)
run_command tagtrack-$OUTPUT-$1 true
;;
-
+ mka)
+ run_command tagtrack-$OUTPUT-$1 true
+ ;;
+ aiff)
+ run_command tagtrack-$OUTPUT-$1 true
+ ;;
flac)
(
echo ARTIST="$TRACKARTIST"
echo GENRE="$CDGENRE"
fi
echo TRACKNUMBER="${TRACKNUM:-$1}"
+ # TRACKTOTAL is not in the proposed, minimal list of standard field names from
+ # xiph.org: https://www.xiph.org/vorbis/doc/v-comment.html but is in common usage
+ # and read by mediainfo, ffprobe, vlc, Aqualung, ogg123, Foobar. And now abcde :)
+ # The tag is quietly ignored by Audacious, MPlayer, mpv, XMMS....
+ echo TRACKTOTAL="${TRACKS}"
if [ -n "$DISCNUMBER" ]; then
echo DISCNUMBER="$DISCNUMBER"
fi
*) echo 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
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
if checkerrors "tagtrack-(.{3,6})-$1"; then :; else
run_command tagtrack-$1 true
fi
-
}
# do_nogap_encode
case "$OUTPUT" in
mp3)
case "$MP3ENCODERSYNTAX" in
- lame|toolame)
+ lame)
(
cd "$ABCDETEMPDIR"
TRACKFILES=
nice $ENCNICE $MP3ENCODER $MP3ENCODEROPTS --nogap $TRACKFILES
RETURN=$?
if [ "$RETURN" != "0" ]; then
- echo "nogap-encode: $ENCODER returned code $RETURN" >> errors
+ echo "nogap-encode: $ENCODER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
else
for UTRACKNUM in $TRACKQUEUE
do
opus)
TEMPARG="PIPE_$OPUSENCODERSYNTAX"
;;
+ mka)
+ TEMPARG="PIPE_$MKAENCODERSYNTAX"
+ ;;
+ aiff)
+ TEMPARG="PIPE_$AIFFENCODERSYNTAX"
+ ;;
flac)
TEMPARG="PIPE_$FLACENCODERSYNTAX"
;;
wv)
TEMPARG="PIPE_$WVENCODERSYNTAX"
;;
+ tta)
+ TEMPARG="PIPE_$TTAENCODERSYNTAX"
+ ;;
aac)
TEMPARG="PIPE_$AACENCODERSYNTAX"
;;
opus)
OUTPUT=$OPUSOUTPUTCONTAINER
;;
+ mka)
+ OUTPUT=$MKAOUTPUTCONTAINER
+ ;;
+ aiff)
+ OUTPUT=$AIFFOUTPUTCONTAINER
+ ;;
flac)
OUTPUT=$FLACOUTPUTCONTAINER
;;
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 ;;
;;
esac
;;
+ mka)
+ case "$MKAENCODERSYNTAX" in
+ ffmpeg)
+ if [ "$DOTAG" = "y" ]; then
+ $RUN_COMMAND nice $EFFECTIVE_NICE $MKAENCODER -i "$IN" $MKAENCODEROPTS -metadata artist="$TRACKARTIST" \
+ -metadata album="$DALBUM" -metadata title="$TRACKNAME" -metadata track=${TRACKNUM:-$1} -metadata date="$CDYEAR" \
+ -metadata genre="$CDGENRE" -metadata comment="$COMMENT" "$OUT"
+ else
+ $RUN_COMMAND nice $EFFECTIVE_NICE $MKAENCODER -i "$IN" $MKAENCODEROPTS "$OUT"
+ fi
+ ;;
+ esac
+ ;;
+ aiff)
+ case "$AIFFENCODERSYNTAX" in
+ ffmpeg)
+ if [ "$DOTAG" = "y" ]; then
+ $RUN_COMMAND nice $EFFECTIVE_NICE $AIFFENCODER -i "$IN" $AIFFENCODEROPTS -metadata artist="$TRACKARTIST" \
+ -metadata album="$DALBUM" -metadata title="$TRACKNAME" -metadata track=${TRACKNUM:-$1} -metadata date="$CDYEAR" \
+ -metadata genre="$CDGENRE" -metadata comment="$COMMENT" "$OUT"
+ else
+ $RUN_COMMAND nice $EFFECTIVE_NICE $AIFFENCODER -i "$IN" $AIFFENCODEROPTS "$OUT"
+ fi
+ ;;
+ esac
+ ;;
flac)
case "$2" in
%local*%)
$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).
$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)
$NORMALIZER -b $NORMALIZEROPTS $TRACKFILES
RETURN=$?
if [ "$RETURN" != "0" ]; then
- echo "batch-normalize: $NORMALIZER returned code $RETURN" >> errors
+ echo "batch-normalize: $NORMALIZER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
else
for UTRACKNUM in $TRACKQUEUE
do
- echo normalizetrack-$UTRACKNUM >> status
+ echo "normalizetrack-$UTRACKNUM" >> "$ABCDETEMPDIR/status"
done
fi
)
$NORMALIZER -b $NORMALIZEROPTS $TRACKFILES
RETURN=$?
if [ "$RETURN" != "0" ]; then
- echo "batch-normalize: $NORMALIZER returned code $RETURN" >> errors
+ echo "batch-normalize: $NORMALIZER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
else
for UTRACKNUM in $TRACKQUEUE
do
- echo normalizetrack-$UTRACKNUM >> status
+ echo "normalizetrack-$UTRACKNUM" >> "$ABCDETEMPDIR/status"
done
fi
)
OUTPUT="$TMPOUTPUT"
# Create ALBUMFILE, ARTISTFILE, TRACKFILE
- # Munge filenames as follows:
- # ' ' -> '_'
- # '/' -> '_'
- # ''' -> ''
- # '?' -> ''
- # Eat control characters
- ALBUMFILE="$(mungefilename "$DALBUM")"
- ARTISTFILE="$(mungefilename "$TRACKARTIST")"
- TRACKFILE="$(mungefilename "$TRACKNAME")"
+ ALBUMFILE="$(mungealbumname "$DALBUM")"
+ ARTISTFILE="$(mungeartistname "$TRACKARTIST")"
+ TRACKFILE="$(mungetrackname "$TRACKNAME")"
GENRE="$(mungegenre "$GENRE")"
YEAR=${CDYEAR:-$CDYEAR}
# If we want to start the tracks with a given number, we need to modify
opus)
OUTPUT=$OPUSOUTPUTCONTAINER
;;
+ mka)
+ OUTPUT=$MKAOUTPUTCONTAINER
+ ;;
+ aiff)
+ OUTPUT=$AIFFOUTPUTCONTAINER
+ ;;
flac)
OUTPUT=$FLACOUTPUTCONTAINER
;;
opus)
OUTPUT=$OPUSOUTPUTCONTAINER
;;
+ mka)
+ OUTPUT=$MKAOUTPUTCONTAINER
+ ;;
+ aiff)
+ OUTPUT=$AIFFOUTPUTCONTAINER
+ ;;
flac)
OUTPUT=$FLACOUTPUTCONTAINER
;;
# Create a playlist file for the playlist data to go into.
# We used to wipe it out if it existed. Now we request permission if interactive.
for LASTTRACK in $TRACKQUEUE; do :; done
- ALBUMFILE="$(mungefilename "$DALBUM")"
- ARTISTFILE="$(mungefilename "$DARTIST")"
+ ALBUMFILE="$(mungealbumname "$DALBUM")"
+ ARTISTFILE="$(mungeartistname "$DARTIST")"
GENRE="$(mungegenre "$GENRE")"
YEAR=${CDYEAR:-$CDYEAR}
if [ "$VARIOUSARTISTS" = "y" ] ; then
CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
getcddbinfo TRACKNAME
splitvarious
- TRACKFILE="$(mungefilename "$TRACKNAME")"
- ARTISTFILE="$(mungefilename "$TRACKARTIST")"
- ALBUMFILE="$(mungefilename "$DALBUM")"
+ TRACKFILE="$(mungetrackname "$TRACKNAME")"
+ ARTISTFILE="$(mungeartistname "$TRACKARTIST")"
+ ALBUMFILE="$(mungealbumname "$DALBUM")"
# If we want to start the tracks with a given number, we need to modify the
# TRACKNUM value before evaluation
gettracknum
LEADOUT=$(( $LEADOUT + $LEADIN ))
LENGTH=$(( $LEADOUT/75 - $TRACK1/75 ))
- DISCID=$(( ( $N % 255 ) * 2**24 | $LENGTH * 2**8 | $TRACKS ))
- printf "%08x %i" $DISCID $TRACKS
+ CDDBDISCID=$(( ( $N % 255 ) * 2**24 | $LENGTH * 2**8 | $TRACKS ))
+ printf "%08x %i" $CDDBDISCID $TRACKS
j=1
while [ $j -le $TRACKS ] ; do
# Remaining track index values offset by <pregap value>
#
# Variables used:
-# TRACKINFO
+# CDDBTRACKINFO
abcde.mkcue () {
echomsf () {
fi
vecho "One track is $ONETRACK"
- TRACKFILE="$(mungefilename "$TRACKNAME")"
- ARTISTFILE="$(mungefilename "$TRACKARTIST")"
- ALBUMFILE="$(mungefilename "$DALBUM")"
+ TRACKFILE="$(mungetrackname "$TRACKNAME")"
+ ARTISTFILE="$(mungeartistname "$TRACKARTIST")"
+ ALBUMFILE="$(mungealbumname "$DALBUM")"
if [ "$ONETRACK" = "y" ]; then
if [ "$VARIOUSARTISTS" = "y" ]; then
CUEWAVFILE="$(eval echo \""$VAONETRACKOUTPUTFORMAT"\" | sed -e 's@^.*/@@').$OUTPUT"
CUEWAVFILE="dummy.wav"
fi
- set -- $TRACKINFO
+ set -- $CDDBTRACKINFO
DISCID=$1
TRACKS=$2
# This essentially the start of things
do_discid ()
{
- # Query the CD to get the track info, unless the user specified -C
- # or we are using some actions which do not need the CDDB data at all
- #if [ ! X"$EXPACTIONS" = "X" ]; then
- # :
- #elif [ -z "$DISCID" ]; then
- if [ -z "$DISCID" ]; then
+ if [ -z "$CDDBDISCID" ]; then
vecho -n "Getting CD track info... "
# In OSX, unmount the disc before a query
if [ "$OSFLAVOUR" = "OSX" ]; then
;;
*)
#vecho "Using external python cue2discid implementation..."
- TRACKINFO=$($METAFLAC $METAFLACOPTS --export-cuesheet-to=- "$CDROM" | $CUE2DISCID)
+ CDDBTRACKINFO=$($METAFLAC $METAFLACOPTS --export-cuesheet-to=- "$CDROM" | $CUE2DISCID)
;;
esac
else
exit 1
fi
;;
-# cdparanoia|debug)
-# CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -Q --verbose 2>&1 )"
-# RET=$?
-# if [ ! "$RET" = "0" ];then
-# log warning "something went wrong while querying the CD... Maybe a DATA CD?"
-# fi
-#
-# TRACKS="$(echo "$CDPARANOIAOUTPUT" | grep -E '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ')"
-# CDPARANOIAAUDIOTRACKS="$TRACKS"
-#
-# LEADOUT="$(echo "$CDPARANOIAOUTPUT" | grep -Eo '^TOTAL[[:space:]]+([[:digit:]]+)' | get_last)"
-# OFFSETS="$(echo "$CDPARANOIAOUTPUT" | sed -n -e's/^ .* \([0-9]\+\) \[.*/\1/p')"
-# makeids
-# ;;
+ cdparanoia|debug)
+ CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -Q --verbose 2>&1 )"
+ RET=$?
+ if [ ! "$RET" = "0" ];then
+ log warning "something went wrong while querying the CD... Maybe a DATA CD?"
+ fi
+
+ TRACKS="$(echo "$CDPARANOIAOUTPUT" | grep -E '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ')"
+ CDPARANOIAAUDIOTRACKS="$TRACKS"
+
+ LEADOUT="$(echo "$CDPARANOIAOUTPUT" | grep -Eo '^TOTAL[[:space:]]+([[:digit:]]+)' | get_last)"
+ OFFSETS="$(echo "$CDPARANOIAOUTPUT" | sed -n -e's/^ .* \([0-9]\+\) \[.*/\1/p')"
+ makeids
+ ;;
*)
- case "$CDDBMETHOD" in
- cddb) TRACKINFO=$($CDDISCID "$CDROM") ;;
- musicbrainz) TRACKINFO=$($MUSICBRAINZ --command id --device "$CDROM") ;;
+ # Calculate the cddb discid in all
+ # cases now. We'll use the cddb discid
+ # for reference in most cases for
+ # consistency. Also calculate the
+ # musicbrainz discid if we need it.
+ CDDBTRACKINFO=$($CDDISCID "$CDROM")
+ CDDBDISCID=$(echo $CDDBTRACKINFO | cut -d' ' -f1)
+ case $CDDBMETHOD in
+ *musicbrainz*)
+ MBTRACKINFO=$($MUSICBRAINZ --command id --device "$CDROM")
+ MBDISCID=$(echo $MBTRACKINFO | cut -d' ' -f1)
+ ;;
esac
- ;;
esac
# Make sure there's a CD in there by checking cd-discid's return code
if [ ! "$?" = "0" ]; then
diskutil mount ${CDROM#/dev/}
fi
WEHAVEACD=y
- DISCID=$(echo $TRACKINFO | cut -f1 -d' ')
+ CDDBDISCID=$(echo $CDDBTRACKINFO | cut -f1 -d' ')
else
- TRACKINFO=$(cat "$WAVOUTPUTDIR/abcde.$DISCID/discid")
+ CDDBTRACKINFO=$(cat "$WAVOUTPUTDIR/abcde.$CDDBDISCID/cddbdiscid")
fi
# Get a full enumeration of tracks, sort it, and put it in the TRACKQUEUE.
TRACKNUMPADDING=2
fi
- ABCDETEMPDIR="$WAVOUTPUTDIR/abcde.$(echo $TRACKINFO | cut -f1 -d' ')"
+ ABCDETEMPDIR="$WAVOUTPUTDIR/abcde.$(echo $CDDBTRACKINFO | cut -f1 -d' ')"
if [ -z "$TRACKQUEUE" ]; then
if [ ! "$STRIPDATATRACKS" = "n" ]; then
case "$CDROMREADERSYNTAX" in
- cdparanoia|debug)
+ cdparanoia|libcdio|debug)
if [ "$WEHAVEACD" = "y" ]; then
vecho "Querying the CD for audio tracks..."
CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -Q --verbose 2>&1 )"
rm -f "$ABCDETEMPDIR/cdparanoia-audio-tracks"
fi
if [ -f "$ABCDETEMPDIR/status" ] && TRACKS=$(checkstatus cdparanoia-audio-tracks); then :; else
- TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
+ TRACKS=$(echo $CDDBTRACKINFO | cut -f2 -d' ')
fi
fi
;;
- *) TRACKS=$(echo $TRACKINFO | cut -f2 -d' ') ;;
+ *) TRACKS=$(echo $CDDBTRACKINFO | cut -f2 -d' ') ;;
esac
else
- TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
+ TRACKS=$(echo $CDDBTRACKINFO | cut -f2 -d' ')
fi
if echo "$TRACKS" | grep "[[:digit:]]" > /dev/null 2>&1 ;then :;else
log info "The disc does not contain any tracks. Giving up..."
done
echo $TRACKQUEUE
else
- TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
+ TRACKS=$(echo $CDDBTRACKINFO | cut -f2 -d' ')
# User-supplied track queue.
# Weed out non-numbers, whitespace, then sort and weed out duplicates
TRACKQUEUE=$(echo $TRACKQUEUE | sed 's-[^0-9 ]--g' | tr ' ' '\n' | grep -v ^$ | sort -n | uniq | tr '\n' ' ' | sed 's- $--g')
fi
echo .
# See if it's populated
- if [ ! -f "$ABCDETEMPDIR/discid" ]; then
+ if [ ! -f "$ABCDETEMPDIR/cddbdiscid" ]; then
# Wipe and start fresh
- echo "abcde: $ABCDETEMPDIR/discid not found. Abcde must remove and recreate" >&2
+ echo "abcde: $ABCDETEMPDIR/cddbdiscid not found. Abcde must remove and recreate" >&2
echo -n "this directory to continue. Continue [y/N]? " >&2
if [ "$INTERACTIVE" = "y" ]; then
read ANSWER
fi
if [ X"$DOCUE" = "Xy" -a X"$WEHAVEACD" = "Xy" ]; then
if checkstatus cuefile > /dev/null 2>&1 ; then :; else
- CUEFILE=cue-$(echo "$TRACKINFO" | cut -f1 -d' ').txt
+ CUEFILE=cue-$(echo "$CDDBTRACKINFO" | cut -f1 -d' ').txt
vecho "Creating cue file..."
case $CDROMREADERSYNTAX in
flac)
fi
fi
- # Create the discid file
- echo "$TRACKINFO" > "$ABCDETEMPDIR/discid"
- if checkstatus cddbmethod > /dev/null 2>&1 ; then :; else
- echo "cddbmethod=$CDDBMETHOD" >> "$ABCDETEMPDIR/status"
- fi
+ # Create the discid files
+ echo "$CDDBTRACKINFO" > "$ABCDETEMPDIR/cddbdiscid"
+ case $CDDBMETHOD in
+ *musicbrainz*)
+ echo "$MBTRACKINFO" > "$ABCDETEMPDIR/mbdiscid"
+ ;;
+ esac
}
# do_cleancue
elif [ "$ONETRACK" = "y" ] &&
echo "$line" | grep '^FILE "dummy.wav" WAVE' > /dev/null 2>&1 ; then
- TRACKFILE="$(mungefilename "$TRACKNAME")"
- ARTISTFILE="$(mungefilename "$TRACKARTIST")"
- ALBUMFILE="$(mungefilename "$DALBUM")"
+ TRACKFILE="$(mungetrackname "$TRACKNAME")"
+ ARTISTFILE="$(mungeartistname "$TRACKARTIST")"
+ ALBUMFILE="$(mungealbumname "$DALBUM")"
if [ "$VARIOUSARTISTS" = "y" ]; then
OUTPUTFILE="$(eval echo \""$VAONETRACKOUTPUTFORMAT"\" | sed -e 's@^.*/@@').$OUTPUT"
if [ "$ONETRACK" = "y" ]; then
vecho "ONETRACK mode selected: displaying only the title of the CD..."
fi
- echo "---- $(grep DTITLE "${CDDBPARSEFILE}" | cut '-d=' -f2- | tr -d \\r\\n ) ----"
+ echo "---- $(grep -a DTITLE "${CDDBPARSEFILE}" | cut '-d=' -f2- | tr -d \\r\\n ) ----"
if [ X"$SHOWCDDBYEAR" = "Xy" ]; then
- PARSEDYEAR=$(grep DYEAR "${CDDBPARSEFILE}" | cut '-d=' -f2-)
+ PARSEDYEAR=$(grep -a DYEAR "${CDDBPARSEFILE}" | cut '-d=' -f2-)
if [ ! X"$PARSEDYEAR" = "X" ]; then
echo "Year: $PARSEDYEAR"
fi
fi
if [ X"$SHOWCDDBGENRE" = "Xy" ]; then
- PARSEDGENRE=$(grep DGENRE "${CDDBPARSEFILE}" | cut '-d=' -f2-)
+ PARSEDGENRE=$(grep -a DGENRE "${CDDBPARSEFILE}" | cut '-d=' -f2-)
if [ ! X"$PARSEDGENRE" = "X" ]; then
echo "Genre: $PARSEDGENRE"
fi
if [ ! "$ONETRACK" = "y" ]; then
for TRACK in $(f_seq_row 1 $TRACKS)
do
- echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "${CDDBPARSEFILE}" | cut -f2- -d= | tr -d \\r\\n)"
+ echo $TRACK: "$(grep -a ^TTITLE$(expr $TRACK - 1)= "${CDDBPARSEFILE}" | cut -f2- -d= | tr -d \\r\\n)"
done
fi
}
-# do_localcddb
+# do_localcddb_read
# Check for a local CDDB file, and report success
-do_localcddb ()
+do_localcddb_read ()
{
if checkstatus cddb-readcomplete && checkstatus cddb-choice >/dev/null; then :; else
CDDBLOCALSTATUS="notfound"
- CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
+ CDDBDISCID=$(echo $CDDBTRACKINFO | cut -d' ' -f1)
USELOCALRESP="y"
if [ "$CDDBLOCALRECURSIVE" = "y" ]; then
#echo "Using local copy of CDDB data"
echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "$ABCDETEMPDIR/cddbread.1"
cat "$ABCDETEMPDIR/cddblocalread.$CDDBLOCALCHOICENUM" >> "$ABCDETEMPDIR/cddbread.1"
+ echo "local" > "$ABCDETEMPDIR/datasource.1"
echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB
echo cddb-readcomplete >> "$ABCDETEMPDIR/status"
do_cddbparse "$ABCDETEMPDIR/cddbread.1" > "$ABCDETEMPDIR/cddbchoices"
#echo "Using local copy of CDDB data"
echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "$ABCDETEMPDIR/cddbread.1"
cat "${CDDBLOCALFILE}" >> "$ABCDETEMPDIR/cddbread.1"
+ echo "local" > "$ABCDETEMPDIR/datasource.1"
echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB
echo cddb-readcomplete >> "$ABCDETEMPDIR/status"
do_cddbparse "${CDDBLOCALFILE}" > "$ABCDETEMPDIR/cddbchoices"
fi
}
-# do_cdtext
+# do_cdtext_read
# Try to read CD-Text from the drive using icedax / cdda2wav
-do_cdtext ()
+do_cdtext_read ()
{
if new_checkexec icedax; then
CDTEXT_READER=icedax
elif new_checkexec cdda2wav; then
CDTEXT_READER=cdda2wav
- else
+ else
# Didn't find either, bail
return 0
fi
+ vecho "Obtaining CD-Text results..."
+ CDTDISCID=$(echo $CDDBTRACKINFO | cut -d' ' -f1)
+ local SOURCE_WORKDIR="$ABCDETEMPDIR/data-cdtext"
+ mkdir -p "${SOURCE_WORKDIR}"
+
if [ "$OSFLAVOUR" = "OSX" ] ; then
# Hei, we have to unmount the device before running anything like cdda2wav/icedax in OSX
diskutil unmount ${CDROM#/dev/}
fi
# Do we have CD-Text on the disc (and can the drive read it?)
- ${CDTEXT_READER} -J -N -D ${CDDA2WAVCDROM} > "$ABCDETEMPDIR/cd-text" 2>&1
- grep -q '^CD-Text: detected' "$ABCDETEMPDIR/cd-text"
+ (
+ cd "${SOURCE_WORKDIR}" && rm -f audio.* audio_*
+ ${CDTEXT_READER} -J -v titles -D ${CDDA2WAVCDROM} > "${SOURCE_WORKDIR}/cd-text" 2>&1
+ )
+ grep -a -q '^CD-Text: detected' "${SOURCE_WORKDIR}/cd-text"
ERRORCODE=$?
if [ $ERRORCODE -ne 0 ]; then
# No CD-Text found, bail
return 0
fi
- rm -f "$ABCDETEMPDIR/cddbchoices"
- CDDBCHOICES=1
+ NUM_CDDB_MATCHES=$(($NUM_CDDB_MATCHES + 1))
# Make an empty template
- $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.1"
- echo -n "Retrieved 1 CD-Text match..." >> "$ABCDETEMPDIR/cddbchoices"
- echo "done." >> "$ABCDETEMPDIR/cddbchoices"
- echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
- echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
- ATITLE=$(grep -e '^Album title:' "${ABCDETEMPDIR}/cd-text" | cut -c14- )
- echo "200 none ${ATITLE}" >> "$ABCDETEMPDIR/cddbquery"
- # List out disc title/author and contents
- echo ---- ${ATITLE} ---- >> "$ABCDETEMPDIR/cddbchoices"
- for TRACK in $(f_seq_row 1 $TRACKS)
- do
- TRACKM1=$(($TRACK - 1))
- TITLE="$(grep -E ^Track\ +$TRACK: "$ABCDETEMPDIR/cd-text" | tr -d \\r\\n | sed 's~^Track ..: .~~g;'"s~'$~~g")"
- echo "$TRACK: $TITLE" >> "$ABCDETEMPDIR/cddbchoices"
- sed "s~^TTITLE${TRACKM1}=.*~TTITLE${TRACKM1}=${TITLE}~" "$ABCDETEMPDIR/cddbread.1" > "$ABCDETEMPDIR/cddbread.new"
- mv -f "$ABCDETEMPDIR/cddbread.new" "$ABCDETEMPDIR/cddbread.1"
- done
- sed "s~^DTITLE=.*~DTITLE=${ATITLE}~" "$ABCDETEMPDIR/cddbread.1" > "$ABCDETEMPDIR/cddbread.new"
- mv -f "$ABCDETEMPDIR/cddbread.new" "$ABCDETEMPDIR/cddbread.1"
- echo >> "$ABCDETEMPDIR/cddbchoices"
+ $CDDBTOOL template $(cat "${ABCDETEMPDIR}/cddbdiscid") > "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}"
+ echo cddb-read-${NUM_CDDB_MATCHES}-complete >> "${ABCDETEMPDIR}/status"
+ rm -f "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}"
+
+ # XXX FIXME - this is a hack and should be replaced by proper
+ # character set tracking for the CDDB data we have.
+ if test "$CDDBPROTO" -ge 6 ; then
+ # convert to Unicode
+ iconv -f iso-8859-1 -t utf-8 <"${SOURCE_WORKDIR}/audio.cddb" >"${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}"
+ else
+ # copy verbatim, assuming CD-TEXT is in ISO-8859-1 format
+ # apparently icedax/cdda2wav have no support for 16-bit
+ # characters yet, either
+ cp -p "${SOURCE_WORKDIR}/audio.cddb" "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}"
+ fi
+
+ CDDBDISCID=$(echo $CDDBTRACKINFO | cut -d' ' -f1)
+ ATITLE=$(grep -a -e '^DTITLE=' "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}" | cut -c8- | tr -d \\r\\n)
+ echo "CD-Text" > ${SOURCE_WORKDIR}/datasource.${NUM_CDDB_MATCHES}
+ echo "none $CDDBDISCID ${ATITLE}" >> "${SOURCE_WORKDIR}/cddbquery.${NUM_CDDB_MATCHES}"
+
+ ( cd "${SOURCE_WORKDIR}" && rm -f audio_* audio.* )
+ cp "${SOURCE_WORKDIR}/"*."${NUM_CDDB_MATCHES}" "$ABCDETEMPDIR"
echo "cdtext-readcomplete" >> "$ABCDETEMPDIR/status"
}
-# do_musicbrainz
+# do_musicbrainz_read
# Work with the musicbrainz WS API, then transform the results here so
# they look (very) like the results from CDDB. Maybe not the best way
# to go, but it Works For Me (TM)
-
-do_musicbrainz ()
+#
+# List out all the matches individually into $SOURCE_WORKDIR/cddbread.X
+#
+do_musicbrainz_read ()
{
if checkstatus musicbrainz-readcomplete; then :; else
vecho "Obtaining Musicbrainz results..."
# If MB is to be used, interpret the query results and read all
# the available entries.
- rm -f "$ABCDETEMPDIR/cddbchoices"
- CDDBCHOICES=1 # Overridden by multiple matches
- MBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
- ${MUSICBRAINZ} --command data --discid "$MBDISCID" --workdir "$ABCDETEMPDIR"
+ CDDBDISCID=$(echo $CDDBTRACKINFO | cut -d' ' -f1)
+ MBDISCID=$(echo $MBTRACKINFO | cut -d' ' -f1)
+ local SOURCE_WORKDIR="${ABCDETEMPDIR}/data-musicbrainz"
+ mkdir -p "${SOURCE_WORKDIR}"
+ ${MUSICBRAINZ} --command data --discid "$MBDISCID" --workdir "${SOURCE_WORKDIR}" --start ${NUM_CDDB_MATCHES}
+ # Check for no matches.
# The helper script will write disc matches out to
# cddbread.*. Count how many we have
- if [ ! -f "${ABCDETEMPDIR}/cddbread.1" ] ; then
- # No matches. Use the normal cddb template for the user to
- # fill in
- echo "No Musicbrainz match." >> "$ABCDETEMPDIR/cddbchoices"
- $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
- # List out disc title/author and contents of template
- echo ---- Unknown Artist / Unknown Album ---- >> "$ABCDETEMPDIR/cddbchoices"
- UNKNOWNDISK=y
- for TRACK in $(f_seq_row 1 $TRACKS)
- do
- echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.0" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
+ NUM_RESPONSES=$(echo "${SOURCE_WORKDIR}"/cddbread.* | wc -w)
+ if [ "$NUM_RESPONSES" -gt 0 ] ; then
+ # One or more exact matches
+ i=1
+ while [ $i -le $NUM_RESPONSES ]; do
+ NUM_CDDB_MATCHES=$(($NUM_CDDB_MATCHES + 1))
+ i=$(($i + 1))
+ echo cddb-read-${NUM_CDDB_MATCHES}-complete >> "$ABCDETEMPDIR/status"
+ ATITLE=$(grep -a -e '^DTITLE=' "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}" | cut -c8- | tr -d \\r\\n)
+ echo "none $CDDBDISCID ${ATITLE}" >> "${SOURCE_WORKDIR}/cddbquery.${NUM_CDDB_MATCHES}"
+ echo "Musicbrainz" > "${SOURCE_WORKDIR}/datasource.${NUM_CDDB_MATCHES}"
+ cp -f "${SOURCE_WORKDIR}/"*."${NUM_CDDB_MATCHES}" "$ABCDETEMPDIR"
done
- echo >> "$ABCDETEMPDIR/cddbchoices"
- echo cddb-read-0-complete >> "$ABCDETEMPDIR/status"
- echo cddb-choice=0 >> "$ABCDETEMPDIR/status"
- echo 503 > "$ABCDETEMPDIR/cddbquery"
- else
- # We have some matches
- NUM_RESPONSES=$(echo "${ABCDETEMPDIR}"/cddbread.* | wc -w)
- if [ "$NUM_RESPONSES" -eq 1 ] ; then
- # One exact match
- echo -n "Retrieved 1 Musicbrainz match..." >> "$ABCDETEMPDIR/cddbchoices"
- echo "done." >> "$ABCDETEMPDIR/cddbchoices"
- echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
- echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
- ATITLE=$(grep -e '^DTITLE=' "${ABCDETEMPDIR}/cddbread.1" | cut -c8- )
- echo "200 none ${ATITLE}" >> "$ABCDETEMPDIR/cddbquery"
- # List out disc title/author and contents
- echo ---- ${ATITLE} ---- >> "$ABCDETEMPDIR/cddbchoices"
- for TRACK in $(f_seq_row 1 $TRACKS)
- do
- echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
- done
- echo >> "$ABCDETEMPDIR/cddbchoices"
- else
- echo "210 Found exact matches, list follows (until terminating .)" > "$ABCDETEMPDIR/cddbquery"
- echo "Multiple Musicbrainz matches:" >> "$ABCDETEMPDIR/cddbchoices"
- for file in "$ABCDETEMPDIR"/cddbread.*
- do
- X=$(echo $file | sed 's/^.*cddbread\.//g')
- echo cddb-read-$X-complete >> "$ABCDETEMPDIR/status"
- ATITLE=$(grep -e '^DTITLE=' "${ABCDETEMPDIR}"/cddbread.$X | cut -c8- )
- echo "none ${ATITLE}" >> "$ABCDETEMPDIR/cddbquery"
- # List out disc title/author and contents
- echo "#$X: ---- ${ATITLE} ----" >> "$ABCDETEMPDIR/cddbchoices"
- for TRACK in $(f_seq_row 1 $TRACKS)
- do
- echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.$X" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
- done
- echo >> "$ABCDETEMPDIR/cddbchoices"
- done
- echo "." >> "$ABCDETEMPDIR/cddbquery"
- fi
fi
echo "musicbrainz-readcomplete" >> "$ABCDETEMPDIR/status"
fi
}
-# do_cddbstat
-do_cddbstat ()
+# do_cddb_read
+do_cddb_read ()
{
+ local SOURCE_WORKDIR="${ABCDETEMPDIR}/data-cddb"
+ mkdir -p "${SOURCE_WORKDIR}"
+
+ ###########
+ # cddbstat
+ ###########
+
# Perform CDDB protocol version check if it hasn't already been done
if checkstatus cddb-statcomplete; then :; else
if [ "$CDDBAVAIL" = "n" ]; then
ERRORCODE=no_query
- echo 503 > "$ABCDETEMPDIR/cddbstat"
+ echo 503 > "${SOURCE_WORKDIR}/cddbstat"
else
rc=1
CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
while test $rc -eq 1 -a $CDDBPROTO -ge 3; do
vecho "Checking CDDB server status..."
- $CDDBTOOL stat $CDDBURL $CDDBUSER $CDDBHOST $CDDBPROTO > "$ABCDETEMPDIR/cddbstat"
- RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbstat" | cut -f1 -d' ')
+ $CDDBTOOL stat $CDDBURL $CDDBUSER $CDDBHOST $CDDBPROTO > "${SOURCE_WORKDIR}/cddbstat"
+ RESPONSECODE=$(head -n 1 "${SOURCE_WORKDIR}/cddbstat" | cut -f1 -d' ')
case "$RESPONSECODE" in
210) # 210 OK, status information follows (until terminating `.')
rc=0
;;
*) # Try a cddb query, since freedb2.org doesn't support the stat or ver commands
# FreeDB TESTCD disc-id is used for query
- $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST 03015501 1 296 344 > "$ABCDETEMPDIR/cddbstat"
- RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbstat" | cut -f1 -d' ')
+ $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST 03015501 1 296 344 > "${SOURCE_WORKDIR}/cddbstat"
+ RESPONSECODE=$(head -n 1 "${SOURCE_WORKDIR}/cddbstat" | cut -f1 -d' ')
case "$RESPONSECODE" in
2??) # Server responded, everything seems OK
rc=0
fi
echo cddb-statcomplete >> "$ABCDETEMPDIR/status"
fi
-}
+ ###########
+ # cddbquery
+ ###########
-# do_cddbquery
-do_cddbquery ()
-{
- CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
+ CDDBDISCID=$(echo $CDDBTRACKINFO | cut -d' ' -f1)
CDDBLOCALFILE="${CDDBLOCALDIR}/${CDDBDISCID}"
# Perform CDDB query if it hasn't already been done
if checkstatus cddb-querycomplete; then :; else
if [ "$CDDBAVAIL" = "n" ]; then
ERRORCODE=no_query
- echo 503 > "$ABCDETEMPDIR/cddbquery"
+ echo 503 > "${SOURCE_WORKDIR}/cddbquery"
# The default CDDBLOCALSTATUS is "notfound"
# This part will be triggered if the user CDDB repo does not
# contain the entry, or if we are not trying to use the repo.
vecho "Querying the CDDB server..."
CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
- $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $TRACKINFO > "$ABCDETEMPDIR/cddbquery"
+ $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $CDDBTRACKINFO > "${SOURCE_WORKDIR}/cddbquery"
ERRORCODE=$?
case $ERRORCODE in
0) # success
;;
12|13|14)
- # no match found in database,
- # wget/fetch error, or user requested not to use CDDB
- # Make up an error code (503) that abcde
- # will recognize in do_cddbread
+ # no match found in database, wget/fetch error,
+ # or user requested not to use CDDB. Make up an
+ # error code (503) that abcde will recognize later
# and compensate by making a template
- echo 503 > "$ABCDETEMPDIR/cddbquery"
+ echo 503 > "${SOURCE_WORKDIR}/cddbquery"
;;
*) # strange and unknown error
echo ERRORCODE=$ERRORCODE
fi
echo cddb-querycomplete >> "$ABCDETEMPDIR/status"
fi
-}
-# do_cddbread
-do_cddbread ()
-{
+ ###########
+ # cddbread
+ ###########
+
# If it's not to be used, generate a template.
# Then, display it (or them) and let the user choose/edit it
if checkstatus cddb-readcomplete; then :; else
+ RESPONSECODE=$(head -n 1 "${SOURCE_WORKDIR}/cddbquery" | cut -f1 -d' ')
vecho "Obtaining CDDB results..."
- # If CDDB is to be used, interpret the query results and read all
- # the available entries.
- rm -f "$ABCDETEMPDIR/cddbchoices"
- CDDBCHOICES=1 # Overridden by multiple matches
- RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbquery" | cut -f1 -d' ')
case "$RESPONSECODE" in
200)
# One exact match, retrieve it
# 200 [section] [discid] [artist] / [title]
- if checkstatus cddb-read-1-complete; then :; else
- echo -n "Retrieving 1 CDDB match..." >> "$ABCDETEMPDIR/cddbchoices"
- $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(cut -f2,3 -d' ' "$ABCDETEMPDIR/cddbquery") > "$ABCDETEMPDIR/cddbread.1"
- echo "done." >> "$ABCDETEMPDIR/cddbchoices"
- echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
- echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
- fi
- # List out disc title/author and contents
- echo ---- "$(cut '-d ' -f4- "$ABCDETEMPDIR/cddbquery")" ---- >> "$ABCDETEMPDIR/cddbchoices"
- for TRACK in $(f_seq_row 1 $TRACKS)
- do
- echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
- done
- echo >> "$ABCDETEMPDIR/cddbchoices"
+ NUM_CDDB_MATCHES=$(($NUM_CDDB_MATCHES + 1))
+ $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(cut -f2,3 -d' ' "${SOURCE_WORKDIR}/cddbquery") > "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}"
+ cat ${SOURCE_WORKDIR}/cddbquery | cut -f2- -d' ' > ${SOURCE_WORKDIR}/cddbquery.${NUM_CDDB_MATCHES}
+ echo "cddb" > ${SOURCE_WORKDIR}/datasource.${NUM_CDDB_MATCHES}
+ echo cddb-read-${NUM_CDDB_MATCHES}-complete >> "${ABCDETEMPDIR}/status"
;;
- 202|403|409|503)
- # No match
- case "$RESPONSECODE" in
- 202) echo "No CDDB match." >> "$ABCDETEMPDIR/cddbchoices" ;;
- 403|409) echo "CDDB entry is corrupt, or the handshake failed." >> "$ABCDETEMPDIR/cddbchoices" ;;
- 503) echo "CDDB unavailable." >> "$ABCDETEMPDIR/cddbchoices" ;;
- esac
- $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
- # List out disc title/author and contents of template
- echo ---- Unknown Artist / Unknown Album ---- >> "$ABCDETEMPDIR/cddbchoices"
- UNKNOWNDISK=y
- for TRACK in $(f_seq_row 1 $TRACKS)
- do
- echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.0" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
- done
- echo >> "$ABCDETEMPDIR/cddbchoices"
- echo cddb-read-0-complete >> "$ABCDETEMPDIR/status"
- echo cddb-choice=0 >> "$ABCDETEMPDIR/status"
+ 202|403|409|500|503)
+ # TODO: Explain these error codes a little more accurately:
+ # http://ftp.freedb.org/pub/freedb/misc/freedb_CDDB_protcoldoc.zip
+ # No match response:
;;
210|211)
# Multiple exact, (possibly multiple) inexact matches
- IN=
- if [ "$RESPONSECODE" = "211" ]; then IN=in; fi
- if [ "$(wc -l < "$ABCDETEMPDIR/cddbquery" | tr -d ' ')" -eq 3 ]; then
- echo "One ${IN}exact match:" >> "$ABCDETEMPDIR/cddbchoices"
- tail -n +2 "$ABCDETEMPDIR/cddbquery" | head -n 1 >> "$ABCDETEMPDIR/cddbchoices"
- echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
- else
- echo "Multiple ${IN}exact matches:" >> "$ABCDETEMPDIR/cddbchoices"
- fi
vecho -n "Retrieving multiple matches... "
- grep -v ^[.]$ "$ABCDETEMPDIR/cddbquery" | ( X=0
- read DISCINFO # eat top line
- while read DISCINFO
- do
- X=$(expr $X + 1)
- if checkstatus cddb-read-$X-complete; then :; else
- $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(echo $DISCINFO | cut -f1,2 -d' ') > "$ABCDETEMPDIR/cddbread.$X"
- echo cddb-read-$X-complete >> "$ABCDETEMPDIR/status"
- fi
- # List out disc title/author and contents
- echo \#$X: ---- "$DISCINFO" ---- >> "$ABCDETEMPDIR/cddbchoices"
- for TRACK in $(f_seq_row 1 $TRACKS)
+ grep -v ^[.]$ "${SOURCE_WORKDIR}/cddbquery" | (
+ read DISCINFO # eat top line
+ while read DISCINFO
do
- echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.$X" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
- done
- echo >> "$ABCDETEMPDIR/cddbchoices"
- done )
+ NUM_CDDB_MATCHES=$(($NUM_CDDB_MATCHES + 1))
+ if checkstatus cddb-read-${NUM_CDDB_MATCHES}-complete; then :; else
+ $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(echo $DISCINFO | cut -f1,2 -d' ') > "${SOURCE_WORKDIR}/cddbread.${NUM_CDDB_MATCHES}"
+ echo "$DISCINFO" > ${SOURCE_WORKDIR}/cddbquery.${NUM_CDDB_MATCHES}
+ echo "cddb/$CDDBHOST" > ${SOURCE_WORKDIR}/datasource.${NUM_CDDB_MATCHES}
+ echo cddb-read-${NUM_CDDB_MATCHES}-complete >> "$ABCDETEMPDIR/status"
+ fi
+ done )
vecho "done."
- CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
;;
999)
# Using local copy.
- for TRACK in $(f_seq_row 1 $TRACKS)
- do
- echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
- done
- echo >> "$ABCDETEMPDIR/cddbchoices"
- echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
- echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
+ NUM_CDDB_MATCHES=$(($NUM_CDDB_MATCHES + 1))
+ echo cddb-read-${NUM_CDDB_MATCHES}-complete >> "$ABCDETEMPDIR/status"
;;
esac
echo "cddb-readcomplete" >> "$ABCDETEMPDIR/status"
+ cp -f "${SOURCE_WORKDIR}/"*.* "$ABCDETEMPDIR"
fi
}
# Display the $ABCDETEMPDIR/cddbchoices file created above
# Pick a pager so that if the tracks overflow the screen the user can still view everything
if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
- CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
CHOICE=$(checkstatus cddb-choice)
if [ -n "$CHOICE" ] ; then
- case $CDDBCHOICES in
- -1) if head -1 "$ABCDETEMPDIR/cddbquery" | grep "^$" > /dev/null 2>&1 ; then
- log error "CDDB query failed!"
- exit 1
- else
- cat "$ABCDETEMPDIR/cddbchoices"
- fi
- ;;
+ case $NUM_CDDB_MATCHES in
1) cat "$ABCDETEMPDIR/cddbchoices" ;;
*)
- echo "Selected: #$CHOICE"
+ ATITLE=$(grep -a ^DTITLE= "$ABCDETEMPDIR/cddbread.$CHOICE" | cut -f2- -d= | tr -d \\r\\n)
+ SOURCE=$(cat "${ABCDETEMPDIR}/datasource.$CHOICE")
+ echo "Selected: #$CDCHOICENUM ($SOURCE) ($ATITLE)"
do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
;;
esac
# Setting the choice to an impossible integer to avoid errors in the numeric comparisons
CDCHOICENUM=-1
# I'll take CDDB read #3 for $400, Alex
- while [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; do
- echo -n "Which entry would you like abcde to use (0 for none)? [0-$CDDBCHOICES]: " >&2
+ while [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $NUM_CDDB_MATCHES ]; do
+ echo -n "Which entry would you like abcde to use (0 for none)? [0-$NUM_CDDB_MATCHES]: " >&2
read CDDBCHOICE
[ X"$CDDBCHOICE" = "X" ] && CDDBCHOICE=1
if echo $CDDBCHOICE | grep -E "[[:space:]]*[[:digit:]]+,[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
if [ ! X"$DIFF" = "X" ]; then
PARSECHOICE1=$(echo $CDDBCHOICE | cut -d"," -f1 | xargs printf %d 2>/dev/null)
PARSECHOICE2=$(echo $CDDBCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null)
- if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBCHOICES ] || \
- [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBCHOICES ] || \
+ if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $NUM_CDDB_MATCHES ] || \
+ [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $NUM_CDDB_MATCHES ] || \
[ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then
- echo "Invalid diff range. Please select two comma-separated numbers between 1 and $CDDBCHOICES" >&2
+ echo "Invalid diff range. Please select two comma-separated numbers between 1 and $NUM_CDDB_MATCHES" >&2
else
# We parse the 2 choices to diff, store them in temporary files and diff them.
for PARSECHOICE in $(echo $CDDBCHOICE | tr , \ ); do
fi
fi
else
- echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBCHOICES." >&2
+ echo "The diff program was not found in your path. Please choose a number between 0 and $NUM_CDDB_MATCHES." >&2
fi
elif echo $CDDBCHOICE | grep -E "[[:space:]]*[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
# Make sure we get a valid choice
CDCHOICENUM=$(echo $CDDBCHOICE | xargs printf %d 2>/dev/null)
- if [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; then
- echo "Invalid selection. Please choose a number between 0 and $CDDBCHOICES." >&2
+ if [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $NUM_CDDB_MATCHES ]; then
+ echo "Invalid selection. Please choose a number between 0 and $NUM_CDDB_MATCHES." >&2
fi
fi
done
if [ "$CDCHOICENUM" = "0" ]; then
vecho "Creating empty CDDB template..."
UNKNOWNDISK=y
- $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
+ $CDDBTOOL template $(cat "$ABCDETEMPDIR/cddbdiscid") > "$ABCDETEMPDIR/cddbread.0"
else
- echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
+ ATITLE=$(grep -a ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n)
+ SOURCE=$(cat "${ABCDETEMPDIR}/datasource.$CDCHOICENUM")
+ echo "Selected: #$CDCHOICENUM ($SOURCE) ($ATITLE)" >&2
do_cddbparse "$ABCDETEMPDIR/cddbread.$CDCHOICENUM"
fi
echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
# Display the $ABCDETEMPDIR/cddbchoices file created above
# Pick a pager so that if the tracks overflow the screen the user can still view everything
if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
- CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
CHOICE=$(checkstatus cddb-choice)
if [ "$USELOCALRESP" = "y" ]; then :; else
if [ -n "$CHOICE" ] ; then
- case $CDDBCHOICES in
+ case $NUM_CDDB_MATCHES in
0)
UNKNOWNDISK=y
echo "Selected template."
CDCHOICENUM=1
echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
fi
- echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
+ echo "Selected: #$CDCHOICENUM ($(grep -a ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
fi
fi
exit 1
fi
CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
+ CDDBSOURCE=$(cat "$ABCDETEMPDIR/datasource.$(checkstatus cddb-choice)")
echo -n "Edit selected CDDB data " >&2
if [ "$INTERACTIVE" = "y" ]; then
if [ "$UNKNOWNDISK" = "y" ]; then
# Some heuristics first. Look at Disc Title, and if it starts with
# "Various", then we'll assume Various Artists
- if [ "$(grep ^DTITLE= "$CDDBDATA" | cut -f2- -d= | grep -Eci '^(various|soundtrack|varios|sonora|ost)')" != "0" ]; then
+ if [ "$(grep -a ^DTITLE= "$CDDBDATA" | cut -f2- -d= | grep -aEci '^(various|soundtrack|varios|sonora|ost)')" != "0" ]; then
echo "Looks like a Multi-Artist CD" >&2
VARIOUSARTISTS=y
else
# Set a default
DEFAULTSTYLE=1
# Need NUMTRACKS before cddb-tool will return it:
- NUMTRACKS=$(grep -E '^TTITLE[0-9]+=' "$CDDBDATA" | wc -l)
- if [ "$(grep -c "^TTITLE.*\/" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
+ NUMTRACKS=$(grep -a -E '^TTITLE[0-9]+=' "$CDDBDATA" | wc -l)
+ if [ "$(grep -ac "^TTITLE.*\/" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
# More than 1/2 tracks contain a "/", so guess forward
DEFAULTSTYLE=1
- elif [ "$(grep -c "^TTITLE.*\-" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
+ elif [ "$(grep -ac "^TTITLE.*\-" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
# More than 1/2 contain a "-", so guess forward-dash
DEFAULTSTYLE=2
- elif [ "$(grep -c "^TTITLE.*(.*)" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
+ elif [ "$(grep -ac "^TTITLE.*(.*)" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
# More than 1/2 contain something in parens, so guess trailing-paren
DEFAULTSTYLE=6
fi
echo "variousartists=$VARIOUSARTISTS" >> "$ABCDETEMPDIR/status"
echo "variousartiststyle=$VARIOUSARTISTSTYLE" >> "$ABCDETEMPDIR/status"
- if [ "$EDITCDDB" = "y" ] && [ "$CDDBMETHOD" = "cddb" ] && [ "$UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE" = "y" ]; then
+ if [ "$EDITCDDB" = "y" ] && [ "$CDDBSOURCE" = "cddb" ] && [ "$UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE" = "y" ]; then
if [ "$CDDBDATAMD5SUM" != "" ] && [ "$CDDBDATAMD5SUM" != "$($MD5SUM "$CDDBDATA" | cut -d " " -f 1)" ]; then
# This works but does not have the necessary error checking
# yet. If you are familiar with the CDDB spec
if [ "$CDDBCOPYLOCAL" = "y" ]; then
# Make sure the cache directory exists
mkdir -p $CDDBLOCALDIR
- cat "$CDDBDATA" | tail -n $(expr $(cat "$CDDBDATA" | wc -l ) - 1 ) > ${CDDBLOCALDIR}/$(echo "$TRACKINFO" | cut -d' ' -f1)
+ cat "$CDDBDATA" | tail -n $(expr $(cat "$CDDBDATA" | wc -l ) - 1 ) > ${CDDBLOCALDIR}/$(echo "$CDDBTRACKINFO" | cut -d' ' -f1)
fi
echo "cddb-edit" >> "$ABCDETEMPDIR/status"
}
+# do_getalbumart
+# try to download CD cover
+do_getalbumart()
+{
+ # set variables
+ ALBUMFILE="$(mungealbumname "$DALBUM")"
+ ARTISTFILE="$(mungeartistname "$DARTIST")"
+ GENRE="$(mungegenre "$GENRE")"
+ YEAR=${CDYEAR:-$CDYEAR}
+ # have we got a musicbrainz mbid or amazon asin?
+ case "$CDDBMETHOD" in
+ *musicbrainz*)
+ # 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
+}
+
+# Optionally embed the albumart downloaded by the getalbumart fuction.
+# FIXME: It would be nice to have this also selectable from within the
+# FIXME: getalbumart function itself. Andrew
+do_embedalbumart()
+{
+ # Set variables:
+ ALBUMFILE="$(mungealbumname "$DALBUM")"
+ ARTISTFILE="$(mungeartistname "$DARTIST")"
+ GENRE="$(mungegenre "$GENRE")"
+ YEAR=${CDYEAR:-$CDYEAR}
+
+ # Allow for multiple output formats:
+ for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
+ do
+ # Find the output directory for multi track encodes:
+ if [ "$ONETRACK" != "y" ] ; then
+ if [ "$VARIOUSARTISTS" = "y" ] ; then
+ FINDPATH="$(eval echo "$VAOUTPUTFORMAT")"
+ else
+ FINDPATH="$(eval echo "$OUTPUTFORMAT")"
+ fi
+ fi
+ # Find the output directory for single track encodes:
+ if [ "$ONETRACK" = "y" ] ; then
+ if [ "$VARIOUSARTISTS" = "y" ] ; then
+ FINDPATH="$(eval echo "$VAONETRACKOUTPUTFORMAT")"
+ else
+ FINDPATH="$(eval echo "$ONETRACKOUTPUTFORMAT")"
+ fi
+ fi
+
+ FINALDIR="$(dirname "$OUTPUTDIR/$FINDPATH")"
+ cd "$FINALDIR"
+
+# Instructions for each format, feel free to add more. It would be nice to
+# make the backup directory selectable and perhaps also have an option for
+# the bold to simply have the image deleted. Work for another day... Andrew.
+ if [ -e "$ALBUMARTFILE" ] ; then
+ case "$OUTPUT" in
+ mp3)
+ for i in *.mp3
+ do
+ "$EYED3" --add-image "$ALBUMARTFILE":FRONT_COVER "$i"
+ done
+ mkdir "$FINALDIR"/albumart_backup
+ mv "$ALBUMARTFILE" "$FINALDIR"/albumart_backup
+ vecho "Successfully embedded the album art into your $OUTPUT tracks" >&2
+ ;;
+ flac)
+ for i in *.flac
+ do
+ "$METAFLAC" --import-picture-from="$ALBUMARTFILE" "$i"
+ done
+ mkdir "$FINALDIR"/albumart_backup
+ mv "$ALBUMARTFILE" "$FINALDIR"/albumart_backup
+ vecho "Successfully embedded the album art into your $OUTPUT tracks" >&2
+ ;;
+ m4a)
+ for i in *.m4a
+ do
+ "$ATOMICPARSLEY" "$i" --artwork "$ALBUMARTFILE" --overWrite
+ done
+ mkdir "$FINALDIR"/albumart_backup
+ mv "$ALBUMARTFILE" "$FINALDIR"/albumart_backup
+ vecho "Successfully embedded the album art into your $OUTPUT tracks" >&2
+ ;;
+ wv)
+ for i in *.wv
+ do
+ "$WVTAG" --write-binary-tag "Cover Art (Front)=@"$ALBUMARTFILE"" "$i"
+ done
+ mkdir "$FINALDIR"/albumart_backup
+ mv "$ALBUMARTFILE" "$FINALDIR"/albumart_backup
+ vecho "Successfully embedded the album art into your $OUTPUT tracks" >&2
+ ;;
+ ogg)
+ # ----------------
+ # This technique is drawn from 2 sources (the first link being the primary source):
+ # 1. https://github.com/biapy/howto.biapy.com/blob/master/various/mussync-tools
+ # 2. https://github.com/acabal/scripts/blob/master/ogg-cover-art
+ # In abcde a few steps are used in this sequence:
+ #
+ # 1. Create a 'legal' header for the cover art image
+ # 2. Makes a copy of the existing tags
+ # 3. base64 the cover art image
+ # 4. Copy the original tags + the base64 image back to the original ogg file
+ #
+ # Might need some fine tuning but it is a start for abcde 2.8.2 Andrew.
+ # FIXME: I am not sure if there is a maximum size for images converted in this
+ # way, but this could be perhaps handled by CONVERTOPTS called from do_getalbumart.
+ # ----------------
+ # First some variables we can reuse:
+ # Use MIMETYPECOVER to allow use of either png or the more common jpeg:
+ MIMETYPECOVER=$(file -b --mime-type "$ALBUMARTFILE")
+ EXPORTTAGS="$ABCDETEMPDIR/export_ogg_tags"
+ BUILDHEADER="$ABCDETEMPDIR/build_header"
+ # Now build the header, gory details are here:
+ # https://xiph.org/flac/format.html#metadata_block_picture
+ # Picture Type:
+ printf "0: %.8x" 3 | xxd -r -g0 > "$BUILDHEADER"
+ # Mime type length
+ printf "0: %.8x" $(echo -n "$MIMETYPECOVER" | wc -c) | xxd -r -g0 >> "$BUILDHEADER"
+ # Mime type:
+ echo -n "$MIMETYPECOVER" >> "$BUILDHEADER"
+ # Description length. FIXME: I have used 'Cover Image' but I am not sure
+ # if this is better left as an empty field. Andrew
+ printf "0: %.8x" $(echo -n "Cover Image" | wc -c) | xxd -r -g0 >> "$BUILDHEADER"
+ # Description:
+ echo -n "Cover Image" >> "$BUILDHEADER"
+ # Picture width:
+ printf "0: %.8x" 0 | xxd -r -g0 >> "$BUILDHEADER"
+ # Picture height:
+ printf "0: %.8x" 0 | xxd -r -g0 >> "$BUILDHEADER"
+ # Picture color depth:
+ printf "0: %.8x" 0 | xxd -r -g0 >> "$BUILDHEADER"
+ # Picture color count:
+ printf "0: %.8x" 0 | xxd -r -g0 >> "$BUILDHEADER"
+ # Image file size:
+ printf "0: %.8x" $(wc -c "$ALBUMARTFILE" | cut --delimiter=' ' --fields=1) | xxd -r -g0 >> "$BUILDHEADER"
+ # cat the image file:
+ cat "$ALBUMARTFILE" >> "$BUILDHEADER"
+ # Now process each ogg file by first exporting the original tags then
+ # appending the cover image and finally copying the whole thing back
+ # to the original image:
+ for i in *.ogg
+ do
+ # Make a backup of the existing tags:
+ "$VORBISCOMMENT" --list --raw "$i" > "EXPORTTAGS"
+ # base64 the file and then mix it all together with the exported tags:
+ echo "metadata_block_picture=$(base64 --wrap=0 < "$BUILDHEADER")" >> "EXPORTTAGS"
+ # Update the original ogg file with exported tags and the appended base64'd image:
+ "$VORBISCOMMENT" --write --raw --commentfile "EXPORTTAGS" "$i"
+ # Delete the EXPORTTAGS file ready to be recreated for the next file in the loop,
+ # note that the header file BUILDHEADER will be reused for each file in the loop:
+ rm "EXPORTTAGS"
+ done
+ mkdir "$FINALDIR"/albumart_backup
+ mv "$ALBUMARTFILE" "$FINALDIR"/albumart_backup
+ vecho "Successfully embedded the album art into your $OUTPUT tracks" >&2
+ ;;
+ *) vecho "Sorry, abcde does not embed album art for the $OUTPUT container..." >&2
+ esac
+ else
+ vecho "Suitable cover image not found, no embedding done..." >&2
+ fi
+done
+}
+
# do_cdread [tracknumber]
# do_cdread onetrack [firsttrack] [lasttrack]
#
LASTTRACK=$(expr $3 + 0)
UTRACKNUM=$FIRSTTRACK
case "$CDROMREADERSYNTAX" in
- flac) READTRACKNUMS="$FIRSTTRACK.1-$(($LASTTRACK + 1)).0" ;;
- cdparanoia)
+ flac) READTRACKNUMS="-" ;;
+ cdparanoia|libcdio)
#XX FIXME XX
- # Add a variable to check if tracks are provided in command line and if not, use "0-" to rip the tracks
- READTRACKNUMS="$FIRSTTRACK-$LASTTRACK" ;;
+ # Add a variable to check if tracks are provided in command line and if not, rip the whole CD
+ # We must make sure to rip from sector 0, both lines below work
+ # READTRACKNUMS="-- -$LASTTRACK" ;;
+ READTRACKNUMS="[.0]-" ;;
cdda2wav | icedax) READTRACKNUMS="$FIRSTTRACK+$LASTTRACK" ;;
pird) READTRACKNUMS="$FIRSTTRACK..$LASTTRACK" ;;
*) echo "abcde error: $CDROMREADERSYNTAX does not support ONETRACK mode"
if [ "$USEPIPES" = "y" ]; then
TEMPARG="PIPERIPPER_$CDROMREADERSYNTAX"
FILEARG="$( eval echo "\$$TEMPARG" )"
- REDIR=""
PIPE_MESSAGE="and encoding "
else
WAVDATA="$ABCDETEMPDIR/track$UTRACKNUM.wav"
FILEARG="$WAVDATA"
;;
esac
- REDIR=">&2"
fi
if [ "$1" = "onetrack" ]; then
echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2
# 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/}
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)
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
if [ x"$EXTRAVERBOSE" != "x" ] && [ $EXTRAVERBOSE -gt 0 ] ; then
case $1 in
warning) shift ; log warning "$@" ;;
- *) echo "$@" ;;
+ *) >&4 echo "$@" ;;
esac
fi
}
if [ x"$EXTRAVERBOSE" != "x" ] && [ $EXTRAVERBOSE -gt 1 ] ; then
case $1 in
warning) shift ; log warning "$@" ;;
- *) echo "$@" ;;
+ *) >&4 echo "$@" ;;
esac
fi
}
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
}
# 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 filename munging specific to track names:
+mungetrackname ()
+{
+ mungefilename $@
+}
+
+# Custom filename munging specific to artist names:
+mungeartistname ()
+{
+ mungefilename $@
+}
+
+# Custom filename munging specific to album names:
+mungealbumname ()
+{
+ mungefilename $@
}
# Custom genre munging:
# Builtin defaults
# CDDB
-# Defaults to FreeDB, but musicbrainz can be used too, via the abcde-musicbrainz-tool script
-CDDBMETHOD=cddb
+# Currently three supported options ("musicbrainz", "cddb" for freedb.org and "cdtext")
+CDDBMETHOD=musicbrainz
CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"
CDDBSUBMIT=freedb-submit@freedb.org
CDDBPROTO=6
MP3ENCODERSYNTAX=default
OGGENCODERSYNTAX=default
OPUSENCODERSYNTAX=default
+MKAENCODERSYNTAX=default
+AIFFENCODERSYNTAX=default
FLACENCODERSYNTAX=default
SPEEXENCODERSYNTAX=default
MPCENCODERSYNTAX=default
WVENCODERSYNTAX=default
+TTAENCODERSYNTAX=default
APENCODERSYNTAX=default
+MP2ENCODERSYNTAX=default
AACENCODERSYNTAX=default
NORMALIZERSYNTAX=default
CUEREADERSYNTAX=default
# program paths - defaults to checking your $PATH
# mp3
LAME=lame
-TOOLAME=toolame
GOGO=gogo
BLADEENC=bladeenc
L3ENC=l3enc
# 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
+WVTAG=wvtag
+WINE=wine
CDPARANOIA=cdparanoia
+CD_PARANOIA=cd-paranoia
CDDA2WAV=icedax
DAGRAB=dagrab
CDDAFS=cp
MKTOC=cdrdao
DIFF=diff
CUE2DISCID=builtin
+GLYRC=glyrc
+IDENTIFY=identify
+CONVERT=convert
+DISPLAYCMD=display
-# Options for programs called from abcde
+# Options for programs called from abcde:
+#
+# aiff
+# These options needed by FFmpeg for tagging and selection of id3v2 version:
+# 1. '-write_id3v2 1' allows id3v2 tagging while '-write_id3v2 0' disables tagging
+# 2. '-id3v2_version 4' gives version id3v2.4 while '3' gives id3v2.3
+AIFFENCOPTS="-write_id3v2 1 -id3v2_version 4"
# mp3
LAMEOPTS=
-TOOLAMEOPTS=
GOGOOPTS=
BLADEENCOPTS=
L3ENCOPTS=
# 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='192k'
+FDKAACENCOPTS='--bitrate 192k'
+QAACENCOPTS=
+FHGAACENCOPTS=
+FFMPEGENCOPTS=
ID3OPTS=
+ID3TAGOPTS=
EYED3OPTS=""
+ATOMICPARSLEYOPTS=
CDPARANOIAOPTS=
PIRDOPTS=
CDDA2WAVOPTS=
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
# 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:fdkaac: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.
OSFLAVOUR=FBSD
elif [ X$(uname) = "XDarwin" ] ; then
HTTPGET=curl
+# By default md5sum is not installed, use md5 instead:
+ MD5SUM=md5
OSFLAVOUR=OSX
# We should have diskutil in OSX, but let's be sure...
NEEDDISKUTIL=y
# 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
if [ "$HTTPGETOPTS" = "" ] ; then
case $HTTPGET in
wget) HTTPGETOPTS="-q -nv -e timestamping=off -O -";;
- curl) HTTPGETOPTS="-f -s";;
+ curl) HTTPGETOPTS="-f -s -L";;
fetch)HTTPGETOPTS="-q -o -";;
ftp) HTTPGETOPTS="-a -V -o - ";;
*) log warning "HTTPGET in non-standard and HTTPGETOPTS are not defined." ;;
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:bBc:C:d:DefgGhj:klLmMnNo:pP:Q:r:s:S:t:T:UvVxX:w:W:z opt ; do
case "$opt" in
1) ONETRACK=y ;;
a) ACTIONS="$OPTARG" ;;
A) EXPACTIONS="$OPTARG" ;;
b) BATCHNORM=y ;;
+ B) GETALBUMART=y ; EMBEDALBUMART=y ;;
c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else log error "config file \"$OPTARG\" cannot be found." ; exit 1 ; fi ;;
- C) DISCID="$( echo ${OPTARG#abcde.} | tr -d /)" ;;
+ C) CDDBDISCID="$( echo ${OPTARG#abcde.} | tr -d /)" ;;
d) CDROM="$OPTARG" ;;
D) set -x ;;
h) usage; exit ;;
E) ENCODING="$OPTARG" ;;
f) FORCE=y ;;
g) NOGAP=y ;;
+ G) GETALBUMART=y ;;
i) INLINETAG=y ;;
j) MAXPROCS="$OPTARG" ;;
k) KEEPWAVS=y ;;
o) OUTPUTTYPE="$OPTARG" ;;
p) PADTRACKS=y ;;
P) USEPIPES=y ;;
+ Q) CDDBMETHOD="$OPTARG" ;;
r) REMOTEHOSTS="$OPTARG" ;;
R) CDDBLOCALRECURSIVE=y ;;
s) SHOWCDDBFIELDS="$OPTARG" ;;
EJECTCD=n
fi
-# If the user provided a DISCID, disable eject
-if [ -n "$DISCID" ] || [ "$CDROMREADERSYNTAX" = "flac" ]; then EJECTCD=n ; fi
+# If the user provided a CDDBDISCID, disable eject
+if [ -n "$CDDBDISCID" ] || [ "$CDROMREADERSYNTAX" = "flac" ]; then EJECTCD=n ; fi
# Check the available cd rippers in the system, from the ones we know.
if [ "$CDROMREADERSYNTAX" = "" ]; then
# 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"
replaygain) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOREPLAYGAIN=y;;
playlist) DOCDDB=y; DOPLAYLIST=y;;
clean) DOCLEAN=y;;
+ getalbumart) GETALBUMART=y;;
+ embedalbumart) GETALBUMART=y; EMBEDALBUMART=y;;
esac
done
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"
case "$OUTPUT" in
vorbis:*|ogg:*) OGGENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
opus:*) OPUSENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
+ mka:*) MKAENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
+ aiff:*) AIFFENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
mp3:*) MP3ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
flac:*) FLACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
spx:*) SPEEXENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
mpc:*) MPCENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
wv:*) WVENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
+ tta:*) TTAENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
ape:*) APENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
+ mp2:*) MP2ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
m4a:*|aac:*) AACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
esac
done
esac
# If nothing has been specified, use oggenc for oggs and lame for mp3s and flac
-# for flacs and speexenc for speex and mpcenc for mpcs and faac for m4as and
+# for flacs and speexenc for speex and mpcenc for mpcs and fdkaac for m4as and
# wavpack for wvs...
# Getting ready for multiple output changes
[ "$OPUSENCODERSYNTAX" = "default" ] && OPUSENCODERSYNTAX=opusenc
OPUSOUTPUTCONTAINER=opus
;;
+ mka)
+ [ "$MKAENCODERSYNTAX" = "default" ] && MKAENCODERSYNTAX=ffmpeg
+ MKAOUTPUTCONTAINER=mka
+ ;;
+ aiff)
+ [ "$AIFFENCODERSYNTAX" = "default" ] && AIFFENCODERSYNTAX=ffmpeg
+ AIFFOUTPUTCONTAINER=aiff
+ ;;
mp3)
[ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame
[ "$DOTAG" = "y" ] && NEEDTAGGER=y
[ "$DOREPLAYGAIN" = "y" ] && NEEDMP3GAIN=y
+ [ "$EMBEDALBUMART" = "y" ] && NEEDEYED3=y
;;
flac)
[ "$FLACENCODERSYNTAX" = "default" ] && FLACENCODERSYNTAX=flac
[ "$DOTAG" = "y" ] && NEEDMETAFLAC=y
[ "$DOREPLAYGAIN" = "y" ] && NEEDMETAFLAC=y
[ "$ONETRACK" = "y" ] && [ "$DOCUE" = "y" ] && NEEDMETAFLAC=y
+ [ "$EMBEDALBUMART" = "y" ] && NEEDMETAFLAC=y
;;
spx)
[ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc
[ "$WVENCODERSYNTAX" = "default" ] && WVENCODERSYNTAX=wavpack
[ "$DOTAG" = "y" ]
[ "$DOREPLAYGAIN" = "y" ] && NEEDWVGAIN=y
+ [ "$WVENCODERSYNTAX" = "ffmpeg" ] && DOREPLAYGAIN=n
+ [ "$EMBEDALBUMART" = "y" ] && NEEDWVTAG=y
;;
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" = "default" ] && AACENCODERSYNTAX=fdkaac
+ [ "$AACENCODERSYNTAX" = "faac" ] && [ "$DOTAG" = "y" ] && CHECKFAACBUILD=y
[ "$AACENCODERSYNTAX" = "neroAacEnc" ] && NEEDNEROAACTAG=y
+ [ "$AACENCODERSYNTAX" = "qaac" ] && NEEDWINE=y
+ [ "$AACENCODERSYNTAX" = "fhgaacenc" ] && NEEDWINE=y && NEEDATOMICPARSLEY=y
+ [ "$AACENCODERSYNTAX" = "ffmpeg" ] && [ "$DOTAG" = "y" ]
+ [ "$EMBEDALBUMART" = "y" ] && NEEDATOMICPARSLEY=y
;;
wav)
if [ "$KEEPWAVS" = "y" ]; then
MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$LAMEOPTS}"
MP3ENCODER="$LAME"
;;
- toolame)
- MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$TOOLAMEOPTS}"
- MP3ENCODER="$TOOLAME"
- ;;
gogo)
MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$GOGOOPTS}"
MP3ENCODER="$GOGO"
OPUSENCODER="$OPUSENC"
;;
esac
+case "$MKAENCODERSYNTAX" in
+ ffmpeg)
+ MKAENCODEROPTS="${MKAENCODEROPTSCLI:-$FFMPEGENCOPTS}"
+ MKAENCODER="$FFMPEG"
+ ;;
+esac
+case "$AIFFENCODERSYNTAX" in
+ ffmpeg)
+ AIFFENCODEROPTS="${AIFFENCODEROPTSCLI:-$AIFFENCOPTS}"
+ AIFFENCODER="$FFMPEG"
+ ;;
+esac
case "$FLACENCODERSYNTAX" in
flac)
FLACENCODEROPTS="${FLACENCODEROPTSCLI:-$FLACOPTS}"
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
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.6.1 onwards.
+ # version 2.7 onwards.
faac)
if [ -z "$FAACENCOPTS" ] && [ -n "$AACENCOPTS" ]; then
AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
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
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
NEEDEJECT=y
fi
if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then
- if [ "$CDDBMETHOD" = "cddb" ]; then
- NEEDHTTPGET=y
- elif [ "$CDDBMETHOD" = "musicbrainz" ]; then
- :
- fi
+ # Need an http tool to be able to do CDDB
+ case $CDDBMETHOD in
+ *cddb*)
+ NEEDHTTPGET=y;;
+ esac
fi
if [ "$DOCUE" = "y" ]; then
NEEDCUEREADER=y
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="" ;;
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="-"
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.
PIPEENCODERSVARCHECK="PIPE_$OGGENCODERSYNTAX" ;;
opus)
PIPEENCODERSVARCHECK="PIPE_$OPUSENCODERSYNTAX" ;;
+ mka)
+ PIPEENCODERSVARCHECK="PIPE_$MKAENCODERSYNTAX" ;;
+ aiff)
+ PIPEENCODERSVARCHECK="PIPE_$AIFFENCODERSYNTAX" ;;
flac)
PIPEENCODERSVARCHECK="PIPE_$FLACENCODERSYNTAX" ;;
spx)
PIPEENCODERSVARCHECK="PIPE_$MPCENCODERSYNTAX" ;;
wv)
PIPEENCODERSVARCHECK="PIPE_$WVENCODERSYNTAX" ;;
+ tta)
+ PIPEENCODERSVARCHECK="PIPE_$TTAENCODERSYNTAX" ;;
m4a)
PIPEENCODERSVARCHECK="PIPE_$AACENCODERSYNTAX" ;;
aac)
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 $AIFFENCODER \
${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \
${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMP3GAIN+$MP3GAIN} \
${NEEDMPCGAIN+$MPCGAIN} ${NEEDCUEREADER+$CUEREADER} \
${NEEDWVGAIN+WVGAIN} ${NEEDAPETAG+$APETAG} \
- ${NEEDCUE2DISCID+$CUE2DISCID} ${NEEDNEROAACTAG+$NEROAACTAG}
+ ${NEEDCUE2DISCID+$CUE2DISCID} ${NEEDNEROAACTAG+$NEROAACTAG} \
+ ${NEEDGLYRC+$GLYRC} ${NEEDWINE+$WINE} ${NEEDATOMICPARSLEY+$ATOMICPARSLEY} \
+ ${NEEDMID3V2+$MID3V2} ${NEEDEYED3+$EYED3} ${NEEDWVTAG+$WVTAG}
do
checkexec "$X"
done
if faac --help 2>&1 | grep -q -F 'MP4 support unavailable.'; then
echo "WARNING: Your copy of Faac does not have mp4 support"
echo "WARNING: Encoding untagged files to aac..."
- OUTPUTTYPE=aac
+ # Replace m4a with aac for single and multi-output encodes:
+ OUTPUTTYPE=$(echo "$OUTPUTTYPE" | sed 's/m4a/aac/')
else
echo "Using Faac to Tag AAC Tracks..."
fi
## Now that we have metaflac, check if we need cue2discid
#case $CDROMREADERSYNTAX in
# flac)
-# TRACKINFO=$($METAFLAC --show-tag=CDDB $CDROM | cut -d"=" -f2 | grep -E "[a-f0-9]{8}")
-# if [ "$TRACKINFO" = "" ]; then
+# CDDBTRACKINFO=$($METAFLAC --show-tag=CDDB $CDROM | cut -d"=" -f2 | grep -E "[a-f0-9]{8}")
+# if [ "$CDDBTRACKINFO" = "" ]; then
# checkexec ${NEEDCUE2DISCID+$CUE2DISCID}
# fi
# ;;
# Here it used to say:
# One thousand lines in, we can start doing stuff with things
# Well, right now we are at line 3737 ;)
+# Hey, for grins, as of 2016-08-30 this is now line 4814! -GR
# Export needed things so they can be read in this subshell
export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS
# start with a sane default:
CDDBLOCALSTATUS=notfound
if [ $CDDBUSELOCAL = "y" ]; then
- do_localcddb
+ do_localcddb_read
fi
if checkstatus cddb-choice > /dev/null; then
:
else
+ NUM_CDDB_MATCHES=0
if [ "$CDDBLOCALSTATUS" = "notfound" ] ; then
- case "$CDDBMETHOD" in
+ idx=0
+ for CDDBMETHCHOICE in $(echo "$CDDBMETHOD" | tr -d ' ' | tr , ' ')
+ do
+ addstatus "CDDB method $idx: $CDDBMETHCHOICE"
+ idx=$(($idx + 1))
+ vecho "Trying CDDB method ${CDDBMETHCHOICE}, found $NUM_CDDB_MATCHES matches so far"
+
+ # Run all the desired data acquisition methods, in the order
+ # specified by the user. Each will use its own temporary
+ # subdirectory, then copy the cddbread.* etc. files up into
+ # $ABCDETEMPDIR
+ case "$CDDBMETHCHOICE" in
cddb)
- do_cddbstat
- do_cddbquery
- do_cddbread
+ do_cddb_read
;;
musicbrainz)
- do_musicbrainz
+ do_musicbrainz_read
;;
- esac
- fi
- CHOICE=$(checkstatus cddb-choice)
- if [ "$CHOICE" = 0 ] ; then
- # We don't have any information at all; try to fall back
- # to CD-Text for basic information
- vecho "No CDDB information found, trying cdtext from the CD"
- do_cdtext
+ cdtext)
+ do_cdtext_read
+ ;;
+ *)
+ echo "Unknown CDDB method $CDDBMETHCHOICE. Aborting." >&2
+ exit 1
+ ;;
+ esac
+
+ done
+
+ rm -f "${ABCDETEMPDIR}/cddbchoices"
+ CDDBDISCID=$(echo $CDDBTRACKINFO | cut -d' ' -f1)
+
+ if [ $NUM_CDDB_MATCHES = 0 ]; then
+ # If we got no matches, we need to
+ # generate a blank CDDB template.
+ vecho "Unable to find any matches, generating unknown template."
+ echo "No CDDB match." >> "${ABCDETEMPDIR}/cddbchoices"
+ $CDDBTOOL template $(cat "${ABCDETEMPDIR}/cddbdiscid") > "${ABCDETEMPDIR}/cddbread.0"
+ # List out disc title/author and contents of template
+ echo ---- Unknown Artist / Unknown Album ---- >> "${ABCDETEMPDIR}/cddbchoices"
+ UNKNOWNDISK=y
+ for TRACK in $(f_seq_row 1 $TRACKS)
+ do
+ echo $TRACK: "$(grep -a ^TTITLE$(expr $TRACK - 1)= "${ABCDETEMPDIR}/cddbread.0" | cut -f2- -d= | tr -d \\r\\n)" >> "${ABCDETEMPDIR}/cddbchoices"
+ done
+ echo >> "${ABCDETEMPDIR}/cddbchoices"
+ echo cddb-read-0-complete >> "${ABCDETEMPDIR}/status"
+ echo cddb-choice=0 >> "${ABCDETEMPDIR}/status"
+ echo 503 > "$ABCDETEMPDIR/cddbquery"
+ else
+ # We have matches; create the cddbchoices and cddbquery
+ # files from all the inputs we have
+ if [ $NUM_CDDB_MATCHES = 1 ]; then
+ echo "Retrieved 1 match..." >> "$ABCDETEMPDIR/cddbchoices"
+ echo -n "200 " > "$ABCDETEMPDIR/cddbquery"
+ cat "$ABCDETEMPDIR/cddbquery.1" >> "$ABCDETEMPDIR/cddbquery"
+ else
+ echo "Retrieved $NUM_CDDB_MATCHES matches..." >> "$ABCDETEMPDIR/cddbchoices"
+ echo "210 Found exact matches, list follows (until terminating .)" > "$ABCDETEMPDIR/cddbquery"
+ for X in $(f_seq_row 1 $NUM_CDDB_MATCHES)
+ do
+ cat "$ABCDETEMPDIR/cddbquery.$X" >> "$ABCDETEMPDIR/cddbquery"
+ done
+ echo "." >> "$ABCDETEMPDIR/cddbquery"
+ fi
+
+ for X in $(f_seq_row 1 $NUM_CDDB_MATCHES)
+ do
+ ATITLE=$(grep -a -e '^DTITLE=' "${ABCDETEMPDIR}/cddbread.$X" | cut -c8- | tr -d \\r\\n)
+ SOURCE=$(cat ${ABCDETEMPDIR}/datasource.$X)
+ echo "#$X ($SOURCE): ---- ${ATITLE} ----" >> "$ABCDETEMPDIR/cddbchoices"
+ for TRACK in $(f_seq_row 1 $TRACKS)
+ do
+ echo $TRACK: "$(grep -a ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.$X" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
+ done
+ echo >> "$ABCDETEMPDIR/cddbchoices"
+ done
+ fi
fi
fi
do_cddbedit
if [ X"$CDSPEEDVALUE" != "X" ]; then
case "$CDROMREADERSYNTAX" in
- cdparanoia|debug) ;;
+ cdparanoia|libcdio|debug) ;;
pird) ;;
flac) ;;
*) do_cdspeed ;;
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
# CD tray. If not, we do not eject the CD, since it might be so that the
# user ejected it manually.
#CURRENTTRACKINFO=$($CDDISCID $CDROM)
- #if if [ "$?" != "1" ] && [ "$CURRENTTRACKINFO" = "$TRACKINFO" ] ; then
+ #if if [ "$?" != "1" ] && [ "$CURRENTTRACKINFO" = "$CDDBTRACKINFO" ] ; then
# More FreeBSD bits.
if [ X"$(uname)" = X"FreeBSD" ] ; then
# FreeBSD eject uses the EJECT environment variable to name the CDROM
$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
#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
do_replaygain
fi
+if [ "$EMBEDALBUMART" = "y" ]; then
+ do_embedalbumart
+fi
+
# Execute the user-defined post_encode function before cleaning up
post_encode
log warning "The encoded formats does not match with the moved ones"
log warning "Formats encoded: $( echo $ENCODED_FORMATS | tr "|" " " )"
log warning "Formats moved: $( echo $MOVED_FORMATS | tr "|" " " )"
- log warning "Use \"abcde -a clean -f -C $DISCID\" to force the removal of the remaining data."
+ log warning "Use \"abcde -a clean -f -C $CDDBDISCID\" to force the removal of the remaining data."
DOCLEAN=n
fi
fi