Skip to content

MIDI messages for MiniDexed Performance parameters #915

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open

Conversation

probonopd
Copy link
Owner

@probonopd probonopd commented May 11, 2025

So far, MiniDexed Performances were not entirely editable via MIDI commands.

To change this, and to allow for interactive ways to change the performance parameters in user interfaces like this, we need MIDI commands.

image

Proposed MiniDexed Performance SysEx Message Format (still subject to change)

F0 7D XX pp pp vv vv F7

Where:

  • F0 and F7 are the start and end of the SysEx message.
  • 7D is the Manufacturer ID reserved for prototyping, test, private use and experimentation.
  • XX
    • 10 is the get (dump) command ID for MiniDexed global performance parameter request.
    • 11 is the get (dump) command ID for per-TG performance parameter request.
    • 20 is the set (write) command ID for MiniDexed global performance parameter change.
    • 21 is the set (write) command ID for per-TG performance parameter change.
  • pp is the parameter number.
  • vv vv is the parameter value (or empty if requesting a dump).
  • The sequence pp pp vv vv may be repeated as often as needed if more than one parameter shall be set.

To request a dump of the corresponding value, leave the vv vv away.

To request a dump of all global parameters:

F0 7D 10 F7

The response to this get request will be in the format:

F0 7D 20 pp pp vv vv pp pp vv vv F7

To request a dump of all parameters of TG nn:

F0 7D 11 nn F7

The response to this get request will be in the format:

F0 7D 21 nn pp pp vv vv pp pp vv vv F7

Table 1: Global Parameters (Non-Tone Generator-Specific)

Parameter SysEx Command (MiniDexed Format) Allowed Values (vv vv)
CompressorEnable F0 7D 10 00 00 F7 (get) / F0 7D 20 00 00 vv vv F7 (set) 00 00 (off) .. 00 01 (on)
ReverbEnable F0 7D 10 00 01 F7 (get) / F0 7D 20 00 01 vv vv F7 (set) 00 00 (off) .. 00 01 (on)
ReverbSize F0 7D 10 00 02 F7 (get) / F0 7D 20 00 02 vv vv F7 (set) 00 00 (0) .. 00 63 (99)
ReverbHighDamp F0 7D 10 00 03 F7 (get) / F0 7D 20 00 03 vv vv F7 (set) 00 00 (0) .. 00 63 (99)
ReverbLowDamp F0 7D 10 00 04 F7 (get) / F0 7D 20 00 04 vv vv F7 (set) 00 00 (0) .. 00 63 (99)
ReverbLowPass F0 7D 10 00 05 F7 (get) / F0 7D 20 00 05 vv vv F7 (set) 00 00 (0) .. 00 63 (99)
ReverbDiffusion F0 7D 10 00 06 F7 (get) / F0 7D 20 00 06 vv vv F7 (set) 00 00 (0) .. 00 63 (99)
ReverbLevel F0 7D 10 00 07 F7 (get) / F0 7D 20 00 07 vv vv F7 (set) 00 00 (0) .. 00 63 (99)

Table 2: Tone Generator-Specific Parameters

