changeset 540:549f71180d21

Row-major matrices for framer functions
author Chris Cannam
date Thu, 20 Mar 2014 16:14:09 +0000
parents 2ec0d9f8a360
children acc244cab1b7
files src/may/matrix.yeti src/may/stream/convolve.yeti src/may/stream/framer.yeti src/may/stream/manipulate.yeti
diffstat 4 files changed, 50 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/src/may/matrix.yeti	Thu Mar 20 11:02:09 2014 +0000
+++ b/src/may/matrix.yeti	Thu Mar 20 16:14:09 2014 +0000
@@ -692,11 +692,10 @@
 
 concatWithGrain tagger getter counter mm =
     tagger (array
-       (concat
-           (map do m:
-               n = counter (size m);
-               map do i: getter i m done [0..n-1]
-               done mm)));
+       (concatMap do m:
+           n = counter (size m);
+           map do i: getter i m done [0..n-1]
+        done mm));
 
 sparseConcat direction first mm =
    (dimension d f = if direction == d then sum (map f mm) else f first fi;
--- a/src/may/stream/convolve.yeti	Thu Mar 20 11:02:09 2014 +0000
+++ b/src/may/stream/convolve.yeti	Thu Mar 20 16:14:09 2014 +0000
@@ -19,6 +19,7 @@
     // framesize*2, in which each frame contains all channels one
     // after another (not interleaved) [because we lack a complex
     // matrix type]
+    //!!! we now have a complex matrix type, revisit this
    (forwardTransform = fft.realForward (framesize * 2);
     do stream:
         padded = 
@@ -46,29 +47,36 @@
     else parts.fst :: splitInto n parts.snd;
     fi);
 
-fastConvolvedWith ir framesize s =
+fastConvolvedWith ir framesize =
     // prerequisite: ir and s have same number of channels
    (framer = zeroPaddedFreqFrames framesize (mat.height ir);
-    ch = s.channels;
+    ch = mat.height ir;
     irfr = framer (syn.precalculated 1 ir); // rate arg is irrelevant here
-    sigfr = framer s;
     inverseTransform = fft.realInverse (framesize * 2);
-    extended = sigfr ++
-        map do _: list (cplx.zeros (ch * (framesize + 1))) done
-           [1..length irfr-1];
-    cframes = doFastConvolve irfr extended; 
-    rframes = (mat.zeroMatrix { rows = ch, columns = framesize * 2}) ::
-        map do fr:
-            mat.fromRows
-               (map inverseTransform (splitInto (framesize+1) fr))
-            done cframes;
-    fr.streamed s.sampleRate (framesize * 2)
-        [ Window win.boxcar, Hop framesize ]
-        rframes;
+    do s:
+        if ch != s.channels then
+            failWith "Signal stream and IR must have same number of channels (\(s.channels) != \(ch))"
+        fi;
+        sigfr = framer s;
+        extended = sigfr ++
+            map do _: list (cplx.zeros (ch * (framesize + 1))) done
+               [1..length irfr-1];
+        cframes = doFastConvolve irfr extended; 
+        rframes =
+           (mat.toRowMajor (mat.zeroMatrix { rows = ch, columns = framesize * 2})) ::
+            map do fr:
+                mat.fromRows
+                   (map inverseTransform (splitInto (framesize+1) fr))
+                done cframes;
+        fr.streamed s.sampleRate (framesize * 2)
+            [ Window win.boxcar, Hop framesize ]
+            rframes;
+    done;
 );
 
 plainConvolvedWith ir s =
     // prerequisite: ir and s have same number of channels
+    //!!! test that and throw
    (var history = mat.toRowMajor
        (mat.zeroMatrix { rows = s.channels, columns = mat.width ir - 1 });
     s with 
@@ -127,23 +135,21 @@
         fi;
     nextPowerOfTwo' 1 n);
 
-//!!! todo: partial application so as to preprocess ir (in fast convolution case)
-convolvedWith options ir s = //!!! cheap mono thing here
+//!!! doc note: this supports partial application (it returns a function that
+// expects the signal) so as to pre-process the IR
+convolvedWith options ir = //!!! cheap mono thing here
 //!!! doc note: fast convolution output is padded to next frame boundary
-   (if mat.height ir != s.channels then
-        failWith "Signal stream and IR must have same number of channels (\(s.channels) != \(mat.height ir))"
-    fi;
-    var type = Fast ();
+   (var type = Fast ();
     var framesize = nextPowerOfTwo (mat.width ir);
     for options \case of
-        Fast s: if s then type := Fast () else type := Plain () fi;
+        Fast f: if f then type := Fast () else type := Plain () fi;
         Framesize n: framesize := nextPowerOfTwo n;
         esac;
     case type of
     Fast ():
-        fastConvolvedWith ir framesize s;
+        fastConvolvedWith ir framesize;
     Plain ():
-        plainConvolvedWith ir s;
+        plainConvolvedWith ir;
     esac);
 
 {
--- a/src/may/stream/framer.yeti	Thu Mar 20 11:02:09 2014 +0000
+++ b/src/may/stream/framer.yeti	Thu Mar 20 16:14:09 2014 +0000
@@ -70,7 +70,8 @@
             else 
                 mat.asRows
                    (mat.concatHorizontal
-                       [mat.zeroMatrix { rows = stream.channels, columns = hop },
+                       [mat.toRowMajor
+                           (mat.zeroMatrix { rows = stream.channels, columns = hop }),
                         stream.read (framesize - hop)]);
             fi;
         overlappingBlockList framesize hop stream framesize initialBuffer;
@@ -122,7 +123,8 @@
    (var remaining = frames;
     var position = 0;
     channels = mat.height (head frames); // so we don't need to keep a head ptr
-    var buffered = mat.zeroMatrix { rows = channels, columns = 0 };
+    var buffered = mat.toRowMajor
+       (mat.zeroMatrix { rows = channels, columns = 0 });
     {
         get position () = position,
         get channels () = channels,
@@ -170,7 +172,7 @@
     first::rest:
         mat.concatHorizontal (ola rest first []);
      _: 
-        mat.zeroMatrix { rows = 0, columns = 0 };
+        mat.toRowMajor (mat.zeroMatrix { rows = 0, columns = 0 });
     esac);
 
 streamOverlapping rate { framesize, hop, window } frames =
@@ -181,7 +183,8 @@
     w = vec.scaled factor (window framesize);
     channels = mat.height (head frames); // so we don't need to keep a head ptr
 
-    var buffered = mat.zeroMatrix { rows = channels, columns = 0 };
+    var buffered = 
+        mat.toRowMajor (mat.zeroMatrix { rows = channels, columns = 0 });
 
     syncd = synchronized remaining;
 
--- a/src/may/stream/manipulate.yeti	Thu Mar 20 11:02:09 2014 +0000
+++ b/src/may/stream/manipulate.yeti	Thu Mar 20 16:14:09 2014 +0000
@@ -41,7 +41,8 @@
             if not s.finished? then
                 mat.resizedTo { rows = s.channels, columns = n } (s.read n);
             else 
-                mat.zeroMatrix { columns = n, rows = s.channels }
+                mat.toRowMajor
+                   (mat.zeroMatrix { columns = n, rows = s.channels });
             fi),
     });
 
@@ -49,7 +50,7 @@
    (var prepos = 0;
     zeros n = mat.toRowMajor
        (prepos := prepos + n;
-        mat.zeroMatrix { rows = s.channels, columns = n });
+        mat.toRowMajor (mat.zeroMatrix { rows = s.channels, columns = n }));
     delay = 
         if nsamples < 0 then
             \0 (s.read (-nsamples));
@@ -105,7 +106,9 @@
                 pos := pos + zc;
                 toAdd := toAdd - zc;
                 mat.concatHorizontal
-                   [r, mat.zeroMatrix { rows = s.channels, columns = zc }];
+                   [r, 
+                    mat.toRowMajor
+                       (mat.zeroMatrix { rows = s.channels, columns = zc })];
             fi),
         close = s.close
     });
@@ -214,7 +217,8 @@
     if s.available == Infinite () then s
     else
         var pos = 0;
-        var cache = mat.zeroMatrix { rows = s.channels, columns = 0 };
+        var cache = mat.toRowMajor
+           (mat.zeroMatrix { rows = s.channels, columns = 0 });
         chunks = array [];
         cachedPartsFor count =
            (start = pos % (mat.width cache);
@@ -377,7 +381,7 @@
         read n =
            (m = s.read (n*frac);
             obtained = maths.ceil ((mat.width m) / frac);
-            mat.flipped
+            mat.toRowMajor
                (mat.fromColumns
                    (map do c: mat.getColumn (c*frac) m done [0..obtained-1])))
     };