1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
|
title:: Pattern Guide Cookbook 06: Phrase Network
summary:: Sequencing by a network of phrases, Articulating notes with PmonoArtic
related:: Tutorials/A-Practical-Guide/PG_Cookbook05_Using_Samples, Tutorials/A-Practical-Guide/PG_Cookbook07_Rhythmic_Variations
categories:: Streams-Patterns-Events>A-Practical-Guide
section::Sequencing by a network of phrases
section::Articulating notes with PmonoArtic
Two for one here!
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.
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.
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.
- 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.
code::
// the following are equivalent:
a = #[1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5];
({ a.choose } ! 100).histo(5, 1, 5);
a = WeighBag.with((1..5), #[4, 2, 2, 2, 1]);
({ a.wchoose } ! 100).histo(5, 1, 5);
::
subsection::Example
code::
(
// this SynthDef has a strong attack, emphasizing the articulation
SynthDef(\sawpulse, { |out, freq = 440, gate = 0.5, plfofreq = 6, mw = 0, ffreq = 2000, rq = 0.3, freqlag = 0.05, amp = 1|
var sig, plfo, fcurve;
plfo = SinOsc.kr(plfofreq, mul:mw, add:1);
freq = Lag.kr(freq, freqlag) * plfo;
fcurve = EnvGen.kr(Env.adsr(0, 0.3, 0.1, 20), gate);
fcurve = (fcurve - 1).madd(0.7, 1) * ffreq;
sig = Mix.ar([Pulse.ar(freq, 0.9), Saw.ar(freq*1.007)]);
sig = RLPF.ar(sig, fcurve, rq)
* EnvGen.kr(Env.adsr(0.04, 0.2, 0.6, 0.1), gate, doneAction: Done.freeSelf)
* amp;
Out.ar(out, sig ! 2)
}).add;
)
(
TempoClock.default.tempo = 128/60;
// Pmul does only one thing here: take ~amp from each event
// and replace it with ~amp * 0.4
p = Pmul(\amp, 0.4, Pfsm([
#[0, 3, 1], // starting places
PmonoArtic(\sawpulse,
\midinote, Pseq([78, 81, 78, 76, 78, 76, 72, 71, 69, 66], 1),
\dur, Pseq(#[0.25, 1.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 1),
\sustain, Pseq(#[0.3, 1.2, 0.3, 0.2, 0.3, 0.2, 0.3, 0.2, 0.3, 0.2],1 ),
\amp, Pseq(#[1, 0.5, 0.75, 0.5, 0.75, 0.5, 0.75, 0.5, 0.75, 0.5], 1),
\mw, Pseq([0, 0.03, Pseq(#[0], inf)], 1)
), #[1, 2, 3, 4, 7],
PmonoArtic(\sawpulse,
\midinote, Pseq([64, 66, 69, 71, 72, 73], 1),
\dur, Pseq(#[0.25], 6),
\sustain, Pseq(#[0.3, 0.2, 0.2, 0.2, 0.3, 0.2], 1),
\amp, Pseq(#[1, 0.5, 0.5, 0.5, 0.5, 0.5], 1),
\mw, 0
), #[1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5],
PmonoArtic(\sawpulse,
\midinote, Pseq([69, 71, 69, 66, 64, 69, 71, 69], 1),
\dur, Pseq(#[0.125, 0.625, 0.25, 0.25, 0.25, 0.25, 0.25, 0.75], 1),
\sustain, Pseq(#[0.2, 0.64, 0.2, 0.2, 0.2, 0.3, 0.3, 0.75], 1),
\amp, Pseq(#[0.5, 0.75, 0.5, 0.5, 0.5, 1, 0.5, 0.5], 1),
\mw, 0
), #[0, 1, 1, 1, 1, 3, 3, 3, 3, 5],
PmonoArtic(\sawpulse,
\midinote, Pseq([72, 73, 76, 72, 71, 69, 66, 71, 69], 1),
\dur, Pseq(#[0.25, 0.25, 0.25, 0.083, 0.083, 0.084, 0.25, 0.25, 0.25], 1),
\sustain, Pseq(#[0.3, 0.2, 0.2, 0.1, 0.07, 0.07, 0.2, 0.3, 0.2], 1),
\amp, Pseq(#[1, 0.5, 0.5, 1, 0.3, 0.3, 0.75, 0.75, 0.5], 1),
\mw, 0
), #[1, 1, 1, 1, 3, 3, 4, 4, 4],
PmonoArtic(\sawpulse,
\midinote, Pseq([64, 66, 69, 71, 72, 73, 71, 69, 66, 71, 69, 66, 64, 69], 1),
\dur, Pseq(#[0.25, 0.25, 0.25, 0.25, 0.125, 0.375, 0.166, 0.166, 0.168,
0.5, 0.166, 0.166, 0.168, 0.5], 1),
\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),
\amp, Pseq(#[0.5, 0.5, 0.6, 0.8, 1, 0.5, 0.5, 0.5, 0.5, 1,
0.5, 0.5, 0.5, 0.45], 1),
\mw, 0
), #[0, 1, 1, 1, 1, 3, 3, 5],
PmonoArtic(\sawpulse,
\midinote, Pseq([72, 73, 76, 78, 81, 78, 83, 81, 84, 85], 1),
\dur, Pseq(#[0.25, 0.25, 0.25, 0.25, 0.5, 0.5, 0.5, 0.5, 0.125, 1.125], 1),
\sustain, Pseq(#[0.3, 0.2, 0.2, 0.2, 0.95, 0.25, 0.95, 0.25, 0.2, 1.13], 1),
\amp, Pseq(#[0.7, 0.5, 0.5, 0.5, 0.7, 0.5, 0.8, 0.5, 1, 0.5], 1),
\mw, Pseq([Pseq(#[0], 9), 0.03], 1)
), #[6, 6, 6, 8, 9, 10, 10, 10, 10, 11, 11, 13, 13],
PmonoArtic(\sawpulse,
\midinote, Pseq([83, 81, 78, 83, 81, 78, 76, 72, 73, 78, 72, 72, 71], 1),
\dur, Pseq(#[0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
0.25, 2], 1),
\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),
\amp, Pseq(#[0.5, 0.5, 0.5, 0.8, 0.5, 0.5, 0.5, 0.8, 0.5, 0.8, 0.5,
1, 0.4], 1),
\mw, Pseq([Pseq([0], 12), 0.03], 1)
), #[0, 7, 7, 7, 7, 7, 3, 3, 3, 3],
PmonoArtic(\sawpulse,
\midinote, Pseq([69, 71, 72, 71, 69, 66, 64, 69, 71], 1),
\dur, Pseq(#[0.25, 0.25, 0.25, 0.25, 0.166, 0.167, 0.167, 0.25, 0.25], 1),
\sustain, Pseq(#[0.2, 0.2, 0.3, 0.2, 0.2, 0.2, 0.14, 0.3, 0.2], 1),
\amp, Pseq(#[0.5, 0.5, 0.8, 0.5, 0.5, 0.5, 0.5, 0.8, 0.5], 1)
), #[3, 3, 3, 4, 4, 5],
PmonoArtic(\sawpulse,
\midinote, Pseq([84, 85, 84, 84, 88, 84, 83, 81, 83, 81, 78, 76, 81, 83], 1),
\dur, Pseq(#[0.125, 0.535, 0.67, 1.92, 0.25, 0.166, 0.167, 0.167,
0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 1),
\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,
0.3, 0.2], 1),
\amp, Pseq(#[1, 0.8, 0.8, 0.8, 1, 1, 0.8, 0.8, 1, 0.8, 0.8, 0.8,
1, 0.8], 1),
\mw, Pseq([0, 0.005, 0.005, 0.06, Pseq(#[0], 10)], 1)
), #[10, 10, 10, 11, 11, 11, 11, 12, 12, 12],
// same as #4, 8va
PmonoArtic(\sawpulse,
\midinote, Pseq(([64, 66, 69, 71, 72, 73, 71, 69, 66, 71, 69, 66, 64, 69]+12), 1),
\dur, Pseq(#[0.25, 0.25, 0.25, 0.25, 0.125, 0.375, 0.166, 0.166, 0.168,
0.5, 0.166, 0.166, 0.168, 0.5], 1),
\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),
\amp, Pseq(#[0.5, 0.5, 0.6, 0.8, 1, 0.5, 0.5, 0.5, 0.5, 1,
0.5, 0.5, 0.5, 0.45], 1),
\mw, 0
), #[11, 11, 11, 11, 11, 12, 12],
PmonoArtic(\sawpulse,
\midinote, Pseq([81, 84, 83, 81, 78, 76, 81, 83], 1),
\dur, Pseq(#[0.25], 8),
\sustain, Pseq(#[0.2, 0.3, 0.3, 0.2, 0.3, 0.2, 0.3, 0.2], 1),
\amp, Pseq(#[0.5, 1, 0.5, 0.5, 0.6, 0.5, 0.8, 0.5], 1),
\mw, 0
), #[0, 9, 9, 11, 11, 12, 12, 12, 12, 12],
// same as #1, 8va
PmonoArtic(\sawpulse,
\midinote, Pseq(([64, 66, 69, 71, 72, 73]+12), 1),
\dur, Pseq(#[0.25], 6),
\sustain, Pseq(#[0.3, 0.2, 0.2, 0.2, 0.3, 0.2], 1),
\amp, Pseq(#[1, 0.5, 0.5, 0.5, 0.5, 0.5], 1),
\mw, 0
), #[6, 6, 8, 9, 9, 9, 9, 10, 10, 10, 10, 13, 13, 13],
PmonoArtic(\sawpulse,
\midinote, Pseq([78, 81, 83, 78, 83, 84, 78, 84, 85], 1),
\dur, Pseq(#[0.25, 0.25, 0.5, 0.25, 0.25, 0.5, 0.25, 0.25, 1.75], 1),
\sustain, Pseq(#[0.2, 0.3, 0.2, 0.2, 0.3, 0.2, 0.2, 0.3, 1.75], 1),
\amp, Pseq(#[0.4, 0.8, 0.5, 0.4, 0.8, 0.5, 0.4, 1, 0.8], 1),
\mw, Pseq([Pseq([0], 8), 0.03], 1)
), #[8, 13, 13],
PmonoArtic(\sawpulse,
\midinote, Pseq([88, 84, 83, 81, 83, 81, 78, 76, 81, 83], 1),
\dur, Pseq(#[0.25, 0.166, 0.167, 0.167,
0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 1),
\sustain, Pseq(#[0.2, 0.2, 0.2, 0.15, 0.3, 0.2, 0.2, 0.2,
0.3, 0.2], 1),
\amp, Pseq(#[1, 1, 0.8, 0.8, 1, 0.8, 0.8, 0.8,
1, 0.8], 1),
\mw, 0
), #[10]
], inf)).play;
)
p.stop;
::
Previous: link::Tutorials/A-Practical-Guide/PG_Cookbook05_Using_Samples::
Next: link::Tutorials/A-Practical-Guide/PG_Cookbook07_Rhythmic_Variations::
|