00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 package com.meapsoft;
00024
00025 import gnu.getopt.Getopt;
00026
00027 import java.io.IOException;
00028 import java.util.Iterator;
00029 import java.util.Vector;
00030
00031 import javax.sound.sampled.AudioInputStream;
00032
00033 import com.meapsoft.featextractors.AvgMelSpec;
00034 import com.meapsoft.featextractors.FeatureExtractor;
00035
00042 public class FeatExtractor extends MEAPUtil
00043 {
00044
00045 FeatFile[] featFiles;
00046 FeatFile outFile = null;
00047
00048
00049 Vector featExts;
00050 String feat_names = "";
00051
00056 public FeatExtractor(String infile, String outfile, Vector extractors)
00057 {
00058 this(new FeatFile(infile), new FeatFile(outfile), extractors);
00059 }
00060
00065 public FeatExtractor(FeatFile infile, FeatFile outfile, Vector extractors)
00066 {
00067 this((FeatFile[])null, outfile, extractors);
00068
00069 featFiles = new FeatFile[1];
00070 featFiles[0] = infile;
00071 }
00072
00077 public FeatExtractor(FeatFile[] infiles, FeatFile outfile, Vector extractors)
00078 {
00079 featFiles = infiles;
00080 outFile = outfile;
00081 featExts = extractors;
00082
00083 if(extractors.size() == 0)
00084 extractors.add(new AvgMelSpec());
00085 }
00086
00087 public void printUsageAndExit()
00088 {
00089 System.out.println("Usage: FeatExtractor [-options] file1.feat file2.feat ... \n\n" +
00090 " where options include:\n" +
00091 " -o output_file append features into output file (defaults to input file)");
00092 printCommandLineOptions('f');
00093 System.out.println();
00094 System.exit(0);
00095 }
00096
00100 public FeatExtractor(String[] args)
00101 {
00102 if(args.length == 0)
00103 printUsageAndExit();
00104
00105
00106 String argString = "f:o:";
00107 featExts = parseFeatureExtractor(args, argString);
00108
00109 Getopt opt = new Getopt("FeatExtracter", args, argString);
00110 opt.setOpterr(false);
00111
00112 int c = -1;
00113 while ((c = opt.getopt()) != -1)
00114 {
00115 switch(c)
00116 {
00117 case 'o':
00118 outFile = new FeatFile(opt.getOptarg());
00119 break;
00120 case 'f':
00121 break;
00122 case '?':
00123 printUsageAndExit();
00124 break;
00125 default:
00126 System.out.print("getopt() returned " + c + "\n");
00127 }
00128 }
00129
00130
00131 int ind = opt.getOptind();
00132 if(ind > args.length)
00133 printUsageAndExit();
00134
00135 featFiles = new FeatFile[args.length - ind];
00136 for(int i=ind; i<args.length; i++)
00137 featFiles[i-ind] = new FeatFile(args[i]);
00138
00139
00140 for(int i = 0; i < featExts.size(); i++)
00141 feat_names += featExts.get(i).getClass().getName() + " ";
00142
00143 feat_names = feat_names.substring(0, feat_names.length()-1);
00144 }
00145
00146 public void setup() throws IOException, ParserException
00147 {
00148 for(int i = 0; i < featFiles.length; i++)
00149 if(!featFiles[i].haveReadFile)
00150 featFiles[i].readFile();
00151 }
00152
00153
00157 public FeatFile[] processFeatFiles() throws IOException
00158 {
00159 for(int i = 0; i < featFiles.length; i++)
00160 processFeatFile(featFiles[i]);
00161
00162 return featFiles;
00163 }
00164
00168 public FeatFile processFeatFile(FeatFile f) throws IOException
00169 {
00170 FeatFile file = (FeatFile)f.clone();
00171
00172 STFT stft = null;
00173
00174 file.featureDescription = "";
00175 boolean wroteFeatDesc = false;
00176
00177 String lastAudioFile="";
00178 Iterator c = file.chunks.iterator();
00179 while(c.hasNext())
00180 {
00181 FeatChunk ch = (FeatChunk)c.next();
00182
00183
00184
00185
00186 if(!ch.srcFile.equals(lastAudioFile))
00187 {
00188 AudioInputStream ais = openInputStream(ch.srcFile);
00189
00190
00191 int histSize = (int)(ais.getFrameLength()/frameSize);
00192
00193
00194
00195
00196
00197
00198
00199
00200 if(histSize <= 0)
00201 {
00202 histSize = 10*60*samplingRate/frameSize;
00203 System.out.println("Warning - problem reading audio file... guessing file length. If this doesn't "
00204 + "work like you expected it to, try again with a 44.1kHz mono WAV file.");
00205 }
00206
00207 stft = new STFT(ais, frameSize, histSize);
00208 stft.start();
00209 ais.close();
00210 }
00211 lastAudioFile = ch.srcFile;
00212
00213
00214 Iterator i = featExts.listIterator();
00215 while(i.hasNext())
00216 {
00217 FeatureExtractor fe = (FeatureExtractor)i.next();
00218 double[] feats = fe.features(stft, stft.seconds2fr(ch.startTime),
00219 (int)stft.seconds2fr(ch.length));
00220 ch.addFeature(feats);
00221
00222
00223 if(!wroteFeatDesc)
00224 file.featureDescription += fe.getClass().getName() + "(" + feats.length + ") ";
00225 }
00226
00227 wroteFeatDesc = true;
00228 }
00229
00230 if(outFile != null)
00231 {
00232 outFile.chunks.addAll(file.chunks);
00233 outFile.featureDescription = file.featureDescription;
00234
00235
00236 outFile.haveReadFile = true;
00237 }
00238
00239 return file;
00240 }
00241
00242
00246 public void go()
00247 {
00248 try
00249 {
00250 setup();
00251 }
00252 catch(Exception e)
00253 {
00254 e.printStackTrace();
00255 System.exit(1);
00256 }
00257
00258 FeatFile fn = outFile;
00259
00260
00261 for(int i = 0; i < featFiles.length; i++)
00262 {
00263 if(outFile == null)
00264 fn = featFiles[i];
00265 System.out.println("Extracting features (" + feat_names +
00266 ") from " + featFiles[i].filename + " to "
00267 + fn.filename + ".");
00268
00269 long startTime = System.currentTimeMillis();
00270 try
00271 {
00272 FeatFile f = processFeatFile(featFiles[i]);
00273 f.writeFile(fn.filename);
00274 }
00275 catch(Exception e)
00276 {
00277 e.printStackTrace();
00278 System.exit(1);
00279 }
00280 System.out.println("Done. Took " +
00281 ((System.currentTimeMillis() - startTime)/1000.0)
00282 + "s");
00283 }
00284 }
00285
00286
00287 public static void main(String[] args)
00288 {
00289 FeatExtractor o2or = new FeatExtractor(args);
00290 o2or.go();
00291 System.exit(0);
00292 }
00293 }
00294