Roland checksum – how to

Home Forums General Using Ctrlr Roland checksum – how to

This topic contains 28 replies, has 4 voices, and was last updated by Quimquim Quimquim 4 months, 1 week ago.

Viewing 20 posts - 1 through 20 (of 29 total)
  • Author
    Posts
  • #71053

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    here are the notes i found for calculating the Roland checksum
    -cribbed Eddie Lotter’s webpage, abbreviated –
    (early devices, don’t know if it changes for anything more recent)
    ——————————————————————
    The checksum is a value derived from the address and the data. The
    device will also calculate it from the address and data it receives
    and check its checksum against the one you supply. If they match then
    it has received the SysEx message correctly.

    example: if the address is 40h 00h 04h and the data is 64h
    Here’s how the checksum is derived:
    ——————————————————————
    method #1:
    Add each of the values, one by one. Each time the value exceeds 127 (7Fh)
    subtract 128 (80h) from it. Finally subtract the resultant value from 128
    and you have your checksum!

    In hexadecimal: (I won’t put h after each value for clarity)
    40 + 00 = 40 (Surprise!)
    40 + 04 = 44
    44 + 64 = A8 ( A8 > 7F so…)
    A8 – 80 = 28
    80 – 28 = 58 (The checksum is 58h)

    In decimal:
    64 + 0 = 0
    64 + 4 = 68
    68 + 100 = 168 ( 168 > 127 so…)
    168 – 128 = 40
    128 – 40 = 88 (The checksum is 88)

    To show what is actually happening I’ll show you the last line in binary:

    10000000 – 00101000 = 01011000

    According to the manual “The error checking process uses a checksum that
    provides a bit pattern where the least significant 7 bits are zero when
    values for an address, [data], and that checksum are summed.”
    The low bits in binary are on the right. In the binary calculation above,
    add the address, data and checksum and you get back to 128, which has all
    seven lower bits clear:

    address & data + checksum = 128
    00101000 + 01011000 = 10000000

    Note that in this example, while summing the values we exceeded 127 and
    had to subtract 128. This is not always necessary, as long as the
    summed values do not exceed 127.

    If the sum of the values comes to 128 then I’m sure it is clear that
    the checksum is 128! Look at the arithmetic:
    x + y = 128 ( 128 > 127 so…)
    128 – 128 = 0
    128 – 0 = 128 (The checksum is 128)

    If anything in this document is ambiguous or unclear, please let me know
    so that I can improve it for everyone’s benefit.

    Eddie
    lotter@cc.und.ac.za
    —————————————————————————
    method #2: (note: i prefer this, easier)

    The manual shows a different method which involves slightly more complicated arithmatic.
    In essence it involves adding all the values together, dividing by 128 and subtracting the remainder from 128. Thus:

    1. Convert hex to decimal:
    40h = 64
    11h = 17
    00h = 0
    41h = 65
    63h = 99

    2. Add values:
    64 + 17 + 0 + 65 + 99 = 245

    3. Divide by 128
    245 / 128 = 1 remainder 117

    4. Subtract remainder from 128
    128 – 117 = 11

    5. Covert to hex:
    11 = 0Bh

    (Eddie Lotter)
    ——————————
    eg: (aa+aa+aa+dd+dd)/128 > take remainder
    128-(remainder)=checksum

    >check that against method#1:
    1. Convert hex to decimal:
    40h = 64
    11h = 17
    00h = 0
    41h = 65
    63h = 99

    2. Add values, keeping result under 128:
    64 + 17 = 81
    81 + 0 = 81
    81 + 65 = 146 ( 146 – 128 = 18 )
    18 + 99 = 117

    3. Subtract answer from 128
    128 – 117 = 11

    4. Covert to hex:
    11 = 0Bh
    —————————————————–
    note: once you’ve calculated the checksum, you will
    notice that it proceeds in inverse direction to the
    value;
    ie: as the value increments, the checksum decrements.

    hope this is useful.

    #71073
    Possemo
    Possemo
    Participant
    • Topics: 13
    • Replies: 489
    • Total: 502
    • ★★★

    Here is a demo panel with one slider (cutoff of part1). One script for all parameters.

    To specify the address the following fields are used:

    addresspart1 = Custom modulator index group
    addresspart2 = A custom group name
    addresspart3 = Custom modulator index

    All values in decimal.

    Use at your own risk. I won’t be responsible for any damage this will do on whatever software/hardware.

    • This reply was modified 1 year, 9 months ago by Possemo Possemo.
    Attachments:
    You must be logged in to view attached files.
    #71076
    Possemo
    Possemo
    Participant
    • Topics: 13
    • Replies: 489
    • Total: 502
    • ★★★

    An improved version. On this one the address in the sysexstring is done with global variables so the sysex-field will allways be the same. You just have to enter the address in the Custom fields – as said:

    addresspart1 = Custom modulator index group
    addresspart2 = A custom group name
    addresspart3 = Custom modulator index

    Attachments:
    You must be logged in to view attached files.
    #71079

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    don’t worry, not sending it to anything; can use midiox anyway, with
    loopbe1.

    ok, so i’ve got that up in front of me now. i recognise the header with
    manuf, deviceID, midiCh etc. and then you have k0, k1, k2, xx, k3, F7,
    where: k0/k1/k2 is the address, xx is the variable value, and k3 is the
    checksum.

    looking down the properties panel, i see:

    ‘luaModulatorGetValueForMIDI’ with ‘calcChecksum’ selected. i see there’s
    a list of options: none, calcChecksul, and a few others.

    i hadn’t looked at this before tbh. nor did i check out the icons
    and what they do. did you add these methods or are they standard?
    let’s try ‘Edit method’ to see what that looks like:
    ———————————————————————
    calcChecksum = function(modulator, numericModulatorValue)

    — assign address fields
    addressPart1=modulator:getPropertyInt(“modulatorCustomIndexGroup”)
    addressPart2=modulator:getPropertyInt(“modulatorCustomNameGroup”)
    addressPart3=modulator:getPropertyInt(“modulatorCustomIndex”)

    — sum is the addition of addresses and value. I used decimal here, 25hex is 37decimal.
    sum=addressPart1+addressPart2+addressPart3+numericModulatorValue

    — if sum is greater than 127 then do..
    if sum>127 then sum=127-sum end

    checksum=128-sum

    panel:setProperty(“panelGlobalVariables”,addressPart1..”:”..addressPart2..”:”..addressPart3..”:”..checksum..”:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0″,false)

    return numericModulatorValue

    end
    ————————————————————
    ah! ok, so that appears to be a built-in instruction, calcChecksum, right?
    and the 2nd calculation method i described earlier…okaaay..i see that;
    it just looks so different from what i’m used to.

    ‘–‘ are ren ‘d comments…

    let’s have a picture – see attachment(hopefully will upload)
    i don’t really understand the last bit, ‘set property’ etc.
    because i don’t speaka da lingo yet.

    so k0…k3
    i substitute k0, K1, k2 with the address?

    i’ve also seen checksum in the JayVee panel with ‘z5’ at the
    checksum position. is that the same method? i’d better have a
    fresh look at that.

    thanks for your help+patience !

    • This reply was modified 1 year, 9 months ago by  human fly.
    Attachments:
    You must be logged in to view attached files.
    #71082
    Possemo
    Possemo
    Participant
    • Topics: 13
    • Replies: 489
    • Total: 502
    • ★★★

    No, this is not built in. Panel developers have to do that themselves.

    yes, — are remarks

    the last bit sets the Ctrlr global variables. I think Roman made this to get the Matrix-1000 panel working, so it is a bit of an awkward feature but very handy in this case:

    panel:setProperty(“panelGlobalVariables”,addressPart1..”:”..addressPart2..”:”..addressPart3..”:”..checksum..”:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0″,false)

    This sets the first four global variables, the rest is set to “0”. When you use the global variables in the SysexString k0 is the first variable, k1 the second etc.

    Screenshot attached shows you the fields I used for the address:

    addressPart1=modulator:getPropertyInt(“modulatorCustomIndexGroup”)
    addressPart2=modulator:getPropertyInt(“modulatorCustomNameGroup”)
    addressPart3=modulator:getPropertyInt(“modulatorCustomIndex”)

    Just fyi, the second screenshot shows the global variables, but there you can do nothing else but looking at how they are set.

    Attachments:
    You must be logged in to view attached files.
    #71085

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    ok i found those first ones. i wouldn’t have found the
    Panel Global variables.

    it seems like a really complicated way of doing a simple thing 🙂

    do you have the JayVee Family panel? have a look at the sysex
    line in that: i can’t see a lua. the checksum position has
    ‘z5’. and that seems to be it. maybe z5 is a shorthand for the
    checksum lua? i ‘ve never tested that panel.

    • This reply was modified 1 year, 9 months ago by  human fly.
    #71088
    Possemo
    Possemo
    Participant
    • Topics: 13
    • Replies: 489
    • Total: 502
    • ★★★

    I just looked into the JayVee panel. Yes you are right. Indeed it looks like z5 triggers a builtin Roland checksum calculator.

    Well, that’s one of the problems of Ctrlr – so much features and zero documentation.

    So, forget my approach, it’s completely obsolete…

    #71096

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    well thank you for the introduction to those lua tabs.
    i need to take some time out to study that.
    don’t know how the JayVee author found out about z5.
    i’m relieved if it’s just that !

    absolutely true, there needs to be some proper
    documentation on the basics. synthedit is a bit like
    that, mostly finding out stuff by trying and asking
    questions.

    it’s been a long Ctrlr day..

    #71097

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    update:
    ok i just checked this with midiox, and it is working.
    but it has to be in Panel Mode or (sysex/all?) output
    is disabled.

    it just has to have ‘xx’ for the variable, and ‘z5’ for
    the checksum byte.

    glad that it is simple! i knew it had to be hehe

    #71100

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    little post script to this: initially had a bit of
    a headscratch moment, because it wasn’t working again:
    i had forgotten to set ‘MIDI message type’, it still
    said ‘None’ – so you have to set that to ‘sysex’, of
    course.

    all working now !

    i then had another little issue with one control that
    was producing a sysex running status message instead:
    ?why? was that? i noticed its value range was -7<>+7,
    and minus values don’t exist with MIDI, so i set it to
    0-14 with centre detent 7 instead, and it started
    working again. resolved, except it now displayed the
    absolute MIDI values instead of the DISPLAYED value
    range, and i want it to show the Display values, like
    the other -/+ controls i have, that are working.

    this, of course, is resolved under ‘Modulator’ with the
    ‘Expression to evaluate when calculating midi message
    value from the modulator value’ entry:
    it says ‘ModulatorValue’ and you change that to say:

    ‘Modulator value+7’, to add the necessary offset
    (in the case of -7<>+7/0-14)

    hehe, it only took a minuite or so to figure that out,
    i’m getting better at this… :o)

    #71164

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    JayVee z5 thing does not currently produce the correct checksum.

    found a method in the JD800 panel. not checked, but worth a look.
    lots of stuff in the Lua section.

    D50 panel is sending the correct checksum, but it seems the panel
    is private, can’t see what is going on.

    here’s for the JD800 panel checksum:

    function sendSysexModulatorValue(modulator, newValue)

    local uid, val, add, lsb, chk, syx

    uid = getModulatorUID(modulator)

    if (uid <= 383) then add = math.floor(uid / 128) lsb = (uid % 128) val = newValue chk = (128 - ((add + lsb + val) % 128)) syx = string.format("f0 41 10 3d 12 00 %.2x %.2x %.2x %.2x f7", add, lsb, val, chk) panel:sendMidiMessageNow(CtrlrMidiMessage(syx)) else if (gPanelMode ~= cPanelModeToneXInit) then for i = 1, 4, 1 do if (gToneButtons[i + 4]:getModulatorValue() == 1) then uid = ((i - 1) * 72) + 96 + tonumber(modulator:getPropertyString("modulatorCustomIndex")) + 1 assignPatchModulatorValue(gPatchModulators[uid], newValue) end end end end end function setActiveTones(newValue) setCommandTones(newValue, 4) end

    #71165

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    it doesn’t use the MIDI message type, it uses ‘Called when the
    modulator value changes, and the Lua ?method? is called
    metSendSysexModulatorChanged. it’s longer than what i showed above.

    i can’t work out how the JayVee panel is providing a checksum
    via the z5 signifier. have to check if it’s even sending the
    correct checksum…(JD800 isn’t sending anything)
    JayVee DOES send correct checksum. what am i missing?
    am using this good little checksum calculator, just unzip,
    no install:

    http://www.bwalk.com.au/Convert/Convert.html

    #71166

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    just guessing, but i reckon a good way would be a method
    that specifies the number of bytes between F0 and F7,
    identifying the address bytes (3) and values byte(1) to
    be checksummed, and how, using a signifier LIKE ‘z5’ to be
    the checksum byte, – KEEPING the MIDI message type category,
    and using Modulator/CalledWhenModulatorValueChanges for the
    Lua.

    that is the most straightforward, in my limited capacity
    to judge this. certainly most userfriendly. you can still
    keep the easy sysex message entry box, copy and paste,
    view it easily, etc. – it is reasonably logical for a first
    time user to understand and bears some relation to the way
    you do it on other platforms.

    what would also be good, especially for multitimbral synths
    such as this, would be to be able to specify basic MIDI
    channel, so you’re not always stuck with using it on ie:
    MIDI channel 1.

    #71185

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    Possemo, check this out: z5 represents the number of
    bytes in the address+value. jv1080 uses 5 bytes, the
    D-110 uses 4, so z5 needs to be z4 in this case.
    just going to try it now.

    #71187

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    excellent – it’s correct now.

    go on, just say it: rtfm 🙂
    i had not looked at that before. it looks very
    complete, i’ll have a proper read. it looks like
    a good general reference.

    “Checksums tN t=type N=num bytes to count
    All checksums have the same format, tN, where the “t” token indicates the type of checksum to calculate, and N is a number that tells Ctrlr how many bytes to before the checksum byte to include in the checksum algorithm (a checksum is a number that verifies if the reception of data is correct, it needs some data to be calculated, so the N number tells Ctrlr how much data to read)

    Roland JP8080 checksum, (zN for example z5)
    Waldorf Rack Attack checksum (wN for example w5)
    Ignore this byte on input, this is a special IGNORE token, that tells Ctrlr not to use this byte when comparing incoming MIDI data, it will considered always a “match”

    #72742
    dnaldoog
    dnaldoog
    Participant
    • Topics: 0
    • Replies: 153
    • Total: 153
    • ★★
    07/10/2018 Note: see the end of this post for a better formula. This formula returns an incorrect value for numbers adding up to over 256 (although maybe a sysex sent message never adds up to that much?)

    The following function calculates and returns a Roland checksum. Pass parameters to it as in:
    local cs=myCheckSum(0x06,0x30,0x00,0x4F,0x64) for example
    cs = 23 (or 0x17)

    myCheckSum=function(...)
        --1. Convert the hex values to decimal. (function parameters are automatically converted)
        --2. Add the values together, but if the answer to any sum exceeds 127 then subtract 128.
        --3. Subtract the final answer from 128.
        --4. Convert the resulting value back to hex and use as the checksum.
        local total=0
        local result=0
        for i,v in ipairs(arg) do
            total=total+v --add up all the numbers
            if(total > 127) then
                total=total - 128
            end
        end
    
        result=128-total
    	if result== 128 then result = 0 end -- If the result is 128 then substitute a value of 0
        return tonumber(result,10)
    
    end --function
    ---------------------------------------------------------
    • This reply was modified 10 months, 1 week ago by dnaldoog dnaldoog. Reason: correction if result == 128 then return 0 as checksum
    • This reply was modified 4 months, 1 week ago by dnaldoog dnaldoog. Reason: formula may return a wrong value for numbers over 256
    #72746

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    thanks! will check that out, am going to need to
    construct the sysex message at some point, instead of
    using the built-in sysex message entry box.

    #72753
    dnaldoog
    dnaldoog
    Participant
    • Topics: 0
    • Replies: 153
    • Total: 153
    • ★★

    You’re welcome Human Fly! – took me a while to work out, so I thought I would pass it on. As you can see from the commented code, I too used that web page as a reference.

    #84524
    dnaldoog
    dnaldoog
    Participant
    • Topics: 0
    • Replies: 153
    • Total: 153
    • ★★

    Hi Human Fly!

    If the sum of the values comes to 128 then I’m sure it is clear that
    the checksum is 128! Look at the arithmetic:
    x + y = 128 ( 128 > 127 so…)
    128 – 128 = 0
    128 – 0 = 128 (The checksum is 128)

    I think this is actually incorrect. If the result = 128, the checksum should be 0.

    There’s a good explanation here:
    https://www.bome.com/forums/viewtopic.php?t=11986
    in Lua, something like:

    
     
    myCheckSum=function(...) -- Roland Checksum
    local sum=0
    local result=0
    for _,v in ipairs(arg) do
    sum=sum+v
    end
    --// calculate the remainder of sum/128
    local remainder=sum % 0x80
    --// subtract the remainder from 128
    result=0x80 - remainder
    if result==0x80 then result=0 end 
    return result
    end --function
    ---------------------------------------------------------
    
    
    #84526

    human fly
    Participant
    • Topics: 123
    • Replies: 1052
    • Total: 1175
    • ★★★★

    hi dnaldoog !

    i was quoting eddie lotter there 😉
    will test your new method – have not been doing
    much Ctrlr lately. stuck on latest projet (ran
    out of ideas temporarily)

Viewing 20 posts - 1 through 20 (of 29 total)

You must be logged in to reply to this topic.

There is currently 0 users and 27 guests online
No users are currently active
Forum Statistics
Threads: 2,166, Posts: 15,277, Members: 22,130
Most users ever online was 10 on October 29, 2018 2:54 pm
Do NOT follow this link or you will be banned from the site!