27779b1e2cb0d63e426238ca0dbbeb70bdb99ee8
[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 # do_getcddbinfo
386 # Finds an specific field from cddbinfo
387 do_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 # do_gettracknum
400 # Get the track number we are going to use for different actions
401 do_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 do_getcddbinfo TRACKNAME
435 splitvarious
436 TRACKFILE="$(mungefilename "$TRACKNAME")"
437 ARTISTFILE="$(mungefilename "$TRACKARTIST")"
438 ALBUMFILE="$(mungefilename "$DALBUM")"
439 do_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 do_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 OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
1198 do
1199 # Create ALBUMFILE, ARTISTFILE, TRACKFILE
1200 # Munge filenames as follows:
1201 # ' ' -> '_'
1202 # '/' -> '_'
1203 # ''' -> ''
1204 # '?' -> ''
1205 # Eat control characters
1206 ALBUMFILE="$(mungefilename "$DALBUM")"
1207 ARTISTFILE="$(mungefilename "$TRACKARTIST")"
1208 TRACKFILE="$(mungefilename "$TRACKNAME")"
1209 GENRE="$(mungegenre "$GENRE")"
1210 YEAR="$(echo $CDYEAR)"
1211 # If we want to start the tracks with a given number, we need to modify the
1212 # TRACKNUM value before evaluation
1213 do_gettracknum
1214 # Supported variables for OUTPUTFORMAT are GENRE, ALBUMFILE, ARTISTFILE,
1215 # TRACKFILE, and TRACKNUM.
1216 if [ "$VARIOUSARTISTS" = "y" ]; then
1217 OUTPUTFILE="$(eval echo "$VAOUTPUTFORMAT")"
1218 else
1219 OUTPUTFILE="$(eval echo "$OUTPUTFORMAT")"
1220 fi
1221 if checkerrors "tagtrack-$OUTPUT-$1"; then :; else
1222 # Once we know the specific output was successful, we can change the OUTPUT to the value containing the container
1223 case $OUTPUT in
1224 vorbis|ogg)
1225 OUTPUT=$OGGOUTPUTCONTAINER
1226 ;;
1227 flac)
1228 OUTPUT=$FLACOUTPUTCONTAINER
1229 ;;
1230 esac
1231 # Check that the directory for OUTPUTFILE exists, if it doesn't, create it
1232 OUTPUTFILEDIR="$(dirname "$OUTPUTDIR/$OUTPUTFILE")"
1233 case $OUTPUT in
1234 wav)
1235 if [ "$DOCLEAN" != "y" ] && [ "$FORCE" != "y" ]; then
1236 # FIXME # introduce warnings?
1237 :
1238 else
1239 # mkdir -p shouldn't return an error if the directory already exists
1240 mkdir -p "$OUTPUTFILEDIR"
1241 run_command movetrack-$1 mv "$ABCDETEMPDIR/track$1.$OUTPUT" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
1242 if checkstatus movetrack-output-$OUTPUT; then :; else
1243 run_command movetrack-output-$OUTPUT true
1244 fi
1245 fi
1246 ;;
1247 *)
1248 # mkdir -p shouldn't return an error if the directory already exists
1249 mkdir -p "$OUTPUTFILEDIR"
1250 run_command movetrack-$1 mv "$ABCDETEMPDIR/track$1.$OUTPUT" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
1251 if checkstatus movetrack-output-$OUTPUT; then :; else
1252 run_command movetrack-output-$OUTPUT true
1253 fi
1254 ;;
1255 esac
1256 # Lets move the cue file
1257 if CUEFILE=$(checkstatus cuefile) >/dev/null ; then
1258 if [ -r "$ABCDETEMPDIR/$CUEFILE" ]; then
1259 if checkstatus movecue-$OUTPUT; then :; else
1260 # Silence the Copying output since it overlaps with encoding processes...
1261 #run_command '' vecho "Copying cue file to its destination directory..."
1262 if checkstatus onetrack >/dev/null ; then
1263 case $OUTPUT in
1264 wav)
1265 if [ "$DOCLEAN" != "y" ] && [ "$FORCE" != "y" ]; then
1266 # We dont have the dir, since it was not created before.
1267 :
1268 else
1269 run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.cue"
1270 fi
1271 ;;
1272 # NOTE: Creating a cue file with the 3-char-extension files is to comply with
1273 # http://brianvictor.tripod.com/mp3cue.htm#details
1274 [a-z0-9][a-z0-9][a-z0-9])
1275 run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.cue"
1276 ;;
1277 *)
1278 run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTDIR/$OUTPUTFILE.$OUTPUT.cue"
1279 ;;
1280 esac
1281 else
1282 run_command movecue-$OUTPUT cp "$ABCDETEMPDIR/$CUEFILE" "$OUTPUTFILEDIR/$CUEFILE"
1283 fi
1284 echo movecue-$OUTPUT >> "$ABCDETEMPDIR/status"
1285 fi
1286 fi
1287 fi
1288 fi
1289 done
1290 }
1291
1292 # do_playlist
1293 # Create the playlist if wanted
1294 # Variables used:
1295 # PLAYLISTFORMAT, PLAYLISTDATAPREFIX, VAPLAYLISTFORMAT, VAPLAYLISTDATAPREFIX,
1296 # VARIOUSARTISTS, OUTPUTDIR
1297 do_playlist ()
1298 {
1299 for TMPOUTPUT in $(echo $OUTPUTTYPE | tr , \ )
1300 do
1301 case $TMPOUTPUT in
1302 vorbis|ogg)
1303 OUTPUT=$OGGOUTPUTCONTAINER
1304 ;;
1305 flac)
1306 OUTPUT=$FLACOUTPUTCONTAINER
1307 ;;
1308 *)
1309 OUTPUT=$TMPOUTPUT
1310 ;;
1311 esac
1312 # Create a playlist file for the playlist data to go into.
1313 # We used to wipe it out if it existed. Now we request permision if interactive.
1314 for LASTTRACK in $TRACKQUEUE; do :; done
1315 ALBUMFILE="$(mungefilename "$DALBUM")"
1316 ARTISTFILE="$(mungefilename "$DARTIST")"
1317 GENRE=$(mungegenre "$GENRE")
1318 YEAR=${CDYEAR:-$CDYEAR}
1319 if [ "$VARIOUSARTISTS" = "y" ] ; then
1320 PLAYLISTFILE=$(eval echo $VAPLAYLISTFORMAT)
1321 else
1322 PLAYLISTFILE=$(eval echo $PLAYLISTFORMAT)
1323 fi
1324 FINALPLAYLISTDIR=$(dirname "$OUTPUTDIR/$PLAYLISTFILE")
1325 mkdir -p "$FINALPLAYLISTDIR"
1326 if [ -s "$OUTPUTDIR/$PLAYLISTFILE" ]; then
1327 echo -n "Erase, Append to, or Keep the existing playlist file? [e/a/k] (e): " >&2
1328 if [ "$INTERACTIVE" = "y" ]; then
1329 while [ "$DONE" != "y" ]; do
1330 read ERASEPLAYLIST
1331 case $ERASEPLAYLIST in
1332 e|E|a|A|k|K) DONE=y ;;
1333 *) ;;
1334 esac
1335 done
1336 else
1337 echo e >&2
1338 ERASEPLAYLIST=e
1339 fi
1340 # Once we erase the playlist, we use append to create the new one.
1341 [ "$ERASEPLAYLIST" = "e" -o "$ERASEPLAYLIST" = "E" ] && rm -f "$OUTPUTDIR/$PLAYLISTFILE" && ERASEPLAYLIST=a
1342 else
1343 # The playlist does not exist, so we can safelly use append to create the new list
1344 ERASEPLAYLIST=a
1345 fi
1346 if [ "$ERASEPLAYLIST" = "a" -o "$ERASEPLAYLIST" = "A" ]; then
1347 touch "$OUTPUTDIR/$PLAYLISTFILE"
1348 for UTRACKNUM in $TRACKQUEUE
1349 do
1350 # Shares some code with do_move since the filenames have to match
1351 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
1352 do_getcddbinfo TRACKNAME
1353 splitvarious
1354 TRACKFILE="$(mungefilename "$TRACKNAME")"
1355 ARTISTFILE="$(mungefilename "$TRACKARTIST")"
1356 ALBUMFILE="$(mungefilename "$DALBUM")"
1357 # If we want to start the tracks with a given number, we need to modify the
1358 # TRACKNUM value before evaluation
1359 do_gettracknum
1360 if [ "$VARIOUSARTISTS" = "y" ]; then
1361 OUTPUTFILE=$(eval echo $VAOUTPUTFORMAT)
1362 else
1363 OUTPUTFILE=$(eval echo $OUTPUTFORMAT)
1364 fi
1365 if [ "$VARIOUSARTISTS" = "y" ]; then
1366 if [ "$VAPLAYLISTDATAPREFIX" ] ; then
1367 echo ${VAPLAYLISTDATAPREFIX}$OUTPUTFILE.$OUTPUT >> "$OUTPUTDIR/$PLAYLISTFILE"
1368 else
1369 relpath "$PLAYLISTFILE", "$OUTPUTFILE.$OUTPUT" >> "$OUTPUTDIR/$PLAYLISTFILE"
1370 fi
1371 else
1372 if [ "$PLAYLISTDATAPREFIX" ]; then
1373 echo ${PLAYLISTDATAPREFIX}$OUTPUTFILE.$OUTPUT >> "$OUTPUTDIR/$PLAYLISTFILE"
1374 else
1375 relpath "$PLAYLISTFILE", "$OUTPUTFILE.$OUTPUT" >> "$OUTPUTDIR/$PLAYLISTFILE"
1376 fi
1377 fi
1378 done
1379 fi
1380 ## this will convert the playlist to have CRLF line-endings, if specified
1381 ## (some hardware players insist on CRLF endings)
1382 if [ "$DOSPLAYLIST" = "y" ]; then
1383 awk '{substr("\r",""); printf "%s\r\n", $0}' "$OUTPUTDIR/$PLAYLISTFILE" > "$ABCDETEMPDIR/PLAYLISTFILE.tmp"
1384 # mv -f "$ABCDETEMPDIR/PLAYLISTFILE.tmp" "$OUTPUTDIR/$PLAYLISTFILE"
1385 cat "$ABCDETEMPDIR/PLAYLISTFILE.tmp" | sed 's/\//\\/' > "$OUTPUTDIR/$PLAYLISTFILE"
1386 fi
1387 echo "playlistcomplete" >> "$ABCDETEMPDIR/status"
1388 done
1389 }
1390
1391 # do_discid
1392 # This essentially the start of things
1393 do_discid ()
1394 {
1395 # Query the CD to get the track info, unless the user specified -C
1396 # or we are using some actions which do not need the CDDB data at all
1397 #if [ ! X"$EXPACTIONS" = "X" ]; then
1398 # :
1399 #elif [ -z "$DISCID" ]; then
1400 if [ -z "$DISCID" ]; then
1401 vecho -n "Getting CD track info... "
1402 # In OSX, unmount the disc before a query
1403 if [ "$OSFLAVOUR" = "OSX" ]; then
1404 disktool -u ${CDROM#/dev/}
1405 fi
1406 if [ "$CDROMREADERSYNTAX" = "flac" ] ; then
1407 if $METAFLAC $METAFLACOPTS --export-cuesheet-to=- $CDROM > /dev/null 2>&1 ; then
1408 TRACKINFO=$($METAFLAC $METAFLACOPTS --export-cuesheet-to=- $CDROM | $CUE2DISCID)
1409 else
1410 log error "the input flac file does not contain a cuesheet."
1411 exit 1
1412 fi
1413 else
1414 case "$CDDBMETHOD" in
1415 cddb) TRACKINFO=$($CDDISCID $CDROM) ;;
1416 # FIXME # musicbrainz needs a cleanup
1417 musicbrainz) TRACKINFO=$($MUSICBRAINZ -c $CDROM ) ;;
1418 esac
1419 fi
1420 # Make sure there's a CD in there by checking cd-discid's return code
1421 if [ ! "$?" = "0" ]; then
1422 if [ "$CDROMREADERSYNTAX" = "flac" ] ; then
1423 log error "cuesheet information from the flac file could not be read."
1424 log error "Perhaps the flac file does not contain a cuesheet?."
1425 exit 1
1426 else
1427 log error "CD could not be read. Perhaps there's no CD in the drive?"
1428 exit 1
1429 fi
1430 fi
1431 # In OSX, remount the disc again
1432 if [ "$OSFLAVOUR" = "OSX" ]; then
1433 disktool -m ${CDROM#/dev/}
1434 fi
1435 WEHAVEACD=y
1436 DISCID=$(echo $TRACKINFO | cut -f1 -d' ')
1437 else
1438 TRACKINFO=$(cat "$WAVOUTPUTDIR/abcde.$DISCID/discid")
1439 fi
1440
1441 # Get a full enumeration of tracks, sort it, and put it in the TRACKQUEUE.
1442 # This needs to be done now because a section of the resuming code will need
1443 # it later.
1444
1445 # get the number of digits to pad TRACKNUM with - we'll use this later
1446 # a CD can only hold 99 tracks, but since we support a feature for starting
1447 # numbering the tracks from a given number, we might need to set it as a
1448 # variable for the user to define... or obtain it somehow.
1449 if [ "$PADTRACKS" = "y" ] ; then
1450 TRACKNUMPADDING=2
1451 fi
1452
1453 ABCDETEMPDIR="$WAVOUTPUTDIR/abcde.$(echo $TRACKINFO | cut -f1 -d' ')"
1454 if [ -z "$TRACKQUEUE" ]; then
1455 if [ ! "$STRIPDATATRACKS" = "y" ]; then
1456 case "$CDROMREADERSYNTAX" in
1457 cdparanoia|debug)
1458 if [ "$WEHAVEACD" = "y" ]; then
1459 vecho "Querying the CD for audio tracks..."
1460 CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS $CDROM -Q --verbose 2>&1 )"
1461 RET=$?
1462 if [ ! "$RET" = "0" ];then
1463 log warning "something went wrong while querying the CD... Maybe a DATA CD?"
1464 fi
1465 TRACKS="$(echo "$CDPARANOIAOUTPUT" | egrep '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ')"
1466 CDPARANOIAAUDIOTRACKS="$TRACKS"
1467 else
1468 # Previous versions of abcde would store the tracks on a file, instead of the status record.
1469 if [ -f "$ABCDETEMPDIR/cdparanoia-audio-tracks" ]; then
1470 echo cdparanoia-audio-tracks=$( cat "$ABCDETEMPDIR/cdparanoia-audio-tracks" ) >> "$ABCDETEMPDIR/status"
1471 rm -f "$ABCDETEMPDIR/cdparanoia-audio-tracks"
1472 fi
1473 if [ -f "$ABCDETEMPDIR/status" ] && TRACKS=$(checkstatus cdparanoia-audio-tracks); then :; else
1474 TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
1475 fi
1476 fi
1477 ;;
1478 *) TRACKS=$(echo $TRACKINFO | cut -f2 -d' ') ;;
1479 esac
1480 else
1481 TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
1482 fi
1483 if echo "$TRACKS" | grep "[[:digit:]]" > /dev/null 2>&1 ;then :;else
1484 log info "The disc does not contain any tracks. Giving up..."
1485 exit 0
1486 fi
1487 echo -n "Grabbing entire CD - tracks: "
1488 if [ ! "$PADTRACKS" = "y" ] ; then
1489 TRACKNUMPADDING=$(echo -n $TRACKS | wc -c | tr -d ' ')
1490 fi
1491 TRACKS=$(printf "%0.${TRACKNUMPADDING}d" $TRACKS)
1492 X=0
1493 while [ "$X" -ne "$TRACKS" ]
1494 do
1495 X=$(printf "%0.${TRACKNUMPADDING}d" $(expr $X + 1))
1496 TRACKQUEUE=$(echo $TRACKQUEUE $X)
1497 done
1498 echo $TRACKQUEUE
1499 else
1500 TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
1501 # User-supplied track queue.
1502 # Weed out non-numbers, whitespace, then sort and weed out duplicates
1503 TRACKQUEUE=$(echo $TRACKQUEUE | sed 's-[^0-9 ]--g' | tr ' ' '\n' | grep -v ^$ | sort -n | uniq | tr '\n' ' ' | sed 's- $--g')
1504 # Once cleaned, obtain the highest value in the trackqueue for number padding
1505 for LASTTRACK in $TRACKQUEUE; do :; done
1506 if [ ! "$PADTRACKS" = "y" ] ; then
1507 TRACKNUMPADDING=$(echo -n $LASTTRACK | wc -c | tr -d ' ')
1508 fi
1509 # Now we normalize the trackqueue
1510 for TRACK in $TRACKQUEUE ; do
1511 TRACKNUM=$(printf %0.${TRACKNUMPADDING}d $(expr ${TRACK} + 0 ))
1512 PADTRACKQUEUE=$(echo $PADTRACKQUEUE $TRACKNUM)
1513 done
1514 TRACKQUEUE=$PADTRACKQUEUE
1515 echo Grabbing tracks: "$TRACKQUEUE"
1516 fi
1517
1518 QUEUEDTRACKS=$(echo $TRACKQUEUE | wc -w | tr -d ' ')
1519
1520 # We have the discid, create a temp directory after it to store all the temp
1521 # info
1522
1523 if [ -e "$ABCDETEMPDIR" ]; then
1524 echo -n "abcde: attempting to resume from $ABCDETEMPDIR"
1525 # It already exists, see if it's a directory
1526 if [ ! -d "$ABCDETEMPDIR" ]; then
1527 # This is a file/socket/fifo/device/etc, not a directory
1528 # Complain and exit
1529 echo >&2
1530 echo "abcde: file $ABCDETEMPDIR already exists and does not belong to abcde." >&2
1531 echo "Please investigate, remove it, and rerun abcde." >&2
1532 exit 1
1533 fi
1534 echo -n .
1535 # It's a directory, let's see if it's owned by us
1536 if [ ! -O "$ABCDETEMPDIR" ]; then
1537 # Nope, complain and exit
1538 echo >&2
1539 echo "abcde: directory $ABCDETEMPDIR already exists and is not owned by you." >&2
1540 echo "Please investigate, remove it, and rerun abcde." >&2
1541 exit 1
1542 fi
1543 echo .
1544 # See if it's populated
1545 if [ ! -f "$ABCDETEMPDIR/discid" ]; then
1546 # Wipe and start fresh
1547 echo "abcde: $ABCDETEMPDIR/discid not found. Abcde must remove and recreate" >&2
1548 echo -n "this directory to continue. Continue? [y/n] (n)" >&2
1549 if [ "$INTERACTIVE" = "y" ]; then
1550 read ANSWER
1551 else
1552 echo y >&2
1553 ANSWER=y
1554 fi
1555 if [ "$ANSWER" != "y" ]; then
1556 exit 1
1557 fi
1558 rm -rf "$ABCDETEMPDIR" || exit 1
1559 mkdir -p "$ABCDETEMPDIR"
1560 if [ "$?" -gt "0" ]; then
1561 # Directory already exists or could not be created
1562 echo "abcde: Temp directory $ABCDETEMPDIR could not be created." >&2
1563 exit 1
1564 fi
1565 else
1566 # Everything is fine. Check for ^encodetracklocation-
1567 # and encode-output entries in the status file and
1568 # remove them. These are not relevant across sessions.
1569 if [ -f "$ABCDETEMPDIR/status" ]; then
1570 mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
1571 grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
1572 | grep -v ^encode-output > "$ABCDETEMPDIR/status"
1573 fi
1574 # Remove old error messages
1575 if [ -f "$ABCDETEMPDIR/errors" ]; then
1576 rm -f "$ABCDETEMPDIR/errors"
1577 fi
1578 fi
1579 else
1580 # We are starting from scratch
1581 mkdir -p "$ABCDETEMPDIR"
1582 if [ "$?" -gt "0" ]; then
1583 # Directory already exists or could not be created
1584 echo "abcde: Temp directory $ABCDETEMPDIR could not be created." >&2
1585 exit 1
1586 fi
1587 cat /dev/null > "$ABCDETEMPDIR/status"
1588 # Store the abcde version in the status file.
1589 echo "abcde-version=$VERSION" >> "$ABCDETEMPDIR/status"
1590 fi
1591 if [ X"$MAKECUEFILE" = "Xy" -a X"$WEHAVEACD" = "Xy" ]; then
1592 if checkstatus cuefile > /dev/null 2>&1 ; then :; else
1593 CUEFILE=cue-$(echo "$TRACKINFO" | cut -f1 -d' ').txt
1594 vecho "Creating cue file..."
1595 case $CDROMREADERSYNTAX in
1596 flac)
1597 if $METAFLAC --export-cuesheet-to=- $CDROM > "$ABCDETEMPDIR/$CUEFILE"; then :; else
1598 log warning "the input flac file does not contain a cuesheet."
1599 fi
1600 ;;
1601 *)
1602 if $CUEREADER $CUEREADEROPTS > "$ABCDETEMPDIR/$CUEFILE"; then
1603 echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status"
1604 else
1605 log warning "reading the CUE sheet with mkcue is still considered experimental"
1606 log warning "and there was a problem with the CD reading. abcde will continue,"
1607 log warning "but consider reporting the problem to the abcde author"
1608 fi
1609 ;;
1610 esac
1611 fi
1612 fi
1613 # If we got the CDPARANOIA status and it is not recorded, save it now
1614 if [ -n "$CDPARANOIAAUDIOTRACKS" ]; then
1615 if checkstatus cdparanoia-audio-tracks > /dev/null 2>&1; then :; else
1616 echo cdparanoia-audio-tracks=$CDPARANOIAAUDIOTRACKS >> "$ABCDETEMPDIR/status"
1617 fi
1618 fi
1619
1620 # Create the discid file
1621 echo "$TRACKINFO" > "$ABCDETEMPDIR/discid"
1622 if checkstatus cddbmethod > /dev/null 2>&1 ; then :; else
1623 echo "cddbmethod=$CDDBMETHOD" >> "$ABCDETEMPDIR/status"
1624 fi
1625 }
1626
1627 # do_cleancue
1628 # Create a proper CUE file based on the CUE file we created before.
1629 do_cleancue()
1630 {
1631 if CUEFILE_IN="$ABCDETEMPDIR"/$(checkstatus cuefile); then
1632 CUEFILE_OUT=$CUEFILE_IN.out
1633 ### FIXME ### checkstatus cddb
1634 if [ -e "$CDDBDATA" ]; then
1635 vecho "Adding metadata to the cue file..."
1636 # FIXME It doesn't preserve spaces! Why?
1637 # FIXME parse $track into PERFORMER and TITLE - abcde already has code for this?
1638 n=1
1639 echo "PERFORMER \"$DARTIST\"" >> "$CUEFILE_OUT"
1640 echo "TITLE \"$DALBUM\"" >> "$CUEFILE_OUT"
1641 cat "$CUEFILE_IN" | while read line
1642 do
1643 if echo "$line" | grep -q "INDEX"
1644 then
1645 eval track="\$TRACK$n"
1646 n=$(expr $n + 1)
1647 echo "TITLE \"$track\"" >> "$CUEFILE_OUT"
1648 fi
1649 echo "$line" >> "$CUEFILE_OUT"
1650 done
1651 mv "$CUEFILE_OUT" "$CUEFILE_IN"
1652 echo "cleancuefile" >> "$ABCDETEMPDIR/status"
1653 fi
1654 fi
1655 }
1656
1657 # do_cddbparse
1658 # Parses a CDDB file and outputs the title and the track names.
1659 # Variables: CDDBFILE
1660 do_cddbparse ()
1661 {
1662 CDDBPARSEFILE="$1"
1663 # List out disc title/author and contents
1664 if [ "$ONETRACK" = "y" ]; then
1665 vecho "ONETRACK mode selected: displaying only the title of the CD..."
1666 fi
1667 echo "---- $(grep DTITLE "${CDDBPARSEFILE}" | cut '-d=' -f2- | tr -d \\r\\n ) ----"
1668 if [ X"$SHOWCDDBYEAR" = "Xy" ]; then
1669 PARSEDYEAR=$(grep DYEAR "${CDDBPARSEFILE}" | cut '-d=' -f2-)
1670 if [ ! X"$PARSEDYEAR" = "X" ]; then
1671 echo "Year: $PARSEDYEAR"
1672 fi
1673 fi
1674 if [ X"$SHOWCDDBGENRE" = "Xy" ]; then
1675 PARSEDGENRE=$(grep DGENRE "${CDDBPARSEFILE}" | cut '-d=' -f2-)
1676 if [ ! X"$PARSEDGENRE" = "X" ]; then
1677 echo "Genre: $PARSEDGENRE"
1678 fi
1679 fi
1680 if [ ! "$ONETRACK" = "y" ]; then
1681 for TRACK in $(f_seq_row 1 $TRACKS)
1682 do
1683 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "${CDDBPARSEFILE}" | cut -f2- -d= | tr -d \\r\\n)"
1684 done
1685 fi
1686 }
1687
1688 # do_localcddb
1689 # Check for a local CDDB file, and report success
1690 do_localcddb ()
1691 {
1692 if checkstatus cddb-readcomplete && checkstatus cddb-choice >/dev/null; then :; else
1693
1694 CDDBLOCALSTATUS="notfound"
1695 CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
1696 USELOCALRESP="y"
1697
1698 if [ "$CDDBLOCALRECURSIVE" = "y" ]; then
1699 CDDBLOCALRESULTS="$(find ${CDDBLOCALDIR} -name "${CDDBDISCID}" -type f 2> /dev/null)"
1700 if [ ! "${CDDBLOCALRESULTS}" = "" ]; then
1701 if (( $(echo "${CDDBLOCALRESULTS}" | wc -l) == 1 )); then
1702 CDDBLOCALFILE="${CDDBLOCALRESULTS}"
1703 CDDBLOCALMATCH=single
1704 elif (( $(echo "${CDDBLOCALRESULTS}" | wc -l) > 1 )); then
1705 CDDBLOCALMATCH=multiple
1706 fi
1707 else
1708 CDDBLOCALMATCH=none
1709 fi
1710 elif [ "$CDDBLOCALMATCH" = "none" ] && [ -r "${CDDBLOCALDIR}/${CDDBDISCID}" ]; then
1711 CDDBLOCALFILE="${CDDBLOCALDIR}/${CDDBDISCID}"
1712 CDDBLOCALMATCH=single
1713 else
1714 CDDBLOCALMATCH=none
1715 fi
1716
1717 # If the user has selected to check a local CDDB repo, we proceed with it
1718 case $CDDBLOCALMATCH in
1719 multiple)
1720 echo "Processing multiple matching CDDB entries..." > "$ABCDETEMPDIR/cddblocalchoices"
1721 X=0
1722 echo "$CDDBLOCALRESULTS" | while read RESULT ; do
1723 X=$(expr $X + 1)
1724 # List out disc title/author and contents
1725 CDDBLOCALREAD="$ABCDETEMPDIR/cddblocalread.$X"
1726 cat "$RESULT" > "${CDDBLOCALREAD}"
1727 {
1728 echo -n "#$X: "
1729 do_cddbparse "${CDDBLOCALREAD}"
1730 echo ""
1731 } >> "$ABCDETEMPDIR/cddblocalchoices"
1732 done
1733 if [ $(cat "$ABCDETEMPDIR/cddblocalchoices" | wc -l) -ge 24 ]; then
1734 page "$ABCDETEMPDIR/cddblocalchoices"
1735 else
1736 # It's all going to fit in one page, cat it
1737 cat "$ABCDETEMPDIR/cddblocalchoices" >&2
1738 fi
1739 CDDBLOCALCHOICES=$( echo "$CDDBLOCALRESULTS" | wc -l )
1740 # Setting the choice to an impossible integer to avoid errors in the numeric comparisons
1741 CDDBLOCALCHOICENUM=-1
1742 if [ "$INTERACTIVE" = "y" ]; then
1743 while [ $CDDBLOCALCHOICENUM -lt 0 ] || [ $CDDBLOCALCHOICENUM -gt $CDDBLOCALCHOICES ]; do
1744 echo -n "Locally cached CDDB entries found. Which one would you like to use (0 for none)? [0-$CDDBLOCALCHOICES]: " >&2
1745 read CDDBLOCALCHOICE
1746 [ x"$CDDBLOCALCHOICE" = "x" ] && CDDBLOCALCHOICE="1"
1747 # FIXME # Introduce diff's
1748 if echo $CDDBLOCALCHOICE | egrep -q "[[:space:]]*[[:digit:]]+,[[:digit:]]+[[:space:]]*" ; then
1749 diffentries cddblocalread "$CDDBLOCALCHOICES" "$CDDBLOCALCHOICE"
1750 elif echo $CDDBLOCALCHOICE | egrep -q "[[:space:]]*[[:digit:]]+[[:space:]]*" ; then
1751 # Make sure we get a valid choice
1752 CDDBLOCALCHOICENUM=$(echo $CDDBLOCALCHOICE | xargs printf %d 2>/dev/null)
1753 if [ $CDDBLOCALCHOICENUM -lt 0 ] || [ $CDDBLOCALCHOICENUM -gt $CDDBLOCALCHOICES ]; then
1754 echo "Invalid selection. Please choose a number between 0 and $CDDBLOCALCHOICES." >&2
1755 fi
1756 fi
1757 done
1758 else
1759 ### FIXME ###
1760 echo "Selected ..."
1761 CDDBLOCALRESP=y
1762 fi
1763 if [ ! "$CDDBLOCALCHOICENUM" = "0" ]; then
1764 #echo "Using local copy of CDDB data"
1765 echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "$ABCDETEMPDIR/cddbread.1"
1766 cat "$ABCDETEMPDIR/cddblocalread.$CDDBLOCALCHOICENUM" >> "$ABCDETEMPDIR/cddbread.1"
1767 echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB
1768 echo cddb-readcomplete >> "$ABCDETEMPDIR/status"
1769 do_cddbparse "$ABCDETEMPDIR/cddbread.1" > "$ABCDETEMPDIR/cddbchoices"
1770 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
1771 CDDBLOCALSTATUS="found"
1772 else
1773 #echo "Not using local copy of CDDB data"
1774 CDDBLOCALSTATUS="notfound"
1775 fi
1776 ;;
1777 single)
1778 # List out disc title/author and contents
1779 do_cddbparse "${CDDBLOCALFILE}"
1780 if [ "$CDROMREADERSYNTAX" = "flac" ] ; then
1781 echo -n "Embedded cuesheet entry found, use it? [y/n] (y): " >&2
1782 else
1783 echo -n "Locally cached CDDB entry found, use it? [y/n] (y): " >&2
1784 fi
1785 if [ "$INTERACTIVE" = "y" ]; then
1786 read USELOCALRESP
1787 while [ "$USELOCALRESP" != "y" ] && [ "$USELOCALRESP" != "n" ] && [ "$USELOCALRESP" != "" ] ; do
1788 echo -n 'Invalid selection. Please answer "y" or "n": ' >&2
1789 read USELOCALRESP
1790 done
1791 [ x"$USELOCALRESP" = "x" ] && USELOCALRESP="y"
1792 else
1793 echo "y" >&2
1794 fi
1795 if [ "$USELOCALRESP" = "y" ]; then
1796 #echo "Using local copy of CDDB data"
1797 echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "$ABCDETEMPDIR/cddbread.1"
1798 cat "${CDDBLOCALFILE}" >> "$ABCDETEMPDIR/cddbread.1"
1799 echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB
1800 echo cddb-readcomplete >> "$ABCDETEMPDIR/status"
1801 do_cddbparse "${CDDBLOCALFILE}" > "$ABCDETEMPDIR/cddbchoices"
1802 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
1803 CDDBLOCALSTATUS="single"
1804 else
1805 #echo "Not using local copy of CDDB data"
1806 CDDBLOCALSTATUS="notfound"
1807 fi
1808 ;;
1809 none)
1810 CDDBLOCALSTATUS="notfound"
1811 ;;
1812 esac
1813 fi
1814 }
1815
1816 do_musicbrainzstat ()
1817 {
1818 :
1819 }
1820
1821 do_musizbrainz ()
1822 {
1823 :
1824 }
1825
1826 # do_cddbstat
1827 do_cddbstat ()
1828 {
1829 # Perform CDDB protocol version check if it hasn't already been done
1830 if checkstatus cddb-statcomplete; then :; else
1831 if [ "$CDDBAVAIL" = "n" ]; then
1832 ERRORCODE=no_query
1833 echo 503 > "$ABCDETEMPDIR/cddbstat"
1834 else
1835 rc=1
1836 CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
1837 CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
1838 while test $rc -eq 1 -a $CDDBPROTO -ge 3; do
1839 vecho "Checking CDDB server status..."
1840 $CDDBTOOL stat $CDDBURL $CDDBUSER $CDDBHOST $CDDBPROTO > "$ABCDETEMPDIR/cddbstat"
1841 RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbstat" | cut -f1 -d' ')
1842 case "$RESPONSECODE" in
1843 210) # 210 OK, status information follows (until terminating `.')
1844 rc=0;
1845 ;;
1846 501|*) # 501 Illegal CDDB protocol level: <n>.
1847 CDDBPROTO=`expr $CDDBPROTO - 1`
1848 ;;
1849 esac
1850 done
1851 if test $rc -eq 1; then
1852 CDDBAVAIL="n"
1853 fi
1854 fi
1855 echo cddb-statcomplete >> "$ABCDETEMPDIR/status"
1856 fi
1857 }
1858
1859
1860 # do_cddbquery
1861 do_cddbquery ()
1862 {
1863 CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
1864 CDDBLOCALFILE="${CDDBLOCALDIR}/${CDDBDISCID}"
1865
1866 # Perform CDDB query if it hasn't already been done
1867 if checkstatus cddb-querycomplete; then :; else
1868 if [ "$CDDBAVAIL" = "n" ]; then
1869 ERRORCODE=no_query
1870 echo 503 > "$ABCDETEMPDIR/cddbquery"
1871 # The default CDDBLOCALSTATUS is "notfound"
1872 # This part will be triggered if the user CDDB repo does not
1873 # contain the entry, or if we are not trying to use the repo.
1874 else
1875 vecho "Querying the CDDB server..."
1876 CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
1877 CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
1878 $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $TRACKINFO > "$ABCDETEMPDIR/cddbquery"
1879 ERRORCODE=$?
1880 case $ERRORCODE in
1881 0) # success
1882 ;;
1883 12|13|14)
1884 # no match found in database,
1885 # wget/fetch error, or user requested not to use CDDB
1886 # Make up an error code (503) that abcde
1887 # will recognize in do_cddbread
1888 # and compensate by making a template
1889 echo 503 > "$ABCDETEMPDIR/cddbquery"
1890 ;;
1891 *) # strange and unknown error
1892 echo ERRORCODE=$ERRORCODE
1893 echo "abcde: $CDDBTOOL returned unknown error code"
1894 ;;
1895 esac
1896 fi
1897 echo cddb-querycomplete >> "$ABCDETEMPDIR/status"
1898 fi
1899 }
1900
1901 # do_cddbread
1902 do_cddbread ()
1903 {
1904 # If it's not to be used, generate a template.
1905 # Then, display it (or them) and let the user choose/edit it
1906 if checkstatus cddb-readcomplete; then :; else
1907 vecho "Obtaining CDDB results..."
1908 # If CDDB is to be used, interpret the query results and read all
1909 # the available entries.
1910 rm -f "$ABCDETEMPDIR/cddbchoices"
1911 CDDBCHOICES=1 # Overridden by multiple matches
1912 RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbquery" | cut -f1 -d' ')
1913 case "$RESPONSECODE" in
1914 200)
1915 # One exact match, retrieve it
1916 # 200 [section] [discid] [artist] / [title]
1917 if checkstatus cddb-read-1-complete; then :; else
1918 echo -n "Retrieving 1 CDDB match..." >> "$ABCDETEMPDIR/cddbchoices"
1919 $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(cut -f2,3 -d' ' "$ABCDETEMPDIR/cddbquery") > "$ABCDETEMPDIR/cddbread.1"
1920 echo "done." >> "$ABCDETEMPDIR/cddbchoices"
1921 echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
1922 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
1923 fi
1924 # List out disc title/author and contents
1925 echo ---- "$(cut '-d ' -f4- "$ABCDETEMPDIR/cddbquery")" ---- >> "$ABCDETEMPDIR/cddbchoices"
1926 for TRACK in $(f_seq_row 1 $TRACKS)
1927 do
1928 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
1929 done
1930 echo >> "$ABCDETEMPDIR/cddbchoices"
1931 ;;
1932 202|403|409|503)
1933 # No match
1934 case "$RESPONSECODE" in
1935 202) echo "No CDDB match." >> "$ABCDETEMPDIR/cddbchoices" ;;
1936 403|409) echo "CDDB entry is corrupt, or the handshake failed." >> "$ABCDETEMPDIR/cddbchoices" ;;
1937 503) echo "CDDB unavailable." >> "$ABCDETEMPDIR/cddbchoices" ;;
1938 esac
1939 $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
1940 # List out disc title/author and contents of template
1941 echo ---- Unknown Artist / Unknown Album ---- >> "$ABCDETEMPDIR/cddbchoices"
1942 UNKNOWNDISK=y
1943 for TRACK in $(f_seq_row 1 $TRACKS)
1944 do
1945 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.0" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
1946 done
1947 echo >> "$ABCDETEMPDIR/cddbchoices"
1948 echo cddb-read-0-complete >> "$ABCDETEMPDIR/status"
1949 echo cddb-choice=0 >> "$ABCDETEMPDIR/status"
1950 ;;
1951 210|211)
1952 # Multiple exact, (possibly multiple) inexact matches
1953 IN=
1954 if [ "$RESPONSECODE" = "211" ]; then IN=in; fi
1955 if [ "$(wc -l < "$ABCDETEMPDIR/cddbquery" | tr -d ' ')" -eq 3 ]; then
1956 echo "One ${IN}exact match:" >> "$ABCDETEMPDIR/cddbchoices"
1957 tail -n +2 "$ABCDETEMPDIR/cddbquery" | head -n 1 >> "$ABCDETEMPDIR/cddbchoices"
1958 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
1959 else
1960 echo "Multiple ${IN}exact matches:" >> "$ABCDETEMPDIR/cddbchoices"
1961 fi
1962 vecho -n "Retrieving multiple matches... "
1963 grep -v ^[.]$ "$ABCDETEMPDIR/cddbquery" | ( X=0
1964 read DISCINFO # eat top line
1965 while read DISCINFO
1966 do
1967 X=$(expr $X + 1)
1968 if checkstatus cddb-read-$X-complete; then :; else
1969 $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(echo $DISCINFO | cut -f1,2 -d' ') > "$ABCDETEMPDIR/cddbread.$X"
1970 echo cddb-read-$X-complete >> "$ABCDETEMPDIR/status"
1971 fi
1972 # List out disc title/author and contents
1973 echo \#$X: ---- "$DISCINFO" ---- >> "$ABCDETEMPDIR/cddbchoices"
1974 for TRACK in $(f_seq_row 1 $TRACKS)
1975 do
1976 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.$X" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
1977 done
1978 echo >> "$ABCDETEMPDIR/cddbchoices"
1979 done )
1980 vecho "done."
1981 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
1982 ;;
1983 999)
1984 # Using local copy.
1985 for TRACK in $(f_seq_row 1 $TRACKS)
1986 do
1987 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
1988 done
1989 echo >> "$ABCDETEMPDIR/cddbchoices"
1990 echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
1991 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
1992 ;;
1993 esac
1994 echo "cddb-readcomplete" >> "$ABCDETEMPDIR/status"
1995 fi
1996 }
1997
1998 # do_cddbedit
1999 do_cddbedit ()
2000 {
2001 if checkstatus cddb-edit >/dev/null; then
2002 CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
2003 VARIOUSARTISTS="$(checkstatus variousartists)"
2004 VARIOUSARTISTSTYLE="$(checkstatus variousartiststyle)"
2005 return 0
2006 fi
2007 if [ "$INTERACTIVE" = "y" ]; then
2008 # We should show the CDDB results both when we are not using the local CDDB repo
2009 # or when we are using it but we could not find a proper match
2010 if [ "$CDDBUSELOCAL" = "y" ] && [ "$CDDBLOCALSTATUS" = "notfound" ] || [ ! "$CDDBUSELOCAL" = "y" ]; then
2011 # Display the $ABCDETEMPDIR/cddbchoices file created above
2012 # Pick a pager so that if the tracks overflow the screen the user can still view everything
2013 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
2014 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
2015 CHOICE=$(checkstatus cddb-choice)
2016 if [ -n "$CHOICE" ] ; then
2017 case $CDDBCHOICES in
2018 -1) if head -1 "$ABCDETEMPDIR/cddbquery" | grep -q "^$" ; then
2019 log error "CDDB query failed!"
2020 exit 1
2021 else
2022 cat "$ABCDETEMPDIR/cddbchoices"
2023 fi
2024 ;;
2025 1) cat "$ABCDETEMPDIR/cddbchoices" ;;
2026 *)
2027 echo "Selected: #$CHOICE"
2028 do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
2029 ;;
2030 esac
2031 else
2032 # The user has a choice to make, display the info in a pager if necessary
2033 if [ $(cat "$ABCDETEMPDIR/cddbchoices" | wc -l) -ge 24 ]; then
2034 page "$ABCDETEMPDIR/cddbchoices"
2035 else
2036 # It's all going to fit in one page, cat it
2037 cat "$ABCDETEMPDIR/cddbchoices" >&2
2038 fi
2039
2040 CDDBCHOICENUM=""
2041 # Setting the choice to an impossible integer to avoid errors in the numeric comparisons
2042 CDCHOICENUM=-1
2043 # I'll take CDDB read #3 for $400, Alex
2044 while [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; do
2045 echo -n "Which entry would you like abcde to use (0 for none)? [0-$CDDBCHOICES]: " >&2
2046 read CDDBCHOICE
2047 [ X"$CDDBCHOICE" = "X" ] && CDDBCHOICE=1
2048 if echo $CDDBCHOICE | egrep -q "[[:space:]]*[[:digit:]]+,[[:digit:]]+[[:space:]]*" ; then
2049 if [ ! X"$DIFF" = "X" ]; then
2050 PARSECHOICE1=$(echo $CDDBCHOICE | cut -d"," -f1 | xargs printf %d 2>/dev/null)
2051 PARSECHOICE2=$(echo $CDDBCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null)
2052 if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBCHOICES ] || \
2053 [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBCHOICES ] || \
2054 [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then
2055 echo "Invalid diff range. Please select two coma-separated numbers between 1 and $CDDBCHOICES" >&2
2056 else
2057 # We parse the 2 choices to diff, store them in temporary files and diff them.
2058 for PARSECHOICE in $(echo $CDDBCHOICE | tr , \ ); do
2059 do_cddbparse "$ABCDETEMPDIR/cddbread.$PARSECHOICE" > "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE"
2060 done
2061 echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..." > "$ABCDETEMPDIR/cddbread.diff"
2062 $DIFF $DIFFOPTS "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE1" "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE2" >> "$ABCDETEMPDIR/cddbread.diff"
2063 if [ $(cat "$ABCDETEMPDIR/cddbread.diff" | wc -l) -ge 24 ]; then
2064 page "$ABCDETEMPDIR/cddbread.diff"
2065 else
2066 cat "$ABCDETEMPDIR/cddbread.diff" >&2
2067 fi
2068 fi
2069 else
2070 echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBCHOICES." >&2
2071 fi
2072 elif echo $CDDBCHOICE | egrep -q "[[:space:]]*[[:digit:]]+[[:space:]]*" ; then
2073 # Make sure we get a valid choice
2074 CDCHOICENUM=$(echo $CDDBCHOICE | xargs printf %d 2>/dev/null)
2075 if [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; then
2076 echo "Invalid selection. Please choose a number between 0 and $CDDBCHOICES." >&2
2077 fi
2078 fi
2079 done
2080 if [ "$CDCHOICENUM" = "0" ]; then
2081 vecho "Creating empty CDDB template..."
2082 UNKNOWNDISK=y
2083 $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
2084 else
2085 echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
2086 do_cddbparse "$ABCDETEMPDIR/cddbread.$CDCHOICENUM"
2087 fi
2088 echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
2089 fi
2090 fi
2091 else
2092 # We need some code to show the selected option when local repository is selected and we have found a match
2093 vecho "Using cached CDDB match..." >&2
2094 # Display the $ABCDETEMPDIR/cddbchoices file created above
2095 # Pick a pager so that if the tracks overflow the screen the user can still view everything
2096 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
2097 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
2098 CHOICE=$(checkstatus cddb-choice)
2099 if [ "$USELOCALRESP" = "y" ]; then :; else
2100 if [ -n "$CHOICE" ] ; then
2101 case $CDDBCHOICES in
2102 0)
2103 UNKNOWNDISK=y
2104 echo "Selected template."
2105 ;;
2106 1) cat "$ABCDETEMPDIR/cddbchoices" ;;
2107 *)
2108 echo "Selected: #$CHOICE"
2109 do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
2110 ;;
2111 esac
2112 fi
2113 fi
2114 fi
2115 fi
2116 else
2117 # We're noninteractive - pick the first choice.
2118 # But in case we run a previous instance and selected a choice, use it.
2119 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
2120 # Show the choice if we are not using the locally stored one
2121 # or when the local search failed to find a match.
2122 PREVIOUSCHOICE=$(checkstatus cddb-choice)
2123 if [ "$CDDBUSELOCAL" = "y" ] && [ "$CDDBLOCALSTATUS" = "notfound" ] || [ ! "$CDDBUSELOCAL" = "y" ]; then
2124 #if [ "$PREVIOUSCHOICE" ]; then
2125 cat "$ABCDETEMPDIR/cddbchoices"
2126 #fi
2127 fi
2128 if [ ! -z "$PREVIOUSCHOICE" ] ; then
2129 CDCHOICENUM=$PREVIOUSCHOICE
2130 else
2131 CDCHOICENUM=1
2132 echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
2133 fi
2134 echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
2135 fi
2136 fi
2137
2138 # sanity check
2139 if checkstatus cddb-choice >/dev/null; then :; else
2140 echo "abcde: internal error: cddb-choice not recorded." >&2
2141 exit 1
2142 fi
2143 CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
2144 echo -n "Edit selected CDDB data? [y/n] (" >&2
2145 if [ "$INTERACTIVE" = "y" ]; then
2146 if [ "$UNKNOWNDISK" = "y" ]; then
2147 echo -n "y): " >&2
2148 read EDITCDDB
2149 [ "$EDITCDDB" != "n" ] && EDITCDDB=y
2150 else
2151 echo -n "n): " >&2
2152 read EDITCDDB
2153 fi
2154 else
2155 echo "n): n" >&2
2156 EDITCDDB=n
2157 fi
2158 if [ "$EDITCDDB" = "y" ]; then
2159 CDDBDATAMD5SUM=$($MD5SUM "$CDDBDATA" | cut -d " " -f 1);
2160
2161 # Use the debian sensible-editor wrapper to pick the editor that the
2162 # user has requested via their $EDITOR environment variable
2163 if [ -x "/usr/bin/sensible-editor" ]; then
2164 /usr/bin/sensible-editor "$CDDBDATA"
2165 elif [ -n "$EDITOR" ]; then
2166 if [ -x $(which "${EDITOR%%\ *}") ]; then
2167 # That failed, try to load the preferred editor, starting
2168 # with their EDITOR variable
2169 eval $(echo "$EDITOR") \"$CDDBDATA\"
2170 fi
2171 # If that fails, check for a vi
2172 elif which vi >/dev/null 2>&1; then
2173 vi "$CDDBDATA"
2174 elif [ -x /usr/bin/vim ]; then
2175 /usr/bin/vim "$CDDBDATA"
2176 elif [ -x /usr/bin/vi ]; then
2177 /usr/bin/vi "$CDDBDATA"
2178 elif [ -x /bin/vi ]; then
2179 /bin/vi "$CDDBDATA"
2180 # nano should be on all (modern, i.e., sarge) debian systems
2181 elif which nano >/dev/null 2>&1 ; then
2182 nano "$CDDBDATA"
2183 elif [ -x /usr/bin/nano ]; then
2184 /usr/bin/nano "$CDDBDATA"
2185 # mg should be on all OpenBSD systems
2186 elif which mg >/dev/null 2>&1 ; then
2187 mg "$CDDBDATA"
2188 elif [ -x /usr/bin/mg ]; then
2189 /usr/bin/mg "$CDDBDATA"
2190 # bomb out
2191 else
2192 log warning "no editor available. Check your EDITOR environment variable."
2193 fi
2194 # delete editor backup file if it exists
2195 if [ -w "$CDDBDATA~" ]; then
2196 rm -f "$CDDBDATA~"
2197 fi
2198 fi
2199
2200 # Some heuristics first. Look at Disc Title, and if it starts with
2201 # "Various", then we'll assume Various Artists
2202 if [ "$(grep ^DTITLE= "$CDDBDATA" | cut -f2- -d= | egrep -ci '^(various|soundtrack|varios|sonora|ost)')" != "0" ]; then
2203 echo "Looks like a Multi-Artist CD" >&2
2204 VARIOUSARTISTS=y
2205 else
2206 echo -n "Is the CD multi-artist? [y/n] (n): " >&2
2207 if [ "$INTERACTIVE" = "y" ]; then
2208 read VARIOUSARTISTS
2209 else
2210 echo n >&2
2211 VARIOUSARTISTS=n
2212 fi
2213 fi
2214 if [ "$VARIOUSARTISTS" = "y" ] && [ ! "$ONETRACK" = "y" ]; then
2215 # Set a default
2216 DEFAULTSTYLE=1
2217 # Need NUMTRACKS before cddb-tool will return it:
2218 NUMTRACKS=$(egrep '^TTITLE[0-9]+=' "$CDDBDATA" | wc -l)
2219 if [ "$(grep -c "^TTITLE.*\/" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2220 # More than 1/2 tracks contain a "/", so guess forward
2221 DEFAULTSTYLE=1
2222 elif [ "$(grep -c "^TTITLE.*\-" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2223 # More than 1/2 contain a "-", so guess forward-dash
2224 DEFAULTSTYLE=2
2225 elif [ "$(grep -c "^TTITLE.*(.*)" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2226 # More than 1/2 contain something in parens, so guess trailing-paren
2227 DEFAULTSTYLE=6
2228 fi
2229
2230 echo "1) Artist / Title" >&2
2231 echo "2) Artist - Title" >&2
2232 echo "3) Title / Artist" >&2
2233 echo "4) Title - Artist" >&2
2234 echo "5) Artist: Title" >&2
2235 echo "6) Title (Artist)" >&2
2236 echo "7) This is a single-artist CD" >&2
2237 echo -n "Which style of multiple artist entries is it? [1-7] ($DEFAULTSTYLE): " >&2
2238 if [ "$INTERACTIVE" = "y" ]; then
2239 read VARIOUSARTISTSTYLE
2240 else
2241 echo $DEFAULTSTYLE >&2
2242 VARIOUSARTISTSTYLE=$DEFAULTSTYLE
2243 fi
2244 VARIOUSARTISTSTYLE=$(echo 0$VARIOUSARTISTSTYLE | xargs printf %d)
2245 # If they press Enter, then the default style (0) was chosen
2246 while [ $VARIOUSARTISTSTYLE -lt 0 ] || [ $VARIOUSARTISTSTYLE -gt 7 ]; do
2247 echo "Invalid selection. Please choose a number between 1 and 7."
2248 echo -n "Selection [1-7]: "
2249 read VARIOUSARTISTSTYLE
2250 VARIOUSARTISTSTYLE=$(echo 0$VARIOUSARTISTSTYLE | xargs printf %d)
2251 done
2252 if [ "$VARIOUSARTISTSTYLE" = "0" ]; then
2253 VARIOUSARTISTSTYLE=$DEFAULTSTYLE
2254 fi
2255 vecho "Selected: $VARIOUSARTISTSTYLE"
2256 case "$VARIOUSARTISTSTYLE" in
2257 1) # Artist / Title
2258 VARIOUSARTISTSTYLE=forward
2259 ;;
2260 2) # Artist - Title
2261 VARIOUSARTISTSTYLE=forward-dash
2262 ;;
2263 3) # Title / Artist
2264 VARIOUSARTISTSTYLE=reverse
2265 ;;
2266 4) # Title - Artist
2267 VARIOUSARTISTSTYLE=reverse-dash
2268 ;;
2269 5) # Artist: Title
2270 VARIOUSARTISTSTYLE=colon
2271 ;;
2272 6) # Title (Artist)
2273 VARIOUSARTISTSTYLE=trailing-paren
2274 ;;
2275 7) # Single Artist
2276 VARIOUSARTISTS=n
2277 ;;
2278 esac
2279 fi
2280
2281 echo "variousartists=$VARIOUSARTISTS" >> "$ABCDETEMPDIR/status"
2282 echo "variousartiststyle=$VARIOUSARTISTSTYLE" >> "$ABCDETEMPDIR/status"
2283
2284 if [ "$EDITCDDB" = "y" ] && [ "$UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE" = "y" ]; then
2285 if [ "$CDDBDATAMD5SUM" != "" ] && [ "$CDDBDATAMD5SUM" != "$($MD5SUM "$CDDBDATA" | cut -d " " -f 1)" ]; then
2286 # This works but does not have the necessary error checking
2287 # yet. If you are familiar with the CDDB spec
2288 # (see http://www.freedb.org/src/latest/DBFORMAT)
2289 # and can create an error-free entry on your own, then put
2290 # UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE=y in your
2291 # abcde.conf to enable it. Put CDDBSUBMIT=email@address in
2292 # your abcde.conf to change the email address submissions are
2293 # sent to.
2294
2295 # submit the modified file, if they want
2296 if [ "$NOSUBMIT" != "y" ]; then
2297 echo -n "Do you want to submit this entry to $CDDBSUBMIT? [y/n] (n): "
2298 read YESNO
2299 while [ "$YESNO" != "y" ] && [ "$YESNO" != "n" ] && [ "$YESNO" != "Y" ] && \
2300 [ "$YESNO" != "N" ] && [ "$YESNO" != "" ]
2301 do
2302 echo -n 'Invalid selection. Please answer "y" or "n": '
2303 read YESNO
2304 done
2305 if [ "$YESNO" = "y" ] || [ "$YESNO" = "Y" ]; then
2306 echo -n "Sending..."
2307 $CDDBTOOL send "$CDDBDATA" $CDDBSUBMIT
2308 echo "done."
2309 fi
2310 fi
2311 fi
2312 fi
2313 ### FIXME ###
2314 # User CDDBLOCALPOLICY to find out if we store the file or not...
2315 # Cache edited CDDB entry in the user's cddb dir
2316 if [ "$CDDBCOPYLOCAL" = "y" ]; then
2317 # Make sure the cache directory exists
2318 mkdir -p $CDDBLOCALDIR
2319 cat "$CDDBDATA" | tail -n $(expr $(cat "$CDDBDATA" | wc -l ) - 1 ) > ${CDDBLOCALDIR}/$(echo "$TRACKINFO" | cut -d' ' -f1)
2320 fi
2321
2322 echo "cddb-edit" >> "$ABCDETEMPDIR/status"
2323 }
2324
2325 # do_cdread [tracknumber]
2326 # do_cdread onetrack [firsttrack] [lasttrack]
2327 #
2328 do_cdread ()
2329 {
2330 # The commands here don't go through run_command because they're never supposed to be silenced
2331 # return codes need to be doublechecked anyway, however
2332 if [ "$1" = "onetrack" ]; then
2333 # FIXME # Add the possibility of grabbing ranges of tracks in onetrack
2334 # FIXME # Until then, we grab the whole CD in one track, no matter what
2335 # the user said
2336 # We need the first and last track for cdda2wav
2337 FIRSTTRACK=$2
2338 LASTTRACK=$(expr $3 + 0)
2339 UTRACKNUM=$FIRSTTRACK
2340 case "$CDROMREADERSYNTAX" in
2341 flac) READTRACKNUMS="$FIRSTTRACK.1-$(($LASTTRACK + 1)).0" ;;
2342 cdparanoia) READTRACKNUMS="$FIRSTTRACK-$LASTTRACK" ;;
2343 cdda2wav) READTRACKNUMS="$FIRSTTRACK+$LASTTRACK" ;;
2344 *) echo "abcde error: $CDROMREADERSYNTAX does not support ONETRACK mode"
2345 exit 1 ;;
2346 esac
2347 else
2348 UTRACKNUM=$1
2349 fi
2350 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
2351 if [ "$USEPIPES" = "y" ]; then
2352 TEMPARG="PIPERIPPER_$CDROMREADERSYNTAX"
2353 FILEARG="$( eval echo "\$$TEMPARG" )"
2354 REDIR=""
2355 PIPE_MESSAGE="and encoding "
2356 else
2357 WAVDATA="$ABCDETEMPDIR/track$UTRACKNUM.wav"
2358 case "$CDROMREADERSYNTAX" in
2359 ## FIXME ## Find the cases for dagrab and flac, to avoid exceptions
2360 flac)
2361 FILEARG="--output-name=$WAVDATA"
2362 ;;
2363 dagrab)
2364 FILEARG="-f $WAVDATA"
2365 ;;
2366 *)
2367 FILEARG="$WAVDATA"
2368 ;;
2369 esac
2370 REDIR=">&2"
2371 fi
2372 if [ "$1" = "onetrack" ]; then
2373 echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2
2374 else
2375 if [ -r "$CDDBDATA" ]; then
2376 do_getcddbinfo TRACKNAME
2377 echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM: $TRACKNAME..." >&2
2378 else
2379 echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM..." >&2
2380 fi
2381 fi
2382 case "$CDROMREADERSYNTAX" in
2383 ### FIXME ### use an exception for flac, since it uses -o
2384 ### FIXME ### Shall we just use -o $FILEARG ??
2385 flac)
2386 # Avoid problems wit math expressions by unpadding the given UTRACKNUM
2387 STRIPTRACKNUM=$(expr $UTRACKNUM + 0)
2388 nice $READNICE $FLAC -d -f --cue=${READTRACKNUMS:-$STRIPTRACKNUM.1-$(($STRIPTRACKNUM + 1)).0} "$FILEARG" "$CDROM" ;;
2389 cdparanoia)
2390 nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS $CDROM ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR ;;
2391 cdda2wav)
2392 if [ "$OSFLAVOUR" = "OSX" ] ; then
2393 # Hei, we have to unmount the device before running anything like cdda2wav in OSX
2394 disktool -u ${CDROM#/dev/} 0
2395 # Also, in OSX the cdrom device for cdda2wav changes...
2396 CDDA2WAVCDROM="IODVDServices"
2397 elif [ "$OSFLAVOUR" = "FBSD" ] ; then
2398 CDDA2WAVCDROM="$CDROMID"
2399 else
2400 if [ "$CDROMID" = "" ]; then
2401 CDDA2WAVCDROM="$CDROM"
2402 else
2403 CDDA2WAVCDROM="$CDROMID"
2404 fi
2405 fi
2406 nice $READNICE $CDROMREADER -D $CDDA2WAVCDROM -t ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR
2407 ;;
2408 ## FIXME ## We have an exception for dagrab, since it uses -f
2409 ## FIXME ## Shall we just use -f $FILEARG ??
2410 dagrab) nice $READNICE $CDROMREADER -d $CDROM -v $UTRACKNUM "$FILEARG" $REDIR
2411 ;;
2412 cddafs)
2413 # Find the track's mounted path
2414 REALTRACKNUM=$(expr $UTRACKNUM + 0)
2415 FILEPATH=$(mount | grep "$CDROM on" | sed 's/^[^ ]* on \(.*\) (.*/\1/')
2416 FILEPATH=$(find "$FILEPATH" | grep "/$REALTRACKNUM ");
2417 # If the file exists, copy it
2418 if [ -e "$FILEPATH" ] ; then
2419 nice $READNICE $CDROMREADER "$FILEPATH" "$FILEARG" $REDIR
2420 else
2421 false
2422 fi ;;
2423 debug) nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS $CDROM -w $UTRACKNUM-[:1] "$FILEARG" $REDIR
2424 ;;
2425 esac
2426 RETURN=$?
2427 # If we get some error or we get some missing wav
2428 # (as long as we dont use pipes)
2429 if [ "$RETURN" != "0" -o \( ! -s "$WAVDATA" -a X"$USEPIPES" != "Xy" \) ]; then
2430 # Thank goodness errors is only machine-parseable up to the
2431 # first colon, otherwise this woulda sucked
2432 if [ "$RETURN" = "0" -a ! -s "$WAVDATA" ]; then
2433 RETURN=73 # fake a return code as cdparanoia return 0 also on aborted reads
2434 fi
2435 if [ "$USEPIPES" = "y" ]; then
2436 echo "readencodetrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
2437 else
2438 echo "readtrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
2439 fi
2440 return $RETURN
2441 else
2442 if [ "$USEPIPES" = "y" ]; then
2443 echo readencodetrack-$UTRACKNUM >> "$ABCDETEMPDIR/status"
2444 else
2445 echo readtrack-$UTRACKNUM >> "$ABCDETEMPDIR/status"
2446 fi
2447 if [ "$1" = "onetrack" ]; then
2448 echo onetrack >> "$ABCDETEMPDIR/status"
2449 fi
2450 fi
2451 }
2452
2453 # do_cdspeed
2454 # No values accepted, only uses env variables
2455 do_cdspeed ()
2456 {
2457 if "$CDSPEED" "$CDSPEEDOPTS" "$CDSPEEDVALUE" >/dev/null ; then
2458 vecho "Setting CD speed to ${CDSPEEDVALUE}x"
2459 else
2460 echo "abcde: unable to set the device speed" >&2
2461 fi
2462 }
2463
2464 # vecho [message]
2465 #
2466 # vecho outputs a message if EXTRAVERBOSE is selected
2467 vecho ()
2468 {
2469 if [ x"$EXTRAVERBOSE" != "x" ]; then
2470 case $1 in
2471 warning) shift ; log warning "$@" ;;
2472 *) echo "$@" ;;
2473 esac
2474 fi
2475 }
2476
2477 # decho [message]
2478 #
2479 # decho outputs a debug message if DEBUG is selected
2480 decho ()
2481 {
2482 if [ x"$DEBUG" != "x" ]; then
2483 if echo $1 | grep -q "^\[" ; then
2484 DEBUGECHO=$(echo "$@" | tr -d '[]')
2485 echo "[DEBUG] $DEBUGECHO: `eval echo \\$${DEBUGECHO}`"
2486 else
2487 echo "[DEBUG] $1"
2488 fi
2489 fi
2490 }
2491
2492 # User-redefinable functions
2493 # Custom filename munging:
2494 mungefilename ()
2495 {
2496 #echo "$@" | sed s,:,\ -,g | tr \ /\* __+ | tr -d \'\"\?\[:cntrl:\]
2497 echo "$@" | sed s,:,\ -,g | tr \ / __ | tr -d \'\"\?\[:cntrl:\]
2498 }
2499
2500 # Custom genre munging:
2501 mungegenre ()
2502 {
2503 echo $CDGENRE | tr "[:upper:]" "[:lower:]"
2504 }
2505
2506 # pre_read
2507 # Empty pre_read function, to be defined in the configuration file.
2508 pre_read ()
2509 {
2510 :
2511 }
2512
2513 # post_read
2514 # Empty post_read function, to be defined in the configuration file.
2515 post_read ()
2516 {
2517 :
2518 }
2519
2520 ###############################################################################
2521 # End of functions
2522 #
2523 # Start of execution
2524 ###############################################################################
2525
2526 # Builtin defaults
2527
2528 # CDDB
2529 # Defaults to FreeDB, but a python musicbrainz can be used
2530 CDDBMETHOD=cddb
2531 CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"
2532 CDDBSUBMIT=freedb-submit@freedb.org
2533 CDDBPROTO=5
2534 HELLOINFO="$(whoami)@$(hostname)"
2535 CDDBCOPYLOCAL="n"
2536 CDDBLOCALPOLICY="always"
2537 CDDBLOCALRECURSIVE="y"
2538 CDDBLOCALDIR="$HOME/.cddb"
2539 CDDBUSELOCAL="n"
2540
2541 # List of fields we parse and show during the CDDB parsing...
2542 SHOWCDDBFIELDS="year,genre"
2543
2544 INTERACTIVE=y
2545 #CDROMREADERSYNTAX=cdparanoia
2546 ENCODERSYNTAX=default
2547
2548 MP3ENCODERSYNTAX=default
2549 OGGENCODERSYNTAX=default
2550 FLACENCODERSYNTAX=default
2551 SPEEXENCODERSYNTAX=default
2552 MPPENCODERSYNTAX=default
2553 AACENCODERSYNTAX=default
2554 NORMALIZERSYNTAX=default
2555 CUEREADERSYNTAX=default
2556
2557 OUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${TRACKNUM}.${TRACKFILE}'
2558 # Use the following VAOUTPUTFORMAT to revert to 2.0.x VA format:
2559 #VAOUTPUTFORMAT=${OUTPUTFORMAT}
2560 VAOUTPUTFORMAT='Various-${ALBUMFILE}/${TRACKNUM}.${ARTISTFILE}-${TRACKFILE}'
2561 ONETRACKOUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${ALBUMFILE}'
2562 VAONETRACKOUTPUTFORMAT='Various-${ALBUMFILE}/${ALBUMFILE}'
2563 PLAYLISTFORMAT='${ARTISTFILE}-${ALBUMFILE}.${OUTPUT}.m3u'
2564 PLAYLISTDATAPREFIX=''
2565 VAPLAYLISTFORMAT='${ARTISTFILE}-${ALBUMFILE}.${OUTPUT}.m3u'
2566 VAPLAYLISTDATAPREFIX=''
2567 DOSPLAYLIST=n
2568 COMMENT=''
2569 ID3TAGV=2
2570 ENCNICE=10
2571 READNICE=10
2572 DISTMP3NICE=10
2573 VARIOUSARTISTS=n
2574 VARIOUSARTISTSTYLE=forward
2575 KEEPWAVS=n
2576 PADTRACKS=n
2577 NOGAP=n
2578 BATCHNORM=n
2579
2580 # If using scsi devices, cdda2wav needs a CDROMID, instead of a device node
2581 # i.e. CDROMID="1,0,0"
2582 CDROMID=""
2583 # If we are using the IDE bus, we need CDPARANOIACDROMBUS defined as "d"
2584 # If we are using the ide-scsi emulation layer, we need to define a "g"
2585 CDPARANOIACDROMBUS="d"
2586
2587 # program paths - defaults to checking your $PATH
2588 # mp3
2589 LAME=lame
2590 TOOLAME=toolame
2591 GOGO=gogo
2592 BLADEENC=bladeenc
2593 L3ENC=l3enc
2594 XINGMP3ENC=xingmp3enc
2595 MP3ENC=mp3enc
2596 # ogg
2597 VORBIZE=vorbize
2598 OGGENC=oggenc
2599 # flac
2600 FLAC=flac
2601 # speex
2602 SPEEXENC=speexenc
2603 # mpp (Musepack)
2604 MPPENC=mppenc
2605 # m4a
2606 AACENC=faac
2607
2608 ID3=id3
2609 ID3V2=id3v2
2610 EYED3=eyeD3
2611 CDPARANOIA=cdparanoia
2612 CDDA2WAV=cdda2wav
2613 DAGRAB=dagrab
2614 CDDAFS=cp
2615 CDDISCID=cd-discid
2616 CDDBTOOL=cddb-tool
2617 MUSICBRAINZ=musicbrainz-get-tracks
2618 EJECT=eject
2619 MD5SUM=md5sum
2620 DISTMP3=distmp3
2621 VORBISCOMMENT=vorbiscomment
2622 METAFLAC=metaflac
2623 NORMALIZE=normalize-audio
2624 CDSPEED=eject
2625 VORBISGAIN=vorbisgain
2626 MP3GAIN=mp3gain
2627 MPPGAIN=replaygain
2628 MKCUE=mkcue
2629 MKTOC=cdrdao
2630 DIFF=diff
2631 CUE2DISCID=cue2discid
2632
2633 # Options for programs called from abcde
2634 # mp3
2635 LAMEOPTS=
2636 TOOLAMEOPTS=
2637 GOGOOPTS=
2638 BLADEENCOPTS=
2639 L3ENCOPTS=
2640 XINGMP3ENCOPTS=
2641 MP3ENCOPTS=
2642 # ogg
2643 VORBIZEOPTS=
2644 OGGENCOPTS=
2645 # flac
2646 FLACOPTS=
2647 # speex
2648 SPEEXENCOPTS=
2649 # mpc
2650 MPPENCOPTS=
2651 # m4a
2652 AACENCOPTS=
2653
2654 ID3OPTS=
2655 ID3V2OPTS=
2656 CDPARANOIAOPTS=
2657 CDDA2WAVOPTS=
2658 DAGRABOPTS=
2659 CDDAFSOPTS="-f"
2660 CDDBTOOLOPTS=
2661 EJECTOPTS=
2662 DISTMP3OPTS=
2663 NORMALIZEOPTS=
2664 CDSPEEDOPTS="-x"
2665 CDSPEEDVALUE=
2666 MKCUEOPTS=
2667 MKTOCOPTS=""
2668 VORBISCOMMENTOPTS="-R"
2669 METAFLACOPTS="--no-utf8-convert"
2670 DIFFOPTS=
2671
2672 # Default to one process if -j isn't specified
2673 MAXPROCS=1
2674
2675 # List of actions to perform - by default, run to completion
2676 ACTIONS=cddb,read,encode,tag,move,clean
2677
2678 # This option is basicaly for Debian package dependencies:
2679 # List of prefered outputs - by default, run with whatever we have in the path
2680 DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:lame,mp3:bladeenc,spx:speex
2681
2682 # List of prefered cdromreaders - by default, run whichever we have in the path
2683 DEFAULT_CDROMREADERS="cdparanoia cdda2wav"
2684
2685 # Asume fetch if under FreeBSD. curl is used for Mac OS X. wget is used for Linux/OpenBSD/NetBSD.
2686 # Let's use these checkings to determine the OS flavour, which will be used later
2687 if [ X$(uname) = "XFreeBSD" ] ; then
2688 HTTPGET=fetch
2689 MD5SUM=md5
2690 NEEDCDROMID=y
2691 OSFLAVOUR=FBSD
2692 elif [ X$(uname) = "XDarwin" ] ; then
2693 HTTPGET=curl
2694 OSFLAVOUR=OSX
2695 # We should have disktool in OSX, but let's be sure...
2696 NEEDDISKTOOL=y
2697 CDROMREADERSYNTAX=cddafs
2698 elif [ X$(uname) = "XOpenBSD" ] ; then
2699 HTTPGET=wget
2700 MD5SUM=md5
2701 elif [ X$(uname) = "XNetBSD" ] ; then
2702 HTTPGET=ftp
2703 MD5SUM=md5
2704 else
2705 HTTPGET=wget
2706 fi
2707
2708 # If CDDBAVAIL is set to n, no CDDB read is done
2709 # If USEID3 is set to n, no ID3 tagging is done
2710 CDDBAVAIL=y
2711 USEID3=y
2712 USEID3V2=y
2713
2714 if [ -z "$OUTPUTDIR" ]; then
2715 OUTPUTDIR=$(pwd)
2716 fi
2717
2718 if [ -z "$WAVOUTPUTDIR" ]; then
2719 WAVOUTPUTDIR="$OUTPUTDIR"
2720 fi
2721
2722 # Load system defaults
2723 if [ -r /etc/abcde.conf ]; then
2724 . /etc/abcde.conf
2725 fi
2726 # Load user preference defaults
2727 if [ -r $HOME/.abcde.conf ]; then
2728 . $HOME/.abcde.conf
2729 fi
2730
2731 # By this time, we need some HTTPGETOPTS already defined.
2732 # If the user has defined a non-default HTTPGET method, we should not be empty.
2733
2734 if [ "$HTTPGETOPTS" = "" ] ; then
2735 case $HTTPGET in
2736 wget) HTTPGETOPTS="-q -O -";;
2737 curl) HTTPGETOPTS="-f -s";;
2738 fetch)HTTPGETOPTS="-q -o -";;
2739 ftp) HTTPGETOPTS="-q -o -";;
2740 *) log warning "HTTPGET in non-standard and HTTPGETOPTS are not defined." ;;
2741 esac
2742 fi
2743
2744 # If the CDROM has not been set yet, find a suitable one.
2745 # If this is a devfs system, default to /dev/cdroms/cdrom0
2746 # instead of /dev/cdrom
2747 if [ "$CDROM" = "" ] ; then
2748 if [ -e /dev/cdroms/cdrom0 ]; then
2749 CDROM=/dev/cdroms/cdrom0
2750 elif [ -e /dev/cdrom ]; then
2751 CDROM=/dev/cdrom
2752 elif [ -e /dev/cd0c ]; then
2753 CDROM=/dev/cd0c
2754 elif [ -e /dev/acd0c ]; then
2755 CDROM=/dev/acd0c
2756 elif [ -e /dev/disk1 ]; then
2757 CDROM=/dev/disk1
2758 fi
2759 fi
2760
2761 # Parse command line options
2762 #while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:t:T:vVxw:W: opt ; do
2763 while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:uvVxw:W:z opt ; do
2764 case "$opt" in
2765 1) ONETRACK=y ;;
2766 a) ACTIONS="$OPTARG" ;;
2767 A) EXPACTIONS="$OPTARG" ;;
2768 b) BATCHNORM=y ;;
2769 B) NOBATCHREPLAYGAIN=y ;;
2770 c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else log error "config file \"$OPTARG\" cannot be found." ; exit 1 ; fi ;;
2771 C) DISCID="$( echo ${OPTARG#abcde.} | tr -d /)" ;;
2772 d) CDROM="$OPTARG" ;;
2773 D) set -x ;;
2774 e) ERASEENCODEDSTATUS=y ;;
2775 h) usage; exit ;;
2776 e) ERASEENCODEDSTATUS=y ;;
2777 E) ENCODING="$OPTARG" ;;
2778 f) FORCE=y ;;
2779 g) NOGAP=y ;;
2780 i) INLINETAG=y ;;
2781 j) MAXPROCS="$OPTARG" ;;
2782 k) KEEPWAVS=y ;;
2783 l) LOWDISK=y ;;
2784 L) CDDBUSELOCAL=y ;;
2785 n) CDDBAVAIL=n ;;
2786 N) INTERACTIVE=n ;;
2787 m) DOSPLAYLIST=y ;;
2788 M) MAKECUEFILE=y ;;
2789 o) OUTPUTTYPE="$OPTARG" ;;
2790 p) PADTRACKS=y ;;
2791 P) USEPIPES=y ;;
2792 r) REMOTEHOSTS="$OPTARG" ;;
2793 R) DOREPLAYGAIN=y ;;
2794 s) SHOWCDDBFIELDS="$OPTARG" ;;
2795 S) CDSPEEDVALUE="$OPTARG" ;;
2796 t) STARTTRACKNUMBER="$OPTARG" ;;
2797 T) STARTTRACKNUMBER="$OPTARG" ; STARTTRACKNUMBERTAG="y" ;;
2798 u) CDDBPROTO=6 ;;
2799 v)
2800 echo "This is abcde v$VERSION."
2801 echo "Usage: abcde [options] [tracks]"
2802 echo "abcde -h for extra help"
2803 exit
2804 ;;
2805 V) EXTRAVERBOSE="y" ;;
2806 x) EJECTCD="y" ;;
2807 w) COMMENT="$OPTARG" ;;
2808 W) if echo $OPTARG | grep -q "[[:digit:]]" ; then
2809 STARTTRACKNUMBER="${OPTARG}01" ; STARTTRACKNUMBERTAG="y" ; COMMENT="CD${OPTARG}"
2810 else
2811 log error "argument of -W must be integer"
2812 exit 1
2813 fi
2814 ;;
2815 z) DEBUG=y ; CDROMREADERSYNTAX=debug ; EJECTCD="n" ;;
2816 ?) usage; exit ;;
2817 esac
2818 done
2819
2820 shift $(($OPTIND - 1))
2821
2822 # If the user specified a flac file, then switch to special flac mode
2823 if echo $CDROM | grep -i -q '.flac$'; then
2824 vecho warning "abcde: switching to flac CDROMREADERSYNTAX..."
2825 CDROMREADERSYNTAX=flac
2826 # Added a need on CUE2DISCID until we manage to convert the python script to bash.
2827 NEEDCUE2DISCID=y
2828 NEEDMETAFLAC=y
2829 EJECTCD=n
2830 fi
2831
2832 # If the user provided a DISCID, disable eject
2833 if [ -n "$DISCID" ] || [ "$CDROMREADERSYNTAX" = "flac" ]; then EJECTCD=n ; fi
2834
2835 # Check the available cd rippers in the system, from the ones we know.
2836 if [ "$CDROMREADERSYNTAX" = "" ]; then
2837 for DEFAULT_CDROMREADER in $DEFAULT_CDROMREADERS; do
2838 if [ -x $( which $DEFAULT_CDROMREADER ) ]; then
2839 CDROMREADERSYNTAX=$DEFAULT_CDROMREADER
2840 break
2841 fi
2842 done
2843 if [ "$CDROMREADERSYNTAX" = "" ]; then
2844 log error "no cdreader found in your PATH"
2845 log error "hints: are all dependencies installed? has the \$PATH been modified?"
2846 exit 1
2847 fi
2848 fi
2849
2850 # Decide if we can continue.
2851 if [ "$ONETRACK" = "y" ]; then
2852 # FIXME # remove check as soon as we find out about the other readers
2853 case "$CDROMREADERSYNTAX" in
2854 flac) ;;
2855 cdparanoia) ;;
2856 cdda2wav) ;;
2857 *) log error "$CDROMREADERSYNTAX does not support ONETRACK mode"
2858 exit 1 ;;
2859 esac
2860 if [ "$BATCHNORM" = "y" ]; then
2861 log warning "BATCHNORM mode is not compatible with ONETRACK mode. Disabling..."
2862 BATCHNORM=n
2863 fi
2864 if [ "$NOGAP" = "y" ]; then
2865 log warning "NOGAP mode is not compatible with ONETRACK mode. Disabling..."
2866 NOGAP=n
2867 fi
2868 # It does not matter how many tracks we want. In ONETRACK mode we grab them all
2869 # FIXME # allow ranges of tracks to be selected for onetrack ripping
2870 if [ $# -gt 0 ]; then
2871 log warning "ONETRACK mode selected, grabbing all tracks..."
2872 fi
2873 else
2874 while [ $# -gt 0 ]; do
2875 # Range parsing code courtesy of Vincent Ho
2876 RSTART=$(echo $1 | cut -f1 -d-)
2877 REND=$(echo $1 | cut -f2 -d-)
2878 if [ "$RSTART" = "$REND" ]; then
2879 NEWTRACKS="$RSTART"
2880 else
2881 NEWTRACKS=$(f_seq_line $RSTART $REND)
2882 fi
2883 TRACKQUEUE=$(echo "$TRACKQUEUE" "$NEWTRACKS")
2884 shift
2885 done
2886 fi
2887
2888 # List of valid actions: cddb,read,normalize,encode,tag,move,playlist,clean
2889 # List of experimental actions: retag,transcode
2890
2891 # Determine what actions are to be done from $ACTIONS and set the
2892 # following environment variables for them:
2893 DOCDDB=n
2894 DOREAD=n
2895 DONORMALIZE=n
2896 DOPREPROCESS=n
2897 DOENCODE=n
2898 DOPOSTPROCESS=n
2899 DOTAG=n
2900 DOMOVE=n
2901 DOREPLAYGAIN=n
2902 DOPLAYLIST=n
2903 DOCLEAN=n
2904
2905 for ACTION in $(echo $ACTIONS | tr , \ )
2906 do
2907 case $ACTION in
2908 cddb) DOCDDB=y;;
2909 read) DOREAD=y;;
2910 normalize) DONORMALIZE=y; DOREAD=y;;
2911 # preprocess) DOPREPROCESS=y; DOREAD=y;;
2912 encode) DOENCODE=y; DOREAD=y;;
2913 # postprocess) DOPREPROCESS=y; DOENCODE=y; DOREAD=y;;
2914 tag) DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
2915 move) DOMOVE=y; DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
2916 replaygain) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOREPLAYGAIN=y;;
2917 playlist) DOCDDB=y; DOPLAYLIST=y;;
2918 clean) DOCLEAN=y;;
2919 esac
2920 done
2921
2922 if [ "$DONORMALIZE" = "y" ] && [ "$DOREPLAYGAIN" = "y" ]; then
2923 # FIXME # should we abort on error or just inform the user?
2924 log warning "selected both normalize and replaygain actions"
2925 fi
2926
2927 for SHOWCDDBFIELD in $(echo $SHOWCDDBFIELDS | tr , \ ); do
2928 case $SHOWCDDBFIELD in
2929 y*|Y*) SHOWCDDBYEAR="y";;
2930 g*|G*) SHOWCDDBGENRE="y";;
2931 *) ;;
2932 esac
2933 done
2934
2935 # Sanity checks:
2936
2937 # At this point a CDROM has to be defined, so we check it exists.
2938 if [ X"$CDROM" != "X" ] ; then
2939 if [ "$CDROMREADERSYNTAX" = "cdda2wav" ] && [ "$NEEDCDROMID" = "y" ] ; then
2940 if [ "$OSFLAVOUR" = "FBSD" ]; then
2941 if ! echo "$CDROMID" | grep "^[0-9],[0-9],[0-9]$" >/dev/null 2>&1 ; then
2942 log error "CDROMID not in the right format for $CDROMREADERSYNTAX"
2943 log error "Use \"cdrecord -scanbus\" to obtain a adecuate ID an set CDROMID accordingly"
2944 exit 1
2945 fi
2946 fi
2947 elif [ ! -e "$CDROM" -a X"$DOREAD" = "Xy" ]; then
2948 log error "CDROM device cannot be found."
2949 exit 1
2950 fi
2951 # avoid processing if we are not going to hit the CDROM.
2952 elif [ X"$DOREAD" = "Xy" ]; then
2953 log error "CDROM has not been defined or cannot be found"
2954 exit 1
2955 fi
2956
2957 # USEPIPES pre-tests, before we get into more serious stuff
2958 # Not compatible with:
2959 # - multiple outputs
2960 # - normalize
2961 # - lowdisk algorithm
2962 # - anything else?
2963 if [ X"$USEPIPES" = "Xy" ]; then
2964 if [ $(echo "$OUTPUTTYPE" | tr , \ | wc -w ) -gt 1 ]; then
2965 log error "Unix pipes not compatible with multiple outputs"
2966 exit 1
2967 fi
2968 if [ X"$DONORMALIZE" = "Xy" ]; then
2969 log error "Unix pipes not compatible with normalizer"
2970 # FIXME # Do we need to exit or shall we just disable the mode?
2971 exit 1
2972 fi
2973 if [ X"$BATCHNORM" = "Xy" ]; then
2974 log error "Unix pipes not compatible with BATCHNORM encoding"
2975 exit 1
2976 fi
2977 if [ X"$NOGAP" = "Xy" ]; then
2978 log error "Unix pipes not compatible with NOGAP encoding"
2979 exit 1
2980 fi
2981 if [ X"$DOENCODE" = "Xn" ]; then
2982 vecho warning "Disabling Unix pipes since we are not encoding!"
2983 USEPIPES=n
2984 fi
2985 if [ X"$LOWDISK" = "Xy" ]; then
2986 log error "Unix pipes not compatible with lowdisk algorithm"
2987 exit 1
2988 fi
2989 fi
2990
2991 # LOWDISK pre-tests, before we get into more problematic stuff
2992 # Not compatible with anything that needs all the files in the hard disc:
2993 # - BATCHNORM
2994 # - NOGAP lame mode
2995 if [ X"$LOWDISK" = "Xy" ]; then
2996 if [ X"$BATCHNORM" = "Xy" ]; then
2997 log error "Unix pipes not compatible with BATCHNORM encoding"
2998 exit 1
2999 fi
3000 if [ X"$NOGAP" = "Xy" ]; then
3001 log error "Unix pipes not compatible with NOGAP encoding"
3002 exit 1
3003 fi
3004 fi
3005
3006 # BATCHNORM pre-tests, before we get into serious problems
3007 # Not compatible with
3008 if [ "$BATCHNORM" = "y" ] && [ "$DONORMALIZE" = "n" ]; then
3009 vecho warning "Disabling BATCHNORM since we are not normalizing!"
3010 BATCHNORM=n
3011 fi
3012
3013 # Check the encoding format from the ones available in the system, if nothing has been configured in the system.
3014 if [ X"$OUTPUTTYPE" = "X" ]; then
3015 for DEFAULT_OUTPUT in $( echo "$DEFAULT_OUTPUT_BINARIES" | tr , \ ); do
3016 DEFAULT_OUTPUT_FORMAT="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 1)"
3017 DEFAULT_OUTPUT_BINARY="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 2)"
3018 if [ -x $(which $DEFAULT_OUTPUT_BINARY) ] ; then
3019 OUTPUTTYPE=$DEFAULT_OUTPUT_FORMAT
3020 vecho "No default output type defined. Autoselecting $OUTPUTTYPE..." >&2
3021 break
3022 fi
3023 done
3024 if [ X"$OUTPUTTYPE" = "X" ]; then
3025 log error "no encoder found in the PATH"
3026 log error "hints: are all dependencies installed? has the \$PATH been modified?"
3027 exit 1
3028 fi
3029 fi
3030
3031 # Decide which CDROM reader we're gonna use
3032 case "$CDROMREADERSYNTAX" in
3033 cdparanoia|debug)
3034 CDROMREADER="$CDPARANOIA"
3035 CDROMREADEROPTS="$CDPARANOIAOPTS"
3036 ;;
3037 cdda2wav)
3038 CDROMREADER="$CDDA2WAV"
3039 CDROMREADEROPTS="$CDDA2WAVOPTS"
3040 ;;
3041 dagrab)
3042 CDROMREADER="$DAGRAB"
3043 CDROMREADEROPTS="$DAGRABOPTS"
3044 ;;
3045 cddafs)
3046 CDROMREADER="$CDDAFS"
3047 CDROMREADEROPTS="$CDDAFSOPTS"
3048 ;;
3049 flac)
3050 CDROMREADER="$FLAC"
3051 CDROMREADEROPTS="$FLACOPTS"
3052 ;;
3053 esac
3054
3055 # There's only one normalize...
3056 case "$NORMALIZERSYNTAX" in
3057 default|normalize)
3058 NORMALIZER="$NORMALIZE"
3059 NORMALIZEROPTS="$NORMALIZEOPTS"
3060 ;;
3061 esac
3062
3063 # Allow -o OUTPUT(1):OPTIONS(1),...,OUTPUT(N):OPTIONS(N) mode of operation
3064 if echo "$OUTPUTTYPE" | grep ":" > /dev/null 2>&1 ; then
3065 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do
3066 case "$OUTPUT" in
3067 vorbis:*|ogg:*) OGGENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3068 mp3:*) MP3ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3069 flac:*) FLACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3070 spx:*) SPEEXENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3071 mpc:*) MPPENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3072 m4a:*) AACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3073 esac
3074 done
3075 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do
3076 TEMPOUTPUT=$( echo "$OUTPUT" | cut -d: -f1 )
3077 TEMPOUTPUTTYPE="${TEMPOUTPUTTYPE:+$TEMPOUTPUTTYPE,}$TEMPOUTPUT"
3078 done
3079 OUTPUTTYPE="$TEMPOUTPUTTYPE"
3080 fi
3081
3082 # If nothing has been specified, use oggenc for oggs and lame for mp3s and flac
3083 # for flacs and speexenc for speex and mppenc for mpps and faac for m4as
3084
3085 # Getting ready for multiple output changes
3086 for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
3087 do
3088 case $OUTPUT in
3089 vorbis|ogg)
3090 [ "$OGGENCODERSYNTAX" = "default" ] && OGGENCODERSYNTAX=oggenc
3091 [ "$DOTAG" = "y" ] && NEEDCOMMENTER=y
3092 [ "$DOREPLAYGAIN" = "y" ] && NEEDVORBISGAIN=y
3093 OGGOUTPUTCONTAINER=ogg
3094 ;;
3095 mp3)
3096 [ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame
3097 [ "$DOTAG" = "y" ] && NEEDTAGGER=y
3098 [ "$DOREPLAYGAIN" = "y" ] && NEEDMP3GAIN=y
3099 ;;
3100 flac)
3101 [ "$FLACENCODERSYNTAX" = "default" ] && FLACENCODERSYNTAX=flac
3102 [ "$DOTAG" = "y" ] && NEEDMETAFLAC=y
3103 [ "$DOREPLAYGAIN" = "y" ] && NEEDMETAFLAC=y
3104 ;;
3105 spx)
3106 [ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc
3107 # [ "$DOREPLAYGAIN" = "y" ] &&
3108 ;;
3109 mpc)
3110 [ "$MPPENCODERSYNTAX" = "default" ] && MPPENCODERSYNTAX=mppenc
3111 [ "$DOREPLAYGAIN" = "y" ] && NEEDMPPGAIN=y
3112 ;;
3113 m4a)
3114 [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac
3115 ;;
3116 wav)
3117 if [ "$KEEPWAVS" = "y" ]; then
3118 vecho "Unsetting the KEEPWAVS option, since the resulting wav files were requested..."
3119 fi
3120 KEEPWAVS=move
3121 ;;
3122 *) log error "Invalid OUTPUTTYPE defined"
3123 exit 1
3124 ;;
3125 esac
3126 done
3127
3128 # decide which encoder
3129 case "$MP3ENCODERSYNTAX" in
3130 lame)
3131 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$LAMEOPTS}"
3132 MP3ENCODER="$LAME"
3133 ;;
3134 toolame)
3135 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$TOOLAMEOPTS}"
3136 MP3ENCODER="$TOOLAME"
3137 ;;
3138 gogo)
3139 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$GOGOOPTS}"
3140 MP3ENCODER="$GOGO"
3141 ;;
3142 bladeenc)
3143 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$BLADEENCOPTS}"
3144 MP3ENCODER="$BLADEENC"
3145 ;;
3146 l3enc)
3147 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$L3ENCOPTS}"
3148 MP3ENCODER="$L3ENC"
3149 ;;
3150 xingmp3enc)
3151 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$XINGMP3ENCOPTS}"
3152 MP3ENCODER="$XINGMP3ENC"
3153 ;;
3154 mp3enc)
3155 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$MP3ENCOPTS}"
3156 MP3ENCODER="$MP3ENC"
3157 ;;
3158 esac
3159 case "$OGGENCODERSYNTAX" in
3160 vorbize)
3161 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$VORBIZEOPTS}"
3162 OGGENCODER="$VORBIZE"
3163 ;;
3164 oggenc)
3165 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$OGGENCOPTS}"
3166 OGGENCODER="$OGGENC"
3167 ;;
3168 esac
3169 case "$FLACENCODERSYNTAX" in
3170 flac)
3171 FLACENCODEROPTS="${FLACENCODEROPTSCLI:-$FLACOPTS}"
3172 FLACENCODER="$FLAC"
3173 # FLAC streams can be encapsulated on a Ogg transport layer
3174 if echo "$FLACENCODEROPTS" | egrep -q -- "(^| )--ogg($| )" ;then
3175 log error "FLAC on an Ogg container is not yet supported"
3176 log error "due to problem with adding comments to such files"
3177 exit 1
3178 FLACOUTPUTCONTAINER=ogg
3179 else
3180 FLACOUTPUTCONTAINER=flac
3181 fi
3182 ;;
3183 esac
3184 case "$SPEEXENCODERSYNTAX" in
3185 speexenc)
3186 SPEEXENCODEROPTS="${SPEEXENCODEROPTSCLI:-$SPEEXENCOPTS}"
3187 SPEEXENCODER="$SPEEXENC"
3188 ;;
3189 esac
3190 case "$MPPENCODERSYNTAX" in
3191 mppenc)
3192 MPPENCODEROPTS="${MPPENCODEROPTSCLI:-$MPPENCOPTS}"
3193 MPPENCODER="$MPPENC"
3194 ;;
3195 esac
3196 case "$AACENCODERSYNTAX" in
3197 faac)
3198 AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
3199 AACENCODER="$AACENC"
3200 ;;
3201 esac
3202 # and which tagger
3203
3204 if [ "$ID3TAGV" = "1" ]; then
3205 TAGGER="$ID3"
3206 TAGGEROPTS="$ID3OPTS"
3207 else
3208 TAGGER="$ID3V2"
3209 TAGGEROPTS="$ID3V2OPTS"
3210 fi
3211
3212 # Specific for NOGAP is the use of lame. Another encoder fails...
3213 if [ "$NOGAP" = "y" ] && [ ! "$MP3ENCODER" = "lame" ]; then
3214 log warning "the NOGAP option is specific of lame. Deactivating..."
3215 NOGAP=n
3216 fi
3217
3218 # Options for mkcue
3219 case "$CUEREADERSYNTAX" in
3220 default|mkcue)
3221 CUEREADEROPTS="${CDROM}"
3222 CUEREADER="$MKCUE"
3223 ;;
3224 esac
3225
3226 # which information retrieval tool are we using?
3227 case "$CDDBTOOL" in
3228 cddb) ;;
3229 musicbrainz) ;;
3230 esac
3231
3232 # Check if both OGGEOUTPUTCONTAINER and FLACOUTPUTCONTAINER are the same, and differentiante them
3233 if [ X"$OGGOUTPUTCONTAINER" = "Xogg" ] && [ X"$FLACOUTPUTCONTAINER" = "Xogg" ]; then
3234 log error "FLAC on an Ogg container is not yet supported"
3235 log error "due to problem with adding comments to such files"
3236 exit 1
3237 OGGOUTPUTCONTAINER=ogg.ogg
3238 FLACOUTPUTCONTAINER=flac.ogg
3239 vecho warning "modified file endings due to conflicting transport layers in Ogg/Vorbis and Ogg/FLAC"
3240 fi
3241
3242 # Clean up nice options (either use '-n NICELEVEL or -NICELEVEL')
3243
3244 if [ "$ENCNICE" ]; then
3245 ENCNICE="-n $ENCNICE"
3246 fi
3247 if [ "$READNICE" ]; then
3248 READNICE="-n $READNICE"
3249 fi
3250 if [ "$DISTMP3NICE" ]; then
3251 DISTMP3NICE="-n $DISTMP3NICE"
3252 fi
3253
3254 # Don't check for stuff if it's not needed
3255 if [ "$REMOTEHOSTS" ]; then
3256 NEEDDISTMP3=y
3257 fi
3258 if [ "$DONORMALIZE" = "y" ]; then
3259 NEEDNORMALIZER=y
3260 fi
3261 if [ "$EJECTCD" = "y" ]; then
3262 NEEDEJECT=y
3263 fi
3264 if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then
3265 if [ "$CDDBMETHOD" = "cddb" ]; then
3266 NEEDHTTPGET=y
3267 elif [ "$CDDBMETHOD" = "musicbrainz" ]; then
3268 :
3269 fi
3270 fi
3271 if [ "$MAKECUEFILE" = "y" ]; then
3272 NEEDCUEREADER=y
3273 fi
3274
3275 if [ X"$CDSPEEDVALUE" != "X" ] && [ "$DOREAD" = "y"]; then
3276 case "$CDROMREADERSYNTAX" in
3277 cdparanoia|debug) CDROMREADEROPTS="$CDPARANOIAOPTS -S $CDSPEEDVALUE" ;;
3278 ### FIXME ### translate "cue2discid" from python to bash
3279 flac) NEEDMETAFLAC=y ; NEEDCUE2DISCID=y ; CDSPEEDVALUE="" ;;
3280 *) NEEDCDSPEED=y ;;
3281 esac
3282 fi
3283
3284 ###USEPIPESSUPPORT###
3285
3286 # Rippers with USEPIPE support
3287 # FIXME # Include here all the rippers we can figure out support pipes
3288 PIPERIPPER_cdparanoia="-"
3289 PIPERIPPER_debug="-"
3290 PIPERIPPER_flac="-c "
3291
3292 # Encoders with USEPIPE support
3293 # FIXME # Include here all the encoders we can figure out support pipes
3294 PIPE_lame="-"
3295 PIPE_bladeenc="-"
3296 PIPE_oggenc="-"
3297 PIPE_flac="-"
3298
3299 # Figure out if we can use pipes with the ripper/encoder combination
3300 # exit otherwise
3301 if [ "$USEPIPES" = "y" ]; then
3302 PIPERIPPERSVARCHECK="PIPERIPPER_${CDROMREADERSYNTAX}"
3303 case "$OUTPUT" in
3304 mp3)
3305 PIPEENCODERSVARCHECK="PIPE_$MP3ENCODERSYNTAX" ;;
3306 vorbis|ogg)
3307 PIPEENCODERSVARCHECK="PIPE_$OGGENCODERSYNTAX" ;;
3308 flac)
3309 PIPEENCODERSVARCHECK="PIPE_$FLACENCODERSYNTAX" ;;
3310 spx)
3311 PIPEENCODERSVARCHECK="PIPE_$SPEEXENCODER" ;;
3312 mpc)
3313 PIPEENCODERSVARCHECK="PIPE_$MPPENCODER" ;;
3314 esac
3315 decho "PIPERIPPERSVARCHECK: $( eval echo "\$$PIPERIPPERSVARCHECK" )"
3316 if [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "$" ] || \
3317 [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "" ] ; then
3318 log error "no support for pipes with given ripper"
3319 log error "read the USEPIPES file from the source tarball to get help."
3320 log error "On a Debian system, it is under /usr/share/doc/abcde/USEPIPES.gz"
3321 exit 1;
3322 fi
3323 decho "PIPEENCODERSVARCHECK: $( eval echo "\$$PIPEENCODERSVARCHECK" )"
3324 if [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "$" ] || \
3325 [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "" ] ; then
3326 log error "no support for pipes with given encoder"
3327 log error "read the USEPIPES file from the source tarball to help"
3328 log error "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz"
3329 exit 1;
3330 fi
3331 fi
3332
3333 # Make sure a buncha things exist
3334 for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
3335 $OGGENCODER $FLACENCODER $SPEEXENCODER $MPPENCODER \
3336 ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \
3337 ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
3338 ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
3339 ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} \
3340 ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMP3GAIN+$MP3GAIN} \
3341 ${NEEDMPPGAIN+$MPPGAIN} ${NEEDCUEREADER+$CUEREADER} \
3342 ${NEEDCUE2DISCID+$CUE2DISCID}
3343 do
3344 checkexec "$X"
3345 done
3346
3347 # And last but not least, check if we can diff between files
3348 if [ -x $(which $DIFF) ]; then :; else
3349 vecho warning "Disabling diff since we cannot find it in the \$PATH..."
3350 DIFF=""
3351 fi
3352
3353 ## Now that we have metaflac, check if we need cue2discid
3354 #case $CDROMREADERSYNTAX in
3355 # flac)
3356 # TRACKINFO=$($METAFLAC --show-tag=CDDB $CDROM | cut -d"=" -f2 | egrep "[a-f0-9]{8}")
3357 # if [ "$TRACKINFO" = "" ]; then
3358 # checkexec ${NEEDCUE2DISCID+$CUE2DISCID}
3359 # fi
3360 # ;;
3361 #esac
3362
3363 CDROMREADER="$CDROMREADER $CDROMREADEROPTS"
3364 CDDBTOOL="$CDDBTOOL $CDDBTOOLOPTS"
3365 HTTPGET="$HTTPGET $HTTPGETOPTS"
3366
3367 # Here it used to say:
3368 # One thousand lines in, we can start doing stuff with things
3369 # Well, right now we are at line 3306 ;)
3370
3371 # Export needed things so they can be read in this subshell
3372 export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS
3373 export CDROM CDDBDATA REMOTEHOSTS MAXPROCS HTTPGET MD5SUM
3374
3375 if [ "$DOREAD" = "y" ]; then
3376 # User-definable function to set some things. Use it for
3377 # - closing the CD tray with eject -t
3378 # - set the CD speed value with eject -x
3379 vecho -n "Executing customizable pre-read function... "
3380
3381 pre_read # Execute the user-defined pre-read funtion. Close the CD with it.
3382
3383 vecho "done."
3384 fi
3385
3386 case "$CDDBMETHOD" in
3387 cddb)
3388 do_discid # Get ABCDETEMPDIR created and status file initialized
3389 ;;
3390 musicbrainz)
3391 do_musicbrainz
3392 ;;
3393 esac
3394
3395 if [ "$DOCDDB" = "y" ]; then
3396 # start with a sane default:
3397 CDDBLOCALSTATUS=notfound
3398 if [ $CDDBUSELOCAL = "y" ]; then
3399 do_localcddb
3400 fi
3401 if checkstatus cddb-choice > /dev/null; then
3402 :
3403 else
3404 if [ "$CDDBLOCALSTATUS" = "notfound" ] ; then
3405 case "$CDDBMETHOD" in
3406 cddb)
3407 do_cddbstat
3408 do_cddbquery
3409 do_cddbread
3410 ;;
3411 musicbrainz)
3412 do_musicbrainz
3413 ;;
3414 esac
3415 fi
3416 fi
3417 do_cddbedit
3418
3419 eval "$($CDDBTOOL parse "$CDDBDATA")"
3420 fi
3421
3422 # Before reading tracks, we set the speed of the device
3423
3424 if [ X"$CDSPEEDVALUE" != "X" ]; then
3425 case "$CDROMREADERSYNTAX" in
3426 cdparanoia|debug) ;;
3427 flac) ;;
3428 *) do_cdspeed ;;
3429 esac
3430 fi
3431
3432 # Define the first and last track, since we might need them later in several places
3433 FIRSTTRACK=$( get_first $TRACKQUEUE )
3434 LASTTRACK=$( get_last $TRACKQUEUE )
3435
3436 if [ -f "$ABCDETEMPDIR/status" ] && [ X"$ERASEENCODEDSTATUS" = "Xy" ]; then
3437 mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
3438 grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
3439 | grep -v ^encode-output > "$ABCDETEMPDIR/status"
3440 fi
3441
3442 if checkstatus onetrack ; then ONETRACK=y ; fi
3443
3444 if [ "$ONETRACK" = "y" ]; then
3445 # Reuse the CUEFILE in case we created it in a previous run
3446 if CUEFILE=$(checkstatus cuefile); then
3447 IMPORTCUESHEET=y
3448 fi
3449 fi
3450
3451 # Create playlist if needed (backgroundable) and start reading in tracks
3452
3453 (
3454
3455 if [ ! "$ONETRACK" = "y" ]; then
3456 if [ "$DOPLAYLIST" = "y" ]; then
3457 echo Creating playlist... >&2
3458 do_playlist
3459 fi
3460 fi
3461
3462 # For the lowdisk option, only one program is running at once so the encoder
3463 # can be unsilenced right away.
3464 if [ "$LOWDISK" = "y" ] || [ "$ONETRACK" = "y" ]; then
3465 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3466 fi
3467
3468 if [ "$ONETRACK" = "y" ]; then
3469 TRACKS="$FIRSTTRACK"
3470 if [ "$USEPIPES" = "y" ]; then
3471 if checkstatus readencodetrack-$FIRSTTRACK; then :; else
3472 do_cdread onetrack $FIRSTTRACK $LASTTRACK | do_encode $FIRSTTRACK %local0% > /dev/null 2>&1
3473 fi
3474 else
3475 if checkstatus readtrack-$FIRSTTRACK; then :; else
3476 do_cdread onetrack $FIRSTTRACK $LASTTRACK
3477 fi
3478 fi
3479 else
3480 for UTRACKNUM in $TRACKQUEUE
3481 do
3482 if [ "$DOREAD" = "y" ]; then
3483 if [ "$USEPIPES" = "y" ]; then
3484 if checkstatus readencodetrack-$UTRACKNUM; then :; else
3485 # Read, pipe, shut up!
3486 do_cdread $UTRACKNUM | do_encode $UTRACKNUM %local0% > /dev/null 2>&1
3487 fi
3488 else
3489 if checkstatus readtrack-$UTRACKNUM; then :; else
3490 do_cdread $UTRACKNUM
3491 fi
3492 if [ "$?" != "0" ]; then
3493 # CD read failed - don't give the goahead to
3494 # the encoder
3495 echo NO
3496 exit
3497 fi
3498 fi
3499 fi
3500 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ]; then
3501 :
3502 else
3503 # If we are not reading, set the encode output to loud already, so
3504 # that we can see the output of the first track.
3505 if [ "$MAXPROCS" = "1" ] && [ ! "$DOREAD" = "y" ]; then
3506 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3507 fi
3508 echo NEXTTRACK # Get the encoder machine churning again
3509 if [ "$DOREAD" = "y" ]; then
3510 if [ "$LOWDISK" = "y" ] && [ "$DOENCODE" = "y" ]; then
3511 until checkstatus encodetrack-$UTRACKNUM
3512 do
3513 if checkerrors encodetrack-$UTRACKNUM; then
3514 break
3515 fi
3516 sleep 2
3517 done
3518 fi
3519 fi
3520 fi
3521 done
3522 fi
3523
3524 # Now that we're done the encoding can be loud again -
3525 # if we're not using SMP.
3526 if [ "$MAXPROCS" = "1" ]; then
3527 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3528 fi
3529
3530 # All tracks read, start encoding.
3531 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ] || [ "$ONETRACK" = "y" ]; then
3532 echo NEXTTRACK
3533 fi
3534
3535 # Execute the user-defined post_read funtion before ejecting CD
3536 post_read
3537
3538 # We are now finished with the cdrom - it can be safely ejected. Note that
3539 # abcde will not have completed yet.
3540 if [ "$EJECTCD" = "y" ] && [ -x $(which $EJECT) ]; then
3541 # We check if the disk we are processing is actually the disk inside the
3542 # CD tray. If not, we do not eject the CD, since it might be so that the
3543 # user ejected it manually.
3544 #CURRENTTRACKINFO=$($CDDISCID $CDROM)
3545 #if if [ "$?" != "1" ] && [ "$CURRENTTRACKINFO" = "$TRACKINFO" ] ; then
3546 # More FreeBSD bits.
3547 if [ X"$(uname)" = X"FreeBSD" ] ; then
3548 # FreeBSD eject uses the EJECT environment variable to name the CDROM
3549 # but in this script EJECT is in the envionment and names the program
3550 eject=$EJECT
3551 unset EJECT
3552 # The FreeBSD eject needs "adc0" not "/dev/adc0c"
3553 cd="$(echo $CDROM | sed -e 's=.*/==;s=[a-h]$==;')"
3554 $eject $EJECTOPTS $cd
3555 elif [ X"$(uname)" = X"Darwin" ] ; then
3556 disktool -e ${CDROM#/dev/} 0
3557 else
3558 $EJECT $EJECTOPTS $CDROM
3559 fi
3560 #fi
3561 fi
3562
3563 ) | (
3564
3565 ## Do we need to pre-process
3566 #if [ x"$PREPROCESS" = "x" ] ; then
3567 # cat
3568 #else
3569 # for PRETRACKNUM in $TRACKQUEUE
3570 # do
3571 # read GOAHEAD
3572 # if [ "$GOAHEAD" = "NO" ]; then break; fi
3573 # PREPROCEED=
3574 # until [ $PREPROCEED ]
3575 # do
3576 # if checkstatus readtrack-$PRETRACKNUM; then PREPROCEED=y; break; fi
3577 # # all locations are working, wait and try again later
3578 # if [ ! $PREPROCEED ]; then sleep 3; fi
3579 # done
3580 # ( do_preprocess $PRETRACKNUM
3581 # echo "NEXTTRACK"
3582 # ) &
3583 # done
3584 #fi
3585 #
3586 #) | (
3587
3588 # In BATCHNORM and/or NOGAP modes, we want all tracks to be read first.
3589 #BACK
3590 if [ "$BATCHNORM" = "y" ] || [ "$NOGAP" = "y" ]; then
3591 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
3592 if [ "$GOAHEAD" = "NO" ]; then break; fi
3593 for LASTTRACK in $TRACKQUEUE; do :; done
3594 if checkstatus readtrack-$LASTTRACK; then
3595 if [ "$DONORMALIZE" = "y" ] && [ "$BATCHNORM" = "y" ]; then
3596 if checkstatus normalizetrack-$LASTTRACK; then :; else do_batch_normalize; fi
3597 if checkerrors batch-normalize; then exit 1; fi
3598 fi
3599 if [ "$DOENCODE" = "y" ] && [ "$NOGAP" = "y" ]; then
3600 if [ "$DONORMALIZE" = "y" ]; then
3601 for UTRACKNUM in $TRACKQUEUE
3602 do
3603 if checkstatus readtrack-$UTRACKNUM; then
3604 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
3605 fi
3606 done
3607 fi
3608 if checkstatus encodetrack-$LASTTRACK; then :; else do_nogap_encode; fi
3609 if checkerrors nogap-encode; then exit 1; fi
3610 fi
3611 fi
3612 fi
3613
3614 # If we are using ONETRACK, we can proceed with the normal encoding using just the $FIRSTTRACK as TRACKQUEUE
3615 if [ "$ONETRACK" = "y" ] ; then
3616 TRACKQUEUE="$FIRSTTRACK"
3617 TRACKS="$FIRSTTRACK"
3618 fi
3619
3620 # Do the encoding, including parallelization of remote encoding
3621 # Figure out where each track is going to be encoded
3622 ENCODELOCATIONS="$(echo $REMOTEHOSTS | tr , ' ')"
3623 if [ "$MAXPROCS" != "0" ]; then
3624 for NUM in $(f_seq_row 1 "$MAXPROCS")
3625 do
3626 ENCODELOCATIONS="$ENCODELOCATIONS %local$NUM%"
3627 done
3628 fi
3629 # Strip whitespace
3630 ENCODELOCATIONS=$(echo $ENCODELOCATIONS)
3631 for UTRACKNUM in $TRACKQUEUE
3632 do
3633 # Wait for our cue
3634 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
3635 if [ "$GOAHEAD" = "NO" ]; then break; fi
3636 # find out where this track is to be encoded
3637 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
3638 # Make sure we have a place to encode this, if not, exit stage right
3639 if [ -z "$ENCODELOCATIONS" ]; then
3640 continue
3641 fi
3642 PROCEED=
3643 until [ $PROCEED ]
3644