// title: Hymn #15 - generative melody by array rewriting // author: madamdata // description: // This composition uses a task to read an array of durations and pitches. Every certain number of cycles, the functions scrambRand and octRand are called. scrambRand reverses a random sub-segment of the array. octRand randomly transposes a note up or down an octave. Every so often, all pitches are transposed according to the transp array. // // Two instances of this process are run simultaneously, one left and one right. // code: ( SynthDef(\ping, { arg freq = 440, pan = 0; var sig; sig = SinOsc.ar(freq, 0, 0.3); sig = sig * EnvGen.ar(Env.perc(0.01, 1), doneAction:2); sig = Pan2.ar(sig, pan); Out.ar(0, sig) }).add; ) ( ~scramb = {|pan| var notes = [0,4,7,14,9,12,4,7,9,7]; var dur = [1,1,2,3,6,3,4,5,2,1,13]; var transp = [0, 5, 7, 3, 2]; var scrambRand = {|array| var rand = rrand(0, array.size-3); var end = rand + rrand(1,2); var range = (rand..end); var reverseRange = range.reverse; var temp = array.copy; range.postln; range.do({|item, index| array[item] = temp[reverseRange[index]]; }); array; }; var octRand = {|array| var rand = rrand(0, array.size-1); array[rand] = array[rand] + [-12,0,12].choose; }; var task = Task { var step = 0; var transpStep = 0; loop { var freq = (notes.wrapAt(step) + 60 + transp.wrapAt(transpStep)).midicps; Synth(\ping, [\freq, freq, \pan, pan]); (dur.wrapAt(step) * 0.15).wait; step = step + 1 % (notes.size * 12;); if (step%32 == 0, {scrambRand.value(notes)}); if (step%20 == 0, {scrambRand.value(dur)}); if (step%66 == 0, {transpStep = transpStep + 1 % (transp.size)}); if (step%24 == 0, {notes = notes.rotate(rrand(-1, 1))}); if (step%56 ==0, {octRand.value(notes)}); } }.play; }; ) ( ~scramb.value(-0.7);~scramb.value(0.7); )