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