Mercurial > hg > constant-q-cpp
changeset 81:788799487b1e
More on tests and inverse stuff
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Tue, 29 Apr 2014 16:52:16 +0100 |
parents | 872fc9dc0321 |
children | 24ff66e793fd |
files | yeti/build.xml yeti/icqt.yeti yeti/test_cqtkernel.yeti yeti/test_frequency.yeti |
diffstat | 4 files changed, 110 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/yeti/build.xml Tue Apr 29 08:36:47 2014 +0100 +++ b/yeti/build.xml Tue Apr 29 16:52:16 2014 +0100 @@ -1,4 +1,4 @@ -<project name="cqt" default="jar" basedir="."> +<project name="cqt" default="test" basedir="."> <property name="maydir" value="${basedir}/../../may"/> <property name="yetidir" value="${basedir}/../../yeti"/> @@ -45,10 +45,25 @@ <jar jarfile="${basedir}/cqt.jar"> <fileset dir="${basedir}/classes" includes="**/*.class" - excludes="**/test/*.class"/> + excludes="**/test*.class"/> </jar> </target> + <target name="testjar" depends="classes,taskdef"> + <jar jarfile="${basedir}/test.jar"> + <fileset dir="${basedir}/classes" + includes="**/test*.class"/> + </jar> + </target> + + <target name="test" depends="jar,testjar,taskdef"> + <java classpath="${basedir}/test.jar:${basedir}/cqt.jar:${maydir}/may.jar:${yetidir}/yeti.jar:${extjars}" + classname="test" + fork="true" failonerror="true"> + <sysproperty key="java.library.path" path="${maydir}/ext/native/${archtag}"/> + </java> + </target> + <target name="clean"> <delete dir="${basedir}/classes"/> </target>
--- a/yeti/icqt.yeti Tue Apr 29 08:36:47 2014 +0100 +++ b/yeti/icqt.yeti Tue Apr 29 16:52:16 2014 +0100 @@ -31,13 +31,66 @@ module icqt; cqt = load cqt; +cm = load may.matrix.complex; +mm = load may.mathmisc; icqt cq = (kdata = cq.kernel; - // kdata.kernel is the kernel matrix for a single octave, of width - // kdata.fftSize and height kdata.binsPerOctave. !!! todo: unit - // tests for kernel size etc kdata.fftHop is the overlap between - // kernel matrices in a single octave. cq.sampleRate is the - // output stream sample rate. + // kdata.kernel is the kernel matrix for a single octave. It has + // width kdata.fftSize and height kdata.binsPerOctave * + // kdata.atomsPerFrame. + // + // kdata.fftHop is the overlap between kernel matrices in a single + // octave. + // + // cq.sampleRate is the output stream sample rate and cq.octaves + // the number of octaves. + // + // cq.cqComplex is the list of complex matrices containing the CQ + // output. Each has width kdata.atomsPerFrame * 2^(cq.octaves-1) + // and height kdata.binsPerOctave * cq.octaves. + bpo = kdata.binsPerOctave; + octaves = cq.octaves; + + // transform a single block, all octaves tall, into an array + // (indexed by octave) of lists of individual columns (valid + // values for that octave only) + decomposeOctaves mat = array + (map do oct: + octMat = cm.rowSlice mat (bpo * oct) (bpo * (oct + 1)); + gap = (mm.pow 2 oct) - 1; + pickFrom cols = + case cols of + c::cs: c::(pickFrom (drop gap cs)); + _: []; + esac; + pickFrom (cm.asColumns octMat); + done [0..octaves-1]); + + // transform a list of the arrays produced by decomposeOctaves + // into a single array (indexed by octave) of lists of the + // individual columns + flattenOctaves decomposed = + (flattenAux acc decomposed = + case decomposed of + chunk::rest: + flattenAux + (array + (map do oct: + acc[oct] ++ chunk[oct] + done [0..octaves-1])) + rest; + _: []; + esac; + flattenAux (array (map \[] [0..octaves-1])) decomposed); + + octaveColumnLists = flattenOctaves (map decomposeOctaves cq.cqComplex); + + + for octaveColumnLists do l: println "octave column list length: \(length l)" done; + +); + +{icqt}
--- a/yeti/test_cqtkernel.yeti Tue Apr 29 08:36:47 2014 +0100 +++ b/yeti/test_cqtkernel.yeti Tue Apr 29 16:52:16 2014 +0100 @@ -31,16 +31,32 @@ module test_cqtkernel; cm = load may.matrix.complex; +mm = load may.mathmisc; + +{ compare, compareUsing } = load may.test; { makeKernel } = load cqtkernel; +eps = 1e-7; + +compareClose = compareUsing do a b: abs (a - b) < eps done; + [ "minimal": \( k = makeKernel { sampleRate = 16, maxFreq = 8, binsPerOctave = 4 }; -print k; -cm.print k.kernel; -false; + compare k.binsPerOctave 4 and + compare (cm.size k.kernel) { + rows = k.binsPerOctave * k.atomsPerFrame, + columns = k.fftSize + } and + compareClose k.maxFrequency 8 and + compareClose k.minFrequency (4 * (mm.pow 2 (1/4))) and + compare k.atomsPerFrame 5 and + compare k.fftSize 32 and + compare (length k.binFrequencies) k.binsPerOctave and + compareClose (head k.binFrequencies) k.minFrequency and + compareClose (head (reverse k.binFrequencies)) k.maxFrequency ), ] is hash<string, () -> boolean>
--- a/yeti/test_frequency.yeti Tue Apr 29 08:36:47 2014 +0100 +++ b/yeti/test_frequency.yeti Tue Apr 29 16:52:16 2014 +0100 @@ -38,6 +38,8 @@ syn = load may.stream.syntheticstream; plot = load may.plot; +{ compare } = load may.test; + { cqt } = load cqt; // Test with a single windowed sinusoid, repeating at various frequencies @@ -71,23 +73,30 @@ report message matrix = (eprintln message; eprintln "matrix is:"; - mat.eprint matrix; - chart = plot.plot [Grid matrix]; - sleep 100; - chart#dispose()); + mat.eprint matrix); +// chart = plot.plot [Grid matrix]; +// sleep 100; +// chart#dispose()); tests = mapIntoHash do f: "freq_\(f)" done do f: \( str = streamBuilder f; cq = cqt { maxFreq = cqmax, minFreq = cqmin, binsPerOctave = bpo } str; - out = cq.cqComplex; - m = mat.concatHorizontal (map cm.magnitudes out); + spec = cq.cqSpectrogram; + rightSize = all id + (map do s: + compare (mat.size s) { + rows = cq.kernel.binsPerOctave * cq.octaves, + columns = cq.kernel.atomsPerFrame * mm.pow 2 (cq.octaves - 1) + } + done spec); + m = mat.concatHorizontal spec; // println "binFrequencies = \(cq.kernel.binFrequencies)"; // println "binForFreq \(f) = \(binForFreq f)"; var colno = 0; success = all id - (map do c: + (rightSize :: map do c: // The test passes for this column if: // // * the max bin is the expected one, or