Parameter SysEx Command (MiniDexed Format) Allowed Values (vv vv)
BankNumber F0 7D 11 nn 00 00 F7 / F0 7D 21 nn 00 00 vv vv F7 00 00 (0) .. 00 7F (127)
VoiceNumber F0 7D 11 nn 00 01 F7 / F0 7D 21 nn 00 01 vv vv F7 00 00 (0) .. 00 1F (31)
MIDIChannel F0 7D 11 nn 00 02 F7 / F0 7D 21 nn 00 02 vv vv F7 00 00 (0) .. 00 0F (15), 00 10 (omni), 00 11 (off)
Volume F0 7D 11 nn 00 03 F7 / F0 7D 21 nn 00 03 vv vv F7 00 00 (0) .. 00 7F (127)
Pan F0 7D 11 nn 00 04 F7 / F0 7D 21 nn 00 04 vv vv F7 00 00 (0) .. 00 7F (127)
Detune F0 7D 11 nn 00 05 F7 / F0 7D 21 nn 00 05 vv vv F7 3F 1D (-99) .. 00 63 (99) 7-bit note
Cutoff F0 7D 11 nn 00 06 F7 / F0 7D 21 nn 00 06 vv vv F7 00 00 (0) .. 00 63 (99)
Resonance F0 7D 11 nn 00 07 F7 / F0 7D 21 nn 00 07 vv vv F7 00 00 (0) .. 00 63 (99)
NoteLimitLow F0 7D 11 nn 00 08 F7 / F0 7D 21 nn 00 08 vv vv F7 00 00 (0) .. 00 7F (127)
NoteLimitHigh F0 7D 11 nn 00 09 F7 / F0 7D 21 nn 00 09 vv vv F7 00 00 (0) .. 00 7F (127)
NoteShift F0 7D 11 nn 00 0A F7 / F0 7D 21 nn 00 0A vv vv F7 3F 38 (-24) .. 00 18 (24) 7-bit note
ReverbSend F0 7D 11 nn 00 0B F7 / F0 7D 21 nn 00 0B vv vv F7 00 00 (0) .. 00 7F (127)
PitchBendRange F0 7D 11 nn 00 0C F7 / F0 7D 21 nn 00 0C vv vv F7 00 00 (0) .. 00 0C (12)
PitchBendStep F0 7D 11 nn 00 0D F7 / F0 7D 21 nn 00 0D vv vv F7 00 00 (0) .. 00 0C (12)
PortamentoMode F0 7D 11 nn 00 0E F7 / F0 7D 21 nn 00 0E vv vv F7 00 00 (off) .. 00 01 (on)
PortamentoGlissando F0 7D 11 nn 00 0F F7 / F0 7D 21 nn 00 0F vv vv F7 00 00 (off) .. 00 01 (on)
PortamentoTime F0 7D 11 nn 00 10 F7 / F0 7D 21 nn 00 10 vv vv F7 00 00 (0) .. 00 63 (99)
MonoMode F0 7D 11 nn 00 11 F7 / F0 7D 21 nn 00 11 vv vv F7 00 00 (off) .. 00 01 (on)
ModWheelRange F0 7D 11 nn 00 12 F7 / F0 7D 21 nn 00 12 vv vv F7 00 00 (0) .. 00 63 (99)
ModWheelTarget F0 7D 11 nn 00 13 F7 / F0 7D 21 nn 00 13 vv vv F7 00 00 .. 00 07
FootCtrlRange F0 7D 11 nn 00 14 F7 / F0 7D 21 nn 00 14 vv vv F7 00 00 (0) .. 00 63 (99)
FootCtrlTarget F0 7D 11 nn 00 15 F7 / F0 7D 21 nn 00 15 vv vv F7 00 00 .. 00 07
BreathCtrlRange F0 7D 11 nn 00 16 F7 / F0 7D 21 nn 00 16 vv vv F7 00 00 (0) .. 00 63 (99)
BreathCtrlTarget F0 7D 11 nn 00 17 F7 / F0 7D 21 nn 00 17 vv vv F7 00 00 .. 00 07
AftertouchRange F0 7D 11 nn 00 18 F7 / F0 7D 21 nn 00 18 vv vv F7 00 00 (0) .. 00 63 (99)
AftertouchTarget F0 7D 11 nn 00 19 F7 / F0 7D 21 nn 00 19 vv vv F7 00 00 .. 00 07

Notes:

  • For get (dump) requests: Leave the vv vv field empty. For example, to get the CompressorEnable status:

    F0 7D 10 00 00 F7
    

    The system will respond with:

    F0 7D 20 00 00 00 01 F7
    

    indicating the value is 00 01 (on).

  • For set (write) requests: Include the vv vv field to specify the value. For example, to set the CompressorEnable to on:

    F0 7D 20 00 00 00 01 F7
    

    This writes the value 00 01 (on) to the CompressorEnable parameter.

  • 7-bit note: For signed values (Detune, NoteShift), use 2's complement (2 bytes across two 7-bit bytes), split into two MIDI-safe 7-bit bytes:

    • Detune: 3F 1D (-99) .. 00 63 (99)
    • NoteShift: 3F 38 (-24) .. 00 18 (24)
  • For boolean values, 00 00 = off/false, 00 01 = on/true.

  • For MIDI Channel: 00 00 (0) .. 00 0F (15), 00 10 (omni), 00 11 (off).

  • nn in the SysEx command is the Tone Generator (TG) number, not the MIDI channel.

  • For unknown or unsupported parameter numbers, or malformed SysEx messages, the system should simply ignore the message and take no action.

