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