# HG changeset patch # User Chris Cannam # Date 1395332143 0 # Node ID 642df7b3346f2f9b5e6cbd8490029eb530224829 # Parent 4767faa6726fcc67cdbd4a25de89be75e30c06a8 Support returning a magnitude spectrum (dense) etc diff -r 4767faa6726f -r 642df7b3346f yeti/cqt.yeti --- a/yeti/cqt.yeti Wed Mar 19 10:30:20 2014 +0000 +++ b/yeti/cqt.yeti Thu Mar 20 16:15:43 2014 +0000 @@ -33,6 +33,7 @@ cqtkernel = load cqtkernel; resample = load may.stream.resample; manipulate = load may.stream.manipulate; +mat = load may.matrix; cm = load may.matrix.complex; framer = load may.stream.framer; cplx = load may.complex; @@ -175,7 +176,36 @@ done { rows, columns }; ); - processOctaveLists octs = + assembleBlockSpectrogram bits = + (// As assembleBlock, but producing a dense magnitude + // spectrogram (rather than a complex output with zeros + // between the cell values in lower octaves). (todo: smoothing) + + //eprintln "assembleBlockSpectrogram: structure of bits is:"; + //eprintln (map length bits); + + rows = octaves * kdata.binsPerOctave; + columns = (pow 2 (octaves - 1)) * kdata.atomsPerFrame; + + mat.generate do row col: + + oct = int (row / binsPerOctave); + binNo = row % kdata.binsPerOctave; + + chunks = pow 2 oct; + colsPerAtom = int (columns / (chunks * kdata.atomsPerFrame)); + atomNo = int (col / colsPerAtom); + + if atomNo < length bits[oct] then + cplx.magnitude bits[oct][atomNo][binNo]; + else + 0 + fi; + + done { rows, columns }; + ); + + processOctaveLists assembler octs = case octs[0] of block::rest: (toAssemble = array @@ -189,7 +219,7 @@ array [] fi done (keys octs)); - assembleBlock toAssemble :. \(processOctaveLists octs)); + assembler toAssemble :. \(processOctaveLists assembler octs)); _: [] esac; @@ -218,7 +248,14 @@ done (reverse (list kdata.binFrequencies)) done [0..octaves-1]) }, - output = processOctaveLists octaveLists + octaves, + output type = + case type of + ComplexCQ (): + Complex (processOctaveLists assembleBlock octaveLists); + Spectrogram (): + Real (processOctaveLists assembleBlockSpectrogram octaveLists); + esac } ); diff -r 4767faa6726f -r 642df7b3346f yeti/cqtkernel.yeti --- a/yeti/cqtkernel.yeti Wed Mar 19 10:30:20 2014 +0000 +++ b/yeti/cqtkernel.yeti Thu Mar 20 16:15:43 2014 +0000 @@ -124,7 +124,7 @@ wx1 = vec.maxindex (complex.magnitudes (cm.getRow 0 kmat)); wx2 = vec.maxindex (complex.magnitudes (cm.getRow (cm.height kmat - 1) kmat)); - subset = cm.columnSlice kmat wx1 (wx2+1); + subset = cm.flipped (cm.columnSlice kmat wx1 (wx2+1)); square = cm.product (cm.conjugateTransposed subset) subset; diag = complex.magnitudes (cm.getDiagonal 0 square); diff -r 4767faa6726f -r 642df7b3346f yeti/nbproject/ide-file-targets.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/yeti/nbproject/ide-file-targets.xml Thu Mar 20 16:15:43 2014 +0000 @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 4767faa6726f -r 642df7b3346f yeti/nbproject/project.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/yeti/nbproject/project.xml Thu Mar 20 16:15:43 2014 +0000 @@ -0,0 +1,53 @@ + + + org.netbeans.modules.ant.freeform + + + + cqt + + + + + jar + + + clean + + + clean + jar + + + + debug-nb + + + + profile-nb + + + + + + build.xml + + + + + + + + + + + + + + + diff -r 4767faa6726f -r 642df7b3346f yeti/plotfile.yeti --- a/yeti/plotfile.yeti Wed Mar 19 10:30:20 2014 +0000 +++ b/yeti/plotfile.yeti Thu Mar 20 16:15:43 2014 +0000 @@ -8,23 +8,34 @@ { cqt } = load cqt; +minFreq = 27.5; +maxRateDivisor = 3; +binsPerOctave = 60; + plotfile f = (testStream = af.open f; eprintln "Opened file stream..."; + start = System#currentTimeMillis(); cq = cqt { - maxFreq = testStream.sampleRate/2, - minFreq = 50, - binsPerOctave = 24 + maxFreq = testStream.sampleRate/maxRateDivisor, + minFreq, + binsPerOctave } testStream; - eprintln "Generated kernel and primed transform, now calculating..."; - bigM = mat.concatHorizontal (map cm.magnitudes cq.output); + middle = System#currentTimeMillis(); + eprintln "Generated kernel \(cm.size cq.kernel.kernel) and primed transform (\(cq.octaves) octaves), took \(middle-start)ms, now calculating..."; + bigM = case (cq.output (Spectrogram ())) of + Real s: mat.concatHorizontal s; + _: failWith "Real expected"; + esac; + finish = System#currentTimeMillis(); + eprintln "Done, that part took \(finish-middle)ms, all CQ stuff took \(finish-start)ms"; eprintln "Plotting..."; \() (plot.plot [Contour bigM])); usage () = (eprintln "\nUsage: plotfile file.wav"; - eprintln "\n Loads audio from file.wav and plots a 24bpo Constant-Q spectrogram"; - eprintln " from 50Hz up to half the file samplerate"); + eprintln "\n Loads audio from file.wav and plots a \(binsPerOctave)bpo Constant-Q spectrogram"; + eprintln " from \(minFreq)Hz up to 1/\(maxRateDivisor) of the file samplerate"); case (list _argv) of file::[]: plotfile file; diff -r 4767faa6726f -r 642df7b3346f yeti/test_frequency.yeti --- a/yeti/test_frequency.yeti Wed Mar 19 10:30:20 2014 +0000 +++ b/yeti/test_frequency.yeti Thu Mar 20 16:15:43 2014 +0000 @@ -81,7 +81,11 @@ do f: \( str = streamBuilder f; cq = cqt { maxFreq = cqmax, minFreq = cqmin, binsPerOctave = bpo } str; - m = mat.concatHorizontal (map cm.magnitudes cq.output); + out = case cq.output (ComplexCQ ()) of + Complex c: c; + _: failWith "expected complex"; + esac; + m = mat.concatHorizontal (map cm.magnitudes out); // println "binFrequencies = \(cq.kernel.binFrequencies)"; // println "binForFreq \(f) = \(binForFreq f)"; var colno = 0;