Make new version 2.4.1 not 2.4.0.1
[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.0.1'
17
18 usage ()
19 {
20 echo "This is abcde v$VERSION."
21 echo "Usage: abcde [options] [tracks]"
22 echo "Options:"
23 echo "-1 Encode the whole CD in a single file"
24 echo "-a <action1[,action2]...>"
25 echo " Actions to perform:"
26 echo " cddb,read,normalize,encode,tag,move,replaygain,playlist,clean"
27 #echo "-A Experimental actions (retag, transcode)"
28 echo "-b Enable batch normalization"
29 #echo "-B Disable batch replaygain (do file by file)"
30 echo "-c <file>"
31 echo " Specify a configuration file (overrides system and user config files)"
32 echo "-C <discid#>"
33 echo " Specify discid to resume from (only needed if you no longer have the cd)"
34 echo "-d <device>"
35 echo " Specify CDROM device to grab (flac uses a single-track flac file)"
36 echo "-D Debugging mode (equivalent to sh -x abcde)"
37 echo "-e Erase encoded track information from status file"
38 echo "-f Force operations that otherwise are considered harmful. Read \"man abcde\""
39 echo "-g Use \"lame --nogap\" for MP3 encoding. Disables low disk and pipes flags"
40 echo "-h This help information"
41 #echo "-i Tag files while encoding, when possible (local only) -NWY-"
42 echo "-j <#> Number of encoder processes to run at once (localhost)"
43 echo "-k Keep the wav tracks for later use"
44 echo "-l Use low disk space algorithm"
45 echo "-L Use local CDDB storage directory"
46 echo "-n No lookup. Don't query CDDB, just create and use template"
47 echo "-N Noninteractive. Never prompt for anything"
48 echo "-m Modify playlist to include CRLF endings, to comply with some players"
49 echo " WARNING: Deprecated. Use \"cue\" action"
50 #echo "-M Create a CUE file"
51 echo "-o <type1[,type2]...>"
52 echo " Output file type(s) (vorbis,mp3,flac,spx,mpc,wav,m4a). Defaults to vorbis"
53 echo "-p Pad track numbers with 0's (if less than 10 tracks)"
54 echo "-P Use UNIX pipes to read+encode without wav files"
55 echo "-q <level>"
56 echo " Set quality level (high,medium,low)"
57 echo "-r <host1[,host2]...>"
58 echo " Also encode on these remote hosts"
59 echo "-R Use local CDDB in recursive mode"
60 echo "-s <field>"
61 echo " Show fields from the CDDB info (year,genre)"
62 echo "-S <#> Set the CD speed"
63 echo "-t <#> Start the track numbering at a given number"
64 echo "-T <#> Same as -t but modifies tag numbering"
65 echo "-U Do NOT use UNICODE (UTF8) tags and comments"
66 echo "-v Show version number and exit"
67 echo "-V Be a bit more verbose about what is happening behind the scenes"
68 echo "-x Eject CD after all tracks are read"
69 echo "-w <comment>"
70 echo " Add a comment to the CD tracks"
71 echo "-W <#> Concatenate CDs: -T #01 -w \"CD #\""
72 echo "-z Use debug CDROMREADERSYNTAX option (needs cdparanoia)"
73 echo ""
74 echo "Tracks is a space-delimited list of tracks to grab."
75 echo "Ranges specified with hyphens are allowed (i.e., 1-5)."
76 echo ""
77 #echo "Double hyphens are used to concatenate tracks"
78 }
79
80 addstatus ()
81 {
82 echo "$@" >> "$ABCDETEMPDIR/status"
83 }
84
85 # log [level] [message]
86 #
87 # log outputs the right message in a common format
88 log ()
89 {
90 BLURB="$1"
91 shift
92 case $BLURB in
93 error) echo "[ERROR] abcde: $@" >&2 ;;
94 warning) echo "[WARNING] $@" >&2 ;;
95 info) echo "[INFO] $@" ;;
96 esac
97 }
98
99 # Funtions to replace the need of seq, which is too distribution dependant.
100 f_seq_row ()
101 {
102 i=$1
103 while [ $i -ne `expr $2 + 1` ]
104 do
105 echo $i
106 i=`expr $i + 1`
107 done
108 }
109
110 f_seq_line ()
111 {
112 i=$1
113 if echo $i | grep "[[:digit:]]" > /dev/null 2>&1 ; then
114 while [ $i -ne `expr $2 + 1` ]
115 do
116 printf $i" "
117 i=`expr $i + 1`
118 done
119 echo
120 else
121 log error "syntax error while processing track numbers"
122 exit 1
123 fi
124 }
125
126 # Functions to replace the need of awk {print $1} and {print $NF}
127 get_first()
128 {
129 if [ X"$1" = "X" ]; then
130 for first in `cat`; do
131 break
132 done
133 else
134 first=$1
135 fi
136 echo $first
137 }
138
139 get_last()
140 {
141 if [ X"$1" = "X" ]; then
142 for stdin in `cat`; do
143 last=$stdin
144 done
145 else
146 for last in $@ ; do :; done
147 fi
148 echo $last
149 }
150
151 # checkstatus [blurb]
152 # Returns "0" if the blurb was found, returns 1 if it wasn't
153 # Puts the blurb content, if available, on stdout.
154 # Otherwise, returns "".
155 checkstatus ()
156 {
157 # Take the last line in the status file if there's multiple matches
158 PATTERN="^$1(=.*)?$"
159 BLURB=$(egrep $PATTERN "$ABCDETEMPDIR/status" | tail -n 1)
160
161 if [ -z "$BLURB" ]; then
162 # No matches found
163 return 1
164 else
165 # Matches found
166 # See if there's a = in it
167 if [ "$(echo $BLURB | grep -c =)" != "0" ]; then
168 echo "$(echo $BLURB | cut -f2- -d=)"
169 fi
170 return 0
171 fi
172 }
173
174 # checkwarnings [blurb]
175 # Returns "0" if the blurb was found (meaning there was an warning),
176 # returns 1 if it wasn't (yes this is a little backwards).
177 # Does not print the blurb on stdout.
178 # Otherwise, returns "".
179 checkwarnings ()
180 {
181 if [ -e "$ABCDETEMPDIR/warnings" ]; then :; else
182 return 1
183 fi
184 # Take the last line in the status file if there's multiple matches
185 PATTERN="^$1(:.*)?$"
186 BLURB="$(egrep $PATTERN "$ABCDETEMPDIR/warnings" | tail -n 1)"
187
188 if [ -z "$BLURB" ]; then
189 # negative, we did not have a negative...
190 return 1
191 else
192 # affirmative, we had a negative...
193 return 0
194 fi
195 }
196
197 # checkerrors [blurb]
198 # Returns "0" if the blurb was found (meaning there was an error),
199 # returns 1 if it wasn't (yes this is a little backwards).
200 # Does not print the blurb on stdout.
201 # Otherwise, returns "".
202 checkerrors ()
203 {
204 if [ -e "$ABCDETEMPDIR/errors" ]; then :; else
205 return 1
206 fi
207 # Take the last line in the status file if there's multiple matches
208 PATTERN="^$1(:.*)?$"
209 BLURB="$(egrep $PATTERN "$ABCDETEMPDIR/errors" | tail -n 1)"
210
211 if [ -z "$BLURB" ]; then
212 # negative, we did not have a negative...
213 return 1
214 else
215 # affirmative, we had a negative...
216 return 0
217 fi
218 }
219
220 # page [file]
221 # Finds the right pager in the system to display a file
222 page ()
223 {
224 PAGEFILE="$1"
225 # Use the debian sensible-pager wrapper to pick the pager
226 # user has requested via their $PAGER environment variable
227 if [ -x "/usr/bin/sensible-pager" ]; then
228 /usr/bin/sensible-pager "$PAGEFILE"
229 elif [ -x "$PAGER" ]; then
230 # That failed, try to load the preferred editor, starting
231 # with their PAGER variable
232 $PAGER "$PAGEFILE"
233 # If that fails, check for less
234 elif [ -x /usr/bin/less ]; then
235 /usr/bin/less -f "$PAGEFILE"
236 # more should be on all UNIX systems
237 elif [ -x /bin/more ]; then
238 /bin/more "$PAGEFILE"
239 else
240 # No bananas, just cat the thing
241 cat "$PAGEFILE" >&2
242 fi
243 }
244
245 # run_command [blurb] [command...]
246 # Runs a command, silently if necessary, and updates the status file
247 run_command ()
248 {
249 BLURB="$1"
250 shift
251 # See if this is supposed to be silent
252 if [ "$(checkstatus encode-output)" = "loud" ]; then
253 "$@" >&2
254 RETURN=$?
255 else
256 # Special case for SMP, since
257 # encoder output is never displayed, don't mute echos
258 if [ -z "$BLURB" -a "$MAXPROCS" != "1" ]; then
259 "$@" >&2
260 RETURN=$?
261 else
262 "$@" >/dev/null 2>&1
263 RETURN=$?
264 fi
265 fi
266 case "$1" in
267 normalize|normalize-audio)
268 if [ "$RETURN" = "2" ]; then
269 # File was already normalized.
270 RETURN=0
271 fi
272 ;;
273 esac
274 if [ "$RETURN" != "0" ]; then
275 # Put an error in the errors file. For various reasons we
276 # can't capture a copy of the program's output but we can
277 # log what we attempted to execute and the error code
278 # returned by the program.
279 if [ "$BLURB" ]; then
280 TWEAK="$BLURB: "
281 fi
282 echo "${TWEAK}returned code $RETURN: $@" >> "$ABCDETEMPDIR/errors"
283 return $RETURN # Do not pass go, do not update the status file
284 fi
285 if [ "$BLURB" ]; then
286 echo $BLURB >> "$ABCDETEMPDIR/status"
287 fi
288 }
289
290 # relpath() and slash() are Copyright (c) 1999 Stuart Ballard and
291 # distributed under the terms of the GNU GPL v2 or later, at your option
292
293 # Function to determine if a word contains a slash.
294 slash ()
295 {
296 case "$1" in
297 */*) return 0;;
298 *) return 1;;
299 esac
300 }
301
302 # Function to give the relative path from one file to another.
303 # Usage: relpath fromfile tofile
304 # eg relpath music/Artist/Album.m3u music/Artist/Album/Song.mp3
305 # (the result would be Album/Song.mp3)
306 # Output is relative path to $2 from $1 on stdout
307
308 # This code has the following restrictions:
309 # Multiple ////s are not collapsed into single /s, with strange effects.
310 # Absolute paths and ../s are handled wrong in FR (but they work in TO)
311 # If FR is a directory it must have a trailing /
312
313 relpath ()
314 {
315 FR="$1"
316 TO="$2"
317
318 case "$TO" in
319 /*) ;; # No processing is needed for absolute paths
320 *)
321 # Loop through common prefixes, ignoring them.
322 while slash "$FR" && [ "$(echo "$FR" | cut -d/ -f1)" = "$(echo "$TO" | cut -d/ -f1)" ]
323 do
324 FR="$(echo "$FR" | cut -d/ -f2-)"
325 TO="$(echo "$TO" | cut -d/ -f2-)"
326 done
327 # Loop through directory portions left in FR, adding appropriate ../s.
328 while slash "$FR"
329 do
330 FR="$(echo "$FR" | cut -d/ -f2-)"
331 TO="../$TO"
332 done
333 ;;
334 esac
335
336 echo $TO
337 }
338
339 new_checkexec ()
340 {
341 if [ ! "$@" = "" ]; then
342 # Cut off any command-line option we added in
343 X=$(echo $@ | cut -d' ' -f2)
344 if [ "$(which $X)" = "" ]; then
345 return 1
346 elif [ ! -x $(which $X) ]; then
347 return 2
348 fi
349 fi
350 return 0
351 }
352
353 checkexec ()
354 {
355 if [ ! "$@" = "" ]; then
356 # Cut off any command-line option we added in
357 X=$(echo $@ | cut -d' ' -f2)
358 # Test for built-in abcde.function
359 [ "$X" != "${X#abcde.}" ] && type $X >/dev/null 2>&1 && return
360 if [ "$(which $X)" = "" ]; then
361 log error "$X is not in your path." >&2
362 log info "Define the full path to the executable if it exists on your system." >&2
363 if [ -e /etc/debian_release ] ; then
364 case $X in
365 oggenc) MISSING_PACKAGE=vorbis-tools ;;
366 lame|flac) MISSING_PACKAGE=$X ;;
367 esac
368 log info "Hint: apt-get install $MISSING_PACKAGE" >&2
369 fi
370 exit 1
371 elif [ ! -x "$(which $X)" ]; then
372 log error "$X is not executable." >&2
373 exit 1
374 fi
375 fi
376 }
377
378 # diffentries <filename> <max_value> <entry1>,<entry2>
379 # max_value: the range of entries goes from 1 to <max_value>
380 diffentries ()
381 {
382 FILENAME=$1
383 shift
384 local CDDBDIFFCHOICES=$1
385 shift
386 local CDDBDIFFCHOICE="$@"
387 if [ ! X"$DIFF" = "X" ]; then
388 PARSECHOICE1=$(echo $CDDBDIFFCHOICE | cut -d"," -f1 | xargs printf %d 2>/dev/null)
389 PARSECHOICE2=$(echo $CDDBDIFFCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null)
390 if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBDIFFCHOICES ] || \
391 [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBDIFFCHOICES ] || \
392 [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then
393 echo "Invalid diff range. Please select two comma-separated numbers between 1 and $CDDBDIFFCHOICES" >&2
394 else
395 # We parse the 2 choices to diff, store them in temporary files and diff them.
396 for PARSECHOICE in $(echo $CDDBDIFFCHOICE | tr , \ ); do
397 do_cddbparse "$ABCDETEMPDIR/$FILENAME.$PARSECHOICE" > "$ABCDETEMPDIR/$FILENAME.parsechoice.$PARSECHOICE"
398 done
399 echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..." > "$ABCDETEMPDIR/$FILENAME.diff"
400 $DIFF $DIFFOPTS "$ABCDETEMPDIR/$FILENAME.parsechoice.$PARSECHOICE1" "$ABCDETEMPDIR/$FILENAME.parsechoice.$PARSECHOICE2" >> "$ABCDETEMPDIR/$FILENAME.diff"
401 if [ $(cat "$ABCDETEMPDIR/$FILENAME.diff" | wc -l) -ge 24 ]; then
402 page "$ABCDETEMPDIR/$FILENAME.diff"
403 else
404 cat "$ABCDETEMPDIR/$FILENAME.diff" >&2
405 fi
406 fi
407 else
408 echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBDIFFCHOICES." >&2
409 fi
410 }
411
412 # getcddbinfo
413 # Finds an specific field from cddbinfo
414 getcddbinfo()
415 {
416 case $1 in
417 TRACKNAME1)
418 TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
419 ;;
420 TRACKNAME)
421 TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
422 ;;
423 TRACK-INFO)
424 grep ^EXTT$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | 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 replaygain information..."
500 for TMPOUTPUT in $( echo $OUTPUTTYPE | tr , \ )
501 do
502 case $TMPOUTPUT in
503 vorbis|ogg)
504 OUTPUT=$OGGOUTPUTCONTAINER
505 ;;
506 flac)
507 OUTPUT=$FLACOUTPUTCONTAINER
508 ;;
509 *)
510 OUTPUT=$TMPOUTPUT
511 ;;
512 esac
513 OUTPUTFILES=""
514 REPLAYINDEX=0
515 for UTRACKNUM in $TRACKQUEUE
516 do
517 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
518 getcddbinfo TRACKNAME
519 splitvarious
520 TRACKFILE="$(mungefilename "$TRACKNAME")"
521 ARTISTFILE="$(mungefilename "$TRACKARTIST")"
522 ALBUMFILE="$(mungefilename "$DALBUM")"
523 GENRE="$(mungegenre "$GENRE")"
524 YEAR=${CDYEAR:-$CDYEAR}
525 gettracknum
526 if [ "$ONETRACK" = "y" ]; then
527 if [ "$VARIOUSARTISTS" = "y" ]; then
528 OUTPUTFILE="$(eval echo \""$VAONETRACKOUTPUTFORMAT"\")"
529 else
530 OUTPUTFILE="$(eval echo \""$ONETRACKOUTPUTFORMAT"\")"
531 fi
532 else
533 if [ "$VARIOUSARTISTS" = "y" ]; then
534 OUTPUTFILE="$(eval echo \""$VAOUTPUTFORMAT"\")"
535 else
536 OUTPUTFILE="$(eval echo \""$OUTPUTFORMAT"\")"
537 fi
538 fi
539 OUTPUTFILES[$REPLAYINDEX]="$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
540 (( REPLAYINDEX = $REPLAYINDEX + 1 ))
541 done
542 case "$OUTPUT" in
543 flac)
544 run_command replaygain-flac nice $ENCNICE $METAFLAC $FLACGAINOPTS "${OUTPUTFILES[@]}"
545 #run_command replaygain-flac true
546 ;;
547 vorbis|ogg)
548 run_command replaygain-vorbis nice $ENCNICE $VORBISGAIN $VORBISGAINOPTS "${OUTPUTFILES[@]}"
549 ;;
550 mp3)
551 run_command replaygain-mp3 nice $ENCNICE $MP3GAIN $MP3GAINOPTS "${OUTPUTFILES[@]}"
552 ;;
553 mpc)
554 run_command replaygain-mpc nice $ENCNICE $MPPGAIN --auto "${OUTPUTFILES[@]}"
555 ;;
556 *);;
557 esac
558 done
559 if checkerrors "replaygain-.{3,6}"; then :; else
560 run_command replaygain true
561 fi
562 fi
563 }
564
565 # This code splits the a Various Artist track name from one of the following
566 # forms:
567 #
568 # forward: Artist / Track
569 # forward-dash: Artist - Track
570 # reverse: Track / Artist
571 # reverse-dash: Track - Artist
572 # colon: Artist: Track
573 # trailing-paren: Artist (Track)
574 #
575 # variables used:
576 # VARIOUSARTISTS, VARIOUSARTISTSTYLE, TRACKNAME, TRACKARTIST
577 splitvarious ()
578 {
579 if [ "$VARIOUSARTISTS" = "y" ] && [ ! "$ONETRACK" = "y" ]; then
580 case "$VARIOUSARTISTSTYLE" in
581 forward)
582 DTITLEARTIST="$(echo "$TRACKNAME" | sed 's- / -~-g')"
583 TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
584 TRACKNAME="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
585 ;;
586 forward-dash)
587 DTITLEARTIST="$(echo "$TRACKNAME" | sed 's, - ,~,g')"
588 TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
589 TRACKNAME="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
590 ;;
591 reverse)
592 DTITLEARTIST="$(echo "$TRACKNAME" | sed 's- / -~-g')"
593 TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
594 TRACKNAME="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
595 ;;
596 reverse-dash)
597 DTITLEARTIST="$(echo "$TRACKNAME" | sed 's, - ,~,g')"
598 TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
599 TRACKNAME="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
600 ;;
601 colon)
602 DTITLEARTIST="$(echo "$TRACKNAME" | sed 's-: -~-g')"
603 TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
604 TRACKNAME="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
605 ;;
606 trailing-paren)
607 DTITLEARTIST="$(echo "$TRACKNAME" | sed 's,^\(.*\) (\(.*\)),\1~\2,')"
608 TRACKARTIST="$(echo "$DTITLEARTIST" | cut -f2 -d~)"
609 TRACKNAME="$(echo "$DTITLEARTIST" | cut -f1 -d~)"
610 ;;
611 esac
612 elif [ "$VARIOUSARTISTS" = "y" ] && [ "$ONETRACK" = "y" ]; then
613 TRACKARTIST="Various"
614 else
615 TRACKARTIST="$DARTIST"
616 fi
617 }
618
619 do_getgenreid () {
620 local genre=$(echo "${@}" | tr '[A-Z]' '[a-z]')
621 local id=""
622 case ${genre} in
623 "blues") id=0 ;;
624 "classic rock") id=1 ;;
625 "country") id=2 ;;
626 "dance") id=3 ;;
627 "disco") id=4 ;;
628 "funk") id=5 ;;
629 "grunge") id=6 ;;
630 "hip-hop") id=7 ;;
631 "jazz") id=8 ;;
632 "metal") id=9 ;;
633 "new age") id=10 ;;
634 "oldies") id=11 ;;
635 "other") id=12 ;;
636 "pop") id=13 ;;
637 "r&b") id=14 ;;
638 "rap") id=15 ;;
639 "reggae") id=16 ;;
640 "rock") id=17 ;;
641 "techno") id=18 ;;
642 "industrial") id=19 ;;
643 "alternative") id=20 ;;
644 "ska") id=21 ;;
645 "death metal") id=22 ;;
646 "pranks") id=23 ;;
647 "soundtrack") id=24 ;;
648 "euro-techno") id=25 ;;
649 "ambient") id=26 ;;
650 "trip-hop") id=27 ;;
651 "vocal") id=28 ;;
652 "jazz+funk") id=29 ;;
653 "fusion") id=30 ;;
654 "trance") id=31 ;;
655 "classical") id=32 ;;
656 "instrumental") id=33 ;;
657 "acid") id=34 ;;
658 "house") id=35 ;;
659 "game") id=36 ;;
660 "sound clip") id=37 ;;
661 "gospel") id=38 ;;
662 "noise") id=39 ;;
663 "alt. rock") id=40 ;;
664 "bass") id=41 ;;
665 "soul") id=42 ;;
666 "punk") id=43 ;;
667 "space") id=44 ;;
668 "meditative") id=45 ;;
669 "instrum. pop") id=46 ;;
670 "instrum. rock") id=47 ;;
671 "ethnic") id=48 ;;
672 "gothic") id=49 ;;
673 "darkwave") id=50 ;;
674 "techno-indust.") id=51 ;;
675 "electronic") id=52 ;;
676 "pop-folk") id=53 ;;
677 "eurodance") id=54 ;;
678 "dream") id=55 ;;
679 "southern rock") id=56 ;;
680 "comedy") id=57 ;;
681 "cult") id=58 ;;
682 "gangsta") id=59 ;;
683 "top 40") id=60 ;;
684 "christian rap") id=61 ;;
685 "pop/funk"|"pop / funk") id=62 ;;
686 "jungle") id=63 ;;
687 "native american") id=64 ;;
688 "cabaret") id=65 ;;
689 "new wave") id=66 ;;
690 "psychadelic") id=67 ;;
691 "rave") id=68 ;;
692 "showtunes") id=69 ;;
693 "trailer") id=70 ;;
694 "lo-fi") id=71 ;;
695 "tribal") id=72 ;;
696 "acid punk") id=73 ;;
697 "acid jazz") id=74 ;;
698 "polka") id=75 ;;
699 "retro") id=76 ;;
700 "musical") id=77 ;;
701 "rock & roll") id=78 ;;
702 "hard rock") id=79 ;;
703 "folk") id=80 ;;
704 "folk/rock") id=81 ;;
705 "national folk") id=82 ;;
706 "swing") id=83 ;;
707 "fusion") id=84 ;;
708 "bebob") id=85 ;;
709 "latin") id=86 ;;
710 "revival") id=87 ;;
711 "celtic") id=88 ;;
712 "bluegrass") id=89 ;;
713 "avantgarde") id=90 ;;
714 "gothic rock") id=91 ;;
715 "progress. rock") id=92 ;;
716 "psychadel. rock") id=93 ;;
717 "symphonic rock") id=94 ;;
718 "slow rock") id=95 ;;
719 "big band") id=96 ;;
720 "chorus") id=97 ;;
721 "easy listening") id=98 ;;
722 "acoustic") id=99 ;;
723 "humour") id=100 ;;
724 "speech") id=101 ;;
725 "chanson") id=102 ;;
726 "opera") id=103 ;;
727 "chamber music") id=104 ;;
728 "sonata") id=105 ;;
729 "symphony") id=106 ;;
730 "booty bass") id=107 ;;
731 "primus") id=108 ;;
732 "porn groove") id=109 ;;
733 "satire") id=110 ;;
734 "slow jam") id=111 ;;
735 "club") id=112 ;;
736 "tango") id=113 ;;
737 "samba") id=114 ;;
738 "folklore") id=115 ;;
739 "ballad") id=116 ;;
740 "power ballad") id=117 ;;
741 "rhythmic soul") id=118 ;;
742 "freestyle") id=119 ;;
743 "duet") id=120 ;;
744 "punk rock") id=121 ;;
745 "drum solo") id=122 ;;
746 "a capella") id=123 ;;
747 "euro-house") id=124 ;;
748 "dance hall") id=125 ;;
749 "goa") id=126 ;;
750 "drum & bass") id=127 ;;
751 "club-house") id=128 ;;
752 "hardcore") id=129 ;;
753 "terror") id=130 ;;
754 "indie") id=131 ;;
755 "britpop") id=132 ;;
756 "negerpunk") id=133 ;;
757 "polsk punk") id=134 ;;
758 "beat") id=135 ;;
759 "christian gangsta rap") id=136 ;;
760 "heavy metal") id=137 ;;
761 "black metal") id=138 ;;
762 "crossover") id=139 ;;
763 "contemporary christian")id=140 ;;
764 "christian rock") id=141 ;;
765 "merengue") id=142 ;;
766 "salsa") id=143 ;;
767 "thrash metal") id=144 ;;
768 "anime") id=145 ;;
769 "jpop") id=146 ;;
770 "synthpop") id=147 ;;
771 "rock/pop"|"rock / pop") id=148 ;;
772 *) return 1 ;;
773 esac
774 echo ${id}
775 return 0
776 }
777
778 # do_tag [tracknumber]
779 # id3 tags a filename
780 # variables used:
781 # TRACKS, TRACKNAME, TRACKARTIST, TAGGER, TAGGEROPTS, VORBISCOMMENT, METAFLAC, ATOMICPARSLEY
782 # COMMENT, DALBUM, DARTIST, CDYEAR, CDGENRE (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 "$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/icedax
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 | icedax) 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 | icedax)
2782 if [ "$OSFLAVOUR" = "OSX" ] ; then
2783 # Hei, we have to unmount the device before running anything like cdda2wav/icedax in OSX
2784 disktool -u ${CDROM#/dev/} 0
2785 # Also, in OSX the cdrom device for cdda2wav/icedax 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/icedax 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=icedax
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 MP3GAINOPTS="-a -k"
3058 # ogg
3059 VORBIZEOPTS=
3060 OGGENCOPTS=
3061 VORBISGAINOPTS="--album"
3062 # flac
3063 FLACOPTS=
3064 FLACGAINOPTS="--add-replay-gain"
3065 # speex
3066 SPEEXENCOPTS=
3067 # mpc
3068 MPPENCOPTS=
3069 # m4a
3070 AACENCOPTS=
3071
3072 ID3OPTS=
3073 ID3V2OPTS=
3074 CDPARANOIAOPTS=
3075 CDDA2WAVOPTS=
3076 DAGRABOPTS=
3077 CDDAFSOPTS="-f"
3078 CDDBTOOLOPTS=
3079 EJECTOPTS=
3080 DISTMP3OPTS=
3081 NORMALIZEOPTS=
3082 CDSPEEDOPTS="-x"
3083 CDSPEEDVALUE=
3084 MKCUEOPTS=
3085 MKTOCOPTS=""
3086 VORBISCOMMENTOPTS="-R"
3087 METAFLACOPTS="--no-utf8-convert"
3088 DIFFOPTS=
3089
3090 # Default to one process if -j isn't specified
3091 MAXPROCS=1
3092
3093 # List of actions to perform - by default, run to completion
3094 ACTIONS=cddb,read,encode,tag,move,clean
3095
3096 # This option is basicaly for Debian package dependencies:
3097 # List of prefered outputs - by default, run with whatever we have in the path
3098 DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:toolame,mp3:lame,mp3:bladeenc,spx:speex,m4a:faac
3099
3100 # List of prefered cdromreaders - by default, run whichever we have in the path
3101 DEFAULT_CDROMREADERS="cdparanoia icedax cdda2wav"
3102
3103 # List of quality levels associated with the encoders:
3104 DEFAULT_QUALITY_XLO="oggenc:-q -1,lame:-q 9,speex:--quality 1,m4a:"
3105 DEFAULT_QUALITY_LO="oggenc:-q 1,lame:-q 7,speex:--quality 5,m4a:"
3106 DEFAULT_QUALITY_HI="oggenc:-q 7,lame:--preset standard,speex:--quality 9,m4a:"
3107 DEFAULT_QUALITY_XHI="oggenc:-q 10,lame:--preset extreme,speex:--quality 10,m4a:"
3108
3109 # Asume fetch if under FreeBSD. curl is used for Mac OS X. wget is used for
3110 # Linux/OpenBSD. ftp is user for NetBSD.
3111 # Let's use these checkings to determine the OS flavour, which will be used
3112 # later
3113 if [ X$(uname) = "XFreeBSD" ] ; then
3114 HTTPGET=fetch
3115 MD5SUM=md5
3116 NEEDCDROMID=y
3117 OSFLAVOUR=FBSD
3118 elif [ X$(uname) = "XDarwin" ] ; then
3119 HTTPGET=curl
3120 OSFLAVOUR=OSX
3121 # We should have disktool in OSX, but let's be sure...
3122 NEEDDISKTOOL=y
3123 CDROMREADERSYNTAX=cddafs
3124 elif [ X$(uname) = "XOpenBSD" ] ; then
3125 HTTPGET=wget
3126 MD5SUM=md5
3127 OSFLAVOUR=OBSD
3128 elif [ X$(uname) = "XNetBSD" ] ; then
3129 HTTPGET=ftp
3130 MD5SUM=md5
3131 OSFLAVOUR=NBSD
3132 elif [ X$(uname) = "SunOS" ] ; then
3133 HTTPGET=""
3134 MD5SUM=md5
3135 OSFLAVOUR=SunOS
3136 else
3137 HTTPGET=wget
3138 fi
3139
3140 # If CDDBAVAIL is set to n, no CDDB read is done
3141 # If USEID3 is set to n, no ID3 tagging is done
3142 CDDBAVAIL=y
3143 USEID3=y
3144 USEID3V2=y
3145
3146 # There we go..
3147 # But before we get into business, let us chop off any GREP environmental
3148 # variables.
3149 GREP_OPTIONS=""
3150 GREP_COLOR=""
3151
3152 if [ -z "$OUTPUTDIR" ]; then
3153 OUTPUTDIR=$(pwd)
3154 fi
3155
3156 if [ -z "$WAVOUTPUTDIR" ]; then
3157 WAVOUTPUTDIR="$OUTPUTDIR"
3158 fi
3159
3160 # Load system defaults
3161 if [ -r /etc/abcde.conf ]; then
3162 . /etc/abcde.conf
3163 fi
3164 # Load user preference defaults
3165 if [ -r $HOME/.abcde.conf ]; then
3166 . $HOME/.abcde.conf
3167 fi
3168
3169 # By this time, we need some HTTPGETOPTS already defined.
3170 # If the user has defined a non-default HTTPGET method, we should not be empty.
3171
3172 if [ "$HTTPGETOPTS" = "" ] ; then
3173 case $HTTPGET in
3174 wget) HTTPGETOPTS="-q -nv -e timestamping=off -O -";;
3175 curl) HTTPGETOPTS="-f -s";;
3176 fetch)HTTPGETOPTS="-q -o -";;
3177 ftp) HTTPGETOPTS="-a -V -o - ";;
3178 *) log warning "HTTPGET in non-standard and HTTPGETOPTS are not defined." ;;
3179 esac
3180 fi
3181
3182 # If the CDROM has not been set yet, find a suitable one.
3183 # If this is a devfs system, default to /dev/cdroms/cdrom0
3184 # instead of /dev/cdrom
3185 if [ "$CDROM" = "" ] ; then
3186 if [ -e /dev/cdroms/cdrom0 ]; then
3187 CDROM=/dev/cdroms/cdrom0
3188 elif [ -e /dev/cdrom ]; then
3189 CDROM=/dev/cdrom
3190 elif [ -e /dev/cd0c ]; then
3191 CDROM=/dev/cd0c
3192 elif [ -e /dev/acd0c ]; then
3193 CDROM=/dev/acd0c
3194 elif [ -e /dev/disk1 ]; then
3195 CDROM=/dev/disk1
3196 fi
3197 fi
3198
3199 # Parse command line options
3200 #while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPq:r:Rs:S:t:T:vVxw:W: opt ; do
3201 while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:UvVxX:w:W:z opt ; do
3202 case "$opt" in
3203 1) ONETRACK=y ;;
3204 a) ACTIONS="$OPTARG" ;;
3205 A) EXPACTIONS="$OPTARG" ;;
3206 b) BATCHNORM=y ;;
3207 B) NOBATCHREPLAYGAIN=y ;;
3208 c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else log error "config file \"$OPTARG\" cannot be found." ; exit 1 ; fi ;;
3209 C) DISCID="$( echo ${OPTARG#abcde.} | tr -d /)" ;;
3210 d) CDROM="$OPTARG" ;;
3211 D) set -x ;;
3212 h) usage; exit ;;
3213 e) ERASEENCODEDSTATUS=y ;;
3214 E) ENCODING="$OPTARG" ;;
3215 f) FORCE=y ;;
3216 g) NOGAP=y ;;
3217 i) INLINETAG=y ;;
3218 j) MAXPROCS="$OPTARG" ;;
3219 k) KEEPWAVS=y ;;
3220 l) LOWDISK=y ;;
3221 L) CDDBUSELOCAL=y ;;
3222 n) CDDBAVAIL=n ;;
3223 N) INTERACTIVE=n ;;
3224 m) DOSPLAYLIST=y ;;
3225 M) DOCUE=y ;;
3226 o) OUTPUTTYPE="$OPTARG" ;;
3227 p) PADTRACKS=y ;;
3228 P) USEPIPES=y ;;
3229 q) QUALITYLEVEL="$OPTARG" ;;
3230 r) REMOTEHOSTS="$OPTARG" ;;
3231 R) CDDBLOCALRECURSIVE=y ;;
3232 s) SHOWCDDBFIELDS="$OPTARG" ;;
3233 S) CDSPEEDVALUE="$OPTARG" ;;
3234 t) STARTTRACKNUMBER="$OPTARG" ;;
3235 T) STARTTRACKNUMBER="$OPTARG" ; STARTTRACKNUMBERTAG="y" ;;
3236 U) CDDBPROTO=5 ;;
3237 v)
3238 echo "This is abcde v$VERSION."
3239 echo "Usage: abcde [options] [tracks]"
3240 echo "abcde -h for extra help"
3241 exit
3242 ;;
3243 V) EXTRAVERBOSE="y" ;;
3244 x) EJECTCD="y" ;;
3245 X) CUE2DISCID="$OPTARG" ;;
3246 w) COMMENT="$OPTARG" ;;
3247 W) if echo $OPTARG | grep "[[:digit:]]" > /dev/null 2>&1 ; then
3248 STARTTRACKNUMBER="${OPTARG}01"
3249 STARTTRACKNUMBERTAG="y"
3250 COMMENT="CD${OPTARG}"
3251 DISCNUMBER="${OPTARG}"
3252 else
3253 log error "argument of -W must be integer"
3254 exit 1
3255 fi
3256 ;;
3257 z) DEBUG=y ; CDROMREADERSYNTAX=debug ; EJECTCD="n" ;;
3258 ?) usage; exit ;;
3259 esac
3260 done
3261
3262 shift $(($OPTIND - 1))
3263
3264 # Here it comes the worse part of the whole thing. From here until we start
3265 # ripping, we have a mixture of sanity checks, verifications, default settigs
3266 # and other crazy stuff that interdepends, but hey, someone has to do it.
3267
3268 # If NOCDDBQUERY is set, don't query the CDDB server.
3269 if [ "$NOCDDBQUERY" = "y" ]; then
3270 CDDBAVAIL="n"
3271 fi
3272
3273 # If the user specified a flac file, then switch to special flac mode
3274 if echo "$CDROM" | grep -i '.flac$' > /dev/null 2>&1 ; then
3275 if [ ! -f "$CDROM" ]; then
3276 log error "the defined file for FLAC ripping cannot be found" >&2
3277 exit 1
3278 fi
3279 vecho warning "switching to flac CDROMREADERSYNTAX..."
3280 CDROMREADERSYNTAX=flac
3281 # We have a builtin version of cue2discid...
3282 case "$CUE2DISCID" in
3283 builtin);;
3284 *) NEEDCUE2DISCID=y;;
3285 esac
3286 NEEDMETAFLAC=y
3287 EJECTCD=n
3288 fi
3289
3290 # If the user provided a DISCID, disable eject
3291 if [ -n "$DISCID" ] || [ "$CDROMREADERSYNTAX" = "flac" ]; then EJECTCD=n ; fi
3292
3293 # Check the available cd rippers in the system, from the ones we know.
3294 if [ "$CDROMREADERSYNTAX" = "" ]; then
3295 for DEFAULT_CDROMREADER in $DEFAULT_CDROMREADERS; do
3296 if new_checkexec $DEFAULT_CDROMREADER; then
3297 CDROMREADERSYNTAX=$DEFAULT_CDROMREADER
3298 break
3299 fi
3300 done
3301 if [ "$CDROMREADERSYNTAX" = "" ]; then
3302 log error "no cdreader found in your PATH"
3303 log error "hints: are all dependencies installed? has the \$PATH been modified?"
3304 exit 1
3305 fi
3306 fi
3307
3308 # Decide if we can continue.
3309 if [ "$ONETRACK" = "y" ]; then
3310 # FIXME # remove check as soon as we find out about the other readers
3311 case "$CDROMREADERSYNTAX" in
3312 flac) ;;
3313 cdparanoia) ;;
3314 cdda2wav | icedax) ;;
3315 *) log error "$CDROMREADERSYNTAX does not support ONETRACK mode"
3316 exit 1 ;;
3317 esac
3318 if [ "$BATCHNORM" = "y" ]; then
3319 log warning "BATCHNORM mode is not compatible with ONETRACK mode. Disabling..."
3320 BATCHNORM=n
3321 fi
3322 if [ "$NOGAP" = "y" ]; then
3323 log warning "NOGAP mode is not compatible with ONETRACK mode. Disabling..."
3324 NOGAP=n
3325 fi
3326 # It does not matter how many tracks we want. In ONETRACK mode we grab them all
3327 # FIXME # allow ranges of tracks to be selected for onetrack ripping
3328 if [ $# -gt 0 ]; then
3329 log warning "ONETRACK mode selected, grabbing all tracks..."
3330 fi
3331 else
3332 while [ $# -gt 0 ]; do
3333 # Range parsing code courtesy of Vincent Ho
3334 # Cleaned up to use shell built-ins by Charles Steinkuehler
3335 if [ "${1#*[^0-9-]}" != "$1" ]; then
3336 log error "syntax error while processing track numbers"
3337 else
3338 RSTART=${1%%-*}
3339 REND=${1##*-}
3340 while [ ${RSTART:=1} -le ${REND:=0} ] ; do
3341 TRACKQUEUE="$TRACKQUEUE $RSTART"
3342 RSTART=$(( $RSTART + 1 ))
3343 done
3344 fi
3345 shift
3346 done
3347 fi
3348
3349 # List of valid actions: cddb,read,normalize,encode,tag,move,playlist,clean
3350 # List of experimental actions: retag,transcode
3351
3352 # Determine what actions are to be done from $ACTIONS and set the
3353 # following environment variables for them:
3354 DOCDDB=n
3355 DOREAD=n
3356 DONORMALIZE=n
3357 DOPREPROCESS=n
3358 DOENCODE=n
3359 DOPOSTPROCESS=n
3360 DOTAG=n
3361 DOMOVE=n
3362 DOREPLAYGAIN=n
3363 DOPLAYLIST=n
3364 DOCLEAN=n
3365 ## FIXME ## Lets keep compatibility with -M
3366 [ "$DOCUE" != "y" ] && DOCUE=n
3367
3368 for ACTION in $(echo $ACTIONS | tr , \ )
3369 do
3370 case $ACTION in
3371 default) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOCLEAN=y;;
3372 cue) DOCUE=y ; MAKECUEFILE=y ;;
3373 cddb) DOCDDB=y;;
3374 read) DOREAD=y;;
3375 normalize) DONORMALIZE=y; DOREAD=y;;
3376 # preprocess) DOPREPROCESS=y; DOREAD=y;;
3377 encode) DOENCODE=y; DOREAD=y;;
3378 # postprocess) DOPREPROCESS=y; DOENCODE=y; DOREAD=y;;
3379 tag) DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
3380 move) DOMOVE=y; DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
3381 replaygain) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOREPLAYGAIN=y;;
3382 playlist) DOCDDB=y; DOPLAYLIST=y;;
3383 clean) DOCLEAN=y;;
3384 esac
3385 done
3386
3387 if [ "$DONORMALIZE" = "y" ] && [ "$DOREPLAYGAIN" = "y" ]; then
3388 # FIXME # should we abort on error or just inform the user?
3389 log warning "selected both normalize and replaygain actions"
3390 fi
3391
3392 for SHOWCDDBFIELD in $(echo $SHOWCDDBFIELDS | tr , \ ); do
3393 case $SHOWCDDBFIELD in
3394 y*|Y*) SHOWCDDBYEAR="y";;
3395 g*|G*) SHOWCDDBGENRE="y";;
3396 *) ;;
3397 esac
3398 done
3399
3400 # At this point a CDROM has to be defined, so we check it exists.
3401 if [ X"$CDROM" != "X" ] ; then
3402 if ( [ "$CDROMREADERSYNTAX" = "cdda2wav" ] || [ "$CDROMREADERSYNTAX" = "icedax" ] ) && [ "$NEEDCDROMID" = "y" ] ; then
3403 if [ "$OSFLAVOUR" = "FBSD" ]; then
3404 if echo "$CDROMID" | grep "^[0-9],[0-9],[0-9]$" >/dev/null 2>&1 ; then :; else
3405 log error "CDROMID not in the right format for $CDROMREADERSYNTAX"
3406 log error "Use \"cdrecord -scanbus\" to obtain a adecuate ID an set CDROMID accordingly"
3407 exit 1
3408 fi
3409 fi
3410 elif [ ! -e "$CDROM" -a X"$DOREAD" = "Xy" ]; then
3411 log error "CDROM device cannot be found."
3412 exit 1
3413 fi
3414 # avoid processing if we are not going to hit the CDROM.
3415 elif [ X"$DOREAD" = "Xy" ]; then
3416 log error "CDROM has not been defined or cannot be found"
3417 exit 1
3418 fi
3419
3420 # USEPIPES pre-tests, before we get into more serious stuff
3421 # Not compatible with:
3422 # - multiple outputs
3423 # - normalize
3424 # - lowdisk algorithm
3425 # - anything else?
3426 if [ X"$USEPIPES" = "Xy" ]; then
3427 if [ $(echo "$OUTPUTTYPE" | tr , \ | wc -w ) -gt 1 ]; then
3428 log error "Unix pipes not compatible with multiple outputs"
3429 exit 1
3430 fi
3431 if [ X"$DONORMALIZE" = "Xy" ]; then
3432 log error "Unix pipes not compatible with normalizer"
3433 # FIXME # Do we need to exit or shall we just disable the mode?
3434 exit 1
3435 fi
3436 if [ X"$BATCHNORM" = "Xy" ]; then
3437 log error "Unix pipes not compatible with BATCHNORM encoding"
3438 exit 1
3439 fi
3440 if [ X"$NOGAP" = "Xy" ]; then
3441 log error "Unix pipes not compatible with NOGAP encoding"
3442 exit 1
3443 fi
3444 if [ X"$DOENCODE" = "Xn" ]; then
3445 vecho warning "Disabling Unix pipes since we are not encoding!"
3446 USEPIPES=n
3447 fi
3448 if [ X"$LOWDISK" = "Xy" ]; then
3449 log error "Unix pipes not compatible with lowdisk algorithm"
3450 exit 1
3451 fi
3452 fi
3453
3454 # LOWDISK pre-tests, before we get into more problematic stuff
3455 # Not compatible with anything that needs all the files in the hard disc:
3456 # - BATCHNORM
3457 # - NOGAP lame mode
3458 if [ X"$LOWDISK" = "Xy" ]; then
3459 if [ X"$BATCHNORM" = "Xy" ]; then
3460 log error "Unix pipes not compatible with BATCHNORM encoding"
3461 exit 1
3462 fi
3463 if [ X"$NOGAP" = "Xy" ]; then
3464 log error "Unix pipes not compatible with NOGAP encoding"
3465 exit 1
3466 fi
3467 fi
3468
3469 # BATCHNORM pre-tests, before we get into serious problems
3470 # Not compatible with
3471 if [ "$BATCHNORM" = "y" ] && [ "$DONORMALIZE" = "n" ]; then
3472 vecho warning "Disabling BATCHNORM since we are not normalizing!"
3473 BATCHNORM=n
3474 fi
3475
3476 # Check the encoding format from the ones available in the system, if nothing has been configured.
3477 if [ X"$OUTPUTTYPE" = "X" ]; then
3478 for DEFAULT_OUTPUT in $( echo "$DEFAULT_OUTPUT_BINARIES" | tr , \ ); do
3479 DEFAULT_OUTPUT_FORMAT="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 1)"
3480 DEFAULT_OUTPUT_BINARY="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 2)"
3481 if [ -x $(which $DEFAULT_OUTPUT_BINARY) ] ; then
3482 OUTPUTTYPE=$DEFAULT_OUTPUT_FORMAT
3483 vecho "No default output type defined. Autoselecting $OUTPUTTYPE..." >&2
3484 break
3485 fi
3486 done
3487 if [ X"$OUTPUTTYPE" = "X" ]; then
3488 log error "no encoder found in the PATH"
3489 log error "hints: are all dependencies installed? has the \$PATH been modified?"
3490 exit 1
3491 fi
3492 fi
3493
3494 # Decide which CDROM reader we're gonna use
3495 case "$CDROMREADERSYNTAX" in
3496 cdparanoia|debug)
3497 CDROMREADER="$CDPARANOIA"
3498 CDROMREADEROPTS="$CDPARANOIAOPTS"
3499 ;;
3500 cdda2wav | icedax)
3501 CDROMREADER="$CDDA2WAV"
3502 CDROMREADEROPTS="$CDDA2WAVOPTS"
3503 ;;
3504 dagrab)
3505 CDROMREADER="$DAGRAB"
3506 CDROMREADEROPTS="$DAGRABOPTS"
3507 ;;
3508 cddafs)
3509 CDROMREADER="$CDDAFS"
3510 CDROMREADEROPTS="$CDDAFSOPTS"
3511 ;;
3512 flac)
3513 CDROMREADER="$FLAC"
3514 CDROMREADEROPTS="$FLACOPTS"
3515 ;;
3516 esac
3517
3518 # There's only one normalize...
3519 case "$NORMALIZERSYNTAX" in
3520 default|normalize)
3521 NORMALIZER="$NORMALIZE"
3522 NORMALIZEROPTS="$NORMALIZEOPTS"
3523 ;;
3524 esac
3525
3526 # Allow -o OUTPUT(1):OPTIONS(1),...,OUTPUT(N):OPTIONS(N) mode of operation
3527 if echo "$OUTPUTTYPE" | grep ":" > /dev/null 2>&1 ; then
3528 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr \ \|| tr , \ | tr \| \ )"; do
3529 case "$OUTPUT" in
3530 vorbis:*|ogg:*) OGGENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3531 mp3:*) MP3ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3532 flac:*) FLACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3533 spx:*) SPEEXENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3534 mpc:*) MPPENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3535 m4a:*) AACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
3536 esac
3537 done
3538 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do
3539 TEMPOUTPUT=$( echo "$OUTPUT" | cut -d: -f1 )
3540 TEMPOUTPUTTYPE="${TEMPOUTPUTTYPE:+$TEMPOUTPUTTYPE,}$TEMPOUTPUT"
3541 done
3542 OUTPUTTYPE="$TEMPOUTPUTTYPE"
3543 fi
3544
3545 # If nothing has been specified, use oggenc for oggs and lame for mp3s and flac
3546 # for flacs and speexenc for speex and mppenc for mpps and faac for m4as
3547
3548 # Getting ready for multiple output changes
3549 for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
3550 do
3551 case $OUTPUT in
3552 vorbis|ogg)
3553 [ "$OGGENCODERSYNTAX" = "default" ] && OGGENCODERSYNTAX=oggenc
3554 [ "$DOTAG" = "y" ] && NEEDCOMMENTER=y
3555 [ "$DOREPLAYGAIN" = "y" ] && NEEDVORBISGAIN=y
3556 OGGOUTPUTCONTAINER=ogg
3557 ;;
3558 mp3)
3559 [ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame
3560 [ "$DOTAG" = "y" ] && NEEDTAGGER=y
3561 [ "$DOREPLAYGAIN" = "y" ] && NEEDMP3GAIN=y
3562 ;;
3563 flac)
3564 [ "$FLACENCODERSYNTAX" = "default" ] && FLACENCODERSYNTAX=flac
3565 [ "$DOTAG" = "y" ] && NEEDMETAFLAC=y
3566 [ "$DOREPLAYGAIN" = "y" ] && NEEDMETAFLAC=y
3567 [ "$ONETRACK" = "y" ] && [ "$DOCUE" = "y" ] && NEEDMETAFLAC=y
3568 ;;
3569 spx)
3570 [ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc
3571 # [ "$DOREPLAYGAIN" = "y" ] &&
3572 ;;
3573 mpc)
3574 [ "$MPPENCODERSYNTAX" = "default" ] && MPPENCODERSYNTAX=mppenc
3575 [ "$DOREPLAYGAIN" = "y" ] && NEEDMPPGAIN=y
3576 ;;
3577 m4a)
3578 [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac
3579 [ "$DOTAG" = "y" ] && CHECKATOMICPARSLEY=y
3580 ;;
3581 wav)
3582 if [ "$KEEPWAVS" = "y" ]; then
3583 vecho "Setting the KEEPWAVS option, since the resulting wav files were requested..."
3584 fi
3585 KEEPWAVS=move
3586 ;;
3587 *) log error "Invalid OUTPUTTYPE defined"
3588 exit 1
3589 ;;
3590 esac
3591 done
3592
3593 # decide which encoder
3594 case "$MP3ENCODERSYNTAX" in
3595 lame)
3596 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$LAMEOPTS}"
3597 MP3ENCODER="$LAME"
3598 ;;
3599 toolame)
3600 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$TOOLAMEOPTS}"
3601 MP3ENCODER="$TOOLAME"
3602 ;;
3603 gogo)
3604 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$GOGOOPTS}"
3605 MP3ENCODER="$GOGO"
3606 ;;
3607 bladeenc)
3608 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$BLADEENCOPTS}"
3609 MP3ENCODER="$BLADEENC"
3610 ;;
3611 l3enc)
3612 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$L3ENCOPTS}"
3613 MP3ENCODER="$L3ENC"
3614 ;;
3615 xingmp3enc)
3616 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$XINGMP3ENCOPTS}"
3617 MP3ENCODER="$XINGMP3ENC"
3618 ;;
3619 mp3enc)
3620 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$MP3ENCOPTS}"
3621 MP3ENCODER="$MP3ENC"
3622 ;;
3623 esac
3624 case "$OGGENCODERSYNTAX" in
3625 vorbize)
3626 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$VORBIZEOPTS}"
3627 OGGENCODER="$VORBIZE"
3628 ;;
3629 oggenc)
3630 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$OGGENCOPTS}"
3631 OGGENCODER="$OGGENC"
3632 ;;
3633 esac
3634 case "$FLACENCODERSYNTAX" in
3635 flac)
3636 FLACENCODEROPTS="${FLACENCODEROPTSCLI:-$FLACOPTS}"
3637 FLACENCODER="$FLAC"
3638 if [ "$DOREPLAYGAIN" = "y" ]; then
3639 FLACENCODEROPTS="${FLACENCODEROPTS} --replay-gain"
3640 fi
3641 # FLAC streams can be encapsulated on a Ogg transport layer
3642 if echo "$FLACENCODEROPTS" | egrep -- "(^| )--ogg($| )" > /dev/null 2>&1 ;then
3643 log error "FLAC on an Ogg container is not yet supported"
3644 log error "due to problem with adding comments to such files"
3645 exit 1
3646 FLACOUTPUTCONTAINER=ogg
3647 else
3648 FLACOUTPUTCONTAINER=flac
3649 fi
3650 ;;
3651 esac
3652 case "$SPEEXENCODERSYNTAX" in
3653 speexenc)
3654 SPEEXENCODEROPTS="${SPEEXENCODEROPTSCLI:-$SPEEXENCOPTS}"
3655 SPEEXENCODER="$SPEEXENC"
3656 ;;
3657 esac
3658 case "$MPPENCODERSYNTAX" in
3659 mppenc)
3660 MPPENCODEROPTS="${MPPENCODEROPTSCLI:-$MPPENCOPTS}"
3661 MPPENCODER="$MPPENC"
3662 ;;
3663 esac
3664 case "$AACENCODERSYNTAX" in
3665 faac)
3666 AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
3667 AACENCODER="$AACENC"
3668 ;;
3669 esac
3670
3671 # and which tagger
3672 if [ "$ID3TAGV" = "1" ]; then
3673 TAGGER="$ID3"
3674 TAGGEROPTS="$ID3OPTS"
3675 else
3676 TAGGER="$ID3V2"
3677 TAGGEROPTS="$ID3V2OPTS"
3678 fi
3679
3680 # NOGAP is specific to lame. Other encoders fail ...
3681 if [ "$NOGAP" = "y" ] && [ ! "$MP3ENCODER" = "lame" ]; then
3682 log warning "the NOGAP option is specific to lame. Deactivating..."
3683 NOGAP=n
3684 fi
3685
3686 # Options for mkcue
3687 case "$CUEREADERSYNTAX" in
3688 default|mkcue)
3689 CUEREADEROPTS="${CDROM}"
3690 CUEREADER="$MKCUE"
3691 ;;
3692 esac
3693
3694 # which information retrieval tool are we using?
3695 case "$CDDBTOOL" in
3696 cddb) ;;
3697 musicbrainz) ;;
3698 esac
3699
3700 # Check if both OGGEOUTPUTCONTAINER and FLACOUTPUTCONTAINER are the same, and differentiante them
3701 if [ X"$OGGOUTPUTCONTAINER" = "Xogg" ] && [ X"$FLACOUTPUTCONTAINER" = "Xogg" ]; then
3702 log error "FLAC on an Ogg container is not yet supported"
3703 log error "due to problem with adding comments to such files"
3704 exit 1
3705 OGGOUTPUTCONTAINER=ogg.ogg
3706 FLACOUTPUTCONTAINER=flac.ogg
3707 vecho warning "modified file endings due to conflicting transport layers in Ogg/Vorbis and Ogg/FLAC"
3708 fi
3709
3710 # Clean up nice options (either use '-n NICELEVEL or -NICELEVEL')
3711
3712 if [ "$ENCNICE" ]; then
3713 ENCNICE="-n $ENCNICE"
3714 fi
3715 if [ "$READNICE" ]; then
3716 READNICE="-n $READNICE"
3717 fi
3718 if [ "$DISTMP3NICE" ]; then
3719 DISTMP3NICE="-n $DISTMP3NICE"
3720 fi
3721
3722 # Don't check for stuff if it's not needed
3723 if [ "$REMOTEHOSTS" ]; then
3724 NEEDDISTMP3=y
3725 fi
3726 if [ "$DONORMALIZE" = "y" ]; then
3727 NEEDNORMALIZER=y
3728 fi
3729 if [ "$EJECTCD" = "y" ]; then
3730 NEEDEJECT=y
3731 fi
3732 if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then
3733 if [ "$CDDBMETHOD" = "cddb" ]; then
3734 NEEDHTTPGET=y
3735 elif [ "$CDDBMETHOD" = "musicbrainz" ]; then
3736 :
3737 fi
3738 fi
3739 if [ "$DOCUE" = "y" ]; then
3740 NEEDCUEREADER=y
3741 fi
3742
3743 if [ X"$CDSPEEDVALUE" != "X" ] && [ "$DOREAD" = "y" ]; then
3744 case "$CDROMREADERSYNTAX" in
3745 cdparanoia|debug) CDROMREADEROPTS="$CDPARANOIAOPTS -S $CDSPEEDVALUE" ;;
3746 ### FIXME ### translate "cue2discid" from python to bash
3747 flac) NEEDMETAFLAC=y ; NEEDCUE2DISCID=y ; CDSPEEDVALUE="" ;;
3748 *) NEEDCDSPEED=y ;;
3749 esac
3750 fi
3751
3752 ###USEPIPESSUPPORT###
3753
3754 # Rippers with USEPIPE support
3755 # FIXME # Include here all the rippers we can figure out support pipes
3756 PIPERIPPER_cdparanoia="-"
3757 PIPERIPPER_debug="-"
3758 PIPERIPPER_flac="-c "
3759
3760 # Encoders with USEPIPE support
3761 # FIXME # Include here all the encoders we can figure out support pipes
3762 PIPE_lame="-"
3763 PIPE_bladeenc="-"
3764 PIPE_oggenc="-"
3765 PIPE_flac="-"
3766
3767 # Figure out if we can use pipes with the ripper/encoder combination
3768 # exit otherwise
3769 if [ "$USEPIPES" = "y" ]; then
3770 PIPERIPPERSVARCHECK="PIPERIPPER_${CDROMREADERSYNTAX}"
3771 case "$OUTPUT" in
3772 mp3)
3773 PIPEENCODERSVARCHECK="PIPE_$MP3ENCODERSYNTAX" ;;
3774 vorbis|ogg)
3775 PIPEENCODERSVARCHECK="PIPE_$OGGENCODERSYNTAX" ;;
3776 flac)
3777 PIPEENCODERSVARCHECK="PIPE_$FLACENCODERSYNTAX" ;;
3778 spx)
3779 PIPEENCODERSVARCHECK="PIPE_$SPEEXENCODER" ;;
3780 mpc)
3781 PIPEENCODERSVARCHECK="PIPE_$MPPENCODER" ;;
3782 esac
3783 decho "PIPERIPPERSVARCHECK: $( eval echo "\$$PIPERIPPERSVARCHECK" )"
3784 if [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "$" ] || \
3785 [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "" ] ; then
3786 log error "no support for pipes with given ripper"
3787 log error "read the USEPIPES file from the source tarball to get help."
3788 log error "On a Debian system, it is under /usr/share/doc/abcde/USEPIPES.gz"
3789 exit 1;
3790 fi
3791 decho "PIPEENCODERSVARCHECK: $( eval echo "\$$PIPEENCODERSVARCHECK" )"
3792 if [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "$" ] || \
3793 [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "" ] ; then
3794 log error "no support for pipes with given encoder"
3795 log error "read the USEPIPES file from the source tarball to help"
3796 log error "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz"
3797 exit 1;
3798 fi
3799 fi
3800
3801 # Make sure a buncha things exist
3802 for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
3803 $OGGENCODER $FLACENCODER $SPEEXENCODER $MPPENCODER \
3804 $AACENCODER \
3805 ${NEEDATOMICPARSLEY+$ATOMICPARSLEY} \
3806 ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \
3807 ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
3808 ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
3809 ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} \
3810 ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMP3GAIN+$MP3GAIN} \
3811 ${NEEDMPPGAIN+$MPPGAIN} ${NEEDCUEREADER+$CUEREADER} \
3812 ${NEEDCUE2DISCID+$CUE2DISCID}
3813 do
3814 checkexec "$X"
3815 done
3816
3817 if [ "$CHECKATOMICPARSLEY" = "y" ]; then
3818 if ! new_checkexec "$ATOMICPARSLEY"; then
3819 echo "WARNING: $ATOMICPARSLEY Not Found Not Post-Tagging!"
3820 DOTAG='n'
3821 else
3822 echo "Using $ATOMICPARSLEY To Tag AAC Tracks."
3823 fi
3824 fi
3825
3826 # And last but not least, check if we can diff between files. We do not abort,
3827 # since diffing is not critical...
3828 if [ -x $(which $DIFF) ]; then :; else
3829 vecho warning "Disabling diff since we cannot find it in the \$PATH..."
3830 DIFF=""
3831 fi
3832
3833 ## Now that we have metaflac, check if we need cue2discid
3834 #case $CDROMREADERSYNTAX in
3835 # flac)
3836 # TRACKINFO=$($METAFLAC --show-tag=CDDB $CDROM | cut -d"=" -f2 | egrep "[a-f0-9]{8}")
3837 # if [ "$TRACKINFO" = "" ]; then
3838 # checkexec ${NEEDCUE2DISCID+$CUE2DISCID}
3839 # fi
3840 # ;;
3841 #esac
3842
3843 CDROMREADER="$CDROMREADER $CDROMREADEROPTS"
3844 CDDBTOOL="$CDDBTOOL $CDDBTOOLOPTS"
3845 HTTPGET="$HTTPGET $HTTPGETOPTS"
3846
3847 # Here it used to say:
3848 # One thousand lines in, we can start doing stuff with things
3849 # Well, right now we are at line 3737 ;)
3850
3851 # Export needed things so they can be read in this subshell
3852 export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS
3853 export CDROM CDDBDATA REMOTEHOSTS MAXPROCS HTTPGET MD5SUM
3854
3855 if [ "$DOREAD" = "y" ]; then
3856 # User-definable function to set some things. Use it for
3857 # - closing the CD tray with eject -t
3858 # - set the CD speed value with eject -x
3859 vecho -n "Executing customizable pre-read function... "
3860
3861 pre_read # Execute the user-defined pre-read funtion. Close the CD with it.
3862
3863 vecho "done."
3864 fi
3865
3866 case "$CDDBMETHOD" in
3867 cddb)
3868 do_discid # Get ABCDETEMPDIR created and status file initialized
3869 ;;
3870 musicbrainz)
3871 do_musicbrainz id
3872 ;;
3873 esac
3874
3875 if [ "$DOCDDB" = "y" ]; then
3876 # start with a sane default:
3877 CDDBLOCALSTATUS=notfound
3878 if [ $CDDBUSELOCAL = "y" ]; then
3879 do_localcddb
3880 fi
3881 if checkstatus cddb-choice > /dev/null; then
3882 :
3883 else
3884 if [ "$CDDBLOCALSTATUS" = "notfound" ] ; then
3885 case "$CDDBMETHOD" in
3886 cddb)
3887 do_cddbstat
3888 do_cddbquery
3889 do_cddbread
3890 ;;
3891 musicbrainz)
3892 do_musicbrainz
3893 ;;
3894 esac
3895 fi
3896 fi
3897 do_cddbedit
3898
3899 eval "$($CDDBTOOL parse "$CDDBDATA")"
3900 fi
3901
3902 # Before reading tracks, we set the speed of the device
3903
3904 if [ X"$CDSPEEDVALUE" != "X" ]; then
3905 case "$CDROMREADERSYNTAX" in
3906 cdparanoia|debug) ;;
3907 flac) ;;
3908 *) do_cdspeed ;;
3909 esac
3910 fi
3911
3912 # Define the first and last track, since we might need them later in several places
3913 FIRSTTRACK=$( get_first $TRACKQUEUE )
3914 LASTTRACK=$( get_last $TRACKQUEUE )
3915
3916 if [ -f "$ABCDETEMPDIR/status" ] && [ X"$ERASEENCODEDSTATUS" = "Xy" ]; then
3917 mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
3918 grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
3919 | grep -v ^encode-output > "$ABCDETEMPDIR/status"
3920 fi
3921
3922 if checkstatus onetrack ; then ONETRACK=y ; fi
3923
3924 if [ "$ONETRACK" = "y" ]; then
3925 # Reuse the CUEFILE in case we created it (now or in a previous run)
3926 if CUEFILE=$(checkstatus cuefile); then
3927 IMPORTCUESHEET=y
3928 fi
3929 fi
3930
3931 # Create playlist if needed (backgroundable) and start reading in tracks
3932
3933 (
3934
3935 if [ ! "$ONETRACK" = "y" ]; then
3936 if [ "$DOPLAYLIST" = "y" ]; then
3937 echo Creating playlist... >&2
3938 do_playlist
3939 fi
3940 fi
3941
3942 # For the lowdisk option, only one program is running at once so the encoder
3943 # can be unsilenced right away.
3944 if [ "$LOWDISK" = "y" ] || [ "$ONETRACK" = "y" ]; then
3945 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3946 fi
3947
3948 if [ "$ONETRACK" = "y" ]; then
3949 TRACKS="$FIRSTTRACK"
3950 if [ "$USEPIPES" = "y" ]; then
3951 if checkstatus readencodetrack-$FIRSTTRACK; then :; else
3952 do_cdread onetrack $FIRSTTRACK $LASTTRACK | do_encode $FIRSTTRACK %local0% > /dev/null 2>&1
3953 fi
3954 else
3955 if checkstatus readtrack-$FIRSTTRACK; then :; else
3956 do_cdread onetrack $FIRSTTRACK $LASTTRACK
3957 fi
3958 fi
3959 else
3960 for UTRACKNUM in $TRACKQUEUE
3961 do
3962 if [ "$DOREAD" = "y" ]; then
3963 if [ "$USEPIPES" = "y" ]; then
3964 if checkstatus readencodetrack-$UTRACKNUM; then :; else
3965 # Read, pipe, shut up!
3966 do_cdread $UTRACKNUM | do_encode $UTRACKNUM %local0% > /dev/null 2>&1
3967 fi
3968 else
3969 if checkstatus readtrack-$UTRACKNUM; then :; else
3970 do_cdread $UTRACKNUM
3971 fi
3972 if [ "$?" != "0" ]; then
3973 # CD read failed - don't give the goahead to
3974 # the encoder
3975 echo NO
3976 exit
3977 fi
3978 fi
3979 fi
3980 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ]; then
3981 :
3982 else
3983 # If we are not reading, set the encode output to loud already, so
3984 # that we can see the output of the first track.
3985 if [ "$MAXPROCS" = "1" ] && [ ! "$DOREAD" = "y" ]; then
3986 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3987 fi
3988 echo NEXTTRACK # Get the encoder machine churning again
3989 if [ "$DOREAD" = "y" ]; then
3990 if [ "$LOWDISK" = "y" ] && [ "$DOENCODE" = "y" ]; then
3991 until checkstatus encodetrack-$UTRACKNUM
3992 do
3993 if checkerrors encodetrack-$UTRACKNUM; then
3994 break
3995 fi
3996 sleep 2
3997 done
3998 fi
3999 fi
4000 fi
4001 done
4002 fi
4003
4004 # Now that we're done the encoding can be loud again -
4005 # if we're not using SMP.
4006 if [ "$MAXPROCS" = "1" ]; then
4007 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
4008 fi
4009
4010 # All tracks read, start encoding.
4011 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ] || [ "$ONETRACK" = "y" ]; then
4012 echo NEXTTRACK
4013 fi
4014
4015 # Execute the user-defined post_read funtion before ejecting CD
4016 post_read
4017
4018 # We are now finished with the cdrom - it can be safely ejected. Note that
4019 # abcde will not have completed yet.
4020 if [ "$EJECTCD" = "y" ] && [ -x $(which $EJECT) ]; then
4021 # We check if the disk we are processing is actually the disk inside the
4022 # CD tray. If not, we do not eject the CD, since it might be so that the
4023 # user ejected it manually.
4024 #CURRENTTRACKINFO=$($CDDISCID $CDROM)
4025 #if if [ "$?" != "1" ] && [ "$CURRENTTRACKINFO" = "$TRACKINFO" ] ; then
4026 # More FreeBSD bits.
4027 if [ X"$(uname)" = X"FreeBSD" ] ; then
4028 # FreeBSD eject uses the EJECT environment variable to name the CDROM
4029 # but in this script EJECT is in the envionment and names the program
4030 eject=$EJECT
4031 unset EJECT
4032 # The FreeBSD eject needs "adc0" not "/dev/adc0c"
4033 cd="$(echo $CDROM | sed -e 's=.*/==;s=[a-h]$==;')"
4034 $eject $EJECTOPTS $cd
4035 elif [ X"$(uname)" = X"Darwin" ] ; then
4036 disktool -e ${CDROM#/dev/} 0
4037 else
4038 $EJECT $EJECTOPTS "$CDROM"
4039 fi
4040 #fi
4041 fi
4042
4043 ) | (
4044
4045 ## Do we need to pre-process
4046 #if [ x"$PREPROCESS" = "x" ] ; then
4047 # cat
4048 #else
4049 # for PRETRACKNUM in $TRACKQUEUE
4050 # do
4051 # read GOAHEAD
4052 # if [ "$GOAHEAD" = "NO" ]; then break; fi
4053 # PREPROCEED=
4054 # until [ $PREPROCEED ]
4055 # do
4056 # if checkstatus readtrack-$PRETRACKNUM; then PREPROCEED=y; break; fi
4057 # # all locations are working, wait and try again later
4058 # if [ ! $PREPROCEED ]; then sleep 3; fi
4059 # done
4060 # ( do_preprocess $PRETRACKNUM
4061 # echo "NEXTTRACK"
4062 # ) &
4063 # done
4064 #fi
4065 #
4066 #) | (
4067
4068 # In BATCHNORM and/or NOGAP modes, we want all tracks to be read first.
4069 #BACK
4070 if [ "$BATCHNORM" = "y" ] || [ "$NOGAP" = "y" ]; then
4071 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
4072 if [ "$GOAHEAD" = "NO" ]; then break; fi
4073 for LASTTRACK in $TRACKQUEUE; do :; done
4074 if checkstatus readtrack-$LASTTRACK; then
4075 if [ "$DONORMALIZE" = "y" ] && [ "$BATCHNORM" = "y" ]; then
4076 if checkstatus normalizetrack-$LASTTRACK; then :; else do_batch_normalize; fi
4077 if checkerrors batch-normalize; then exit 1; fi
4078 fi
4079 if [ "$DOENCODE" = "y" ] && [ "$NOGAP" = "y" ]; then
4080 if [ "$DONORMALIZE" = "y" ]; then
4081 for UTRACKNUM in $TRACKQUEUE
4082 do
4083 if checkstatus readtrack-$UTRACKNUM; then
4084 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
4085 fi
4086 done
4087 fi
4088 if checkstatus encodetrack-$LASTTRACK; then :; else do_nogap_encode; fi
4089 if checkerrors nogap-encode; then exit 1; fi
4090 fi
4091 fi
4092 fi
4093
4094 # If we are using ONETRACK, we can proceed with the normal encoding using just the $FIRSTTRACK as TRACKQUEUE
4095 if [ "$ONETRACK" = "y" ] ; then
4096 TRACKQUEUE="$FIRSTTRACK"
4097 TRACKS="$FIRSTTRACK"
4098 fi
4099
4100 # Do the encoding, including parallelization of remote encoding
4101 # Figure out where each track is going to be encoded
4102 ENCODELOCATIONS="$(echo $REMOTEHOSTS | tr , ' ')"
4103 if [ "$MAXPROCS" != "0" ]; then
4104 for NUM in $(f_seq_row 1 "$MAXPROCS")
4105 do
4106 ENCODELOCATIONS="$ENCODELOCATIONS %local$NUM%"
4107 done
4108 fi
4109 # Strip whitespace
4110 ENCODELOCATIONS=$(echo $ENCODELOCATIONS)
4111 for UTRACKNUM in $TRACKQUEUE
4112 do
4113 # Wait for our cue
4114 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
4115 if [ "$GOAHEAD" = "NO" ]; then break; fi
4116 # find out where this track is to be encoded
4117 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
4118 # Make sure we have a place to encode this, if not, exit stage right
4119 if [ -z "$ENCODELOCATIONS" ]; then
4120 continue
4121 fi
4122 PROCEED=
4123 until [ $PROCEED ]
4124 do
4125 for LOCATION in $ENCODELOCATIONS
4126 do
4127 PREVIOUSTRACK="$(checkstatus encodetracklocation-$LOCATION)"
4128 # check first if a track has ever been assigned to this location
4129 if [ -z "$PREVIOUSTRACK" ]; then PROCEED=y; break; fi
4130 # If it errored out, rebuild $ENCODELOCATIONS without this location in it
4131 if checkerrors encodetrack-$PREVIOUSTRACK; then
4132 for TEMPLOCATION in $ENCODELOCATIONS
4133 do
4134 if [ "$TEMPLOCATION" != "$LOCATION" ]; then
4135 TEMPENCODELOCATIONS="$TEMPENCODELOCATIONS $TEMPLOCATION"
4136 fi
4137 done
4138 ENCODELOCATIONS=$(echo $TEMPENCODELOCATIONS)
4139 ABORT=y
4140 PROCEED=y
4141 break
4142 fi
4143 # We're still here, this location must have been previously assigned,
4144 # and last completed without error - check if it's done with the
4145 # previous track yet
4146 if checkstatus encodetrack-$PREVIOUSTRACK; then PROCEED=y; break; fi
4147 done
4148 # all locations are working, wait and try again later
4149 if [ ! $PROCEED ]; then sleep 3; fi
4150 done
4151 # Record the location we're about to encode the next track at
4152 echo "encodetracklocation-$LOCATION=$UTRACKNUM" >> "$ABCDETEMPDIR/status"
4153 fi
4154 # Don't proceed with the rest of the loop if we can't encode
4155 if [ "$ABORT" ]; then continue; fi
4156 ## FIXME ## Add here
4157 ## run_command tagtrack-$OUTPUT-$1 $METAFLAC $METAFLACOPTS ${IMPORTCUESHEET:+--import-cuesheet-from="$ABCDETEMPDIR/$CUEFILE"} --import-tags-from=- "$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
4158 # Set TRACKNUM, TRACKNAME
4159 if [ -e "$CDDBDATA" ]; then
4160 if [ "$ONETRACK" = "y" ]; then
4161 TRACKNAME="$DALBUM"
4162 TRACKNUM="$FIRSTTRACK"
4163 splitvarious
4164 else
4165 TRACKNUM=$UTRACKNUM
4166 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
4167 getcddbinfo TRACKNAME
4168 splitvarious
4169 fi
4170 fi
4171 # You can't encode a file which needs to be normalized before finishing
4172 # You can't tag a file before it's finished encoding -
4173 # thus all of this is backgrounded together
4174 (
4175 if [ "$DONORMALIZE" = "y" ]; then
4176 if checkstatus readtrack-$UTRACKNUM; then
4177 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
4178 fi
4179 fi
4180 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
4181 if checkstatus readtrack-$UTRACKNUM; then
4182 #if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION; fi
4183 if [ "$DONORMALIZE" = "y" ]; then
4184 if checkstatus normalizetrack-$UTRACKNUM; then
4185 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
4186 fi
4187 else
4188 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
4189 fi
4190 fi
4191 fi
4192 if [ "$DOTAG" = "y" ]; then
4193 if checkstatus encodetrack-$UTRACKNUM; then
4194 if checkstatus tagtrack-$UTRACKNUM; then :; else do_tag $UTRACKNUM; fi
4195 fi
4196 # Lets tag the cue file
4197 if checkstatus cleancuefile >/dev/null; then :; else
4198 if checkstatus cuefile >/dev/null ; then
4199 do_cleancue
4200 fi
4201 fi
4202 fi
4203 if [ "$DOMOVE" = "y" ]; then
4204 if checkstatus tagtrack-$UTRACKNUM; then
4205 if checkstatus movetrack-$UTRACKNUM; then :; else do_move $UTRACKNUM; fi
4206 fi
4207 fi
4208 ) &
4209 done
4210
4211
4212 # Go through it again and make sure there's no distmp3 stragglers, otherwise
4213 # we'll delete the files they're working on
4214 # Do NOT play ball if there is no ball to play (so ABORT if needed)
4215 ## FIXME ## Check also for files which are encoded using PIPEs.
4216 if [ "$DOENCODE" = "y" ] && [ "$USEPIPES" != "y" ] && [ ! "$ABORT" ]; then
4217 PROCEED=
4218 until [ $PROCEED ]
4219 do
4220 PROCEED=y
4221 for LOCATION in $ENCODELOCATIONS
4222 do
4223 CHECKTRACK="$(checkstatus encodetracklocation-$LOCATION)"
4224 # "How can he give us a status update, if he's DEAD?"
4225 if checkstatus encodetrack-$CHECKTRACK; then
4226 continue
4227 fi
4228 # Nothing to see here please go quietly back to your homes
4229 if [ -z "$CHECKTRACK" ]; then continue; fi
4230 # You're still here? Maybe there is something...
4231 if checkstatus encodetrack-$CHECKTRACK; then :; else PROCEED= ; break; fi
4232 done
4233 # hold up
4234 if [ ! $PROCEED ]; then sleep 5; fi
4235 done
4236 fi
4237 # If the above didn't catch the stragglers, this will
4238 wait
4239 if [ "$DOREPLAYGAIN" = "y" ]; then
4240 do_replaygain
4241 fi
4242
4243 # Execute the user-defined post_encode function before cleaning up
4244 post_encode
4245
4246 # Check to see if run_command logged any errors
4247 if [ -f "$ABCDETEMPDIR/errors" ]; then
4248 log error "The following commands failed to run:"
4249 cat "$ABCDETEMPDIR/errors"
4250 # Don't clean up
4251 DOCLEAN=n
4252 fi
4253 if [ "$KEEPWAVS" = "y" ];then
4254 # Don't clean up
4255 DOCLEAN=n
4256 fi
4257 # Check if we have moved all the formats we had previously encoded, if we are not using the FORCE.
4258 if [ "$DOCLEAN" = "y" ] && [ ! "$FORCE" = "y" ]; then
4259 ENCODED_FORMATS=$(egrep "^encodetrack-(.{3,6})-(.{1,2})$" "$ABCDETEMPDIR/status" | cut -d"-" -f2 | sort -u | tr '\n' '|')
4260 MOVED_FORMATS=$(egrep "^movetrack-output-(.{3,6})$" "$ABCDETEMPDIR/status" | cut -d"-" -f3 | sort -u | tr '\n' '|')
4261 if [ "$ENCODED_FORMATS" != "$MOVED_FORMATS" ]; then
4262 log warning "The encoded formats does not match with the moved ones"
4263 log warning "Formats encoded: $( echo $ENCODED_FORMATS | tr "|" " " )"
4264 log warning "Formats moved: $( echo $MOVED_FORMATS | tr "|" " " )"
4265 log warning "Use \"abcde -a clean -f -C $DISCID\" to force the removal of the remaining data."
4266 DOCLEAN=n
4267 fi
4268 fi
4269 if [ "$DOCLEAN" = "y" ]; then
4270 # Wipe all the evidence
4271 # Gimme gimme gimme some more time!
4272 sleep 5
4273 rm -rf "$ABCDETEMPDIR"
4274 echo "Finished."
4275 else
4276 echo "Finished. Not cleaning $ABCDETEMPDIR."
4277 fi
4278 )
4279 exit 0
4280
4281 # b:is_bash
4282 # vim:tabstop=4