1 title:: Understanding Streams, Patterns and Events - Part 6
2 summary:: Parallel Patterns
3 related:: Tutorials/Streams-Patterns-Events1, Tutorials/Streams-Patterns-Events2, Tutorials/Streams-Patterns-Events3, Tutorials/Streams-Patterns-Events4, Tutorials/Streams-Patterns-Events5, Tutorials/Streams-Patterns-Events7
4 categories:: Streams-Patterns-Events>Understanding-Streams-Patterns-and-Events
6 section::Parallel Patterns
10 The link::Classes/Ppar:: pattern allows you to merge multiple event streams to play in parallel.
12 Ppar is a link::Classes/ListPattern:: and so like most ListPatterns it takes two arguments, a strong::list:: of event patterns to play in parallel and a strong::repeats:: count.
14 Ppar's child patterns must be event patterns. Using value patterns in a Ppar is an error because value patterns contain no duration data.
16 A Ppar is done when all of its subpatterns are done.
21 Pbind(\dur, 0.2, \midinote, Pseq([62, 65, 69, 72], inf)),
22 Pbind(\dur, 0.4, \midinote, Pseq([50, 45], inf))
28 // Ppars can be nested
31 \dur, Prand([0.2, 0.4, 0.6], inf),
32 \midinote, Prand([72, 74, 76, 77, 79, 81], inf),
37 Pbind(\dur, 3.2, \freq, Pseq([\rest]) ),
40 Pbind(\dur, 0.2, \pan, 0.5, \midinote, Pseq([60, 64, 67, 64])),
41 Pbind(\dur, 0.4, \pan, -0.5, \midinote, Pseq([48, 43]))
44 Pbind(\dur, 0.2, \pan, 0.5, \midinote, Pseq([62, 65, 69, 65])),
45 Pbind(\dur, 0.4, \pan, -0.5, \midinote, Pseq([50, 45]))
48 Pbind(\dur, 0.2, \pan, 0.5, \midinote, Pseq([64, 67, 71, 67])),
49 Pbind(\dur, 0.4, \pan, -0.5, \midinote, Pseq([52, 47]))
59 The link::Classes/Ppar:: pattern starts all of its subpatterns at the same time.
61 A link::Classes/Ptpar:: pattern includes a start time parameter before each subpattern which allow the subpatterns to be started at some time delay within the pattern. The start time is given in beats.
65 var makePattern, durpat;
67 durpat = Pseq([ Pgeom(0.05, 1.1, 24), Pgeom(0.5, 0.909, 24) ], 2);
69 makePattern = { arg note, db, pan;
70 Pbind( \dur, durpat, \db, db, \pan, pan, \midinote, Pseq([note, note-4], inf) );
74 0.0, makePattern.value(53, -20, -0.9),
75 2.0, makePattern.value(60, -23, -0.3),
76 4.0, makePattern.value(67, -26, 0.3),
77 6.0, makePattern.value(74, -29, 0.9)
82 The time arguments are sent the code::value:: message when the Ptpar pattern is started, so you may use functions to specify the times.
86 var makePattern, durpat;
88 durpat = Pseq([ Pgeom(0.05, 1.1, 24), Pgeom(0.5, 0.909, 24) ], 2);
90 makePattern = { arg note, db, pan;
91 Pbind( \dur, durpat, \db, db, \pan, pan, \midinote, Pseq([note, note-4], inf) );
95 { 0.0 }, makePattern.value(53, -20, -0.9),
96 { 8.0.rand }, makePattern.value(60, -23, -0.3),
97 { 8.0.rand }, makePattern.value(67, -26, 0.3),
98 { 8.0.rand }, makePattern.value(74, -29, 0.9)
103 section::FilterPatterns and transformation
105 FilterPatterns take an existing pattern and apply some modification to its properties.
107 subsection::Padd, Pmul, Pset, Pstretch
109 There is a simpler way to write the modal transposition example given in part 5. In fact the earlier examples are setting the values of code::mtranspose:: and code::ctranspose:: which is not the best way to change those variables, because it wipes out any modifications to them by parent patterns. It is better to take the current value of those properties and add a value to them.
111 The link::Classes/Padd:: filter takes the current value of a property and adds a value to it.
115 // modal transposition
118 // define the basic pattern
121 \degree, Pseq([ Pshuf(#[-7,-3,0,2,4,7], 4), Pseq([0,1,2,3,4,5,6,7]) ], 1)
125 pattern, // untransposed
126 Padd(\mtranspose, 1, pattern), // modal transpose up 1 degree
127 Padd(\mtranspose, 2, pattern) // modal transpose up 2 degrees
132 Similarly, link::Classes/Pmul:: multiplies the current value of a property by a value. link::Classes/Pset:: sets the property to a value.
134 In order to process duration correctly link::Classes/Pstretch:: should be used.
138 // beat stretching using Pstretch
141 // define the basic pattern
144 \degree, Pseq([ Pshuf(#[-7,-3,0,2,4,7], 4), Pseq([0,1,2,3,4,5,6,7]) ], 1)
149 Pstretch(0.5, pattern), // stretch durations by a factor of 1/2
150 Pstretch(2.0, pattern) // stretch durations by a factor of 2
155 subsection::Paddp, Pmulp, Psetp, Pstretchp
157 In fact there is an even shorter version of the modal transposition example. link::Classes/Paddp:: reads one pattern to get values for adding to a property and plays the second pattern once through modified with each new value.
161 // modal transposition
164 // define the basic pattern
167 \degree, Pseq([ Pshuf(#[-7,-3,0,2,4,7], 4), Pseq([0,1,2,3,4,5,6,7]) ], 1)
171 \mtranspose, // property to be modified
172 Pseq([0,1,2], inf), // a value pattern as a source of values for adding to mtranspose
173 pattern // the pattern to be modified
178 Nested modifications:
182 // modal transposition
185 // define the basic pattern
188 \degree, Pseq([ Pshuf(#[-7,-3,0,2,4,7], 4), Pseq([0,1,2,3,4,5,6,7]) ], 1)
192 \mtranspose, // property to be modified
193 Pseq([0,1,2]), // a value pattern as a source of values for adding to mtranspose
196 Padd(\mtranspose, -3, pat1), // down a 4th
197 Padd(\mtranspose, 2, pat1) // up a 3rd
202 pat1, // unmodified pattern
203 pat2, // parallel sequence
204 Pstretch(1.5, pat2) // parallel sequence stretched by 3/2
209 Another example using Paddp:
214 chord = Prand([[53, 58, 64],[53, 60, 64],[57,60,65]]);
215 Paddp(\ctranspose, Prand([-1,0,2,4,5], inf),
217 Pbind( // melody part
218 \dur, Prand([0.2, 0.4, 0.6], inf),
219 \midinote, Pxrand([71, 72, 74, 76, 77, 79], 10),
223 Pbind( // harmony part
225 \dur, Pseq([0.1, 0.5, 0.4, 0.6], 4),
226 \midinote, Pseq([chord,\rest,chord,\rest], 4)
231 \midinote, Pseq([38, 45, 38, 36], 4)
239 // chromatic transposition
242 // define the basic pattern
245 \degree, Pseq([0,1,2,3,4,5,6,7])
249 \ctranspose, // property to be modified
250 Pseries(0,1,12), // a value pattern as a source of values for multiplying with ctranspose
251 pattern // the pattern to be modified
257 // beat time stretching
260 // define the basic pattern
263 \degree, Pseq([0,1,2,3,4,5,6,7])
267 Pseq([1,2,3], inf), // a value pattern as a source of values for multiplying with stretch
268 pattern // the pattern to be modified
275 link::Classes/Pbindf:: is like link::Classes/Pbind:: except that it merges all the bound symbols into events that it gets from a subpattern. It takes the same initial arguments in pairs as Pbind does, with an additional pattern to be modified as the last argument.
280 pattern = Pbind( \midinote, Pseq(#[60, 62, 64, 65, 67, 69, 71, 72]) );
283 Pbindf(pattern, \legato, 0.1, \dur, 0.2),
284 Pbindf(pattern, \legato, 1.0, \dur, 0.125),
285 Pbindf(pattern, \legato, 2.0, \dur, 0.3)
290 Patterns can be used as the arguments to Pbindf.
295 pattern = Pbind( \midinote, Pseq(#[60, 62, 64, 65, 67, 69, 71, 72, 74, 76, 77, 79]) );
298 Pbindf(pattern,\legato, 0.1, \dur, Pgeom(0.3, 0.85, inf)),
299 Pbindf(pattern,\legato, 1.0, \dur, Pseq([0.3, 0.15], inf)),
300 Pbindf(pattern,\legato, 2.0, \dur, Pseq([0.2, 0.2, 0.4], inf))
305 To go to the next file:
306 link::Tutorials/Streams-Patterns-Events7::