Copy link

Build for testing:
MiniDexed_1182_2025-05-11-d701bcd_32bit
MiniDexed_1182_2025-05-11-d701bcd_64bit
Use at your own risk.

@soyersoyer
Copy link
Contributor

For signed values (Detune, NoteShift), use 2's complement, 2 bytes:

Detune: FF 9D (-99) .. 00 63 (99)
NoteShift: FF E8 (-24) .. 00 18 (24)

SysEX bytes are 7 bits, so I don't think this will work in this way.

@probonopd
Copy link
Owner Author

How on earth can you be so quick to figure this stuff out?

Copy link

Build for testing:
MiniDexed_1183_2025-05-11-97622b0_32bit
MiniDexed_1183_2025-05-11-97622b0_64bit
Use at your own risk.

@probonopd
Copy link
Owner Author

probonopd commented May 11, 2025

The Performance Editor in https://github.com/probonopd/MiniDexed_Service_Utility/releases/tag/continuous should now work with this. Still a bit rough around the edges but it is a start.

@BobanSpasic
Copy link

On a real DX, you have two methods for signed values:

  • sign bit in a separate byte
  • translation (e.g. values -7 to 7 are sent over MIDI as 0 to 15)

SysEx are 7-bit just because the bit 8 is reserved for status byte. The bit 8 must not occur in data/values. Every occurrence of bit 8 will be a start of a new message for every device in the chain.
The summary on midi.org: https://midi.org/summary-of-midi-1-0-messages

@soyersoyer
Copy link
Contributor

soyersoyer commented May 12, 2025

How on earth can you be so quick to figure this stuff out?

I've seen a few sysex messages in the sysex-controls project :)

Have you seen how MIDI encodes the 14-bit signed Pitch-bend values with translation? The encoding could be similar here.

@probonopd
Copy link
Owner Author

@soyersoyer do you think using that scheme would have advantages over what I have described above?

Copy link

Build for testing:
MiniDexed_1184_2025-05-12-057b788_32bit
MiniDexed_1184_2025-05-12-057b788_64bit
Use at your own risk.

@soyersoyer
Copy link
Contributor

@soyersoyer do you think using that scheme would have advantages over what I have described above?

I think yes, consistency is better.

@diyelectromusic What do you think?

@diyelectromusic
Copy link
Collaborator

diyelectromusic commented May 12, 2025

@soyersoyer do you think using that scheme would have advantages over what I have described above?

I think yes, consistency is better.

@diyelectromusic What do you think?

To be honest, there is quite a lot to digest here and seems a bit of a change of heart from previous discussions where such things didn't seem to be wanted.

With regards to the specific comment re 14-bit MIDI values that is a standard MIDI way of doing things. We see it in pitch bend and with LSB/MSB pairing of bank numbers, and with LSB/MSB splits of CC messages, so that definitely ought to be the first option for anything more than 127 in my view.

With regards to this general idea - there are many options for this kind of thing and I'm a little nervous about apparently inventing yet another.

The DX7II I think has the various SysEx options already.

Some relevant previous discussions: #702 #604 #496 (comment) #504

As I recall things, the DX7 SysEx format has options for setting parameters and options for simulating DX7 button presses; and at some point it may be that using NRPNs makes more sense... And I have to admit I still quite liked my simple extension idea that allowed the UI TG messages to be passed over MIDI (more here) but that is not quite the same thing as this I think?

In short, I'd need to think about it a bit - but are we sure there aren't already existing mechanisms in the specs, even if not in MiniDexed at the moment? :)

