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