annotate yeti/test.yeti @ 59:a219bab90abe

Start on automated tests
author Chris Cannam <c.cannam@qmul.ac.uk>
date Fri, 31 Jan 2014 11:40:01 +0000
parents e2b7f7462618
children d6b07e6bf1db
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@59 10 mm = load may.mathmisc;
c@37 11 manipulate = load may.stream.manipulate;
c@37 12 syn = load may.stream.syntheticstream;
c@37 13
c@37 14 { cqt } = load cqt;
c@37 15
c@59 16 // Test with a single windowed sinusoid, repeating at various frequencies
c@59 17
c@59 18 sinTestStream sampleRate duration signalFreq = // duration is in samples
c@59 19 (sin = syn.sinusoid sampleRate signalFreq;
c@59 20 chunk = mat.getRow 0 (sin.read duration);
c@59 21 syn.precalculatedMono sampleRate (win.windowed win.hann chunk));
c@59 22
c@59 23 // We want to make a CQ transform spanning more than one octave, but
c@59 24 // not going all the way to fs/2 so we can test it also with
c@59 25 // frequencies above and below its extents
c@59 26
c@59 27 sampleRate = 100;
c@59 28
c@59 29 // fs/2 = 50 so 10->40 gives us 2 octaves
c@59 30 cqmin = 10;
c@59 31 cqmax = 40;
c@59 32 bpo = 4; // fairly arbitrary
c@59 33
c@59 34 testFreqs = map (* 5) [ 0..10 ];
c@59 35 duration = sampleRate * 2;
c@59 36
c@59 37 streamBuilder = sinTestStream sampleRate duration;
c@59 38
c@59 39 binForFreq f =
c@59 40 mm.round (bpo * mm.log2 (f / cqmin)) - 1;
c@59 41
c@59 42 for testFreqs do f:
c@59 43 str = streamBuilder f;
c@59 44 cq = cqt { maxFreq = cqmax, minFreq = cqmin, binsPerOctave = bpo } str;
c@59 45 m = mat.concatHorizontal (map cm.magnitudes cq.output);
c@59 46 println "binFrequencies = \(cq.kernel.binFrequencies)";
c@59 47 println "binForFreq \(f) = \(binForFreq f)";
c@59 48 success = all id
c@59 49 (map do c:
c@59 50 // passes test if the correct max bin, or the expected max
c@59 51 // is out of range, or if all bins are below a threshold
c@59 52 expected = binForFreq f;
c@59 53 good =
c@59 54 (expected < 0 or expected >= vec.length c) or
c@59 55 (vec.max c < 0.001) or
c@59 56 (vec.maxindex c == binForFreq f);
c@59 57 if (not good) then
c@59 58 println " * bad! maxindex \(vec.maxindex c) != expected \(binForFreq f) for freq \(f) in column: \(vec.list c)";
c@59 59 // println "matrix is:";
c@59 60 // mat.print m;
c@59 61 else
c@59 62 print "✓";
c@59 63 fi;
c@59 64 good;
c@59 65 done (mat.asColumns m));
c@59 66 println " success = \(success) for freq \(f)";
c@59 67 done;
c@59 68
c@59 69
c@59 70
c@59 71 /*
c@37 72 //testStream = manipulate.withDuration 96000 (syn.sinusoid 48000 500);
c@37 73 //testStream = manipulate.withDuration 96000 (syn.pulseTrain 48000 4);
c@44 74 testStream = af.open "sweep-48000.wav";
c@37 75 //testStream = af.open "sweep.wav";
c@37 76
c@43 77 // So the stream is [ 0, 1, 0, -1, 0, 1, 0, -1, ... ] :
c@44 78 //testStream = manipulate.withDuration 64 (syn.sinusoid 8 2);
c@38 79
c@56 80 testStream = manipulate.withDuration 32 (syn.pulseTrain 8 0.001);
c@37 81
c@37 82 eprintln "have test stream";
c@37 83
c@44 84 cq = cqt { maxFreq = testStream.sampleRate/2, minFreq = 50, binsPerOctave = 24 } testStream;
c@37 85
c@40 86 eprintln "bin frequencies: \(cq.kernel.binFrequencies)";
c@40 87
c@40 88 bigM = mat.concatHorizontal (map cm.magnitudes cq.output);
c@37 89
c@38 90 eprintln "overall output size = \(mat.size bigM)";
c@38 91
c@39 92 mat.print bigM;
c@38 93
c@38 94 //\() (plot.plot [Contour bigM]);
c@56 95 \() (plot.plot [Grid bigM]);
c@59 96 */
c@37 97 ()
c@37 98