Fix formatting for track number tagging.
[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'
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:\] | perl -p -e 's/\\n/\n/;'
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 replygain 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 --add-replay-gain "${OUTPUTFILES[@]}"
545 #run_command replaygain-flac true
546 ;;
547 vorbis|ogg)
548 run_command replaygain-vorbis nice $ENCNICE $VORBISGAIN --album "${OUTPUTFILES[@]}"
549 ;;
550 mp3)
551 run_command replaygain-mp3 nice $ENCNICE $MP3GAIN -a -k "${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 (and temporarily) ID3TAGV
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" "$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
1666
1667 if [ "$1" = --wholedisc ] ; then
1668 MODE=INDEX
1669 else
1670 MODE=PREGAP
1671 fi
1672
1673 set -- $TRACKINFO
1674
1675 DISCID=$1
1676 TRACKS=$2
1677 shift 2
1678
1679 echo REM DISCID $DISCID
1680 echo FILE \"dummy.wav\" WAVE
1681
1682 if [ $1 -ne 150 ] && [ $MODE = "PREGAP" ] ; then
1683 OFFSET=$1
1684 else
1685 OFFSET=150
1686 fi
1687
1688 i=1
1689 while [ $i -le "$TRACKS" ] ; do
1690 LBA=$(( $1 - $OFFSET ))
1691 printf " TRACK %02i AUDIO\n" $i
1692 if [ $i -eq 1 -a $1 -ne 150 ] ; then
1693 if [ $MODE = PREGAP ] ; then
1694 echomsf " PREGAP " $(($OFFSET-150))
1695 else
1696 echo " INDEX 00 00:00:00"
1697 fi
1698 fi
1699 echomsf " INDEX 01 " $LBA
1700 i=$(($i+1))
1701 shift
1702 done
1703 }
1704
1705 # do_discid
1706 # This essentially the start of things
1707 do_discid ()
1708 {
1709 # Query the CD to get the track info, unless the user specified -C
1710 # or we are using some actions which do not need the CDDB data at all
1711 #if [ ! X"$EXPACTIONS" = "X" ]; then
1712 # :
1713 #elif [ -z "$DISCID" ]; then
1714 if [ -z "$DISCID" ]; then
1715 vecho -n "Getting CD track info... "
1716 # In OSX, unmount the disc before a query
1717 if [ "$OSFLAVOUR" = "OSX" ]; then
1718 disktool -u ${CDROM#/dev/}
1719 fi
1720 case "$CDROMREADERSYNTAX" in
1721 flac)
1722 if $METAFLAC $METAFLACOPTS --export-cuesheet-to=- "$CDROM" > /dev/null 2>&1 ; then
1723 case "$CUE2DISCID" in
1724 # FIXME # right now we have 2 cue2discid internal
1725 # implementations: builtin and abcde.cue2discid. Test
1726 # both of them and decide which one we want to use.
1727 builtin)
1728 #vecho "Using builtin cue2discid implementation..."
1729 CUESHEET="$(metaflac $METAFLACOPTS --export-cuesheet-to=- "$CDROM")"
1730
1731 #TRACKS=$(echo $CUESHEET | egrep "TRACK \+[[:digit:]]\+ \+AUDIO" |wc -l)
1732 #TRACKS=0
1733 OFFSETTIMES=( $(echo "$CUESHEET" | sed -n -e's/\ *INDEX 01\ \+//p' ) )
1734 TRACKS=${#OFFSETTIMES[@]}
1735 unset OFFSETS
1736 #echo "processing offsetimes ${OFFSETTIMES[@]}"
1737 for OFFSETTIME in ${OFFSETTIMES[@]}; do
1738 OFFSETS="$OFFSETS $(( 10#${OFFSETTIME:0:2} * 4500 + 10#${OFFSETTIME:3:2} * 75 + 10#${OFFSETTIME:6:2} ))"
1739 #OFFSETS[${#OFFSETS[*]}]=$(( 10#${OFFSETTIME:0:2} * 4500 + 10#${OFFSETTIME:3:2} * 75 + 10#${OFFSETTIME:6:2} ))
1740 done
1741
1742 LEADOUT=$(( $(echo "$CUESHEET" | grep lead-out | get_last) / 44100 * 75 ))
1743 LEADIN=$(( $(echo "$CUESHEET" | grep lead-in | get_last) / 44100 * 75 ))
1744 makeids
1745 ;;
1746 *)
1747 #vecho "Using external python cue2discid implementation..."
1748 TRACKINFO=$($METAFLAC $METAFLACOPTS --export-cuesheet-to=- "$CDROM" | $CUE2DISCID)
1749 ;;
1750 esac
1751 else
1752 log error "the input flac file does not contain a cuesheet."
1753 exit 1
1754 fi
1755 ;;
1756 # cdparanoia|debug)
1757 # CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -Q --verbose 2>&1 )"
1758 # RET=$?
1759 # if [ ! "$RET" = "0" ];then
1760 # log warning "something went wrong while querying the CD... Maybe a DATA CD?"
1761 # fi
1762 #
1763 # TRACKS="$(echo "$CDPARANOIAOUTPUT" | egrep '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ')"
1764 # CDPARANOIAAUDIOTRACKS="$TRACKS"
1765 #
1766 # LEADOUT="$(echo "$CDPARANOIAOUTPUT" | egrep -o '^TOTAL[[:space:]]+([[:digit:]]+)' | get_last)"
1767 # OFFSETS="$(echo "$CDPARANOIAOUTPUT" | sed -n -e's/^ .* \([0-9]\+\) \[.*/\1/p')"
1768 # makeids
1769 # ;;
1770 *)
1771 case "$CDDBMETHOD" in
1772 cddb) TRACKINFO=$($CDDISCID "$CDROM") ;;
1773 # FIXME # musicbrainz needs a cleanup
1774 musicbrainz) TRACKINFO=$($MUSICBRAINZ -c "$CDROM" ) ;;
1775 esac
1776 ;;
1777 esac
1778 # Make sure there's a CD in there by checking cd-discid's return code
1779 if [ ! "$?" = "0" ]; then
1780 if [ "$CDROMREADERSYNTAX" = "flac" ] ; then
1781 log error "cuesheet information from the flac file could not be read."
1782 log error "Perhaps the flac file does not contain a cuesheet?."
1783 exit 1
1784 else
1785 log error "CD could not be read. Perhaps there's no CD in the drive?"
1786 exit 1
1787 fi
1788 fi
1789 # In OSX, remount the disc again
1790 if [ "$OSFLAVOUR" = "OSX" ]; then
1791 disktool -m ${CDROM#/dev/}
1792 fi
1793 WEHAVEACD=y
1794 DISCID=$(echo $TRACKINFO | cut -f1 -d' ')
1795 else
1796 TRACKINFO=$(cat "$WAVOUTPUTDIR/abcde.$DISCID/discid")
1797 fi
1798
1799 # Get a full enumeration of tracks, sort it, and put it in the TRACKQUEUE.
1800 # This needs to be done now because a section of the resuming code will need
1801 # it later.
1802
1803 # get the number of digits to pad TRACKNUM with - we'll use this later
1804 # a CD can only hold 99 tracks, but since we support a feature for starting
1805 # numbering the tracks from a given number, we might need to set it as a
1806 # variable for the user to define... or obtain it somehow.
1807 if [ "$PADTRACKS" = "y" ] ; then
1808 TRACKNUMPADDING=2
1809 fi
1810
1811 ABCDETEMPDIR="$WAVOUTPUTDIR/abcde.$(echo $TRACKINFO | cut -f1 -d' ')"
1812 if [ -z "$TRACKQUEUE" ]; then
1813 if [ ! "$STRIPDATATRACKS" = "n" ]; then
1814 case "$CDROMREADERSYNTAX" in
1815 cdparanoia|debug)
1816 if [ "$WEHAVEACD" = "y" ]; then
1817 vecho "Querying the CD for audio tracks..."
1818 CDPARANOIAOUTPUT="$( $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -Q --verbose 2>&1 )"
1819 RET=$?
1820 if [ ! "$RET" = "0" ];then
1821 log warning "something went wrong while querying the CD... Maybe a DATA CD?"
1822 fi
1823 TRACKS="$(echo "$CDPARANOIAOUTPUT" | egrep '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ')"
1824 CDPARANOIAAUDIOTRACKS="$TRACKS"
1825 else
1826 # Previous versions of abcde would store the tracks on a file, instead of the status record.
1827 if [ -f "$ABCDETEMPDIR/cdparanoia-audio-tracks" ]; then
1828 echo cdparanoia-audio-tracks=$( cat "$ABCDETEMPDIR/cdparanoia-audio-tracks" ) >> "$ABCDETEMPDIR/status"
1829 rm -f "$ABCDETEMPDIR/cdparanoia-audio-tracks"
1830 fi
1831 if [ -f "$ABCDETEMPDIR/status" ] && TRACKS=$(checkstatus cdparanoia-audio-tracks); then :; else
1832 TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
1833 fi
1834 fi
1835 ;;
1836 *) TRACKS=$(echo $TRACKINFO | cut -f2 -d' ') ;;
1837 esac
1838 else
1839 TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
1840 fi
1841 if echo "$TRACKS" | grep "[[:digit:]]" > /dev/null 2>&1 ;then :;else
1842 log info "The disc does not contain any tracks. Giving up..."
1843 exit 0
1844 fi
1845 echo -n "Grabbing entire CD - tracks: "
1846 if [ ! "$PADTRACKS" = "y" ] ; then
1847 TRACKNUMPADDING=$(echo -n $TRACKS | wc -c | tr -d ' ')
1848 fi
1849 TRACKS=$(printf "%0.${TRACKNUMPADDING}d" $TRACKS)
1850 X=0
1851 while [ "$X" -ne "$TRACKS" ]
1852 do
1853 X=$(printf "%0.${TRACKNUMPADDING}d" $(expr $X + 1))
1854 TRACKQUEUE=$(echo $TRACKQUEUE $X)
1855 done
1856 echo $TRACKQUEUE
1857 else
1858 TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
1859 # User-supplied track queue.
1860 # Weed out non-numbers, whitespace, then sort and weed out duplicates
1861 TRACKQUEUE=$(echo $TRACKQUEUE | sed 's-[^0-9 ]--g' | tr ' ' '\n' | grep -v ^$ | sort -n | uniq | tr '\n' ' ' | sed 's- $--g')
1862 # Once cleaned, obtain the highest value in the trackqueue for number padding
1863 for LASTTRACK in $TRACKQUEUE; do :; done
1864 if [ ! "$PADTRACKS" = "y" ] ; then
1865 TRACKNUMPADDING=$(echo -n $LASTTRACK | wc -c | tr -d ' ')
1866 fi
1867 # Now we normalize the trackqueue
1868 for TRACK in $TRACKQUEUE ; do
1869 TRACKNUM=$(printf %0.${TRACKNUMPADDING}d $(expr ${TRACK} + 0 ))
1870 PADTRACKQUEUE=$(echo $PADTRACKQUEUE $TRACKNUM)
1871 done
1872 TRACKQUEUE=$PADTRACKQUEUE
1873 echo Grabbing tracks: "$TRACKQUEUE"
1874 fi
1875
1876 QUEUEDTRACKS=$(echo $TRACKQUEUE | wc -w | tr -d ' ')
1877
1878 # We have the discid, create a temp directory after it to store all the temp
1879 # info
1880
1881 if [ -e "$ABCDETEMPDIR" ]; then
1882 echo -n "abcde: attempting to resume from $ABCDETEMPDIR"
1883 # It already exists, see if it's a directory
1884 if [ ! -d "$ABCDETEMPDIR" ]; then
1885 # This is a file/socket/fifo/device/etc, not a directory
1886 # Complain and exit
1887 echo >&2
1888 echo "abcde: file $ABCDETEMPDIR already exists and does not belong to abcde." >&2
1889 echo "Please investigate, remove it, and rerun abcde." >&2
1890 exit 1
1891 fi
1892 echo -n .
1893 # It's a directory, let's see if it's writable by us
1894 if [ ! -r "$ABCDETEMPDIR" ] || [ ! -w "$ABCDETEMPDIR" ] || [ ! -x "$ABCDETEMPDIR" ]; then
1895 # Nope, complain and exit
1896 echo >&2
1897 echo "abcde: directory $ABCDETEMPDIR already exists and is not writeable." >&2
1898 echo "Please investigate, remove it, and rerun abcde." >&2
1899 exit 1
1900 fi
1901 echo .
1902 # See if it's populated
1903 if [ ! -f "$ABCDETEMPDIR/discid" ]; then
1904 # Wipe and start fresh
1905 echo "abcde: $ABCDETEMPDIR/discid not found. Abcde must remove and recreate" >&2
1906 echo -n "this directory to continue. Continue? [y/n] (n)" >&2
1907 if [ "$INTERACTIVE" = "y" ]; then
1908 read ANSWER
1909 else
1910 echo y >&2
1911 ANSWER=y
1912 fi
1913 if [ "$ANSWER" != "y" ]; then
1914 exit 1
1915 fi
1916 rm -rf "$ABCDETEMPDIR" || exit 1
1917 mkdir -p "$ABCDETEMPDIR"
1918 if [ "$?" -gt "0" ]; then
1919 # Directory already exists or could not be created
1920 echo "abcde: Temp directory $ABCDETEMPDIR could not be created." >&2
1921 exit 1
1922 fi
1923 else
1924 # Everything is fine. Check for ^encodetracklocation-
1925 # and encode-output entries in the status file and
1926 # remove them. These are not relevant across sessions.
1927 if [ -f "$ABCDETEMPDIR/status" ]; then
1928 mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
1929 grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
1930 | grep -v ^encode-output > "$ABCDETEMPDIR/status"
1931 fi
1932 # Remove old error messages
1933 if [ -f "$ABCDETEMPDIR/errors" ]; then
1934 rm -f "$ABCDETEMPDIR/errors"
1935 fi
1936 fi
1937 else
1938 # We are starting from scratch
1939 mkdir -p "$ABCDETEMPDIR"
1940 if [ "$?" -gt "0" ]; then
1941 # Directory already exists or could not be created
1942 echo "abcde: Temp directory $ABCDETEMPDIR could not be created." >&2
1943 exit 1
1944 fi
1945 cat /dev/null > "$ABCDETEMPDIR/status"
1946 # Store the abcde version in the status file.
1947 echo "abcde-version=$VERSION" >> "$ABCDETEMPDIR/status"
1948 fi
1949 if [ X"$DOCUE" = "Xy" -a X"$WEHAVEACD" = "Xy" ]; then
1950 if checkstatus cuefile > /dev/null 2>&1 ; then :; else
1951 CUEFILE=cue-$(echo "$TRACKINFO" | cut -f1 -d' ').txt
1952 vecho "Creating cue file..."
1953 case $CDROMREADERSYNTAX in
1954 flac)
1955 if $METAFLAC --export-cuesheet-to=- "$CDROM" > "$ABCDETEMPDIR/$CUEFILE"; then
1956 echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status"
1957 else
1958 log warning "the input flac file does not contain a cuesheet."
1959 fi
1960 ;;
1961 *)
1962 if $CUEREADER $CUEREADEROPTS > "$ABCDETEMPDIR/$CUEFILE"; then
1963 echo cuefile=$CUEFILE >> "$ABCDETEMPDIR/status"
1964 else
1965 log warning "reading the CUE sheet is still considered experimental"
1966 log warning "and there was a problem with the CD reading. abcde will continue,"
1967 log warning "but consider reporting the problem to the abcde author"
1968 fi
1969 ;;
1970 esac
1971 fi
1972 fi
1973 # If we got the CDPARANOIA status and it is not recorded, save it now
1974 if [ -n "$CDPARANOIAAUDIOTRACKS" ]; then
1975 if checkstatus cdparanoia-audio-tracks > /dev/null 2>&1; then :; else
1976 echo cdparanoia-audio-tracks=$CDPARANOIAAUDIOTRACKS >> "$ABCDETEMPDIR/status"
1977 fi
1978 fi
1979
1980 # Create the discid file
1981 echo "$TRACKINFO" > "$ABCDETEMPDIR/discid"
1982 if checkstatus cddbmethod > /dev/null 2>&1 ; then :; else
1983 echo "cddbmethod=$CDDBMETHOD" >> "$ABCDETEMPDIR/status"
1984 fi
1985 }
1986
1987 # do_cleancue
1988 # Create a proper CUE file based on the CUE file we created before.
1989 do_cleancue()
1990 {
1991 if CUEFILE_IN="$ABCDETEMPDIR"/$(checkstatus cuefile); then
1992 CUEFILE_OUT=$CUEFILE_IN.out
1993 ### FIXME ### checkstatus cddb
1994 if [ -e "$CDDBDATA" ]; then
1995 vecho "Adding metadata to the cue file..."
1996 # FIXME It doesn't preserve spaces! Why?
1997 # FIXME parse $track into PERFORMER and TITLE - abcde already has code for this?
1998 n=1
1999 echo "PERFORMER \"$DARTIST\"" >> "$CUEFILE_OUT"
2000 echo "TITLE \"$DALBUM\"" >> "$CUEFILE_OUT"
2001 # Set IFS to <newline> to prevent read from swallowing spaces and tabs
2002 OIFS="$IFS"
2003 IFS='
2004 '
2005 cat "$CUEFILE_IN" | while read line
2006 do
2007 if echo "$line" | grep "INDEX 01" > /dev/null 2>&1 ; then
2008 # FIXME # Possible patch: remove the line above, uncomment the 2 lines below.
2009 # echo "$line" >> "$CUEFILE_OUT"
2010 # if echo "$line" | grep "^[[:space:]]*TRACK" > /dev/null 2>&1 ; then
2011 eval track="\$TRACK$n"
2012 n=$(expr $n + 1)
2013 echo " TITLE \"$track\"" >> "$CUEFILE_OUT"
2014 fi
2015 # FIXME # If the lines above are uncommented, remove the line below.
2016 echo "$line" >> "$CUEFILE_OUT"
2017 done
2018 IFS="$OIFS"
2019 mv "$CUEFILE_OUT" "$CUEFILE_IN"
2020 echo "cleancuefile" >> "$ABCDETEMPDIR/status"
2021 fi
2022 fi
2023 }
2024
2025 # do_cddbparse
2026 # Parses a CDDB file and outputs the title and the track names.
2027 # Variables: CDDBFILE
2028 do_cddbparse ()
2029 {
2030 CDDBPARSEFILE="$1"
2031 # List out disc title/author and contents
2032 if [ "$ONETRACK" = "y" ]; then
2033 vecho "ONETRACK mode selected: displaying only the title of the CD..."
2034 fi
2035 echo "---- $(grep DTITLE "${CDDBPARSEFILE}" | cut '-d=' -f2- | tr -d \\r\\n ) ----"
2036 if [ X"$SHOWCDDBYEAR" = "Xy" ]; then
2037 PARSEDYEAR=$(grep DYEAR "${CDDBPARSEFILE}" | cut '-d=' -f2-)
2038 if [ ! X"$PARSEDYEAR" = "X" ]; then
2039 echo "Year: $PARSEDYEAR"
2040 fi
2041 fi
2042 if [ X"$SHOWCDDBGENRE" = "Xy" ]; then
2043 PARSEDGENRE=$(grep DGENRE "${CDDBPARSEFILE}" | cut '-d=' -f2-)
2044 if [ ! X"$PARSEDGENRE" = "X" ]; then
2045 echo "Genre: $PARSEDGENRE"
2046 fi
2047 fi
2048 if [ ! "$ONETRACK" = "y" ]; then
2049 for TRACK in $(f_seq_row 1 $TRACKS)
2050 do
2051 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "${CDDBPARSEFILE}" | cut -f2- -d= | tr -d \\r\\n)"
2052 done
2053 fi
2054 }
2055
2056 # do_localcddb
2057 # Check for a local CDDB file, and report success
2058 do_localcddb ()
2059 {
2060 if checkstatus cddb-readcomplete && checkstatus cddb-choice >/dev/null; then :; else
2061
2062 CDDBLOCALSTATUS="notfound"
2063 CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
2064 USELOCALRESP="y"
2065
2066 if [ "$CDDBLOCALRECURSIVE" = "y" ]; then
2067 CDDBLOCALRESULTS="$(find ${CDDBLOCALDIR} -name "${CDDBDISCID}" -type f 2> /dev/null)"
2068 if [ ! "${CDDBLOCALRESULTS}" = "" ]; then
2069 if (( $(echo "${CDDBLOCALRESULTS}" | wc -l) == 1 )); then
2070 CDDBLOCALFILE="${CDDBLOCALRESULTS}"
2071 CDDBLOCALMATCH=single
2072 elif (( $(echo "${CDDBLOCALRESULTS}" | wc -l) > 1 )); then
2073 CDDBLOCALMATCH=multiple
2074 fi
2075 else
2076 CDDBLOCALMATCH=none
2077 fi
2078 elif [ "$CDDBLOCALMATCH" = "none" ] && [ -r "${CDDBLOCALDIR}/${CDDBDISCID}" ]; then
2079 CDDBLOCALFILE="${CDDBLOCALDIR}/${CDDBDISCID}"
2080 CDDBLOCALMATCH=single
2081 else
2082 CDDBLOCALMATCH=none
2083 fi
2084
2085 # If the user has selected to check a local CDDB repo, we proceed with it
2086 case $CDDBLOCALMATCH in
2087 multiple)
2088 echo "Processing multiple matching CDDB entries..." > "$ABCDETEMPDIR/cddblocalchoices"
2089 X=0
2090 echo "$CDDBLOCALRESULTS" | while read RESULT ; do
2091 X=$(expr $X + 1)
2092 # List out disc title/author and contents
2093 CDDBLOCALREAD="$ABCDETEMPDIR/cddblocalread.$X"
2094 cat "$RESULT" > "${CDDBLOCALREAD}"
2095 {
2096 echo -n "#$X: "
2097 do_cddbparse "${CDDBLOCALREAD}"
2098 echo ""
2099 ##FIXME## QUICK HACK !!!!
2100 if [ ! "$INTERACTIVE" = "y" ]; then break ; fi
2101 } >> "$ABCDETEMPDIR/cddblocalchoices"
2102 done
2103 if [ $(cat "$ABCDETEMPDIR/cddblocalchoices" | wc -l) -ge 24 ] && [ "$INTERACTIVE" = "y" ]; then
2104 page "$ABCDETEMPDIR/cddblocalchoices"
2105 else
2106 # It's all going to fit in one page, cat it
2107 cat "$ABCDETEMPDIR/cddblocalchoices" >&2
2108 fi
2109 CDDBLOCALCHOICES=$( echo "$CDDBLOCALRESULTS" | wc -l )
2110 # Setting the choice to an impossible integer to avoid errors in the numeric comparisons
2111 CDDBLOCALCHOICENUM=-1
2112 if [ "$INTERACTIVE" = "y" ]; then
2113 while [ $CDDBLOCALCHOICENUM -lt 0 ] || [ $CDDBLOCALCHOICENUM -gt $CDDBLOCALCHOICES ]; do
2114 echo -n "Locally cached CDDB entries found. Which one would you like to use (0 for none)? [0-$CDDBLOCALCHOICES]: " >&2
2115 read CDDBLOCALCHOICE
2116 [ x"$CDDBLOCALCHOICE" = "x" ] && CDDBLOCALCHOICE="1"
2117 # FIXME # Introduce diff's
2118 if echo $CDDBLOCALCHOICE | egrep "[[:space:]]*[[:digit:]]+,[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
2119 diffentries cddblocalread "$CDDBLOCALCHOICES" "$CDDBLOCALCHOICE"
2120 elif echo $CDDBLOCALCHOICE | egrep "[[:space:]]*[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
2121 # Make sure we get a valid choice
2122 CDDBLOCALCHOICENUM=$(echo $CDDBLOCALCHOICE | xargs printf %d 2>/dev/null)
2123 if [ $CDDBLOCALCHOICENUM -lt 0 ] || [ $CDDBLOCALCHOICENUM -gt $CDDBLOCALCHOICES ]; then
2124 echo "Invalid selection. Please choose a number between 0 and $CDDBLOCALCHOICES." >&2
2125 fi
2126 fi
2127 done
2128 else
2129 ### FIXME ###
2130 #echo "Selected ..."
2131 CDDBLOCALRESP=y
2132 CDDBLOCALCHOICENUM=1
2133 fi
2134 if [ ! "$CDDBLOCALCHOICENUM" = "0" ]; then
2135 #echo "Using local copy of CDDB data"
2136 echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "$ABCDETEMPDIR/cddbread.1"
2137 cat "$ABCDETEMPDIR/cddblocalread.$CDDBLOCALCHOICENUM" >> "$ABCDETEMPDIR/cddbread.1"
2138 echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB
2139 echo cddb-readcomplete >> "$ABCDETEMPDIR/status"
2140 do_cddbparse "$ABCDETEMPDIR/cddbread.1" > "$ABCDETEMPDIR/cddbchoices"
2141 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2142 CDDBLOCALSTATUS="found"
2143 else
2144 #echo "Not using local copy of CDDB data"
2145 CDDBLOCALSTATUS="notfound"
2146 fi
2147 ;;
2148 single)
2149 # List out disc title/author and contents
2150 do_cddbparse "${CDDBLOCALFILE}"
2151 #if [ "$CDROMREADERSYNTAX" = "flac" ] ; then
2152 # echo -n "Embedded cuesheet entry found, use it? [y/n] (y): " >&2
2153 #else
2154 echo -n "Locally cached CDDB entry found, use it? [y/n] (y): " >&2
2155 #fi
2156 if [ "$INTERACTIVE" = "y" ]; then
2157 read USELOCALRESP
2158 while [ "$USELOCALRESP" != "y" ] && [ "$USELOCALRESP" != "n" ] && [ "$USELOCALRESP" != "" ] ; do
2159 echo -n 'Invalid selection. Please answer "y" or "n": ' >&2
2160 read USELOCALRESP
2161 done
2162 [ x"$USELOCALRESP" = "x" ] && USELOCALRESP="y"
2163 else
2164 echo "y" >&2
2165 fi
2166 if [ "$USELOCALRESP" = "y" ]; then
2167 #echo "Using local copy of CDDB data"
2168 echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "$ABCDETEMPDIR/cddbread.1"
2169 cat "${CDDBLOCALFILE}" >> "$ABCDETEMPDIR/cddbread.1"
2170 echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB
2171 echo cddb-readcomplete >> "$ABCDETEMPDIR/status"
2172 do_cddbparse "${CDDBLOCALFILE}" > "$ABCDETEMPDIR/cddbchoices"
2173 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2174 CDDBLOCALSTATUS="single"
2175 else
2176 #echo "Not using local copy of CDDB data"
2177 CDDBLOCALSTATUS="notfound"
2178 fi
2179 ;;
2180 none)
2181 CDDBLOCALSTATUS="notfound"
2182 ;;
2183 esac
2184 fi
2185 }
2186
2187 do_musicbrainzstat ()
2188 {
2189 :
2190 }
2191
2192 do_musicbrainz ()
2193 {
2194 # Use MBE_TOCGetCDIndexId on a perl query
2195 :
2196 }
2197
2198 # do_cddbstat
2199 do_cddbstat ()
2200 {
2201 # Perform CDDB protocol version check if it hasn't already been done
2202 if checkstatus cddb-statcomplete; then :; else
2203 if [ "$CDDBAVAIL" = "n" ]; then
2204 ERRORCODE=no_query
2205 echo 503 > "$ABCDETEMPDIR/cddbstat"
2206 else
2207 rc=1
2208 CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
2209 CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
2210 while test $rc -eq 1 -a $CDDBPROTO -ge 3; do
2211 vecho "Checking CDDB server status..."
2212 $CDDBTOOL stat $CDDBURL $CDDBUSER $CDDBHOST $CDDBPROTO > "$ABCDETEMPDIR/cddbstat"
2213 RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbstat" | cut -f1 -d' ')
2214 case "$RESPONSECODE" in
2215 210) # 210 OK, status information follows (until terminating `.')
2216 rc=0
2217 ;;
2218 501) # 501 Illegal CDDB protocol level: <n>.
2219 CDDBPROTO=`expr $CDDBPROTO - 1`
2220 ;;
2221 *) # Try a cddb query, since freedb2.org doesn't support the stat or ver commands
2222 # FreeDB TESTCD disc-id is used for query
2223 $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST 03015501 1 296 344 > "$ABCDETEMPDIR/cddbstat"
2224 RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbstat" | cut -f1 -d' ')
2225 case "$RESPONSECODE" in
2226 2??) # Server responded, everything seems OK
2227 rc=0
2228 ;;
2229 esac
2230 ;;
2231 esac
2232 done
2233 if test $rc -eq 1; then
2234 CDDBAVAIL="n"
2235 fi
2236 fi
2237 echo cddb-statcomplete >> "$ABCDETEMPDIR/status"
2238 fi
2239 }
2240
2241
2242 # do_cddbquery
2243 do_cddbquery ()
2244 {
2245 CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
2246 CDDBLOCALFILE="${CDDBLOCALDIR}/${CDDBDISCID}"
2247
2248 # Perform CDDB query if it hasn't already been done
2249 if checkstatus cddb-querycomplete; then :; else
2250 if [ "$CDDBAVAIL" = "n" ]; then
2251 ERRORCODE=no_query
2252 echo 503 > "$ABCDETEMPDIR/cddbquery"
2253 # The default CDDBLOCALSTATUS is "notfound"
2254 # This part will be triggered if the user CDDB repo does not
2255 # contain the entry, or if we are not trying to use the repo.
2256 else
2257 vecho "Querying the CDDB server..."
2258 CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
2259 CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
2260 $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $TRACKINFO > "$ABCDETEMPDIR/cddbquery"
2261 ERRORCODE=$?
2262 case $ERRORCODE in
2263 0) # success
2264 ;;
2265 12|13|14)
2266 # no match found in database,
2267 # wget/fetch error, or user requested not to use CDDB
2268 # Make up an error code (503) that abcde
2269 # will recognize in do_cddbread
2270 # and compensate by making a template
2271 echo 503 > "$ABCDETEMPDIR/cddbquery"
2272 ;;
2273 *) # strange and unknown error
2274 echo ERRORCODE=$ERRORCODE
2275 echo "abcde: $CDDBTOOL returned unknown error code"
2276 ;;
2277 esac
2278 fi
2279 echo cddb-querycomplete >> "$ABCDETEMPDIR/status"
2280 fi
2281 }
2282
2283 # do_cddbread
2284 do_cddbread ()
2285 {
2286 # If it's not to be used, generate a template.
2287 # Then, display it (or them) and let the user choose/edit it
2288 if checkstatus cddb-readcomplete; then :; else
2289 vecho "Obtaining CDDB results..."
2290 # If CDDB is to be used, interpret the query results and read all
2291 # the available entries.
2292 rm -f "$ABCDETEMPDIR/cddbchoices"
2293 CDDBCHOICES=1 # Overridden by multiple matches
2294 RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbquery" | cut -f1 -d' ')
2295 case "$RESPONSECODE" in
2296 200)
2297 # One exact match, retrieve it
2298 # 200 [section] [discid] [artist] / [title]
2299 if checkstatus cddb-read-1-complete; then :; else
2300 echo -n "Retrieving 1 CDDB match..." >> "$ABCDETEMPDIR/cddbchoices"
2301 $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(cut -f2,3 -d' ' "$ABCDETEMPDIR/cddbquery") > "$ABCDETEMPDIR/cddbread.1"
2302 echo "done." >> "$ABCDETEMPDIR/cddbchoices"
2303 echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
2304 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2305 fi
2306 # List out disc title/author and contents
2307 echo ---- "$(cut '-d ' -f4- "$ABCDETEMPDIR/cddbquery")" ---- >> "$ABCDETEMPDIR/cddbchoices"
2308 for TRACK in $(f_seq_row 1 $TRACKS)
2309 do
2310 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
2311 done
2312 echo >> "$ABCDETEMPDIR/cddbchoices"
2313 ;;
2314 202|403|409|503)
2315 # No match
2316 case "$RESPONSECODE" in
2317 202) echo "No CDDB match." >> "$ABCDETEMPDIR/cddbchoices" ;;
2318 403|409) echo "CDDB entry is corrupt, or the handshake failed." >> "$ABCDETEMPDIR/cddbchoices" ;;
2319 503) echo "CDDB unavailable." >> "$ABCDETEMPDIR/cddbchoices" ;;
2320 esac
2321 $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
2322 # List out disc title/author and contents of template
2323 echo ---- Unknown Artist / Unknown Album ---- >> "$ABCDETEMPDIR/cddbchoices"
2324 UNKNOWNDISK=y
2325 for TRACK in $(f_seq_row 1 $TRACKS)
2326 do
2327 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.0" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
2328 done
2329 echo >> "$ABCDETEMPDIR/cddbchoices"
2330 echo cddb-read-0-complete >> "$ABCDETEMPDIR/status"
2331 echo cddb-choice=0 >> "$ABCDETEMPDIR/status"
2332 ;;
2333 210|211)
2334 # Multiple exact, (possibly multiple) inexact matches
2335 IN=
2336 if [ "$RESPONSECODE" = "211" ]; then IN=in; fi
2337 if [ "$(wc -l < "$ABCDETEMPDIR/cddbquery" | tr -d ' ')" -eq 3 ]; then
2338 echo "One ${IN}exact match:" >> "$ABCDETEMPDIR/cddbchoices"
2339 tail -n +2 "$ABCDETEMPDIR/cddbquery" | head -n 1 >> "$ABCDETEMPDIR/cddbchoices"
2340 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2341 else
2342 echo "Multiple ${IN}exact matches:" >> "$ABCDETEMPDIR/cddbchoices"
2343 fi
2344 vecho -n "Retrieving multiple matches... "
2345 grep -v ^[.]$ "$ABCDETEMPDIR/cddbquery" | ( X=0
2346 read DISCINFO # eat top line
2347 while read DISCINFO
2348 do
2349 X=$(expr $X + 1)
2350 if checkstatus cddb-read-$X-complete; then :; else
2351 $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(echo $DISCINFO | cut -f1,2 -d' ') > "$ABCDETEMPDIR/cddbread.$X"
2352 echo cddb-read-$X-complete >> "$ABCDETEMPDIR/status"
2353 fi
2354 # List out disc title/author and contents
2355 echo \#$X: ---- "$DISCINFO" ---- >> "$ABCDETEMPDIR/cddbchoices"
2356 for TRACK in $(f_seq_row 1 $TRACKS)
2357 do
2358 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.$X" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
2359 done
2360 echo >> "$ABCDETEMPDIR/cddbchoices"
2361 done )
2362 vecho "done."
2363 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
2364 ;;
2365 999)
2366 # Using local copy.
2367 for TRACK in $(f_seq_row 1 $TRACKS)
2368 do
2369 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
2370 done
2371 echo >> "$ABCDETEMPDIR/cddbchoices"
2372 echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
2373 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
2374 ;;
2375 esac
2376 echo "cddb-readcomplete" >> "$ABCDETEMPDIR/status"
2377 fi
2378 }
2379
2380 # do_cddbedit
2381 do_cddbedit ()
2382 {
2383 if checkstatus cddb-edit >/dev/null; then
2384 CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
2385 VARIOUSARTISTS="$(checkstatus variousartists)"
2386 VARIOUSARTISTSTYLE="$(checkstatus variousartiststyle)"
2387 return 0
2388 fi
2389 if [ "$INTERACTIVE" = "y" ]; then
2390 # We should show the CDDB results both when we are not using the local CDDB repo
2391 # or when we are using it but we could not find a proper match
2392 if [ "$CDDBUSELOCAL" = "y" ] && [ "$CDDBLOCALSTATUS" = "notfound" ] || [ ! "$CDDBUSELOCAL" = "y" ]; then
2393 # Display the $ABCDETEMPDIR/cddbchoices file created above
2394 # Pick a pager so that if the tracks overflow the screen the user can still view everything
2395 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
2396 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
2397 CHOICE=$(checkstatus cddb-choice)
2398 if [ -n "$CHOICE" ] ; then
2399 case $CDDBCHOICES in
2400 -1) if head -1 "$ABCDETEMPDIR/cddbquery" | grep "^$" > /dev/null 2>&1 ; then
2401 log error "CDDB query failed!"
2402 exit 1
2403 else
2404 cat "$ABCDETEMPDIR/cddbchoices"
2405 fi
2406 ;;
2407 1) cat "$ABCDETEMPDIR/cddbchoices" ;;
2408 *)
2409 echo "Selected: #$CHOICE"
2410 do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
2411 ;;
2412 esac
2413 else
2414 # The user has a choice to make, display the info in a pager if necessary
2415 if [ $(cat "$ABCDETEMPDIR/cddbchoices" | wc -l) -ge 24 ]; then
2416 page "$ABCDETEMPDIR/cddbchoices"
2417 else
2418 # It's all going to fit in one page, cat it
2419 cat "$ABCDETEMPDIR/cddbchoices" >&2
2420 fi
2421
2422 CDDBCHOICENUM=""
2423 # Setting the choice to an impossible integer to avoid errors in the numeric comparisons
2424 CDCHOICENUM=-1
2425 # I'll take CDDB read #3 for $400, Alex
2426 while [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; do
2427 echo -n "Which entry would you like abcde to use (0 for none)? [0-$CDDBCHOICES]: " >&2
2428 read CDDBCHOICE
2429 [ X"$CDDBCHOICE" = "X" ] && CDDBCHOICE=1
2430 if echo $CDDBCHOICE | egrep "[[:space:]]*[[:digit:]]+,[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
2431 if [ ! X"$DIFF" = "X" ]; then
2432 PARSECHOICE1=$(echo $CDDBCHOICE | cut -d"," -f1 | xargs printf %d 2>/dev/null)
2433 PARSECHOICE2=$(echo $CDDBCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null)
2434 if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBCHOICES ] || \
2435 [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBCHOICES ] || \
2436 [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then
2437 echo "Invalid diff range. Please select two comma-separated numbers between 1 and $CDDBCHOICES" >&2
2438 else
2439 # We parse the 2 choices to diff, store them in temporary files and diff them.
2440 for PARSECHOICE in $(echo $CDDBCHOICE | tr , \ ); do
2441 do_cddbparse "$ABCDETEMPDIR/cddbread.$PARSECHOICE" > "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE"
2442 done
2443 echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..." > "$ABCDETEMPDIR/cddbread.diff"
2444 $DIFF $DIFFOPTS "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE1" "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE2" >> "$ABCDETEMPDIR/cddbread.diff"
2445 if [ $(cat "$ABCDETEMPDIR/cddbread.diff" | wc -l) -ge 24 ]; then
2446 page "$ABCDETEMPDIR/cddbread.diff"
2447 else
2448 cat "$ABCDETEMPDIR/cddbread.diff" >&2
2449 fi
2450 fi
2451 else
2452 echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBCHOICES." >&2
2453 fi
2454 elif echo $CDDBCHOICE | egrep "[[:space:]]*[[:digit:]]+[[:space:]]*" > /dev/null 2>&1 ; then
2455 # Make sure we get a valid choice
2456 CDCHOICENUM=$(echo $CDDBCHOICE | xargs printf %d 2>/dev/null)
2457 if [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; then
2458 echo "Invalid selection. Please choose a number between 0 and $CDDBCHOICES." >&2
2459 fi
2460 fi
2461 done
2462 if [ "$CDCHOICENUM" = "0" ]; then
2463 vecho "Creating empty CDDB template..."
2464 UNKNOWNDISK=y
2465 $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
2466 else
2467 echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
2468 do_cddbparse "$ABCDETEMPDIR/cddbread.$CDCHOICENUM"
2469 fi
2470 echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
2471 fi
2472 fi
2473 else
2474 # We need some code to show the selected option when local repository is selected and we have found a match
2475 vecho "Using cached CDDB match..." >&2
2476 # Display the $ABCDETEMPDIR/cddbchoices file created above
2477 # Pick a pager so that if the tracks overflow the screen the user can still view everything
2478 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
2479 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
2480 CHOICE=$(checkstatus cddb-choice)
2481 if [ "$USELOCALRESP" = "y" ]; then :; else
2482 if [ -n "$CHOICE" ] ; then
2483 case $CDDBCHOICES in
2484 0)
2485 UNKNOWNDISK=y
2486 echo "Selected template."
2487 ;;
2488 1) cat "$ABCDETEMPDIR/cddbchoices" ;;
2489 *)
2490 echo "Selected: #$CHOICE"
2491 do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
2492 ;;
2493 esac
2494 fi
2495 fi
2496 fi
2497 fi
2498 else
2499 # We're noninteractive - pick the first choice.
2500 # But in case we run a previous instance and selected a choice, use it.
2501 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
2502 # Show the choice if we are not using the locally stored one
2503 # or when the local search failed to find a match.
2504 PREVIOUSCHOICE=$(checkstatus cddb-choice)
2505 if [ "$CDDBUSELOCAL" = "y" ] && [ "$CDDBLOCALSTATUS" = "notfound" ] || [ ! "$CDDBUSELOCAL" = "y" ]; then
2506 #if [ "$PREVIOUSCHOICE" ]; then
2507 cat "$ABCDETEMPDIR/cddbchoices"
2508 #fi
2509 fi
2510 if [ ! -z "$PREVIOUSCHOICE" ] ; then
2511 CDCHOICENUM=$PREVIOUSCHOICE
2512 else
2513 CDCHOICENUM=1
2514 echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
2515 fi
2516 echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
2517 fi
2518 fi
2519
2520 # sanity check
2521 if checkstatus cddb-choice >/dev/null; then :; else
2522 echo "abcde: internal error: cddb-choice not recorded." >&2
2523 exit 1
2524 fi
2525 CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
2526 echo -n "Edit selected CDDB data? [y/n] (" >&2
2527 if [ "$INTERACTIVE" = "y" ]; then
2528 if [ "$UNKNOWNDISK" = "y" ]; then
2529 echo -n "y): " >&2
2530 read EDITCDDB
2531 [ "$EDITCDDB" != "n" ] && EDITCDDB=y
2532 else
2533 echo -n "n): " >&2
2534 read EDITCDDB
2535 fi
2536 else
2537 echo "n): n" >&2
2538 EDITCDDB=n
2539 fi
2540 if [ "$EDITCDDB" = "y" ]; then
2541 CDDBDATAMD5SUM=$($MD5SUM "$CDDBDATA" | cut -d " " -f 1);
2542
2543 # Use the debian sensible-editor wrapper to pick the editor that the
2544 # user has requested via their $EDITOR environment variable
2545 if [ -x "/usr/bin/sensible-editor" ]; then
2546 /usr/bin/sensible-editor "$CDDBDATA"
2547 elif [ -n "$EDITOR" ]; then
2548 if [ -x $(which "${EDITOR%%\ *}") ]; then
2549 # That failed, try to load the preferred editor, starting
2550 # with their EDITOR variable
2551 eval $(echo "$EDITOR") \"$CDDBDATA\"
2552 fi
2553 # If that fails, check for a vi
2554 elif which vi >/dev/null 2>&1; then
2555 vi "$CDDBDATA"
2556 elif [ -x /usr/bin/vim ]; then
2557 /usr/bin/vim "$CDDBDATA"
2558 elif [ -x /usr/bin/vi ]; then
2559 /usr/bin/vi "$CDDBDATA"
2560 elif [ -x /bin/vi ]; then
2561 /bin/vi "$CDDBDATA"
2562 # nano should be on all (modern, i.e., sarge) debian systems
2563 elif which nano >/dev/null 2>&1 ; then
2564 nano "$CDDBDATA"
2565 elif [ -x /usr/bin/nano ]; then
2566 /usr/bin/nano "$CDDBDATA"
2567 # mg should be on all OpenBSD systems
2568 elif which mg >/dev/null 2>&1 ; then
2569 mg "$CDDBDATA"
2570 elif [ -x /usr/bin/mg ]; then
2571 /usr/bin/mg "$CDDBDATA"
2572 # bomb out
2573 else
2574 log warning "no editor available. Check your EDITOR environment variable."
2575 fi
2576 # delete editor backup file if it exists
2577 if [ -w "$CDDBDATA~" ]; then
2578 rm -f "$CDDBDATA~"
2579 fi
2580 fi
2581
2582 # Some heuristics first. Look at Disc Title, and if it starts with
2583 # "Various", then we'll assume Various Artists
2584 if [ "$(grep ^DTITLE= "$CDDBDATA" | cut -f2- -d= | egrep -ci '^(various|soundtrack|varios|sonora|ost)')" != "0" ]; then
2585 echo "Looks like a Multi-Artist CD" >&2
2586 VARIOUSARTISTS=y
2587 else
2588 echo -n "Is the CD multi-artist? [y/n] (n): " >&2
2589 if [ "$INTERACTIVE" = "y" ]; then
2590 read VARIOUSARTISTS
2591 else
2592 echo n >&2
2593 VARIOUSARTISTS=n
2594 fi
2595 fi
2596 if [ "$VARIOUSARTISTS" = "y" ] && [ ! "$ONETRACK" = "y" ]; then
2597 # Set a default
2598 DEFAULTSTYLE=1
2599 # Need NUMTRACKS before cddb-tool will return it:
2600 NUMTRACKS=$(egrep '^TTITLE[0-9]+=' "$CDDBDATA" | wc -l)
2601 if [ "$(grep -c "^TTITLE.*\/" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2602 # More than 1/2 tracks contain a "/", so guess forward
2603 DEFAULTSTYLE=1
2604 elif [ "$(grep -c "^TTITLE.*\-" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2605 # More than 1/2 contain a "-", so guess forward-dash
2606 DEFAULTSTYLE=2
2607 elif [ "$(grep -c "^TTITLE.*(.*)" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2608 # More than 1/2 contain something in parens, so guess trailing-paren
2609 DEFAULTSTYLE=6
2610 fi
2611
2612 echo "1) Artist / Title" >&2
2613 echo "2) Artist - Title" >&2
2614 echo "3) Title / Artist" >&2
2615 echo "4) Title - Artist" >&2
2616 echo "5) Artist: Title" >&2
2617 echo "6) Title (Artist)" >&2
2618 echo "7) This is a single-artist CD" >&2
2619 echo -n "Which style of multiple artist entries is it? [1-7] ($DEFAULTSTYLE): " >&2
2620 if [ "$INTERACTIVE" = "y" ]; then
2621 read VARIOUSARTISTSTYLE
2622 else
2623 echo $DEFAULTSTYLE >&2
2624 VARIOUSARTISTSTYLE=$DEFAULTSTYLE
2625 fi
2626 VARIOUSARTISTSTYLE=$(echo 0$VARIOUSARTISTSTYLE | xargs printf %d)
2627 # If they press Enter, then the default style (0) was chosen
2628 while [ $VARIOUSARTISTSTYLE -lt 0 ] || [ $VARIOUSARTISTSTYLE -gt 7 ]; do
2629 echo "Invalid selection. Please choose a number between 1 and 7."
2630 echo -n "Selection [1-7]: "
2631 read VARIOUSARTISTSTYLE
2632 VARIOUSARTISTSTYLE=$(echo 0$VARIOUSARTISTSTYLE | xargs printf %d)
2633 done
2634 if [ "$VARIOUSARTISTSTYLE" = "0" ]; then
2635 VARIOUSARTISTSTYLE=$DEFAULTSTYLE
2636 fi
2637 vecho "Selected: $VARIOUSARTISTSTYLE"
2638 case "$VARIOUSARTISTSTYLE" in
2639 1) # Artist / Title
2640 VARIOUSARTISTSTYLE=forward
2641 ;;
2642 2) # Artist - Title
2643 VARIOUSARTISTSTYLE=forward-dash
2644 ;;
2645 3) # Title / Artist
2646 VARIOUSARTISTSTYLE=reverse
2647 ;;
2648 4) # Title - Artist
2649 VARIOUSARTISTSTYLE=reverse-dash
2650 ;;
2651 5) # Artist: Title
2652 VARIOUSARTISTSTYLE=colon
2653 ;;
2654 6) # Title (Artist)
2655 VARIOUSARTISTSTYLE=trailing-paren
2656 ;;
2657 7) # Single Artist
2658 VARIOUSARTISTS=n
2659 ;;
2660 esac
2661 fi
2662
2663 echo "variousartists=$VARIOUSARTISTS" >> "$ABCDETEMPDIR/status"
2664 echo "variousartiststyle=$VARIOUSARTISTSTYLE" >> "$ABCDETEMPDIR/status"
2665
2666 if [ "$EDITCDDB" = "y" ] && [ "$UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE" = "y" ]; then
2667 if [ "$CDDBDATAMD5SUM" != "" ] && [ "$CDDBDATAMD5SUM" != "$($MD5SUM "$CDDBDATA" | cut -d " " -f 1)" ]; then
2668 # This works but does not have the necessary error checking
2669 # yet. If you are familiar with the CDDB spec
2670 # (see http://www.freedb.org/src/latest/DBFORMAT)
2671 # and can create an error-free entry on your own, then put
2672 # UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE=y in your
2673 # abcde.conf to enable it. Put CDDBSUBMIT=email@address in
2674 # your abcde.conf to change the email address submissions are
2675 # sent to.
2676
2677 # submit the modified file, if they want
2678 if [ "$NOSUBMIT" != "y" ]; then
2679 echo -n "Do you want to submit this entry to $CDDBSUBMIT? [y/n] (n): "
2680 read YESNO
2681 while [ "$YESNO" != "y" ] && [ "$YESNO" != "n" ] && [ "$YESNO" != "Y" ] && \
2682 [ "$YESNO" != "N" ] && [ "$YESNO" != "" ]
2683 do
2684 echo -n 'Invalid selection. Please answer "y" or "n": '
2685 read YESNO
2686 done
2687 if [ "$YESNO" = "y" ] || [ "$YESNO" = "Y" ]; then
2688 echo -n "Sending..."
2689 $CDDBTOOL send "$CDDBDATA" $CDDBSUBMIT
2690 echo "done."
2691 fi
2692 fi
2693 fi
2694 fi
2695 ### FIXME ###
2696 # User CDDBLOCALPOLICY to find out if we store the file or not...
2697 # Cache edited CDDB entry in the user's cddb dir
2698 if [ "$CDDBCOPYLOCAL" = "y" ]; then
2699 # Make sure the cache directory exists
2700 mkdir -p $CDDBLOCALDIR
2701 cat "$CDDBDATA" | tail -n $(expr $(cat "$CDDBDATA" | wc -l ) - 1 ) > ${CDDBLOCALDIR}/$(echo "$TRACKINFO" | cut -d' ' -f1)
2702 fi
2703
2704 echo "cddb-edit" >> "$ABCDETEMPDIR/status"
2705 }
2706
2707 # do_cdread [tracknumber]
2708 # do_cdread onetrack [firsttrack] [lasttrack]
2709 #
2710 do_cdread ()
2711 {
2712 # The commands here don't go through run_command because they're never supposed to be silenced
2713 # return codes need to be doublechecked anyway, however
2714 if [ "$1" = "onetrack" ]; then
2715 # FIXME # Add the possibility of grabbing ranges of tracks in onetrack
2716 # FIXME # Until then, we grab the whole CD in one track, no matter what
2717 # the user said
2718 # We need the first and last track for cdda2wav
2719 FIRSTTRACK=$2
2720 LASTTRACK=$(expr $3 + 0)
2721 UTRACKNUM=$FIRSTTRACK
2722 case "$CDROMREADERSYNTAX" in
2723 flac) READTRACKNUMS="$FIRSTTRACK.1-$(($LASTTRACK + 1)).0" ;;
2724 cdparanoia)
2725 #XX FIXME XX
2726 # Add a variable to check if tracks are provided in command line and if not, use "0-" to rip the tracks
2727 READTRACKNUMS="$FIRSTTRACK-$LASTTRACK" ;;
2728 cdda2wav) READTRACKNUMS="$FIRSTTRACK+$LASTTRACK" ;;
2729 *) echo "abcde error: $CDROMREADERSYNTAX does not support ONETRACK mode"
2730 exit 1 ;;
2731 esac
2732 else
2733 UTRACKNUM=$1
2734 fi
2735 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
2736 if [ "$USEPIPES" = "y" ]; then
2737 TEMPARG="PIPERIPPER_$CDROMREADERSYNTAX"
2738 FILEARG="$( eval echo "\$$TEMPARG" )"
2739 REDIR="y"
2740 PIPE_MESSAGE="and encoding "
2741 else
2742 WAVDATA="$ABCDETEMPDIR/track$UTRACKNUM.wav"
2743 case "$CDROMREADERSYNTAX" in
2744 ## FIXME ## Find the cases for dagrab and flac, to avoid exceptions
2745 flac)
2746 FILEARG="--output-name=$WAVDATA"
2747 ;;
2748 dagrab)
2749 FILEARG="-f $WAVDATA"
2750 ;;
2751 *)
2752 FILEARG="$WAVDATA"
2753 ;;
2754 esac
2755 REDIR="n"
2756 fi
2757 if [ "$1" = "onetrack" ]; then
2758 echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2
2759 else
2760 if [ -r "$CDDBDATA" ]; then
2761 getcddbinfo TRACKNAME
2762 echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM: $TRACKNAME..." >&2
2763 else
2764 echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM..." >&2
2765 fi
2766 fi
2767 case "$CDROMREADERSYNTAX" in
2768 ### FIXME ### use an exception for flac, since it uses -o
2769 ### FIXME ### Shall we just use -o $FILEARG ??
2770 flac)
2771 # Avoid problems wit math expressions by unpadding the given UTRACKNUM
2772 STRIPTRACKNUM=$(expr $UTRACKNUM + 0)
2773 nice $READNICE $FLAC -d -f --cue=${READTRACKNUMS:-$STRIPTRACKNUM.1-$(($STRIPTRACKNUM + 1)).0} "$FILEARG" "$CDROM" ;;
2774 cdparanoia)
2775 if [ "$REDIR" = "y" ]; then
2776 nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" >&2
2777 else
2778 nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG"
2779 fi;;
2780
2781 cdda2wav)
2782 if [ "$OSFLAVOUR" = "OSX" ] ; then
2783 # Hei, we have to unmount the device before running anything like cdda2wav in OSX
2784 disktool -u ${CDROM#/dev/} 0
2785 # Also, in OSX the cdrom device for cdda2wav changes...
2786 CDDA2WAVCDROM="IODVDServices"
2787 elif [ "$OSFLAVOUR" = "FBSD" ] ; then
2788 CDDA2WAVCDROM="$CDROMID"
2789 else
2790 if [ "$CDROMID" = "" ]; then
2791 CDDA2WAVCDROM="$CDROM"
2792 else
2793 CDDA2WAVCDROM="$CDROMID"
2794 fi
2795 fi
2796 if [ "$REDIR" = "y" ]; then
2797 nice $READNICE $CDROMREADER -D $CDDA2WAVCDROM -t ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" >&2
2798 else
2799 nice $READNICE $CDROMREADER -D $CDDA2WAVCDROM -t ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG"
2800 fi ;;
2801 ## FIXME ## We have an exception for dagrab, since it uses -f
2802 ## FIXME ## Shall we just use -f $FILEARG ??
2803 dagrab)
2804 if [ "$REDIR" = "y" ]; then
2805 nice $READNICE $CDROMREADER -d "$CDROM" -v $UTRACKNUM "$FILEARG" >&2
2806 else
2807 nice $READNICE $CDROMREADER -d "$CDROM" -v $UTRACKNUM "$FILEARG"
2808 fi ;;
2809 cddafs)
2810 # Find the track's mounted path
2811 REALTRACKNUM=$(expr $UTRACKNUM + 0)
2812 FILEPATH=$(mount | grep "$CDROM on" | sed 's/^[^ ]* on \(.*\) (.*/\1/')
2813 FILEPATH=$(find "$FILEPATH" | grep "/$REALTRACKNUM ");
2814 # If the file exists, copy it
2815 if [ -e "$FILEPATH" ] ; then
2816 if [ "$REDIR" = "y" ]; then
2817 nice $READNICE $CDROMREADER "$FILEPATH" "$FILEARG" >&2
2818 else
2819 nice $READNICE $CDROMREADER "$FILEPATH" "$FILEARG"
2820 fi
2821 else
2822 false
2823 fi ;;
2824 debug)
2825 if [ "$REDIR" = "y" ]; then
2826 nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -w $UTRACKNUM-[:1] "$FILEARG" >&2
2827 else
2828 nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS "$CDROM" -w $UTRACKNUM-[:1] "$FILEARG"
2829 fi ;;
2830 esac
2831 RETURN=$?
2832 # If we get some error or we get some missing wav
2833 # (as long as we dont use pipes)
2834 if [ "$RETURN" != "0" -o \( ! -s "$WAVDATA" -a X"$USEPIPES" != "Xy" \) ]; then
2835 # Thank goodness errors is only machine-parseable up to the
2836 # first colon, otherwise this woulda sucked
2837 if [ "$RETURN" = "0" -a ! -s "$WAVDATA" ]; then
2838 RETURN=73 # fake a return code as cdparanoia return 0 also on aborted reads
2839 fi
2840 if [ "$USEPIPES" = "y" ]; then
2841 echo "readencodetrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
2842 else
2843 echo "readtrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
2844 fi
2845 return $RETURN
2846 else
2847 if [ "$USEPIPES" = "y" ]; then
2848 echo readencodetrack-$UTRACKNUM >> "$ABCDETEMPDIR/status"
2849 else
2850 echo readtrack-$UTRACKNUM >> "$ABCDETEMPDIR/status"
2851 fi
2852 if [ "$1" = "onetrack" ]; then
2853 echo onetrack >> "$ABCDETEMPDIR/status"
2854 fi
2855 fi
2856 }
2857
2858 # do_cdspeed
2859 # No values accepted, only uses env variables
2860 do_cdspeed ()
2861 {
2862 if "$CDSPEED" "$CDSPEEDOPTS" "$CDSPEEDVALUE" >/dev/null ; then
2863 vecho "Setting CD speed to ${CDSPEEDVALUE}x"
2864 else
2865 echo "abcde: unable to set the device speed" >&2
2866 fi
2867 }
2868
2869 # vecho [message]
2870 #
2871 # vecho outputs a message if EXTRAVERBOSE is selected
2872 vecho ()
2873 {
2874 if [ x"$EXTRAVERBOSE" != "x" ]; then
2875 case $1 in
2876 warning) shift ; log warning "$@" ;;
2877 *) echo "$@" ;;
2878 esac
2879 fi
2880 }
2881
2882 # decho [message]
2883 #
2884 # decho outputs a debug message if DEBUG is selected
2885 decho ()
2886 {
2887 if [ x"$DEBUG" != "x" ]; then
2888 if echo $1 | grep "^\[" > /dev/null 2>&1 ; then
2889 DEBUGECHO=$(echo "$@" | tr -d '[]')
2890 echo "[DEBUG] $DEBUGECHO: `eval echo \\$${DEBUGECHO}`"
2891 else
2892 echo "[DEBUG] $1"
2893 fi
2894 fi
2895 }
2896
2897 # User-redefinable functions
2898 # Custom filename munging:
2899 mungefilename ()
2900 {
2901 #echo "$@" | sed s,:,\ -,g | tr \ /\* __+ | tr -d \'\"\?\[:cntrl:\]
2902 echo "$@" | sed s,:,\ -,g | tr \ / __ | tr -d \'\"\?\[:cntrl:\]
2903 }
2904
2905 # Custom genre munging:
2906 mungegenre ()
2907 {
2908 echo $CDGENRE | tr "[:upper:]" "[:lower:]"
2909 }
2910
2911 # pre_read
2912 # Empty pre_read function, to be defined in the configuration file.
2913 pre_read ()
2914 {
2915 :
2916 }
2917
2918 # post_read
2919 # Empty post_read function, to be defined in the configuration file.
2920 post_read ()
2921 {
2922 :
2923 }
2924
2925 # post_encode
2926 # Empty post_encode function, to be defined in the configuration file.
2927 post_encode ()
2928 {
2929 :
2930 }
2931
2932 ###############################################################################
2933 # End of functions
2934 #
2935 # Start of execution
2936 ###############################################################################
2937
2938 # Builtin defaults
2939
2940 # CDDB
2941 # Defaults to FreeDB, but a python musicbrainz can be used
2942 CDDBMETHOD=cddb
2943 CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"
2944 CDDBSUBMIT=freedb-submit@freedb.org
2945 CDDBPROTO=6
2946 HELLOINFO="$(whoami)@$(hostname)"
2947 CDDBCOPYLOCAL="n"
2948 CDDBLOCALPOLICY="always"
2949 CDDBLOCALRECURSIVE="y"
2950 CDDBLOCALDIR="$HOME/.cddb"
2951 CDDBUSELOCAL="n"
2952
2953 # List of fields we parse and show during the CDDB parsing...
2954 SHOWCDDBFIELDS="year,genre"
2955
2956 INTERACTIVE=y
2957 #CDROMREADERSYNTAX=cdparanoia
2958 ENCODERSYNTAX=default
2959
2960 MP3ENCODERSYNTAX=default
2961 OGGENCODERSYNTAX=default
2962 FLACENCODERSYNTAX=default
2963 SPEEXENCODERSYNTAX=default
2964 MPPENCODERSYNTAX=default
2965 AACENCODERSYNTAX=default
2966 NORMALIZERSYNTAX=default
2967 CUEREADERSYNTAX=default
2968
2969 OUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${TRACKNUM}.${TRACKFILE}'
2970 # Use the following VAOUTPUTFORMAT to revert to 2.0.x VA format:
2971 #VAOUTPUTFORMAT=${OUTPUTFORMAT}
2972 VAOUTPUTFORMAT='Various-${ALBUMFILE}/${TRACKNUM}.${ARTISTFILE}-${TRACKFILE}'
2973 ONETRACKOUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${ALBUMFILE}'
2974 VAONETRACKOUTPUTFORMAT='Various-${ALBUMFILE}/${ALBUMFILE}'
2975 PLAYLISTFORMAT='${ARTISTFILE}-${ALBUMFILE}.${OUTPUT}.m3u'
2976 PLAYLISTDATAPREFIX=''
2977 VAPLAYLISTFORMAT='${ARTISTFILE}-${ALBUMFILE}.${OUTPUT}.m3u'
2978 VAPLAYLISTDATAPREFIX=''
2979 DOSPLAYLIST=n
2980 COMMENT=''
2981 ID3TAGV=2
2982 ENCNICE=10
2983 READNICE=10
2984 DISTMP3NICE=10
2985 VARIOUSARTISTS=n
2986 VARIOUSARTISTSTYLE=forward
2987 KEEPWAVS=n
2988 PADTRACKS=n
2989 NOGAP=n
2990 BATCHNORM=n
2991 NOCDDBQUERY=n
2992
2993 # If using scsi devices, cdda2wav needs a CDROMID, instead of a device node
2994 # i.e. CDROMID="1,0,0"
2995 CDROMID=""
2996 # If we are using the IDE bus, we need CDPARANOIACDROMBUS defined as "d"
2997 # If we are using the ide-scsi emulation layer, we need to define a "g"
2998 CDPARANOIACDROMBUS="d"
2999
3000 # program paths - defaults to checking your $PATH
3001 # mp3
3002 LAME=lame
3003 TOOLAME=toolame
3004 GOGO=gogo
3005 BLADEENC=bladeenc
3006 L3ENC=l3enc
3007 XINGMP3ENC=xingmp3enc
3008 MP3ENC=mp3enc
3009 # ogg
3010 VORBIZE=vorbize
3011 OGGENC=oggenc
3012 # flac
3013 FLAC=flac
3014 # speex
3015 SPEEXENC=speexenc
3016 # mpp (Musepack)
3017 MPPENC=mppenc
3018 # m4a
3019 AACENC=faac
3020
3021 ID3=id3
3022 ID3V2=id3v2
3023 EYED3=eyeD3
3024 VORBISCOMMENT=vorbiscomment
3025 METAFLAC=metaflac
3026 AACTAG=faac
3027
3028 CDPARANOIA=cdparanoia
3029 CDDA2WAV=cdda2wav
3030 DAGRAB=dagrab
3031 CDDAFS=cp
3032 CDDISCID=cd-discid
3033 CDDBTOOL=cddb-tool
3034 MUSICBRAINZ=musicbrainz-get-tracks
3035 EJECT=eject
3036 MD5SUM=md5sum
3037 DISTMP3=distmp3
3038 NORMALIZE=normalize-audio
3039 CDSPEED=eject
3040 VORBISGAIN=vorbisgain
3041 MP3GAIN=mp3gain
3042 MPPGAIN=replaygain
3043 MKCUE=mkcue
3044 MKTOC=cdrdao
3045 DIFF=diff
3046 CUE2DISCID=builtin
3047
3048 # Options for programs called from abcde
3049 # mp3
3050 LAMEOPTS=
3051 TOOLAMEOPTS=
3052 GOGOOPTS=
3053 BLADEENCOPTS=
3054 L3ENCOPTS=
3055 XINGMP3ENCOPTS=
3056 MP3ENCOPTS=
3057 # ogg
3058 VORBIZEOPTS=
3059 OGGENCOPTS=
3060 # flac
3061 FLACOPTS=
3062 # speex
3063 SPEEXENCOPTS=
3064 # mpc
3065 MPPENCOPTS=
3066 # m4a
3067 AACENCOPTS=
3068
3069 ID3OPTS=
3070 ID3V2OPTS=
3071 CDPARANOIAOPTS=
3072 CDDA2WAVOPTS=
3073 DAGRABOPTS=
3074 CDDAFSOPTS="-f"
3075 CDDBTOOLOPTS=
3076 EJECTOPTS=
3077 DISTMP3OPTS=
3078 NORMALIZEOPTS=
3079 CDSPEEDOPTS="-x"
3080 CDSPEEDVALUE=
3081 MKCUEOPTS=
3082 MKTOCOPTS=""
3083 VORBISCOMMENTOPTS="-R"
3084 METAFLACOPTS="--no-utf8-convert"
3085 DIFFOPTS=
3086
3087 # Default to one process if -j isn't specified
3088 MAXPROCS=1
3089
3090 # List of actions to perform - by default, run to completion
3091 ACTIONS=cddb,read,encode,tag,move,clean
3092
3093 # This option is basicaly for Debian package dependencies:
3094 # List of prefered outputs - by default, run with whatever we have in the path
3095 DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:toolame,mp3:lame,mp3:bladeenc,spx:speex,m4a:faac
3096
3097 # List of prefered cdromreaders - by default, run whichever we have in the path
3098 DEFAULT_CDROMREADERS="cdparanoia cdda2wav"
3099
3100 # List of quality levels associated with the encoders:
3101 DEFAULT_QUALITY_XLO="oggenc:-q -1,lame:-q 9,speex:--quality 1,m4a:"
3102 DEFAULT_QUALITY_LO="oggenc:-q 1,lame:-q 7,speex:--quality 5,m4a:"
3103 DEFAULT_QUALITY_HI="oggenc:-q 7,lame:--preset standard,speex:--quality 9,m4a:"
3104 DEFAULT_QUALITY_XHI="oggenc:-q 10,lame:--preset extreme,speex:--quality 10,m4a:"
3105
3106 # Asume fetch if under FreeBSD. curl is used for Mac OS X. wget is used for
3107 # Linux/OpenBSD. ftp is user for NetBSD.
3108 # Let's use these checkings to determine the OS flavour, which will be used
3109 # later
3110 if [ X$(uname) = "XFreeBSD" ] ; then
3111 HTTPGET=fetch
3112 MD5SUM=md5
3113 NEEDCDROMID=y
3114 OSFLAVOUR=FBSD
3115 elif [ X$(uname) = "XDarwin" ] ; then
3116 HTTPGET=curl
3117 OSFLAVOUR=OSX
3118 # We should have disktool in OSX, but let's be sure...
3119 NEEDDISKTOOL=y
3120 CDROMREADERSYNTAX=cddafs
3121 elif [ X$(uname) = "XOpenBSD" ] ; then
3122 HTTPGET=wget
3123 MD5SUM=md5
3124 OSFLAVOUR=OBSD
3125 elif [ X$(uname) = "XNetBSD" ] ; then
3126 HTTPGET=ftp
3127 MD5SUM=md5
3128 OSFLAVOUR=NBSD
3129 elif [ X$(uname) = "SunOS" ] ; then
3130 HTTPGET=""
3131 MD5SUM=md5
3132 OSFLAVOUR=SunOS
3133 else
3134 HTTPGET=wget
3135 fi
3136
3137 # If CDDBAVAIL is set to n, no CDDB read is done
3138 # If USEID3 is set to n, no ID3 tagging is done
3139 CDDBAVAIL=y
3140 USEID3=y
3141 USEID3V2=y
3142
3143 # There we go..
3144 # But before we get into business, let us chop off any GREP environmental
3145 # variables.
3146 GREP_OPTIONS=""
3147 GREP_COLOR=""
3148
3149 if [ -z "$OUTPUTDIR" ]; then
3150 OUTPUTDIR=$(pwd)
3151 fi
3152
3153 if [ -z "$WAVOUTPUTDIR" ]; then
3154 WAVOUTPUTDIR="$OUTPUTDIR"
3155 fi
3156
3157 # Load system defaults
3158 if [ -r /etc/abcde.conf ]; then
3159 . /etc/abcde.conf
3160 fi
3161 # Load user preference defaults
3162 if [ -r $HOME/.abcde.conf ]; then
3163 . $HOME/.abcde.conf
3164 fi
3165
3166 # By this time, we need some HTTPGETOPTS already defined.
3167 # If the user has defined a non-default HTTPGET method, we should not be empty.
3168
3169 if [ "$HTTPGETOPTS" = "" ] ; then
3170 case $HTTPGET in
3171 wget) HTTPGETOPTS="-q -nv -e timestamping=off -O -";;
3172 curl) HTTPGETOPTS="-f -s";;
3173 fetch)HTTPGETOPTS="-q -o -";;
3174 ftp) HTTPGETOPTS="-a -V -o - ";;
3175 *) log warning "HTTPGET in non-standard and HTTPGETOPTS are not defined." ;;
3176 esac
3177 fi
3178
3179 # If the CDROM has not been set yet, find a suitable one.
3180 # If this is a devfs system, default to /dev/cdroms/cdrom0
3181 # instead of /dev/cdrom
3182 if [ "$CDROM" = "" ] ; then
3183 if [ -e /dev/cdroms/cdrom0 ]; then
3184 CDROM=/dev/cdroms/cdrom0
3185 elif [ -e /dev/cdrom ]; then
3186 CDROM=/dev/cdrom
3187 elif [ -e /dev/cd0c ]; then
3188 CDROM=/dev/cd0c
3189 elif [ -e /dev/acd0c ]; then
3190 CDROM=/dev/acd0c
3191 elif [ -e /dev/disk1 ]; then
3192 CDROM=/dev/disk1
3193 fi
3194 fi
3195
3196 # Parse command line options
3197 #while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPq:r:Rs:S:t:T:vVxw:W: opt ; do
3198 while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:UvVxX:w:W:z opt ; do
3199 case "$opt" in
3200 1) ONETRACK=y ;;
3201 a) ACTIONS="$OPTARG" ;;
3202 A) EXPACTIONS="$OPTARG" ;;
3203 b) BATCHNORM=y ;;
3204 B) NOBATCHREPLAYGAIN=y ;;
3205 c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else log error "config file \"$OPTARG\" cannot be found." ; exit 1 ; fi ;;
3206 C) DISCID="$( echo ${OPTARG#abcde.} | tr -d /)" ;;
3207 d) CDROM="$OPTARG" ;;
3208 D) set -x ;;
3209 h) usage; exit ;;
3210 e) ERASEENCODEDSTATUS=y ;;
3211 E) ENCODING="$OPTARG" ;;
3212 f) FORCE=y ;;
3213 g) NOGAP=y ;;
3214 i) INLINETAG=y ;;
3215 j) MAXPROCS="$OPTARG" ;;
3216 k) KEEPWAVS=y ;;
3217 l) LOWDISK=y ;;
3218 L) CDDBUSELOCAL=y ;;
3219 n) CDDBAVAIL=n ;;
3220 N) INTERACTIVE=n ;;
3221 m) DOSPLAYLIST=y ;;
3222 M) DOCUE=y ;;
3223 o) OUTPUTTYPE="$OPTARG" ;;
3224 p) PADTRACKS=y ;;
3225 P) USEPIPES=y ;;
3226 q) QUALITYLEVEL="$OPTARG" ;;
3227 r) REMOTEHOSTS="$OPTARG" ;;
3228 R) CDDBLOCALRECURSIVE=y ;;
3229 s) SHOWCDDBFIELDS="$OPTARG" ;;
3230 S) CDSPEEDVALUE="$OPTARG" ;;
3231 t) STARTTRACKNUMBER="$OPTARG" ;;
3232 T) STARTTRACKNUMBER="$OPTARG" ; STARTTRACKNUMBERTAG="y" ;;
3233 U) CDDBPROTO=5 ;;
3234 v)
3235 echo "This is abcde v$VERSION."
3236 echo "Usage: abcde [options] [tracks]"
3237 echo "abcde -h for extra help"
3238 exit
3239 ;;
3240 V) EXTRAVERBOSE="y" ;;
3241 x) EJECTCD="y" ;;
3242 X) CUE2DISCID="$OPTARG" ;;
3243 w) COMMENT="$OPTARG" ;;
3244 W) if echo $OPTARG | grep "[[:digit:]]" > /dev/null 2>&1 ; then
3245 STARTTRACKNUMBER="${OPTARG}01"
3246 STARTTRACKNUMBERTAG="y"
3247 COMMENT="CD${OPTARG}"
3248 DISCNUMBER="${OPTARG}"
3249 else
3250 log error "argument of -W must be integer"
3251 exit 1
3252 fi
3253 ;;
3254 z) DEBUG=y ; CDROMREADERSYNTAX=debug ; EJECTCD="n" ;;
3255 ?) usage; exit ;;
3256 esac
3257 done
3258
3259 shift $(($OPTIND - 1))
3260
3261 # Here it comes the worse part of the whole thing. From here until we start
3262 # ripping, we have a mixture of sanity checks, verifications, default settigs
3263 # and other crazy stuff that interdepends, but hey, someone has to do it.
3264
3265 # If NOCDDBQUERY is set, don't query the CDDB server.
3266 if [ "$NOCDDBQUERY" = "y" ]; then
3267 CDDBAVAIL="n"
3268 fi
3269
3270 # If the user specified a flac file, then switch to special flac mode
3271 if echo "$CDROM" | grep -i '.flac$' > /dev/null 2>&1 ; then
3272 if [ ! -f "$CDROM" ]; then
3273 log error "the defined file for FLAC ripping cannot be found" >&2
3274 exit 1
3275 fi
3276 vecho warning "switching to flac CDROMREADERSYNTAX..."
3277 CDROMREADERSYNTAX=flac
3278 # We have a builtin version of cue2discid...
3279 case "$CUE2DISCID" in
3280 builtin);;
3281 *) NEEDCUE2DISCID=y;;
3282 esac
3283 NEEDMETAFLAC=y
3284 EJECTCD=n
3285 fi
3286
3287 # If the user provided a DISCID, disable eject
3288 if [ -n "$DISCID" ] || [ "$CDROMREADERSYNTAX" = "flac" ]; then EJECTCD=n ; fi
3289
3290 # Check the available cd rippers in the system, from the ones we know.
3291 if [ "$CDROMREADERSYNTAX" = "" ]; then
3292 for DEFAULT_CDROMREADER in $DEFAULT_CDROMREADERS; do
3293 if new_checkexec $DEFAULT_CDROMREADER; then
3294 CDROMREADERSYNTAX=$DEFAULT_CDROMREADER
3295 break
3296 fi
3297 done
3298 if [ "$CDROMREADERSYNTAX" = "" ]; then
3299 log error "no cdreader found in your PATH"
3300 log error "hints: are all dependencies installed? has the \$PATH been modified?"
3301 exit 1
3302 fi
3303 fi
3304
3305 # Decide if we can continue.
3306 if [ "$ONETRACK" = "y" ]; then
3307 # FIXME # remove check as soon as we find out about the other readers
3308 case "$CDROMREADERSYNTAX" in
3309 flac) ;;
3310 cdparanoia) ;;
3311 cdda2wav) ;;
3312 *) log error "$CDROMREADERSYNTAX does not support ONETRACK mode"
3313 exit 1 ;;
3314 esac
3315 if [ "$BATCHNORM" = "y" ]; then
3316 log warning "BATCHNORM mode is not compatible with ONETRACK mode. Disabling..."
3317 BATCHNORM=n
3318 fi
3319 if [ "$NOGAP" = "y" ]; then
3320 log warning "NOGAP mode is not compatible with ONETRACK mode. Disabling..."
3321 NOGAP=n
3322 fi
3323 # It does not matter how many tracks we want. In ONETRACK mode we grab them all
3324 # FIXME # allow ranges of tracks to be selected for onetrack ripping
3325 if [ $# -gt 0 ]; then
3326 log warning "ONETRACK mode selected, grabbing all tracks..."
3327 fi
3328 else
3329 while [ $# -gt 0 ]; do
3330 # Range parsing code courtesy of Vincent Ho
3331 # Cleaned up to use shell built-ins by Charles Steinkuehler
3332 if [ "${1#*[^0-9-]}" != "$1" ]; then
3333 log error "syntax error while processing track numbers"
3334 else
3335 RSTART=${1%%-*}
3336 REND=${1##*-}
3337 while [ ${RSTART:=1} -le ${REND:=0} ] ; do
3338 TRACKQUEUE="$TRACKQUEUE $RSTART"
3339 RSTART=$(( $RSTART + 1 ))
3340 done
3341 fi
3342 shift
3343 done
3344 fi
3345
3346 # List of valid actions: cddb,read,normalize,encode,tag,move,playlist,clean
3347 # List of experimental actions: retag,transcode
3348
3349 # Determine what actions are to be done from $ACTIONS and set the
3350 # following environment variables for them:
3351 DOCDDB=n
3352 DOREAD=n
3353 DONORMALIZE=n
3354 DOPREPROCESS=n
3355 DOENCODE=n
3356 DOPOSTPROCESS=n
3357 DOTAG=n
3358 DOMOVE=n
3359 DOREPLAYGAIN=n
3360 DOPLAYLIST=n
3361 DOCLEAN=n
3362 ## FIXME ## Lets keep compatibility with -M
3363 [ "$DOCUE" != "y" ] && DOCUE=n
3364
3365 for ACTION in $(echo $ACTIONS | tr , \ )
3366 do
3367 case $ACTION in
3368 default) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOCLEAN=y;;
3369 cue) DOCUE=y ; MAKECUEFILE=y ;;
3370 cddb) DOCDDB=y;;
3371 read) DOREAD=y;;
3372 normalize) DONORMALIZE=y; DOREAD=y;;
3373 # preprocess) DOPREPROCESS=y; DOREAD=y;;
3374 encode) DOENCODE=y; DOREAD=y;;
3375 # postprocess) DOPREPROCESS=y; DOENCODE=y; DOREAD=y;;
3376 tag) DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
3377 move) DOMOVE=y; DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
3378 replaygain) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOREPLAYGAIN=y;;
3379 playlist) DOCDDB=y; DOPLAYLIST=y;;
3380 clean) DOCLEAN=y;;
3381 esac
3382 done
3383
3384 if [ "$DONORMALIZE" = "y" ] && [ "$DOREPLAYGAIN" = "y" ]; then
3385 # FIXME # should we abort on error or just inform the user?
3386 log warning "selected both normalize and replaygain actions"
3387 fi
3388
3389 for SHOWCDDBFIELD in $(echo $SHOWCDDBFIELDS | tr , \ ); do
3390 case $SHOWCDDBFIELD in
3391 y*|Y*) SHOWCDDBYEAR="y";;
3392 g*|G*) SHOWCDDBGENRE="y";;
3393 *) ;;
3394 esac
3395 done
3396
3397 # At this point a CDROM has to be defined, so we check it exists.
3398 if [ X"$CDROM" != "X" ] ; then
3399 if [ "$CDROMREADERSYNTAX" = "cdda2wav" ] && [ "$NEEDCDROMID" = "y" ] ; then
3400 if [ "$OSFLAVOUR" = "FBSD" ]; then
3401 if echo "$CDROMID" | grep "^[0-9],[0-9],[0-9]$" >/dev/null 2>&1 ; then :; else
3402 log error "CDROMID not in the right format for $CDROMREADERSYNTAX"
3403 log error "Use \"cdrecord -scanbus\" to obtain a adecuate ID an set CDROMID accordingly"
3404 exit 1
3405 fi
3406 fi
3407 elif [ ! -e "$CDROM" -a X"$DOREAD" = "Xy" ]; then
3408 log error "CDROM device cannot be found."
3409 exit 1
3410 fi
3411 # avoid processing if we are not going to hit the CDROM.
3412 elif [ X"$DOREAD" = "Xy" ]; then
3413 log error "CDROM has not been defined or cannot be found"
3414 exit 1
3415 fi
3416
3417 # USEPIPES pre-tests, before we get into more serious stuff
3418 # Not compatible with:
3419 # - multiple outputs
3420 # - normalize
3421 # - lowdisk algorithm
3422 # - anything else?
3423 if [ X"$USEPIPES" = "Xy" ]; then
3424 if [ $(echo "$OUTPUTTYPE" | tr , \ | wc -w ) -gt 1 ]; then
3425 log error "Unix pipes not compatible with multiple outputs"
3426 exit 1
3427 fi
3428 if [ X"$DONORMALIZE" = "Xy" ]; then
3429 log error "Unix pipes not compatible with normalizer"
3430 # FIXME # Do we need to exit or shall we just disable the mode?
3431 exit 1
3432 fi
3433 if [ X"$BATCHNORM" = "Xy" ]; then
3434 log error "Unix pipes not compatible with BATCHNORM encoding"
3435 exit 1
3436 fi
3437 if [ X"$NOGAP" = "Xy" ]; then
3438 log error "Unix pipes not compatible with NOGAP encoding"
3439 exit 1
3440 fi
3441 if [ X"$DOENCODE" = "Xn" ]; then
3442 vecho warning "Disabling Unix pipes since we are not encoding!"
3443 USEPIPES=n
3444 fi
3445 if [ X"$LOWDISK" = "Xy" ]; then
3446 log error "Unix pipes not compatible with lowdisk algorithm"
3447 exit 1
3448 fi
3449 fi
3450
3451 # LOWDISK pre-tests, before we get into more problematic stuff
3452 # Not compatible with anything that needs all the files in the hard disc:
3453 # - BATCHNORM
3454 # - NOGAP lame mode
3455 if [ X"$LOWDISK" = "Xy" ]; then
3456 if [ X"$BATCHNORM" = "Xy" ]; then
3457 log error "Unix pipes not compatible with BATCHNORM encoding"
3458 exit 1
3459 fi
3460 if [ X"$NOGAP" = "Xy" ]; then
3461 log error "Unix pipes not compatible with NOGAP encoding"
3462 exit 1
3463 fi
3464 fi
3465
3466 # BATCHNORM pre-tests, before we get into serious problems
3467 # Not compatible with
3468 if [ "$BATCHNORM" = "y" ] && [ "$DONORMALIZE" = "n" ]; then
3469 vecho warning "Disabling BATCHNORM since we are not normalizing!"
3470 BATCHNORM=n
3471 fi
3472
3473 # Check the encoding format from the ones available in the system, if nothing has been configured.
3474 if [ X"$OUTPUTTYPE" = "X" ]; then
3475 for DEFAULT_OUTPUT in $( echo "$DEFAULT_OUTPUT_BINARIES" | tr , \ ); do
3476 DEFAULT_OUTPUT_FORMAT="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 1)"
3477 DEFAULT_OUTPUT_BINARY="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 2)"
3478 if [ -x $(which $DEFAULT_OUTPUT_BINARY) ] ; then
3479 OUTPUTTYPE=$DEFAULT_OUTPUT_FORMAT
3480 vecho "No default output type defined. Autoselecting $OUTPUTTYPE..." >&2
3481 break
3482 fi
3483 done
3484 if [ X"$OUTPUTTYPE" = "X" ]; then
3485 log error "no encoder found in the PATH"
3486 log error "hints: are all dependencies installed? has the \$PATH been modified?"
3487 exit 1
3488 fi
3489 fi
3490
3491 # Decide which CDROM reader we're gonna use
3492 case "$CDROMREADERSYNTAX" in
3493 cdparanoia|debug)
3494 CDROMREADER="$CDPARANOIA"
3495 CDROMREADEROPTS="$CDPARANOIAOPTS"
3496 ;;
3497 cdda2wav)
3498 CDROMREADER="$CDDA2WAV"
3499 CDROMREADEROPTS="$CDDA2WAVOPTS"
3500 ;;
3501 dagrab)
3502 CDROMREADER="$DAGRAB"
3503 CDROMREADEROPTS="$DAGRABOPTS"
3504 ;;
3505 cddafs)
3506 CDROMREADER="$CDDAFS"
3507 CDROMREADEROPTS="$CDDAFSOPTS"
3508 ;;
3509 flac)
3510 CDROMREADER="$FLAC"
3511 CDROMREADEROPTS="$FLACOPTS"
3512 ;;
3513 esac
3514
3515 # There's only one normalize...
3516 case "$NORMALIZERSYNTAX" in
3517 default|normalize)
3518 NORMALIZER="$NORMALIZE"
3519 NORMALIZEROPTS="$NORMALIZEOPTS"
3520 ;;
3521 esac
3522
3523 # Allow -o OUTPUT(1):OPTIONS(1),...,OUTPUT(N):OPTIONS(N) mode of operation
3524 if echo "$OUTPUTTYPE" | grep ":" > /dev/null 2>&1 ; then
3525 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr \ \|| tr , \ | tr \| \ )"; do
3526 case "$OUTPUT" in
3527 vorbis:*|ogg:*) OGGENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3528 mp3:*) MP3ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3529 flac:*) FLACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3530 spx:*) SPEEXENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3531 mpc:*) MPPENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3532 m4a:*) AACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3533 esac
3534 done
3535 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do
3536 TEMPOUTPUT=$( echo "$OUTPUT" | cut -d: -f1 )
3537 TEMPOUTPUTTYPE="${TEMPOUTPUTTYPE:+$TEMPOUTPUTTYPE,}$TEMPOUTPUT"
3538 done
3539 OUTPUTTYPE="$TEMPOUTPUTTYPE"
3540 fi
3541
3542 # If nothing has been specified, use oggenc for oggs and lame for mp3s and flac
3543 # for flacs and speexenc for speex and mppenc for mpps and faac for m4as
3544
3545 # Getting ready for multiple output changes
3546 for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
3547 do
3548 case $OUTPUT in
3549 vorbis|ogg)
3550 [ "$OGGENCODERSYNTAX" = "default" ] && OGGENCODERSYNTAX=oggenc
3551 [ "$DOTAG" = "y" ] && NEEDCOMMENTER=y
3552 [ "$DOREPLAYGAIN" = "y" ] && NEEDVORBISGAIN=y
3553 OGGOUTPUTCONTAINER=ogg
3554 ;;
3555 mp3)
3556 [ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame
3557 [ "$DOTAG" = "y" ] && NEEDTAGGER=y
3558 [ "$DOREPLAYGAIN" = "y" ] && NEEDMP3GAIN=y
3559 ;;
3560 flac)
3561 [ "$FLACENCODERSYNTAX" = "default" ] && FLACENCODERSYNTAX=flac
3562 [ "$DOTAG" = "y" ] && NEEDMETAFLAC=y
3563 [ "$DOREPLAYGAIN" = "y" ] && NEEDMETAFLAC=y
3564 [ "$ONETRACK" = "y" ] && [ "$DOCUE" = "y" ] && NEEDMETAFLAC=y
3565 ;;
3566 spx)
3567 [ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc
3568 # [ "$DOREPLAYGAIN" = "y" ] &&
3569 ;;
3570 mpc)
3571 [ "$MPPENCODERSYNTAX" = "default" ] && MPPENCODERSYNTAX=mppenc
3572 [ "$DOREPLAYGAIN" = "y" ] && NEEDMPPGAIN=y
3573 ;;
3574 m4a)
3575 [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac
3576 [ "$DOTAG" = "y" ] && CHECKATOMICPARSLEY=y
3577 ;;
3578 wav)
3579 if [ "$KEEPWAVS" = "y" ]; then
3580 vecho "Setting the KEEPWAVS option, since the resulting wav files were requested..."
3581 fi
3582 KEEPWAVS=move
3583 ;;
3584 *) log error "Invalid OUTPUTTYPE defined"
3585 exit 1
3586 ;;
3587 esac
3588 done
3589
3590 # decide which encoder
3591 case "$MP3ENCODERSYNTAX" in
3592 lame)
3593 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$LAMEOPTS}"
3594 MP3ENCODER="$LAME"
3595 ;;
3596 toolame)
3597 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$TOOLAMEOPTS}"
3598 MP3ENCODER="$TOOLAME"
3599 ;;
3600 gogo)
3601 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$GOGOOPTS}"
3602 MP3ENCODER="$GOGO"
3603 ;;
3604 bladeenc)
3605 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$BLADEENCOPTS}"
3606 MP3ENCODER="$BLADEENC"
3607 ;;
3608 l3enc)
3609 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$L3ENCOPTS}"
3610 MP3ENCODER="$L3ENC"
3611 ;;
3612 xingmp3enc)
3613 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$XINGMP3ENCOPTS}"
3614 MP3ENCODER="$XINGMP3ENC"
3615 ;;
3616 mp3enc)
3617 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$MP3ENCOPTS}"
3618 MP3ENCODER="$MP3ENC"
3619 ;;
3620 esac
3621 case "$OGGENCODERSYNTAX" in
3622 vorbize)
3623 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$VORBIZEOPTS}"
3624 OGGENCODER="$VORBIZE"
3625 ;;
3626 oggenc)
3627 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$OGGENCOPTS}"
3628 OGGENCODER="$OGGENC"
3629 ;;
3630 esac
3631 case "$FLACENCODERSYNTAX" in
3632 flac)
3633 FLACENCODEROPTS="${FLACENCODEROPTSCLI:-$FLACOPTS}"
3634 FLACENCODER="$FLAC"
3635 if [ "$DOREPLAYGAIN" = "y" ]; then
3636 FLACENCODEROPTS="${FLACENCODEROPTS} --replay-gain"
3637 fi
3638 # FLAC streams can be encapsulated on a Ogg transport layer
3639 if echo "$FLACENCODEROPTS" | egrep -- "(^| )--ogg($| )" > /dev/null 2>&1 ;then
3640 log error "FLAC on an Ogg container is not yet supported"
3641 log error "due to problem with adding comments to such files"
3642 exit 1
3643 FLACOUTPUTCONTAINER=ogg
3644 else
3645 FLACOUTPUTCONTAINER=flac
3646 fi
3647 ;;
3648 esac
3649 case "$SPEEXENCODERSYNTAX" in
3650 speexenc)
3651 SPEEXENCODEROPTS="${SPEEXENCODEROPTSCLI:-$SPEEXENCOPTS}"
3652 SPEEXENCODER="$SPEEXENC"
3653 ;;
3654 esac
3655 case "$MPPENCODERSYNTAX" in
3656 mppenc)
3657 MPPENCODEROPTS="${MPPENCODEROPTSCLI:-$MPPENCOPTS}"
3658 MPPENCODER="$MPPENC"
3659 ;;
3660 esac
3661 case "$AACENCODERSYNTAX" in
3662 faac)
3663 AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
3664 AACENCODER="$AACENC"
3665 ;;
3666 esac
3667
3668 # and which tagger
3669 if [ "$ID3TAGV" = "1" ]; then
3670 TAGGER="$ID3"
3671 TAGGEROPTS="$ID3OPTS"
3672 else
3673 TAGGER="$ID3V2"
3674 TAGGEROPTS="$ID3V2OPTS"
3675 fi
3676
3677 # NOGAP is specific to lame. Other encoders fail ...
3678 if [ "$NOGAP" = "y" ] && [ ! "$MP3ENCODER" = "lame" ]; then
3679 log warning "the NOGAP option is specific to lame. Deactivating..."
3680 NOGAP=n
3681 fi
3682
3683 # Options for mkcue
3684 case "$CUEREADERSYNTAX" in
3685 default|mkcue)
3686 CUEREADEROPTS="${CDROM}"
3687 CUEREADER="$MKCUE"
3688 ;;
3689 esac
3690
3691 # which information retrieval tool are we using?
3692 case "$CDDBTOOL" in
3693 cddb) ;;
3694 musicbrainz) ;;
3695 esac
3696
3697 # Check if both OGGEOUTPUTCONTAINER and FLACOUTPUTCONTAINER are the same, and differentiante them
3698 if [ X"$OGGOUTPUTCONTAINER" = "Xogg" ] && [ X"$FLACOUTPUTCONTAINER" = "Xogg" ]; then
3699 log error "FLAC on an Ogg container is not yet supported"
3700 log error "due to problem with adding comments to such files"
3701 exit 1
3702 OGGOUTPUTCONTAINER=ogg.ogg
3703 FLACOUTPUTCONTAINER=flac.ogg
3704 vecho warning "modified file endings due to conflicting transport layers in Ogg/Vorbis and Ogg/FLAC"
3705 fi
3706
3707 # Clean up nice options (either use '-n NICELEVEL or -NICELEVEL')
3708
3709 if [ "$ENCNICE" ]; then
3710 ENCNICE="-n $ENCNICE"
3711 fi
3712 if [ "$READNICE" ]; then
3713 READNICE="-n $READNICE"
3714 fi
3715 if [ "$DISTMP3NICE" ]; then
3716 DISTMP3NICE="-n $DISTMP3NICE"
3717 fi
3718
3719 # Don't check for stuff if it's not needed
3720 if [ "$REMOTEHOSTS" ]; then
3721 NEEDDISTMP3=y
3722 fi
3723 if [ "$DONORMALIZE" = "y" ]; then
3724 NEEDNORMALIZER=y
3725 fi
3726 if [ "$EJECTCD" = "y" ]; then
3727 NEEDEJECT=y
3728 fi
3729 if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then
3730 if [ "$CDDBMETHOD" = "cddb" ]; then
3731 NEEDHTTPGET=y
3732 elif [ "$CDDBMETHOD" = "musicbrainz" ]; then
3733 :
3734 fi
3735 fi
3736 if [ "$DOCUE" = "y" ]; then
3737 NEEDCUEREADER=y
3738 fi
3739
3740 if [ X"$CDSPEEDVALUE" != "X" ] && [ "$DOREAD" = "y" ]; then
3741 case "$CDROMREADERSYNTAX" in
3742 cdparanoia|debug) CDROMREADEROPTS="$CDPARANOIAOPTS -S $CDSPEEDVALUE" ;;
3743 ### FIXME ### translate "cue2discid" from python to bash
3744 flac) NEEDMETAFLAC=y ; NEEDCUE2DISCID=y ; CDSPEEDVALUE="" ;;
3745 *) NEEDCDSPEED=y ;;
3746 esac
3747 fi
3748
3749 ###USEPIPESSUPPORT###
3750
3751 # Rippers with USEPIPE support
3752 # FIXME # Include here all the rippers we can figure out support pipes
3753 PIPERIPPER_cdparanoia="-"
3754 PIPERIPPER_debug="-"
3755 PIPERIPPER_flac="-c "
3756
3757 # Encoders with USEPIPE support
3758 # FIXME # Include here all the encoders we can figure out support pipes
3759 PIPE_lame="-"
3760 PIPE_bladeenc="-"
3761 PIPE_oggenc="-"
3762 PIPE_flac="-"
3763
3764 # Figure out if we can use pipes with the ripper/encoder combination
3765 # exit otherwise
3766 if [ "$USEPIPES" = "y" ]; then
3767 PIPERIPPERSVARCHECK="PIPERIPPER_${CDROMREADERSYNTAX}"
3768 case "$OUTPUT" in
3769 mp3)
3770 PIPEENCODERSVARCHECK="PIPE_$MP3ENCODERSYNTAX" ;;
3771 vorbis|ogg)
3772 PIPEENCODERSVARCHECK="PIPE_$OGGENCODERSYNTAX" ;;
3773 flac)
3774 PIPEENCODERSVARCHECK="PIPE_$FLACENCODERSYNTAX" ;;
3775 spx)
3776 PIPEENCODERSVARCHECK="PIPE_$SPEEXENCODER" ;;
3777 mpc)
3778 PIPEENCODERSVARCHECK="PIPE_$MPPENCODER" ;;
3779 esac
3780 decho "PIPERIPPERSVARCHECK: $( eval echo "\$$PIPERIPPERSVARCHECK" )"
3781 if [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "$" ] || \
3782 [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "" ] ; then
3783 log error "no support for pipes with given ripper"
3784 log error "read the USEPIPES file from the source tarball to get help."
3785 log error "On a Debian system, it is under /usr/share/doc/abcde/USEPIPES.gz"
3786 exit 1;
3787 fi
3788 decho "PIPEENCODERSVARCHECK: $( eval echo "\$$PIPEENCODERSVARCHECK" )"
3789 if [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "$" ] || \
3790 [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "" ] ; then
3791 log error "no support for pipes with given encoder"
3792 log error "read the USEPIPES file from the source tarball to help"
3793 log error "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz"
3794 exit 1;
3795 fi
3796 fi
3797
3798 # Make sure a buncha things exist
3799 for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
3800 $OGGENCODER $FLACENCODER $SPEEXENCODER $MPPENCODER \
3801 $AACENCODER \
3802 ${NEEDATOMICPARSLEY+$ATOMICPARSLEY} \
3803 ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \
3804 ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
3805 ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
3806 ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} \
3807 ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMP3GAIN+$MP3GAIN} \
3808 ${NEEDMPPGAIN+$MPPGAIN} ${NEEDCUEREADER+$CUEREADER} \
3809 ${NEEDCUE2DISCID+$CUE2DISCID}
3810 do
3811 checkexec "$X"
3812 done
3813
3814 if [ "$CHECKATOMICPARSLEY" = "y" ]; then
3815 if ! new_checkexec "$ATOMICPARSLEY"; then
3816 echo "WARNING: $ATOMICPARSLEY Not Found Not Post-Tagging!"
3817 DOTAG='n'
3818 else
3819 echo "Using $ATOMICPARSLEY To Tag AAC Tracks."
3820 fi
3821 fi
3822
3823 # And last but not least, check if we can diff between files. We do not abort,
3824 # since diffing is not critical...
3825 if [ -x $(which $DIFF) ]; then :; else
3826 vecho warning "Disabling diff since we cannot find it in the \$PATH..."
3827 DIFF=""
3828 fi
3829
3830 ## Now that we have metaflac, check if we need cue2discid
3831 #case $CDROMREADERSYNTAX in
3832 # flac)
3833 # TRACKINFO=$($METAFLAC --show-tag=CDDB $CDROM | cut -d"=" -f2 | egrep "[a-f0-9]{8}")
3834 # if [ "$TRACKINFO" = "" ]; then
3835 # checkexec ${NEEDCUE2DISCID+$CUE2DISCID}
3836 # fi
3837 # ;;
3838 #esac
3839
3840 CDROMREADER="$CDROMREADER $CDROMREADEROPTS"
3841 CDDBTOOL="$CDDBTOOL $CDDBTOOLOPTS"
3842 HTTPGET="$HTTPGET $HTTPGETOPTS"
3843
3844 # Here it used to say:
3845 # One thousand lines in, we can start doing stuff with things
3846 # Well, right now we are at line 3737 ;)
3847
3848 # Export needed things so they can be read in this subshell
3849 export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS
3850 export CDROM CDDBDATA REMOTEHOSTS MAXPROCS HTTPGET MD5SUM
3851
3852 if [ "$DOREAD" = "y" ]; then
3853 # User-definable function to set some things. Use it for
3854 # - closing the CD tray with eject -t
3855 # - set the CD speed value with eject -x
3856 vecho -n "Executing customizable pre-read function... "
3857
3858 pre_read # Execute the user-defined pre-read funtion. Close the CD with it.
3859
3860 vecho "done."
3861 fi
3862
3863 case "$CDDBMETHOD" in
3864 cddb)
3865 do_discid # Get ABCDETEMPDIR created and status file initialized
3866 ;;
3867 musicbrainz)
3868 do_musicbrainz id
3869 ;;
3870 esac
3871
3872 if [ "$DOCDDB" = "y" ]; then
3873 # start with a sane default:
3874 CDDBLOCALSTATUS=notfound
3875 if [ $CDDBUSELOCAL = "y" ]; then
3876 do_localcddb
3877 fi
3878 if checkstatus cddb-choice > /dev/null; then
3879 :
3880 else
3881 if [ "$CDDBLOCALSTATUS" = "notfound" ] ; then
3882 case "$CDDBMETHOD" in
3883 cddb)
3884 do_cddbstat
3885 do_cddbquery
3886 do_cddbread
3887 ;;
3888 musicbrainz)
3889 do_musicbrainz
3890 ;;
3891 esac
3892 fi
3893 fi
3894 do_cddbedit
3895
3896 eval "$($CDDBTOOL parse "$CDDBDATA")"
3897 fi
3898
3899 # Before reading tracks, we set the speed of the device
3900
3901 if [ X"$CDSPEEDVALUE" != "X" ]; then
3902 case "$CDROMREADERSYNTAX" in
3903 cdparanoia|debug) ;;
3904 flac) ;;
3905 *) do_cdspeed ;;
3906 esac
3907 fi
3908
3909 # Define the first and last track, since we might need them later in several places
3910 FIRSTTRACK=$( get_first $TRACKQUEUE )
3911 LASTTRACK=$( get_last $TRACKQUEUE )
3912
3913 if [ -f "$ABCDETEMPDIR/status" ] && [ X"$ERASEENCODEDSTATUS" = "Xy" ]; then
3914 mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
3915 grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
3916 | grep -v ^encode-output > "$ABCDETEMPDIR/status"
3917 fi
3918
3919 if checkstatus onetrack ; then ONETRACK=y ; fi
3920
3921 if [ "$ONETRACK" = "y" ]; then
3922 # Reuse the CUEFILE in case we created it (now or in a previous run)
3923 if CUEFILE=$(checkstatus cuefile); then
3924 IMPORTCUESHEET=y
3925 fi
3926 fi
3927
3928 # Create playlist if needed (backgroundable) and start reading in tracks
3929
3930 (
3931
3932 if [ ! "$ONETRACK" = "y" ]; then
3933 if [ "$DOPLAYLIST" = "y" ]; then
3934 echo Creating playlist... >&2
3935 do_playlist
3936 fi
3937 fi
3938
3939 # For the lowdisk option, only one program is running at once so the encoder
3940 # can be unsilenced right away.
3941 if [ "$LOWDISK" = "y" ] || [ "$ONETRACK" = "y" ]; then
3942 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3943 fi
3944
3945 if [ "$ONETRACK" = "y" ]; then
3946 TRACKS="$FIRSTTRACK"
3947 if [ "$USEPIPES" = "y" ]; then
3948 if checkstatus readencodetrack-$FIRSTTRACK; then :; else
3949 do_cdread onetrack $FIRSTTRACK $LASTTRACK | do_encode $FIRSTTRACK %local0% > /dev/null 2>&1
3950 fi
3951 else
3952 if checkstatus readtrack-$FIRSTTRACK; then :; else
3953 do_cdread onetrack $FIRSTTRACK $LASTTRACK
3954 fi
3955 fi
3956 else
3957 for UTRACKNUM in $TRACKQUEUE
3958 do
3959 if [ "$DOREAD" = "y" ]; then
3960 if [ "$USEPIPES" = "y" ]; then
3961 if checkstatus readencodetrack-$UTRACKNUM; then :; else
3962 # Read, pipe, shut up!
3963 do_cdread $UTRACKNUM | do_encode $UTRACKNUM %local0% > /dev/null 2>&1
3964 fi
3965 else
3966 if checkstatus readtrack-$UTRACKNUM; then :; else
3967 do_cdread $UTRACKNUM
3968 fi
3969 if [ "$?" != "0" ]; then
3970 # CD read failed - don't give the goahead to
3971 # the encoder
3972 echo NO
3973 exit
3974 fi
3975 fi
3976 fi
3977 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ]; then
3978 :
3979 else
3980 # If we are not reading, set the encode output to loud already, so
3981 # that we can see the output of the first track.
3982 if [ "$MAXPROCS" = "1" ] && [ ! "$DOREAD" = "y" ]; then
3983 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3984 fi
3985 echo NEXTTRACK # Get the encoder machine churning again
3986 if [ "$DOREAD" = "y" ]; then
3987 if [ "$LOWDISK" = "y" ] && [ "$DOENCODE" = "y" ]; then
3988 until checkstatus encodetrack-$UTRACKNUM
3989 do
3990 if checkerrors encodetrack-$UTRACKNUM; then
3991 break
3992 fi
3993 sleep 2
3994 done
3995 fi
3996 fi
3997 fi
3998 done
3999 fi
4000
4001 # Now that we're done the encoding can be loud again -
4002 # if we're not using SMP.
4003 if [ "$MAXPROCS" = "1" ]; then
4004 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
4005 fi
4006
4007 # All tracks read, start encoding.
4008 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ] || [ "$ONETRACK" = "y" ]; then
4009 echo NEXTTRACK
4010 fi
4011
4012 # Execute the user-defined post_read funtion before ejecting CD
4013 post_read
4014
4015 # We are now finished with the cdrom - it can be safely ejected. Note that
4016 # abcde will not have completed yet.
4017 if [ "$EJECTCD" = "y" ] && [ -x $(which $EJECT) ]; then
4018 # We check if the disk we are processing is actually the disk inside the
4019 # CD tray. If not, we do not eject the CD, since it might be so that the
4020 # user ejected it manually.
4021 #CURRENTTRACKINFO=$($CDDISCID $CDROM)
4022 #if if [ "$?" != "1" ] && [ "$CURRENTTRACKINFO" = "$TRACKINFO" ] ; then
4023 # More FreeBSD bits.
4024 if [ X"$(uname)" = X"FreeBSD" ] ; then
4025 # FreeBSD eject uses the EJECT environment variable to name the CDROM
4026 # but in this script EJECT is in the envionment and names the program
4027 eject=$EJECT
4028 unset EJECT
4029 # The FreeBSD eject needs "adc0" not "/dev/adc0c"
4030 cd="$(echo $CDROM | sed -e 's=.*/==;s=[a-h]$==;')"
4031 $eject $EJECTOPTS $cd
4032 elif [ X"$(uname)" = X"Darwin" ] ; then
4033 disktool -e ${CDROM#/dev/} 0
4034 else
4035 $EJECT $EJECTOPTS "$CDROM"
4036 fi
4037 #fi
4038 fi
4039
4040 ) | (
4041
4042 ## Do we need to pre-process
4043 #if [ x"$PREPROCESS" = "x" ] ; then
4044 # cat
4045 #else
4046 # for PRETRACKNUM in $TRACKQUEUE
4047 # do
4048 # read GOAHEAD
4049 # if [ "$GOAHEAD" = "NO" ]; then break; fi
4050 # PREPROCEED=
4051 # until [ $PREPROCEED ]
4052 # do
4053 # if checkstatus readtrack-$PRETRACKNUM; then PREPROCEED=y; break; fi
4054 # # all locations are working, wait and try again later
4055 # if [ ! $PREPROCEED ]; then sleep 3; fi
4056 # done
4057 # ( do_preprocess $PRETRACKNUM
4058 # echo "NEXTTRACK"
4059 # ) &
4060 # done
4061 #fi
4062 #
4063 #) | (
4064
4065 # In BATCHNORM and/or NOGAP modes, we want all tracks to be read first.
4066 #BACK
4067 if [ "$BATCHNORM" = "y" ] || [ "$NOGAP" = "y" ]; then
4068 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
4069 if [ "$GOAHEAD" = "NO" ]; then break; fi
4070 for LASTTRACK in $TRACKQUEUE; do :; done
4071 if checkstatus readtrack-$LASTTRACK; then
4072 if [ "$DONORMALIZE" = "y" ] && [ "$BATCHNORM" = "y" ]; then
4073 if checkstatus normalizetrack-$LASTTRACK; then :; else do_batch_normalize; fi
4074 if checkerrors batch-normalize; then exit 1; fi
4075 fi
4076 if [ "$DOENCODE" = "y" ] && [ "$NOGAP" = "y" ]; then
4077 if [ "$DONORMALIZE" = "y" ]; then
4078 for UTRACKNUM in $TRACKQUEUE
4079 do
4080 if checkstatus readtrack-$UTRACKNUM; then
4081 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
4082 fi
4083 done
4084 fi
4085 if checkstatus encodetrack-$LASTTRACK; then :; else do_nogap_encode; fi
4086 if checkerrors nogap-encode; then exit 1; fi
4087 fi
4088 fi
4089 fi
4090
4091 # If we are using ONETRACK, we can proceed with the normal encoding using just the $FIRSTTRACK as TRACKQUEUE
4092 if [ "$ONETRACK" = "y" ] ; then
4093 TRACKQUEUE="$FIRSTTRACK"
4094 TRACKS="$FIRSTTRACK"
4095 fi
4096
4097 # Do the encoding, including parallelization of remote encoding
4098 # Figure out where each track is going to be encoded
4099 ENCODELOCATIONS="$(echo $REMOTEHOSTS | tr , ' ')"
4100 if [ "$MAXPROCS" != "0" ]; then
4101 for NUM in $(f_seq_row 1 "$MAXPROCS")
4102 do
4103 ENCODELOCATIONS="$ENCODELOCATIONS %local$NUM%"
4104 done
4105 fi
4106 # Strip whitespace
4107 ENCODELOCATIONS=$(echo $ENCODELOCATIONS)
4108 for UTRACKNUM in $TRACKQUEUE
4109 do
4110 # Wait for our cue
4111 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
4112 if [ "$GOAHEAD" = "NO" ]; then break; fi
4113 # find out where this track is to be encoded
4114 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
4115 # Make sure we have a place to encode this, if not, exit stage right
4116 if [ -z "$ENCODELOCATIONS" ]; then
4117 continue
4118 fi
4119 PROCEED=
4120 until [ $PROCEED ]
4121 do
4122 for LOCATION in $ENCODELOCATIONS
4123 do
4124 PREVIOUSTRACK="$(checkstatus encodetracklocation-$LOCATION)"
4125 # check first if a track has ever been assigned to this location
4126 if [ -z "$PREVIOUSTRACK" ]; then PROCEED=y; break; fi
4127 # If it errored out, rebuild $ENCODELOCATIONS without this location in it
4128 if checkerrors encodetrack-$PREVIOUSTRACK; then
4129 for TEMPLOCATION in $ENCODELOCATIONS
4130 do
4131 if [ "$TEMPLOCATION" != "$LOCATION" ]; then
4132 TEMPENCODELOCATIONS="$TEMPENCODELOCATIONS $TEMPLOCATION"
4133 fi
4134 done
4135 ENCODELOCATIONS=$(echo $TEMPENCODELOCATIONS)
4136 ABORT=y
4137 PROCEED=y
4138 break
4139 fi
4140 # We're still here, this location must have been previously assigned,
4141 # and last completed without error - check if it's done with the
4142 # previous track yet
4143 if checkstatus encodetrack-$PREVIOUSTRACK; then PROCEED=y; break; fi
4144 done
4145 # all locations are working, wait and try again later
4146 if [ ! $PROCEED ]; then sleep 3; fi
4147 done
4148 # Record the location we're about to encode the next track at
4149 echo "encodetracklocation-$LOCATION=$UTRACKNUM" >> "$ABCDETEMPDIR/status"
4150 fi
4151 # Don't proceed with the rest of the loop if we can't encode
4152 if [ "$ABORT" ]; then continue; fi
4153 ## FIXME ## Add here
4154 ## run_command tagtrack-$OUTPUT-$1 $METAFLAC $METAFLACOPTS ${IMPORTCUESHEET:+--import-cuesheet-from="$ABCDETEMPDIR/$CUEFILE"} --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
4155 # Set TRACKNUM, TRACKNAME
4156 if [ -e "$CDDBDATA" ]; then
4157 if [ "$ONETRACK" = "y" ]; then
4158 TRACKNAME="$DALBUM"
4159 TRACKNUM="$FIRSTTRACK"
4160 splitvarious
4161 else
4162 TRACKNUM=$UTRACKNUM
4163 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
4164 getcddbinfo TRACKNAME
4165 splitvarious
4166 fi
4167 fi
4168 # You can't encode a file which needs to be normalized before finishing
4169 # You can't tag a file before it's finished encoding -
4170 # thus all of this is backgrounded together
4171 (
4172 if [ "$DONORMALIZE" = "y" ]; then
4173 if checkstatus readtrack-$UTRACKNUM; then
4174 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
4175 fi
4176 fi
4177 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
4178 if checkstatus readtrack-$UTRACKNUM; then
4179 #if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION; fi
4180 if [ "$DONORMALIZE" = "y" ]; then
4181 if checkstatus normalizetrack-$UTRACKNUM; then
4182 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
4183 fi
4184 else
4185 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
4186 fi
4187 fi
4188 fi
4189 if [ "$DOTAG" = "y" ]; then
4190 if checkstatus encodetrack-$UTRACKNUM; then
4191 if checkstatus tagtrack-$UTRACKNUM; then :; else do_tag $UTRACKNUM; fi
4192 fi
4193 # Lets tag the cue file
4194 if checkstatus cleancuefile >/dev/null; then :; else
4195 if checkstatus cuefile >/dev/null ; then
4196 do_cleancue
4197 fi
4198 fi
4199 fi
4200 if [ "$DOMOVE" = "y" ]; then
4201 if checkstatus tagtrack-$UTRACKNUM; then
4202 if checkstatus movetrack-$UTRACKNUM; then :; else do_move $UTRACKNUM; fi
4203 fi
4204 fi
4205 ) &
4206 done
4207
4208
4209 # Go through it again and make sure there's no distmp3 stragglers, otherwise
4210 # we'll delete the files they're working on
4211 # Do NOT play ball if there is no ball to play (so ABORT if needed)
4212 ## FIXME ## Check also for files which are encoded using PIPEs.
4213 if [ "$DOENCODE" = "y" ] && [ "$USEPIPES" != "y" ] && [ ! "$ABORT" ]; then
4214 PROCEED=
4215 until [ $PROCEED ]
4216 do
4217 PROCEED=y
4218 for LOCATION in $ENCODELOCATIONS
4219 do
4220 CHECKTRACK="$(checkstatus encodetracklocation-$LOCATION)"
4221 # "How can he give us a status update, if he's DEAD?"
4222 if checkstatus encodetrack-$CHECKTRACK; then
4223 continue
4224 fi
4225 # Nothing to see here please go quietly back to your homes
4226 if [ -z "$CHECKTRACK" ]; then continue; fi
4227 # You're still here? Maybe there is something...
4228 if checkstatus encodetrack-$CHECKTRACK; then :; else PROCEED= ; break; fi
4229 done
4230 # hold up
4231 if [ ! $PROCEED ]; then sleep 5; fi
4232 done
4233 fi
4234 # If the above didn't catch the stragglers, this will
4235 wait
4236 if [ "$DOREPLAYGAIN" = "y" ]; then
4237 do_replaygain
4238 fi
4239
4240 # Execute the user-defined post_encode function before cleaning up
4241 post_encode
4242
4243 # Check to see if run_command logged any errors
4244 if [ -f "$ABCDETEMPDIR/errors" ]; then
4245 log error "The following commands failed to run:"
4246 cat "$ABCDETEMPDIR/errors"
4247 # Don't clean up
4248 DOCLEAN=n
4249 fi
4250 if [ "$KEEPWAVS" = "y" ];then
4251 # Don't clean up
4252 DOCLEAN=n
4253 fi
4254 # Check if we have moved all the formats we had previously encoded, if we are not using the FORCE.
4255 if [ "$DOCLEAN" = "y" ] && [ ! "$FORCE" = "y" ]; then
4256 ENCODED_FORMATS=$(egrep "^encodetrack-(.{3,6})-(.{1,2})$" "$ABCDETEMPDIR/status" | cut -d"-" -f2 | sort -u | tr '\n' '|')
4257 MOVED_FORMATS=$(egrep "^movetrack-output-(.{3,6})$" "$ABCDETEMPDIR/status" | cut -d"-" -f3 | sort -u | tr '\n' '|')
4258 if [ "$ENCODED_FORMATS" != "$MOVED_FORMATS" ]; then
4259 log warning "The encoded formats does not match with the moved ones"
4260 log warning "Formats encoded: $( echo $ENCODED_FORMATS | tr "|" " " )"
4261 log warning "Formats moved: $( echo $MOVED_FORMATS | tr "|" " " )"
4262 log warning "Use \"abcde -a clean -f -C $DISCID\" to force the removal of the remaining data."
4263 DOCLEAN=n
4264 fi
4265 fi
4266 if [ "$DOCLEAN" = "y" ]; then
4267 # Wipe all the evidence
4268 # Gimme gimme gimme some more time!
4269 sleep 5
4270 rm -rf "$ABCDETEMPDIR"
4271 echo "Finished."
4272 else
4273 echo "Finished. Not cleaning $ABCDETEMPDIR."
4274 fi
4275 )
4276 exit 0
4277
4278 # b:is_bash
4279 # vim:tabstop=4