]>
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): $!");
91 verbose
("Running flac\n");
92 $status = system('flac', '-o', "../$artist/$outfile.flac-tmp",
93 '--delete-input-file', '-V', '--cuesheet',
94 'cue', '--no-padding', '--best',
95 map({ ('-T', $_) } @tags),
97 if (WIFEXITED
($status) and ($status = WEXITSTATUS
($status)) != 0) {
99 } elsif (WIFSIGNALED
($status)) {
100 die("flac killed with signal ", WTERMSIG
($status));
101 } elsif (WIFSTOPPED
($status)) {
102 die("flac stopped with signal ", WSTOPSIG
($status));
105 verbose
("Cleaning up $dir\n");
106 unlink('using-tags') or die("unlink(using-tags): $!");
107 unlink('cue') or die("unlink(cue): $!");
108 rename('log', "../$artist/$outfile.log")
109 or die("rename(log, ../$artist/$outfile.log): $!");
110 chdir('..') or die("chdir(..): $!");
111 rmdir($dir) or die("rmdir($dir): $!");
113 rename("$artist/$outfile.flac-tmp", "$artist/$outfile.flac")
114 or die("rename($artist/$outfile.flac-tmp, $artist/$outfile.flac): $!");
122 while (($pid = waitpid(-1, WNOHANG
)) > 0) {
123 push(@finished, [$pid, $?]);
126 $SIG{CHLD
} = \
&reaper
;
134 if (not defined($pid)) {
136 } elsif ($pid == 0) {
137 $SIG{CHLD
} = 'IGNORE';
138 open(STDERR
, ">$dir/log") or die("open(STDERR, >$dir/log): $!");
142 verbose
("new job $pid for $dir\n");
152 $pid = $finished[$i][0];
153 $status = $finished[$i][1];
155 verbose
("$pid finished (");
156 if (WIFEXITED
($status)) {
157 verbose
('exited ', WEXITSTATUS
($status));
158 } elsif (WIFSIGNALED
($status)) {
159 verbose
('signalled ', WTERMSIG
($status));
160 } elsif (WIFSTOPPED
($status)) {
161 verbose
('stopped ', WSTOPSIG
($status));
165 for ($j = 0; $j <= $#jobs; $j++) {
166 $pid == $jobs[$j] and splice(@jobs, $j, 1) and last;
169 splice(@finished, $i, 1);
178 $SIG{CHLD
} = \
&reaper
;
180 if (scalar(@jobs) <= $MAXJOBS) {
181 foreach $i (glob('*/tags')) {
182 push(@jobs, newjob
(dirname
($i))) <= $MAXJOBS or last;
186 for ($i = 0; $i <= $#finished; $i++) {
190 verbose
(scalar(@jobs), " jobs\n");
200 if (not getopts
('j:v', \
%opts)) {
201 print(STDERR
"usage: flacd [-jN -v]\n");
205 $verbose = $opts{'v'};
207 flacloop
($opts{'j'});
215 B<fa-flacd>, B<fa-rip>, and B<fa-tags> together comprise
216 B<flac-archive>, a system for archiving audio CDs to single FLAC
217 files. B<fa-flacd> is the guts of the system. It runs in the
218 directory where the audio archives are stored, scanning for new CDs to
219 encode and rename; it never exits. B<fa-rip> generates the inputs for
220 B<fa-flacd>: the ripped WAV file, Vorbis tags, and a cuesheet.
221 B<fa-tags> is not meant to be run directly; B<fa-rip> uses it to
222 generate the candidate Vorbis tags.
224 All three programs expect to be run from the same directory. They use
225 that directory to manage directories named by artist and by disc ID.
226 Intermediate files are written to the disc ID directory. B<fa-flacd>
227 processes the disc ID directories into per-album files in the artist
232 B<fa-flacd> does not exit; it runs until the user kills it. Every 5
233 seconds it scans its current directory for directories with a file
234 called "tags" and creates a processing job for each one. The number
235 of jobs B<fa-flacd> attempts to run is controlled by the B<-j> option
236 and defaults to 4. B<fa-flacd> will print diagnostic output when the
237 B<-v> option is given.
239 A processing job first renames the directory's "tags" file to
240 "using-tags" so that B<ra-flacd> will not try to start another job for
241 this directory. This file is left as is when an error is encountered,
242 so a new job will not be started until the user corrects the error
243 condition and renames "using-tags" back to "tags". Next, it encodes
244 the "wav" file to a FLAC file, using the "cue" file for the cuesheet
245 and "using-tags" for Vorbis tags. Any diagnostic output is saved in
246 the "log" file. Finally, the "cue" and "log" files are moved to the
247 artist directory (and named by album) and the ID directory is removed.
251 B<fa-rip> uses C<mktemp(1)> to create a directory for storage of its
252 intermediate files. It uses C<cdrdao(1)> to create the "cue" file and
253 then passes the number of tracks (from the "cue" file) as command-line
254 arguments to B<fa-tags>. Finally, it execs C<cdparanoia(1)> to rip
255 the CD to the "wav" file.
257 In order for this CD to be processed by B<fa-flacd>, the user must
258 create a "tags" file. This is usually done by renaming one of the
259 candidate-tags files and deleting the others.
263 B<fa-tags> uses C<MusicBrainz::Client> to populate candidate-tags
264 files. These are numbered in the order of entries read from
265 MusicBrainz, e.g. candidate-tags-1, candidate-tags-2, etc. B<fa-tags>
266 also creates candidate-tags-0, which has the correct fields for this
267 CD (including correct number of TITLE= lines), but with all fields
270 B<fa-tags> requires the number of tracks as its sole argument.
278 B<fa-rip> uses this to rip audio and save the cuesheet for a CD. It
279 makes some effort to check some common device names for FreeBSD,
280 Linux, and NetBSD by default.
286 Written by Eric Gillespie <epg@pretzelnet.org>.
288 flac-archive is free software; you may redistribute it and/or modify
289 it under the same terms as Perl itself.
294 # cperl-indent-level: 4
295 # perl-indent-level: 4
296 # indent-tabs-mode: nil
299 # vi: set tabstop=4 expandtab: