package Plugins::MID;

# SlimServer Copyright (c) 2001-2004 Sean Adams, Slim Devices Inc.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License,
# version 2.

# Created from many other scripts by Gerph (11 Oct 2005)
#
# Purpose:
#    Provides conversion of MIDI files using Timidity.
#
# Limitations:
#    It's not fast - that's just the way it goes with converting.
#
# Requirements/Installation:
#    This source - copy it into the Plugins directory
#    Timidity - copy it into the Bin directory or install it in the path.
#          On debian, use 'apt-get install timidity'.
#    Timidity - copy it into the Bin directory or install it in the path.
#          On debian, use 'apt-get install timidity'; you might need the
#          sound patches too; 'apt-get install freepats'.
#          Be aware that this lot is big.
#    Modifications to the custom-types.conf and slimserver-convert.conf files
#      - you can do this automatically by doing the following :
#          perl -MMID -e Plugins::MID::AddTypes
#    Restarting the server.
#
# Note: Timidity is configured to perform only linear resampling in the
#       custom-convert.conf file. This allows my little 500MHz PIII server to 
#       keep up when using the wave output. Any higher and it drops out
#       completely. I recommend going to the 'Server settings' -> 'Filetypes'
#       menu and disabling the MP3 option unless you've got a server 
#       that can handle the extra processing hit that will impose. 
#       Obviously a WAV output will require more bandwidth, but this is 
#       the trade-off you make.


###############################################################################
# FILE: Plugins::MID.pm
#
# DESCRIPTION:
#     Fake some information just so that MIDI files play. Not entirely accurate(!)
#
###############################################################################

use strict;

$Slim::Music::Info::tagFunctions{'mid'} = {
		'module' => 'Plugins::MID',
		'loaded' => 1,
		'getTag' => \&Plugins::MID::getTag,
};

our $config_artist = "[MIDI]";
# Export the version to the server
use vars qw($VERSION);
$VERSION = "0.02";
# 0.01 (13 Oct 2005) - initial version created from MOD.pm
# 0.02 (17 Oct 2005) - added artist grouping

sub getDisplayName { return 'PLUGIN_MID' };

sub strings
{
    local $/ = undef;
    <DATA>;
}

# Given a file, return a hash of name value pairs,
# where each name is a tag name.
sub getTag {
	my $tags = {};

	my $file = shift || "";

	$tags->{'ARTIST'} = $config_artist;
	$tags->{'STEREO'} = 2;

	$tags->{'SECS'} = -1; # We're going to lie, just so that we have a value
	$tags->{'SIZE'} = -s $file;

	# stolen from MP3::Info
	$tags->{'MM'}	    = int $tags->{'SECS'} / 60;
	$tags->{'SS'}	    = int $tags->{'SECS'} % 60;
	$tags->{'MS'}	    = (($tags->{'SECS'} - ($tags->{'MM'} * 60) - $tags->{'SS'}) * 1000);
	$tags->{'TIME'}	    = sprintf "%.2d:%.2d", @{$tags}{'MM', 'SS'};

	close(FILE); return $tags;
}

##########
##########
# We now try to be clever, modifying the existing configuration files if
# possible.

sub AddTypes
{
  my $file;
  my $timidity;
  
  if (!-e "../slimserver.pl")
  { die "I don't know what you're doing. Copy this file to Plugins. Then try this again, from there\n"; }
  
  print "Attempting to add types to custom.conf\n";
  
  $file = "";
  if (open (IN, "< ../custom-types.conf"))
  {
    # The file exists; we need to read and extract the bits we have
    # so that we can update the file with our new support
    while (<IN>)
    { 
      $file .= $_; # Process $_ if necessary
    } # get the lot
    $file =~ s/\n# Timidity bits\n(.*)# Timidity end\n/\n# Timidity bits\n/s;
  }
  
  if ($file !~ /\n# Timidity bits\n/)
  { $file .= "\n# Timidity bits\n"; }
  
  $timidity =<<EOM;
mid     mid             audio/midi              audio
EOM
  $file =~ s/\n# Timidity bits\n/\n# Timidity bits\n$timidity# Timidity end\n/s;
  open(OUT, "> ../custom-types.conf") || die "Couldn't update custom-types.conf\n";
  print OUT $file;
  close(OUT);
  
  
  
  ########
  # Now we do the same thing with slimserver-convert.conf
  print "Attempting to add types to slimserver-convert.conf\n";
  
  $file = "";
  if (open (IN, "< ../slimserver-convert.conf"))
  {
    # The file exists; we need to read and extract the bits we have
    # so that we can update the file with our new support
    while (<IN>)
    { 
      $file .= $_; # Process $_ if necessary
    } # get the lot
    $file =~ s/\n# Timidity bits\n(.*)# Timidity end\n/\n# Timidity bits\n/s;
  }
  
  if ($file !~ /\n# Timidity bits\n/)
  { $file .= "\n# Timidity bits\n"; }
  
  $timidity =<<EOM;
# (you'll probably want to disable the mid->mp3)
mid mp3 * *
        [timidity] -idqq -EFresamp=1 -OrSs1lx -o - \$FILE\$ | lame --quiet -f -r - -
# (my little 500MHz PIII barely keeps up; using the lower resampling rate helps)
mid wav * *
        [timidity] -idqq -EFresamp=1 -Ow -o - \$FILE\$
EOM
  $file =~ s/\n# Timidity bits\n/\n# Timidity bits\n$timidity# Timidity end\n/s;
  open(OUT, "> ../slimserver-convert.conf") || die "Couldn't update slimserver-convert.conf\n";
  print OUT $file;
  close(OUT);
  
  print "\nFiles updated.\n";
  print "\nYou will need to restart the server for this plugin to take effect.\n";
}

1;

__DATA__

PLUGIN_MID
	EN	MIDI file converter

MID
	EN	MIDI sound file
