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