% signal - Base class for signal
%
% signal :: signal(C:natural,R:nonneg).
%
% The signal(C,R) type denotes the type of a signal with C
% channels and a sampling rate of R. 
%
% The base signal class cannot be used without subclassing since
% any attempt to instantiate the live signal generator will throw
% an exception.
%
% METHODS
%    channels :: signal(C,R) -> natural.
%    rate     :: signal(C,R) -> nonneg. 
%    construct:: signal(C,R) -> livesig(C).
%    length   :: signal(C,R) -> natural.
%    gather   :: signal(C,R), options -> [[C,N]].
%    gathern  :: N:natural, signal(C,R), options -> [[C,N]], natural.
%
% livesig(C) :== struct {
%    start   :: void->void;
%    stop    :: void->void;
%    dispose :: void->void;
%    reader  :: N:natural -> (void->[[C,N]]);
% }

classdef signal
	methods (Abstract)
		c=channels(s)
		u=construct(s)
		r=rate(s)
	end

	methods
		function s=signal, end

		function s=and(s1,s2), s=sigcat(s1,s2); end
		function y=cache(x), y=reclock(rate(x),sigarray(gather(x))); end
		function display(a)
			disp(sprintf('    %s :: signal(%s,%s)',tostring(a),fmt(channels(a)),fmt(rate(a))));
			function s=fmt(x), if isnan(x), s='_'; else s=num2str(x); end; end
		end

		function y=map(f,x), y=sigmap(f,x); end
		function s=mpower(a,b), s=resample(b,a); end
		function s=or(s1,s2), s=sigbinop(@vertcat,s1,s2,@plus); end
		function s2=reclock(r,s1), s2=sigreclock(r,s1); end
		function y=drop(n,x), y=sigdrop(n,x); end
		function y=take(n,x), y=sigtake(n,x); end

		function y=dropt(t,x), 
			if isnan(rate(x)), error('Cannot dropt without definite sampling rate'); end
			y=sigdrop(round(t*rate(x)),x);
		end
			
		function y=taket(t,x), 
			if isnan(rate(x)), error('Cannot taket without definite sampling rate'); end
			y=sigtake(round(t*rate(x)),x);
		end
			
		function y=cycle(x), 
			y=siglzcat(x,@cyclef);
			function [s1,sx]=cyclef, s1=x; sx=@cyclef; end
		end

		function s2=resample(f2,s1,varargin)
			if isnan(rate(s1)), error('no sample rate set'); end
			if rate(s1)==f2, s2=s1;
			else, s2=sigresample(f2,s1,varargin{:}); end
		end

		function varargout=specgrm(x,varargin)
			 [varargout{1:nargout}]=specgrm(gather(x),varargin{:},'fs',rate(x));
		 end
	end
end
