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