¿ªÔÆÌåÓý

ctrl + shift + ? for shortcuts
© 2025 Groups.io

Xpander sysex patch spec- the Xplorer version


 

I'm trying to understand the calculations that the single patch browser (included with Xplorer) ueses.

Looking at XpanderSysEx.h



// Single patch data sysex length is 399 bytes
// 6 bytes for sysex intro: F0 10 02....
static const int PRG_DUMP_DATA_FOLLOWS_INTRO_LENGTH = 6;
// 188 double bytes data for the values and 8 double bytes for the patch name
static const int PATCHNAME_LENGTH = 8;
static const int OBWORDS_DATA_LENGTH = 196 - PATCHNAME_LENGTH;
// 6 (intro) +196*2 (data+name) +1 (EOX) = 399


I understand that?PRG_DUMP_DATA_FOLLOWS_INTRO_LENGTH is for the Sysex cmd overhead to request a single patch, however, I don't understand why he subtracts the patchname length from 196, when the patch name is part of each single patch.


196 & 2 + 8 = 399 bytes, which is correct


What am I missing?








 

I think the comments explain it:

"188 double bytes data for the values and 8 double bytes for the patch name"

What is meant by "double bytes" is some form of encoding bytes (8-bit values) into sysex data, which is a string of 7-bit values. Often this means splitting a byte into a high nibble and a low nibble (4+4 bits) but I don't know if that's what the Xpander does.

Also see the second comment:

"6 (intro) +196*2 (data+name) +1 (EOX) = 399"

So 7 MIDI bytes of framing, leaving 399-7=392 sysex data "bytes" (7-bit values). Divide that by 2, and you get 196 proper bytes (8-bit values).




2018-05-22 22:46 GMT+02:00 cappy2112@... [xpantastic] <xpantastic@...>:

?

I'm trying to understand the calculations that the single patch browser (included with Xplorer) ueses.

Looking at XpanderSysEx.h



// Single patch data sysex length is 399 bytes
// 6 bytes for sysex intro: F0 10 02....
static const int PRG_DUMP_DATA_FOLLOWS_INTRO_LENGTH = 6;
// 188 double bytes data for the values and 8 double bytes for the patch name
static const int PATCHNAME_LENGTH = 8;
static const int OBWORDS_DATA_LENGTH = 196 - PATCHNAME_LENGTH;
// 6 (intro) +196*2 (data+name) +1 (EOX) = 399


I understand that?PRG_DUMP_DATA_FOLLOWS_INTRO_LENGTH is for the Sysex cmd overhead to request a single patch, however, I don't understand why he subtracts the patchname length from 196, when the patch name is part of each single patch.


196 & 2 + 8 = 399 bytes, which is correct


What am I missing?









 


>>?196 & 2 + 8 = 399 bytes, which is correct

I have to correct my own calculation, however it still doesn't add up from what i can see.
196 *2 = 392 bytes, including the patch name. Add the first 6 bytes for the sysex command, + 1 EOX, 399 bytes.


On Tue, May 22, 2018 at 1:46 PM, cappy2112@... [xpantastic] <xpantastic@...> wrote:
?

I'm trying to understand the calculations that the single patch browser (included with Xplorer) ueses.

Looking at XpanderSysEx.h



// Single patch data sysex length is 399 bytes
// 6 bytes for sysex intro: F0 10 02....
static const int PRG_DUMP_DATA_FOLLOWS_INTRO_LENGTH = 6;
// 188 double bytes data for the values and 8 double bytes for the patch name
static const int PATCHNAME_LENGTH = 8;
static const int OBWORDS_DATA_LENGTH = 196 - PATCHNAME_LENGTH;
// 6 (intro) +196*2 (data+name) +1 (EOX) = 399


I understand that?PRG_DUMP_DATA_FOLLOWS_INTRO_LENGTH is for the Sysex cmd overhead to request a single patch, however, I don't understand why he subtracts the patchname length from 196, when the patch name is part of each single patch.


196 & 2 + 8 = 399 bytes, which is correct


What am I missing?









 

Hi,

you should look at the XpanderSinglePatchViewer.cpp, it is self explanatory there.
you have OBWORDS_DATA_LENGTH of data to be "repacked" as double byte values, which is not required of course for the patch name (string) that comes afterward.

??? // for each double byte, repack the value, and set the Patch property accordingly
??? unsigned char* pByte= (unsigned char*)pPatch;
??? for (int i=0;i<OBWORDS_DATA_LENGTH;i++) {
??? ??? // 8th bit of the 8 bits value is the first bit of the high byte
??? ??? unsigned char cValue = ((shortArray[i] & 0x0100)>>1) | (shortArray[i] & 0x00ff);
??? ??? *pByte=cValue;
??? ??? pByte++;
??? }
...
??? // name is 2 bytes/char, high byte never used, thus wchar_t compatible
??? iReadBytes=0;
??? iReadBytes=fread(&pPatch->name,sizeof(wchar_t),PATCHNAME_LENGTH,pFile);
??? assert(iReadBytes==PATCHNAME_LENGTH);

Regards,