]>
diplodocus.org Git - flac-archive/blob - fa-flacd
7 B<fa-flacd>, B<fa-rip>, B<fa-tags> - archive CDs to single FLAC files
15 B<fa-tags> ID TRACKCOUNT OFFSET [OFFSET ...] LENGTH
23 use Getopt
::Std
; $Getopt::Std
::STANDARD_HELP_VERSION
= 1;
24 use POSIX
':sys_wait_h';
33 $verbose and print(STDERR
$_) for @_;
36 # Return the ARTIST, ALBUM, and DATE followed by a list of all the
37 # lines in the file FN.
46 verbose
("Opening tags file $fn\n");
47 open(TAGS
, $fn) or die("open($fn): $!");
52 ($tag, $value) = split(/=/, $_, 2);
56 verbose
("ARTIST $artist from $fn\n");
59 verbose
("ALBUM $album from $fn\n");
62 close(TAGS
) or die("close($fn): $!");
64 return ($artist, $album, @tags);
67 # Process the fa-rip output in the directory DIR.
75 verbose
("Renaming $dir/tags\n");
76 rename("$dir/tags", "$dir/using-tags")
77 or die("rename($dir/tags, $dir/using-tags): $!");
79 ($artist, $album, @tags) = get_tags
("$dir/using-tags");
81 verbose
("mkdir($artist)\n");
82 -d
$artist or mkdir($artist) or die("mkdir($artist): $!");
84 verbose
("chdir($dir)\n");
85 chdir($dir) or die("chdir($dir): $!");
87 verbose
("Running flac\n");
88 $status = system('flac', '-o', "../$artist/$album.flac-tmp",
89 '--delete-input-file', '-V', '--cuesheet',
90 'cue', '--no-padding', '--best',
91 map({ ('-T', $_) } @tags),
93 if (WIFEXITED
($status) and ($status = WEXITSTATUS
($status)) != 0) {
95 } elsif (WIFSIGNALED
($status)) {
96 die("flac killed with signal ", WTERMSIG
($status));
97 } elsif (WIFSTOPPED
($status)) {
98 die("flac stopped with signal ", WSTOPSIG
($status));
101 verbose
("Cleaning up $dir\n");
102 unlink('using-tags') or die("unlink(using-tags): $!");
103 unlink('cue') or die("unlink(cue): $!");
104 rename('toc', "../$artist/$album.toc")
105 or die("rename(toc, ../$artist/$album.toc): $!");
106 rename('log', "../$artist/$album.log")
107 or die("rename(log, ../$artist/$album.log): $!");
108 chdir('..') or die("chdir(..): $!");
109 rmdir($dir) or die("rmdir($dir): $!");
111 rename("$artist/$album.flac-tmp", "$artist/$album.flac")
112 or die("rename($artist/$album.flac-tmp, $artist/$album.flac): $!");
120 while (($pid = waitpid(0, WNOHANG
)) > 0) {
121 push(@finished, [$pid, $?]);
124 $SIG{CHLD
} = \
&reaper
;
132 if (not defined($pid)) {
134 } elsif ($pid == 0) {
135 $SIG{CHLD
} = 'IGNORE';
136 open(STDERR
, ">$dir/log") or die("open(STDERR, >$dir/log): $!");
140 verbose
("new job $pid for $dir\n");
150 $pid = $finished[$i][0];
151 $status = $finished[$i][1];
153 verbose
("$pid finished (");
154 if (WIFEXITED
($status)) {
155 verbose
('exited ', WEXITSTATUS
($status));
156 } elsif (WIFSIGNALED
($status)) {
157 verbose
('signalled ', WTERMSIG
($status));
158 } elsif (WIFSTOPPED
($status)) {
159 verbose
('stopped ', WSTOPSIG
($status));
163 for ($j = 0; $j <= $#jobs; $j++) {
164 $pid == $jobs[$j] and splice(@jobs, $j, 1) and last;
167 splice(@finished, $i, 1);
176 $SIG{CHLD
} = \
&reaper
;
178 if (scalar(@jobs) <= $MAXJOBS) {
179 foreach $i (glob('*/tags')) {
180 push(@jobs, newjob
(dirname
($i))) <= $MAXJOBS or last;
184 for ($i = 0; $i <= $#finished; $i++) {
188 verbose
(scalar(@jobs), " jobs\n");
198 if (not getopts
('j:v', \
%opts)) {
199 print("usage: flacd [-jN -v]\n");
203 $verbose = $opts{'v'};
205 flacloop
($opts{'j'});
213 B<fa-flacd>, B<fa-rip>, and B<fa-tags> together comprise
214 B<flac-archive>, a system for archiving audio CDs to single FLAC
215 files. B<fa-flacd> is the guts of the system. It runs in the
216 directory where the audio archives are stored, scanning for new CDs to
217 encode and rename; it never exits. B<fa-rip> generates the inputs for
218 B<fa-flacd>: the ripped WAV file, Vorbis tags, and a cuesheet.
219 B<fa-tags> is not meant to be run directly; B<fa-rip> uses it to
220 generate the candidate Vorbis tags.
222 All three programs expect to be run from the same directory. They use
223 that directory to manage directories named by artist and by disc ID.
224 Intermediate files are written to the disc ID directory. B<fa-flacd>
225 processes the disc ID directories into per-album files in the artist
230 B<fa-flacd> does not exit; it runs until the user kills it. Every 5
231 seconds it scans its current directory for directories with a file
232 called "tags" and creates a processing job for each one. The number
233 of jobs B<fa-flacd> attempts to run is controlled by the B<-j> option
234 and defaults to 4. B<fa-flacd> will print diagnostic output when the
235 B<-v> option is given.
237 A processing job first renames the directory's "tags" file to
238 "using-tags" so that B<ra-flacd> will not try to start another job for
239 this directory. This file is left as is when an error is encountered,
240 so a new job will not be started until the user corrects the error
241 condition and renames "using-tags" back to "tags". Next, it encodes
242 the "wav" file to a FLAC file, using the "cue" file for the cuesheet
243 and "using-tags" for Vorbis tags. Any diagnostic output is saved in
244 the "log" file. Finally, the "cue" and "log" files are moved to the
245 artist directory (and named by album) and the ID directory is removed.
249 B<fa-rip> uses C<cd-discid(1)> to retrieve the disc ID and track
250 information. It creates a directory named by ID for storage of its
251 intermediate files. It passes the C<cd-discid(1)> output as
252 command-line arguments to B<fa-tags> in the background. It then uses
253 C<cdrdao(1)> to create the "cue" file in the background. Finally, it
254 execs C<cdparanoia(1)> to rip the CD to the "wav" file.
256 In order for this CD to be processed by B<fa-flacd>, the user must
257 create a "tags" file. This is usually done by renaming one of the
258 candidate-tags files and deleting the others.
262 B<fa-tags> uses C<cddb-tool(1)> (from the B<abcde> package) to
263 populate candidate-tags files. These are numbered in the order of
264 entries read from CDDB, e.g. candidate-tags-1, candidate-tags-2, etc.
265 B<fa-tags> also creates candidate-tags-0, which has the correct fields
266 for this CD (including correct number of TITLE= lines), but with all
269 B<fa-tags> expects the output of C<cd-discid(1)> as command-line
270 arguments. That is, the disc ID, number of tracks, list of track
271 offsets, and total length of the CD in seconds.
279 B<fa-tags> uses this to retrieve candidate Vorbis tags. Defaults to
280 "http://freedb.freedb.org/~cddb/cddb.cgi".
284 B<fa-rip> uses this to rip audio and save the cuesheet for a CD. It
285 makes some effort to check some common device names for FreeBSD,
286 Linux, and NetBSD by default.
292 Written by Eric Gillespie <epg@pretzelnet.org>.
294 flac-archive is free software; you may redistribute it and/or modify
295 it under the same terms as Perl itself.
300 # cperl-indent-level: 4
301 # perl-indent-level: 4
302 # indent-tabs-mode: nil
305 # vi: set tabstop=4 expandtab: