#!/usr/bin/env perl
# convert a SID into WAV/MP3 files.
# By default this perl program uses sidplayfp and lame to convert to WAV and MP3 file formats.
# You can use other programs by changing the $ENV variables below.
#
# this program was written by Dirk Jagdmann <doj@cubic.org> 2020-07-03

use strict;
use Digest::MD5;

die "usage: sid2mp3.pl <filename>+" unless $#ARGV >= 0;

$ENV{SONGLENGTHS} ||= 'DOCUMENTS/Songlengths.md5';
my %songlength;
open(A, $ENV{SONGLENGTHS}) or die "could not open $ENV{SONGLENGTHS}: $!";
while(<A>)
{
    chomp;
    if (/(.+?)=(.+)/)
    {
	my @a = split(/\s+/, $2);
	$songlength{$1} = \@a;
    }
}
close(A);

# setup defaults for conversion programs
$ENV{SIDPLAY} ||= 'sidplayfp';
$ENV{LAME} ||= 'lame --quiet -b 64 -h --add-id3v2 --tg Instrumental';

# convert all jobs
foreach my $fn (@ARGV)
{
    unless (-f $fn)
    {
	print STDERR "could not find $fn\n";
	next;
    }

    open(my $fd, '<', $fn) or die "could not open $fn : $!";
    binmode ($fd);
    my $md5 = Digest::MD5->new->addfile($fd)->hexdigest();

    unless (exists $songlength{$md5})
    {
	print STDERR "could not find songlength for $fn $md5\n";
	next;
    }

    my @a = @{$songlength{$md5}};
    for(my $i = 0; $i <= $#a; ++$i)
    {
	my $num = sprintf(formatstr($#a + 1), $i + 1);
	print STDERR "$fn $num $a[$i]\n";

	my $wav = $fn;
	$wav =~ s/\.sid$/-${num}.wav/i;

	# convert SID to WAV
	unlink($wav);

	my $o = `$ENV{SIDPLAY} -o$num -t$a[$i] -w$wav $fn 2>&1`;

	# parse output of sidplay to get information
	my $title = '';
	my $author = '';
	my $released = '';
	my $year = '';
	if ($o =~ /Title\s+: (.+)\s+\|/) {
	    $title = $1;
	}
	if ($o =~ /Author\s+: (.+)\s+\|/) {
	    $author = $1;
	}
	if ($o =~ /Released\s+: (.+)\s+\+/) {
	    $released = $1;
	    if ($released =~ /^((19|20)\d\d)/)
	    {
		$year = $1;
	    }
	}
	# add number to title
	$title .= " $num" if $#a > 0;
	# remove problematic characters (for unix command line)
	# TODO: escape these characters instead of removing them.
	$title =~ s/["\$]//g;
	$author =~ s/["\$]//g;
	$released =~ s/["\$]//g;
	$year =~ s/["\$]//g;

	# convert WAV to MP3
	my $mp3 = $wav;
	$mp3 =~ s/\.wav$/.mp3/;
	unlink($mp3);
	system("$ENV{LAME} --tt \"$title\" --ta \"$author\" --tl \"$released\" --tn \"$num\" --ty \"$year\" $wav $mp3");
	unlink($wav);

	print "$mp3\n";
    }
}

sub formatstr
{
    my $val = shift;
    if ($val < 10) {
	return '%i';
    }
    if ($val < 100) {
	return '%02i';
    }
    if ($val < 1000) {
	return '%03i';
    }
    if ($val < 10000) {
	return '%04i';
    }
    return '%s';
}
