Changeset 22430

Show
Ignore:
Timestamp:
19.07.2010 13:41:26 (9 years ago)
Author:
davidb
Message:

Further development of MusicIR support to point where simple test collection could be built

Location:
gs2-extensions/music-ir/trunk/perllib/plugins
Files:
1 added
1 modified

Legend:

Unmodified
Added
Removed
  • gs2-extensions/music-ir/trunk/perllib/plugins/jAudioExtractor.pm

    r22323 r22430  
    11########################################################################### 
    22# 
    3 # jAudioConverter - helper plugin that does office document conversion  
     3# jAudioExtractor - helper plugin that does office document conversion  
    44#                       using jodconverter combined with MIR 
    55# 
     
    2525# 
    2626########################################################################### 
    27 package jAudioConverter; 
     27package jAudioExtractor; 
    2828 
    2929use BaseMediaConverter; 
     30 
     31use Cwd; 
    3032 
    3133use strict; 
    3234no strict 'refs'; # allow filehandles to be variables and viceversa 
    3335 
    34 use gsprintf 'gsprintf'; 
    3536 
    3637BEGIN { 
    37     @jAudioConverter::ISA = ('BaseMediaConverter'); 
     38    @jAudioExtractor::ISA = ('BaseMediaConverter'); 
    3839} 
    3940 
     
    4142my $arguments = [ 
    4243    { 'name' => "window_size", 
    43       'desc' => "{jAudioConverter.window_size}", 
     44      'desc' => "{jAudioExtractor.window_size}", 
    4445      'type' => "int", 
    4546      'range' => "128,", 
     
    4748      'reqd' => "no" }, 
    4849    { 'name' => "window_overlap", 
    49       'desc' => "{jAudioConverter.window_overlap}", 
     50      'desc' => "{jAudioExtractor.window_overlap}", 
    5051      'type' => "string", 
    5152      'range' => "0.0", 
     
    5354      'reqd' => "no" }, 
    5455    { 'name' => "sample_rate", 
    55       'desc' => "{jAudioConverter.sample_rate}", 
     56      'desc' => "{jAudioExtractor.sample_rate}", 
    5657      'type' => "enum", 
    57       'list' => [{'name' => "8 kHz",      'desc' => "{jAudioConverter.8000Hz}"}, 
    58          {'name' => "11.025 kHz", 'desc' => "{jAudioConverter.11025Hz}"}, 
    59          {'name' => "16 kHz",     'desc' => "{jAudioConverter.16000Hz}"}, 
    60          {'name' => "22.05 kHz",  'desc' => "{jAudioConverter.22050Hz}"}, 
    61          {'name' => "44.1 kHz",   'desc' => "{jAudioConverter.44100Hz}"} ], 
     58      'list' => [{'name' => "8 kHz",      'desc' => "{jAudioExtractor.8000Hz}"}, 
     59         {'name' => "11.025 kHz", 'desc' => "{jAudioExtractor.11025Hz}"}, 
     60         {'name' => "16 kHz",     'desc' => "{jAudioExtractor.16000Hz}"}, 
     61         {'name' => "22.05 kHz",  'desc' => "{jAudioExtractor.22050Hz}"}, 
     62         {'name' => "44.1 kHz",   'desc' => "{jAudioExtractor.44100Hz}"} ], 
    6263      'deft' => '16 kHz', 
    6364      'reqd' => "no" }, 
    6465    { 'name' => "extracted_data", 
    65       'desc' => "{jAudioConverter.extracted_data}", 
     66      'desc' => "{jAudioExtractor.extracted_data}", 
    6667      'type' => "enum", 
    67       'list' => [{'name' => "Overall and Windowed", 'desc' => "{jAudioConverter.overall_and_windowed}"}, 
    68          {'name' => "Windowed only", 'desc' => "{jAudioConverter.windowed_only}"}, 
    69          {'name' => "Overall only", 'desc' => "{jAudioConverter.overall_only}"}], 
     68      'list' => [{'name' => "Overall and Windowed", 'desc' => "{jAudioExtractor.overall_and_windowed}"}, 
     69         {'name' => "Windowed only", 'desc' => "{jAudioExtractor.windowed_only}"}, 
     70         {'name' => "Overall only", 'desc' => "{jAudioExtractor.overall_only}"}], 
    7071      'deft' => 'Overall and Windowed', 
    7172      'reqd' => "no" }, 
    7273    { 'name' => "output_type", 
    73       'desc' => "{jAudioConverter.output_type}", 
     74      'desc' => "{jAudioExtractor.output_type}", 
    7475      'type' => "enum", 
    75       'list' => [{'name' => "ACE XML", 'desc' => "{jAudioConverter.ace_xml}"}, 
    76          {'name' => "Weka ARFF", 'desc' => "{jAudioConverter.weka_arff}"}], 
     76      'list' => [{'name' => "ACE XML", 'desc' => "{jAudioExtractor.ace_xml}"}, 
     77         {'name' => "Weka ARFF", 'desc' => "{jAudioExtractor.weka_arff}"}], 
    7778      'deft' => 'ACE XML', 
    7879      'reqd' => "no" } 
     
    8182 
    8283 
    83 my $options = { 'name' => "jAudioConverter", 
    84         'desc' => "{jAudioConverter.desc}", 
     84my $options = { 'name' => "jAudioExtractor", 
     85        'desc' => "{jAudioExtractor.desc}", 
    8586        'abstract' => "yes", 
    8687        'inherits' => "yes", 
     
    9798    my $self = new BaseMediaConverter($pluginlist, $inputargs, $hashArgOptLists, 1); 
    9899 
     100    # Set controlling variables 
     101    my $gsdl_home = $ENV{'GSDLHOME'}; 
     102    my $music_ir_home = $ENV{'GEXT_MUSICIR'}; 
     103 
     104    $self->{'ace_xml_output_directory'} = &util::filename_cat($gsdl_home,"tmp"); # Set the directory to save the the ACE XML output files in 
     105    $self->{'jmir_directory'} = &util::filename_cat($music_ir_home,"lib","java"); # Set the directory holding the jMIR .jar files 
     106 
     107 
    99108    return bless $self, $class; 
    100109} 
    101      
    102  
    103 sub convert { 
     110 
     111 
     112# Create and save a temporary jAudio batch file referring to a file to extract 
     113# features from 
     114sub prepareTempJAudioBatchFile  
     115{ 
     116    # ARG Ob1: $new_batch_file_path refers to the path of the temporary batch file to create 
     117    # ARG Ob2: $model_batch_file_path refers to the path of the model batch file to base the temporary one on 
     118    # ARG Ob3: $input_music_file_path refers to the file to extract features with 
     119    # ARG Ob4: $feature_values_file_path refers to the path of the ACE XML Feature Values file that the jMIR component will output to 
     120    # ARG Ob5: $feature_values_file_path refers to the path of the ACE XML Feature Descriptions file that the jMIR component will output to 
     121    my ( $self, $new_batch_file_path, $model_batch_file_path, $input_music_file_path, $feature_values_file_path, $feature_descriptions_file_path ) = @_; 
     122 
     123    # Retrieve settings for jAudioPlugin and use in batch file that is generated 
     124    my $sample_rate = $self->{'sample_rate'}; # sample of how to get parameter from Greenstone/GLI 
     125 
     126 
     127    # Read the contents of the model batch file 
     128    my $batch_file_contents; 
     129    local $/=undef; 
     130    open (INPUT, "$model_batch_file_path") or die "Could not read the model jAudio batch file $model_batch_file_path"; 
     131    binmode INPUT; 
     132    $batch_file_contents = <INPUT>; 
     133    close INPUT; 
     134 
     135    # Set the batch ID tag in the temporary file 
     136    $batch_file_contents =~ s/<batch ID="SampleJAudioBatch">/<batch ID="$input_music_file_path">/; 
     137 
     138    # Set the input file name in the file tag in the temporary file 
     139    $batch_file_contents =~ s/<file><\/file>/<file>$input_music_file_path<\/file>/; 
     140 
     141    # Set the feature vales save path in the temporary file 
     142    $batch_file_contents =~ s/<destination><\/destination>/<destination>$feature_descriptions_file_path<\/destination>/; 
     143 
     144    # Set the feature vales save path in the temporary file 
     145    $batch_file_contents =~ s/<destination><\/destination>/<destination>$feature_values_file_path<\/destination>/; 
     146 
     147    # Save the temporary batch file 
     148    open (OUTPUT, ">$new_batch_file_path") or die "Could not create the temporary jAudio batch file $new_batch_file_path"; 
     149    print OUTPUT "$batch_file_contents"; 
     150    close OUTPUT; 
     151     
     152    # Done 
     153    return 0; 
     154} 
     155 
     156 
     157sub compute_features 
     158{ 
    104159    my $self = shift(@_); 
    105160    my $source_file_path = shift(@_); 
    106     my $target_file_type = shift(@_); 
    107161    my $convert_options  = shift(@_) || ""; 
    108     my $convert_id       = shift(@_) || ""; 
    109     my $cache_mode       = shift(@_) || ""; 
    110162 
    111163    my $outhandle = $self->{'outhandle'}; 
     
    114166    my $source_file_no_path = &File::Basename::basename($source_file_path); 
    115167 
     168    $self->init_cache_for_file($source_file_path); 
     169 
    116170    # Determine the full name and path of the output file 
    117171    my $target_file_path; 
     172    my $feature_values_file_path; 
     173    my $feature_descriptions_file_path; 
     174 
     175    my $target_file_type; 
     176    if ($self->{'output_type'} eq "ACE XML") { 
     177    $target_file_type="xml"; 
     178    } 
     179    else { 
     180    # ARFF 
     181    $target_file_type="arff"; 
     182    } 
     183 
    118184    if ($self->{'enable_cache'}) { 
    119185    my $cached_dir = $self->{'cached_dir'}; 
    120186    my $file_root = $self->{'cached_file_root'}; 
    121     $file_root .= "_$convert_id" if ($convert_id ne ""); 
    122     my $audio_file = "$file_root.$target_file_type"; 
    123     $target_file_path = &util::filename_cat($cached_file_dir,$audio_file); 
     187 
     188    my $target_file = "$file_root.$target_file_type"; 
     189 
     190    $target_file_path = &util::filename_cat($cached_dir,$target_file); 
    124191    } 
    125192    else { 
     
    127194    } 
    128195 
    129  
    130     my jar_home = &util::filename_cat($ENV{'GEXT_MUSICIR'},"lib","java"); 
    131     my $jaudio_jar = &util::filename_cat($jar_home,"jAudio.jar"); 
    132  
    133     # Generate and run the convert command 
    134     my $convert_command = "java -jar $jaudio_jar $convert_options \"$source_file_path\" \"$target_file_path\""; 
    135  
    136     my $print_info = { 'message_prefix' => $convert_id, 
    137                'message' => "Converting $source_file_no_path to: $convert_id $target_file_type" }; 
    138     $print_info->{'cache_mode'} = $cache_mode if ($cache_mode ne ""); 
    139  
    140     my ($regenerated,$result,$had_error)  
    141     = $self->autorun_general_cmd($convert_command,$target_file_path,$print_info); 
    142  
    143     return ($result,$target_file_path); 
    144 } 
    145  
    146 sub convert_without_result { 
    147     my $self = shift(@_); 
    148  
    149     my $source_file_path = shift(@_); 
    150     my $target_file_type = shift(@_); 
    151     my $convert_options  = shift(@_) || ""; 
    152     my $convert_id       = shift(@_) || ""; 
    153  
    154     return $self->convert($source_file_path,$target_file_type, 
    155               $convert_options,$convert_id,"without_result"); 
    156 } 
     196    if ($self->{'output_type'} eq "ACE XML") { 
     197    $feature_values_file_path = $target_file_path; 
     198    $feature_values_file_path =~ s/\.xml$/_FV.xml/; 
     199 
     200    $feature_descriptions_file_path = $target_file_path; 
     201    $feature_descriptions_file_path =~ s/\.xml$/_FD.xml/; 
     202 
     203    # Make target_file_path be the principle file generated by jAudio when using ACE XML 
     204    $target_file_path = $feature_values_file_path; 
     205    } 
     206 
     207    my $ace_xml_output_directory = $self->{'ace_xml_output_directory'}; 
     208    my $jmir_directory = $self->{'jmir_directory'}; 
     209 
     210 
     211    my $store_cwd = cwd(); 
     212 
     213    if (!-d $jmir_directory) { 
     214    print STDERR "Error: Unable able to find directory '$jmir_directory'\n"; 
     215    print STDERR "       Cannot run jAudio\n"; 
     216    } 
     217    elsif (chdir($jmir_directory)) { 
     218 
     219    # Run the feature extraction. 
     220 
     221    # Specify the name for a temporary jAudio batch file 
     222    my $template_batch_file_path = &util::filename_cat($jmir_directory,"SampleJAudioBatchFile.xml.in"); 
     223    my $batch_file_path = &util::filename_cat($ace_xml_output_directory,"tempjaudiobatchfile.xml"); 
     224     
     225    # Create the batch file 
     226    $self->prepareTempJAudioBatchFile( $batch_file_path, $template_batch_file_path,  
     227                       $source_file_path, $feature_values_file_path, $feature_descriptions_file_path ); 
     228     
     229    # Input and Output files to use are stored in the batch_file 
     230    my $jaudio_cmd = "java -Xmx1024M -jar jAudio.jar $convert_options -b \"$batch_file_path\""; 
     231         
     232    # Test the execution path 
     233    # print("EXECUTION CMD: $jaudio_cmd\n"); 
     234     
     235    my $print_info = { 'message_prefix' => "jAudio", 
     236               'message' => "Extracting audio features from $source_file_no_path" }; 
     237     
     238    my ($regenerated,$result,$had_error)  
     239        = $self->autorun_general_cmd($jaudio_cmd,$target_file_path,$print_info); 
     240     
     241    # Delete the jAudio batch file 
     242    unlink($batch_file_path); 
     243    } 
     244    else { 
     245    print STDERR "Error: failed to change directory to '$jmir_directory'\n"; 
     246    print STDERR "       Cannot run jAudio\n"; 
     247    } 
     248 
     249    chdir($store_cwd); 
     250 
     251    return ($target_file_path); 
     252} 
     253     
    157254 
    158255