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.composers;
00024
00025 import gnu.getopt.Getopt;
00026
00027 import java.io.IOException;
00028 import java.text.NumberFormat;
00029 import java.util.Random;
00030 import java.util.Vector;
00031
00032 import com.meapsoft.BasicHist;
00033 import com.meapsoft.Chunk;
00034 import com.meapsoft.EDLChunk;
00035 import com.meapsoft.EDLFile;
00036 import com.meapsoft.FeatChunk;
00037 import com.meapsoft.FeatFile;
00038 import com.meapsoft.ParserException;
00039
00047 public class HeadBangComposer extends Composer
00048 {
00049 public static String description = "HeadBangComposer rocks it hard-core style. \n" +
00050 "Finds the most common chunk length L and lengths related by a " +
00051 "factor of 2, i.e. L/2, L/4, L/8, L*2. "+
00052 "These chunks are then shuffled to create a new piece with a clear beat.\n";
00053
00054 String outFileName = "headBang.edl";
00055
00056 FeatFile featFile;
00057
00058 int binsNum;
00059 int durRange;
00060 int newPieceLength;
00061 boolean debug = false;
00062
00063 public HeadBangComposer(String featFN, String outFN)
00064 {
00065 this(featFN, outFN, 5000, 300);
00066 }
00067
00068 public HeadBangComposer(FeatFile featFN, EDLFile outFN)
00069 {
00070 this(featFN, outFN, 5000,300);
00071 }
00072
00073 public HeadBangComposer(String featFN, String outFN, int binsNum, int newPieceLength)
00074 {
00075 this(new FeatFile(featFN), new EDLFile(outFN), binsNum, newPieceLength);
00076 }
00077
00078 public HeadBangComposer(FeatFile featFN, EDLFile outFN, int binsNum, int newPieceLength)
00079 {
00080 featFile = featFN;
00081 outFile = outFN;
00082 this.binsNum = binsNum;
00083
00084 this.newPieceLength = newPieceLength;
00085
00086 if(outFile == null)
00087 outFile = new EDLFile("");
00088 }
00089
00090 public void printUsageAndExit()
00091 {
00092 System.out.println("Usage: HeadBangComposer [-options] features.feat \n\n" +
00093 " where options include:\n" +
00094 " -o output_file the file to write the output to (defaults to sorted.edl)\n" +
00095 " -g debug mode (prints out chunk features on each line of output file)\n" +
00096 " -b number of bins for length histogram\n" +
00097 " -l new piece length in number of chunks");
00098 printCommandLineOptions('i');
00099
00100 System.out.println();
00101 System.exit(0);
00102 }
00103
00104 public HeadBangComposer(String[] args)
00105 {
00106 if(args.length == 0)
00107 printUsageAndExit();
00108
00109 Vector features = new Vector();
00110
00111
00112 String argString = "o:gb:l:";
00113
00114 Getopt opt = new Getopt("HeadBangComposer", args, argString);
00115 opt.setOpterr(false);
00116
00117 int c = -1;
00118 while ((c =opt.getopt()) != -1)
00119 {
00120 switch(c)
00121 {
00122 case 'o':
00123 outFileName = opt.getOptarg();
00124 break;
00125 case 'l':
00126
00127 newPieceLength = Integer.valueOf( opt.getOptarg() ).intValue();
00128 break;
00129 case 'g':
00130 debug = true;
00131 break;
00132 case 'b':
00133
00134 binsNum = Integer.valueOf( opt.getOptarg() ).intValue();
00135 break;
00136 case '?':
00137 printUsageAndExit();
00138 break;
00139 default:
00140 System.out.print("getopt() returned " + c + "\n");
00141 }
00142 }
00143
00144
00145 int ind = opt.getOptind();
00146 if(ind > args.length)
00147 printUsageAndExit();
00148
00149 featFile = new FeatFile(args[args.length-1]);
00150 outFile = new EDLFile(outFileName);
00151
00152 System.out.println("Composing " + outFileName +
00153 " from " + args[args.length-1] + ".");
00154 }
00155
00156 public void setup() throws IOException, ParserException
00157 {
00158 super.setup();
00159
00160 if(!featFile.haveReadFile)
00161 featFile.readFile();
00162
00163 if(featFile.chunks.size() == 0)
00164 throw new ParserException(featFile.filename, "No chunks found");
00165
00166 progress.setMaximum(featFile.chunks.size());
00167 }
00168
00169 public EDLFile compose()
00170 {
00171
00172 int bins = binsNum;
00173 int range = 25856;
00174 BasicHist hist = new BasicHist(bins,0,range);
00175
00176 for (int i = 0; i < featFile.chunks.size(); i=i+1 ){
00177
00178 double len = Math.floor(((Chunk)featFile.chunks.get(i)).length * samplingRate);
00179 hist.add(Math.log(len)/Math.log(2));
00180
00181 }
00182
00183
00184
00185 int currentValue = 0;
00186 int maxValue = 0;
00187 int maxValueBin =0;
00188 for (int i=0; i< bins; i++)
00189 {
00190 currentValue = hist.getValue(i);
00191 if (currentValue > maxValue)
00192 {
00193 maxValue = currentValue;
00194 maxValueBin = i;
00195 }
00196
00197
00198
00199 }
00200
00201
00202
00203 double lowBound = Math.pow(2, ((double)range / (double)bins * maxValueBin));
00204 double highBound = Math.pow(2, ((double)range / (double)bins * (maxValueBin + 1)));
00205
00206
00207
00208 double lowBoundDiv = lowBound / 2;
00209 double highBoundDiv = highBound / 2;
00210 double lowBoundDiv2 = lowBound / 4;
00211 double highBoundDiv2 = highBound / 4;
00212 double lowBoundMult = lowBound * 2;
00213 double highBoundMult = highBound * 2;
00214
00215 Vector featChunks = new Vector(featFile.chunks);
00216
00217
00218 FeatChunk tempFeatChunk;
00219 double tempFeatLen;
00220 Vector modeChunks = new Vector();
00221 Vector multModeChunks = new Vector();
00222 Vector divModeChunks = new Vector();
00223 Vector div2ModeChunks = new Vector();
00224
00225
00226 for (int i=0; i < featChunks.size(); i++)
00227 {
00228 tempFeatChunk = (FeatChunk)featChunks.get(i);
00229 tempFeatLen = Math.floor(tempFeatChunk.length * samplingRate);
00230
00231 if (lowBoundDiv2 < tempFeatLen && tempFeatLen < highBoundDiv2)
00232 {
00233 div2ModeChunks.add(featChunks.get(i));
00234
00235 }
00236 else if (lowBoundDiv < tempFeatLen && tempFeatLen < highBoundDiv)
00237 {
00238 divModeChunks.add(featChunks.get(i));
00239
00240 }
00241 else if (lowBoundMult < tempFeatLen && tempFeatLen < highBoundMult)
00242 {
00243 multModeChunks.add(featChunks.get(i));
00244
00245 }
00246 else if (lowBound < tempFeatLen && tempFeatLen < highBound)
00247 {
00248 modeChunks.add(featChunks.get(i));
00249
00250 }
00251 }
00252
00253
00254 Vector outChunks = new Vector();
00255
00256
00257 Random rand = new Random();
00258 int index;
00259 for (int i=0; i < newPieceLength; i++)
00260 {
00261 index = rand.nextInt(16);
00262 if (0 <= index && index < 4)
00263 {
00264 if (div2ModeChunks.size() > 0)
00265 {
00266 outChunks.add(div2ModeChunks.get(rand.nextInt(div2ModeChunks.size())));
00267 outChunks.add(div2ModeChunks.get(rand.nextInt(div2ModeChunks.size())));
00268 outChunks.add(div2ModeChunks.get(rand.nextInt(div2ModeChunks.size())));
00269 outChunks.add(div2ModeChunks.get(rand.nextInt(div2ModeChunks.size())));
00270 outChunks.add(div2ModeChunks.get(rand.nextInt(div2ModeChunks.size())));
00271 outChunks.add(div2ModeChunks.get(rand.nextInt(div2ModeChunks.size())));
00272 outChunks.add(div2ModeChunks.get(rand.nextInt(div2ModeChunks.size())));
00273 outChunks.add(div2ModeChunks.get(rand.nextInt(div2ModeChunks.size())));
00274
00275
00276 }
00277 }
00278 else if (4 <= index && index < 6)
00279 {
00280 if (divModeChunks.size() > 0)
00281 {
00282 outChunks.add(divModeChunks.get(rand.nextInt(divModeChunks.size())));
00283 outChunks.add(divModeChunks.get(rand.nextInt(divModeChunks.size())));
00284 outChunks.add(divModeChunks.get(rand.nextInt(divModeChunks.size())));
00285 outChunks.add(divModeChunks.get(rand.nextInt(divModeChunks.size())));
00286
00287 }
00288 }
00289 else if (6 <= index && index < 14)
00290 {
00291 if (modeChunks.size() > 0)
00292 {
00293 outChunks.add(modeChunks.get(rand.nextInt(modeChunks.size())));
00294 outChunks.add(modeChunks.get(rand.nextInt(modeChunks.size())));
00295
00296 }
00297 }
00298 else if (14 <= index )
00299 {
00300 if (multModeChunks.size() > 0)
00301 {
00302 outChunks.add(multModeChunks.get(rand.nextInt(multModeChunks.size())));
00303
00304 }
00305 }
00306
00307 progress.setValue(progress.getValue()+1);
00308 }
00309
00310
00311 double currTime = 0;
00312 while(outChunks.size() > 0)
00313 {
00314 FeatChunk match = (FeatChunk)outChunks.remove(0);
00315
00316
00317 EDLChunk nc = new EDLChunk(match, currTime);
00318
00319 if(debug)
00320 {
00321 NumberFormat fmt = NumberFormat.getInstance();
00322 fmt.setMaximumFractionDigits(3);
00323 nc.comment = " # feats = ";
00324 double[] feat = match.getFeatures();
00325 for(int x = 0; x < feat.length-1; x++)
00326 nc.comment += fmt.format(feat[x]) + ", ";
00327 nc.comment += fmt.format(feat[feat.length-1]);
00328 }
00329
00330 outFile.chunks.add(nc);
00331
00332 currTime += match.length;
00333 }
00334
00335
00336 outFile.haveReadFile = true;
00337
00338 return outFile;
00339 }
00340
00341 public static void main(String[] args)
00342 {
00343 HeadBangComposer m = new HeadBangComposer(args);
00344 long startTime = System.currentTimeMillis();
00345 m.run();
00346 System.out.println("Done. Took " +
00347 ((System.currentTimeMillis() - startTime)/1000.0)
00348 + "s");
00349 System.exit(0);
00350 }
00351 }