probonopd / MiniDexed

Dexed FM synthesizer similar to 8x DX7 (TX816/TX802) running on a bare metal Raspberry Pi (without a Linux kernel or operating system)
https://github.com/probonopd/MiniDexed/wiki
1.13k stars 81 forks source link

Performance sysex (PCED) #24

Open probonopd opened 2 years ago

probonopd commented 2 years ago

Our objective is to ultimately run multiple Dexed instances at the same time (#12).

Sound generators like the TX816 and TX802 use the performance sysex format. We should support it.

probonopd commented 2 years ago

UPDATE: Looks like MicroDexed already has code to handle performance sysex: https://codeberg.org/dcoredump/MicroDexed/src/branch/master/dexed_sd.cpp#L576

It even has code for effects sysex. Are those compatible to any Japanese OEM device @dcoredump?

So we "just" need to port dexed_sd.cpp over to Circle?

dcoredump commented 2 years ago

UPDATE: Looks like MicroDexed already has code to handle performance sysex: https://codeberg.org/dcoredump/MicroDexed/src/branch/master/dexed_sd.cpp#L576

It even has code for effects sysex. Are those compatible to any Japanese OEM device @dcoredump?

So we "just" need to port dexed_sd.cpp over to Circle?

Yes, in fact this is what I want to do. But I think it would be better to put the code into Synth_Dexed (without the file handling code) due to it has no dependence to the used OS/uC. So it is easier to maintain errors in the code.

Wdyt?

probonopd commented 2 years ago

Agree. Same for effects.

By the way, do you know a documentation of the TX802 PCED format?

rsta2 commented 2 years ago

Have a look at this:

https://github.com/asb2m10/dexed/blob/master/Documentation/TX802-SYSEX.pdf

It may contain the wanted info.

probonopd commented 2 years ago

TX802_Factory_Performances.syx is available on GitHub.

This is the original factory performance data for the TX802. There are 54 performances. The remander of them are the "Init" performance with the name removed for better esthetic value. These were programmed buy hand and tripple checked against the original performance lists that came with the TX802.

Let's use this file as the test for loading performances.

https://github.com/weekend-at-bernies/sysex_utils/tree/master/patches/yamaha_TX802 has more information.

rsta2 commented 2 years ago

I had a look at the sysex performance file format and extended the class CSysExFileLoader respectively. Up to 32 files can be loaded from /sysex/performance. The filenames have the same format as used for voice banks. There is a method GetPerformance(), which returns the data for one performance in the PMEM format:

struct TPMEMData
{
    struct
    {
        uint8_t RXCH    : 5,
            VCHOFS  : 3;
    }
    VCHOFS_RXCH[8];

    uint8_t VNUM[8];
    uint8_t MTTNUM[8];
    uint8_t OUTVOL[8];

    struct
    {
        uint8_t OUTCH   : 2,
            KASG    : 1,
            DETUNE  : 4,
            Ignore  : 1;
    }
    DETUNE_KASG_OUTCH[8];

    uint8_t NLMTL[8];
    uint8_t NLMTH[8];

    struct
    {
        uint8_t NSHFT   : 6,
            FDAMP   : 1,
            Ignore  : 1;
    }
    FDAMP_NSHFT[8];

    uint8_t PNAM[20];
};

Currently the meaning of the parameters VCHOFS (voice channel offset), MTTNUM (tuning) and KASG (key assign group) is not fully clear to me.

I could send a PR for the extended class CSysExFileLoader. I tested it by dumping the data of some performances. There is a method DumpPerformance() included.

What is not clear at the moment is, how this can be added to the UI? Maybe a menu item "PERFORMANCE", where one can "scroll" though the different performances of the first loaded file, would be a possible solution. The default value can be "NONE", which means, that the parameters have to be configured manually as before.

If we want to use the factory performance file for testing, we also need the factory voice banks, because the performances reference these voices. I don't know, if it is legal to include these voice banks into MiniDexed?

probonopd commented 2 years ago

Here are first spontaneous thoughts. Will need to think more about this.

Looking at page 14+ of the TX802 user manual, I am not sure whether Dexed supports everything that the TX802 supports. Also, I don't find a description of "voice channel offset", "tuning", and "key assign group" in the user manual. In this case, shall we just leave the such parameters in performance sysex as "ignored"/unimplemented for now? Maybe we can find a TX802 owner to help us a bit with information at some time to understand those.

But reading the User user manual, I have wonder which of the performance features are really widely understod by users and actually used (I think we have the most important ones covered already in the performance .ini) and which ones may be rather esoteric and seldomly used. Maybe we should just stay with performance .ini files, add a way to switch between different performance .ini files, and maybe optimize them a bit? Wdyt?

As for the GUI, maybe we need a "top level menu" that would one allow to, e.g., "Select Performance", "Edit TG1-TG8" (what we have so far), etc.?

probonopd commented 2 years ago

If we want to use the factory performance file for testing, we also need the factory voice banks, because the performances reference these voices.

With "use this file as the test for loading performances" I meant during development and testing. Not to ship those performances by default. So we don't have to ship the matching voices by default.

rsta2 commented 2 years ago

TX802 compatibility is not easy to reach. Perhaps we can go for this in a future version. For now I would agree to use multiple .ini files. We could provide a tool for converting performance .syx files to .ini files.

I think we cannot support all performance parameters of the TX802, but the note low and high limits and note shift are still possible, also in the .ini file. This would allow to split a keyboard for playing different voices.

We should think about the UI menus again from a user perspective. What we have at the moment was only a first approach. I think we need some menu tree and should use the rotary encoder in a way, that it is easy to use, for example:

A question is also, if it makes sense to provide all voice parameters for editing? It's probably much more easy to use the original Dexed to edit voices, but to click through many menus in the MiniDexed UI to change some parameter.

probonopd commented 2 years ago

Fully agree.

I don't think we need TX802 compatibility, unless soemone really has the need for it, wants to do it, and maybe a TX802 owner steps up to help us. Low and high limits and note shift would be useful indeed, would be great to have them available.

For the UI menus I was thinking of extactly something as you are describing, which is very similar to how typicsl 3D printer menus work.

Maybe we can use graphical arrow symbols (triangles) in the LCD to show what turning a knob changes. Like this:

image

Turning the knob here would change Detune to another parameter.

Clicking here would change to

image

Turning the knob here would change the value of Detune.

Maybe we could use a 1-digit triangle symbol instead of 2-digit <-, ->. Or maybe we should use the blinking cursor for this purpose?

I have never had a chance to use an actual DX7 but it uses the same exact display as we do. Maybe it'd be worthwhile to study how the menu is structured there (albeit that user interface was often criticized, and the DX7 has many hardware buttons which we don't.)

rsta2 commented 2 years ago

Yes, that UI idea is good. The character set of the LCD is here. Perhaps we should use the arrows 0x7E and 0x7F. It is also possible to define and use eight user characters (5x7 pixel matrix). The blinking block cursor is also available, but I personally would prefer the arrows. I had a look into the DX7 Manual, which gives some info about the available menus, but yes, we have only one knob, so we need a different concept.

I'm currently testing the USB FIQ support for Circle to ensure nothing is broken after some modifications. When I'm ready with this, I would implement the note limits and shift, and when there would be a concept for the (new) UI, I could work on this.

probonopd commented 2 years ago

Closing for now as we are using .ini files for performances. Please comment below if you think this (or parts of it) should be reopened.

probonopd commented 1 year ago

Reopening due to renewed interest in being able to parse DX1/DX5/TX7/... performance sysex.

Based on the information from https://github.com/probonopd/MiniDexed/discussions/554 (thanks @BobanSpasic) this is what I have:

// Load TX7 performance data from a file
// and show the values of the parameters

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <stdexcept>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

typedef unsigned char byte;
typedef byte PMEM_Dump[64];
typedef byte PCED_Dump[94];

// PCED (Performance Edit)
// PCED contais performance data, including settings for voices, effects, and other parameters

