Mercurial > hg > may
changeset 291:c40821ff70f8
Hurrah! Overlap-add now produces valid output streams (finally) and passes the tests
author | Chris Cannam |
---|---|
date | Fri, 31 May 2013 15:14:09 +0100 |
parents | 21ec05237c1a |
children | 240eb77ee2e8 |
files | yetilab/stream/filter.yeti yetilab/stream/framer.yeti yetilab/stream/test/test_framer.yeti |
diffstat | 3 files changed, 78 insertions(+), 68 deletions(-) [+] |
line wrap: on
line diff
--- a/yetilab/stream/filter.yeti Fri May 31 10:58:00 2013 +0100 +++ b/yetilab/stream/filter.yeti Fri May 31 15:14:09 2013 +0100 @@ -9,6 +9,8 @@ load yetilab.vector.type; load yetilab.matrix.type; +//!!! todo: synchronized for everything with state assignment + minDurationOf d1 d2 = case d1 of Known a:
--- a/yetilab/stream/framer.yeti Fri May 31 10:58:00 2013 +0100 +++ b/yetilab/stream/framer.yeti Fri May 31 15:14:09 2013 +0100 @@ -13,9 +13,10 @@ fft = load yetilab.transform.fft; mat = load yetilab.matrix; ch = load yetilab.stream.channels; -syn = load yetilab.stream.syntheticstream; filt = load yetilab.stream.filter; +//!!! todo: synchronized for everything with state assignment + blockList framesize stream = if stream.finished? then stream.close (); @@ -94,26 +95,25 @@ close = \(), }); -overlapAdd channels overlap frames = +overlapAdd overlap frames = (ola fr acc = - if empty? fr then - [acc] - else - pre = mat.columnSlice acc 0 (mat.width acc - overlap); - added = mat.sum (head fr) - (mat.resizedTo { columns = mat.width (head fr), rows = channels } - (mat.columnSlice acc (mat.width acc - overlap) (mat.width acc))); - /* - frameSized = mat.resizedTo - { columns = framesize, rows = channels }; - extended = frameSized - (mat.columnSlice acc hop (mat.width acc)); - added = mat.sum (frameSized (head fr)) extended; - (mat.columnSlice acc 0 hop) :: ola (tail fr) added; -*/ - pre :: ola (tail fr) added; - fi; - mat.concat (Horizontal ()) (ola frames (mat.zeroSizeMatrix ()))); + case fr of + first::rest: + (w = mat.width acc; + pre = mat.columnSlice acc 0 (w - overlap); + added = mat.sum first + (mat.resizedTo (mat.size first) + (mat.columnSlice acc (w - overlap) w)); + pre :: ola rest added); + _: + [acc]; + esac; + case frames of + first::rest: + mat.concat (Horizontal ()) (ola rest first); + _: + mat.zeroSizeMatrix (); + esac); streamOverlapping rate framesize hop frames = (var remaining = frames; @@ -121,21 +121,21 @@ var position = 0; factor = hop / (framesize/2); w = bf.scaled factor (win.hann framesize); // periodic window, not symmetric - println "window is \(vec.list w)"; channels = mat.height (head frames); // so we don't need to keep a head ptr - filt.delayedBy (- framesize) + syncd = synchronized remaining; + finished () = syncd \(empty? remaining and mat.empty? buffered); + filt.delayedBy (- (framesize - hop)) { - get position () = position, + get position () = syncd \(position), get channels () = channels, get sampleRate () = rate, - get finished? () = empty? remaining and mat.empty? buffered, - get available () = Unknown (), - read count = - (framesFor samples acc = + get finished? () = finished (), + get available () = if finished () then Known 0 else Unknown () fi, + read count = syncd + \(framesFor samples acc = if samples <= 0 or empty? remaining then acc else - println "multiplying \(head remaining) by window"; this = mat.resizedTo { columns = framesize, rows = channels } (mat.newMatrix (RowMajor ()) @@ -144,13 +144,11 @@ remaining := tail remaining; framesFor (samples - hop) (acc ++ [this]) fi; - source = overlapAdd channels (framesize - hop) + source = overlapAdd (framesize - hop) (framesFor count [buffered]); toReturn = mat.columnSlice source 0 count; position := position + mat.width toReturn; buffered := mat.columnSlice source count (mat.width source); - println "count = \(count), framesize = \(framesize), hop = \(hop)"; - println "leaving position = \(position), buffered = \(buffered), returning \(toReturn)"; toReturn), close = \(), });
--- a/yetilab/stream/test/test_framer.yeti Fri May 31 10:58:00 2013 +0100 +++ b/yetilab/stream/test/test_framer.yeti Fri May 31 15:14:09 2013 +0100 @@ -19,31 +19,38 @@ testFramesWith params length expected firstChunkSize = (f = fr.frames params (testStream length); str = fr.streamed rate params f; - sz = params.framesize; - ts = testStream length; - - overlapping = params.framesize > params.hop; - incomplete = overlapping and // Can't reconstruct with < 50% overlap - params.framesize < params.hop * 2; - - println "firstChunkSize = \(firstChunkSize):"; - - firstChunk = str.read firstChunkSize; - restChunk = str.read (length - firstChunkSize); + ts = testStream length; // newly initialised stream compareFrames f expected and - (incomplete or - compareUsing mat.equal - firstChunk (ts.read firstChunkSize)) and - (incomplete or - compareUsing mat.equal - restChunk (ts.read (length - firstChunkSize))) and + + (firstChunk = str.read firstChunkSize; + compareUsing mat.equal + firstChunk (ts.read firstChunkSize)) and + + compare str.position firstChunkSize and + compare str.finished? false and + + (restChunk = str.read (length - firstChunkSize); + compareUsing mat.equal + restChunk (ts.read (length - firstChunkSize))) and compare str.position length and - (overlapping or // (overlapping streamer doesn't know when it'll end!) - compare str.available (Known (sz - (length % sz))))); + + (trailingZeros = str.read (params.framesize + 1); + compareUsing mat.equal + trailingZeros + (mat.zeroMatrix + { rows = str.channels, columns = mat.width trailingZeros }) and + (mat.width trailingZeros < params.framesize)) and + + compare str.finished? true and + compare str.available (Known 0)); + +testFramesInvertible params length expected = + all id (map (testFramesWith params length expected) [1..length]); testFrames params length expected = - all id (map (testFramesWith params length expected) [1..length]); + (f = fr.frames params (testStream length); + compareFrames f expected); [ @@ -103,7 +110,7 @@ ), "frames-2x5": \( - testFrames { framesize = 2, hop = 2 } 5 [ [1,2], [3,4], [5,0] ]; + testFramesInvertible { framesize = 2, hop = 2 } 5 [ [1,2], [3,4], [5,0] ]; ), "frames-4.3x4": \( @@ -115,46 +122,49 @@ ), "frames-3.1x6": \( - testFrames { framesize = 3, hop = 1 } 6 + testFramesInvertible { framesize = 3, hop = 1 } 6 [ [0,0,1], [0,1,2], [1,2,3], [2,3,4], [3,4,5], [4,5,6], [5,6,0], [6,0,0] ]; ), "frames-4.2x8": \( - testFrames { framesize = 4, hop = 2 } 8 + testFramesInvertible { framesize = 4, hop = 2 } 8 [ [0,0,1,2], [1,2,3,4], [3,4,5,6], [5,6,7,8], [7,8,0,0] ]; ), "overlapAdd-3.1": \( compareUsing (mat.equal) - (fr.overlapAdd 1 2 [ mat.newRowVector (vec.fromList [ 1,2,3 ]), - mat.newRowVector (vec.fromList [ 4,5,6 ]), - mat.newRowVector (vec.fromList [ 7,8,9 ]) ]) + (fr.overlapAdd 2 [ mat.newRowVector (vec.fromList [ 1,2,3 ]), + mat.newRowVector (vec.fromList [ 4,5,6 ]), + mat.newRowVector (vec.fromList [ 7,8,9 ]) ]) (mat.newRowVector (vec.fromList [ 1,6,15,14,9 ])) ), "overlapAdd-3.2": \( compareUsing (mat.equal) - (fr.overlapAdd 1 1 [ mat.newRowVector (vec.fromList [ 1,2,3 ]), - mat.newRowVector (vec.fromList [ 4,5,6 ]), - mat.newRowVector (vec.fromList [ 7,8,9 ]) ]) + (fr.overlapAdd 1 [ mat.newRowVector (vec.fromList [ 1,2,3 ]), + mat.newRowVector (vec.fromList [ 4,5,6 ]), + mat.newRowVector (vec.fromList [ 7,8,9 ]) ]) (mat.newRowVector (vec.fromList [ 1,2,7,5,13,8,9 ])) ), "overlapAdd-4.2": \( compareUsing (mat.equal) - (fr.overlapAdd 1 2 [ mat.newRowVector (vec.fromList [ 1,2,3,4 ]), - mat.newRowVector (vec.fromList [ 5,6,7,8 ]), - mat.newRowVector (vec.fromList [ 9,0,1,2 ]) ]) + (fr.overlapAdd 2 [ mat.newRowVector (vec.fromList [ 1,2,3,4 ]), + mat.newRowVector (vec.fromList [ 5,6,7,8 ]), + mat.newRowVector (vec.fromList [ 9,0,1,2 ]) ]) (mat.newRowVector (vec.fromList [ 1,2,8,10,16,8,1,2 ])) ), -"overlapAdd-6+4.2": \( // Must work even if blocks vary in length (what if shorter than overlap though?) +"overlapAdd-6+4.2": \( + // Must work even if blocks vary in length (what if shorter than + // overlap though?) compareUsing (mat.equal) - (fr.overlapAdd 1 2 [ mat.newRowVector (vec.fromList [ 1,2,3,4,5,6 ]), - mat.newRowVector (vec.fromList [ 7,8,9,0 ]), - mat.newRowVector (vec.fromList [ 1,2,3,4 ]) ]) - (mat.newRowVector (vec.fromList [ 1,2,3,4,12,14,10,2,3,4 ])) + (fr.overlapAdd 2 [ mat.newRowVector (vec.fromList [ 1,2,3,4,5,6 ]), + mat.newRowVector (vec.fromList [ 7,8,9,0 ]), + mat.newRowVector (vec.fromList [ 1,2,3 ]), + mat.newRowVector (vec.fromList [ 4,5,6 ]) ]) + (mat.newRowVector (vec.fromList [ 1,2,3,4,12,14,10,6,8,6 ])) ), ] is hash<string, () -> boolean>;