changeset 158:b6db07468ed1

Rework stream to support indefinite-length streams and handle multiple channels in framer. Make compile, but some tests fail (and others are still missing).
author Chris Cannam
date Wed, 01 May 2013 12:03:45 +0100
parents ed7e1fb91745
children a9d58d9c71ca
files yetilab/block/block.yeti yetilab/block/fmatrix.yeti yetilab/block/matrix.yeti yetilab/matrix/matrix.yeti yetilab/matrix/test/test_matrix.yeti yetilab/stream/audiofile.yeti yetilab/stream/channels.yeti yetilab/stream/framer.yeti yetilab/stream/playback.yeti yetilab/stream/stream.yeti yetilab/stream/syntheticstream.yeti yetilab/stream/test/audiofile_reference.yeti yetilab/stream/test/test_framer.yeti yetilab/stream/test/test_stream.yeti yetilab/test/test.yeti yetilab/vamp/test/test_vamp.yeti
diffstat 16 files changed, 194 insertions(+), 275 deletions(-) [+]
line wrap: on
line diff
--- a/yetilab/block/block.yeti	Wed May 01 07:58:39 2013 +0100
+++ b/yetilab/block/block.yeti	Wed May 01 12:03:45 2013 +0100
@@ -6,39 +6,39 @@
 typedef opaque block = ~double[];
 
 {
-zeros = vec.zeros,
-consts = vec.consts,
-ones = vec.ones,
-block v = v,
-data b = b,
-vector b = vec.copyOf b,
-floats = vec.floats,
-fromFloats ff = vec.fromFloats ff,
-fromList l = vec.vector l,
-list = vec.list,
-length = vec.length,
-equal = vec.equal,
-copyOf = vec.copyOf,
-rangeOf = vec.rangeOf,
-resizedTo = vec.resizedTo,
-concat = vec.concat,
+    zeros = vec.zeros,
+    consts = vec.consts,
+    ones = vec.ones,
+    block v = v,
+    data b = b,
+    vector b = vec.copyOf b,
+    floats = vec.floats,
+    fromFloats ff = vec.fromFloats ff,
+    fromList l = vec.vector l,
+    list = vec.list,
+    length = vec.length,
+    equal = vec.equal,
+    copyOf = vec.copyOf,
+    rangeOf = vec.rangeOf,
+    resizedTo = vec.resizedTo,
+    concat = vec.concat,
 } as {
-zeros is number -> block,
-consts is number -> number -> block,
-ones is number -> block,
-block is ~double[] -> block,
-data is block -> ~double[],
-vector is block -> ~double[],
-floats is block -> ~float[],
-fromFloats is ~float[] -> block,
-fromList is list?<number> -> block,
-list is block -> list<number>,
-length is block -> number,
-equal is block -> block -> boolean,
-copyOf is block -> block,
-rangeOf is block -> number -> number -> block,
-resizedTo is number -> block -> block,
-concat is list?<block> -> block,
+    zeros is number -> block,
+    consts is number -> number -> block,
+    ones is number -> block,
+    block is ~double[] -> block,
+    data is block -> ~double[],
+    vector is block -> ~double[],
+    floats is block -> ~float[],
+    fromFloats is ~float[] -> block,
+    fromList is list?<number> -> block,
+    list is block -> list<number>,
+    length is block -> number,
+    equal is block -> block -> boolean,
+    copyOf is block -> block,
+    rangeOf is block -> number -> number -> block,
+    resizedTo is number -> block -> block,
+    concat is list?<block> -> block,
 }
 
 