Kevin

@probonopd
Copy link
Owner Author

Thanks for your feedback @diyelectromusic. The way I see it, "MiniDexed Performances" are their own thing that have no direct Yamaha equivalent. Hence there is no single, consistent Yamaha way to edit the parameters in them. Yes, you can set/get some values, but not all in a consistent way. This is why I thought of the above.

The whole NPRN thing I must admit I don't fully understand yet.

I don't think "MiniDexed Performances" must stay the only type of performances we support. I recently implemented the sysex for TX816 performances. And who says that no one will implement DX7II style and maybe even TX802 style performances as well one day, too? If so, we should use their native SysEx and in-memory format for them.

@diyelectromusic
Copy link
Collaborator

diyelectromusic commented May 12, 2025

Well the thinking behind my SysEx proposal that I used to extend the UI across devices was that we already had messages floating around the system for communicating TG and GLOBAL parameters around, so I just implemented a relatively simple mapping of them onto MIDI. That way, whenever a new parameter is added they are automatically recognised.

I don't know if that allows you to do everything you're proposing here, but it does have the advantage of allowing full remote control of anything settable in the MiniDexed UI over MIDI.

And whilst we have parameters not in the original spec for our MiniDexed performances, there is (as I recall) a fair bit of expandability built into the existing SysEx messages to add things rather than reimplement a new system.

But I've not looked at it for a while so would probably need to check again...

Kevin

@probonopd
Copy link
Owner Author

For the time being, we may consider the 7D stuff undocumented/experimental/subject to change. I just needed something like it to get ahead with the MiniDexed Service Utility.
To make communication fast and efficient, I was looking for a way to request/set one or multiple (or all) MiniDexed Voice Parameters in one message. I am not aware of an existing MIDI convention that does that. I took care to limit the whole MIDI vendor code 7D handling to one class (two files) as to not litter that into the rest of the system.

Copy link

Build for testing:
MiniDexed_1185_2025-05-14-86af00f_32bit
MiniDexed_1185_2025-05-14-86af00f_64bit
Use at your own risk.

@probonopd
Copy link
Owner Author

UPDATE: Proposed MiniDexed Performance SysEx Message Format

F0 7D XX pp pp vv vv F7

Where:

  • F0 and F7 are the start and end of the SysEx message.
  • 7D is the Manufacturer ID reserved for prototyping, test, private use and experimentation.
  • XX
    • 10 is the get (dump) command ID for MiniDexed global performance parameter request.
    • 11 is the get (dump) command ID for per-TG performance parameter request.
    • 20 is the set (write) command ID for MiniDexed global performance parameter change.
    • 21 is the set (write) command ID for per-TG performance parameter change.
  • pp is the parameter number.
  • vv vv is the parameter value (or empty if requesting a dump).
  • The sequence pp pp vv vv may be repeated as often as needed if more than one parameter shall be set.

To request a dump of the corresponding value, leave the vv vv away.

To request a dump of all global parameters:

F0 7D 10 F7

The response to this get request will be in the format:

F0 7D 20 pp pp vv vv pp pp vv vv F7

To request a dump of all parameters of TG nn:

F0 7D 11 nn F7

The response to this get request will be in the format:

F0 7D 21 nn pp pp vv vv pp pp vv vv F7

Table 1: Global Parameters (Non-Tone Generator-Specific)

