source: gs2-extensions/music-ir/trunk/perllib/plugins/jAudioExtractor.pm@ 22430

Last change on this file since 22430 was 22430, checked in by davidb, 14 years ago

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

  • Property svn:executable set to *
File size: 9.2 KB
Line 
1###########################################################################
2#
3# jAudioExtractor - helper plugin that does office document conversion
4# using jodconverter combined with MIR
5#
6# A component of the Greenstone digital library software
7# from the New Zealand Digital Library Project at the
8# University of Waikato, New Zealand.
9#
10# Copyright (C) 2010 New Zealand Digital Library Project
11#
12# This program is free software; you can redistribute it and/or modify
13# it under the terms of the GNU General Public License as published by
14# the Free Software Foundation; either version 2 of the License, or
15# (at your option) any later version.
16#
17# This program is distributed in the hope that it will be useful,
18# but WITHOUT ANY WARRANTY; without even the implied warranty of
19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20# GNU General Public License for more details.
21#
22# You should have received a copy of the GNU General Public License
23# along with this program; if not, write to the Free Software
24# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25#
26###########################################################################
27package jAudioExtractor;
28
29use BaseMediaConverter;
30
31use Cwd;
32
33use strict;
34no strict 'refs'; # allow filehandles to be variables and viceversa
35
36
37BEGIN {
38 @jAudioExtractor::ISA = ('BaseMediaConverter');
39}
40
41
42my $arguments = [
43 { 'name' => "window_size",
44 'desc' => "{jAudioExtractor.window_size}",
45 'type' => "int",
46 'range' => "128,",
47 'deft' => '512',
48 'reqd' => "no" },
49 { 'name' => "window_overlap",
50 'desc' => "{jAudioExtractor.window_overlap}",
51 'type' => "string",
52 'range' => "0.0",
53 'deft' => '0.0',
54 'reqd' => "no" },
55 { 'name' => "sample_rate",
56 'desc' => "{jAudioExtractor.sample_rate}",
57 'type' => "enum",
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}"} ],
63 'deft' => '16 kHz',
64 'reqd' => "no" },
65 { 'name' => "extracted_data",
66 'desc' => "{jAudioExtractor.extracted_data}",
67 'type' => "enum",
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}"}],
71 'deft' => 'Overall and Windowed',
72 'reqd' => "no" },
73 { 'name' => "output_type",
74 'desc' => "{jAudioExtractor.output_type}",
75 'type' => "enum",
76 'list' => [{'name' => "ACE XML", 'desc' => "{jAudioExtractor.ace_xml}"},
77 {'name' => "Weka ARFF", 'desc' => "{jAudioExtractor.weka_arff}"}],
78 'deft' => 'ACE XML',
79 'reqd' => "no" }
80 ];
81
82
83
84my $options = { 'name' => "jAudioExtractor",
85 'desc' => "{jAudioExtractor.desc}",
86 'abstract' => "yes",
87 'inherits' => "yes",
88 'args' => $arguments };
89
90sub new {
91 my ($class) = shift (@_);
92 my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
93 push(@$pluginlist, $class);
94
95 push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
96 push(@{$hashArgOptLists->{"OptList"}},$options);
97
98 my $self = new BaseMediaConverter($pluginlist, $inputargs, $hashArgOptLists, 1);
99
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
108 return bless $self, $class;
109}
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{
159 my $self = shift(@_);
160 my $source_file_path = shift(@_);
161 my $convert_options = shift(@_) || "";
162
163 my $outhandle = $self->{'outhandle'};
164 my $verbosity = $self->{'verbosity'};
165
166 my $source_file_no_path = &File::Basename::basename($source_file_path);
167
168 $self->init_cache_for_file($source_file_path);
169
170 # Determine the full name and path of the output file
171 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
184 if ($self->{'enable_cache'}) {
185 my $cached_dir = $self->{'cached_dir'};
186 my $file_root = $self->{'cached_file_root'};
187
188 my $target_file = "$file_root.$target_file_type";
189
190 $target_file_path = &util::filename_cat($cached_dir,$target_file);
191 }
192 else {
193 $target_file_path = &util::get_tmp_filename($target_file_type);
194 }
195
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
254
255
256
2571;
Note: See TracBrowser for help on using the repository browser.