Hey all,
I’m experimenting with an external MIDI device for the first time. When I looked at the cues from my nanoKontrol2, I realized that there was basically a single MIDI event sent by the device, with different indexes for each button/knob/slider.
Are there any established patterns for working with such events? My go at it is below, any feedback? Had to up my Ruby game a bit. Is a live loop the right way to keep my controller ‘state’ up to date?
class Kontrol
def initialize
@slots = []
8.times do
@slots.push(KontrolSlot.new)
end
@buttons = []
5.times do
@buttons.push(KontrolButton.new)
end
end
attr_reader :slots, :buttons
end
class KontrolSlot
def initialize
@knob = 0
@slide = 0
end
attr_accessor :knob
attr_accessor :slide
end
class KontrolButton
def initialize
@pressed = false
@down = false
end
attr_reader :down
def push_down
@down = true
end
def release
@down = false
@pressed = true
end
# toggle off after checking
def was_pressed
was_pressed = @pressed
@pressed = false
was_pressed
end
end
kontrol = Kontrol.new
live_loop :control do
use_real_time
control_index, value = sync "/midi:nanokontrol2_slider_knob:1/control_change"
case control_index
when 0..7
slot = kontrol.slots[control_index]
slot.slide = value
when 16..23
slot = kontrol.slots[control_index-16]
slot.knob = value
when 41..45
button = kontrol.buttons[control_index-41]
if (value > 0)
button.push_down
else
button.release
end
end
end
live_loop :synth do
amp = kontrol.slots[0].slide/127.0 #between 0 and 1
pan = kontrol.slots[0].knob/63.5 - 1 #between -1 and 1
note = :d4
if (kontrol.buttons[0].down)
note = :e4
end
if (kontrol.buttons[1].was_pressed)
use_synth synth_names[rrand_i(0, 10)]
end
play note, amp: amp, pan: pan
sleep 1
end