annotate yeti/test.yeti @ 60:d6b07e6bf1db

Merge with pulled changes
author Chris Cannam <c.cannam@qmul.ac.uk>
date Mon, 03 Feb 2014 12:41:43 +0000
parents a219bab90abe
children 625d922494f5
rev   line source
c@37 1
c@37 2 program test;
c@37 3
c@37 4 af = load may.stream.audiofile;
c@37 5 plot = load may.plot;
c@37 6 cm = load may.matrix.complex;
c@37 7 mat = load may.matrix;
c@37 8 vec = load may.vector;
c@59 9 win = load may.signal.window;
c@60 10 test = load may.test.test;
c@59 11 mm = load may.mathmisc;
c@37 12 manipulate = load may.stream.manipulate;
c@37 13 syn = load may.stream.syntheticstream;
c@37 14
c@60 15 { cqtkernel } = load cqtkernel;
c@37 16 { cqt } = load cqt;
c@37 17
c@60 18 // We want to test:
c@60 19 //
c@60 20 // Kernel design -- check size (number of bins, number of atoms);
c@60 21 // check an example kernel against known data
c@60 22 //
c@60 23 // Time alignment -- feed a dirac train, check that peaks in all bins
c@60 24 // align
c@60 25 //
c@60 26 // Frequency discrimination -- feed a sinusoid, check peaks
c@60 27 //
c@60 28 // Latency compensation -- for dirac at 0, check peak can be found at
c@60 29 // 0 plus the declared latency
c@60 30 //
c@60 31 // Signal-noise ratio
c@60 32 //
c@60 33 // Specimen output for simple test case
c@60 34
c@60 35 /*
c@60 36
c@59 37 // Test with a single windowed sinusoid, repeating at various frequencies
c@59 38
c@59 39 sinTestStream sampleRate duration signalFreq = // duration is in samples
c@59 40 (sin = syn.sinusoid sampleRate signalFreq;
c@59 41 chunk = mat.getRow 0 (sin.read duration);
c@59 42 syn.precalculatedMono sampleRate (win.windowed win.hann chunk));
c@59 43
c@59 44 // We want to make a CQ transform spanning more than one octave, but
c@59 45 // not going all the way to fs/2 so we can test it also with
c@59 46 // frequencies above and below its extents
c@59 47
c@59 48 sampleRate = 100;
c@59 49
c@59 50 // fs/2 = 50 so 10->40 gives us 2 octaves
c@59 51 cqmin = 10;
c@59 52 cqmax = 40;
c@59 53 bpo = 4; // fairly arbitrary
c@59 54
c@59 55 testFreqs = map (* 5) [ 0..10 ];
c@59 56 duration = sampleRate * 2;
c@59 57
c@59 58 streamBuilder = sinTestStream sampleRate duration;
c@59 59
c@59 60 binForFreq f =
c@59 61 mm.round (bpo * mm.log2 (f / cqmin)) - 1;
c@59 62
c@59 63 for testFreqs do f:
c@59 64 str = streamBuilder f;
c@59 65 cq = cqt { maxFreq = cqmax, minFreq = cqmin, binsPerOctave = bpo } str;
c@59 66 m = mat.concatHorizontal (map cm.magnitudes cq.output);
c@59 67 println "binFrequencies = \(cq.kernel.binFrequencies)";
c@59 68 println "binForFreq \(f) = \(binForFreq f)";
c@59 69 success = all id
c@59 70 (map do c:
c@59 71 // passes test if the correct max bin, or the expected max
c@59 72 // is out of range, or if all bins are below a threshold
c@59 73 expected = binForFreq f;
c@59 74 good =
c@59 75 (expected < 0 or expected >= vec.length c) or
c@59 76 (vec.max c < 0.001) or
c@59 77 (vec.maxindex c == binForFreq f);
c@59 78 if (not good) then
c@59 79 println " * bad! maxindex \(vec.maxindex c) != expected \(binForFreq f) for freq \(f) in column: \(vec.list c)";
c@59 80 // println "matrix is:";
c@59 81 // mat.print m;
c@59 82 else
c@59 83 print "✓";
c@59 84 fi;
c@59 85 good;
c@59 86 done (mat.asColumns m));
c@59 87 println " success = \(success) for freq \(f)";
c@59 88 done;
c@59 89
c@59 90
c@59 91
c@59 92 /*
c@37 93 //testStream = manipulate.withDuration 96000 (syn.sinusoid 48000 500);
c@37 94 //testStream = manipulate.withDuration 96000 (syn.pulseTrain 48000 4);
c@44 95 testStream = af.open "sweep-48000.wav";
c@37 96 //testStream = af.open "sweep.wav";
c@37 97
c@43 98 // So the stream is [ 0, 1, 0, -1, 0, 1, 0, -1, ... ] :
c@44 99 //testStream = manipulate.withDuration 64 (syn.sinusoid 8 2);
c@38 100
c@56 101 testStream = manipulate.withDuration 32 (syn.pulseTrain 8 0.001);
c@37 102
c@37 103 eprintln "have test stream";
c@37 104
c@44 105 cq = cqt { maxFreq = testStream.sampleRate/2, minFreq = 50, binsPerOctave = 24 } testStream;
c@37 106
c@40 107 eprintln "bin frequencies: \(cq.kernel.binFrequencies)";
c@40 108
c@40 109 bigM = mat.concatHorizontal (map cm.magnitudes cq.output);
c@37 110
c@38 111 eprintln "overall output size = \(mat.size bigM)";
c@38 112
c@39 113 mat.print bigM;
c@38 114
c@38 115 //\() (plot.plot [Contour bigM]);
c@56 116 \() (plot.plot [Grid bigM]);
c@59 117 */
c@37 118 ()
c@37 119