Mercurial > hg > may
changeset 430:7ee8c2d55e58
Some tidying
author | Chris Cannam |
---|---|
date | Tue, 08 Oct 2013 07:58:09 +0100 |
parents | 2fbf3ce1e08b |
children | f9a954e103db |
files | src/may/stream/resample.yeti src/may/stream/test/test_resample.yeti |
diffstat | 2 files changed, 39 insertions(+), 68 deletions(-) [+] |
line wrap: on
line diff
--- a/src/may/stream/resample.yeti Tue Oct 08 07:57:27 2013 +0100 +++ b/src/may/stream/resample.yeti Tue Oct 08 07:58:09 2013 +0100 @@ -37,10 +37,11 @@ pp = win.kaiserParameters (ByFrequency { attenuation, bandwidth, samplerate }); length = if pp.length % 2 == 0 then pp.length + 1 else pp.length fi; kw = win.kaiser (pp with { length }); + middle = System#currentTimeMillis(); sw = win.sinc (n*2) length; filter = bf.multiply sw kw; after = System#currentTimeMillis(); - println "filter generation took \(after - before)ms"; + println "filter generation took \(after - before)ms (kaiser \(middle - before)ms, sinc \(after - middle)ms)"; filter); durationAdjusterFor factor s = @@ -134,8 +135,8 @@ fparams = { n = peakToPole, - attenuation = 120, - bandwidth = (lower / g) / 1000, + attenuation = 100, + bandwidth = 0.02, samplerate = (higher / g), }; @@ -143,29 +144,6 @@ println "for target rate \(targetRate) and source rate \(sourceRate), gcd = \(g) and peakToPole = \(peakToPole), filt parameters \(fparams), filter length \(vec.length filt)"; -//filt = kaiserSincWindow 7 peakToPole 80; -//println "temporary: filter length \(vec.length filt)"; - - println "for target rate \(targetRate) and source rate \(sourceRate), gcd = \(g) and peakToPole = \(peakToPole), filter length \(vec.length filt)"; - - //!!! ponder -/* - filt = kaiserSincFilterFor { - n = peakToPole, - attenuation = 140, -// bandwidth = 10, - bandwidth = lower / 100, - samplerate = lower - }; - - filt = kaiserSincFilterFor { - n = peakToPole, - attenuation = 80, - bandwidth = 1, - samplerate = higher - }; -*/ - // Now we have a filter of (odd) length flen in which the lower // sample rate corresponds to every n'th point and the higher rate // to every m'th where n and m are higher and lower rates divided @@ -283,7 +261,7 @@ s.read Math#ceil((halflen + 1) / inputSpacing) ]); -// println "initial buffer (for flen = \(flen) and inputSpacing = \(inputSpacing)) with input phase \(phase) has length \(mat.width buffer)"; + println "initial buffer (for flen = \(flen), inputSpacing = \(inputSpacing), outputSpacing = \(outputSpacing)) with input phase \(phase) has length \(mat.width buffer)"; var pos = 0;
--- a/src/may/stream/test/test_resample.yeti Tue Oct 08 07:57:27 2013 +0100 +++ b/src/may/stream/test/test_resample.yeti Tue Oct 08 07:58:09 2013 +0100 @@ -47,13 +47,11 @@ compare str.available (Known 4) and compare str.finished? false and (r = str.read 3; - println "r = \(r)"; compare (mat.size r) { rows = 1, columns = 3 }) and compare str.position 3 and compare str.available (Known 1) and compare str.finished? false and (r = str.read 3; - println "r = \(r)"; compare (mat.size r) { rows = 1, columns = 1 }) and compare str.position 4 and compare str.available (Known 0) and @@ -137,49 +135,44 @@ */ "resample-spectrum": \( - // Generate a wave with a lot of harmonics, resample by some - // ratio, check that the resulting signal has substantially the - // same magnitude spectrum as the original - inrate = 44100; - outrate = 48000; - freq = 500; - forms = manip.duplicated 2 (waves.saw inrate freq); - inform = forms[0]; - outform = resample.resampledTo outrate forms[1]; + // Principle: Generate a wave with a lot of harmonics, resample by + // some ratio, check that the resulting signal has substantially + // the same magnitude spectrum as the original. + + // Read and window a chunk of signal from a stream sigOf str n = - (\() (str.read n); - sig = mat.getRow 0 (str.read n); + (sig = mat.getRow 0 (str.read n); win.windowed win.hann sig); - incount = inrate; - outcount = outrate; - insig = time "read original, \(incount*2) at rate \(inrate)" \(sigOf inform incount); - outsig = time "read resampled, \(outcount*2) at rate \(outrate)" \(sigOf outform outcount); - speclen = (min incount outcount) / 2 + 1; - inmag = bf.divideBy incount (vec.resizedTo speclen (fft.realForwardMagnitude incount insig)); - outmag = bf.divideBy outcount (vec.resizedTo speclen (fft.realForwardMagnitude outcount outsig)); - diff = bf.subtract inmag outmag; - compareMatrices 1e-7 (mat.newRowVector outmag) (mat.newRowVector inmag); -/* -// compareMatrices 1e-8 [vec.list inmag] [vec.list outmag] or - (//println "inmag: \(vec.list inmag)"; - //println "outmag: \(vec.list outmag)"; - //println "diff: \(vec.list diff)"; - println "\nout of range: "; - var i = 0; - for (vec.list diff) do d: - if abs d > 1e-8 then - print " * \(d) at \(i) [\(vec.at inmag i) vs \(vec.at outmag i)]\n"; - fi; - i := i + 1; - done; - println ""; -// \() (pl.plot [Vector inmag, Vector outmag]); -// \() (pl.plot [Vector diff]); - false); -*/ + + // Return magnitude spectrum, running fft at n points and then + // truncating to m + specOf sig n m = + vec.resizedTo m (bf.divideBy n (fft.realForwardMagnitude n sig)); + + //!!! better to generate n separate tests here? + + all id + (map do inrate: + all id + (map do outrate: + freq = 500; + forms = manip.duplicated 2 (waves.saw inrate freq); + inform = forms[0]; + outform = resample.resampledTo outrate forms[1]; + incount = inrate; + outcount = outrate; + // We don't compare bins within 1% of the Nyquist freq + speclen = (min incount outcount) / 2; + speclen = speclen - int (speclen / 100); + inmag = specOf (sigOf inform incount) incount speclen; + outmag = specOf (sigOf outform outcount) outcount speclen; + compareMatrices 1e-7 + (mat.newRowVector outmag) + (mat.newRowVector inmag); + done [8000,44100,48000]) + done [8000,44100,48000]); ), - "interpolated-misc": \( // Interpolating any signal by N should give a signal in which // every Nth sample is the original signal