]>
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 map({ print(STDERR
$_) } @_);
36 # Return the ARTIST, ALBUM, and DATE followed by a list of all the
37 # lines in the file FN.
47 verbose
("Opening tags file $fn\n");
48 open(TAGS
, $fn) or die("open($fn): $!");
53 ($tag, $value) = split(/=/, $_, 2);
57 verbose
("ARTIST $artist from $fn\n");
60 verbose
("ALBUM $album from $fn\n");
63 verbose
("DATE $date from $fn\n");
66 close(TAGS
) or die("close($fn): $!");
68 return ($artist, $album, $date, @tags);
71 # Process the fa-rip output in the directory DIR.
80 verbose
("Renaming $dir/tags\n");
81 rename("$dir/tags", "$dir/using-tags")
82 or die("rename($dir/tags, $dir/using-tags): $!");
84 ($artist, $album, $date, @tags) = get_tags
("$dir/using-tags");
86 verbose
("mkdir($artist)\n");
87 -d
$artist or mkdir($artist) or die("mkdir($artist): $!");
89 verbose
("chdir($dir)\n");
90 chdir($dir) or die("chdir($dir): $!");
92 verbose
("Running flac\n");
93 $status = system('flac', '-o', "../$artist/$album.flac-tmp",
94 '--delete-input-file', '-V', '--cuesheet',
95 'cue', '--no-padding', '--best',
96 map({ ('-T', $_) } @tags),
98 if (WIFEXITED
($status) and ($status = WEXITSTATUS
($status)) != 0) {
100 } elsif (WIFSIGNALED
($status)) {
101 die("flac killed with signal ", WTERMSIG
($status));
102 } elsif (WIFSTOPPED
($status)) {
103 die("flac stopped with signal ", WSTOPSIG
($status));
106 verbose
("Cleaning up $dir\n");
107 unlink('using-tags') or die("unlink(using-tags): $!");
108 unlink('cue') or die("unlink(cue): $!");
109 rename('toc', "../$artist/$album.toc")
110 or die("rename(toc, ../$artist/$album.toc): $!");
111 rename('log', "../$artist/$album.log")
112 or die("rename(log, ../$artist/$album.log): $!");
113 chdir('..') or die("chdir(..): $!");
114 rmdir($dir) or die("rmdir($dir): $!");
116 rename("$artist/$album.flac-tmp", "$artist/$album.flac")
117 or die("rename($artist/$album.flac-tmp, $artist/$album.flac): $!");
125 while (($pid = waitpid(0, WNOHANG
)) > 0) {
126 push(@finished, [$pid, $?]);
129 $SIG{CHLD
} = \
&reaper
;
137 if (not defined($pid)) {
139 } elsif ($pid == 0) {
140 $SIG{CHLD
} = 'IGNORE';
141 open(STDERR
, ">$dir/log") or die("open(STDERR, >$dir/log): $!");
145 verbose
("new job $pid for $dir\n");
155 $pid = $finished[$i][0];
156 $status = $finished[$i][1];
158 verbose
("$pid finished (");
159 if (WIFEXITED
($status)) {
160 verbose
('exited ', WEXITSTATUS
($status));
161 } elsif (WIFSIGNALED
($status)) {
162 verbose
('signalled ', WTERMSIG
($status));
163 } elsif (WIFSTOPPED
($status)) {
164 verbose
('stopped ', WSTOPSIG
($status));
168 for ($j = 0; $j <= $#jobs; $j++) {
169 $pid == $jobs[$j] and splice(@jobs, $j, 1) and last;
172 splice(@finished, $i, 1);
181 $SIG{CHLD
} = \
&reaper
;
183 if (scalar(@jobs) <= $MAXJOBS) {
184 foreach $i (glob('*/tags')) {
185 push(@jobs, newjob
(dirname
($i))) <= $MAXJOBS or last;
189 for ($i = 0; $i <= $#finished; $i++) {
193 verbose
(scalar(@jobs), " jobs\n");
203 if (not getopts
('j:v', \
%opts)) {
204 print("usage: flacd [-jN -v]\n");
208 $verbose = $opts{'v'};
210 flacloop
($opts{'j'});
218 B<fa-flacd>, B<fa-rip>, and B<fa-tags> together comprise
219 B<flac-archive>, a system for archiving audio CDs to single FLAC
220 files. B<fa-flacd> is the guts of the system. It runs in the
221 directory where the audio archives are stored, scanning for new CDs to
222 encode and rename; it never exits. B<fa-rip> generates the inputs for
223 B<fa-flacd>: the ripped WAV file, Vorbis tags, and a cuesheet.
224 B<fa-tags> is not meant to be run directly; B<fa-rip> uses it to
225 generate the candidate Vorbis tags.
227 All three programs expect to be run from the same directory. They use
228 that directory to manage directories named by artist and by disc ID.
229 Intermediate files are written to the disc ID directory. B<fa-flacd>
230 processes the disc ID directories into per-album files in the artist
235 B<fa-flacd> does not exit; it runs until the user kills it. Every 5
236 seconds it scans its current directory for directories with a file
237 called "tags" and creates a processing job for each one. The number
238 of jobs B<fa-flacd> attempts to run is controlled by the B<-j> option
239 and defaults to 4. B<fa-flacd> will print diagnostic output when the
240 B<-v> option is given.
242 A processing job first renames the directory's "tags" file to
243 "using-tags" so that B<ra-flacd> will not try to start another job for
244 this directory. This file is left as is when an error is encountered,
245 so a new job will not be started until the user corrects the error
246 condition and renames "using-tags" back to "tags". Next, it encodes
247 the "wav" file to a FLAC file, using the "cue" file for the cuesheet
248 and "using-tags" for Vorbis tags. Any diagnostic output is saved in
249 the "log" file. Finally, the "cue" and "log" files are moved to the
250 artist directory (and named by album) and the ID directory is removed.
254 B<fa-rip> uses C<cd-discid(1)> to retrieve the disc ID and track
255 information. It creates a directory named by ID for storage of its
256 intermediate files. It passes the C<cd-discid(1)> output as
257 command-line arguments to B<fa-tags> in the background. It then uses
258 C<cdrdao(1)> to create the "cue" file in the background. Finally, it
259 execs C<cdparanoia(1)> to rip the CD to the "wav" file.
261 In order for this CD to be processed by B<fa-flacd>, the user must
262 create a "tags" file. This is usually done by renaming one of the
263 candidate-tags files and deleting the others.
267 B<fa-tags> uses C<cddb-tool(1)> (from the B<abcde> package) to
268 populate candidate-tags files. These are numbered in the order of
269 entries read from CDDB, e.g. candidate-tags-1, candidate-tags-2, etc.
270 B<fa-tags> also creates candidate-tags-0, which has the correct fields
271 for this CD (including correct number of TITLE= lines), but with all
274 B<fa-tags> expects the output of C<cd-discid(1)> as command-line
275 arguments. That is, the disc ID, number of tracks, list of track
276 offsets, and total length of the CD in seconds.
284 B<fa-tags> uses this to retrieve candidate Vorbis tags. Defaults to
285 "http://freedb.freedb.org/~cddb/cddb.cgi".
289 B<fa-rip> uses this to rip audio and save the cuesheet for a CD. It
290 makes some effort to check some common device names for FreeBSD,
291 Linux, and NetBSD by default.
297 Written by Eric Gillespie <epg@pretzelnet.org>. B<fa-tags> contains
298 code from B<abcde>, which bears the following notice:
300 # Copyright (c) 1998-2001 Robert Woodcock <rcw@debian.org>
301 # Copyright (c) 2003-2004 Jesus Climent <jesus.climent@hispalinux.es>
302 # This code is hereby licensed for public consumption under either the
303 # GNU GPL v2 or greater, or Larry Wall's Artistic license - your choice.
305 B<flac-archive> is hereby licensed for public consumption under either
306 the GNU GPL v2 or greater, or Larry Wall's Artistic license - your
312 # cperl-indent-level: 4
313 # perl-indent-level: 4
314 # indent-tabs-mode: nil
317 # vi: set tabstop=4 expandtab: