Mercurial > hg > may
changeset 280:7f000ae124db
Make convolver work. Ugly though
author | Chris Cannam |
---|---|
date | Tue, 28 May 2013 20:41:11 +0100 |
parents | 3aacfde637fd |
children | f3784641245f |
files | yetilab/matrix/test/test_matrix.yeti yetilab/stream/filter.yeti yetilab/stream/syntheticstream.yeti yetilab/stream/test/test_filter.yeti |
diffstat | 4 files changed, 59 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/yetilab/matrix/test/test_matrix.yeti Mon May 27 23:37:57 2013 +0100 +++ b/yetilab/matrix/test/test_matrix.yeti Tue May 28 20:41:11 2013 +0100 @@ -397,6 +397,15 @@ (newMatrix (ColumnMajor ()) [[1,4],[0,5],[3,6]]) ), +"concatEmpty-horiz-\(name)": \( + compareMatrices + (mat.concat (Horizontal ()) + [(newMatrix (ColumnMajor ()) [[]]), + (newMatrix (RowMajor ()) [[]]), + (mat.zeroSizeMatrix ())]) + (mat.zeroSizeMatrix ()); +), + "sparseConcat-horiz-\(name)": \( s = mat.concat (Horizontal ()) [mat.toSparse (newMatrix (ColumnMajor ()) [[1,4],[0,5]]),
--- a/yetilab/stream/filter.yeti Mon May 27 23:37:57 2013 +0100 +++ b/yetilab/stream/filter.yeti Tue May 28 20:41:11 2013 +0100 @@ -7,6 +7,7 @@ load yetilab.stream.type; load yetilab.vector.type; +load yetilab.matrix.type; minDurationOf d1 d2 = case d1 of @@ -260,36 +261,59 @@ 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 }); +convolvedWith ir s = + (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 history = mat.toRowMajor + (mat.zeroMatrix { rows = s.channels, columns = mat.width ir - 1 }); s with { + get finished? () = + s.finished? and (mat.isZeroSize? history), get available () = case s.available of - Known n: Known (n + vec.length ir - 1); + Known n: Known (n + mat.width history); other: other; esac, read count = - (signal = s.read count; - out = array (map \(new double[mat.width signal]) [1..s.channels]); + (// Example: The IR is four samples long; we have three + // samples in history; two samples are available to read + // before the stream runs out. That means we can return + // up to five samples. Caller requests 6. + signal = s.read count; // -> two samples + siglen = mat.width signal; // -> 2 + histlen = mat.width history; // -> 3 + convlen = min count (siglen + histlen); // -> 5 + input = mat.resizedTo { rows = s.channels, columns = convlen } + signal; // example input now 5 samples, of which 2 are signal + output = array (map \(new double[convlen]) [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); + for [0..mat.width input - 1] do i: + for [0..mat.width ir - 1] do j: + v = + if i >= j then + mat.at input ch (i - j) + else + ix = mat.width ir + i - j - 1; + if ix >= histlen then + 0 + else + mat.at history ch ix + fi + fi; + output[ch][i] := output[ch][i] + v * (mat.at ir ch j); done; done; done; - extended = mat.concat (Horizontal ()) [buffer, signal]; + // Remove from history a number of samples equal to the + // number returned; add to it a number equal to the number + // read from source + extended = mat.concat (Horizontal ()) [history, signal]; // -> 5 + newlen = (histlen + siglen) - convlen; // -> 0 w = mat.width extended; - buffer := mat.columnSlice extended (w - vec.length ir) w; - mat.newMatrix (RowMajor ()) (map vec.vector out)), + history := mat.columnSlice extended (w - newlen) w; + mat.newMatrix (RowMajor ()) (map vec.vector output)), }); { @@ -300,6 +324,6 @@ multiplexed is list<stream> -> stream, repeated is stream -> stream, duplicated is number -> stream -> list<stream>, - convolvedWith is vector -> stream -> stream, + convolvedWith is matrix -> stream -> stream, }
--- a/yetilab/stream/syntheticstream.yeti Mon May 27 23:37:57 2013 +0100 +++ b/yetilab/stream/syntheticstream.yeti Tue May 28 20:41:11 2013 +0100 @@ -35,7 +35,7 @@ silent rate = generated rate \0; -precalculated rate data = //!!! hang on -- these are returning 1-ch vectors, not matrices like other streams. how is this working? +precalculated rate data = (n = vec.length data; var position = 0; {
--- a/yetilab/stream/test/test_filter.yeti Mon May 27 23:37:57 2013 +0100 +++ b/yetilab/stream/test/test_filter.yeti Tue May 28 20:41:11 2013 +0100 @@ -532,17 +532,19 @@ ), "convolvedWith-\(name)": \( - ir = vec.fromList [1,2,3]; + ir = mat.newRowVector (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 (map vec.list (mat.asRows (c.read 3))) + [[ 1*1, 2*1 + 1*2, 0*1 + 2*2 + 1*3 ]] and + compare c.available (Known 1) and compare c.finished? false and - compare (map vec.list (mat.asRows (c.read 4))) [[6]] and + compare (map vec.list (mat.asRows (c.read 4))) + [[ 0*1 + 0*2 + 2*3 ]] and compare c.available (Known 0) and compare c.finished? true and ( c.close (); true )