Small changes
[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 VORBISCOMMENT=vorbiscomment
2961 METAFLAC=metaflac
2962 AACTAG=faac
2963
2964 CDPARANOIA=cdparanoia
2965 CDDA2WAV=cdda2wav
2966 DAGRAB=dagrab
2967 CDDAFS=cp
2968 CDDISCID=cd-discid
2969 CDDBTOOL=cddb-tool
2970 MUSICBRAINZ=musicbrainz-get-tracks
2971 EJECT=eject
2972 MD5SUM=md5sum
2973 DISTMP3=distmp3
2974 NORMALIZE=normalize-audio
2975 CDSPEED=eject
2976 VORBISGAIN=vorbisgain
2977 MP3GAIN=mp3gain
2978 MPPGAIN=replaygain
2979 MKCUE=mkcue
2980 MKTOC=cdrdao
2981 DIFF=diff
2982 CUE2DISCID=builtin
2983
2984 # Options for programs called from abcde
2985 # mp3
2986 LAMEOPTS=
2987 TOOLAMEOPTS=
2988 GOGOOPTS=
2989 BLADEENCOPTS=
2990 L3ENCOPTS=
2991 XINGMP3ENCOPTS=
2992 MP3ENCOPTS=
2993 # ogg
2994 VORBIZEOPTS=
2995 OGGENCOPTS=
2996 # flac
2997 FLACOPTS=
2998 # speex
2999 SPEEXENCOPTS=
3000 # mpc
3001 MPPENCOPTS=
3002 # m4a
3003 AACENCOPTS=
3004
3005 ID3OPTS=
3006 ID3V2OPTS=
3007 CDPARANOIAOPTS=
3008 CDDA2WAVOPTS=
3009 DAGRABOPTS=
3010 CDDAFSOPTS="-f"
3011 CDDBTOOLOPTS=
3012 EJECTOPTS=
3013 DISTMP3OPTS=
3014 NORMALIZEOPTS=
3015 CDSPEEDOPTS="-x"
3016 CDSPEEDVALUE=
3017 MKCUEOPTS=
3018 MKTOCOPTS=""
3019 VORBISCOMMENTOPTS="-R"
3020 METAFLACOPTS="--no-utf8-convert"
3021 DIFFOPTS=
3022
3023 # Default to one process if -j isn't specified
3024 MAXPROCS=1
3025
3026 # List of actions to perform - by default, run to completion
3027 ACTIONS=cddb,read,encode,tag,move,clean
3028
3029 # This option is basicaly for Debian package dependencies:
3030 # List of prefered outputs - by default, run with whatever we have in the path
3031 DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:toolame,mp3:lame,mp3:bladeenc,spx:speex,m4a:faac
3032
3033 # List of prefered cdromreaders - by default, run whichever we have in the path
3034 DEFAULT_CDROMREADERS="cdparanoia cdda2wav"
3035
3036 # List of quality levels associated with the encoders:
3037 DEFAULT_QUALITY_XLO="oggenc:-q -1,lame:-q 9,speex:--quality 1,m4a:"
3038 DEFAULT_QUALITY_LO="oggenc:-q 1,lame:-q 7,speex:--quality 5,m4a:"
3039 DEFAULT_QUALITY_HI="oggenc:-q 7,lame:--preset standard,speex:--quality 9,m4a:"
3040 DEFAULT_QUALITY_XHI="oggenc:-q 10,lame:--preset extreme,speex:--quality 10,m4a:"
3041
3042 # Asume fetch if under FreeBSD. curl is used for Mac OS X. wget is used for
3043 # Linux/OpenBSD. ftp is user for NetBSD.
3044 # Let's use these checkings to determine the OS flavour, which will be used
3045 # later
3046 if [ X$(uname) = "XFreeBSD" ] ; then
3047 HTTPGET=fetch
3048 MD5SUM=md5
3049 NEEDCDROMID=y
3050 OSFLAVOUR=FBSD
3051 elif [ X$(uname) = "XDarwin" ] ; then
3052 HTTPGET=curl
3053 OSFLAVOUR=OSX
3054 # We should have disktool in OSX, but let's be sure...
3055 NEEDDISKTOOL=y
3056 CDROMREADERSYNTAX=cddafs
3057 elif [ X$(uname) = "XOpenBSD" ] ; then
3058 HTTPGET=wget
3059 MD5SUM=md5
3060 OSFLAVOUR=OBSD
3061 elif [ X$(uname) = "XNetBSD" ] ; then
3062 HTTPGET=ftp
3063 MD5SUM=md5
3064 OSFLAVOUR=NBSD
3065 elif [ X$(uname) = "SunOS" ] ; then
3066 HTTPGET=""
3067 MD5SUM=md5
3068 OSFLAVOUR=SunOS
3069 else
3070 HTTPGET=wget
3071 fi
3072
3073 # If CDDBAVAIL is set to n, no CDDB read is done
3074 # If USEID3 is set to n, no ID3 tagging is done
3075 CDDBAVAIL=y
3076 USEID3=y
3077 USEID3V2=y
3078
3079 # There we go..
3080 # But before we get into business, let us chop off any GREP environmental
3081 # variables.
3082 GREP_OPTIONS=""
3083 GREP_COLOR=""
3084
3085 if [ -z "$OUTPUTDIR" ]; then
3086 OUTPUTDIR=$(pwd)
3087 fi
3088
3089 if [ -z "$WAVOUTPUTDIR" ]; then
3090 WAVOUTPUTDIR="$OUTPUTDIR"
3091 fi
3092
3093 # Load system defaults
3094 if [ -r /etc/abcde.conf ]; then
3095 . /etc/abcde.conf
3096 fi
3097 # Load user preference defaults
3098 if [ -r $HOME/.abcde.conf ]; then
3099 . $HOME/.abcde.conf
3100 fi
3101
3102 # By this time, we need some HTTPGETOPTS already defined.
3103 # If the user has defined a non-default HTTPGET method, we should not be empty.
3104
3105 if [ "$HTTPGETOPTS" = "" ] ; then
3106 case $HTTPGET in
3107 wget) HTTPGETOPTS="-q -nv -O -";;
3108 curl) HTTPGETOPTS="-f -s";;
3109 fetch)HTTPGETOPTS="-q -o -";;
3110 ftp) HTTPGETOPTS="-a -V -o - ";;
3111 *) log warning "HTTPGET in non-standard and HTTPGETOPTS are not defined." ;;
3112 esac
3113 fi
3114
3115 # If the CDROM has not been set yet, find a suitable one.
3116 # If this is a devfs system, default to /dev/cdroms/cdrom0
3117 # instead of /dev/cdrom
3118 if [ "$CDROM" = "" ] ; then
3119 if [ -e /dev/cdroms/cdrom0 ]; then
3120 CDROM=/dev/cdroms/cdrom0
3121 elif [ -e /dev/cdrom ]; then
3122 CDROM=/dev/cdrom
3123 elif [ -e /dev/cd0c ]; then
3124 CDROM=/dev/cd0c
3125 elif [ -e /dev/acd0c ]; then
3126 CDROM=/dev/acd0c
3127 elif [ -e /dev/disk1 ]; then
3128 CDROM=/dev/disk1
3129 fi
3130 fi
3131
3132 # Parse command line options
3133 #while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPq:r:Rs:S:t:T:vVxw:W: opt ; do
3134 while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:UvVxX:w:W:z opt ; do
3135 case "$opt" in
3136 1) ONETRACK=y ;;
3137 a) ACTIONS="$OPTARG" ;;
3138 A) EXPACTIONS="$OPTARG" ;;
3139 b) BATCHNORM=y ;;
3140 B) NOBATCHREPLAYGAIN=y ;;
3141 c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else log error "config file \"$OPTARG\" cannot be found." ; exit 1 ; fi ;;
3142 C) DISCID="$( echo ${OPTARG#abcde.} | tr -d /)" ;;
3143 d) CDROM="$OPTARG" ;;
3144 D) set -x ;;
3145 h) usage; exit ;;
3146 e) ERASEENCODEDSTATUS=y ;;
3147 E) ENCODING="$OPTARG" ;;
3148 f) FORCE=y ;;
3149 g) NOGAP=y ;;
3150 i) INLINETAG=y ;;
3151 j) MAXPROCS="$OPTARG" ;;
3152 k) KEEPWAVS=y ;;
3153 l) LOWDISK=y ;;
3154 L) CDDBUSELOCAL=y ;;
3155 n) CDDBAVAIL=n ;;
3156 N) INTERACTIVE=n ;;
3157 m) DOSPLAYLIST=y ;;
3158 M) DOCUE=y ;;
3159 o) OUTPUTTYPE="$OPTARG" ;;
3160 p) PADTRACKS=y ;;
3161 P) USEPIPES=y ;;
3162 q) QUALITYLEVEL="$OPTARG" ;;
3163 r) REMOTEHOSTS="$OPTARG" ;;
3164 R) CDDBLOCALRECURSIVE=y ;;
3165 s) SHOWCDDBFIELDS="$OPTARG" ;;
3166 S) CDSPEEDVALUE="$OPTARG" ;;
3167 t) STARTTRACKNUMBER="$OPTARG" ;;
3168 T) STARTTRACKNUMBER="$OPTARG" ; STARTTRACKNUMBERTAG="y" ;;
3169 U) CDDBPROTO=5 ;;
3170 v)
3171 echo "This is abcde v$VERSION."
3172 echo "Usage: abcde [options] [tracks]"
3173 echo "abcde -h for extra help"
3174 exit
3175 ;;
3176 V) EXTRAVERBOSE="y" ;;
3177 x) EJECTCD="y" ;;
3178 X) CUE2DISCID="$OPTARG" ;;
3179 w) COMMENT="$OPTARG" ;;
3180 W) if echo $OPTARG | grep "[[:digit:]]" > /dev/null 2>&1 ; then
3181 STARTTRACKNUMBER="${OPTARG}01"
3182 STARTTRACKNUMBERTAG="y"
3183 COMMENT="CD${OPTARG}"
3184 DISCNUMBER="${OPTARG}"
3185 else
3186 log error "argument of -W must be integer"
3187 exit 1
3188 fi
3189 ;;
3190 z) DEBUG=y ; CDROMREADERSYNTAX=debug ; EJECTCD="n" ;;
3191 ?) usage; exit ;;
3192 esac
3193 done
3194
3195 shift $(($OPTIND - 1))
3196
3197 # Here it comes the worse part of the whole thing. From here until we start
3198 # ripping, we have a mixture of sanity checks, verifications, default settigs
3199 # and other crazy stuff that interdepends, but hey, someone has to do it.
3200
3201 # If NOCDDBQUERY is set, don't query the CDDB server.
3202 if [ "$NOCDDBQUERY" = "y" ]; then
3203 CDDBAVAIL="n"
3204 fi
3205
3206 # If the user specified a flac file, then switch to special flac mode
3207 if echo "$CDROM" | grep -i '.flac$' > /dev/null 2>&1 ; then
3208 if [ ! -f "$CDROM" ]; then
3209 log error "the defined file for FLAC ripping cannot be found" >&2
3210 exit 1
3211 fi
3212 vecho warning "switching to flac CDROMREADERSYNTAX..."
3213 CDROMREADERSYNTAX=flac
3214 # We have a builtin version of cue2discid...
3215 case "$CUE2DISCID" in
3216 builtin);;
3217 *) NEEDCUE2DISCID=y;;
3218 esac
3219 NEEDMETAFLAC=y
3220 EJECTCD=n
3221 fi
3222
3223 # If the user provided a DISCID, disable eject
3224 if [ -n "$DISCID" ] || [ "$CDROMREADERSYNTAX" = "flac" ]; then EJECTCD=n ; fi
3225
3226 # Check the available cd rippers in the system, from the ones we know.
3227 if [ "$CDROMREADERSYNTAX" = "" ]; then
3228 for DEFAULT_CDROMREADER in $DEFAULT_CDROMREADERS; do
3229 if new_checkexec $DEFAULT_CDROMREADER; then
3230 CDROMREADERSYNTAX=$DEFAULT_CDROMREADER
3231 break
3232 fi
3233 done
3234 if [ "$CDROMREADERSYNTAX" = "" ]; then
3235 log error "no cdreader found in your PATH"
3236 log error "hints: are all dependencies installed? has the \$PATH been modified?"
3237 exit 1
3238 fi
3239 fi
3240
3241 # Decide if we can continue.
3242 if [ "$ONETRACK" = "y" ]; then
3243 # FIXME # remove check as soon as we find out about the other readers
3244 case "$CDROMREADERSYNTAX" in
3245 flac) ;;
3246 cdparanoia) ;;
3247 cdda2wav) ;;
3248 *) log error "$CDROMREADERSYNTAX does not support ONETRACK mode"
3249 exit 1 ;;
3250 esac
3251 if [ "$BATCHNORM" = "y" ]; then
3252 log warning "BATCHNORM mode is not compatible with ONETRACK mode. Disabling..."
3253 BATCHNORM=n
3254 fi
3255 if [ "$NOGAP" = "y" ]; then
3256 log warning "NOGAP mode is not compatible with ONETRACK mode. Disabling..."
3257 NOGAP=n
3258 fi
3259 # It does not matter how many tracks we want. In ONETRACK mode we grab them all
3260 # FIXME # allow ranges of tracks to be selected for onetrack ripping
3261 if [ $# -gt 0 ]; then
3262 log warning "ONETRACK mode selected, grabbing all tracks..."
3263 fi
3264 else
3265 while [ $# -gt 0 ]; do
3266 # Range parsing code courtesy of Vincent Ho
3267 RSTART=$(echo $1 | cut -f1 -d-)
3268 REND=$(echo $1 | cut -f2 -d-)
3269 if [ "$RSTART" = "$REND" ]; then
3270 NEWTRACKS="$RSTART"
3271 else
3272 NEWTRACKS=$(f_seq_line $RSTART $REND)
3273 fi
3274 TRACKQUEUE=$(echo "$TRACKQUEUE" "$NEWTRACKS")
3275 shift
3276 done
3277 fi
3278
3279 # List of valid actions: cddb,read,normalize,encode,tag,move,playlist,clean
3280 # List of experimental actions: retag,transcode
3281
3282 # Determine what actions are to be done from $ACTIONS and set the
3283 # following environment variables for them:
3284 DOCDDB=n
3285 DOREAD=n
3286 DONORMALIZE=n
3287 DOPREPROCESS=n
3288 DOENCODE=n
3289 DOPOSTPROCESS=n
3290 DOTAG=n
3291 DOMOVE=n
3292 DOREPLAYGAIN=n
3293 DOPLAYLIST=n
3294 DOCLEAN=n
3295 ## FIXME ## Lets keep compatibility with -M
3296 [ "$DOCUE" != "y" ] && DOCUE=n
3297
3298 for ACTION in $(echo $ACTIONS | tr , \ )
3299 do
3300 case $ACTION in
3301 default) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOCLEAN=y;;
3302 cue) DOCUE=y ; MAKECUEFILE=y ;;
3303 cddb) DOCDDB=y;;
3304 read) DOREAD=y;;
3305 normalize) DONORMALIZE=y; DOREAD=y;;
3306 # preprocess) DOPREPROCESS=y; DOREAD=y;;
3307 encode) DOENCODE=y; DOREAD=y;;
3308 # postprocess) DOPREPROCESS=y; DOENCODE=y; DOREAD=y;;
3309 tag) DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
3310 move) DOMOVE=y; DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
3311 replaygain) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOREPLAYGAIN=y;;
3312 playlist) DOCDDB=y; DOPLAYLIST=y;;
3313 clean) DOCLEAN=y;;
3314 esac
3315 done
3316
3317 if [ "$DONORMALIZE" = "y" ] && [ "$DOREPLAYGAIN" = "y" ]; then
3318 # FIXME # should we abort on error or just inform the user?
3319 log warning "selected both normalize and replaygain actions"
3320 fi
3321
3322 for SHOWCDDBFIELD in $(echo $SHOWCDDBFIELDS | tr , \ ); do
3323 case $SHOWCDDBFIELD in
3324 y*|Y*) SHOWCDDBYEAR="y";;
3325 g*|G*) SHOWCDDBGENRE="y";;
3326 *) ;;
3327 esac
3328 done
3329
3330 # At this point a CDROM has to be defined, so we check it exists.
3331 if [ X"$CDROM" != "X" ] ; then
3332 if [ "$CDROMREADERSYNTAX" = "cdda2wav" ] && [ "$NEEDCDROMID" = "y" ] ; then
3333 if [ "$OSFLAVOUR" = "FBSD" ]; then
3334 if echo "$CDROMID" | grep "^[0-9],[0-9],[0-9]$" >/dev/null 2>&1 ; then :; else
3335 log error "CDROMID not in the right format for $CDROMREADERSYNTAX"
3336 log error "Use \"cdrecord -scanbus\" to obtain a adecuate ID an set CDROMID accordingly"
3337 exit 1
3338 fi
3339 fi
3340 elif [ ! -e "$CDROM" -a X"$DOREAD" = "Xy" ]; then
3341 log error "CDROM device cannot be found."
3342 exit 1
3343 fi
3344 # avoid processing if we are not going to hit the CDROM.
3345 elif [ X"$DOREAD" = "Xy" ]; then
3346 log error "CDROM has not been defined or cannot be found"
3347 exit 1
3348 fi
3349
3350 # USEPIPES pre-tests, before we get into more serious stuff
3351 # Not compatible with:
3352 # - multiple outputs
3353 # - normalize
3354 # - lowdisk algorithm
3355 # - anything else?
3356 if [ X"$USEPIPES" = "Xy" ]; then
3357 if [ $(echo "$OUTPUTTYPE" | tr , \ | wc -w ) -gt 1 ]; then
3358 log error "Unix pipes not compatible with multiple outputs"
3359 exit 1
3360 fi
3361 if [ X"$DONORMALIZE" = "Xy" ]; then
3362 log error "Unix pipes not compatible with normalizer"
3363 # FIXME # Do we need to exit or shall we just disable the mode?
3364 exit 1
3365 fi
3366 if [ X"$BATCHNORM" = "Xy" ]; then
3367 log error "Unix pipes not compatible with BATCHNORM encoding"
3368 exit 1
3369 fi
3370 if [ X"$NOGAP" = "Xy" ]; then
3371 log error "Unix pipes not compatible with NOGAP encoding"
3372 exit 1
3373 fi
3374 if [ X"$DOENCODE" = "Xn" ]; then
3375 vecho warning "Disabling Unix pipes since we are not encoding!"
3376 USEPIPES=n
3377 fi
3378 if [ X"$LOWDISK" = "Xy" ]; then
3379 log error "Unix pipes not compatible with lowdisk algorithm"
3380 exit 1
3381 fi
3382 fi
3383
3384 # LOWDISK pre-tests, before we get into more problematic stuff
3385 # Not compatible with anything that needs all the files in the hard disc:
3386 # - BATCHNORM
3387 # - NOGAP lame mode
3388 if [ X"$LOWDISK" = "Xy" ]; then
3389 if [ X"$BATCHNORM" = "Xy" ]; then
3390 log error "Unix pipes not compatible with BATCHNORM encoding"
3391 exit 1
3392 fi
3393 if [ X"$NOGAP" = "Xy" ]; then
3394 log error "Unix pipes not compatible with NOGAP encoding"
3395 exit 1
3396 fi
3397 fi
3398
3399 # BATCHNORM pre-tests, before we get into serious problems
3400 # Not compatible with
3401 if [ "$BATCHNORM" = "y" ] && [ "$DONORMALIZE" = "n" ]; then
3402 vecho warning "Disabling BATCHNORM since we are not normalizing!"
3403 BATCHNORM=n
3404 fi
3405
3406 # Check the encoding format from the ones available in the system, if nothing has been configured.
3407 if [ X"$OUTPUTTYPE" = "X" ]; then
3408 for DEFAULT_OUTPUT in $( echo "$DEFAULT_OUTPUT_BINARIES" | tr , \ ); do
3409 DEFAULT_OUTPUT_FORMAT="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 1)"
3410 DEFAULT_OUTPUT_BINARY="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 2)"
3411 if [ -x $(which $DEFAULT_OUTPUT_BINARY) ] ; then
3412 OUTPUTTYPE=$DEFAULT_OUTPUT_FORMAT
3413 vecho "No default output type defined. Autoselecting $OUTPUTTYPE..." >&2
3414 break
3415 fi
3416 done
3417 if [ X"$OUTPUTTYPE" = "X" ]; then
3418 log error "no encoder found in the PATH"
3419 log error "hints: are all dependencies installed? has the \$PATH been modified?"
3420 exit 1
3421 fi
3422 fi
3423
3424 # Decide which CDROM reader we're gonna use
3425 case "$CDROMREADERSYNTAX" in
3426 cdparanoia|debug)
3427 CDROMREADER="$CDPARANOIA"
3428 CDROMREADEROPTS="$CDPARANOIAOPTS"
3429 ;;
3430 cdda2wav)
3431 CDROMREADER="$CDDA2WAV"
3432 CDROMREADEROPTS="$CDDA2WAVOPTS"
3433 ;;
3434 dagrab)
3435 CDROMREADER="$DAGRAB"
3436 CDROMREADEROPTS="$DAGRABOPTS"
3437 ;;
3438 cddafs)
3439 CDROMREADER="$CDDAFS"
3440 CDROMREADEROPTS="$CDDAFSOPTS"
3441 ;;
3442 flac)
3443 CDROMREADER="$FLAC"
3444 CDROMREADEROPTS="$FLACOPTS"
3445 ;;
3446 esac
3447
3448 # There's only one normalize...
3449 case "$NORMALIZERSYNTAX" in
3450 default|normalize)
3451 NORMALIZER="$NORMALIZE"
3452 NORMALIZEROPTS="$NORMALIZEOPTS"
3453 ;;
3454 esac
3455
3456 # Allow -o OUTPUT(1):OPTIONS(1),...,OUTPUT(N):OPTIONS(N) mode of operation
3457 if echo "$OUTPUTTYPE" | grep ":" > /dev/null 2>&1 ; then
3458 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr \ \|| tr , \ | tr \| \ )"; do
3459 case "$OUTPUT" in
3460 vorbis:*|ogg:*) OGGENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3461 mp3:*) MP3ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3462 flac:*) FLACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3463 spx:*) SPEEXENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3464 mpc:*) MPPENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3465 m4a:*) AACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3466 esac
3467 done
3468 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do
3469 TEMPOUTPUT=$( echo "$OUTPUT" | cut -d: -f1 )
3470 TEMPOUTPUTTYPE="${TEMPOUTPUTTYPE:+$TEMPOUTPUTTYPE,}$TEMPOUTPUT"
3471 done
3472 OUTPUTTYPE="$TEMPOUTPUTTYPE"
3473 fi
3474
3475 # If nothing has been specified, use oggenc for oggs and lame for mp3s and flac
3476 # for flacs and speexenc for speex and mppenc for mpps and faac for m4as
3477
3478 # Getting ready for multiple output changes
3479 for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
3480 do
3481 case $OUTPUT in
3482 vorbis|ogg)
3483 [ "$OGGENCODERSYNTAX" = "default" ] && OGGENCODERSYNTAX=oggenc
3484 [ "$DOTAG" = "y" ] && NEEDCOMMENTER=y
3485 [ "$DOREPLAYGAIN" = "y" ] && NEEDVORBISGAIN=y
3486 OGGOUTPUTCONTAINER=ogg
3487 ;;
3488 mp3)
3489 [ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame
3490 [ "$DOTAG" = "y" ] && NEEDTAGGER=y
3491 [ "$DOREPLAYGAIN" = "y" ] && NEEDMP3GAIN=y
3492 ;;
3493 flac)
3494 [ "$FLACENCODERSYNTAX" = "default" ] && FLACENCODERSYNTAX=flac
3495 [ "$DOTAG" = "y" ] && NEEDMETAFLAC=y
3496 [ "$DOREPLAYGAIN" = "y" ] && NEEDMETAFLAC=y
3497 [ "$ONETRACK" = "y" ] && [ "$DOCUE" = "y" ] && NEEDMETAFLAC=y
3498 ;;
3499 spx)
3500 [ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc
3501 # [ "$DOREPLAYGAIN" = "y" ] &&
3502 ;;
3503 mpc)
3504 [ "$MPPENCODERSYNTAX" = "default" ] && MPPENCODERSYNTAX=mppenc
3505 [ "$DOREPLAYGAIN" = "y" ] && NEEDMPPGAIN=y
3506 ;;
3507 m4a)
3508 [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac
3509 ;;
3510 wav)
3511 if [ "$KEEPWAVS" = "y" ]; then
3512 vecho "Setting the KEEPWAVS option, since the resulting wav files were requested..."
3513 fi
3514 KEEPWAVS=move
3515 ;;
3516 *) log error "Invalid OUTPUTTYPE defined"
3517 exit 1
3518 ;;
3519 esac
3520 done
3521
3522 # decide which encoder
3523 case "$MP3ENCODERSYNTAX" in
3524 lame)
3525 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$LAMEOPTS}"
3526 MP3ENCODER="$LAME"
3527 ;;
3528 toolame)
3529 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$TOOLAMEOPTS}"
3530 MP3ENCODER="$TOOLAME"
3531 ;;
3532 gogo)
3533 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$GOGOOPTS}"
3534 MP3ENCODER="$GOGO"
3535 ;;
3536 bladeenc)
3537 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$BLADEENCOPTS}"
3538 MP3ENCODER="$BLADEENC"
3539 ;;
3540 l3enc)
3541 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$L3ENCOPTS}"
3542 MP3ENCODER="$L3ENC"
3543 ;;
3544 xingmp3enc)
3545 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$XINGMP3ENCOPTS}"
3546 MP3ENCODER="$XINGMP3ENC"
3547 ;;
3548 mp3enc)
3549 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$MP3ENCOPTS}"
3550 MP3ENCODER="$MP3ENC"
3551 ;;
3552 esac
3553 case "$OGGENCODERSYNTAX" in
3554 vorbize)
3555 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$VORBIZEOPTS}"
3556 OGGENCODER="$VORBIZE"
3557 ;;
3558 oggenc)
3559 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$OGGENCOPTS}"
3560 OGGENCODER="$OGGENC"
3561 ;;
3562 esac
3563 case "$FLACENCODERSYNTAX" in
3564 flac)
3565 FLACENCODEROPTS="${FLACENCODEROPTSCLI:-$FLACOPTS}"
3566 FLACENCODER="$FLAC"
3567 # FLAC streams can be encapsulated on a Ogg transport layer
3568 if echo "$FLACENCODEROPTS" | egrep -- "(^| )--ogg($| )" > /dev/null 2>&1 ;then
3569 log error "FLAC on an Ogg container is not yet supported"
3570 log error "due to problem with adding comments to such files"
3571 exit 1
3572 FLACOUTPUTCONTAINER=ogg
3573 else
3574 FLACOUTPUTCONTAINER=flac
3575 fi
3576 ;;
3577 esac
3578 case "$SPEEXENCODERSYNTAX" in
3579 speexenc)
3580 SPEEXENCODEROPTS="${SPEEXENCODEROPTSCLI:-$SPEEXENCOPTS}"
3581 SPEEXENCODER="$SPEEXENC"
3582 ;;
3583 esac
3584 case "$MPPENCODERSYNTAX" in
3585 mppenc)
3586 MPPENCODEROPTS="${MPPENCODEROPTSCLI:-$MPPENCOPTS}"
3587 MPPENCODER="$MPPENC"
3588 ;;
3589 esac
3590 case "$AACENCODERSYNTAX" in
3591 faac)
3592 AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
3593 AACENCODER="$AACENC"
3594 ;;
3595 esac
3596
3597 # and which tagger
3598 if [ "$ID3TAGV" = "1" ]; then
3599 TAGGER="$ID3"
3600 TAGGEROPTS="$ID3OPTS"
3601 else
3602 TAGGER="$ID3V2"
3603 TAGGEROPTS="$ID3V2OPTS"
3604 fi
3605
3606 # Specific for NOGAP is the use of lame. Another encoder fails...
3607 if [ "$NOGAP" = "y" ] && [ ! "$MP3ENCODER" = "lame" ]; then
3608 log warning "the NOGAP option is specific of lame. Deactivating..."
3609 NOGAP=n
3610 fi
3611
3612 # Options for mkcue
3613 case "$CUEREADERSYNTAX" in
3614 default|mkcue)
3615 CUEREADEROPTS="${CDROM}"
3616 CUEREADER="$MKCUE"
3617 ;;
3618 esac
3619
3620 # which information retrieval tool are we using?
3621 case "$CDDBTOOL" in
3622 cddb) ;;
3623 musicbrainz) ;;
3624 esac
3625
3626 # Check if both OGGEOUTPUTCONTAINER and FLACOUTPUTCONTAINER are the same, and differentiante them
3627 if [ X"$OGGOUTPUTCONTAINER" = "Xogg" ] && [ X"$FLACOUTPUTCONTAINER" = "Xogg" ]; then
3628 log error "FLAC on an Ogg container is not yet supported"
3629 log error "due to problem with adding comments to such files"
3630 exit 1
3631 OGGOUTPUTCONTAINER=ogg.ogg
3632 FLACOUTPUTCONTAINER=flac.ogg
3633 vecho warning "modified file endings due to conflicting transport layers in Ogg/Vorbis and Ogg/FLAC"
3634 fi
3635
3636 # Clean up nice options (either use '-n NICELEVEL or -NICELEVEL')
3637
3638 if [ "$ENCNICE" ]; then
3639 ENCNICE="-n $ENCNICE"
3640 fi
3641 if [ "$READNICE" ]; then
3642 READNICE="-n $READNICE"
3643 fi
3644 if [ "$DISTMP3NICE" ]; then
3645 DISTMP3NICE="-n $DISTMP3NICE"
3646 fi
3647
3648 # Don't check for stuff if it's not needed
3649 if [ "$REMOTEHOSTS" ]; then
3650 NEEDDISTMP3=y
3651 fi
3652 if [ "$DONORMALIZE" = "y" ]; then
3653 NEEDNORMALIZER=y
3654 fi
3655 if [ "$EJECTCD" = "y" ]; then
3656 NEEDEJECT=y
3657 fi
3658 if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then
3659 if [ "$CDDBMETHOD" = "cddb" ]; then
3660 NEEDHTTPGET=y
3661 elif [ "$CDDBMETHOD" = "musicbrainz" ]; then
3662 :
3663 fi
3664 fi
3665 if [ "$DOCUE" = "y" ]; then
3666 NEEDCUEREADER=y
3667 fi
3668
3669 if [ X"$CDSPEEDVALUE" != "X" ] && [ "$DOREAD" = "y" ]; then
3670 case "$CDROMREADERSYNTAX" in
3671 cdparanoia|debug) CDROMREADEROPTS="$CDPARANOIAOPTS -S $CDSPEEDVALUE" ;;
3672 ### FIXME ### translate "cue2discid" from python to bash
3673 flac) NEEDMETAFLAC=y ; NEEDCUE2DISCID=y ; CDSPEEDVALUE="" ;;
3674 *) NEEDCDSPEED=y ;;
3675 esac
3676 fi
3677
3678 ###USEPIPESSUPPORT###
3679
3680 # Rippers with USEPIPE support
3681 # FIXME # Include here all the rippers we can figure out support pipes
3682 PIPERIPPER_cdparanoia="-"
3683 PIPERIPPER_debug="-"
3684 PIPERIPPER_flac="-c "
3685
3686 # Encoders with USEPIPE support
3687 # FIXME # Include here all the encoders we can figure out support pipes
3688 PIPE_lame="-"
3689 PIPE_bladeenc="-"
3690 PIPE_oggenc="-"
3691 PIPE_flac="-"
3692
3693 # Figure out if we can use pipes with the ripper/encoder combination
3694 # exit otherwise
3695 if [ "$USEPIPES" = "y" ]; then
3696 PIPERIPPERSVARCHECK="PIPERIPPER_${CDROMREADERSYNTAX}"
3697 case "$OUTPUT" in
3698 mp3)
3699 PIPEENCODERSVARCHECK="PIPE_$MP3ENCODERSYNTAX" ;;
3700 vorbis|ogg)
3701 PIPEENCODERSVARCHECK="PIPE_$OGGENCODERSYNTAX" ;;
3702 flac)
3703 PIPEENCODERSVARCHECK="PIPE_$FLACENCODERSYNTAX" ;;
3704 spx)
3705 PIPEENCODERSVARCHECK="PIPE_$SPEEXENCODER" ;;
3706 mpc)
3707 PIPEENCODERSVARCHECK="PIPE_$MPPENCODER" ;;
3708 esac
3709 decho "PIPERIPPERSVARCHECK: $( eval echo "\$$PIPERIPPERSVARCHECK" )"
3710 if [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "$" ] || \
3711 [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "" ] ; then
3712 log error "no support for pipes with given ripper"
3713 log error "read the USEPIPES file from the source tarball to get help."
3714 log error "On a Debian system, it is under /usr/share/doc/abcde/USEPIPES.gz"
3715 exit 1;
3716 fi
3717 decho "PIPEENCODERSVARCHECK: $( eval echo "\$$PIPEENCODERSVARCHECK" )"
3718 if [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "$" ] || \
3719 [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "" ] ; then
3720 log error "no support for pipes with given encoder"
3721 log error "read the USEPIPES file from the source tarball to help"
3722 log error "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz"
3723 exit 1;
3724 fi
3725 fi
3726
3727 # Make sure a buncha things exist
3728 for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
3729 $OGGENCODER $FLACENCODER $SPEEXENCODER $MPPENCODER \
3730 $AACENCODER \
3731 ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \
3732 ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
3733 ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
3734 ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} \
3735 ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMP3GAIN+$MP3GAIN} \
3736 ${NEEDMPPGAIN+$MPPGAIN} ${NEEDCUEREADER+$CUEREADER} \
3737 ${NEEDCUE2DISCID+$CUE2DISCID}
3738 do
3739 checkexec "$X"
3740 done
3741
3742 # And last but not least, check if we can diff between files. We do not abort,
3743 # since diffing is not critical...
3744 if [ -x $(which $DIFF) ]; then :; else
3745 vecho warning "Disabling diff since we cannot find it in the \$PATH..."
3746 DIFF=""
3747 fi
3748
3749 ## Now that we have metaflac, check if we need cue2discid
3750 #case $CDROMREADERSYNTAX in
3751 # flac)
3752 # TRACKINFO=$($METAFLAC --show-tag=CDDB $CDROM | cut -d"=" -f2 | egrep "[a-f0-9]{8}")
3753 # if [ "$TRACKINFO" = "" ]; then
3754 # checkexec ${NEEDCUE2DISCID+$CUE2DISCID}
3755 # fi
3756 # ;;
3757 #esac
3758
3759 CDROMREADER="$CDROMREADER $CDROMREADEROPTS"
3760 CDDBTOOL="$CDDBTOOL $CDDBTOOLOPTS"
3761 HTTPGET="$HTTPGET $HTTPGETOPTS"
3762
3763 # Here it used to say:
3764 # One thousand lines in, we can start doing stuff with things
3765 # Well, right now we are at line 3737 ;)
3766
3767 # Export needed things so they can be read in this subshell
3768 export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS
3769 export CDROM CDDBDATA REMOTEHOSTS MAXPROCS HTTPGET MD5SUM
3770
3771 if [ "$DOREAD" = "y" ]; then
3772 # User-definable function to set some things. Use it for
3773 # - closing the CD tray with eject -t
3774 # - set the CD speed value with eject -x
3775 vecho -n "Executing customizable pre-read function... "
3776
3777 pre_read # Execute the user-defined pre-read funtion. Close the CD with it.
3778
3779 vecho "done."
3780 fi
3781
3782 case "$CDDBMETHOD" in
3783 cddb)
3784 do_discid # Get ABCDETEMPDIR created and status file initialized
3785 ;;
3786 musicbrainz)
3787 do_musicbrainz id
3788 ;;
3789 esac
3790
3791 if [ "$DOCDDB" = "y" ]; then
3792 # start with a sane default:
3793 CDDBLOCALSTATUS=notfound
3794 if [ $CDDBUSELOCAL = "y" ]; then
3795 do_localcddb
3796 fi
3797 if checkstatus cddb-choice > /dev/null; then
3798 :
3799 else
3800 if [ "$CDDBLOCALSTATUS" = "notfound" ] ; then
3801 case "$CDDBMETHOD" in
3802 cddb)
3803 do_cddbstat
3804 do_cddbquery
3805 do_cddbread
3806 ;;
3807 musicbrainz)
3808 do_musicbrainz
3809 ;;
3810 esac
3811 fi
3812 fi
3813 do_cddbedit
3814
3815 eval "$($CDDBTOOL parse "$CDDBDATA")"
3816 fi
3817
3818 # Before reading tracks, we set the speed of the device
3819
3820 if [ X"$CDSPEEDVALUE" != "X" ]; then
3821 case "$CDROMREADERSYNTAX" in
3822 cdparanoia|debug) ;;
3823 flac) ;;
3824 *) do_cdspeed ;;
3825 esac
3826 fi
3827
3828 # Define the first and last track, since we might need them later in several places
3829 FIRSTTRACK=$( get_first $TRACKQUEUE )
3830 LASTTRACK=$( get_last $TRACKQUEUE )
3831
3832 if [ -f "$ABCDETEMPDIR/status" ] && [ X"$ERASEENCODEDSTATUS" = "Xy" ]; then
3833 mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
3834 grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
3835 | grep -v ^encode-output > "$ABCDETEMPDIR/status"
3836 fi
3837
3838 if checkstatus onetrack ; then ONETRACK=y ; fi
3839
3840 if [ "$ONETRACK" = "y" ]; then
3841 # Reuse the CUEFILE in case we created it (now or in a previous run)
3842 if CUEFILE=$(checkstatus cuefile); then
3843 IMPORTCUESHEET=y
3844 fi
3845 fi
3846
3847 # Create playlist if needed (backgroundable) and start reading in tracks
3848
3849 (
3850
3851 if [ ! "$ONETRACK" = "y" ]; then
3852 if [ "$DOPLAYLIST" = "y" ]; then
3853 echo Creating playlist... >&2
3854 do_playlist
3855 fi
3856 fi
3857
3858 # For the lowdisk option, only one program is running at once so the encoder
3859 # can be unsilenced right away.
3860 if [ "$LOWDISK" = "y" ] || [ "$ONETRACK" = "y" ]; then
3861 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3862 fi
3863
3864 if [ "$ONETRACK" = "y" ]; then
3865 TRACKS="$FIRSTTRACK"
3866 if [ "$USEPIPES" = "y" ]; then
3867 if checkstatus readencodetrack-$FIRSTTRACK; then :; else
3868 do_cdread onetrack $FIRSTTRACK $LASTTRACK | do_encode $FIRSTTRACK %local0% > /dev/null 2>&1
3869 fi
3870 else
3871 if checkstatus readtrack-$FIRSTTRACK; then :; else
3872 do_cdread onetrack $FIRSTTRACK $LASTTRACK
3873 fi
3874 fi
3875 else
3876 for UTRACKNUM in $TRACKQUEUE
3877 do
3878 if [ "$DOREAD" = "y" ]; then
3879 if [ "$USEPIPES" = "y" ]; then
3880 if checkstatus readencodetrack-$UTRACKNUM; then :; else
3881 # Read, pipe, shut up!
3882 do_cdread $UTRACKNUM | do_encode $UTRACKNUM %local0% > /dev/null 2>&1
3883 fi
3884 else
3885 if checkstatus readtrack-$UTRACKNUM; then :; else
3886 do_cdread $UTRACKNUM
3887 fi
3888 if [ "$?" != "0" ]; then
3889 # CD read failed - don't give the goahead to
3890 # the encoder
3891 echo NO
3892 exit
3893 fi
3894 fi
3895 fi
3896 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ]; then
3897 :
3898 else
3899 # If we are not reading, set the encode output to loud already, so
3900 # that we can see the output of the first track.
3901 if [ "$MAXPROCS" = "1" ] && [ ! "$DOREAD" = "y" ]; then
3902 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3903 fi
3904 echo NEXTTRACK # Get the encoder machine churning again
3905 if [ "$DOREAD" = "y" ]; then
3906 if [ "$LOWDISK" = "y" ] && [ "$DOENCODE" = "y" ]; then
3907 until checkstatus encodetrack-$UTRACKNUM
3908 do
3909 if checkerrors encodetrack-$UTRACKNUM; then
3910 break
3911 fi
3912 sleep 2
3913 done
3914 fi
3915 fi
3916 fi
3917 done
3918 fi
3919
3920 # Now that we're done the encoding can be loud again -
3921 # if we're not using SMP.
3922 if [ "$MAXPROCS" = "1" ]; then
3923 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3924 fi
3925
3926 # All tracks read, start encoding.
3927 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ] || [ "$ONETRACK" = "y" ]; then
3928 echo NEXTTRACK
3929 fi
3930
3931 # Execute the user-defined post_read funtion before ejecting CD
3932 post_read
3933
3934 # We are now finished with the cdrom - it can be safely ejected. Note that
3935 # abcde will not have completed yet.
3936 if [ "$EJECTCD" = "y" ] && [ -x $(which $EJECT) ]; then
3937 # We check if the disk we are processing is actually the disk inside the
3938 # CD tray. If not, we do not eject the CD, since it might be so that the
3939 # user ejected it manually.
3940 #CURRENTTRACKINFO=$($CDDISCID $CDROM)
3941 #if if [ "$?" != "1" ] && [ "$CURRENTTRACKINFO" = "$TRACKINFO" ] ; then
3942 # More FreeBSD bits.
3943 if [ X"$(uname)" = X"FreeBSD" ] ; then
3944 # FreeBSD eject uses the EJECT environment variable to name the CDROM
3945 # but in this script EJECT is in the envionment and names the program
3946 eject=$EJECT
3947 unset EJECT
3948 # The FreeBSD eject needs "adc0" not "/dev/adc0c"
3949 cd="$(echo $CDROM | sed -e 's=.*/==;s=[a-h]$==;')"
3950 $eject $EJECTOPTS $cd
3951 elif [ X"$(uname)" = X"Darwin" ] ; then
3952 disktool -e ${CDROM#/dev/} 0
3953 else
3954 $EJECT $EJECTOPTS "$CDROM"
3955 fi
3956 #fi
3957 fi
3958
3959 ) | (
3960
3961 ## Do we need to pre-process
3962 #if [ x"$PREPROCESS" = "x" ] ; then
3963 # cat
3964 #else
3965 # for PRETRACKNUM in $TRACKQUEUE
3966 # do
3967 # read GOAHEAD
3968 # if [ "$GOAHEAD" = "NO" ]; then break; fi
3969 # PREPROCEED=
3970 # until [ $PREPROCEED ]
3971 # do
3972 # if checkstatus readtrack-$PRETRACKNUM; then PREPROCEED=y; break; fi
3973 # # all locations are working, wait and try again later
3974 # if [ ! $PREPROCEED ]; then sleep 3; fi
3975 # done
3976 # ( do_preprocess $PRETRACKNUM
3977 # echo "NEXTTRACK"
3978 # ) &
3979 # done
3980 #fi
3981 #
3982 #) | (
3983
3984 # In BATCHNORM and/or NOGAP modes, we want all tracks to be read first.
3985 #BACK
3986 if [ "$BATCHNORM" = "y" ] || [ "$NOGAP" = "y" ]; then
3987 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
3988 if [ "$GOAHEAD" = "NO" ]; then break; fi
3989 for LASTTRACK in $TRACKQUEUE; do :; done
3990 if checkstatus readtrack-$LASTTRACK; then
3991 if [ "$DONORMALIZE" = "y" ] && [ "$BATCHNORM" = "y" ]; then
3992 if checkstatus normalizetrack-$LASTTRACK; then :; else do_batch_normalize; fi
3993 if checkerrors batch-normalize; then exit 1; fi
3994 fi
3995 if [ "$DOENCODE" = "y" ] && [ "$NOGAP" = "y" ]; then
3996 if [ "$DONORMALIZE" = "y" ]; then
3997 for UTRACKNUM in $TRACKQUEUE
3998 do
3999 if checkstatus readtrack-$UTRACKNUM; then
4000 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
4001 fi
4002 done
4003 fi
4004 if checkstatus encodetrack-$LASTTRACK; then :; else do_nogap_encode; fi
4005 if checkerrors nogap-encode; then exit 1; fi
4006 fi
4007 fi
4008 fi
4009
4010 # If we are using ONETRACK, we can proceed with the normal encoding using just the $FIRSTTRACK as TRACKQUEUE
4011 if [ "$ONETRACK" = "y" ] ; then
4012 TRACKQUEUE="$FIRSTTRACK"
4013 TRACKS="$FIRSTTRACK"
4014 fi
4015
4016 # Do the encoding, including parallelization of remote encoding
4017 # Figure out where each track is going to be encoded
4018 ENCODELOCATIONS="$(echo $REMOTEHOSTS | tr , ' ')"
4019 if [ "$MAXPROCS" != "0" ]; then
4020 for NUM in $(f_seq_row 1 "$MAXPROCS")
4021 do
4022 ENCODELOCATIONS="$ENCODELOCATIONS %local$NUM%"
4023 done
4024 fi
4025 # Strip whitespace
4026 ENCODELOCATIONS=$(echo $ENCODELOCATIONS)
4027 for UTRACKNUM in $TRACKQUEUE
4028 do
4029 # Wait for our cue
4030 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
4031 if [ "$GOAHEAD" = "NO" ]; then break; fi
4032 # find out where this track is to be encoded
4033 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
4034 # Make sure we have a place to encode this, if not, exit stage right
4035 if [ -z "$ENCODELOCATIONS" ]; then
4036 continue
4037 fi
4038 PROCEED=
4039 until [ $PROCEED ]
4040 do
4041 for LOCATION in $ENCODELOCATIONS
4042 do
4043 PREVIOUSTRACK="$(checkstatus encodetracklocation-$LOCATION)"
4044 # check first if a track has ever been assigned to this location
4045 if [ -z "$PREVIOUSTRACK" ]; then PROCEED=y; break; fi
4046 # If it errored out, rebuild $ENCODELOCATIONS without this location in it
4047 if checkerrors encodetrack-$PREVIOUSTRACK; then
4048 for TEMPLOCATION in $ENCODELOCATIONS
4049 do
4050 if [ "$TEMPLOCATION" != "$LOCATION" ]; then
4051 TEMPENCODELOCATIONS="$TEMPENCODELOCATIONS $TEMPLOCATION"
4052 fi
4053 done
4054 ENCODELOCATIONS=$(echo $TEMPENCODELOCATIONS)
4055 ABORT=y
4056 PROCEED=y
4057 break
4058 fi
4059 # We're still here, this location must have been previously assigned,
4060 # and last completed without error - check if it's done with the
4061 # previous track yet
4062 if checkstatus encodetrack-$PREVIOUSTRACK; then PROCEED=y; break; fi
4063 done
4064 # all locations are working, wait and try again later
4065 if [ ! $PROCEED ]; then sleep 3; fi
4066 done
4067 # Record the location we're about to encode the next track at
4068 echo "encodetracklocation-$LOCATION=$UTRACKNUM" >> "$ABCDETEMPDIR/status"
4069 fi
4070 # Don't proceed with the rest of the loop if we can't encode
4071 if [ "$ABORT" ]; then continue; fi
4072 ## FIXME ## Add here
4073 ## run_command tagtrack-$OUTPUT-$1 $METAFLAC $METAFLACOPTS ${IMPORTCUESHEET:+--import-cuesheet-from="$ABCDETEMPDIR/$CUEFILE"} --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
4074 # Set TRACKNUM, TRACKNAME
4075 if [ -e "$CDDBDATA" ]; then
4076 if [ "$ONETRACK" = "y" ]; then
4077 TRACKNAME="$DALBUM"
4078 TRACKNUM="$FIRSTTRACK"
4079 splitvarious
4080 else
4081 TRACKNUM=$UTRACKNUM
4082 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
4083 getcddbinfo TRACKNAME
4084 splitvarious
4085 fi
4086 fi
4087 # You can't encode a file which needs to be normalized before finishing
4088 # You can't tag a file before it's finished encoding -
4089 # thus all of this is backgrounded together
4090 (
4091 if [ "$DONORMALIZE" = "y" ]; then
4092 if checkstatus readtrack-$UTRACKNUM; then
4093 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
4094 fi
4095 fi
4096 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
4097 if checkstatus readtrack-$UTRACKNUM; then
4098 #if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION; fi
4099 if [ "$DONORMALIZE" = "y" ]; then
4100 if checkstatus normalizetrack-$UTRACKNUM; then
4101 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
4102 fi
4103 else
4104 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
4105 fi
4106 fi
4107 fi
4108 if [ "$DOTAG" = "y" ]; then
4109 if checkstatus encodetrack-$UTRACKNUM; then
4110 if checkstatus tagtrack-$UTRACKNUM; then :; else do_tag $UTRACKNUM; fi
4111 fi
4112 # Lets tag the cue file
4113 if checkstatus cleancuefile >/dev/null; then :; else
4114 if checkstatus cuefile >/dev/null ; then
4115 do_cleancue
4116 fi
4117 fi
4118 fi
4119 if [ "$DOMOVE" = "y" ]; then
4120 if checkstatus tagtrack-$UTRACKNUM; then
4121 if checkstatus movetrack-$UTRACKNUM; then :; else do_move $UTRACKNUM; fi
4122 fi
4123 fi
4124 ) &
4125 done
4126
4127
4128 # Go through it again and make sure there's no distmp3 stragglers, otherwise
4129 # we'll delete the files they're working on
4130 # Do NOT play ball if there is no ball to play (so ABORT if needed)
4131 ## FIXME ## Check also for files which are encoded using PIPEs.
4132 if [ "$DOENCODE" = "y" ] && [ "$USEPIPES" != "y" ] && [ ! "$ABORT" ]; then
4133 PROCEED=
4134 until [ $PROCEED ]
4135 do
4136 PROCEED=y
4137 for LOCATION in $ENCODELOCATIONS
4138 do
4139 CHECKTRACK="$(checkstatus encodetracklocation-$LOCATION)"
4140 # "How can he give us a status update, if he's DEAD?"
4141 if checkstatus encodetrack-$CHECKTRACK; then
4142 continue
4143 fi
4144 # Nothing to see here please go quietly back to your homes
4145 if [ -z "$CHECKTRACK" ]; then continue; fi
4146 # You're still here? Maybe there is something...
4147 if checkstatus encodetrack-$CHECKTRACK; then :; else PROCEED= ; break; fi
4148 done
4149 # hold up
4150 if [ ! $PROCEED ]; then sleep 5; fi
4151 done
4152 fi
4153 # If the above didn't catch the stragglers, this will
4154 wait
4155 if [ "$DOREPLAYGAIN" = "y" ]; then
4156 do_replaygain
4157 fi
4158
4159 # Check to see if run_command logged any errors
4160 if [ -f "$ABCDETEMPDIR/errors" ]; then
4161 log error "The following commands failed to run:"
4162 cat "$ABCDETEMPDIR/errors"
4163 # Don't clean up
4164 DOCLEAN=n
4165 fi
4166 if [ "$KEEPWAVS" = "y" ];then
4167 # Don't clean up
4168 DOCLEAN=n
4169 fi
4170 # Check if we have moved all the formats we had previously encoded, if we are not using the FORCE.
4171 if [ "$DOCLEAN" = "y" ] && [ ! "$FORCE" = "y" ]; then
4172 ENCODED_FORMATS=$(egrep "^encodetrack-(.{3,6})-(.{1,2})$" "$ABCDETEMPDIR/status" | cut -d"-" -f2 | sort -u | tr '\n' '|')
4173 MOVED_FORMATS=$(egrep "^movetrack-output-(.{3,6})$" "$ABCDETEMPDIR/status" | cut -d"-" -f3 | sort -u | tr '\n' '|')
4174 if [ "$ENCODED_FORMATS" != "$MOVED_FORMATS" ]; then
4175 log warning "The encoded formats does not match with the moved ones"
4176 log warning "Formats encoded: $( echo $ENCODED_FORMATS | tr "|" " " )"
4177 log warning "Formats moved: $( echo $MOVED_FORMATS | tr "|" " " )"
4178 log warning "Use \"abcde -a clean -f -C $DISCID\" to force the removal of the remaining data."
4179 DOCLEAN=n
4180 fi
4181 fi
4182 if [ "$DOCLEAN" = "y" ]; then
4183 # Wipe all the evidence
4184 # Gimme gimme gimme some more time!
4185 sleep 5
4186 rm -rf "$ABCDETEMPDIR"
4187 echo "Finished."
4188 else
4189 echo "Finished. Not cleaning $ABCDETEMPDIR."
4190 fi
4191 )
4192 exit 0
4193
4194 # b:is_bash
4195 # vim:tabstop=4