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