--- a/yetilab/block/fmatrix.yeti	Wed May 01 07:58:39 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-module yetilab.block.fmatrix;
-
-// Basic matrices using primitive array of double as each row
-
-vec = load yetilab.block.fvector;
-
-zeroMatrix rows cols = array (map \(vec.zeros cols) [1..rows]);
-
-generate f rows cols =
-   (m = zeroMatrix rows cols;
-    for [0..rows-1] do row:
-        for [0..cols-1] do col:
-            m[row][col] := f row col;
-        done;
-    done;
-    m);
-
-constMatrix n = generate do row col: n done;
-randomMatrix = generate do row col: Math#random() done;
-identityMatrix = constMatrix 1;
-
-width m = if length m > 0 then vec.length m[0] else 0 fi;
-cols = width;
-
-height m = length m;
-rows = height;
-
-dimensions m = { cols = width m, rows = height m };
-
-copyOf m = array (map vec.copyOf m);
-
-transposed m is array<~double[]> -> array<~double[]> = 
-    generate do row col: m[col][row] done (cols m) (rows m);
-
-{
-generate, constMatrix, randomMatrix, zeroMatrix, identityMatrix,
-width, cols, height, rows, dimensions,
-copyOf,
-transposed,
-}
-
--- a/yetilab/block/matrix.yeti	Wed May 01 07:58:39 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-module yetilab.block.matrix;
-
-// Basic matrices using number type (rather than primitive arrays)
-
-zeros n = array(map \0 [1..n]);
-ones  n = array(map \1 [1..n]);
-
-generateMatrix f rows cols = array
-   (map do row: array
-       (map (f row) [0..cols-1])
-    done [0..rows-1]);
-
-constMatrix n = generateMatrix do row col: n done;
-
-randomMatrix = generateMatrix do row col: Math#random() done;
-
-zeroMatrix = constMatrix 0;
-identityMatrix = constMatrix 1;
-
-width m = if length m > 0 then length m[0] else 0 fi;
-
-height m = length m;
-
-dimensions m = { cols = width m, rows = height m };
-
-transposed m = array
-   (map do n: array
-       (map do a: a[n-1] done m)
-    done [1..width m]);
-
-interleaved m = array(concat(transposed m));
-
-deinterleaved rows v =
-    generateMatrix do row col:
-        v[rows * col + row]
-    done rows (length v / rows);
-
-{
-zeros, ones,
-generateMatrix, constMatrix, randomMatrix, zeroMatrix, identityMatrix,
-width, height, dimensions,
-transposed,
-interleaved, deinterleaved,
-}
-
--- a/yetilab/matrix/matrix.yeti	Wed May 01 07:58:39 2013 +0100
+++ b/yetilab/matrix/matrix.yeti	Wed May 01 12:03:45 2013 +0100
@@ -45,7 +45,7 @@
         RowM rows: r = rows[row]; (r is ~double[])[col];
         ColM cols: c = cols[col]; (c is ~double[])[row];
         esac,
-    setAt row col n =
+    setAt row col n = //!!! dangerous, could modify copies -- should it be allowed?
         case d of
         RowM rows: r = rows[row]; (r is ~double[])[col] := n;
         ColM cols: c = cols[col]; (c is ~double[])[row] := n;
@@ -77,6 +77,7 @@
 constMatrix n = generate do row col: n done;
 randomMatrix = generate do row col: Math#random() done;
 identityMatrix = constMatrix 1;
+zeroSizeMatrix () = zeroMatrix { rows = 0, columns = 0 };
 
 width m = m.size.columns;
 height m = m.size.rows;
@@ -134,6 +135,16 @@
 scaled factor m =
     generate do row col: factor * m.getAt row col done m.size;
 
+resizedTo newsize m =
+   (oldsize = m.size;
+    if newsize == oldsize then m
+    else 
+        generate do row col:
+            if row < oldsize.rows and col < oldsize.columns
+            then m.getAt row col else 0 fi
+            done newsize;
+    fi);
+
 sum' m1 m2 =
     if m1.size != m2.size
     then failWith "Matrices are not the same size: \(m1.size), \(m2.size)";
@@ -151,7 +162,7 @@
     fi;
 
 {
-constMatrix, randomMatrix, zeroMatrix, identityMatrix,
+constMatrix, randomMatrix, zeroMatrix, identityMatrix, zeroSizeMatrix,
 generate,
 width, height,
 equal,
@@ -159,6 +170,7 @@
 transposed,
 flipped,
 scaled,
+resizedTo,
 sum = sum', product,
 newMatrix, newRowVector, newColumnVector,
 }
--- a/yetilab/matrix/test/test_matrix.yeti	Wed May 01 07:58:39 2013 +0100
+++ b/yetilab/matrix/test/test_matrix.yeti	Wed May 01 12:03:45 2013 +0100
@@ -6,15 +6,9 @@
 
 import yeti.lang: FailureException;
 
-{ compare } = load yetilab.test.test;
+{ compare, compareUsing } = load yetilab.test.test;
 
-compareMatrices obtained expected =
-    if mat.equal obtained expected then
-        true;
-    else
-        println "** expected: \(expected.data)\n   obtained: \(obtained.data)";
-        false;
-    fi;
+compareMatrices = compareUsing mat.equal;
 
 makeTests name flipper =
    (constMatrix n s = flipper (mat.constMatrix n s);
@@ -229,6 +223,27 @@
     yrt
 ),
 
+"resizedTo-\(name)": \(
+    compareMatrices
+       (mat.resizedTo { rows = 2, columns = 2 }
+           (newMatrix (ColumnMajor ()) [[1,4],[2,5],[3,6]]))
+       (newMatrix (ColumnMajor ()) [[1,4],[2,5],[3,6]]) and
+        compareMatrices
+           (mat.resizedTo { rows = 3, columns = 4 }
+               (newMatrix (ColumnMajor ()) [[1,4],[2,5],[3,6]]))
+           (newMatrix (ColumnMajor ()) [[1,4,0],[2,5,0],[3,6,0],[0,0,0]]) and
+        compareMatrices
+           (mat.resizedTo { rows = 1, columns = 1 }
+               (newMatrix (ColumnMajor ()) [[1,4],[2,5],[3,6]]))
+           (newMatrix (ColumnMajor ()) [[1]])
+),
+
+"zeroSizeMatrix-\(name)": \(
+    compareMatrices
+       (mat.zeroSizeMatrix ())
+       (newMatrix (ColumnMajor ()) [])
+),
+
 ]);
 
 colhash = makeTests "column-major" id;
--- a/yetilab/stream/audiofile.yeti	Wed May 01 07:58:39 2013 +0100
+++ b/yetilab/stream/audiofile.yeti	Wed May 01 12:03:45 2013 +0100
@@ -9,7 +9,6 @@
 
 import java.nio: ByteBuffer, ByteOrder;
 
-str = load yetilab.stream.stream;
 ch = load yetilab.stream.channels;
 block = load yetilab.block.block;
 
@@ -96,16 +95,13 @@
     aistream = AudioSystem#getAudioInputStream(f);
     format = aistream#getFormat();
     len = available' { format, aistream }; // at start of stream
