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