Midi SYSEX Error

Hello

to control a Kemper amplifier i need to send some sysex strings…

4 hex chars represent the value (00 00 to 7f 7f).
I use a knob in the range of 0 - 32639 (x’7f7f’).

the section OSC i have filled in these values:

address: /sysex
preargs:
JS{{
return “xx xx xx …” + (@{this}+0x10000).toString(16).substr(-4) + “xx”
}}
target: [“midi:yyyy”]

some values produce a error “ERROR: MIDI: could not convert osc to midi…” e.g.: 18343, 18073,…
(values like 18477, 17938 produce no error)

seems like no problem so far, but why i get these errors ?

thanks in advance

Hi, could you please upload a session file with this setup so that I can reproduce the bug ?

hi, of course…
redesign_v12.json (168.1 KB)

thanks…

Your code produces hexadecimal bytes between 0 and 255 (ff), the maximum value in midi is 127 ( f7), this is why half of the messages can’t be sent.

thanks for investigating, but i don’t understand.
the range is between 0 and 32639 which results in 00 00 to 7f 7f, can’t see ff anywhere??

(255+0x10000).toString(16).substr(-4) returns '00ff

The thing is you can’t encode 32640 values with two 7-bits (00-7f) values, each of these can represent 128 different values, so you can only encode 128*128=16384 values.

Hello jean-emmanuel,
ok it is getting clearer to me…

i need to get a value in a range from 0 to 16383 to 0000 -> 7f7f

(127 steps of precision would be enough in my case…)

i tried it with bit shifting, but no success

    JS{{
           return (((@{this}+0x10000).toString(16).substr(-4) & 0x7F) << 7) | 
                      (((@{this}+0x10000).toString(16).substr(-4) >> 7) & 0x7F)
    }}

why does this not work?
(derived from here: https://stackoverflow.com/questions/5320439/how-do-i-swap-endian-ness-byte-order-of-a-variable-in-javascript)

thanks…

Here is a valid conversion:

JS{{
var v = @{this}
return (v & 0x7f).toString(16).padStart(2, '0') + ((v >> 7) & 0x7f).toString(16).padStart(2, '0')
}}

thanks! awesome, i have much to learn as it seems.
had to use 128 steps and a range from 0 to 32639 (00 00 to 7f 7e) -> but that is good enough (rounding error???) -> otherwise i get “jumping” values.

thanks again!

@jean-emmanuel could you please help me out another time ?
i started on this topic again and found out that i need this conversion the other way round.
0x00 00 -> 0x7f 7f (14 bit) to 0 -> 16383. (parse the incoming sysex and position the knob when turning the knobs on the “real” device).

Thanks!

You have to separate the two 7-bit bytes, the first one is the most significant bit (msb), the second is the least significant bit (lsb), the conversion formula is: value = msb * 128 + lsb . It could look like this:

// assuming msb  = "7f" and lsb = "7f"
var value = parseInt(msb, 16) * 128 + parseInt(lsb, 16)