Mahalo Sonic Pilots!
Thought that I would report in on my current progress with an Idea I had to program a simple sequencer with Sonic Pi and my 8x8 Monome.
The end goal was to be able to program some beats from here (apologies for profanity in the url - not mine):
with this in mind I wanted the top 2 rows to be an “sample select” the next 2 to be an indicator of where the current step is and the next 2 rows to toggle the step on or off.
Results below - I can successfully program a basic “Boots and cats” 16 bar beat using the 3 sample and add more trivially.
Clearly none of this would have been possible without the amazing (and much more fully featured libraries) shared by @Martin here that I grokked my way through and lifted large sections of:
# Welcome to Sonic Pi
use_osc "localhost", 11117
#Initialise Variables to Hold Monome and track state
pages = []
page0 = [ [0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]]
pages.push(page0)
#Lookup to convert button index to BCD
lookup = [1,2,4,8,16,32,64,128]
set :pages, pages
set :active_sound, 0
#Update Grid Lights with active sound selection, step number and sequence value
define :update_grid do
active = get :active_sound
##| pages = get :pages
p = pages[0]
#Clear entire Monome before resetting
osc "/monome/grid/led/all",0
#Show active Sample
x,y = n2c(active)
#Rows 4 and 5 to show sequence steps that are active
row1 = p[active][0]
row2 = p[active][1]
#Very ugly conversion from array values to row values
puts p[active][0].to_s(2).rjust(8,'0').reverse + p[active][1].to_s(2).rjust(8,'0').reverse
puts (bools (p[active][0].to_s(2).rjust(8,'0').reverse + p[active][1].to_s(2).rjust(8,'0').reverse).chars)
osc "/monome/grid/led/set",x,y,1
osc "/monome/grid/led/row",0,4,row1
osc "/monome/grid/led/row",0,5,row2
end
define :page_set do | sound, line, s, page = 0 |
p = pages[page]
p[sound][line] = s
pages[page] = p
puts "---------------------- Page: #{p} --------------"
puts "---------------------- Pages: #{pages} --------------"
set :pages, pages
end
define :page_all do | s, page = 0 |
p = []
15.times do
p.push(s)
end
pages[page] = p
set :pages, pages
end
define :pages_print do
get(:pages).length.times do | p |
row = ""
puts "Page #{p}: ----------------"
get(:pages)[0].length.times do | y |
row += get(:pages)[p][y].to_s
puts get(:pages)[p][y].to_s
end
puts "------------------------"
end
end
define :c2n do | x, y |
num = x.to_i + 8 * y.to_i
return num
end
define :n2c do | n |
x = n % 8
y = n / 8
coords = [x.to_i, y.to_i]
return coords
end
live_loop :listen_monome do
use_real_time
x, y, s = sync "/osc:127.0.0.1:11117/monome/grid/key"
pressed = c2n(x, y)
if s == 1
case pressed
when 0
page_init(0)
when 1..15
set :active_sound, pressed
update_grid
when 32..39
value = lookup[x]
active = get(:active_sound)
p = pages[0]
puts p
old_value = p[active][0]
puts old_value
puts "Bitwise: " + (old_value & value).to_s
if (old_value & value) == 0
puts "ADDED !!!"
page_set(active,0,old_value+value)
pages[0] =p
set :pages, pages
puts pages_print
update_grid
else
puts "REMOVED !!!"
page_set(active,0,old_value-value)
pages[0] =p
set :pages, pages
puts pages_print
update_grid
end
when 40..47
value = lookup[x]
active = get(:active_sound)
puts value
p = pages[0]
puts p
old_value = p[active][1]
puts old_value
puts "Bitwise: " + (old_value & value).to_s
if (old_value & value) == 0
puts "ADDED !!!"
page_set(active,1,old_value+value)
puts pages_print
update_grid
else
puts "REMOVED !!!"
page_set(active,1,old_value-value)
puts pages_print
update_grid
end
end
end
end
define :pattern do |pattern|
return pattern.ring.look == "1"
end
live_loop :play_stuff do
#Play the samples if the patterns are active
x,y = n2c(look)
patterns = []
get(:pages).length.times do | p |
get(:pages)[0].length.times do | y |
patterns.push(get(:pages)[p][y][0].to_s(2).rjust(8,'0').reverse + get(:pages)[p][y][1].to_s(2).rjust(8,'0').reverse)
end
end
sample :drum_bass_hard if pattern patterns[2]
sample :sn_generic if pattern patterns[3]
sample :hat_snap if pattern patterns[4]
osc "/monome/grid/led/set",x,y+2,1
if look == 15
tick_reset
end
tick
sleep 0.125
osc "/monome/grid/led/set",x,y+2,0
end