Main Page   Class Hierarchy   Compound List   File List   Compound Members  

FeatFile.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;
00024 
00025 import java.io.BufferedReader;
00026 import java.io.FileReader;
00027 import java.io.IOException;
00028 import java.io.Writer;
00029 import java.util.Iterator;
00030 import java.util.Vector;
00031 import java.util.regex.Matcher;
00032 import java.util.regex.Pattern;
00033 
00040 public class FeatFile extends MEAPFile implements Cloneable
00041 {
00042     String featureDescription = "";
00043     public Vector chunks;  // Vector of FeatChunks
00044     
00045     // regular expressions for parsing FEATFiles
00046     protected static final Pattern commentPattern = Pattern.compile("#\\.*");
00047     protected static final Pattern linePattern = Pattern.compile("\\s*([^#\\s]+)\\s*");
00048     protected static final Pattern featDescPattern = Pattern.compile("^#\\s*Features:\\s*");
00049 
00050     public FeatFile(String fn)
00051     {
00052         filename = fn;
00053         chunks = new Vector(100, 0);
00054     }
00055 
00056     // Java bitches if this is not present for some reason.  Don't use
00057     // it - its bad news.
00058     protected FeatFile() { }
00059 
00060 
00067     public double[][] getFeatures()
00068     {
00069         return getFeatures(null);
00070     }
00071 
00078     public double[][] getFeatures(int[] featdim)
00079     {
00080         // how many feature dimensions are we using?
00081         int maxdim = 0;
00082         if(featdim != null)
00083             maxdim = featdim.length;
00084         else
00085             maxdim = ((FeatChunk)chunks.get(0)).numFeatures();
00086 
00087         double[][] mat = new double[chunks.size()][maxdim];
00088 
00089         for(int x = 0; x < chunks.size(); x++)
00090         {
00091             FeatChunk c = (FeatChunk)chunks.get(x);
00092 
00093             double[] currFeat = c.getFeatures(featdim);
00094             for(int y = 0; y < currFeat.length; y++)
00095                 mat[x][y] = currFeat[y];
00096         }
00097         
00098         return mat;
00099     }
00100 
00104     public void readFile() throws IOException, ParserException
00105     {
00106         BufferedReader in  = new BufferedReader(new FileReader(filename));
00107 
00108         String audioFile;
00109         double chunkStartTime;
00110         double chunkLength;
00111 
00112         // each line (excluding comments) should look like: 
00113         // audioFile chunkStartTime chunkLength feature1 feature2 ...
00114 
00115         // Parse each line of the input file            
00116         boolean haveWrittenHeader = false;
00117         long lineno = 0;
00118         String line;
00119         while((line = in.readLine()) != null) 
00120         { 
00121             lineno++;
00122             
00123             // extract any comments from the current line
00124             String comment = "";
00125             Matcher c = commentPattern.matcher(line+"\n");
00126             if(c.find())
00127             {
00128                 // comments go all the way to the end of the line
00129                 comment = c.group() + line.substring(c.end()) + "\n";
00130                 line = line.substring(0, c.start());
00131 
00132                 // extract featureDescription from comment
00133                 Matcher fd = featDescPattern.matcher(comment);
00134                 if(fd.find())
00135                     featureDescription = comment.substring(c.end()).trim();
00136             }
00137 
00138             Matcher p = linePattern.matcher(line);
00139             // is there anything else?
00140             if(!p.find())
00141                 continue;
00142             audioFile = p.group(1);
00143             if(!p.find())
00144                 throw new ParserException(filename, lineno, 
00145                                           "Could not find chunk start time.");
00146             try { chunkStartTime = Double.parseDouble(p.group(1)); }
00147             catch(NumberFormatException nfe) { 
00148                 throw new ParserException(filename, lineno, 
00149                                           "Could not parse chunk start time \"" 
00150                                           + p.group(1)  + "\".");  }
00151             if(!p.find())
00152                 throw new ParserException(filename, lineno, 
00153                                           "Could not find chunk length.");
00154             try { chunkLength = Double.parseDouble(p.group(1)); }
00155             catch(NumberFormatException nfe) { 
00156                 throw new ParserException(filename, lineno, 
00157                                           "Could not parse chunk length \"" 
00158                                           + p.group(1)  + "\".");  }
00159             
00160             FeatChunk ch = new FeatChunk(audioFile, chunkStartTime, chunkLength);
00161             ch.comment = comment;
00162 
00163             // save the remaining features on the line
00164             while(p.find())
00165             {
00166                 // what kind of feature is this?  If its not a double then its a string;
00167                 try 
00168                 {
00169                     ch.addFeature(Double.parseDouble(p.group(1)));
00170                 }
00171                 catch (NumberFormatException e)
00172                 {
00173                     ch.addFeature(p.group(1));
00174                 }
00175             }
00176 
00177             chunks.add(ch);
00178         }
00179 
00180         in.close();
00181         haveReadFile = true;
00182     }
00183     
00187     public void clearChunks()
00188     {
00189         chunks.clear();
00190     }
00191 
00195     public void clearFeatures()
00196     {
00197         Iterator i = chunks.iterator();
00198         while(i.hasNext())
00199             ((FeatChunk)i.next()).clearFeatures();
00200     }
00201     
00205     protected void write(Writer w) throws IOException
00206     {
00207         // write the header
00208         w.write("# filename onset_time chunk_length [features]\n# Features: ");
00209         w.write(featureDescription + "\n");
00210 
00211         Iterator i = chunks.iterator();
00212         while(i.hasNext())
00213             w.write(i.next().toString());
00214     }
00215 
00219     public Object clone()
00220     {
00221         FeatFile o = new FeatFile(this.filename);
00222        
00223         // superclass (MEAPFile) fields
00224         o.haveReadFile = this.haveReadFile;
00225         o.haveWrittenFile = this.haveWrittenFile;
00226 
00227         // local fields
00228         o.featureDescription = this.featureDescription;
00229 
00230         o.chunks = new Vector();
00231         Iterator i = this.chunks.iterator();
00232         while(i.hasNext())
00233             o.chunks.add(((FeatChunk)i.next()).clone());
00234 
00235         return o;
00236     }
00237 
00243     public boolean isCompatibleWith(FeatFile f)
00244     {
00245         //todo{Should really check if feature names match excluding
00246         //whitespace and other meaningless gunk.}
00247         return this.featureDescription.equalsIgnoreCase(f.featureDescription);
00248     }
00249 }

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