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