/usr/share/SuperCollider/HelpSource/Classes/TempoClock.schelp is in supercollider-common 1:3.8.0~repack-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | CLASS::TempoClock
categories::Scheduling>Clocks
summary::tempo based scheduler
related::Classes/AppClock, Classes/SystemClock
DESCRIPTION::
TempoClock is a scheduler like link::Classes/SystemClock::, but it schedules relative to a
strong::tempo:: in beats per second.
See link::Classes/Clock:: for general explanation of how clocks operate.
CLASSMETHODS::
private::initClass
method::new
Creates a new instance of TempoClock.
argument:: tempo
The initial link::#-tempo#tempo::. Defaults to code::1::.
argument:: beats
The time in beats, corresponding to the reference time given with the code::seconds:: argument.
Defaults to code::0::.
argument:: seconds
The reference time in seconds, to which the code::beats:: argument corresponds.
Defaults to the current Thread's logical time
(see link::Classes/Thread#-seconds::).
argument:: queueSize
The storage size of the scheduling queue. Each scheduled item takes 2 counts of space, so this size
divided by 2 gives the amount of items that can be scheduled at a time. See also link::#-queue::.
discussion::
The TempoClock will be created strong::as if:: it started counting beats at the time given in the
code::seconds:: argument with the starting amount given in the code::beats:: argument. The current
count of beats will thus be equal to that starting amount plus the amount of beats that would be
counted since the given reference time in seconds, according to the given tempo.
The default arguments create a TempoClock that starts counting beats with code::0:: at the current
logical time.
code::
// Create a TempoClock that starts counting beats with 5 now.
(
t = TempoClock.new(2, 5);
"current beats:" + t.beats;
)
// Create a TempoClock, as if it started counting beats 5 seconds ago with 0.
(
t = TempoClock.new(2, 0, thisThread.seconds - 5);
"current beats:" + t.beats;
)
::
method::default
Sets or gets the permanent default TempoClock instantiated at startup.
code::
TempoClock.default.beats // beats since default TempoClock was started
::
subsection:: Forwarding to the default instance
The following methods only forward to the link::#*default#default instance::, allowing you to use
the TempoClock class itself in place of code::TempoClock.default::.
method::stop, play, sched, schedAbs, clear, tempo, etempo, beats, beats2secs, secs2beats, nextTimeOnGrid, timeToNextBeat, setTempoAtBeat, setTempoAtSec, setMeterAtBeat, beatsPerBar, baseBarBeat, baseBar, playNextBar, beatDur, elapsedBeats, beats2bars, bars2beats, bar, nextBar, beatInBar
INSTANCEMETHODS::
private::prDump, prStart, prStop, prClear
method::stop
Destroys the scheduler and releases the OS thread running the scheduler.
method::clear
Removes all tasks from the scheduling queue.
method::tempo
Sets or gets the current tempo in beats per second.
code::
t= TempoClock.new;
t.tempo_(2.0); // equivalent to t.tempo = 2.0;
t.tempo;
t.tempo_(72/60) // 72 beats per minute
t.tempo;
::
method::permanent
Sets or gets a link::Classes/Boolean:: value indicating whether the clock will survive cmd-period. If false the clock is stopped (and thus removed) on cmd-period. If true the clock survives cmd-period. It is false by default.
method::beats
Gets or sets the current logical time in beats according to this clock.
When strong::getting:: code::beats::, if this clock is the current Thread's
link::Classes/Thread#-clock#associated clock::, the Thread's own
link::Classes/Thread#-beats#time in beats:: is returned, otherwise the Thread's
link::Classes/Thread#-seconds#time in seconds:: converted to beats according to this
clock is returned.
After strong::changing:: code::beats:: towards the strong::future::, the clock will
immediately perform all tasks scheduled until the new time. Likewise, when changing
code::beats:: towards the strong::past::, already scheduled tasks will be postponed, so
they will still be performed at the scheduled time in beats.
note::
When changing code::beats::, you are only changing the clocks's notion of time, and not
the current Thread's link::Classes/Thread#-beats#logical time::, which will stay the
same until the Thread is called again. Hence, if this clock is the current Thread's
link::Classes/Thread#-clock#associated clock::, and you ask the clock for time in beats
just after changing it, you will see no effect. Nevertheless, the effect will be visible
immediately on a different Thread.
::
code::
(
t = TempoClock.new;
t.sched(3, {
t.beats = 100;
t.beats.postln; // still 3
nil
});
)
(
c = TempoClock.new;
fork {
loop {
c.beats.postln; // updates, because ".wait" calls the thread
1.wait;
}
};
)
c.beats = 100;
::
method::schedAbs
Schedules a task to be performed at a particular time in strong::beats::.
When the scheduling time is up, the task's code::awake:: method is called. If the method
returns a number, the task will be rescheduled for the time equal to the last scheduling
time plus the returned value.
See also: link::Classes/Clock#Scheduling::, link::Classes/Object#-awake::.
method::sched
Schedules a task to be performed code::delta:: amount of strong::beats:: after the
current Thread's logical time. If this clock is the current Thread's
link::Classes/Thread#-clock#associated clock::, the Thread's
link::Classes/Thread#-beats#time in beats:: is used, otherwise the Thread's
link::Classes/Thread#-seconds#time in seconds:: is converted to beats according to this
clock's tempo and time of origin.
When the scheduling time is up, the task's code::awake:: method is called. If the method
returns a number, the task will be rescheduled for the time equal to the last scheduling
time plus the returned value.
See also: link::Classes/Clock#Scheduling::, link::Classes/Object#-awake::.
method::play
Plays task (a function) at the next beat, where strong::quant:: is 1 by default. Shortcut for link::#-schedAbs::; see link::#-seconds:: and link::#-nextTimeOnGrid:: for further details on time and quant.
code::
t= TempoClock.default;
t.play({arg beats, time, clock; [beats, time, clock].postln});
::
method::playNextBar
Plays task (a function) at the next bar using link::#-schedAbs::.
method::queue
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.
method::beatDur
Returns the duration in seconds of a current whole beat.
method::beatsPerBar
Gets or sets the number of beats per bar. The default is 4. Setting must be done from within the scheduling thread, e.g.
code::
t= TempoClock.new;
t.schedAbs(t.nextBar, {t.beatsPerBar_(3)});
t.beatsPerBar;
::
method::bar
Returns the current bar. See link::#-bars2beats:: for returning beat of current bar.
method::nextBar
Returns the number of beats at the next bar line relative to the beat argument. If strong::beat:: is not supplied, returns the beat at which the next bar begins.
method::beatInBar
Returns the current bar beat (as a link::Classes/Float::) in relation to link::#-beatsPerBar::. Values range from 0 to < beatsPerBar.
method::baseBar
Returns bar at which link::#-beatsPerBar:: was last changed. If beatsPerBar has not been changed since the clock was created, returns 0.
method::baseBarBeat
Returns beat at which the link::#-beatsPerBar:: was last changed. If beatsPerBar has not been changed since the clock was created, returns 0.
method::beats2bars
Returns a bar as a float relative to link::#-baseBarBeat::.
method::bars2beats
Returns a beat relative to link::#-baseBar::.
code::
t= TempoClock.default;
t.bars2beats(t.bar) // downbeat of the current bar
::
method::timeToNextBeat
Returns the logical time to next beat. strong::quant:: is 1 by default, relative to baseBarBeat, see link::#-nextTimeOnGrid::.
method::nextTimeOnGrid
With default values, returns the next whole beat. strong::quant:: is 1 by default, strong::phase:: is 0. quant is relative to link::#-baseBarBeat::, such that
code::
t= TempoClock.default;
t.nextTimeOnGrid(t.beatsPerBar) == t.nextBar // => true
::
Together strong::quant:: and strong::phase:: are useful for finding the next n beat in a bar, e.g. code::nextTimeOnGrid(4, 2):: will return the next 3rd beat of a bar (of 4 beats), whereas code::nextBar-2:: may return an elapsed beat.
method::elapsedBeats
Returns the current elapsed time in beats. This is equivalent to code::tempoClock.secs2beats(Main.elapsedTime)::. It is often preferable to use link::#-beats:: instead of elapsedBeats because beats uses a thread's logical time.
method::seconds
Returns the current elapsed time. (This method is inherited from link::Classes/Clock::.)
method::beats2secs
Converts absolute strong::beats:: to absolute strong::seconds::, returning the elapsed time of the clock at the given strong::beats::. Only works for times in the current tempo. If the tempo changes any computed time in future will be wrong.
code::
t= TempoClock.default;
t.beats2secs(t.beats) // equivalent to t.seconds
t.beats2secs(0) // how many seconds after startup did beat 0 occur?
::
method::secs2beats
Converts absolute strong::seconds:: to absolute beats. Only works for times in the current tempo. If the tempo changes any computed time in future will be wrong.
EXAMPLES::
code::
t = TempoClock(1); // create a TempoClock
// schedule an event at next whole beat
t.schedAbs(t.beats.ceil, { arg beat, sec; [beat, sec].postln; 1 });
t.tempo = 2;
t.tempo = 4;
t.tempo = 0.5;
t.tempo = 1;
t.clear;
t.schedAbs(t.beats.ceil, { arg beat, sec; [beat, sec].postln; 1 });
t.stop;
::
code::
(
// get elapsed time, round up to next second
v = Main.elapsedTime.ceil;
// create two clocks in a 5:2 relation, starting at time v.
t = TempoClock(1, 0, v);
u = TempoClock(0.4, 0, v);
// start two functions at beat zero in each clock.
t.schedAbs(0, { arg beat, sec; [\t, beat, sec].postln; 1 });
u.schedAbs(0, { arg beat, sec; [\u, beat, sec].postln; 1 });
)
(
u.tempo = u.tempo * 3;
t.tempo = t.tempo * 3;
)
(
u.tempo = u.tempo * 1/4;
t.tempo = t.tempo * 1/4;
)
(
t.stop;
u.stop;
)
::
code::
(
// get elapsed time, round up to next second
v = Main.elapsedTime.ceil;
// create two clocks, starting at time v.
t = TempoClock(1, 0, v);
u = TempoClock(1, 0, v);
// start two functions at beat zero in each clock.
// t controls u's tempo. They should stay in sync.
t.schedAbs(0, { arg beat, sec; u.tempo = t.tempo * [1,2,3,4,5].choose; [\t, beat, sec].postln; 1 });
u.schedAbs(0, { arg beat, sec; [\u, beat, sec].postln; 1 });
)
(
u.tempo = u.tempo * 3;
t.tempo = t.tempo * 3;
)
(
u.tempo = u.tempo * 1/4;
t.tempo = t.tempo * 1/4;
)
(
t.stop;
u.stop;
)
::
|