1d0c4461a353161a960c25bc0edf73c182dee569
[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 RSTART=$(echo $1 | cut -f1 -d-)
3295 REND=$(echo $1 | cut -f2 -d-)
3296 if [ "$RSTART" = "$REND" ]; then
3297 NEWTRACKS="$RSTART"
3298 else
3299 NEWTRACKS=$(f_seq_line $RSTART $REND)
3300 fi
3301 TRACKQUEUE=$(echo "$TRACKQUEUE" "$NEWTRACKS")
3302 shift
3303 done
3304 fi
3305
3306 # List of valid actions: cddb,read,normalize,encode,tag,move,playlist,clean
3307 # List of experimental actions: retag,transcode
3308
3309 # Determine what actions are to be done from $ACTIONS and set the
3310 # following environment variables for them:
3311 DOCDDB=n
3312 DOREAD=n
3313 DONORMALIZE=n
3314 DOPREPROCESS=n
3315 DOENCODE=n
3316 DOPOSTPROCESS=n
3317 DOTAG=n
3318 DOMOVE=n
3319 DOREPLAYGAIN=n
3320 DOPLAYLIST=n
3321 DOCLEAN=n
3322 ## FIXME ## Lets keep compatibility with -M
3323 [ "$DOCUE" != "y" ] && DOCUE=n
3324
3325 for ACTION in $(echo $ACTIONS | tr , \ )
3326 do
3327 case $ACTION in
3328 default) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOCLEAN=y;;
3329 cue) DOCUE=y ; MAKECUEFILE=y ;;
3330 cddb) DOCDDB=y;;
3331 read) DOREAD=y;;
3332 normalize) DONORMALIZE=y; DOREAD=y;;
3333 # preprocess) DOPREPROCESS=y; DOREAD=y;;
3334 encode) DOENCODE=y; DOREAD=y;;
3335 # postprocess) DOPREPROCESS=y; DOENCODE=y; DOREAD=y;;
3336 tag) DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
3337 move) DOMOVE=y; DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
3338 replaygain) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOREPLAYGAIN=y;;
3339 playlist) DOCDDB=y; DOPLAYLIST=y;;
3340 clean) DOCLEAN=y;;
3341 esac
3342 done
3343
3344 if [ "$DONORMALIZE" = "y" ] && [ "$DOREPLAYGAIN" = "y" ]; then
3345 # FIXME # should we abort on error or just inform the user?
3346 log warning "selected both normalize and replaygain actions"
3347 fi
3348
3349 for SHOWCDDBFIELD in $(echo $SHOWCDDBFIELDS | tr , \ ); do
3350 case $SHOWCDDBFIELD in
3351 y*|Y*) SHOWCDDBYEAR="y";;
3352 g*|G*) SHOWCDDBGENRE="y";;
3353 *) ;;
3354 esac
3355 done
3356
3357 # At this point a CDROM has to be defined, so we check it exists.
3358 if [ X"$CDROM" != "X" ] ; then
3359 if [ "$CDROMREADERSYNTAX" = "cdda2wav" ] && [ "$NEEDCDROMID" = "y" ] ; then
3360 if [ "$OSFLAVOUR" = "FBSD" ]; then
3361 if echo "$CDROMID" | grep "^[0-9],[0-9],[0-9]$" >/dev/null 2>&1 ; then :; else
3362 log error "CDROMID not in the right format for $CDROMREADERSYNTAX"
3363 log error "Use \"cdrecord -scanbus\" to obtain a adecuate ID an set CDROMID accordingly"
3364 exit 1
3365 fi
3366 fi
3367 elif [ ! -e "$CDROM" -a X"$DOREAD" = "Xy" ]; then
3368 log error "CDROM device cannot be found."
3369 exit 1
3370 fi
3371 # avoid processing if we are not going to hit the CDROM.
3372 elif [ X"$DOREAD" = "Xy" ]; then
3373 log error "CDROM has not been defined or cannot be found"
3374 exit 1
3375 fi
3376
3377 # USEPIPES pre-tests, before we get into more serious stuff
3378 # Not compatible with:
3379 # - multiple outputs
3380 # - normalize
3381 # - lowdisk algorithm
3382 # - anything else?
3383 if [ X"$USEPIPES" = "Xy" ]; then
3384 if [ $(echo "$OUTPUTTYPE" | tr , \ | wc -w ) -gt 1 ]; then
3385 log error "Unix pipes not compatible with multiple outputs"
3386 exit 1
3387 fi
3388 if [ X"$DONORMALIZE" = "Xy" ]; then
3389 log error "Unix pipes not compatible with normalizer"
3390 # FIXME # Do we need to exit or shall we just disable the mode?
3391 exit 1
3392 fi
3393 if [ X"$BATCHNORM" = "Xy" ]; then
3394 log error "Unix pipes not compatible with BATCHNORM encoding"
3395 exit 1
3396 fi
3397 if [ X"$NOGAP" = "Xy" ]; then
3398 log error "Unix pipes not compatible with NOGAP encoding"
3399 exit 1
3400 fi
3401 if [ X"$DOENCODE" = "Xn" ]; then
3402 vecho warning "Disabling Unix pipes since we are not encoding!"
3403 USEPIPES=n
3404 fi
3405 if [ X"$LOWDISK" = "Xy" ]; then
3406 log error "Unix pipes not compatible with lowdisk algorithm"
3407 exit 1
3408 fi
3409 fi
3410
3411 # LOWDISK pre-tests, before we get into more problematic stuff
3412 # Not compatible with anything that needs all the files in the hard disc:
3413 # - BATCHNORM
3414 # - NOGAP lame mode
3415 if [ X"$LOWDISK" = "Xy" ]; then
3416 if [ X"$BATCHNORM" = "Xy" ]; then
3417 log error "Unix pipes not compatible with BATCHNORM encoding"
3418 exit 1
3419 fi
3420 if [ X"$NOGAP" = "Xy" ]; then
3421 log error "Unix pipes not compatible with NOGAP encoding"
3422 exit 1
3423 fi
3424 fi
3425
3426 # BATCHNORM pre-tests, before we get into serious problems
3427 # Not compatible with
3428 if [ "$BATCHNORM" = "y" ] && [ "$DONORMALIZE" = "n" ]; then
3429 vecho warning "Disabling BATCHNORM since we are not normalizing!"
3430 BATCHNORM=n
3431 fi
3432
3433 # Check the encoding format from the ones available in the system, if nothing has been configured.
3434 if [ X"$OUTPUTTYPE" = "X" ]; then
3435 for DEFAULT_OUTPUT in $( echo "$DEFAULT_OUTPUT_BINARIES" | tr , \ ); do
3436 DEFAULT_OUTPUT_FORMAT="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 1)"
3437 DEFAULT_OUTPUT_BINARY="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 2)"
3438 if [ -x $(which $DEFAULT_OUTPUT_BINARY) ] ; then
3439 OUTPUTTYPE=$DEFAULT_OUTPUT_FORMAT
3440 vecho "No default output type defined. Autoselecting $OUTPUTTYPE..." >&2
3441 break
3442 fi
3443 done
3444 if [ X"$OUTPUTTYPE" = "X" ]; then
3445 log error "no encoder found in the PATH"
3446 log error "hints: are all dependencies installed? has the \$PATH been modified?"
3447 exit 1
3448 fi
3449 fi
3450
3451 # Decide which CDROM reader we're gonna use
3452 case "$CDROMREADERSYNTAX" in
3453 cdparanoia|debug)
3454 CDROMREADER="$CDPARANOIA"
3455 CDROMREADEROPTS="$CDPARANOIAOPTS"
3456 ;;
3457 cdda2wav)
3458 CDROMREADER="$CDDA2WAV"
3459 CDROMREADEROPTS="$CDDA2WAVOPTS"
3460 ;;
3461 dagrab)
3462 CDROMREADER="$DAGRAB"
3463 CDROMREADEROPTS="$DAGRABOPTS"
3464 ;;
3465 cddafs)
3466 CDROMREADER="$CDDAFS"
3467 CDROMREADEROPTS="$CDDAFSOPTS"
3468 ;;
3469 flac)
3470 CDROMREADER="$FLAC"
3471 CDROMREADEROPTS="$FLACOPTS"
3472 ;;
3473 esac
3474
3475 # There's only one normalize...
3476 case "$NORMALIZERSYNTAX" in
3477 default|normalize)
3478 NORMALIZER="$NORMALIZE"
3479 NORMALIZEROPTS="$NORMALIZEOPTS"
3480 ;;
3481 esac
3482
3483 # Allow -o OUTPUT(1):OPTIONS(1),...,OUTPUT(N):OPTIONS(N) mode of operation
3484 if echo "$OUTPUTTYPE" | grep ":" > /dev/null 2>&1 ; then
3485 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr \ \|| tr , \ | tr \| \ )"; do
3486 case "$OUTPUT" in
3487 vorbis:*|ogg:*) OGGENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3488 mp3:*) MP3ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3489 flac:*) FLACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3490 spx:*) SPEEXENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3491 mpc:*) MPPENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3492 m4a:*) AACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3493 esac
3494 done
3495 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do
3496 TEMPOUTPUT=$( echo "$OUTPUT" | cut -d: -f1 )
3497 TEMPOUTPUTTYPE="${TEMPOUTPUTTYPE:+$TEMPOUTPUTTYPE,}$TEMPOUTPUT"
3498 done
3499 OUTPUTTYPE="$TEMPOUTPUTTYPE"
3500 fi
3501
3502 # If nothing has been specified, use oggenc for oggs and lame for mp3s and flac
3503 # for flacs and speexenc for speex and mppenc for mpps and faac for m4as
3504
3505 # Getting ready for multiple output changes
3506 for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
3507 do
3508 case $OUTPUT in
3509 vorbis|ogg)
3510 [ "$OGGENCODERSYNTAX" = "default" ] && OGGENCODERSYNTAX=oggenc
3511 [ "$DOTAG" = "y" ] && NEEDCOMMENTER=y
3512 [ "$DOREPLAYGAIN" = "y" ] && NEEDVORBISGAIN=y
3513 OGGOUTPUTCONTAINER=ogg
3514 ;;
3515 mp3)
3516 [ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame
3517 [ "$DOTAG" = "y" ] && NEEDTAGGER=y
3518 [ "$DOREPLAYGAIN" = "y" ] && NEEDMP3GAIN=y
3519 ;;
3520 flac)
3521 [ "$FLACENCODERSYNTAX" = "default" ] && FLACENCODERSYNTAX=flac
3522 [ "$DOTAG" = "y" ] && NEEDMETAFLAC=y
3523 [ "$DOREPLAYGAIN" = "y" ] && NEEDMETAFLAC=y
3524 [ "$ONETRACK" = "y" ] && [ "$DOCUE" = "y" ] && NEEDMETAFLAC=y
3525 ;;
3526 spx)
3527 [ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc
3528 # [ "$DOREPLAYGAIN" = "y" ] &&
3529 ;;
3530 mpc)
3531 [ "$MPPENCODERSYNTAX" = "default" ] && MPPENCODERSYNTAX=mppenc
3532 [ "$DOREPLAYGAIN" = "y" ] && NEEDMPPGAIN=y
3533 ;;
3534 m4a)
3535 [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac
3536 [ "$DOTAG" = "y" ] && CHECKATOMICPARSLEY=y
3537 ;;
3538 wav)
3539 if [ "$KEEPWAVS" = "y" ]; then
3540 vecho "Setting the KEEPWAVS option, since the resulting wav files were requested..."
3541 fi
3542 KEEPWAVS=move
3543 ;;
3544 *) log error "Invalid OUTPUTTYPE defined"
3545 exit 1
3546 ;;
3547 esac
3548 done
3549
3550 # decide which encoder
3551 case "$MP3ENCODERSYNTAX" in
3552 lame)
3553 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$LAMEOPTS}"
3554 MP3ENCODER="$LAME"
3555 ;;
3556 toolame)
3557 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$TOOLAMEOPTS}"
3558 MP3ENCODER="$TOOLAME"
3559 ;;
3560 gogo)
3561 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$GOGOOPTS}"
3562 MP3ENCODER="$GOGO"
3563 ;;
3564 bladeenc)
3565 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$BLADEENCOPTS}"
3566 MP3ENCODER="$BLADEENC"
3567 ;;
3568 l3enc)
3569 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$L3ENCOPTS}"
3570 MP3ENCODER="$L3ENC"
3571 ;;
3572 xingmp3enc)
3573 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$XINGMP3ENCOPTS}"
3574 MP3ENCODER="$XINGMP3ENC"
3575 ;;
3576 mp3enc)
3577 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$MP3ENCOPTS}"
3578 MP3ENCODER="$MP3ENC"
3579 ;;
3580 esac
3581 case "$OGGENCODERSYNTAX" in
3582 vorbize)
3583 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$VORBIZEOPTS}"
3584 OGGENCODER="$VORBIZE"
3585 ;;
3586 oggenc)
3587 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$OGGENCOPTS}"
3588 OGGENCODER="$OGGENC"
3589 ;;
3590 esac
3591 case "$FLACENCODERSYNTAX" in
3592 flac)
3593 FLACENCODEROPTS="${FLACENCODEROPTSCLI:-$FLACOPTS}"
3594 FLACENCODER="$FLAC"
3595 if [ "$DOREPLAYGAIN" = "y" ]; then
3596 FLACENCODEROPTS="${FLACENCODEROPTS} --replay-gain"
3597 fi
3598 # FLAC streams can be encapsulated on a Ogg transport layer
3599 if echo "$FLACENCODEROPTS" | egrep -- "(^| )--ogg($| )" > /dev/null 2>&1 ;then
3600 log error "FLAC on an Ogg container is not yet supported"
3601 log error "due to problem with adding comments to such files"
3602 exit 1
3603 FLACOUTPUTCONTAINER=ogg
3604 else
3605 FLACOUTPUTCONTAINER=flac
3606 fi
3607 ;;
3608 esac
3609 case "$SPEEXENCODERSYNTAX" in
3610 speexenc)
3611 SPEEXENCODEROPTS="${SPEEXENCODEROPTSCLI:-$SPEEXENCOPTS}"
3612 SPEEXENCODER="$SPEEXENC"
3613 ;;
3614 esac
3615 case "$MPPENCODERSYNTAX" in
3616 mppenc)
3617 MPPENCODEROPTS="${MPPENCODEROPTSCLI:-$MPPENCOPTS}"
3618 MPPENCODER="$MPPENC"
3619 ;;
3620 esac
3621 case "$AACENCODERSYNTAX" in
3622 faac)
3623 AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
3624 AACENCODER="$AACENC"
3625 ;;
3626 esac
3627
3628 # and which tagger
3629 if [ "$ID3TAGV" = "1" ]; then
3630 TAGGER="$ID3"
3631 TAGGEROPTS="$ID3OPTS"
3632 else
3633 TAGGER="$ID3V2"
3634 TAGGEROPTS="$ID3V2OPTS"
3635 fi
3636
3637 # NOGAP is specific to lame. Other encoders fail ...
3638 if [ "$NOGAP" = "y" ] && [ ! "$MP3ENCODER" = "lame" ]; then
3639 log warning "the NOGAP option is specific to lame. Deactivating..."
3640 NOGAP=n
3641 fi
3642
3643 # Options for mkcue
3644 case "$CUEREADERSYNTAX" in
3645 default|mkcue)
3646 CUEREADEROPTS="${CDROM}"
3647 CUEREADER="$MKCUE"
3648 ;;
3649 esac
3650
3651 # which information retrieval tool are we using?
3652 case "$CDDBTOOL" in
3653 cddb) ;;
3654 musicbrainz) ;;
3655 esac
3656
3657 # Check if both OGGEOUTPUTCONTAINER and FLACOUTPUTCONTAINER are the same, and differentiante them
3658 if [ X"$OGGOUTPUTCONTAINER" = "Xogg" ] && [ X"$FLACOUTPUTCONTAINER" = "Xogg" ]; then
3659 log error "FLAC on an Ogg container is not yet supported"
3660 log error "due to problem with adding comments to such files"
3661 exit 1
3662 OGGOUTPUTCONTAINER=ogg.ogg
3663 FLACOUTPUTCONTAINER=flac.ogg
3664 vecho warning "modified file endings due to conflicting transport layers in Ogg/Vorbis and Ogg/FLAC"
3665 fi
3666
3667 # Clean up nice options (either use '-n NICELEVEL or -NICELEVEL')
3668
3669 if [ "$ENCNICE" ]; then
3670 ENCNICE="-n $ENCNICE"
3671 fi
3672 if [ "$READNICE" ]; then
3673 READNICE="-n $READNICE"
3674 fi
3675 if [ "$DISTMP3NICE" ]; then
3676 DISTMP3NICE="-n $DISTMP3NICE"
3677 fi
3678
3679 # Don't check for stuff if it's not needed
3680 if [ "$REMOTEHOSTS" ]; then
3681 NEEDDISTMP3=y
3682 fi
3683 if [ "$DONORMALIZE" = "y" ]; then
3684 NEEDNORMALIZER=y
3685 fi
3686 if [ "$EJECTCD" = "y" ]; then
3687 NEEDEJECT=y
3688 fi
3689 if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then
3690 if [ "$CDDBMETHOD" = "cddb" ]; then
3691 NEEDHTTPGET=y
3692 elif [ "$CDDBMETHOD" = "musicbrainz" ]; then
3693 :
3694 fi
3695 fi
3696 if [ "$DOCUE" = "y" ]; then
3697 NEEDCUEREADER=y
3698 fi
3699
3700 if [ X"$CDSPEEDVALUE" != "X" ] && [ "$DOREAD" = "y" ]; then
3701 case "$CDROMREADERSYNTAX" in
3702 cdparanoia|debug) CDROMREADEROPTS="$CDPARANOIAOPTS -S $CDSPEEDVALUE" ;;
3703 ### FIXME ### translate "cue2discid" from python to bash
3704 flac) NEEDMETAFLAC=y ; NEEDCUE2DISCID=y ; CDSPEEDVALUE="" ;;
3705 *) NEEDCDSPEED=y ;;
3706 esac
3707 fi
3708
3709 ###USEPIPESSUPPORT###
3710
3711 # Rippers with USEPIPE support
3712 # FIXME # Include here all the rippers we can figure out support pipes
3713 PIPERIPPER_cdparanoia="-"
3714 PIPERIPPER_debug="-"
3715 PIPERIPPER_flac="-c "
3716
3717 # Encoders with USEPIPE support
3718 # FIXME # Include here all the encoders we can figure out support pipes
3719 PIPE_lame="-"
3720 PIPE_bladeenc="-"
3721 PIPE_oggenc="-"
3722 PIPE_flac="-"
3723
3724 # Figure out if we can use pipes with the ripper/encoder combination
3725 # exit otherwise
3726 if [ "$USEPIPES" = "y" ]; then
3727 PIPERIPPERSVARCHECK="PIPERIPPER_${CDROMREADERSYNTAX}"
3728 case "$OUTPUT" in
3729 mp3)
3730 PIPEENCODERSVARCHECK="PIPE_$MP3ENCODERSYNTAX" ;;
3731 vorbis|ogg)
3732 PIPEENCODERSVARCHECK="PIPE_$OGGENCODERSYNTAX" ;;
3733 flac)
3734 PIPEENCODERSVARCHECK="PIPE_$FLACENCODERSYNTAX" ;;
3735 spx)
3736 PIPEENCODERSVARCHECK="PIPE_$SPEEXENCODER" ;;
3737 mpc)
3738 PIPEENCODERSVARCHECK="PIPE_$MPPENCODER" ;;
3739 esac
3740 decho "PIPERIPPERSVARCHECK: $( eval echo "\$$PIPERIPPERSVARCHECK" )"
3741 if [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "$" ] || \
3742 [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "" ] ; then
3743 log error "no support for pipes with given ripper"
3744 log error "read the USEPIPES file from the source tarball to get help."
3745 log error "On a Debian system, it is under /usr/share/doc/abcde/USEPIPES.gz"
3746 exit 1;
3747 fi
3748 decho "PIPEENCODERSVARCHECK: $( eval echo "\$$PIPEENCODERSVARCHECK" )"
3749 if [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "$" ] || \
3750 [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "" ] ; then
3751 log error "no support for pipes with given encoder"
3752 log error "read the USEPIPES file from the source tarball to help"
3753 log error "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz"
3754 exit 1;
3755 fi
3756 fi
3757
3758 # Make sure a buncha things exist
3759 for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
3760 $OGGENCODER $FLACENCODER $SPEEXENCODER $MPPENCODER \
3761 $AACENCODER \
3762 ${NEEDATOMICPARSLEY+$ATOMICPARSLEY} \
3763 ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \
3764 ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
3765 ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
3766 ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} \
3767 ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMP3GAIN+$MP3GAIN} \
3768 ${NEEDMPPGAIN+$MPPGAIN} ${NEEDCUEREADER+$CUEREADER} \
3769 ${NEEDCUE2DISCID+$CUE2DISCID}
3770 do
3771 checkexec "$X"
3772 done
3773
3774 if [ "$CHECKATOMICPARSLEY" = "y" ]; then
3775 if ! new_checkexec "$ATOMICPARSLEY"; then
3776 echo "WARNING: $ATOMICPARSLEY Not Found Not Post-Tagging!"
3777 DOTAG='n'
3778 else
3779 echo "Using $ATOMICPARSLEY To Tag AAC Tracks."
3780 fi
3781 fi
3782
3783 # And last but not least, check if we can diff between files. We do not abort,
3784 # since diffing is not critical...
3785 if [ -x $(which $DIFF) ]; then :; else
3786 vecho warning "Disabling diff since we cannot find it in the \$PATH..."
3787 DIFF=""
3788 fi
3789
3790 ## Now that we have metaflac, check if we need cue2discid
3791 #case $CDROMREADERSYNTAX in
3792 # flac)
3793 # TRACKINFO=$($METAFLAC --show-tag=CDDB $CDROM | cut -d"=" -f2 | egrep "[a-f0-9]{8}")
3794 # if [ "$TRACKINFO" = "" ]; then
3795 # checkexec ${NEEDCUE2DISCID+$CUE2DISCID}
3796 # fi
3797 # ;;
3798 #esac
3799
3800 CDROMREADER="$CDROMREADER $CDROMREADEROPTS"
3801 CDDBTOOL="$CDDBTOOL $CDDBTOOLOPTS"
3802 HTTPGET="$HTTPGET $HTTPGETOPTS"
3803
3804 # Here it used to say:
3805 # One thousand lines in, we can start doing stuff with things
3806 # Well, right now we are at line 3737 ;)
3807
3808 # Export needed things so they can be read in this subshell
3809 export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS
3810 export CDROM CDDBDATA REMOTEHOSTS MAXPROCS HTTPGET MD5SUM
3811
3812 if [ "$DOREAD" = "y" ]; then
3813 # User-definable function to set some things. Use it for
3814 # - closing the CD tray with eject -t
3815 # - set the CD speed value with eject -x
3816 vecho -n "Executing customizable pre-read function... "
3817
3818 pre_read # Execute the user-defined pre-read funtion. Close the CD with it.
3819
3820 vecho "done."
3821 fi
3822
3823 case "$CDDBMETHOD" in
3824 cddb)
3825 do_discid # Get ABCDETEMPDIR created and status file initialized
3826 ;;
3827 musicbrainz)
3828 do_musicbrainz id
3829 ;;
3830 esac
3831
3832 if [ "$DOCDDB" = "y" ]; then
3833 # start with a sane default:
3834 CDDBLOCALSTATUS=notfound
3835 if [ $CDDBUSELOCAL = "y" ]; then
3836 do_localcddb
3837 fi
3838 if checkstatus cddb-choice > /dev/null; then
3839 :
3840 else
3841 if [ "$CDDBLOCALSTATUS" = "notfound" ] ; then
3842 case "$CDDBMETHOD" in
3843 cddb)
3844 do_cddbstat
3845 do_cddbquery
3846 do_cddbread
3847 ;;
3848 musicbrainz)
3849 do_musicbrainz
3850 ;;
3851 esac
3852 fi
3853 fi
3854 do_cddbedit
3855
3856 eval "$($CDDBTOOL parse "$CDDBDATA")"
3857 fi
3858
3859 # Before reading tracks, we set the speed of the device
3860
3861 if [ X"$CDSPEEDVALUE" != "X" ]; then
3862 case "$CDROMREADERSYNTAX" in
3863 cdparanoia|debug) ;;
3864 flac) ;;
3865 *) do_cdspeed ;;
3866 esac
3867 fi
3868
3869 # Define the first and last track, since we might need them later in several places
3870 FIRSTTRACK=$( get_first $TRACKQUEUE )
3871 LASTTRACK=$( get_last $TRACKQUEUE )
3872
3873 if [ -f "$ABCDETEMPDIR/status" ] && [ X"$ERASEENCODEDSTATUS" = "Xy" ]; then
3874 mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
3875 grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
3876 | grep -v ^encode-output > "$ABCDETEMPDIR/status"
3877 fi
3878
3879 if checkstatus onetrack ; then ONETRACK=y ; fi
3880
3881 if [ "$ONETRACK" = "y" ]; then
3882 # Reuse the CUEFILE in case we created it (now or in a previous run)
3883 if CUEFILE=$(checkstatus cuefile); then
3884 IMPORTCUESHEET=y
3885 fi
3886 fi
3887
3888 # Create playlist if needed (backgroundable) and start reading in tracks
3889
3890 (
3891
3892 if [ ! "$ONETRACK" = "y" ]; then
3893 if [ "$DOPLAYLIST" = "y" ]; then
3894 echo Creating playlist... >&2
3895 do_playlist
3896 fi
3897 fi
3898
3899 # For the lowdisk option, only one program is running at once so the encoder
3900 # can be unsilenced right away.
3901 if [ "$LOWDISK" = "y" ] || [ "$ONETRACK" = "y" ]; then
3902 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3903 fi
3904
3905 if [ "$ONETRACK" = "y" ]; then
3906 TRACKS="$FIRSTTRACK"
3907 if [ "$USEPIPES" = "y" ]; then
3908 if checkstatus readencodetrack-$FIRSTTRACK; then :; else
3909 do_cdread onetrack $FIRSTTRACK $LASTTRACK | do_encode $FIRSTTRACK %local0% > /dev/null 2>&1
3910 fi
3911 else
3912 if checkstatus readtrack-$FIRSTTRACK; then :; else
3913 do_cdread onetrack $FIRSTTRACK $LASTTRACK
3914 fi
3915 fi
3916 else
3917 for UTRACKNUM in $TRACKQUEUE
3918 do
3919 if [ "$DOREAD" = "y" ]; then
3920 if [ "$USEPIPES" = "y" ]; then
3921 if checkstatus readencodetrack-$UTRACKNUM; then :; else
3922 # Read, pipe, shut up!
3923 do_cdread $UTRACKNUM | do_encode $UTRACKNUM %local0% > /dev/null 2>&1
3924 fi
3925 else
3926 if checkstatus readtrack-$UTRACKNUM; then :; else
3927 do_cdread $UTRACKNUM
3928 fi
3929 if [ "$?" != "0" ]; then
3930 # CD read failed - don't give the goahead to
3931 # the encoder
3932 echo NO
3933 exit
3934 fi
3935 fi
3936 fi
3937 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ]; then
3938 :
3939 else
3940 # If we are not reading, set the encode output to loud already, so
3941 # that we can see the output of the first track.
3942 if [ "$MAXPROCS" = "1" ] && [ ! "$DOREAD" = "y" ]; then
3943 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3944 fi
3945 echo NEXTTRACK # Get the encoder machine churning again
3946 if [ "$DOREAD" = "y" ]; then
3947 if [ "$LOWDISK" = "y" ] && [ "$DOENCODE" = "y" ]; then
3948 until checkstatus encodetrack-$UTRACKNUM
3949 do
3950 if checkerrors encodetrack-$UTRACKNUM; then
3951 break
3952 fi
3953 sleep 2
3954 done
3955 fi
3956 fi
3957 fi
3958 done
3959 fi
3960
3961 # Now that we're done the encoding can be loud again -
3962 # if we're not using SMP.
3963 if [ "$MAXPROCS" = "1" ]; then
3964 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3965 fi
3966
3967 # All tracks read, start encoding.
3968 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ] || [ "$ONETRACK" = "y" ]; then
3969 echo NEXTTRACK
3970 fi
3971
3972 # Execute the user-defined post_read funtion before ejecting CD
3973 post_read
3974
3975 # We are now finished with the cdrom - it can be safely ejected. Note that
3976 # abcde will not have completed yet.
3977 if [ "$EJECTCD" = "y" ] && [ -x $(which $EJECT) ]; then
3978 # We check if the disk we are processing is actually the disk inside the
3979 # CD tray. If not, we do not eject the CD, since it might be so that the
3980 # user ejected it manually.
3981 #CURRENTTRACKINFO=$($CDDISCID $CDROM)
3982 #if if [ "$?" != "1" ] && [ "$CURRENTTRACKINFO" = "$TRACKINFO" ] ; then
3983 # More FreeBSD bits.
3984 if [ X"$(uname)" = X"FreeBSD" ] ; then
3985 # FreeBSD eject uses the EJECT environment variable to name the CDROM
3986 # but in this script EJECT is in the envionment and names the program
3987 eject=$EJECT
3988 unset EJECT
3989 # The FreeBSD eject needs "adc0" not "/dev/adc0c"
3990 cd="$(echo $CDROM | sed -e 's=.*/==;s=[a-h]$==;')"
3991 $eject $EJECTOPTS $cd
3992 elif [ X"$(uname)" = X"Darwin" ] ; then
3993 disktool -e ${CDROM#/dev/} 0
3994 else
3995 $EJECT $EJECTOPTS "$CDROM"
3996 fi
3997 #fi
3998 fi
3999
4000 ) | (
4001
4002 ## Do we need to pre-process
4003 #if [ x"$PREPROCESS" = "x" ] ; then
4004 # cat
4005 #else
4006 # for PRETRACKNUM in $TRACKQUEUE
4007 # do
4008 # read GOAHEAD
4009 # if [ "$GOAHEAD" = "NO" ]; then break; fi
4010 # PREPROCEED=
4011 # until [ $PREPROCEED ]
4012 # do
4013 # if checkstatus readtrack-$PRETRACKNUM; then PREPROCEED=y; break; fi
4014 # # all locations are working, wait and try again later
4015 # if [ ! $PREPROCEED ]; then sleep 3; fi
4016 # done
4017 # ( do_preprocess $PRETRACKNUM
4018 # echo "NEXTTRACK"
4019 # ) &
4020 # done
4021 #fi
4022 #
4023 #) | (
4024
4025 # In BATCHNORM and/or NOGAP modes, we want all tracks to be read first.
4026 #BACK
4027 if [ "$BATCHNORM" = "y" ] || [ "$NOGAP" = "y" ]; then
4028 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
4029 if [ "$GOAHEAD" = "NO" ]; then break; fi
4030 for LASTTRACK in $TRACKQUEUE; do :; done
4031 if checkstatus readtrack-$LASTTRACK; then
4032 if [ "$DONORMALIZE" = "y" ] && [ "$BATCHNORM" = "y" ]; then
4033 if checkstatus normalizetrack-$LASTTRACK; then :; else do_batch_normalize; fi
4034 if checkerrors batch-normalize; then exit 1; fi
4035 fi
4036 if [ "$DOENCODE" = "y" ] && [ "$NOGAP" = "y" ]; then
4037 if [ "$DONORMALIZE" = "y" ]; then
4038 for UTRACKNUM in $TRACKQUEUE
4039 do
4040 if checkstatus readtrack-$UTRACKNUM; then
4041 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
4042 fi
4043 done
4044 fi
4045 if checkstatus encodetrack-$LASTTRACK; then :; else do_nogap_encode; fi
4046 if checkerrors nogap-encode; then exit 1; fi
4047 fi
4048 fi
4049 fi
4050
4051 # If we are using ONETRACK, we can proceed with the normal encoding using just the $FIRSTTRACK as TRACKQUEUE
4052 if [ "$ONETRACK" = "y" ] ; then
4053 TRACKQUEUE="$FIRSTTRACK"
4054 TRACKS="$FIRSTTRACK"
4055 fi
4056
4057 # Do the encoding, including parallelization of remote encoding
4058 # Figure out where each track is going to be encoded
4059 ENCODELOCATIONS="$(echo $REMOTEHOSTS | tr , ' ')"
4060 if [ "$MAXPROCS" != "0" ]; then
4061 for NUM in $(f_seq_row 1 "$MAXPROCS")
4062 do
4063 ENCODELOCATIONS="$ENCODELOCATIONS %local$NUM%"
4064 done
4065 fi
4066 # Strip whitespace
4067 ENCODELOCATIONS=$(echo $ENCODELOCATIONS)
4068 for UTRACKNUM in $TRACKQUEUE
4069 do
4070 # Wait for our cue
4071 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
4072 if [ "$GOAHEAD" = "NO" ]; then break; fi
4073 # find out where this track is to be encoded
4074 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
4075 # Make sure we have a place to encode this, if not, exit stage right
4076 if [ -z "$ENCODELOCATIONS" ]; then
4077 continue
4078 fi
4079 PROCEED=
4080 until [ $PROCEED ]
4081 do
4082 for LOCATION in $ENCODELOCATIONS
4083 do
4084 PREVIOUSTRACK="$(checkstatus encodetracklocation-$LOCATION)"
4085 # check first if a track has ever been assigned to this location
4086 if [ -z "$PREVIOUSTRACK" ]; then PROCEED=y; break; fi
4087 # If it errored out, rebuild $ENCODELOCATIONS without this location in it
4088 if checkerrors encodetrack-$PREVIOUSTRACK; then
4089 for TEMPLOCATION in $ENCODELOCATIONS
4090 do
4091 if [ "$TEMPLOCATION" != "$LOCATION" ]; then
4092 TEMPENCODELOCATIONS="$TEMPENCODELOCATIONS $TEMPLOCATION"
4093 fi
4094 done
4095 ENCODELOCATIONS=$(echo $TEMPENCODELOCATIONS)
4096 ABORT=y
4097 PROCEED=y
4098 break
4099 fi
4100 # We're still here, this location must have been previously assigned,
4101 # and last completed without error - check if it's done with the
4102 # previous track yet
4103 if checkstatus encodetrack-$PREVIOUSTRACK; then PROCEED=y; break; fi
4104 done
4105 # all locations are working, wait and try again later
4106 if [ ! $PROCEED ]; then sleep 3; fi
4107 done
4108 # Record the location we're about to encode the next track at
4109 echo "encodetracklocation-$LOCATION=$UTRACKNUM" >> "$ABCDETEMPDIR/status"
4110 fi
4111 # Don't proceed with the rest of the loop if we can't encode
4112 if [ "$ABORT" ]; then continue; fi
4113 ## FIXME ## Add here
4114 ## run_command tagtrack-$OUTPUT-$1 $METAFLAC $METAFLACOPTS ${IMPORTCUESHEET:+--import-cuesheet-from="$ABCDETEMPDIR/$CUEFILE"} --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
4115 # Set TRACKNUM, TRACKNAME
4116 if [ -e "$CDDBDATA" ]; then
4117 if [ "$ONETRACK" = "y" ]; then
4118 TRACKNAME="$DALBUM"
4119 TRACKNUM="$FIRSTTRACK"
4120 splitvarious
4121 else
4122 TRACKNUM=$UTRACKNUM
4123 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
4124 getcddbinfo TRACKNAME
4125 splitvarious
4126 fi
4127 fi
4128 # You can't encode a file which needs to be normalized before finishing
4129 # You can't tag a file before it's finished encoding -
4130 # thus all of this is backgrounded together
4131 (
4132 if [ "$DONORMALIZE" = "y" ]; then
4133 if checkstatus readtrack-$UTRACKNUM; then
4134 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
4135 fi
4136 fi
4137 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
4138 if checkstatus readtrack-$UTRACKNUM; then
4139 #if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION; fi
4140 if [ "$DONORMALIZE" = "y" ]; then
4141 if checkstatus normalizetrack-$UTRACKNUM; then
4142 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
4143 fi
4144 else
4145 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
4146 fi
4147 fi
4148 fi
4149 if [ "$DOTAG" = "y" ]; then
4150 if checkstatus encodetrack-$UTRACKNUM; then
4151 if checkstatus tagtrack-$UTRACKNUM; then :; else do_tag $UTRACKNUM; fi
4152 fi
4153 # Lets tag the cue file
4154 if checkstatus cleancuefile >/dev/null; then :; else
4155 if checkstatus cuefile >/dev/null ; then
4156 do_cleancue
4157 fi
4158 fi
4159 fi
4160 if [ "$DOMOVE" = "y" ]; then
4161 if checkstatus tagtrack-$UTRACKNUM; then
4162 if checkstatus movetrack-$UTRACKNUM; then :; else do_move $UTRACKNUM; fi
4163 fi
4164 fi
4165 ) &
4166 done
4167
4168
4169 # Go through it again and make sure there's no distmp3 stragglers, otherwise
4170 # we'll delete the files they're working on
4171 # Do NOT play ball if there is no ball to play (so ABORT if needed)
4172 ## FIXME ## Check also for files which are encoded using PIPEs.
4173 if [ "$DOENCODE" = "y" ] && [ "$USEPIPES" != "y" ] && [ ! "$ABORT" ]; then
4174 PROCEED=
4175 until [ $PROCEED ]
4176 do
4177 PROCEED=y
4178 for LOCATION in $ENCODELOCATIONS
4179 do
4180 CHECKTRACK="$(checkstatus encodetracklocation-$LOCATION)"
4181 # "How can he give us a status update, if he's DEAD?"
4182 if checkstatus encodetrack-$CHECKTRACK; then
4183 continue
4184 fi
4185 # Nothing to see here please go quietly back to your homes
4186 if [ -z "$CHECKTRACK" ]; then continue; fi
4187 # You're still here? Maybe there is something...
4188 if checkstatus encodetrack-$CHECKTRACK; then :; else PROCEED= ; break; fi
4189 done
4190 # hold up
4191 if [ ! $PROCEED ]; then sleep 5; fi
4192 done
4193 fi
4194 # If the above didn't catch the stragglers, this will
4195 wait
4196 if [ "$DOREPLAYGAIN" = "y" ]; then
4197 do_replaygain
4198 fi
4199
4200 # Execute the user-defined post_encode function before cleaning up
4201 post_encode
4202
4203 # Check to see if run_command logged any errors
4204 if [ -f "$ABCDETEMPDIR/errors" ]; then
4205 log error "The following commands failed to run:"
4206 cat "$ABCDETEMPDIR/errors"
4207 # Don't clean up
4208 DOCLEAN=n
4209 fi
4210 if [ "$KEEPWAVS" = "y" ];then
4211 # Don't clean up
4212 DOCLEAN=n
4213 fi
4214 # Check if we have moved all the formats we had previously encoded, if we are not using the FORCE.
4215 if [ "$DOCLEAN" = "y" ] && [ ! "$FORCE" = "y" ]; then
4216 ENCODED_FORMATS=$(egrep "^encodetrack-(.{3,6})-(.{1,2})$" "$ABCDETEMPDIR/status" | cut -d"-" -f2 | sort -u | tr '\n' '|')
4217 MOVED_FORMATS=$(egrep "^movetrack-output-(.{3,6})$" "$ABCDETEMPDIR/status" | cut -d"-" -f3 | sort -u | tr '\n' '|')
4218 if [ "$ENCODED_FORMATS" != "$MOVED_FORMATS" ]; then
4219 log warning "The encoded formats does not match with the moved ones"
4220 log warning "Formats encoded: $( echo $ENCODED_FORMATS | tr "|" " " )"
4221 log warning "Formats moved: $( echo $MOVED_FORMATS | tr "|" " " )"
4222 log warning "Use \"abcde -a clean -f -C $DISCID\" to force the removal of the remaining data."
4223 DOCLEAN=n
4224 fi
4225 fi
4226 if [ "$DOCLEAN" = "y" ]; then
4227 # Wipe all the evidence
4228 # Gimme gimme gimme some more time!
4229 sleep 5
4230 rm -rf "$ABCDETEMPDIR"
4231 echo "Finished."
4232 else
4233 echo "Finished. Not cleaning $ABCDETEMPDIR."
4234 fi
4235 )
4236 exit 0
4237
4238 # b:is_bash
4239 # vim:tabstop=4