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