1 title:: PG_Cookbook06_Phrase_Network
2 summary:: Sequencing by a network of phrases, Articulating notes with PmonoArtic
3 related:: Tutorials/A-Practical-Guide/PG_Cookbook05_Using_Samples, Tutorials/A-Practical-Guide/PG_Cookbook07_Rhythmic_Variations
4 categories:: Streams-Patterns-Events>A-Practical-Guide
6 section::Sequencing by a network of phrases
7 section::Articulating notes with PmonoArtic
11 Most conventional synthesizers have a mode where playing a note while the previous note is still sustaining slides from one note to the other. The link::Classes/PmonoArtic:: pattern does this based on the event's sustain value. The delta value is the number of beats until the next event; sustain is the number of beats until the note releases. If sustain is shorter than delta, the note should cut off early and the next event should produce a new synth.
13 The example uses link::Classes/Pfsm:: (finite state machine) to arrange a set of predefined phrases in a partially randomized order. Each phrase is followed by a list pointing to the phrases that could legitimately follow the current phrase. That is, it might make musical sense to go from phrase 1 to phrase 2, but not from 1 to 3. Defining the successors for 1 appropriately makes sure that a nonsense transition will not be made.
15 This is a long example, but it's only because there are lots of phrases. The structure is very simple: just a set of phrases chosen in succession by Pfsm.
17 - strong::Third-party extension alert:: : In this example, the selection of the next phrase is explicitly weighted by repeating array elements, such as code::#[1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5]::. A more elegant way to do this is using the strong::WeighBag:: class in the strong::MathLib:: quark.
20 // the following are equivalent:
21 a = #[1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5];
22 ({ a.choose } ! 100).histo(5, 1, 5);
24 a = WeighBag.with((1..5), #[4, 2, 2, 2, 1]);
25 ({ a.wchoose } ! 100).histo(5, 1, 5);
32 // this SynthDef has a strong attack, emphasizing the articulation
33 SynthDef(\sawpulse, { |out, freq = 440, gate = 0.5, plfofreq = 6, mw = 0, ffreq = 2000, rq = 0.3, freqlag = 0.05, amp = 1|
34 var sig, plfo, fcurve;
35 plfo = SinOsc.kr(plfofreq, mul:mw, add:1);
36 freq = Lag.kr(freq, freqlag) * plfo;
37 fcurve = EnvGen.kr(Env.adsr(0, 0.3, 0.1, 20), gate);
38 fcurve = (fcurve - 1).madd(0.7, 1) * ffreq;
39 sig = Mix.ar([Pulse.ar(freq, 0.9), Saw.ar(freq*1.007)]);
40 sig = RLPF.ar(sig, fcurve, rq)
41 * EnvGen.kr(Env.adsr(0.04, 0.2, 0.6, 0.1), gate, doneAction:2)
48 TempoClock.default.tempo = 128/60;
50 // Pmul does only one thing here: take ~amp from each event
51 // and replace it with ~amp * 0.4
52 p = Pmul(\amp, 0.4, Pfsm([
53 #[0, 3, 1], // starting places
55 \midinote, Pseq([78, 81, 78, 76, 78, 76, 72, 71, 69, 66], 1),
56 \dur, Pseq(#[0.25, 1.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 1),
57 \sustain, Pseq(#[0.3, 1.2, 0.3, 0.2, 0.3, 0.2, 0.3, 0.2, 0.3, 0.2],1 ),
58 \amp, Pseq(#[1, 0.5, 0.75, 0.5, 0.75, 0.5, 0.75, 0.5, 0.75, 0.5], 1),
59 \mw, Pseq([0, 0.03, Pseq(#[0], inf)], 1)
63 \midinote, Pseq([64, 66, 69, 71, 72, 73], 1),
64 \dur, Pseq(#[0.25], 6),
65 \sustain, Pseq(#[0.3, 0.2, 0.2, 0.2, 0.3, 0.2], 1),
66 \amp, Pseq(#[1, 0.5, 0.5, 0.5, 0.5, 0.5], 1),
68 ), #[1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5],
71 \midinote, Pseq([69, 71, 69, 66, 64, 69, 71, 69], 1),
72 \dur, Pseq(#[0.125, 0.625, 0.25, 0.25, 0.25, 0.25, 0.25, 0.75], 1),
73 \sustain, Pseq(#[0.2, 0.64, 0.2, 0.2, 0.2, 0.3, 0.3, 0.75], 1),
74 \amp, Pseq(#[0.5, 0.75, 0.5, 0.5, 0.5, 1, 0.5, 0.5], 1),
76 ), #[0, 1, 1, 1, 1, 3, 3, 3, 3, 5],
79 \midinote, Pseq([72, 73, 76, 72, 71, 69, 66, 71, 69], 1),
80 \dur, Pseq(#[0.25, 0.25, 0.25, 0.083, 0.083, 0.084, 0.25, 0.25, 0.25], 1),
81 \sustain, Pseq(#[0.3, 0.2, 0.2, 0.1, 0.07, 0.07, 0.2, 0.3, 0.2], 1),
82 \amp, Pseq(#[1, 0.5, 0.5, 1, 0.3, 0.3, 0.75, 0.75, 0.5], 1),
84 ), #[1, 1, 1, 1, 3, 3, 4, 4, 4],
87 \midinote, Pseq([64, 66, 69, 71, 72, 73, 71, 69, 66, 71, 69, 66, 64, 69], 1),
88 \dur, Pseq(#[0.25, 0.25, 0.25, 0.25, 0.125, 0.375, 0.166, 0.166, 0.168,
89 0.5, 0.166, 0.166, 0.168, 0.5], 1),
90 \sustain, Pseq(#[0.3, 0.2, 0.2, 0.2, 0.14, 0.4, 0.2, 0.2, 0.2, 0.6, 0.2, 0.2, 0.2, 0.5],1),
91 \amp, Pseq(#[0.5, 0.5, 0.6, 0.8, 1, 0.5, 0.5, 0.5, 0.5, 1,
92 0.5, 0.5, 0.5, 0.45], 1),
94 ), #[0, 1, 1, 1, 1, 3, 3, 5],
97 \midinote, Pseq([72, 73, 76, 78, 81, 78, 83, 81, 84, 85], 1),
98 \dur, Pseq(#[0.25, 0.25, 0.25, 0.25, 0.5, 0.5, 0.5, 0.5, 0.125, 1.125], 1),
99 \sustain, Pseq(#[0.3, 0.2, 0.2, 0.2, 0.95, 0.25, 0.95, 0.25, 0.2, 1.13], 1),
100 \amp, Pseq(#[0.7, 0.5, 0.5, 0.5, 0.7, 0.5, 0.8, 0.5, 1, 0.5], 1),
101 \mw, Pseq([Pseq(#[0], 9), 0.03], 1)
102 ), #[6, 6, 6, 8, 9, 10, 10, 10, 10, 11, 11, 13, 13],
104 PmonoArtic(\sawpulse,
105 \midinote, Pseq([83, 81, 78, 83, 81, 78, 76, 72, 73, 78, 72, 72, 71], 1),
106 \dur, Pseq(#[0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
108 \sustain, Pseq(#[0.3, 0.3, 0.2, 0.3, 0.3, 0.3, 0.2, 0.3, 0.2, 0.3, 0.2, 0.3, 2], 1),
109 \amp, Pseq(#[0.5, 0.5, 0.5, 0.8, 0.5, 0.5, 0.5, 0.8, 0.5, 0.8, 0.5,
111 \mw, Pseq([Pseq([0], 12), 0.03], 1)
112 ), #[0, 7, 7, 7, 7, 7, 3, 3, 3, 3],
114 PmonoArtic(\sawpulse,
115 \midinote, Pseq([69, 71, 72, 71, 69, 66, 64, 69, 71], 1),
116 \dur, Pseq(#[0.25, 0.25, 0.25, 0.25, 0.166, 0.167, 0.167, 0.25, 0.25], 1),
117 \sustain, Pseq(#[0.2, 0.2, 0.3, 0.2, 0.2, 0.2, 0.14, 0.3, 0.2], 1),
118 \amp, Pseq(#[0.5, 0.5, 0.8, 0.5, 0.5, 0.5, 0.5, 0.8, 0.5], 1)
119 ), #[3, 3, 3, 4, 4, 5],
121 PmonoArtic(\sawpulse,
122 \midinote, Pseq([84, 85, 84, 84, 88, 84, 83, 81, 83, 81, 78, 76, 81, 83], 1),
123 \dur, Pseq(#[0.125, 0.535, 0.67, 1.92, 0.25, 0.166, 0.167, 0.167,
124 0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 1),
125 \sustain, Pseq(#[0.2, 3.12, 0.2, 0.2, 0.2, 0.2, 0.2, 0.15, 0.3, 0.2, 0.2, 0.2,
127 \amp, Pseq(#[1, 0.8, 0.8, 0.8, 1, 1, 0.8, 0.8, 1, 0.8, 0.8, 0.8,
129 \mw, Pseq([0, 0.005, 0.005, 0.06, Pseq(#[0], 10)], 1)
130 ), #[10, 10, 10, 11, 11, 11, 11, 12, 12, 12],
133 PmonoArtic(\sawpulse,
134 \midinote, Pseq(([64, 66, 69, 71, 72, 73, 71, 69, 66, 71, 69, 66, 64, 69]+12), 1),
135 \dur, Pseq(#[0.25, 0.25, 0.25, 0.25, 0.125, 0.375, 0.166, 0.166, 0.168,
136 0.5, 0.166, 0.166, 0.168, 0.5], 1),
137 \sustain, Pseq(#[0.3, 0.2, 0.2, 0.2, 0.14, 0.4, 0.2, 0.2, 0.2, 0.6, 0.2, 0.2, 0.2, 0.5],1),
138 \amp, Pseq(#[0.5, 0.5, 0.6, 0.8, 1, 0.5, 0.5, 0.5, 0.5, 1,
139 0.5, 0.5, 0.5, 0.45], 1),
141 ), #[11, 11, 11, 11, 11, 12, 12],
143 PmonoArtic(\sawpulse,
144 \midinote, Pseq([81, 84, 83, 81, 78, 76, 81, 83], 1),
145 \dur, Pseq(#[0.25], 8),
146 \sustain, Pseq(#[0.2, 0.3, 0.3, 0.2, 0.3, 0.2, 0.3, 0.2], 1),
147 \amp, Pseq(#[0.5, 1, 0.5, 0.5, 0.6, 0.5, 0.8, 0.5], 1),
149 ), #[0, 9, 9, 11, 11, 12, 12, 12, 12, 12],
152 PmonoArtic(\sawpulse,
153 \midinote, Pseq(([64, 66, 69, 71, 72, 73]+12), 1),
154 \dur, Pseq(#[0.25], 6),
155 \sustain, Pseq(#[0.3, 0.2, 0.2, 0.2, 0.3, 0.2], 1),
156 \amp, Pseq(#[1, 0.5, 0.5, 0.5, 0.5, 0.5], 1),
158 ), #[6, 6, 8, 9, 9, 9, 9, 10, 10, 10, 10, 13, 13, 13],
160 PmonoArtic(\sawpulse,
161 \midinote, Pseq([78, 81, 83, 78, 83, 84, 78, 84, 85], 1),
162 \dur, Pseq(#[0.25, 0.25, 0.5, 0.25, 0.25, 0.5, 0.25, 0.25, 1.75], 1),
163 \sustain, Pseq(#[0.2, 0.3, 0.2, 0.2, 0.3, 0.2, 0.2, 0.3, 1.75], 1),
164 \amp, Pseq(#[0.4, 0.8, 0.5, 0.4, 0.8, 0.5, 0.4, 1, 0.8], 1),
165 \mw, Pseq([Pseq([0], 8), 0.03], 1)
168 PmonoArtic(\sawpulse,
169 \midinote, Pseq([88, 84, 83, 81, 83, 81, 78, 76, 81, 83], 1),
170 \dur, Pseq(#[0.25, 0.166, 0.167, 0.167,
171 0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 1),
172 \sustain, Pseq(#[0.2, 0.2, 0.2, 0.15, 0.3, 0.2, 0.2, 0.2,
174 \amp, Pseq(#[1, 1, 0.8, 0.8, 1, 0.8, 0.8, 0.8,
184 Previous: link::Tutorials/A-Practical-Guide/PG_Cookbook05_Using_Samples::
186 Next: link::Tutorials/A-Practical-Guide/PG_Cookbook07_Rhythmic_Variations::