Parameter SysEx Command (MiniDexed Format) Allowed Values (vv vv)
CompressorEnable F0 7D 10 00 00 F7 (get) / F0 7D 20 00 00 vv vv F7 (set) 00 00 (off) .. 00 01 (on)
ReverbEnable F0 7D 10 00 01 F7 (get) / F0 7D 20 00 01 vv vv F7 (set) 00 00 (off) .. 00 01 (on)
ReverbSize F0 7D 10 00 02 F7 (get) / F0 7D 20 00 02 vv vv F7 (set) 00 00 (0) .. 00 63 (99)
ReverbHighDamp F0 7D 10 00 03 F7 (get) / F0 7D 20 00 03 vv vv F7 (set) 00 00 (0) .. 00 63 (99)
ReverbLowDamp F0 7D 10 00 04 F7 (get) / F0 7D 20 00 04 vv vv F7 (set) 00 00 (0) .. 00 63 (99)
ReverbLowPass F0 7D 10 00 05 F7 (get) / F0 7D 20 00 05 vv vv F7 (set) 00 00 (0) .. 00 63 (99)
ReverbDiffusion F0 7D 10 00 06 F7 (get) / F0 7D 20 00 06 vv vv F7 (set) 00 00 (0) .. 00 63 (99)
ReverbLevel F0 7D 10 00 07 F7 (get) / F0 7D 20 00 07 vv vv F7 (set) 00 00 (0) .. 00 63 (99)

Table 2: Tone Generator-Specific Parameters

Parameter SysEx Command (MiniDexed Format) Allowed Values (vv vv)
BankNumber F0 7D 11 nn 00 00 F7 / F0 7D 21 nn 00 00 vv vv F7 00 00 (0) .. 00 7F (127)
VoiceNumber F0 7D 11 nn 00 01 F7 / F0 7D 21 nn 00 01 vv vv F7 00 00 (0) .. 00 1F (31)
MIDIChannel F0 7D 11 nn 00 02 F7 / F0 7D 21 nn 00 02 vv vv F7 00 00 (0) .. 00 0F (15), 00 10 (omni), 00 11 (off)
Volume F0 7D 11 nn 00 03 F7 / F0 7D 21 nn 00 03 vv vv F7 00 00 (0) .. 00 7F (127)
Pan F0 7D 11 nn 00 04 F7 / F0 7D 21 nn 00 04 vv vv F7 00 00 (0) .. 00 7F (127)
Detune F0 7D 11 nn 00 05 F7 / F0 7D 21 nn 00 05 vv vv F7 00 00 (-99) .. 00 63 (99) see note
Cutoff F0 7D 11 nn 00 06 F7 / F0 7D 21 nn 00 06 vv vv F7 00 00 (0) .. 00 63 (99)
Resonance F0 7D 11 nn 00 07 F7 / F0 7D 21 nn 00 07 vv vv F7 00 00 (0) .. 00 63 (99)
NoteLimitLow F0 7D 11 nn 00 08 F7 / F0 7D 21 nn 00 08 vv vv F7 00 00 (0) .. 00 7F (127)
NoteLimitHigh F0 7D 11 nn 00 09 F7 / F0 7D 21 nn 00 09 vv vv F7 00 00 (0) .. 00 7F (127)
NoteShift F0 7D 11 nn 00 0A F7 / F0 7D 21 nn 00 0A vv vv F7 00 00 (-24) .. 00 18 (24) see note
ReverbSend F0 7D 11 nn 00 0B F7 / F0 7D 21 nn 00 0B vv vv F7 00 00 (0) .. 00 7F (127)
PitchBendRange F0 7D 11 nn 00 0C F7 / F0 7D 21 nn 00 0C vv vv F7 00 00 (0) .. 00 0C (12)
PitchBendStep F0 7D 11 nn 00 0D F7 / F0 7D 21 nn 00 0D vv vv F7 00 00 (0) .. 00 0C (12)
PortamentoMode F0 7D 11 nn 00 0E F7 / F0 7D 21 nn 00 0E vv vv F7 00 00 (off) .. 00 01 (on)
PortamentoGlissando F0 7D 11 nn 00 0F F7 / F0 7D 21 nn 00 0F vv vv F7 00 00 (off) .. 00 01 (on)
PortamentoTime F0 7D 11 nn 00 10 F7 / F0 7D 21 nn 00 10 vv vv F7 00 00 (0) .. 00 63 (99)
MonoMode F0 7D 11 nn 00 11 F7 / F0 7D 21 nn 00 11 vv vv F7 00 00 (off) .. 00 01 (on)
ModWheelRange F0 7D 11 nn 00 12 F7 / F0 7D 21 nn 00 12 vv vv F7 00 00 (0) .. 00 63 (99)
ModWheelTarget F0 7D 11 nn 00 13 F7 / F0 7D 21 nn 00 13 vv vv F7 00 00 .. 00 07
FootCtrlRange F0 7D 11 nn 00 14 F7 / F0 7D 21 nn 00 14 vv vv F7 00 00 (0) .. 00 63 (99)
FootCtrlTarget F0 7D 11 nn 00 15 F7 / F0 7D 21 nn 00 15 vv vv F7 00 00 .. 00 07
BreathCtrlRange F0 7D 11 nn 00 16 F7 / F0 7D 21 nn 00 16 vv vv F7 00 00 (0) .. 00 63 (99)
BreathCtrlTarget F0 7D 11 nn 00 17 F7 / F0 7D 21 nn 00 17 vv vv F7 00 00 .. 00 07
AftertouchRange F0 7D 11 nn 00 18 F7 / F0 7D 21 nn 00 18 vv vv F7 00 00 (0) .. 00 63 (99)
AftertouchTarget F0 7D 11 nn 00 19 F7 / F0 7D 21 nn 00 19 vv vv F7 00 00 .. 00 07

