X-Git-Url: https://git.hcoop.net/clinton/abcde.git/blobdiff_plain/2d38e786853e86344ff7cfbdf1ff2dc86149109d..2c2dffe6d58521463918acd4425cf9e99d8001e8:/abcde diff --git a/abcde b/abcde index ab24d28..d585c16 100755 --- a/abcde +++ b/abcde @@ -1,19 +1,19 @@ #!/bin/bash # Copyright (c) 1998-2001 Robert Woodcock -# Copyright (c) 2003-2005 Jesus Climent +# Copyright (c) 2003-2006 Jesus Climent # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# 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. # # $Id$ -VERSION='2.3.99-$Revision$' +VERSION='2.4.2' usage () { @@ -46,27 +46,29 @@ echo "-L Use local CDDB storage directory" echo "-n No lookup. Don't query CDDB, just create and use template" echo "-N Noninteractive. Never prompt for anything" echo "-m Modify playlist to include CRLF endings, to comply with some players" -echo "-M Create a CUE file" +#echo " WARNING: Deprecated. Use \"cue\" action" +#echo "-M Create a CUE file" echo "-o " echo " Output file type(s) (vorbis,mp3,flac,spx,mpc,wav,m4a). 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 " +echo " Set quality level (high,medium,low)" echo "-r " echo " Also encode on these remote hosts" echo "-R Use local CDDB in recursive mode" -#echo "-R Add replaygain values to the tag info (only for vorbis,flac,mp3)" echo "-s " -echo " Show dielfs from the CDDB info (year,genre)" +echo " Show fields from the CDDB info (year,genre)" echo "-S <#> Set the CD speed" echo "-t <#> Start the track numbering at a given number" echo "-T <#> Same as -t but modifies tag numbering" -echo "-u Use UNICODE tags and comments" +echo "-U Do NOT use UNICODE (UTF8) tags and comments" echo "-v Show version number and exit" echo "-V Be a bit more verbose about what is happening behind the scenes" echo "-x Eject CD after all tracks are read" echo "-w " echo " Add a comment to the CD tracks" -echo "-W <#> Contatenate CDs: -T #01 -w \"CD #\"" +echo "-W <#> Concatenate CDs: -T #01 -w \"CD #\"" echo "-z Use debug CDROMREADERSYNTAX option (needs cdparanoia)" echo "" echo "Tracks is a space-delimited list of tracks to grab." @@ -81,7 +83,7 @@ addstatus () } # log [level] [message] -# +# # log outputs the right message in a common format log () { @@ -169,7 +171,7 @@ checkstatus () fi } -# chechwarnings [blurb] +# checkwarnings [blurb] # Returns "0" if the blurb was found (meaning there was an warning), # returns 1 if it wasn't (yes this is a little backwards). # Does not print the blurb on stdout. @@ -353,11 +355,20 @@ checkexec () if [ ! "$@" = "" ]; then # Cut off any command-line option we added in X=$(echo $@ | cut -d' ' -f2) + # Test for built-in abcde.function + [ "$X" != "${X#abcde.}" ] && type $X >/dev/null 2>&1 && return if [ "$(which $X)" = "" ]; then 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 + case $X in + oggenc) MISSING_PACKAGE=vorbis-tools ;; + lame|flac) MISSING_PACKAGE=$X ;; + esac + log info "Hint: apt-get install $MISSING_PACKAGE" >&2 + fi exit 1 - elif [ ! -x $(which $X) ]; then + elif [ ! -x "$(which $X)" ]; then log error "$X is not executable." >&2 exit 1 fi @@ -378,8 +389,8 @@ diffentries () PARSECHOICE2=$(echo $CDDBDIFFCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null) if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBDIFFCHOICES ] || \ [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBDIFFCHOICES ] || \ - [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then - echo "Invalid diff range. Please select two coma-separated numbers between 1 and $CDDBDIFFCHOICES" >&2 + [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then + echo "Invalid diff range. Please select two comma-separated numbers between 1 and $CDDBDIFFCHOICES" >&2 else # We parse the 2 choices to diff, store them in temporary files and diff them. for PARSECHOICE in $(echo $CDDBDIFFCHOICE | tr , \ ); do @@ -409,6 +420,9 @@ getcddbinfo() TRACKNAME) TRACKNAME="$(grep ^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' + ;; esac } @@ -425,10 +439,64 @@ gettracknum() fi } +# makeids +# +# Calculate cddb disc ids without requiring specialized helper programs. +# largely copied from cd-discid and musicbrainz examples. some of the steps +# don't make sense, but they're necessary to match the ids generated by other +# programs. +# +## FIXME ## Right now, we get 2 frames more than with cue2discid ?? +# data@petit:~$ sh /tmp/cue2discid /home/data/tmp/flac/01.Roisin_Murphy--Ruby_Blue.flac +# processing offsetimes 00:00:00 04:47:10 08:20:37 11:46:46 17:45:36 21:41:57 27:32:21 32:03:73 35:39:28 38:27:33 43:50:38 44:42:34 +# 980b4b0c 12 150 21685 37687 53146 80061 97782 124071 144448 160603 173208 197438 201334 2895 +# data@petit:~$ metaflac --export-cuesheet-to=- /home/data/tmp/flac/01.Roisin_Murphy--Ruby_Blue.flac| python /home/data/sources/abcde/trunk/examples/cue2discid +# 980b4b0c 12 150 21685 37687 53146 80061 97782 124071 144448 160603 173208 197438 201334 2893 +# +# Variables: OFFSETS, TRACKS, LEADOUT, [LEADIN] +makeids () +{ + if [ X"$LEADOUT" = "X" ]; then + log warning "Error trying to calculate disc ids without lead-out information." + exit 1 + fi + + # default to a two second lead-in + IDMAGICNUM=150 + LEADIN=${LEADIN:=150} + + # number of cdframes per second + CDFRAMES=75 + + # reset cddb checksum for cddb disc-id calululation + CDDBCKSUM=0 + + COOKEDOFFSETS="" + for OFFSET in $(echo $OFFSETS) + do + COOKEDOFFSETS="${COOKEDOFFSETS} $(($OFFSET + $LEADIN))" + + OFFSETTIME=$(( ($OFFSET + $LEADIN) / $CDFRAMES )) + while [ $OFFSETTIME -gt 0 ]; do + CDDBCKSUM=$(($CDDBCKSUM + $OFFSETTIME % 10)) + OFFSETTIME=$(($OFFSETTIME / 10)) + done + + done + + COOKEDOFFSETS="${COOKEDOFFSETS:1}" # eat the leading space + + PREGAP=$(($(echo $OFFSETS | cut -f1 -d' '))) + TOTALTIME=$(( (($LEADOUT + $LEADIN + $PREGAP) / $CDFRAMES) - (($LEADIN + $PREGAP) / $CDFRAMES))) + + printf -v HEXSUM "%08lx" $(( ($CDDBCKSUM % 0xff) << 24 | $TOTALTIME << 8 | $TRACKS)) + TRACKINFO="${HEXSUM} $((TRACKS)) ${COOKEDOFFSETS} $((($LEADOUT + $LEADIN + $IDMAGICNUM) / $CDFRAMES))" +} + do_replaygain() { if checkstatus replaygain; then :; else - run_command "" echo "Adding replygain information..." + run_command "" echo "Adding replaygain information..." for TMPOUTPUT in $( echo $OUTPUTTYPE | tr , \ ) do case $TMPOUTPUT in @@ -452,27 +520,38 @@ do_replaygain() TRACKFILE="$(mungefilename "$TRACKNAME")" ARTISTFILE="$(mungefilename "$TRACKARTIST")" ALBUMFILE="$(mungefilename "$DALBUM")" + GENRE="$(mungegenre "$GENRE")" + YEAR=${CDYEAR:-$CDYEAR} gettracknum - if [ "$VARIOUSARTISTS" = "y" ]; then - OUTPUTFILE="$(eval echo "$VAOUTPUTFORMAT")" - else - OUTPUTFILE="$(eval echo "$OUTPUTFORMAT")" + if [ "$ONETRACK" = "y" ]; then + if [ "$VARIOUSARTISTS" = "y" ]; then + OUTPUTFILE="$(eval echo \""$VAONETRACKOUTPUTFORMAT"\")" + else + OUTPUTFILE="$(eval echo \""$ONETRACKOUTPUTFORMAT"\")" + fi + else + if [ "$VARIOUSARTISTS" = "y" ]; then + OUTPUTFILE="$(eval echo \""$VAOUTPUTFORMAT"\")" + else + OUTPUTFILE="$(eval echo \""$OUTPUTFORMAT"\")" + fi fi OUTPUTFILES[$REPLAYINDEX]="$OUTPUTDIR/$OUTPUTFILE.$OUTPUT" (( REPLAYINDEX = $REPLAYINDEX + 1 )) done case "$OUTPUT" in flac) - run_command replaygain-flac $METAFLAC --add-replay-gain "${OUTPUTFILES[@]}" + run_command replaygain-flac nice $ENCNICE $METAFLAC $FLACGAINOPTS "${OUTPUTFILES[@]}" + #run_command replaygain-flac true ;; vorbis|ogg) - run_command replaygain-vorbis $VORBISGAIN --album "${OUTPUTFILES[@]}" + run_command replaygain-vorbis nice $ENCNICE $VORBISGAIN $VORBISGAINOPTS "${OUTPUTFILES[@]}" ;; mp3) - run_command replaygain-mp3 $MP3GAIN -a "${OUTPUTFILES[@]}" + run_command replaygain-mp3 nice $ENCNICE $MP3GAIN $MP3GAINOPTS "${OUTPUTFILES[@]}" ;; mpc) - run_command replaygain-mpc $MPPGAIN --auto "${OUTPUTFILES[@]}" + run_command replaygain-mpc nice $ENCNICE $MPPGAIN --auto "${OUTPUTFILES[@]}" ;; *);; esac @@ -699,11 +778,14 @@ return 0 # do_tag [tracknumber] # id3 tags a filename # variables used: -# TRACKS, TRACKNAME, TRACKARTIST, TAGGER, TAGGEROPTS, VORBISCOMMENT, METAFLAC, -# COMMENT, DALBUM, DARTIST, CDYEAR, CDGENRE (and temporarily) ID3TAGV +# TRACKS, TRACKNAME, TRACKARTIST, TAGGER, TAGGEROPTS, VORBISCOMMENT, METAFLAC, ATOMICPARSLEY +# COMMENT, DALBUM, DARTIST, CDYEAR, CDGENRE do_tag () { COMMENTOUTPUT="$(eval echo ${COMMENT})" + if [ -z "$COMMENTOUTPUT" ]; then + COMMENTOUTPUT="$(getcddbinfo TRACK-INFO)" + fi CDDBDISCID=$(echo $TRACKINFO | 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 @@ -717,22 +799,43 @@ do_tag () mp3) # id3v2 v0.1.9 claims to have solved the -c bug, so we merge both id3 and id3v2 GENREID=$(do_getgenreid "${CDGENRE}") + # Set TPE2 in case we have a Various Artists rip. + TPE2="" + if [ "$VARIOUSARTISTS" = "y" ]; then + TPE2="Various" + fi case "$ID3SYNTAX" in id3);; eyed3) - # FIXME # track numbers in mp3 come with 1/10, so we cannot happily substitute them with $TRACKNUM - run_command tagtrack-$OUTPUT-$1 $TAGGER $TAGGEROPTS --commen=::"$COMMENTOUTPUT" \ - -A "$DALBUM" -a "$TRACKARTIST" -t "$TRACKNAME" -Y "$CDYEAR" \ - -G "$GENREID" -n "${TRACKNUM:-$1}" "${TRACKNUM:+-N $TRACKS}" \ - "${ENCODING:+--set-encoding=$ENCODING}" + # 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 \ + --comment=::"$COMMENTOUTPUT" -A "$DALBUM" \ + -a "$TRACKARTIST" -t "$TRACKNAME" -Y "$CDYEAR" \ + -G "$GENREID" -n "${TRACKNUM:-$1}" \ + "${TRACKNUM:+-N $TRACKS}" \ + "${ENCODING:+--set-encoding=$ENCODING}" \ + "${TPE2:+--set-user-text-frame=TPE2:$TPE2}" \ + "$ABCDETEMPDIR/track$1.$OUTPUT" + ;; + # FIXME # Still not activated... + id3ed) + run_command tagtrack-$OUTPUT-$1 nice $ENCNICE \ + $TAGGER $TAGGEROPTS -c "$COMMENTOUTPUT" \ + -a "$DALBUM" -n "$TRACKARTIST" -s "$TRACKNAME" \ + -y "$CDYEAR" -g "$GENREID" -k "${TRACKNUM:-$1}" \ "$ABCDETEMPDIR/track$1.$OUTPUT" ;; *) - # FIXME # track numbers in mp3 come with 1/10, so we cannot happily substitute them with $TRACKNUM - run_command tagtrack-$OUTPUT-$1 $TAGGER $TAGGEROPTS -c "$COMMENTOUTPUT" \ - -A "$DALBUM" -a "$TRACKARTIST" -t "$TRACKNAME" -y "$CDYEAR" \ - -g "$GENREID" -T "${TRACKNUM:-$1/$TRACKS}" \ + # 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" -t "$TRACKNAME" \ + -y "$CDYEAR" -g "$GENREID" \ + -T "${TRACKNUM:-$1}/$TRACKS" \ + ${TPE2:+--TPE2 "$TPE2"} \ "$ABCDETEMPDIR/track$1.$OUTPUT" ;; esac @@ -745,7 +848,9 @@ do_tag () mv "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" fi ( - # These are from http://www.xiph.org/ogg/vorbis/doc/v-comment.html + # These are from + # http://www.xiph.org/ogg/vorbis/doc/v-comment.html + echo ARTIST="$TRACKARTIST" echo ALBUM="$DALBUM" echo TITLE="$TRACKNAME" @@ -756,6 +861,9 @@ do_tag () echo GENRE="$CDGENRE" fi echo TRACKNUMBER=${TRACKNUM:-$1} + if [ -n "$DISCNUMBER" ]; then + echo DISCNUMBER="$DISCNUMBER" + fi echo CDDB=$CDDBDISCID if [ "$(eval echo ${COMMENT})" != "" ]; then case "$COMMENTOUTPUT" in @@ -763,9 +871,11 @@ do_tag () *) echo COMMENT="$COMMENTOUTPUT";; esac fi - ) | run_command tagtrack-$OUTPUT-$1 $VORBISCOMMENT $VORBISCOMMENTOPTS -w \ + ) | run_command tagtrack-$OUTPUT-$1 nice $ENCNICE \ + $VORBISCOMMENT $VORBISCOMMENTOPTS -w \ "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" - # Doublecheck that the commented file was created successfully before wiping the original + # Doublecheck that the commented file was created + # successfully before wiping the original if [ -f "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" ]; then rm -f "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" else @@ -786,6 +896,9 @@ do_tag () echo GENRE="$CDGENRE" fi echo TRACKNUMBER="${TRACKNUM:-$1}" + if [ -n "$DISCNUMBER" ]; then + echo DISCNUMBER="$DISCNUMBER" + fi echo CDDB="$CDDBDISCID" if [ "$(eval echo ${COMMENT})" != "" ]; then case "$COMMENTOUTPUT" in @@ -793,7 +906,7 @@ do_tag () *) echo COMMENT="$COMMENTOUTPUT";; esac fi - ) | run_command tagtrack-$OUTPUT-$1 $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 @@ -802,7 +915,20 @@ do_tag () run_command tagtrack-$OUTPUT-$1 true ;; m4a) - run_command tagtrack-$OUTPUT-$1 true + # Use a temp-file of our choice. --overWrite seems to + # case core dumps with AtomicParsley 0.9.0 + ATOMICTEMPFILE="$ABCDETEMPDIR/track$1.m4a-atomic" + + VARIOUSBOOL="false" + if [ "$VARIOUSARTISTS" = "y" ]; then + VARIOUSBOOL="true" + fi + + #It has to be command file opts for 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" --compilation $VARIOUSBOOL --comment "$COMMENTOUTPUT" --output $ATOMICTEMPFILE + if [ -f $ATOMICTEMPFILE ]; then + mv "$ATOMICTEMPFILE" "$ABCDETEMPDIR/track$1.m4a" + fi ;; wav) run_command tagtrack-$OUTPUT-$1 true @@ -820,14 +946,15 @@ do_tag () # OUTPUTTYPE, {FOO}ENCODERSYNTAX, ENCNICE, ENCODER, ENCODEROPTS do_nogap_encode () { - # The commands here don't go through run_command because they're never supposed to be silenced + # The commands here don't go through run_command because they're never + # supposed to be silenced echo "Encoding gapless MP3 tracks: $TRACKQUEUE" for OUTPUT in $(echo $OUTPUTTYPE | tr , \ ) do case "$OUTPUT" in mp3) case "$MP3ENCODERSYNTAX" in - lame) + lame|toolame) ( cd "$ABCDETEMPDIR" TRACKFILES= @@ -859,8 +986,8 @@ do_nogap_encode () fi fi fi - # Other encoders fall through to normal encoding as the tracks - # have not been entered in the status file. + # Other encoders fall through to normal encoding as the tracks have not + # been entered in the status file. } # do_encode [tracknumber] [hostname] @@ -917,39 +1044,43 @@ do_encode () do case "$TMPOUTPUT" in vorbis|ogg) - OUT="$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" OUTPUT=$OGGOUTPUTCONTAINER ;; flac) - OUT="$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER" OUTPUT=$FLACOUTPUTCONTAINER ;; *) - OUT="$ABCDETEMPDIR/track$1.$OUTPUT" OUTPUT=$TMPOUTPUT ;; esac - if [ "$NOGAP" = "y" ] && checkstatus encodetrack-$OUTPUT-$1 ; then + OUT="$ABCDETEMPDIR/track$1.$OUTPUT" + if [ "$NOGAP" = "y" ] && checkstatus encodetrack-$OUTPUT-$1 ; then continue fi if [ X"$USEPIPES" = "Xy" ]; then RUN_COMMAND="" # We need a way to store the creation of the files when using PIPES RUN_COMMAND_PIPES="run_command encodetrack-$OUTPUT-$1 true" + # When pipping it does not make sense to have a higher nice for + # reading than for encoding, since it will be hold by the + # encoding process. Setting an effective nice, to calm down a + # bit the reading process. + EFFECTIVE_NICE=$READNICE else run_command '' echo "Encoding track $1 of $TRACKS: $TRACKNAME..." RUN_COMMAND="run_command encodetrack-$OUTPUT-$1" + EFFECTIVE_NICE=$ENCNICE fi case "$OUTPUT" in mp3) case "$2" in %local*%) case "$MP3ENCODERSYNTAX" in - lame|gogo) $RUN_COMMAND nice $ENCNICE $MP3ENCODER $MP3ENCODEROPTS "$IN" "$OUT" ;; - bladeenc) $RUN_COMMAND nice $ENCNICE $MP3ENCODER $MP3ENCODEROPTS -quit "$IN" ;; - l3enc|xingmp3enc) $RUN_COMMAND nice $ENCNICE $MP3ENCODER "$IN" "$OUT" $MP3ENCODEROPTS ;; + lame|toolame|gogo) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER $MP3ENCODEROPTS "$IN" "$OUT" ;; + bladeenc) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER $MP3ENCODEROPTS -quit "$IN" ;; + l3enc|xingmp3enc) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER "$IN" "$OUT" $MP3ENCODEROPTS ;; # FIXME # Relates to the previous FIXME since it might need the "-if" removed. - mp3enc) $RUN_COMMAND nice $ENCNICE $MP3ENCODER -if "$IN" -of "$OUT" $MP3ENCODEROPTS ;; + mp3enc) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER -if "$IN" -of "$OUT" $MP3ENCODEROPTS ;; esac ;; *) @@ -961,8 +1092,8 @@ do_encode () case "$2" in %local*%) case "$OGGENCODERSYNTAX" in - vorbize) $RUN_COMMAND nice $ENCNICE $OGGENCODER $OGGENCODEROPTS -w "$OUT" "$IN" ;; - oggenc) $RUN_COMMAND nice $ENCNICE $OGGENCODER $OGGENCODEROPTS -o "$OUT" "$IN" ;; + vorbize) $RUN_COMMAND nice $EFFECTIVE_NICE $OGGENCODER $OGGENCODEROPTS -w "$OUT" "$IN" ;; + oggenc) $RUN_COMMAND nice $EFFECTIVE_NICE $OGGENCODER $OGGENCODEROPTS -o "$OUT" "$IN" ;; esac ;; *) @@ -974,8 +1105,8 @@ do_encode () case "$2" in %local*%) case "$FLACENCODERSYNTAX" in - flac) $RUN_COMMAND nice $ENCNICE $FLACENCODER -f $FLACENCODEROPTS -o "$OUT" "$IN" ;; - esac + flac) $RUN_COMMAND nice $EFFECTIVE_NICE $FLACENCODER -f $FLACENCODEROPTS -o "$OUT" "$IN" ;; + esac ;; *) vecho -n "DISTMP3:" @@ -994,9 +1125,9 @@ do_encode () fi # Quick hack to avoid tagging Ogg/Speex, since there is no other way to tag than inline tagging if [ ! "$DOTAG" = "y" ]; then - $RUN_COMMAND nice $ENCNICE $SPEEXENCODER $SPEEXENCODEROPTS --author "$TRACKARTIST" --title "$TRACKNAME" "$COMMENT" "$IN" "$OUT" + $RUN_COMMAND nice $EFFECTIVE_NICE $SPEEXENCODER $SPEEXENCODEROPTS --author "$TRACKARTIST" --title "$TRACKNAME" --comment "$COMMENT" "$IN" "$OUT" else - $RUN_COMMAND nice $ENCNICE $SPEEXENCODER $SPEEXENCODEROPTS "$IN" "$OUT" + $RUN_COMMAND nice $EFFECTIVE_NICE $SPEEXENCODER $SPEEXENCODEROPTS "$IN" "$OUT" fi ;; mpc) @@ -1006,12 +1137,12 @@ do_encode () # errors, so I have not tried it myself. ## FIXME ## Needs some cleanup to determine if an empty tag sent ## FIXME ## to the encoder ends up empty. - $RUN_COMMAND nice $ENCNICE $MPPENCODER $MPPENCODEROPTS --artist "$TRACKARTIST" --album "$DALBUM" --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" --year "$CDYEAR" --comment "$COMMENT" "$IN" "$OUT" + $RUN_COMMAND nice $EFFECTIVE_NICE $MPPENCODER $MPPENCODEROPTS --artist "$TRACKARTIST" --album "$DALBUM" --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" --year "$CDYEAR" --comment "$COMMENT" "$IN" "$OUT" ;; m4a) # Quick hack to avoid tagging Ogg/Speex, since there is no other way to tag than inline tagging if [ ! "$DOTAG" = "y" ]; then - $RUN_COMMAND nice $ENCNICE $AACENCODER $AACENCODEROPTS --artist "$TRACKARTIST" --album "$DALBUM" --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" --year "$CDYEAR" --comment "$COMMENT" -o "$OUT" "$IN" + $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS --artist "$TRACKARTIST" --album "$DALBUM" --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" --year "$CDYEAR" --comment "$COMMENT" -o "$OUT" "$IN" else $RUN_COMMAND nice $ENCNICE $AACENCODER $AACENCODEROPTS -o "$OUT" "$IN" @@ -1065,7 +1196,7 @@ do_encode () # esac # done # # Only remove .wav if the encoding succeeded -# if checkerrors "preprocess-(.{3,4})-$1"; then +# if checkerrors "preprocess-(.{3,4})-$1"; then # run_command preprocess-$1 false # else # run_command preprocess-$1 true @@ -1103,7 +1234,7 @@ do_encode () # run_command postprocess-$OUTPUT-$1 nice $POSTNICE $SPX_POST $IF $OF ;; # esac # # Only remove .wav if the encoding succeeded -# if checkerrors "postprocess-(.{3,4})-$1"; then +# if checkerrors "postprocess-(.{3,4})-$1"; then # run_command postprocess-$1 false # else # run_command postprocess-$1 true @@ -1233,10 +1364,18 @@ do_move () gettracknum # Supported variables for OUTPUTFORMAT are GENRE, YEAR, ALBUMFILE, # ARTISTFILE, TRACKFILE, and TRACKNUM. - if [ "$VARIOUSARTISTS" = "y" ]; then - OUTPUTFILE="$(eval echo "$VAOUTPUTFORMAT")" - else - OUTPUTFILE="$(eval echo "$OUTPUTFORMAT")" + if [ "$ONETRACK" = "y" ]; then + if [ "$VARIOUSARTISTS" = "y" ]; then + OUTPUTFILE="$(eval echo \""$VAONETRACKOUTPUTFORMAT"\")" + else + OUTPUTFILE="$(eval echo \""$ONETRACKOUTPUTFORMAT"\")" + fi + else + if [ "$VARIOUSARTISTS" = "y" ]; then + OUTPUTFILE="$(eval echo \""$VAOUTPUTFORMAT"\")" + else + OUTPUTFILE="$(eval echo \""$OUTPUTFORMAT"\")" + fi fi if checkerrors "tagtrack-$OUTPUT-$1"; then :; else # Once we know the specific output was successful, we can change @@ -1278,7 +1417,7 @@ do_move () ;; esac # Lets move the cue file - if CUEFILE=$(checkstatus cuefile) >/dev/null ; then + if CUEFILE=$(checkstatus cuefile) >/dev/null ; then if [ -r "$ABCDETEMPDIR/$CUEFILE" ]; then if checkstatus movecue-$OUTPUT; then :; else # Silence the Copying output since it overlaps with encoding processes... @@ -1354,6 +1493,7 @@ do_playlist () read ERASEPLAYLIST case $ERASEPLAYLIST in e|E|a|A|k|K) DONE=y ;; + "") ERASEPLAYLIST=e ; DONE=y ;; *) ;; esac done @@ -1382,9 +1522,9 @@ do_playlist () # TRACKNUM value before evaluation gettracknum if [ "$VARIOUSARTISTS" = "y" ]; then - OUTPUTFILE="$(eval echo "$VAOUTPUTFORMAT")" + OUTPUTFILE="$(eval echo \""$VAOUTPUTFORMAT\"")" else - OUTPUTFILE="$(eval echo "$OUTPUTFORMAT")" + OUTPUTFILE="$(eval echo \""$OUTPUTFORMAT\"")" fi if [ "$VARIOUSARTISTS" = "y" ]; then if [ "$VAPLAYLISTDATAPREFIX" ] ; then @@ -1412,6 +1552,171 @@ do_playlist () done } +# abcde.cue2discid +# This function reads a cuefile on stdin and writes an extended +# cddb query on stdout. Any PREGAP for track 1 is properly +# handled, although cue files embedded in FLAC files do not +# appear to properly store the PREGAP setting. :( +abcde.cue2discid () { + + cddb_sum () { + val=$1 + ret=0 + while [ $val -gt 0 ] ; do + ret=$(( $ret + ( $val % 10) )) + val=$(( $val / 10 )) + done + echo $ret + } + + msf2lba () { + OIFS="$IFS" + IFS=":" + set -- $1 + IFS="$OIFS" + local first second third + first=$(expr ${1} + 0 ) + second=$(expr ${2} + 0 ) + third=$(expr ${3} + 0 ) + + echo $(( ((($first * 60) + $second) * 75) + $third )) + } + + OFFSET=150 + PREGAP=0 + LEADOUT=0 + LEADIN=88200 + i=0 + N=0 + + while read line ; do + set -- $line + case "$1" in + TRACK) i=$(( i + 1 )) + ;; + INDEX) if [ "$2" -eq 1 ] ; then + LBA=$(msf2lba $3) + START=$(( $LBA + $PREGAP + $OFFSET )) + eval TRACK$i=$START + X=$(cddb_sum $(( $START / 75 )) ) + N=$(( $N + $X )) + fi + ;; + PREGAP) PREGAP=$(msf2lba $2) + ;; + REM) case "$2" in + FLAC__lead-out) + LEADOUT=$(( $4 / 588 )) + ;; + FLAC__lead-in) + LEADIN=$(( $3 / 588 )) + ;; + esac + ;; + esac + + done + + TRACKS=$i + LEADOUT=$(( $LEADOUT + $LEADIN )) + + LENGTH=$(( $LEADOUT/75 - $TRACK1/75 )) + DISCID=$(( ( $N % 255 ) * 2**24 | $LENGTH * 2**8 | $TRACKS )) + printf "%08x %i" $DISCID $TRACKS + + j=1 + while [ $j -le $TRACKS ] ; do + eval echo -n "\" \$TRACK$j\"" + j=$((j+1)) + done + echo " $(( $LEADOUT / 75 ))" +} + +# abcde.mkcue +# abcde.mkcue [--wholedisk] +# This creates a cuefile directly from the extended discid information +# The --wholedisk option controls whether we're ripping data from the +# start of track one or from the start of the disk (usually, but not +# always the same thing!) +# +# Track one leadin/pregap (if any) handeling: +# --wholedisk specified: +# TRACK 01 AUDIO +# INDEX 00 00:00:00 +# INDEX 01 +# Remaining track index values unchanged from disc TOC +# +# --wholedisk not specified +# TRACK 01 AUDIO +# PREGAP +# INDEX 01 00:00:00 +# Remaining track index values offset by +# +# Variables used: +# TRACKINFO +abcde.mkcue () { + + echomsf () { + printf "$1%02i:%02i:%02i\n" $(($2/4500)) $((($2/75)%60)) $(($2%75)) + } + + local MODE DISCID TRACKS + local i OFFSET LBA + local CUEWAVFILE + + if [ "$1" = --wholedisc ] ; then + MODE=INDEX + else + MODE=PREGAP + fi + + vecho "One track is $ONETRACK" + TRACKFILE="$(mungefilename "$TRACKNAME")" + ARTISTFILE="$(mungefilename "$TRACKARTIST")" + ALBUMFILE="$(mungefilename "$DALBUM")" + if [ "$ONETRACK" = "y" ]; then + if [ "$VARIOUSARTISTS" = "y" ]; then + CUEWAVFILE="$(eval echo \""$VAONETRACKOUTPUTFORMAT"\" | sed -e 's@^.*/@@').$OUTPUT" + else + CUEWAVFILE="$(eval echo \""$ONETRACKOUTPUTFORMAT"\" | sed -e 's@^.*/@@').$OUTPUT" + fi + vecho "Cue wav file is $CUEWAVFILE" + else + CUEWAVFILE="dummy.wav" + fi + + set -- $TRACKINFO + + DISCID=$1 + TRACKS=$2 + shift 2 + + echo REM DISCID $DISCID + echo FILE \""$CUEWAVEFILE"\" WAVE + + if [ $1 -ne 150 ] && [ $MODE = "PREGAP" ] ; then + OFFSET=$1 + else + OFFSET=150 + fi + + i=1 + while [ $i -le "$TRACKS" ] ; do + LBA=$(( $1 - $OFFSET )) + printf " TRACK %02i AUDIO\n" $i + if [ $i -eq 1 -a $1 -ne 150 ] ; then + if [ $MODE = PREGAP ] ; then + echomsf " PREGAP " $(($OFFSET-150)) + else + echo " INDEX 00 00:00:00" + fi + fi + echomsf " INDEX 01 " $LBA + i=$(($i+1)) + shift + done +} + # do_discid # This essentially the start of things do_discid () @@ -1427,20 +1732,63 @@ do_discid () if [ "$OSFLAVOUR" = "OSX" ]; then disktool -u ${CDROM#/dev/} fi - if [ "$CDROMREADERSYNTAX" = "flac" ] ; then - if $METAFLAC $METAFLACOPTS --export-cuesheet-to=- $CDROM > /dev/null 2>&1 ; then - TRACKINFO=$($METAFLAC $METAFLACOPTS --export-cuesheet-to=- $CDROM | $CUE2DISCID) - else - log error "the input flac file does not contain a cuesheet." - exit 1 - fi - else - case "$CDDBMETHOD" in - cddb) TRACKINFO=$($CDDISCID $CDROM) ;; - # FIXME # musicbrainz needs a cleanup - musicbrainz) TRACKINFO=$($MUSICBRAINZ -c $CDROM ) ;; - esac - fi + case "$CDROMREADERSYNTAX" in + flac) + if $METAFLAC $METAFLACOPTS --export-cuesheet-to=- "$CDROM" > /dev/null 2>&1 ; then + case "$CUE2DISCID" in + # FIXME # right now we have 2 cue2discid internal + # implementations: builtin and abcde.cue2discid. Test + # both of them and decide which one we want to use. + builtin) + #vecho "Using builtin cue2discid implementation..." + CUESHEET="$(metaflac $METAFLACOPTS --export-cuesheet-to=- "$CDROM")" + + #TRACKS=$(echo $CUESHEET | egrep "TRACK \+[[:digit:]]\+ \+AUDIO" |wc -l) + #TRACKS=0 + OFFSETTIMES=( $(echo "$CUESHEET" | sed -n -e's/\ *INDEX 01\ \+//p' ) ) + TRACKS=${#OFFSETTIMES[@]} + unset OFFSETS + #echo "processing offsetimes ${OFFSETTIMES[@]}" + for OFFSETTIME in ${OFFSETTIMES[@]}; do + OFFSETS="$OFFSETS $(( 10#${OFFSETTIME:0:2} * 4500 + 10#${OFFSETTIME:3:2} * 75 + 10#${OFFSETTIME:6:2} ))" + #OFFSETS[${#OFFSETS[*]}]=$(( 10#${OFFSETTIME:0:2} * 4500 + 10#${OFFSETTIME:3:2} * 75 + 10#${OFFSETTIME:6:2} )) + done + + LEADOUT=$(( $(echo "$CUESHEET" | grep lead-out | get_last) * 75 / 44100 )) + LEADIN=$(( $(echo "$CUESHEET" | grep lead-in | get_last) * 75 / 44100 )) + makeids + ;; + *) + #vecho "Using external python cue2discid implementation..." + TRACKINFO=$($METAFLAC $METAFLACOPTS --export-cuesheet-to=- "$CDROM" | $CUE2DISCID) + ;; + esac + else + log error "the input flac file does not contain a cuesheet." + 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" | egrep '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ')" +# CDPARANOIAAUDIOTRACKS="$TRACKS" +# +# LEADOUT="$(echo "$CDPARANOIAOUTPUT" | egrep -o '^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") ;; + esac + ;; + esac # Make sure there's a CD in there by checking cd-discid's return code if [ ! "$?" = "0" ]; then if [ "$CDROMREADERSYNTAX" = "flac" ] ; then @@ -1476,12 +1824,12 @@ do_discid () ABCDETEMPDIR="$WAVOUTPUTDIR/abcde.$(echo $TRACKINFO | cut -f1 -d' ')" if [ -z "$TRACKQUEUE" ]; then - if [ ! "$STRIPDATATRACKS" = "y" ]; then + if [ ! "$STRIPDATATRACKS" = "n" ]; then case "$CDROMREADERSYNTAX" in cdparanoia|debug) if [ "$WEHAVEACD" = "y" ]; then vecho "Querying the CD for audio tracks..." - CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS $CDROM -Q --verbose 2>&1 )" + CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -Q --verbose 2>&1 )" RET=$? if [ ! "$RET" = "0" ];then log warning "something went wrong while querying the CD... Maybe a DATA CD?" @@ -1556,11 +1904,11 @@ do_discid () exit 1 fi echo -n . - # It's a directory, let's see if it's owned by us - if [ ! -O "$ABCDETEMPDIR" ]; then + # It's a directory, let's see if it's writable by us + if [ ! -r "$ABCDETEMPDIR" ] || [ ! -w "$ABCDETEMPDIR" ] || [ ! -x "$ABCDETEMPDIR" ]; then # Nope, complain and exit echo >&2 - echo "abcde: directory $ABCDETEMPDIR already exists and is not owned by you." >&2 + echo "abcde: directory $ABCDETEMPDIR already exists and is not writeable." >&2 echo "Please investigate, remove it, and rerun abcde." >&2 exit 1 fi @@ -1612,13 +1960,15 @@ do_discid () # Store the abcde version in the status file. echo "abcde-version=$VERSION" >> "$ABCDETEMPDIR/status" fi - if [ X"$MAKECUEFILE" = "Xy" -a X"$WEHAVEACD" = "Xy" ]; then + 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 vecho "Creating cue file..." case $CDROMREADERSYNTAX in flac) - if $METAFLAC --export-cuesheet-to=- $CDROM > "$ABCDETEMPDIR/$CUEFILE"; then :; else + if $METAFLAC --export-cuesheet-to=- "$CDROM" > "$ABCDETEMPDIR/$CUEFILE"; then + echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status" + else log warning "the input flac file does not contain a cuesheet." fi ;; @@ -1626,7 +1976,7 @@ do_discid () if $CUEREADER $CUEREADEROPTS > "$ABCDETEMPDIR/$CUEFILE"; then echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status" else - log warning "reading the CUE sheet with mkcue is still considered experimental" + log warning "reading the CUE sheet is still considered experimental" log warning "and there was a problem with the CD reading. abcde will continue," log warning "but consider reporting the problem to the abcde author" fi @@ -1662,15 +2012,43 @@ do_cleancue() n=1 echo "PERFORMER \"$DARTIST\"" >> "$CUEFILE_OUT" echo "TITLE \"$DALBUM\"" >> "$CUEFILE_OUT" + # Set IFS to to prevent read from swallowing spaces and tabs + OIFS="$IFS" + IFS=' +' cat "$CUEFILE_IN" | while read line do - if echo "$line" | grep "INDEX" > /dev/null 2>&1 ; then + if echo "$line" | grep "INDEX 01" > /dev/null 2>&1 ; then +# FIXME # Possible patch: remove the line above, uncomment the 2 lines below. +# echo "$line" >> "$CUEFILE_OUT" +# if echo "$line" | grep "^[[:space:]]*TRACK" > /dev/null 2>&1 ; then eval track="\$TRACK$n" n=$(expr $n + 1) - echo "TITLE \"$track\"" >> "$CUEFILE_OUT" + echo " TITLE \"$track\"" >> "$CUEFILE_OUT" + # When making a single-track rip, put the + # actual file name into the file declaration + # in the cue file so that it is usable by + # music players and the like + elif [ "$ONETRACK" = "y" ] && + echo "$line" | grep '^FILE "dummy.wav" WAVE' > /dev/null 2>&1 ; then + + TRACKFILE="$(mungefilename "$TRACKNAME")" + ARTISTFILE="$(mungefilename "$TRACKARTIST")" + ALBUMFILE="$(mungefilename "$DALBUM")" + + if [ "$VARIOUSARTISTS" = "y" ]; then + OUTPUTFILE="$(eval echo \""$VAONETRACKOUTPUTFORMAT"\" | sed -e 's@^.*/@@').$OUTPUT" + else + OUTPUTFILE="$(eval echo \""$ONETRACKOUTPUTFORMAT"\" | sed -e 's@^.*/@@').$OUTPUT" + fi + + echo "FILE \"$OUTPUTFILE\" WAVE" >> "$CUEFILE_OUT" + continue fi +# FIXME # If the lines above are uncommented, remove the line below. echo "$line" >> "$CUEFILE_OUT" done + IFS="$OIFS" mv "$CUEFILE_OUT" "$CUEFILE_IN" echo "cleancuefile" >> "$ABCDETEMPDIR/status" fi @@ -1749,11 +2127,13 @@ do_localcddb () cat "$RESULT" > "${CDDBLOCALREAD}" { echo -n "#$X: " - do_cddbparse "${CDDBLOCALREAD}" + do_cddbparse "${CDDBLOCALREAD}" echo "" + ##FIXME## QUICK HACK !!!! + if [ ! "$INTERACTIVE" = "y" ]; then break ; fi } >> "$ABCDETEMPDIR/cddblocalchoices" done - if [ $(cat "$ABCDETEMPDIR/cddblocalchoices" | wc -l) -ge 24 ]; then + if [ $(cat "$ABCDETEMPDIR/cddblocalchoices" | wc -l) -ge 24 ] && [ "$INTERACTIVE" = "y" ]; then page "$ABCDETEMPDIR/cddblocalchoices" else # It's all going to fit in one page, cat it @@ -1780,8 +2160,9 @@ do_localcddb () done else ### FIXME ### - echo "Selected ..." + #echo "Selected ..." CDDBLOCALRESP=y + CDDBLOCALCHOICENUM=1 fi if [ ! "$CDDBLOCALCHOICENUM" = "0" ]; then #echo "Using local copy of CDDB data" @@ -1800,11 +2181,11 @@ do_localcddb () single) # List out disc title/author and contents do_cddbparse "${CDDBLOCALFILE}" - if [ "$CDROMREADERSYNTAX" = "flac" ] ; then - echo -n "Embedded cuesheet entry found, use it? [y/n] (y): " >&2 - else + #if [ "$CDROMREADERSYNTAX" = "flac" ] ; then + # echo -n "Embedded cuesheet entry found, use it? [y/n] (y): " >&2 + #else echo -n "Locally cached CDDB entry found, use it? [y/n] (y): " >&2 - fi + #fi if [ "$INTERACTIVE" = "y" ]; then read USELOCALRESP while [ "$USELOCALRESP" != "y" ] && [ "$USELOCALRESP" != "n" ] && [ "$USELOCALRESP" != "" ] ; do @@ -1836,14 +2217,76 @@ do_localcddb () fi } -do_musicbrainzstat () -{ - : -} +# do_musicbrainz +# 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_musizbrainz () +do_musicbrainz () { - : + 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 + ${MUSICBRAINZ} --command data --device "$CDROM" --workdir $ABCDETEMPDIR + + # The helper script will write disc matches out to + # cddbread.*. Count how many we have + 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" + elif [ "$NUM_RESPONSES" -eq 0 ] ; 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" + done + echo >> "$ABCDETEMPDIR/cddbchoices" + echo cddb-read-0-complete >> "$ABCDETEMPDIR/status" + echo cddb-choice=0 >> "$ABCDETEMPDIR/status" + echo 503 > "$ABCDETEMPDIR/cddbquery" + 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 + echo "musicbrainz-readcomplete" >> "$ABCDETEMPDIR/status" + fi } # do_cddbstat @@ -1864,15 +2307,25 @@ do_cddbstat () RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbstat" | cut -f1 -d' ') case "$RESPONSECODE" in 210) # 210 OK, status information follows (until terminating `.') - rc=0; + rc=0 ;; - 501|*) # 501 Illegal CDDB protocol level: . + 501) # 501 Illegal CDDB protocol level: . CDDBPROTO=`expr $CDDBPROTO - 1` ;; - esac + *) # 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' ') + case "$RESPONSECODE" in + 2??) # Server responded, everything seems OK + rc=0 + ;; + esac + ;; + esac done if test $rc -eq 1; then - CDDBAVAIL="n" + CDDBAVAIL="n" fi fi echo cddb-statcomplete >> "$ABCDETEMPDIR/status" @@ -1892,7 +2345,7 @@ do_cddbquery () ERRORCODE=no_query echo 503 > "$ABCDETEMPDIR/cddbquery" # The default CDDBLOCALSTATUS is "notfound" - # This part will be triggered if the user CDDB repo does not + # This part will be triggered if the user CDDB repo does not # contain the entry, or if we are not trying to use the repo. else vecho "Querying the CDDB server..." @@ -1978,7 +2431,7 @@ do_cddbread () 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" + echo cddb-choice=1 >> "$ABCDETEMPDIR/status" else echo "Multiple ${IN}exact matches:" >> "$ABCDETEMPDIR/cddbchoices" fi @@ -2039,7 +2492,7 @@ do_cddbedit () if [ -n "$CHOICE" ] ; then case $CDDBCHOICES in -1) if head -1 "$ABCDETEMPDIR/cddbquery" | grep "^$" > /dev/null 2>&1 ; then - log error "CDDB query failed!" + log error "CDDB query failed!" exit 1 else cat "$ABCDETEMPDIR/cddbchoices" @@ -2074,8 +2527,8 @@ do_cddbedit () PARSECHOICE2=$(echo $CDDBCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null) if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBCHOICES ] || \ [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBCHOICES ] || \ - [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then - echo "Invalid diff range. Please select two coma-separated numbers between 1 and $CDDBCHOICES" >&2 + [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then + echo "Invalid diff range. Please select two comma-separated numbers between 1 and $CDDBCHOICES" >&2 else # We parse the 2 choices to diff, store them in temporary files and diff them. for PARSECHOICE in $(echo $CDDBCHOICE | tr , \ ); do @@ -2122,7 +2575,7 @@ do_cddbedit () if [ "$USELOCALRESP" = "y" ]; then :; else if [ -n "$CHOICE" ] ; then case $CDDBCHOICES in - 0) + 0) UNKNOWNDISK=y echo "Selected template." ;; @@ -2308,7 +2761,7 @@ do_cddbedit () if [ "$CDDBDATAMD5SUM" != "" ] && [ "$CDDBDATAMD5SUM" != "$($MD5SUM "$CDDBDATA" | cut -d " " -f 1)" ]; then # This works but does not have the necessary error checking # yet. If you are familiar with the CDDB spec - # (see http://www.freedb.org/src/latest/DBFORMAT) + # (see http://www.freedb.org/src/latest/DBFORMAT) # and can create an error-free entry on your own, then put # UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE=y in your # abcde.conf to enable it. Put CDDBSUBMIT=email@address in @@ -2347,7 +2800,7 @@ do_cddbedit () # do_cdread [tracknumber] # do_cdread onetrack [firsttrack] [lasttrack] -# +# do_cdread () { # The commands here don't go through run_command because they're never supposed to be silenced @@ -2356,14 +2809,17 @@ do_cdread () # FIXME # Add the possibility of grabbing ranges of tracks in onetrack # FIXME # Until then, we grab the whole CD in one track, no matter what # the user said - # We need the first and last track for cdda2wav + # We need the first and last track for cdda2wav/icedax FIRSTTRACK=$2 LASTTRACK=$(expr $3 + 0) UTRACKNUM=$FIRSTTRACK case "$CDROMREADERSYNTAX" in flac) READTRACKNUMS="$FIRSTTRACK.1-$(($LASTTRACK + 1)).0" ;; - cdparanoia) READTRACKNUMS="$FIRSTTRACK-$LASTTRACK" ;; - cdda2wav) READTRACKNUMS="$FIRSTTRACK+$LASTTRACK" ;; + cdparanoia) + #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" ;; + cdda2wav | icedax) READTRACKNUMS="$FIRSTTRACK+$LASTTRACK" ;; *) echo "abcde error: $CDROMREADERSYNTAX does not support ONETRACK mode" exit 1 ;; esac @@ -2374,7 +2830,7 @@ do_cdread () if [ "$USEPIPES" = "y" ]; then TEMPARG="PIPERIPPER_$CDROMREADERSYNTAX" FILEARG="$( eval echo "\$$TEMPARG" )" - REDIR="" + REDIR="y" PIPE_MESSAGE="and encoding " else WAVDATA="$ABCDETEMPDIR/track$UTRACKNUM.wav" @@ -2390,7 +2846,7 @@ do_cdread () FILEARG="$WAVDATA" ;; esac - REDIR=">&2" + REDIR="n" fi if [ "$1" = "onetrack" ]; then echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2 @@ -2409,13 +2865,18 @@ do_cdread () # Avoid problems wit 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) + cdparanoia) + if [ "$REDIR" = "y" ]; then + nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" >&2 + else + nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" + fi;; + + cdda2wav | icedax) if [ "$OSFLAVOUR" = "OSX" ] ; then - # Hei, we have to unmount the device before running anything like cdda2wav in OSX + # Hei, we have to unmount the device before running anything like cdda2wav/icedax in OSX disktool -u ${CDROM#/dev/} 0 - # Also, in OSX the cdrom device for cdda2wav changes... + # Also, in OSX the cdrom device for cdda2wav/icedax changes... CDDA2WAVCDROM="IODVDServices" elif [ "$OSFLAVOUR" = "FBSD" ] ; then CDDA2WAVCDROM="$CDROMID" @@ -2426,12 +2887,19 @@ do_cdread () CDDA2WAVCDROM="$CDROMID" fi fi - nice $READNICE $CDROMREADER -D $CDDA2WAVCDROM -t ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR - ;; + if [ "$REDIR" = "y" ]; then + nice $READNICE $CDROMREADER -D $CDDA2WAVCDROM -t ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" >&2 + else + nice $READNICE $CDROMREADER -D $CDDA2WAVCDROM -t ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" + fi ;; ## FIXME ## We have an exception for dagrab, since it uses -f ## FIXME ## Shall we just use -f $FILEARG ?? - dagrab) nice $READNICE $CDROMREADER -d $CDROM -v $UTRACKNUM "$FILEARG" $REDIR - ;; + dagrab) + if [ "$REDIR" = "y" ]; then + nice $READNICE $CDROMREADER -d "$CDROM" -v $UTRACKNUM "$FILEARG" >&2 + else + nice $READNICE $CDROMREADER -d "$CDROM" -v $UTRACKNUM "$FILEARG" + fi ;; cddafs) # Find the track's mounted path REALTRACKNUM=$(expr $UTRACKNUM + 0) @@ -2439,15 +2907,23 @@ do_cdread () FILEPATH=$(find "$FILEPATH" | grep "/$REALTRACKNUM "); # If the file exists, copy it if [ -e "$FILEPATH" ] ; then - nice $READNICE $CDROMREADER "$FILEPATH" "$FILEARG" $REDIR + if [ "$REDIR" = "y" ]; then + nice $READNICE $CDROMREADER "$FILEPATH" "$FILEARG" >&2 + else + nice $READNICE $CDROMREADER "$FILEPATH" "$FILEARG" + fi else false fi ;; - debug) nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS $CDROM -w $UTRACKNUM-[:1] "$FILEARG" $REDIR - ;; + debug) + if [ "$REDIR" = "y" ]; then + nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -w $UTRACKNUM-[:1] "$FILEARG" >&2 + else + nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -w $UTRACKNUM-[:1] "$FILEARG" + fi ;; esac RETURN=$? - # If we get some error or we get some missing wav + # If we get some error or we get some missing wav # (as long as we dont use pipes) if [ "$RETURN" != "0" -o \( ! -s "$WAVDATA" -a X"$USEPIPES" != "Xy" \) ]; then # Thank goodness errors is only machine-parseable up to the @@ -2475,7 +2951,7 @@ do_cdread () # do_cdspeed # No values accepted, only uses env variables -do_cdspeed () +do_cdspeed () { if "$CDSPEED" "$CDSPEEDOPTS" "$CDSPEEDVALUE" >/dev/null ; then vecho "Setting CD speed to ${CDSPEEDVALUE}x" @@ -2540,6 +3016,13 @@ post_read () : } +# post_encode +# Empty post_encode function, to be defined in the configuration file. +post_encode () +{ +: +} + ############################################################################### # End of functions # @@ -2549,11 +3032,11 @@ post_read () # Builtin defaults # CDDB -# Defaults to FreeDB, but a python musicbrainz can be used +# Defaults to FreeDB, but musicbrainz can be used too, via the abcde-musicbrainz-tool script CDDBMETHOD=cddb CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi" CDDBSUBMIT=freedb-submit@freedb.org -CDDBPROTO=5 +CDDBPROTO=6 HELLOINFO="$(whoami)@$(hostname)" CDDBCOPYLOCAL="n" CDDBLOCALPOLICY="always" @@ -2599,8 +3082,9 @@ KEEPWAVS=n PADTRACKS=n NOGAP=n BATCHNORM=n +NOCDDBQUERY=n -# If using scsi devices, cdda2wav needs a CDROMID, instead of a device node +# If using scsi devices, cdda2wav/icedax needs a CDROMID, instead of a device node # i.e. CDROMID="1,0,0" CDROMID="" # If we are using the IDE bus, we need CDPARANOIACDROMBUS defined as "d" @@ -2631,18 +3115,20 @@ AACENC=faac ID3=id3 ID3V2=id3v2 EYED3=eyeD3 +VORBISCOMMENT=vorbiscomment +METAFLAC=metaflac +AACTAG=faac + CDPARANOIA=cdparanoia -CDDA2WAV=cdda2wav +CDDA2WAV=icedax DAGRAB=dagrab CDDAFS=cp CDDISCID=cd-discid CDDBTOOL=cddb-tool -MUSICBRAINZ=musicbrainz-get-tracks +MUSICBRAINZ=abcde-musicbrainz-tool EJECT=eject MD5SUM=md5sum DISTMP3=distmp3 -VORBISCOMMENT=vorbiscomment -METAFLAC=metaflac NORMALIZE=normalize-audio CDSPEED=eject VORBISGAIN=vorbisgain @@ -2651,7 +3137,7 @@ MPPGAIN=replaygain MKCUE=mkcue MKTOC=cdrdao DIFF=diff -CUE2DISCID=cue2discid +CUE2DISCID=builtin # Options for programs called from abcde # mp3 @@ -2662,11 +3148,14 @@ BLADEENCOPTS= L3ENCOPTS= XINGMP3ENCOPTS= MP3ENCOPTS= +MP3GAINOPTS="-a -k" # ogg VORBIZEOPTS= OGGENCOPTS= +VORBISGAINOPTS="--album" # flac FLACOPTS= +FLACGAINOPTS="--add-replay-gain" # speex SPEEXENCOPTS= # mpc @@ -2698,12 +3187,18 @@ MAXPROCS=1 # List of actions to perform - by default, run to completion ACTIONS=cddb,read,encode,tag,move,clean -# This option is basicaly for Debian package dependencies: +# This option is basicaly for Debian package dependencies: # List of prefered outputs - by default, run with whatever we have in the path -DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:lame,mp3:bladeenc,spx:speex +DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:toolame,mp3:lame,mp3:bladeenc,spx:speex,m4a:faac # List of prefered cdromreaders - by default, run whichever we have in the path -DEFAULT_CDROMREADERS="cdparanoia cdda2wav" +DEFAULT_CDROMREADERS="cdparanoia icedax cdda2wav" + +# List of quality levels associated with the encoders: +DEFAULT_QUALITY_XLO="oggenc:-q -1,lame:-q 9,speex:--quality 1,m4a:" +DEFAULT_QUALITY_LO="oggenc:-q 1,lame:-q 7,speex:--quality 5,m4a:" +DEFAULT_QUALITY_HI="oggenc:-q 7,lame:--preset standard,speex:--quality 9,m4a:" +DEFAULT_QUALITY_XHI="oggenc:-q 10,lame:--preset extreme,speex:--quality 10,m4a:" # Asume fetch if under FreeBSD. curl is used for Mac OS X. wget is used for # Linux/OpenBSD. ftp is user for NetBSD. @@ -2728,7 +3223,7 @@ elif [ X$(uname) = "XNetBSD" ] ; then HTTPGET=ftp MD5SUM=md5 OSFLAVOUR=NBSD -elif [ X$(uname) = "Solaris" ] ; then +elif [ X$(uname) = "SunOS" ] ; then HTTPGET="" MD5SUM=md5 OSFLAVOUR=SunOS @@ -2742,6 +3237,12 @@ CDDBAVAIL=y USEID3=y USEID3V2=y +# There we go.. +# But before we get into business, let us chop off any GREP environmental +# variables. +GREP_OPTIONS="" +GREP_COLOR="" + if [ -z "$OUTPUTDIR" ]; then OUTPUTDIR=$(pwd) fi @@ -2764,10 +3265,10 @@ fi if [ "$HTTPGETOPTS" = "" ] ; then case $HTTPGET in - wget) HTTPGETOPTS="-q -O -";; + wget) HTTPGETOPTS="-q -nv -e timestamping=off -O -";; curl) HTTPGETOPTS="-f -s";; fetch)HTTPGETOPTS="-q -o -";; - ftp) HTTPGETOPTS="-q -o -";; + ftp) HTTPGETOPTS="-a -V -o - ";; *) log warning "HTTPGET in non-standard and HTTPGETOPTS are not defined." ;; esac fi @@ -2790,8 +3291,8 @@ if [ "$CDROM" = "" ] ; then fi # Parse command line options -#while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:t:T:vVxw:W: opt ; do -while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:uvVxw:W:z opt ; do +#while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPq:r:Rs:S:t:T:vVxw:W: opt ; do +while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:UvVxX:w:W:z opt ; do case "$opt" in 1) ONETRACK=y ;; a) ACTIONS="$OPTARG" ;; @@ -2802,7 +3303,6 @@ while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:uvVxw:W:z opt ; do C) DISCID="$( echo ${OPTARG#abcde.} | tr -d /)" ;; d) CDROM="$OPTARG" ;; D) set -x ;; - e) ERASEENCODEDSTATUS=y ;; h) usage; exit ;; e) ERASEENCODEDSTATUS=y ;; E) ENCODING="$OPTARG" ;; @@ -2816,18 +3316,19 @@ while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:uvVxw:W:z opt ; do n) CDDBAVAIL=n ;; N) INTERACTIVE=n ;; m) DOSPLAYLIST=y ;; - M) MAKECUEFILE=y ;; + M) DOCUE=y ;; o) OUTPUTTYPE="$OPTARG" ;; p) PADTRACKS=y ;; P) USEPIPES=y ;; + q) QUALITYLEVEL="$OPTARG" ;; r) REMOTEHOSTS="$OPTARG" ;; R) CDDBLOCALRECURSIVE=y ;; s) SHOWCDDBFIELDS="$OPTARG" ;; S) CDSPEEDVALUE="$OPTARG" ;; t) STARTTRACKNUMBER="$OPTARG" ;; T) STARTTRACKNUMBER="$OPTARG" ; STARTTRACKNUMBERTAG="y" ;; - u) CDDBPROTO=6 ;; - v) + U) CDDBPROTO=5 ;; + v) echo "This is abcde v$VERSION." echo "Usage: abcde [options] [tracks]" echo "abcde -h for extra help" @@ -2835,11 +3336,15 @@ while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:uvVxw:W:z opt ; do ;; V) EXTRAVERBOSE="y" ;; x) EJECTCD="y" ;; + X) CUE2DISCID="$OPTARG" ;; w) COMMENT="$OPTARG" ;; - W) if echo $OPTARG | grep "[[:digit:]]" > /dev/null 2>&1 ; then - STARTTRACKNUMBER="${OPTARG}01" ; STARTTRACKNUMBERTAG="y" ; COMMENT="CD${OPTARG}" + W) if echo $OPTARG | grep "[[:digit:]]" > /dev/null 2>&1 ; then + STARTTRACKNUMBER="${OPTARG}01" + STARTTRACKNUMBERTAG="y" + COMMENT="CD${OPTARG}" + DISCNUMBER="${OPTARG}" else - log error "argument of -W must be integer" + log error "argument of -W must be integer" exit 1 fi ;; @@ -2854,6 +3359,11 @@ shift $(($OPTIND - 1)) # ripping, we have a mixture of sanity checks, verifications, default settigs # and other crazy stuff that interdepends, but hey, someone has to do it. +# If NOCDDBQUERY is set, don't query the CDDB server. +if [ "$NOCDDBQUERY" = "y" ]; then + CDDBAVAIL="n" +fi + # If the user specified a flac file, then switch to special flac mode if echo "$CDROM" | grep -i '.flac$' > /dev/null 2>&1 ; then if [ ! -f "$CDROM" ]; then @@ -2862,8 +3372,11 @@ if echo "$CDROM" | grep -i '.flac$' > /dev/null 2>&1 ; then fi vecho warning "switching to flac CDROMREADERSYNTAX..." CDROMREADERSYNTAX=flac - # Added a need on CUE2DISCID until we manage to convert the python script to bash. - NEEDCUE2DISCID=y + # We have a builtin version of cue2discid... + case "$CUE2DISCID" in + builtin);; + *) NEEDCUE2DISCID=y;; + esac NEEDMETAFLAC=y EJECTCD=n fi @@ -2887,14 +3400,14 @@ if [ "$CDROMREADERSYNTAX" = "" ]; then fi # Decide if we can continue. -if [ "$ONETRACK" = "y" ]; then +if [ "$ONETRACK" = "y" ]; then # FIXME # remove check as soon as we find out about the other readers case "$CDROMREADERSYNTAX" in flac) ;; cdparanoia) ;; - cdda2wav) ;; + cdda2wav | icedax) ;; *) log error "$CDROMREADERSYNTAX does not support ONETRACK mode" - exit 1 ;; + exit 1 ;; esac if [ "$BATCHNORM" = "y" ]; then log warning "BATCHNORM mode is not compatible with ONETRACK mode. Disabling..." @@ -2912,14 +3425,17 @@ if [ "$ONETRACK" = "y" ]; then else while [ $# -gt 0 ]; do # Range parsing code courtesy of Vincent Ho - RSTART=$(echo $1 | cut -f1 -d-) - REND=$(echo $1 | cut -f2 -d-) - if [ "$RSTART" = "$REND" ]; then - NEWTRACKS="$RSTART" + # Cleaned up to use shell built-ins by Charles Steinkuehler + if [ "${1#*[^0-9-]}" != "$1" ]; then + log error "syntax error while processing track numbers" else - NEWTRACKS=$(f_seq_line $RSTART $REND) + RSTART=${1%%-*} + REND=${1##*-} + while [ ${RSTART:=1} -le ${REND:=0} ] ; do + TRACKQUEUE="$TRACKQUEUE $RSTART" + RSTART=$(( $RSTART + 1 )) + done fi - TRACKQUEUE=$(echo "$TRACKQUEUE" "$NEWTRACKS") shift done fi @@ -2940,11 +3456,14 @@ DOMOVE=n DOREPLAYGAIN=n DOPLAYLIST=n DOCLEAN=n +## FIXME ## Lets keep compatibility with -M +[ "$DOCUE" != "y" ] && DOCUE=n for ACTION in $(echo $ACTIONS | tr , \ ) do case $ACTION in default) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOCLEAN=y;; + cue) DOCUE=y ; MAKECUEFILE=y ;; cddb) DOCDDB=y;; read) DOREAD=y;; normalize) DONORMALIZE=y; DOREAD=y;; @@ -2973,8 +3492,8 @@ for SHOWCDDBFIELD in $(echo $SHOWCDDBFIELDS | tr , \ ); do done # At this point a CDROM has to be defined, so we check it exists. -if [ X"$CDROM" != "X" ] ; then - if [ "$CDROMREADERSYNTAX" = "cdda2wav" ] && [ "$NEEDCDROMID" = "y" ] ; then +if [ X"$CDROM" != "X" ] ; then + if ( [ "$CDROMREADERSYNTAX" = "cdda2wav" ] || [ "$CDROMREADERSYNTAX" = "icedax" ] ) && [ "$NEEDCDROMID" = "y" ] ; then if [ "$OSFLAVOUR" = "FBSD" ]; then if echo "$CDROMID" | grep "^[0-9],[0-9],[0-9]$" >/dev/null 2>&1 ; then :; else log error "CDROMID not in the right format for $CDROMREADERSYNTAX" @@ -3042,13 +3561,13 @@ if [ X"$LOWDISK" = "Xy" ]; then fi # BATCHNORM pre-tests, before we get into serious problems -# Not compatible with +# Not compatible with if [ "$BATCHNORM" = "y" ] && [ "$DONORMALIZE" = "n" ]; then vecho warning "Disabling BATCHNORM since we are not normalizing!" BATCHNORM=n fi -# Check the encoding format from the ones available in the system, if nothing has been configured in the system. +# Check the encoding format from the ones available in the system, if nothing has been configured. if [ X"$OUTPUTTYPE" = "X" ]; then for DEFAULT_OUTPUT in $( echo "$DEFAULT_OUTPUT_BINARIES" | tr , \ ); do DEFAULT_OUTPUT_FORMAT="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 1)" @@ -3072,7 +3591,7 @@ case "$CDROMREADERSYNTAX" in CDROMREADER="$CDPARANOIA" CDROMREADEROPTS="$CDPARANOIAOPTS" ;; - cdda2wav) + cdda2wav | icedax) CDROMREADER="$CDDA2WAV" CDROMREADEROPTS="$CDDA2WAVOPTS" ;; @@ -3100,7 +3619,7 @@ esac # Allow -o OUTPUT(1):OPTIONS(1),...,OUTPUT(N):OPTIONS(N) mode of operation if echo "$OUTPUTTYPE" | grep ":" > /dev/null 2>&1 ; then - for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do + for OUTPUT in "$(echo "$OUTPUTTYPE" | tr \ \|| tr , \ | tr \| \ )"; do case "$OUTPUT" in vorbis:*|ogg:*) OGGENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;; mp3:*) MP3ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;; @@ -3139,6 +3658,7 @@ do [ "$FLACENCODERSYNTAX" = "default" ] && FLACENCODERSYNTAX=flac [ "$DOTAG" = "y" ] && NEEDMETAFLAC=y [ "$DOREPLAYGAIN" = "y" ] && NEEDMETAFLAC=y + [ "$ONETRACK" = "y" ] && [ "$DOCUE" = "y" ] && NEEDMETAFLAC=y ;; spx) [ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc @@ -3150,6 +3670,7 @@ do ;; m4a) [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac + [ "$DOTAG" = "y" ] && CHECKATOMICPARSLEY=y ;; wav) if [ "$KEEPWAVS" = "y" ]; then @@ -3208,6 +3729,9 @@ case "$FLACENCODERSYNTAX" in flac) FLACENCODEROPTS="${FLACENCODEROPTSCLI:-$FLACOPTS}" FLACENCODER="$FLAC" + if [ "$DOREPLAYGAIN" = "y" ]; then + FLACENCODEROPTS="${FLACENCODEROPTS} --replay-gain" + fi # FLAC streams can be encapsulated on a Ogg transport layer if echo "$FLACENCODEROPTS" | egrep -- "(^| )--ogg($| )" > /dev/null 2>&1 ;then log error "FLAC on an Ogg container is not yet supported" @@ -3247,9 +3771,9 @@ else TAGGEROPTS="$ID3V2OPTS" fi -# Specific for NOGAP is the use of lame. Another encoder fails... +# NOGAP is specific to lame. Other encoders fail ... if [ "$NOGAP" = "y" ] && [ ! "$MP3ENCODER" = "lame" ]; then - log warning "the NOGAP option is specific of lame. Deactivating..." + log warning "the NOGAP option is specific to lame. Deactivating..." NOGAP=n fi @@ -3290,7 +3814,7 @@ if [ "$DISTMP3NICE" ]; then fi # Don't check for stuff if it's not needed -if [ "$REMOTEHOSTS" ]; then +if [ "$REMOTEHOSTS" ]; then NEEDDISTMP3=y fi if [ "$DONORMALIZE" = "y" ]; then @@ -3306,11 +3830,11 @@ if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then : fi fi -if [ "$MAKECUEFILE" = "y" ]; then +if [ "$DOCUE" = "y" ]; then NEEDCUEREADER=y fi -if [ X"$CDSPEEDVALUE" != "X" ] && [ "$DOREAD" = "y"]; then +if [ X"$CDSPEEDVALUE" != "X" ] && [ "$DOREAD" = "y" ]; then case "$CDROMREADERSYNTAX" in cdparanoia|debug) CDROMREADEROPTS="$CDPARANOIAOPTS -S $CDSPEEDVALUE" ;; ### FIXME ### translate "cue2discid" from python to bash @@ -3371,6 +3895,8 @@ fi # Make sure a buncha things exist for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \ $OGGENCODER $FLACENCODER $SPEEXENCODER $MPPENCODER \ + $AACENCODER \ + ${NEEDATOMICPARSLEY+$ATOMICPARSLEY} \ ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \ ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \ ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \ @@ -3382,6 +3908,15 @@ do checkexec "$X" done +if [ "$CHECKATOMICPARSLEY" = "y" ]; then + if ! new_checkexec "$ATOMICPARSLEY"; then + echo "WARNING: $ATOMICPARSLEY Not Found Not Post-Tagging!" + DOTAG='n' + else + echo "Using $ATOMICPARSLEY To Tag AAC Tracks." + fi +fi + # And last but not least, check if we can diff between files. We do not abort, # since diffing is not critical... if [ -x $(which $DIFF) ]; then :; else @@ -3393,7 +3928,7 @@ fi #case $CDROMREADERSYNTAX in # flac) # TRACKINFO=$($METAFLAC --show-tag=CDDB $CDROM | cut -d"=" -f2 | egrep "[a-f0-9]{8}") -# if [ "$TRACKINFO" = "" ]; then +# if [ "$TRACKINFO" = "" ]; then # checkexec ${NEEDCUE2DISCID+$CUE2DISCID} # fi # ;; @@ -3405,7 +3940,7 @@ HTTPGET="$HTTPGET $HTTPGETOPTS" # Here it used to say: # One thousand lines in, we can start doing stuff with things -# Well, right now we are at line 3306 ;) +# Well, right now we are at line 3737 ;) # Export needed things so they can be read in this subshell export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS @@ -3422,14 +3957,8 @@ if [ "$DOREAD" = "y" ]; then vecho "done." fi -case "$CDDBMETHOD" in - cddb) - do_discid # Get ABCDETEMPDIR created and status file initialized - ;; - musicbrainz) - do_musicbrainz id - ;; -esac +# Get ABCDETEMPDIR created and status file initialized +do_discid if [ "$DOCDDB" = "y" ]; then # start with a sane default: @@ -3439,7 +3968,7 @@ if [ "$DOCDDB" = "y" ]; then fi if checkstatus cddb-choice > /dev/null; then : - else + else if [ "$CDDBLOCALSTATUS" = "notfound" ] ; then case "$CDDBMETHOD" in cddb) @@ -3480,8 +4009,8 @@ fi if checkstatus onetrack ; then ONETRACK=y ; fi -if [ "$ONETRACK" = "y" ]; then - # Reuse the CUEFILE in case we created it in a previous run +if [ "$ONETRACK" = "y" ]; then + # Reuse the CUEFILE in case we created it (now or in a previous run) if CUEFILE=$(checkstatus cuefile); then IMPORTCUESHEET=y fi @@ -3504,7 +4033,7 @@ if [ "$LOWDISK" = "y" ] || [ "$ONETRACK" = "y" ]; then echo "encode-output=loud" >> "$ABCDETEMPDIR/status" fi -if [ "$ONETRACK" = "y" ]; then +if [ "$ONETRACK" = "y" ]; then TRACKS="$FIRSTTRACK" if [ "$USEPIPES" = "y" ]; then if checkstatus readencodetrack-$FIRSTTRACK; then :; else @@ -3537,7 +4066,7 @@ else fi fi if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ]; then - : + : else # If we are not reading, set the encode output to loud already, so # that we can see the output of the first track. @@ -3577,11 +4106,11 @@ post_read # We are now finished with the cdrom - it can be safely ejected. Note that # abcde will not have completed yet. if [ "$EJECTCD" = "y" ] && [ -x $(which $EJECT) ]; then - # We check if the disk we are processing is actually the disk inside the + # We check if the disk we are processing is actually the disk inside the # 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" = "$TRACKINFO" ] ; then # More FreeBSD bits. if [ X"$(uname)" = X"FreeBSD" ] ; then # FreeBSD eject uses the EJECT environment variable to name the CDROM @@ -3594,14 +4123,14 @@ if [ "$EJECTCD" = "y" ] && [ -x $(which $EJECT) ]; then elif [ X"$(uname)" = X"Darwin" ] ; then disktool -e ${CDROM#/dev/} 0 else - $EJECT $EJECTOPTS $CDROM + $EJECT $EJECTOPTS "$CDROM" fi #fi fi ) | ( -## Do we need to pre-process +## Do we need to pre-process #if [ x"$PREPROCESS" = "x" ] ; then # cat #else @@ -3616,7 +4145,7 @@ fi # # all locations are working, wait and try again later # if [ ! $PREPROCEED ]; then sleep 3; fi # done -# ( do_preprocess $PRETRACKNUM +# ( do_preprocess $PRETRACKNUM # echo "NEXTTRACK" # ) & # done @@ -3712,9 +4241,11 @@ do fi # Don't proceed with the rest of the loop if we can't encode if [ "$ABORT" ]; then continue; fi + ## FIXME ## Add here + ## run_command tagtrack-$OUTPUT-$1 $METAFLAC $METAFLACOPTS ${IMPORTCUESHEET:+--import-cuesheet-from="$ABCDETEMPDIR/$CUEFILE"} --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER" # Set TRACKNUM, TRACKNAME if [ -e "$CDDBDATA" ]; then - if [ "$ONETRACK" = "y" ]; then + if [ "$ONETRACK" = "y" ]; then TRACKNAME="$DALBUM" TRACKNUM="$FIRSTTRACK" splitvarious @@ -3752,7 +4283,7 @@ do fi # Lets tag the cue file if checkstatus cleancuefile >/dev/null; then :; else - if checkstatus cuefile >/dev/null ; then + if checkstatus cuefile >/dev/null ; then do_cleancue fi fi @@ -3768,8 +4299,9 @@ done # Go through it again and make sure there's no distmp3 stragglers, otherwise # we'll delete the files they're working on +# Do NOT play ball if there is no ball to play (so ABORT if needed) ## FIXME ## Check also for files which are encoded using PIPEs. -if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then +if [ "$DOENCODE" = "y" ] && [ "$USEPIPES" != "y" ] && [ ! "$ABORT" ]; then PROCEED= until [ $PROCEED ] do @@ -3796,6 +4328,9 @@ if [ "$DOREPLAYGAIN" = "y" ]; then do_replaygain fi +# Execute the user-defined post_encode function before cleaning up +post_encode + # Check to see if run_command logged any errors if [ -f "$ABCDETEMPDIR/errors" ]; then log error "The following commands failed to run:"