[HMMComposer tweaks
ronw@ee.columbia.edu**20061215205035] {
hunk ./src/com/meapsoft/composers/HMMComposer.java 51
- * complex structure.  Later versions will support limited HMM
+ * complex structure.  Later versions will support more constrained HMM
hunk ./src/com/meapsoft/composers/HMMComposer.java 60
-    public static String description = "HMMComposer uses a features file to train a simple statistical model of a song and uses it to randomly generate a new sequence of chunks";
+    public static String description = "HMMComposer uses a features file to train a simple statistical model of a song and uses it to randomly generate a new sequence of chunks.  This works best when used with chunks created by the beat detector.";
hunk ./src/com/meapsoft/composers/HMMComposer.java 62
-    private int sequenceLength = 100;
+    private int sequenceLength = 50;
hunk ./src/com/meapsoft/composers/HMMComposer.java 67
-
+    // how many beats should we put in each state?
+    private int beatsPerState = 4;
hunk ./src/com/meapsoft/composers/HMMComposer.java 81
-               "    -q codebook_size number of templates to use in the VQ codebook (defaults to "+cbSize+")\n" + 
+               "    -q codebook_size number of states in the HMM (defaults to "+cbSize+")\n" + 
+               "    -b nbeats        number of beats each HMM state should contain (defaults to "+beatsPerState+")\n" + 
hunk ./src/com/meapsoft/composers/HMMComposer.java 102
-		String argString = "o:c:q:i:gd:s:";
+		String argString = "o:c:q:i:gd:s:b:";
hunk ./src/com/meapsoft/composers/HMMComposer.java 124
+			case 'b':
+				beatsPerState = Integer.parseInt(opt.getOptarg());
+				break;
hunk ./src/com/meapsoft/composers/HMMComposer.java 161
+    public void setBeatsPerState(int bps)
+    {
+        beatsPerState = bps;
+    }
+
+	public void setup() throws IOException, ParserException
+	{
+		super.setup();
+
+        // super.setup() takes care of cloning trainFile for us so we
+        // can modify it as much as we want
+
+        // To change the number of beats per state all we have to do
+        // is modify the chunks in trainFile by joining every
+        // beatsPerMeasure chunk into one a superchunk.
+        Vector newChunks = new Vector();
+        for(int x = 0; x < trainFile.chunks.size()-beatsPerState+1; 
+            x += beatsPerState)
+        {
+            FeatChunk newChunk = 
+                (FeatChunk)((FeatChunk)trainFile.chunks.get(x)).clone();
+
+            double length = 0;
+            for(int y = 1; y < beatsPerState; y++)
+            {
+                FeatChunk f = (FeatChunk)trainFile.chunks.get(x+y);
+                
+                newChunk.addFeature(f.getFeatures());
+                newChunk.length += f.length;
+            }
+            
+            newChunks.add(newChunk);
+        }
+
+        trainFile.chunks = newChunks;
+
+        progress.setMaximum(trainFile.chunks.size());
+	}    
+
hunk ./src/com/meapsoft/gui/ComposerPanel.java 104
+	JSlider hmmBeatsPerState;
hunk ./src/com/meapsoft/gui/ComposerPanel.java 840
-        vqFeatFileField = new JTextField("chunk database .feat file");
+        vqFeatFileField = new JTextField(".feat file");
hunk ./src/com/meapsoft/gui/ComposerPanel.java 901
+        p = new JPanel();
+        p.setBackground(c);
+		p.add(new JLabel("beats per state:"));
+        hmmBeatsPerState = new JSlider(JSlider.HORIZONTAL, 0, 16, 4);
+        hmmBeatsPerState.setBackground(c);
+        hmmBeatsPerState.setPaintLabels(true);
+        hmmBeatsPerState.setMajorTickSpacing(2);
+        hmmBeatsPerState.setPaintTicks(true);		
+		p.add(hmmBeatsPerState);
+		controlsPanel.add(p);
+
hunk ./src/com/meapsoft/gui/ComposerPanel.java 1242
+            ((HMMComposer)composer).setBeatsPerState(
+                hmmBeatsPerState.getValue());
+
}
