«Markov Chain Experiment II» by Jacob Joaquin

on 25 Aug'11 09:26 in markov chain

A simple melody algorithmically generated with a Markov Chain.

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
/* Markov Chain Experiment II
   Jacob Joaquin

   Get a visual representation of the Markov Chain here:
   http://codehop.com/supercollider-markov-chain/
*/

(
// Synthesizer
SynthDef(\my_synth, {|dur = 1.0, amp = 1.0, freq = 440|
	var env = EnvGen.ar(Env.new([1, 0.1, 0], [0.06, dur - 0.06]), doneAction: 2);
	Out.ar([0, 1], SinOsc.ar([freq * 0.995, freq * 1.005], 0, env * amp))
}).add;		

// Create task
t = Task({
	// Set attributes of each node
	// [freq, dur, [[next_state, weighted_random],…]]
	var node_list = [
		[60, 1, [[1, 2]]],
		[62, 0.5, [[0, 1], [2, 1]]],
		[63, 1, [[0, 1], [3, 1]]],
		[65, 0.5, [[0, 1], [3, 4], [4, 1]]],
		[67, 1, [[5, 1]]],
		[70, 1.5, [[4, 1], [6, 2]]],
		[69, 1, [[4, 1], [7, 2]]],
		[72, 0.5, [[4, 1], [7, 4], [0, 2]]]
	];

	var node_index = 0;
	var bps = 133.0 / 60.0;  // Beats per second
	
	inf.do({
		var weight = 0;
		var random;
		var accumulator;
		var node = node_list[node_index];		
		var freq = node[0].midicps;
		var dur = node[1] / bps;
		var paths = node[2];
		
		// Get total statistical weight of connected nodes
		(0 .. paths.size - 1).do {|i| weight = weight + paths[i][1]};
		
		// Generate random value for choosing next node
		random = weight.rand;

		// Choose next node based on statistical weights
		accumulator = paths[0][1];
				
		node_index = block {|break|
			paths.size.do {|i|
				if ((random < accumulator), {
					break.value(paths[i][0])
				}, {
					accumulator = accumulator + paths[i + 1][1]					
				})
			}
		};
		
		// Play
		Synth(\my_synth, [\dur, dur, \amp, -3.dbamp, \freq, freq]);					
		dur.wait;
	})
});

t.start;
)
descendants
«vicodin» by anonymous (private)
«Chrgaurrip» by anonymous (private)
full graph
raw 1670 chars (focus & ctrl+a+c to copy)
reception
comments