Midi sysex ( roland checksum) experts wanted

DSP, Plug-in and Host development discussion.
User avatar
KVRAF
4433 posts since 22 Mar, 2009 from gent

Post Thu Jul 29, 2021 4:35 am

So I made a sysex editor in loomer architect for the roland integra controlling the pcm engine , it all works perfectly .
viewtopic.php?f=141&t=568331
I sended a sysex message from the hardware unit into architect ,analyzed the message adding some variables for midi channel , part number and obviously the data value itself and send it back as sysex ,
I can send every parameter for every part over every midi channel ( here is it ), iow it works flawlessly.
The only thing that I did NOT include is the check sum , because I am not even sure if the check sum is part of an incoming message .
Let me clarify
This is a sysex string for amp.env.attack time for partial one on midi channel 1 ( they are already converted from hex to decimal )
The first 6 values remain unchanged (always)
65, 16, 0, 0, 100, 18, 25, 0, 32, 102, 51, 46
Value 25,0 is the midi channel ( in this case 1 ) , (25,0),(25,32),(25,64),(25,96),(26,0),(26,32) etc ..for all other channels
Image
The start /end message is rejected as these are not relevant for the calculation of the checksum
Value 32 is the partial nr (roland speak for oscilator) , value 102 is the id of the parameter (in this case amp env.attack time ) , 51 is the actual value which is replaced by a variable
Now the last parameter 46 , always changes when the variable changes so I assume this is the checksum ( is a checksum also send from hardware ) ?
I totally neglected this last value when making the editor and it still works but I want to figure out how to get it
According to some info the checksum is the sum of all data divided by 128 , and then subtract the remainder from 128 ( assuming the checksum is 46 , we should get this result
So ( using the example above ) the actual data we are using is
100+18+25+32+102+51 =238
328/128= 2
remainder :72
128-72=56
noppes
I tried it when excluding 100 , so 18+25+0+32+102+51 =228
228/128
remainder :100
128-100= 28
Noppes
Or I could be totally wrong and '46'isn't the chem sum at all
Eyeball exchanging
Soul calibrating ..frequencies

User avatar
KVRAF
13035 posts since 8 Mar, 2005 from Utrecht, Holland

Post Thu Jul 29, 2021 6:20 am

This is the first time I see 128 used as checksum divider, and it's considered a rather bad choice. swapping the order of bytes does not get detected. Usually it's a prime number and the numbers get multiplied by their position. In bank accounts they often use 11 (old style Dutch bank account numbers) and 97 (new style IBAN) and there are many possible algorithms.

But a quick google indicates your example algorithm was used at some time :shrug:

Tip: increase the value of just one byte by one and inspect the change in the last byte.
In your example that's the value 51. Increase with one to 52 and look what happens. If the checksum goes from 46 to 47 then the algorithm can be as easy as you found. The devil is in the details...
We are the KVR collective. Resistance is futile. You will be assimilated. Image
My MusicCalc is back online!!

User avatar
KVRAF

Topic Starter

4433 posts since 22 Mar, 2009 from gent

Post Thu Jul 29, 2021 6:58 am

The last value changes inversely to the previous one , but then the formula should give me the correct result , no ?
Eyeball exchanging
Soul calibrating ..frequencies

KVRist
136 posts since 18 Mar, 2012

Post Thu Jul 29, 2021 7:46 am

The checksum starts from the address so it's:

Code: Select all

uint32_t ck = 25+0+32+102  +   51;
ck = 0x80 - (ck & 0x7F);
ck = ck & 0x7F;
Last edited by bitwise on Thu Jul 29, 2021 1:24 pm, edited 1 time in total.

KVRist
73 posts since 4 Mar, 2010

Post Thu Jul 29, 2021 11:29 am

When calculating the Checksum, you must add up the address bytes and the data bytes. Then you divide by 128 and take the remainder. Finally, you subtract the remainder from 128. You should end up with a value of 127 or less if you did it correctly.

KVRist
488 posts since 4 Jan, 2007

Post Thu Jul 29, 2021 12:43 pm

I don't know the protocol at all, just commenting on the last message.

It doesn't sound right. If the remainder is 0, 128 - 0 = 128. One doesn't end up with a value from 0 to 127.

KVRist
488 posts since 4 Jan, 2007

Post Thu Jul 29, 2021 1:19 pm

So the last line should be:

ck = (0x80 - ck) & 7f

KVRist
136 posts since 18 Mar, 2012

Post Thu Jul 29, 2021 1:25 pm

rafa1981 wrote:
Thu Jul 29, 2021 12:43 pm
I don't know the protocol at all, just commenting on the last message.

It doesn't sound right. If the remainder is 0, 128 - 0 = 128. One doesn't end up with a value from 0 to 127.
I edited my code to include this case.

KVRist
488 posts since 4 Jan, 2007

Post Thu Jul 29, 2021 1:31 pm

Just run the sum on a uint8_t variable, letting it do wraparound overflow, then apply bitwise NOT and then add 1. That's easier or least error prone IMO.

https://godbolt.org/z/fnz5Ms7Wa
Last edited by rafa1981 on Thu Jul 29, 2021 1:42 pm, edited 2 times in total.

User avatar
KVRAF
1889 posts since 6 Jul, 2013

Post Thu Jul 29, 2021 1:33 pm

rafa1981 wrote:
Thu Jul 29, 2021 12:43 pm
It doesn't sound right. If the remainder is 0, 128 - 0 = 128. One doesn't end up with a value from 0 to 127.
This is a common case that often is left out of documentation you find online. It *is* important though...

KVRist
136 posts since 18 Mar, 2012

Post Thu Jul 29, 2021 2:15 pm

rafa1981 wrote:
Thu Jul 29, 2021 1:31 pm
Just run the sum on a uint8_t variable, letting it do wraparound overflow, then apply bitwise NOT and then add 1. That's easier or least error prone IMO.
Well, at this point you could also add the checksum itself and expect zero.

Return to “DSP and Plug-in Development”