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