Index: /gs2-extensions/music-ir/trunk/perllib/plugins/MusicIRPlugin.pm
===================================================================
--- /gs2-extensions/music-ir/trunk/perllib/plugins/MusicIRPlugin.pm	(revision 22438)
+++ /gs2-extensions/music-ir/trunk/perllib/plugins/MusicIRPlugin.pm	(revision 22439)
@@ -29,4 +29,5 @@
 use BasePlugin;
 use jAudioExtractor;
+use jSongMinerExtractor;
 
 use strict;
@@ -37,5 +38,5 @@
 
 sub BEGIN {
-    @MusicIRPlugin::ISA = ('BasePlugin', 'jAudioExtractor');
+    @MusicIRPlugin::ISA = ('BasePlugin', 'jAudioExtractor', 'jSongMinerExtractor');
 }
 
@@ -44,4 +45,11 @@
       { 'name' => "compute_mir_features",
 	'desc' => "{BasePlugin.compute_mir_features}",
+	'type' => "enum",
+	'list' => [{'name' => "true",  'desc' => "{common.true}"},
+		   {'name' => "false", 'desc' => "{common.false}"}],
+	'deft' => "false",
+	'reqd' => "no" },
+      { 'name' => "retrieve_mir_metadata",
+	'desc' => "{BasePlugin.retrieve_mir_metadata}",
 	'type' => "enum",
 	'list' => [{'name' => "true",  'desc' => "{common.true}"},
@@ -73,8 +81,9 @@
 
     
-    my $jac_self = new jAudioExtractor($pluginlist, $inputargs, $hashArgOptLists);
+    my $jae_self = new jAudioExtractor($pluginlist, $inputargs, $hashArgOptLists,1);
+    my $jsme_self = new jSongMinerExtractor($pluginlist, $inputargs, $hashArgOptLists,1);
     my $base_self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
 
-    my $self = BasePlugin::merge_inheritance($jac_self,$base_self);
+    my $self = BasePlugin::merge_inheritance($jae_self,$jsme_self,$base_self);
 
     return bless $self, $class;
@@ -93,4 +102,5 @@
     $self->SUPER::begin(@_);
     $self->jAudioExtractor::begin(@_);
+    $self->jSongMinerExtractor::begin(@_);
 }
 
@@ -122,4 +132,5 @@
     }
 
+    
     #we have no text - adds dummy text and NoText metadata
     $self->add_dummy_text($doc_obj, $doc_obj->get_top_section());
@@ -129,4 +140,27 @@
 }
 
+sub post_process_doc_obj {
+    my $self = shift (@_);  
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+
+    if ($self->{'retrieve_mir_metadata'} eq "true") {
+	my $top_section = $doc_obj->get_top_section();
+	my $id3_titles = $doc_obj->get_metadata($top_section,"ID3.Title");
+
+	my $id3_title = shift @$id3_titles || "Unknown";
+
+	my $id3_artists = $doc_obj->get_metadata($top_section,"ID3.Artist");
+	my $id3_artist = shift @$id3_artists || "Unkown";
+
+	my $metadata_txt_filename = $self->retrieve_metadata($filename_full_path,$id3_title,$id3_artist);
+    }
+
+
+    return 1;
+}
+
 
 1;
Index: /gs2-extensions/music-ir/trunk/perllib/plugins/jAudioExtractor.pm
===================================================================
--- /gs2-extensions/music-ir/trunk/perllib/plugins/jAudioExtractor.pm	(revision 22438)
+++ /gs2-extensions/music-ir/trunk/perllib/plugins/jAudioExtractor.pm	(revision 22439)
@@ -1,6 +1,6 @@
 ###########################################################################
 #
-# jAudioExtractor - helper plugin that does office document conversion 
-#                       using jodconverter combined with MIR
+# jAudioExtractor - helper plugin that computers audio features for 
+#                        music information retrieval use, using jAudio
 #
 # A component of the Greenstone digital library software