typedef struct {
  byte A_NU0;                      //       Reserved (not used in TX7)
  byte A_NU1;                      //       Reserved (not used in TX7) (MIDI Channel)
  byte A_PolyMono;                 //       0-1
  byte A_PitchBendRange;           //       0-12
  byte A_PitchBendStep;            //       0-12
  byte A_PortamentoTime;           //       0-99
  byte A_PortaGlissando;           //       0-1
  byte A_PortamentoMode;           //       0-1
  byte A_NU8;                      //       Reserved (not used in TX7)
  byte A_ModWheelSens;             //       0-15  translates to 0-99 for DX7
  byte A_ModWheelAssign;           //       0-7
  byte A_FootCtrlSens;             //       0-15  translates to 0-99 for DX7
  byte A_FootCtrlAssign;           //       0-7
  byte A_AfterTouchSens;           //       0-15  translates to 0-99 for DX7
  byte A_AfterTouchAssign;         //       0-7
  byte A_BrthCtrlSens;             //       0-15  translates to 0-99 for DX7
  byte A_BrthCtrlAssign;           //       0-7
  byte A_NU17;                     //       Reserved (not used in TX7)
  byte A_NU18;                     //       Reserved (not used in TX7)
  byte A_NU19;                     //       Reserved (not used in TX7)
  byte A_NU20;                     //       Reserved (not used in TX7)
  byte A_NU21;                     //       Reserved (not used in TX7)
  byte A_NU22;                     //       Reserved (not used in TX7)
  byte A_NU23;                     //       Reserved (not used in TX7)
  byte A_NU24;                     //       Reserved (not used in TX7)
  byte A_NU25;                     //       Reserved (not used in TX7)
  byte A_VoiceAttn;                //       0-7  translates to 0-99 for DX7
  byte A_NU27;                     //       Reserved (not used in TX7)
  byte A_NU28;                     //       Reserved (not used in TX7)
  byte A_NU29;                     //       Reserved (not used in TX7)

  byte B_NU0;                      //       Reserved (not used in TX7)
  byte B_NU1;                      //       Reserved (not used in TX7)
  byte B_PolyMono;                 //       0-1
  byte B_PitchBendRange;           //       0-12
  byte B_PitchBendStep;            //       0-12
  byte B_PortamentoTime;           //       0-99
  byte B_PortaGlissando;           //       0-1
  byte B_PortamentoMode;           //       0-1
  byte B_NU8;                      //       Reserved (not used in TX7)
  byte B_ModWheelSens;             //       0-15  translates to 0-99 for DX7
  byte B_ModWheelAssign;           //       0-7
  byte B_FootCtrlSens;             //       0-15  translates to 0-99 for DX7
  byte B_FootCtrlAssign;           //       0-7
  byte B_AfterTouchSens;           //       0-15  translates to 0-99 for DX7
  byte B_AfterTouchAssign;         //       0-7
  byte B_BrthCtrlSens;             //       0-15  translates to 0-99 for DX7
  byte B_BrthCtrlAssign;           //       0-7
  byte B_NU17;                     //       Reserved (not used in TX7)
  byte B_NU18;                     //       Reserved (not used in TX7)
  byte B_NU19;                     //       Reserved (not used in TX7)
  byte B_NU20;                     //       Reserved (not used in TX7)
  byte B_NU21;                     //       Reserved (not used in TX7)
  byte B_NU22;                     //       Reserved (not used in TX7)
  byte B_NU23;                     //       Reserved (not used in TX7)
  byte B_NU24;                     //       Reserved (not used in TX7)
  byte B_NU25;                     //       Reserved (not used in TX7)
  byte B_VoiceAttn;                //       0-7  translates to 0-99 for DX7
  byte B_NU27;                     //       Reserved (not used in TX7)
  byte B_NU28;                     //       Reserved (not used in TX7)
  byte B_NU29;                     //       Reserved (not used in TX7)

  byte G_NU60;                     //       Reserved (not used in TX7)
  byte G_VoiceMemSelFlag;          //       0-1
  byte G_NU62;                     //       Reserved (not used in TX7)
  byte G_NU63;                     //       Reserved (not used in TX7)
  byte G_PerfName01;               //       ASCII
  byte G_PerfName02;               //       ASCII
  byte G_PerfName03;               //       ASCII
  byte G_PerfName04;               //       ASCII
  byte G_PerfName05;               //       ASCII
  byte G_PerfName06;               //       ASCII
  byte G_PerfName07;               //       ASCII
  byte G_PerfName08;               //       ASCII
  byte G_PerfName09;               //       ASCII
  byte G_PerfName10;               //       ASCII
  byte G_PerfName11;               //       ASCII
  byte G_PerfName12;               //       ASCII
  byte G_PerfName13;               //       ASCII
  byte G_PerfName14;               //       ASCII
  byte G_PerfName15;               //       ASCII
  byte G_PerfName16;               //       ASCII
  byte G_PerfName17;               //       ASCII
  byte G_PerfName18;               //       ASCII
  byte G_PerfName19;               //       ASCII
  byte G_PerfName20;               //       ASCII
  byte G_PerfName21;               //       ASCII
  byte G_PerfName22;               //       ASCII
  byte G_PerfName23;               //       ASCII
  byte G_PerfName24;               //       ASCII
  byte G_PerfName25;               //       ASCII
  byte G_PerfName26;               //       ASCII
  byte G_PerfName27;               //       ASCII
  byte G_PerfName28;               //       ASCII
  byte G_PerfName29;               //       ASCII
  byte G_PerfName30;               //       ASCII
} PCED_Params;

// PMEM (Performance Memory)
// PMEM  contains performance data, including settings for voices, effects, and other parameters

typedef struct {
  byte A_PolyMono;                 //       PM |    |    |    |    |    |    |
  byte A_PBSlo_PBR;                //          PBS Lo    |        PBR        |
  byte A_PortaTime;                //       0-99
  byte A_PM_PGL;                   //       0  |                   | M  | GL |
  byte A_MWA_MWS;                  //           MWA      |        MWS        |
  byte A_FCA_FCS;                  //           FCA      |        FCS        |
  byte A_ATA_ATS;                  //           ATA      |        ATS        |
  byte A_BCA_BCS;                  //           BCA      |        BCS        |
  byte A_NU08;
  byte A_NU09;
  byte A_NU10;
  byte A_NU11;
  byte A_NU12;
  byte A_NU13;
  byte A_ATN;                      //       0 |               |    ATN       |
  byte A_PBShi;                    //       (MSB)

  byte B_PolyMono;                 //       PM |    |    |    |    |    |    |
  byte B_PBSlo_PBR;                //          PBS Lo    |        PBR        |
  byte B_PortaTime;                //       0-99
  byte B_PM_PGL;                   //       0  |                   | M  | GL |
  byte B_MWA_MWS;                  //           MWA      |        MWS        |
  byte B_FCA_FCS;                  //           FCA      |        FCS        |
  byte B_ATA_ATS;                  //           ATA      |        ATS        |
  byte B_BCA_BCS;                  //           BCA      |        BCS        |
  byte B_NU08;
  byte B_NU09;
  byte B_NU10;
  byte B_NU11;
  byte B_NU12;
  byte B_NU13;
  byte B_ATN;                      //       0 |               |    ATN       |
  byte B_PBShi;                    //       PS|

  byte G_VMS_KMOD;                 //       0 |    |    |    | VMS|   KMOD   |
  byte G_NU33;
  byte G_PerfName01;               //       ASCII
  byte G_PerfName02;               //       ASCII
  byte G_PerfName03;               //       ASCII
  byte G_PerfName04;               //       ASCII
  byte G_PerfName05;               //       ASCII
  byte G_PerfName06;               //       ASCII
  byte G_PerfName07;               //       ASCII
  byte G_PerfName08;               //       ASCII
  byte G_PerfName09;               //       ASCII
  byte G_PerfName10;               //       ASCII
  byte G_PerfName11;               //       ASCII
  byte G_PerfName12;               //       ASCII
  byte G_PerfName13;               //       ASCII
  byte G_PerfName14;               //       ASCII
  byte G_PerfName15;               //       ASCII
  byte G_PerfName16;               //       ASCII
  byte G_PerfName17;               //       ASCII
  byte G_PerfName18;               //       ASCII
  byte G_PerfName19;               //       ASCII
  byte G_PerfName20;               //       ASCII
  byte G_PerfName21;               //       ASCII
  byte G_PerfName22;               //       ASCII
  byte G_PerfName23;               //       ASCII
  byte G_PerfName24;               //       ASCII
  byte G_PerfName25;               //       ASCII
  byte G_PerfName26;               //       ASCII
  byte G_PerfName27;               //       ASCII
  byte G_PerfName28;               //       ASCII
  byte G_PerfName29;               //       ASCII
  byte G_PerfName30;               //       ASCII
} PMEM_Params;

