Skip to content

Instantly share code, notes, and snippets.

@amiika
Created April 8, 2021 20:51
Show Gist options
  • Save amiika/09229279a7f4e684926282f846a5b0b2 to your computer and use it in GitHub Desktop.
Save amiika/09229279a7f4e684926282f846a5b0b2 to your computer and use it in GitHub Desktop.
Cellular automaton version that changes only one note per loop
# https://in-thread.sonic-pi.net/t/self-modifying-algorithms/5360/21
use_debug false
generations = {
:gen1=>{:cells=>[0, 0, 1, 0, 0, 0, 0, 1, 1]},
:gen2=>{:cells=>[1, 0, 0, 0, 1, 0, 0, 0, 0]}
}
define :create_ruleset do |n|
rules = Hash.new
return rules if n > 255
binary = "%08b" % n
8.times do |i|
key = "%03b" % i
rules[key] = binary[7-i].to_i
end
return rules
end
rule_110 = create_ruleset 110
rule_150 = create_ruleset 150
define :cells do |gen|
generations[gen][:cells]
end
define :store_state do |gen|
generations[gen][:last] = generations[gen][:cells].dup # dup to create new object
end
define :mutate do |rule, gen, i|
store_state gen if i == 0 # Store state in first cycle
cells = generations[gen][:cells]
last_gen = generations[gen][:last]
left = i > 0 ? i - 1 : cells.length - 1;
right = i < cells.length - 1 ? i + 1 : 0;
pattern = "#{last_gen[left]}#{last_gen[i]}#{last_gen[right]}";
cells[i] = rule[pattern]
end
use_synth :pluck
use_synth_defaults release: 1.5, coef: 0.4
with_fx :reverb, mix: 0.4 do
with_fx :flanger, wave: 3, depth: 7, decay: 1.5 do
live_loop :organism_1 do
print cells(:gen1)
cells(:gen1).each_with_index do |s,i|
play (degree i+1, :d, :dorian), pan: rrand(-0.5, 0.5) if s==1
sleep 0.25
end
mutate(rule_110, :gen1, tick%cells(:gen1).length)
end
live_loop :organism_2 do
print cells(:gen2)
cells(:gen2).each_with_index do |s,i|
play (degree i+1, :d3, :dorian), pan: rrand(-0.5, 0.5) if s==1
sleep 0.25
end
mutate(rule_150, :gen2, tick%cells(:gen2).length)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment