Last changes... we are getting bugs fixed and ready for a 2.4 release
[clinton/abcde.git] / abcde
1 #!/bin/bash
2 # Copyright (c) 1998-2001 Robert Woodcock <rcw@debian.org>
3 # Copyright (c) 2003-2006 Jesus Climent <jesus.climent@hispalinux.es>
4 # This code is hereby licensed for public consumption under either the
5 # GNU GPL v2 or greater, or Larry Wall's Artistic license - your choice.
6 #
7 # You should have received a copy of the GNU General Public License along
8 # with this program; if not, write to the Free Software Foundation, Inc.,
9 # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
10 #
11 # Copyright for this work is to expire January 1, 2010, after which it
12 # shall be public domain.
13 #
14 # $Id$
15
16 VERSION='2.3.99-$Revision$'
17
18 usage ()
19 {
20 echo "This is abcde v$VERSION."
21 echo "Usage: abcde [options] [tracks]"
22 echo "Options:"
23 echo "-1 Encode the whole CD in a single file"
24 echo "-a <action1[,action2]...>"
25 echo " Actions to perform:"
26 echo " cddb,read,normalize,encode,tag,move,replaygain,playlist,clean"
27 #echo "-A Experimental actions (retag, transcode)"
28 echo "-b Enable batch normalization"
29 #echo "-B Disable batch replaygain (do file by file)"
30 echo "-c <file>"
31 echo " Specify a configuration file (overrides system and user config files)"
32 echo "-C <discid#>"
33 echo " Specify discid to resume from (only needed if you no longer have the cd)"
34 echo "-d <device>"
35 echo " Specify CDROM device to grab (flac uses a single-track flac file)"
36 echo "-D Debugging mode (equivalent to sh -x abcde)"
37 echo "-e Erase encoded track information from status file"
38 echo "-f Force operations that otherwise are considered harmful. Read \"man abcde\""
39 echo "-g Use \"lame --nogap\" for MP3 encoding. Disables low disk and pipes flags"
40 echo "-h This help information"
41 #echo "-i Tag files while encoding, when possible (local only) -NWY-"
42 echo "-j <#> Number of encoder processes to run at once (localhost)"
43 echo "-k Keep the wav tracks for later use"
44 echo "-l Use low disk space algorithm"
45 echo "-L Use local CDDB storage directory"
46 echo "-n No lookup. Don't query CDDB, just create and use template"
47 echo "-N Noninteractive. Never prompt for anything"
48 echo "-m Modify playlist to include CRLF endings, to comply with some players"
49 echo " WARNING: Deprecated. Use \"cue\" action"
50 #echo "-M Create a CUE file"
51 echo "-o <type1[,type2]...>"
52 echo " Output file type(s) (vorbis,mp3,flac,spx,mpc,wav,m4a). Defaults to vorbis"
53 echo "-p Pad track numbers with 0's (if less than 10 tracks)"
54 echo "-P Use UNIX pipes to read+encode without wav files"
55 echo "-q <level>"
56 echo " Set quality level (high,medium,low)"
57 echo "-r <host1[,host2]...>"
58 echo " Also encode on these remote hosts"
59 echo "-R Use local CDDB in recursive mode"
60 echo "-s <field>"
61 echo " Show dielfs from the CDDB info (year,genre)"
62 echo "-S <#> Set the CD speed"
63 echo "-t <#> Start the track numbering at a given number"
64 echo "-T <#> Same as -t but modifies tag numbering"
65 echo "-U Do NOT use UNICODE (UTF8) tags and comments"
66 echo "-v Show version number and exit"
67 echo "-V Be a bit more verbose about what is happening behind the scenes"
68 echo "-x Eject CD after all tracks are read"
69 echo "-w <comment>"
70 echo " Add a comment to the CD tracks"
71 echo "-W <#> Contatenate CDs: -T #01 -w \"CD #\""
72 echo "-z Use debug CDROMREADERSYNTAX option (needs cdparanoia)"
73 echo ""
74 echo "Tracks is a space-delimited list of tracks to grab."
75 echo "Ranges specified with hyphens are allowed (i.e., 1-5)."
76 echo ""
77 #echo "Double hyphens are used to concatenate tracks"
78 }
79
80 addstatus ()
81 {
82 echo "$@" >> "$ABCDETEMPDIR/status"
83 }
84
85 # log [level] [message]
86 #
87 # log outputs the right message in a common format
88 log ()
89 {
90 BLURB="$1"
91 shift
92 case $BLURB in
93 error) echo "[ERROR] abcde: $@" >&2 ;;
94 warning) echo "[WARNING] $@" >&2 ;;
95 info) echo "[INFO] $@" ;;
96 esac
97 }
98
99 # Funtions to replace the need of seq, which is too distribution dependant.
100 f_seq_row ()
101 {
102 i=$1
103 while [ $i -ne `expr $2 + 1` ]
104 do
105 echo $i
106 i=`expr $i + 1`
107 done
108 }
109
110 f_seq_line ()
111 {
112 i=$1
113 if echo $i | grep "[[:digit:]]" > /dev/null 2>&1 ; then
114 while [ $i -ne `expr $2 + 1` ]
115 do
116 printf $i" "
117 i=`expr $i + 1`
118 done
119 echo
120 else
121 log error "syntax error while processing track numbers"
122 exit 1
123 fi
124 }
125
126 # Functions to replace the need of awk {print $1} and {print $NF}
127 get_first()
128 {
129 if [ X"$1" = "X" ]; then
130 for first in `cat`; do
131 break
132 done
133 else
134 first=$1
135 fi
136 echo $first
137 }
138
139 get_last()
140 {
141 if [ X"$1" = "X" ]; then
142 for stdin in `cat`; do
143 last=$stdin
144 done
145 else
146 for last in $@ ; do :; done
147 fi
148 echo $last
149 }
150
151 # checkstatus [blurb]
152 # Returns "0" if the blurb was found, returns 1 if it wasn't
153 # Puts the blurb content, if available, on stdout.
154 # Otherwise, returns "".
155 checkstatus ()
156 {
157 # Take the last line in the status file if there's multiple matches
158 PATTERN="^$1(=.*)?$"
159 BLURB=$(egrep $PATTERN "$ABCDETEMPDIR/status" | tail -n 1)
160
161 if [ -z "$BLURB" ]; then
162 # No matches found
163 return 1
164 else
165 # Matches found
166 # See if there's a = in it
167 if [ "$(echo $BLURB | grep -c =)" != "0" ]; then
168 echo "$(echo $BLURB | cut -f2- -d=)"
169 fi
170 return 0
171 fi
172 }
173
174 # checkwarnings [blurb]
175 # Returns "0" if the blurb was found (meaning there was an warning),
176 # returns 1 if it wasn't (yes this is a little backwards).
177 # Does not print the blurb on stdout.
178 # Otherwise, returns "".
179 checkwarnings ()
180 {
181 if [ -e "$ABCDETEMPDIR/warnings" ]; then :; else
182 return 1
183 fi
184 # Take the last line in the status file if there's multiple matches
185 PATTERN="^$1(:.*)?$"
186 BLURB="$(egrep $PATTERN "$ABCDETEMPDIR/warnings" | tail -n 1)"
187
188 if [ -z "$BLURB" ]; then
189 # negative, we did not have a negative...
190 return 1
191 else
192 # affirmative, we had a negative...
193 return 0
194 fi
195 }
196
197 # checkerrors [blurb]
198 # Returns "0" if the blurb was found (meaning there was an error),
199 # returns 1 if it wasn't (yes this is a little backwards).
200 # Does not print the blurb on stdout.
201 # Otherwise, returns "".
202 checkerrors ()
203 {
204 if [ -e "$ABCDETEMPDIR/errors" ]; then :; else
205 return 1
206 fi
207 # Take the last line in the status file if there's multiple matches
208 PATTERN="^$1(:.*)?$"
209 BLURB="$(egrep $PATTERN "$ABCDETEMPDIR/errors" | tail -n 1)"
210
211 if [ -z "$BLURB" ]; then
212 # negative, we did not have a negative...
213 return 1
214 else
215 # affirmative, we had a negative...
216 return 0
217 fi
218 }
219
220 # page [file]
221 # Finds the right pager in the system to display a file
222 page ()
223 {
224 PAGEFILE="$1"
225 # Use the debian sensible-pager wrapper to pick the pager
226 # user has requested via their $PAGER environment variable
227 if [ -x "/usr/bin/sensible-pager" ]; then
228 /usr/bin/sensible-pager "$PAGEFILE"
229 elif [ -x "$PAGER" ]; then
230 # That failed, try to load the preferred editor, starting
231 # with their PAGER variable
232 $PAGER "$PAGEFILE"
233 # If that fails, check for less
234 elif [ -x /usr/bin/less ]; then
235 /usr/bin/less -f "$PAGEFILE"
236 # more should be on all UNIX systems
237 elif [ -x /bin/more ]; then
238 /bin/more "$PAGEFILE"
239 else
240 # No bananas, just cat the thing
241 cat "$PAGEFILE" >&2
242 fi
243 }
244
245 # run_command [blurb] [command...]
246 # Runs a command, silently if necessary, and updates the status file
247 run_command ()
248 {
249 BLURB="$1"
250 shift
251 # See if this is supposed to be silent
252 if [ "$(checkstatus encode-output)" = "loud" ]; then
253 "$@" >&2
254 RETURN=$?
255 else
256 # Special case for SMP, since
257 # encoder output is never displayed, don't mute echos
258 if [ -z "$BLURB" -a "$MAXPROCS" != "1" ]; then
259 "$@" >&2
260 RETURN=$?
261 else
262 "$@" >/dev/null 2>&1
263 RETURN=$?
264 fi
265 fi
266 case "$1" in
267 normalize|normalize-audio)
268 if [ "$RETURN" = "2" ]; then
269 # File was already normalized.
270 RETURN=0
271 fi
272 ;;
273 esac
274 if [ "$RETURN" != "0" ]; then
275 # Put an error in the errors file. For various reasons we
276 # can't capture a copy of the program's output but we can
277 # log what we attempted to execute and the error code
278 # returned by the program.
279 if [ "$BLURB" ]; then
280 TWEAK="$BLURB: "
281 fi
282 echo "${TWEAK}returned code $RETURN: $@" >> "$ABCDETEMPDIR/errors"
283 return $RETURN # Do not pass go, do not update the status file
284 fi
285 if [ "$BLURB" ]; then
286 echo $BLURB >> "$ABCDETEMPDIR/status"
287 fi
288 }
289
290 # relpath() and slash() are Copyright (c) 1999 Stuart Ballard and
291 # distributed under the terms of the GNU GPL v2 or later, at your option
292
293 # Function to determine if a word contains a slash.
294 slash ()
295 {
296 case "$1" in
297 */*) return 0;;
298 *) return 1;;
299 esac
300 }
301
302 # Function to give the relative path from one file to another.
303 # Usage: relpath fromfile tofile
304 # eg relpath music/Artist/Album.m3u music/Artist/Album/Song.mp3
305 # (the result would be Album/Song.mp3)
306 # Output is relative path to $2 from $1 on stdout
307
308 # This code has the following restrictions:
309 # Multiple ////s are not collapsed into single /s, with strange effects.
310 # Absolute paths and ../s are handled wrong in FR (but they work in TO)
311 # If FR is a directory it must have a trailing /
312
313 relpath ()
314 {
315 FR="$1"
316 TO="$2"
317
318 case "$TO" in
319 /*) ;; # No processing is needed for absolute paths
320 *)
321 # Loop through common prefixes, ignoring them.
322 while slash "$FR" && [ "$(echo "$FR" | cut -d/ -f1)" = "$(echo "$TO" | cut -d/ -f1)" ]
323 do
324 FR="$(echo "$FR" | cut -d/ -f2-)"
325 TO="$(echo "$TO" | cut -d/ -f2-)"
326 done
327 # Loop through directory portions left in FR, adding appropriate ../s.
328 while slash "$FR"
329 do
330 FR="$(echo "$FR" | cut -d/ -f2-)"
331 TO="../$TO"
332 done
333 ;;
334 esac
335
336 echo $TO
337 }
338
339 new_checkexec ()
340 {
341 if [ ! "$@" = "" ]; then
342 # Cut off any command-line option we added in
343 X=$(echo $@ | cut -d' ' -f2)
344 if [ "$(which $X)" = "" ]; then
345 return 1
346 elif [ ! -x $(which $X) ]; then
347 return 2
348 fi
349 fi
350 return 0
351 }
352
353 checkexec ()
354 {
355 if [ ! "$@" = "" ]; then
356 # Cut off any command-line option we added in
357 X=$(echo $@ | cut -d' ' -f2)
358 # Test for built-in abcde.function
359 [ "$X" != "${X#abcde.}" ] && type $X >/dev/null 2>&1 && return
360 if [ "$(which $X)" = "" ]; then
361 log error "$X is not in your path." >&2
362 log info "Define the full path to the executable if it exists on your system." >&2
363 exit 1
364 elif [ ! -x "$(which $X)" ]; then
365 log error "$X is not executable." >&2
366 exit 1
367 fi
368 fi
369 }
370
371 # diffentries <filename> <max_value> <entry1>,<entry2>
372 # max_value: the range of entries goes from 1 to <max_value>
373 diffentries ()
374 {
375 FILENAME=$1
376 shift
377 local CDDBDIFFCHOICES=$1
378 shift
379 local CDDBDIFFCHOICE="$@"
380 if [ ! X"$DIFF" = "X" ]; then
381 PARSECHOICE1=$(echo $CDDBDIFFCHOICE | cut -d"," -f1 | xargs printf %d 2>/dev/null)
382 PARSECHOICE2=$(echo $CDDBDIFFCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null)
383 if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBDIFFCHOICES ] || \
384 [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBDIFFCHOICES ] || \
385 [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then
386 echo "Invalid diff range. Please select two coma-separated numbers between 1 and $CDDBDIFFCHOICES" >&2
387 else
388 # We parse the 2 choices to diff, store them in temporary files and diff them.
389 for PARSECHOICE in $(echo $CDDBDIFFCHOICE | tr , \ ); do
390 do_cddbparse "$ABCDETEMPDIR/$FILENAME.$PARSECHOICE" > "$ABCDETEMPDIR/$FILENAME.parsechoice.$PARSECHOICE"
391 done
392 echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..." > "$ABCDETEMPDIR/$FILENAME.diff"
393 $DIFF $DIFFOPTS "$ABCDETEMPDIR/$FILENAME.parsechoice.$PARSECHOICE1" "$ABCDETEMPDIR/$FILENAME.parsechoice.$PARSECHOICE2" >> "$ABCDETEMPDIR/$FILENAME.diff"
394 if [ $(cat "$ABCDETEMPDIR/$FILENAME.diff" | wc -l) -ge 24 ]; then
395 page "$ABCDETEMPDIR/$FILENAME.diff"
396 else
397 cat "$ABCDETEMPDIR/$FILENAME.diff" >&2
398 fi
399 fi
400 else
401 echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBDIFFCHOICES." >&2
402 fi
403 }
404
405 # getcddbinfo
406 # Finds an specific field from cddbinfo
407 getcddbinfo()
408 {
409 case $1 in
410 TRACKNAME1)
411 TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
412 ;;
413 TRACKNAME)
414 TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
415 ;;
416 esac
417 }
418
419 # gettracknum
420 # Get the track number we are going to use for different actions
421 gettracknum()
422 {
423 if [ -n "$STARTTRACKNUMBER" ] ; then
424 # Get the trackpadding from the current track
425 CURRENTTRACKPADDING=$(echo -n $UTRACKNUM | wc -c)
426 TRACKNUM=$( printf %0.${CURRENTTRACKPADDING}d $(expr ${UTRACKNUM} + ${STARTTRACKNUMBER} - $FIRSTTRACK ))
427 else
428 TRACKNUM=${UTRACKNUM}
429 fi
430 }
431
432 # makeids
433 #
434 # Calculate cddb disc ids without requiring specialized helper programs.
435 # largely copied from cd-discid and musicbrainz examples. some of the steps
436 # don't make sense, but they're necessary to match the ids generated by other
437 # programs.
438 #
439 ## FIXME ## Right now, we get 2 frames more than with cue2discid ??
440 # data@petit:~$ sh /tmp/cue2discid /home/data/tmp/flac/01.Roisin_Murphy--Ruby_Blue.flac
441 # 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
442 # 980b4b0c 12 150 21685 37687 53146 80061 97782 124071 144448 160603 173208 197438 201334 2895
443 # data@petit:~$ metaflac --export-cuesheet-to=- /home/data/tmp/flac/01.Roisin_Murphy--Ruby_Blue.flac| python /home/data/sources/abcde/trunk/examples/cue2discid
444 # 980b4b0c 12 150 21685 37687 53146 80061 97782 124071 144448 160603 173208 197438 201334 2893
445 #
446 # Variables: OFFSETS, TRACKS, LEADOUT, [LEADIN]
447 makeids ()
448 {
449 if [ X"$LEADOUT" = "X" ]; then
450 log warning "Error trying to calculate disc ids without lead-out information."
451 exit 1
452 fi
453
454 # default to a two second lead-in
455 IDMAGICNUM=150
456 LEADIN=${LEADIN:=150}
457
458 # number of cdframes per second
459 CDFRAMES=75
460
461 # reset cddb checksum for cddb disc-id calululation
462 CDDBCKSUM=0
463
464 COOKEDOFFSETS=""
465 for OFFSET in $(echo $OFFSETS)
466 do
467 COOKEDOFFSETS="${COOKEDOFFSETS} $(($OFFSET + $LEADIN))"
468
469 OFFSETTIME=$(( ($OFFSET + $LEADIN) / $CDFRAMES ))
470 while [ $OFFSETTIME -gt 0 ]; do
471 CDDBCKSUM=$(($CDDBCKSUM + $OFFSETTIME % 10))
472 OFFSETTIME=$(($OFFSETTIME / 10))
473 done
474
475 done
476
477 COOKEDOFFSETS="${COOKEDOFFSETS:1}" # eat the leading space
478
479 PREGAP=$(($(echo $OFFSETS | cut -f1 -d' ')))
480 TOTALTIME=$(( (($LEADOUT + $LEADIN + $PREGAP) / $CDFRAMES) - (($LEADIN + $PREGAP) / $CDFRAMES)))
481
482 printf -v HEXSUM "%08lx" $(( ($CDDBCKSUM % 0xff) << 24 | $TOTALTIME << 8 | $TRACKS))
483 TRACKINFO="${HEXSUM} $((TRACKS)) ${COOKEDOFFSETS} $((($LEADOUT + $LEADIN + $IDMAGICNUM) / $CDFRAMES))"
484 }
485
486 do_replaygain()
487 {
488 if checkstatus replaygain; then :; else
489 run_command "" echo "Adding replygain information..."
490 for TMPOUTPUT in $( echo $OUTPUTTYPE | tr , \ )
491 do
492 case $TMPOUTPUT in
493 vorbis|ogg)
494 OUTPUT=$OGGOUTPUTCONTAINER
495 ;;
496 flac)
497 OUTPUT=$FLACOUTPUTCONTAINER
498 ;;
499 *)
500 OUTPUT=$TMPOUTPUT
501 ;;
502 esac
503 OUTPUTFILES=""
504 REPLAYINDEX=0
505 for UTRACKNUM in $TRACKQUEUE
506 do
507 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
508 getcddbinfo TRACKNAME
509 splitvarious
510 TRACKFILE="$(mungefilename "$TRACKNAME")"
511 ARTISTFILE="$(mungefilename "$TRACKARTIST")"
512 ALBUMFILE="$(mungefilename "$DALBUM")"
513 gettracknum
514 if [ "$ONETRACK" = "y" ]; then
515 if [ "$VARIOUSARTISTS" = "y" ]; then
516 OUTPUTFILE="$(eval echo \""$VAONETRACKOUTPUTFORMAT"\")"
517 else
518 OUTPUTFILE="$(eval echo \""$ONETRACKOUTPUTFORMAT"\")"
519 fi
520 else
521 if [ "$VARIOUSARTISTS" = "y" ]; then
522 OUTPUTFILE="$(eval echo \""$VAOUTPUTFORMAT"\")"
523 else
524 OUTPUTFILE="$(eval echo \""$OUTPUTFORMAT"\")"
525 fi
526 fi
527 OUTPUTFILES[$REPLAYINDEX]="$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
528 (( REPLAYINDEX = $REPLAYINDEX + 1 ))
529 done
530 case "$OUTPUT" in
531 flac)
532 run_command replaygain-flac nice $ENCNICE $METAFLAC --add-replay-gain "${OUTPUTFILES[@]}"
533 ;;
534 vorbis|ogg)
535 run_command replaygain-vorbis nice $ENCNICE $VORBISGAIN --album "${OUTPUTFILES[@]}"
536 ;;
537 mp3)
538 run_command replaygain-mp3 nice $ENCNICE $MP3GAIN -a "${OUTPUTFILES[@]}"
539 ;;
540 mpc)
541 run_command replaygain-mpc nice $ENCNICE $MPPGAIN --auto "${OUTPUTFILES[@]}"
542 ;;
543 *);;
544 esac
545 done
546 if checkerrors "replaygain-.{3,6}"; then :; else
547 run_command replaygain true
548 fi
549 fi
550 }
551
552 # This code splits the a Various Artist track name from one of the following
553 # forms:
554 #
555 # forward: Artist / Track
556 # forward-dash: Artist - Track
557 # reverse: Track / Artist
558 # reverse-dash: Track - Artist
559 # colon: Artist: Track
560 # trailing-paren: Artist (Track)
561 #
562 # variables used:
563 # VARIOUSARTISTS, VARIOUSARTISTSTYLE, TRACKNAME, TRACKARTIST
564 splitvarious ()
565 {
566 if [ "$VARIOUSARTISTS" = "y" ] && [ ! "$ONETRACK" = "y" ]; then
567 case "$VARIOUSARTISTSTYLE" in
568 forward)
569 DTITLEARTIST="$(echo "$TRACKNAME" | sed 's- / -~-g')"
570 TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
571 TRACKNAME="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
572 ;;
573 forward-dash)
574 DTITLEARTIST="$(echo "$TRACKNAME" | sed 's, - ,~,g')"
575 TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
576 TRACKNAME="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
577 ;;
578 reverse)
579 DTITLEARTIST="$(echo "$TRACKNAME" | sed 's- / -~-g')"
580 TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
581 TRACKNAME="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
582 ;;
583 reverse-dash)
584 DTITLEARTIST="$(echo "$TRACKNAME" | sed 's, - ,~,g')"
585 TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
586 TRACKNAME="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
587 ;;
588 colon)
589 DTITLEARTIST="$(echo "$TRACKNAME" | sed 's-: -~-g')"
590 TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
591 TRACKNAME="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
592 ;;
593 trailing-paren)
594 DTITLEARTIST="$(echo "$TRACKNAME" | sed 's,^\(.*\) (\(.*\)),\1~\2,')"
595 TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
596 TRACKNAME="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
597 ;;
598 esac
599 elif [ "$VARIOUSARTISTS" = "y" ] && [ "$ONETRACK" = "y" ]; then
600 TRACKARTIST="Various"
601 else
602 TRACKARTIST="$DARTIST"
603 fi
604 }
605
606 do_getgenreid () {
607 local genre=$(echo "${@}" | tr '[A-Z]' '[a-z]')
608 local id=""
609 case ${genre} in
610 "blues") id=0 ;;
611 "classic rock") id=1 ;;
612 "country") id=2 ;;
613 "dance") id=3 ;;
614 "disco") id=4 ;;
615 "funk") id=5 ;;
616 "grunge") id=6 ;;
617 "hip-hop") id=7 ;;
618 "jazz") id=8 ;;
619 "metal") id=9 ;;
620 "new age") id=10 ;;
621 "oldies") id=11 ;;
622 "other") id=12 ;;
623 "pop") id=13 ;;
624 "r&b") id=14 ;;
625 "rap") id=15 ;;
626 "reggae") id=16 ;;
627 "rock") id=17 ;;
628 "techno") id=18 ;;
629 "industrial") id=19 ;;
630 "alternative") id=20 ;;
631 "ska") id=21 ;;
632 "death metal") id=22 ;;
633 "pranks") id=23 ;;
634 "soundtrack") id=24 ;;
635 "euro-techno") id=25 ;;
636 "ambient") id=26 ;;
637 "trip-hop") id=27 ;;
638 "vocal") id=28 ;;
639 "jazz+funk") id=29 ;;
640 "fusion") id=30 ;;
641 "trance") id=31 ;;
642 "classical") id=32 ;;
643 "instrumental") id=33 ;;
644 "acid") id=34 ;;
645 "house") id=35 ;;
646 "game") id=36 ;;
647 "sound clip") id=37 ;;
648 "gospel") id=38 ;;
649 "noise") id=39 ;;
650 "alt. rock") id=40 ;;
651 "bass") id=41 ;;
652 "soul") id=42 ;;
653 "punk") id=43 ;;
654 "space") id=44 ;;
655 "meditative") id=45 ;;
656 "instrum. pop") id=46 ;;
657 "instrum. rock") id=47 ;;
658 "ethnic") id=48 ;;
659 "gothic") id=49 ;;
660 "darkwave") id=50 ;;
661 "techno-indust.") id=51 ;;
662 "electronic") id=52 ;;
663 "pop-folk") id=53 ;;
664 "eurodance") id=54 ;;
665 "dream") id=55 ;;
666 "southern rock") id=56 ;;
667 "comedy") id=57 ;;
668 "cult") id=58 ;;
669 "gangsta") id=59 ;;
670 "top 40") id=60 ;;
671 "christian rap") id=61 ;;
672 "pop/funk"|"pop / funk") id=62 ;;
673 "jungle") id=63 ;;
674 "native american") id=64 ;;
675 "cabaret") id=65 ;;
676 "new wave") id=66 ;;
677 "psychadelic") id=67 ;;
678 "rave") id=68 ;;
679 "showtunes") id=69 ;;
680 "trailer") id=70 ;;
681 "lo-fi") id=71 ;;
682 "tribal") id=72 ;;
683 "acid punk") id=73 ;;
684 "acid jazz") id=74 ;;
685 "polka") id=75 ;;
686 "retro") id=76 ;;
687 "musical") id=77 ;;
688 "rock & roll") id=78 ;;
689 "hard rock") id=79 ;;
690 "folk") id=80 ;;
691 "folk/rock") id=81 ;;
692 "national folk") id=82 ;;
693 "swing") id=83 ;;
694 "fusion") id=84 ;;
695 "bebob") id=85 ;;
696 "latin") id=86 ;;
697 "revival") id=87 ;;
698 "celtic") id=88 ;;
699 "bluegrass") id=89 ;;
700 "avantgarde") id=90 ;;
701 "gothic rock") id=91 ;;
702 "progress. rock") id=92 ;;
703 "psychadel. rock") id=93 ;;
704 "symphonic rock") id=94 ;;
705 "slow rock") id=95 ;;
706 "big band") id=96 ;;
707 "chorus") id=97 ;;
708 "easy listening") id=98 ;;
709 "acoustic") id=99 ;;
710 "humour") id=100 ;;
711 "speech") id=101 ;;
712 "chanson") id=102 ;;
713 "opera") id=103 ;;
714 "chamber music") id=104 ;;
715 "sonata") id=105 ;;
716 "symphony") id=106 ;;
717 "booty bass") id=107 ;;
718 "primus") id=108 ;;
719 "porn groove") id=109 ;;
720 "satire") id=110 ;;
721 "slow jam") id=111 ;;
722 "club") id=112 ;;
723 "tango") id=113 ;;
724 "samba") id=114 ;;
725 "folklore") id=115 ;;
726 "ballad") id=116 ;;
727 "power ballad") id=117 ;;
728 "rhythmic soul") id=118 ;;
729 "freestyle") id=119 ;;
730 "duet") id=120 ;;
731 "punk rock") id=121 ;;
732 "drum solo") id=122 ;;
733 "a capella") id=123 ;;
734 "euro-house") id=124 ;;
735 "dance hall") id=125 ;;
736 "goa") id=126 ;;
737 "drum & bass") id=127 ;;
738 "club-house") id=128 ;;
739 "hardcore") id=129 ;;
740 "terror") id=130 ;;
741 "indie") id=131 ;;
742 "britpop") id=132 ;;
743 "negerpunk") id=133 ;;
744 "polsk punk") id=134 ;;
745 "beat") id=135 ;;
746 "christian gangsta rap") id=136 ;;
747 "heavy metal") id=137 ;;
748 "black metal") id=138 ;;
749 "crossover") id=139 ;;
750 "contemporary christian")id=140 ;;
751 "christian rock") id=141 ;;
752 "merengue") id=142 ;;
753 "salsa") id=143 ;;
754 "thrash metal") id=144 ;;
755 "anime") id=145 ;;
756 "jpop") id=146 ;;
757 "synthpop") id=147 ;;
758 "rock/pop"|"rock / pop") id=148 ;;
759 *) return 1 ;;
760 esac
761 echo ${id}
762 return 0
763 }
764
765 # do_tag [tracknumber]
766 # id3 tags a filename
767 # variables used:
768 # TRACKS, TRACKNAME, TRACKARTIST, TAGGER, TAGGEROPTS, VORBISCOMMENT, METAFLAC,
769 # COMMENT, DALBUM, DARTIST, CDYEAR, CDGENRE (and temporarily) ID3TAGV
770 do_tag ()
771 {
772 COMMENTOUTPUT="$(eval echo ${COMMENT})"
773 CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
774 run_command '' echo "Tagging track $1 of $TRACKS: $TRACKNAME..."
775 # If we want to start the tracks with a given number, we need to modify the
776 # TRACKNUM value before evaluation
777 if [ -n "$STARTTRACKNUMBERTAG" ] ; then
778 gettracknum
779 fi
780 for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
781 do
782 case "$OUTPUT" in
783 mp3)
784 # id3v2 v0.1.9 claims to have solved the -c bug, so we merge both id3 and id3v2
785 GENREID=$(do_getgenreid "${CDGENRE}")
786
787 case "$ID3SYNTAX" in
788 id3);;
789 eyed3)
790 # FIXME # track numbers in mp3 come with 1/10, so we cannot
791 # happily substitute them with $TRACKNUM
792 run_command tagtrack-$OUTPUT-$1 nice $ENCNICE $TAGGER $TAGGEROPTS \
793 --comment=::"$COMMENTOUTPUT" -A "$DALBUM" \
794 -a "$TRACKARTIST" -t "$TRACKNAME" -Y "$CDYEAR" \
795 -G "$GENREID" -n "${TRACKNUM:-$1}" \
796 "${TRACKNUM:+-N $TRACKS}" \
797 "${ENCODING:+--set-encoding=$ENCODING}" \
798 "$ABCDETEMPDIR/track$1.$OUTPUT"
799 ;;
800 # FIXME # Still not activated...
801 id3ed)
802 run_command tagtrack-$OUTPUT-$1 nice $ENCNICE \
803 $TAGGER $TAGGEROPTS -c "$COMMENTOUTPUT" \
804 -a "$DALBUM" -n "$TRACKARTIST" -s "$TRACKNAME" \
805 -y "$CDYEAR" -g "$GENREID" -k "${TRACKNUM:-$1}" \
806 "$ABCDETEMPDIR/track$1.$OUTPUT"
807 ;;
808 *)
809 # FIXME # track numbers in mp3 come with 1/10, so we cannot
810 # happily substitute them with $TRACKNUM
811 run_command tagtrack-$OUTPUT-$1 nice $ENCNICE \
812 $TAGGER $TAGGEROPTS -c "$COMMENTOUTPUT" \
813 -A "$DALBUM" -a "$TRACKARTIST" -t "$TRACKNAME" \
814 -y "$CDYEAR" -g "$GENREID" \
815 -T "${TRACKNUM:-$1/$TRACKS}" \
816 "$ABCDETEMPDIR/track$1.$OUTPUT"
817 ;;
818 esac
819 ;;
820 vorbis|ogg)
821 case "$OGGENCODERSYNTAX" in
822 vorbize|oggenc)
823 # vorbiscomment can't do in-place modification, mv the file first
824 if [ -f "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" -a ! -f "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" ]; then
825 mv "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER"
826 fi
827 (
828 # These are from
829 # http://www.xiph.org/ogg/vorbis/doc/v-comment.html
830
831 echo ARTIST="$TRACKARTIST"
832 echo ALBUM="$DALBUM"
833 echo TITLE="$TRACKNAME"
834 if [ -n "$CDYEAR" ]; then
835 echo DATE="$CDYEAR"
836 fi
837 if [ -n "$CDGENRE" ]; then
838 echo GENRE="$CDGENRE"
839 fi
840 echo TRACKNUMBER=${TRACKNUM:-$1}
841 echo CDDB=$CDDBDISCID
842 if [ "$(eval echo ${COMMENT})" != "" ]; then
843 case "$COMMENTOUTPUT" in
844 *=*) echo "$COMMENTOUTPUT";;
845 *) echo COMMENT="$COMMENTOUTPUT";;
846 esac
847 fi
848 ) | run_command tagtrack-$OUTPUT-$1 nice $ENCNICE \
849 $VORBISCOMMENT $VORBISCOMMENTOPTS -w \
850 "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
851 # Doublecheck that the commented file was created
852 # successfully before wiping the original
853 if [ -f "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER" ]; then
854 rm -f "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER"
855 else
856 mv "$ABCDETEMPDIR/track$1.uncommented.$OGGOUTPUTCONTAINER" "$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
857 fi
858 ;;
859 esac
860 ;;
861 flac)
862 (
863 echo ARTIST="$TRACKARTIST"
864 echo ALBUM="$DALBUM"
865 echo TITLE="$TRACKNAME"
866 if [ -n "$CDYEAR" ]; then
867 echo DATE="$CDYEAR"
868 fi
869 if [ -n "$CDGENRE" ]; then
870 echo GENRE="$CDGENRE"
871 fi
872 echo TRACKNUMBER="${TRACKNUM:-$1}"
873 echo CDDB="$CDDBDISCID"
874 if [ "$(eval echo ${COMMENT})" != "" ]; then
875 case "$COMMENTOUTPUT" in
876 *=*) echo "$COMMENTOUTPUT";;
877 *) echo COMMENT="$COMMENTOUTPUT";;
878 esac
879 fi
880 ) | run_command tagtrack-$OUTPUT-$1 nice $ENCNICE $METAFLAC $METAFLACOPTS ${IMPORTCUESHEET:+--import-cuesheet-from="$ABCDETEMPDIR/$CUEFILE"} --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
881 ;;
882 spx)
883 run_command tagtrack-$OUTPUT-$1 true
884 ;;
885 mpc)
886 run_command tagtrack-$OUTPUT-$1 true
887 ;;
888 m4a)
889 run_command tagtrack-$OUTPUT-$1 true
890 ;;
891 wav)
892 run_command tagtrack-$OUTPUT-$1 true
893 ;;
894 esac
895 done
896 if checkerrors "tagtrack-(.{3,6})-$1"; then :; else
897 run_command tagtrack-$1 true
898 fi
899
900 }
901
902 # do_nogap_encode
903 # variables used:
904 # OUTPUTTYPE, {FOO}ENCODERSYNTAX, ENCNICE, ENCODER, ENCODEROPTS
905 do_nogap_encode ()
906 {
907 # The commands here don't go through run_command because they're never
908 # supposed to be silenced
909 echo "Encoding gapless MP3 tracks: $TRACKQUEUE"
910 for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
911 do
912 case "$OUTPUT" in
913 mp3)
914 case "$MP3ENCODERSYNTAX" in
915 lame|toolame)
916 (
917 cd "$ABCDETEMPDIR"
918 TRACKFILES=
919 for UTRACKNUM in $TRACKQUEUE
920 do
921 TRACKFILES="$TRACKFILES track$UTRACKNUM.wav"
922 done
923 nice $ENCNICE $MP3ENCODER $MP3ENCODEROPTS --nogap $TRACKFILES
924 RETURN=$?
925 if [ "$RETURN" != "0" ]; then
926 echo "nogap-encode: $ENCODER returned code $RETURN" >> errors
927 else
928 for UTRACKNUM in $TRACKQUEUE
929 do
930 run_command encodetrack-$OUTPUT-$UTRACKNUM true
931 #run_command encodetrack-$UTRACKNUM true
932 done
933 fi
934 )
935 ;;
936 esac
937 ;;
938 esac
939 done
940 if checkerrors "nogap-encode"; then :; else
941 if [ ! "$KEEPWAVS" = "y" ] ; then
942 if [ ! "$KEEPWAVS" = "move" ] ; then
943 rm -f "$IN"
944 fi
945 fi
946 fi
947 # Other encoders fall through to normal encoding as the tracks have not
948 # been entered in the status file.
949 }
950
951 # do_encode [tracknumber] [hostname]
952 # If no hostname is specified, encode locally
953 # variables used:
954 # TRACKS, TRACKNAME, TRACKARTIST, DISTMP3, DISTMP3OPTS, {FOO}ENCODERSYNTAX, OUTPUTTYPE, ENCODEROPTS, DALBUM, DARTIST, ENCNICE, CDYEAR, CDGENRE, COMMENT
955 do_encode ()
956 {
957 if [ "$USEPIPES" = "y" ]; then
958 case "$OUTPUT" in
959 mp3)
960 TEMPARG="PIPE_$MP3ENCODERSYNTAX"
961 ;;
962 vorbis|ogg)
963 TEMPARG="PIPE_$OGGENCODERSYNTAX"
964 ;;
965 flac)
966 TEMPARG="PIPE_$FLACENCODERSYNTAX"
967 ;;
968 spx)
969 TEMPARG="PIPE_$SPEEXENCODER"
970 ;;
971 mpc)
972 TEMPARG="PIPE_$MPPENCODER"
973 ;;
974 m4a)
975 TEMPARG="PIPE_$MPPENCODER"
976 ;;
977 esac
978 IN="$( eval echo "\$$TEMPARG" )"
979 else
980 IN="$ABCDETEMPDIR/track$1.wav"
981 case "$OUTPUT" in
982 mp3)
983 case "$MP3ENCODERSYNTAX" in
984 # FIXME # check if mp3enc needs -if for pipes
985 # FIXME # I have not been able to find a working mp3enc binary
986 mp3enc)
987 FILEARG="-if $IN"
988 ;;
989 *)
990 FILEARG="$IN"
991 ;;
992 esac
993 ;;
994 *)
995 FILEARG="$IN"
996 ;;
997 esac
998 fi
999 # We need IN to proceed, if we are not using pipes.
1000 if [ -s "$IN" -o X"$USEPIPES" = "Xy" ] ; then
1001 for TMPOUTPUT in $(echo $OUTPUTTYPE | tr , \ )
1002 do
1003 case "$TMPOUTPUT" in
1004 vorbis|ogg)
1005 OUTPUT=$OGGOUTPUTCONTAINER
1006 ;;
1007 flac)
1008 OUTPUT=$FLACOUTPUTCONTAINER
1009 ;;
1010 *)
1011 OUTPUT=$TMPOUTPUT
1012 ;;
1013 esac
1014 OUT="$ABCDETEMPDIR/track$1.$OUTPUT"
1015 if [ "$NOGAP" = "y" ] && checkstatus encodetrack-$OUTPUT-$1 ; then
1016 continue
1017 fi
1018 if [ X"$USEPIPES" = "Xy" ]; then
1019 RUN_COMMAND=""
1020 # We need a way to store the creation of the files when using PIPES
1021 RUN_COMMAND_PIPES="run_command encodetrack-$OUTPUT-$1 true"
1022 # When pipping it does not make sense to have a higher nice for
1023 # reading than for encoding, since it will be hold by the
1024 # encoding process. Setting an effective nice, to calm down a
1025 # bit the reading process.
1026 EFFECTIVE_NICE=$READNICE
1027 else
1028 run_command '' echo "Encoding track $1 of $TRACKS: $TRACKNAME..."
1029 RUN_COMMAND="run_command encodetrack-$OUTPUT-$1"
1030 EFFECTIVE_NICE=$ENCNICE
1031 fi
1032 case "$OUTPUT" in
1033 mp3)
1034 case "$2" in
1035 %local*%)
1036 case "$MP3ENCODERSYNTAX" in
1037 lame|toolame|gogo) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER $MP3ENCODEROPTS "$IN" "$OUT" ;;
1038 bladeenc) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER $MP3ENCODEROPTS -quit "$IN" ;;
1039 l3enc|xingmp3enc) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER "$IN" "$OUT" $MP3ENCODEROPTS ;;
1040 # FIXME # Relates to the previous FIXME since it might need the "-if" removed.
1041 mp3enc) $RUN_COMMAND nice $EFFECTIVE_NICE $MP3ENCODER -if "$IN" -of "$OUT" $MP3ENCODEROPTS ;;
1042 esac
1043 ;;
1044 *)
1045 $RUN_COMMAND nice $DISTMP3NICE $DISTMP3 $DISTMP3OPTS "$2" "$IN" "$OUT" >/dev/null 2>&1
1046 ;;
1047 esac
1048 ;;
1049 vorbis|ogg)
1050 case "$2" in
1051 %local*%)
1052 case "$OGGENCODERSYNTAX" in
1053 vorbize) $RUN_COMMAND nice $EFFECTIVE_NICE $OGGENCODER $OGGENCODEROPTS -w "$OUT" "$IN" ;;
1054 oggenc) $RUN_COMMAND nice $EFFECTIVE_NICE $OGGENCODER $OGGENCODEROPTS -o "$OUT" "$IN" ;;
1055 esac
1056 ;;
1057 *)
1058 $RUN_COMMAND nice $DISTMP3NICE $DISTMP3 $DISTMP3OPTS "$2" "$IN" "$OUT" >/dev/null 2>&1
1059 ;;
1060 esac
1061 ;;
1062 flac)
1063 case "$2" in
1064 %local*%)
1065 case "$FLACENCODERSYNTAX" in
1066 flac) $RUN_COMMAND nice $EFFECTIVE_NICE $FLACENCODER -f $FLACENCODEROPTS -o "$OUT" "$IN" ;;
1067 esac
1068 ;;
1069 *)
1070 vecho -n "DISTMP3:"
1071 vecho "$DISTMP3 $DISTMP3OPTS $2 $IN $OUT >/dev/null 2>&1"
1072 $RUN_COMMAND nice $DISTMP3NICE $DISTMP3 $DISTMP3OPTS "$2" "$IN" "$OUT" > /dev/null 2>&1
1073 ;;
1074 esac
1075 ;;
1076 spx)
1077 if [ "$(eval echo ${COMMENT})" != "" ]; then
1078 case "$COMMENT" in
1079 *=*) ;;
1080 *) COMMENT="COMMENT=$COMMENT" ;;
1081 esac
1082 COMMENT="--comment \"$COMMENT\""
1083 fi
1084 # Quick hack to avoid tagging Ogg/Speex, since there is no other way to tag than inline tagging
1085 if [ ! "$DOTAG" = "y" ]; then
1086 $RUN_COMMAND nice $EFFECTIVE_NICE $SPEEXENCODER $SPEEXENCODEROPTS --author "$TRACKARTIST" --title "$TRACKNAME" "$COMMENT" "$IN" "$OUT"
1087 else
1088 $RUN_COMMAND nice $EFFECTIVE_NICE $SPEEXENCODER $SPEEXENCODEROPTS "$IN" "$OUT"
1089 fi
1090 ;;
1091 mpc)
1092 # MPP/MP+(Musepack) format (.mpc) is done locally, with inline
1093 # tagging.
1094 # I tried compiling the mppenc from corecodecs.org and got some
1095 # errors, so I have not tried it myself.
1096 ## FIXME ## Needs some cleanup to determine if an empty tag sent
1097 ## FIXME ## to the encoder ends up empty.
1098 $RUN_COMMAND nice $EFFECTIVE_NICE $MPPENCODER $MPPENCODEROPTS --artist "$TRACKARTIST" --album "$DALBUM" --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" --year "$CDYEAR" --comment "$COMMENT" "$IN" "$OUT"
1099 ;;
1100 m4a)
1101 # Quick hack to avoid tagging Ogg/Speex, since there is no other way to tag than inline tagging
1102 if [ ! "$DOTAG" = "y" ]; then
1103 $RUN_COMMAND nice $EFFECTIVE_NICE $AACENCODER $AACENCODEROPTS --artist "$TRACKARTIST" --album "$DALBUM" --title "$TRACKNAME" --track "$1" --genre "$CDGENRE" --year "$CDYEAR" --comment "$COMMENT" -o "$OUT" "$IN"
1104
1105 else
1106 $RUN_COMMAND nice $ENCNICE $AACENCODER $AACENCODEROPTS -o "$OUT" "$IN"
1107 fi
1108 ;;
1109 wav)
1110 # In case of wav output we need nothing. Just keep the wavs.
1111 ;;
1112 esac
1113 $RUN_COMMAND_PIPES
1114 done
1115 # Only remove .wav if the encoding succeeded
1116 if checkerrors "encodetrack-(.{3,6})-$1"; then :; else
1117 run_command encodetrack-$1 true
1118 if [ ! "$KEEPWAVS" = "y" ] ; then
1119 if [ ! "$KEEPWAVS" = "move" ] ; then
1120 rm -f "$IN"
1121 fi
1122 fi
1123 fi
1124 else
1125 run_command "" echo "HEH! The file we were about to encode disappeared:"
1126 run_command "" echo ">> $IN"
1127 run_command encodetrack-$1 false
1128 fi
1129 }
1130
1131 # do_preprocess [tracknumber]
1132 # variables used:
1133 # TRACKS, TRACKNAME, TRACKARTIST, DISTMP3, DISTMP3OPTS, {FOO}ENCODERSYNTAX, OUTPUTTYPE, ENCODEROPTS, DALBUM, DARTIST, ENCNICE, CDYEAR, CDGENRE, COMMENT
1134 #do_preprocess ()
1135 #{
1136 # IN="$ABCDETEMPDIR/track$1.wav"
1137 # # We need IN to proceed.
1138 # if [ -s "$IN" ] ; then
1139 # for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
1140 # do
1141 # #OUT="$ABCDETEMPDIR/track$1.$OUTPUT"
1142 # run_command '' echo "Pre-processing track $1 of $TRACKS..."
1143 # case "$POSTPROCESSFORMAT" in
1144 # all|wav*)
1145 # run_command preprocess-$OUTPUT-$1 nice $PRENICE $WAV_PRE $IF $OF ;;
1146 # mp3)
1147 # run_command preprocess-$OUTPUT-$1 nice $PRENICE $MP3_PRE $IF $OF ;;
1148 # ogg)
1149 # run_command preprocess-$OUTPUT-$1 nice $PRENICE $OGG_PRE $IF $OF ;;
1150 # flac)
1151 # run_command preprocess-$OUTPUT-$1 nice $PRENICE $FLAC_PRE $IF $OF ;;
1152 # spx)
1153 # run_command preprocess-$OUTPUT-$1 nice $PRENICE $SPX_PRE $IF $OF ;;
1154 # esac
1155 # done
1156 # # Only remove .wav if the encoding succeeded
1157 # if checkerrors "preprocess-(.{3,4})-$1"; then
1158 # run_command preprocess-$1 false
1159 # else
1160 # run_command preprocess-$1 true
1161 # fi
1162 # else
1163 # if [ "$(checkstatus encode-output)" = "loud" ]; then
1164 # echo "HEH! The file we were about to pre-process disappeared:"
1165 # echo ">> $IN"
1166 # fi
1167 # run_command preprocess-$1 false
1168 # fi
1169 #}
1170
1171
1172 # do_postprocess [tracknumber]
1173 # variables used:
1174 # TRACKS, TRACKNAME, TRACKARTIST, DISTMP3, DISTMP3OPTS, {FOO}ENCODERSYNTAX, OUTPUTTYPE, ENCODEROPTS, DALBUM, DARTIST, ENCNICE, CDYEAR, CDGENRE, COMMENT
1175 #do_postprocess ()
1176 #{
1177 # for POSTPROCESSFORMAT in $(echo $POSTPROCESSFORMATS | tr , \ )
1178 # do
1179 # IN="$ABCDETEMPDIR/track$1.$POSTPROCESSFORMAT"
1180 # # We need IN to proceed.
1181 # if [ -s "$IN" ] ; then
1182 # #OUT="$ABCDETEMPDIR/track$1.$OUTPUT"
1183 # run_command '' echo "Post-processing track $1 of $TRACKS..."
1184 # case "$POSTPROCESSFORMAT" in
1185 # mp3)
1186 # run_command postprocess-$OUTPUT-$1 nice $POSTNICE $MP3_POST $IF $OF ;;
1187 # ogg)
1188 # run_command postprocess-$OUTPUT-$1 nice $POSTNICE $OGG_POST $IF $OF ;;
1189 # flac)
1190 # run_command postprocess-$OUTPUT-$1 nice $POSTNICE $FLAC_POST $IF $OF ;;
1191 # spx)
1192 # run_command postprocess-$OUTPUT-$1 nice $POSTNICE $SPX_POST $IF $OF ;;
1193 # esac
1194 # # Only remove .wav if the encoding succeeded
1195 # if checkerrors "postprocess-(.{3,4})-$1"; then
1196 # run_command postprocess-$1 false
1197 # else
1198 # run_command postprocess-$1 true
1199 # fi
1200 # else
1201 # if [ "$(checkstatus encode-output)" = "loud" ]; then
1202 # echo "HEH! The file we were about to post-process disappeared:"
1203 # echo ">> $IN"
1204 # fi
1205 # run_command postprocess-$1 false
1206 # fi
1207 # done
1208 #}
1209
1210 # do_single_gain
1211 # variables used:
1212 # FIXME #
1213 do_single_gain ()
1214 {
1215 :
1216 }
1217
1218 # do_batch_gain
1219 # variables used:
1220 # MP3GAIN, MP3GAINOPTS, VORBISGAIN, VORBISGAINOPTS, MPPGAIN, MPPGAINOPTS
1221 # FIXME #
1222 do_batch_gain ()
1223 {
1224 # The commands here don't go through run_command because they're never supposed to be silenced
1225 echo "Batch analizing gain in tracks: $TRACKQUEUE"
1226 (
1227 cd "$ABCDETEMPDIR"
1228 BLURB=
1229 TRACKFILES=
1230 for UTRACKNUM in $TRACKQUEUE
1231 do
1232 MP3FILES="$TRACKFILES track$UTRACKNUM.mp3"
1233 done
1234 # FIXME # Hard-coded batch option!
1235 $NORMALIZER -b $NORMALIZEROPTS $TRACKFILES
1236 RETURN=$?
1237 if [ "$RETURN" != "0" ]; then
1238 echo "batch-normalize: $NORMALIZER returned code $RETURN" >> errors
1239 else
1240 for UTRACKNUM in $TRACKQUEUE
1241 do
1242 echo normalizetrack-$UTRACKNUM >> status
1243 done
1244 fi
1245 )
1246 }
1247
1248 # do_batch_normalize
1249 # variables used:
1250 # NORMALIZER, NORMALIZEROPTS
1251 do_batch_normalize ()
1252 {
1253 # The commands here don't go through run_command because they're never supposed to be silenced
1254 echo "Batch normalizing tracks: $TRACKQUEUE"
1255 (
1256 cd "$ABCDETEMPDIR"
1257 BLURB=
1258 TRACKFILES=
1259 for UTRACKNUM in $TRACKQUEUE
1260 do
1261 TRACKFILES="$TRACKFILES track$UTRACKNUM.wav"
1262 done
1263 # XXX: Hard-coded batch option!
1264 $NORMALIZER -b $NORMALIZEROPTS $TRACKFILES
1265 RETURN=$?
1266 if [ "$RETURN" != "0" ]; then
1267 echo "batch-normalize: $NORMALIZER returned code $RETURN" >> errors
1268 else
1269 for UTRACKNUM in $TRACKQUEUE
1270 do
1271 echo normalizetrack-$UTRACKNUM >> status
1272 done
1273 fi
1274 )
1275 }
1276
1277 # do_normalize [tracknumber]
1278 # variables used:
1279 # TRACKS, TRACKNAME, NORMALIZER, NORMALIZEROPTS
1280 do_normalize ()
1281 {
1282 IN="$ABCDETEMPDIR/track$1.wav"
1283 if [ -e "$IN" ] ; then
1284 run_command '' echo "Normalizing track $1 of $TRACKS: $TRACKNAME..."
1285 run_command normalizetrack-$1 $NORMALIZER $NORMALIZEROPTS "$IN"
1286 else
1287 if [ "$(checkstatus encode-output)" = "loud" ]; then
1288 echo "HEH! The file we were about to normalize disappeared:"
1289 echo ">> $IN"
1290 fi
1291 run_command normalizetrack-$1 false "File $IN was not found"
1292 fi
1293 }
1294
1295 # do_move [tracknumber]
1296 # Deduces the outfile from environment variables
1297 # Creates directory if necessary
1298 # variables used:
1299 # TRACKNUM, TRACKNAME, TRACKARTIST, DALBUM, OUTPUTFORMAT, CDGENRE, CDYEAR
1300 do_move ()
1301 {
1302 for TMPOUTPUT in $(echo $OUTPUTTYPE | tr , \ )
1303 do
1304 # For now, set OUTPUT as TMPOUTPUT, and then change it once we have
1305 # defined the OUTPUTFILE:
1306 OUTPUT="$TMPOUTPUT"
1307
1308 # Create ALBUMFILE, ARTISTFILE, TRACKFILE
1309 # Munge filenames as follows:
1310 # ' ' -> '_'
1311 # '/' -> '_'
1312 # ''' -> ''
1313 # '?' -> ''
1314 # Eat control characters
1315 ALBUMFILE="$(mungefilename "$DALBUM")"
1316 ARTISTFILE="$(mungefilename "$TRACKARTIST")"
1317 TRACKFILE="$(mungefilename "$TRACKNAME")"
1318 GENRE="$(mungegenre "$GENRE")"
1319 YEAR=${CDYEAR:-$CDYEAR}
1320 # If we want to start the tracks with a given number, we need to modify
1321 # the TRACKNUM value before evaluation
1322 gettracknum
1323 # Supported variables for OUTPUTFORMAT are GENRE, YEAR, ALBUMFILE,
1324 # ARTISTFILE, TRACKFILE, and TRACKNUM.
1325 if [ "$ONETRACK" = "y" ]; then
1326 if [ "$VARIOUSARTISTS" = "y" ]; then
1327 OUTPUTFILE="$(eval echo \""$VAONETRACKOUTPUTFORMAT"\")"
1328 else
1329 OUTPUTFILE="$(eval echo \""$ONETRACKOUTPUTFORMAT"\")"
1330 fi
1331 else
1332 if [ "$VARIOUSARTISTS" = "y" ]; then
1333 OUTPUTFILE="$(eval echo \""$VAOUTPUTFORMAT"\")"
1334 else
1335 OUTPUTFILE="$(eval echo \""$OUTPUTFORMAT"\")"
1336 fi
1337 fi
1338 if checkerrors "tagtrack-$OUTPUT-$1"; then :; else
1339 # Once we know the specific output was successful, we can change
1340 # the OUTPUT to the value containing the container
1341 case $TMPOUTPUT in
1342 vorbis|ogg)
1343 OUTPUT=$OGGOUTPUTCONTAINER
1344 ;;
1345 flac)
1346 OUTPUT=$FLACOUTPUTCONTAINER
1347 ;;
1348 *)
1349 OUTPUT=$TMPOUTPUT
1350 ;;
1351 esac
1352 # Check that the directory for OUTPUTFILE exists, if it doesn't, create it
1353 OUTPUTFILEDIR="$(dirname "$OUTPUTDIR/$OUTPUTFILE")"
1354 case $OUTPUT in
1355 wav)
1356 if [ "$DOCLEAN" != "y" ] && [ "$FORCE" != "y" ]; then
1357 # FIXME # introduce warnings?
1358 :
1359 else
1360 # mkdir -p shouldn't return an error if the directory already exists
1361 mkdir -p "$OUTPUTFILEDIR"
1362 run_command movetrack-$1 mv "$ABCDETEMPDIR/track$1.$OUTPUT" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
1363 if checkstatus movetrack-output-$OUTPUT; then :; else
1364 run_command movetrack-output-$OUTPUT true
1365 fi
1366 fi
1367 ;;
1368 *)
1369 # mkdir -p shouldn't return an error if the directory already exists
1370 mkdir -p "$OUTPUTFILEDIR"
1371 run_command movetrack-$1 mv "$ABCDETEMPDIR/track$1.$OUTPUT" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
1372 if checkstatus movetrack-output-$OUTPUT; then :; else
1373 run_command movetrack-output-$OUTPUT true
1374 fi
1375 ;;
1376 esac
1377 # Lets move the cue file
1378 if CUEFILE=$(checkstatus cuefile) >/dev/null ; then
1379 if [ -r "$ABCDETEMPDIR/$CUEFILE" ]; then
1380 if checkstatus movecue-$OUTPUT; then :; else
1381 # Silence the Copying output since it overlaps with encoding processes...
1382 #run_command '' vecho "Copying cue file to its destination directory..."
1383 if checkstatus onetrack >/dev/null ; then
1384 case $OUTPUT in
1385 wav)
1386 if [ "$DOCLEAN" != "y" ] && [ "$FORCE" != "y" ]; then
1387 # We dont have the dir, since it was not created before.
1388 :
1389 else
1390 run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.cue"
1391 fi
1392 ;;
1393 # NOTE: Creating a cue file with the 3-char-extension files is to comply with
1394 # http://brianvictor.tripod.com/mp3cue.htm#details
1395 [a-z0-9][a-z0-9][a-z0-9])
1396 run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.cue"
1397 ;;
1398 *)
1399 run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT.cue"
1400 ;;
1401 esac
1402 else
1403 run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTFILEDIR/$CUEFILE"
1404 fi
1405 echo movecue-$OUTPUT >> "$ABCDETEMPDIR/status"
1406 fi
1407 fi
1408 fi
1409 fi
1410 done
1411 }
1412
1413 # do_playlist
1414 # Create the playlist if wanted
1415 # Variables used:
1416 # PLAYLISTFORMAT, PLAYLISTDATAPREFIX, VAPLAYLISTFORMAT, VAPLAYLISTDATAPREFIX,
1417 # VARIOUSARTISTS, OUTPUTDIR
1418 do_playlist ()
1419 {
1420 for TMPOUTPUT in $(echo $OUTPUTTYPE | tr , \ )
1421 do
1422 case $TMPOUTPUT in
1423 vorbis|ogg)
1424 OUTPUT=$OGGOUTPUTCONTAINER
1425 ;;
1426 flac)
1427 OUTPUT=$FLACOUTPUTCONTAINER
1428 ;;
1429 *)
1430 OUTPUT=$TMPOUTPUT
1431 ;;
1432 esac
1433 # Create a playlist file for the playlist data to go into.
1434 # We used to wipe it out if it existed. Now we request permision if interactive.
1435 for LASTTRACK in $TRACKQUEUE; do :; done
1436 ALBUMFILE="$(mungefilename "$DALBUM")"
1437 ARTISTFILE="$(mungefilename "$DARTIST")"
1438 GENRE="$(mungegenre "$GENRE")"
1439 YEAR=${CDYEAR:-$CDYEAR}
1440 if [ "$VARIOUSARTISTS" = "y" ] ; then
1441 PLAYLISTFILE="$(eval echo "$VAPLAYLISTFORMAT")"
1442 else
1443 PLAYLISTFILE="$(eval echo "$PLAYLISTFORMAT")"
1444 fi
1445 FINALPLAYLISTDIR="$(dirname "$OUTPUTDIR/$PLAYLISTFILE")"
1446 mkdir -p "$FINALPLAYLISTDIR"
1447 if [ -s "$OUTPUTDIR/$PLAYLISTFILE" ]; then
1448 echo -n "Erase, Append to, or Keep the existing playlist file? [e/a/k] (e): " >&2
1449 if [ "$INTERACTIVE" = "y" ]; then
1450 while [ "$DONE" != "y" ]; do
1451 read ERASEPLAYLIST
1452 case $ERASEPLAYLIST in
1453 e|E|a|A|k|K) DONE=y ;;
1454 *) ;;
1455 esac
1456 done
1457 else
1458 echo e >&2
1459 ERASEPLAYLIST=e
1460 fi
1461 # Once we erase the playlist, we use append to create the new one.
1462 [ "$ERASEPLAYLIST" = "e" -o "$ERASEPLAYLIST" = "E" ] && rm -f "$OUTPUTDIR/$PLAYLISTFILE" && ERASEPLAYLIST=a
1463 else
1464 # The playlist does not exist, so we can safelly use append to create the new list
1465 ERASEPLAYLIST=a
1466 fi
1467 if [ "$ERASEPLAYLIST" = "a" -o "$ERASEPLAYLIST" = "A" ]; then
1468 touch "$OUTPUTDIR/$PLAYLISTFILE"
1469 for UTRACKNUM in $TRACKQUEUE
1470 do
1471 # Shares some code with do_move since the filenames have to match
1472 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
1473 getcddbinfo TRACKNAME
1474 splitvarious
1475 TRACKFILE="$(mungefilename "$TRACKNAME")"
1476 ARTISTFILE="$(mungefilename "$TRACKARTIST")"
1477 ALBUMFILE="$(mungefilename "$DALBUM")"
1478 # If we want to start the tracks with a given number, we need to modify the
1479 # TRACKNUM value before evaluation
1480 gettracknum
1481 if [ "$VARIOUSARTISTS" = "y" ]; then
1482 OUTPUTFILE="$(eval echo \""$VAOUTPUTFORMAT\"")"
1483 else
1484 OUTPUTFILE="$(eval echo \""$OUTPUTFORMAT\"")"
1485 fi
1486 if [ "$VARIOUSARTISTS" = "y" ]; then
1487 if [ "$VAPLAYLISTDATAPREFIX" ] ; then
1488 echo ${VAPLAYLISTDATAPREFIX}$OUTPUTFILE.$OUTPUT >> "$OUTPUTDIR/$PLAYLISTFILE"
1489 else
1490 relpath "$PLAYLISTFILE", "$OUTPUTFILE.$OUTPUT" >> "$OUTPUTDIR/$PLAYLISTFILE"
1491 fi
1492 else
1493 if [ "$PLAYLISTDATAPREFIX" ]; then
1494 echo ${PLAYLISTDATAPREFIX}$OUTPUTFILE.$OUTPUT >> "$OUTPUTDIR/$PLAYLISTFILE"
1495 else
1496 relpath "$PLAYLISTFILE", "$OUTPUTFILE.$OUTPUT" >> "$OUTPUTDIR/$PLAYLISTFILE"
1497 fi
1498 fi
1499 done
1500 fi
1501 ## this will convert the playlist to have CRLF line-endings, if specified
1502 ## (some hardware players insist on CRLF endings)
1503 if [ "$DOSPLAYLIST" = "y" ]; then
1504 awk '{substr("\r",""); printf "%s\r\n", $0}' "$OUTPUTDIR/$PLAYLISTFILE" > "$ABCDETEMPDIR/PLAYLISTFILE.tmp"
1505 # mv -f "$ABCDETEMPDIR/PLAYLISTFILE.tmp" "$OUTPUTDIR/$PLAYLISTFILE"
1506 cat "$ABCDETEMPDIR/PLAYLISTFILE.tmp" | sed 's/\//\\/' > "$OUTPUTDIR/$PLAYLISTFILE"
1507 fi
1508 echo "playlistcomplete" >> "$ABCDETEMPDIR/status"
1509 done
1510 }
1511
1512 # abcde.cue2discid
1513 # This function reads a cuefile on stdin and writes an extended
1514 # cddb query on stdout. Any PREGAP for track 1 is properly
1515 # handled, although cue files embedded in FLAC files do not
1516 # appear to properly store the PREGAP setting. :(
1517 abcde.cue2discid () {
1518
1519 cddb_sum () {
1520 val=$1
1521 ret=0
1522 while [ $val -gt 0 ] ; do
1523 ret=$(( $ret + ( $val % 10) ))
1524 val=$(( $val / 10 ))
1525 done
1526 echo $ret
1527 }
1528
1529 msf2lba () {
1530 OIFS="$IFS"
1531 IFS=":"
1532 set -- $1
1533 IFS="$OIFS"
1534 local first second third
1535 first=$(expr ${1} + 0 )
1536 second=$(expr ${2} + 0 )
1537 third=$(expr ${3} + 0 )
1538
1539 echo $(( ((($first * 60) + $second) * 75) + $third ))
1540 }
1541
1542 OFFSET=150
1543 PREGAP=0
1544 LEADOUT=0
1545 LEADIN=88200
1546 i=0
1547 N=0
1548
1549 while read line ; do
1550 set -- $line
1551 case "$1" in
1552 TRACK) i=$(( i + 1 ))
1553 ;;
1554 INDEX) if [ "$2" -eq 1 ] ; then
1555 LBA=$(msf2lba $3)
1556 START=$(( $LBA + $PREGAP + $OFFSET ))
1557 eval TRACK$i=$START
1558 X=$(cddb_sum $(( $START / 75 )) )
1559 N=$(( $N + $X ))
1560 fi
1561 ;;
1562 PREGAP) PREGAP=$(msf2lba $2)
1563 ;;
1564 REM) case "$2" in
1565 FLAC__lead-out)
1566 LEADOUT=$(( $4 / 588 ))
1567 ;;
1568 FLAC__lead-in)
1569 LEADIN=$(( $3 / 588 ))
1570 ;;
1571 esac
1572 ;;
1573 esac
1574
1575 done
1576
1577 TRACKS=$i
1578 LEADOUT=$(( $LEADOUT + $LEADIN ))
1579
1580 LENGTH=$(( $LEADOUT/75 - $TRACK1/75 ))
1581 DISCID=$(( ( $N % 255 ) * 2**24 | $LENGTH * 2**8 | $TRACKS ))
1582 printf "%08x %i" $DISCID $TRACKS
1583
1584 j=1
1585 while [ $j -le $TRACKS ] ; do
1586 eval echo -n "\" \$TRACK$j\""
1587 j=$((j+1))
1588 done
1589 echo " $(( $LEADOUT / 75 ))"
1590 }
1591
1592 # abcde.mkcue
1593 # abcde.mkcue [--wholedisk]
1594 # This creates a cuefile directly from the extended discid information
1595 # The --wholedisk option controls whether we're ripping data from the
1596 # start of track one or from the start of the disk (usually, but not
1597 # always the same thing!)
1598 #
1599 # Track one leadin/pregap (if any) handeling:
1600 # --wholedisk specified:
1601 # TRACK 01 AUDIO
1602 # INDEX 00 00:00:00
1603 # INDEX 01 <pregap value>
1604 # Remaining track index values unchanged from disc TOC
1605 #
1606 # --wholedisk not specified
1607 # TRACK 01 AUDIO
1608 # PREGAP <pregap value>
1609 # INDEX 01 00:00:00
1610 # Remaining track index values offset by <pregap value>
1611 #
1612 # Variables used:
1613 # TRACKINFO
1614 abcde.mkcue () {
1615
1616 echomsf () {
1617 printf "$1%02i:%02i:%02i\n" $(($2/4500)) $((($2/75)%60)) $(($2%75))
1618 }
1619
1620 local MODE DISCID TRACKS
1621 local i OFFSET LBA
1622
1623
1624 if [ "$1" = --wholedisc ] ; then
1625 MODE=INDEX
1626 else
1627 MODE=PREGAP
1628 fi
1629
1630 set -- $TRACKINFO
1631
1632 DISCID=$1
1633 TRACKS=$2
1634 shift 2
1635
1636 echo REM DISCID $DISCID
1637 echo FILE \"dummy.wav\" WAVE
1638
1639 if [ $1 -ne 150 ] && [ $MODE = "PREGAP"] ; then
1640 OFFSET=$1
1641 else
1642 OFFSET=150
1643 fi
1644
1645 i=1
1646 while [ $i -le "$TRACKS" ] ; do
1647 LBA=$(( $1 - $OFFSET ))
1648 printf " TRACK %02i AUDIO\n" $i
1649 if [ $i -eq 1 -a $1 -ne 150 ] ; then
1650 if [ $MODE = PREGAP ] ; then
1651 echomsf " PREGAP " $(($OFFSET-150))
1652 else
1653 echo " INDEX 00 00:00:00"
1654 fi
1655 fi
1656 echomsf " INDEX 01 " $LBA
1657 i=$(($i+1))
1658 shift
1659 done
1660 }
1661
1662 # do_discid
1663 # This essentially the start of things
1664 do_discid ()
1665 {
1666 # Query the CD to get the track info, unless the user specified -C
1667 # or we are using some actions which do not need the CDDB data at all
1668 #if [ ! X"$EXPACTIONS" = "X" ]; then
1669 # :
1670 #elif [ -z "$DISCID" ]; then
1671 if [ -z "$DISCID" ]; then
1672 vecho -n "Getting CD track info... "
1673 # In OSX, unmount the disc before a query
1674 if [ "$OSFLAVOUR" = "OSX" ]; then
1675 disktool -u ${CDROM#/dev/}
1676 fi
1677 case "$CDROMREADERSYNTAX" in
1678 flac)
1679 if $METAFLAC $METAFLACOPTS --export-cuesheet-to=- "$CDROM" > /dev/null 2>&1 ; then
1680 case "$CUE2DISCID" in
1681 # FIXME # right now we have 2 cue2discid internal
1682 # implementations: builtin and abcde.cue2discid. Test
1683 # both of them and decide which one we want to use.
1684 builtin)
1685 #vecho "Using builtin cue2discid implementation..."
1686 CUESHEET="$(metaflac $METAFLACOPTS --export-cuesheet-to=- "$CDROM")"
1687
1688 #TRACKS=$(echo $CUESHEET | egrep "TRACK \+[[:digit:]]\+ \+AUDIO" |wc -l)
1689 #TRACKS=0
1690 OFFSETTIMES=( $(echo "$CUESHEET" | sed -n -e's/\ *INDEX 01\ \+//p' ) )
1691 TRACKS=${#OFFSETTIMES[@]}
1692 unset OFFSETS
1693 #echo "processing offsetimes ${OFFSETTIMES[@]}"
1694 for OFFSETTIME in ${OFFSETTIMES[@]}; do
1695 OFFSETS="$OFFSETS $(( 10#${OFFSETTIME:0:2} * 4500 + 10#${OFFSETTIME:3:2} * 75 + 10#${OFFSETTIME:6:2} ))"
1696 #OFFSETS[${#OFFSETS[*]}]=$(( 10#${OFFSETTIME:0:2} * 4500 + 10#${OFFSETTIME:3:2} * 75 + 10#${OFFSETTIME:6:2} ))
1697 done
1698
1699 LEADOUT=$(( $(echo "$CUESHEET" | grep lead-out | get_last) / 44100 * 75 ))
1700 LEADIN=$(( $(echo "$CUESHEET" | grep lead-in | get_last) / 44100 * 75 ))
1701 makeids
1702 ;;
1703 *)
1704 #vecho "Using external python cue2discid implementation..."
1705 TRACKINFO=$($METAFLAC $METAFLACOPTS --export-cuesheet-to=- "$CDROM" | $CUE2DISCID)
1706 ;;
1707 esac
1708 else
1709 log error "the input flac file does not contain a cuesheet."
1710 exit 1
1711 fi
1712 ;;
1713 # cdparanoia|debug)
1714 # CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -Q --verbose 2>&1 )"
1715 # RET=$?
1716 # if [ ! "$RET" = "0" ];then
1717 # log warning "something went wrong while querying the CD... Maybe a DATA CD?"
1718 # fi
1719 #
1720 # TRACKS="$(echo "$CDPARANOIAOUTPUT" | egrep '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ')"
1721 # CDPARANOIAAUDIOTRACKS="$TRACKS"
1722 #
1723 # LEADOUT="$(echo "$CDPARANOIAOUTPUT" | egrep -o '^TOTAL[[:space:]]+([[:digit:]]+)' | get_last)"
1724 # OFFSETS="$(echo "$CDPARANOIAOUTPUT" | sed -n -e's/^ .* \([0-9]\+\) \[.*/\1/p')"
1725 # makeids
1726 # ;;
1727 *)
1728 case "$CDDBMETHOD" in
1729 cddb) TRACKINFO=$($CDDISCID "$CDROM") ;;
1730 # FIXME # musicbrainz needs a cleanup
1731 musicbrainz) TRACKINFO=$($MUSICBRAINZ -c "$CDROM" ) ;;
1732 esac
1733 ;;
1734 esac
1735 # Make sure there's a CD in there by checking cd-discid's return code
1736 if [ ! "$?" = "0" ]; then
1737 if [ "$CDROMREADERSYNTAX" = "flac" ] ; then
1738 log error "cuesheet information from the flac file could not be read."
1739 log error "Perhaps the flac file does not contain a cuesheet?."
1740 exit 1
1741 else
1742 log error "CD could not be read. Perhaps there's no CD in the drive?"
1743 exit 1
1744 fi
1745 fi
1746 # In OSX, remount the disc again
1747 if [ "$OSFLAVOUR" = "OSX" ]; then
1748 disktool -m ${CDROM#/dev/}
1749 fi
1750 WEHAVEACD=y
1751 DISCID=$(echo $TRACKINFO | cut -f1 -d' ')
1752 else
1753 TRACKINFO=$(cat "$WAVOUTPUTDIR/abcde.$DISCID/discid")
1754 fi
1755
1756 # Get a full enumeration of tracks, sort it, and put it in the TRACKQUEUE.
1757 # This needs to be done now because a section of the resuming code will need
1758 # it later.
1759
1760 # get the number of digits to pad TRACKNUM with - we'll use this later
1761 # a CD can only hold 99 tracks, but since we support a feature for starting
1762 # numbering the tracks from a given number, we might need to set it as a
1763 # variable for the user to define... or obtain it somehow.
1764 if [ "$PADTRACKS" = "y" ] ; then
1765 TRACKNUMPADDING=2
1766 fi
1767
1768 ABCDETEMPDIR="$WAVOUTPUTDIR/abcde.$(echo $TRACKINFO | cut -f1 -d' ')"
1769 if [ -z "$TRACKQUEUE" ]; then
1770 if [ ! "$STRIPDATATRACKS" = "n" ]; then
1771 case "$CDROMREADERSYNTAX" in
1772 cdparanoia|debug)
1773 if [ "$WEHAVEACD" = "y" ]; then
1774 vecho "Querying the CD for audio tracks..."
1775 CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -Q --verbose 2>&1 )"
1776 RET=$?
1777 if [ ! "$RET" = "0" ];then
1778 log warning "something went wrong while querying the CD... Maybe a DATA CD?"
1779 fi
1780 TRACKS="$(echo "$CDPARANOIAOUTPUT" | egrep '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ')"
1781 CDPARANOIAAUDIOTRACKS="$TRACKS"
1782 else
1783 # Previous versions of abcde would store the tracks on a file, instead of the status record.
1784 if [ -f "$ABCDETEMPDIR/cdparanoia-audio-tracks" ]; then
1785 echo cdparanoia-audio-tracks=$( cat "$ABCDETEMPDIR/cdparanoia-audio-tracks" ) >> "$ABCDETEMPDIR/status"
1786 rm -f "$ABCDETEMPDIR/cdparanoia-audio-tracks"
1787 fi
1788 if [ -f "$ABCDETEMPDIR/status" ] && TRACKS=$(checkstatus cdparanoia-audio-tracks); then :; else
1789 TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
1790 fi
1791 fi
1792 ;;
1793 *) TRACKS=$(echo $TRACKINFO | cut -f2 -d' ') ;;
1794 esac
1795 else
1796 TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
1797 fi
1798 if echo "$TRACKS" | grep "[[:digit:]]" > /dev/null 2>&1 ;then :;else
1799 log info "The disc does not contain any tracks. Giving up..."
1800 exit 0
1801 fi
1802 echo -n "Grabbing entire CD - tracks: "
1803 if [ ! "$PADTRACKS" = "y" ] ; then
1804 TRACKNUMPADDING=$(echo -n $TRACKS | wc -c | tr -d ' ')
1805 fi
1806 TRACKS=$(printf "%0.${TRACKNUMPADDING}d" $TRACKS)
1807 X=0
1808 while [ "$X" -ne "$TRACKS" ]
1809 do
1810 X=$(printf "%0.${TRACKNUMPADDING}d" $(expr $X + 1))
1811 TRACKQUEUE=$(echo $TRACKQUEUE $X)
1812 done
1813 echo $TRACKQUEUE
1814 else
1815 TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
1816 # User-supplied track queue.
1817 # Weed out non-numbers, whitespace, then sort and weed out duplicates
1818 TRACKQUEUE=$(echo $TRACKQUEUE | sed 's-[^0-9 ]--g' | tr ' ' '\n' | grep -v ^$ | sort -n | uniq | tr '\n' ' ' | sed 's- $--g')
1819 # Once cleaned, obtain the highest value in the trackqueue for number padding
1820 for LASTTRACK in $TRACKQUEUE; do :; done
1821 if [ ! "$PADTRACKS" = "y" ] ; then
1822 TRACKNUMPADDING=$(echo -n $LASTTRACK | wc -c | tr -d ' ')
1823 fi
1824 # Now we normalize the trackqueue
1825 for TRACK in $TRACKQUEUE ; do
1826 TRACKNUM=$(printf %0.${TRACKNUMPADDING}d $(expr ${TRACK} + 0 ))
1827 PADTRACKQUEUE=$(echo $PADTRACKQUEUE $TRACKNUM)
1828 done
1829 TRACKQUEUE=$PADTRACKQUEUE
1830 echo Grabbing tracks: "$TRACKQUEUE"
1831 fi
1832
1833 QUEUEDTRACKS=$(echo $TRACKQUEUE | wc -w | tr -d ' ')
1834
1835 # We have the discid, create a temp directory after it to store all the temp
1836 # info
1837
1838 if [ -e "$ABCDETEMPDIR" ]; then
1839 echo -n "abcde: attempting to resume from $ABCDETEMPDIR"
1840 # It already exists, see if it's a directory
1841 if [ ! -d "$ABCDETEMPDIR" ]; then
1842 # This is a file/socket/fifo/device/etc, not a directory
1843 # Complain and exit
1844 echo >&2
1845 echo "abcde: file $ABCDETEMPDIR already exists and does not belong to abcde." >&2
1846 echo "Please investigate, remove it, and rerun abcde." >&2
1847 exit 1
1848 fi
1849 echo -n .
1850 # It's a directory, let's see if it's owned by us
1851 if [ ! -O "$ABCDETEMPDIR" ]; then
1852 # Nope, complain and exit
1853 echo >&2
1854 echo "abcde: directory $ABCDETEMPDIR already exists and is not owned by you." >&2
1855 echo "Please investigate, remove it, and rerun abcde." >&2
1856 exit 1
1857 fi
1858 echo .
1859 # See if it's populated
1860 if [ ! -f "$ABCDETEMPDIR/discid" ]; then
1861 # Wipe and start fresh
1862 echo "abcde: $ABCDETEMPDIR/discid not found. Abcde must remove and recreate" >&2
1863 echo -n "this directory to continue. Continue? [y/n] (n)" >&2
1864 if [ "$INTERACTIVE" = "y" ]; then
1865 read ANSWER
1866 else
1867 echo y >&2
1868 ANSWER=y
1869 fi
1870 if [ "$ANSWER" != "y" ]; then
1871 exit 1
1872 fi
1873 rm -rf "$ABCDETEMPDIR" || exit 1
1874 mkdir -p "$ABCDETEMPDIR"
1875 if [ "$?" -gt "0" ]; then
1876 # Directory already exists or could not be created
1877 echo "abcde: Temp directory $ABCDETEMPDIR could not be created." >&2
1878 exit 1
1879 fi
1880 else
1881 # Everything is fine. Check for ^encodetracklocation-
1882 # and encode-output entries in the status file and
1883 # remove them. These are not relevant across sessions.
1884 if [ -f "$ABCDETEMPDIR/status" ]; then
1885 mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
1886 grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
1887 | grep -v ^encode-output > "$ABCDETEMPDIR/status"
1888 fi
1889 # Remove old error messages
1890 if [ -f "$ABCDETEMPDIR/errors" ]; then
1891 rm -f "$ABCDETEMPDIR/errors"
1892 fi
1893 fi
1894 else
1895 # We are starting from scratch
1896 mkdir -p "$ABCDETEMPDIR"
1897 if [ "$?" -gt "0" ]; then
1898 # Directory already exists or could not be created
1899 echo "abcde: Temp directory $ABCDETEMPDIR could not be created." >&2
1900 exit 1
1901 fi
1902 cat /dev/null > "$ABCDETEMPDIR/status"
1903 # Store the abcde version in the status file.
1904 echo "abcde-version=$VERSION" >> "$ABCDETEMPDIR/status"
1905 fi
1906 if [ X"$DOCUE" = "Xy" -a X"$WEHAVEACD" = "Xy" ]; then
1907 if checkstatus cuefile > /dev/null 2>&1 ; then :; else
1908 CUEFILE=cue-$(echo "$TRACKINFO" | cut -f1 -d' ').txt
1909 vecho "Creating cue file..."
1910 case $CDROMREADERSYNTAX in
1911 flac)
1912 if $METAFLAC --export-cuesheet-to=- "$CDROM" > "$ABCDETEMPDIR/$CUEFILE"; then
1913 echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status"
1914 else
1915 log warning "the input flac file does not contain a cuesheet."
1916 fi
1917 ;;
1918 *)
1919 if $CUEREADER $CUEREADEROPTS > "$ABCDETEMPDIR/$CUEFILE"; then
1920 echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status"
1921 else
1922 log warning "reading the CUE sheet is still considered experimental"
1923 log warning "and there was a problem with the CD reading. abcde will continue,"
1924 log warning "but consider reporting the problem to the abcde author"
1925 fi
1926 ;;
1927 esac
1928 fi
1929 fi
1930 # If we got the CDPARANOIA status and it is not recorded, save it now
1931 if [ -n "$CDPARANOIAAUDIOTRACKS" ]; then
1932 if checkstatus cdparanoia-audio-tracks > /dev/null 2>&1; then :; else
1933 echo cdparanoia-audio-tracks=$CDPARANOIAAUDIOTRACKS >> "$ABCDETEMPDIR/status"
1934 fi
1935 fi
1936
1937 # Create the discid file
1938 echo "$TRACKINFO" > "$ABCDETEMPDIR/discid"
1939 if checkstatus cddbmethod > /dev/null 2>&1 ; then :; else
1940 echo "cddbmethod=$CDDBMETHOD" >> "$ABCDETEMPDIR/status"
1941 fi
1942 }
1943
1944 # do_cleancue
1945 # Create a proper CUE file based on the CUE file we created before.
1946 do_cleancue()
1947 {
1948 if CUEFILE_IN="$ABCDETEMPDIR"/$(checkstatus cuefile); then
1949 CUEFILE_OUT=$CUEFILE_IN.out
1950 ### FIXME ### checkstatus cddb
1951 if [ -e "$CDDBDATA" ]; then
1952 vecho "Adding metadata to the cue file..."
1953 # FIXME It doesn't preserve spaces! Why?
1954 # FIXME parse $track into PERFORMER and TITLE - abcde already has code for this?
1955 n=1
1956 echo "PERFORMER \"$DARTIST\"" >> "$CUEFILE_OUT"
1957 echo "TITLE \"$DALBUM\"" >> "$CUEFILE_OUT"
1958 # Set IFS to <newline> to prevent read from swallowing spaces and tabs
1959 OIFS="$IFS"
1960 IFS='
1961 '
1962 cat "$CUEFILE_IN" | while read line
1963 do
1964 if echo "$line" | grep "INDEX 01" > /dev/null 2>&1 ; then
1965 # FIXME # Possible patch: remove the line above, uncomment the 2 lines below.
1966 # echo "$line" >> "$CUEFILE_OUT"
1967 # if echo "$line" | grep "^[[:space:]]*TRACK" > /dev/null 2>&1 ; then
1968 eval track="\$TRACK$n"
1969 n=$(expr $n + 1)
1970 echo " TITLE \"$track\"" >> "$CUEFILE_OUT"
1971 fi
1972 # FIXME # If the lines above are uncommented, remove the line below.
1973 echo "$line" >> "$CUEFILE_OUT"
1974 done
1975 IFS="$OIFS"
1976 mv "$CUEFILE_OUT" "$CUEFILE_IN"
1977 echo "cleancuefile" >> "$ABCDETEMPDIR/status"
1978 fi
1979 fi
1980 }
1981
1982 # do_cddbparse
1983 # Parses a CDDB file and outputs the title and the track names.
1984 # Variables: CDDBFILE
1985 do_cddbparse ()
1986 {
1987 CDDBPARSEFILE="$1"
1988 # List out disc title/author and contents
1989 if [ "$ONETRACK" = "y" ]; then
1990 vecho "ONETRACK mode selected: displaying only the title of the CD..."
1991 fi
1992 echo "---- $(grep DTITLE "${CDDBPARSEFILE}" | cut '-d=' -f2- | tr -d \\r\\n ) ----"
1993 if [ X"$SHOWCDDBYEAR" = "Xy" ]; then
1994 PARSEDYEAR=$(grep DYEAR "${CDDBPARSEFILE}" | cut '-d=' -f2-)
1995 if [ ! X"$PARSEDYEAR" = "X" ]; then
1996 echo "Year: $PARSEDYEAR"
1997 fi
1998 fi
1999 if [ X"$SHOWCDDBGENRE" = "Xy" ]; then
2000 PARSEDGENRE=$(grep DGENRE "${CDDBPARSEFILE}" | cut '-d=' -f2-)
2001 if [ ! X"$PARSEDGENRE" = "X" ]; then
2002 echo "Genre: $PARSEDGENRE"
2003 fi
2004 fi
2005 if [ ! "$ONETRACK" = "y" ]; then
2006 for TRACK in $(f_seq_row 1 $TRACKS)
2007 do
2008 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "${CDDBPARSEFILE}" | cut -f2- -d= | tr -d \\r\\n)"
2009 done
2010 fi
2011 }
2012
2013 # do_localcddb
2014 # Check for a local CDDB file, and report success
2015 do_localcddb ()
2016 {
2017 if checkstatus cddb-readcomplete && checkstatus cddb-choice >/dev/null; then :; else
2018
2019 CDDBLOCALSTATUS="notfound"
2020 CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
2021 USELOCALRESP="y"
2022
2023 if [ "$CDDBLOCALRECURSIVE" = "y" ]; then
2024 CDDBLOCALRESULTS="$(find ${CDDBLOCALDIR} -name "${CDDBDISCID}" -type f 2> /dev/null)"
2025 if [ ! "${CDDBLOCALRESULTS}" = "" ]; then
2026 if (( $(echo "${CDDBLOCALRESULTS}" | wc -l) == 1 )); then
2027 CDDBLOCALFILE="${CDDBLOCALRESULTS}"
2028 CDDBLOCALMATCH=single
2029 elif (( $(echo "${CDDBLOCALRESULTS}" | wc -l) > 1 )); then
2030 CDDBLOCALMATCH=multiple
2031 fi
2032 else
2033 CDDBLOCALMATCH=none
2034 fi
2035 elif [ "$CDDBLOCALMATCH" = "none" ] && [ -r "${CDDBLOCALDIR}/${CDDBDISCID}" ]; then
2036 CDDBLOCALFILE="${CDDBLOCALDIR}/${CDDBDISCID}"
2037 CDDBLOCALMATCH=single
2038 else
2039 CDDBLOCALMATCH=none
2040 fi
2041
2042 # If the user has selected to check a local CDDB repo, we proceed with it
2043 case $CDDBLOCALMATCH in
2044 multiple)
2045 echo "Processing multiple matching CDDB entries..." > "$ABCDETEMPDIR/cddblocalchoices"
2046 X=0
2047 echo "$CDDBLOCALRESULTS" | while read RESULT ; do
2048 X=$(expr $X + 1)
2049 # List out disc title/author and contents
2050 CDDBLOCALREAD="$ABCDETEMPDIR/cddblocalread.$X"
2051 cat "$RESULT" > "${CDDBLOCALREAD}"
2052 {
2053 echo -n "#$X: "
2054 do_cddbparse "${CDDBLOCALREAD}"
2055 echo ""
2056 ##FIXME## QUICK HACK !!!!
2057 if [ ! "$INTERACTIVE" = "y" ]; then break ; fi
2058 } >> "$ABCDETEMPDIR/cddblocalchoices"
2059 done
2060 if [ $(cat "$ABCDETEMPDIR/cddblocalchoices" | wc -l) -ge 24 ] && [ "$INTERACTIVE" = "y" ]; then
2061 page "$ABCDETEMPDIR/cddblocalchoices"
2062 else
2063 # It's all going to fit in one page, cat it
2064 cat "$ABCDETEMPDIR/cddblocalchoices" >&2
2065 fi
2066 CDDBLOCALCHOICES=$( echo "$CDDBLOCALRESULTS" | wc -l )
2067 # Setting the choice to an impossible integer to avoid errors in the numeric comparisons
2068 CDDBLOCALCHOICENUM=-1
2069 if [ "$INTERACTIVE" = "y" ]; then
2070 while [ $CDDBLOCALCHOICENUM -lt 0 ] || [ $CDDBLOCALCHOICENUM -gt $CDDBLOCALCHOICES ]; do
2071 echo -n "Locally cached CDDB entries found. Which one would you like to use (0 for none)? [0-$CDDBLOCALCHOICES]: " >&2
2072 read CDDBLOCALCHOICE
2073 [ x"$CDDBLOCALCHOICE" = "x" ] && CDDBLOCALCHOICE="1"
2074 # FIXME # Introduce diff's
2075 if echo $CDDBLOCALCHOICE | egrep "[[:space:]]*[[:digit:]]+,[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
2076 diffentries cddblocalread "$CDDBLOCALCHOICES" "$CDDBLOCALCHOICE"
2077 elif echo $CDDBLOCALCHOICE | egrep "[[:space:]]*[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
2078 # Make sure we get a valid choice
2079 CDDBLOCALCHOICENUM=$(echo $CDDBLOCALCHOICE | xargs printf %d 2>/dev/null)
2080 if [ $CDDBLOCALCHOICENUM -lt 0 ] || [ $CDDBLOCALCHOICENUM -gt $CDDBLOCALCHOICES ]; then
2081 echo "Invalid selection. Please choose a number between 0 and $CDDBLOCALCHOICES." >&2
2082 fi
2083 fi
2084 done
2085 else
2086 ### FIXME ###
2087 #echo "Selected ..."
2088 CDDBLOCALRESP=y
2089 CDDBLOCALCHOICENUM=1
2090 fi
2091 if [ ! "$CDDBLOCALCHOICENUM" = "0" ]; then
2092 #echo "Using local copy of CDDB data"
2093 echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "$ABCDETEMPDIR/cddbread.1"
2094 cat "$ABCDETEMPDIR/cddblocalread.$CDDBLOCALCHOICENUM" >> "$ABCDETEMPDIR/cddbread.1"
2095 echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB
2096 echo cddb-readcomplete >> "$ABCDETEMPDIR/status"
2097 do_cddbparse "$ABCDETEMPDIR/cddbread.1" > "$ABCDETEMPDIR/cddbchoices"
2098 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2099 CDDBLOCALSTATUS="found"
2100 else
2101 #echo "Not using local copy of CDDB data"
2102 CDDBLOCALSTATUS="notfound"
2103 fi
2104 ;;
2105 single)
2106 # List out disc title/author and contents
2107 do_cddbparse "${CDDBLOCALFILE}"
2108 #if [ "$CDROMREADERSYNTAX" = "flac" ] ; then
2109 # echo -n "Embedded cuesheet entry found, use it? [y/n] (y): " >&2
2110 #else
2111 echo -n "Locally cached CDDB entry found, use it? [y/n] (y): " >&2
2112 #fi
2113 if [ "$INTERACTIVE" = "y" ]; then
2114 read USELOCALRESP
2115 while [ "$USELOCALRESP" != "y" ] && [ "$USELOCALRESP" != "n" ] && [ "$USELOCALRESP" != "" ] ; do
2116 echo -n 'Invalid selection. Please answer "y" or "n": ' >&2
2117 read USELOCALRESP
2118 done
2119 [ x"$USELOCALRESP" = "x" ] && USELOCALRESP="y"
2120 else
2121 echo "y" >&2
2122 fi
2123 if [ "$USELOCALRESP" = "y" ]; then
2124 #echo "Using local copy of CDDB data"
2125 echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "$ABCDETEMPDIR/cddbread.1"
2126 cat "${CDDBLOCALFILE}" >> "$ABCDETEMPDIR/cddbread.1"
2127 echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB
2128 echo cddb-readcomplete >> "$ABCDETEMPDIR/status"
2129 do_cddbparse "${CDDBLOCALFILE}" > "$ABCDETEMPDIR/cddbchoices"
2130 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2131 CDDBLOCALSTATUS="single"
2132 else
2133 #echo "Not using local copy of CDDB data"
2134 CDDBLOCALSTATUS="notfound"
2135 fi
2136 ;;
2137 none)
2138 CDDBLOCALSTATUS="notfound"
2139 ;;
2140 esac
2141 fi
2142 }
2143
2144 do_musicbrainzstat ()
2145 {
2146 :
2147 }
2148
2149 do_musicbrainz ()
2150 {
2151 # Use MBE_TOCGetCDIndexId on a perl query
2152 :
2153 }
2154
2155 # do_cddbstat
2156 do_cddbstat ()
2157 {
2158 # Perform CDDB protocol version check if it hasn't already been done
2159 if checkstatus cddb-statcomplete; then :; else
2160 if [ "$CDDBAVAIL" = "n" ]; then
2161 ERRORCODE=no_query
2162 echo 503 > "$ABCDETEMPDIR/cddbstat"
2163 else
2164 rc=1
2165 CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
2166 CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
2167 while test $rc -eq 1 -a $CDDBPROTO -ge 3; do
2168 vecho "Checking CDDB server status..."
2169 $CDDBTOOL stat $CDDBURL $CDDBUSER $CDDBHOST $CDDBPROTO > "$ABCDETEMPDIR/cddbstat"
2170 RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbstat" | cut -f1 -d' ')
2171 case "$RESPONSECODE" in
2172 210) # 210 OK, status information follows (until terminating `.')
2173 rc=0;
2174 ;;
2175 501|*) # 501 Illegal CDDB protocol level: <n>.
2176 CDDBPROTO=`expr $CDDBPROTO - 1`
2177 ;;
2178 esac
2179 done
2180 if test $rc -eq 1; then
2181 CDDBAVAIL="n"
2182 fi
2183 fi
2184 echo cddb-statcomplete >> "$ABCDETEMPDIR/status"
2185 fi
2186 }
2187
2188
2189 # do_cddbquery
2190 do_cddbquery ()
2191 {
2192 CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
2193 CDDBLOCALFILE="${CDDBLOCALDIR}/${CDDBDISCID}"
2194
2195 # Perform CDDB query if it hasn't already been done
2196 if checkstatus cddb-querycomplete; then :; else
2197 if [ "$CDDBAVAIL" = "n" ]; then
2198 ERRORCODE=no_query
2199 echo 503 > "$ABCDETEMPDIR/cddbquery"
2200 # The default CDDBLOCALSTATUS is "notfound"
2201 # This part will be triggered if the user CDDB repo does not
2202 # contain the entry, or if we are not trying to use the repo.
2203 else
2204 vecho "Querying the CDDB server..."
2205 CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
2206 CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
2207 $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $TRACKINFO > "$ABCDETEMPDIR/cddbquery"
2208 ERRORCODE=$?
2209 case $ERRORCODE in
2210 0) # success
2211 ;;
2212 12|13|14)
2213 # no match found in database,
2214 # wget/fetch error, or user requested not to use CDDB
2215 # Make up an error code (503) that abcde
2216 # will recognize in do_cddbread
2217 # and compensate by making a template
2218 echo 503 > "$ABCDETEMPDIR/cddbquery"
2219 ;;
2220 *) # strange and unknown error
2221 echo ERRORCODE=$ERRORCODE
2222 echo "abcde: $CDDBTOOL returned unknown error code"
2223 ;;
2224 esac
2225 fi
2226 echo cddb-querycomplete >> "$ABCDETEMPDIR/status"
2227 fi
2228 }
2229
2230 # do_cddbread
2231 do_cddbread ()
2232 {
2233 # If it's not to be used, generate a template.
2234 # Then, display it (or them) and let the user choose/edit it
2235 if checkstatus cddb-readcomplete; then :; else
2236 vecho "Obtaining CDDB results..."
2237 # If CDDB is to be used, interpret the query results and read all
2238 # the available entries.
2239 rm -f "$ABCDETEMPDIR/cddbchoices"
2240 CDDBCHOICES=1 # Overridden by multiple matches
2241 RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbquery" | cut -f1 -d' ')
2242 case "$RESPONSECODE" in
2243 200)
2244 # One exact match, retrieve it
2245 # 200 [section] [discid] [artist] / [title]
2246 if checkstatus cddb-read-1-complete; then :; else
2247 echo -n "Retrieving 1 CDDB match..." >> "$ABCDETEMPDIR/cddbchoices"
2248 $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(cut -f2,3 -d' ' "$ABCDETEMPDIR/cddbquery") > "$ABCDETEMPDIR/cddbread.1"
2249 echo "done." >> "$ABCDETEMPDIR/cddbchoices"
2250 echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
2251 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2252 fi
2253 # List out disc title/author and contents
2254 echo ---- "$(cut '-d ' -f4- "$ABCDETEMPDIR/cddbquery")" ---- >> "$ABCDETEMPDIR/cddbchoices"
2255 for TRACK in $(f_seq_row 1 $TRACKS)
2256 do
2257 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
2258 done
2259 echo >> "$ABCDETEMPDIR/cddbchoices"
2260 ;;
2261 202|403|409|503)
2262 # No match
2263 case "$RESPONSECODE" in
2264 202) echo "No CDDB match." >> "$ABCDETEMPDIR/cddbchoices" ;;
2265 403|409) echo "CDDB entry is corrupt, or the handshake failed." >> "$ABCDETEMPDIR/cddbchoices" ;;
2266 503) echo "CDDB unavailable." >> "$ABCDETEMPDIR/cddbchoices" ;;
2267 esac
2268 $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
2269 # List out disc title/author and contents of template
2270 echo ---- Unknown Artist / Unknown Album ---- >> "$ABCDETEMPDIR/cddbchoices"
2271 UNKNOWNDISK=y
2272 for TRACK in $(f_seq_row 1 $TRACKS)
2273 do
2274 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.0" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
2275 done
2276 echo >> "$ABCDETEMPDIR/cddbchoices"
2277 echo cddb-read-0-complete >> "$ABCDETEMPDIR/status"
2278 echo cddb-choice=0 >> "$ABCDETEMPDIR/status"
2279 ;;
2280 210|211)
2281 # Multiple exact, (possibly multiple) inexact matches
2282 IN=
2283 if [ "$RESPONSECODE" = "211" ]; then IN=in; fi
2284 if [ "$(wc -l < "$ABCDETEMPDIR/cddbquery" | tr -d ' ')" -eq 3 ]; then
2285 echo "One ${IN}exact match:" >> "$ABCDETEMPDIR/cddbchoices"
2286 tail -n +2 "$ABCDETEMPDIR/cddbquery" | head -n 1 >> "$ABCDETEMPDIR/cddbchoices"
2287 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2288 else
2289 echo "Multiple ${IN}exact matches:" >> "$ABCDETEMPDIR/cddbchoices"
2290 fi
2291 vecho -n "Retrieving multiple matches... "
2292 grep -v ^[.]$ "$ABCDETEMPDIR/cddbquery" | ( X=0
2293 read DISCINFO # eat top line
2294 while read DISCINFO
2295 do
2296 X=$(expr $X + 1)
2297 if checkstatus cddb-read-$X-complete; then :; else
2298 $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(echo $DISCINFO | cut -f1,2 -d' ') > "$ABCDETEMPDIR/cddbread.$X"
2299 echo cddb-read-$X-complete >> "$ABCDETEMPDIR/status"
2300 fi
2301 # List out disc title/author and contents
2302 echo \#$X: ---- "$DISCINFO" ---- >> "$ABCDETEMPDIR/cddbchoices"
2303 for TRACK in $(f_seq_row 1 $TRACKS)
2304 do
2305 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.$X" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
2306 done
2307 echo >> "$ABCDETEMPDIR/cddbchoices"
2308 done )
2309 vecho "done."
2310 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
2311 ;;
2312 999)
2313 # Using local copy.
2314 for TRACK in $(f_seq_row 1 $TRACKS)
2315 do
2316 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
2317 done
2318 echo >> "$ABCDETEMPDIR/cddbchoices"
2319 echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
2320 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2321 ;;
2322 esac
2323 echo "cddb-readcomplete" >> "$ABCDETEMPDIR/status"
2324 fi
2325 }
2326
2327 # do_cddbedit
2328 do_cddbedit ()
2329 {
2330 if checkstatus cddb-edit >/dev/null; then
2331 CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
2332 VARIOUSARTISTS="$(checkstatus variousartists)"
2333 VARIOUSARTISTSTYLE="$(checkstatus variousartiststyle)"
2334 return 0
2335 fi
2336 if [ "$INTERACTIVE" = "y" ]; then
2337 # We should show the CDDB results both when we are not using the local CDDB repo
2338 # or when we are using it but we could not find a proper match
2339 if [ "$CDDBUSELOCAL" = "y" ] && [ "$CDDBLOCALSTATUS" = "notfound" ] || [ ! "$CDDBUSELOCAL" = "y" ]; then
2340 # Display the $ABCDETEMPDIR/cddbchoices file created above
2341 # Pick a pager so that if the tracks overflow the screen the user can still view everything
2342 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
2343 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
2344 CHOICE=$(checkstatus cddb-choice)
2345 if [ -n "$CHOICE" ] ; then
2346 case $CDDBCHOICES in
2347 -1) if head -1 "$ABCDETEMPDIR/cddbquery" | grep "^$" > /dev/null 2>&1 ; then
2348 log error "CDDB query failed!"
2349 exit 1
2350 else
2351 cat "$ABCDETEMPDIR/cddbchoices"
2352 fi
2353 ;;
2354 1) cat "$ABCDETEMPDIR/cddbchoices" ;;
2355 *)
2356 echo "Selected: #$CHOICE"
2357 do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
2358 ;;
2359 esac
2360 else
2361 # The user has a choice to make, display the info in a pager if necessary
2362 if [ $(cat "$ABCDETEMPDIR/cddbchoices" | wc -l) -ge 24 ]; then
2363 page "$ABCDETEMPDIR/cddbchoices"
2364 else
2365 # It's all going to fit in one page, cat it
2366 cat "$ABCDETEMPDIR/cddbchoices" >&2
2367 fi
2368
2369 CDDBCHOICENUM=""
2370 # Setting the choice to an impossible integer to avoid errors in the numeric comparisons
2371 CDCHOICENUM=-1
2372 # I'll take CDDB read #3 for $400, Alex
2373 while [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; do
2374 echo -n "Which entry would you like abcde to use (0 for none)? [0-$CDDBCHOICES]: " >&2
2375 read CDDBCHOICE
2376 [ X"$CDDBCHOICE" = "X" ] && CDDBCHOICE=1
2377 if echo $CDDBCHOICE | egrep "[[:space:]]*[[:digit:]]+,[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
2378 if [ ! X"$DIFF" = "X" ]; then
2379 PARSECHOICE1=$(echo $CDDBCHOICE | cut -d"," -f1 | xargs printf %d 2>/dev/null)
2380 PARSECHOICE2=$(echo $CDDBCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null)
2381 if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBCHOICES ] || \
2382 [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBCHOICES ] || \
2383 [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then
2384 echo "Invalid diff range. Please select two coma-separated numbers between 1 and $CDDBCHOICES" >&2
2385 else
2386 # We parse the 2 choices to diff, store them in temporary files and diff them.
2387 for PARSECHOICE in $(echo $CDDBCHOICE | tr , \ ); do
2388 do_cddbparse "$ABCDETEMPDIR/cddbread.$PARSECHOICE" > "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE"
2389 done
2390 echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..." > "$ABCDETEMPDIR/cddbread.diff"
2391 $DIFF $DIFFOPTS "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE1" "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE2" >> "$ABCDETEMPDIR/cddbread.diff"
2392 if [ $(cat "$ABCDETEMPDIR/cddbread.diff" | wc -l) -ge 24 ]; then
2393 page "$ABCDETEMPDIR/cddbread.diff"
2394 else
2395 cat "$ABCDETEMPDIR/cddbread.diff" >&2
2396 fi
2397 fi
2398 else
2399 echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBCHOICES." >&2
2400 fi
2401 elif echo $CDDBCHOICE | egrep "[[:space:]]*[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
2402 # Make sure we get a valid choice
2403 CDCHOICENUM=$(echo $CDDBCHOICE | xargs printf %d 2>/dev/null)
2404 if [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; then
2405 echo "Invalid selection. Please choose a number between 0 and $CDDBCHOICES." >&2
2406 fi
2407 fi
2408 done
2409 if [ "$CDCHOICENUM" = "0" ]; then
2410 vecho "Creating empty CDDB template..."
2411 UNKNOWNDISK=y
2412 $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
2413 else
2414 echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
2415 do_cddbparse "$ABCDETEMPDIR/cddbread.$CDCHOICENUM"
2416 fi
2417 echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
2418 fi
2419 fi
2420 else
2421 # We need some code to show the selected option when local repository is selected and we have found a match
2422 vecho "Using cached CDDB match..." >&2
2423 # Display the $ABCDETEMPDIR/cddbchoices file created above
2424 # Pick a pager so that if the tracks overflow the screen the user can still view everything
2425 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
2426 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
2427 CHOICE=$(checkstatus cddb-choice)
2428 if [ "$USELOCALRESP" = "y" ]; then :; else
2429 if [ -n "$CHOICE" ] ; then
2430 case $CDDBCHOICES in
2431 0)
2432 UNKNOWNDISK=y
2433 echo "Selected template."
2434 ;;
2435 1) cat "$ABCDETEMPDIR/cddbchoices" ;;
2436 *)
2437 echo "Selected: #$CHOICE"
2438 do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
2439 ;;
2440 esac
2441 fi
2442 fi
2443 fi
2444 fi
2445 else
2446 # We're noninteractive - pick the first choice.
2447 # But in case we run a previous instance and selected a choice, use it.
2448 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
2449 # Show the choice if we are not using the locally stored one
2450 # or when the local search failed to find a match.
2451 PREVIOUSCHOICE=$(checkstatus cddb-choice)
2452 if [ "$CDDBUSELOCAL" = "y" ] && [ "$CDDBLOCALSTATUS" = "notfound" ] || [ ! "$CDDBUSELOCAL" = "y" ]; then
2453 #if [ "$PREVIOUSCHOICE" ]; then
2454 cat "$ABCDETEMPDIR/cddbchoices"
2455 #fi
2456 fi
2457 if [ ! -z "$PREVIOUSCHOICE" ] ; then
2458 CDCHOICENUM=$PREVIOUSCHOICE
2459 else
2460 CDCHOICENUM=1
2461 echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
2462 fi
2463 echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
2464 fi
2465 fi
2466
2467 # sanity check
2468 if checkstatus cddb-choice >/dev/null; then :; else
2469 echo "abcde: internal error: cddb-choice not recorded." >&2
2470 exit 1
2471 fi
2472 CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
2473 echo -n "Edit selected CDDB data? [y/n] (" >&2
2474 if [ "$INTERACTIVE" = "y" ]; then
2475 if [ "$UNKNOWNDISK" = "y" ]; then
2476 echo -n "y): " >&2
2477 read EDITCDDB
2478 [ "$EDITCDDB" != "n" ] && EDITCDDB=y
2479 else
2480 echo -n "n): " >&2
2481 read EDITCDDB
2482 fi
2483 else
2484 echo "n): n" >&2
2485 EDITCDDB=n
2486 fi
2487 if [ "$EDITCDDB" = "y" ]; then
2488 CDDBDATAMD5SUM=$($MD5SUM "$CDDBDATA" | cut -d " " -f 1);
2489
2490 # Use the debian sensible-editor wrapper to pick the editor that the
2491 # user has requested via their $EDITOR environment variable
2492 if [ -x "/usr/bin/sensible-editor" ]; then
2493 /usr/bin/sensible-editor "$CDDBDATA"
2494 elif [ -n "$EDITOR" ]; then
2495 if [ -x $(which "${EDITOR%%\ *}") ]; then
2496 # That failed, try to load the preferred editor, starting
2497 # with their EDITOR variable
2498 eval $(echo "$EDITOR") \"$CDDBDATA\"
2499 fi
2500 # If that fails, check for a vi
2501 elif which vi >/dev/null 2>&1; then
2502 vi "$CDDBDATA"
2503 elif [ -x /usr/bin/vim ]; then
2504 /usr/bin/vim "$CDDBDATA"
2505 elif [ -x /usr/bin/vi ]; then
2506 /usr/bin/vi "$CDDBDATA"
2507 elif [ -x /bin/vi ]; then
2508 /bin/vi "$CDDBDATA"
2509 # nano should be on all (modern, i.e., sarge) debian systems
2510 elif which nano >/dev/null 2>&1 ; then
2511 nano "$CDDBDATA"
2512 elif [ -x /usr/bin/nano ]; then
2513 /usr/bin/nano "$CDDBDATA"
2514 # mg should be on all OpenBSD systems
2515 elif which mg >/dev/null 2>&1 ; then
2516 mg "$CDDBDATA"
2517 elif [ -x /usr/bin/mg ]; then
2518 /usr/bin/mg "$CDDBDATA"
2519 # bomb out
2520 else
2521 log warning "no editor available. Check your EDITOR environment variable."
2522 fi
2523 # delete editor backup file if it exists
2524 if [ -w "$CDDBDATA~" ]; then
2525 rm -f "$CDDBDATA~"
2526 fi
2527 fi
2528
2529 # Some heuristics first. Look at Disc Title, and if it starts with
2530 # "Various", then we'll assume Various Artists
2531 if [ "$(grep ^DTITLE= "$CDDBDATA" | cut -f2- -d= | egrep -ci '^(various|soundtrack|varios|sonora|ost)')" != "0" ]; then
2532 echo "Looks like a Multi-Artist CD" >&2
2533 VARIOUSARTISTS=y
2534 else
2535 echo -n "Is the CD multi-artist? [y/n] (n): " >&2
2536 if [ "$INTERACTIVE" = "y" ]; then
2537 read VARIOUSARTISTS
2538 else
2539 echo n >&2
2540 VARIOUSARTISTS=n
2541 fi
2542 fi
2543 if [ "$VARIOUSARTISTS" = "y" ] && [ ! "$ONETRACK" = "y" ]; then
2544 # Set a default
2545 DEFAULTSTYLE=1
2546 # Need NUMTRACKS before cddb-tool will return it:
2547 NUMTRACKS=$(egrep '^TTITLE[0-9]+=' "$CDDBDATA" | wc -l)
2548 if [ "$(grep -c "^TTITLE.*\/" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2549 # More than 1/2 tracks contain a "/", so guess forward
2550 DEFAULTSTYLE=1
2551 elif [ "$(grep -c "^TTITLE.*\-" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2552 # More than 1/2 contain a "-", so guess forward-dash
2553 DEFAULTSTYLE=2
2554 elif [ "$(grep -c "^TTITLE.*(.*)" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2555 # More than 1/2 contain something in parens, so guess trailing-paren
2556 DEFAULTSTYLE=6
2557 fi
2558
2559 echo "1) Artist / Title" >&2
2560 echo "2) Artist - Title" >&2
2561 echo "3) Title / Artist" >&2
2562 echo "4) Title - Artist" >&2
2563 echo "5) Artist: Title" >&2
2564 echo "6) Title (Artist)" >&2
2565 echo "7) This is a single-artist CD" >&2
2566 echo -n "Which style of multiple artist entries is it? [1-7] ($DEFAULTSTYLE): " >&2
2567 if [ "$INTERACTIVE" = "y" ]; then
2568 read VARIOUSARTISTSTYLE
2569 else
2570 echo $DEFAULTSTYLE >&2
2571 VARIOUSARTISTSTYLE=$DEFAULTSTYLE
2572 fi
2573 VARIOUSARTISTSTYLE=$(echo 0$VARIOUSARTISTSTYLE | xargs printf %d)
2574 # If they press Enter, then the default style (0) was chosen
2575 while [ $VARIOUSARTISTSTYLE -lt 0 ] || [ $VARIOUSARTISTSTYLE -gt 7 ]; do
2576 echo "Invalid selection. Please choose a number between 1 and 7."
2577 echo -n "Selection [1-7]: "
2578 read VARIOUSARTISTSTYLE
2579 VARIOUSARTISTSTYLE=$(echo 0$VARIOUSARTISTSTYLE | xargs printf %d)
2580 done
2581 if [ "$VARIOUSARTISTSTYLE" = "0" ]; then
2582 VARIOUSARTISTSTYLE=$DEFAULTSTYLE
2583 fi
2584 vecho "Selected: $VARIOUSARTISTSTYLE"
2585 case "$VARIOUSARTISTSTYLE" in
2586 1) # Artist / Title
2587 VARIOUSARTISTSTYLE=forward
2588 ;;
2589 2) # Artist - Title
2590 VARIOUSARTISTSTYLE=forward-dash
2591 ;;
2592 3) # Title / Artist
2593 VARIOUSARTISTSTYLE=reverse
2594 ;;
2595 4) # Title - Artist
2596 VARIOUSARTISTSTYLE=reverse-dash
2597 ;;
2598 5) # Artist: Title
2599 VARIOUSARTISTSTYLE=colon
2600 ;;
2601 6) # Title (Artist)
2602 VARIOUSARTISTSTYLE=trailing-paren
2603 ;;
2604 7) # Single Artist
2605 VARIOUSARTISTS=n
2606 ;;
2607 esac
2608 fi
2609
2610 echo "variousartists=$VARIOUSARTISTS" >> "$ABCDETEMPDIR/status"
2611 echo "variousartiststyle=$VARIOUSARTISTSTYLE" >> "$ABCDETEMPDIR/status"
2612
2613 if [ "$EDITCDDB" = "y" ] && [ "$UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE" = "y" ]; then
2614 if [ "$CDDBDATAMD5SUM" != "" ] && [ "$CDDBDATAMD5SUM" != "$($MD5SUM "$CDDBDATA" | cut -d " " -f 1)" ]; then
2615 # This works but does not have the necessary error checking
2616 # yet. If you are familiar with the CDDB spec
2617 # (see http://www.freedb.org/src/latest/DBFORMAT)
2618 # and can create an error-free entry on your own, then put
2619 # UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE=y in your
2620 # abcde.conf to enable it. Put CDDBSUBMIT=email@address in
2621 # your abcde.conf to change the email address submissions are
2622 # sent to.
2623
2624 # submit the modified file, if they want
2625 if [ "$NOSUBMIT" != "y" ]; then
2626 echo -n "Do you want to submit this entry to $CDDBSUBMIT? [y/n] (n): "
2627 read YESNO
2628 while [ "$YESNO" != "y" ] && [ "$YESNO" != "n" ] && [ "$YESNO" != "Y" ] && \
2629 [ "$YESNO" != "N" ] && [ "$YESNO" != "" ]
2630 do
2631 echo -n 'Invalid selection. Please answer "y" or "n": '
2632 read YESNO
2633 done
2634 if [ "$YESNO" = "y" ] || [ "$YESNO" = "Y" ]; then
2635 echo -n "Sending..."
2636 $CDDBTOOL send "$CDDBDATA" $CDDBSUBMIT
2637 echo "done."
2638 fi
2639 fi
2640 fi
2641 fi
2642 ### FIXME ###
2643 # User CDDBLOCALPOLICY to find out if we store the file or not...
2644 # Cache edited CDDB entry in the user's cddb dir
2645 if [ "$CDDBCOPYLOCAL" = "y" ]; then
2646 # Make sure the cache directory exists
2647 mkdir -p $CDDBLOCALDIR
2648 cat "$CDDBDATA" | tail -n $(expr $(cat "$CDDBDATA" | wc -l ) - 1 ) > ${CDDBLOCALDIR}/$(echo "$TRACKINFO" | cut -d' ' -f1)
2649 fi
2650
2651 echo "cddb-edit" >> "$ABCDETEMPDIR/status"
2652 }
2653
2654 # do_cdread [tracknumber]
2655 # do_cdread onetrack [firsttrack] [lasttrack]
2656 #
2657 do_cdread ()
2658 {
2659 # The commands here don't go through run_command because they're never supposed to be silenced
2660 # return codes need to be doublechecked anyway, however
2661 if [ "$1" = "onetrack" ]; then
2662 # FIXME # Add the possibility of grabbing ranges of tracks in onetrack
2663 # FIXME # Until then, we grab the whole CD in one track, no matter what
2664 # the user said
2665 # We need the first and last track for cdda2wav
2666 FIRSTTRACK=$2
2667 LASTTRACK=$(expr $3 + 0)
2668 UTRACKNUM=$FIRSTTRACK
2669 case "$CDROMREADERSYNTAX" in
2670 flac) READTRACKNUMS="$FIRSTTRACK.1-$(($LASTTRACK + 1)).0" ;;
2671 cdparanoia)
2672 #XX FIXME XX
2673 # Add a variable to check if tracks are provided in command line and if not, use "0-" to rip the tracks
2674 READTRACKNUMS="$FIRSTTRACK-$LASTTRACK" ;;
2675 cdda2wav) READTRACKNUMS="$FIRSTTRACK+$LASTTRACK" ;;
2676 *) echo "abcde error: $CDROMREADERSYNTAX does not support ONETRACK mode"
2677 exit 1 ;;
2678 esac
2679 else
2680 UTRACKNUM=$1
2681 fi
2682 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
2683 if [ "$USEPIPES" = "y" ]; then
2684 TEMPARG="PIPERIPPER_$CDROMREADERSYNTAX"
2685 FILEARG="$( eval echo "\$$TEMPARG" )"
2686 REDIR=""
2687 PIPE_MESSAGE="and encoding "
2688 else
2689 WAVDATA="$ABCDETEMPDIR/track$UTRACKNUM.wav"
2690 case "$CDROMREADERSYNTAX" in
2691 ## FIXME ## Find the cases for dagrab and flac, to avoid exceptions
2692 flac)
2693 FILEARG="--output-name=$WAVDATA"
2694 ;;
2695 dagrab)
2696 FILEARG="-f $WAVDATA"
2697 ;;
2698 *)
2699 FILEARG="$WAVDATA"
2700 ;;
2701 esac
2702 REDIR=">&2"
2703 fi
2704 if [ "$1" = "onetrack" ]; then
2705 echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2
2706 else
2707 if [ -r "$CDDBDATA" ]; then
2708 getcddbinfo TRACKNAME
2709 echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM: $TRACKNAME..." >&2
2710 else
2711 echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM..." >&2
2712 fi
2713 fi
2714 case "$CDROMREADERSYNTAX" in
2715 ### FIXME ### use an exception for flac, since it uses -o
2716 ### FIXME ### Shall we just use -o $FILEARG ??
2717 flac)
2718 # Avoid problems wit math expressions by unpadding the given UTRACKNUM
2719 STRIPTRACKNUM=$(expr $UTRACKNUM + 0)
2720 nice $READNICE $FLAC -d -f --cue=${READTRACKNUMS:-$STRIPTRACKNUM.1-$(($STRIPTRACKNUM + 1)).0} "$FILEARG" "$CDROM" ;;
2721 cdparanoia)
2722 nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR ;;
2723 cdda2wav)
2724 if [ "$OSFLAVOUR" = "OSX" ] ; then
2725 # Hei, we have to unmount the device before running anything like cdda2wav in OSX
2726 disktool -u ${CDROM#/dev/} 0
2727 # Also, in OSX the cdrom device for cdda2wav changes...
2728 CDDA2WAVCDROM="IODVDServices"
2729 elif [ "$OSFLAVOUR" = "FBSD" ] ; then
2730 CDDA2WAVCDROM="$CDROMID"
2731 else
2732 if [ "$CDROMID" = "" ]; then
2733 CDDA2WAVCDROM="$CDROM"
2734 else
2735 CDDA2WAVCDROM="$CDROMID"
2736 fi
2737 fi
2738 nice $READNICE $CDROMREADER -D $CDDA2WAVCDROM -t ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR
2739 ;;
2740 ## FIXME ## We have an exception for dagrab, since it uses -f
2741 ## FIXME ## Shall we just use -f $FILEARG ??
2742 dagrab) nice $READNICE $CDROMREADER -d "$CDROM" -v $UTRACKNUM "$FILEARG" $REDIR
2743 ;;
2744 cddafs)
2745 # Find the track's mounted path
2746 REALTRACKNUM=$(expr $UTRACKNUM + 0)
2747 FILEPATH=$(mount | grep "$CDROM on" | sed 's/^[^ ]* on \(.*\) (.*/\1/')
2748 FILEPATH=$(find "$FILEPATH" | grep "/$REALTRACKNUM ");
2749 # If the file exists, copy it
2750 if [ -e "$FILEPATH" ] ; then
2751 nice $READNICE $CDROMREADER "$FILEPATH" "$FILEARG" $REDIR
2752 else
2753 false
2754 fi ;;
2755 debug) nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -w $UTRACKNUM-[:1] "$FILEARG" $REDIR
2756 ;;
2757 esac
2758 RETURN=$?
2759 # If we get some error or we get some missing wav
2760 # (as long as we dont use pipes)
2761 if [ "$RETURN" != "0" -o \( ! -s "$WAVDATA" -a X"$USEPIPES" != "Xy" \) ]; then
2762 # Thank goodness errors is only machine-parseable up to the
2763 # first colon, otherwise this woulda sucked
2764 if [ "$RETURN" = "0" -a ! -s "$WAVDATA" ]; then
2765 RETURN=73 # fake a return code as cdparanoia return 0 also on aborted reads
2766 fi
2767 if [ "$USEPIPES" = "y" ]; then
2768 echo "readencodetrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
2769 else
2770 echo "readtrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
2771 fi
2772 return $RETURN
2773 else
2774 if [ "$USEPIPES" = "y" ]; then
2775 echo readencodetrack-$UTRACKNUM >> "$ABCDETEMPDIR/status"
2776 else
2777 echo readtrack-$UTRACKNUM >> "$ABCDETEMPDIR/status"
2778 fi
2779 if [ "$1" = "onetrack" ]; then
2780 echo onetrack >> "$ABCDETEMPDIR/status"
2781 fi
2782 fi
2783 }
2784
2785 # do_cdspeed
2786 # No values accepted, only uses env variables
2787 do_cdspeed ()
2788 {
2789 if "$CDSPEED" "$CDSPEEDOPTS" "$CDSPEEDVALUE" >/dev/null ; then
2790 vecho "Setting CD speed to ${CDSPEEDVALUE}x"
2791 else
2792 echo "abcde: unable to set the device speed" >&2
2793 fi
2794 }
2795
2796 # vecho [message]
2797 #
2798 # vecho outputs a message if EXTRAVERBOSE is selected
2799 vecho ()
2800 {
2801 if [ x"$EXTRAVERBOSE" != "x" ]; then
2802 case $1 in
2803 warning) shift ; log warning "$@" ;;
2804 *) echo "$@" ;;
2805 esac
2806 fi
2807 }
2808
2809 # decho [message]
2810 #
2811 # decho outputs a debug message if DEBUG is selected
2812 decho ()
2813 {
2814 if [ x"$DEBUG" != "x" ]; then
2815 if echo $1 | grep "^\[" > /dev/null 2>&1 ; then
2816 DEBUGECHO=$(echo "$@" | tr -d '[]')
2817 echo "[DEBUG] $DEBUGECHO: `eval echo \\$${DEBUGECHO}`"
2818 else
2819 echo "[DEBUG] $1"
2820 fi
2821 fi
2822 }
2823
2824 # User-redefinable functions
2825 # Custom filename munging:
2826 mungefilename ()
2827 {
2828 #echo "$@" | sed s,:,\ -,g | tr \ /\* __+ | tr -d \'\"\?\[:cntrl:\]
2829 echo "$@" | sed s,:,\ -,g | tr \ / __ | tr -d \'\"\?\[:cntrl:\]
2830 }
2831
2832 # Custom genre munging:
2833 mungegenre ()
2834 {
2835 echo $CDGENRE | tr "[:upper:]" "[:lower:]"
2836 }
2837
2838 # pre_read
2839 # Empty pre_read function, to be defined in the configuration file.
2840 pre_read ()
2841 {
2842 :
2843 }
2844
2845 # post_read
2846 # Empty post_read function, to be defined in the configuration file.
2847 post_read ()
2848 {
2849 :
2850 }
2851
2852 ###############################################################################
2853 # End of functions
2854 #
2855 # Start of execution
2856 ###############################################################################
2857
2858 # Builtin defaults
2859
2860 # CDDB
2861 # Defaults to FreeDB, but a python musicbrainz can be used
2862 CDDBMETHOD=cddb
2863 CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"
2864 CDDBSUBMIT=freedb-submit@freedb.org
2865 CDDBPROTO=6
2866 HELLOINFO="$(whoami)@$(hostname)"
2867 CDDBCOPYLOCAL="n"
2868 CDDBLOCALPOLICY="always"
2869 CDDBLOCALRECURSIVE="y"
2870 CDDBLOCALDIR="$HOME/.cddb"
2871 CDDBUSELOCAL="n"
2872
2873 # List of fields we parse and show during the CDDB parsing...
2874 SHOWCDDBFIELDS="year,genre"
2875
2876 INTERACTIVE=y
2877 #CDROMREADERSYNTAX=cdparanoia
2878 ENCODERSYNTAX=default
2879
2880 MP3ENCODERSYNTAX=default
2881 OGGENCODERSYNTAX=default
2882 FLACENCODERSYNTAX=default
2883 SPEEXENCODERSYNTAX=default
2884 MPPENCODERSYNTAX=default
2885 AACENCODERSYNTAX=default
2886 NORMALIZERSYNTAX=default
2887 CUEREADERSYNTAX=default
2888
2889 OUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${TRACKNUM}.${TRACKFILE}'
2890 # Use the following VAOUTPUTFORMAT to revert to 2.0.x VA format:
2891 #VAOUTPUTFORMAT=${OUTPUTFORMAT}
2892 VAOUTPUTFORMAT='Various-${ALBUMFILE}/${TRACKNUM}.${ARTISTFILE}-${TRACKFILE}'
2893 ONETRACKOUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${ALBUMFILE}'
2894 VAONETRACKOUTPUTFORMAT='Various-${ALBUMFILE}/${ALBUMFILE}'
2895 PLAYLISTFORMAT='${ARTISTFILE}-${ALBUMFILE}.${OUTPUT}.m3u'
2896 PLAYLISTDATAPREFIX=''
2897 VAPLAYLISTFORMAT='${ARTISTFILE}-${ALBUMFILE}.${OUTPUT}.m3u'
2898 VAPLAYLISTDATAPREFIX=''
2899 DOSPLAYLIST=n
2900 COMMENT=''
2901 ID3TAGV=2
2902 ENCNICE=10
2903 READNICE=10
2904 DISTMP3NICE=10
2905 VARIOUSARTISTS=n
2906 VARIOUSARTISTSTYLE=forward
2907 KEEPWAVS=n
2908 PADTRACKS=n
2909 NOGAP=n
2910 BATCHNORM=n
2911 NOCDDBQUERY=n
2912
2913 # If using scsi devices, cdda2wav needs a CDROMID, instead of a device node
2914 # i.e. CDROMID="1,0,0"
2915 CDROMID=""
2916 # If we are using the IDE bus, we need CDPARANOIACDROMBUS defined as "d"
2917 # If we are using the ide-scsi emulation layer, we need to define a "g"
2918 CDPARANOIACDROMBUS="d"
2919
2920 # program paths - defaults to checking your $PATH
2921 # mp3
2922 LAME=lame
2923 TOOLAME=toolame
2924 GOGO=gogo
2925 BLADEENC=bladeenc
2926 L3ENC=l3enc
2927 XINGMP3ENC=xingmp3enc
2928 MP3ENC=mp3enc
2929 # ogg
2930 VORBIZE=vorbize
2931 OGGENC=oggenc
2932 # flac
2933 FLAC=flac
2934 # speex
2935 SPEEXENC=speexenc
2936 # mpp (Musepack)
2937 MPPENC=mppenc
2938 # m4a
2939 AACENC=faac
2940
2941 ID3=id3
2942 ID3V2=id3v2
2943 EYED3=eyeD3
2944 CDPARANOIA=cdparanoia
2945 CDDA2WAV=cdda2wav
2946 DAGRAB=dagrab
2947 CDDAFS=cp
2948 CDDISCID=cd-discid
2949 CDDBTOOL=cddb-tool
2950 MUSICBRAINZ=musicbrainz-get-tracks
2951 EJECT=eject
2952 MD5SUM=md5sum
2953 DISTMP3=distmp3
2954 VORBISCOMMENT=vorbiscomment
2955 METAFLAC=metaflac
2956 NORMALIZE=normalize-audio
2957 CDSPEED=eject
2958 VORBISGAIN=vorbisgain
2959 MP3GAIN=mp3gain
2960 MPPGAIN=replaygain
2961 MKCUE=mkcue
2962 MKTOC=cdrdao
2963 DIFF=diff
2964 CUE2DISCID=builtin
2965
2966 # Options for programs called from abcde
2967 # mp3
2968 LAMEOPTS=
2969 TOOLAMEOPTS=
2970 GOGOOPTS=
2971 BLADEENCOPTS=
2972 L3ENCOPTS=
2973 XINGMP3ENCOPTS=
2974 MP3ENCOPTS=
2975 # ogg
2976 VORBIZEOPTS=
2977 OGGENCOPTS=
2978 # flac
2979 FLACOPTS=
2980 # speex
2981 SPEEXENCOPTS=
2982 # mpc
2983 MPPENCOPTS=
2984 # m4a
2985 AACENCOPTS=
2986
2987 ID3OPTS=
2988 ID3V2OPTS=
2989 CDPARANOIAOPTS=
2990 CDDA2WAVOPTS=
2991 DAGRABOPTS=
2992 CDDAFSOPTS="-f"
2993 CDDBTOOLOPTS=
2994 EJECTOPTS=
2995 DISTMP3OPTS=
2996 NORMALIZEOPTS=
2997 CDSPEEDOPTS="-x"
2998 CDSPEEDVALUE=
2999 MKCUEOPTS=
3000 MKTOCOPTS=""
3001 VORBISCOMMENTOPTS="-R"
3002 METAFLACOPTS="--no-utf8-convert"
3003 DIFFOPTS=
3004
3005 # Default to one process if -j isn't specified
3006 MAXPROCS=1
3007
3008 # List of actions to perform - by default, run to completion
3009 ACTIONS=cddb,read,encode,tag,move,clean
3010
3011 # This option is basicaly for Debian package dependencies:
3012 # List of prefered outputs - by default, run with whatever we have in the path
3013 DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:toolame,mp3:lame,mp3:bladeenc,spx:speex,m4a:faac
3014
3015 # List of prefered cdromreaders - by default, run whichever we have in the path
3016 DEFAULT_CDROMREADERS="cdparanoia cdda2wav"
3017
3018 # List of quality levels associated with the encoders:
3019 DEFAULT_QUALITY_XLO="oggenc:-q -1,lame:-q 9,speex:--quality 1,m4a:"
3020 DEFAULT_QUALITY_LO="oggenc:-q 1,lame:-q 7,speex:--quality 5,m4a:"
3021 DEFAULT_QUALITY_HI="oggenc:-q 7,lame:--preset standard,speex:--quality 9,m4a:"
3022 DEFAULT_QUALITY_XHI="oggenc:-q 10,lame:--preset extreme,speex:--quality 10,m4a:"
3023
3024 # Asume fetch if under FreeBSD. curl is used for Mac OS X. wget is used for
3025 # Linux/OpenBSD. ftp is user for NetBSD.
3026 # Let's use these checkings to determine the OS flavour, which will be used
3027 # later
3028 if [ X$(uname) = "XFreeBSD" ] ; then
3029 HTTPGET=fetch
3030 MD5SUM=md5
3031 NEEDCDROMID=y
3032 OSFLAVOUR=FBSD
3033 elif [ X$(uname) = "XDarwin" ] ; then
3034 HTTPGET=curl
3035 OSFLAVOUR=OSX
3036 # We should have disktool in OSX, but let's be sure...
3037 NEEDDISKTOOL=y
3038 CDROMREADERSYNTAX=cddafs
3039 elif [ X$(uname) = "XOpenBSD" ] ; then
3040 HTTPGET=wget
3041 MD5SUM=md5
3042 OSFLAVOUR=OBSD
3043 elif [ X$(uname) = "XNetBSD" ] ; then
3044 HTTPGET=ftp
3045 MD5SUM=md5
3046 OSFLAVOUR=NBSD
3047 elif [ X$(uname) = "SunOS" ] ; then
3048 HTTPGET=""
3049 MD5SUM=md5
3050 OSFLAVOUR=SunOS
3051 else
3052 HTTPGET=wget
3053 fi
3054
3055 # If CDDBAVAIL is set to n, no CDDB read is done
3056 # If USEID3 is set to n, no ID3 tagging is done
3057 CDDBAVAIL=y
3058 USEID3=y
3059 USEID3V2=y
3060
3061 # There we go..
3062 # But before we get into business, let us chop off any GREP environmental
3063 # variables.
3064 GREP_OPTIONS=""
3065 GREP_COLOR=""
3066
3067 if [ -z "$OUTPUTDIR" ]; then
3068 OUTPUTDIR=$(pwd)
3069 fi
3070
3071 if [ -z "$WAVOUTPUTDIR" ]; then
3072 WAVOUTPUTDIR="$OUTPUTDIR"
3073 fi
3074
3075 # Load system defaults
3076 if [ -r /etc/abcde.conf ]; then
3077 . /etc/abcde.conf
3078 fi
3079 # Load user preference defaults
3080 if [ -r $HOME/.abcde.conf ]; then
3081 . $HOME/.abcde.conf
3082 fi
3083
3084 # By this time, we need some HTTPGETOPTS already defined.
3085 # If the user has defined a non-default HTTPGET method, we should not be empty.
3086
3087 if [ "$HTTPGETOPTS" = "" ] ; then
3088 case $HTTPGET in
3089 wget) HTTPGETOPTS="-q -nv -O -";;
3090 curl) HTTPGETOPTS="-f -s";;
3091 fetch)HTTPGETOPTS="-q -o -";;
3092 ftp) HTTPGETOPTS="-a -V -o - ";;
3093 *) log warning "HTTPGET in non-standard and HTTPGETOPTS are not defined." ;;
3094 esac
3095 fi
3096
3097 # If the CDROM has not been set yet, find a suitable one.
3098 # If this is a devfs system, default to /dev/cdroms/cdrom0
3099 # instead of /dev/cdrom
3100 if [ "$CDROM" = "" ] ; then
3101 if [ -e /dev/cdroms/cdrom0 ]; then
3102 CDROM=/dev/cdroms/cdrom0
3103 elif [ -e /dev/cdrom ]; then
3104 CDROM=/dev/cdrom
3105 elif [ -e /dev/cd0c ]; then
3106 CDROM=/dev/cd0c
3107 elif [ -e /dev/acd0c ]; then
3108 CDROM=/dev/acd0c
3109 elif [ -e /dev/disk1 ]; then
3110 CDROM=/dev/disk1
3111 fi
3112 fi
3113
3114 # Parse command line options
3115 #while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPq:r:Rs:S:t:T:vVxw:W: opt ; do
3116 while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:UvVxX:w:W:z opt ; do
3117 case "$opt" in
3118 1) ONETRACK=y ;;
3119 a) ACTIONS="$OPTARG" ;;
3120 A) EXPACTIONS="$OPTARG" ;;
3121 b) BATCHNORM=y ;;
3122 B) NOBATCHREPLAYGAIN=y ;;
3123 c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else log error "config file \"$OPTARG\" cannot be found." ; exit 1 ; fi ;;
3124 C) DISCID="$( echo ${OPTARG#abcde.} | tr -d /)" ;;
3125 d) CDROM="$OPTARG" ;;
3126 D) set -x ;;
3127 h) usage; exit ;;
3128 e) ERASEENCODEDSTATUS=y ;;
3129 E) ENCODING="$OPTARG" ;;
3130 f) FORCE=y ;;
3131 g) NOGAP=y ;;
3132 i) INLINETAG=y ;;
3133 j) MAXPROCS="$OPTARG" ;;
3134 k) KEEPWAVS=y ;;
3135 l) LOWDISK=y ;;
3136 L) CDDBUSELOCAL=y ;;
3137 n) CDDBAVAIL=n ;;
3138 N) INTERACTIVE=n ;;
3139 m) DOSPLAYLIST=y ;;
3140 M) DOCUE=y ;;
3141 o) OUTPUTTYPE="$OPTARG" ;;
3142 p) PADTRACKS=y ;;
3143 P) USEPIPES=y ;;
3144 q) QUALITYLEVEL="$OPTARG" ;;
3145 r) REMOTEHOSTS="$OPTARG" ;;
3146 R) CDDBLOCALRECURSIVE=y ;;
3147 s) SHOWCDDBFIELDS="$OPTARG" ;;
3148 S) CDSPEEDVALUE="$OPTARG" ;;
3149 t) STARTTRACKNUMBER="$OPTARG" ;;
3150 T) STARTTRACKNUMBER="$OPTARG" ; STARTTRACKNUMBERTAG="y" ;;
3151 U) CDDBPROTO=5 ;;
3152 v)
3153 echo "This is abcde v$VERSION."
3154 echo "Usage: abcde [options] [tracks]"
3155 echo "abcde -h for extra help"
3156 exit
3157 ;;
3158 V) EXTRAVERBOSE="y" ;;
3159 x) EJECTCD="y" ;;
3160 X) CUE2DISCID="$OPTARG" ;;
3161 w) COMMENT="$OPTARG" ;;
3162 W) if echo $OPTARG | grep "[[:digit:]]" > /dev/null 2>&1 ; then
3163 STARTTRACKNUMBER="${OPTARG}01" ; STARTTRACKNUMBERTAG="y" ; COMMENT="CD${OPTARG}"
3164 else
3165 log error "argument of -W must be integer"
3166 exit 1
3167 fi
3168 ;;
3169 z) DEBUG=y ; CDROMREADERSYNTAX=debug ; EJECTCD="n" ;;
3170 ?) usage; exit ;;
3171 esac
3172 done
3173
3174 shift $(($OPTIND - 1))
3175
3176 # Here it comes the worse part of the whole thing. From here until we start
3177 # ripping, we have a mixture of sanity checks, verifications, default settigs
3178 # and other crazy stuff that interdepends, but hey, someone has to do it.
3179
3180 # If NOCDDBQUERY is set, don't query the CDDB server.
3181 if [ "$NOCDDBQUERY" = "y" ]; then
3182 CDDBAVAIL="n"
3183 fi
3184
3185 # If the user specified a flac file, then switch to special flac mode
3186 if echo "$CDROM" | grep -i '.flac$' > /dev/null 2>&1 ; then
3187 if [ ! -f "$CDROM" ]; then
3188 log error "the defined file for FLAC ripping cannot be found" >&2
3189 exit 1
3190 fi
3191 vecho warning "switching to flac CDROMREADERSYNTAX..."
3192 CDROMREADERSYNTAX=flac
3193 # We have a builtin version of cue2discid...
3194 case "$CUE2DISCID" in
3195 builtin);;
3196 *) NEEDCUE2DISCID=y;;
3197 esac
3198 NEEDMETAFLAC=y
3199 EJECTCD=n
3200 fi
3201
3202 # If the user provided a DISCID, disable eject
3203 if [ -n "$DISCID" ] || [ "$CDROMREADERSYNTAX" = "flac" ]; then EJECTCD=n ; fi
3204
3205 # Check the available cd rippers in the system, from the ones we know.
3206 if [ "$CDROMREADERSYNTAX" = "" ]; then
3207 for DEFAULT_CDROMREADER in $DEFAULT_CDROMREADERS; do
3208 if new_checkexec $DEFAULT_CDROMREADER; then
3209 CDROMREADERSYNTAX=$DEFAULT_CDROMREADER
3210 break
3211 fi
3212 done
3213 if [ "$CDROMREADERSYNTAX" = "" ]; then
3214 log error "no cdreader found in your PATH"
3215 log error "hints: are all dependencies installed? has the \$PATH been modified?"
3216 exit 1
3217 fi
3218 fi
3219
3220 # Decide if we can continue.
3221 if [ "$ONETRACK" = "y" ]; then
3222 # FIXME # remove check as soon as we find out about the other readers
3223 case "$CDROMREADERSYNTAX" in
3224 flac) ;;
3225 cdparanoia) ;;
3226 cdda2wav) ;;
3227 *) log error "$CDROMREADERSYNTAX does not support ONETRACK mode"
3228 exit 1 ;;
3229 esac
3230 if [ "$BATCHNORM" = "y" ]; then
3231 log warning "BATCHNORM mode is not compatible with ONETRACK mode. Disabling..."
3232 BATCHNORM=n
3233 fi
3234 if [ "$NOGAP" = "y" ]; then
3235 log warning "NOGAP mode is not compatible with ONETRACK mode. Disabling..."
3236 NOGAP=n
3237 fi
3238 # It does not matter how many tracks we want. In ONETRACK mode we grab them all
3239 # FIXME # allow ranges of tracks to be selected for onetrack ripping
3240 if [ $# -gt 0 ]; then
3241 log warning "ONETRACK mode selected, grabbing all tracks..."
3242 fi
3243 else
3244 while [ $# -gt 0 ]; do
3245 # Range parsing code courtesy of Vincent Ho
3246 RSTART=$(echo $1 | cut -f1 -d-)
3247 REND=$(echo $1 | cut -f2 -d-)
3248 if [ "$RSTART" = "$REND" ]; then
3249 NEWTRACKS="$RSTART"
3250 else
3251 NEWTRACKS=$(f_seq_line $RSTART $REND)
3252 fi
3253 TRACKQUEUE=$(echo "$TRACKQUEUE" "$NEWTRACKS")
3254 shift
3255 done
3256 fi
3257
3258 # List of valid actions: cddb,read,normalize,encode,tag,move,playlist,clean
3259 # List of experimental actions: retag,transcode
3260
3261 # Determine what actions are to be done from $ACTIONS and set the
3262 # following environment variables for them:
3263 DOCDDB=n
3264 DOREAD=n
3265 DONORMALIZE=n
3266 DOPREPROCESS=n
3267 DOENCODE=n
3268 DOPOSTPROCESS=n
3269 DOTAG=n
3270 DOMOVE=n
3271 DOREPLAYGAIN=n
3272 DOPLAYLIST=n
3273 DOCLEAN=n
3274 ## FIXME ## Lets keep compatibility with -M
3275 [ "$DOCUE" != "y" ] && DOCUE=n
3276
3277 for ACTION in $(echo $ACTIONS | tr , \ )
3278 do
3279 case $ACTION in
3280 default) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOCLEAN=y;;
3281 cue) DOCUE=y ; MAKECUEFILE=y ;;
3282 cddb) DOCDDB=y;;
3283 read) DOREAD=y;;
3284 normalize) DONORMALIZE=y; DOREAD=y;;
3285 # preprocess) DOPREPROCESS=y; DOREAD=y;;
3286 encode) DOENCODE=y; DOREAD=y;;
3287 # postprocess) DOPREPROCESS=y; DOENCODE=y; DOREAD=y;;
3288 tag) DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
3289 move) DOMOVE=y; DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
3290 replaygain) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOREPLAYGAIN=y;;
3291 playlist) DOCDDB=y; DOPLAYLIST=y;;
3292 clean) DOCLEAN=y;;
3293 esac
3294 done
3295
3296 if [ "$DONORMALIZE" = "y" ] && [ "$DOREPLAYGAIN" = "y" ]; then
3297 # FIXME # should we abort on error or just inform the user?
3298 log warning "selected both normalize and replaygain actions"
3299 fi
3300
3301 for SHOWCDDBFIELD in $(echo $SHOWCDDBFIELDS | tr , \ ); do
3302 case $SHOWCDDBFIELD in
3303 y*|Y*) SHOWCDDBYEAR="y";;
3304 g*|G*) SHOWCDDBGENRE="y";;
3305 *) ;;
3306 esac
3307 done
3308
3309 # At this point a CDROM has to be defined, so we check it exists.
3310 if [ X"$CDROM" != "X" ] ; then
3311 if [ "$CDROMREADERSYNTAX" = "cdda2wav" ] && [ "$NEEDCDROMID" = "y" ] ; then
3312 if [ "$OSFLAVOUR" = "FBSD" ]; then
3313 if echo "$CDROMID" | grep "^[0-9],[0-9],[0-9]$" >/dev/null 2>&1 ; then :; else
3314 log error "CDROMID not in the right format for $CDROMREADERSYNTAX"
3315 log error "Use \"cdrecord -scanbus\" to obtain a adecuate ID an set CDROMID accordingly"
3316 exit 1
3317 fi
3318 fi
3319 elif [ ! -e "$CDROM" -a X"$DOREAD" = "Xy" ]; then
3320 log error "CDROM device cannot be found."
3321 exit 1
3322 fi
3323 # avoid processing if we are not going to hit the CDROM.
3324 elif [ X"$DOREAD" = "Xy" ]; then
3325 log error "CDROM has not been defined or cannot be found"
3326 exit 1
3327 fi
3328
3329 # USEPIPES pre-tests, before we get into more serious stuff
3330 # Not compatible with:
3331 # - multiple outputs
3332 # - normalize
3333 # - lowdisk algorithm
3334 # - anything else?
3335 if [ X"$USEPIPES" = "Xy" ]; then
3336 if [ $(echo "$OUTPUTTYPE" | tr , \ | wc -w ) -gt 1 ]; then
3337 log error "Unix pipes not compatible with multiple outputs"
3338 exit 1
3339 fi
3340 if [ X"$DONORMALIZE" = "Xy" ]; then
3341 log error "Unix pipes not compatible with normalizer"
3342 # FIXME # Do we need to exit or shall we just disable the mode?
3343 exit 1
3344 fi
3345 if [ X"$BATCHNORM" = "Xy" ]; then
3346 log error "Unix pipes not compatible with BATCHNORM encoding"
3347 exit 1
3348 fi
3349 if [ X"$NOGAP" = "Xy" ]; then
3350 log error "Unix pipes not compatible with NOGAP encoding"
3351 exit 1
3352 fi
3353 if [ X"$DOENCODE" = "Xn" ]; then
3354 vecho warning "Disabling Unix pipes since we are not encoding!"
3355 USEPIPES=n
3356 fi
3357 if [ X"$LOWDISK" = "Xy" ]; then
3358 log error "Unix pipes not compatible with lowdisk algorithm"
3359 exit 1
3360 fi
3361 fi
3362
3363 # LOWDISK pre-tests, before we get into more problematic stuff
3364 # Not compatible with anything that needs all the files in the hard disc:
3365 # - BATCHNORM
3366 # - NOGAP lame mode
3367 if [ X"$LOWDISK" = "Xy" ]; then
3368 if [ X"$BATCHNORM" = "Xy" ]; then
3369 log error "Unix pipes not compatible with BATCHNORM encoding"
3370 exit 1
3371 fi
3372 if [ X"$NOGAP" = "Xy" ]; then
3373 log error "Unix pipes not compatible with NOGAP encoding"
3374 exit 1
3375 fi
3376 fi
3377
3378 # BATCHNORM pre-tests, before we get into serious problems
3379 # Not compatible with
3380 if [ "$BATCHNORM" = "y" ] && [ "$DONORMALIZE" = "n" ]; then
3381 vecho warning "Disabling BATCHNORM since we are not normalizing!"
3382 BATCHNORM=n
3383 fi
3384
3385 # Check the encoding format from the ones available in the system, if nothing has been configured in the system.
3386 if [ X"$OUTPUTTYPE" = "X" ]; then
3387 for DEFAULT_OUTPUT in $( echo "$DEFAULT_OUTPUT_BINARIES" | tr , \ ); do
3388 DEFAULT_OUTPUT_FORMAT="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 1)"
3389 DEFAULT_OUTPUT_BINARY="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 2)"
3390 if [ -x $(which $DEFAULT_OUTPUT_BINARY) ] ; then
3391 OUTPUTTYPE=$DEFAULT_OUTPUT_FORMAT
3392 vecho "No default output type defined. Autoselecting $OUTPUTTYPE..." >&2
3393 break
3394 fi
3395 done
3396 if [ X"$OUTPUTTYPE" = "X" ]; then
3397 log error "no encoder found in the PATH"
3398 log error "hints: are all dependencies installed? has the \$PATH been modified?"
3399 exit 1
3400 fi
3401 fi
3402
3403 # Decide which CDROM reader we're gonna use
3404 case "$CDROMREADERSYNTAX" in
3405 cdparanoia|debug)
3406 CDROMREADER="$CDPARANOIA"
3407 CDROMREADEROPTS="$CDPARANOIAOPTS"
3408 ;;
3409 cdda2wav)
3410 CDROMREADER="$CDDA2WAV"
3411 CDROMREADEROPTS="$CDDA2WAVOPTS"
3412 ;;
3413 dagrab)
3414 CDROMREADER="$DAGRAB"
3415 CDROMREADEROPTS="$DAGRABOPTS"
3416 ;;
3417 cddafs)
3418 CDROMREADER="$CDDAFS"
3419 CDROMREADEROPTS="$CDDAFSOPTS"
3420 ;;
3421 flac)
3422 CDROMREADER="$FLAC"
3423 CDROMREADEROPTS="$FLACOPTS"
3424 ;;
3425 esac
3426
3427 # There's only one normalize...
3428 case "$NORMALIZERSYNTAX" in
3429 default|normalize)
3430 NORMALIZER="$NORMALIZE"
3431 NORMALIZEROPTS="$NORMALIZEOPTS"
3432 ;;
3433 esac
3434
3435 # Allow -o OUTPUT(1):OPTIONS(1),...,OUTPUT(N):OPTIONS(N) mode of operation
3436 if echo "$OUTPUTTYPE" | grep ":" > /dev/null 2>&1 ; then
3437 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr \ \|| tr , \ | tr \| \ )"; do
3438 case "$OUTPUT" in
3439 vorbis:*|ogg:*) OGGENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3440 mp3:*) MP3ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3441 flac:*) FLACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3442 spx:*) SPEEXENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3443 mpc:*) MPPENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3444 m4a:*) AACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3445 esac
3446 done
3447 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do
3448 TEMPOUTPUT=$( echo "$OUTPUT" | cut -d: -f1 )
3449 TEMPOUTPUTTYPE="${TEMPOUTPUTTYPE:+$TEMPOUTPUTTYPE,}$TEMPOUTPUT"
3450 done
3451 OUTPUTTYPE="$TEMPOUTPUTTYPE"
3452 fi
3453
3454 # If nothing has been specified, use oggenc for oggs and lame for mp3s and flac
3455 # for flacs and speexenc for speex and mppenc for mpps and faac for m4as
3456
3457 # Getting ready for multiple output changes
3458 for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
3459 do
3460 case $OUTPUT in
3461 vorbis|ogg)
3462 [ "$OGGENCODERSYNTAX" = "default" ] && OGGENCODERSYNTAX=oggenc
3463 [ "$DOTAG" = "y" ] && NEEDCOMMENTER=y
3464 [ "$DOREPLAYGAIN" = "y" ] && NEEDVORBISGAIN=y
3465 OGGOUTPUTCONTAINER=ogg
3466 ;;
3467 mp3)
3468 [ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame
3469 [ "$DOTAG" = "y" ] && NEEDTAGGER=y
3470 [ "$DOREPLAYGAIN" = "y" ] && NEEDMP3GAIN=y
3471 ;;
3472 flac)
3473 [ "$FLACENCODERSYNTAX" = "default" ] && FLACENCODERSYNTAX=flac
3474 [ "$DOTAG" = "y" ] && NEEDMETAFLAC=y
3475 [ "$DOREPLAYGAIN" = "y" ] && NEEDMETAFLAC=y
3476 [ "$ONETRACK" = "y" ] && [ "$DOCUE" = "y" ] && NEEDMETAFLAC=y
3477 ;;
3478 spx)
3479 [ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc
3480 # [ "$DOREPLAYGAIN" = "y" ] &&
3481 ;;
3482 mpc)
3483 [ "$MPPENCODERSYNTAX" = "default" ] && MPPENCODERSYNTAX=mppenc
3484 [ "$DOREPLAYGAIN" = "y" ] && NEEDMPPGAIN=y
3485 ;;
3486 m4a)
3487 [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac
3488 ;;
3489 wav)
3490 if [ "$KEEPWAVS" = "y" ]; then
3491 vecho "Setting the KEEPWAVS option, since the resulting wav files were requested..."
3492 fi
3493 KEEPWAVS=move
3494 ;;
3495 *) log error "Invalid OUTPUTTYPE defined"
3496 exit 1
3497 ;;
3498 esac
3499 done
3500
3501 # decide which encoder
3502 case "$MP3ENCODERSYNTAX" in
3503 lame)
3504 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$LAMEOPTS}"
3505 MP3ENCODER="$LAME"
3506 ;;
3507 toolame)
3508 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$TOOLAMEOPTS}"
3509 MP3ENCODER="$TOOLAME"
3510 ;;
3511 gogo)
3512 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$GOGOOPTS}"
3513 MP3ENCODER="$GOGO"
3514 ;;
3515 bladeenc)
3516 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$BLADEENCOPTS}"
3517 MP3ENCODER="$BLADEENC"
3518 ;;
3519 l3enc)
3520 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$L3ENCOPTS}"
3521 MP3ENCODER="$L3ENC"
3522 ;;
3523 xingmp3enc)
3524 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$XINGMP3ENCOPTS}"
3525 MP3ENCODER="$XINGMP3ENC"
3526 ;;
3527 mp3enc)
3528 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$MP3ENCOPTS}"
3529 MP3ENCODER="$MP3ENC"
3530 ;;
3531 esac
3532 case "$OGGENCODERSYNTAX" in
3533 vorbize)
3534 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$VORBIZEOPTS}"
3535 OGGENCODER="$VORBIZE"
3536 ;;
3537 oggenc)
3538 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$OGGENCOPTS}"
3539 OGGENCODER="$OGGENC"
3540 ;;
3541 esac
3542 case "$FLACENCODERSYNTAX" in
3543 flac)
3544 FLACENCODEROPTS="${FLACENCODEROPTSCLI:-$FLACOPTS}"
3545 FLACENCODER="$FLAC"
3546 # FLAC streams can be encapsulated on a Ogg transport layer
3547 if echo "$FLACENCODEROPTS" | egrep -- "(^| )--ogg($| )" > /dev/null 2>&1 ;then
3548 log error "FLAC on an Ogg container is not yet supported"
3549 log error "due to problem with adding comments to such files"
3550 exit 1
3551 FLACOUTPUTCONTAINER=ogg
3552 else
3553 FLACOUTPUTCONTAINER=flac
3554 fi
3555 ;;
3556 esac
3557 case "$SPEEXENCODERSYNTAX" in
3558 speexenc)
3559 SPEEXENCODEROPTS="${SPEEXENCODEROPTSCLI:-$SPEEXENCOPTS}"
3560 SPEEXENCODER="$SPEEXENC"
3561 ;;
3562 esac
3563 case "$MPPENCODERSYNTAX" in
3564 mppenc)
3565 MPPENCODEROPTS="${MPPENCODEROPTSCLI:-$MPPENCOPTS}"
3566 MPPENCODER="$MPPENC"
3567 ;;
3568 esac
3569 case "$AACENCODERSYNTAX" in
3570 faac)
3571 AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
3572 AACENCODER="$AACENC"
3573 ;;
3574 esac
3575
3576 # and which tagger
3577 if [ "$ID3TAGV" = "1" ]; then
3578 TAGGER="$ID3"
3579 TAGGEROPTS="$ID3OPTS"
3580 else
3581 TAGGER="$ID3V2"
3582 TAGGEROPTS="$ID3V2OPTS"
3583 fi
3584
3585 # Specific for NOGAP is the use of lame. Another encoder fails...
3586 if [ "$NOGAP" = "y" ] && [ ! "$MP3ENCODER" = "lame" ]; then
3587 log warning "the NOGAP option is specific of lame. Deactivating..."
3588 NOGAP=n
3589 fi
3590
3591 # Options for mkcue
3592 case "$CUEREADERSYNTAX" in
3593 default|mkcue)
3594 CUEREADEROPTS="${CDROM}"
3595 CUEREADER="$MKCUE"
3596 ;;
3597 esac
3598
3599 # which information retrieval tool are we using?
3600 case "$CDDBTOOL" in
3601 cddb) ;;
3602 musicbrainz) ;;
3603 esac
3604
3605 # Check if both OGGEOUTPUTCONTAINER and FLACOUTPUTCONTAINER are the same, and differentiante them
3606 if [ X"$OGGOUTPUTCONTAINER" = "Xogg" ] && [ X"$FLACOUTPUTCONTAINER" = "Xogg" ]; then
3607 log error "FLAC on an Ogg container is not yet supported"
3608 log error "due to problem with adding comments to such files"
3609 exit 1
3610 OGGOUTPUTCONTAINER=ogg.ogg
3611 FLACOUTPUTCONTAINER=flac.ogg
3612 vecho warning "modified file endings due to conflicting transport layers in Ogg/Vorbis and Ogg/FLAC"
3613 fi
3614
3615 # Clean up nice options (either use '-n NICELEVEL or -NICELEVEL')
3616
3617 if [ "$ENCNICE" ]; then
3618 ENCNICE="-n $ENCNICE"
3619 fi
3620 if [ "$READNICE" ]; then
3621 READNICE="-n $READNICE"
3622 fi
3623 if [ "$DISTMP3NICE" ]; then
3624 DISTMP3NICE="-n $DISTMP3NICE"
3625 fi
3626
3627 # Don't check for stuff if it's not needed
3628 if [ "$REMOTEHOSTS" ]; then
3629 NEEDDISTMP3=y
3630 fi
3631 if [ "$DONORMALIZE" = "y" ]; then
3632 NEEDNORMALIZER=y
3633 fi
3634 if [ "$EJECTCD" = "y" ]; then
3635 NEEDEJECT=y
3636 fi
3637 if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then
3638 if [ "$CDDBMETHOD" = "cddb" ]; then
3639 NEEDHTTPGET=y
3640 elif [ "$CDDBMETHOD" = "musicbrainz" ]; then
3641 :
3642 fi
3643 fi
3644 if [ "$DOCUE" = "y" ]; then
3645 NEEDCUEREADER=y
3646 fi
3647
3648 if [ X"$CDSPEEDVALUE" != "X" ] && [ "$DOREAD" = "y" ]; then
3649 case "$CDROMREADERSYNTAX" in
3650 cdparanoia|debug) CDROMREADEROPTS="$CDPARANOIAOPTS -S $CDSPEEDVALUE" ;;
3651 ### FIXME ### translate "cue2discid" from python to bash
3652 flac) NEEDMETAFLAC=y ; NEEDCUE2DISCID=y ; CDSPEEDVALUE="" ;;
3653 *) NEEDCDSPEED=y ;;
3654 esac
3655 fi
3656
3657 ###USEPIPESSUPPORT###
3658
3659 # Rippers with USEPIPE support
3660 # FIXME # Include here all the rippers we can figure out support pipes
3661 PIPERIPPER_cdparanoia="-"
3662 PIPERIPPER_debug="-"
3663 PIPERIPPER_flac="-c "
3664
3665 # Encoders with USEPIPE support
3666 # FIXME # Include here all the encoders we can figure out support pipes
3667 PIPE_lame="-"
3668 PIPE_bladeenc="-"
3669 PIPE_oggenc="-"
3670 PIPE_flac="-"
3671
3672 # Figure out if we can use pipes with the ripper/encoder combination
3673 # exit otherwise
3674 if [ "$USEPIPES" = "y" ]; then
3675 PIPERIPPERSVARCHECK="PIPERIPPER_${CDROMREADERSYNTAX}"
3676 case "$OUTPUT" in
3677 mp3)
3678 PIPEENCODERSVARCHECK="PIPE_$MP3ENCODERSYNTAX" ;;
3679 vorbis|ogg)
3680 PIPEENCODERSVARCHECK="PIPE_$OGGENCODERSYNTAX" ;;
3681 flac)
3682 PIPEENCODERSVARCHECK="PIPE_$FLACENCODERSYNTAX" ;;
3683 spx)
3684 PIPEENCODERSVARCHECK="PIPE_$SPEEXENCODER" ;;
3685 mpc)
3686 PIPEENCODERSVARCHECK="PIPE_$MPPENCODER" ;;
3687 esac
3688 decho "PIPERIPPERSVARCHECK: $( eval echo "\$$PIPERIPPERSVARCHECK" )"
3689 if [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "$" ] || \
3690 [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "" ] ; then
3691 log error "no support for pipes with given ripper"
3692 log error "read the USEPIPES file from the source tarball to get help."
3693 log error "On a Debian system, it is under /usr/share/doc/abcde/USEPIPES.gz"
3694 exit 1;
3695 fi
3696 decho "PIPEENCODERSVARCHECK: $( eval echo "\$$PIPEENCODERSVARCHECK" )"
3697 if [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "$" ] || \
3698 [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "" ] ; then
3699 log error "no support for pipes with given encoder"
3700 log error "read the USEPIPES file from the source tarball to help"
3701 log error "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz"
3702 exit 1;
3703 fi
3704 fi
3705
3706 # Make sure a buncha things exist
3707 for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
3708 $OGGENCODER $FLACENCODER $SPEEXENCODER $MPPENCODER \
3709 $AACENCODER \
3710 ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \
3711 ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
3712 ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
3713 ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} \
3714 ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMP3GAIN+$MP3GAIN} \
3715 ${NEEDMPPGAIN+$MPPGAIN} ${NEEDCUEREADER+$CUEREADER} \
3716 ${NEEDCUE2DISCID+$CUE2DISCID}
3717 do
3718 checkexec "$X"
3719 done
3720
3721 # And last but not least, check if we can diff between files. We do not abort,
3722 # since diffing is not critical...
3723 if [ -x $(which $DIFF) ]; then :; else
3724 vecho warning "Disabling diff since we cannot find it in the \$PATH..."
3725 DIFF=""
3726 fi
3727
3728 ## Now that we have metaflac, check if we need cue2discid
3729 #case $CDROMREADERSYNTAX in
3730 # flac)
3731 # TRACKINFO=$($METAFLAC --show-tag=CDDB $CDROM | cut -d"=" -f2 | egrep "[a-f0-9]{8}")
3732 # if [ "$TRACKINFO" = "" ]; then
3733 # checkexec ${NEEDCUE2DISCID+$CUE2DISCID}
3734 # fi
3735 # ;;
3736 #esac
3737
3738 CDROMREADER="$CDROMREADER $CDROMREADEROPTS"
3739 CDDBTOOL="$CDDBTOOL $CDDBTOOLOPTS"
3740 HTTPGET="$HTTPGET $HTTPGETOPTS"
3741
3742 # Here it used to say:
3743 # One thousand lines in, we can start doing stuff with things
3744 # Well, right now we are at line 3737 ;)
3745
3746 # Export needed things so they can be read in this subshell
3747 export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS
3748 export CDROM CDDBDATA REMOTEHOSTS MAXPROCS HTTPGET MD5SUM
3749
3750 if [ "$DOREAD" = "y" ]; then
3751 # User-definable function to set some things. Use it for
3752 # - closing the CD tray with eject -t
3753 # - set the CD speed value with eject -x
3754 vecho -n "Executing customizable pre-read function... "
3755
3756 pre_read # Execute the user-defined pre-read funtion. Close the CD with it.
3757
3758 vecho "done."
3759 fi
3760
3761 case "$CDDBMETHOD" in
3762 cddb)
3763 do_discid # Get ABCDETEMPDIR created and status file initialized
3764 ;;
3765 musicbrainz)
3766 do_musicbrainz id
3767 ;;
3768 esac
3769
3770 if [ "$DOCDDB" = "y" ]; then
3771 # start with a sane default:
3772 CDDBLOCALSTATUS=notfound
3773 if [ $CDDBUSELOCAL = "y" ]; then
3774 do_localcddb
3775 fi
3776 if checkstatus cddb-choice > /dev/null; then
3777 :
3778 else
3779 if [ "$CDDBLOCALSTATUS" = "notfound" ] ; then
3780 case "$CDDBMETHOD" in
3781 cddb)
3782 do_cddbstat
3783 do_cddbquery
3784 do_cddbread
3785 ;;
3786 musicbrainz)
3787 do_musicbrainz
3788 ;;
3789 esac
3790 fi
3791 fi
3792 do_cddbedit
3793
3794 eval "$($CDDBTOOL parse "$CDDBDATA")"
3795 fi
3796
3797 # Before reading tracks, we set the speed of the device
3798
3799 if [ X"$CDSPEEDVALUE" != "X" ]; then
3800 case "$CDROMREADERSYNTAX" in
3801 cdparanoia|debug) ;;
3802 flac) ;;
3803 *) do_cdspeed ;;
3804 esac
3805 fi
3806
3807 # Define the first and last track, since we might need them later in several places
3808 FIRSTTRACK=$( get_first $TRACKQUEUE )
3809 LASTTRACK=$( get_last $TRACKQUEUE )
3810
3811 if [ -f "$ABCDETEMPDIR/status" ] && [ X"$ERASEENCODEDSTATUS" = "Xy" ]; then
3812 mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
3813 grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
3814 | grep -v ^encode-output > "$ABCDETEMPDIR/status"
3815 fi
3816
3817 if checkstatus onetrack ; then ONETRACK=y ; fi
3818
3819 if [ "$ONETRACK" = "y" ]; then
3820 # Reuse the CUEFILE in case we created it (now or in a previous run)
3821 if CUEFILE=$(checkstatus cuefile); then
3822 IMPORTCUESHEET=y
3823 fi
3824 fi
3825
3826 # Create playlist if needed (backgroundable) and start reading in tracks
3827
3828 (
3829
3830 if [ ! "$ONETRACK" = "y" ]; then
3831 if [ "$DOPLAYLIST" = "y" ]; then
3832 echo Creating playlist... >&2
3833 do_playlist
3834 fi
3835 fi
3836
3837 # For the lowdisk option, only one program is running at once so the encoder
3838 # can be unsilenced right away.
3839 if [ "$LOWDISK" = "y" ] || [ "$ONETRACK" = "y" ]; then
3840 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3841 fi
3842
3843 if [ "$ONETRACK" = "y" ]; then
3844 TRACKS="$FIRSTTRACK"
3845 if [ "$USEPIPES" = "y" ]; then
3846 if checkstatus readencodetrack-$FIRSTTRACK; then :; else
3847 do_cdread onetrack $FIRSTTRACK $LASTTRACK | do_encode $FIRSTTRACK %local0% > /dev/null 2>&1
3848 fi
3849 else
3850 if checkstatus readtrack-$FIRSTTRACK; then :; else
3851 do_cdread onetrack $FIRSTTRACK $LASTTRACK
3852 fi
3853 fi
3854 else
3855 for UTRACKNUM in $TRACKQUEUE
3856 do
3857 if [ "$DOREAD" = "y" ]; then
3858 if [ "$USEPIPES" = "y" ]; then
3859 if checkstatus readencodetrack-$UTRACKNUM; then :; else
3860 # Read, pipe, shut up!
3861 do_cdread $UTRACKNUM | do_encode $UTRACKNUM %local0% > /dev/null 2>&1
3862 fi
3863 else
3864 if checkstatus readtrack-$UTRACKNUM; then :; else
3865 do_cdread $UTRACKNUM
3866 fi
3867 if [ "$?" != "0" ]; then
3868 # CD read failed - don't give the goahead to
3869 # the encoder
3870 echo NO
3871 exit
3872 fi
3873 fi
3874 fi
3875 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ]; then
3876 :
3877 else
3878 # If we are not reading, set the encode output to loud already, so
3879 # that we can see the output of the first track.
3880 if [ "$MAXPROCS" = "1" ] && [ ! "$DOREAD" = "y" ]; then
3881 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3882 fi
3883 echo NEXTTRACK # Get the encoder machine churning again
3884 if [ "$DOREAD" = "y" ]; then
3885 if [ "$LOWDISK" = "y" ] && [ "$DOENCODE" = "y" ]; then
3886 until checkstatus encodetrack-$UTRACKNUM
3887 do
3888 if checkerrors encodetrack-$UTRACKNUM; then
3889 break
3890 fi
3891 sleep 2
3892 done
3893 fi
3894 fi
3895 fi
3896 done
3897 fi
3898
3899 # Now that we're done the encoding can be loud again -
3900 # if we're not using SMP.
3901 if [ "$MAXPROCS" = "1" ]; then
3902 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3903 fi
3904
3905 # All tracks read, start encoding.
3906 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ] || [ "$ONETRACK" = "y" ]; then
3907 echo NEXTTRACK
3908 fi
3909
3910 # Execute the user-defined post_read funtion before ejecting CD
3911 post_read
3912
3913 # We are now finished with the cdrom - it can be safely ejected. Note that
3914 # abcde will not have completed yet.
3915 if [ "$EJECTCD" = "y" ] && [ -x $(which $EJECT) ]; then
3916 # We check if the disk we are processing is actually the disk inside the
3917 # CD tray. If not, we do not eject the CD, since it might be so that the
3918 # user ejected it manually.
3919 #CURRENTTRACKINFO=$($CDDISCID $CDROM)
3920 #if if [ "$?" != "1" ] && [ "$CURRENTTRACKINFO" = "$TRACKINFO" ] ; then
3921 # More FreeBSD bits.
3922 if [ X"$(uname)" = X"FreeBSD" ] ; then
3923 # FreeBSD eject uses the EJECT environment variable to name the CDROM
3924 # but in this script EJECT is in the envionment and names the program
3925 eject=$EJECT
3926 unset EJECT
3927 # The FreeBSD eject needs "adc0" not "/dev/adc0c"
3928 cd="$(echo $CDROM | sed -e 's=.*/==;s=[a-h]$==;')"
3929 $eject $EJECTOPTS $cd
3930 elif [ X"$(uname)" = X"Darwin" ] ; then
3931 disktool -e ${CDROM#/dev/} 0
3932 else
3933 $EJECT $EJECTOPTS "$CDROM"
3934 fi
3935 #fi
3936 fi
3937
3938 ) | (
3939
3940 ## Do we need to pre-process
3941 #if [ x"$PREPROCESS" = "x" ] ; then
3942 # cat
3943 #else
3944 # for PRETRACKNUM in $TRACKQUEUE
3945 # do
3946 # read GOAHEAD
3947 # if [ "$GOAHEAD" = "NO" ]; then break; fi
3948 # PREPROCEED=
3949 # until [ $PREPROCEED ]
3950 # do
3951 # if checkstatus readtrack-$PRETRACKNUM; then PREPROCEED=y; break; fi
3952 # # all locations are working, wait and try again later
3953 # if [ ! $PREPROCEED ]; then sleep 3; fi
3954 # done
3955 # ( do_preprocess $PRETRACKNUM
3956 # echo "NEXTTRACK"
3957 # ) &
3958 # done
3959 #fi
3960 #
3961 #) | (
3962
3963 # In BATCHNORM and/or NOGAP modes, we want all tracks to be read first.
3964 #BACK
3965 if [ "$BATCHNORM" = "y" ] || [ "$NOGAP" = "y" ]; then
3966 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
3967 if [ "$GOAHEAD" = "NO" ]; then break; fi
3968 for LASTTRACK in $TRACKQUEUE; do :; done
3969 if checkstatus readtrack-$LASTTRACK; then
3970 if [ "$DONORMALIZE" = "y" ] && [ "$BATCHNORM" = "y" ]; then
3971 if checkstatus normalizetrack-$LASTTRACK; then :; else do_batch_normalize; fi
3972 if checkerrors batch-normalize; then exit 1; fi
3973 fi
3974 if [ "$DOENCODE" = "y" ] && [ "$NOGAP" = "y" ]; then
3975 if [ "$DONORMALIZE" = "y" ]; then
3976 for UTRACKNUM in $TRACKQUEUE
3977 do
3978 if checkstatus readtrack-$UTRACKNUM; then
3979 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
3980 fi
3981 done
3982 fi
3983 if checkstatus encodetrack-$LASTTRACK; then :; else do_nogap_encode; fi
3984 if checkerrors nogap-encode; then exit 1; fi
3985 fi
3986 fi
3987 fi
3988
3989 # If we are using ONETRACK, we can proceed with the normal encoding using just the $FIRSTTRACK as TRACKQUEUE
3990 if [ "$ONETRACK" = "y" ] ; then
3991 TRACKQUEUE="$FIRSTTRACK"
3992 TRACKS="$FIRSTTRACK"
3993 fi
3994
3995 # Do the encoding, including parallelization of remote encoding
3996 # Figure out where each track is going to be encoded
3997 ENCODELOCATIONS="$(echo $REMOTEHOSTS | tr , ' ')"
3998 if [ "$MAXPROCS" != "0" ]; then
3999 for NUM in $(f_seq_row 1 "$MAXPROCS")
4000 do
4001 ENCODELOCATIONS="$ENCODELOCATIONS %local$NUM%"
4002 done
4003 fi
4004 # Strip whitespace
4005 ENCODELOCATIONS=$(echo $ENCODELOCATIONS)
4006 for UTRACKNUM in $TRACKQUEUE
4007 do
4008 # Wait for our cue
4009 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
4010 if [ "$GOAHEAD" = "NO" ]; then break; fi
4011 # find out where this track is to be encoded
4012 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
4013 # Make sure we have a place to encode this, if not, exit stage right
4014 if [ -z "$ENCODELOCATIONS" ]; then
4015 continue
4016 fi
4017 PROCEED=
4018 until [ $PROCEED ]
4019 do
4020 for LOCATION in $ENCODELOCATIONS
4021 do
4022 PREVIOUSTRACK="$(checkstatus encodetracklocation-$LOCATION)"
4023 # check first if a track has ever been assigned to this location
4024 if [ -z "$PREVIOUSTRACK" ]; then PROCEED=y; break; fi
4025 # If it errored out, rebuild $ENCODELOCATIONS without this location in it
4026 if checkerrors encodetrack-$PREVIOUSTRACK; then
4027 for TEMPLOCATION in $ENCODELOCATIONS
4028 do
4029 if [ "$TEMPLOCATION" != "$LOCATION" ]; then
4030 TEMPENCODELOCATIONS="$TEMPENCODELOCATIONS $TEMPLOCATION"
4031 fi
4032 done
4033 ENCODELOCATIONS=$(echo $TEMPENCODELOCATIONS)
4034 ABORT=y
4035 PROCEED=y
4036 break
4037 fi
4038 # We're still here, this location must have been previously assigned,
4039 # and last completed without error - check if it's done with the
4040 # previous track yet
4041 if checkstatus encodetrack-$PREVIOUSTRACK; then PROCEED=y; break; fi
4042 done
4043 # all locations are working, wait and try again later
4044 if [ ! $PROCEED ]; then sleep 3; fi
4045 done
4046 # Record the location we're about to encode the next track at
4047 echo "encodetracklocation-$LOCATION=$UTRACKNUM" >> "$ABCDETEMPDIR/status"
4048 fi
4049 # Don't proceed with the rest of the loop if we can't encode
4050 if [ "$ABORT" ]; then continue; fi
4051 ## FIXME ## Add here
4052 ## run_command tagtrack-$OUTPUT-$1 $METAFLAC $METAFLACOPTS ${IMPORTCUESHEET:+--import-cuesheet-from="$ABCDETEMPDIR/$CUEFILE"} --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
4053 # Set TRACKNUM, TRACKNAME
4054 if [ -e "$CDDBDATA" ]; then
4055 if [ "$ONETRACK" = "y" ]; then
4056 TRACKNAME="$DALBUM"
4057 TRACKNUM="$FIRSTTRACK"
4058 splitvarious
4059 else
4060 TRACKNUM=$UTRACKNUM
4061 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
4062 getcddbinfo TRACKNAME
4063 splitvarious
4064 fi
4065 fi
4066 # You can't encode a file which needs to be normalized before finishing
4067 # You can't tag a file before it's finished encoding -
4068 # thus all of this is backgrounded together
4069 (
4070 if [ "$DONORMALIZE" = "y" ]; then
4071 if checkstatus readtrack-$UTRACKNUM; then
4072 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
4073 fi
4074 fi
4075 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
4076 if checkstatus readtrack-$UTRACKNUM; then
4077 #if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION; fi
4078 if [ "$DONORMALIZE" = "y" ]; then
4079 if checkstatus normalizetrack-$UTRACKNUM; then
4080 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
4081 fi
4082 else
4083 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
4084 fi
4085 fi
4086 fi
4087 if [ "$DOTAG" = "y" ]; then
4088 if checkstatus encodetrack-$UTRACKNUM; then
4089 if checkstatus tagtrack-$UTRACKNUM; then :; else do_tag $UTRACKNUM; fi
4090 fi
4091 # Lets tag the cue file
4092 if checkstatus cleancuefile >/dev/null; then :; else
4093 if checkstatus cuefile >/dev/null ; then
4094 do_cleancue
4095 fi
4096 fi
4097 fi
4098 if [ "$DOMOVE" = "y" ]; then
4099 if checkstatus tagtrack-$UTRACKNUM; then
4100 if checkstatus movetrack-$UTRACKNUM; then :; else do_move $UTRACKNUM; fi
4101 fi
4102 fi
4103 ) &
4104 done
4105
4106
4107 # Go through it again and make sure there's no distmp3 stragglers, otherwise
4108 # we'll delete the files they're working on
4109 # Do NOT play ball if there is no ball to play (so ABORT if needed)
4110 ## FIXME ## Check also for files which are encoded using PIPEs.
4111 if [ "$DOENCODE" = "y" ] && [ "$USEPIPES" != "y" ] && [ ! "$ABORT" ]; then
4112 PROCEED=
4113 until [ $PROCEED ]
4114 do
4115 PROCEED=y
4116 for LOCATION in $ENCODELOCATIONS
4117 do
4118 CHECKTRACK="$(checkstatus encodetracklocation-$LOCATION)"
4119 # "How can he give us a status update, if he's DEAD?"
4120 if checkstatus encodetrack-$CHECKTRACK; then
4121 continue
4122 fi
4123 # Nothing to see here please go quietly back to your homes
4124 if [ -z "$CHECKTRACK" ]; then continue; fi
4125 # You're still here? Maybe there is something...
4126 if checkstatus encodetrack-$CHECKTRACK; then :; else PROCEED= ; break; fi
4127 done
4128 # hold up
4129 if [ ! $PROCEED ]; then sleep 5; fi
4130 done
4131 fi
4132 # If the above didn't catch the stragglers, this will
4133 wait
4134 if [ "$DOREPLAYGAIN" = "y" ]; then
4135 do_replaygain
4136 fi
4137
4138 # Check to see if run_command logged any errors
4139 if [ -f "$ABCDETEMPDIR/errors" ]; then
4140 log error "The following commands failed to run:"
4141 cat "$ABCDETEMPDIR/errors"
4142 # Don't clean up
4143 DOCLEAN=n
4144 fi
4145 if [ "$KEEPWAVS" = "y" ];then
4146 # Don't clean up
4147 DOCLEAN=n
4148 fi
4149 # Check if we have moved all the formats we had previously encoded, if we are not using the FORCE.
4150 if [ "$DOCLEAN" = "y" ] && [ ! "$FORCE" = "y" ]; then
4151 ENCODED_FORMATS=$(egrep "^encodetrack-(.{3,6})-(.{1,2})$" "$ABCDETEMPDIR/status" | cut -d"-" -f2 | sort -u | tr '\n' '|')
4152 MOVED_FORMATS=$(egrep "^movetrack-output-(.{3,6})$" "$ABCDETEMPDIR/status" | cut -d"-" -f3 | sort -u | tr '\n' '|')
4153 if [ "$ENCODED_FORMATS" != "$MOVED_FORMATS" ]; then
4154 log warning "The encoded formats does not match with the moved ones"
4155 log warning "Formats encoded: $( echo $ENCODED_FORMATS | tr "|" " " )"
4156 log warning "Formats moved: $( echo $MOVED_FORMATS | tr "|" " " )"
4157 log warning "Use \"abcde -a clean -f -C $DISCID\" to force the removal of the remaining data."
4158 DOCLEAN=n
4159 fi
4160 fi
4161 if [ "$DOCLEAN" = "y" ]; then
4162 # Wipe all the evidence
4163 # Gimme gimme gimme some more time!
4164 sleep 5
4165 rm -rf "$ABCDETEMPDIR"
4166 echo "Finished."
4167 else
4168 echo "Finished. Not cleaning $ABCDETEMPDIR."
4169 fi
4170 )
4171 exit 0
4172
4173 # b:is_bash
4174 # vim:tabstop=4