// Performance syx from DX5

/*
$FO start of System Exclusive
$43 Yamaha Identification
$00 Sub-status and channel (ssss nnnn, where n = MIDI channel)
$09 Format number
$20 Byte count MSB
$00 Byte count LSB ($2000 = 4096)
*/

const uint8_t example_DX5_PerfData[] = {
    // Header
    0xf0, // Start of System Exclusive
    0x43, // Manufacturer Yamaha
    0x00, // $00 Sub-status and channel (ssss nnnn, where n = MIDI channel)
    0x02, // Format number
    0x20, 0x00, // Byte count MSB: $2000 = 4096

    // Performance data (4096 bytes)
    0x0a, 0x02, 0x00, 0x06, 
    0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1d, 0x0c, 0x2a, 0x02, 0x00, 0x06, 0x1a, 0x70, 0x1b, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5d, 0x0c, 0x2d, 0x7e, 
    0x54, 0x4f, 0x4d, 0x20, 0x41, 0x4e, 0x44, 0x20, 0x44, 0x41, 
    0x56, 0x45, 0x20, 0x2d, 0x20, 0x49, 0x4e, 0x54, 0x52, 0x4f, 
    0x20, 0x46, 0x41, 0x44, 0x45, 0x42, 0x45, 0x4c, 0x4c, 0x53, 
    0x1e, 0x02, 0x00, 0x06, 0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1d, 0x1f, 0x3e, 0x02, 0x00, 0x06, 
    0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x5d, 0x18, 0x29, 0x7e, 0x54, 0x4f, 0x4d, 0x20, 0x41, 0x4e, 
    0x44, 0x20, 0x44, 0x41, 0x56, 0x45, 0x20, 0x2d, 0x20, 0x42, 
    0x4c, 0x4f, 0x43, 0x4b, 0x20, 0x46, 0x49, 0x46, 0x54, 0x48, 
    0x53, 0x20, 0x20, 0x20, 0x1d, 0x02, 0x00, 0x06, 0x19, 0x70, 
    0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 
    0x3d, 0x02, 0x00, 0x06, 0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x5e, 0x18, 0x29, 0x7e, 0x54, 0x4f, 
    0x4d, 0x20, 0x41, 0x4e, 0x44, 0x20, 0x44, 0x41, 0x56, 0x45, 
    0x20, 0x2d, 0x20, 0x4b, 0x4f, 0x54, 0x4f, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x12, 0x02, 
    0x00, 0x06, 0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1c, 0x18, 0x32, 0x02, 0x00, 0x06, 0x1a, 0x70, 
    0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5c, 0x18, 
    0x2d, 0x7e, 0x54, 0x4f, 0x4d, 0x20, 0x41, 0x4e, 0x44, 0x20, 
    0x44, 0x41, 0x56, 0x45, 0x20, 0x2d, 0x20, 0x4d, 0x41, 0x4c, 
    0x45, 0x20, 0x43, 0x48, 0x4f, 0x49, 0x52, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x14, 0x02, 0x00, 0x06, 0x19, 0x70, 0x3a, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 0x34, 0x02, 
    0x00, 0x06, 0x1a, 0x70, 0x1f, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x5e, 0x18, 0x29, 0x7e, 0x54, 0x4f, 0x4d, 0x20, 
    0x41, 0x4e, 0x44, 0x20, 0x44, 0x41, 0x56, 0x45, 0x20, 0x2d, 
    0x20, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x20, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x13, 0x02, 0x00, 0x06, 
    0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1f, 0x24, 0x33, 0x02, 0x00, 0x06, 0x1a, 0x70, 0x1b, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5f, 0x24, 0x2d, 0x7e, 
    0x54, 0x4f, 0x4d, 0x20, 0x41, 0x4e, 0x44, 0x20, 0x44, 0x41, 
    0x56, 0x45, 0x20, 0x2d, 0x20, 0x46, 0x4c, 0x55, 0x54, 0x45, 
    0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
    0x16, 0x02, 0x00, 0x06, 0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1d, 0x0c, 0x36, 0x02, 0x00, 0x06, 
    0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x5d, 0x0c, 0x2d, 0x7e, 0x54, 0x4f, 0x4d, 0x20, 0x41, 0x4e, 
    0x44, 0x20, 0x44, 0x41, 0x56, 0x45, 0x20, 0x2d, 0x20, 0x53, 
    0x54, 0x52, 0x49, 0x4e, 0x47, 0x53, 0x20, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x20, 0x53, 0x00, 0x02, 0x00, 0x06, 0x19, 0x70, 
    0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1d, 0x24, 
    0x20, 0x02, 0x00, 0x06, 0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x5d, 0x24, 0x2d, 0x7e, 0x54, 0x4f, 
    0x4d, 0x20, 0x41, 0x4e, 0x44, 0x20, 0x44, 0x41, 0x56, 0x45, 
    0x20, 0x2d, 0x20, 0x53, 0x4f, 0x4c, 0x4f, 0x4e, 0x47, 0x53, 
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x05, 0x02, 
    0x00, 0x06, 0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1d, 0x18, 0x25, 0x02, 0x00, 0x06, 0x1a, 0x70, 
    0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1d, 0x18, 
    0x09, 0x7e, 0x41, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x41, 0x20, 
    0x45, 0x4e, 0x44, 0x20, 0x4f, 0x46, 0x7e, 0x32, 0x4e, 0x44, 
    0x7e, 0x56, 0x45, 0x52, 0x53, 0x45, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x02, 0x02, 0x0a, 0x06, 0x19, 0x70, 0x2a, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 0x20, 0x02, 
    0x0a, 0x06, 0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x5d, 0x24, 0x25, 0x7e, 0x41, 0x4d, 0x45, 0x52, 
    0x49, 0x43, 0x41, 0x20, 0x49, 0x4e, 0x54, 0x52, 0x4f, 0x20, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x02, 0x02, 0x0a, 0x06, 
    0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1d, 0x18, 0x3f, 0x02, 0x0a, 0x06, 0x1a, 0x70, 0x1b, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5e, 0x18, 0x21, 0x7e, 
    0x41, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x41, 0x20, 0x4d, 0x49, 
    0x44, 0x20, 0x43, 0x48, 0x4f, 0x52, 0x44, 0x53, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x05, 0x02, 0x00, 0x06, 0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1d, 0x18, 0x22, 0x02, 0x00, 0x06, 
    0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1d, 0x18, 0x0d, 0x7e, 0x47, 0x49, 0x52, 0x4c, 0x53, 0x20, 
    0x44, 0x41, 0x4e, 0x43, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x32, 
    0x4e, 0x44, 0x7e, 0x56, 0x45, 0x52, 0x53, 0x45, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x1e, 0x02, 0x00, 0x1e, 0x19, 0x70, 
    0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1d, 0x24, 
    0x3a, 0x02, 0x00, 0x26, 0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x5d, 0x24, 0x01, 0x7e, 0x4c, 0x4f, 
    0x56, 0x45, 0x20, 0x41, 0x4e, 0x44, 0x20, 0x4d, 0x4f, 0x4e, 
    0x45, 0x59, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x45, 
    0x51, 0x55, 0x45, 0x4e, 0x43, 0x45, 0x2e, 0x7e, 0x1d, 0x02, 
    0x00, 0x1e, 0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1d, 0x0c, 0x34, 0x02, 0x00, 0x26, 0x1a, 0x70, 
    0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5c, 0x00, 
    0x05, 0x7e, 0x4c, 0x4f, 0x56, 0x45, 0x20, 0x41, 0x4e, 0x44, 
    0x20, 0x4d, 0x4f, 0x4e, 0x45, 0x59, 0x2e, 0x20, 0x4d, 0x49, 
    0x44, 0x20, 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x45, 
    0x2e, 0x7e, 0x1f, 0x02, 0x00, 0x1e, 0x19, 0x70, 0x2a, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 0x20, 0x02, 
    0x00, 0x26, 0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x5d, 0x24, 0x05, 0x7e, 0x47, 0x49, 0x52, 0x4c, 
    0x53, 0x20, 0x44, 0x41, 0x4e, 0x43, 0x45, 0x2d, 0x20, 0x4d, 
    0x49, 0x44, 0x20, 0x43, 0x48, 0x4f, 0x52, 0x44, 0x53, 0x2e, 
    0x20, 0x20, 0x20, 0x20, 0x20, 0x7e, 0x08, 0x02, 0x00, 0x1e, 
    0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1d, 0x0c, 0x3d, 0x02, 0x00, 0x1e, 0x1a, 0x70, 0x1b, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5f, 0x18, 0x15, 0x7e, 
    0x48, 0x4c, 0x41, 0x44, 0x20, 0x56, 0x45, 0x52, 0x53, 0x45, 
    0x53, 0x2e, 0x20, 0x20, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x08, 0x02, 0x00, 0x06, 0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 0x28, 0x02, 0x00, 0x06, 
    0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x5e, 0x18, 0x21, 0x7e, 0x57, 0x44, 0x59, 0x43, 0x57, 0x4d, 
    0x20, 0x20, 0x49, 0x4e, 0x54, 0x52, 0x4f, 0x20, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x1c, 0x02, 0x10, 0x06, 0x19, 0x70, 
    0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1f, 0x18, 
    0x3c, 0x02, 0x10, 0x06, 0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x5f, 0x18, 0x21, 0x7e, 0x57, 0x44, 
    0x59, 0x43, 0x57, 0x4d, 0x20, 0x4d, 0x45, 0x4c, 0x4f, 0x44, 
    0x59, 0x20, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x14, 0x02, 
    0x00, 0x06, 0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1e, 0x0c, 0x34, 0x02, 0x00, 0x06, 0x1a, 0x70, 
    0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5e, 0x0c, 
    0x21, 0x7e, 0x57, 0x44, 0x59, 0x43, 0x57, 0x4d, 0x20, 0x20, 
    0x4f, 0x52, 0x47, 0x41, 0x4e, 0x20, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x00, 0x02, 0x00, 0x06, 0x19, 0x70, 0x2a, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1f, 0x2b, 0x28, 0x02, 
    0x00, 0x06, 0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1f, 0x2b, 0x21, 0x7e, 0x57, 0x44, 0x59, 0x43, 
    0x57, 0x4d, 0x20, 0x20, 0x53, 0x4f, 0x4c, 0x4f, 0x20, 0x31, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00, 0x02, 0x00, 0x06, 
    0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1f, 0x24, 0x28, 0x02, 0x00, 0x06, 0x1a, 0x70, 0x1b, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1f, 0x24, 0x21, 0x7e, 
    0x57, 0x44, 0x59, 0x43, 0x57, 0x4d, 0x20, 0x20, 0x53, 0x4f, 
    0x4c, 0x4f, 0x20, 0x32, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x08, 0x02, 0x00, 0x06, 0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1f, 0x24, 0x28, 0x02, 0x00, 0x06, 
    0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x5f, 0x24, 0x11, 0x7e, 0x57, 0x44, 0x59, 0x43, 0x57, 0x4d, 
    0x20, 0x4f, 0x55, 0x54, 0x52, 0x4f, 0x2e, 0x20, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x1a, 0x02, 0x00, 0x1e, 0x19, 0x70, 
    0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1d, 0x18, 
    0x3a, 0x02, 0x00, 0x1e, 0x1a, 0x70, 0x1b, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x5d, 0x18, 0x25, 0x7e, 0x4d, 0x41, 
    0x4b, 0x49, 0x4e, 0x20, 0x57, 0x49, 0x53, 0x48, 0x45, 0x53, 
    0x20, 0x2d, 0x20, 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 
    0x45, 0x2e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x14, 0x02, 
    0x00, 0x06, 0x19, 0x70, 0x2a, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1e, 0x18, 0x34, 0x02, 0x00, 0x06, 0x1a, 0x70, 
    0x1b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5e, 0x18, 
    0x25, 0x7e, 0x4d, 0x41, 0x4b, 0x49, 0x4e, 0x20, 0x57, 0x49, 
    0x53, 0x48, 0x45, 0x53, 0x2d, 0x20, 0x4f, 0x52, 0x47, 0x41, 
    0x4e, 0x2e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x1f, 0x4c, 0x7e, 0x06, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1d, 0x58, 0x29, 0x4c, 
    0x7e, 0x06, 0x7e, 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x5d, 0x4c, 0x19, 0x7e, 0x4f, 0x4e, 0x45, 0x20, 
    0x53, 0x54, 0x45, 0x50, 0x20, 0x41, 0x54, 0x20, 0x41, 0x20, 
    0x54, 0x49, 0x4d, 0x45, 0x2e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x11, 0x18, 
    0x49, 0x11, 0x39, 0x37, 0x11, 0x24, 0x31, 0x11, 0x2e, 0x31, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x01, 0x2e, 0x40, 0x7e, 0x01, 0x18, 0x40, 
    0x01, 0x39, 0x40, 0x01, 0x24, 0x40, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x11, 0x33, 0x71, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x01, 0x33, 0x40, 0x11, 0x37, 0x52, 0x7e, 0x7e, 0x7e, 0x01, 
    0x37, 0x40, 0x11, 0x35, 0x5c, 0x7e, 0x7e, 0x7e, 0x7e, 0x01, 
    0x35, 0x40, 0x11, 0x33, 0x68, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x01, 0x33, 0x40, 0x11, 0x32, 0x5c, 0x7e, 0x7e, 
    0x01, 0x32, 0x40, 0x7e, 0x11, 0x30, 0x55, 0x7e, 0x7e, 0x01, 
    0x30, 0x40, 0x11, 0x32, 0x4f, 0x7e, 0x7e, 0x01, 0x32, 0x40, 
    0x11, 0x33, 0x5c, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x01, 0x33, 0x40, 0x11, 0x37, 0x43, 0x7e, 0x7e, 0x01, 0x37, 
    0x40, 0x11, 0x35, 0x4f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x01, 
    0x35, 0x40, 0x11, 0x33, 0x68, 0x7e, 0x7e, 0x01, 0x33, 0x40, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 
    0x7e, 0x7e, 0x7e, 0x7e, 0x00, 0x02, 0x00, 0x06, 0x19, 0x70, 
    0x3a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 
    0x20, 0x02, 0x00, 0x06, 0x1a, 0x70, 0x1f, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x5e, 0x18, 0x2d, 0x7e, 0x46, 0x41, 
    0x54, 0x48, 0x45, 0x52, 0x20, 0x50, 0x41, 0x52, 0x53, 0x4f, 
    0x4e, 0x2d, 0x20, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x2d, 0x4d, 
    0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x04, 0x02, 
    0x00, 0x06, 0x19, 0x70, 0x3a, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1e, 0x18, 0x2b, 0x02, 0x00, 0x06, 0x1a, 0x70, 
    0x1f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5e, 0x18, 
    0x2d, 0x7e, 0x46, 0x41, 0x54, 0x48, 0x45, 0x52, 0x20, 0x50, 
    0x41, 0x52, 0x53, 0x4f, 0x4e, 0x2d, 0x20, 0x4f, 0x52, 0x47, 
    0x41, 0x4e, 0x2d, 0x4d, 0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x10, 0x02, 0x00, 0x06, 0x19, 0x70, 0x3a, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 0x2a, 0x02, 
    0x00, 0x06, 0x1a, 0x70, 0x1f, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x5e, 0x18, 0x2d, 0x7e, 0x46, 0x41, 0x54, 0x48, 
    0x45, 0x52, 0x20, 0x50, 0x41, 0x52, 0x53, 0x4f, 0x4e, 0x2d, 
    0x20, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x2d, 0x4d, 0x49, 0x44, 
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0c, 0x02, 0x00, 0x06, 
    0x19, 0x70, 0x3a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1e, 0x18, 0x3e, 0x02, 0x00, 0x06, 0x1a, 0x70, 0x1f, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5e, 0x18, 0x2d, 0x7e, 
    0x46, 0x41, 0x54, 0x48, 0x45, 0x52, 0x20, 0x50, 0x41, 0x52, 
    0x53, 0x4f, 0x4e, 0x2d, 0x20, 0x4f, 0x52, 0x47, 0x41, 0x4e, 
    0x2d, 0x4d, 0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
    0x0d, 0x02, 0x00, 0x06, 0x19, 0x70, 0x3a, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 0x24, 0x02, 0x00, 0x06, 
    0x1a, 0x70, 0x1f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x5e, 0x18, 0x2d, 0x7e, 0x46, 0x41, 0x54, 0x48, 0x45, 0x52, 
    0x20, 0x50, 0x41, 0x52, 0x53, 0x4f, 0x4e, 0x2d, 0x20, 0x4f, 
    0x52, 0x47, 0x41, 0x4e, 0x2d, 0x4d, 0x49, 0x44, 0x20, 0x20, 
    0x20, 0x20, 0x20, 0x20, 0x11, 0x02, 0x00, 0x06, 0x19, 0x70, 
    0x3a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 
    0x3c, 0x02, 0x00, 0x06, 0x1a, 0x70, 0x1f, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x5e, 0x18, 0x2d, 0x7e, 0x46, 0x41, 
    0x54, 0x48, 0x45, 0x52, 0x20, 0x50, 0x41, 0x52, 0x53, 0x4f, 
    0x4e, 0x2d, 0x20, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x2d, 0x4d, 
    0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1c, 0x02, 
    0x01, 0x06, 0x19, 0x70, 0x3a, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1e, 0x18, 0x32, 0x02, 0x01, 0x06, 0x1a, 0x70, 
    0x1f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5e, 0x18, 
    0x2d, 0x7e, 0x46, 0x41, 0x54, 0x48, 0x45, 0x52, 0x20, 0x50, 
    0x41, 0x52, 0x53, 0x4f, 0x4e, 0x2d, 0x20, 0x4f, 0x52, 0x47, 
    0x41, 0x4e, 0x2d, 0x4d, 0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x1c, 0x02, 0x01, 0x06, 0x19, 0x70, 0x3a, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 0x31, 0x02, 
    0x01, 0x06, 0x1a, 0x70, 0x1f, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x5e, 0x18, 0x2d, 0x7e, 0x46, 0x41, 0x54, 0x48, 
    0x45, 0x52, 0x20, 0x50, 0x41, 0x52, 0x53, 0x4f, 0x4e, 0x2d, 
    0x20, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x2d, 0x4d, 0x49, 0x44, 
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1e, 0x02, 0x00, 0x24, 
    0x17, 0x2f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1f, 0x18, 0x3f, 0x02, 0x00, 0x1c, 0x17, 0x2f, 0x18, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1f, 0x24, 0x05, 0x27, 
    0x44, 0x52, 0x4b, 0x2d, 0x20, 0x48, 0x4c, 0x41, 0x44, 0x2e, 
    0x20, 0x20, 0x49, 0x4e, 0x54, 0x52, 0x4f, 0x20, 0x2d, 0x20, 
    0x46, 0x49, 0x52, 0x53, 0x54, 0x2e, 0x20, 0x20, 0x20, 0x20, 
    0x00, 0x02, 0x0c, 0x04, 0x17, 0x20, 0x18, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1d, 0x24, 0x31, 0x02, 0x0c, 0x04, 
    0x17, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1e, 0x18, 0x1d, 0x27, 0x44, 0x52, 0x4b, 0x2d, 0x20, 0x48, 
    0x4f, 0x57, 0x4c, 0x20, 0x4c, 0x49, 0x4b, 0x45, 0x20, 0x41, 
    0x20, 0x44, 0x4f, 0x47, 0x2e, 0x20, 0x49, 0x4e, 0x54, 0x52, 
    0x4f, 0x20, 0x20, 0x20, 0x00, 0x02, 0x00, 0x04, 0x17, 0x20, 
    0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1c, 0x24, 
    0x25, 0x02, 0x00, 0x04, 0x17, 0x20, 0x17, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1d, 0x18, 0x1d, 0x2a, 0x48, 0x4f, 
    0x57, 0x4c, 0x20, 0x4c, 0x49, 0x4b, 0x45, 0x20, 0x41, 0x20, 
    0x44, 0x4f, 0x47, 0x2d, 0x20, 0x43, 0x48, 0x4f, 0x52, 0x55, 
    0x53, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0b, 0x07, 
    0x00, 0x06, 0x18, 0x08, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x17, 0x18, 0x2b, 0x07, 0x00, 0x06, 0x18, 0x08, 
    0x08, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x17, 0x18, 
    0x00, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x0c, 0x00, 0x00, 0x04, 0x17, 0x00, 0x18, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1d, 0x30, 0x2a, 0x00, 
    0x00, 0x04, 0x17, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1f, 0x24, 0x01, 0x27, 0x44, 0x52, 0x4b, 0x2d, 
    0x20, 0x41, 0x20, 0x43, 0x45, 0x52, 0x54, 0x41, 0x49, 0x4e, 
    0x20, 0x4b, 0x49, 0x53, 0x53, 0x20, 0x49, 0x4e, 0x54, 0x52, 
    0x4f, 0x20, 0x53, 0x51, 0x55, 0x2e, 0x14, 0x02, 0x00, 0x04, 
    0x17, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1f, 0x18, 0x34, 0x02, 0x00, 0x04, 0x17, 0x00, 0x18, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1f, 0x18, 0x2d, 0x27, 
    0x44, 0x52, 0x4b, 0x2d, 0x20, 0x41, 0x20, 0x43, 0x45, 0x52, 
    0x54, 0x41, 0x49, 0x4e, 0x2e, 0x20, 0x4c, 0x41, 0x53, 0x54, 
    0x20, 0x53, 0x4f, 0x4c, 0x4f, 0x20, 0x20, 0x20, 0x20, 0x20, 
    0x1c, 0x05, 0x0f, 0x04, 0x1a, 0x00, 0x17, 0x40, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1f, 0x18, 0x3c, 0x05, 0x13, 0x04, 
    0x19, 0x00, 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1f, 0x18, 0x2d, 0x18, 0x41, 0x20, 0x43, 0x45, 0x52, 0x54, 
    0x41, 0x49, 0x4e, 0x20, 0x4b, 0x49, 0x53, 0x53, 0x2d, 0x20, 
    0x47, 0x54, 0x52, 0x20, 0x45, 0x4e, 0x44, 0x20, 0x55, 0x4e, 
    0x49, 0x53, 0x4f, 0x4e, 0x1b, 0x02, 0x00, 0x04, 0x17, 0x2f, 
    0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 
    0x2d, 0x02, 0x00, 0x04, 0x17, 0x2f, 0x18, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1f, 0x18, 0x18, 0x27, 0x41, 0x20, 
    0x43, 0x45, 0x52, 0x54, 0x41, 0x49, 0x4e, 0x20, 0x4b, 0x49, 
    0x53, 0x53, 0x2d, 0x20, 0x53, 0x49, 0x4c, 0x4c, 0x59, 0x20, 
    0x53, 0x4f, 0x55, 0x4e, 0x44, 0x20, 0x31, 0x2e, 0x1c, 0x02, 
    0x00, 0x06, 0x19, 0x70, 0x3a, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1e, 0x18, 0x24, 0x02, 0x00, 0x06, 0x1a, 0x70, 
    0x1f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5d, 0x18, 
    0x29, 0x7e, 0x46, 0x41, 0x54, 0x48, 0x45, 0x52, 0x20, 0x50, 
    0x41, 0x52, 0x53, 0x4f, 0x4e, 0x2d, 0x20, 0x4f, 0x52, 0x47, 
    0x41, 0x4e, 0x2d, 0x4d, 0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x1c, 0x02, 0x00, 0x06, 0x19, 0x70, 0x3a, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x1f, 0x34, 0x02, 
    0x00, 0x06, 0x1a, 0x70, 0x1f, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x5e, 0x18, 0x01, 0x30, 0x46, 0x41, 0x54, 0x48, 
    0x45, 0x52, 0x20, 0x50, 0x41, 0x52, 0x53, 0x4f, 0x4e, 0x2d, 
    0x20, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x2d, 0x4d, 0x49, 0x44, 
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x02, 0x07, 0x06, 
    0x19, 0x70, 0x3a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1f, 0x24, 0x35, 0x02, 0x07, 0x06, 0x1a, 0x70, 0x1f, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5e, 0x24, 0x01, 0x30, 
    0x46, 0x41, 0x54, 0x48, 0x45, 0x52, 0x20, 0x50, 0x41, 0x52, 
    0x53, 0x4f, 0x4e, 0x2d, 0x20, 0x4f, 0x52, 0x47, 0x41, 0x4e, 
    0x2d, 0x4d, 0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
    0x00, 0x02, 0x07, 0x06, 0x19, 0x70, 0x3a, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1f, 0x24, 0x25, 0x02, 0x07, 0x06, 
    0x1a, 0x70, 0x1f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1f, 0x18, 0x05, 0x30, 0x46, 0x41, 0x54, 0x48, 0x45, 0x52, 
    0x20, 0x50, 0x41, 0x52, 0x53, 0x4f, 0x4e, 0x2d, 0x20, 0x4f, 
    0x52, 0x47, 0x41, 0x4e, 0x2d, 0x4d, 0x49, 0x44, 0x20, 0x20, 
    0x20, 0x20, 0x20, 0x20, 0x00, 0x02, 0x07, 0x06, 0x19, 0x70, 
    0x3a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1f, 0x24, 
    0x22, 0x02, 0x07, 0x06, 0x1a, 0x70, 0x1f, 0x70, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x5f, 0x24, 0x05, 0x11, 0x46, 0x41, 
    0x54, 0x48, 0x45, 0x52, 0x20, 0x50, 0x41, 0x52, 0x53, 0x4f, 
    0x4e, 0x2d, 0x20, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x2d, 0x4d, 
    0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x02, 
    0x07, 0x06, 0x19, 0x70, 0x3a, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1f, 0x24, 0x20, 0x02, 0x07, 0x06, 0x1a, 0x70, 
    0x1f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5e, 0x1f, 
    0x05, 0x11, 0x46, 0x41, 0x54, 0x48, 0x45, 0x52, 0x20, 0x50, 
    0x41, 0x52, 0x53, 0x4f, 0x4e, 0x2d, 0x20, 0x4f, 0x52, 0x47, 
    0x41, 0x4e, 0x2d, 0x4d, 0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x1b, 0x02, 0x00, 0x06, 0x19, 0x70, 0x3a, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 0x3b, 0x02, 
    0x00, 0x06, 0x1a, 0x70, 0x1f, 0x70, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x5e, 0x18, 0x2d, 0x3a, 0x46, 0x41, 0x54, 0x48, 
    0x45, 0x52, 0x20, 0x50, 0x41, 0x52, 0x53, 0x4f, 0x4e, 0x2d, 
    0x20, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x2d, 0x4d, 0x49, 0x44, 
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x06, 0x02, 0x00, 0x06, 
    0x19, 0x70, 0x3a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1e, 0x18, 0x32, 0x02, 0x00, 0x06, 0x1a, 0x70, 0x1f, 0x70, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x5d, 0x18, 0x2d, 0x7e, 
    0x46, 0x41, 0x54, 0x48, 0x45, 0x52, 0x20, 0x50, 0x41, 0x52, 
    0x53, 0x4f, 0x4e, 0x2d, 0x20, 0x4f, 0x52, 0x47, 0x41, 0x4e, 
    0x2d, 0x4d, 0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
    0x09, 0x02, 0x00, 0x04, 0x17, 0x2f, 0x18, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 0x31, 0x02, 0x00, 0x04, 
    0x17, 0x20, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1e, 0x18, 0x1d, 0x2a, 0x53, 0x48, 0x41, 0x4d, 0x45, 0x20, 
    0x4f, 0x4e, 0x20, 0x59, 0x4f, 0x55, 0x2d, 0x20, 0x49, 0x4e, 
    0x54, 0x52, 0x4f, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x20, 0x20, 0x00, 0x02, 0x00, 0x04, 0x17, 0x2f, 
    0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x24, 
    0x21, 0x02, 0x00, 0x04, 0x17, 0x20, 0x1f, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1d, 0x18, 0x1d, 0x2a, 0x54, 0x48, 
    0x49, 0x53, 0x20, 0x49, 0x53, 0x20, 0x49, 0x54, 0x2e, 0x20, 
    0x43, 0x48, 0x4f, 0x52, 0x55, 0x53, 0x20, 0x4d, 0x45, 0x4c, 
    0x4f, 0x44, 0x59, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x00, 0x02, 
    0x00, 0x04, 0x17, 0x2f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1e, 0x24, 0x21, 0x02, 0x00, 0x04, 0x17, 0x20, 
    0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 
    0x19, 0x2a, 0x54, 0x48, 0x49, 0x53, 0x20, 0x49, 0x53, 0x20, 
    0x49, 0x54, 0x2e, 0x20, 0x4d, 0x49, 0x44, 0x20, 0x20, 0x20, 
    0x20, 0x4d, 0x45, 0x4c, 0x4f, 0x44, 0x59, 0x2e, 0x20, 0x20, 
    0x20, 0x20, 0x00, 0x02, 0x00, 0x04, 0x17, 0x2f, 0x18, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x24, 0x25, 0x02, 
    0x00, 0x04, 0x17, 0x20, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1e, 0x18, 0x1d, 0x2a, 0x54, 0x48, 0x49, 0x53, 
    0x20, 0x49, 0x53, 0x20, 0x49, 0x54, 0x2e, 0x20, 0x53, 0x4f, 
    0x4c, 0x4f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x18, 0x02, 0x00, 0x04, 
    0x17, 0x2f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1f, 0x24, 0x35, 0x02, 0x00, 0x04, 0x17, 0x20, 0x1f, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x24, 0x1d, 0x2a, 
    0x53, 0x48, 0x41, 0x4d, 0x45, 0x20, 0x4f, 0x4e, 0x20, 0x55, 
    0x2e, 0x20, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x20, 0x53, 
    0x4f, 0x4c, 0x4f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
    0x14, 0x02, 0x00, 0x1c, 0x17, 0x20, 0x18, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x1e, 0x0c, 0x34, 0x02, 0x00, 0x24, 
    0x17, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 
    0x1e, 0x0c, 0x19, 0x27, 0x44, 0x52, 0x4b, 0x2d, 0x57, 0x48, 
    0x41, 0x54, 0x20, 0x41, 0x42, 0x4f, 0x55, 0x54, 0x2d, 0x20, 
    0x43, 0x48, 0x4f, 0x52, 0x55, 0x53, 0x20, 0x4f, 0x52, 0x47, 
    0x41, 0x4e, 0x2e, 0x20, 0x14, 0x02, 0x00, 0x04, 0x17, 0x20, 
    0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1e, 0x18, 
    0x34, 0x02, 0x00, 0x04, 0x17, 0x20, 0x18, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x63, 0x63, 0x5e, 0x18, 0x19, 0x27, 0x44, 0x52, 
    0x4b, 0x2d, 0x57, 0x48, 0x41, 0x54, 0x20, 0x41, 0x42, 0x4f, 
    0x55, 0x54, 0x2d, 0x20, 0x20, 0x56, 0x45, 0x52, 0x53, 0x45, 
    0x20, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x2e, 0x20, 0x0d, 0x07, 
    0x00, 0x04, 0x17, 0x2f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x63, 0x63, 0x1e, 0x0c, 0x3b, 0x07, 0x00, 0x1c, 0x10, 0x20, 
    0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x1f, 0x0c, 
    0x04, 0x27, 0x44, 0x52, 0x4b, 0x2d, 0x20, 0x48, 0x4c, 0x41, 
    0x44, 0x2e, 0x20, 0x20, 0x49, 0x4e, 0x54, 0x52, 0x4f, 0x20, 
    0x2d, 0x20, 0x46, 0x49, 0x52, 0x53, 0x54, 0x2e, 0x20, 0x20, 
    0x20, 0x20,

    // Tail
    0x7f, // Checksum
    0xf7  // End of sysex
};

