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.48">
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: 14.0px Helvetica
}
13 p
.p4
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #000000}
14 p
.p5
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #bf0000}
15 p
.p6
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #0000bf}
16 p
.p7
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #007300}
17 p
.p8
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #000000; min-height: 12.0px}
18 span
.s1
{font: 18.0px Helvetica
}
19 span
.s2
{color: #0000ff}
20 span
.s3
{color: #0000bf}
21 span
.s4
{color: #000000}
22 span
.s5
{color: #007300}
23 span
.Apple-tab-span
{white-space:pre
}
27 <p class=
"p1"><span class=
"s1"><b>Pspawn
</b></span><b><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>Spawns sub-patterns based on parameters in an event pattern
</b></p>
28 <p class=
"p2"><br></p>
29 <p class=
"p1"><b>Inherits from: AbstractFunction : Pattern : FilterPattern
</b></p>
30 <p class=
"p2"><br></p>
31 <p class=
"p1">Pspawn is a pattern-based version of
<a href=
"Pspawner.html"><span class=
"s2">Pspawner
</span></a>. Where Pspawner uses a Routine-style function to determine when and how to spawn child patterns into the result stream, Pspawn uses an event pattern to determine the actions to take.
</p>
32 <p class=
"p2"><br></p>
33 <p class=
"p1">Recommended to read the
<a href=
"Pspawner.html"><span class=
"s2">Pspawner
</span></a> help file to become familiar with pattern spawning capabilities.
</p>
34 <p class=
"p2"><br></p>
35 <p class=
"p1"><b>Important:
</b> There are two kinds of events involved in Pspawn:
</p>
36 <p class=
"p2"><br></p>
37 <p class=
"p1">-
<b>parent
</b> events, which specify the pattern to embed, how to embed it (in parallel or sequence), and how long to wait until the next action;
</p>
38 <p class=
"p1">-
<b>child
</b> events, which produce the resulting notes (or take other actions on the server).
</p>
39 <p class=
"p2"><br></p>
40 <p class=
"p1">Of these, only the child events are returned to the event stream player during play. The parent events are used strictly internally to control spawning behavior. The parent and child event streams do not mix together. Thus pattern composition (Pchain) and parallelization (Ppar) may be used without special handling. It is up to the user to be aware of whether the parent or child stream should be subject to further manipulation, and put that manipulation in the right place. If it is to affect the child stream, it should enclose the entire Pspawn; for the parent stream, it should be inside Pspawn. (See the examples below.)
</p>
41 <p class=
"p2"><br></p>
42 <p class=
"p3"><b>Creation
</b></p>
43 <p class=
"p2"><br></p>
44 <p class=
"p1"><b>*new(pattern, spawnProtoEvent)
</b></p>
45 <p class=
"p2"><br></p>
46 <p class=
"p1"><b>pattern:
</b> An event pattern (typically Pbind) encapsulating the desired spawning behavior. Parameters in this event are described below.
</p>
47 <p class=
"p1"><b>spawnProtoEvent:
</b> The event prototype against which the pattern is evaluated. Good for giving default values that should apply to all spawning (parent) events.
</p>
48 <p class=
"p2"><br></p>
49 <p class=
"p1">Pspawn uses the following items in the parent pattern:
</p>
50 <p class=
"p2"><br></p>
51 <p class=
"p1"><b>method:
</b> The action to call on the spawner object. Currently supported: wait, seq, par, suspendAll.
</p>
52 <p class=
"p1"><b>delta:
</b> How long to wait until the next action.
</p>
53 <p class=
"p1"><b>dict:
</b> If 'pattern' is given as a symbol (see below), this is the dictionary in which the pattern will be looked up. If not specified, the
<a href=
"../../Libraries/JITLib/Patterns/Pdef.html"><span class=
"s2">Pdef
</span></a> collection will be used.
</p>
54 <p class=
"p1"><b>pattern:
</b> If 'method' is seq or par, this is a pattern or function to be embedded, according to the following rules.
</p>
55 <p class=
"p2"><br></p>
56 <p class=
"p1"><b>'pattern' in the event
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>Resulting behavior
</b></p>
57 <p class=
"p2"><br></p>
58 <p class=
"p1">A function:
<b>{ ... }
</b><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>The function should return a pattern; this pattern is spawned.
</p>
59 <p class=
"p1">A Ref to a pattern:
<b>`Pbind(...)
</b><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>The referenced pattern is spawned.
</p>
60 <p class=
"p1">A Symbol:
<b>\scaleUp
</b><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>The pattern is looked up in the event's 'dict'.
</p>
61 <p class=
"p2"><br></p>
62 <p class=
"p2"><br></p>
63 <p class=
"p3"><b>Using references to protect patterns from embedding
</b></p>
64 <p class=
"p2"><br></p>
65 <p class=
"p1">Normally, when a pattern appears inside another pattern, the subpattern is embedded in the main output stream. It is not visible to the outside world as a pattern in itself; only its values appear.
</p>
66 <p class=
"p2"><br></p>
67 <p class=
"p4"><span class=
"s3">Pseq
</span>([
<span class=
"s3">Pwhite
</span>(
0,
9,
5),
<span class=
"s3">Pwhite
</span>(
10,
19,
5)],
1).asStream.all;
</p>
68 <p class=
"p2"><br></p>
69 <p class=
"p1">When using Pspawn, a sub pattern must be returned directly into the event. To accomplish this, every such pattern should be wrapped in a Ref:
</p>
70 <p class=
"p2"><br></p>
71 <p class=
"p4"><span class=
"s3">Pseq
</span>([`
<span class=
"s3">Pwhite
</span>(
0,
9,
5), `
<span class=
"s3">Pwhite
</span>(
10,
19,
5)],
1).asStream.all;
</p>
72 <p class=
"p2"><br></p>
73 <p class=
"p1"><b>Hint:
</b> Pfunc is another good way to wrap patterns, because it simply returns its result values without further embedding. See the first example.
</p>
74 <p class=
"p2"><br></p>
75 <p class=
"p2"><br></p>
76 <p class=
"p3"><b>Examples:
</b></p>
77 <p class=
"p2"><br></p>
78 <p class=
"p5">// Play overlapping major scales, up and down
</p>
80 <p class=
"p6"><span class=
"s4">p =
</span>Pspawn
<span class=
"s4">(
</span>Pbind
<span class=
"s4">(
</span></p>
81 <p class=
"p5"><span class=
"s4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// Pbind returned by Pfunc is not embedded, just placed in the event
</p>
82 <p class=
"p5"><span class=
"s4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// So, it can be spawned
</p>
83 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"s5">\pattern
</span>,
<span class=
"s3">Pfunc
</span> {
<span class=
"s3">Pbind
</span>(
<span class=
"s5">\degree
</span>,
<span class=
"s3">Pseries
</span>(rrand(
0,
10), #[-
1,
1].choose, rrand(
4,
10)),
<span class=
"s5">\dur
</span>,
0.125) },
</p>
84 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"s5">\delta
</span>,
<span class=
"s3">Pwhite
</span>(
1,
5,
<span class=
"s3">inf
</span>) *
0.125,
</p>
85 <p class=
"p7"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>\method
<span class=
"s4">,
</span>\par
</p>
86 <p class=
"p4">)).play;
</p>
88 <p class=
"p8"><br></p>
89 <p class=
"p4">p.stop;
</p>
90 <p class=
"p8"><br></p>
91 <p class=
"p8"><br></p>
92 <p class=
"p5">// Same, using a dictionary of patterns, changing dur rhythm also
</p>
94 <p class=
"p4"><span class=
"s3">var
</span><span class=
"Apple-tab-span"> </span>patternChoices = (
</p>
95 <p class=
"p4"><span class=
"Apple-tab-span"> </span>up: {
<span class=
"s3">Pbind
</span>(
<span class=
"s5">\degree
</span>,
<span class=
"s3">Pseries
</span>(rrand(-
4,
5),
1, rrand(
4,
10)),
<span class=
"s5">\dur
</span>,
0.125) },
</p>
96 <p class=
"p4"><span class=
"Apple-tab-span"> </span>down: {
<span class=
"s3">Pbind
</span>(
<span class=
"s5">\degree
</span>,
<span class=
"s3">Pseries
</span>(rrand(
4,
11), -
1, rrand(
4,
10)),
<span class=
"s5">\dur
</span>,
0.125 *
4/
3) }
</p>
98 <p class=
"p8"><br></p>
99 <p class=
"p6"><span class=
"s4">p =
</span>Pspawn
<span class=
"s4">(
</span>Pbind
<span class=
"s4">(
</span></p>
100 <p class=
"p7"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>\pattern
<span class=
"s4">,
</span><span class=
"s3">Prand
</span><span class=
"s4">([
</span>\up
<span class=
"s4">,
</span>\down
<span class=
"s4">],
</span><span class=
"s3">inf
</span><span class=
"s4">),
</span></p>
101 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"s5">\delta
</span>,
<span class=
"s3">Pwhite
</span>(
1,
5,
<span class=
"s3">inf
</span>) *
0.125,
</p>
102 <p class=
"p7"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>\method
<span class=
"s4">,
</span>\par
</p>
103 <p class=
"p4">), (dict: patternChoices)).play;
</p>
105 <p class=
"p8"><br></p>
106 <p class=
"p4">p.stop;
</p>
107 <p class=
"p8"><br></p>
108 <p class=
"p8"><br></p>
109 <p class=
"p5">// Using pattern composition (perhaps gratuitously) to build the parent events
</p>
111 <p class=
"p4"><span class=
"s3">var
</span><span class=
"Apple-tab-span"> </span>patternChoices = (
</p>
112 <p class=
"p4"><span class=
"Apple-tab-span"> </span>up: {
<span class=
"s3">Pbind
</span>(
<span class=
"s5">\degree
</span>,
<span class=
"s3">Pseries
</span>(rrand(-
4,
5),
1, rrand(
4,
10)),
<span class=
"s5">\dur
</span>,
0.125) },
</p>
113 <p class=
"p4"><span class=
"Apple-tab-span"> </span>down: {
<span class=
"s3">Pbind
</span>(
<span class=
"s5">\degree
</span>,
<span class=
"s3">Pseries
</span>(rrand(
4,
11), -
1, rrand(
4,
10)),
<span class=
"s5">\dur
</span>,
0.125 *
4/
3) }
</p>
115 <p class=
"p8"><br></p>
116 <p class=
"p6"><span class=
"s4">p =
</span>Pspawn
<span class=
"s4">(
</span>Pchain
<span class=
"s4">(
</span></p>
117 <p class=
"p6"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>Pbind
<span class=
"s4">(
</span></p>
118 <p class=
"p7"><span class=
"s4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>\pattern
<span class=
"s4">,
</span><span class=
"s3">Prand
</span><span class=
"s4">([
</span>\up
<span class=
"s4">,
</span>\down
<span class=
"s4">],
</span><span class=
"s3">inf
</span><span class=
"s4">),
</span></p>
119 <p class=
"p7"><span class=
"s4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>\method
<span class=
"s4">,
</span>\par
</p>
120 <p class=
"p4"><span class=
"Apple-tab-span"> </span>),
</p>
121 <p class=
"p6"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>Pbind
<span class=
"s4">(
</span></p>
122 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s5">\delta
</span>,
<span class=
"s3">Pwhite
</span>(
1,
5,
<span class=
"s3">inf
</span>) *
0.125</p>
123 <p class=
"p4"><span class=
"Apple-tab-span"> </span>)
</p>
124 <p class=
"p4">), (dict: patternChoices)).play;
</p>
126 <p class=
"p8"><br></p>
127 <p class=
"p4">p.stop;
</p>
128 <p class=
"p8"><br></p>
129 <p class=
"p8"><br></p>
130 <p class=
"p5">// Play parallel scales in the left channel and sequentially-arranged scales in the right
</p>
131 <p class=
"p5">// This means parallelizing (Ppar) the child streams; thus Ppar surrounds a pair of Pspawns
</p>
132 <p class=
"p8"><br></p>
133 <p class=
"p5">// Handling of \pan is interesting: \pan needs to be a property of the patternChoices items
</p>
134 <p class=
"p5">// It is NOT a property of the spawning events
</p>
135 <p class=
"p5">// To reuse patternChoices, the Pspawns wrap the base patterns in a Pbindf, which adds new values
</p>
137 <p class=
"p4"><span class=
"s3">var
</span><span class=
"Apple-tab-span"> </span>patternChoices = (
</p>
138 <p class=
"p4"><span class=
"Apple-tab-span"> </span>up: {
<span class=
"s3">Pbind
</span>(
<span class=
"s5">\degree
</span>,
<span class=
"s3">Pseries
</span>(rrand(-
4,
5),
1, rrand(
4,
10)),
<span class=
"s5">\dur
</span>,
0.125) },
</p>
139 <p class=
"p4"><span class=
"Apple-tab-span"> </span>down: {
<span class=
"s3">Pbind
</span>(
<span class=
"s5">\degree
</span>,
<span class=
"s3">Pseries
</span>(rrand(
4,
11), -
1, rrand(
4,
10)),
<span class=
"s5">\dur
</span>,
0.125 *
4/
3) }
</p>
141 <p class=
"p8"><br></p>
142 <p class=
"p4">p =
<span class=
"s3">Ppar
</span>([
</p>
143 <p class=
"p6"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>Pspawn
<span class=
"s4">(
</span>Pbind
<span class=
"s4">(
</span></p>
144 <p class=
"p5"><span class=
"s4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// intermediate value
</p>
145 <p class=
"p7"><span class=
"s4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>\patternKey
<span class=
"s4">,
</span><span class=
"s3">Prand
</span><span class=
"s4">([
</span>\up
<span class=
"s4">,
</span>\down
<span class=
"s4">],
</span><span class=
"s3">inf
</span><span class=
"s4">),
</span></p>
146 <p class=
"p5"><span class=
"s4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// pattern is selected and pan applied here
</p>
147 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s5">\pattern
</span>,
<span class=
"s3">Pfunc
</span> {
<span class=
"s3">|ev|
</span> <span class=
"s3">Pbindf
</span>(ev.dict[ev.patternKey].value,
<span class=
"s5">\pan
</span>, -
1) },
</p>
148 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s5">\delta
</span>,
<span class=
"s3">Pwhite
</span>(
1,
5,
<span class=
"s3">inf
</span>) *
0.125,
</p>
149 <p class=
"p7"><span class=
"s4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>\method
<span class=
"s4">,
</span>\par
</p>
150 <p class=
"p4"><span class=
"Apple-tab-span"> </span>), (dict: patternChoices)),
</p>
151 <p class=
"p6"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>Pspawn
<span class=
"s4">(
</span>Pbind
<span class=
"s4">(
</span></p>
152 <p class=
"p7"><span class=
"s4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>\patternKey
<span class=
"s4">,
</span><span class=
"s3">Prand
</span><span class=
"s4">([
</span>\up
<span class=
"s4">,
</span>\down
<span class=
"s4">],
</span><span class=
"s3">inf
</span><span class=
"s4">),
</span></p>
153 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s5">\pattern
</span>,
<span class=
"s3">Pfunc
</span> {
<span class=
"s3">|ev|
</span> <span class=
"s3">Pbindf
</span>(ev.dict[ev.patternKey].value,
<span class=
"s5">\pan
</span>,
1) },
</p>
154 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s5">\delta
</span>,
<span class=
"s3">Pwhite
</span>(
1,
5,
<span class=
"s3">inf
</span>) *
0.125,
</p>
155 <p class=
"p7"><span class=
"s4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>\method
<span class=
"s4">,
</span>\seq
</p>
156 <p class=
"p4"><span class=
"Apple-tab-span"> </span>), (dict: patternChoices)),
<span class=
"Apple-tab-span"> </span></p>
157 <p class=
"p4">]).play;
</p>
159 <p class=
"p8"><br></p>
160 <p class=
"p4">p.stop;
</p>