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