# «functors - Using Pdef for building abstract pattern functions while live coding» byjulian.rohrhuber

on 27 Sep'13 16:22 in

A simple example that shows of how to build higher-level patterns using Pdef

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
// For a long time I was thinking of what would be the best way to do this: function composition (functors) in live coding with patterns - it seems all in place anyway.

// some synthdef
(
SynthDef(\Pdefhelp, { arg out, freq, sustain=1, amp=1, pan;
var env, u=1;
env = EnvGen.kr(Env.perc(0.03, sustain), 1, doneAction:2);
3.do { var d; d = exprand(0.01, 1); u = SinOsc.ar(d * 300, u, rrand(0.1,1.2) * d, 1) };
Out.ar(out, Pan2.ar(SinOsc.ar(u + 1 * freq, 0, amp * env), pan));
)

Pdef(\stut, { Pstutter(~stutter ? 1, ~pattern) }); // this defines a function that maps one pattern to another.
Pdef(\x, Pbind(\instrument, \Pdefhelp, \note, Pseq([0, 4, 7, 3, 0, 1, 0], inf)));
Pdef(\y, Pdef(\stut) <> (pattern: Pdef(\x), stutter: Pseq([2, 2, 4, 3], inf)) <> (dur: 0.1, legato: 0.2)).play;
Pdef(\y, Pdef(\stut) <> (pattern: Pdef(\x), stutter: Pseq([2, 2, 4, 3], inf)) <> (dur: 0.1, legato: 0.2)).play;

// Up to a certain point, this also works for non-event-patterns:

// pattern as an argument
Pdefn(\x, Pseq([1, 2, 5, 6, 7], inf));
Pdefn(\x); // omitting the second argument, we can access the proxy
Pdefn(\x).asStream.nextN(20); // ... play one event stream
Pdefn(\x).source.postcs; // ... and inspect the event pattern itself.

// function as an argument, create a new pattern each time it is called
Pdefn(\x, { Pseq({ 10.rand } ! 8) });
Pn(Pdefn(\x)).asStream.nextN(16);

// the function is called in the incoming event as current environment, so parameters can be passed:
Pdef(\stut, { Pstutter(~stutter ? 1, ~pattern) }); // note that we use a Pdef here, not a Pdefn
Pdefn(\y, Pdef(\stut) <> (pattern: Pdefn(\x), stutter: Pseq([2, 2, 4, 3], inf))).asStream.nextN(16);

::
raw 1735 chars (focus & ctrl+a+c to copy)
reception