Created
November 12, 2017 16:28
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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