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