Index: /gs2-extensions/music-ir/trunk/perllib/plugins/jSongMinerExtractor.pm
===================================================================
--- /gs2-extensions/music-ir/trunk/perllib/plugins/jSongMinerExtractor.pm	(revision 22439)
+++ /gs2-extensions/music-ir/trunk/perllib/plugins/jSongMinerExtractor.pm	(revision 22439)
@@ -0,0 +1,120 @@
+###########################################################################
+#
+# jSongMinerExtractor - helper plugin that identifies audio through
+#                       external web services based on either an audio
+#                       computed fingerprint or ID3 title and album
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2010 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+package jSongMinerExtractor;
+
+use BaseMediaConverter;
+
+use Cwd;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+
+BEGIN {
+    @jSongMinerExtractor::ISA = ('BaseMediaConverter');
+}
+
+
+my $arguments = [
+    { 'name' => "track_identification",
+      'desc' => "{jSongMinerExtractor.track_identification}",
+      'type' => "enum",
+      'list' => [{'name' => "Fingerprint then ID3 tags", 'desc' => "{jSongMinerExtractor.fingerprint_first}"},
+		 {'name' => "ID3 tags only", 'desc' => "{jSongMinerExtractor.only_ids}"},
+		 {'name' => "Disabled",     'desc' => "{jSongMinerExtractor.off}"} ],
+      'deft' => 'Fingerprint then ID3 tags',
+      'reqd' => "no" }
+    ];
+
+my $options = { 'name' => "jSongMinerExtractor",
+		'desc' => "{jSongMinerExtractor.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+		'args' => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseMediaConverter($pluginlist, $inputargs, $hashArgOptLists, 1);
+
+    # Set controlling variables
+    my $gsdl_home = $ENV{'GSDLHOME'};
+    my $music_ir_home = $ENV{'GEXT_MUSICIR'};
+
+    return bless $self, $class;
+}
+
+sub retrieve_metadata
+{
+    my $self = shift(@_);
+    my ($source_file_path,$id3_title,$id3_artist,$convert_options) = @_;
+
+    $convert_options = "" if (!defined $convert_options);
+
+    my $outhandle = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+
+    my $source_file_no_path = &File::Basename::basename($source_file_path);
+
+    $self->init_cache_for_file($source_file_path);
+
+    my $target_file_path;
+    if ($self->{'enable_cache'}) {
+	my $cached_dir = $self->{'cached_dir'};
+	my $file_root = $self->{'cached_file_root'};
+
+	my $target_file = "${file_root}_metadata.txt";
+
+	$target_file_path = &util::filename_cat($cached_dir,$target_file);
+    }
+    else {
+	$target_file_path = &util::get_tmp_filename("_metadata.txt");
+    }
+
+    my $jsongminer_cmd = "java -Xmx1024M -jar jSongMinor.jar $convert_options \"$id3_title\" \"$id3_artist\"";
+		
+    print STDERR "*** cmd: $jsongminer_cmd\n";
+
+    my $print_info = { 'message_prefix' => "jSongMiner",
+		       'message' => "Retrieving audio metadata for $source_file_no_path" };
+	
+#    my ($regenerated,$result,$had_error) 
+#	= $self->autorun_general_cmd($jsongminer_cmd,$source_file_path,$target_file_path,$print_info);
+	
+    return ($target_file_path);
+}
+    
+
+
+
+1;	
Index: /gs2-extensions/music-ir/trunk/perllib/plugins/jSongMinerMetadata.pm
===================================================================
--- /gs2-extensions/music-ir/trunk/perllib/plugins/jSongMinerMetadata.pm	(revision 22439)
+++ /gs2-extensions/music-ir/trunk/perllib/plugins/jSongMinerMetadata.pm	(revision 22439)
@@ -0,0 +1,257 @@
+###########################################################################
+#
+# jAudioExtractor - helper plugin that does office document conversion 
+#                       using jodconverter combined with MIR
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2010 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+package jAudioExtractor;
+
+use BaseMediaConverter;
+
+use Cwd;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+
+BEGIN {
+    @jAudioExtractor::ISA = ('BaseMediaConverter');
+}
+
+
+my $arguments = [
+    { 'name' => "window_size",
+      'desc' => "{jAudioExtractor.window_size}",
+      'type' => "int",
+      'range' => "128,",
+      'deft' => '512',
+      'reqd' => "no" },
+    { 'name' => "window_overlap",
+      'desc' => "{jAudioExtractor.window_overlap}",
+      'type' => "string",
+      'range' => "0.0",
+      'deft' => '0.0',
+      'reqd' => "no" },
+    { 'name' => "sample_rate",
+      'desc' => "{jAudioExtractor.sample_rate}",
+      'type' => "enum",
+      'list' => [{'name' => "8 kHz",      'desc' => "{jAudioExtractor.8000Hz}"},
+		 {'name' => "11.025 kHz", 'desc' => "{jAudioExtractor.11025Hz}"},
+		 {'name' => "16 kHz",     'desc' => "{jAudioExtractor.16000Hz}"},
+		 {'name' => "22.05 kHz",  'desc' => "{jAudioExtractor.22050Hz}"},
+		 {'name' => "44.1 kHz",   'desc' => "{jAudioExtractor.44100Hz}"} ],
+      'deft' => '16 kHz',
+      'reqd' => "no" },
+    { 'name' => "extracted_data",
+      'desc' => "{jAudioExtractor.extracted_data}",
+      'type' => "enum",
+      'list' => [{'name' => "Overall and Windowed", 'desc' => "{jAudioExtractor.overall_and_windowed}"},
+		 {'name' => "Windowed only", 'desc' => "{jAudioExtractor.windowed_only}"},
+		 {'name' => "Overall only", 'desc' => "{jAudioExtractor.overall_only}"}],
+      'deft' => 'Overall and Windowed',
+      'reqd' => "no" },
+    { 'name' => "output_type",
+      'desc' => "{jAudioExtractor.output_type}",
+      'type' => "enum",
+      'list' => [{'name' => "ACE XML", 'desc' => "{jAudioExtractor.ace_xml}"},
+		 {'name' => "Weka ARFF", 'desc' => "{jAudioExtractor.weka_arff}"}],
+      'deft' => 'ACE XML',
+      'reqd' => "no" }
+    ];
+
+
+
+my $options = { 'name' => "jAudioExtractor",
+		'desc' => "{jAudioExtractor.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+		'args' => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseMediaConverter($pluginlist, $inputargs, $hashArgOptLists, 1);
+
+    # Set controlling variables
+    my $gsdl_home = $ENV{'GSDLHOME'};
+    my $music_ir_home = $ENV{'GEXT_MUSICIR'};
+
+    $self->{'ace_xml_output_directory'} = &util::filename_cat($gsdl_home,"tmp"); # Set the directory to save the the ACE XML output files in
+    $self->{'jmir_directory'} = &util::filename_cat($music_ir_home,"lib","java"); # Set the directory holding the jMIR .jar files
+
+
+    return bless $self, $class;
+}
+
+
+# Create and save a temporary jAudio batch file referring to a file to extract
+# features from
+sub prepareTempJAudioBatchFile 
+{
+    # ARG Ob1: $new_batch_file_path refers to the path of the temporary batch file to create
+    # ARG Ob2: $model_batch_file_path refers to the path of the model batch file to base the temporary one on
+    # ARG Ob3: $input_music_file_path refers to the file to extract features with
+    # ARG Ob4: $feature_values_file_path refers to the path of the ACE XML Feature Values file that the jMIR component will output to
+    # ARG Ob5: $feature_values_file_path refers to the path of the ACE XML Feature Descriptions file that the jMIR component will output to
+    my ( $self, $new_batch_file_path, $model_batch_file_path, $input_music_file_path, $feature_values_file_path, $feature_descriptions_file_path ) = @_;
+
+    # Retrieve settings for jAudioPlugin and use in batch file that is generated
+    my $sample_rate = $self->{'sample_rate'}; # sample of how to get parameter from Greenstone/GLI
+
+
+    # Read the contents of the model batch file
+    my $batch_file_contents;
+    local $/=undef;
+    open (INPUT, "$model_batch_file_path") or die "Could not read the model jAudio batch file $model_batch_file_path";
+    binmode INPUT;
+    $batch_file_contents = <INPUT>;
+    close INPUT;
+
+    # Set the batch ID tag in the temporary file
+    $batch_file_contents =~ s/<batch ID="SampleJAudioBatch">/<batch ID="$input_music_file_path">/;
+
+    # Set the input file name in the file tag in the temporary file
+    $batch_file_contents =~ s/<file><\/file>/<file>$input_music_file_path<\/file>/;
+
+    # Set the feature vales save path in the temporary file
+    $batch_file_contents =~ s/<destination><\/destination>/<destination>$feature_descriptions_file_path<\/destination>/;
+
+    # Set the feature vales save path in the temporary file
+    $batch_file_contents =~ s/<destination><\/destination>/<destination>$feature_values_file_path<\/destination>/;
+
+    # Save the temporary batch file
+    open (OUTPUT, ">$new_batch_file_path") or die "Could not create the temporary jAudio batch file $new_batch_file_path";
+    print OUTPUT "$batch_file_contents";
+    close OUTPUT;
+    
+    # Done
+    return 0;
+}
+
+
+sub compute_features
+{
+    my $self = shift(@_);
+    my $source_file_path = shift(@_);
+    my $convert_options  = shift(@_) || "";
+
+    my $outhandle = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+
+    my $source_file_no_path = &File::Basename::basename($source_file_path);
+
+    $self->init_cache_for_file($source_file_path);
+
+    # Determine the full name and path of the output file
+    my $target_file_path;
+    my $feature_values_file_path;
+    my $feature_descriptions_file_path;
+
+    my $target_file_type;
+    if ($self->{'output_type'} eq "ACE XML") {
+	$target_file_type="xml";
+    }
+    else {
+	# ARFF
+	$target_file_type="arff";
+    }
+
+    if ($self->{'enable_cache'}) {
+	my $cached_dir = $self->{'cached_dir'};
+	my $file_root = $self->{'cached_file_root'};
+
+	my $target_file = "$file_root.$target_file_type";
+
+	$target_file_path = &util::filename_cat($cached_dir,$target_file);
+    }
+    else {
+	$target_file_path = &util::get_tmp_filename($target_file_type);
+    }
+
+    if ($self->{'output_type'} eq "ACE XML") {
+	$feature_values_file_path = $target_file_path;
+	$feature_values_file_path =~ s/\.xml$/_FV.xml/;
+
+	$feature_descriptions_file_path = $target_file_path;
+	$feature_descriptions_file_path =~ s/\.xml$/_FD.xml/;
+
+	# Make target_file_path be the principle file generated by jAudio when using ACE XML
+	$target_file_path = $feature_values_file_path;
+    }
+
+    my $ace_xml_output_directory = $self->{'ace_xml_output_directory'};
+    my $jmir_directory = $self->{'jmir_directory'};
+
+
+    my $store_cwd = cwd();
+
+    if (!-d $jmir_directory) {
+	print STDERR "Error: Unable able to find directory '$jmir_directory'\n";
+	print STDERR "       Cannot run jAudio\n";
+    }
+    elsif (chdir($jmir_directory)) {
+
+	# Run the feature extraction.
+
+	# Specify the name for a temporary jAudio batch file
+	my $template_batch_file_path = &util::filename_cat($jmir_directory,"SampleJAudioBatchFile.xml.in");
+	my $batch_file_path = &util::filename_cat($ace_xml_output_directory,"tempjaudiobatchfile.xml");
+	
+	# Create the batch file
+	$self->prepareTempJAudioBatchFile( $batch_file_path, $template_batch_file_path, 
+					   $source_file_path, $feature_values_file_path, $feature_descriptions_file_path );
+	
+	# Input and Output files to use are stored in the batch_file
+	my $jaudio_cmd = "java -Xmx1024M -jar jAudio.jar $convert_options -b \"$batch_file_path\"";
+		
+	# Test the execution path
+	# print("EXECUTION CMD: $jaudio_cmd\n");
+    
+	my $print_info = { 'message_prefix' => "jAudio",
+			   'message' => "Extracting audio features from $source_file_no_path" };
+	
+	my ($regenerated,$result,$had_error) 
+	    = $self->autorun_general_cmd($jaudio_cmd,$source_file_path,$target_file_path,$print_info);
+	
+	# Delete the jAudio batch file
+	unlink($batch_file_path);
+    }
+    else {
+	print STDERR "Error: failed to change directory to '$jmir_directory'\n";
+	print STDERR "       Cannot run jAudio\n";
+    }
+
+    chdir($store_cwd);
+
+    return ($target_file_path);
+}
+    
+
+
+
+1;	
