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