X-Git-Url: https://git.hcoop.net/clinton/abcde.git/blobdiff_plain/99d009faf6f6e870485c182f7701ce93ed5bbdb3..0460999875df81fcc8886287633f544e29c219c6:/abcde diff --git a/abcde b/abcde index 852164d..1d16606 100755 --- a/abcde +++ b/abcde @@ -11,7 +11,7 @@ # Copyright for this work is to expire January 1, 2010, after which it # shall be public domain. -VERSION=2.1.20-2.2pre2 +VERSION="2.1pre2.2.0" usage () { @@ -20,12 +20,13 @@ echo "Usage: abcde [options] [tracks]" echo "Options:" echo "-1 Encode the whole CD in a single file" echo "-a Actions to perform (cddb,read,normalize,encode,tag,move,playlist,clean)" +echo "-A Experimental actions (retag, transcode)" echo "-b Batch mode: enable album normalization and nogap encoding" echo "-c Specify a configuration file (overrides system and user config files)" echo "-C Specify discid to resume from (only needed if you no longer have the cd)" echo "-d Specify CDROM device to grab" echo "-D Debugging mode (equivalent to sh -x abcde)" -#echo "-f Force the use of a local CDDB entry. Otherwise use an empty template" +echo "-f Force the use of a local CDDB entry. Use an empty template if not found" 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" @@ -35,11 +36,12 @@ 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 "-o Output file type(s) (ogg,mp3,flac,spx). Defaults to ogg" +echo "-o Output file type(s) (ogg,mp3,flac,spx,mpc). Defaults to ogg" echo "-p Pad track numbers with 0's (if less than 10 tracks)" echo "-r [host1,host2...] Also encode on these remote hosts" +echo "-R Add replaygain values to the tag info (ogg,flac)" echo "-s Start the track numbering at a given number" -echo "-S Set the CD speed (if possible)" +echo "-S Set the CD speed" #echo "-t File types to preprocess (wav)" #echo "-T Set postprocessing options" echo "-v Show version number and exit" @@ -301,6 +303,7 @@ do_tag () echo GENRE="$CDGENRE" fi echo TRACKNUMBER=$1 + echo CDDB=$CDDBDISCID if [ "$(eval echo ${COMMENT})" != "" ]; then case "$COMMENTOUTPUT" in *=*) echo "$COMMENTOUTPUT";; @@ -329,13 +332,14 @@ do_tag () if [ -n "$CDGENRE" ]; then echo GENRE="$CDGENRE" fi + echo TRACKNUMBER=$1 + echo CDDB=$CDDBDISCID if [ "$(eval echo ${COMMENT})" != "" ]; then case "$COMMENTOUTPUT" in *=*) echo "$COMMENTOUTPUT";; *) echo COMMENT="$COMMENTOUTPUT";; esac fi - echo TRACKNUMBER=$1 ) | run_command tagtrack-$1 $METAFLAC --import-vc-from=- --no-utf8-convert "$ABCDETEMPDIR/track$1.$OUTPUT" ;; spx) @@ -465,7 +469,7 @@ 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 encodetrack-$OUTPUT-$1 nice $ENCNICE $MPPENCODER $MPPENCOPTS --artist "$TRACKARTIST" --album "$DALBUM" --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" --year "$CDYEAR" --comment "$COMMENT" "$IN" "$OUT" + run_command encodetrack-$OUTPUT-$1 nice $ENCNICE $MPPENCODER $MPPENCODEROPTS --artist "$TRACKARTIST" --album "$DALBUM" --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" --year "$CDYEAR" --comment "$COMMENT" "$IN" "$OUT" ;; esac done @@ -661,7 +665,7 @@ do_move () ALBUMFILE=$(mungefilename "$DALBUM") ARTISTFILE=$(mungefilename "$TRACKARTIST") TRACKFILE=$(mungefilename "$TRACKNAME") - GENRE=$(echo $CDGENRE | tr "[:upper:]" "[:lower:]") + GENRE=$(mungegenre "$GENRE") YEAR=$(echo $CDYEAR) # If we want to start the tracks with a given number, we need to modify the # TRACKNUM value before evaluation @@ -701,7 +705,7 @@ do_playlist () for LASTTRACK in $TRACKQUEUE; do :; done ALBUMFILE=$(mungefilename "$DALBUM") ARTISTFILE=$(mungefilename "$DARTIST") - GENRE=$(echo $CDGENRE | tr "[:upper:]" "[:lower:]") + GENRE=$(mungegenre "$GENRE") if [ "$VARIOUSARTISTS" = "y" ] ; then PLAYLISTFILE=$(eval echo $VAPLAYLISTFORMAT) else @@ -710,7 +714,6 @@ do_playlist () FINALPLAYLISTDIR=$(dirname "$OUTPUTDIR/$PLAYLISTFILE") mkdir -p "$FINALPLAYLISTDIR" if [ -s "$OUTPUTDIR/$PLAYLISTFILE" ]; then - ## FIXME ## Erase, Append or Keep the playlist? #echo -n "Erase any existing playlist file? [y/n] (y): " >&2 echo -n "Erase, Append to, or Keep the existing playlist file? [e/a/k] (e): " >&2 if [ "$INTERACTIVE" = "y" ]; then @@ -725,7 +728,11 @@ do_playlist () echo e >&2 ERASEPLAYLIST=e fi - [ "$ERASEPLAYLIST" = "e" -o "$ERASEPLAYLIST" = "E" ] && rm -f "$OUTPUTDIR/$PLAYLISTFILE" + # Once we erase the playlist, we use append to create the new one. + [ "$ERASEPLAYLIST" = "e" -o "$ERASEPLAYLIST" = "E" ] && rm -f "$OUTPUTDIR/$PLAYLISTFILE" && ERASEPLAYLIST=a + else + # The playlist does not exist, so we can safelly use append to create the new list + ERASEPLAYLIST=a fi if [ "$ERASEPLAYLIST" = "a" -o "$ERASEPLAYLIST" = "A" ]; then touch "$OUTPUTDIR/$PLAYLISTFILE" @@ -782,8 +789,12 @@ do_playlist () 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 - echo -n "Getting CD track info... " + vecho -n "Getting CD track info... " TRACKINFO=$($CDDISCID $CDROM) # Make sure there's a CD in there by checking cd-discid's return code if [ "$?" = "1" ]; then @@ -800,6 +811,9 @@ do_discid () # it later. # get the number of digits to pad TRACKNUM with - we'll use this later + # a CD can only hold 99 tracks, but since we support a feature for starting + # numbering the tracks from a given number, we might need to set it as a + # variable for the user to define... or obtain it somehow. if [ "$PADTRACKS" = "y" ] ; then TRACKNUMPADDING=2 fi @@ -864,7 +878,6 @@ do_discid () # We have the discid, create a temp directory after it to store all the temp # info - ABCDETEMPDIR="$WAVOUTPUTDIR/abcde.$(echo $TRACKINFO | cut -f1 -d' ')" if [ -e "$ABCDETEMPDIR" ]; then echo -n "abcde: attempting to resume from $ABCDETEMPDIR" # It already exists, see if it's a directory @@ -1004,36 +1017,41 @@ do_localcddb () USELOCALRESP="y" # If the user has selected to check a local CDDB repo, we proceed with it - if [ "$CDDBUSELOCAL" = "y" ]; then - if [ -r "${CDDBLOCALFILE}" ]; then - # List out disc title/author and contents - do_cddbparse "${CDDBLOCALFILE}" - echo -n "Locally cached CDDB entry found, use it? [y/n] (y): " - if [ "$INTERACTIVE" = "y" ]; then + if [ -r "${CDDBLOCALFILE}" ]; then + # List out disc title/author and contents + do_cddbparse "${CDDBLOCALFILE}" + echo -n "Locally cached CDDB entry found, use it? [y/n] (y): " + if [ "$INTERACTIVE" = "y" ]; then + read USELOCALRESP + while [ "$USELOCALRESP" != "y" ] && [ "$USELOCALRESP" != "n" ] && [ "$USELOCALRESP" != "" ] ; do + echo -n 'Invalid selection. Please answer "y" or "n": ' read USELOCALRESP - while [ "$USELOCALRESP" != "y" ] && [ "$USELOCALRESP" != "n" ] && [ "$USELOCALRESP" != "" ] ; do - echo -n 'Invalid selection. Please answer "y" or "n": ' - read USELOCALRESP - done - [ x"$USELOCALRESP" = "x" ] && USELOCALRESP="y" - else - echo "y">&2 - fi - if [ "$USELOCALRESP" = "y" ]; then - #echo "Using local copy of CDDB data" - cp "${CDDBLOCALFILE}" "$ABCDETEMPDIR/cddbread.1" - echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB - echo cddb-readcomplete >> "$ABCDETEMPDIR/status" - do_cddbparse "${CDDBLOCALFILE}" > "$ABCDETEMPDIR/cddbchoices" - echo cddb-choice=1 >> "$ABCDETEMPDIR/status" - CDDBLOCALSUCCESS="y" - else - #echo "Not using local copy of CDDB data" - CDDBLOCALSUCCESS="n" - fi + done + [ x"$USELOCALRESP" = "x" ] && USELOCALRESP="y" + else + echo "y" >&2 + fi + if [ "$USELOCALRESP" = "y" ]; then + #echo "Using local copy of CDDB data" + cp "${CDDBLOCALFILE}" "$ABCDETEMPDIR/cddbread.1" + echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB + echo cddb-readcomplete >> "$ABCDETEMPDIR/status" + do_cddbparse "${CDDBLOCALFILE}" > "$ABCDETEMPDIR/cddbchoices" + echo cddb-choice=1 >> "$ABCDETEMPDIR/status" + CDDBLOCALSUCCESS="y" else + #echo "Not using local copy of CDDB data" CDDBLOCALSUCCESS="n" fi + elif [ "$FORCECDDBUSELOCAL"= "y" ]; then + $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0" + echo 998 > "$ABCDETEMPDIR/cddbquery" # Assuming 998 isn't used by CDDB + echo cddb-readcomplete >> "$ABCDETEMPDIR/status" + do_cddbparse "${CDDBLOCALFILE}" > "$ABCDETEMPDIR/cddbchoices" + echo cddb-choice=0 >> "$ABCDETEMPDIR/status" + CDDBLOCALSUCCESS="y" + else + CDDBLOCALSUCCESS="n" fi fi } @@ -1286,7 +1304,7 @@ do_cddbedit () fi else # We need some code to show the selected option when local repository is selected and we have found a match - vecho "Using cached CDDB match..." + vecho "Using cached CDDB match..." >&2 # Display the $ABCDETEMPDIR/cddbchoices file created above # Pick a pager so that if the tracks overflow the screen the user can still view everything if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then @@ -1295,6 +1313,10 @@ do_cddbedit () if [ "$USELOCALRESP" = "y" ]; then :; else if [ -n "$CHOICE" ] ; then case $CDDBCHOICES in + 0) + UNKNOWNDISK=y + echo "Selected template." + ;; 1) cat "$ABCDETEMPDIR/cddbchoices" ;; *) echo "Selected: #$CHOICE" @@ -1333,7 +1355,7 @@ do_cddbedit () exit 1 fi CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)" - echo -n "Edit selected CDDB data? [y/n] (" + echo -n "Edit selected CDDB data? [y/n] (" >&2 if [ "$INTERACTIVE" = "y" ]; then if [ "$UNKNOWNDISK" = "y" ]; then echo -n "y): " >&2 @@ -1547,9 +1569,12 @@ do_cdread_one () debug) nice $READNICE $CDROMREADER -d $CDROM -w $UTRACKNUM-[:1] "$WAVDATA" >&2 ;; esac RETURN=$? - if [ "$RETURN" != "0" ]; then + if [ "$RETURN" != "0" -o ! -s "$WAVDATA" ]; then # Thank goodness errors is only machine-parseable up to the # first colon, otherwise this woulda sucked + if [ "$RETURN" = "0" -a ! -s "$WAVDATA" ]; then + RETURN=73 # fake a return code as cdparanoia return 0 also on aborted reads + fi echo "readtrack-$FIRSTTRACKNUMBER: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors" return $RETURN else @@ -1607,9 +1632,12 @@ do_cdread () debug) nice $READNICE $CDROMREADER -d $CDROM -w $UTRACKNUM-[:1] "$WAVDATA" >&2 ;; esac RETURN=$? - if [ "$RETURN" != "0" ]; then + if [ "$RETURN" != "0" -o ! -s "$WAVDATA" ]; then # Thank goodness errors is only machine-parseable up to the # first colon, otherwise this woulda sucked + if [ "$RETURN" = "0" -a ! -s "$WAVDATA" ]; then + RETURN=73 # fake a return code as cdparanoia return 0 also on aborted reads + fi echo "readtrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors" return $RETURN else @@ -1655,6 +1683,7 @@ OGGENCODERSYNTAX=default FLACENCODERSYNTAX=default SPEEXENCODERSYNTAX=default MPPENCODERSYNTAX=default +NORMALIZERSYNTAX=default OUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${TRACKNUM}.${TRACKFILE}' # Use the following VAOUTPUTFORMAT to revert to 2.0.x VA format: @@ -1674,7 +1703,6 @@ READNICE=10 DISTMP3NICE=10 VARIOUSARTISTS=n VARIOUSARTISTSTYLE=forward -NORMALIZERSYNTAX=default KEEPWAVS=n PADTRACKS=n CDDBCOPYLOCAL="n" @@ -1716,8 +1744,9 @@ MD5SUM=md5sum DISTMP3=distmp3 VORBISCOMMENT=vorbiscomment METAFLAC=metaflac -NORMALIZE=normalize +NORMALIZE=normalize-audio CDSPEED=eject +VORBISGAIN=vorbisgain # Options for programs called from abcde # mp3 @@ -1734,6 +1763,8 @@ OGGENCOPTS= FLACOPTS= # speex SPEEXENCOPTS= +# mpc +MPPENCOPTS= ID3OPTS= ID3V2OPTS= @@ -1758,7 +1789,13 @@ ACTIONS=cddb,read,encode,tag,move,clean # Custom filename munging: mungefilename () { - echo "$@" | sed s,:,\ -,g | tr \ / __ | tr -d \'\"\?\[:cntrl:\] + echo "$@" | sed s,:,\ -,g | tr \ /\* __+ | tr -d \'\"\?\[:cntrl:\] +} + +# Custom genre munging: +mungegenre () +{ + echo $CDGENRE | tr "[:upper:]" "[:lower:]" } # pre_read @@ -1839,10 +1876,11 @@ fi # Parse command line options #while getopts 1a:bc:C:d:Dhj:klLnNo:pr:S:t:T:vVx opt ; do -while getopts 1a:bc:C:d:Dhj:klLnNo:pr:s:S:vVx opt ; do +while getopts 1a:A:bc:C:d:Dfhj:klLnNo:pr:Rs:S:vVx opt ; do case "$opt" in 1) ONETRACK=y ;; a) ACTIONS="$OPTARG" ;; + A) EXPACTIONS="$OPTARG";; b) BATCH=y ;; c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else echo "abcde error: config file \"$OPTARG\" cannot be found." >&2 ; exit 1 ; fi ;; C) DISCID="${OPTARG#abcde.}" ;; @@ -1861,6 +1899,7 @@ while getopts 1a:bc:C:d:Dhj:klLnNo:pr:s:S:vVx opt ; do o) OUTPUTTYPE="$OPTARG" ;; p) PADTRACKS="y" ;; r) REMOTEHOSTS="$OPTARG" ;; + R) REPLAYGAIN=y ;; s) STARTTRACKNUMBER="$OPTARG" ;; S) CDSPEEDVALUE="$OPTARG" ;; t) PREPROCESSFORMATS="$OPTARG" @@ -1963,6 +2002,7 @@ do case $OUTPUT in ogg) [ "$OGGENCODERSYNTAX" = "default" ] && OGGENCODERSYNTAX=oggenc echo $ACTIONS | grep tag > /dev/null 2>&1 && NEEDCOMMENTER=y + if [ "$REPLAYGAIN" = "y" ]; then NEEDVORBISGAIN=y; fi ;; mp3) [ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame echo $ACTIONS | grep tag > /dev/null 2>&1 && NEEDTAGGER=y @@ -2076,7 +2116,8 @@ for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \ ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \ ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \ ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \ - ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} + ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} \ + ${NEEDVORBISGAIN+$VORBISGAIN} do # Cut off the command-line options we just added in X=$(echo $X | cut -d' ' -f2) @@ -2093,9 +2134,12 @@ CDROMREADER="$CDROMREADER $CDROMREADEROPTS" CDDBTOOL="$CDDBTOOL $CDDBTOOLOPTS" HTTPGET="$HTTPGET $HTTPGETOPTS" -# One thousand seven hundred lines in, we can start doing stuff with things +# Here it used to say: +# One thousand lines in, we can start doing stuff with things +# Well, right now we are at line 2139 ;) -# List of valid actions: cddb,playlist,read,normalize,encode,tag,move +# List of valid actions: cddb,read,normalize,encode,tag,playlist,move,clean +# List of experimental actions: retag,transcode # Export needed things so they can be read in this subshell export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS