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
00029 import javax.sound.sampled.AudioFormat;
00030 import javax.sound.sampled.AudioInputStream;
00031 import javax.sound.sampled.UnsupportedAudioFileException;
00032
00033
00041 public class Segmenter extends MEAPUtil
00042 {
00043
00044 String[] audioFiles;
00045 String outFileName="out.segments";
00046 FeatFile outFile;
00047
00048
00049 AudioInputStream ais;
00050 STFT stft;
00051 boolean useBeatOD = true;
00052 OnsetDetector detector;
00053 SegmentExtractor extractor;
00054
00055 boolean onsetAtFirstFrame = false;
00056
00057
00058 double threshMult = 1.0;
00059
00060 double smtime = 0.1;
00061
00062 double tempoMult = 1;
00063
00064 public Segmenter(String[] inFiles, String outputFile)
00065 {
00066 audioFiles = inFiles;
00067
00068 outFileName = outputFile;
00069 outFile = new FeatFile(outFileName);
00070 }
00071
00072 public Segmenter(String inFile, String outputFile)
00073 {
00074 audioFiles = new String[1];
00075 audioFiles[0] = inFile;
00076
00077 outFileName = outputFile;
00078 outFile = new FeatFile(outFileName);
00079 }
00080
00081 public Segmenter(String[] inFiles, String outputFile, double thr, boolean beatOD, boolean oaff)
00082 {
00083 this(inFiles, outputFile);
00084
00085 threshMult = thr;
00086 useBeatOD = beatOD;
00087 onsetAtFirstFrame = oaff;
00088 }
00089
00090 public Segmenter(String[] inFiles, String outputFile, double thr, double smt, boolean beatOD, boolean oaff)
00091 {
00092 this(inFiles, outputFile);
00093
00094 threshMult = thr;
00095 useBeatOD = beatOD;
00096 onsetAtFirstFrame = oaff;
00097 smtime = smt;
00098 }
00099 public Segmenter(String inFile, String outputFile, double thr, boolean beatOD, boolean oaff)
00100 {
00101 this(inFile, outputFile);
00102
00103 threshMult = thr;
00104 useBeatOD = beatOD;
00105 onsetAtFirstFrame = oaff;
00106 }
00107
00108 public Segmenter(String inFile, String outputFile, double thr, double smt, boolean beatOD, boolean oaff)
00109 {
00110 this(inFile, outputFile);
00111
00112 threshMult = thr;
00113 useBeatOD = beatOD;
00114 onsetAtFirstFrame = oaff;
00115 smtime = smt;
00116 }
00117
00118 public void printUsageAndExit()
00119 {
00120 System.out.println("Usage: Segmenter [-options] source1.wav source2.mp3 ... \n\n" +
00121 " where options include:\n" +
00122 " -o output_file the file to write the output to (defaults to ./out.segments)\n" +
00123 " -m N [0] use mixer N for input\n" +
00124 " -t D.D [1.0] onset detector threshold (event detector), tempo multiplier (beat detector)\n" +
00125 " -s D.D [0.1] length of smoothing window in seconds for event detector\n" +
00126 " -d use the old style onset detector (defaults to BeatOnsetDetector)\n" +
00127 " -0 add an onset at the very beginning of the file\n" +
00128 "");
00129 System.exit(0);
00130 }
00131
00135 public Segmenter(String[] args)
00136 {
00137 if(args.length == 0)
00138 printUsageAndExit();
00139
00140
00141 Getopt opt = new Getopt("Segmenter", args, "m:t:do:s:0");
00142 opt.setOpterr(false);
00143
00144 int c = -1;
00145 while ((c = opt.getopt()) != -1)
00146 {
00147 switch(c)
00148 {
00149 case 'm':
00150 mixerToUse = Integer.parseInt(opt.getOptarg());
00151 System.out.println("Using mixer " + mixerToUse);
00152 break;
00153 case 't':
00154 threshMult = Double.parseDouble(opt.getOptarg());
00155 tempoMult = threshMult;
00156 break;
00157 case 's':
00158 smtime = Double.parseDouble(opt.getOptarg());
00159 break;
00160 case 'd':
00161 useBeatOD = false;
00162 break;
00163 case 'o':
00164 outFileName = opt.getOptarg();
00165 break;
00166 case '0':
00167 onsetAtFirstFrame = true;
00168 break;
00169 case '?':
00170 printUsageAndExit();
00171 break;
00172 default:
00173 System.out.print("getopt() returned " + c + "\n");
00174 }
00175 }
00176
00177
00178 int ind = opt.getOptind();
00179 if(ind > args.length)
00180 printUsageAndExit();
00181
00182 audioFiles = new String[args.length - ind];
00183 for(int i=ind; i<args.length; i++)
00184 audioFiles[i-ind] = args[i];
00185
00186 outFile = new FeatFile(outFileName);
00187 }
00188
00189 public FeatFile processAudioFile() throws IOException, UnsupportedAudioFileException
00190 {
00191 return processAudioFile(outFile.filename);
00192 }
00193
00194 public FeatFile processAudioFile(String fn) throws IOException, UnsupportedAudioFileException
00195 {
00196
00197
00198
00199 ais = openInputStream(fn, new AudioFormat(DpweOnsetDetector.sr,
00200 bitsPerSamp, 1, signed,
00201 bigEndian));
00202
00203 long frameLength = ais.getFrameLength();
00204
00205
00206
00207 if(frameLength < 0)
00208 {
00209 frameLength = 50000*DpweOnsetDetector.swin/2;
00210
00211 }
00212 int numFrames = (int) frameLength/(DpweOnsetDetector.swin/2);
00213
00214
00215 progress.setMinimum(0);
00216 progress.setMaximum(numFrames);
00217 progress.setValue(0);
00218
00219
00220 stft = new STFT(ais, DpweOnsetDetector.swin, DpweOnsetDetector.swin/2, frameLatency);
00221
00222 if(useBeatOD)
00223
00224 detector = new DpweBeatOnsetDetector(stft, numFrames, tempoMult);
00225 else
00226
00227 detector = new DpweOnsetDetector(stft, numFrames, threshMult, smtime);
00228
00229 extractor = new SegmentExtractor(stft, fn, outFile, progress);
00230 detector.addOnsetListener(extractor);
00231
00232
00233 stft.addFrameListener(extractor);
00234
00235
00236 if(onsetAtFirstFrame)
00237 extractor.newOnset(0, 0);
00238
00239
00240 extractor.run();
00241
00242
00243 outFile.haveReadFile = true;
00244
00245 return outFile;
00246 }
00247
00251 public void run()
00252 {
00253
00254 for(int i=0; i<audioFiles.length; i++)
00255 {
00256
00257 if(verbose)
00258 System.out.println("Writing segments from " + audioFiles[i] + " to "
00259 + outFileName + ".");
00260
00261 long startTime = System.currentTimeMillis();
00262
00263 try
00264 {
00265 processAudioFile(audioFiles[i]);
00266
00267 if(writeMEAPFile)
00268 outFile.writeFile();
00269 }
00270 catch(Exception e)
00271 {
00272 exceptionHandler.handleException(e);
00273 }
00274
00275 if(verbose)
00276 System.out.println("Done. Took " +
00277 ((System.currentTimeMillis() - startTime)/1000.0)
00278 + "s");
00279 }
00280 }
00281
00282
00283 public void setTempoMultiplier(double mult)
00284 {
00285 tempoMult = mult;
00286 }
00287
00288 public FeatFile getSegFile()
00289 {
00290 return outFile;
00291 }
00292
00293 public static void main(String[] args)
00294 {
00295 Segmenter o2or = new Segmenter(args);
00296 o2or.verbose = true;
00297 o2or.run();
00298 System.exit(0);
00299 }
00300 }