Having learnt SPi I’ve been happily using it as the main way of making and playing BTs for live work. I’ve shied away from controlling them via MIDI, opting to use the coding interface as Sam our leader intended
That said, I’ve got such a repeatable pattern now I thought I’d give it a look. I have a useful device the Akai Midimix which has lots of buttons, knobs and faders. I’m thinking the system as a more like a hardwre device.
I thought I’d share my code for using this. In one buffer I have the following code, which runs two live loops to pick up knob changes and toggle buttons. They set values using the set
function. Then some utility functions: iscc() cc() trackvol()
that I can use in my music loops to pick up volumes and switch loops on and off.
live_loop :midiccin do
use_real_time
n,v=sync "/midi*/control_change"
set "cc_"+n.to_s,v
end
live_loop :midicctoggle do
use_real_time
n,v=sync "/midi*/control_change"
s = "cc_toggle_"+n.to_s
x=get[s]
x=1 if x==nil
if v==127 and n>0 and n<25
if x==0
x=1
else
x=0
end
set s,x
puts s,x
end
end
define :iscc do |n|
x=get["cc_toggle_"+n.to_s]
x==nil or x==1
end
define :cc do |n,min,max,default|
v=get["cc_"+n.to_s]
if v==nil
x=default
else
x=min+(v/128.0)*(max-min)
end
puts "cc "+n.to_s + "," + x.to_s
x
end
define :trackvol do |n|
case n
when 1
button=1
fader=19
when 2
button=4
fader=23
when 3
button=7
fader=27
when 4
button=10
fader=31
end
v=0
if iscc(button)
v=cc(fader,0.0,1.0,0.0)
end
puts "trackvol "+n.to_s+" "+v.to_s
v
end
Here’s an example applied to a drum machine, where the sounds are assigned to ‘tracks’ 1-4, each of which can be toggled on/off, and the volume modified with a fader.
#Drumkit V14
#With CC track controls
use_bpm 80
live_loop :drumtest do
#stop
#midiclock 4
set :trigdrum, tick
sleep 4
end
live_loop :drums do
n=sync :trigdrum
print n
#stop
a = 0.5
s = [:bd_gas,
:sn_dolf,
:drum_cymbal_closed,
:tabla_na,
:tabla_na,
:tabla_na,
:tabla_na]
sample :bd_gas if false
define :p do |i|
case i
when 0
sample s[i], rate: 2, finish: 0.1, amp: a*trackvol(1)
when 1
sample s[i], rate: (ring 1,1.2,1.4,1.6).tick(:s1), finish: 0.2, amp: a*0.2*trackvol(2)
when 2
sample s[i], rate: 1, amp: a*0.6*trackvol(3)
when 3
sample s[i], rate: 3, finish: 0.1, amp: a*0.5*trackvol(4)
when 4
sample s[i], rate: 2, finish: 0.1, amp: a*0.5*trackvol(4)
when 5
sample s[i], rate: 3, finish: 0.1, amp: a*0.5*trackvol(4)
when 6
sample s[i], rate: 4, finish: 0.1, amp: a*0.5*trackvol(4)
else
sample s[i], rate: 5, finish: 0.1, amp: a*0.1
end
end
with_fx :echo, mix: 0.2, phase: 0.75, decay: 6 do
in_thread do
16.times do
tick
if n%6<6
p(0) if ("x---x---x---x---"[look]=="x")
end
if n%6<4
p(1) if ("----x-------x---"[look]=="x")
else
p(1) if ("----x-----------"[look]=="x")
end
if n%4==0
p(1) if ("-----------x----"[look]=="x")
end
if n%4<4
p(2) if ("--x---x---x---x-"[look]=="x")
else
p(2) if ("-xx--xx--xx--xx-"[look]=="x")
end
if n%6==0 then
p(3) if ("xxx---xxxx---xxx"[look]=="x")
else
p(3) if ("------x-----x---"[look]=="x")
end
if n%5<2 then
p(4) if ("-----x----------"[look]=="x") ^ one_in(6)
p(5) if ("-------x---x--x-"[look]=="x") ^ one_in(6)
p(6) if ("----x----x-----x"[look]=="x") ^ one_in(6)
end
p(7) if ("--x---x---x---x---"[look]=="x")
sleep 1.0/4
end
end
end
end