sclang: ServerShmInterface - try to avoid multiple destructor calls
[supercollider.git] / HelpSource / Classes / Pproto.schelp
blob78081b0498640275cd94b963c3b250bc6a69abff
1 class:: Pproto
2 summary:: provide a proto event for an event stream
3 related:: Classes/Pattern
4 categories:: Streams-Patterns-Events>Patterns>Server Control
6 description::
8 Pproto uses the strong::makeFunction:: to allocate resources (buffers, buses, groups) and create a protoEvent that makes those resources available to a pattern. It is fully compatible with non-realtime synthesis using strong::render::.
10 The strong::makeFunction:: "makes" the protoEvent (i.e. protoEvent is code::currentEnvironment::). Typically, it defines and yields a sequence of events that create the needed resources using the following eventTypes:
12 definitionList::
13 ## \allocRead || load a file from ~path, starting at ~firstFileFrame, reading ~numFrames sample frames
14 ## \cue || cue a file for DiskIn, with ~bufferSize frames
15 ## \table || load ~amps directly into a buffer
16 ## \sine1 || generate a buffer from ~amps
17 ## \sine2 || generate a buffer from ~freqs, ~amps
18 ## \sine3 || generate a buffer from ~freqs, ~amps, ~pahses
19 ## \cheby || generate a waveshape buffer from ~amps
20 ## \audioBus || allocate ~channels consecutive audio buses
21 ## \controlBus || allocate ~channels consecutive control buses
22 ## \on || create a synth
25 note::
26 These eventTypes will allocate their own buffers and buses unless they are specified. To support this, the key code::\bufNum:: is used rather than code::\bufnum:: which has a default value assigned.
29 When Pproto ends, these eventTypes will respond to the strong::cleanup:: call by strong::deallocating any resources they have allocated::. Do not assume your buffers, buses etc. will exist after Pproto stops!
31 The function yields each event. That event is then performed with possible modifications by enclosing patterns and the player (either an link::Classes/EventStreamPlayer:: or a link::Classes/ScoreStreamPlayer::). The resultant event is returned to the function where it can be assigned to a key within the protoEvent.
33 The patternarray is played using Pfpar, a variant of Ppar that ends when any of its subpatterns end. In this way,
34 you can use Pproto to create effects that can be controlled by a pattern that runs in parallel with the note generating pattern and ends together with that note generating pattern (see example 0 below).
36 A strong::cleanupFunction:: that deallocates resources when the pattern ends or is stopped is automatically created. It can be replaced with a user defined cleanup if needed. This function receives two arguments: strong::proto::, the prototype event, and strong::flag::, which is set false if all nodes have been freed already by link::Classes/CmdPeriod::.
38 Examples::
40 subsection::Example 0, using an effect with parallel control.
42 code::
44 SynthDef(\echo, { arg out=0, maxdtime=0.2, dtime=0.2, decay=2, gate=1;
45         var env, in;
46         env = Linen.kr(gate, 0.05, 1, 5, 2);
47         in = In.ar(out, 2);
48         XOut.ar(out, env, CombL.ar(in * env, maxdtime, Lag.kr(dtime, 4), decay, 1, in));
49 }, [\ir, \ir, 0.1, 0.1, 0]).add;
51 SynthDef(\fm, { arg out=0, freq, index, decay=2, gate=1;
52         var env, in;
53         env = Linen.kr(gate, 0.05, 1, 5, 2);
54         in = In.ar(out, 2);
55         XOut.ar(out, env, SinOsc.ar(freq, in * index));
56 }).add;
58 Pproto({
59         ~fsynth = ( type: \on, instrument: \fm, freq: 4, index: 1, addAction: 1, db: -30).yield;
60         ~fControl = [\set, ~fsynth[\id], ~fsynth[\msgFunc] ];
62         ~synth = ( type: \on, instrument: \echo, addAction: 1).yield;
63         ~sControl = [\set, ~synth[\id], ~synth[\msgFunc] ];
65         }, [
66         Pbind(*[
67                 #[type, id, msgFunc],   Pkey(\fControl),
69                 freq:   Pseg([0,1], 10).linexp(0,1, 0.1, 1000),
70                 index:  Pseg([0,1], 10).linexp(0,1, 0.1, 100),
71                 dur:    0.1
72         ]),
73         Pbind(*[
74                 #[type, id, msgFunc],   Pkey(\sControl),
76                 dtime:  Pwhite(0,0.2),
77                 decay:  Pwhite(0.1,2),
78                 dur:    1
79         ]),
80         Pbind(*[
81                 instrument: \default,
82                 freq: Pwhite(1,16) * 100,
83                 dur: 0.2,
84                 db:     0
85         ])
86         ]
87 ).play
91 subsection::Example 1, loading and granulating a sound file.
93 code::
95 SynthDef(\help_playbuf, { | out=0, bufnum = 0, rate = 1, startPos = 0, amp = 0.1, sustain = 1, pan = 0, loop = 1|
96         var audio;
97         rate = rate * BufRateScale.kr(bufnum);
98         startPos = startPos * BufFrames.kr(bufnum);
100         audio = BufRd.ar(1, bufnum, Phasor.ar(0, rate, startPos, BufFrames.ir(bufnum)), 1, 1);
101         audio = EnvGen.ar(Env.sine, 1, timeScale: sustain, doneAction: 2) * audio;
102         audio = Pan2.ar(audio, pan, amp);
103         OffsetOut.ar(out, audio);
104 }).add;
106 a = Pproto({
107         ~newgroup = (type: \group).yield;
108         ~sf1 = SoundFile(Help.dir +/+ "sounds/a11wlk01-44_1.aiff").asEvent.yield;
109 //      (type: \on).yield
111         Pbind(*[
112                 instrument:     \help_playbuf,
113                 dur:            Pseg([0,0,0.25,0.5, 0.75, 1],10).linexp(0,1,0.01,2),
114                 legato:         4,
115                 startPos:       Pn(Pseg([0,1], 20), inf),
116                 rate:           Pwhite(1, 1).midiratio,
117                 loop:           0,
118                 group:          Pkey(\newgroup),
119                 bufnum:         Pkey(\sf1)
120         ])
122 a.play;
125 //a.render("sounds/test.aif", 40)
126 //SoundFile.openRead("sounds/test.aif").play
129 subsection::Example 2, loading a waveform buffer and modifying it in performance.
131 code::
133 SynthDef(\osc,{ arg out=0, bufnum=0, numbufs = 8, sustain = 1, freq = 500, amp = 0.1, pan = 0;
134         var audio;
135         audio = Osc.ar(bufnum, freq);
136         audio = EnvGen.ar(Env.linen(0.01, 0.90,0.9), 1, timeScale: sustain, doneAction: 2) * audio;
137         audio = Pan2.ar(audio, pan, amp);
138         OffsetOut.ar(out, audio);
139 }).add;
141 b = Pproto({
142         ~bufnum = (type: \sine1, amps: 1.0/[1,2,3,4,5,6] ).yield;
143         },
144         Ppar([
145                 Pbind(*[
146                         instrument:     \osc,
147                         freq:           Pwhite(1, 16) * 100,
148                         detune:         Pfunc { Array.fill(3.rand + 1, {3.0.rand}) },
149                         dur:            Prand([2,2,2.5,1],10),
150                         db:             Pn(Pstep([-10, -20, -20, -15, -20, -20, -20], 0.5) ),
151                         legato:         Pwhite(0.0,1).linexp(0,1,0.1, 3)
152                 ]),
153                 Pbind(*[
154                         type:           \sine1,
155                         amps:           Pseg(Pfunc{ | ev | Array.fill(10, {1.0.rand}) }, 1),
156                         numOvertones:   Pseg(Pwhite(0, 9), 10).asInteger,
157                         amps:           Pfunc{ | ev | ev[\amps].copyRange(0, ev[\numOvertones]) },
158                         dur:            0.05,
159                         bufNum:         Pkey(\bufnum)
160                 ])
161         ])
163 b.play
166 //b.render("sounds/test.aif", 40)
167 //SoundFile.openRead("sounds/test.aif").play
170 subsection::Example 3, loading a waveshaper buffer and modifying it in performance.
172 code::
174 SynthDef(\shaper,{ arg out=0, bufnum=0, numbufs = 8, sustain = 1, freq = 500, amp = 0.1, pan = 0;
175         var audio;
176         audio = SinOsc.ar(freq);
177         audio = EnvGen.ar(Env.linen(0.4, 0.50,0.9), 1, timeScale: sustain, doneAction: 2) * audio;
178         audio = Shaper.ar(bufnum, audio);
179         audio = Pan2.ar(audio, pan, amp);
180         OffsetOut.ar(out, LeakDC.ar(audio));
181 }).add;
183 c = Pproto({
184         ~bufnum = (type: \cheby, amps: 1.0/[1,2,3,4,5,6] ).yield;
185         },
186         Ppar([
187                 Pbind(*[
188                         instrument:     \shaper,
189                         freq:           Pwhite(1, 16) * 100,
190                         detune:         Pfunc { Array.fill(3.rand + 1, {3.0.rand}) },
191                         dur:            Prand([2,2,2.5,1],inf),
192                         db:             Pn(Pstep([-10, -20, -20, -15, -20, -20, -20], 0.5) ),
193                         legato:         Pwhite(0.0,1).linexp(0,1,1.1, 5)
194                 ]),
195                 Pbind(*[
196                         type:           \cheby,
197                         amps:           Pseg(Pfunc{ | ev | Array.fill(10, {1.0.rand}) }, 4),
198                         dur:            0.05
199                 ])
200         ])
202 c.play
204 //c.render("sounds/test.aif", 40)
205 //SoundFile("sounds/test.aif").play