Bug in MIDI function?

Tags: #<Tag:0x00007f9785e585e8>

Not sure if it’s me, but something is weird. Today I tried some more complex Sysex expressions, and used the function midivarlen(x) for the first time. But I don’t think the output is correct - unless I misunderstand completely:

When I enter midivarlen(127), I get a correct output of 7F (hex), but when I go up to 128, suddenly the output is 81 00 - funky, I always thought it should be 01 00… Also, the highest bit should not be set in sysex data - only 7 bits used.

midivarlen(7000) results in B6 58 - again a funky illegal first byte. Same phenomenon when I move up to midivarlen(70000) - AA DC 60.

It seems that midivarlen(x) adds 0x80 to every byte but the last - not very helpful…

@brad - can you confirm and help?



oh, and BTW: I was able to completely hang up Cantabile by entering midivarlen(-1) :scream:

Hey @Torsten,

You’re right, the midivarlen function isn’t very useful for sysex because of the way it encodes the variable length bytes. It’s included because it’s a function I already had written for writing MIDI files and the format is explained here.

TL;DR: I think it’s working correctly, but not very useful in sysex.

I guess the question is what exactly are you trying to send via sysex - perhaps I can add other functions if there’s a format you need - or at least figure out if it can be done in an expression directly.

A QA tester walks into a bar and orders a beer, orders 9999999 beers, orders -1 beers.

(I’ll look into it)


Essentially I’m trying to break down 14-bit or 28-bit values into 7-bit chunks; same calculation you need for MSB/LSB breakdowns. Since the sysex spec requires all data bytes to be 7 bit only, this requires splitting up longer numbers into chunks of 7 bits.

If I want to set some parameters on my VoiceLive via Sysex, I need to feed it the parameter value coded as a 4-byte (signed) 28-bit value. OK, most values really are at maximum 14 bits and positive, so I can get away with sending two fixed 0x00 bytes, unless I have to deal with negative values.

So maybe a function convert14bit and convert28bit?

Here’s some code that TC Helicon provided to illustrate how they deal with signed values:



Hi @Torsten… I can probably provide an implementation of this if you need it but won’t get to it until next week. In the meantime, have you seen this blog post - it covers a similar thing but for Roland sys-ex. Maybe it can give you enough to translate the above.

1 Like

No hurry at all - at the moment, all I’m sending are fixed values, so I can do the math myself. But should I want to automate some parameters directly from Cantabile values, such functions could come in handy. I’ll see what I can knock together based on the Roland example…

Hi @Torsten,

Had a closer look at this. I think all you need is this:

var valU = uint(value < 0 ? value + 268435456 : value)

0xF0 0x00 0x00

(valU >> 21) & 0x7F
(valU >> 14) & 0x7F
(valU >> 7) & 0x7F
(valU) & 0x7F


Unfortunately there’s a bug in the current implementation of the uint cast which is failing but I’ve fixed for the next build.

Of course, fill out the surround sys-ex bits with whatever you need.


1 Like

Very cool - thanx!

New build 3692 has a fix for the above mentioned uint cast bug.