samer@0
|
1 function Timer=msched(e0)
|
samer@0
|
2 % msched - Schedule events where each event returns the next event.
|
samer@0
|
3 %
|
samer@0
|
4 % msched ::
|
samer@0
|
5 % cell {
|
samer@0
|
6 % double ~'time of event',
|
samer@0
|
7 % event ~'first event action'
|
samer@0
|
8 % }
|
samer@0
|
9 % -> action timer ~'timer being used'.
|
samer@0
|
10 %
|
samer@0
|
11 % event ::=
|
samer@0
|
12 % ( double ~'scheduled time',
|
samer@0
|
13 % double ~'actual time'
|
samer@0
|
14 % -> action (
|
samer@0
|
15 % event ~'the next event action',
|
samer@0
|
16 % double ~'time for next action',
|
samer@0
|
17 % double ~'execution time of current event'
|
samer@0
|
18 % )
|
samer@0
|
19 % ).
|
samer@0
|
20
|
samer@0
|
21 % this is most like a Routine or Task in Supercollider, except
|
samer@0
|
22 % that instead of coroutining via yield, each action explicitly
|
samer@0
|
23 % returns the continuation action.
|
samer@0
|
24
|
samer@0
|
25 persistent ERROR
|
samer@0
|
26
|
samer@0
|
27 ERROR=[];
|
samer@0
|
28 warning('off','MATLAB:TIMER:STARTDELAYPRECISION');
|
samer@0
|
29
|
samer@0
|
30 [t0,a0]=cdeal(e0);
|
samer@0
|
31
|
samer@0
|
32 Timer=timer;
|
samer@0
|
33 set(Timer,'TimerFcn',@(o,e)timercb(o,e,t0,a0),'StopFcn',@chain);
|
samer@0
|
34 set(Timer,'StartDelay',max(0,t0-nows)); % there will be some small error here..
|
samer@0
|
35 start(Timer);
|
samer@0
|
36
|
samer@0
|
37 function timercb(o,e,t,a)
|
samer@0
|
38 [a1,t1,tt]=a(t,e.Data.time);
|
samer@0
|
39 set(o,'UserData',{a1,t1});
|
samer@0
|
40 ERROR=vertcat(ERROR,tt-t);
|
samer@0
|
41 end
|
samer@0
|
42
|
samer@0
|
43 function chain(o,e)
|
samer@0
|
44 [a1,t1]=cdeal(get(o,'UserData'));
|
samer@0
|
45 correction=mean(ERROR);
|
samer@0
|
46 while ~isempty(t1)
|
samer@0
|
47 tnow=nows;
|
samer@0
|
48 delay=t1-correction-tnow;
|
samer@0
|
49 if delay>=0,
|
samer@0
|
50 set(o,'TimerFcn',@(oo,ee)timercb(oo,ee,t1,a1));
|
samer@0
|
51 set(o,'StartDelay',delay);
|
samer@0
|
52 start(o);
|
samer@0
|
53 return;
|
samer@0
|
54 end
|
samer@0
|
55 [a1,t1,tt]=a1(t1,tnow);
|
samer@0
|
56 end
|
samer@0
|
57
|
samer@0
|
58 fprintf('\n| stopping\n');
|
samer@0
|
59 set(o,'UserData',ERROR);
|
samer@0
|
60 timer_release(o);
|
samer@0
|
61 end
|
samer@0
|
62 end
|