diff yeti/silvet_onecolumn.yeti @ 27:9ec18d453889

Split single-column and matrix versions
author Chris Cannam
date Mon, 31 Mar 2014 17:06:24 +0100
parents yeti/silvet.yeti@fbc4011c7693
children cd9fd74931bb
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/yeti/silvet_onecolumn.yeti	Mon Mar 31 17:06:24 2014 +0100
@@ -0,0 +1,104 @@
+
+program silvet_onecolumn;
+
+{ prepareTimeFrequency } = load timefreq;
+{ loadTemplates, extractRanges } = load templates;
+
+em1 = load em_onecolumn;
+
+mat = load may.matrix;
+vec = load may.vector;
+plot = load may.plot;
+
+templates = loadTemplates ();
+
+ranges = extractRanges templates;
+
+eprintln "\nWe have \(length (keys templates)) instruments:";
+for (sort (keys templates)) do k:
+    eprintln " * \(k) \(mat.size templates[k]) range \(ranges[k].lowest) -> \(ranges[k].highest)";
+done;
+eprintln "";
+
+columns = prepareTimeFrequency "test.wav";
+
+height = if empty? columns then 0 else vec.length (head columns) fi;
+
+em1data = em1.initialise ranges templates 88;
+
+col = head (drop 50 columns); // (drop ((length columns) / 2) columns);
+
+\() (plot.plot [ Caption "Source frequency distribution", Vector col ]);
+
+\() (plot.plot [ Caption "Source distribution beforehand", Grid em1data.sources]);
+
+normalise v =
+   (s = vec.sum v;
+    if s > 0 then vec.divideBy s v 
+    else v
+    fi);
+
+oneIteration em1data col n =
+   ({ estimate, q } = em1.performExpectation em1data col;
+    newdata = em1.performMaximisation em1data col q;
+    if (n % 6 == 0) then
+        \() (plot.plot [ Caption "Pitch distribution before and after M-step update for iteration \(n)", Vector (em1data.pitches), Vector (newdata.pitches) ]);
+        \() (plot.plot [ Caption "Source distribution after M-step update for iteration \(n)", Grid newdata.sources ]);
+        \() (plot.plot [ Caption "Q function for E-step iteration \(n)", Vector q ]);
+        \() (plot.plot [ Caption "Estimate from E-step iteration \(n) against original source distribution, and difference between them", Vector estimate, Vector (normalise col), Vector (vec.subtract estimate (normalise col)) ]);
+    fi;
+    newdata);
+
+iterations = 12;
+
+var d = em1data;
+
+for [1..iterations] do i:
+    d := oneIteration d col i;
+done;    
+
+var sounding = [];
+
+println "pitch distribution: \(vec.list d.pitches)";
+
+for [d.lowest .. d.highest] do p:
+    if (vec.at d.pitches p) > 0.05 then
+        sounding := sounding ++ [p];
+    fi;
+done;
+
+println "Sounding: \(sounding)";
+
+toNote p = (array ["A","A#","B","C","C#","D","D#","E","F","F#","G","G#"])[p % 12];
+
+println "Notes: \(map toNote sounding)";
+
+var instruments = [];
+for sounding do p:
+    var best = 0;
+    var bestp = 0;
+    for [0..d.instCount-1] do i:
+        if mat.at d.sources p i > bestp then
+            bestp := mat.at d.sources p i;
+            best := i;
+        fi;
+    done;
+    if bestp > 0 then
+        instruments := instruments ++ [best];
+    else
+        instruments := instruments ++ [-1];
+    fi;
+done;
+
+println "Instruments: \(map do i: (d.instruments[i]) done instruments)";
+
+if not (empty? sounding) then
+   p = head sounding;
+   i = head instruments;
+   w = mat.getColumn p d.templates[i];
+   \() (plot.plot [ Vector w, Vector (normalise col), Caption "Template for instrument \(d.instruments[i]), pitch \(p), against normalised source distribution" ]);
+fi;
+
+();
+
+