File: jitlib_basic_concepts_02.schelp

package info (click to toggle)
supercollider 1%3A3.6.6~repack-2-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 23,792 kB
  • ctags: 25,269
  • sloc: cpp: 177,129; lisp: 63,421; ansic: 11,297; python: 1,787; perl: 766; yacc: 311; sh: 286; lex: 181; ruby: 173; makefile: 168; xml: 13
file content (295 lines) | stat: -rw-r--r-- 9,242 bytes parent folder | download
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
title:: jitlib_basic_concepts_02
summary:: proxy space - basic concepts
categories:: Libraries>JITLib>Tutorials
related:: Overviews/JITLib, Tutorials/JITLib/jitlib_basic_concepts_01, Tutorials/JITLib/jitlib_basic_concepts_03

external structure of the node proxy, referencing in proxyspace and environments.

This document covers:

list::
## link::#a)_normal_environment_lookup#a) normal environment lookup::
## link::#b)_a_proxyspace_as_an_environment#b) a proxyspace as an environment::
## link::#c)_using_the_proxyspace_to_change_processes_on_the_fly#c) using the proxyspace to change processes on the fly::
## link::#d)_when_are_the_node_proxies_initialized?#d) when are the node proxies initialized?::
## link::#e)_moving_out_of_the_proxy_space#e) moving out of the proxy space::
## link::#f)_using_ProxySpace_together_with_other_Environments#f) using ProxySpace together with other Environments::
::

section::a) normal environment lookup

code::
currentEnvironment.postln; // anEnvironment (if not, you haven't left it from last helppage..)

~a; // access the environment: there is nothing stored: nil
~a = 9; // store something
~a; 	// now 9 is stored
~a + 100; // calculate with it

currentEnvironment.postln; // the value is stored in the environment

~b + ~a; // cause an error: ~b is nil.
~b = -90; // set ~b

~b + ~a; // now this works.

// note that you can always access environments (or ProxySpaces) from outside as well:

x = currentEnvironment;
x[\a] + x[\b] // equivalent to ~b + ~a

// or, if "know" is true, you can access named things with message-like syntax:
x.know = true;
x.a + x.b;
::

further readings: link::Classes/Environment::

section::b) a proxyspace as an environment

one can replace the current environment with a special type of environment, a ProxySpace. this environment represents processes that play audio on a server.

code::
p = ProxySpace.new(s);	// create a new environment, store it in variable p for now.
p.push;			// push it, so i becomes the current environment.
currentEnvironment.postln;
currentEnvironment === p; // and they are identical.

~x;		// accessing creates a NodeProxy (uninitialized) automatically.
~x + ~y;	// this works immediately, because the lookup does not return nil,
		// but a placeholder (proxy) instead

p.postln;	// now there are two empty placeholders in the environment.
::

section::c) using the proxyspace to change processes on the fly

code::
// boot the server
s.boot;


// as soon as a sound function (or any compatible input) is assigned to a proxy
// this sound plays on its own private bus (so it is not audible yet.)
(
~x = {
	RLPF.ar(Impulse.ar(4) * 20, [850, 950], 0.2)
}
)

// the proxy has been initialized by its first assignment.
// it plays at audio rate (because we have assigned an audio rate ugen function)
// and it has two channels (because the function has stereo output)

~x.index;	// a nodeproxy owns a private bus, so its signal can be used in diverse ways.
		// what is the proxy bus's index? this posts the index to the postwindow
		// before it was .ir(nil), now it is initialized to .ar(2)

~x.bus // what is the proxy's bus?


~x.play;	// now listen to it. a monitor is created (see Monitor) that plays the signal
		// onto a public bus - by default, this is bus 0, the first audio output bus.
		// This monitoring function is independent of the proxy itself.
		// for further info see: jitlib_basic_concepts_03 (part c)



// the sound function can be changed at any time:
(
~x = {
	RLPF.ar(Impulse.ar([5, 7]) * 5, [1450, 1234], 0.2)
}
)

// You can tune a sound function to your liking very easily
// by replacing it with little (or big) variations:

		// filter freqs higher:
~x = {	RLPF.ar(Impulse.ar([5, 7]) * 5, [1800, 2000], 0.2) }

		// same pulse ratio (5/8), different pulse tempo:
~x = {	RLPF.ar(Impulse.ar([5, 8] * 3.2) * 5, [1800, 2000], 0.2) }

		// different filter:
~x = {	Ringz.ar(Impulse.ar([5, 8] * 3.2), [1800, 2000], 0.05) }

// and if you set the proxy's fadeTime, you can create little
// textures by hand:

~x.fadeTime = 3;
		// different filter freqs every time:
~x = {	Ringz.ar(Impulse.ar([5, 8] * rrand(0.5, 1.5)) * 0.5, ({ exprand(200, 4000) } ! 2), 0.05) }



// here is another proxy:
~y = { Pan2.ar(Dust.ar(20), 0) };

~y.bus; // it has two channels, just as the ~x., but it plays on another (private) bus.

