For a while I've thought about creating single files with corresponding cue files. Instead of re-ripping my collection, the script below will reassemble the flac files in a directory to a single wav and then create the necessary cue file. It's a simple script and only processes one directory at a time. Later, I'll put the code into this to process an artist and all album directories.
#!/usr/bin/perl
use strict;
use warnings;
use Cwd;
use File::Glob;
use Sysadm::Install qw(tap);
# Read directory for all flac
# soxi -d *.flac to get the times
# shntool join -o flac *.flac
# note: shntool cue *.flac > joined.cue will create the correct cue sheet without TITLE info.
# Had to install Sysadm::Install (did it through CPAN)
sub System_Call {
my @args = @_;
system (@args);
if ($? == -1) {
print "\nFailed to execute: $!\n";
exit 2;
}
elsif ($? & 127) {
printf "\nChild died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
exit 2;
}
return $?;
}
sub Get_Artist_Album {
return ( split m!/!, cwd() )[-2,-1];
}
sub Add_Times {
my $NewTime;
my $BeginTime = $_[0];
my $TrackLen = $_[1];
my $NewSec = 0;
my $NewMin = 0;
my $NewHr = 0;
my ($bMM, $bSS) = ( split m!:!, $BeginTime )[-2,-1];
my ($tMM, $tSS) = ( split m!:!, $TrackLen )[-2,-1];
$NewSec = $bSS+$tSS;
if ($NewSec > 59) {
$bMM = $bMM + 1;
$NewSec = $NewSec-60;
}
$NewMin = $bMM+$tMM;
# if ($NewMin > 59) {
# $NewMin = $NewMin-60;
# }
$NewTime = sprintf("%02d",$NewMin).":".sprintf("%02.2f",$NewSec);
return $NewTime;
}
sub Create_CUE {
my $WAV_FILE = $_[0] or die "I need the name of the WAV\n\n";;
my $i = 1;
my $Track = 1;
my @files = sort <*.flac>;
my $StartTime = "00:00:00";
my ($Artist, $Album) = Get_Artist_Album;
open (CUEFILE, '>CDImage.cue');
print CUEFILE "PERFORMER \"".$Artist."\"\n";
print CUEFILE "TITLE \"".$Album."\"\n";
print CUEFILE "FILE \"$WAV_FILE\" WAVE\n";
foreach my $file (@files) {
$Track = sprintf("%02d", $i);
my $Title = $file;
$Title =~ s{\.[^.]+$}{}; #Remove the extension
$Title =~ s(^\d+[\.\_\-\ ]+)(); #Remove the leading track number
print CUEFILE " TRACK ".$Track." AUDIO\n";
print CUEFILE " TITLE \"".$Title."\"\n";
if ($i > 1) {
my ($NewMM, $NewSS) = ( split m!:!, $StartTime )[-2,-1];
my ($NewSecL,$NewSecR) = ( split m!\.!, $NewSS )[-2,-1];
$NewSecL = sprintf("%02d",$NewSecL);
$NewSecR = $NewSecR * 0.6;
$NewSecR = sprintf("%02d",$NewSecR);
my $NewSecF = $NewMM.":".$NewSecL.":".$NewSecR;
print CUEFILE " INDEX 01 ".$NewSecF."\n";
} else {
print CUEFILE " INDEX 01 ".$StartTime."\n";
}
my ($TrackTime, $stderr, $rc) = tap "soxi", "-d", $file;
$StartTime = Add_Times $StartTime, $TrackTime;
$i++;
}
close (CUEFILE);
}
sub Create_Single_WAV {
my @files = sort <*.flac>;
my $rc = System_Call "shntool", "join", "-o wav", @files;
print "Error Code: $rc \n";
if ($rc == 0) {
rename "joined.wav","CDImage.wav";
return 0;
}
return $rc;
}
unless (-x "/usr/bin/shntool") {
print "I need the program shntool to function\n";
exit 1;
}
unless (-x "/usr/bin/soxi") {
print "I need the program soxi to function\n";
exit 1;
}
my $results = Create_Single_WAV();
if ($results == 0) {
Create_CUE "CDImage.wav";
}
use strict;
use warnings;
use Cwd;
use File::Glob;
use Sysadm::Install qw(tap);
# Read directory for all flac
# soxi -d *.flac to get the times
# shntool join -o flac *.flac
# note: shntool cue *.flac > joined.cue will create the correct cue sheet without TITLE info.
# Had to install Sysadm::Install (did it through CPAN)
sub System_Call {
my @args = @_;
system (@args);
if ($? == -1) {
print "\nFailed to execute: $!\n";
exit 2;
}
elsif ($? & 127) {
printf "\nChild died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
exit 2;
}
return $?;
}
sub Get_Artist_Album {
return ( split m!/!, cwd() )[-2,-1];
}
sub Add_Times {
my $NewTime;
my $BeginTime = $_[0];
my $TrackLen = $_[1];
my $NewSec = 0;
my $NewMin = 0;
my $NewHr = 0;
my ($bMM, $bSS) = ( split m!:!, $BeginTime )[-2,-1];
my ($tMM, $tSS) = ( split m!:!, $TrackLen )[-2,-1];
$NewSec = $bSS+$tSS;
if ($NewSec > 59) {
$bMM = $bMM + 1;
$NewSec = $NewSec-60;
}
$NewMin = $bMM+$tMM;
# if ($NewMin > 59) {
# $NewMin = $NewMin-60;
# }
$NewTime = sprintf("%02d",$NewMin).":".sprintf("%02.2f",$NewSec);
return $NewTime;
}
sub Create_CUE {
my $WAV_FILE = $_[0] or die "I need the name of the WAV\n\n";;
my $i = 1;
my $Track = 1;
my @files = sort <*.flac>;
my $StartTime = "00:00:00";
my ($Artist, $Album) = Get_Artist_Album;
open (CUEFILE, '>CDImage.cue');
print CUEFILE "PERFORMER \"".$Artist."\"\n";
print CUEFILE "TITLE \"".$Album."\"\n";
print CUEFILE "FILE \"$WAV_FILE\" WAVE\n";
foreach my $file (@files) {
$Track = sprintf("%02d", $i);
my $Title = $file;
$Title =~ s{\.[^.]+$}{}; #Remove the extension
$Title =~ s(^\d+[\.\_\-\ ]+)(); #Remove the leading track number
print CUEFILE " TRACK ".$Track." AUDIO\n";
print CUEFILE " TITLE \"".$Title."\"\n";
if ($i > 1) {
my ($NewMM, $NewSS) = ( split m!:!, $StartTime )[-2,-1];
my ($NewSecL,$NewSecR) = ( split m!\.!, $NewSS )[-2,-1];
$NewSecL = sprintf("%02d",$NewSecL);
$NewSecR = $NewSecR * 0.6;
$NewSecR = sprintf("%02d",$NewSecR);
my $NewSecF = $NewMM.":".$NewSecL.":".$NewSecR;
print CUEFILE " INDEX 01 ".$NewSecF."\n";
} else {
print CUEFILE " INDEX 01 ".$StartTime."\n";
}
my ($TrackTime, $stderr, $rc) = tap "soxi", "-d", $file;
$StartTime = Add_Times $StartTime, $TrackTime;
$i++;
}
close (CUEFILE);
}
sub Create_Single_WAV {
my @files = sort <*.flac>;
my $rc = System_Call "shntool", "join", "-o wav", @files;
print "Error Code: $rc \n";
if ($rc == 0) {
rename "joined.wav","CDImage.wav";
return 0;
}
return $rc;
}
unless (-x "/usr/bin/shntool") {
print "I need the program shntool to function\n";
exit 1;
}
unless (-x "/usr/bin/soxi") {
print "I need the program soxi to function\n";
exit 1;
}
my $results = Create_Single_WAV();
if ($results == 0) {
Create_CUE "CDImage.wav";
}