«Molecular music box» by grirgz

on 27 Aug'14 18:31 in patterngenerativemolecular

Inspired by this post http://www.kimri.org/blog/?p=487 I rewritten the algo to use more the patterns, so it's generated on the fly and it's easy to customize it =)

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
(
	TempoClock.default.tempo = 1;
	
	Pbind(
		\index, Pseq((0..15),inf),
		\dur, 1/4,
		\octave, 4,
		\do, Prout({ arg ev;
			var degstr = Pseq((0..24)).asStream; // degrees
			var lenstr = Pseq([4,3],inf).asStream; // note length
			var buf = Array.fill(16,{List.new}); // record loop buffer
			var deg, len;

			len = lenstr.next;

			inf.do { 

				var i = ev[\index];
				var n = buf[i];

				if(n.size != 0) {
					// previous note found, change note length
					len = lenstr.next;
				};

				deg = degstr.next;
				n.add([deg, len]);

				len.do {
					var i = ev[\index];
					var n = buf[i];

					if(n.size != 0) {
						ev[\degree] = n.flop[0];
						ev[\legato] = n.flop[1];
					} {
						ev[\isRest] = true;
					};
					ev = deg.yield;
				};
			}
		}),
	).trace.play
)

(
// change the rules a bit
	
Pdef(\mol,
	Pbind(
		\index, Pseq((0..15),inf),
		\dur, 1/4,
		//\root, Pseq([2,0],inf),
		\mtranspose, Pseq([0,3,4,3],inf).stutter(8),
		\octave, 4,
		\scale, Scale.dorian,
		\do, Prout({ arg ev;
			var degstr = Pseq((0..13),inf).asStream;
			var lenstr = Pseq([3,8,2],inf).asStream;
			var buf = Array.fill(16,{List.new});
			var keep = 3; // max note per chord
			var deg, len;

			len = lenstr.next;

			inf.do { 

				var i = ev[\index];
				var n;
				buf[i] = buf[i].keep(0-keep);
				n = buf[i];

				if(n.size != 0) {
					// previous note found, change note length
					len = lenstr.next;
				};

				deg = degstr.next;
				n.add([deg, len]);

				len.do {
					var i = ev[\index];
					var n = buf[i];

					if(n.size != 0) {
						ev[\degree] = n.flop[0];
						ev[\legato] = n.flop[1]/2;
						//ev[\legato] = 1;
					} {
						ev[\isRest] = true;
					};
					ev = deg.yield;
				};
			}
		}),
	).trace
).play;
)
raw 1838 chars (focus & ctrl+a+c to copy)
reception
comments
grirgz user 26 Sep'17 20:12

Here is the explanation of the modifications I made in the second version:

Instead of changing from length 3 to 4, I change from 3 to 8 then 2 :

var lenstr = Pseq([3,8,2],inf).asStream;

instead of walking on two octaves, i walk only on the 14 first notes

var degstr = Pseq((0..13),inf).asStream;

I noticed that with some rules, there can be a lot of note playing a the same time, which is not so beautiful. So I keep only 3 notes, if there is a note added, I discard the oldest

var keep = 3; // max note per chord buf[i] = buf[i].keep(0-keep);

keep(-3) mean keep the last 3 item of the array

then for fun, I've changed the scale

\scale, Scale.dorian,

and added a cyclic modal transposition pattern (shift the note each 8 beat)

\mtranspose, Pseq([0,3,4,3],inf).stutter(8),