Hello
I’m creating a custom orc with opcodes for setting up a Launchcontrol midi controller.
Currently I have the following setup, which is working fine, but I think it would be more optimal to set this all up in a loop, rather than manually by hand. I guess it’s not too much hassle to do once, but it seems ripe for the computer to do that.
Firstly here is the working setup. There are essentially 2 UDOs:
launchcontrol_unit_cc
- is a wrapper for ctrl7, with niceties like state initialisation, debugging and a rough soft-takeover function:
opcode launchcontrol_unit_cc, k, ikiiki
ichn, kccn, imin, imax, kctrlinitstate, idebug xin
print ichn, imin, imax, idebug
ktakeover init 0
iccn = i(kccn)
ictrlinitstate = i(kctrlinitstate)
; have to run a reinit as the k-rate input variables kccn and kctrlinitstate
; are 0 on initial pass and the ctrl7 opcode needs them converted to i-rate
recalc:
prints "recalc'd\n"
iccn = i(kccn)
ictrlinitstate = i(kctrlinitstate)
; print iccn ,ictrlinitstate
rireturn
reinit recalc
; print iccn ,ictrlinitstate
kctrl = ctrl7:k(ichn, iccn, imin, imax)
; implement soft-takeover (is decent? not really...)
if kctrl > (ictrlinitstate-2) && kctrl < (ictrlinitstate+2) then
ktakeover = 1
endif
if ktakeover == 1 then
; kctrlout = port(kctrl, 0.002)
kctrlout = kctrl
else
kctrlout = ictrlinitstate
endif
if idebug == 1 && changed2(kctrlout) == 1 then
println "Chan %d : CC%d : %f", ichn, kccn, kctrlout
endif
xout kctrlout
endop
launchcontrolarray
- is a parent controller UDO for the unit UDOs above:
opcode launchcontrolarray, k[], ii
ibase, idebug xin
kctrls[] init 16
; top row dials
kctrls[0] = launchcontrol_unit_cc(1, 57, 0, 127, i(gkcntrlsorig, 0), idebug)
kctrls[1] = launchcontrol_unit_cc(1, 58, 0, 127, i(gkcntrlsorig, 1), idebug)
kctrls[2] = launchcontrol_unit_cc(1, 59, 0, 127, i(gkcntrlsorig, 2), idebug)
kctrls[3] = launchcontrol_unit_cc(1, 60, 0, 127, i(gkcntrlsorig, 3), idebug)
kctrls[4] = launchcontrol_unit_cc(1, 61, 0, 127, i(gkcntrlsorig, 4), idebug)
kctrls[5] = launchcontrol_unit_cc(1, 62, 0, 127, i(gkcntrlsorig, 5), idebug)
kctrls[6] = launchcontrol_unit_cc(1, 63, 0, 127, i(gkcntrlsorig, 6), idebug)
kctrls[7] = launchcontrol_unit_cc(1, 64, 0, 127, i(gkcntrlsorig, 7), idebug)
; bottom row dials
; kctrls[8] = launchcontrol_unit_cc(1, 65, 0, 127, i(gkcntrlsorig, 8), idebug)
; kctrls[9] = launchcontrol_unit_cc(1, 66, 0, 127, i(gkcntrlsorig, 9), idebug)
; kctrls[10] = launchcontrol_unit_cc(1, 67, 0, 127, i(gkcntrlsorig, 10) idebug)
; kctrls[11] = launchcontrol_unit_cc(1, 68, 0, 127, i(gkcntrlsorig, 11), idebug)
; kctrls[12] = launchcontrol_unit_cc(1, 69, 0, 127, i(gkcntrlsorig, 12), idebug)
; kctrls[13] = launchcontrol_unit_cc(1, 70, 0, 127, i(gkcntrlsorig, 13), idebug)
; kctrls[14] = launchcontrol_unit_cc(1, 71, 0, 127, i(gkcntrlsorig, 14), idebug)
; kctrls[15] = launchcontrol_unit_cc(1, 72, 0, 127, i(gkcntrlsorig, 15), idebug)
xout kctrls
endop
and this is all started in this instrument:
instr LaunchTestArray
prints "LaunchTestArray\n"
idebug = p4
ibasecc = p5
gkcntrls launchcontrolarray ibasecc, idebug
endin
schedule("LaunchTestArray", 2, -1, 1, 57)
N.B
gkcntrls
- is a global k-rate array that holds the current state of each launchcontrol_unit_cc
gkcntrlsorig
- is an initial state to start things off (actually ready from a txt file in ftload that’s part of some automatic state saving stuff - not so relevant here)
Hope this all makes sense!
OK so here is the ‘automated’ version of launchcontrolarray
UDO:
opcode launchcontrolarray, k[], ii
ibase, idebug xin
kcnt = 0
kctrls[] init 16
while kcnt < 8 do
;printks "initial value from save state: %f\n", 0, gkcntrlsorig[kcnt]
;printks "CC number: %d\n", 0.1, 57+kcnt
kctrls[kcnt] = launchcontrol_unit_cc(1, ibase+kcnt, 0, 127, gkcntrlsorig[kcnt], idebug)
kcnt += 1
od
xout kctrls
endop
The problem is that launchcontrol_unit_cc
needs a reinit
pass to get the proper values for kccn
and kctrlinitstate
, but everything goes into an endless loop, no doubt caused by the k-rate while loop. I imagine the while loop recreates the launchcontrol_unit_cc
udo at each pass?
I have had this working if I hard code the values for kccn
and kctrlinitstate
, but that’s only going to work for one cc number. So the issue I can see is around the initialisation of the k-rate variables, and having to reinitialise them to get any value other than zero.
I’m not clear whether this can be achieved using a i-rate loop to setup the udos and have their values write to the kctrls
array and so on? If that is done , then it think the launchcontrol_unit_cc
won’t be running at k-rate and will effectively only output one value.
Is what I’m trying to achieve possible?
Sorry for the long post. I can upload a CSD file if that make things simpler.
Cheers