Main Page   Class Hierarchy   Compound List   File List   Compound Members  

MashupComposer.java

00001 /*
00002  *  Copyright 2006 Columbia University.
00003  *
00004  *  This file is part of MEAPsoft.
00005  *
00006  *  MEAPsoft is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License version 2 as
00008  *  published by the Free Software Foundation.
00009  *
00010  *  MEAPsoft is distributed in the hope that it will be useful, but
00011  *  WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with MEAPsoft; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00018  *  02110-1301 USA
00019  *
00020  *  See the file "COPYING" for the text of the license.
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.Iterator;
00030 
00031 import com.meapsoft.ChunkDist;
00032 import com.meapsoft.EDLChunk;
00033 import com.meapsoft.EDLFile;
00034 import com.meapsoft.EuclideanDist;
00035 import com.meapsoft.FeatChunk;
00036 import com.meapsoft.FeatFile;
00037 import com.meapsoft.ParserException;
00038 
00049 public class MashupComposer extends Composer
00050 {
00051         public static String description = "Attempts to match chunks in the target features file using " +
00052         "chunks from the input features file. The result is a target sound " +
00053         "file created from pieces of the source sound file.";
00054         
00055     String outFileName = "mashup.edl";
00056     
00057     FeatFile dstFile;
00058     FeatFile DBFile;
00059     int[] featdim = null;
00060     ChunkDist dist;
00061 
00062     public MashupComposer(String featFN, String DBFN, String outFN)
00063     {
00064         this(featFN, DBFN, outFN, new EuclideanDist());
00065     }
00066 
00067     public MashupComposer(String featFN, String DBFN, String outFN, ChunkDist cd)
00068     {
00069         this(new FeatFile(featFN), new FeatFile(DBFN), new EDLFile(outFN), cd);
00070     }
00071 
00072     public MashupComposer(FeatFile featFN, FeatFile DBFN, EDLFile outFN)
00073     {
00074         this(featFN, DBFN, outFN, new EuclideanDist());
00075     }
00076 
00077     public MashupComposer(FeatFile featFN, FeatFile DBFN, EDLFile outFN, ChunkDist cd)
00078     {
00079         dstFile = featFN;
00080         DBFile = DBFN;
00081         outFile = outFN;
00082         dist = cd;
00083         featdim = cd.featdim;
00084 
00085         if(outFile == null)
00086             outFile = new EDLFile("");
00087     }
00088 
00089     public void printUsageAndExit() 
00090     {
00091         System.out.println("Usage: MashupComposer [-options] dest.feat chunkdb.feat \n\n" + 
00092                        "  where options include:\n" + 
00093                        "    -o output_file  the file to write the output to (defaults to mashup.edl)");
00094         printCommandLineOptions('i');
00095         printCommandLineOptions('d');
00096         printCommandLineOptions('c');
00097         System.out.println();
00098         System.exit(0);
00099     }
00100 
00104     public MashupComposer(String[] args) 
00105     {
00106         if(args.length == 0)
00107             printUsageAndExit();
00108 
00109         // Parse arguments
00110         String argString = "d:i:o:c:";
00111         featdim = parseFeatDim(args, argString);
00112         dist = parseChunkDist(args, argString, featdim);
00113         parseCommands(args, argString);
00114        
00115         Getopt opt = new Getopt("MashupComposer", args, argString);
00116         opt.setOpterr(false);
00117 
00118         int c = -1;
00119         while ((c = opt.getopt()) != -1) 
00120         {
00121             switch(c) 
00122             {
00123             case 'o':
00124                 outFileName = opt.getOptarg();
00125                 break;
00126             case 'd':  // already handled above
00127                 break;
00128             case 'i':  // already handled above
00129                 break;
00130             case 'c':  // already handled above
00131                 break;
00132             case '?':
00133                 printUsageAndExit();
00134                 break;
00135             default:
00136                 System.out.print("getopt() returned " + c + "\n");
00137             }
00138         }
00139 
00140         // parse arguments
00141         int ind = opt.getOptind();
00142         if(ind > args.length)
00143             printUsageAndExit();
00144         
00145         dstFile = new FeatFile(args[args.length-2]);
00146         DBFile = new FeatFile(args[args.length-1]);
00147         outFile = new EDLFile(outFileName);
00148 
00149         System.out.println("Composing " + outFileName + 
00150                            " from " +  args[args.length-2] +
00151                            " (chunk db: " + args[args.length-1] + ").");
00152     }
00153 
00154     public void setup() throws IOException, ParserException
00155     {
00156         super.setup();
00157 
00158         if(!dstFile.haveReadFile)
00159             dstFile.readFile();
00160         if(!DBFile.haveReadFile)
00161             DBFile.readFile();
00162         
00163         if(dstFile.chunks.size() == 0)  
00164             throw new ParserException(dstFile.filename, "No chunks found");
00165         if(DBFile.chunks.size() == 0)
00166             throw new ParserException(DBFile.filename, "No chunks found");
00167 
00168         // What if features don't match
00169         if(!dstFile.isCompatibleWith(DBFile))
00170             throw new ParserException(DBFile.filename, 
00171                           "Features do not match those in " + dstFile.filename);
00172     }
00173 
00174     public EDLFile compose()
00175     {
00176         NumberFormat fmt = NumberFormat.getInstance();
00177         fmt.setMaximumFractionDigits(3);
00178 
00179         Iterator dstchunks = dstFile.chunks.iterator();
00180         while(dstchunks.hasNext())
00181         {
00182             FeatChunk currChunk = (FeatChunk)dstchunks.next();
00183             double mindist = Double.MAX_VALUE;
00184             FeatChunk match = null;
00185             
00186             // find closest match to currChunk in DB
00187             Iterator i = DBFile.chunks.iterator();
00188             while(i.hasNext())
00189             {
00190                 FeatChunk c = (FeatChunk)i.next();
00191                 double d = dist.distance(currChunk, c);
00192 
00193                 if(d < mindist)
00194                 {
00195                     mindist = d;
00196                     match = c;
00197                 }
00198             }
00199             
00200             // turn match chunk into an EDL chunk 
00201             EDLChunk nc = new EDLChunk(match, currChunk.startTime);
00202             nc.comment = "    # dist = " + fmt.format(mindist);
00203             outFile.chunks.add(nc);
00204         }
00205 
00206         // outFile now contains some chunks.
00207         outFile.haveReadFile = true;
00208 
00209         return outFile;
00210     } 
00211 
00212     public static void main(String[] args) 
00213     {
00214         MashupComposer m = new MashupComposer(args);
00215         long startTime = System.currentTimeMillis();
00216         m.go();
00217         System.out.println("Done. Took " +
00218                            ((System.currentTimeMillis() - startTime)/1000.0)
00219                            + "s");
00220         System.exit(0);
00221     }
00222 }

Generated on Thu May 11 15:04:10 2006 for MEAPsoft by doxygen1.2.18