Skip to content

Instantly share code, notes, and snippets.

@tomekr
Created November 12, 2017 16:28
Show Gist options
  • Save tomekr/e614656861592bb93e98523ec2ad4e3a to your computer and use it in GitHub Desktop.
Save tomekr/e614656861592bb93e98523ec2ad4e3a to your computer and use it in GitHub Desktop.
Sonic Pi code that uses Wolfram's Rule 30 1D Cellular Automaton to generate a melody+rhythm
x = "/Users/Dev/sonic_pi/Music Hack/samples/Fluteloop.wav"
def converter(desired, original)
output = (2 ** ((desired - original) / 12.0)) / 2
end
class Chord
def initialize(key, root, custom = false)
modes = [[0, 2, 4, 5, 7, 9, 11],
[0, 2, 3, 5, 7, 9, 10],
[0, 1, 3, 5, 7, 8, 10],
[0, 2, 4, 6, 7, 8, 11],
[0, 2, 4, 5, 7, 9, 10],
[0, 2, 3, 5, 7, 8, 10],
[0, 1, 3, 5, 6, 8, 10]
]
if !!custom
mode = custom
else
mode = modes[modes[0].find_index((root - key) % 12)]
end
@bass = [root - 12, root]
@tenor = [12 + root,
12 + root + mode[2],
12 + root + mode[4]
]
@alto = [24 + root,
24 + root + mode[2],
24 + root + mode[4]
]
@soprano = [24 + root + mode[6],
36 + root + mode[1],
36 + root + mode[2]
]
end
def bass
@bass
end
def tenor
@tenor
end
def alto
@alto
end
def soprano
@soprano
end
end
$rules = { '111' => 0, '110' => 0, '101' => 0, '100' => 1,
'011' => 1, '010' => 1, '001' => 1, '000' => 0}
triggers = [0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1]
def nextGeneration(last)
result = []
for idx in (0...last.length)
leftIdx = idx > 0 ? idx - 1 : last.length - 1;
rightIdx = idx < last.length - 1 ? idx + 1 : 0;
key = "#{last[leftIdx]}#{last[idx]}#{last[rightIdx]}";
print("Key is: " + key + "\n");
result[idx] = $rules[key];
end
return result;
end
chord_sequence = [0, 0, 3, 0, 4, 0, 4, 0, 3, 4, 3, 2, 3, 4, 3, 4, 2, 4, 0, 2, 4, 5, 4, 4, 0, 4, 0, 4, 4, 0, 3, 4, 4, 0, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 3, 0, 2, 2, 0, 2, 2, 4, 2, 4, 4, 4, 0, 4, 0, 4, 0, 4, 0]
chords = [Chord.new(40, 40), Chord.new(40,47), Chord.new(40, 45), Chord.new(40, 42), Chord.new(40, 37), Chord.new(40, 44)]
n = 0
m = 0
with_fx :reverb do |r|
control r, room: 1, damp: 0.1
loop do
c = chords[chord_sequence[n % chord_sequence.length]]
sample x, rate: converter(c.bass[m], 52), sustain: 0, release: 4
m = (m + 1) % 2
sleep 2
note_array = c.tenor + c.alto + c.soprano
3.times do
9.times do |t|
if triggers[t] == 0
sample x, rate: converter(note_array[t], 52), release: 0, sustain: 0.25, amp: 0.4, attack: 0.25
end
end
sleep 0.5
triggers = nextGeneration(triggers)
end
sleep 0.5
n += 1
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment