X-Git-Url: https://diplodocus.org/git/flac-archive/blobdiff_plain/e350541f5050e1acba67e729c2fd7b61585cdb98..f939ddf8a554a1f938a510d46648935d6463408b:/fa-flacd diff --git a/fa-flacd b/fa-flacd index d378a1b..d49e02e 100755 --- a/fa-flacd +++ b/fa-flacd @@ -38,6 +38,7 @@ sub get_tags { my $value; my $artist; my $album; + my $discnum; my @tags; verbose("Opening tags file $fn\n"); @@ -54,11 +55,59 @@ sub get_tags { } elsif (/^ALBUM=/i) { $album = $value; verbose("ALBUM $album from $fn\n"); # cperl-mode sucks " + } elsif (/^DISCNUMBER=/i) { + $discnum = int($value); + verbose("DISCNUMBER $discnum from $fn\n"); } } close(TAGS) or die("close($fn): $!"); - return ($artist, $album, @tags); + return ($artist, $album, $discnum, @tags); +} + +sub track_tags { + my $h = shift; + my @result; + + while (my ($key, $vall) = each(%$h)) { + for my $val (@$vall) { + push(@result, "$key=$val") + } + } + + return @result; +} + +sub run_flac { + my $infile = shift; + my $cue = shift; + my $outfile = shift; + + my @cue; + if (defined($cue)) { + @cue = ('--cuesheet', $cue); + } + + verbose("Running flac\n"); + my $status = system('flac', '-o', "$outfile.flac-tmp", + '--delete-input-file', '-V', '--no-padding', '--best', + @cue, + map({ ('-T', $_) } @_), + $infile); + if (WIFEXITED($status)) { + if (($status = WEXITSTATUS($status)) != 0) { + die("flac exited with status $status"); + } + } elsif (WIFSIGNALED($status)) { + die("flac killed with signal ", WTERMSIG($status)); + } elsif (WIFSTOPPED($status)) { + die("flac stopped with signal ", WSTOPSIG($status)); + } else { + die("Major horkage on system(flac): \$? = $? \$! = $!"); + } + + rename("$outfile.flac-tmp", "$outfile.flac") + or die("rename($outfile.flac-tmp, $outfile.flac): $!"); } # Process the fa-rip output in the directory DIR. @@ -66,56 +115,101 @@ sub flac { my $dir = shift; my $artist; my $album; + my $discnum; my @tags; + my $single_file = -e "$dir/wav"; + my $outdir; my $outfile; - my $status; + my $outlog; + my @files; verbose("Renaming $dir/tags\n"); rename("$dir/tags", "$dir/using-tags") or die("rename($dir/tags, $dir/using-tags): $!"); - ($artist, $album, @tags) = get_tags("$dir/using-tags"); + ($artist, $album, $discnum, @tags) = get_tags("$dir/using-tags"); + for ($artist, $album) { + s|/|_|g; + } verbose("mkdir($artist)\n"); -d $artist or mkdir($artist) or die("mkdir($artist): $!"); + if (not $single_file) { + $outdir = "$artist/$album"; + verbose("mkdir($outdir)\n"); + -d "$outdir" or mkdir("$outdir") or die("mkdir($outdir): $!"); + } + verbose("chdir($dir)\n"); chdir($dir) or die("chdir($dir): $!"); - $outfile = "$album"; - $outfile =~ s/\//_/g; + if ($single_file) { + $outfile = $album; + defined($discnum) and $outfile .= " (disc $discnum)"; + run_flac('wav', 'cue', "../$artist/$outfile", @tags); + $outlog = "../$artist/$outfile.log"; + @files = ("$artist/$outfile.flac"); + } else { + # Go over @tags, store all [n] tags in a list keyed by n in + # %tracks_to_tags, store all ARTIST (not ARTIST[n]) tags in + # @disc_artist, and leave the rest in @tags. + my %tracks_to_tags; + my @disc_artist; + my @tmp; + for my $tag (@tags) { + if ($tag =~ /^([^[]+)\[(\d+)]=(.*)/) { + push(@{$tracks_to_tags{$2}->{$1}}, $3); + } elsif ($tag =~ /^ARTIST=/) { + push(@disc_artist, $tag); + } else { + push(@tmp, $tag); + } + } + @tags = @tmp; + + for my $tracknum (sort(map(int, keys(%tracks_to_tags)))) { + my $title = join(' ', map(split, @{$tracks_to_tags{$tracknum}->{'TITLE'}})); + $title =~ s|/|_|g; + $outfile = join('/', + $outdir, + join(' ', + (defined($discnum) + ? sprintf('%02d', $discnum) + : ()), + sprintf('%02d', $tracknum), + $title)); + + # If we have ARTIST[n] tags for this track, set + # @track_artist to the empty list; they will go in along + # with the other [n] tags. + my @track_artist; + if (exists($tracks_to_tags{$tracknum}->{'ARTIST'})) { + @track_artist = (); + } else { + @track_artist = @disc_artist; + } - verbose("Running flac\n"); - $status = system('flac', '-o', "../$artist/$outfile.flac-tmp", - '--delete-input-file', '-V', '--cuesheet', - 'cue', '--no-padding', '--best', - map({ ('-T', $_) } @tags), - 'wav'); - if (WIFEXITED($status)) { - if (($status = WEXITSTATUS($status)) != 0) { - die("flac exited with status $status"); + run_flac(sprintf('track%02d.cdda.wav', $tracknum), undef, + "../$outfile", + @track_artist, + @tags, + track_tags($tracks_to_tags{$tracknum})); + push(@files, "$outfile.flac"); } - } elsif (WIFSIGNALED($status)) { - die("flac killed with signal ", WTERMSIG($status)); - } elsif (WIFSTOPPED($status)) { - die("flac stopped with signal ", WSTOPSIG($status)); - } else { - die("Major horkage on system(flac): \$? = $? \$! = $!"); + $outlog = "../$outdir/log"; } verbose("Cleaning up $dir\n"); unlink('using-tags') or die("unlink(using-tags): $!"); unlink('cue') or die("unlink(cue): $!"); - rename('log', "../$artist/$outfile.log") - or die("rename(log, ../$artist/$outfile.log): $!"); + rename('log', $outlog) + or die("rename(log, $outlog): $!"); chdir('..') or die("chdir(..): $!"); - rename("$artist/$outfile.flac-tmp", "$artist/$outfile.flac") - or die("rename($artist/$outfile.flac-tmp, $artist/$outfile.flac): $!"); - if (-x "$dir/post-processor") { - verbose("Running './$dir/post-processor $artist/$outfile.flac'\n"); - system("./$dir/post-processor", "$artist/$outfile.flac"); + verbose(join(' ', "Running ./$dir/post-processor", @files), "\n"); + system("./$dir/post-processor", @files); unlink("$dir/post-processor") or die("unlink($dir/post-processor): $!"); } @@ -146,7 +240,7 @@ sub newjob { } if ($debug or $pid == 0) { - $SIG{CHLD} = 'IGNORE'; + $SIG{CHLD} = 'DEFAULT'; open(STDERR, ">$dir/log") or die("open(STDERR, >$dir/log): $!"); exit(flac($dir)); }