]>
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> I<track-count>
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.
76 verbose
("Renaming $dir/tags\n");
77 rename("$dir/tags", "$dir/using-tags")
78 or die("rename($dir/tags, $dir/using-tags): $!");
80 ($artist, $album, @tags) = get_tags
("$dir/using-tags");
82 verbose
("mkdir($artist)\n");
83 -d
$artist or mkdir($artist) or die("mkdir($artist): $!");
85 verbose
("chdir($dir)\n");
86 chdir($dir) or die("chdir($dir): $!");
96 verbose
("Running flac\n");
97 $status = system('flac', '-o', "../$artist/$outfile.flac-tmp",
98 '--delete-input-file', '-V', '--cuesheet',
99 'cue', '--no-padding', '--best',
100 map({ ('-T', $_) } @tags),
102 if (WIFEXITED
($status) and ($status = WEXITSTATUS
($status)) != 0) {
103 die("flac: $status");
104 } elsif (WIFSIGNALED
($status)) {
105 die("flac killed with signal ", WTERMSIG
($status));
106 } elsif (WIFSTOPPED
($status)) {
107 die("flac stopped with signal ", WSTOPSIG
($status));
110 verbose
("Cleaning up $dir\n");
111 unlink('using-tags') or die("unlink(using-tags): $!");
112 unlink('cue') or die("unlink(cue): $!");
113 rename('toc', "../$artist/$outfile.toc")
114 or die("rename(toc, ../$artist/$outfile.toc): $!");
115 rename('log', "../$artist/$outfile.log")
116 or die("rename(log, ../$artist/$outfile.log): $!");
117 chdir('..') or die("chdir(..): $!");
118 rmdir($dir) or die("rmdir($dir): $!");
120 rename("$artist/$outfile.flac-tmp", "$artist/$outfile.flac")
121 or die("rename($artist/$outfile.flac-tmp, $artist/$outfile.flac): $!");
129 while (($pid = waitpid(-1, WNOHANG
)) > 0) {
130 push(@finished, [$pid, $?]);
133 $SIG{CHLD
} = \
&reaper
;
141 if (not defined($pid)) {
143 } elsif ($pid == 0) {
144 $SIG{CHLD
} = 'IGNORE';
145 open(STDERR
, ">$dir/log") or die("open(STDERR, >$dir/log): $!");
149 verbose
("new job $pid for $dir\n");
159 $pid = $finished[$i][0];
160 $status = $finished[$i][1];
162 verbose
("$pid finished (");
163 if (WIFEXITED
($status)) {
164 verbose
('exited ', WEXITSTATUS
($status));
165 } elsif (WIFSIGNALED
($status)) {
166 verbose
('signalled ', WTERMSIG
($status));
167 } elsif (WIFSTOPPED
($status)) {
168 verbose
('stopped ', WSTOPSIG
($status));
172 for ($j = 0; $j <= $#jobs; $j++) {
173 $pid == $jobs[$j] and splice(@jobs, $j, 1) and last;
176 splice(@finished, $i, 1);
185 $SIG{CHLD
} = \
&reaper
;
187 if (scalar(@jobs) <= $MAXJOBS) {
188 foreach $i (glob('*/tags')) {
189 push(@jobs, newjob
(dirname
($i))) <= $MAXJOBS or last;
193 for ($i = 0; $i <= $#finished; $i++) {
197 verbose
(scalar(@jobs), " jobs\n");
207 if (not getopts
('j:v', \
%opts)) {
208 print(STDERR
"usage: flacd [-jN -v]\n");
212 $verbose = $opts{'v'};
214 flacloop
($opts{'j'});
222 B<fa-flacd>, B<fa-rip>, and B<fa-tags> together comprise
223 B<flac-archive>, a system for archiving audio CDs to single FLAC
224 files. B<fa-flacd> is the guts of the system. It runs in the
225 directory where the audio archives are stored, scanning for new CDs to
226 encode and rename; it never exits. B<fa-rip> generates the inputs for
227 B<fa-flacd>: the ripped WAV file, Vorbis tags, and a cuesheet.
228 B<fa-tags> is not meant to be run directly; B<fa-rip> uses it to
229 generate the candidate Vorbis tags.
231 All three programs expect to be run from the same directory. They use
232 that directory to manage directories named by artist and by disc ID.
233 Intermediate files are written to the disc ID directory. B<fa-flacd>
234 processes the disc ID directories into per-album files in the artist
239 B<fa-flacd> does not exit; it runs until the user kills it. Every 5
240 seconds it scans its current directory for directories with a file
241 called "tags" and creates a processing job for each one. The number
242 of jobs B<fa-flacd> attempts to run is controlled by the B<-j> option
243 and defaults to 4. B<fa-flacd> will print diagnostic output when the
244 B<-v> option is given.
246 A processing job first renames the directory's "tags" file to
247 "using-tags" so that B<ra-flacd> will not try to start another job for
248 this directory. This file is left as is when an error is encountered,
249 so a new job will not be started until the user corrects the error
250 condition and renames "using-tags" back to "tags". Next, it encodes
251 the "wav" file to a FLAC file, using the "cue" file for the cuesheet
252 and "using-tags" for Vorbis tags. Any diagnostic output is saved in
253 the "log" file. Finally, the "cue" and "log" files are moved to the
254 artist directory (and named by album) and the ID directory is removed.
258 B<fa-rip> uses C<mktemp(1)> to create a directory for storage of its
259 intermediate files. It uses C<cdrdao(1)> to create the "cue" file and
260 then passes the number of tracks (from the "cue" file) as command-line
261 arguments to B<fa-tags>. Finally, it execs C<cdparanoia(1)> to rip
262 the CD to the "wav" file.
264 In order for this CD to be processed by B<fa-flacd>, the user must
265 create a "tags" file. This is usually done by renaming one of the
266 candidate-tags files and deleting the others.
270 B<fa-tags> uses C<MusicBrainz::Client> to populate candidate-tags
271 files. These are numbered in the order of entries read from
272 MusicBrainz, e.g. candidate-tags-1, candidate-tags-2, etc. B<fa-tags>
273 also creates candidate-tags-0, which has the correct fields for this
274 CD (including correct number of TITLE= lines), but with all fields
277 B<fa-tags> requires the number of tracks as its sole argument.
285 B<fa-rip> uses this to rip audio and save the cuesheet for a CD. It
286 makes some effort to check some common device names for FreeBSD,
287 Linux, and NetBSD by default.
293 Written by Eric Gillespie <epg@pretzelnet.org>.
295 flac-archive is free software; you may redistribute it and/or modify
296 it under the same terms as Perl itself.
301 # cperl-indent-level: 4
302 # perl-indent-level: 4
303 # indent-tabs-mode: nil
306 # vi: set tabstop=4 expandtab: