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