-
Notifications
You must be signed in to change notification settings - Fork 1
/
AudioMulchClock.html
197 lines (197 loc) · 17.8 KB
/
AudioMulchClock.html
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
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title></title>
<meta name="Generator" content="Cocoa HTML Writer">
<meta name="CocoaVersion" content="949.54">
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #001fe8}
p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #0024b5}
p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #9d281b}
p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #606060}
span.s1 {font: 18.0px Helvetica}
span.s2 {color: #000000}
span.s3 {text-decoration: underline}
span.s4 {color: #526bb5}
span.s5 {color: #5f71a9}
span.s6 {color: #4e69b8}
span.s7 {color: #0030f2}
span.s8 {color: #5c70ac}
span.s9 {color: #2854d6}
span.s10 {color: #0024b5}
span.s11 {color: #3b6c19}
span.Apple-tab-span {white-space:pre}
</style>
</head>
<body>
<p class="p1"><span class="s1"><b>AudioMulchClock</b></span><b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>clock that slaves to AudioMulch over network</b></p>
<p class="p2"><br></p>
<p class="p3"><span class="s2"><b>See also: </b><a href="ClockAudioMulch.html"><b>ClockAudioMulch</b></a></span></p>
<p class="p2"><br></p>
<p class="p2"><br></p>
<p class="p1">Use this class to <b>receive</b> sync and have SuperCollider act as a <b>slave</b>.</p>
<p class="p2"><br></p>
<p class="p1">AudioMulch is a program written by Ross Bencina. <span class="s3">http://www.audiomulch.com/</span></p>
<p class="p1">AudioMulchClock is a SuperCollider class for synchronising playback with this program via network sync.</p>
<p class="p2"><br></p>
<p class="p1">This clock has no notion of time in seconds. Rather time advances in ticks and each incoming network sync message includes a tick counter. There are 24 ticks per beat and 96 per bar (assuming 4/4 - change beatsPerBar to use something different).</p>
<p class="p1">A tick is roughly 1/24 seconds long at tempo 60bpm. Though network jitter will add and subtract to this value.</p>
<p class="p1">Sub tick accurate scheduling (precision lower than 1/24th of a beat) is also possible.</p>
<p class="p2"><br></p>
<p class="p1"><span class="s3">Network setup:</span></p>
<p class="p1">In AudioMulch's preference panel under the <i>Network Sync</i> tab, set the <i>Send to address</i> to 127.0.0.1 and the corresponding UDP Port to 57120. Activate <i>Generate Network Sync</i> under the Control meny.</p>
<p class="p2"><br></p>
<p class="p1"><span class="s3">Known issues:</span></p>
<p class="p1">pbind legato does not behave correctly - scale it with beat duration.</p>
<p class="p2"><br></p>
<p class="p2"><br></p>
<p class="p1"><b><span class="Apple-tab-span"> </span>*new</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>creates a new clock.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><span class="Apple-tab-span"> </span><b>*default</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>returns the default clock. It is created the first time you try to access it and is permanent.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><span class="Apple-tab-span"> </span><b>play(task, quant)</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>schedules a function to be evaluated at some future beat - usually the next beat or next 4 beats (bar).</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>task</b> - a <a href="SC://Function"><span class="s4">Function</span></a>. The function is passed tick, time and clock as first three arguments.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>quant</b> - 1 plays on the next beat, 4 on the next bar etc. The default is 1.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>Also fractions of beats are possible.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><b><span class="Apple-tab-span"> </span>schedAbs(tick, item)</b></p>
<p class="p1"><b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>schedules a function to be evaluated at a certain <i>tick</i>.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>tick</b> - use .tick to find the current tick and then add an offset in ticks to that.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>Also fractions of ticks are possible for sub tick accuracy.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>item</b> - a <a href="SC://Function"><span class="s4">Function</span></a>. The function is passed tick, time and clock as first three arguments.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>if the function returns a number, it will be rescheduled in that amount of beats (yes, not ticks).</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><b><span class="Apple-tab-span"> </span>sched(delta, item)</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>schedules a function to be evaluated at some future beat.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>delta</b> - 1 here means the next upcoming beat.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>Also fractions of beats are possible as well as sub tick accuracy (1<24th of a beat).</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>item</b> - a <a href="SC://Function"><span class="s4">Function</span></a>. The function is passed tick, time and clock as first three arguments.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>if the function returns a number, it will be rescheduled in that amount of beats.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><b><span class="Apple-tab-span"> </span>nextTimeOnGrid(quant, phase)</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>used for finding out at which tick in the future the next beat or bar will occur.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>quant</b> - if 1 then return the tick for the next tick%24==0. If 4 then the tick for the next tick%96==0 etc.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>phase</b> - adds to the quant. e.g. quant 4 and phase 2 will return the tick at the next bar + two beats.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><span class="Apple-tab-span"> </span><b>clear</b></p>
<p class="p1"><b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>stops the clock and removes all tasks from the scheduling queue.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><span class="Apple-tab-span"> </span><b>beatDur</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>return the average beat duration in seconds.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>Note: this value will fluctuate because of network jitter.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><span class="Apple-tab-span"> </span><b>beats</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>return the current beat.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><b><span class="Apple-tab-span"> </span><running</b></p>
<p class="p1"><b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>A <a href="SC://Boolean"><span class="s5">Boolean</span></a> that is set when either a \t_start or a \t_pulse message is received.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>It is cleard when a \t_stop message is received or the clock is cleared.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><b><span class="Apple-tab-span"> </span><tick</b></p>
<p class="p1"><b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>An <a href="SC://Integer"><span class="s5">Integer</span></a> that counts up indefinitely.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><span class="Apple-tab-span"> </span><b><>shift</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>an <a href="SC://Integer"><span class="s6">Integer</span></a> specifying latency compentation in ticks. If negative items will be scheduled slightly early.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><span class="Apple-tab-span"> </span><b><>beatsPerBar</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>an <a href="SC://Integer"><span class="s7">Integer</span></a> that should match the number of beats in a bar. Used when restarting after a t_stop.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><span class="Apple-tab-span"> </span><b><permanent</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>a <a href="SC://Boolean"><span class="s7">Boolean</span></a>. If true then the clock will continue to run after a CmdPeriod.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>The user is responsible for clearing permanent clocks with the <b>clear</b> method.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><b><span class="Apple-tab-span"> </span><tempo</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>A <a href="SC://Float"><span class="s8">Float</span></a> that represents the average tempo in beats per minutes.</p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>Note: this value will fluctuate because of network jitter.</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><span class="Apple-tab-span"> </span><b><>startAction</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>a <a href="SC://Function"><span class="s9">Function</span></a> that is evaluated when the external clock is started (a \t_start is received).</p>
<p class="p2"><span class="Apple-tab-span"> </span></p>
<p class="p1"><span class="Apple-tab-span"> </span><b><>stopAction</b></p>
<p class="p1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>a <a href="SC://Function"><span class="s9">Function</span></a> that is evaluated when the external clock is stopped (a \t_stop is received).</p>
<p class="p2"><br></p>
<p class="p4"><br></p>
<p class="p4"><br></p>
<p class="p5">s.latency= 0.05;</p>
<p class="p5">s.boot;</p>
<p class="p4"><br></p>
<p class="p6"><span class="s2">a= </span>AudioMulchClock<span class="s2">.new;</span></p>
<p class="p7">//now press play in AudioMulch - make sure 'Generate Network Sync' is set under the control menu.</p>
<p class="p7"><span class="s2">a.beatDur<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>//will fluctuate because of network jitter</p>
<p class="p5">a.beats</p>
<p class="p7"><span class="s2">a.tempo<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>//will fluctuate because of network jitter</p>
<p class="p5">a.tick</p>
<p class="p4"><br></p>
<p class="p4"><br></p>
<p class="p4"><br></p>
<p class="p7">//--patterns - note that legato needs to be scaled down - still not working properly</p>
<p class="p5">b= <span class="s10">Pbind</span>(<span class="s11">\degree</span>, <span class="s10">Pseq</span>([0, 5, 2, 1, 0, 5, 2, 1, 0, -1], <span class="s10">inf</span>), <span class="s11">\dur</span>, <span class="s10">Pseq</span>([1, 1, 1, 1, 0.25, 0.25, 0.5, 1, 1, 1], <span class="s10">inf</span>), <span class="s11">\legato</span>, <span class="s10">Pfunc</span>({a.beatDur})).play(a, quant:4)</p>
<p class="p7"><span class="s2">a.shift= -3;<span class="Apple-tab-span"> </span></span>//latency compenstation.<span class="Apple-converted-space"> </span>3 ticks early</p>
<p class="p7">//now try changing tempo in AudioMulch</p>
<p class="p5">b.stop</p>
<p class="p5">a.clear</p>
<p class="p4"><br></p>
<p class="p4"><br></p>
<p class="p4"><br></p>
<p class="p7">//--show manual scheduling in beats</p>
<p class="p6"><span class="s2">a= </span>AudioMulchClock<span class="s2">.new;</span></p>
<p class="p5">(</p>
<p class="p6"><span class="s2">a.sched(3.5, {</span>|tick, time, clock|</p>
<p class="p8"><span class="s2"><span class="Apple-tab-span"> </span>(</span>"3.5 beats later - relative to now"<span class="s2">+tick+time+clock).postln;</span></p>
<p class="p6"><span class="s2"><span class="Apple-tab-span"> </span></span>nil<span class="s2">;</span></p>
<p class="p5">})</p>
<p class="p5">)</p>
<p class="p4"><br></p>
<p class="p5">(</p>
<p class="p7">//note: schedAbs works in ticks so you need to scale with ticks per beat (24)</p>
<p class="p5">a.schedAbs(a.tick+(2*24), {<span class="s10">|tick, time, clock|</span></p>
<p class="p8"><span class="s2"><span class="Apple-tab-span"> </span>(</span>"2 beats later (48 ticks) - absolute time"<span class="s2">+tick+time+clock).postln;</span></p>
<p class="p6"><span class="s2"><span class="Apple-tab-span"> </span></span>nil<span class="s2">;</span></p>
<p class="p5">})</p>
<p class="p5">)</p>
<p class="p4"><br></p>
<p class="p5">(</p>
<p class="p7">//schedules a synth at half a beat after the beginning of the next bar</p>
<p class="p5">a.schedAbs(a.nextTimeOnGrid(4, 0.5), {<span class="s10">|tick, time, clock|</span></p>
<p class="p5"><span class="Apple-tab-span"> </span><span class="s10">var</span> syn= <span class="s10">Synth</span>(<span class="s11">\default</span>);</p>
<p class="p5"><span class="Apple-tab-span"> </span>a.sched(1, {</p>
<p class="p5"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>syn.release;</p>
<p class="p5"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s10">nil</span>;</p>
<p class="p5"><span class="Apple-tab-span"> </span>});</p>
<p class="p7"><span class="s2"><span class="Apple-tab-span"> </span>4;<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>//reschedule every 4 beat</p>
<p class="p5">})</p>
<p class="p5">)</p>
<p class="p5">a.clear</p>
<p class="p4"><br></p>
<p class="p4"><br></p>
<p class="p4"><br></p>
<p class="p7">//--two pbinds on the same clock</p>
<p class="p5">(</p>
<p class="p6">SynthDef<span class="s2">(</span><span class="s11">\audiomulchclock</span><span class="s2">, {</span>|out= 0, atk= 0.01, rel= 0.2, gate= 1, freq= 400, pan= 0, amp= 1|</p>
<p class="p5"><span class="Apple-tab-span"> </span><span class="s10">var</span> env= <span class="s10">EnvGen</span>.kr(<span class="s10">Env</span>.asr(atk, amp, rel), gate, doneAction:2);</p>
<p class="p5"><span class="Apple-tab-span"> </span><span class="s10">var</span> src= <span class="s10">MoogFF</span>.ar(</p>
<p class="p5"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s10">Pulse</span>.ar(freq-(amp-env*50), env*0.25+0.5, env),</p>
<p class="p5"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>env.lag(2).exprange(freq*0.5, freq*2),</p>
<p class="p5"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>3</p>
<p class="p5"><span class="Apple-tab-span"> </span>);</p>
<p class="p5"><span class="Apple-tab-span"> </span><span class="s10">Out</span>.ar(out, <span class="s10">Pan2</span>.ar(src, pan));</p>
<p class="p5">}).add;</p>
<p class="p5">)</p>
<p class="p6"><span class="s2">a= </span>AudioMulchClock<span class="s2">.new;</span></p>
<p class="p5">a.shift= -4;</p>
<p class="p5">b= <span class="s10">Pbind</span>(<span class="s11">\instrument</span>, <span class="s11">\audiomulchclock</span>, <span class="s11">\degree</span>, <span class="s10">Pseq</span>([0, 5, 2, 1, 0, 5, 2, 1], <span class="s10">inf</span>)*[1, 0.5], <span class="s11">\strum</span>, 0.2, <span class="s11">\dur</span>, 0.5, <span class="s11">\pan</span>, [0.5, -0.5], <span class="s11">\amp</span>, cos(<span class="s10">Ptime</span>()*0.3), <span class="s11">\legato</span>, <span class="s10">Pfunc</span>({a.beatDur})).play(a, quant:4);</p>
<p class="p5">c= <span class="s10">Pbind</span>(<span class="s11">\instrument</span>, <span class="s11">\audiomulchclock</span>, <span class="s11">\degree</span>, <span class="s10">Pn</span>(<span class="s10">Pshuf</span>([0, 5, 2, 1, 0, 5, 2, 1], 4), <span class="s10">inf</span>)*[1, 0.5], <span class="s11">\strum</span>, 0.1, <span class="s11">\dur</span>, 0.5, <span class="s11">\pan</span>, [-0.5, 0.5], <span class="s11">\amp</span>, cos(<span class="s10">Ptime</span>()*0.2), <span class="s11">\legato</span>, <span class="s10">Pfunc</span>({a.beatDur}), <span class="s11">\octave</span>, 7).play(a, quant:4);</p>
<p class="p5">c.stop</p>
<p class="p5">b.stop</p>
<p class="p5">a.clear</p>
</body>
</html>