// Number of bytes in the array above: 4104

// Total size of the sysex dump is thus 4096+6+2 = 4104 bytes
// Header is 6 bytes (start of sysex and manufacturer)
// Tail is 2 bytes (checksum and end of sysex)

// PMEM is 64 bytes
// PCED is 94 bytes

// So how can we parse the sysex dump into PMEM and PCED?
BobanSpasic commented 1 year ago

Performance Bank = Header + 64xPMEM_Dump + Tail Single Performance= Header + 1xPCED_Dump + Tail

Internaly, you work with PCED. So, after loading a bank, you pick one PMEM and translate it to PCED, and you use it.

The SysEx headers of PCED and PMEM are different.

Writting from my phone, thus the message edits.

For TX7, one sysex file usualy contains both VMEM and PMEM data, and it is 8192 bytes long. For DX7II, you have VMEM and AMEM in one file, some 5kb long. We could also use this AMEM, it contains usable data for performance.ini The files from DX5 you posted, here is PMEM in a separate file. TX802 is freaky, performance sysex is a 12kb ASCII file. For TX816, I can't say from the top of my head, but it should go into readable category (either TX7 or DX7II alike)

probonopd commented 1 year ago

So far I have figured out that the example_DX5_PerfData is sysex header + 64xPMEM + sysex tail. My current objective is to make performance.ini files that match the factory performances of the DX5.

