]>
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.
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(STDERR
"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<mktemp(1)> to create a directory for storage of its
250 intermediate files. It uses C<cdrdao(1)> to create the "cue" file and
251 then passes the number of tracks (from the "cue" file) as command-line
252 arguments to B<fa-tags>. Finally, it execs C<cdparanoia(1)> to rip
253 the CD to the "wav" file.
255 In order for this CD to be processed by B<fa-flacd>, the user must
256 create a "tags" file. This is usually done by renaming one of the
257 candidate-tags files and deleting the others.
261 B<fa-tags> uses C<MusicBrainz::Client> to populate candidate-tags
262 files. These are numbered in the order of entries read from
263 MusicBrainz, e.g. candidate-tags-1, candidate-tags-2, etc. B<fa-tags>
264 also creates candidate-tags-0, which has the correct fields for this
265 CD (including correct number of TITLE= lines), but with all fields
268 B<fa-tags> requires the number of tracks as its sole argument.
276 B<fa-rip> uses this to rip audio and save the cuesheet for a CD. It
277 makes some effort to check some common device names for FreeBSD,
278 Linux, and NetBSD by default.
284 Written by Eric Gillespie <epg@pretzelnet.org>.
286 flac-archive is free software; you may redistribute it and/or modify
287 it under the same terms as Perl itself.
292 # cperl-indent-level: 4
293 # perl-indent-level: 4
294 # indent-tabs-mode: nil
297 # vi: set tabstop=4 expandtab: