More work on musicbrainz support
[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 CDDBLOCALSUCCESS="n"
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 [ "$(echo "${CDDBLOCALRESULTS}" | wc -l)" = "1" ]; then
1632 CDDBLOCALFILE="${CDDBLOCALDIR}/${CDDBLOCALRESULTS}"
1633 CDDBLOCALMATCH=single
1634 elif (( $(echo "${CDDBLOCALRESULTS}" | wc -l) > 1 )); then
1635 CDDBLOCALMATCH=multiple
1636 else
1637 CDDBLOCALMATCH=none
1638 fi
1639 elif [ -r "${CDDBLOCALDIR}/${CDDBDISCID}" ]; then
1640 CDDBLOCALFILE="${CDDBLOCALDIR}/${CDDBDISCID}"
1641 CDDBLOCALMATCH=single
1642 else
1643 CDDBLOCALMATCH=none
1644 fi
1645
1646 # If the user has selected to check a local CDDB repo, we proceed with it
1647 case $CDDBLOCALMATCH in
1648 single)
1649 # List out disc title/author and contents
1650 do_cddbparse "${CDDBLOCALFILE}"
1651 echo -n "Locally cached CDDB entry found, use it? [y/n] (y): "
1652 if [ "$INTERACTIVE" = "y" ]; then
1653 read USELOCALRESP
1654 while [ "$USELOCALRESP" != "y" ] && [ "$USELOCALRESP" != "n" ] && [ "$USELOCALRESP" != "" ] ; do
1655 echo -n 'Invalid selection. Please answer "y" or "n": '
1656 read USELOCALRESP
1657 done
1658 [ x"$USELOCALRESP" = "x" ] && USELOCALRESP="y"
1659 else
1660 echo "y" >&2
1661 fi
1662 if [ "$USELOCALRESP" = "y" ]; then
1663 #echo "Using local copy of CDDB data"
1664 echo "# DO NOT ERASE THIS LINE! Added by abcde to imitate cddb output" > "$ABCDETEMPDIR/cddbread.1"
1665 cat "${CDDBLOCALFILE}" >> "$ABCDETEMPDIR/cddbread.1"
1666 echo 999 > "$ABCDETEMPDIR/cddbquery" # Assuming 999 isn't used by CDDB
1667 echo cddb-readcomplete >> "$ABCDETEMPDIR/status"
1668 do_cddbparse "${CDDBLOCALFILE}" > "$ABCDETEMPDIR/cddbchoices"
1669 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
1670 CDDBLOCALSUCCESS="y"
1671 else
1672 #echo "Not using local copy of CDDB data"
1673 CDDBLOCALSUCCESS="n"
1674 fi
1675 ;;
1676 none)
1677 CDDBLOCALSUCCESS="n"
1678 ;;
1679 esac
1680 fi
1681 }
1682
1683 do_musicbrainzstat ()
1684 {
1685 :
1686 }
1687
1688 do_musizbrainz ()
1689 {
1690 :
1691 }
1692
1693 # do_cddbstat
1694 do_cddbstat ()
1695 {
1696 # Perform CDDB protocol version check if it hasn't already been done
1697 if checkstatus cddb-statcomplete; then :; else
1698 if [ "$CDDBAVAIL" = "n" ]; then
1699 ERRORCODE=no_query
1700 echo 503 > "$ABCDETEMPDIR/cddbstat"
1701 else
1702 rc=1
1703 CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
1704 CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
1705 while test $rc -eq 1 -a $CDDBPROTO -ge 3; do
1706 vecho "Checking CDDB server status..."
1707 $CDDBTOOL stat $CDDBURL $CDDBUSER $CDDBHOST $CDDBPROTO > "$ABCDETEMPDIR/cddbstat"
1708 RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbstat" | cut -f1 -d' ')
1709 case "$RESPONSECODE" in
1710 210) # 210 OK, status information follows (until terminating `.')
1711 rc=0;
1712 ;;
1713 501|*) # 501 Illegal CDDB protocol level: <n>.
1714 CDDBPROTO=`expr $CDDBPROTO - 1`
1715 ;;
1716 esac
1717 done
1718 if test $rc -eq 1; then
1719 CDDBAVAIL="n"
1720 fi
1721 fi
1722 echo cddb-statcomplete >> "$ABCDETEMPDIR/status"
1723 fi
1724 }
1725
1726
1727 # do_cddbquery
1728 do_cddbquery ()
1729 {
1730 CDDBDISCID=$(echo $TRACKINFO | cut -d' ' -f1)
1731 CDDBLOCALFILE="${CDDBLOCALDIR}/${CDDBDISCID}"
1732
1733 # Perform CDDB query if it hasn't already been done
1734 if checkstatus cddb-querycomplete; then :; else
1735 if [ "$CDDBAVAIL" = "n" ]; then
1736 ERRORCODE=no_query
1737 echo 503 > "$ABCDETEMPDIR/cddbquery"
1738 # The default CDDBLOCALSUCCESS is "n"
1739 # This part will be triggered if the user CDDB repo does not
1740 # contain the entry, or if we are not trying to use the repo.
1741 else
1742 vecho "Querying the CDDB server..."
1743 CDDBUSER=$(echo $HELLOINFO | cut -f1 -d'@')
1744 CDDBHOST=$(echo $HELLOINFO | cut -f2- -d'@')
1745 $CDDBTOOL query $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $TRACKINFO > "$ABCDETEMPDIR/cddbquery"
1746 ERRORCODE=$?
1747 case $ERRORCODE in
1748 0) # success
1749 ;;
1750 12|13|14)
1751 # no match found in database,
1752 # wget/fetch error, or user requested not to use CDDB
1753 # Make up an error code (503) that abcde
1754 # will recognize in do_cddbread
1755 # and compensate by making a template
1756 echo 503 > "$ABCDETEMPDIR/cddbquery"
1757 ;;
1758 *) # strange and unknown error
1759 echo ERRORCODE=$ERRORCODE
1760 echo "abcde: $CDDBTOOL returned unknown error code"
1761 ;;
1762 esac
1763 fi
1764 echo cddb-querycomplete >> "$ABCDETEMPDIR/status"
1765 fi
1766 }
1767
1768 # do_cddbread
1769 do_cddbread ()
1770 {
1771 # If it's not to be used, generate a template.
1772 # Then, display it (or them) and let the user choose/edit it
1773 if checkstatus cddb-readcomplete; then :; else
1774 vecho "Obtaining CDDB results..."
1775 # If CDDB is to be used, interpret the query results and read all
1776 # the available entries.
1777 rm -f "$ABCDETEMPDIR/cddbchoices"
1778 CDDBCHOICES=1 # Overridden by multiple matches
1779 RESPONSECODE=$(head -n 1 "$ABCDETEMPDIR/cddbquery" | cut -f1 -d' ')
1780 case "$RESPONSECODE" in
1781 200)
1782 # One exact match, retrieve it
1783 # 200 [section] [discid] [artist] / [title]
1784 if checkstatus cddb-read-1-complete; then :; else
1785 echo -n "Retrieving 1 CDDB match..." >> "$ABCDETEMPDIR/cddbchoices"
1786 $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(cut -f2,3 -d' ' "$ABCDETEMPDIR/cddbquery") > "$ABCDETEMPDIR/cddbread.1"
1787 echo "done." >> "$ABCDETEMPDIR/cddbchoices"
1788 echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
1789 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
1790 fi
1791 # List out disc title/author and contents
1792 echo ---- "$(cut '-d ' -f4- "$ABCDETEMPDIR/cddbquery")" ---- >> "$ABCDETEMPDIR/cddbchoices"
1793 for TRACK in $(f_seq_row 1 $TRACKS)
1794 do
1795 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
1796 done
1797 echo >> "$ABCDETEMPDIR/cddbchoices"
1798 ;;
1799 202|403|409|503)
1800 # No match
1801 case "$RESPONSECODE" in
1802 202) echo "No CDDB match." >> "$ABCDETEMPDIR/cddbchoices" ;;
1803 403|409) echo "CDDB entry is corrupt, or the handshake failed." >> "$ABCDETEMPDIR/cddbchoices" ;;
1804 503) echo "CDDB unavailable." >> "$ABCDETEMPDIR/cddbchoices" ;;
1805 esac
1806 $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
1807 # List out disc title/author and contents of template
1808 echo ---- Unknown Artist / Unknown Album ---- >> "$ABCDETEMPDIR/cddbchoices"
1809 UNKNOWNDISK=y
1810 for TRACK in $(f_seq_row 1 $TRACKS)
1811 do
1812 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.0" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
1813 done
1814 echo >> "$ABCDETEMPDIR/cddbchoices"
1815 echo cddb-read-0-complete >> "$ABCDETEMPDIR/status"
1816 echo cddb-choice=0 >> "$ABCDETEMPDIR/status"
1817 ;;
1818 210|211)
1819 # Multiple exact, (possibly multiple) inexact matches
1820 IN=
1821 if [ "$RESPONSECODE" = "211" ]; then IN=in; fi
1822 if [ "$(wc -l < "$ABCDETEMPDIR/cddbquery" | tr -d ' ')" -eq 3 ]; then
1823 echo "One ${IN}exact match:" >> "$ABCDETEMPDIR/cddbchoices"
1824 tail -n +2 "$ABCDETEMPDIR/cddbquery" | head -n 1 >> "$ABCDETEMPDIR/cddbchoices"
1825 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
1826 else
1827 echo "Multiple ${IN}exact matches:" >> "$ABCDETEMPDIR/cddbchoices"
1828 fi
1829 vecho -n "Retrieving multiple matches... "
1830 grep -v ^[.]$ "$ABCDETEMPDIR/cddbquery" | ( X=0
1831 read DISCINFO # eat top line
1832 while read DISCINFO
1833 do
1834 X=$(expr $X + 1)
1835 if checkstatus cddb-read-$X-complete; then :; else
1836 $CDDBTOOL read $CDDBURL $CDDBPROTO $CDDBUSER $CDDBHOST $(echo $DISCINFO | cut -f1,2 -d' ') > "$ABCDETEMPDIR/cddbread.$X"
1837 echo cddb-read-$X-complete >> "$ABCDETEMPDIR/status"
1838 fi
1839 # List out disc title/author and contents
1840 echo \#$X: ---- "$DISCINFO" ---- >> "$ABCDETEMPDIR/cddbchoices"
1841 for TRACK in $(f_seq_row 1 $TRACKS)
1842 do
1843 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.$X" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
1844 done
1845 echo >> "$ABCDETEMPDIR/cddbchoices"
1846 done )
1847 vecho "done."
1848 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
1849 ;;
1850 999)
1851 # Using local copy.
1852 for TRACK in $(f_seq_row 1 $TRACKS)
1853 do
1854 echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
1855 done
1856 echo >> "$ABCDETEMPDIR/cddbchoices"
1857 echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
1858 echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
1859 ;;
1860 esac
1861 echo "cddb-readcomplete" >> "$ABCDETEMPDIR/status"
1862 fi
1863 }
1864
1865 # do_cddbedit
1866 do_cddbedit ()
1867 {
1868 if checkstatus cddb-edit >/dev/null; then
1869 CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
1870 VARIOUSARTISTS="$(checkstatus variousartists)"
1871 VARIOUSARTISTSTYLE="$(checkstatus variousartiststyle)"
1872 return 0
1873 fi
1874 if [ "$INTERACTIVE" = "y" ]; then
1875 # We should show the CDDB results both when we are not using the local CDDB repo
1876 # or when we are using it but we could not find a proper match
1877 if [ "$CDDBUSELOCAL" = "y" ] && [ ! "$CDDBLOCALSUCCESS" = "y" ] || [ ! "$CDDBUSELOCAL" = "y" ]; then
1878 # Display the $ABCDETEMPDIR/cddbchoices file created above
1879 # Pick a pager so that if the tracks overflow the screen the user can still view everything
1880 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
1881 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
1882 CHOICE=$(checkstatus cddb-choice)
1883 if [ -n "$CHOICE" ] ; then
1884 case $CDDBCHOICES in
1885 -1) if head -1 "$ABCDETEMPDIR/cddbquery" | grep -q "^$" ; then
1886 log error "CDDB query failed!"
1887 exit 1
1888 else
1889 cat "$ABCDETEMPDIR/cddbchoices"
1890 fi
1891 ;;
1892 1) cat "$ABCDETEMPDIR/cddbchoices" ;;
1893 *)
1894 echo "Selected: #$CHOICE"
1895 do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
1896 ;;
1897 esac
1898 else
1899 # The user has a choice to make, display the info in a pager if necessary
1900 if [ $(cat "$ABCDETEMPDIR/cddbchoices" | wc -l) -ge 24 ]; then
1901 page "$ABCDETEMPDIR/cddbchoices"
1902 else
1903 # It's all going to fit in one page, cat it
1904 cat "$ABCDETEMPDIR/cddbchoices" >&2
1905 fi
1906
1907 CDDBCHOICENUM=""
1908 # Setting the choice to an impossible integer to avoid errors in the numeric comparisons
1909 CDCHOICENUM=-1
1910 # I'll take CDDB read #3 for $400, Alex
1911 while [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; do
1912 echo -n "Which entry would you like abcde to use (0 for none)? [0-$CDDBCHOICES]: " >&2
1913 read CDDBCHOICE
1914 [ X"$CDDBCHOICE" = "X" ] && CDDBCHOICE=1
1915 if echo $CDDBCHOICE | egrep -q "[[:space:]]*[[:digit:]]+,[[:digit:]]+[[:space:]]*" ; then
1916 if [ ! X"$DIFF" = "X" ]; then
1917 PARSECHOICE1=$(echo $CDDBCHOICE | cut -d"," -f1 | xargs printf %d 2>/dev/null)
1918 PARSECHOICE2=$(echo $CDDBCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null)
1919 if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBCHOICES ] || \
1920 [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBCHOICES ] || \
1921 [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then
1922 echo "Invalid diff range. Please select two coma-separated numbers between 1 and $CDDBCHOICES" >&2
1923 else
1924 # We parse the 2 choices to diff, store them in temporary files and diff them.
1925 for PARSECHOICE in $(echo $CDDBCHOICE | tr , \ ); do
1926 do_cddbparse "$ABCDETEMPDIR/cddbread.$PARSECHOICE" > "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE"
1927 done
1928 echo "Showing diff between choices $PARSECHOICE1 and $PARSECHOICE2..." > "$ABCDETEMPDIR/cddbread.diff"
1929 $DIFF $DIFFOPTS "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE1" "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE2" >> "$ABCDETEMPDIR/cddbread.diff"
1930 if [ $(cat "$ABCDETEMPDIR/cddbread.diff" | wc -l) -ge 24 ]; then
1931 page "$ABCDETEMPDIR/cddbread.diff"
1932 else
1933 cat "$ABCDETEMPDIR/cddbread.diff" >&2
1934 fi
1935 fi
1936 else
1937 echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBCHOICES." >&2
1938 fi
1939 elif echo $CDDBCHOICE | egrep -q "[[:space:]]*[[:digit:]]+[[:space:]]*" ; then
1940 # Make sure we get a valid choice
1941 CDCHOICENUM=$(echo $CDDBCHOICE | xargs printf %d 2>/dev/null)
1942 if [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; then
1943 echo "Invalid selection. Please choose a number between 0 and $CDDBCHOICES." >&2
1944 fi
1945 fi
1946 done
1947 if [ "$CDCHOICENUM" = "0" ]; then
1948 vecho "Creating empty CDDB template..."
1949 UNKNOWNDISK=y
1950 $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
1951 else
1952 echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
1953 do_cddbparse "$ABCDETEMPDIR/cddbread.$CDCHOICENUM"
1954 fi
1955 echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
1956 fi
1957 fi
1958 else
1959 # We need some code to show the selected option when local repository is selected and we have found a match
1960 vecho "Using cached CDDB match..." >&2
1961 # Display the $ABCDETEMPDIR/cddbchoices file created above
1962 # Pick a pager so that if the tracks overflow the screen the user can still view everything
1963 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
1964 CDDBCHOICES=$(expr $(cat "$ABCDETEMPDIR/cddbquery" | wc -l) - 2)
1965 CHOICE=$(checkstatus cddb-choice)
1966 if [ "$USELOCALRESP" = "y" ]; then :; else
1967 if [ -n "$CHOICE" ] ; then
1968 case $CDDBCHOICES in
1969 0)
1970 UNKNOWNDISK=y
1971 echo "Selected template."
1972 ;;
1973 1) cat "$ABCDETEMPDIR/cddbchoices" ;;
1974 *)
1975 echo "Selected: #$CHOICE"
1976 do_cddbparse "$ABCDETEMPDIR/cddbread.$CHOICE"
1977 ;;
1978 esac
1979 fi
1980 fi
1981 fi
1982 fi
1983 else
1984 # We're noninteractive - pick the first choice.
1985 # But in case we run a previous instance and selected a choice, use it.
1986 if [ -r "$ABCDETEMPDIR/cddbchoices" ]; then
1987 # Show the choice if we are not using the locally stored one
1988 # or when the local search failed to find a match.
1989 PREVIOUSCHOICE=$(checkstatus cddb-choice)
1990 if [ "$CDDBUSELOCAL" = "y" ] && [ "$CDDBLOCALSUCCESS" = "n" ] || [ ! "$CDDBUSELOCAL" = "y" ]; then
1991 #if [ "$PREVIOUSCHOICE" ]; then
1992 cat "$ABCDETEMPDIR/cddbchoices"
1993 #fi
1994 fi
1995 if [ ! -z "$PREVIOUSCHOICE" ] ; then
1996 CDCHOICENUM=$PREVIOUSCHOICE
1997 else
1998 CDCHOICENUM=1
1999 echo "cddb-choice=$CDCHOICENUM" >> "$ABCDETEMPDIR/status"
2000 fi
2001 echo "Selected: #$CDCHOICENUM ($(grep ^DTITLE= "$ABCDETEMPDIR/cddbread.$CDCHOICENUM" | cut -f2- -d= | tr -d \\r\\n))" >&2
2002 fi
2003 fi
2004
2005 # sanity check
2006 if checkstatus cddb-choice >/dev/null; then :; else
2007 echo "abcde: internal error: cddb-choice not recorded." >&2
2008 exit 1
2009 fi
2010 CDDBDATA="$ABCDETEMPDIR/cddbread.$(checkstatus cddb-choice)"
2011 echo -n "Edit selected CDDB data? [y/n] (" >&2
2012 if [ "$INTERACTIVE" = "y" ]; then
2013 if [ "$UNKNOWNDISK" = "y" ]; then
2014 echo -n "y): " >&2
2015 read EDITCDDB
2016 [ "$EDITCDDB" != "n" ] && EDITCDDB=y
2017 else
2018 echo -n "n): " >&2
2019 read EDITCDDB
2020 fi
2021 else
2022 echo "n): n" >&2
2023 EDITCDDB=n
2024 fi
2025 if [ "$EDITCDDB" = "y" ]; then
2026 CDDBDATAMD5SUM=$($MD5SUM "$CDDBDATA" | cut -d " " -f 1);
2027
2028 # Use the debian sensible-editor wrapper to pick the editor that the
2029 # user has requested via their $EDITOR environment variable
2030 if [ -x "/usr/bin/sensible-editor" ]; then
2031 /usr/bin/sensible-editor "$CDDBDATA"
2032 elif [ -n "$EDITOR" ]; then
2033 if [ -x $(which "${EDITOR%%\ *}") ]; then
2034 # That failed, try to load the preferred editor, starting
2035 # with their EDITOR variable
2036 eval $(echo "$EDITOR") \"$CDDBDATA\"
2037 fi
2038 # If that fails, check for a vi
2039 elif which vi >/dev/null 2>&1; then
2040 vi "$CDDBDATA"
2041 elif [ -x /usr/bin/vim ]; then
2042 /usr/bin/vim "$CDDBDATA"
2043 elif [ -x /usr/bin/vi ]; then
2044 /usr/bin/vi "$CDDBDATA"
2045 elif [ -x /bin/vi ]; then
2046 /bin/vi "$CDDBDATA"
2047 # nano should be on all (modern, i.e., sarge) debian systems
2048 elif which nano >/dev/null 2>&1 ; then
2049 nano "$CDDBDATA"
2050 elif [ -x /usr/bin/nano ]; then
2051 /usr/bin/nano "$CDDBDATA"
2052 # mg should be on all OpenBSD systems
2053 elif which mg >/dev/null 2>&1 ; then
2054 mg "$CDDBDATA"
2055 elif [ -x /usr/bin/mg ]; then
2056 /usr/bin/mg "$CDDBDATA"
2057 # bomb out
2058 else
2059 log warning "no editor available. Check your EDITOR environment variable."
2060 fi
2061 # delete editor backup file if it exists
2062 if [ -w "$CDDBDATA~" ]; then
2063 rm -f "$CDDBDATA~"
2064 fi
2065 fi
2066
2067 # Some heuristics first. Look at Disc Title, and if it starts with
2068 # "Various", then we'll assume Various Artists
2069 if [ "$(grep ^DTITLE= "$CDDBDATA" | cut -f2- -d= | egrep -ci '^(various|soundtrack|varios|sonora|ost)')" != "0" ]; then
2070 echo "Looks like a Multi-Artist CD" >&2
2071 VARIOUSARTISTS=y
2072 else
2073 echo -n "Is the CD multi-artist? [y/n] (n): " >&2
2074 if [ "$INTERACTIVE" = "y" ]; then
2075 read VARIOUSARTISTS
2076 else
2077 echo n >&2
2078 VARIOUSARTISTS=n
2079 fi
2080 fi
2081 if [ "$VARIOUSARTISTS" = "y" ] && [ ! "$ONETRACK" = "y" ]; then
2082 # Set a default
2083 DEFAULTSTYLE=1
2084 # Need NUMTRACKS before cddb-tool will return it:
2085 NUMTRACKS=$(egrep '^TTITLE[0-9]+=' "$CDDBDATA" | wc -l)
2086 if [ "$(grep -c "^TTITLE.*\/" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2087 # More than 1/2 tracks contain a "/", so guess forward
2088 DEFAULTSTYLE=1
2089 elif [ "$(grep -c "^TTITLE.*\-" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2090 # More than 1/2 contain a "-", so guess forward-dash
2091 DEFAULTSTYLE=2
2092 elif [ "$(grep -c "^TTITLE.*(.*)" "$CDDBDATA")" -gt "$(expr $NUMTRACKS / 2 )" ]; then
2093 # More than 1/2 contain something in parens, so guess trailing-paren
2094 DEFAULTSTYLE=6
2095 fi
2096
2097 echo "1) Artist / Title" >&2
2098 echo "2) Artist - Title" >&2
2099 echo "3) Title / Artist" >&2
2100 echo "4) Title - Artist" >&2
2101 echo "5) Artist: Title" >&2
2102 echo "6) Title (Artist)" >&2
2103 echo "7) This is a single-artist CD" >&2
2104 echo -n "Which style of multiple artist entries is it? [1-7] ($DEFAULTSTYLE): " >&2
2105 if [ "$INTERACTIVE" = "y" ]; then
2106 read VARIOUSARTISTSTYLE
2107 else
2108 echo $DEFAULTSTYLE >&2
2109 VARIOUSARTISTSTYLE=$DEFAULTSTYLE
2110 fi
2111 VARIOUSARTISTSTYLE=$(echo 0$VARIOUSARTISTSTYLE | xargs printf %d)
2112 # If they press Enter, then the default style (0) was chosen
2113 while [ $VARIOUSARTISTSTYLE -lt 0 ] || [ $VARIOUSARTISTSTYLE -gt 7 ]; do
2114 echo "Invalid selection. Please choose a number between 1 and 7."
2115 echo -n "Selection [1-7]: "
2116 read VARIOUSARTISTSTYLE
2117 VARIOUSARTISTSTYLE=$(echo 0$VARIOUSARTISTSTYLE | xargs printf %d)
2118 done
2119 if [ "$VARIOUSARTISTSTYLE" = "0" ]; then
2120 VARIOUSARTISTSTYLE=$DEFAULTSTYLE
2121 fi
2122 vecho "Selected: $VARIOUSARTISTSTYLE"
2123 case "$VARIOUSARTISTSTYLE" in
2124 1) # Artist / Title
2125 VARIOUSARTISTSTYLE=forward
2126 ;;
2127 2) # Artist - Title
2128 VARIOUSARTISTSTYLE=forward-dash
2129 ;;
2130 3) # Title / Artist
2131 VARIOUSARTISTSTYLE=reverse
2132 ;;
2133 4) # Title - Artist
2134 VARIOUSARTISTSTYLE=reverse-dash
2135 ;;
2136 5) # Artist: Title
2137 VARIOUSARTISTSTYLE=colon
2138 ;;
2139 6) # Title (Artist)
2140 VARIOUSARTISTSTYLE=trailing-paren
2141 ;;
2142 7) # Single Artist
2143 VARIOUSARTISTS=n
2144 ;;
2145 esac
2146 fi
2147
2148 echo "variousartists=$VARIOUSARTISTS" >> "$ABCDETEMPDIR/status"
2149 echo "variousartiststyle=$VARIOUSARTISTSTYLE" >> "$ABCDETEMPDIR/status"
2150
2151 if [ "$EDITCDDB" = "y" ] && [ "$UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE" = "y" ]; then
2152 if [ "$CDDBDATAMD5SUM" != "" ] && [ "$CDDBDATAMD5SUM" != "$($MD5SUM "$CDDBDATA" | cut -d " " -f 1)" ]; then
2153 # This works but does not have the necessary error checking
2154 # yet. If you are familiar with the CDDB spec
2155 # (see http://www.freedb.org/src/latest/DBFORMAT)
2156 # and can create an error-free entry on your own, then put
2157 # UNINTENTIONALLY_ANGER_THE_FREEDB_PEOPLE=y in your
2158 # abcde.conf to enable it. Put CDDBSUBMIT=email@address in
2159 # your abcde.conf to change the email address submissions are
2160 # sent to.
2161
2162 # submit the modified file, if they want
2163 if [ "$NOSUBMIT" != "y" ]; then
2164 echo -n "Do you want to submit this entry to $CDDBSUBMIT? [y/n] (n): "
2165 read YESNO
2166 while [ "$YESNO" != "y" ] && [ "$YESNO" != "n" ] && [ "$YESNO" != "Y" ] && \
2167 [ "$YESNO" != "N" ] && [ "$YESNO" != "" ]
2168 do
2169 echo -n 'Invalid selection. Please answer "y" or "n": '
2170 read YESNO
2171 done
2172 if [ "$YESNO" = "y" ] || [ "$YESNO" = "Y" ]; then
2173 echo -n "Sending..."
2174 $CDDBTOOL send "$CDDBDATA" $CDDBSUBMIT
2175 echo "done."
2176 fi
2177 fi
2178 fi
2179 fi
2180 # Make sure the cache directory exists
2181 mkdir -p $CDDBLOCALDIR
2182 # Cache edited CDDB entry in the user's cddb dir
2183 if [ "$CDDBCOPYLOCAL" = "y" ] || [ "$COPYCDDBLOCAL" = "Y" ]; then
2184 cat "$CDDBDATA" | tail -n $(expr $(cat "$CDDBDATA" | wc -l ) - 1 ) > ${CDDBLOCALDIR}/$(echo "$TRACKINFO" | cut -d' ' -f1)
2185 fi
2186
2187 echo "cddb-edit" >> "$ABCDETEMPDIR/status"
2188 }
2189
2190 # do_cdread [tracknumber]
2191 # do_cdread onetrack [firsttrack] [lasttrack]
2192 #
2193 do_cdread ()
2194 {
2195 # The commands here don't go through run_command because they're never supposed to be silenced
2196 # return codes need to be doublechecked anyway, however
2197 if [ "$1" = "onetrack" ]; then
2198 # FIXME # Add the possibility of grabbing ranges of tracks in onetrack
2199 # FIXME # Until then, we grab the whole CD in one track, no matter what
2200 # the user said
2201 # We need the first and last track for cdda2wav
2202 FIRSTTRACK=$2
2203 LASTTRACK=$3
2204 UTRACKNUM=$FIRSTTRACK
2205 case "$CDROMREADERSYNTAX" in
2206 flac) READTRACKNUMS="$FIRSTTRACK.1-$(($LASTTRACK + 1)).0" ;;
2207 cdparanoia) READTRACKNUMS="$FIRSTTRACK-$LASTTRACK" ;;
2208 cdda2wav) READTRACKNUMS="$FIRSTTRACK+$LASTRACK" ;;
2209 *) echo "abcde error: $CDROMREADERSYNTAX does not support ONETRACK mode"
2210 exit 1 ;;
2211 esac
2212 else
2213 UTRACKNUM=$1
2214 fi
2215 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
2216 if [ "$USEPIPES" = "y" ]; then
2217 TEMPARG="PIPERIPPER_$CDROMREADERSYNTAX"
2218 FILEARG="$( eval echo "\$$TEMPARG" )"
2219 REDIR=""
2220 PIPE_MESSAGE="and encoding "
2221 else
2222 WAVDATA="$ABCDETEMPDIR/track$UTRACKNUM.wav"
2223 case "$CDROMREADERSYNTAX" in
2224 ## FIXME ## Find the cases for dagrab and flac, to avoid exceptions
2225 flac)
2226 FILEARG="--output-name=$WAVDATA"
2227 ;;
2228 dagrab)
2229 FILEARG="-f $WAVDATA"
2230 ;;
2231 *)
2232 FILEARG="$WAVDATA"
2233 ;;
2234 esac
2235 REDIR=">&2"
2236 fi
2237 if [ "$1" = "onetrack" ]; then
2238 echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2
2239 else
2240 if [ -r "$CDDBDATA" ]; then
2241 do_getcddbinfo TRACKNAME
2242 echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM: $TRACKNAME..." >&2
2243 else
2244 echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM..." >&2
2245 fi
2246 fi
2247 case "$CDROMREADERSYNTAX" in
2248 ### FIXME ### use an exception for flac, since it uses -o
2249 ### FIXME ### Shall we just use -o $FILEARG ??
2250 flac)
2251 nice $READNICE $FLAC -d --cue=${READTRACKNUMS:-$UTRACKNUM.1-$(($UTRACKNUM + 1)).0} "$FILEARG" "$CDROM" ;;
2252 cdparanoia)
2253 echo "nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS $CDROM ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR ;;" > /tmp/log
2254 nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS $CDROM ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR ;;
2255 cdda2wav)
2256 if [ "$OSFLAVOUR" = "OSX" ] ; then
2257 # Hei, we have to unmount the device before running anything like cdda2wav in OSX
2258 disktool -u ${CDROM#/dev/} 0
2259 # Also, in OSX the cdrom device for cdda2wav changes...
2260 CDDA2WAVCDROM="IODVDServices"
2261 elif [ "$OSFLAVOUR" = "FBSD" ] ; then
2262 CDDA2WAVCDROM="$CDROMID"
2263 else
2264 if [ "$CDROMID" = "" ]; then
2265 CDDA2WAVCDROM="$CDROM"
2266 else
2267 CDDA2WAVCDROM="$CDROMID"
2268 fi
2269 fi
2270 nice $READNICE $CDROMREADER -D $CDDA2WAVCDROM -t ${READTRACKNUMS:-$UTRACKNUM} "$FILEARG" $REDIR
2271 ;;
2272 ## FIXME ## We have an exception for dagrab, since it uses -f
2273 ## FIXME ## Shall we just use -f $FILEARG ??
2274 dagrab) nice $READNICE $CDROMREADER -d $CDROM -v $UTRACKNUM "$FILEARG" $REDIR
2275 ;;
2276 cddafs)
2277 # Find the track's mounted path
2278 REALTRACKNUM=$(expr $UTRACKNUM + 0)
2279 FILEPATH=$(mount | grep "$CDROM on" | sed 's/^[^ ]* on \(.*\) (.*/\1/')
2280 FILEPATH=$(find "$FILEPATH" | grep "/$REALTRACKNUM ");
2281 # If the file exists, copy it
2282 if [ -e "$FILEPATH" ] ; then
2283 nice $READNICE $CDROMREADER "$FILEPATH" "$FILEARG" $REDIR
2284 else
2285 false
2286 fi ;;
2287 debug) nice $READNICE $CDROMREADER -$CDPARANOIACDROMBUS $CDROM -w $UTRACKNUM-[:1] "$FILEARG" $REDIR
2288 ;;
2289 esac
2290 RETURN=$?
2291 # If we get some error or we get some missing wav
2292 # (as long as we dont use pipes)
2293 if [ "$RETURN" != "0" -o \( ! -s "$WAVDATA" -a X"$USEPIPES" != "Xy" \) ]; then
2294 # Thank goodness errors is only machine-parseable up to the
2295 # first colon, otherwise this woulda sucked
2296 if [ "$RETURN" = "0" -a ! -s "$WAVDATA" ]; then
2297 RETURN=73 # fake a return code as cdparanoia return 0 also on aborted reads
2298 fi
2299 if [ "$USEPIPES" = "y" ]; then
2300 echo "readencodetrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
2301 else
2302 echo "readtrack-$UTRACKNUM: $CDROMREADER returned code $RETURN" >> "$ABCDETEMPDIR/errors"
2303 fi
2304 return $RETURN
2305 else
2306 if [ "$USEPIPES" = "y" ]; then
2307 echo readencodetrack-$UTRACKNUM >> "$ABCDETEMPDIR/status"
2308 else
2309 echo readtrack-$UTRACKNUM >> "$ABCDETEMPDIR/status"
2310 if [ "$1" = "onetrack" ]; then
2311 echo onetrack >> "$ABCDETEMPDIR/status"
2312 fi
2313 fi
2314 fi
2315 }
2316
2317 # do_cdspeed
2318 # No values accepted, only uses env variables
2319 do_cdspeed ()
2320 {
2321 if "$CDSPEED" "$CDSPEEDOPTS" "$CDSPEEDVALUE" >/dev/null ; then
2322 vecho "Setting CD speed to ${CDSPEEDVALUE}x"
2323 else
2324 echo "abcde: unable to set the device speed" >&2
2325 fi
2326 }
2327
2328 # vecho [message]
2329 #
2330 # vecho outputs a message if EXTRAVERBOSE is selected
2331 vecho ()
2332 {
2333 if [ x"$EXTRAVERBOSE" != "x" ]; then
2334 case $1 in
2335 warning) log warning "$@" ;;
2336 *) echo "$@" ;;
2337 esac
2338 fi
2339 }
2340
2341 # decho [message]
2342 #
2343 # decho outputs a debug message if DEBUG is selected
2344 decho ()
2345 {
2346 if [ x"$DEBUG" != "x" ]; then
2347 if echo $1 | grep -q "^\[" ; then
2348 DEBUGECHO=$(echo "$@" | tr -d '[]')
2349 echo "[DEBUG] $DEBUGECHO: `eval echo \\$${DEBUGECHO}`"
2350 else
2351 echo "[DEBUG] $1"
2352 fi
2353 fi
2354 }
2355
2356 # User-redefinable functions
2357 # Custom filename munging:
2358 mungefilename ()
2359 {
2360 #echo "$@" | sed s,:,\ -,g | tr \ /\* __+ | tr -d \'\"\?\[:cntrl:\]
2361 echo "$@" | sed s,:,\ -,g | tr \ / __ | tr -d \'\"\?\[:cntrl:\]
2362 }
2363
2364 # Custom genre munging:
2365 mungegenre ()
2366 {
2367 echo $CDGENRE | tr "[:upper:]" "[:lower:]"
2368 }
2369
2370 # pre_read
2371 # Empty pre_read function, to be defined in the configuration file.
2372 pre_read ()
2373 {
2374 :
2375 }
2376
2377 # post_read
2378 # Empty post_read function, to be defined in the configuration file.
2379 post_read ()
2380 {
2381 :
2382 }
2383
2384 ###############################################################################
2385 # End of functions
2386 #
2387 # Start of execution
2388 ###############################################################################
2389
2390 # Builtin defaults
2391
2392 # CDDB
2393 # Defaults to FreeDB, but a python musicbrainz can be used
2394 CDDBMETHOD=cddb
2395 CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"
2396 CDDBSUBMIT=freedb-submit@freedb.org
2397 CDDBPROTO=5
2398 HELLOINFO="$(whoami)@$(hostname)"
2399 CDDBCOPYLOCAL="n"
2400 CDDBLOCALDIR="$HOME/.cddb"
2401 CDDBUSELOCAL="n"
2402
2403 # List of fields we parse and show during the CDDB parsing...
2404 SHOWCDDBFIELDS="year,genre"
2405
2406 INTERACTIVE=y
2407 #CDROMREADERSYNTAX=cdparanoia
2408 ENCODERSYNTAX=default
2409
2410 MP3ENCODERSYNTAX=default
2411 OGGENCODERSYNTAX=default
2412 FLACENCODERSYNTAX=default
2413 SPEEXENCODERSYNTAX=default
2414 MPPENCODERSYNTAX=default
2415 AACENCODERSYNTAX=default
2416 NORMALIZERSYNTAX=default
2417 CUEREADERSYNTAX=default
2418
2419 OUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${TRACKNUM}.${TRACKFILE}'
2420 # Use the following VAOUTPUTFORMAT to revert to 2.0.x VA format:
2421 #VAOUTPUTFORMAT=${OUTPUTFORMAT}
2422 VAOUTPUTFORMAT='Various-${ALBUMFILE}/${TRACKNUM}.${ARTISTFILE}-${TRACKFILE}'
2423 ONETRACKOUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${ALBUMFILE}'
2424 VAONETRACKOUTPUTFORMAT='Various-${ALBUMFILE}/${ALBUMFILE}'
2425 PLAYLISTFORMAT='${ARTISTFILE}-${ALBUMFILE}.${OUTPUT}.m3u'
2426 PLAYLISTDATAPREFIX=''
2427 VAPLAYLISTFORMAT='${ARTISTFILE}-${ALBUMFILE}.${OUTPUT}.m3u'
2428 VAPLAYLISTDATAPREFIX=''
2429 DOSPLAYLIST=n
2430 COMMENT=''
2431 ID3TAGV=2
2432 ENCNICE=10
2433 READNICE=10
2434 DISTMP3NICE=10
2435 VARIOUSARTISTS=n
2436 VARIOUSARTISTSTYLE=forward
2437 KEEPWAVS=n
2438 PADTRACKS=n
2439 NOGAP=n
2440 BATCHNORM=n
2441
2442 # If using scsi devices, cdda2wav needs a CDROMID, instead of a device node
2443 # i.e. CDROMID="1,0,0"
2444 CDROMID=""
2445 # If we are using the IDE bus, we need CDPARANOIACDROMBUS defined as "d"
2446 # If we are using the ide-scsi emulation layer, we need to define a "g"
2447 CDPARANOIACDROMBUS="d"
2448
2449 # program paths - defaults to checking your $PATH
2450 # mp3
2451 LAME=lame
2452 TOOLAME=toolame
2453 GOGO=gogo
2454 BLADEENC=bladeenc
2455 L3ENC=l3enc
2456 XINGMP3ENC=xingmp3enc
2457 MP3ENC=mp3enc
2458 # ogg
2459 VORBIZE=vorbize
2460 OGGENC=oggenc
2461 # flac
2462 FLAC=flac
2463 # speex
2464 SPEEXENC=speexenc
2465 # mpp (Musepack)
2466 MPPENC=mppenc
2467 # m4a
2468 AACENC=faac
2469
2470 ID3=id3
2471 ID3V2=id3v2
2472 EYED3=eyeD3
2473 CDPARANOIA=cdparanoia
2474 CDDA2WAV=cdda2wav
2475 DAGRAB=dagrab
2476 CDDAFS=cp
2477 CDDISCID=cd-discid
2478 CDDBTOOL=cddb-tool
2479 MUSICBRAINZ=musicbrainz-get-tracks
2480 EJECT=eject
2481 MD5SUM=md5sum
2482 DISTMP3=distmp3
2483 VORBISCOMMENT=vorbiscomment
2484 METAFLAC=metaflac
2485 NORMALIZE=normalize-audio
2486 CDSPEED=eject
2487 VORBISGAIN=vorbisgain
2488 MP3GAIN=mp3gain
2489 MPPGAIN=replaygain
2490 MKCUE=mkcue
2491 MKTOC=cdrdao
2492 DIFF=diff
2493 CUE2DISCID=cue2discid
2494
2495 # Options for programs called from abcde
2496 # mp3
2497 LAMEOPTS=
2498 TOOLAMEOPTS=
2499 GOGOOPTS=
2500 BLADEENCOPTS=
2501 L3ENCOPTS=
2502 XINGMP3ENCOPTS=
2503 MP3ENCOPTS=
2504 # ogg
2505 VORBIZEOPTS=
2506 OGGENCOPTS=
2507 # flac
2508 FLACOPTS=
2509 # speex
2510 SPEEXENCOPTS=
2511 # mpc
2512 MPPENCOPTS=
2513 # m4a
2514 AACENCOPTS=
2515
2516 ID3OPTS=
2517 ID3V2OPTS=
2518 CDPARANOIAOPTS=
2519 CDDA2WAVOPTS=
2520 DAGRABOPTS=
2521 CDDAFSOPTS="-f"
2522 CDDBTOOLOPTS=
2523 EJECTOPTS=
2524 DISTMP3OPTS=
2525 NORMALIZEOPTS=
2526 CDSPEEDOPTS="-x"
2527 CDSPEEDVALUE=
2528 MKCUEOPTS=
2529 MKTOCOPTS=""
2530 VORBISCOMMENTOPTS="-R"
2531 METAFLACOPTS="--no-utf8-convert"
2532 DIFFOPTS=
2533
2534 # Default to one process if -j isn't specified
2535 MAXPROCS=1
2536
2537 # List of actions to perform - by default, run to completion
2538 ACTIONS=cddb,read,encode,tag,move,clean
2539
2540 # This option is basicaly for Debian package dependencies:
2541 # List of prefered outputs - by default, run with whatever we have in the path
2542 DEFAULT_OUTPUT_BINARIES=vorbis:oggenc,flac:flac,mp3:lame,mp3:bladeenc,spx:speex
2543
2544 # List of prefered cdromreaders - by default, run whichever we have in the path
2545 DEFAULT_CDROMREADERS="cdparanoia cdda2wav"
2546
2547 # Asume fetch if under FreeBSD. curl is used for Mac OS X. wget is used for Linux/OpenBSD/NetBSD.
2548 # Let's use these checkings to determine the OS flavour, which will be used later
2549 if [ X$(uname) = "XFreeBSD" ] ; then
2550 HTTPGET=fetch
2551 MD5SUM=md5
2552 NEEDCDROMID=y
2553 OSFLAVOUR=FBSD
2554 elif [ X$(uname) = "XDarwin" ] ; then
2555 HTTPGET=curl
2556 OSFLAVOUR=OSX
2557 # We should have disktool in OSX, but let's be sure...
2558 NEEDDISKTOOL=y
2559 CDROMREADERSYNTAX=cddafs
2560 elif [ X$(uname) = "XOpenBSD" ] ; then
2561 HTTPGET=wget
2562 MD5SUM=md5
2563 elif [ X$(uname) = "XNetBSD" ] ; then
2564 HTTPGET=ftp
2565 MD5SUM=md5
2566 else
2567 HTTPGET=wget
2568 fi
2569
2570 # If CDDBAVAIL is set to n, no CDDB read is done
2571 # If USEID3 is set to n, no ID3 tagging is done
2572 CDDBAVAIL=y
2573 USEID3=y
2574 USEID3V2=y
2575
2576 if [ -z "$OUTPUTDIR" ]; then
2577 OUTPUTDIR=$(pwd)
2578 fi
2579
2580 if [ -z "$WAVOUTPUTDIR" ]; then
2581 WAVOUTPUTDIR="$OUTPUTDIR"
2582 fi
2583
2584 # Load system defaults
2585 if [ -r /etc/abcde.conf ]; then
2586 . /etc/abcde.conf
2587 fi
2588 # Load user preference defaults
2589 if [ -r $HOME/.abcde.conf ]; then
2590 . $HOME/.abcde.conf
2591 fi
2592
2593 # By this time, we need some HTTPGETOPTS already defined.
2594 # If the user has defined a non-default HTTPGET method, we should not be empty.
2595
2596 if [ "$HTTPGETOPTS" = "" ] ; then
2597 case $HTTPGET in
2598 wget) HTTPGETOPTS="-q -O -";;
2599 curl) HTTPGETOPTS="-f -s";;
2600 fetch)HTTPGETOPTS="-q -o -";;
2601 ftp) HTTPGETOPTS="-q -o -";;
2602 *) log warning "HTTPGET in non-standard and HTTPGETOPTS are not defined." ;;
2603 esac
2604 fi
2605
2606 # If the CDROM has not been set yet, find a suitable one.
2607 # If this is a devfs system, default to /dev/cdroms/cdrom0
2608 # instead of /dev/cdrom
2609 if [ "$CDROM" = "" ] ; then
2610 if [ -e /dev/cdroms/cdrom0 ]; then
2611 CDROM=/dev/cdroms/cdrom0
2612 elif [ -e /dev/cdrom ]; then
2613 CDROM=/dev/cdrom
2614 elif [ -e /dev/cd0c ]; then
2615 CDROM=/dev/cd0c
2616 elif [ -e /dev/acd0c ]; then
2617 CDROM=/dev/acd0c
2618 elif [ -e /dev/disk1 ]; then
2619 CDROM=/dev/disk1
2620 fi
2621 fi
2622
2623 # Parse command line options
2624 #while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:t:T:vVxw:W: opt ; do
2625 while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:uvVxw:W:z opt ; do
2626 case "$opt" in
2627 1) ONETRACK=y ;;
2628 a) ACTIONS="$OPTARG" ;;
2629 A) EXPACTIONS="$OPTARG" ;;
2630 b) BATCHNORM=y ;;
2631 B) NOBATCHREPLAYGAIN=y ;;
2632 c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else log error "config file \"$OPTARG\" cannot be found." ; exit 1 ; fi ;;
2633 C) DISCID="$( echo ${OPTARG#abcde.} | tr -d /)" ;;
2634 d) CDROM="$OPTARG" ;;
2635 D) set -x ;;
2636 e) ERASEENCODEDSTATUS=y ;;
2637 h) usage; exit ;;
2638 e) ERASEENCODEDSTATUS=y ;;
2639 E) ENCODING="$OPTARG" ;;
2640 f) FORCE=y ;;
2641 g) NOGAP=y ;;
2642 i) INLINETAG=y ;;
2643 j) MAXPROCS="$OPTARG" ;;
2644 k) KEEPWAVS=y ;;
2645 l) LOWDISK=y ;;
2646 L) CDDBUSELOCAL=y ;;
2647 n) CDDBAVAIL=n ;;
2648 N) INTERACTIVE=n ;;
2649 m) DOSPLAYLIST=y ;;
2650 M) MAKECUEFILE=y ;;
2651 o) OUTPUTTYPE="$OPTARG" ;;
2652 p) PADTRACKS=y ;;
2653 P) USEPIPES=y ;;
2654 r) REMOTEHOSTS="$OPTARG" ;;
2655 R) DOREPLAYGAIN=y ;;
2656 s) SHOWCDDBFIELDS="$OPTARG" ;;
2657 S) CDSPEEDVALUE="$OPTARG" ;;
2658 t) STARTTRACKNUMBER="$OPTARG" ;;
2659 T) STARTTRACKNUMBER="$OPTARG" ; STARTTRACKNUMBERTAG="y" ;;
2660 u) CDDBPROTO=6 ;;
2661 v)
2662 echo "This is abcde v$VERSION."
2663 echo "Usage: abcde [options] [tracks]"
2664 echo "abcde -h for extra help"
2665 exit
2666 ;;
2667 V) EXTRAVERBOSE="y" ;;
2668 x) EJECTCD="y" ;;
2669 w) COMMENT="$OPTARG" ;;
2670 W) if echo $OPTARG | grep -q "[[:digit:]]" ; then
2671 STARTTRACKNUMBER="${OPTARG}01" ; STARTTRACKNUMBERTAG="y" ; COMMENT="CD${OPTARG}"
2672 else
2673 log error "argument of -W must be integer"
2674 exit 1
2675 fi
2676 ;;
2677 z) DEBUG=y ; CDROMREADERSYNTAX=debug ; EJECTCD="n" ;;
2678 ?) usage; exit ;;
2679 esac
2680 done
2681
2682 shift $(($OPTIND - 1))
2683
2684 # If the user specified a flac file, then switch to special flac mode
2685 if echo $CDROM | grep -i -q '.flac$'; then
2686 vecho "abcde: switching to flac CDROMREADERSYNTAX..."
2687 CDROMREADERSYNTAX=flac
2688 if [ "$EJECTCD" = "y" ];then
2689 vecho "abcde: CDROM flac mode, deactivating EJECTCD..."
2690 EJECTCD=n
2691 fi
2692 fi
2693
2694 # If the user provided a DISCID, disable eject
2695 if [ -n "$DISCID" ]; then EJECTCD=n ; fi
2696
2697 # Check the available cd rippers in the system, from the ones we know.
2698 if [ "$CDROMREADERSYNTAX" = "" ]; then
2699 for DEFAULT_CDROMREADER in $DEFAULT_CDROMREADERS; do
2700 if [ -x $( which $DEFAULT_CDROMREADER ) ]; then
2701 CDROMREADERSYNTAX=$DEFAULT_CDROMREADER
2702 break
2703 fi
2704 done
2705 if [ "$CDROMREADERSYNTAX" = "" ]; then
2706 log error "no cdreader found in your PATH"
2707 log error "hints: are all dependencies installed? has the \$PATH been modified?"
2708 exit 1
2709 fi
2710 fi
2711
2712 # Decide if we can continue.
2713 if [ "$ONETRACK" = "y" ]; then
2714 # FIXME # remove check as soon as we find out about the other readers
2715 case "$CDROMREADERSYNTAX" in
2716 flac) ;;
2717 cdparanoia) ;;
2718 cdda2wav) ;;
2719 *) log error "$CDROMREADERSYNTAX does not support ONETRACK mode"
2720 exit 1 ;;
2721 esac
2722 if [ "$BATCHNORM" = "y" ]; then
2723 log warning "BATCHNORM mode is not compatible with ONETRACK mode. Disabling..."
2724 BATCHNORM=n
2725 fi
2726 if [ "$NOGAP" = "y" ]; then
2727 log warning "NOGAP mode is not compatible with ONETRACK mode. Disabling..."
2728 NOGAP=n
2729 fi
2730 # It does not matter how many tracks we want. In ONETRACK mode we grab them all
2731 # FIXME # allow ranges of tracks to be selected for onetrack ripping
2732 if [ $# -gt 0 ]; then
2733 log warning "ONETRACK mode selected, grabbing all tracks..."
2734 fi
2735 else
2736 while [ $# -gt 0 ]; do
2737 # Range parsing code courtesy of Vincent Ho
2738 RSTART=$(echo $1 | cut -f1 -d-)
2739 REND=$(echo $1 | cut -f2 -d-)
2740 if [ "$RSTART" = "$REND" ]; then
2741 NEWTRACKS="$RSTART"
2742 else
2743 NEWTRACKS=$(f_seq_line $RSTART $REND)
2744 fi
2745 TRACKQUEUE=$(echo "$TRACKQUEUE" "$NEWTRACKS")
2746 shift
2747 done
2748 fi
2749
2750 # List of valid actions: cddb,read,normalize,encode,tag,move,playlist,clean
2751 # List of experimental actions: retag,transcode
2752
2753 # Determine what actions are to be done from $ACTIONS and set the
2754 # following environment variables for them:
2755 DOCDDB=n
2756 DOREAD=n
2757 DONORMALIZE=n
2758 DOPREPROCESS=n
2759 DOENCODE=n
2760 DOPOSTPROCESS=n
2761 DOTAG=n
2762 DOMOVE=n
2763 DOREPLAYGAIN=n
2764 DOPLAYLIST=n
2765 DOCLEAN=n
2766
2767 for ACTION in $(echo $ACTIONS | tr , \ )
2768 do
2769 case $ACTION in
2770 cddb) DOCDDB=y;;
2771 read) DOREAD=y;;
2772 normalize) DONORMALIZE=y; DOREAD=y;;
2773 # preprocess) DOPREPROCESS=y; DOREAD=y;;
2774 encode) DOENCODE=y; DOREAD=y;;
2775 # postprocess) DOPREPROCESS=y; DOENCODE=y; DOREAD=y;;
2776 tag) DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
2777 move) DOMOVE=y; DOTAG=y; DOREAD=y; DOENCODE=y; DOCDDB=y;;
2778 replaygain) DOCDDB=y; DOREAD=y; DOENCODE=y; DOTAG=y; DOMOVE=y; DOREPLAYGAIN=y;;
2779 playlist) DOCDDB=y; DOPLAYLIST=y;;
2780 clean) DOCLEAN=y;;
2781 esac
2782 done
2783
2784 if [ "$DONORMALIZE" = "y" ] && [ "$DOREPLAYGAIN" = "y" ]; then
2785 # FIXME # should we abort on error or just inform the user?
2786 log warning "selected both normalize and replaygain actions"
2787 fi
2788
2789 for SHOWCDDBFIELD in $(echo $SHOWCDDBFIELDS | tr , \ ); do
2790 case $SHOWCDDBFIELD in
2791 y*|Y*) SHOWCDDBYEAR="y";;
2792 g*|G*) SHOWCDDBGENRE="y";;
2793 *) ;;
2794 esac
2795 done
2796
2797 # Sanity checks:
2798
2799 # At this point a CDROM has to be defined, so we check it exists.
2800 if [ X"$CDROM" != "X" ] ; then
2801 if [ "$CDROMREADERSYNTAX" = "cdda2wav" ] && [ "$NEEDCDROMID" = "y" ] ; then
2802 if [ "$OSFLAVOUR" = "FBSD" ]; then
2803 if ! echo "$CDROMID" | grep "^[0-9],[0-9],[0-9]$" >/dev/null 2>&1 ; then
2804 log error "CDROMID not in the right format for $CDROMREADERSYNTAX"
2805 log error "Use \"cdrecord -scanbus\" to obtain a adecuate ID an set CDROMID accordingly"
2806 exit 1
2807 fi
2808 fi
2809 elif [ ! -e "$CDROM" -a X"$DOREAD" = "Xy" ]; then
2810 log error "CDROM device cannot be found."
2811 exit 1
2812 fi
2813 # avoid processing if we are not going to hit the CDROM.
2814 elif [ X"$DOREAD" = "Xy" ]; then
2815 log error "CDROM has not been defined or cannot be found"
2816 exit 1
2817 fi
2818
2819 # USEPIPES pre-tests, before we get into more serious stuff
2820 # Not compatible with:
2821 # - multiple outputs
2822 # - normalize
2823 # - lowdisk algorithm
2824 # - anything else?
2825 if [ X"$USEPIPES" = "Xy" ]; then
2826 if [ $(echo "$OUTPUTTYPE" | tr , \ | wc -w ) -gt 1 ]; then
2827 log error "Unix pipes not compatible with multiple outputs"
2828 exit 1
2829 fi
2830 if [ X"$DONORMALIZE" = "Xy" ]; then
2831 log error "Unix pipes not compatible with normalizer"
2832 # FIXME # Do we need to exit or shall we just disable the mode?
2833 exit 1
2834 fi
2835 if [ X"$BATCHNORM" = "Xy" ]; then
2836 log error "Unix pipes not compatible with BATCHNORM encoding"
2837 exit 1
2838 fi
2839 if [ X"$NOGAP" = "Xy" ]; then
2840 log error "Unix pipes not compatible with NOGAP encoding"
2841 exit 1
2842 fi
2843 if [ X"$DOENCODE" = "Xn" ]; then
2844 vecho warning "Disabling Unix pipes since we are not encoding!"
2845 USEPIPES=n
2846 fi
2847 if [ X"$LOWDISK" = "Xy" ]; then
2848 log error "Unix pipes not compatible with lowdisk algorithm"
2849 exit 1
2850 fi
2851 fi
2852
2853 # LOWDISK pre-tests, before we get into more problematic stuff
2854 # Not compatible with anything that needs all the files in the hard disc:
2855 # - BATCHNORM
2856 # - NOGAP lame mode
2857 if [ X"$LOWDISK" = "Xy" ]; then
2858 if [ X"$BATCHNORM" = "Xy" ]; then
2859 log error "Unix pipes not compatible with BATCHNORM encoding"
2860 exit 1
2861 fi
2862 if [ X"$NOGAP" = "Xy" ]; then
2863 log error "Unix pipes not compatible with NOGAP encoding"
2864 exit 1
2865 fi
2866 fi
2867
2868 # BATCHNORM pre-tests, before we get into serious problems
2869 # Not compatible with
2870 if [ "$BATCHNORM" = "y" ] && [ "$DONORMALIZE" = "n" ]; then
2871 vecho warning "Disabling BATCHNORM since we are not normalizing!"
2872 BATCHNORM=n
2873 fi
2874
2875 # Check the encoding format from the ones available in the system, if nothing has been configured in the system.
2876 if [ X"$OUTPUTTYPE" = "X" ]; then
2877 for DEFAULT_OUTPUT in $( echo "$DEFAULT_OUTPUT_BINARIES" | tr , \ ); do
2878 DEFAULT_OUTPUT_FORMAT="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 1)"
2879 DEFAULT_OUTPUT_BINARY="$(echo $DEFAULT_OUTPUT | cut -d ":" -f 2)"
2880 if [ -x $(which $DEFAULT_OUTPUT_BINARY) ] ; then
2881 OUTPUTTYPE=$DEFAULT_OUTPUT_FORMAT
2882 vecho "No default output type defined. Autoselecting $OUTPUTTYPE..." >&2
2883 break
2884 fi
2885 done
2886 if [ X"$OUTPUTTYPE" = "X" ]; then
2887 log error "no encoder found in the PATH"
2888 log error "hints: are all dependencies installed? has the \$PATH been modified?"
2889 exit 1
2890 fi
2891 fi
2892
2893 # Decide which CDROM reader we're gonna use
2894 case "$CDROMREADERSYNTAX" in
2895 cdparanoia|debug)
2896 CDROMREADER="$CDPARANOIA"
2897 CDROMREADEROPTS="$CDPARANOIAOPTS"
2898 ;;
2899 cdda2wav)
2900 CDROMREADER="$CDDA2WAV"
2901 CDROMREADEROPTS="$CDDA2WAVOPTS"
2902 ;;
2903 dagrab)
2904 CDROMREADER="$DAGRAB"
2905 CDROMREADEROPTS="$DAGRABOPTS"
2906 ;;
2907 cddafs)
2908 CDROMREADER="$CDDAFS"
2909 CDROMREADEROPTS="$CDDAFSOPTS"
2910 ;;
2911 flac)
2912 CDROMREADER="$FLAC"
2913 CDROMREADEROPTS="$FLACOPTS"
2914 ;;
2915 esac
2916
2917 # There's only one normalize...
2918 case "$NORMALIZERSYNTAX" in
2919 default|normalize)
2920 NORMALIZER="$NORMALIZE"
2921 NORMALIZEROPTS="$NORMALIZEOPTS"
2922 ;;
2923 esac
2924
2925 # Allow -o OUTPUT(1):OPTIONS(1),...,OUTPUT(N):OPTIONS(N) mode of operation
2926 if echo "$OUTPUTTYPE" | grep ":" > /dev/null 2>&1 ; then
2927 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do
2928 case "$OUTPUT" in
2929 vorbis:*|ogg:*) OGGENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
2930 mp3:*) MP3ENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
2931 flac:*) FLACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
2932 spx:*) SPEEXENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
2933 mpc:*) MPPENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
2934 m4a:*) AACENCODEROPTSCLI="$( echo $OUTPUT | cut -d: -f2- )" ;;
2935 esac
2936 done
2937 for OUTPUT in "$(echo "$OUTPUTTYPE" | tr , \ )"; do
2938 TEMPOUTPUT=$( echo "$OUTPUT" | cut -d: -f1 )
2939 TEMPOUTPUTTYPE="${TEMPOUTPUTTYPE:+$TEMPOUTPUTTYPE,}$TEMPOUTPUT"
2940 done
2941 OUTPUTTYPE="$TEMPOUTPUTTYPE"
2942 fi
2943
2944 # If nothing has been specified, use oggenc for oggs and lame for mp3s and flac
2945 # for flacs and speexenc for speex and mppenc for mpps and faac for m4as
2946
2947 # Getting ready for multiple output changes
2948 for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
2949 do
2950 case $OUTPUT in
2951 vorbis|ogg)
2952 [ "$OGGENCODERSYNTAX" = "default" ] && OGGENCODERSYNTAX=oggenc
2953 [ "$DOTAG" = "y" ] && NEEDCOMMENTER=y
2954 [ "$DOREPLAYGAIN" = "y" ] && NEEDVORBISGAIN=y
2955 OGGOUTPUTCONTAINER=ogg
2956 ;;
2957 mp3)
2958 [ "$MP3ENCODERSYNTAX" = "default" ] && MP3ENCODERSYNTAX=lame
2959 [ "$DOTAG" = "y" ] && NEEDTAGGER=y
2960 [ "$DOREPLAYGAIN" = "y" ] && NEEDMP3GAIN=y
2961 ;;
2962 flac)
2963 [ "$FLACENCODERSYNTAX" = "default" ] && FLACENCODERSYNTAX=flac
2964 [ "$DOTAG" = "y" ] && NEEDMETAFLAC=y
2965 [ "$DOREPLAYGAIN" = "y" ] && NEEDMETAFLAC=y
2966 ;;
2967 spx)
2968 [ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc
2969 # [ "$DOREPLAYGAIN" = "y" ] &&
2970 ;;
2971 mpc)
2972 [ "$MPPENCODERSYNTAX" = "default" ] && MPPENCODERSYNTAX=mppenc
2973 [ "$DOREPLAYGAIN" = "y" ] && NEEDMPPGAIN=y
2974 ;;
2975 m4a)
2976 [ "$AACENCODERSYNTAX" = "default" ] && AACENCODERSYNTAX=faac
2977 ;;
2978 wav)
2979 if [ "$KEEPWAVS" = "y" ]; then
2980 vecho "Unsetting the KEEPWAVS option, since the resulting wav files were requested..."
2981 fi
2982 KEEPWAVS=move
2983 ;;
2984 *) log error "Invalid OUTPUTTYPE defined"
2985 exit 1
2986 ;;
2987 esac
2988 done
2989
2990 # decide which encoder
2991 case "$MP3ENCODERSYNTAX" in
2992 lame)
2993 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$LAMEOPTS}"
2994 MP3ENCODER="$LAME"
2995 ;;
2996 toolame)
2997 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$TOOLAMEOPTS}"
2998 MP3ENCODER="$TOOLAME"
2999 ;;
3000 gogo)
3001 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$GOGOOPTS}"
3002 MP3ENCODER="$GOGO"
3003 ;;
3004 bladeenc)
3005 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$BLADEENCOPTS}"
3006 MP3ENCODER="$BLADEENC"
3007 ;;
3008 l3enc)
3009 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$L3ENCOPTS}"
3010 MP3ENCODER="$L3ENC"
3011 ;;
3012 xingmp3enc)
3013 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$XINGMP3ENCOPTS}"
3014 MP3ENCODER="$XINGMP3ENC"
3015 ;;
3016 mp3enc)
3017 MP3ENCODEROPTS="${MP3ENCODEROPTSCLI:-$MP3ENCOPTS}"
3018 MP3ENCODER="$MP3ENC"
3019 ;;
3020 esac
3021 case "$OGGENCODERSYNTAX" in
3022 vorbize)
3023 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$VORBIZEOPTS}"
3024 OGGENCODER="$VORBIZE"
3025 ;;
3026 oggenc)
3027 OGGENCODEROPTS="${OGGENCODEROPTSCLI:-$OGGENCOPTS}"
3028 OGGENCODER="$OGGENC"
3029 ;;
3030 esac
3031 case "$FLACENCODERSYNTAX" in
3032 flac)
3033 FLACENCODEROPTS="${FLACENCODEROPTSCLI:-$FLACOPTS}"
3034 FLACENCODER="$FLAC"
3035 # FLAC streams can be encapsulated on a Ogg transport layer
3036 if echo "$FLACENCODEROPTS" | egrep -q -- "(^| )--ogg($| )" ;then
3037 log error "FLAC on an Ogg container is not yet supported"
3038 log error "due to problem with adding comments to such files"
3039 exit 1
3040 FLACOUTPUTCONTAINER=ogg
3041 else
3042 FLACOUTPUTCONTAINER=flac
3043 fi
3044 ;;
3045 esac
3046 case "$SPEEXENCODERSYNTAX" in
3047 speexenc)
3048 SPEEXENCODEROPTS="${SPEEXENCODEROPTSCLI:-$SPEEXENCOPTS}"
3049 SPEEXENCODER="$SPEEXENC"
3050 ;;
3051 esac
3052 case "$MPPENCODERSYNTAX" in
3053 mppenc)
3054 MPPENCODEROPTS="${MPPENCODEROPTSCLI:-$MPPENCOPTS}"
3055 MPPENCODER="$MPPENC"
3056 ;;
3057 esac
3058 case "$AACENCODERSYNTAX" in
3059 faac)
3060 AACENCODEROPTS="${AACENCODEROPTSCLI:-$AACENCOPTS}"
3061 AACENCODER="$AACENC"
3062 ;;
3063 esac
3064 # and which tagger
3065
3066 if [ "$ID3TAGV" = "1" ]; then
3067 TAGGER="$ID3"
3068 TAGGEROPTS="$ID3OPTS"
3069 else
3070 TAGGER="$ID3V2"
3071 TAGGEROPTS="$ID3V2OPTS"
3072 fi
3073
3074 # Specific for NOGAP is the use of lame. Another encoder fails...
3075 if [ "$NOGAP" = "y" ] && [ ! "$MP3ENCODER" = "lame" ]; then
3076 log warning "the NOGAP option is specific of lame. Deactivating..."
3077 NOGAP=n
3078 fi
3079
3080 # Options for mkcue
3081 case "$CUEREADERSYNTAX" in
3082 default|mkcue)
3083 CUEREADEROPTS="${CDROM}"
3084 CUEREADER="$MKCUE"
3085 ;;
3086 esac
3087
3088 # which information retrieval tool are we using?
3089 case "$CDDBTOOL" in
3090 cddb) ;;
3091 musicbrainz) ;;
3092 esac
3093
3094 # Check if both OGGEOUTPUTCONTAINER and FLACOUTPUTCONTAINER are the same, and differentiante them
3095 if [ X"$OGGOUTPUTCONTAINER" = "Xogg" ] && [ X"$FLACOUTPUTCONTAINER" = "Xogg" ]; then
3096 log error "FLAC on an Ogg container is not yet supported"
3097 log error "due to problem with adding comments to such files"
3098 exit 1
3099 OGGOUTPUTCONTAINER=ogg.ogg
3100 FLACOUTPUTCONTAINER=flac.ogg
3101 vecho warning "modified file endings due to conflicting transport layers in Ogg/Vorbis and Ogg/FLAC"
3102 fi
3103
3104 # Clean up nice options (either use '-n NICELEVEL or -NICELEVEL')
3105
3106 if [ "$ENCNICE" ]; then
3107 ENCNICE="-n $ENCNICE"
3108 fi
3109 if [ "$READNICE" ]; then
3110 READNICE="-n $READNICE"
3111 fi
3112 if [ "$DISTMP3NICE" ]; then
3113 DISTMP3NICE="-n $DISTMP3NICE"
3114 fi
3115
3116 # Don't check for stuff if it's not needed
3117 if [ "$REMOTEHOSTS" ]; then
3118 NEEDDISTMP3=y
3119 fi
3120 if [ "$DONORMALIZE" = "y" ]; then
3121 NEEDNORMALIZER=y
3122 fi
3123 if [ "$EJECTCD" = "y" ]; then
3124 NEEDEJECT=y
3125 fi
3126 if [ ! "$CDDBAVAIL" = "n" ] && [ "$DOCDDB" = "y" ]; then
3127 if [ "$CDDBMETHOD" = "cddb" ]; then
3128 NEEDHTTPGET=y
3129 elif [ "$CDDBMETHOD" = "musicbrainz" ]; then
3130 :
3131 fi
3132 fi
3133 if [ "$MAKECUEFILE" = "y" ]; then
3134 NEEDCUEREADER=y
3135 fi
3136
3137 if [ X"$CDSPEEDVALUE" != "X" ]; then
3138 case "$CDROMREADERSYNTAX" in
3139 cdparanoia|debug) CDROMREADEROPTS="$CDPARANOIAOPTS -S $CDSPEEDVALUE" ;;
3140 ### FIXME ### translate "cue2discid" from python to bash
3141 flac) NEEDMETAFLAC=y ; NEEDCUE2DISCID=y ;;
3142 *) NEEDCDSPEED=y ;;
3143 esac
3144 fi
3145
3146 ###USEPIPESSUPPORT###
3147
3148 # Rippers with USEPIPE support
3149 # FIXME # Include here all the rippers we can figure out support pipes
3150 PIPERIPPER_cdparanoia="-"
3151 PIPERIPPER_debug="-"
3152 PIPERIPPER_flac="-c "
3153
3154 # Encoders with USEPIPE support
3155 # FIXME # Include here all the encoders we can figure out support pipes
3156 PIPE_lame="-"
3157 PIPE_bladeenc="-"
3158 PIPE_oggenc="-"
3159 PIPE_flac="-"
3160
3161 # Figure out if we can use pipes with the ripper/encoder combination
3162 # exit otherwise
3163 if [ "$USEPIPES" = "y" ]; then
3164 PIPERIPPERSVARCHECK="PIPERIPPER_${CDROMREADERSYNTAX}"
3165 case "$OUTPUT" in
3166 mp3)
3167 PIPEENCODERSVARCHECK="PIPE_$MP3ENCODERSYNTAX" ;;
3168 vorbis|ogg)
3169 PIPEENCODERSVARCHECK="PIPE_$OGGENCODERSYNTAX" ;;
3170 flac)
3171 PIPEENCODERSVARCHECK="PIPE_$FLACENCODERSYNTAX" ;;
3172 spx)
3173 PIPEENCODERSVARCHECK="PIPE_$SPEEXENCODER" ;;
3174 mpc)
3175 PIPEENCODERSVARCHECK="PIPE_$MPPENCODER" ;;
3176 esac
3177 decho "PIPERIPPERSVARCHECK: $( eval echo "\$$PIPERIPPERSVARCHECK" )"
3178 if [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "$" ] || \
3179 [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "" ] ; then
3180 log error "no support for pipes with given ripper"
3181 log error "read the USEPIPES file from the source tarball to get help."
3182 log error "On a Debian system, it is under /usr/share/doc/abcde/USEPIPES.gz"
3183 exit 1;
3184 fi
3185 decho "PIPEENCODERSVARCHECK: $( eval echo "\$$PIPEENCODERSVARCHECK" )"
3186 if [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "$" ] || \
3187 [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "" ] ; then
3188 log error "no support for pipes with given encoder"
3189 log error "read the USEPIPES file from the source tarball to help"
3190 log error "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz"
3191 exit 1;
3192 fi
3193 fi
3194
3195 # Make sure a buncha things exist
3196 for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
3197 $OGGENCODER $FLACENCODER $SPEEXENCODER $MPPENCODER \
3198 ${NEEDHTTPGET+$HTTPGET} ${NEEDDISTMP3+$DISTMP3} \
3199 ${NEEDCOMMENTER+$VORBISCOMMENT} ${NEEDMETAFLAC+$METAFLAC} \
3200 ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
3201 ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} \
3202 ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMP3GAIN+$MP3GAIN} \
3203 ${NEEDMPPGAIN+$MPPGAIN} \
3204 ${NEEDCUEREADER+$CUEREADER} ${NEEDCUE2DISCID+$CUE2DISCID}
3205 do
3206 # Cut off the command-line options we just added in
3207 X=$(echo $X | cut -d' ' -f2)
3208 if [ "$(which $X)" = "" ]; then
3209 log error "$X is not in your path." >&2
3210 exit 1
3211 elif [ ! -x $(which $X) ]; then
3212 log error "$X is not executable." >&2
3213 exit 1
3214 fi
3215 done
3216
3217 CDROMREADER="$CDROMREADER $CDROMREADEROPTS"
3218 CDDBTOOL="$CDDBTOOL $CDDBTOOLOPTS"
3219 HTTPGET="$HTTPGET $HTTPGETOPTS"
3220
3221 # And last but not least, check if we can diff between files
3222 if [ -x $(which $DIFF) ]; then :; else
3223 vecho warning "Disabling diff since we cannot find it in the \$PATH..."
3224 DIFF=""
3225 fi
3226
3227 # Here it used to say:
3228 # One thousand lines in, we can start doing stuff with things
3229 # Well, right now we are at line 2736 ;)
3230
3231 # Export needed things so they can be read in this subshell
3232 export CDDBTOOL ABCDETEMPDIR TRACKQUEUE LOWDISK EJECTCD EJECT EJECTOPTS
3233 export CDROM CDDBDATA REMOTEHOSTS MAXPROCS HTTPGET MD5SUM
3234
3235 if [ "$DOREAD" = "y" ]; then
3236 # User-definable function to set some things. Use it for
3237 # - closing the CD tray with eject -t
3238 # - set the CD speed value with eject -x
3239 vecho -n "Executing customizable pre-read function... "
3240
3241 pre_read # Execute the user-defined pre-read funtion. Close the CD with it.
3242
3243 vecho "done."
3244 fi
3245
3246 case "$CDDBMETHOD" in
3247 cddb)
3248 do_discid # Get ABCDETEMPDIR created and status file initialized
3249 ;;
3250 musicbrainz)
3251 do_musicbrainz
3252 ;;
3253 esac
3254
3255 if [ "$DOCDDB" = "y" ]; then
3256 if [ $CDDBUSELOCAL = "y" ]; then
3257 do_localcddb
3258 fi
3259 if checkstatus cddb-choice > /dev/null; then
3260 :
3261 else
3262 if [ ! "$CDDBLOCALSUCCESS" = "y" ] ; then
3263 case "$CDDBMETHOD" in
3264 cddb)
3265 do_cddbstat
3266 do_cddbquery
3267 do_cddbread
3268 ;;
3269 musicbrainz)
3270 do_musicbrainz
3271 ;;
3272 esac
3273 fi
3274 fi
3275 do_cddbedit
3276
3277 eval "$($CDDBTOOL parse "$CDDBDATA")"
3278 fi
3279
3280 # Before reading tracks, we set the speed of the device
3281
3282 if [ X"$CDSPEEDVALUE" != "X" ]; then
3283 case "$CDROMREADERSYNTAX" in
3284 cdparanoia|debug) ;;
3285 flac) ;;
3286 *) do_cdspeed ;;
3287 esac
3288 fi
3289
3290 # Define the first and last track, since we might need them later in several places
3291 FIRSTTRACK=$( get_first $TRACKQUEUE )
3292 LASTTRACK=$( get_last $TRACKQUEUE )
3293
3294 if [ -f "$ABCDETEMPDIR/status" ] && [ X"$ERASEENCODEDSTATUS" = "Xy" ]; then
3295 mv "$ABCDETEMPDIR/status" "$ABCDETEMPDIR/status.old"
3296 grep -v ^encodetracklocation- < "$ABCDETEMPDIR/status.old" \
3297 | grep -v ^encode-output > "$ABCDETEMPDIR/status"
3298 fi
3299
3300 # Create playlist if needed (backgroundable) and start reading in tracks
3301
3302 (
3303
3304 if [ ! "$ONETRACK" = "y" ]; then
3305 if [ "$DOPLAYLIST" = "y" ]; then
3306 echo Creating playlist... >&2
3307 do_playlist
3308 fi
3309 fi
3310
3311 # For the lowdisk option, only one program is running at once so the encoder
3312 # can be unsilenced right away.
3313 if [ "$LOWDISK" = "y" ] || [ "$ONETRACK" = "y" ]; then
3314 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3315 fi
3316
3317 if [ "$ONETRACK" = "y" ]; then
3318 TRACKS="$FIRSTTRACK"
3319 if checkstatus readtrack-$FIRSTTRACK; then :; else
3320 if [ "$USEPIPES" = "y" ]; then
3321 do_cdread onetrack $FIRSTTRACK $LASTTRACK | do_encode $FIRSTTRACK %local0% > /dev/null 2>&1
3322 else
3323 do_cdread onetrack $FIRSTTRACK $LASTTRACK
3324 fi
3325 fi
3326 else
3327 for UTRACKNUM in $TRACKQUEUE
3328 do
3329 if [ "$DOREAD" = "y" ]; then
3330 if [ "$USEPIPES" = "y" ]; then
3331 if checkstatus readencodetrack-$UTRACKNUM; then :; else
3332 # Read, pipe, shut up!
3333 do_cdread $UTRACKNUM | do_encode $UTRACKNUM %local0% > /dev/null 2>&1
3334 fi
3335 else
3336 if checkstatus readtrack-$UTRACKNUM; then :; else
3337 do_cdread $UTRACKNUM
3338 fi
3339 if [ "$?" != "0" ]; then
3340 # CD read failed - don't give the goahead to
3341 # the encoder
3342 echo NO
3343 exit
3344 fi
3345 fi
3346 fi
3347 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ]; then
3348 :
3349 else
3350 # If we are not reading, set the encode output to loud already, so
3351 # that we can see the output of the first track.
3352 if [ "$MAXPROCS" = "1" ] && [ ! "$DOREAD" = "y" ]; then
3353 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3354 fi
3355 echo NEXTTRACK # Get the encoder machine churning again
3356 if [ "$DOREAD" = "y" ]; then
3357 if [ "$LOWDISK" = "y" ] && [ "$DOENCODE" = "y" ]; then
3358 until checkstatus encodetrack-$UTRACKNUM
3359 do
3360 if checkerrors encodetrack-$UTRACKNUM; then
3361 break
3362 fi
3363 sleep 2
3364 done
3365 fi
3366 fi
3367 fi
3368 done
3369 fi
3370
3371 # Now that we're done the encoding can be loud again -
3372 # if we're not using SMP.
3373 if [ "$MAXPROCS" = "1" ]; then
3374 echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
3375 fi
3376
3377 # All tracks read, start encoding.
3378 if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ] || [ "$ONETRACK" = "y" ]; then
3379 echo NEXTTRACK
3380 fi
3381
3382 # Execute the user-defined post_read funtion before ejecting CD
3383 post_read
3384
3385 # We are now finished with the cdrom - it can be safely ejected. Note that
3386 # abcde will not have completed yet.
3387 if [ "$EJECTCD" = "y" ] && [ -x $(which $EJECT) ]; then
3388 # We check if the disk we are processing is actually the disk inside the
3389 # CD tray. If not, we do not eject the CD, since it might be so that the
3390 # user ejected it manually.
3391 #CURRENTTRACKINFO=$($CDDISCID $CDROM)
3392 #if if [ "$?" != "1" ] && [ "$CURRENTTRACKINFO" = "$TRACKINFO" ] ; then
3393 # More FreeBSD bits.
3394 if [ X"$(uname)" = X"FreeBSD" ] ; then
3395 # FreeBSD eject uses the EJECT environment variable to name the CDROM
3396 # but in this script EJECT is in the envionment and names the program
3397 eject=$EJECT
3398 unset EJECT
3399 # The FreeBSD eject needs "adc0" not "/dev/adc0c"
3400 cd="$(echo $CDROM | sed -e 's=.*/==;s=[a-h]$==;')"
3401 $eject $EJECTOPTS $cd
3402 elif [ X"$(uname)" = X"Darwin" ] ; then
3403 disktool -e ${CDROM#/dev/} 0
3404 else
3405 $EJECT $EJECTOPTS $CDROM
3406 fi
3407 #fi
3408 fi
3409
3410 ) | (
3411
3412 ## Do we need to pre-process
3413 #if [ x"$PREPROCESS" = "x" ] ; then
3414 # cat
3415 #else
3416 # for PRETRACKNUM in $TRACKQUEUE
3417 # do
3418 # read GOAHEAD
3419 # if [ "$GOAHEAD" = "NO" ]; then break; fi
3420 # PREPROCEED=
3421 # until [ $PREPROCEED ]
3422 # do
3423 # if checkstatus readtrack-$PRETRACKNUM; then PREPROCEED=y; break; fi
3424 # # all locations are working, wait and try again later
3425 # if [ ! $PREPROCEED ]; then sleep 3; fi
3426 # done
3427 # ( do_preprocess $PRETRACKNUM
3428 # echo "NEXTTRACK"
3429 # ) &
3430 # done
3431 #fi
3432 #
3433 #) | (
3434
3435 # In BATCHNORM and/or NOGAP modes, we want all tracks to be read first.
3436 #BACK
3437 if [ "$BATCHNORM" = "y" ] || [ "$NOGAP" = "y" ]; then
3438 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
3439 if [ "$GOAHEAD" = "NO" ]; then break; fi
3440 for LASTTRACK in $TRACKQUEUE; do :; done
3441 if checkstatus readtrack-$LASTTRACK; then
3442 if [ "$DONORMALIZE" = "y" ] && [ "$BATCHNORM" = "y" ]; then
3443 if checkstatus normalizetrack-$LASTTRACK; then :; else do_batch_normalize; fi
3444 if checkerrors batch-normalize; then exit 1; fi
3445 fi
3446 if [ "$DOENCODE" = "y" ] && [ "$NOGAP" = "y" ]; then
3447 if [ "$DONORMALIZE" = "y" ]; then
3448 for UTRACKNUM in $TRACKQUEUE
3449 do
3450 if checkstatus readtrack-$UTRACKNUM; then
3451 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
3452 fi
3453 done
3454 fi
3455 if checkstatus encodetrack-$LASTTRACK; then :; else do_nogap_encode; fi
3456 if checkerrors nogap-encode; then exit 1; fi
3457 fi
3458 fi
3459 fi
3460
3461 # If we are using ONETRACK, we can proceed with the normal encoding using just the $FIRSTTRACK as TRACKQUEUE
3462 if [ "$ONETRACK" = "y" ] ; then
3463 TRACKQUEUE="$FIRSTTRACK"
3464 TRACKS="$FIRSTTRACK"
3465 fi
3466
3467 # Do the encoding, including parallelization of remote encoding
3468 # Figure out where each track is going to be encoded
3469 ENCODELOCATIONS="$(echo $REMOTEHOSTS | tr , ' ')"
3470 if [ "$MAXPROCS" != "0" ]; then
3471 for NUM in $(f_seq_row 1 "$MAXPROCS")
3472 do
3473 ENCODELOCATIONS="$ENCODELOCATIONS %local$NUM%"
3474 done
3475 fi
3476 # Strip whitespace
3477 ENCODELOCATIONS=$(echo $ENCODELOCATIONS)
3478 for UTRACKNUM in $TRACKQUEUE
3479 do
3480 # Wait for our cue
3481 read GOAHEAD # For blocking - will contain either "NO" or "NEXTTRACK"
3482 if [ "$GOAHEAD" = "NO" ]; then break; fi
3483 # find out where this track is to be encoded
3484 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
3485 # Make sure we have a place to encode this, if not, exit stage right
3486 if [ -z "$ENCODELOCATIONS" ]; then
3487 continue
3488 fi
3489 PROCEED=
3490 until [ $PROCEED ]
3491 do
3492 for LOCATION in $ENCODELOCATIONS
3493 do
3494 PREVIOUSTRACK="$(checkstatus encodetracklocation-$LOCATION)"
3495 # check first if a track has ever been assigned to this location
3496 if [ -z "$PREVIOUSTRACK" ]; then PROCEED=y; break; fi
3497 # If it errored out, rebuild $ENCODELOCATIONS without this location in it
3498 if checkerrors encodetrack-$PREVIOUSTRACK; then
3499 for TEMPLOCATION in $ENCODELOCATIONS
3500 do
3501 if [ "$TEMPLOCATION" != "$LOCATION" ]; then
3502 TEMPENCODELOCATIONS="$TEMPENCODELOCATIONS $TEMPLOCATION"
3503 fi
3504 done
3505 ENCODELOCATIONS=$(echo $TEMPENCODELOCATIONS)
3506 ABORT=y
3507 PROCEED=y
3508 break
3509 fi
3510 # We're still here, this location must have been previously assigned,
3511 # and last completed without error - check if it's done with the
3512 # previous track yet
3513 if checkstatus encodetrack-$PREVIOUSTRACK; then PROCEED=y; break; fi
3514 done
3515 # all locations are working, wait and try again later
3516 if [ ! $PROCEED ]; then sleep 3; fi
3517 done
3518 # Record the location we're about to encode the next track at
3519 echo "encodetracklocation-$LOCATION=$UTRACKNUM" >> "$ABCDETEMPDIR/status"
3520 fi
3521 # Don't proceed with the rest of the loop if we can't encode
3522 if [ "$ABORT" ]; then continue; fi
3523 # Set TRACKNUM, TRACKNAME
3524 if [ -e "$CDDBDATA" ]; then
3525 if [ "$ONETRACK" = "y" ]; then
3526 TRACKNAME="$DALBUM"
3527 TRACKNUM="$FIRSTTRACK"
3528 splitvarious
3529 else
3530 TRACKNUM=$UTRACKNUM
3531 CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
3532 do_getcddbinfo TRACKNAME
3533 splitvarious
3534 fi
3535 fi
3536 # You can't encode a file which needs to be normalized before finishing
3537 # You can't tag a file before it's finished encoding -
3538 # thus all of this is backgrounded together
3539 (
3540 if [ "$DONORMALIZE" = "y" ]; then
3541 if checkstatus readtrack-$UTRACKNUM; then
3542 if checkstatus normalizetrack-$UTRACKNUM; then :; else do_normalize $UTRACKNUM; fi
3543 fi
3544 fi
3545 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
3546 if checkstatus readtrack-$UTRACKNUM; then
3547 #if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION; fi
3548 if [ "$DONORMALIZE" = "y" ]; then
3549 if checkstatus normalizetrack-$UTRACKNUM; then
3550 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
3551 fi
3552 else
3553 if checkstatus encodetrack-$UTRACKNUM; then :; else do_encode $UTRACKNUM $LOCATION $OUTPUT; fi
3554 fi
3555 fi
3556 fi
3557 if [ "$DOTAG" = "y" ]; then
3558 if checkstatus encodetrack-$UTRACKNUM; then
3559 if checkstatus tagtrack-$UTRACKNUM; then :; else do_tag $UTRACKNUM; fi
3560 fi
3561 # Lets tag the cue file
3562 if checkstatus cleancuefile >/dev/null; then :; else
3563 if checkstatus cuefile >/dev/null ; then
3564 do_cleancue
3565 fi
3566 fi
3567 fi
3568 if [ "$DOMOVE" = "y" ]; then
3569 if checkstatus tagtrack-$UTRACKNUM; then
3570 if checkstatus movetrack-$UTRACKNUM; then :; else do_move $UTRACKNUM; fi
3571 fi
3572 fi
3573 ) &
3574 done
3575
3576
3577 # Go through it again and make sure there's no distmp3 stragglers, otherwise
3578 # we'll delete the files they're working on
3579 ## FIXME ## Check also for files which are encoded using PIPEs.
3580 if [ "$DOENCODE" = "y" -a "$USEPIPES" != "y" ]; then
3581 PROCEED=
3582 until [ $PROCEED ]
3583 do
3584 PROCEED=y
3585 for LOCATION in $ENCODELOCATIONS
3586 do
3587 CHECKTRACK="$(checkstatus encodetracklocation-$LOCATION)"
3588 # "How can he give us a status update, if he's DEAD?"
3589 if checkstatus encodetrack-$CHECKTRACK; then
3590 continue
3591 fi
3592 # Nothing to see here please go quietly back to your homes
3593 if [ -z "$CHECKTRACK" ]; then continue; fi
3594 # You're still here? Maybe there is something...
3595 if checkstatus encodetrack-$CHECKTRACK; then :; else PROCEED= ; break; fi
3596 done
3597 # hold up
3598 if [ ! $PROCEED ]; then sleep 5; fi
3599 done
3600 fi
3601 # If the above didn't catch the stragglers, this will
3602 wait
3603 if [ "$DOREPLAYGAIN" = "y" ]; then
3604 do_replaygain
3605 fi
3606
3607 # Check to see if run_command logged any errors
3608 if [ -f "$ABCDETEMPDIR/errors" ]; then
3609 log error "The following commands failed to run:"
3610 cat "$ABCDETEMPDIR/errors"
3611 # Don't clean up
3612 DOCLEAN=n
3613 fi
3614 if [ "$KEEPWAVS" = "y" ];then
3615 # Don't clean up
3616 DOCLEAN=n
3617 fi
3618 # Check if we have moved all the formats we had previously encoded, if we are not using the FORCE.
3619 if [ "$DOCLEAN" = "y" ] && [ ! "$FORCE" = "y" ]; then
3620 ENCODED_FORMATS=$(egrep "^encodetrack-(.{3,6})-(.{1,2})$" "$ABCDETEMPDIR/status" | cut -d"-" -f2 | sort -u | tr '\n' '|')
3621 MOVED_FORMATS=$(egrep "^movetrack-output-(.{3,6})$" "$ABCDETEMPDIR/status" | cut -d"-" -f3 | sort -u | tr '\n' '|')
3622 if [ "$ENCODED_FORMATS" != "$MOVED_FORMATS" ]; then
3623 log warning "The encoded formats does not match with the moved ones"
3624 log warning "Formats encoded: $( echo $ENCODED_FORMATS | tr "|" " " )"
3625 log warning "Formats moved: $( echo $MOVED_FORMATS | tr "|" " " )"
3626 log warning "Use \"abcde -a clean -f -C $DISCID\" to force the removal of the remaining data."
3627 DOCLEAN=n
3628 fi
3629 fi
3630 if [ "$DOCLEAN" = "y" ]; then
3631 # Wipe all the evidence
3632 # Gimme gimme gimme some more time!
3633 sleep 5
3634 rm -rf "$ABCDETEMPDIR"
3635 echo "Finished."
3636 else
3637 echo "Finished. Not cleaning $ABCDETEMPDIR."
3638 fi
3639 )
3640 exit 0
3641
3642 # b:is_bash
3643 # vim:tabstop=4