% gather - collect all samples from a finite signal
% gather   :: signal(C,R), options -> [[C,N]].
function x=gather(sig,varargin)
	opts=prefs('chunk',256,'init',512,'grow',2,'max',1e9,varargin{:});

	s=construct(sig);
	try % to make sure we dispose of s once opened
		chunk=uint32(opts.chunk);
		n=uint32(0); CHUNK=1:chunk; 
		cap=opts.init; % initial capacity of buffer
		x=zeros(channels(sig),cap); % buffer
		r=s.reader(opts.chunk);
		rem=0; 
		s.start();
		while rem==0
			if n+chunk>cap % need more room
				if n>opts.max, error('maximum capacity exceeded'); end
				cap=opts.grow*cap; 
				x=repmat(x,1,opts.grow); 
			end
			[x(:,n+CHUNK),rem]=r();
			n=n+chunk;
		end
		n=n-rem; % remove rem samples from end
	catch ex
		s.dispose();
		rethrow(ex);
	end
	s.stop();
	s.dispose();
	x=x(:,1:n); % grab only valid samples
end