probonopd commented 1 year ago

Using this Python script

with open("/tmp/user/_home_user_Downloads_DX5 Carts.zip/DX5 Performance.syx", "rb") as file:
    data = file.read()

# Remove the first 6 bytes (the header) from the data, this is the sysex header
data = data[6:]

# Put the data into a list of 64-byte PMEMs, but only the first 64 ones
pmems = [data[i:i+64] for i in range(0, len(data), 64)][:64]

pmem_params = {
    "A_PolyMono": "Poly/Mono for voice A",
    "A_PBSlo_PBR": "Pitch Bend Slope and Pitch Bend Range for voice A",
    "A_PortaTime": "Portamento Time for voice A",
    "A_PM_PGL": "Pitch Modulation and Pitch Glide for voice A",
    "A_MWA_MWS": "Mod Wheel Assign and Mod Wheel Sensitivity for voice A",
    "A_FCA_FCS": "Foot Control Assign and Foot Control Sensitivity for voice A",
    "A_ATA_ATS": "Aftertouch Assign and Aftertouch Sensitivity for voice A",
    "A_BCA_BCS": "Breath Control Assign and Breath Control Sensitivity for voice A",
    "A_NU08": "Unknown",
    "A_NU09": "Unknown",
    "A_NU10": "Unknown",
    "A_NU11": "Unknown",
    "A_NU12": "Unknown",
    "A_NU13": "Unknown",
    "A_ATN": "Aftertouch Noise for voice A",
    "A_PBShi": "Pitch Bend Shift for voice A",
    "B_PolyMono": "Poly/Mono for voice B",
    "B_PBSlo_PBR": "Pitch Bend Slope and Pitch Bend Range for voice B",
    "B_PortaTime": "Portamento Time for voice B",
    "B_PM_PGL": "Pitch Modulation and Pitch Glide for voice B",
    "B_MWA_MWS": "Mod Wheel Assign and Mod Wheel Sensitivity for voice B",
    "B_FCA_FCS": "Foot Control Assign and Foot Control Sensitivity for voice B",
    "B_ATA_ATS": "Aftertouch Assign and Aftertouch Sensitivity for voice B",
    "B_BCA_BCS": "Breath Control Assign and Breath Control Sensitivity for voice B",
    "B_NU08": "Unknown",
    "B_NU09": "Unknown",
    "B_NU10": "Unknown",
    "B_NU11": "Unknown",
    "B_NU12": "Unknown",
    "B_NU13": "Unknown",
    "B_ATN": "Aftertouch Noise for voice B",
    "B_PBShi": "Pitch Bend Shift for voice B",
    "G_VMS_KMOD": "Voice Mode and Keyboard Mode for voice group G",
    "G_NU33": "Unknown"
}

