]>
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('toc', "../$artist/$outfile.toc")
109 or die("rename(toc, ../$artist/$outfile.toc): $!");
110 rename('log', "../$artist/$outfile.log")
111 or die("rename(log, ../$artist/$outfile.log): $!");
112 chdir('..') or die("chdir(..): $!");
113 rmdir($dir) or die("rmdir($dir): $!");
115 rename("$artist/$outfile.flac-tmp", "$artist/$outfile.flac")
116 or die("rename($artist/$outfile.flac-tmp, $artist/$outfile.flac): $!");
124 while (($pid = waitpid(-1, WNOHANG
)) > 0) {
125 push(@finished, [$pid, $?]);
128 $SIG{CHLD
} = \
&reaper
;
136 if (not defined($pid)) {
138 } elsif ($pid == 0) {
139 $SIG{CHLD
} = 'IGNORE';
140 open(STDERR
, ">$dir/log") or die("open(STDERR, >$dir/log): $!");
144 verbose
("new job $pid for $dir\n");
154 $pid = $finished[$i][0];
155 $status = $finished[$i][1];
157 verbose
("$pid finished (");
158 if (WIFEXITED
($status)) {
159 verbose
('exited ', WEXITSTATUS
($status));
160 } elsif (WIFSIGNALED
($status)) {
161 verbose
('signalled ', WTERMSIG
($status));
162 } elsif (WIFSTOPPED
($status)) {
163 verbose
('stopped ', WSTOPSIG
($status));
167 for ($j = 0; $j <= $#jobs; $j++) {
168 $pid == $jobs[$j] and splice(@jobs, $j, 1) and last;
171 splice(@finished, $i, 1);
180 $SIG{CHLD
} = \
&reaper
;
182 if (scalar(@jobs) <= $MAXJOBS) {
183 foreach $i (glob('*/tags')) {
184 push(@jobs, newjob
(dirname
($i))) <= $MAXJOBS or last;
188 for ($i = 0; $i <= $#finished; $i++) {
192 verbose
(scalar(@jobs), " jobs\n");
202 if (not getopts
('j:v', \
%opts)) {
203 print(STDERR
"usage: flacd [-jN -v]\n");
207 $verbose = $opts{'v'};
209 flacloop
($opts{'j'});
217 B<fa-flacd>, B<fa-rip>, and B<fa-tags> together comprise
218 B<flac-archive>, a system for archiving audio CDs to single FLAC
219 files. B<fa-flacd> is the guts of the system. It runs in the
220 directory where the audio archives are stored, scanning for new CDs to
221 encode and rename; it never exits. B<fa-rip> generates the inputs for
222 B<fa-flacd>: the ripped WAV file, Vorbis tags, and a cuesheet.
223 B<fa-tags> is not meant to be run directly; B<fa-rip> uses it to
224 generate the candidate Vorbis tags.
226 All three programs expect to be run from the same directory. They use
227 that directory to manage directories named by artist and by disc ID.
228 Intermediate files are written to the disc ID directory. B<fa-flacd>
229 processes the disc ID directories into per-album files in the artist
234 B<fa-flacd> does not exit; it runs until the user kills it. Every 5
235 seconds it scans its current directory for directories with a file
236 called "tags" and creates a processing job for each one. The number
237 of jobs B<fa-flacd> attempts to run is controlled by the B<-j> option
238 and defaults to 4. B<fa-flacd> will print diagnostic output when the
239 B<-v> option is given.
241 A processing job first renames the directory's "tags" file to
242 "using-tags" so that B<ra-flacd> will not try to start another job for
243 this directory. This file is left as is when an error is encountered,
244 so a new job will not be started until the user corrects the error
245 condition and renames "using-tags" back to "tags". Next, it encodes
246 the "wav" file to a FLAC file, using the "cue" file for the cuesheet
247 and "using-tags" for Vorbis tags. Any diagnostic output is saved in
248 the "log" file. Finally, the "cue" and "log" files are moved to the
249 artist directory (and named by album) and the ID directory is removed.
253 B<fa-rip> uses C<mktemp(1)> to create a directory for storage of its
254 intermediate files. It uses C<cdrdao(1)> to create the "cue" file and
255 then passes the number of tracks (from the "cue" file) as command-line
256 arguments to B<fa-tags>. Finally, it execs C<cdparanoia(1)> to rip
257 the CD to the "wav" file.
259 In order for this CD to be processed by B<fa-flacd>, the user must
260 create a "tags" file. This is usually done by renaming one of the
261 candidate-tags files and deleting the others.
265 B<fa-tags> uses C<MusicBrainz::Client> to populate candidate-tags
266 files. These are numbered in the order of entries read from
267 MusicBrainz, e.g. candidate-tags-1, candidate-tags-2, etc. B<fa-tags>
268 also creates candidate-tags-0, which has the correct fields for this
269 CD (including correct number of TITLE= lines), but with all fields
272 B<fa-tags> requires the number of tracks as its sole argument.
280 B<fa-rip> uses this to rip audio and save the cuesheet for a CD. It
281 makes some effort to check some common device names for FreeBSD,
282 Linux, and NetBSD by default.
288 Written by Eric Gillespie <epg@pretzelnet.org>.
290 flac-archive is free software; you may redistribute it and/or modify
291 it under the same terms as Perl itself.
296 # cperl-indent-level: 4
297 # perl-indent-level: 4
298 # indent-tabs-mode: nil
301 # vi: set tabstop=4 expandtab: