changeset 498:295b66046da3 redo_framer

Toward a more flexible framer interface
author Chris Cannam
date Tue, 19 Nov 2013 19:26:48 +0000
parents 2202e40f375a
children 8fdcf2fec5bd
files src/may/feature/specdiff.yeti src/may/matrix.yeti src/may/matrix/test/test_matrix.yeti src/may/stream/framer.yeti
diffstat 4 files changed, 90 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/src/may/feature/specdiff.yeti	Tue Nov 19 19:26:15 2013 +0000
+++ b/src/may/feature/specdiff.yeti	Tue Nov 19 19:26:48 2013 +0000
@@ -9,8 +9,9 @@
 specdiff frames = 
     features magdiff (map cplx.magnitudes frames);
 
-specdiffOfFile parameters filename =
-    specdiff (fr.frequencyDomainFramesOfFile parameters filename);
+specdiffOfFile framesize w filename =
+    specdiff
+       (fr.framesOfFile framesize [ FrequencyDomain true, Window w ] filename);
 
 {
     specdiff,
--- a/src/may/matrix.yeti	Tue Nov 19 19:26:15 2013 +0000
+++ b/src/may/matrix.yeti	Tue Nov 19 19:26:48 2013 +0000
@@ -799,6 +799,12 @@
         maxv (map (.v) (enumerate m));
     fi;
 
+transformRows rf m =
+    newMatrix (RowMajor ()) (map rf (asRows m));
+
+transformColumns cf m =
+    newMatrix (ColumnMajor ()) (map cf (asColumns m));
+
 format m =
     strJoin "\n"
        (chunk = 8;
@@ -811,8 +817,8 @@
                    map do v:
                        n = mm.round (v * 10000);
                        strPad ' ' 10 "\(n / 10000)";
-                   done (vec.list row);
-               done (asRows (columnSlice m c0 (c1 + 1))) |> concat |> strJoin "")
+                   done (vec.list row) |> strJoin "";
+               done (asRows (columnSlice m c0 (c1 + 1))) |> strJoin "\n")
             ];
         done [0..width m / chunk - 1] |> concat);
 
@@ -869,6 +875,8 @@
     concatVertical,
     rowSlice,
     columnSlice,
+    transformRows,
+    transformColumns,
     newMatrix,
     newRowVector,
     newColumnVector,
@@ -924,6 +932,8 @@
     concatVertical is list<matrix_t> -> matrix_t,
     rowSlice is matrix_t -> number -> number -> matrix_t, 
     columnSlice is matrix_t -> number -> number -> matrix_t,
+    transformRows is (vec.vector_t -> vec.vector_t) -> matrix_t -> matrix_t,
+    transformColumns is (vec.vector_t -> vec.vector_t) -> matrix_t -> matrix_t,
     newMatrix is (ColumnMajor () | RowMajor ()) -> list<vec.vector_t> -> matrix_t, 
     newRowVector is vec.vector_t -> matrix_t, 
     newColumnVector is vec.vector_t -> matrix_t,
--- a/src/may/matrix/test/test_matrix.yeti	Tue Nov 19 19:26:15 2013 +0000
+++ b/src/may/matrix/test/test_matrix.yeti	Tue Nov 19 19:26:48 2013 +0000
@@ -202,6 +202,22 @@
           (constMatrix 5 { rows = 0, columns = 0 })
 ),
 
+"transformRows-\(name)": \(
+    m = newMatrix (RowMajor ()) [[1,4],[0,5],[3,6]];
+    m' = newMatrix (ColumnMajor ()) [[1,0,3],[4,5,6]];
+    m'' = newMatrix (RowMajor ()) [[2,8],[0,10],[6,12]];
+    compareMatrices (mat.transformRows (vec.scaled 2) m) m'' and
+        compareMatrices (mat.transformRows (vec.scaled 2) m') m''
+),
+
+"transformColumns-\(name)": \(
+    m = newMatrix (RowMajor ()) [[1,4],[0,5],[3,6]];
+    m' = newMatrix (ColumnMajor ()) [[1,0,3],[4,5,6]];
+    m'' = newMatrix (RowMajor ()) [[2,8],[0,10],[6,12]];
+    compareMatrices (mat.transformColumns (vec.scaled 2) m) m'' and
+        compareMatrices (mat.transformColumns (vec.scaled 2) m') m''
+),
+
 "sum-\(name)": \(
     compareMatrices
        (mat.sum (constMatrix 2 { rows = 3, columns = 4 })
--- a/src/may/stream/framer.yeti	Tue Nov 19 19:26:15 2013 +0000
+++ b/src/may/stream/framer.yeti	Tue Nov 19 19:26:48 2013 +0000
@@ -13,6 +13,7 @@
 mat = load may.matrix;
 ch = load may.stream.channels;
 complex = load may.complex;
+cm = load may.matrix.complex;
 
 load may.stream.type;
 
@@ -52,14 +53,62 @@
             :. \(overlappingBlockList size hop stream remaining buffer);
     fi);
 
-frames { framesize, hop } stream =
+//!!! doc: if hop != framesize, stream will be padded at start with
+// framesize - hop zeros if padded is true. if hop == framesize, no
+// padding will occur at start regardless of the value of padded.  The
+// end will always be padded (...?)
+frames' framesize hop padded stream =
     if framesize == hop then
         blockList framesize stream
     else
-        overlappingBlockList framesize hop stream 
-            framesize (map \(vec.zeros framesize) [0..stream.channels-1]);
+        initialBuffer = 
+            if padded then
+                map \(vec.zeros framesize) [0..stream.channels-1];
+            else 
+                mat.asRows
+                   (mat.concatHorizontal
+                       [mat.zeroMatrix { rows = stream.channels, columns = hop },
+                        stream.read framesize]);
+            fi;
+        overlappingBlockList framesize hop stream framesize initialBuffer;
     fi;
 
+frames framesize options stream =
+   (var hop = framesize;
+    var padded = true;
+    var windower = id;
+    var transform = id;
+    for options \case of
+        Hop h: hop := h;
+        Padded p: padded := p;
+        Window w:
+            windower := mat.transformRows (vec.multiply (w framesize));
+        FrequencyDomain f:
+            transform := mat.transformRows (fft.realForwardMagnitude framesize);
+    esac;
+    map transform
+       (map windower
+           (frames' framesize hop padded stream)));
+
+complexFrames framesize options stream =
+   (var hop = framesize;
+    var padded = true;
+    var windower = id;
+    var rowTransform = do r: complex.complexArray r (vec.zeros (vec.length r)) done;
+    for options \case of
+        Hop h: hop := h;
+        Padded p: padded := p;
+        Window w:
+            windower := mat.transformRows (vec.multiply (w framesize));
+        FrequencyDomain f:
+            rowTransform := fft.realForward framesize;
+    esac;
+    map do m:
+        cm.newComplexMatrix (RowMajor ()) (map rowTransform (mat.asRows m))
+        done
+       (map windower
+           (frames' framesize hop padded stream)));
+
 streamContiguous rate framesize frames =
    (var remaining = frames;
     var buffered = mat.zeroSizeMatrix ();
@@ -170,41 +219,17 @@
             frames
     fi;
 
-monoFrames params stream =
-    map ch.mixedDown (frames params stream);
-
-windowedFrames { framesize, hop, window } stream =
-   (win = window framesize;
-    map (vec.multiply win) (monoFrames { framesize, hop } stream));
-
-frequencyDomainFrames parameters stream =
-   (f = fft.realForward parameters.framesize;
-    map f (windowedFrames parameters stream));
-
-typedef params = { framesize is number, hop is number };
-typedef winparams = { framesize is number, hop is number, window is number -> vec.vector_t };
 
 { 
-    frames is params -> stream -> list<mat.matrix_t>,
-    monoFrames is params -> stream -> list<vec.vector_t>,
-    windowedFrames is winparams -> stream -> list<vec.vector_t>,
-    frequencyDomainFrames is winparams -> stream -> list<array<complex.complex_t> >,
+    frames,
+    complexFrames,
 
-    framesOfFile parameters filename =
-        frames parameters (af.open filename),
+    framesOfFile framesize options filename =
+        frames framesize options (af.open filename),
 
-    monoFramesOfFile parameters filename =
-        monoFrames parameters (af.open filename),
+    overlapAdd,
 
-    windowedFramesOfFile parameters filename = 
-        windowedFrames parameters (af.open filename),
-
-    frequencyDomainFramesOfFile parameters filename = 
-        frequencyDomainFrames parameters (af.open filename),
-
-    overlapAdd is number -> list<mat.matrix_t> -> mat.matrix_t,
-
-    streamed is number -> params -> list<mat.matrix_t> -> stream,
-    streamOverlapping is number -> winparams -> list<mat.matrix_t> -> stream,
+    streamed,
+    streamOverlapping,
 }