samer@0: % sinkarray - sink that collects data in an array samer@0: % samer@0: % sinkarray :: samer@0: % ([[C,L]] -> action void) ~'function to do something with array on dispose', samer@0: % C:natural ~'number of channels, samer@0: % L:natural ~'capacity of sink', samer@0: % R:nonneg ~'sampling rate' samer@0: % -> sink(C,R). samer@0: samer@3: classdef sinkarray < sinkbase samer@0: properties (GetAccess=private,SetAccess=immutable) samer@0: length % natural samer@0: cont % [[C,N]] -> void samer@0: end samer@0: methods samer@0: function s=sinkarray(cont,ch,len,rate) samer@0: if nargin<4, rate=nan; end samer@42: s=s@sinkbase(ch,rate); samer@0: s.length=len; samer@0: s.cont=cont; samer@0: end samer@0: samer@0: function s=tostring(sig), samer@3: s=sprintf('sinkarray(%s,<%dx%d>)',tostring(sig.cont),channels(sig),sig.length); samer@0: end samer@0: samer@0: function s=construct(sig) samer@0: s.start = @nop; samer@0: s.stop = @nop; samer@42: if isfinite(sig.length) samer@42: length=sig.length; samer@42: array=zeros(channels(sig),length); samer@42: pos=0; samer@42: samer@42: s.dispose = @dispose; samer@42: s.writer = @writer; samer@42: else samer@42: gg=gatherer([channels(sig),1]); samer@42: s.dispose = @dispose_gatherer; samer@42: s.writer = @writer_gatherer; samer@42: end samer@0: samer@0: function dispose, sig.cont(array(:,1:pos)); end samer@0: samer@0: function r=writer(n) samer@0: r = @next; samer@0: CHUNK = 1:uint32(n); samer@0: function rem=next(x) samer@0: n=size(x,2); samer@0: if pos+n<=length samer@0: array(:,pos+CHUNK)=x; rem=0; samer@0: pos=pos+n; samer@0: else samer@0: rem=n-(length-pos); samer@0: array(:,pos+1:end)=x(:,1:rem); samer@0: pos=length; samer@0: end samer@0: end samer@0: end samer@42: samer@42: function dispose_gatherer, sig.cont(gg.collect()); end samer@42: function r=writer_gatherer(n) samer@42: r = @next; samer@42: function rem=next(x) samer@42: n=size(x,2); samer@42: for i=1:n, gg.append(x(:,i)); end samer@42: rem=0; samer@42: end samer@42: end samer@0: end samer@0: end samer@0: end