1 <!DOCTYPE html PUBLIC
"-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
4 <meta http-equiv=
"Content-Type" content=
"text/html; charset=UTF-8">
5 <meta http-equiv=
"Content-Style-Type" content=
"text/css">
7 <meta name=
"Generator" content=
"Cocoa HTML Writer">
8 <meta name=
"CocoaVersion" content=
"824.44">
9 <style type=
"text/css">
10 p
.p1
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
}
11 p
.p2
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; min-height: 14.0px}
12 p
.p3
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #1e456e; min-height: 12.0px}
13 p
.p4
{margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -29.0px; font: 12.0px Helvetica
}
14 p
.p5
{margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -29.0px; font: 9.0px Monaco
}
15 p
.p6
{margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -29.0px; font: 12.0px Helvetica
; min-height: 14.0px}
16 p
.p7
{margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -29.0px; font: 9.0px Monaco
; color: #ad140d}
17 p
.p8
{margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -29.0px; font: 9.0px Monaco
; min-height: 12.0px}
18 p
.p9
{margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -29.0px; font: 12.0px Lucida Grande
; min-height: 15.0px}
19 p
.p10
{margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -29.0px; font: 12.0px Monaco
; min-height: 16.0px}
20 p
.p11
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Lucida Grande
; min-height: 15.0px}
21 p
.p12
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica
}
22 p
.p13
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; color: #000000; min-height: 14.0px}
23 p
.p14
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #bf0000}
24 p
.p15
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #000000; min-height: 12.0px}
25 p
.p16
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #000000}
26 span
.s1
{font: 18.0px Helvetica
}
27 span
.s2
{font: 12.0px Helvetica
}
28 span
.s3
{color: #001bb9}
29 span
.s4
{color: #000000}
30 span
.s5
{font: 12.0px Helvetica
; color: #000000}
31 span
.s6
{font: 9.0px Monaco
}
32 span
.s7
{font: 12.0px Lucida Grande
}
33 span
.s8
{font: 12.0px Monaco
}
34 span
.s9
{color: #ad140d}
35 span
.s10
{font: 11.0px Monaco
; color: #000000}
36 span
.s11
{color: #0000bf}
37 span
.s12
{color: #007300}
38 span
.Apple-tab-span
{white-space:pre
}
42 <p class=
"p1"><span class=
"s1"><b>TempoClock
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></b></span><b>tempo based scheduler
</b></p>
43 <p class=
"p2"><br></p>
44 <p class=
"p1"><b>Inherits from the abstract class Clock.
</b></p>
45 <p class=
"p3"><br></p>
46 <p class=
"p3"><br></p>
47 <p class=
"p1">TempoClock is a scheduler like SystemClock, but it schedules relative to a
<b>tempo
</b> in beats per second.
</p>
48 <p class=
"p2"><br></p>
49 <p class=
"p2"><br></p>
50 <p class=
"p2"><br></p>
51 <p class=
"p4"><b>*new(tempo, beats, seconds, queueSize)
</b></p>
52 <p class=
"p4"><span class=
"Apple-tab-span"> </span>creates a new TempoClock scheduler with the given tempo and starting times. If not supplied,
<b>tempo
</b> defaults to one,
<b>beats
</b> defaults to zero and
<b>seconds
</b> defaults to the current elapsed time since SuperCollider startup. The default
<b>queueSize
</b> is
256, see
<b>queue
</b>.
</p>
53 <p class=
"p5"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>t =
<span class=
"s3">TempoClock
</span>.new(
1,
0,
<span class=
"s3">Main
</span>.elapsedTime.ceil);
</p>
54 <p class=
"p6"><br></p>
55 <p class=
"p4"><b>stop
</b></p>
56 <p class=
"p4"><span class=
"Apple-tab-span"> </span>destroys the scheduler and releases the OS thread running the scheduler.
</p>
57 <p class=
"p6"><br></p>
58 <p class=
"p4"><b>clear
</b></p>
59 <p class=
"p4"><span class=
"Apple-tab-span"> </span>removes all tasks from the scheduling queue.
</p>
60 <p class=
"p6"><span class=
"Apple-tab-span"> </span></p>
61 <p class=
"p4"><b>tempo
</b></p>
62 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns the current tempo in beats per second.
</p>
63 <p class=
"p6"><span class=
"Apple-tab-span"> </span></p>
64 <p class=
"p4"><b>tempo_(newTempo)
</b></p>
65 <p class=
"p4"><span class=
"Apple-tab-span"> </span>sets the current tempo in beats per second.
</p>
66 <p class=
"p7"><span class=
"s4"><span class=
"Apple-tab-span"> </span>t.tempo_(
2.0);
</span>// equivalent to t.tempo =
2.0;
</p>
67 <p class=
"p7"><span class=
"s4"><span class=
"Apple-tab-span"> </span>t.tempo_(
72/
60)
</span>//
72 beats per minute
</p>
68 <p class=
"p6"><br></p>
69 <p class=
"p4"><b>permanent
</b></p>
70 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns a Boolean value indicating whether the clock will survive cmd-period. false by default.
</p>
71 <p class=
"p6"><br></p>
72 <p class=
"p4"><b>permanent_(bool)
</b></p>
73 <p class=
"p4"><span class=
"Apple-tab-span"> </span>sets whether the clock will survive cmd-period.
<b>bool
</b> is false by default. If false the clock is stopped (and thus removed) on cmd-period. If true the clock survives cmd-period.
</p>
74 <p class=
"p6"><br></p>
75 <p class=
"p4"><b>default
</b></p>
76 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns the permanent default TempoClock instantiated at startup.
</p>
77 <p class=
"p7"><span class=
"s5"><span class=
"Apple-tab-span"> </span></span><span class=
"s3">TempoClock
</span><span class=
"s4">.default.beats
</span>// beats since default TempoClock was started
</p>
78 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
79 <p class=
"p4"><b>default_(aTempoClock)
</b></p>
80 <p class=
"p4"><span class=
"Apple-tab-span"> </span>sets the default TempoClock.
</p>
81 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
82 <p class=
"p4"><b>beats
</b></p>
83 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns the appropriate beat time of the clock from any thread. If the receiver is the clock of the current thread, this returns the current logical time:
<span class=
"s6">thisThread.beats
</span>. If the receiver is not the current thread's clock then this translates the current thread's logical time in seconds to this clock's logical time in beats.
</p>
84 <p class=
"p9"><span class=
"Apple-tab-span"> </span></p>
85 <p class=
"p4"><b>schedAbs(beat, function)
</b></p>
86 <p class=
"p4"><span class=
"Apple-tab-span"> </span>schedules a function to be evaluated at a particular
<b>beat
</b>. If the function returns an Integer or a Float, it will be re-evaluated at the logical time plus the returned value. The function receives a number of default arguments, see
<b>play
</b> example below.
<span class=
"Apple-converted-space"> </span></p>
87 <p class=
"p9"><br></p>
88 <p class=
"p4"><b>sched(delta, function)
</b></p>
89 <p class=
"p4"><span class=
"Apple-tab-span"> </span>schedules a
<b>function
</b> to be evaluated
<b>delta
</b> beats from the current logical time in this clock. If the receiver is the clock of the current thread, the delta is applied to the current logical time. If the receiver is not the current thread's clock then the delta is applied to the clock's elapsed time.
</p>
90 <p class=
"p6"><br></p>
91 <p class=
"p4"><b>play(task, quant)
</b></p>
92 <p class=
"p4"><span class=
"Apple-tab-span"> </span>plays task (a function) at the next beat, where
<b>quant
</b> is
1 by default. Shortcut for
<b>schedAbs
</b>; see
<b>seconds
</b> and
<b>nextTimeOnGrid
</b>for further details on time and quant.
</p>
93 <p class=
"p5"><span class=
"s7"><span class=
"Apple-tab-span"> </span></span>t.play({
<span class=
"s3">arg
</span> beats, time, clock; [beats, time, clock].postln})
</p>
94 <p class=
"p6"><br></p>
95 <p class=
"p4"><b>playNextBar(task)
</b></p>
96 <p class=
"p4"><span class=
"Apple-tab-span"> </span>plays
<b>task
</b> (a function) at the next bar using
<b>schedAbs.
</b></p>
97 <p class=
"p10"><br></p>
98 <p class=
"p4"><b>queue
</b></p>
99 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns the scheduling queue Array in the form [beat, function]. The maximum number of items is determined by the clock's queueSize argument upon instantiation. The default queueSize of
256 allows
128 functions to be in the queue at any time.
</p>
100 <p class=
"p6"><span class=
"s8"><span class=
"Apple-tab-span"> </span></span><span class=
"Apple-tab-span"> </span></p>
101 <p class=
"p4"><b>beatDur
</b></p>
102 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns the duration in seconds of a current whole beat.
</p>
103 <p class=
"p6"><br></p>
104 <p class=
"p4"><b>beatsPerBar
</b></p>
105 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns the number of beats per bar. The default is
4.
</p>
106 <p class=
"p9"><span class=
"Apple-tab-span"> </span></p>
107 <p class=
"p4"><b>beatsPerBar_(newBeatsPerBar)
</b></p>
108 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span></b>sets the number of beats per bar. This must be done from within the scheduling thread, e.g.
</p>
109 <p class=
"p5"><span class=
"Apple-tab-span"> </span>t.schedAbs(t.nextBar, {t.beatsPerBar_(
3)});
</p>
110 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
111 <p class=
"p4"><b>bar
</b></p>
112 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns the current
<b>bar
</b>. See
<b>bars2beats
</b>for returning beat of current bar.
</p>
113 <p class=
"p9"><span class=
"Apple-tab-span"> </span></p>
114 <p class=
"p4"><b>nextBar(beat)
</b></p>
115 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns the number of beats at the next bar line relative to the beat argument. If
<b>beat
</b> is not supplied, returns the beat at which the next bar begins.
</p>
116 <p class=
"p6"><span class=
"Apple-tab-span"> </span></p>
117 <p class=
"p4"><b>beatInBar
</b></p>
118 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns the current bar beat (as a Float) in relation to
<b>beatsPerBar
</b>. Values range from
0 to
< beatsPerBar.
</p>
119 <p class=
"p6"><br></p>
120 <p class=
"p4"><b>baseBar
</b></p>
121 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns bar at which
<b>beatsPerBar
</b> was last changed. If beatsPerBar has not been changed since the clock was created, returns
0.
</p>
122 <p class=
"p6"><br></p>
123 <p class=
"p4"><b>baseBarBeat
</b></p>
124 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns beat at which the
<b>beatsPerBar
</b> was last changed. If beatsPerBar has not been changed since the clock was created, returns
0.
</p>
125 <p class=
"p6"><br></p>
126 <p class=
"p4"><b>beats2bars(beats)
</b></p>
127 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns a bar as a float relative to
<b>baseBarBeat
</b>.
</p>
128 <p class=
"p9"><br></p>
129 <p class=
"p4"><b>bars2beats(bar)
</b></p>
130 <p class=
"p4"><span class=
"Apple-tab-span"> </span> returns a beat relative to
<b>baseBar.
</b></p>
131 <p class=
"p7"><span class=
"s5"><b><span class=
"Apple-tab-span"> </span></b></span><span class=
"s4"> t.bars2beats(t.bar)
</span>// downbeat of the current bar
</p>
132 <p class=
"p6"><br></p>
133 <p class=
"p4"><b>timeToNextBeat(quant)
</b></p>
134 <p class=
"p4"><span class=
"Apple-tab-span"> </span> returns the logical time to next beat.
<b>quant
</b> is
1 by default, relative to
<b>baseBarBeat,
</b>see
<b> nextTimeOnGrid
</b>.
</p>
135 <p class=
"p6"><br></p>
136 <p class=
"p4"><b>nextTimeOnGrid(quant, phase)
</b></p>
137 <p class=
"p4"><span class=
"Apple-tab-span"> </span>with default values, returns the next whole beat.
<b>quant
</b> is
1 by default, phase is
0. quant is relative to
<b>baseBarBeat
</b>, such that
</p>
138 <p class=
"p5"><span class=
"Apple-tab-span"> </span>t.nextTimeOnGrid(t.beatsPerBar) == t.nextBar
<span class=
"s9">// =
> true
</span></p>
139 <p class=
"p4"><span class=
"Apple-tab-span"> </span>Together
<b>quant
</b> and
<b>phase
</b> are useful for finding the next
<i>n
</i> beat in a bar, e.g. nextTimeOnGrid(
4,
2) will return the next
3rd beat of a bar (of
4 beats), whereas nextBar-
2 may return an elapsed beat.
<span class=
"Apple-converted-space"> </span></p>
140 <p class=
"p9"><br></p>
141 <p class=
"p4"><b>elapsedBeats
</b></p>
142 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns the current elapsed time in beats. This is equivalent to tempoClock.secs2beats(Main.elapsedTime). It is often preferable to use
<b>beats
</b> instead of
<b>elapsedBeats
</b>because beats uses a thread's logical time.
</p>
143 <p class=
"p6"><br></p>
144 <p class=
"p4"><b>seconds
</b></p>
145 <p class=
"p4"><span class=
"Apple-tab-span"> </span>returns the current elapsed time. (This method is inherited from Clock.)
</p>
146 <p class=
"p6"><br></p>
147 <p class=
"p4"><b>beats2secs(beats)
</b></p>
148 <p class=
"p4"><span class=
"Apple-tab-span"> </span>converts absolute
<b>beats
</b> to absolute
<b>seconds
</b>, returning the elapsed time of the clock at the given
<b>beats
</b>. Only works for times in the current tempo. If the tempo changes any computed time in future will be wrong.
</p>
149 <p class=
"p7"><span class=
"s5"><span class=
"Apple-tab-span"> </span></span><span class=
"s4">t.beats2secs(t.beats)
</span>// equivalent to t.seconds
</p>
150 <p class=
"p7"><span class=
"s4"><span class=
"Apple-tab-span"> </span>t
</span><span class=
"s10">.
</span><span class=
"s4">beats2secs(
0)
</span>// how many seconds after startup did beat
0 occur?
</p>
151 <p class=
"p6"><b><span class=
"Apple-tab-span"> </span></b></p>
152 <p class=
"p4"><b>secs2beats(seconds)
</b></p>
153 <p class=
"p4"><span class=
"Apple-tab-span"> </span>converts absolute
<b>seconds
</b> to absolute beats. Only works for times in the current tempo. If the tempo changes any computed time in future will be wrong.
</p>
154 <p class=
"p6"><br></p>
155 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-converted-space"> </span></p>
156 <p class=
"p11"><br></p>
157 <p class=
"p12"><b>Examples
</b></p>
158 <p class=
"p13"><br></p>
159 <p class=
"p14">////////////////////////
</p>
160 <p class=
"p15"><br></p>
161 <p class=
"p14"><span class=
"s4">t =
</span><span class=
"s11">TempoClock
</span><span class=
"s4">(
1);
</span>// create a TempoClock
</p>
162 <p class=
"p15"><br></p>
163 <p class=
"p14">// schedule an event at next whole beat
</p>
164 <p class=
"p16">t.schedAbs(t.beats.ceil, {
<span class=
"s11">arg
</span> beat, sec; [beat, sec].postln;
1 });
</p>
165 <p class=
"p15"><br></p>
166 <p class=
"p16">t.tempo =
2;
</p>
167 <p class=
"p16">t.tempo =
4;
</p>
168 <p class=
"p16">t.tempo =
0.5;
</p>
169 <p class=
"p16">t.tempo =
1;
</p>
170 <p class=
"p15"><br></p>
171 <p class=
"p16">t.clear;
</p>
172 <p class=
"p15"><br></p>
173 <p class=
"p16">t.schedAbs(t.beats.ceil, {
<span class=
"s11">arg
</span> beat, sec; [beat, sec].postln;
1 });
</p>
174 <p class=
"p15"><br></p>
175 <p class=
"p16">t.stop;
</p>
176 <p class=
"p15"><br></p>
177 <p class=
"p14">////////////////////////
</p>
178 <p class=
"p15"><br></p>
180 <p class=
"p14">// get elapsed time, round up to next second
</p>
181 <p class=
"p16">v =
<span class=
"s11">Main
</span>.elapsedTime.ceil;
</p>
182 <p class=
"p15"><br></p>
183 <p class=
"p14">// create two clocks in a
5:
2 relation, starting at time v.
</p>
184 <p class=
"p16">t =
<span class=
"s11">TempoClock
</span>(
1,
0, v);
</p>
185 <p class=
"p16">u =
<span class=
"s11">TempoClock
</span>(
0.4,
0, v);
</p>
186 <p class=
"p15"><br></p>
187 <p class=
"p14">// start two functions at beat zero in each clock.
</p>
188 <p class=
"p16">t.schedAbs(
0, {
<span class=
"s11">arg
</span> beat, sec; [
<span class=
"s12">\t
</span>, beat, sec].postln;
1 });
</p>
189 <p class=
"p16">u.schedAbs(
0, {
<span class=
"s11">arg
</span> beat, sec; [
<span class=
"s12">\u
</span>, beat, sec].postln;
1 });
</p>
191 <p class=
"p15"><br></p>
192 <p class=
"p15"><br></p>
194 <p class=
"p16">u.tempo = u.tempo *
3;
</p>
195 <p class=
"p16">t.tempo = t.tempo *
3;
</p>
197 <p class=
"p15"><br></p>
199 <p class=
"p16">u.tempo = u.tempo *
1/
4;
</p>
200 <p class=
"p16">t.tempo = t.tempo *
1/
4;
</p>
202 <p class=
"p15"><br></p>
203 <p class=
"p15"><br></p>
205 <p class=
"p16">t.stop;
</p>
206 <p class=
"p16">u.stop;
</p>
208 <p class=
"p15"><br></p>
209 <p class=
"p14">////////////////////////
</p>
210 <p class=
"p15"><br></p>
212 <p class=
"p14">// get elapsed time, round up to next second
</p>
213 <p class=
"p16">v =
<span class=
"s11">Main
</span>.elapsedTime.ceil;
</p>
214 <p class=
"p15"><br></p>
215 <p class=
"p14">// create two clocks, starting at time v.
</p>
216 <p class=
"p16">t =
<span class=
"s11">TempoClock
</span>(
1,
0, v);
</p>
217 <p class=
"p16">u =
<span class=
"s11">TempoClock
</span>(
1,
0, v);
</p>
218 <p class=
"p15"><br></p>
219 <p class=
"p14">// start two functions at beat zero in each clock.
</p>
220 <p class=
"p14">// t controls u's tempo. They should stay in sync.
</p>
221 <p class=
"p16">t.schedAbs(
0, {
<span class=
"s11">arg
</span> beat, sec; u.tempo = t.tempo * [
1,
2,
3,
4,
5].choose; [
<span class=
"s12">\t
</span>, beat, sec].postln;
1 });
</p>
222 <p class=
"p16">u.schedAbs(
0, {
<span class=
"s11">arg
</span> beat, sec; [
<span class=
"s12">\u
</span>, beat, sec].postln;
1 });
</p>
224 <p class=
"p15"><br></p>
225 <p class=
"p15"><br></p>
227 <p class=
"p16">u.tempo = u.tempo *
3;
</p>
228 <p class=
"p16">t.tempo = t.tempo *
3;
</p>
230 <p class=
"p15"><br></p>
232 <p class=
"p16">u.tempo = u.tempo *
1/
4;
</p>
233 <p class=
"p16">t.tempo = t.tempo *
1/
4;
</p>
235 <p class=
"p15"><br></p>
236 <p class=
"p15"><br></p>
238 <p class=
"p16">t.stop;
</p>
239 <p class=
"p16">u.stop;
</p>