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