Converting MIDI SysEx Values (0–1023) to MIDI CC Values (0–127)

Hello,

I need some help with converting MIDI messages. I have SysEx values in the range 0–1023, coming from a Roland rotary encoder. I’d like to map or convert this range to MIDI CC values (which go from 0 to 127).

sysex.txt (86.9 KB)

Does anyone know how I can do this?

Hi and welcome to the Bome community!

See this tutorial on scaling.

Although it is difficult to tell where you are getting value of 1023 in your SysEx message. The byte before F7 is the roland checksum so should be ignored. The prior 2 bytes seem to be a value but it is confusing to see whether they are all part of the value as they both seem to change when you are turning the knob. I would expect one to change faster (LSB) and the other to change slower (MSB)

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

This rules worked:

F0 41 10 00 00 00 5E 12 30 00 2C 10 tt zz xx yy pp F7

yy=yy
xx=xx*16
zz=zz*256
uu=yy+xx
ii=uu+zz
gg=ii*127
rr = gg/1023

Thanks for help!

Great, I recommend that you use all local variables so that other translators do not interfere with this one. The local variables (10 of them) are oo,pp,qq,rr,ss,tt,uu,vv,ww and xx.

Everything else is a global variable. You can refer to the Bome MIDI Translator Pro manual for more detail (press F1 or use the help menu within Bome MIDI Translator Pro )

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

I’ve never programmed SysEx before, but I imagined it working like a system of three wheels: Wheel1 (yy), Wheel2(xx), and Wheel3(zz).

Wheel1 counts from 0 to 15. When Wheel1 reaches 15 and rolls over back to 0, Wheel2 advances once (increments by 1).

Wheel2 also counts from 0 to 15. When Wheel2 reaches 15 and rolls over back to 0, Wheel3 advances once (Wheel 3 go 0 to 3). All combinations have 1023 values.

Ah, I see, didn’t get the pattern and was only looking at the last two bytes before the checksum.

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

I do it with the bit shift method. The ranges also are 1 bigger 0-1023 = range 1024

Incoming : f0 41 10 00 00 00 5e 12 30 00 2c 10 00 oo pp qq rr f7

Rules

// Shift bits into position
oo=oo<<8
pp=pp<<4
// OR them together
qq=qq|pp
qq=qq|oo
Log "Incoming value = %qq%"
// scale value
qq=qq*128
qq=qq/1024
Log "Outgoing value = %qq%"

Outgoing Control Change 24 on MIDI CH 1 value qq

Finally, I’m using only local variables so this will not interfere with other translators. The local variable for the checksum (rr) is used but ignored since we don’t care what it is.

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

The bit shift method worked very well, thank you for the tip! But now I have another problem. This was used to receive MIDI sysex from the Roland and automatically rotate a motorized rotary encoder, but now I want to do the reverse: rotate the motorized rotary encoder (CC 0 to 127) and send the information to the Roland. How can I do this with the shift method only knowing the CC value and maximum and minimum values of oo pp qq?

Yes, this is a bit trickier because you need to calculate the Roland checksum otherwise the device may not work. Also you will lose some precision when you scale back from 0-127 to 0-1023 - Every value of 1 in will move by a value of 8 out.

I’ve attached an example. The first preset handles from the Roland to knob and the second one from knob to Roland. I had to change the scaling a bit because of the precision if I wanted to go full scale.

Here are the rules.

Log "Log Incoming value = %qq%"
// Scale it
qq=qq*1024
qq=qq/127
if qq>1023 then qq=1023
Log "Log Outgoing value = %qq%"

//exit rules, skip outgoing action

// Break it into 3 chunks
//LSB in tt
tt=qq&15
// next in rr
rr=qq>>4
rr=rr&15
// MSB in uu
uu=qq>>8
uu=uu&3

// Calculate Roland Checksum
//zero data bytes
pp=0
// first address byte
//0x10
pp=pp+16
// add the data bytes
pp=pp+uu
pp=pp+rr
pp=pp+tt
// calculate the remainder of pp/128
pp=pp%128
// subtract the remainder from 128
pp=0x80-pp
if pp==128 then pp=0


Incoming value is qq and outgoing values are in uu, rr, and tt

Sysex-Both-Ways-with-Roland-Checksum.bmtp (3.0 KB)

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

Thank you! Exactly, without the checksum it wasn’t working, I’m still learning, but that was it, knowing the minimum checksum (92), I was able to make it work with these rules:

F0 41 10 00 00 00 5E 12 30 00 00 24 00 yy ss xx ww F7

pp=pp*1024
pp=pp/127
if pp>1023 then pp=1023

xx=pp%16
uu=pp/16
ss=uu%16
vv=pp/256
yy=vv%16

ww=92-xx
ww=ww-uu

Sure, anyway you can calculate it to get to the desired reliable result.