«pattern morphing» by grirgz

on 27 Jul'12 05:18 in patternmorphingevent

A pattern which do morphing between two event pattern (cross-fading synth arguments)

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
(
// example synthdef
SynthDef(\lead2, {	arg out=0, freq = 100, pan=0, amp=0.1, mdetune=1.004, gate=1, rq=0.1, fratio = 1, fbase=400, wet=1, fbfreq=100, fbamp=0.8, fbpamp=1, rt=0.4; 
	var fb, ou, filtenv;
	ou = LFSaw.ar(freq * [1, mdetune]).sum;
	filtenv = EnvGen.ar(Env.adsr(0.01,0.25,0.07,0.3), gate, freq * fratio, fbase, doneAction:0);
	ou = RLPF.ar(ou, filtenv, rq);
	fb = LocalIn.ar(1) + ou;
	fb = HPF.ar(fb, fbfreq);
	LocalOut.ar(fb * fbamp);
	fb = Limiter.ar(fb, amp);
	fb = SelectX.ar(wet, [ou, fb*fbpamp]);
	fb = fb * EnvGen.ar(Env.adsr(0.001,0.4,0.9,rt), gate, doneAction:2);
	fb = Pan2.ar(fb, pan, amp);
	Out.ar(out, fb);
}).store;
)

(
// event morphing
~morph = { arg ev_start, ev_end, time, repeat=1;
	var ev_res;

	if(ev_start.isArray) { ev_start = Event.newFrom(ev_start) };
	if(ev_end.isArray) { ev_end = Event.newFrom(ev_end) };

	ev_res = ();
	ev_start.keys.do { arg key;
		ev_res[key] = Pseg(Pseq([ev_start[key], ev_end[key]],repeat), time);
	};
	Pbind(*ev_res.asKeyValuePairs);
};

// pattern morphing
~morphpat = { arg pat1, pat2, mpat;
	var spat1, spat2, smpat;
	var ev1, ev2, morph;
	var res_ev;
	var rout;
	var exclu = Set[\dur, \instrument];
	spat1 = pat1.asStream;
	spat2 = pat2.asStream;
	smpat = mpat.asStream;
	rout = Routine {
		block { arg break;
			loop {
				ev1 = spat1.next(Event.default);
				ev2 = spat2.next(Event.default);
				morph = smpat.next;
				if(ev1.isNil or: { ev2.isNil or: { morph.isNil }}) { 
					break.value;
				} {
					res_ev = ();
					ev1.keys.difference(exclu).do { arg key;
						res_ev[key] = (ev1[key] * morph) + (ev2[key] * (1 - morph));
					};
					res_ev.debug("res_ev");
					res_ev.yield;
				}
			}
		}
	};
	rout
};

)

// we want to morph from this pattern
(
Pdef(\plop, Pbind(
	\instrument, \lead2,
	\degree, Pseq([0,2,4],inf),
	\fratio, 9,
	\sustain, 0.1,
	\wet, 0.8,
	\fbfreq, 4100,
	\fbpamp, 4,
	\rq, 0.2,
	\dur, 0.25,
	\amp, 0.1
)).play;
);

// to this pattern
(
Pdef(\plop, Pbind(
	\instrument, \lead2,
	\degree, Pseq([0,2,4],inf),
	\fratio, 2.4,
	\sustain, 0.21,
	\wet, 0.1,
	\fbfreq, 4180,
	\fbpamp, 1,
	\rq, 2.01,
	\dur, 0.25,
	\amp, 0.2
)).play;
);


(
// event morphing
Pdef(\plop, Pbind(
	\instrument, \lead2,
	\degree, Pseq([0,2,4,Prand([0,2,4,7,9,-5,-3])],inf),
	\mtranspose, Pstep(Pseq([0,3,1,4, 0,2,1,3],inf),2),
	//\mtranspose, Pstep(Pseq([0,2,1,3],inf),4),
	\dur, 0.25,
	\sustain, Pkey(\sustain) * 4,
	\amp, 0.1
) <> ~morph.([ // work also with event notation
	\fratio, 2.4,
	\sustain, 0.21,
	\wet, 0.1,
	\fbfreq, 180,
	\fbpamp, 1,
	\rq, 2.01,
], [
	\fratio, 9,
	\sustain, 0.1,
	\wet, 0.8,
	\fbfreq, 4800,
	\fbpamp, 4,
	\rq, 0.2,
], 10,inf)).play; // third argument: duration of the morphing, 4th argument: repeat
)


(
// pattern morphing
~pat1 = Pbind(
	\fratio, Pseq([10,2.4],inf),
	\sustain, 0.21,
	\wet, 0.1,
	\fbfreq, Pseq([4000,180],inf),
	\fbpamp, 1,
	\rq, 2.01,
);

~pat2 = Pbind(
	\fratio, 9,
	\sustain, 0.1,
	\wet, 0.8,
	\fbfreq, Pseq([200,4800],inf),
	\fbpamp, 4,
	\rq, 0.2,
);
p = ~morphpat.(~pat1, ~pat2, Pseg(Pseq([0, 1, 0.5],inf),10)); // third argument: 0 = first pattern, 1 = second pattern
(Pbind(
	\instrument,\lead2,
	\degree, Pseq([0,2,4,Prand([0,2,4,7,9,-5,-3])],inf),
	\mtranspose, Pstep(Pseq([0,3,1,4, 0,2,1,3],inf),2),
	\sustain, Pkey(\sustain) * 4,
	\dur, 0.25,
) <> p).trace.play;
)
raw 3455 chars (focus & ctrl+a+c to copy)
reception
comments