#!/usr/bin/perl -w
#
# assemble output from gramofile into some oggs

# datafile format:
#
# # is comment
# Author: specifies author
# Genera: specifies genre
# Album: specifies album
# Inputfile: input file
# anything else is, in 3 tab-delimited columns:
#  <track> <startoffset> <endoffset> <name> <filename, sans .ogg>
# blanklines are kinda handled


# buffer size for copy
$bufsiz = 8192;


# default value
#$inputprefix = 'processed';


sub timediff($$) {
  #my $start = $_[0];
  #my $end = $_[1];
  my @start = split /:/, $_[0];
  my @end = split /:/, $_[1];

  # handle lack of :
  if (! defined $start[1]) {
    $start[1] = $start[0];
    $start[0] = 0;
  }
  if (!defined $end[1]) {
    $end[1] = $end[0];
    $end[0] = 0;
  }

  #print $start[0], ':', $start[1], ' ', $end[0], ':', $end[1], "\n";
  #print $start[0] * 60 + $start[1], "\n";
  #print $end[0] * 60 + $end[1], "\n";

  return (($end[0] * 60 + $end[1]) - ($start[0] * 60 + $start[1]));
}


while ($line = <>) {
  chomp $line;

  if ($line =~ /^\#/) {
    # Comment
    next;
  } elsif ($line =~ /^ *$/) {
    # blankline
    next;
  } elsif ($line =~ /^Author: (.*)$/ ) {
    # Author
    $author = $1;
    next;
  } elsif ($line =~ /^Genera: (.*)$/ ) {
    # Genera
    $genre = $1;
    next;
  } elsif ($line =~ /^Inputfile: (.*)$/) {
    # input file
    $inputfile = $1;
    next;
#  } elsif ($line =~ /^Inputprefix: (.*)$/) {
#    # Input file prefix
#    $inputprefix = $1;
#    next;
  } elsif ($line =~ /^Album: (.*)$/ ) {
    # Album
    $album = $1;
    next;
  } else {
    # And it's data!
    my @l = split /\t/, $line;
    push @data, $l[0];
    push @data, $l[1];
    #my $etime = $l[2];
    # calculate end time - start time (length)
    push @data, timediff($data[$#data], $l[2]);
    push @data, $l[3];
    push @data, $l[4];
    next;
  }
}

# Assemble the static part of the cmdline
push @cmdline, '/usr/bin/flac';
#push @cmdline, '-r';
if (defined $author) {
  push @cmdline, '-T';
  push @cmdline, "artist=$author";
}
if (defined $genre) {
  push @cmdline, '-T';
  push @cmdline, "genre=$genre";
}
if (defined $album) {
  push @cmdline, '-T';
  push @cmdline, "album=$album";
}

push @soxcmdline, '/usr/bin/sox';
push @soxcmdline, $inputfile;
push @soxcmdline, '-t';
push @soxcmdline, 'wav';
push @soxcmdline, '-r';
push @soxcmdline, '44100';
push @soxcmdline, '-c';
push @soxcmdline, '2';
push @soxcmdline, '-w';
# XXX oggenc expects little-endian. afaik, sox will output native-endian.
# kill the -x if noise results.
#push @soxcmdline, '-x';
push @soxcmdline, '-';
push @soxcmdline, 'trim';


# do each
while (defined ($num = shift @data)) {
  my $soff = shift @data;
  my $eoff = shift @data;
  my $name = shift @data;
  my $filename = shift @data;

  # Get title - code borrowed from flacit.pl
  my $safename = '';
  $safename .= "${author}-" if ($author ne '');
  $safename .= "${album}-" if ($album ne '');
  $safename .= sprintf('%02i-', $num);
  $safename .= $name;
  $safename =~ s/[^-a-zA-Z0-9.,_ ]//g;

  # assemble a cmdline
  # No real input sanitization is performed, but then, no untrusted
  # data is expected.
  my @cmd = @cmdline;
  push @cmd, '-T';
  push @cmd, "track=$num";
  push @cmd, '-T';
  push @cmd, "title=$name";
  push @cmd, '-o';
  push @cmd, $safename . '.flac';
  push @cmd, '-';
  #push @cmd, $inputprefix . $num . '.wav';

  my @soxcmd = @soxcmdline;

  push @soxcmd, $soff;
  push @soxcmd, $eoff;

  print join (' ', @soxcmd), "\n";
  print join (' ', @cmd), "\n";
  #next;

  # I ought to just tie the two filehandles together...

  # Okay, I thought that this would work, but...
  #open(SOX, '-|', @soxcmd);
  #open(ENC, '|-', @cmd);

  # we'll do this instead
  my $p1 = open(SOX, "-|");
  if ($p1) {
    my $p2 = open(ENC, "|-");
    if ($p2) {
      # read & copy, $bufsiz at at time
      my $buf;
      while (sysread(SOX, $buf, $bufsiz) > 0) {
        syswrite(ENC, $buf);
      }
      close SOX;
      close ENC;
    } else {
      # writer child
      exec @cmd or die "can't exec encoder\n";
    }
  } else {
    # reader child
    exec @soxcmd or die "can't exec reader\n";
  }

  #system @cmd;
  #print join (' ', @cmd), "\n";

}


# leftover cruft
  #system ("/usr/bin/oggenc", "-a", $author, "-G", $genre, "-l", $album, "-N", $num, "-t", $name, "-o", $filename . ".ogg", "processed" . $num . ".wav");
  #print join (' ', ("/usr/bin/oggenc", "-a", $author, "-G", $genre, "-l", $album, "-N", $num, "-t", $name, "-o", $filename . ".ogg", "processed" . $num . ".wav"), "\n");