Notes:

  • For get (dump) requests: Leave the vv vv field empty. For example, to get the CompressorEnable status:

    F0 7D 10 00 00 F7
    

    The system will respond with:

    F0 7D 20 00 00 00 01 F7
    

    indicating the value is 00 01 (on).

  • For set (write) requests: Include the vv vv field to specify the value. For example, to set the CompressorEnable to on:

    F0 7D 20 00 00 00 01 F7
    

    This writes the value 00 01 (on) to the CompressorEnable parameter.

  • Note on signed values (Detune, NoteShift):
    These are encoded using the standard MIDI 14-bit unsigned mapping, where the center (no detune/shift) is 8192 (0x2000).

    • To encode: value = signed + 8192 (so -99 maps to 8093, 0 maps to 8192, +99 maps to 8291 for Detune; -24 maps to 8168, 0 maps to 8192, +24 maps to 8216 for NoteShift)
    • The value is then split into two 7-bit bytes:
      • LSB = value & 0x7F
      • MSB = (value >> 7) & 0x7F
    • Example:
      • Detune -99: value = -99 + 8192 = 8093 → MSB = 63, LSB = 13 → 3F 0D
      • Detune +99: value = 99 + 8192 = 8291 → MSB = 64, LSB = 99 → 40 63
      • NoteShift -24: value = -24 + 8192 = 8168 → MSB = 63, LSB = 56 → 3F 38
      • NoteShift +24: value = 24 + 8192 = 8216 → MSB = 64, LSB = 24 → 40 18
  • For boolean values, 00 00 = off/false, 00 01 = on/true.

  • For MIDI Channel: 00 00 (0) .. 00 0F (15), 00 10 (omni), 00 11 (off).

  • nn in the SysEx command is the Tone Generator (TG) number, not the MIDI channel.

  • For unknown or unsupported parameter numbers, or malformed SysEx messages, the system should simply ignore the message and take no action.

Copy link

Build for testing:
MiniDexed_1186_2025-05-14-3967f77_32bit
MiniDexed_1186_2025-05-14-3967f77_64bit
Use at your own risk.

Copy link

Build for testing:
MiniDexed_1187_2025-05-18-783cc4f_32bit
Use at your own risk.

Copy link

Build for testing:
MiniDexed_1188_2025-05-18-2655aa3_32bit
MiniDexed_1188_2025-05-18-2655aa3_64bit
Use at your own risk.

@probonopd
Copy link
Owner Author

probonopd commented May 27, 2025

So, this is how the sysex maps to the ini:

MiniDexed Performance Parameter Specification

Global (Non-TG) Parameters