// note that ~y is not audible directly,
// but it can be used like a UGen in any other proxy:
(
~x = {
	RLPF.ar(~y.ar * 8, [1450, 1234], 0.2)
}
)

// when the proxy changes, the result changes dynamically:

~y = { Impulse.ar(MouseX.kr(2, 18, 1)) * [1, 1] };

~y = { PinkNoise.ar(MouseX.kr(0, 0.2) * [1, 1]) };

~y = { Impulse.ar([MouseX.kr(2, 18, 1), MouseY.kr(2, 18, 1)]) };



// stop listening. the proxies run in the background.

~x.stop;

~y.bus; // ~y is playing on a different bus ...
~x.bus; // than ~x.

// we can also listen to ~y directly:
~y.play;

// to remove a proxy source, nil can be used:

~y = nil;

// stop listening
~y.stop;
::

further readings: link::Tutorials/JITLib/proxyspace_examples::, link::Classes/Bus::, link::Classes/AbstractFunction::

section::d) when are the node proxies initialized?

bus initialization of a node proxy happens as soon as it is used for the first time. later inputs are adjusted to this bus, as far as it is possible.

code::
~z2 = { LFNoise0.kr([1, 2, 3, 4]) }; // a four channel control rate proxy
~z2.bus.postln;

~z100 = 0.5;	// a constant value creates a single channel control rate proxy.
~z100.bus.postln;

~z34.ar(3) 		// the first access (with a numChannels argument) allocates the bus
~z34.bus.postln;	// a 3 channel audio proxy

// these initializations can be removed by using clear:
~z34.clear;
~z34.bus.postln;
::

This initialisation happens whenever the proxy is first used. Later, the proxy can be accessed with other rate/numChannels combinations as needed (rates are converted,
numChannels are extended by wrapping, sources with too many channels are wrapped).

Note that this might cause ambiguous initialisation in which case the proxy should
be always initialized first. A typical problem is demonstrated here:

code::
~u.play(0, 2);	// initialize 2 audio channels (default). 0 is the output bus number.
		// if the proxy is not inititialized, play defaults to 2 channels.
		// here it is explicitly given only to make it more clear.
~u = { PinkNoise.ar(0.2) }; // use only one
~u.numChannels;	// 2 channels
~u.clear;
::

if evaluated the other way round, only one channel is used:

code::
~u = { PinkNoise.ar(0.2) };	// initialize 1 audio channel
~u.play(0, 2);			// play 2 channels: the 1 channel is expanded into 2.
				// numChannels of .play defaults to the proxy's numChannels.
				// here it is explicitly given, so to expand the channels
~u.numChannels;	// 1 channel
~u.clear;
::

Thus it can be useful to explicitly initialize proxies that use variable type inputs:

code::
~b.kr(8); ~c.ar;	// explicit initialisation
p.postln;		// post the whole proxy space
::

section::e) moving out of the proxy space

code::
// play the audio:
~x.play;

~x = { PinkNoise.ar(0.5) };

// p is the proxy space:
p.postln;

// to end all processes in p, use end:
p.end(2) // 2 seconds fade out.

// to remove all bus objects and free them from the bus allocato, use clear:
p.clear;

currentEnvironment.postln;

// restore original environment:

p.pop;

currentEnvironment.postln;

~a + ~b; // the old values are still here.

p === currentEnvironment; // this is not the case anymore.

// remove the content, so the garbage collector can release their memory.
p.clear;

// note that if you use this kind of accessing scheme, the objects are not garbage collected
// until the keys are set to nil. This is a common mistake when using normal environments.

// clear all in the normal environment:

currentEnvironment.clear;
::

section::f) using ProxySpace together with other Environments

using proxy space as an access scheme for node proxies can get in the way of the normal use of environments as pseudo variables. Here are some ways to cope with this.

code::
//////////////	EnvirDocument is currently unavailable ////////////
//// if you want to keep using the current environment as usual, you can restrict the
//// scope of proxyspace to one document (note: this is mac-only currently)
//
//EnvirDocument(p, "proxyspace");	// to test this, check for currentEnvironment here
//					// and in the envir document.

// you can also access the proxy space and the proxies in it indirectly:
p[\x].play;
p[\x] = { SinOsc.ar(450, 0, 0.1) };

// or: when the proxyspace is pushed, you can use a normal environment indirectly:
p.push;
d = ();
d[\buffer1] = Buffer.alloc(s, 1024);
d.use { ~buffer1.postln; ~zz = 81; }; // for more than one access to the environment, use .use


// to access the inner environment of proxy space directly,
// e.g. to check whether a proxy exists, one can use .envir:

p.envir.postln;
p.envir[\x].postln;	// a proxy with this name exists
p.envir[\nono].postln;	// there is no proxy with this name.

// p[\nono].postln;	// this access would have created a new proxy called \nono.
::

previous: link::Tutorials/JITLib/jitlib_basic_concepts_01:: next: link::Tutorials/JITLib/jitlib_basic_concepts_03::