Roland SH-32

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: