function Y=unbuffer(X,hop)
% UNBUFFER - Opposite of buffer using overlap and add (for sequences)
% 
% Usage: x=unbuffer(X,hop)
%	X:	sequences of [[N]] frames of signal data
%	hop:	Determines how much overlap there is between neighbouring frames


	if isa(hop,'data')
		Y=zipaccum(@olap2,[],{hop,X});
	else
		if isscalar(hop)
			N=max(size(X));
			ol=N-hop;
			if ol<=hop
				I=1:hop; J=1:ol; K=hop+1:N;
				Y=sfndata(@olap1,zeros(ol,1),X);
			else
				I=1:hop; J=hop+1:ol; K=ol+1:N;
				Y=sfndata(@olap3,zeros(ol,1),X);
			end
		else
			Y=zipaccum(@olap2,[],{windowdata(repeat(hop)),X});
		end
	end

	function [y,s1]=olap1(x,s)
		y=x(I)';
		y(J)=y(J)+s';
		s1=x(K);
	end

	function [y,s1]=olap3(x,s)
		y=(s(I)+x(I))';
		s1=[s(J)+x(J);x(K)];
	end

	function [y,s1]=olap2(hop,x,s)
		ls=length(s);
		lx=length(x);
		if lx>=hop
			if ls>=hop
				% NB: this will fail if ls>lx, but this shouldn't happen since ls<=lx-hop
				y=(x(1:hop)+s(1:hop))';
				s1=[s(hop+1:ls)+x(hop+1:ls);x(ls+1:end)];
			else
				y=[x(1:ls)+s;x(ls+1:hop)]';
				s1=x(hop+1:end);
			end
		else
			if ls>=hop
				y=[s(1:lx)+x;s(lx+1:hop)]';
				s1=s(hop+1:end);
			else
				y=zeros(1,hop);
				y(1:ls)=y(1:ls)+s';
				y(1:lx)=y(1:lx)+x';
			end
		end

		% y=x(1:hop)';
		% ch=min(hop,ls);
		% J=(1:ch)';
		% y(J)=y(J)+s(J)';
		% s1=x(hop+1:end)+[s(ch+1:end);zeros(lx-max(hop,ls),1)];
	end
end

