1title:: Pattern Guide 06d: Parallel Patterns
2summary:: Running multiple event patterns simultaneously
3related:: Tutorials/A-Practical-Guide/PG_06c_Composition_of_Patterns, Tutorials/A-Practical-Guide/PG_06e_Language_Control
4categories:: Streams-Patterns-Events>A-Practical-Guide
5
6section::Parallelizing event patterns
7
8There are a couple of different ways to have several patterns playing at the same time. The most obvious is to play them separately. The patterns' events get scheduled independently on their clock(s) and run concurrently. None of these patterns need to have any knowledge of the others. One advantage of this approach is that the patterns can be stopped and started independently.
9
10The other is to combine them into a parallel stream. The result is a single pattern object that can be played or stopped only as one unit. Some degree of interactive control is lost, but there are times when merging several patterns is necessary -- for instance, converting a pattern into a Score object for NRT rendering.
11
12definitionList::
13## code::Ppar(list, repeats):: || Start each of the event patterns in the code::list:: at the same time. When the last one finishes, the link::Classes/Ppar:: also stops. If code::repeats > 1 ::, all the subpatterns start over again from the beginning.
14## code::Ptpar(list, repeats):: || Here, the list consists of code::[timeOffset0, pattern0, timeOffset1, pattern1...]:: . Each pattern starts after the number of beats given as its time offset. The patterns can start at different times relative to each other.
15## code::Pgpar(list, repeats):: || Like Ppar, but it creates a separate group for each subpattern.
16## code::Pgtpar(list, repeats):: || This is like Ptpar with separate groups for the subpatterns.
17::
18
19An excellent example of link::Classes/Ppar:: and link::Classes/Pseq:: used together to structure an entire piece (Kraftwerk's "Spacelab") can be found in examples/pieces/spacelab.scd.
20
21subsection::Dynamic parallelizing
22
23Ppar and its cousins are good for a fixed set of parallel patterns -- that is, you need to know in advance how many patterns will be parallelized. Once the parallel pattern starts, there is no way to add more streams to it. To keep adding streams, use link::Classes/Pspawner:: and link::Classes/Pspawn::. For the purpose of this overview, some basic features will be illustrated in a couple of simple examples. These classes have more capabilities; refer to their help files for specifics.
24
25definitionList::
26## code::Pspawner(routineFunc):: || The function is run in a Routine. A Spawner object gets passed into this Routine, and this object is used to add or remove streams to/from the parallel stream. New patterns can be added in sequence or in parallel.
27## code::Pspawn(pattern, spawnProtoEvent):: || Supports most of the features of Pspawner, but uses a pattern to control the Spawner object instead of a Routine function.
28
29This example uses link::Classes/Pspawner:: to trigger overlapping scale segments at different speeds. Unlike Ppar, which could handle a fixed number before stopping, Pspawner can keep going indefinitely.
30
31code::
32(
33p = Pspawner({ |sp|	// sp = the Spawner object
34	loop {
35			// run a new pattern in parallel
36			// the pattern is finite
37			// after a few events, it stops and the Pspawner forgets about it
38		sp.par(Pbind(
39			\degree, Pseries(rrand(-5, 7), #[-1, 1].choose, rrand(4, 7)),
40			\pan, rrand(-1.0, 1.0),
41			\dur, rrand(0.1, 0.3)	// duration is chosen once for each pattern
42		));
43			// tell the Spawner to wait a bit before the next pattern goes
44			// DO NOT use numBeats.wait for this!
45			// Everything must go through the Spawner
46		sp.wait(rrand(1, 4) * 0.25);
47	}
48}).play;
49)
50
51p.stop;
52::
53
54The same, written using link::Classes/Pspawn:: :
55
56code::
57(
58p = Pspawn(Pbind(
59	\method, \par,		// embed patterns in parallel
60		// generate the subpattern in a Pfunc (so there's a new pattern each time)
61		// Pfunc returns the pattern without rendering the stream
62		// -- important for Pspawn
63		// See the Pspawn helpfile for other ways to embed patterns
64	\pattern, Pfunc {
65		Pbind(
66			\degree, Pseries(rrand(-5, 7), #[-1, 1].choose, rrand(4, 7)),
67			\pan, rrand(-1.0, 1.0),
68			\dur, rrand(0.1, 0.3)	// duration is chosen once for each pattern
69		)
70	},
71		// The \delta key is used automatically for the spawner.wait() call
72	\delta, Pwhite(1, 4, inf) * 0.25
73)).play;
74)
75
76p.stop;
77::
78::
79
80Previous:	link::Tutorials/A-Practical-Guide/PG_06c_Composition_of_Patterns::
81
82Next:		link::Tutorials/A-Practical-Guide/PG_06e_Language_Control::
83