% playaudio_async - Play stream of audio data asynchronously
%
% playaudio :: 
%    X:seq [[N]]    ~'sequence of arrays',
%    R:nonneg       ~'sampling rate',
%    options {
%       maxbuf  :: natural/2*max(size(X))   ~'maximum buffer size';
%       hook    :: (iterator(S)->iterator(T)) ~'fn to build iterator';
%       onstart :: A -> action      ~'called BEFORE timer starts';
%       onstop  :: A -> action      ~'called AFTER timer stops';
%       onfinish:: A -> action      ~'called when end of signal reached';
%       defer   :: bool / 0         ~'if 1, don't start the timer'
%    }
% -> sched(S) ~'scheduler api functions',
%    (S -> [[N]]) ~'function to recover audio from iterator state'.
%
% iterator(S) ::= cell {(S->action S)~'state transformer', S~'initial state'}.
%
% sched(S) ::= struct {
%		dispose   :: unit -> action unit;
%		isrunning :: unit -> action bool;
%		startat	 :: real -> action unit;
%		start		 :: unit -> action unit;
%		stop		 :: unit -> action unit;
%		rewind	 :: unit -> action unit;
%		getstate	 :: unit -> action S;
%		setstate	 :: S    -> action unit
% }.
%
% The 'hook' option gives the caller an opportunity to elaborate on the
% 'iterator' used to drive the audio playback. The 'iterator' is a cell
% array contain a state transformer function and initial state. The caller
% can use this to build a more complex iterator the does other things
% for each buffer of samples.
%
% The third return value is a function which can be used in a state
% transformer function to recover a buffer of audio samples from the
% current state.
%
% NB: all the audio buffers must be the same size for this to work.
% NB: the rewind function should only be called when the timer is stopped.
function [Sched,GetData]=playaudio_async(Y,Snk,varargin)
	[Sched,GetData]=playaudio_unfold(size(Y,2),@decons,Y,Snk),varargin{:});
end