i = 0
for pmem in pmems:
    i += 1
    print(f"PMEM {i}")
    print("Name: %s" % pmem[-30:].decode("ascii"))

    # Print all parameters in 0x00 format,
    j = 0
    for param in pmem_params.keys():
        print(f"{pmem_params[param]}: 0x{pmem[j]:02x}")
        j += 1
    print("")

# Remove the first 64*64 bytes
data = data[64*64:]

# Print the number of bytes remaining
print(f"Bytes remaining: {len(data)}")

# Print the remaining bytes in 0x00 format
print("Remaining bytes:")
for byte in data:
    print(f"0x{byte:02x} ", end="")
print(" - this is the MIDI sysex checksum and end-of-transmission byte.")

the data is parsed to

PMEM 1
Name: TOM AND DAVE - INTRO FADEBELLS
Poly/Mono for voice A: 0x0a
Pitch Bend Slope and Pitch Bend Range for voice A: 0x02
Portamento Time for voice A: 0x00
Pitch Modulation and Pitch Glide for voice A: 0x06
Mod Wheel Assign and Mod Wheel Sensitivity for voice A: 0x19
Foot Control Assign and Foot Control Sensitivity for voice A: 0x70
Aftertouch Assign and Aftertouch Sensitivity for voice A: 0x2a
Breath Control Assign and Breath Control Sensitivity for voice A: 0x70
Unknown: 0x00
Unknown: 0x00
Unknown: 0x00
Unknown: 0x00
Unknown: 0x63
Unknown: 0x63
Aftertouch Noise for voice A: 0x1d
Pitch Bend Shift for voice A: 0x0c
Poly/Mono for voice B: 0x2a
Pitch Bend Slope and Pitch Bend Range for voice B: 0x02
Portamento Time for voice B: 0x00
Pitch Modulation and Pitch Glide for voice B: 0x06
Mod Wheel Assign and Mod Wheel Sensitivity for voice B: 0x1a
Foot Control Assign and Foot Control Sensitivity for voice B: 0x70
Aftertouch Assign and Aftertouch Sensitivity for voice B: 0x1b
Breath Control Assign and Breath Control Sensitivity for voice B: 0x70
Unknown: 0x00
Unknown: 0x00
Unknown: 0x00
Unknown: 0x00
Unknown: 0x63
Unknown: 0x63
Aftertouch Noise for voice B: 0x5d
Pitch Bend Shift for voice B: 0x0c
Voice Mode and Keyboard Mode for voice group G: 0x2d
Unknown: 0x7e