-    str.stream {
-        format,
-        length = Known len,
-        rate = format#getSampleRate(),
-        channels = format#getChannels(),
+    {
         get position () = len - available' { aistream, format },
+        get channels () = format#getChannels(),
+        get sampleRate () = format#getSampleRate(),
         get available () = Known (available' { aistream, format }),
+        get finished? () = not (aistream#available() > 0),
         read = read' { aistream, format },
-        readInterleaved = readInterleaved' { aistream, format },
-        readMono = readMono' { aistream, format },
         close () = close' { aistream },
     });
 
--- a/yetilab/stream/channels.yeti	Wed May 01 07:58:39 2013 +0100
+++ b/yetilab/stream/channels.yeti	Wed May 01 12:03:45 2013 +0100
@@ -3,70 +3,76 @@
 
 vec = load yetilab.block.fvector;
 block = load yetilab.block.block;
-mat = load yetilab.block.fmatrix;
+mat = load yetilab.matrix.matrix;
         
 interleaved m = 
-   ({ cols, rows } = mat.dimensions m;
-    v = vec.zeros (cols * rows);
+   ({ columns, rows } = m.size;
+    v = vec.zeros (columns * rows);
     for [0..rows-1] do row:
-        for [0..cols-1] do col:
-            v[col * rows + row] := m[row][col];
+        for [0..columns-1] do col:
+            v[col * rows + row] := m.getAt row col;
         done;
     done;
     block.block v);
 
-deinterleaved rows b =
+deinterleaved channels b = //!!! should generate a RowMajor matrix for faster framing
    (v = block.data b;
     mat.generate do row col:
-        v[rows * col + row]
-    done rows ((vec.length v) / rows));
+        v[channels * col + row]
+    done { rows = channels, columns = ((vec.length v) / channels) });
 
 mixedDown m =
-   (if empty? m then block.zeros 0 else
-        { cols, rows } = mat.dimensions m;
-        v = vec.copyOf m[0];
-        for [1..rows-1] do row:
-            for [0..cols-1] do col:
-                v[col] := v[col] + m[row][col];
-            done;
+   ({ columns, rows } = m.size;
+    v = vec.zeros columns;
+    for [0..rows-1] do row:
+        for [0..columns-1] do col:
+            v[col] := v[col] + m.getAt row col;
         done;
-        block.block v;
-    fi);
+    done;
+    block.block v);
 
-mixedDownFromInterleaved rows b =
+mixedDownFromInterleaved channels b =
    (v = block.data b;
-    cols = ((vec.length v) / rows);
-    v' = vec.zeros cols;
-    for [0..rows-1] do row:
-        for [0..cols-1] do col:
-            v'[col] := v'[col] + v[col * rows + row];
+    columns = ((vec.length v) / channels);
+    v' = vec.zeros columns;
+    for [0..channels-1] do row:
+        for [0..columns-1] do col:
+            v'[col] := v'[col] + v[col * channels + row];
         done;
     done;
     block.block v');
 
-mixedFromInterleavedTo targetRows rows b = 
-    if targetRows == rows then
+mixedFromInterleavedTo targetChannels channels b = 
+    if targetChannels == channels then
         b;
-    elif targetRows == 1 then
-        mixedDownFromInterleaved rows b;
+    elif targetChannels == 1 then
+        mixedDownFromInterleaved channels b;
     else
         v = block.data b;
-        cols = ((vec.length v) / rows);
-        v' = vec.zeros (cols * targetRows);
-        for [0..targetRows-1] do target:
-            for [0..cols-1] do col:
-                if target < rows then
-                    v'[col * targetRows + target] := v[col * rows + target];
-                elif rows == 1 then
-                    v'[col * targetRows + target] := v[col * rows];
+        columns = ((vec.length v) / channels);
+        v' = vec.zeros (columns * targetChannels);
+        for [0..targetChannels-1] do target:
+            for [0..columns-1] do col:
+                if target < channels then
+                    v'[col * targetChannels + target] := v[col * channels + target];
+                elif channels == 1 then
+                    v'[col * targetChannels + target] := v[col * channels];
                 fi
             done
         done;
         block.block v';
     fi;
 
+mixedAndInterleavedTo targetChannels m = 
+    if targetChannels == 1 then
+        mixedDown m
+    else
+        interleaved
+           (mat.resizedTo { rows = targetChannels, columns = m.size.columns } m)
+    fi;
+
 {
     interleaved, deinterleaved,
-    mixedDown, mixedDownFromInterleaved, mixedFromInterleavedTo,
+    mixedDown, mixedDownFromInterleaved, mixedFromInterleavedTo, mixedAndInterleavedTo
 }
 
--- a/yetilab/stream/framer.yeti	Wed May 01 07:58:39 2013 +0100
+++ b/yetilab/stream/framer.yeti	Wed May 01 12:03:45 2013 +0100
@@ -3,7 +3,7 @@
 
 /**
  * Framer expresses a stream (or a file) as a lazy list of (possibly
- * overlapping) frames of mono data.
+ * overlapping) frames of data.
  */
 
 block = load yetilab.block.block;
@@ -11,25 +11,32 @@
 af = load yetilab.stream.audiofile;
 win = load yetilab.transform.window;
 fft = load yetilab.transform.fft;
+mat = load yetilab.matrix.matrix;
+ch = load yetilab.stream.channels;
 
 blockList framesize stream =
     if stream.finished? then
-       (stream.close (); [] );
+        stream.close ();
+        [ mat.zeroMatrix { rows = stream.channels, columns = 0 } ]
     else
-        block.resizedTo framesize (stream.readMono framesize)
+        mat.resizedTo { rows = stream.channels, columns = framesize }
+           (stream.read framesize)
             :. \(blockList framesize stream);
     fi;
 
 overlappingBlockList size hop stream valid buffer =
    (
-    b = stream.readMono hop;
-    obtained = block.length b;
+    m = stream.read hop;
+    obtained = mat.width m;
 
     // Retain framesize - hop samples from old buffer, add hop samples
     // (zero-padded if necessary) just read
-    buffer = block.concat
-       [block.rangeOf buffer hop (size-hop),
-        block.resizedTo hop b];
+    buffer = map2
+        do buf row:
+            block.concat
+               [block.rangeOf buf hop (size-hop),
+                block.resizedTo hop (m.getRow row)];
+        done buffer [0..stream.channels-1];
 
     // Number of "valid" elements (not tail-end zero-padding) left in buffer
     remaining = valid - (hop - obtained);
@@ -38,7 +45,8 @@
         stream.close ();
         [];
     else
-        buffer :. \(overlappingBlockList size hop stream remaining buffer);
+        mat.newMatrix (RowMajor ()) (map block.list buffer)
+            :. \(overlappingBlockList size hop stream remaining buffer);
     fi);
 
 frames { framesize, hop } stream =
@@ -46,12 +54,15 @@
         blockList framesize stream
     else
         overlappingBlockList framesize hop stream 
-            framesize (block.zeros framesize);
+            framesize (map \(block.zeros framesize) [0..stream.channels-1]);
     fi;
 
+monoFrames params stream =
+    map ch.mixedDown (frames params stream);
+
 windowedFrames { framesize, hop, window } stream =
    (win = window framesize;
-    map (bf.multiply win) (frames { framesize, hop } stream));
+    map (bf.multiply win) (monoFrames { framesize, hop } stream));
 
 frequencyDomainFrames { framesize, hop } stream =
    (f = fft.realForward framesize;
@@ -59,12 +70,16 @@
 
 { 
     frames,
+    monoFrames,
     windowedFrames,
     frequencyDomainFrames,
 
     framesOfFile parameters filename =
         frames parameters (af.open filename),
 
+    monoFramesOfFile parameters filename =
+        monoFrames parameters (af.open filename),
+
     windowedFramesOfFile parameters filename = 
         windowedFrames parameters (af.open filename),
 
--- a/yetilab/stream/playback.yeti	Wed May 01 07:58:39 2013 +0100
+++ b/yetilab/stream/playback.yeti	Wed May 01 12:03:45 2013 +0100
@@ -42,8 +42,8 @@
    (line = open { rate = stream.sampleRate, channels = stream.channels };
     blocksize = 10240;
     not stream.finished? loop
-        line.play [(ch.mixedFromInterleavedTo line.channels stream.channels
-                    (stream.readInterleaved blocksize))];
+        line.play [(ch.mixedAndInterleavedTo line.channels 
+                    (stream.read blocksize))];
     line.close();
     stream.close());
 
--- a/yetilab/stream/stream.yeti	Wed May 01 07:58:39 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-
-module yetilab.stream.stream;
-
-monoStream box =
-   (readAll' box = box.read (box.len - box.position);
-    {
-        get position () = box.position,
-        get channels () = 1,
-        get sampleRate () = box.rate,
-        get available () = box.len - box.position,
-        get finished? () = not (box.len > box.position),
-        read = box.read,
-        readInterleaved = box.read,
-        readMono = box.read,
-        readAll () = readAll' box,
-        readAllInterleaved () = readAll' box,
-        readAllMono () = readAll' box,
-        close = box.close,
-    });
-
-stream box = 
-   ({
-        get position () = box.position,
-        get channels () = box.channels,
-        get sampleRate () = box.rate,
-        get available () = box.len - box.position,
-        get finished? () = not (box.len > box.position),
-        read = box.read,
-        readInterleaved = box.readInterleaved,
-        readMono = box.readMono,
-        readAll () = box.read (box.len - box.position),
-        readAllInterleaved () = box.readInterleaved (box.len - box.position),
-        readAllMono () = box.readMono (box.len - box.position),
-        close = box.close,
-    });
-
-{ monoStream, stream }
-
--- a/yetilab/stream/syntheticstream.yeti	Wed May 01 07:58:39 2013 +0100
+++ b/yetilab/stream/syntheticstream.yeti	Wed May 01 12:03:45 2013 +0100
@@ -1,24 +1,28 @@
 
 module yetilab.stream.syntheticstream;
 
-str = load yetilab.stream.stream;
+ch = load yetilab.stream.channels;
 vec = load yetilab.block.fvector;
 block = load yetilab.block.block;
 
-generated rate generator =
-    // generator takes time in seconds as arg, returns number in -1,+1 range
-    str.monoStream {
-        var position = 0,
-        rate,
-        read count = 
+generated sampleRate generator =
+   (// generator takes time in seconds as arg, returns number in -1,+1 range
+    var position = 0;
+    {
+        get position () = position,
+        get channels () = 1, 
+        get sampleRate () = sampleRate,
+        get available () = Infinite (),
+        get finished? () = false,
+        read count = ch.deinterleaved 1
            (result = vec.zeros count;
             for [0..count-1] do i:
-                result[i] := generator ((position + i) / rate)
+                result[i] := generator ((position + i) / sampleRate)
             done;
             position := position + count;
             block.block result),
         close = \(),
-        };
+    });
 
 sinusoid rate freq =
     generated rate (sin . (* (freq / (2*pi * rate))));
@@ -26,21 +30,27 @@
 whiteNoise rate =
     generated rate \((Math#random() * 2.0) - 1.0);
 
-precalculated rate data is number -> ~double[] -> 'a =
-   (n = vec.length data;
-    str.monoStream {
-        var position = 0,
-        len = n,
-        rate,
-        read count = 
-           (rc = min count (len - position);
-            result = vec.rangeOf data position rc;
+silent rate =
+    generated rate \0;
+
+precalculated rate data =
+   (n = block.length data;
+    var position = 0;
+    {
+        get position () = position,
+        get channels () = 1,
+        get sampleRate () = rate,
+        get available () = Known (n - position),
+        get finished? () = not (n > position),
+        read count = ch.deinterleaved 1
+           (rc = min count (n - position);
+            result = block.rangeOf data position rc;
             position := position + rc;
-            block.block result),
+            result),
         close = \(),
     });
 
 {
-    generated, precalculated, sinusoid, whiteNoise,
+    generated, precalculated, sinusoid, whiteNoise, silent,
 }
 
--- a/yetilab/stream/test/audiofile_reference.yeti	Wed May 01 07:58:39 2013 +0100
+++ b/yetilab/stream/test/audiofile_reference.yeti	Wed May 01 12:03:45 2013 +0100
@@ -2,8 +2,9 @@
 module yetilab.stream.test.audiofile_reference;
 
 syn = load yetilab.stream.syntheticstream;
-str = load yetilab.stream.stream;
 vec = load yetilab.block.fvector;
 block = load yetilab.block.block;
 
+//!!!
     
+();
--- a/yetilab/stream/test/test_framer.yeti	Wed May 01 07:58:39 2013 +0100
+++ b/yetilab/stream/test/test_framer.yeti	Wed May 01 12:03:45 2013 +0100
@@ -3,8 +3,13 @@
 
 fr = load yetilab.stream.framer;
 block = load yetilab.block.block;
+mat = load yetilab.matrix.matrix;
 
-{ compare, testStream } = load yetilab.test.test;
+{ compare, compareUsing, testStream } = load yetilab.test.test;
+
+compareFrames frames1 frames2 =
+    all id (map2 do f1 f2: compareUsing mat.equal f1 f2 done frames1
+       (map mat.newRowVector frames2));
 
 [
 
@@ -66,26 +71,26 @@
 "frames-2x5": \( 
     fr = fr.frames { framesize = 2, hop = 2 } (testStream 5);
     expected = [ [1,2], [3,4], [5,0] ];
-    compare (map block.list fr) expected;
+    compareFrames fr expected;
 ),
 
 "frames-4.3x4": \( 
     fr = fr.frames { framesize = 4, hop = 3 } (testStream 4);
     expected = [ [0,1,2,3], [3,4,0,0] ];
-    compare (map block.list fr) expected;
+    compareFrames fr expected;
 ),
 
 "frames-3.2x4": \(
     fr = fr.frames { framesize = 3, hop = 2 } (testStream 4);
     expected = [ [0,1,2], [2,3,4], [4,0,0] ];
-    compare (map block.list fr) expected;
+    compareFrames fr expected;
 ),
 
 "frames-3.1x6": \(
     fr = fr.frames { framesize = 3, hop = 1 } (testStream 6);
     expected = [ [0,0,1], [0,1,2], [1,2,3], [2,3,4],
                  [3,4,5], [4,5,6], [5,6,0], [6,0,0] ];
-    compare (map block.list fr) expected;
+    compareFrames fr expected;
 ),
 
 ] is hash<string, () -> boolean>;
--- a/yetilab/stream/test/test_stream.yeti	Wed May 01 07:58:39 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-
-module yetilab.stream.test.test_stream;
-
-str = load yetilab.stream.stream;
-block = load yetilab.block.block;
-
-{ compare, testStream } = load yetilab.test.test;
-
-[
-
-"generated": \(
-//    s = str.generated 10
-//        do i:
-)
-            
-] is hash<string, () -> boolean>;
-
--- a/yetilab/test/test.yeti	Wed May 01 07:58:39 2013 +0100
+++ b/yetilab/test/test.yeti	Wed May 01 12:03:45 2013 +0100
@@ -1,13 +1,13 @@
 module yetilab.test.test;
 
-vec = load yetilab.block.fvector;
+block = load yetilab.block.block;
 ss = load yetilab.stream.syntheticstream;
 
 import yeti.lang: FailureException;
 
-testStream n is number -> 'a  = ss.precalculated 1000 (vec.vector [1..n]);
+testStream n is number -> 'a  = ss.precalculated 1000 (block.fromList [1..n]);
 
-compareWith comparator obtained expected =
+compareUsing comparator obtained expected =
     if comparator obtained expected then
         true;
     else
@@ -15,7 +15,7 @@
         false;
     fi;
 
-compare obtained expected = compareWith (==) obtained expected;
+compare obtained expected = compareUsing (==) obtained expected;
 
 select f = fold do r x: if f x then x::r else r fi done [];
 
@@ -44,6 +44,6 @@
     bad);
 
 {
-    testStream, compare, compareWith, failedTests, runTests
+    testStream, compare, compareUsing, failedTests, runTests
 }
 
--- a/yetilab/vamp/test/test_vamp.yeti	Wed May 01 07:58:39 2013 +0100
+++ b/yetilab/vamp/test/test_vamp.yeti	Wed May 01 12:03:45 2013 +0100
@@ -4,13 +4,13 @@
 synthetic = load yetilab.stream.syntheticstream;
 mat = load yetilab.matrix.matrix;
 
-{ compare, compareWith } = load yetilab.test.test;
+{ compare, compareUsing } = load yetilab.test.test;
 
 testPluginKey = "vamp-test-plugin:vamp-test-plugin";
 
 rate = 44100;
 
-testStream () = synthetic.whiteNoise rate 30;
+testStream () = synthetic.whiteNoise rate;
 
 processTest output = 
     v.processStreamStructured testPluginKey output (testStream ());
@@ -87,7 +87,7 @@
 "grid-oss": \(
     case processTest "grid-oss" of //!!! test spacing?
     Grid g:
-        compareWith mat.equal g 
+        compareUsing mat.equal g 
            (mat.newMatrix (ColumnMajor ())
                (map do x:
                     floats (map do y:
@@ -101,7 +101,7 @@
 "grid-fsr": \(
     case processTest "grid-fsr" of //!!! test spacing?
     Grid g:
-        compareWith mat.equal g 
+        compareUsing mat.equal g 
            (mat.newMatrix (ColumnMajor ())
                (map do x:
                     floats (map do y: