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