(...)

PMEM 64
Name: DRK- HLAD.  INTRO - FIRST.    
Poly/Mono for voice A: 0x0d
Pitch Bend Slope and Pitch Bend Range for voice A: 0x07
Portamento Time for voice A: 0x00
Pitch Modulation and Pitch Glide for voice A: 0x04
Mod Wheel Assign and Mod Wheel Sensitivity for voice A: 0x17
Foot Control Assign and Foot Control Sensitivity for voice A: 0x2f
Aftertouch Assign and Aftertouch Sensitivity for voice A: 0x18
Breath Control Assign and Breath Control Sensitivity for voice A: 0x00
Unknown: 0x00
Unknown: 0x00
Unknown: 0x00
Unknown: 0x00
Unknown: 0x63
Unknown: 0x63
Aftertouch Noise for voice A: 0x1e
Pitch Bend Shift for voice A: 0x0c
Poly/Mono for voice B: 0x3b
Pitch Bend Slope and Pitch Bend Range for voice B: 0x07
Portamento Time for voice B: 0x00
Pitch Modulation and Pitch Glide for voice B: 0x1c
Mod Wheel Assign and Mod Wheel Sensitivity for voice B: 0x10
Foot Control Assign and Foot Control Sensitivity for voice B: 0x20
Aftertouch Assign and Aftertouch Sensitivity for voice B: 0x10
Breath Control Assign and Breath Control Sensitivity for voice B: 0x00
Unknown: 0x00
Unknown: 0x00
Unknown: 0x00
Unknown: 0x00
Unknown: 0x63
Unknown: 0x63
Aftertouch Noise for voice B: 0x1f
Pitch Bend Shift for voice B: 0x0c
Voice Mode and Keyboard Mode for voice group G: 0x04
Unknown: 0x27

Bytes remaining: 2
Remaining bytes:
0x7f 0xf7  - this is the MIDI sysex checksum and end-of-transmission byte.

This is puzzling me. I was expecting to see, for each performance, which combination of voices is being used (what is voice A, what is voice B), which detune is used, etc. but apparently the example_DX5_PerfData does not contain this data?

I was hoping to recreate from page 8 of the DX5 manual:

image

BRASS

STRING

KEYBOARD

COMPLEX

SYNTH

EFFECT

In addition to the voices used (documented in the manual), we would also need to know the other performance parameters.

BobanSpasic commented 1 year ago

I don't know how DX5 is working, but for TX7 is so - selecting perormance 01 will take A1 for first, and B1 for second voice. P2 = A2+B2 etc

Btw. TX7 needs a DX7. Bank A sounds are generated from TX7, Bank B from the DX7 connected over MIDI.

probonopd commented 1 year ago

I don't know how DX5 is working, but for TX7 is so - selecting perormance 01 will take A1 for first, and B1 for second voice. P2 = A2+B2 etc

I can confirm that this seems to be the scheme for the DX5 too:

performance_names = ["DOUBLE HORN SECTION (DETUNED)",
"FANFARE TRUMPETS 1-2",
"FULL SYNTH BRASS (DETUNED)",
"TIGHT BRASS SECTION",
"SYNTH BRASS",
"SYNTH BRASS [F/C CHORUS]",
"С580 BRASS [F/C VIBRATO]",
"STRINGS & BRASS ENSEMBLE",
"CELLO QUARTET",
"VIOLIN ENSEMBLE",
"ENSEMBLE [L]/SOLO VIOLIN [R]",
"STRING ORCHESTRA",
"HIGH STRINGS (ANALOG TYPE)",
"CELLOS & VIOLINS",
"STRING ENSEMBLE [F/C VIBRATO]",
"STRINGS & VELOCITY TRUMPETS",
"ACOUSTIC GRAND PIANO 1",
"ACOUSTIC GRAND PIANO 2",
"ELECTRIC GRAND PIANO",
"ELECTRIC PIANO [M/W TREMOLO]",
"ELECTRIC PIANO (BRIGHT TINE}",
"DIRTY ELECTRIC PIANO",
"CLAV.ENSEMBLE",
"GRAND HARPSICHORD",
"PIPE ORGAN",
"JAZZ ORGAN",
"ROCK ORGAN WITH OLD TONE CAB",
"E.PIANO [L]/JAZZ GUITAR [R]",
"ELEC. BASS",
"DOUBLE HARPS",
"AFRICAN MALLETS",
"VIBRAPHONE",
"ELECTRIC PIANO & BRASS [BC1]",
"ELECTRIC GRAND & BRASS [BC1]",
"ELECTRIC PIANO & SAX [ВС1]",
"ELEC. PIANO & CLAV ENSEMBLE",
"ELECTRIC PIANO & STRINGS",
"HARPSICHORD & STRING ENSEMBLE",
"FULL ORCHESTRA",
"RIDE CYMBAL",
"KICK DRUM [L]/SNARE [R]",
"НІ-НАТ CLOSING: [L/CYMBAL [R]",
"НАND CLAPS [L]/TOM TOMS [R]",
"LOG DRUMS [LI/ROTO TOMS [9]",
"TAMBOURINE [L]/TIMBALI [R]",
"COWBELL [L]/WOOD BLOCK [R]",
"FRETLESS BASS [L]/SAX [ВС1] [R]",
"ACOUSTIC PIANO [L]/FLUTE [R]",
"SYNTHESIZER UPRISING",
"SAMPLE 8 HOLD [L]/LEAD LINE [R]",
"POLY SYNTH [L]/LEAD SYNTH [R]",
"PERCUSSIVE SYNTH",
"TOY MUSIC BOX",
"FM ENSEMBLE",
"PLANET OF ICE",
"MALE & FEMALE CHOIR",
"\"BIG BEN\" [L]/TUNED BELLS [R]",
"GLASS WIND CHIMES",
"JUNGLE NOISE (GROWL/BIRDS)",
"SIDE TO SIDE",
"TRAFFIC",
"FLOATING CLOUDS",
"COMBAT (EXPLOSION [L]; GUNS [R])",
"BOMBS AWAY!!"]

filename_a = "/tmp/user/_home_user_Downloads_DX5 Carts.zip/DX5A1.SYX"
with open(filename_a, "rb") as file:
    data_a = file.read()
basename_a = filename_a.split("/")[-1]

filename_b = "/tmp/user/_home_user_Downloads_DX5 Carts.zip/DX5B1.SYX"
with open(filename_b, "rb") as file:
    data_b = file.read()
basename_b = filename_b.split("/")[-1]

# Remove the first 6 bytes (the header) from the data, this is the sysex header
data_a = data_a[6:]
data_b = data_b[6:]

# Put the data into a list of 128-byte ones, but only the first 32 ones
voices_a = [data_a[i:i+128] for i in range(0, 128*32, 128)]
voices_b = [data_b[i:i+128] for i in range(0, 128*32, 128)]
voicenames_a = []
voicenames_b = []
i = 0
for voice_a in voices_a:
    i += 1
    voicenames_a.append(voice_a[-10:].decode("ascii"))
for voice_b in voices_b:
    i += 1
    voicenames_b.append(voice_b[-10:].decode("ascii"))

for i in range(0, 32):
    print("* %i `%s`: `%s` `%s` + `%s` `%s`" % (i+1, performance_names[i], basename_a, voicenames_a[i], basename_b, voicenames_b[i]))

filename_a = "/tmp/user/_home_user_Downloads_DX5 Carts.zip/DX5A2.SYX"
with open(filename_a, "rb") as file:
    data_a = file.read()
basename_a = filename_a.split("/")[-1]

filename_b = "/tmp/user/_home_user_Downloads_DX5 Carts.zip/DX5B2.SYX"
with open(filename_b, "rb") as file:
    data_b = file.read()
basename_b = filename_b.split("/")[-1]

# Remove the first 6 bytes (the header) from the data, this is the sysex header
data_a = data_a[6:]
data_b = data_b[6:]

# Put the data into a list of 128-byte ones, but only the first 32 ones
voices_a = [data_a[i:i+128] for i in range(0, 128*32, 128)]
voices_b = [data_b[i:i+128] for i in range(0, 128*32, 128)]
voicenames_a = []
voicenames_b = []
i = 0
for voice_a in voices_a:
    voicenames_a.append(voice_a[-10:].decode("ascii"))
for voice_b in voices_b:
    voicenames_b.append(voice_b[-10:].decode("ascii"))

for i in range(0, 32):
    print("* %i `%s`: `%s` `%s` + `%s` `%s`" % (i+33, performance_names[i+32], basename_a, voicenames_a[i], basename_b, voicenames_b[i]))