758510946f7b0780d16094a1ff6ae2197cacd4ed
[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 *) # Try a cddb query, since freedb2.org doesn't support the stat or ver commands
2215 # FreeDB TESTCD disc-id is used for query
2216 $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST 03015501 1 296 344 > "$ABCDETEMPDIR/cddbstat"
2217 RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbstat" | cut -f1 -d' ')
2218 case "$RESPONSECODE" in
2219 2??) # Server responded, everything seems OK
2220 rc=0
2221 ;;
2222 esac
2223 ;;
2224 esac
2225 done
2226 if test $rc -eq 1; then
2227 CDDBAVAIL="n"
2228 fi
2229 fi
2230 echo cddb-statcomplete >> "$ABCDETEMPDIR/status"
2231 fi
2232 }
2233
2234
2235 # do_cddbquery
2236 do_cddbquery ()
2237 {
2238 CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
2239 CDDBLOCALFILE="${CDDBLOCALDIR}/${CDDBDISCID}"
2240
2241 # Perform CDDB query if it hasn't already been done
2242 if checkstatus cddb-querycomplete; then :; else
2243 if [ "$CDDBAVAIL" = "n" ]; then
2244 ERRORCODE=no_query
2245 echo 503 > "$ABCDETEMPDIR/cddbquery"
2246 # The default CDDBLOCALSTATUS is "notfound"
2247 # This part will be triggered if the user CDDB repo does not
2248 # contain the entry, or if we are not trying to use the repo.
2249 else
2250 vecho "Querying the CDDB server..."
2251 CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
2252 CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
2253 $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $TRACKINFO > "$ABCDETEMPDIR/cddbquery"
2254 ERRORCODE=$?
2255 case $ERRORCODE in
2256 0) # success
2257 ;;
2258 12|13|14)
2259 # no match found in database,
2260 # wget/fetch error, or user requested not to use CDDB
2261 # Make up an error code (503) that abcde
2262 # will recognize in do_cddbread
2263 # and compensate by making a template
2264 echo 503 > "$ABCDETEMPDIR/cddbquery"
2265 ;;
2266 *) # strange and unknown error
2267 echo ERRORCODE=$ERRORCODE
2268 echo "abcde: $CDDBTOOL returned unknown error code"
2269 ;;
2270 esac
2271 fi
2272 echo cddb-querycomplete >> "$ABCDETEMPDIR/status"
2273 fi
2274 }
2275
2276 # do_cddbread
2277 do_cddbread ()
2278 {
2279 # If it's not to be used, generate a template.
2280 # Then, display it (or them) and let the user choose/edit it
2281 if checkstatus cddb-readcomplete; then :; else
2282 vecho "Obtaining CDDB results..."
2283 # If CDDB is to be used, interpret the query results and read all
2284 # the available entries.
2285 rm -f "$ABCDETEMPDIR/cddbchoices"
2286 CDDBCHOICES=1 # Overridden by multiple matches
2287 RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbquery" | cut -f1 -d' ')
2288 case "$RESPONSECODE" in
2289 200)
2290 # One exact match, retrieve it
2291 # 200 [section] [discid] [artist] / [title]
2292 if checkstatus cddb-read-1-complete; then :; else
2293 echo -n "Retrieving 1 CDDB match..." >> "$ABCDETEMPDIR/cddbchoices"
2294 $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(cut -f2,3 -d' ' "$ABCDETEMPDIR/cddbquery") > "$ABCDETEMPDIR/cddbread.1"
2295 echo "done." >> "$ABCDETEMPDIR/cddbchoices"
2296 echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
2297 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2298 fi
2299 # List out disc title/author and contents
2300 echo ---- "$(cut '-d ' -f4- "$ABCDETEMPDIR/cddbquery")" ---- >> "$ABCDETEMPDIR/cddbchoices"
2301 for TRACK in $(f_seq_row 1 $TRACKS)
2302 do
2303 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
2304 done
2305 echo >> "$ABCDETEMPDIR/cddbchoices"
2306 ;;
2307 202|403|409|503)
2308 # No match
2309 case "$RESPONSECODE" in
2310 202) echo "No CDDB match." >> "$ABCDETEMPDIR/cddbchoices" ;;
2311 403|409) echo "CDDB entry is corrupt, or the handshake failed." >> "$ABCDETEMPDIR/cddbchoices" ;;
2312 503) echo "CDDB unavailable." >> "$ABCDETEMPDIR/cddbchoices" ;;
2313 esac
2314 $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
2315 # List out disc title/author and contents of template
2316 echo ---- Unknown Artist / Unknown Album ---- >> "$ABCDETEMPDIR/cddbchoices"
2317 UNKNOWNDISK=y
2318 for TRACK in $(f_seq_row 1 $TRACKS)
2319 do
2320 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.0" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
2321 done
2322 echo >> "$ABCDETEMPDIR/cddbchoices"
2323 echo cddb-read-0-complete >> "$ABCDETEMPDIR/status"
2324 echo cddb-choice=0 >> "$ABCDETEMPDIR/status"
2325 ;;
2326 210|211)
2327 # Multiple exact, (possibly multiple) inexact matches
2328 IN=
2329 if [ "$RESPONSECODE" = "211" ]; then IN=in; fi
2330 if [ "$(wc -l < "$ABCDETEMPDIR/cddbquery" | tr -d ' ')" -eq 3 ]; then
2331 echo "One ${IN}exact match:" >> "$ABCDETEMPDIR/cddbchoices"
2332 tail -n +2 "$ABCDETEMPDIR/cddbquery" | head -n 1 >> "$ABCDETEMPDIR/cddbchoices"
2333 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2334 else
2335 echo "Multiple ${IN}exact matches:" >> "$ABCDETEMPDIR/cddbchoices"
2336 fi
2337 vecho -n "Retrieving multiple matches... "
2338 grep -v ^[.]$ "$ABCDETEMPDIR/cddbquery" | ( X=0
2339 read DISCINFO # eat top line
2340 while read DISCINFO
2341 do
2342 X=$(expr $X + 1)
2343 if checkstatus cddb-read-$X-complete; then :; else
2344 $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(echo $DISCINFO | cut -f1,2 -d' ') > "$ABCDETEMPDIR/cddbread.$X"
2345 echo cddb-read-$X-complete >> "$ABCDETEMPDIR/status"
2346 fi
2347 # List out disc title/author and contents
2348 echo \#$X: ---- "$DISCINFO" ---- >> "$ABCDETEMPDIR/cddbchoices"
2349 for TRACK in $(f_seq_row 1 $TRACKS)
2350 do
2351 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.$X" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
2352 done
2353 echo >> "$ABCDETEMPDIR/cddbchoices"
2354 done )
2355 vecho "done."
2356 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
2357 ;;
2358 999)
2359 # Using local copy.
2360 for TRACK in $(f_seq_row 1 $TRACKS)
2361 do
2362 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
2363 done
2364 echo >> "$ABCDETEMPDIR/cddbchoices"
2365 echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
2366 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2367 ;;
2368 esac
2369 echo "cddb-readcomplete" >> "$ABCDETEMPDIR/status"
2370 fi
2371 }
2372
2373 # do_cddbedit
2374 do_cddbedit ()
2375 {
2376 if checkstatus cddb-edit >/dev/null; then
2377 CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
2378 VARIOUSARTISTS="$(checkstatus variousartists)"
2379 VARIOUSARTISTSTYLE="$(checkstatus variousartiststyle)"
2380 return 0
2381 fi
2382 if [ "$INTERACTIVE" = "y" ]; then
2383 # We should show the CDDB results both when we are not using the local CDDB repo
2384 # or when we are using it but we could not find a proper match
2385 if [ "$CDDBUSELOCAL" = "y" ] && [ "$CDDBLOCALSTATUS" = "notfound" ] || [ ! "$CDDBUSELOCAL" = "y" ]; then
2386 # Display the $ABCDETEMPDIR/cddbchoices file created above
2387 # Pick a pager so that if the tracks overflow the screen the user can still view everything
2388 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
2389 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
2390 CHOICE=$(checkstatus cddb-choice)
2391 if [ -n "$CHOICE" ] ; then
2392 case $CDDBCHOICES in
2393 -1) if head -1 "$ABCDETEMPDIR/cddbquery" | grep "^$" > /dev/null 2>&1 ; then
2394 log error "CDDB query failed!"
2395 exit 1
2396 else
2397 cat "$ABCDETEMPDIR/cddbchoices"
2398 fi
2399 ;;
2400 1) cat "$ABCDETEMPDIR/cddbchoices" ;;
2401 *)
2402 echo "Selected: #$CHOICE"
2403 do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
2404 ;;
2405 esac
2406 else
2407 # The user has a choice to make, display the info in a pager if necessary
2408 if [ $(cat "$ABCDETEMPDIR/cddbchoices" | wc -l) -ge 24 ]; then
2409 page "$ABCDETEMPDIR/cddbchoices"
2410 else
2411 # It's all going to fit in one page, cat it
2412 cat "$ABCDETEMPDIR/cddbchoices" >&2
2413 fi
2414
2415 CDDBCHOICENUM=""
2416 # Setting the choice to an impossible integer to avoid errors in the numeric comparisons
2417 CDCHOICENUM=-1
2418 # I'll take CDDB read #3 for $400, Alex
2419 while [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; do
2420 echo -n "Which entry would you like abcde to use (0 for none)? [0-$CDDBCHOICES]: " >&2
2421 read CDDBCHOICE
2422 [ X"$CDDBCHOICE" = "X" ] && CDDBCHOICE=1
2423 if echo $CDDBCHOICE | egrep "[[:space:]]*[[:digit:]]+,[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
2424 if [ ! X"$DIFF" = "X" ]; then
2425 PARSECHOICE1=$(echo $CDDBCHOICE | cut -d"," -f1 | xargs printf %d 2>/dev/null)
2426 PARSECHOICE2=$(echo $CDDBCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null)
2427 if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBCHOICES ] || \
2428 [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBCHOICES ] || \
2429 [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then
2430 echo "Invalid diff range. Please select two comma-separated numbers between 1 and $CDDBCHOICES" >&2
2431 else
2432 # We parse the 2 choices to diff, store them in temporary files and diff them.
2433 for PARSECHOICE in $(echo $CDDBCHOICE | tr , \ ); do
2434 do_cddbparse "$ABCDETEMPDIR/cddbread.$PARSECHOICE" > "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE"
2435 done
2436 echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..." > "$ABCDETEMPDIR/cddbread.diff"
2437 $DIFF $DIFFOPTS "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE1" "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE2" >> "$ABCDETEMPDIR/cddbread.diff"
2438 if [ $(cat "$ABCDETEMPDIR/cddbread.diff" | wc -l) -ge 24 ]; then
2439 page "$ABCDETEMPDIR/cddbread.diff"
2440 else
2441 cat "$ABCDETEMPDIR/cddbread.diff" >&2
2442 fi
2443 fi
2444 else
2445 echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBCHOICES." >&2
2446 fi
2447 elif echo $CDDBCHOICE | egrep "[[:space:]]*[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
2448 # Make sure we get a valid choice
2449 CDCHOICENUM=$(echo $CDDBCHOICE | xargs printf %d 2>/dev/null)
2450 if [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; then
2451 echo "Invalid selection. Please choose a number between 0 and $CDDBCHOICES." >&2
2452 fi
2453 fi
2454 done
2455 if [ "$CDCHOICENUM" = "0" ]; then
2456 vecho "Creating empty CDDB template..."
2457 UNKNOWNDISK=y
2458 $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
2459 else
2460 echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
2461 do_cddbparse "$ABCDETEMPDIR/cddbread.$CDCHOICENUM"
2462 fi
2463 echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
2464 fi
2465 fi
2466 else
2467 # We need some code to show the selected option when local repository is selected and we have found a match
2468 vecho "Using cached CDDB match..." >&2
2469 # Display the $ABCDETEMPDIR/cddbchoices file created above
2470 # Pick a pager so that if the tracks overflow the screen the user can still view everything
2471 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
2472 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
2473 CHOICE=$(checkstatus cddb-choice)
2474 if [ "$USELOCALRESP" = "y" ]; then :; else
2475 if [ -n "$CHOICE" ] ; then
2476 case $CDDBCHOICES in
2477 0)
2478 UNKNOWNDISK=y
2479 echo "Selected template."
2480 ;;
2481 1) cat "$ABCDETEMPDIR/cddbchoices" ;;
2482 *)
2483 echo "Selected: #$CHOICE"
2484 do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
2485 ;;
2486 esac
2487 fi
2488 fi
2489 fi
2490 fi
2491 else
2492 # We're noninteractive - pick the first choice.
2493 # But in case we run a previous instance and selected a choice, use it.
2494 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
2495 # Show the choice if we are not using the locally stored one
2496 # or when the local search failed to find a match.
2497 PREVIOUSCHOICE=$(checkstatus cddb-choice)
2498 if [ "$CDDBUSELOCAL" = "y" ] && [ "$CDDBLOCALSTATUS" = "notfound" ] || [ ! "$CDDBUSELOCAL" = "y" ]; then
2499 #if [ "$PREVIOUSCHOICE" ]; then
2500 cat "$ABCDETEMPDIR/cddbchoices"
2501 #fi
2502 fi
2503 if [ ! -z "$PREVIOUSCHOICE" ] ; then
2504 CDCHOICENUM=$PREVIOUSCHOICE
2505 else
2506 CDCHOICENUM=1
2507 echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
2508 fi
2509 echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
2510 fi
2511 fi
2512
2513 # sanity check
2514 if checkstatus cddb-choice >/dev/null; then :; else
2515 echo "abcde: internal error: cddb-choice not recorded." >&2
2516 exit 1
2517 fi
2518 CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
2519 echo -n "Edit selected CDDB data? [y/n] (" >&2
2520 if [ "$INTERACTIVE" = "y" ]; then
2521 if [ "$UNKNOWNDISK" = "y" ]; then
2522 echo -n "y): " >&2
2523 read EDITCDDB
2524 [ "$EDITCDDB" != "n" ] && EDITCDDB=y
2525 else
2526 echo -n "n): " >&2
2527 read EDITCDDB
2528 fi
2529 else
2530 echo "n): n" >&2
2531 EDITCDDB=n
2532 fi
2533 if [ "$EDITCDDB" = "y" ]; then
2534 CDDBDATAMD5SUM=$($MD5SUM "$CDDBDATA" | cut -d " " -f 1);
2535
2536 # Use the debian sensible-editor wrapper to pick the editor that the
2537 # user has requested via their $EDITOR environment variable
2538 if [ -x "/usr/bin/sensible-editor" ]; then
2539 /usr/bin/sensible-editor "$CDDBDATA"
2540 elif [ -n "$EDITOR" ]; then
2541 if [ -x $(which "${EDITOR%%\ *}") ]; then
2542 # That failed, try to load the preferred editor, starting
2543 # with their EDITOR variable
2544 eval $(echo "$EDITOR") \"$CDDBDATA\"
2545 fi
2546 # If that fails, check for a vi
2547 elif which vi >/dev/null 2>&1; then
2548 vi "$CDDBDATA"
2549 elif [ -x /usr/bin/vim ]; then
2550 /usr/bin/vim "$CDDBDATA"
2551 elif [ -x /usr/bin/vi ]; then
2552 /usr/bin/vi "$CDDBDATA"
2553 elif [ -x /bin/vi ]; then
2554 /bin/vi "$CDDBDATA"
2555 # nano should be on all (modern, i.e., sarge) debian systems
2556 elif which nano >/dev/null 2>&1 ; then
2557 nano "$CDDBDATA"
2558 elif [ -x /usr/bin/nano ]; then
2559 /usr/bin/nano "$CDDBDATA"
2560 # mg should be on all OpenBSD systems
2561 elif which mg >/dev/null 2>&1 ; then
2562 mg "$CDDBDATA"
2563 elif [ -x /usr/bin/mg ]; then
2564 /usr/bin/mg "$CDDBDATA"
2565 # bomb out
2566 else
2567 log warning "no editor available. Check your EDITOR environment variable."
2568 fi
2569 # delete editor backup file if it exists
2570 if [ -w "$CDDBDATA~" ]; then
2571 rm -f "$CDDBDATA~"
2572 fi
2573 fi
2574
2575 # Some heuristics first. Look at Disc Title, and if it starts with
2576 # "Various", then we'll assume Various Artists
2577 if [ "$(grep ^DTITLE= "$CDDBDATA" | cut -f2- -d= | egrep -ci '^(various|soundtrack|varios|sonora|ost)')" != "0" ]; then
2578 echo "Looks like a Multi-Artist CD" >&2
2579 VARIOUSARTISTS=y
2580 else
2581 echo -n "Is the CD multi-artist? [y/n] (n): " >&2
2582 if [ "$INTERACTIVE" = "y" ]; then
2583 read VARIOUSARTISTS
2584 else
2585 echo n >&2
2586 VARIOUSARTISTS=n
2587 fi
2588 fi
2589 if [ "$VARIOUSARTISTS" = "y" ] && [ ! "$ONETRACK" = "y" ]; then
2590 # Set a default
2591 DEFAULTSTYLE=1
2592 # Need NUMTRACKS before cddb-tool will return it:
2593 NUMTRACKS=$(egrep '^TTITLE[0-9]+=' "$CDDBDATA" | wc -l)
2594 if [ "$(grep -c "^TTITLE.*\/" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2595 # More than 1/2 tracks contain a "/", so guess forward
2596 DEFAULTSTYLE=1
2597 elif [ "$(grep -c "^TTITLE.*\-" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2598 # More than 1/2 contain a "-", so guess forward-dash
2599 DEFAULTSTYLE=2
2600 elif [ "$(grep -c "^TTITLE.*(.*)" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2601 # More than 1/2 contain something in parens, so guess trailing-paren
2602 DEFAULTSTYLE=6
2603 fi
2604
2605 echo "1) Artist / Title" >&2
2606 echo "2) Artist - Title" >&2
2607 echo "3) Title / Artist" >&2
2608 echo "4) Title - Artist" >&2
2609 echo "5) Artist: Title" >&2
2610 echo "6) Title (Artist)" >&2
2611 echo "7) This is a single-artist CD" >&2
2612 echo -n "Which style of multiple artist entries is it? [1-7] ($DEFAULTSTYLE): " >&2
2613 if [ "$INTERACTIVE" = "y" ]; then
2614 read VARIOUSARTISTSTYLE
2615 else
2616 echo $DEFAULTSTYLE >&2
2617 VARIOUSARTISTSTYLE=$DEFAULTSTYLE
2618 fi
2619 VARIOUSARTISTSTYLE=$(echo 0$VARIOUSARTISTSTYLE | xargs printf %d)
2620 # If they press Enter, then the default style (0) was chosen
2621 while [ $VARIOUSARTISTSTYLE -lt 0 ] || [ $VARIOUSARTISTSTYLE -gt 7 ]; do
2622 echo "Invalid selection. Please choose a number between 1 and 7."
2623 echo -n "Selection [1-7]: "
2624 read VARIOUSARTISTSTYLE
2625 VARIOUSARTISTSTYLE=$(echo 0$VARIOUSARTISTSTYLE | xargs printf %d)
2626 done
2627 if [ "$VARIOUSARTISTSTYLE" = "0" ]; then
2628 VARIOUSARTISTSTYLE=$DEFAULTSTYLE
2629 fi
2630 vecho "Selected: $VARIOUSARTISTSTYLE"
2631 case "$VARIOUSARTISTSTYLE" in
2632 1) # Artist / Title
2633 VARIOUSARTISTSTYLE=forward
2634 ;;
2635 2) # Artist - Title
2636 VARIOUSARTISTSTYLE=forward-dash
2637 ;;
2638 3) # Title / Artist
2639 VARIOUSARTISTSTYLE=reverse
2640 ;;
2641 4) # Title - Artist
2642 VARIOUSARTISTSTYLE=reverse-dash
2643 ;;
2644 5) # Artist: Title
2645 VARIOUSARTISTSTYLE=colon
2646 ;;
2647 6) # Title (Artist)
2648 VARIOUSARTISTSTYLE=trailing-paren
2649 ;;
2650 7) # Single Artist
2651 VARIOUSARTISTS=n
2652 ;;
2653 esac
2654 fi
2655
2656 echo "variousartists=$VARIOUSARTISTS" >> "$ABCDETEMPDIR/status"
2657 echo "variousartiststyle=$VARIOUSARTISTSTYLE" >> "$ABCDETEMPDIR/status"
2658
2659 if [ "$EDITCDDB" = "y" ] && [ "$UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE" = "y" ]; then
2660 if [ "$CDDBDATAMD5SUM" != "" ] && [ "$CDDBDATAMD5SUM" != "$($MD5SUM "$CDDBDATA" | cut -d " " -f 1)" ]; then
2661 # This works but does not have the necessary error checking
2662 # yet. If you are familiar with the CDDB spec
2663 # (see http://www.freedb.org/src/latest/DBFORMAT)
2664 # and can create an error-free entry on your own, then put
2665 # UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE=y in your
2666 # abcde.conf to enable it. Put CDDBSUBMIT=email@address in
2667 # your abcde.conf to change the email address submissions are
2668 # sent to.
2669
2670 # submit the modified file, if they want
2671 if [ "$NOSUBMIT" != "y" ]; then
2672 echo -n "Do you want to submit this entry to $CDDBSUBMIT? [y/n] (n): "
2673 read YESNO
2674 while [ "$YESNO" != "y" ] && [ "$YESNO" != "n" ] && [ "$YESNO" != "Y" ] && \
2675 [ "$YESNO" != "N" ] && [ "$YESNO" != "" ]
2676 do
2677 echo -n 'Invalid selection. Please answer "y" or "n": '
2678 read YESNO
2679 done
2680 if [ "$YESNO" = "y" ] || [ "$YESNO" = "Y" ]; then
2681 echo -n "Sending..."
2682 $CDDBTOOL send "$CDDBDATA" $CDDBSUBMIT
2683 echo "done."
2684 fi
2685 fi
2686 fi
2687 fi
2688 ### FIXME ###
2689 # User CDDBLOCALPOLICY to find out if we store the file or not...
2690 # Cache edited CDDB entry in the user's cddb dir
2691 if [ "$CDDBCOPYLOCAL" = "y" ]; then
2692 # Make sure the cache directory exists
2693 mkdir -p $CDDBLOCALDIR
2694 cat "$CDDBDATA" | tail -n $(expr $(cat "$CDDBDATA" | wc -l ) - 1 ) > ${CDDBLOCALDIR}/$(echo "$TRACKINFO" | cut -d' ' -f1)
2695 fi
2696
2697 echo "cddb-edit" >> "$ABCDETEMPDIR/status"
2698 }
2699
2700 # do_cdread [tracknumber]
2701 # do_cdread onetrack [firsttrack] [lasttrack]
2702 #
2703 do_cdread ()
2704 {
2705 # The commands here don't go through run_command because they're never supposed to be silenced
2706 # return codes need to be doublechecked anyway, however
2707 if [ "$1" = "onetrack" ]; then
2708 # FIXME # Add the possibility of grabbing ranges of tracks in onetrack
2709 # FIXME # Until then, we grab the whole CD in one track, no matter what
2710 # the user said
2711 # We need the first and last track for cdda2wav
2712 FIRSTTRACK=$2
2713 LASTTRACK=$(expr $3 + 0)
2714 UTRACKNUM=$FIRSTTRACK
2715 case "$CDROMREADERSYNTAX" in
2716 flac) READTRACKNUMS="$FIRSTTRACK.1-$(($LASTTRACK + 1)).0" ;;
2717 cdparanoia)
2718 #XX FIXME XX
2719 # Add a variable to check if tracks are provided in command line and if not, use "0-" to rip the tracks
2720 READTRACKNUMS="$FIRSTTRACK-$LASTTRACK" ;;
2721 cdda2wav) READTRACKNUMS="$FIRSTTRACK+$LASTTRACK" ;;
2722 *) echo "abcde error: $CDROMREADERSYNTAX does not support ONETRACK mode"
2723 exit 1 ;;
2724 esac
2725 else
2726 UTRACKNUM=$1
2727 fi
2728 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
2729 if [ "$USEPIPES" = "y" ]; then
2730 TEMPARG="PIPERIPPER_$CDROMREADERSYNTAX"
2731 FILEARG="$( eval echo "\$$TEMPARG" )"
2732 REDIR=""
2733 PIPE_MESSAGE="and encoding "
2734 else
2735 WAVDATA="$ABCDETEMPDIR/track$UTRACKNUM.wav"
2736 case "$CDROMREADERSYNTAX" in
2737 ## FIXME ## Find the cases for dagrab and flac, to avoid exceptions
2738 flac)
2739 FILEARG="--output-name=$WAVDATA"
2740 ;;
2741 dagrab)
2742 FILEARG="-f $WAVDATA"
2743 ;;
2744 *)
2745 FILEARG="$WAVDATA"
2746 ;;
2747 esac
2748 REDIR=">&2"
2749 fi
2750 if [ "$1" = "onetrack" ]; then
2751 echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2
2752 else
2753 if [ -r "$CDDBDATA" ]; then
2754 getcddbinfo TRACKNAME
2755 echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM: $TRACKNAME..." >&2
2756 else
2757 echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM..." >&2
2758 fi
2759 fi
2760 case "$CDROMREADERSYNTAX" in
2761 ### FIXME ### use an exception for flac, since it uses -o
2762 ### FIXME ### Shall we just use -o $FILEARG ??
2763 flac)
2764 # Avoid problems wit math expressions by unpadding the given UTRACKNUM
2765 STRIPTRACKNUM=$(expr $UTRACKNUM + 0)
2766 nice $READNICE $FLAC -d -f --cue=${READTRACKNUMS:-$STRIPTRACKNUM.1-$(($STRIPTRACKNUM + 1)).0} "$FILEARG" "$CDROM" ;;
2767 cdparanoia)
2768 nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR ;;
2769 cdda2wav)
2770 if [ "$OSFLAVOUR" = "OSX" ] ; then
2771 # Hei, we have to unmount the device before running anything like cdda2wav in OSX
2772 disktool -u ${CDROM#/dev/} 0
2773 # Also, in OSX the cdrom device for cdda2wav changes...
2774 CDDA2WAVCDROM="IODVDServices"
2775 elif [ "$OSFLAVOUR" = "FBSD" ] ; then
2776 CDDA2WAVCDROM="$CDROMID"
2777 else
2778 if [ "$CDROMID" = "" ]; then
2779 CDDA2WAVCDROM="$CDROM"
2780 else
2781 CDDA2WAVCDROM="$CDROMID"
2782 fi
2783 fi
2784 nice $READNICE $CDROMREADER -D $CDDA2WAVCDROM -t ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR
2785 ;;
2786 ## FIXME ## We have an exception for dagrab, since it uses -f
2787 ## FIXME ## Shall we just use -f $FILEARG ??
2788 dagrab) nice $READNICE $CDROMREADER -d "$CDROM" -v $UTRACKNUM "$FILEARG" $REDIR
2789 ;;
2790 cddafs)
2791 # Find the track's mounted path
2792 REALTRACKNUM=$(expr $UTRACKNUM + 0)
2793 FILEPATH=$(mount | grep "$CDROM on" | sed 's/^[^ ]* on \(.*\) (.*/\1/')
2794 FILEPATH=$(find "$FILEPATH" | grep "/$REALTRACKNUM ");
2795 # If the file exists, copy it
2796 if [ -e "$FILEPATH" ] ; then
2797 nice $READNICE $CDROMREADER "$FILEPATH" "$FILEARG" $REDIR
2798 else
2799 false
2800 fi ;;
2801 debug) nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -w $UTRACKNUM-[:1] "$FILEARG" $REDIR
2802 ;;
2803 esac
2804 RETURN=$?
2805 # If we get some error or we get some missing wav
2806 # (as long as we dont use pipes)
2807 if [ "$RETURN" != "0" -o \( ! -s "$WAVDATA" -a X"$USEPIPES" != "Xy" \) ]; then
2808 # Thank goodness errors is only machine-parseable up to the
2809 # first colon, otherwise this woulda sucked
2810 if [ "$RETURN" = "0" -a ! -s "$WAVDATA" ]; then
2811 RETURN=73 # fake a return code as cdparanoia return 0 also on aborted reads
2812 fi
2813 if [ "$USEPIPES" = "y" ]; then
2814 echo "readencodetrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
2815 else
2816 echo "readtrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
2817 fi
2818 return $RETURN
2819 else
2820 if [ "$USEPIPES" = "y" ]; then
2821 echo readencodetrack-$UTRACKNUM >> "$ABCDETEMPDIR/status"
2822 else
2823 echo readtrack-$UTRACKNUM >> "$ABCDETEMPDIR/status"
2824 fi
2825 if [ "$1" = "onetrack" ]; then
2826 echo onetrack >> "$ABCDETEMPDIR/status"
2827 fi
2828 fi
2829 }
2830
2831 # do_cdspeed
2832 # No values accepted, only uses env variables
2833 do_cdspeed ()
2834 {
2835 if "$CDSPEED" "$CDSPEEDOPTS" "$CDSPEEDVALUE" >/dev/null ; then
2836 vecho "Setting CD speed to ${CDSPEEDVALUE}x"
2837 else
2838 echo "abcde: unable to set the device speed" >&2
2839 fi
2840 }
2841
2842 # vecho [message]
2843 #
2844 # vecho outputs a message if EXTRAVERBOSE is selected
2845 vecho ()
2846 {
2847 if [ x"$EXTRAVERBOSE" != "x" ]; then
2848 case $1 in
2849 warning) shift ; log warning "$@" ;;
2850 *) echo "$@" ;;
2851 esac
2852 fi
2853 }
2854
2855 # decho [message]
2856 #
2857 # decho outputs a debug message if DEBUG is selected
2858 decho ()
2859 {
2860 if [ x"$DEBUG" != "x" ]; then
2861 if echo $1 | grep "^\[" > /dev/null 2>&1 ; then
2862 DEBUGECHO=$(echo "$@" | tr -d '[]')
2863 echo "[DEBUG] $DEBUGECHO: `eval echo \\$${DEBUGECHO}`"
2864 else
2865 echo "[DEBUG] $1"
2866 fi
2867 fi
2868 }
2869
2870 # User-redefinable functions
2871 # Custom filename munging:
2872 mungefilename ()
2873 {
2874 #echo "$@" | sed s,:,\ -,g | tr \ /\* __+ | tr -d \'\"\?\[:cntrl:\]
2875 echo "$@" | sed s,:,\ -,g | tr \ / __ | tr -d \'\"\?\[:cntrl:\]
2876 }
2877
2878 # Custom genre munging:
2879 mungegenre ()
2880 {
2881 echo $CDGENRE | tr "[:upper:]" "[:lower:]"
2882 }
2883
2884 # pre_read
2885 # Empty pre_read function, to be defined in the configuration file.
2886 pre_read ()
2887 {
2888 :
2889 }
2890
2891 # post_read
2892 # Empty post_read function, to be defined in the configuration file.
2893 post_read ()
2894 {
2895 :
2896 }
2897
2898 # post_encode
2899 # Empty post_encode function, to be defined in the configuration file.
2900 post_encode ()
2901 {
2902 :
2903 }
2904
2905 ###############################################################################
2906 # End of functions
2907 #
2908 # Start of execution
2909 ###############################################################################
2910
2911 # Builtin defaults
2912
2913 # CDDB
2914 # Defaults to FreeDB, but a python musicbrainz can be used
2915 CDDBMETHOD=cddb
2916 CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"
2917 CDDBSUBMIT=freedb-submit@freedb.org
2918 CDDBPROTO=6
2919 HELLOINFO="$(whoami)@$(hostname)"
2920 CDDBCOPYLOCAL="n"
2921 CDDBLOCALPOLICY="always"
2922 CDDBLOCALRECURSIVE="y"
2923 CDDBLOCALDIR="$HOME/.cddb"
2924 CDDBUSELOCAL="n"
2925
2926 # List of fields we parse and show during the CDDB parsing...
2927 SHOWCDDBFIELDS="year,genre"
2928
2929 INTERACTIVE=y
2930 #CDROMREADERSYNTAX=cdparanoia
2931 ENCODERSYNTAX=default
2932
2933 MP3ENCODERSYNTAX=default
2934 OGGENCODERSYNTAX=default
2935 FLACENCODERSYNTAX=default
2936 SPEEXENCODERSYNTAX=default
2937 MPPENCODERSYNTAX=default
2938 AACENCODERSYNTAX=default
2939 NORMALIZERSYNTAX=default
2940 CUEREADERSYNTAX=default
2941
2942 OUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${TRACKNUM}.${TRACKFILE}'
2943 # Use the following VAOUTPUTFORMAT to revert to 2.0.x VA format:
2944 #VAOUTPUTFORMAT=${OUTPUTFORMAT}
2945 VAOUTPUTFORMAT='Various-${ALBUMFILE}/${TRACKNUM}.${ARTISTFILE}-${TRACKFILE}'
2946 ONETRACKOUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${ALBUMFILE}'
2947 VAONETRACKOUTPUTFORMAT='Various-${ALBUMFILE}/${ALBUMFILE}'
2948 PLAYLISTFORMAT='${ARTISTFILE}-${ALBUMFILE}.${OUTPUT}.m3u'
2949 PLAYLISTDATAPREFIX=''
2950 VAPLAYLISTFORMAT='${ARTISTFILE}-${ALBUMFILE}.${OUTPUT}.m3u'
2951 VAPLAYLISTDATAPREFIX=''
2952 DOSPLAYLIST=n
2953 COMMENT=''
2954 ID3TAGV=2
2955 ENCNICE=10
2956 READNICE=10
2957 DISTMP3NICE=10
2958 VARIOUSARTISTS=n
2959 VARIOUSARTISTSTYLE=forward
2960 KEEPWAVS=n
2961 PADTRACKS=n
2962 NOGAP=n
2963 BATCHNORM=n
2964 NOCDDBQUERY=n
2965
2966 # If using scsi devices, cdda2wav needs a CDROMID, instead of a device node
2967 # i.e. CDROMID="1,0,0"
2968 CDROMID=""
2969 # If we are using the IDE bus, we need CDPARANOIACDROMBUS defined as "d"
2970 # If we are using the ide-scsi emulation layer, we need to define a "g"
2971 CDPARANOIACDROMBUS="d"
2972
2973 # program paths - defaults to checking your $PATH
2974 # mp3
2975 LAME=lame
2976 TOOLAME=toolame
2977 GOGO=gogo
2978 BLADEENC=bladeenc
2979 L3ENC=l3enc
2980 XINGMP3ENC=xingmp3enc
2981 MP3ENC=mp3enc
2982 # ogg
2983 VORBIZE=vorbize
2984 OGGENC=oggenc
2985 # flac
2986 FLAC=flac
2987 # speex
2988 SPEEXENC=speexenc
2989 # mpp (Musepack)
2990 MPPENC=mppenc
2991 # m4a
2992 AACENC=faac
2993
2994 ID3=id3
2995 ID3V2=id3v2
2996 EYED3=eyeD3
2997 VORBISCOMMENT=vorbiscomment
2998 METAFLAC=metaflac
2999 AACTAG=faac
3000
3001 CDPARANOIA=cdparanoia
3002 CDDA2WAV=cdda2wav
3003 DAGRAB=dagrab
3004 CDDAFS=cp
3005 CDDISCID=cd-discid
3006 CDDBTOOL=cddb-tool
3007 MUSICBRAINZ=musicbrainz-get-tracks
3008 EJECT=eject
3009 MD5SUM=md5sum
3010 DISTMP3=distmp3
3011 NORMALIZE=normalize-audio
3012 CDSPEED=eject
3013 VORBISGAIN=vorbisgain
3014 MP3GAIN=mp3gain
3015 MPPGAIN=replaygain
3016 MKCUE=mkcue
3017 MKTOC=cdrdao
3018 DIFF=diff
3019 CUE2DISCID=builtin
3020
3021 # Options for programs called from abcde
3022 # mp3
3023 LAMEOPTS=
3024 TOOLAMEOPTS=
3025 GOGOOPTS=
3026 BLADEENCOPTS=
3027 L3ENCOPTS=
3028 XINGMP3ENCOPTS=
3029 MP3ENCOPTS=
3030 # ogg
3031 VORBIZEOPTS=
3032 OGGENCOPTS=
3033 # flac
3034 FLACOPTS=
3035 # speex
3036 SPEEXENCOPTS=
3037 # mpc
3038 MPPENCOPTS=
3039 # m4a
3040 AACENCOPTS=
3041
3042 ID3OPTS=
3043 ID3V2OPTS=
3044 CDPARANOIAOPTS=
3045 CDDA2WAVOPTS=
3046 DAGRABOPTS=
3047 CDDAFSOPTS="-f"
3048 CDDBTOOLOPTS=
3049 EJECTOPTS=
3050 DISTMP3OPTS=
3051 NORMALIZEOPTS=
3052 CDSPEEDOPTS="-x"
3053 CDSPEEDVALUE=
3054 MKCUEOPTS=
3055 MKTOCOPTS=""
3056 VORBISCOMMENTOPTS="-R"
3057 METAFLACOPTS="--no-utf8-convert"
3058 DIFFOPTS=
3059
3060 # Default to one process if -j isn't specified
3061 MAXPROCS=1
3062
3063 # List of actions to perform - by default, run to completion
3064 ACTIONS=cddb,read,encode,tag,move,clean
3065
3066 # This option is basicaly for Debian package dependencies:
3067 # List of prefered outputs - by default, run with whatever we have in the path
3068 DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:toolame,mp3:lame,mp3:bladeenc,spx:speex,m4a:faac
3069
3070 # List of prefered cdromreaders - by default, run whichever we have in the path
3071 DEFAULT_CDROMREADERS="cdparanoia cdda2wav"
3072
3073 # List of quality levels associated with the encoders:
3074 DEFAULT_QUALITY_XLO="oggenc:-q -1,lame:-q 9,speex:--quality 1,m4a:"
3075 DEFAULT_QUALITY_LO="oggenc:-q 1,lame:-q 7,speex:--quality 5,m4a:"
3076 DEFAULT_QUALITY_HI="oggenc:-q 7,lame:--preset standard,speex:--quality 9,m4a:"
3077 DEFAULT_QUALITY_XHI="oggenc:-q 10,lame:--preset extreme,speex:--quality 10,m4a:"
3078
3079 # Asume fetch if under FreeBSD. curl is used for Mac OS X. wget is used for
3080 # Linux/OpenBSD. ftp is user for NetBSD.
3081 # Let's use these checkings to determine the OS flavour, which will be used
3082 # later
3083 if [ X$(uname) = "XFreeBSD" ] ; then
3084 HTTPGET=fetch
3085 MD5SUM=md5
3086 NEEDCDROMID=y
3087 OSFLAVOUR=FBSD
3088 elif [ X$(uname) = "XDarwin" ] ; then
3089 HTTPGET=curl
3090 OSFLAVOUR=OSX
3091 # We should have disktool in OSX, but let's be sure...
3092 NEEDDISKTOOL=y
3093 CDROMREADERSYNTAX=cddafs
3094 elif [ X$(uname) = "XOpenBSD" ] ; then
3095 HTTPGET=wget
3096 MD5SUM=md5
3097 OSFLAVOUR=OBSD
3098 elif [ X$(uname) = "XNetBSD" ] ; then
3099 HTTPGET=ftp
3100 MD5SUM=md5
3101 OSFLAVOUR=NBSD
3102 elif [ X$(uname) = "SunOS" ] ; then
3103 HTTPGET=""
3104 MD5SUM=md5
3105 OSFLAVOUR=SunOS
3106 else
3107 HTTPGET=wget
3108 fi
3109
3110 # If CDDBAVAIL is set to n, no CDDB read is done
3111 # If USEID3 is set to n, no ID3 tagging is done
3112 CDDBAVAIL=y
3113 USEID3=y
3114 USEID3V2=y
3115
3116 # There we go..
3117 # But before we get into business, let us chop off any GREP environmental
3118 # variables.
3119 GREP_OPTIONS=""
3120 GREP_COLOR=""
3121
3122 if [ -z "$OUTPUTDIR" ]; then
3123 OUTPUTDIR=$(pwd)
3124 fi
3125
3126 if [ -z "$WAVOUTPUTDIR" ]; then
3127 WAVOUTPUTDIR="$OUTPUTDIR"
3128 fi
3129
3130 # Load system defaults
3131 if [ -r /etc/abcde.conf ]; then
3132 . /etc/abcde.conf
3133 fi
3134 # Load user preference defaults
3135 if [ -r $HOME/.abcde.conf ]; then
3136 . $HOME/.abcde.conf
3137 fi
3138
3139 # By this time, we need some HTTPGETOPTS already defined.
3140 # If the user has defined a non-default HTTPGET method, we should not be empty.
3141
3142 if [ "$HTTPGETOPTS" = "" ] ; then
3143 case $HTTPGET in
3144 wget) HTTPGETOPTS="-q -nv -e timestamping=off -O -";;
3145 curl) HTTPGETOPTS="-f -s";;
3146 fetch)HTTPGETOPTS="-q -o -";;
3147 ftp) HTTPGETOPTS="-a -V -o - ";;
3148 *) log warning "HTTPGET in non-standard and HTTPGETOPTS are not defined." ;;
3149 esac
3150 fi
3151
3152 # If the CDROM has not been set yet, find a suitable one.
3153 # If this is a devfs system, default to /dev/cdroms/cdrom0
3154 # instead of /dev/cdrom
3155 if [ "$CDROM" = "" ] ; then
3156 if [ -e /dev/cdroms/cdrom0 ]; then
3157 CDROM=/dev/cdroms/cdrom0
3158 elif [ -e /dev/cdrom ]; then
3159 CDROM=/dev/cdrom
3160 elif [ -e /dev/cd0c ]; then
3161 CDROM=/dev/cd0c
3162 elif [ -e /dev/acd0c ]; then
3163 CDROM=/dev/acd0c
3164 elif [ -e /dev/disk1 ]; then
3165 CDROM=/dev/disk1
3166 fi
3167 fi
3168
3169 # Parse command line options
3170 #while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPq:r:Rs:S:t:T:vVxw:W: opt ; do
3171 while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:UvVxX:w:W:z opt ; do
3172 case "$opt" in
3173 1) ONETRACK=y ;;
3174 a) ACTIONS="$OPTARG" ;;
3175 A) EXPACTIONS="$OPTARG" ;;
3176 b) BATCHNORM=y ;;
3177 B) NOBATCHREPLAYGAIN=y ;;
3178 c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else log error "config file \"$OPTARG\" cannot be found." ; exit 1 ; fi ;;
3179 C) DISCID="$( echo ${OPTARG#abcde.} | tr -d /)" ;;
3180 d) CDROM="$OPTARG" ;;
3181 D) set -x ;;
3182 h) usage; exit ;;
3183 e) ERASEENCODEDSTATUS=y ;;
3184 E) ENCODING="$OPTARG" ;;
3185 f) FORCE=y ;;
3186 g) NOGAP=y ;;
3187 i) INLINETAG=y ;;
3188 j) MAXPROCS="$OPTARG" ;;
3189 k) KEEPWAVS=y ;;
3190 l) LOWDISK=y ;;
3191 L) CDDBUSELOCAL=y ;;
3192 n) CDDBAVAIL=n ;;
3193 N) INTERACTIVE=n ;;
3194 m) DOSPLAYLIST=y ;;
3195 M) DOCUE=y ;;
3196 o) OUTPUTTYPE="$OPTARG" ;;
3197 p) PADTRACKS=y ;;
3198 P) USEPIPES=y ;;
3199 q) QUALITYLEVEL="$OPTARG" ;;
3200 r) REMOTEHOSTS="$OPTARG" ;;
3201 R) CDDBLOCALRECURSIVE=y ;;
3202 s) SHOWCDDBFIELDS="$OPTARG" ;;
3203 S) CDSPEEDVALUE="$OPTARG" ;;
3204 t) STARTTRACKNUMBER="$OPTARG" ;;
3205 T) STARTTRACKNUMBER="$OPTARG" ; STARTTRACKNUMBERTAG="y" ;;
3206 U) CDDBPROTO=5 ;;
3207 v)
3208 echo "This is abcde v$VERSION."
3209 echo "Usage: abcde [options] [tracks]"
3210 echo "abcde -h for extra help"
3211 exit
3212 ;;
3213 V) EXTRAVERBOSE="y" ;;
3214 x) EJECTCD="y" ;;
3215 X) CUE2DISCID="$OPTARG" ;;
3216 w) COMMENT="$OPTARG" ;;
3217 W) if echo $OPTARG | grep "[[:digit:]]" > /dev/null 2>&1 ; then
3218 STARTTRACKNUMBER="${OPTARG}01"
3219 STARTTRACKNUMBERTAG="y"
3220 COMMENT="CD${OPTARG}"
3221 DISCNUMBER="${OPTARG}"
3222 else
3223 log error "argument of -W must be integer"
3224 exit 1
3225 fi
3226 ;;
3227 z) DEBUG=y ; CDROMREADERSYNTAX=debug ; EJECTCD="n" ;;
3228 ?) usage; exit ;;
3229 esac
3230 done
3231
3232 shift $(($OPTIND - 1))
3233
3234 # Here it comes the worse part of the whole thing. From here until we start
3235 # ripping, we have a mixture of sanity checks, verifications, default settigs
3236 # and other crazy stuff that interdepends, but hey, someone has to do it.
3237
3238 # If NOCDDBQUERY is set, don't query the CDDB server.
3239 if [ "$NOCDDBQUERY" = "y" ]; then
3240 CDDBAVAIL="n"
3241 fi
3242
3243 # If the user specified a flac file, then switch to special flac mode
3244 if echo "$CDROM" | grep -i '.flac$' > /dev/null 2>&1 ; then
3245 if [ ! -f "$CDROM" ]; then
3246 log error "the defined file for FLAC ripping cannot be found" >&2
3247 exit 1
3248 fi
3249 vecho warning "switching to flac CDROMREADERSYNTAX..."
3250 CDROMREADERSYNTAX=flac
3251 # We have a builtin version of cue2discid...
3252 case "$CUE2DISCID" in
3253 builtin);;
3254 *) NEEDCUE2DISCID=y;;
3255 esac
3256 NEEDMETAFLAC=y
3257 EJECTCD=n
3258 fi
3259
3260 # If the user provided a DISCID, disable eject
3261 if [ -n "$DISCID" ] || [ "$CDROMREADERSYNTAX" = "flac" ]; then EJECTCD=n ; fi
3262
3263 # Check the available cd rippers in the system, from the ones we know.
3264 if [ "$CDROMREADERSYNTAX" = "" ]; then
3265 for DEFAULT_CDROMREADER in $DEFAULT_CDROMREADERS; do
3266 if new_checkexec $DEFAULT_CDROMREADER; then
3267 CDROMREADERSYNTAX=$DEFAULT_CDROMREADER
3268 break
3269 fi
3270 done
3271 if [ "$CDROMREADERSYNTAX" = "" ]; then
3272 log error "no cdreader found in your PATH"
3273 log error "hints: are all dependencies installed? has the \$PATH been modified?"
3274 exit 1
3275 fi
3276 fi
3277
3278 # Decide if we can continue.
3279 if [ "$ONETRACK" = "y" ]; then
3280 # FIXME # remove check as soon as we find out about the other readers
3281 case "$CDROMREADERSYNTAX" in
3282 flac) ;;
3283 cdparanoia) ;;
3284 cdda2wav) ;;
3285 *) log error "$CDROMREADERSYNTAX does not support ONETRACK mode"
3286 exit 1 ;;
3287 esac
3288 if [ "$BATCHNORM" = "y" ]; then
3289 log warning "BATCHNORM mode is not compatible with ONETRACK mode. Disabling..."
3290 BATCHNORM=n
3291 fi
3292 if [ "$NOGAP" = "y" ]; then
3293 log warning "NOGAP mode is not compatible with ONETRACK mode. Disabling..."
3294 NOGAP=n
3295 fi
3296 # It does not matter how many tracks we want. In ONETRACK mode we grab them all
3297 # FIXME # allow ranges of tracks to be selected for onetrack ripping
3298 if [ $# -gt 0 ]; then
3299 log warning "ONETRACK mode selected, grabbing all tracks..."
3300 fi
3301 else
3302 while [ $# -gt 0 ]; do
3303 # Range parsing code courtesy of Vincent Ho
3304 # Cleaned up to use shell built-ins by Charles Steinkuehler
3305 if [ "${1#*[^0-9-]}" != "$1" ]; then
3306 log error "syntax error while processing track numbers"
3307 else
3308 RSTART=${1%%-*}
3309 REND=${1##*-}
3310 while [ ${RSTART:=1} -le ${REND:=0} ] ; do
3311 TRACKQUEUE="$TRACKQUEUE $RSTART"
3312 RSTART=$(( $RSTART + 1 ))
3313 done
3314 fi
3315 shift
3316 done
3317 fi
3318
3319 # List of valid actions: cddb,read,normalize,encode,tag,move,playlist,clean
3320 # List of experimental actions: retag,transcode
3321
3322 # Determine what actions are to be done from $ACTIONS and set the
3323 # following environment variables for them:
3324 DOCDDB=n
3325 DOREAD=n
3326 DONORMALIZE=n
3327 DOPREPROCESS=n
3328 DOENCODE=n
3329 DOPOSTPROCESS=n
3330 DOTAG=n
3331 DOMOVE=n
3332 DOREPLAYGAIN=n
3333 DOPLAYLIST=n
3334 DOCLEAN=n
3335 ## FIXME ## Lets keep compatibility with -M
3336 [ "$DOCUE" != "y" ] && DOCUE=n
3337
3338 for ACTION in $(echo $ACTIONS | tr , \ )
3339 do
3340 case $ACTION in
3341 default) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOCLEAN=y;;
3342 cue) DOCUE=y ; MAKECUEFILE=y ;;
3343 cddb) DOCDDB=y;;
3344 read) DOREAD=y;;
3345 normalize) DONORMALIZE=y; DOREAD=y;;
3346 # preprocess) DOPREPROCESS=y; DOREAD=y;;
3347 encode) DOENCODE=y; DOREAD=y;;
3348 # postprocess) DOPREPROCESS=y; DOENCODE=y; DOREAD=y;;
3349 tag) DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
3350 move) DOMOVE=y; DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
3351 replaygain) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOREPLAYGAIN=y;;
3352 playlist) DOCDDB=y; DOPLAYLIST=y;;
3353 clean) DOCLEAN=y;;
3354 esac
3355 done
3356
3357 if [ "$DONORMALIZE" = "y" ] && [ "$DOREPLAYGAIN" = "y" ]; then
3358 # FIXME # should we abort on error or just inform the user?
3359 log warning "selected both normalize and replaygain actions"
3360 fi
3361
3362 for SHOWCDDBFIELD in $(echo $SHOWCDDBFIELDS | tr , \ ); do
3363 case $SHOWCDDBFIELD in
3364 y*|Y*) SHOWCDDBYEAR="y";;
3365 g*|G*) SHOWCDDBGENRE="y";;
3366 *) ;;
3367 esac
3368 done
3369
3370 # At this point a CDROM has to be defined, so we check it exists.
3371 if [ X"$CDROM" != "X" ] ; then
3372 if [ "$CDROMREADERSYNTAX" = "cdda2wav" ] && [ "$NEEDCDROMID" = "y" ] ; then
3373 if [ "$OSFLAVOUR" = "FBSD" ]; then
3374 if echo "$CDROMID" | grep "^[0-9],[0-9],[0-9]$" >/dev/null 2>&1 ; then :; else
3375 log error "CDROMID not in the right format for $CDROMREADERSYNTAX"
3376 log error "Use \"cdrecord -scanbus\" to obtain a adecuate ID an set CDROMID accordingly"
3377 exit 1
3378 fi
3379 fi
3380 elif [ ! -e "$CDROM" -a X"$DOREAD" = "Xy" ]; then
3381 log error "CDROM device cannot be found."
3382 exit 1
3383 fi
3384 # avoid processing if we are not going to hit the CDROM.
3385 elif [ X"$DOREAD" = "Xy" ]; then
3386 log error "CDROM has not been defined or cannot be found"
3387 exit 1
3388 fi
3389
3390 # USEPIPES pre-tests, before we get into more serious stuff
3391 # Not compatible with:
3392 # - multiple outputs
3393 # - normalize
3394 # - lowdisk algorithm
3395 # - anything else?
3396 if [ X"$USEPIPES" = "Xy" ]; then
3397 if [ $(echo "$OUTPUTTYPE" | tr , \ | wc -w ) -gt 1 ]; then
3398 log error "Unix pipes not compatible with multiple outputs"
3399 exit 1
3400 fi
3401 if [ X"$DONORMALIZE" = "Xy" ]; then
3402 log error "Unix pipes not compatible with normalizer"
3403 # FIXME # Do we need to exit or shall we just disable the mode?
3404 exit 1
3405 fi
3406 if [ X"$BATCHNORM" = "Xy" ]; then
3407 log error "Unix pipes not compatible with BATCHNORM encoding"
3408 exit 1
3409 fi
3410 if [ X"$NOGAP" = "Xy" ]; then
3411 log error "Unix pipes not compatible with NOGAP encoding"
3412 exit 1
3413 fi
3414 if [ X"$DOENCODE" = "Xn" ]; then
3415 vecho warning "Disabling Unix pipes since we are not encoding!"
3416 USEPIPES=n
3417 fi
3418 if [ X"$LOWDISK" = "Xy" ]; then
3419 log error "Unix pipes not compatible with lowdisk algorithm"
3420 exit 1
3421 fi
3422 fi
3423
3424 # LOWDISK pre-tests, before we get into more problematic stuff
3425 # Not compatible with anything that needs all the files in the hard disc:
3426 # - BATCHNORM
3427 # - NOGAP lame mode
3428 if [ X"$LOWDISK" = "Xy" ]; then
3429 if [ X"$BATCHNORM" = "Xy" ]; then
3430 log error "Unix pipes not compatible with BATCHNORM encoding"
3431 exit 1
3432 fi
3433 if [ X"$NOGAP" = "Xy" ]; then
3434 log error "Unix pipes not compatible with NOGAP encoding"
3435 exit 1
3436 fi
3437 fi
3438
3439 # BATCHNORM pre-tests, before we get into serious problems
3440 # Not compatible with
3441 if [ "$BATCHNORM" = "y" ] && [ "$DONORMALIZE" = "n" ]; then
3442 vecho warning "Disabling BATCHNORM since we are not normalizing!"
3443 BATCHNORM=n
3444 fi
3445
3446 # Check the encoding format from the ones available in the system, if nothing has been configured.
3447 if [ X"$OUTPUTTYPE" = "X" ]; then
3448 for DEFAULT_OUTPUT in $( echo "$DEFAULT_OUTPUT_BINARIES" | tr , \ ); do
3449 DEFAULT_OUTPUT_FORMAT="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 1)"
3450 DEFAULT_OUTPUT_BINARY="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 2)"
3451 if [ -x $(which $DEFAULT_OUTPUT_BINARY) ] ; then
3452 OUTPUTTYPE=$DEFAULT_OUTPUT_FORMAT
3453 vecho "No default output type defined. Autoselecting $OUTPUTTYPE..." >&2
3454 break
3455 fi
3456 done
3457 if [ X"$OUTPUTTYPE" = "X" ]; then
3458 log error "no encoder found in the PATH"
3459 log error "hints: are all dependencies installed? has the \$PATH been modified?"
3460 exit 1
3461 fi
3462 fi
3463
3464 # Decide which CDROM reader we're gonna use
3465 case "$CDROMREADERSYNTAX" in
3466 cdparanoia|debug)
3467 CDROMREADER="$CDPARANOIA"
3468 CDROMREADEROPTS="$CDPARANOIAOPTS"
3469 ;;
3470 cdda2wav)
3471 CDROMREADER="$CDDA2WAV"
3472 CDROMREADEROPTS="$CDDA2WAVOPTS"
3473 ;;
3474 dagrab)
3475 CDROMREADER="$DAGRAB"
3476 CDROMREADEROPTS="$DAGRABOPTS"
3477 ;;
3478 cddafs)
3479 CDROMREADER="$CDDAFS"
3480 CDROMREADEROPTS="$CDDAFSOPTS"
3481 ;;
3482 flac)
3483 CDROMREADER="$FLAC"
3484 CDROMREADEROPTS="$FLACOPTS"
3485 ;;
3486 esac
3487
3488 # There's only one normalize...
3489 case "$NORMALIZERSYNTAX" in
3490 default|normalize)
3491 NORMALIZER="$NORMALIZE"
3492 NORMALIZEROPTS="$NORMALIZEOPTS"
3493 ;;
3494 esac
3495
3496 # Allow -o OUTPUT(1):OPTIONS(1),...,OUTPUT(N):OPTIONS(N) mode of operation
3497 if echo "$OUTPUTTYPE" | grep ":" > /dev/null 2>&1 ; then
3498 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr \ \|| tr , \ | tr \| \ )"; do
3499 case "$OUTPUT" in
3500 vorbis:*|ogg:*) OGGENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3501 mp3:*) MP3ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3502 flac:*) FLACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3503 spx:*) SPEEXENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3504 mpc:*) MPPENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3505 m4a:*) AACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3506 esac
3507 done
3508 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do
3509 TEMPOUTPUT=$( echo "$OUTPUT" | cut -d: -f1 )
3510 TEMPOUTPUTTYPE="${TEMPOUTPUTTYPE:+$TEMPOUTPUTTYPE,}$TEMPOUTPUT"
3511 done
3512 OUTPUTTYPE="$TEMPOUTPUTTYPE"
3513 fi
3514
3515 # If nothing has been specified, use oggenc for oggs and lame for mp3s and flac
3516 # for flacs and speexenc for speex and mppenc for mpps and faac for m4as
3517
3518 # Getting ready for multiple output changes
3519 for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
3520 do
3521 case $OUTPUT in
3522 vorbis|ogg)
3523 [ "$OGGENCODERSYNTAX" = "default" ] && OGGENCODERSYNTAX=oggenc
3524 [ "$DOTAG" = "y" ] && NEEDCOMMENTER=y
3525 [ "$DOREPLAYGAIN" = "y" ] && NEEDVORBISGAIN=y
3526 OGGOUTPUTCONTAINER=ogg
3527 ;;
3528 mp3)
3529 [ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame
3530 [ "$DOTAG" = "y" ] && NEEDTAGGER=y
3531 [ "$DOREPLAYGAIN" = "y" ] && NEEDMP3GAIN=y
3532 ;;
3533 flac)
3534 [ "$FLACENCODERSYNTAX" = "default" ] && FLACENCODERSYNTAX=flac
3535 [ "$DOTAG" = "y" ] && NEEDMETAFLAC=y
3536 [ "$DOREPLAYGAIN" = "y" ] && NEEDMETAFLAC=y
3537 [ "$ONETRACK" = "y" ] && [ "$DOCUE" = "y" ] && NEEDMETAFLAC=y
3538 ;;
3539 spx)
3540 [ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc
3541 # [ "$DOREPLAYGAIN" = "y" ] &&
3542 ;;
3543 mpc)
3544 [ "$MPPENCODERSYNTAX" = "default" ] && MPPENCODERSYNTAX=mppenc
3545 [ "$DOREPLAYGAIN" = "y" ] && NEEDMPPGAIN=y
3546 ;;
3547 m4a)
3548 [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac
3549 [ "$DOTAG" = "y" ] && CHECKATOMICPARSLEY=y
3550 ;;
3551 wav)
3552 if [ "$KEEPWAVS" = "y" ]; then
3553 vecho "Setting the KEEPWAVS option, since the resulting wav files were requested..."
3554 fi
3555 KEEPWAVS=move
3556 ;;
3557 *) log error "Invalid OUTPUTTYPE defined"
3558 exit 1
3559 ;;
3560 esac
3561 done
3562
3563 # decide which encoder
3564 case "$MP3ENCODERSYNTAX" in
3565 lame)
3566 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$LAMEOPTS}"
3567 MP3ENCODER="$LAME"
3568 ;;
3569 toolame)
3570 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$TOOLAMEOPTS}"
3571 MP3ENCODER="$TOOLAME"
3572 ;;
3573 gogo)
3574 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$GOGOOPTS}"
3575 MP3ENCODER="$GOGO"
3576 ;;
3577 bladeenc)
3578 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$BLADEENCOPTS}"
3579 MP3ENCODER="$BLADEENC"
3580 ;;
3581 l3enc)
3582 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$L3ENCOPTS}"
3583 MP3ENCODER="$L3ENC"
3584 ;;
3585 xingmp3enc)
3586 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$XINGMP3ENCOPTS}"
3587 MP3ENCODER="$XINGMP3ENC"
3588 ;;
3589 mp3enc)
3590 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$MP3ENCOPTS}"
3591 MP3ENCODER="$MP3ENC"
3592 ;;
3593 esac
3594 case "$OGGENCODERSYNTAX" in
3595 vorbize)
3596 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$VORBIZEOPTS}"
3597 OGGENCODER="$VORBIZE"
3598 ;;
3599 oggenc)
3600 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$OGGENCOPTS}"
3601 OGGENCODER="$OGGENC"
3602 ;;
3603 esac
3604 case "$FLACENCODERSYNTAX" in
3605 flac)
3606 FLACENCODEROPTS="${FLACENCODEROPTSCLI:-$FLACOPTS}"
3607 FLACENCODER="$FLAC"
3608 if [ "$DOREPLAYGAIN" = "y" ]; then
3609 FLACENCODEROPTS="${FLACENCODEROPTS} --replay-gain"
3610 fi
3611 # FLAC streams can be encapsulated on a Ogg transport layer
3612 if echo "$FLACENCODEROPTS" | egrep -- "(^| )--ogg($| )" > /dev/null 2>&1 ;then
3613 log error "FLAC on an Ogg container is not yet supported"
3614 log error "due to problem with adding comments to such files"
3615 exit 1
3616 FLACOUTPUTCONTAINER=ogg
3617 else
3618 FLACOUTPUTCONTAINER=flac
3619 fi
3620 ;;
3621 esac
3622 case "$SPEEXENCODERSYNTAX" in
3623 speexenc)
3624 SPEEXENCODEROPTS="${SPEEXENCODEROPTSCLI:-$SPEEXENCOPTS}"
3625 SPEEXENCODER="$SPEEXENC"
3626 ;;
3627 esac
3628 case "$MPPENCODERSYNTAX" in
3629 mppenc)
3630 MPPENCODEROPTS="${MPPENCODEROPTSCLI:-$MPPENCOPTS}"
3631 MPPENCODER="$MPPENC"
3632 ;;
3633 esac
3634 case "$AACENCODERSYNTAX" in
3635 faac)
3636 AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
3637 AACENCODER="$AACENC"
3638 ;;
3639 esac
3640
3641 # and which tagger
3642 if [ "$ID3TAGV" = "1" ]; then
3643 TAGGER="$ID3"
3644 TAGGEROPTS="$ID3OPTS"
3645 else
3646 TAGGER="$ID3V2"
3647 TAGGEROPTS="$ID3V2OPTS"
3648 fi
3649
3650 # NOGAP is specific to lame. Other encoders fail ...
3651 if [ "$NOGAP" = "y" ] && [ ! "$MP3ENCODER" = "lame" ]; then
3652 log warning "the NOGAP option is specific to lame. Deactivating..."
3653 NOGAP=n
3654 fi
3655
3656 # Options for mkcue
3657 case "$CUEREADERSYNTAX" in
3658 default|mkcue)
3659 CUEREADEROPTS="${CDROM}"
3660 CUEREADER="$MKCUE"
3661 ;;
3662 esac
3663
3664 # which information retrieval tool are we using?
3665 case "$CDDBTOOL" in
3666 cddb) ;;
3667 musicbrainz) ;;
3668 esac
3669
3670 # Check if both OGGEOUTPUTCONTAINER and FLACOUTPUTCONTAINER are the same, and differentiante them
3671 if [ X"$OGGOUTPUTCONTAINER" = "Xogg" ] && [ X"$FLACOUTPUTCONTAINER" = "Xogg" ]; then
3672 log error "FLAC on an Ogg container is not yet supported"
3673 log error "due to problem with adding comments to such files"
3674 exit 1
3675 OGGOUTPUTCONTAINER=ogg.ogg
3676 FLACOUTPUTCONTAINER=flac.ogg
3677 vecho warning "modified file endings due to conflicting transport layers in Ogg/Vorbis and Ogg/FLAC"
3678 fi
3679
3680 # Clean up nice options (either use '-n NICELEVEL or -NICELEVEL')
3681
3682 if [ "$ENCNICE" ]; then
3683 ENCNICE="-n $ENCNICE"
3684 fi
3685 if [ "$READNICE" ]; then
3686 READNICE="-n $READNICE"
3687 fi
3688 if [ "$DISTMP3NICE" ]; then
3689 DISTMP3NICE="-n $DISTMP3NICE"
3690 fi
3691
3692 # Don't check for stuff if it's not needed
3693 if [ "$REMOTEHOSTS" ]; then
3694 NEEDDISTMP3=y
3695 fi
3696 if [ "$DONORMALIZE" = "y" ]; then
3697 NEEDNORMALIZER=y
3698 fi
3699 if [ "$EJECTCD" = "y" ]; then
3700 NEEDEJECT=y
3701 fi
3702 if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then
3703 if [ "$CDDBMETHOD" = "cddb" ]; then
3704 NEEDHTTPGET=y
3705 elif [ "$CDDBMETHOD" = "musicbrainz" ]; then
3706 :
3707 fi
3708 fi
3709 if [ "$DOCUE" = "y" ]; then
3710 NEEDCUEREADER=y
3711 fi
3712
3713 if [ X"$CDSPEEDVALUE" != "X" ] && [ "$DOREAD" = "y" ]; then
3714 case "$CDROMREADERSYNTAX" in
3715 cdparanoia|debug) CDROMREADEROPTS="$CDPARANOIAOPTS -S $CDSPEEDVALUE" ;;
3716 ### FIXME ### translate "cue2discid" from python to bash
3717 flac) NEEDMETAFLAC=y ; NEEDCUE2DISCID=y ; CDSPEEDVALUE="" ;;
3718 *) NEEDCDSPEED=y ;;
3719 esac
3720 fi
3721
3722 ###USEPIPESSUPPORT###
3723
3724 # Rippers with USEPIPE support
3725 # FIXME # Include here all the rippers we can figure out support pipes
3726 PIPERIPPER_cdparanoia="-"
3727 PIPERIPPER_debug="-"
3728 PIPERIPPER_flac="-c "
3729
3730 # Encoders with USEPIPE support
3731 # FIXME # Include here all the encoders we can figure out support pipes
3732 PIPE_lame="-"
3733 PIPE_bladeenc="-"
3734 PIPE_oggenc="-"
3735 PIPE_flac="-"
3736
3737 # Figure out if we can use pipes with the ripper/encoder combination
3738 # exit otherwise
3739 if [ "$USEPIPES" = "y" ]; then
3740 PIPERIPPERSVARCHECK="PIPERIPPER_${CDROMREADERSYNTAX}"
3741 case "$OUTPUT" in
3742 mp3)
3743 PIPEENCODERSVARCHECK="PIPE_$MP3ENCODERSYNTAX" ;;
3744 vorbis|ogg)
3745 PIPEENCODERSVARCHECK="PIPE_$OGGENCODERSYNTAX" ;;
3746 flac)
3747 PIPEENCODERSVARCHECK="PIPE_$FLACENCODERSYNTAX" ;;
3748 spx)
3749 PIPEENCODERSVARCHECK="PIPE_$SPEEXENCODER" ;;
3750 mpc)
3751 PIPEENCODERSVARCHECK="PIPE_$MPPENCODER" ;;
3752 esac
3753 decho "PIPERIPPERSVARCHECK: $( eval echo "\$$PIPERIPPERSVARCHECK" )"
3754 if [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "$" ] || \
3755 [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "" ] ; then
3756 log error "no support for pipes with given ripper"
3757 log error "read the USEPIPES file from the source tarball to get help."
3758 log error "On a Debian system, it is under /usr/share/doc/abcde/USEPIPES.gz"
3759 exit 1;
3760 fi
3761 decho "PIPEENCODERSVARCHECK: $( eval echo "\$$PIPEENCODERSVARCHECK" )"
3762 if [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "$" ] || \
3763 [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "" ] ; then
3764 log error "no support for pipes with given encoder"
3765 log error "read the USEPIPES file from the source tarball to help"
3766 log error "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz"
3767 exit 1;
3768 fi
3769 fi
3770
3771 # Make sure a buncha things exist
3772 for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
3773 $OGGENCODER $FLACENCODER $SPEEXENCODER $MPPENCODER \
3774 $AACENCODER \
3775 ${NEEDATOMICPARSLEY+$ATOMICPARSLEY} \
3776 ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \
3777 ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
3778 ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
3779 ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} \
3780 ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMP3GAIN+$MP3GAIN} \
3781 ${NEEDMPPGAIN+$MPPGAIN} ${NEEDCUEREADER+$CUEREADER} \
3782 ${NEEDCUE2DISCID+$CUE2DISCID}
3783 do
3784 checkexec "$X"
3785 done
3786
3787 if [ "$CHECKATOMICPARSLEY" = "y" ]; then
3788 if ! new_checkexec "$ATOMICPARSLEY"; then
3789 echo "WARNING: $ATOMICPARSLEY Not Found Not Post-Tagging!"
3790 DOTAG='n'
3791 else
3792 echo "Using $ATOMICPARSLEY To Tag AAC Tracks."
3793 fi
3794 fi
3795
3796 # And last but not least, check if we can diff between files. We do not abort,
3797 # since diffing is not critical...
3798 if [ -x $(which $DIFF) ]; then :; else
3799 vecho warning "Disabling diff since we cannot find it in the \$PATH..."
3800 DIFF=""
3801 fi
3802
3803 ## Now that we have metaflac, check if we need cue2discid
3804 #case $CDROMREADERSYNTAX in
3805 # flac)
3806 # TRACKINFO=$($METAFLAC --show-tag=CDDB $CDROM | cut -d"=" -f2 | egrep "[a-f0-9]{8}")
3807 # if [ "$TRACKINFO" = "" ]; then
3808 # checkexec ${NEEDCUE2DISCID+$CUE2DISCID}
3809 # fi
3810 # ;;
3811 #esac
3812
3813 CDROMREADER="$CDROMREADER $CDROMREADEROPTS"
3814 CDDBTOOL="$CDDBTOOL $CDDBTOOLOPTS"
3815 HTTPGET="$HTTPGET $HTTPGETOPTS"
3816
3817 # Here it used to say:
3818 # One thousand lines in, we can start doing stuff with things
3819 # Well, right now we are at line 3737 ;)
3820
3821 # Export needed things so they can be read in this subshell
3822 export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS
3823 export CDROM CDDBDATA REMOTEHOSTS MAXPROCS HTTPGET MD5SUM
3824
3825 if [ "$DOREAD" = "y" ]; then
3826 # User-definable function to set some things. Use it for
3827 # - closing the CD tray with eject -t
3828 # - set the CD speed value with eject -x
3829 vecho -n "Executing customizable pre-read function... "
3830
3831 pre_read # Execute the user-defined pre-read funtion. Close the CD with it.
3832
3833 vecho "done."
3834 fi
3835
3836 case "$CDDBMETHOD" in
3837 cddb)
3838 do_discid # Get ABCDETEMPDIR created and status file initialized
3839 ;;
3840 musicbrainz)
3841 do_musicbrainz id
3842 ;;
3843 esac
3844
3845 if [ "$DOCDDB" = "y" ]; then
3846 # start with a sane default:
3847 CDDBLOCALSTATUS=notfound
3848 if [ $CDDBUSELOCAL = "y" ]; then
3849 do_localcddb
3850 fi
3851 if checkstatus cddb-choice > /dev/null; then
3852 :
3853 else
3854 if [ "$CDDBLOCALSTATUS" = "notfound" ] ; then
3855 case "$CDDBMETHOD" in
3856 cddb)
3857 do_cddbstat
3858 do_cddbquery
3859 do_cddbread
3860 ;;
3861 musicbrainz)
3862 do_musicbrainz
3863 ;;
3864 esac
3865 fi
3866 fi
3867 do_cddbedit
3868
3869 eval "$($CDDBTOOL parse "$CDDBDATA")"
3870 fi
3871
3872 # Before reading tracks, we set the speed of the device
3873
3874 if [ X"$CDSPEEDVALUE" != "X" ]; then
3875 case "$CDROMREADERSYNTAX" in
3876 cdparanoia|debug) ;;
3877 flac) ;;
3878 *) do_cdspeed ;;
3879 esac
3880 fi
3881
3882 # Define the first and last track, since we might need them later in several places
3883 FIRSTTRACK=$( get_first $TRACKQUEUE )
3884 LASTTRACK=$( get_last $TRACKQUEUE )
3885
3886 if [ -f "$ABCDETEMPDIR/status" ] && [ X"$ERASEENCODEDSTATUS" = "Xy" ]; then
3887 mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
3888 grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
3889 | grep -v ^encode-output > "$ABCDETEMPDIR/status"
3890 fi
3891
3892 if checkstatus onetrack ; then ONETRACK=y ; fi
3893
3894 if [ "$ONETRACK" = "y" ]; then
3895 # Reuse the CUEFILE in case we created it (now or in a previous run)
3896 if CUEFILE=$(checkstatus cuefile); then
3897 IMPORTCUESHEET=y
3898 fi
3899 fi
3900
3901 # Create playlist if needed (backgroundable) and start reading in tracks
3902
3903 (
3904
3905 if [ ! "$ONETRACK" = "y" ]; then
3906 if [ "$DOPLAYLIST" = "y" ]; then
3907 echo Creating playlist... >&2
3908 do_playlist
3909 fi
3910 fi
3911
3912 # For the lowdisk option, only one program is running at once so the encoder
3913 # can be unsilenced right away.
3914 if [ "$LOWDISK" = "y" ] || [ "$ONETRACK" = "y" ]; then
3915 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3916 fi
3917
3918 if [ "$ONETRACK" = "y" ]; then
3919 TRACKS="$FIRSTTRACK"
3920 if [ "$USEPIPES" = "y" ]; then
3921 if checkstatus readencodetrack-$FIRSTTRACK; then :; else
3922 do_cdread onetrack $FIRSTTRACK $LASTTRACK | do_encode $FIRSTTRACK %local0% > /dev/null 2>&1
3923 fi
3924 else
3925 if checkstatus readtrack-$FIRSTTRACK; then :; else
3926 do_cdread onetrack $FIRSTTRACK $LASTTRACK
3927 fi
3928 fi
3929 else
3930 for UTRACKNUM in $TRACKQUEUE
3931 do
3932 if [ "$DOREAD" = "y" ]; then
3933 if [ "$USEPIPES" = "y" ]; then
3934 if checkstatus readencodetrack-$UTRACKNUM; then :; else
3935 # Read, pipe, shut up!
3936 do_cdread $UTRACKNUM | do_encode $UTRACKNUM %local0% > /dev/null 2>&1
3937 fi
3938 else
3939 if checkstatus readtrack-$UTRACKNUM; then :; else
3940 do_cdread $UTRACKNUM
3941 fi
3942 if [ "$?" != "0" ]; then
3943 # CD read failed - don't give the goahead to
3944 # the encoder
3945 echo NO
3946 exit
3947 fi
3948 fi
3949 fi
3950 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ]; then
3951 :
3952 else
3953 # If we are not reading, set the encode output to loud already, so
3954 # that we can see the output of the first track.
3955 if [ "$MAXPROCS" = "1" ] && [ ! "$DOREAD" = "y" ]; then
3956 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3957 fi
3958 echo NEXTTRACK # Get the encoder machine churning again
3959 if [ "$DOREAD" = "y" ]; then
3960 if [ "$LOWDISK" = "y" ] && [ "$DOENCODE" = "y" ]; then
3961 until checkstatus encodetrack-$UTRACKNUM
3962 do
3963 if checkerrors encodetrack-$UTRACKNUM; then
3964 break
3965 fi
3966 sleep 2
3967 done
3968 fi
3969 fi
3970 fi
3971 done
3972 fi
3973
3974 # Now that we're done the encoding can be loud again -
3975 # if we're not using SMP.
3976 if [ "$MAXPROCS" = "1" ]; then
3977 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3978 fi
3979
3980 # All tracks read, start encoding.
3981 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ] || [ "$ONETRACK" = "y" ]; then
3982 echo NEXTTRACK
3983 fi
3984
3985 # Execute the user-defined post_read funtion before ejecting CD
3986 post_read
3987
3988 # We are now finished with the cdrom - it can be safely ejected. Note that
3989 # abcde will not have completed yet.
3990 if [ "$EJECTCD" = "y" ] && [ -x $(which $EJECT) ]; then
3991 # We check if the disk we are processing is actually the disk inside the
3992 # CD tray. If not, we do not eject the CD, since it might be so that the
3993 # user ejected it manually.
3994 #CURRENTTRACKINFO=$($CDDISCID $CDROM)
3995 #if if [ "$?" != "1" ] && [ "$CURRENTTRACKINFO" = "$TRACKINFO" ] ; then
3996 # More FreeBSD bits.
3997 if [ X"$(uname)" = X"FreeBSD" ] ; then
3998 # FreeBSD eject uses the EJECT environment variable to name the CDROM
3999 # but in this script EJECT is in the envionment and names the program
4000 eject=$EJECT
4001 unset EJECT
4002 # The FreeBSD eject needs "adc0" not "/dev/adc0c"
4003 cd="$(echo $CDROM | sed -e 's=.*/==;s=[a-h]$==;')"
4004 $eject $EJECTOPTS $cd
4005 elif [ X"$(uname)" = X"Darwin" ] ; then
4006 disktool -e ${CDROM#/dev/} 0
4007 else
4008 $EJECT $EJECTOPTS "$CDROM"
4009 fi
4010 #fi
4011 fi
4012
4013 ) | (
4014
4015 ## Do we need to pre-process
4016 #if [ x"$PREPROCESS" = "x" ] ; then
4017 # cat
4018 #else
4019 # for PRETRACKNUM in $TRACKQUEUE
4020 # do
4021 # read GOAHEAD
4022 # if [ "$GOAHEAD" = "NO" ]; then break; fi
4023 # PREPROCEED=
4024 # until [ $PREPROCEED ]
4025 # do
4026 # if checkstatus readtrack-$PRETRACKNUM; then PREPROCEED=y; break; fi
4027 # # all locations are working, wait and try again later
4028 # if [ ! $PREPROCEED ]; then sleep 3; fi
4029 # done
4030 # ( do_preprocess $PRETRACKNUM
4031 # echo "NEXTTRACK"
4032 # ) &
4033 # done
4034 #fi
4035 #
4036 #) | (
4037
4038 # In BATCHNORM and/or NOGAP modes, we want all tracks to be read first.
4039 #BACK
4040 if [ "$BATCHNORM" = "y" ] || [ "$NOGAP" = "y" ]; then
4041 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
4042 if [ "$GOAHEAD" = "NO" ]; then break; fi
4043 for LASTTRACK in $TRACKQUEUE; do :; done
4044 if checkstatus readtrack-$LASTTRACK; then
4045 if [ "$DONORMALIZE" = "y" ] && [ "$BATCHNORM" = "y" ]; then
4046 if checkstatus normalizetrack-$LASTTRACK; then :; else do_batch_normalize; fi
4047 if checkerrors batch-normalize; then exit 1; fi
4048 fi
4049 if [ "$DOENCODE" = "y" ] && [ "$NOGAP" = "y" ]; then
4050 if [ "$DONORMALIZE" = "y" ]; then
4051 for UTRACKNUM in $TRACKQUEUE
4052 do
4053 if checkstatus readtrack-$UTRACKNUM; then
4054 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
4055 fi
4056 done
4057 fi
4058 if checkstatus encodetrack-$LASTTRACK; then :; else do_nogap_encode; fi
4059 if checkerrors nogap-encode; then exit 1; fi
4060 fi
4061 fi
4062 fi
4063
4064 # If we are using ONETRACK, we can proceed with the normal encoding using just the $FIRSTTRACK as TRACKQUEUE
4065 if [ "$ONETRACK" = "y" ] ; then
4066 TRACKQUEUE="$FIRSTTRACK"
4067 TRACKS="$FIRSTTRACK"
4068 fi
4069
4070 # Do the encoding, including parallelization of remote encoding
4071 # Figure out where each track is going to be encoded
4072 ENCODELOCATIONS="$(echo $REMOTEHOSTS | tr , ' ')"
4073 if [ "$MAXPROCS" != "0" ]; then
4074 for NUM in $(f_seq_row 1 "$MAXPROCS")
4075 do
4076 ENCODELOCATIONS="$ENCODELOCATIONS %local$NUM%"
4077 done
4078 fi
4079 # Strip whitespace
4080 ENCODELOCATIONS=$(echo $ENCODELOCATIONS)
4081 for UTRACKNUM in $TRACKQUEUE
4082 do
4083 # Wait for our cue
4084 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
4085 if [ "$GOAHEAD" = "NO" ]; then break; fi
4086 # find out where this track is to be encoded
4087 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
4088 # Make sure we have a place to encode this, if not, exit stage right
4089 if [ -z "$ENCODELOCATIONS" ]; then
4090 continue
4091 fi
4092 PROCEED=
4093 until [ $PROCEED ]
4094 do
4095 for LOCATION in $ENCODELOCATIONS
4096 do
4097 PREVIOUSTRACK="$(checkstatus encodetracklocation-$LOCATION)"
4098 # check first if a track has ever been assigned to this location
4099 if [ -z "$PREVIOUSTRACK" ]; then PROCEED=y; break; fi
4100 # If it errored out, rebuild $ENCODELOCATIONS without this location in it
4101 if checkerrors encodetrack-$PREVIOUSTRACK; then
4102 for TEMPLOCATION in $ENCODELOCATIONS
4103 do
4104 if [ "$TEMPLOCATION" != "$LOCATION" ]; then
4105 TEMPENCODELOCATIONS="$TEMPENCODELOCATIONS $TEMPLOCATION"
4106 fi
4107 done
4108 ENCODELOCATIONS=$(echo $TEMPENCODELOCATIONS)
4109 ABORT=y
4110 PROCEED=y
4111 break
4112 fi
4113 # We're still here, this location must have been previously assigned,
4114 # and last completed without error - check if it's done with the
4115 # previous track yet
4116 if checkstatus encodetrack-$PREVIOUSTRACK; then PROCEED=y; break; fi
4117 done
4118 # all locations are working, wait and try again later
4119 if [ ! $PROCEED ]; then sleep 3; fi
4120 done
4121 # Record the location we're about to encode the next track at
4122 echo "encodetracklocation-$LOCATION=$UTRACKNUM" >> "$ABCDETEMPDIR/status"
4123 fi
4124 # Don't proceed with the rest of the loop if we can't encode
4125 if [ "$ABORT" ]; then continue; fi
4126 ## FIXME ## Add here
4127 ## run_command tagtrack-$OUTPUT-$1 $METAFLAC $METAFLACOPTS ${IMPORTCUESHEET:+--import-cuesheet-from="$ABCDETEMPDIR/$CUEFILE"} --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
4128 # Set TRACKNUM, TRACKNAME
4129 if [ -e "$CDDBDATA" ]; then
4130 if [ "$ONETRACK" = "y" ]; then
4131 TRACKNAME="$DALBUM"
4132 TRACKNUM="$FIRSTTRACK"
4133 splitvarious
4134 else
4135 TRACKNUM=$UTRACKNUM
4136 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
4137 getcddbinfo TRACKNAME
4138 splitvarious
4139 fi
4140 fi
4141 # You can't encode a file which needs to be normalized before finishing
4142 # You can't tag a file before it's finished encoding -
4143 # thus all of this is backgrounded together
4144 (
4145 if [ "$DONORMALIZE" = "y" ]; then
4146 if checkstatus readtrack-$UTRACKNUM; then
4147 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
4148 fi
4149 fi
4150 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
4151 if checkstatus readtrack-$UTRACKNUM; then
4152 #if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION; fi
4153 if [ "$DONORMALIZE" = "y" ]; then
4154 if checkstatus normalizetrack-$UTRACKNUM; then
4155 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
4156 fi
4157 else
4158 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
4159 fi
4160 fi
4161 fi
4162 if [ "$DOTAG" = "y" ]; then
4163 if checkstatus encodetrack-$UTRACKNUM; then
4164 if checkstatus tagtrack-$UTRACKNUM; then :; else do_tag $UTRACKNUM; fi
4165 fi
4166 # Lets tag the cue file
4167 if checkstatus cleancuefile >/dev/null; then :; else
4168 if checkstatus cuefile >/dev/null ; then
4169 do_cleancue
4170 fi
4171 fi
4172 fi
4173 if [ "$DOMOVE" = "y" ]; then
4174 if checkstatus tagtrack-$UTRACKNUM; then
4175 if checkstatus movetrack-$UTRACKNUM; then :; else do_move $UTRACKNUM; fi
4176 fi
4177 fi
4178 ) &
4179 done
4180
4181
4182 # Go through it again and make sure there's no distmp3 stragglers, otherwise
4183 # we'll delete the files they're working on
4184 # Do NOT play ball if there is no ball to play (so ABORT if needed)
4185 ## FIXME ## Check also for files which are encoded using PIPEs.
4186 if [ "$DOENCODE" = "y" ] && [ "$USEPIPES" != "y" ] && [ ! "$ABORT" ]; then
4187 PROCEED=
4188 until [ $PROCEED ]
4189 do
4190 PROCEED=y
4191 for LOCATION in $ENCODELOCATIONS
4192 do
4193 CHECKTRACK="$(checkstatus encodetracklocation-$LOCATION)"
4194 # "How can he give us a status update, if he's DEAD?"
4195 if checkstatus encodetrack-$CHECKTRACK; then
4196 continue
4197 fi
4198 # Nothing to see here please go quietly back to your homes
4199 if [ -z "$CHECKTRACK" ]; then continue; fi
4200 # You're still here? Maybe there is something...
4201 if checkstatus encodetrack-$CHECKTRACK; then :; else PROCEED= ; break; fi
4202 done
4203 # hold up
4204 if [ ! $PROCEED ]; then sleep 5; fi
4205 done
4206 fi
4207 # If the above didn't catch the stragglers, this will
4208 wait
4209 if [ "$DOREPLAYGAIN" = "y" ]; then
4210 do_replaygain
4211 fi
4212
4213 # Execute the user-defined post_encode function before cleaning up
4214 post_encode
4215
4216 # Check to see if run_command logged any errors
4217 if [ -f "$ABCDETEMPDIR/errors" ]; then
4218 log error "The following commands failed to run:"
4219 cat "$ABCDETEMPDIR/errors"
4220 # Don't clean up
4221 DOCLEAN=n
4222 fi
4223 if [ "$KEEPWAVS" = "y" ];then
4224 # Don't clean up
4225 DOCLEAN=n
4226 fi
4227 # Check if we have moved all the formats we had previously encoded, if we are not using the FORCE.
4228 if [ "$DOCLEAN" = "y" ] && [ ! "$FORCE" = "y" ]; then
4229 ENCODED_FORMATS=$(egrep "^encodetrack-(.{3,6})-(.{1,2})$" "$ABCDETEMPDIR/status" | cut -d"-" -f2 | sort -u | tr '\n' '|')
4230 MOVED_FORMATS=$(egrep "^movetrack-output-(.{3,6})$" "$ABCDETEMPDIR/status" | cut -d"-" -f3 | sort -u | tr '\n' '|')
4231 if [ "$ENCODED_FORMATS" != "$MOVED_FORMATS" ]; then
4232 log warning "The encoded formats does not match with the moved ones"
4233 log warning "Formats encoded: $( echo $ENCODED_FORMATS | tr "|" " " )"
4234 log warning "Formats moved: $( echo $MOVED_FORMATS | tr "|" " " )"
4235 log warning "Use \"abcde -a clean -f -C $DISCID\" to force the removal of the remaining data."
4236 DOCLEAN=n
4237 fi
4238 fi
4239 if [ "$DOCLEAN" = "y" ]; then
4240 # Wipe all the evidence
4241 # Gimme gimme gimme some more time!
4242 sleep 5
4243 rm -rf "$ABCDETEMPDIR"
4244 echo "Finished."
4245 else
4246 echo "Finished. Not cleaning $ABCDETEMPDIR."
4247 fi
4248 )
4249 exit 0
4250
4251 # b:is_bash
4252 # vim:tabstop=4