Parameter INI Key SysEx Param No. Type Bytes Min Max Default SysEx Value Encoding Notes
CompressorEnable CompressorEnable 0x0000 bool 1 0 1 1 00 00 (off), 00 01 (on)
ReverbEnable ReverbEnable 0x0001 bool 1 0 1 1 00 00 (off), 00 01 (on)
ReverbSize ReverbSize 0x0002 uint8 1 0 99 70 00 00 .. 00 63
ReverbHighDamp ReverbHighDamp 0x0003 uint8 1 0 99 50 00 00 .. 00 63
ReverbLowDamp ReverbLowDamp 0x0004 uint8 1 0 99 50 00 00 .. 00 63
ReverbLowPass ReverbLowPass 0x0005 uint8 1 0 99 30 00 00 .. 00 63
ReverbDiffusion ReverbDiffusion 0x0006 uint8 1 0 99 65 00 00 .. 00 63
ReverbLevel ReverbLevel 0x0007 uint8 1 0 99 99 00 00 .. 00 63

Tone Generator (TG) Parameters

(Each TG: 1–8, INI keys are suffixed with TG number, e.g. BankNumber1)

Parameter INI Key SysEx Param No. Type Bytes Min Max Default SysEx Value Encoding Notes
BankNumber BankNumber 0x0000 uint8 1 0 127 0 00 00 .. 00 7F Used if VoiceData is empty
VoiceNumber VoiceNumber 0x0001 uint8 1 1 32 1 00 00 .. 00 1F (0..31) 1-based in INI, 0-based in SysEx and internal
MIDIChannel MIDIChannel 0x0002 uint8 1 0 255 0 00 00..00 0F (0..15), 00 10 (omni), 00 11 (off) 0=off, 1–16=channel, >16=omni (internal: 255)
Volume Volume 0x0003 uint8 1 0 127 100 00 00 .. 00 7F
Pan Pan 0x0004 uint8 1 0 127 64 00 00 .. 00 7F Center=64
Detune Detune 0x0005 int8 1 -99 99 0 (see below)
Cutoff Cutoff 0x0006 uint8 1 0 99 99 00 00 .. 00 63
Resonance Resonance 0x0007 uint8 1 0 99 0 00 00 .. 00 63
NoteLimitLow NoteLimitLow 0x0008 uint8 1 0 127 0 00 00 .. 00 7F
NoteLimitHigh NoteLimitHigh 0x0009 uint8 1 0 127 127 00 00 .. 00 7F
NoteShift NoteShift 0x000A int8 1 -24 24 0 (see below)
ReverbSend ReverbSend 0x000B uint8 1 0 99 50 00 00 .. 00 63
PitchBendRange PitchBendRange 0x000C uint8 1 0 12 2 00 00 .. 00 0C
PitchBendStep PitchBendStep 0x000D uint8 1 0 12 0 00 00 .. 00 0C
PortamentoMode PortamentoMode 0x000E uint8 1 0 1 0 00 00 (off), 00 01 (on)
PortamentoGlissando PortamentoGlissando 0x000F uint8 1 0 1 0 00 00 (off), 00 01 (on)
PortamentoTime PortamentoTime 0x0010 uint8 1 0 99 0 00 00 .. 00 63
MonoMode MonoMode 0x0011 bool 1 0 1 0 00 00 (off), 00 01 (on)
ModulationWheelRange ModulationWheelRange 0x0012 uint8 1 0 99 99 00 00 .. 00 63
ModulationWheelTarget ModulationWheelTarget 0x0013 uint8 1 0 7 1 00 00 .. 00 07
FootControlRange FootControlRange 0x0014 uint8 1 0 99 99 00 00 .. 00 63
FootControlTarget FootControlTarget 0x0015 uint8 1 0 7 0 00 00 .. 00 07
BreathControlRange BreathControlRange 0x0016 uint8 1 0 99 99 00 00 .. 00 63
BreathControlTarget BreathControlTarget 0x0017 uint8 1 0 7 0 00 00 .. 00 07
AftertouchRange AftertouchRange 0x0018 uint8 1 0 99 99 00 00 .. 00 63
AftertouchTarget AftertouchTarget 0x0019 uint8 1 0 7 0 00 00 .. 00 07
VoiceData VoiceData bytes 156 "" Space-separated hex string, takes precedence if present

