Mercurial > hg > may
changeset 279:3aacfde637fd
Simplistic convolution implementation and (currently failing) tests
author | Chris Cannam |
---|---|
date | Mon, 27 May 2013 23:37:57 +0100 |
parents | 704c58ab4598 |
children | 7f000ae124db |
files | yetilab/stream/filter.yeti yetilab/stream/syntheticstream.yeti yetilab/stream/test/test_filter.yeti |
diffstat | 3 files changed, 53 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/yetilab/stream/filter.yeti Sat May 25 18:42:01 2013 +0100 +++ b/yetilab/stream/filter.yeti Mon May 27 23:37:57 2013 +0100 @@ -3,8 +3,10 @@ mat = load yetilab.matrix; ch = load yetilab.stream.channels; +vec = load yetilab.vector; load yetilab.stream.type; +load yetilab.vector.type; minDurationOf d1 d2 = case d1 of @@ -257,7 +259,38 @@ } done [1..copies]; fi; - + +convolvedWith ir s = //!!! currently ir is single channel vector only; very slow + (var buffer = mat.toRowMajor + (mat.zeroMatrix { rows = s.channels, columns = vec.length ir }); + s with + { + get available () = + case s.available of + Known n: Known (n + vec.length ir - 1); + other: other; + esac, + read count = + (signal = s.read count; + out = array (map \(new double[mat.width signal]) [1..s.channels]); + for [0..s.channels - 1] do ch: + for [0..mat.width signal - 1] do i: + for [0..vec.length ir - 1] do j: + history = + if j > i then + mat.at buffer ch (mat.width buffer + i - j) + else + mat.at signal ch (i - j) + fi; + out[ch][i] := out[ch][i] + history * (vec.at ir j); + done; + done; + done; + extended = mat.concat (Horizontal ()) [buffer, signal]; + w = mat.width extended; + buffer := mat.columnSlice extended (w - vec.length ir) w; + mat.newMatrix (RowMajor ()) (map vec.vector out)), + }); { withDuration is number -> stream -> stream, @@ -267,5 +300,6 @@ multiplexed is list<stream> -> stream, repeated is stream -> stream, duplicated is number -> stream -> list<stream>, + convolvedWith is vector -> stream -> stream, }
--- a/yetilab/stream/syntheticstream.yeti Sat May 25 18:42:01 2013 +0100 +++ b/yetilab/stream/syntheticstream.yeti Mon May 27 23:37:57 2013 +0100 @@ -35,7 +35,7 @@ silent rate = generated rate \0; -precalculated rate data = +precalculated rate data = //!!! hang on -- these are returning 1-ch vectors, not matrices like other streams. how is this working? (n = vec.length data; var position = 0; {
--- a/yetilab/stream/test/test_filter.yeti Sat May 25 18:42:01 2013 +0100 +++ b/yetilab/stream/test/test_filter.yeti Mon May 27 23:37:57 2013 +0100 @@ -531,6 +531,23 @@ ( s1.close (); s2.close() ; true ) ), +"convolvedWith-\(name)": \( + ir = vec.fromList [1,2,3]; + signal = maybeDuration 2 (syn.precalculated 2 (vec.fromList [1,2])); + c = filt.convolvedWith ir signal; + compare c.position 0 and + compare c.channels 1 and + compare c.sampleRate 2 and + compare c.available (maybeKnown 4) and + compare (map vec.list (mat.asRows (c.read 3))) [[1,4,7]] and + compare c.available (maybeKnown 1) and + compare c.finished? false and + compare (map vec.list (mat.asRows (c.read 4))) [[6]] and + compare c.available (Known 0) and + compare c.finished? true and + ( c.close (); true ) +), + //!!! still no tests for filters with multi-channel inputs ]);