view yeti/silvet.yeti @ 21:8e61ec97b34e

I think this may be the right arrangement. Print out some results.
author Chris Cannam
date Fri, 28 Mar 2014 12:52:11 +0000
parents 982aa1197a7e
children 782b910394f3
line wrap: on
line source

program silvet;

{ prepareTimeFrequency } = load timefreq;
{ loadTemplates, extractRanges } = load templates;

em = load em;
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;

chunkSize = { rows = height, columns = 100 };

emdata = em.initialise ranges templates 88 chunkSize;

eprintln "initialised EM data: overall pitch range \(emdata.lowest) -> \(emdata.highest)";

chunkify cols = 
    if empty? cols then []
    else
       (mat.resizedTo chunkSize
           (mat.fromColumns (take chunkSize.columns cols)))
        :. \(chunkify (drop chunkSize.columns cols));
    fi;

chunks = chunkify columns;

eprintln "we have \(length chunks) chunks of size \(mat.size (head chunks))";

eprintln "attempting one expectation phase...";

error = em.performExpectation emdata (head chunks);

eprintln "done, result has dimension \(mat.size error)";

eprintln "attempting one maximisation phase...";

newP = em.performMaximisation emdata (head chunks) error;

eprintln "done";

\() (plot.plot [ Grid (head chunks) ]);
\() (plot.plot [ Grid error ]);

\() (plot.plot [ Grid newP ]);
*/

em1data = em1.initialise ranges templates 88;

col = head (drop ((length columns) / 2) columns);

\() (plot.plot [ Caption "Source frequency distribution", Vector col ]);

sourceGrid d =
    mat.fromColumns (map do k: d.sources[k] done (sort (keys d.sources)));

\() (plot.plot [ Caption "Source distribution beforehand", Grid (sourceGrid em1data)]);

oneIteration em1data col n =
   (q = em1.performExpectation em1data col;
//    \() (plot.plot [ Caption "Frequency distribution and output of E-step for iteration \(n)", Vector col, Vector q ]);
    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 (sourceGrid newdata) ]);
    fi;
    newdata);

iterations = 12;

var d = em1data;

for [1..iterations] do i:
    d := oneIteration d col i;
done;    

var sounding = [];

println "pitch distribution: \(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 = "";
    var bestp = 0;
    for d.instruments do i:
        if vec.at d.sources[i] p > bestp then
            bestp := vec.at d.sources[i] p;
            best := i;
        fi;
    done;
    if bestp > 0 then
        instruments := instruments ++ [best];
    else
        instruments := instruments ++ ["unknown"];
    fi;
done;

println "Instruments: \(instruments)";


();