This topic will be of interest to you too
In the meantime, I’ve managed to control various Roland parameters using a virtual control.The SysEx is thus not to be entered manually per control, but it has been programmed only once to work on any control that should send Sysex:
Lua parts of the solution are (in my case I control an XV5080):
- define the command bytes for the sysex of the Roland XV5080
rolandDeviceID = 16 -- must correspond with Roland XV5080's Device ID
local commandArray ={0x41, rolandDeviceID, 0x00, 0x10, 0x12}
- define the ID’s for the device on the E1 itself
deviceId = 1 -- must correspond with Electra One's Device ID for this synth
device = devices.get(deviceId)
devPort = device:getPort()
- create a function to concatenate two arrays
function concat(t1,t2)
local table = {}
for i=1,#t1 do
table[#table+1] = t1[i]
end
for i=1,#t2 do
table[#table+1] = t2[i]
end
return table
end
- calculate a Roland checksum based on a payload (= an array with bytes)
function calcChecksum(payLoad)
local result = 0
for i= 1, #payLoad do
result = result+payLoad[i]
end
result = (128-result)%128
return result
end
- when a control is changed, send out its Sysex.
The parameter number is used to identify the sysEx address to change: it is converted in the two lower address bytes (in my case I can keep the 2 upper address bytes fixed to 1Fh and 00h).
function parameterMap.onChange (valueObjects, origin, value)-- callback function retrieving MIDI value
if origin == 1 then return end -- only process parameter Change when set from within the E1
local parameterNumber = 0
local parameterType = 0
for i, valueObject in ipairs (valueObjects) do
local control = valueObject:getControl ()
parameterNumber = valueObject:getMessage():getParameterNumber ()
parameterType = valueObject:getMessage():getType ()
if parameterType~= 0 then return end-- only process virtual parameters
break -- only first pair is needed
end
local payLoad = {0x1F, 0x00,math.floor(parameterNumber/256),parameterNumber%256,value} -- array with address and value
local checkSum = {calcChecksum(payLoad)} -- checkSum is a table !!
midi.sendSysex (devPort, concat(commandArray,concat(payLoad,checkSum))) -- double concat
end
The controls themselves are nothing special, except they have a very specific number, that can be rather high: