Go Down

Topic: Midi library Encode/Decode Sysex functions with Korg devices (Read 617 times) previous topic - next topic

TheKikGen

I want to bring to your attention that you could face some issues with the decode and encode sysex functions from the standard Arduino MIDI library with Korg devices.  In the encode/decodesysEx funcs, MSB bits are encoded on the 8th byte from bit 6 to bit 0 corresponding respectively to bytes 1 to 7 in the set. The Korg encoding bits logic is inverted, i.e. from bit 0 to bit 6 : it is at least what I found out from my Electribe ES1 dump but it is probably true for other Korg devices...

For example, the following message received from my ES1
(02) 07 7F 00 00 00 00 00
is corresponding to the decoded msg
07 FF 00 00 00 00 00
but encoded with encodeSysEx, I get
(20) 07 7F 00 00 00 00 00

The code of the 2 functions must be modified as below if you need to encode / decode Sysex to/from Korg devices  (then you must set the optional parameter "fromMsbToLsb"  to false).


I have opened an issue on the Midi library GitHub, but this is not really a bug however... !
the sorrows of sysex....

Code: [Select]


// prototypes  are :
unsigned encodeSysEx(const byte* inData, byte* outSysEx, unsigned inLength,bool fromMsbToLsb=true);
unsigned decodeSysEx(const byte* inSysEx, byte* outData, unsigned inLength,bool fromMsbToLsb=true);


/////////////////////////////////////////////////
// ENCODE 8BITS TO 7BITS SYSEX
/////////////////////////////////////////////////
prototypes  are :
unsigned encodeSysEx(const byte* inData, byte* outSysEx, unsigned inLength,bool fromMsbToLsb)
{
    unsigned outLength  = 0;     // Num bytes in output array.
    byte count          = 0;     // Num 7bytes in a block.
    outSysEx[0]         = 0;

    for (unsigned i = 0; i < inLength; ++i)
    {
        const byte data = inData[i];
        const byte msb  = data >> 7;
        const byte body = data & 0x7f;

        outSysEx[0] |= (msb << (fromMsbToLsb ? 6-count : count ));
        outSysEx[1 + count] = body;

        if (count++ == 6)
        {
            outSysEx   += 8;
            outLength  += 8;
            outSysEx[0] = 0;
            count       = 0;
        }
    }
    return outLength + count + (count != 0 ? 1 : 0);
}
/////////////////////////////////////////////////
// DECODE 7BITS SYSEX TO 8BITS
/////////////////////////////////////////////////
unsigned decodeSysEx(const byte* inSysEx, byte* outData, unsigned inLength,bool fromMsbToLsb)
{
    unsigned count  = 0;
    byte msbStorage = 0;
    byte byteIndex  = 0;

    for (unsigned i = 0; i < inLength; ++i)
    {
        if ((i % 8) == 0)
        {
            msbStorage = inSysEx[i];
            byteIndex  = 6;
        }
        else
        {
            const byte body = inSysEx[i];
            const byte msb  = ((msbStorage >> (fromMsbToLsb ? byteIndex : 6 - byteIndex) ) & 1) << 7;
            byteIndex--;
            outData[count++] = msb | body;
        }
    }
    return count;
}

Gabryx

Many years ago i made a Patch/Timbre/Tone/Envelop editor for Roland D-10 on a Commodore 64 and after on Amiga.
And sysex data transmitted is differents from a productor/model and another, not are a standard on number of bytes trasmitted.
I see for example that Korg ES1 can have also 9 bytes messages.
Or my Roland D-10 want a check sum of data trasmitted at end of message(first of F7 that is end of exclusive).
So good luck with Sysex mesages, i post 2 screen of manual ( Korg and Roland) about sysex.

Bye
https://www.youtube.com/watch?v=hDuxyhfchYg
https://www.youtube.com/watch?v=hyIqT0kAdVo&t=750s
https://www.youtube.com/watch?v=kw-r1wts60Y

TheKikGen

Thanks !

Encoding sysex on the ES1 is done with only 8 bytes, as explained in the midi implementation txt doc. So it is close to what we could suppose to be the encoding standard (as discussed with the author of midi library).

I didn't realize at first, the bits encoding was the reverse of the one coded in the Encode/decode Sysex funcs, because in my ES1 dumps I had a lot of 7 bits data....

But you are perfectly right, SYSEX is so specific... and often badly documented.
For ex , on the ES1 no need to send a checksum. On Roland it is mandatory.
but at less the 8 bits bytes encoding often follow the same logic....






Go Up