Encoding Notes

  • SysEx Parameter Numbers: 2 bytes, big-endian (e.g., 0x0005 = 00 05).
  • SysEx Values: 2 bytes, big-endian, 7-bit safe (MIDI).
  • Signed values (Detune, NoteShift): See table below
  • Boolean values: 00 00 = off/false, 00 01 = on/true.
  • MIDIChannel: 00 00 (off), 00 01..00 10 (channels 1–16), 00 11 (omni).
  • VoiceNumber: 1-based in INI, 0-based in SysEx/internal.
  • VoiceData: Not settable via SysEx; only in INI file.

Encoding for signed values:
value = signed + 8192 (center = 8192 = 0x2000)
LSB = value & 0x7F
MSB = (value >> 7) & 0x7F

Parameter Signed Value Encoded Value MSB (hex) LSB (hex) SysEx Bytes
Detune -99 8093 0x3F 0x0D 3F 0D
Detune 0 8192 0x40 0x00 40 00
Detune +99 8291 0x40 0x63 40 63
NoteShift -24 8168 0x3F 0x38 3F 38
NoteShift 0 8192 0x40 0x00 40 00
NoteShift +24 8216 0x40 0x18 40 18

SysEx Command Format

  • Global Get: F0 7D 10 F7 (response: F0 7D 20 ... F7)
  • TG Get: F0 7D 11 nn F7 (response: F0 7D 21 nn ... F7)
  • Global Set: F0 7D 20 pp pp vv vv ... F7
  • TG Set: F0 7D 21 nn pp pp vv vv ... F7

Example: Set TG1 Volume to 127

F0 7D 21 00 00 03 00 7F F7

(TG index is zero-based in SysEx.)

Example: Get all global parameters

F0 7D 10 F7

@probonopd
Copy link
Owner Author

Considerations on future-proofing:

  • Should we encode the number of TGs explicitly in the MIDI message, so that we can support more than 8 and make parsing easier?
  • Should we encode the number of global and per-TG parameters explicitly in the MIDI message, so that we can add future ones and make parsing easier?

@BobanSpasic
Copy link

For signed values (Detune, NoteShift):

* Encode as 2's complement, split into two 7-bit bytes (MSB, LSB).

Let me know if you need further details or a sample message!

Can any MIDI device send data in such encoding?
NoteShift fits in one byte, with center at 24.
For Detune in range -99 to +99, Yamaha would split it at one byte for the sign, and the other for the absolute value.

@probonopd
Copy link
Owner Author

Oops, that was a leftover from an earlier discussion. Fixed it.

@diyelectromusic
Copy link
Collaborator

Considerations on future-proofing:

  • Should we encode the number of TGs explicitly in the MIDI message, so that we can support more than 8 and make parsing easier?
  • Should we encode the number of global and per-TG parameters explicitly in the MIDI message, so that we can add future ones and make parsing easier?

Did you take a look my original rejected change I referenced above that exposed the internal global and TG parameters into a SysEx message?

I think that approach could be made to do everything you're doing here, if I'm understanding you correctly, without adding another place where TG and global parameters are defined and have to be kept in sync. It already includes TG number/global indication as it is just extending what is already there, not duplicating it.

It was only originally designed for single parameter updates, in response to the UI, but I see no reason why it couldn't be a string of updates in a single message if required, which I think is what you're suggesting here?

Most of the work is in these two functions: https://github.com/diyelectromusic/MiniDexed/blob/16TGExpander/src/minidexed.cpp#L2097

And if you're worried about future-proofing, I ought to mention there seems to be a lot of duplicating information across several files (MIDI handling, MIDI transports, minidexed, performance and the new performance sysex files) which is going to make maintaining the code "fun" pretty quickly I'd imagine... I'm not clear why this requires changes in the MIDI transports themselves for examples. Don't they all already pass SysEx handling into the MIDI parser?

Kevin

Copy link

Build for testing:
MiniDexed_1192_2025-05-28-61d1dcc_32bit
MiniDexed_1192_2025-05-28-61d1dcc_64bit
Use at your own risk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants