Hello, giving a stab at mapping out a preset for a device that most certainly needs it! Most of the parameters I can parse out with simple CC commands, but there are some that are SysEx only. I’m looking for a nudge in the right direction on how to get dynamic SysEx messages to send correctly!
I’ll provide some SysEx messages that determine Osc1 waveform types:
|
Header |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
|
|
|
|
|
|
|
ADDRESS |
|
|
|
|
|
|
Osc1 Waveform |
Exclusive Status |
ID Number |
Device ID (dev) |
Model ID #1 |
Model ID #2 |
Command ID (DT1) |
MSB |
Upper Middle Byte |
Lower Middle Byte |
LSB |
Data |
Checksum |
EOX |
Saw 1 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
05h |
00h |
57h |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
5 |
0 |
87 |
|
Saw 2 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
05h |
01h |
56h |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
5 |
1 |
86 |
|
Saw 3 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
05h |
02h |
55h |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
5 |
2 |
85 |
|
Saw 4 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
05h |
03h |
54h |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
5 |
3 |
84 |
|
Saw 5 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
05h |
04h |
53h |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
5 |
4 |
83 |
|
Saw 6 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
05h |
05h |
52h |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
5 |
5 |
82 |
|
Saw 7 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
05h |
06h |
51h |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
5 |
6 |
81 |
|
Saw 8 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
05h |
07h |
50h |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
5 |
7 |
80 |
|
Saw 9 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
05h |
08h |
4Fh |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
5 |
8 |
79 |
|
Saw 10 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
05h |
09h |
4Eh |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
5 |
9 |
78 |
|
Saw 11 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
05h |
0Ah |
4Dh |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
5 |
10 |
77 |
|
Saw 12 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
05h |
0Bh |
4Ch |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
5 |
11 |
76 |
|
Square 1 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
06h |
00h |
56h |
F7h |
Decimal |
|
|
|
|
|
|
20 |
0 |
16 |
6 |
0 |
86 |
|
Square 2 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
06h |
01h |
55h |
F7h |
Square 3 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
06h |
02h |
54h |
F7h |
Square 4 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
06h |
03h |
53h |
F7h |
Square 5 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
06h |
04h |
52h |
F7h |
Square 6 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
06h |
05h |
51h |
F7h |
Pulse 1 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
07h |
00h |
55h |
F7h |
Pulse 2 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
07h |
01h |
54h |
F7h |
Pulse 3 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
07h |
02h |
53h |
F7h |
Pulse 4 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
07h |
03h |
52h |
F7h |
Pulse 5 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
07h |
04h |
51h |
F7h |
Pulse 6 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
07h |
05h |
50h |
F7h |
Pulse 7 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
07h |
06h |
4Fh |
F7h |
Pulse 8 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
07h |
07h |
4Eh |
F7h |
Pulse 9 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
07h |
08h |
4Dh |
F7h |
PWM Wave |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
04h |
03h |
55h |
F7h |
Triangle/Sine 1 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
08h |
00h |
54h |
F7h |
Triangle/Sine 2 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
08h |
01h |
53h |
F7h |
Triangle/Sine 3 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
08h |
02h |
52h |
F7h |
Triangle/Sine 4 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
08h |
03h |
51h |
F7h |
Triangle/Sine 5 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
08h |
04h |
50h |
F7h |
Spectrum 1 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
00h |
53h |
F7h |
Spectrum 2 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
01h |
52h |
F7h |
Spectrum 3 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
02h |
51h |
F7h |
Spectrum 4 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
03h |
50h |
F7h |
Spectrum 5 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
04h |
4Fh |
F7h |
Spectrum 6 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
05h |
4Eh |
F7h |
Spectrum 7 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
06h |
4Dh |
F7h |
Spectrum 8 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
07h |
4Ch |
F7h |
Spectrum 9 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
08h |
4Bh |
F7h |
Spectrum 10 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
09h |
4Ah |
F7h |
Spectrum 11 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
0Ah |
49h |
F7h |
Spectrum 12 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
0Bh |
48h |
F7h |
Spectrum 13 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
0Ch |
47h |
F7h |
Spectrum 14 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
0Dh |
46h |
F7h |
Spectrum 15 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
0Eh |
45h |
F7h |
Spectrum 16 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
0Fh |
44h |
F7h |
Spectrum 17 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
10h |
43h |
F7h |
Spectrum 18 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
11h |
42h |
F7h |
Spectrum 19 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
12h |
41h |
F7h |
Spectrum 20 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
09h |
13h |
40h |
F7h |
Noise 1 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
0Ah |
00h |
52h |
F7h |
Noise 2 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
0Ah |
01h |
51h |
F7h |
Noise 3 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
0Ah |
02h |
50h |
F7h |
Noise 4 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
0Ah |
03h |
4Fh |
F7h |
Noise 5 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
0Ah |
04h |
4Eh |
F7h |
Noise 6 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
0Ah |
05h |
4Dh |
F7h |
Noise 7 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
0Ah |
06h |
4Ch |
F7h |
Noise 8 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
0Ah |
07h |
4Bh |
F7h |
Noise 9 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
0Ah |
08h |
4Ah |
F7h |
Noise 10 |
F0h |
41h |
10h |
00h |
4Ah |
12h |
14h |
00h |
10h |
0Ah |
09h |
49h |
F7h |
From SH-32 Midi Implementation:
OSC Parameter Address Information

Supplemental Roland Midi Information:
FULL PDF HERE
Here are the marked bits from the analyzer:
Now what isn’t clear to me yet, is how to make a dynamic list that will push the SysEx correctly to the unit. I understand that I need to designate some constant values and some parameter values, but it isn’t clear to me how many. The positions are kind of lost to me. If anyone can point me in the direction of some general materials or even specific electra advice, that would be great! I tried reading over the dev documentation on here, but that still is a little bit above my head!
1 Like
I think you can make a direct relationship between the number in the list and each of the variable bytes you must send. So instead of using values in the sysex, you could use three functions. Each function takes in the number of the list as a value, and returns a byte that fits the SysEx.
By function do you mean defining a LUA function? Wouldn’t mind taking a look at some examples if you there are any in the instrument presets you’ve done!
1 Like
Go look in my Korg 03R/W preset. Most controls are sysex. One of the first bytes is different depending on the base MIDI channel you set the synth to. Instead of hardcoding (and rendering the preset useless for a Korg 03R/W owner with a different base MIDI channel), you solve this with a lua function. In this preset the output for the byte is not based on the value of the control itself, like you’ll need to do, but it should help you get started.
By the way, the osc multisound control shows you also a way the send an 8 bit control value in a sysex message using two bytes. One that will take care of 7 bits, and one that takes care of the eighth bit. Might be useful for you too.
1 Like
Ah I wish I could grok this. I keep trying to reference the Electra documentation that backs up all of this but it either makes too many user knowledge assumptions or lags behind what’s currently possible in the editor.
It’s not clear what the values are when you have a list that are being passed. When it’s a midi cc list it makes sense as they represent a number (0-127) for that CC, but when set to sysex where are those values being passed to and should they be the decimal value that was converted from the hexadecimal sysex string?
Maybe I should just separate out the waveform types to “simplify” it but I wanted to avoid making it too busy just to select the waveform.
There’s a four step approach to this.
1.Are you familiar with SysEx? And with hexadecimal representations? With the way MIDI syntax is made up in Sysex? With MIDI principles?
You’ll need a bit more than just basic MIDI knowledge if you wanna work with Sysex. Sysex implementations are different for each brand, and differ within a brand from model to model. And this knowledge is independent from Electra or any other device that lets you program around Sysex.
-
Once you have taken that hurdle, next step is you describe in plain English and arithmetic how each byte of the Sysex string should be constructed for the purpose you want to reach. If you’ve never done this before I can help you out (but not with a full sysex course
) if you at least try it out for yourself first. So try to describe each of the 13 bytes what their function is.
-
You should know a little bit about lua programming. Just a little. But it is not complicated and lots of info is found on the internet. The basics can be learned in a couple of hours I’m not a skilled programmer myself, so I learn lua along the way, once I know what it is I want to reach. That is why in my opinion step 1 and 2 you better do on your own.
-
Once this second step is done, I or others on the forum can help you how to set this up in Electra. But for the editing part as well as for the lua.
Your request isn’t that difficult once you get the hang of it. But the sysex knowledge is mandatory if you want to make presets that you can maintain yourself whenever you change your setup.
1 Like
I’ve updated my initial post so it’s a little better structured in terms of companion information taken from the SH-32 Midi Implementation. I appreciate the 4-step approach as it allows for personal growth over just getting the answer!
For this specific instance, I seem to be hardcoding most of the start address, but will need a way to determine the offset. I’m a little confused by the way Roland structures the address portion of the bytes (positions 5-8). Maybe I need to go up another level first and define the waveform as a parameter and then link it to the waveform variations? Seem to be getting to a better understanding slowly!
Roland has made it difficult. They always have a lot of imagination when it comes to SysEx.
You don’t have an easier synth to start with? I do have a Roland XV5080, but that one too will have to wait a bit longer , because of its complexity.
And you probably have chosen the most difficult parameter to start with as well. Very ambitious! I suggest you look for another paramter you want to parse first, which has some easier characteristics.
- for instance choose just an on/off , changing from 0 to 1 or from 0 to 64, or you choose a continuous value going from 0 to 127.
- choose one you can easily check on your synth, and which is not far in the sysex payload.
Next, before you think about parsing parameters, first ensure you can control it. So first build the pad or fader in the Electra Editor and try to control the synth with it. in the MIDI implementation you need to look for the ‘Parameter Change’ instructions.
I think the issue is that there are a lot of functions that can be modified by standard CC messages. Once you start going into the nested menus, which is where the electra strives, is where sysex is required.Maybe I’ll workshop one of the other items like filter cutoff that already has a CC, but can also be controlled via sysex.
You don’t have an easier synth to start with?
I wish! The ones that I do have already have templates like:
Waldorf Blofeld
Access Virus B
My other pieces will be more complex than this:
Akai S1100
Kurzweil K2000RS
E-mu Ultra E6400
While I would like to venture into those pieces, I thought the Roland would have been easier, but like you said…they have made it difficult! I did start a project with the CC’s mapped out, it isn’t public yet.
ROLAND SH-32.eproj (11.7 KB)
I do have an E-mu Proteus 2000 coming in this week, but that might be even more of a bear considering the Midi Manual I found for it…here.
1 Like
Let’s stick tot the Roland then.
And as a test let’s control the filter cutoff first, what do you say?
Sounds good, I’ll have to parse that one out manually as that typically transmits over CC so it’ll be good practice.
I was able to successfully implement a toggle switch for the INS-FX which is a sysex only option which is working correctly, but isn’t bidirectional at this time (electra → SH-32 only).
So I implemented the filter freq, analog feel and FX-INS. I’ve noticed no issues with the FX-INS toggle, but for the analog feel and filter freq (127 sliders) they freeze the electra around 40-50 value inputs. If I go slower I can maybe get a little higher, but never a full up/down transmission of data.
Can you send me the link to your preset?
You make me get appetite to start working on the XV5080. The SH32 and the XV are from the same era (2000-2001), they have similar complexities in their MIDI implementation , but they share part of the architecture.
So although I may not be making a full XV5080 preset at this stage, I can try out the challenges you have with a synth that I have. I will give you access to my preset as well, so we can share the findings during the development.
I’ll be starting with similar controls like cutoff control, but in the early stage will already try to use the E1 for selecting patches , performances or rhythm sets. Then move on the effects control.
During lunch I did a quick compare between both synth’s SysEx.
The good news: very comparable. If we solve your challenge, we’ve solved mine as well !
Bad news: the regular parsing as foreseen on the Electra One will not work.
Most synth suppliers foresaw a SysEx where you can request a memory dump, and then receive a dump in a known format. Easy then to parse , as f.i. the twelfth byte always has the same meaning.
For individual parameter changes (outside of CC) these synths then find recourse to NRPN’s or SysEx Parameter Change messages, where only one address is mentioned. The Sysex Parameter change is then typically only used from Electra to the synth. The dump is used for getting all data at once form Synth to Electra.
This Roland SysEx doesn’t use any of these messages. Instead in a data request, we must add a pointer (= the starting address) as well as the length of the requested answer. And if formatted correctly we’ll get an answer to the exact question. In this case, the exact position of a parameter in a SysEx reply will depend on that starting address, or may not even be in the requested answer. There are literally hundreds of ways the header of the replies may look like. Impossible to get that worked out via standard parsing.
So we’ll need a cleverer way of working: one that allows us to define the address in a generic way, depening on patch, part, tone, partial and parameter number. Then we’ll need to read the full string of any incoming data dump, split it according the the start address of the dump and assign it to the appropiate parameter.
Another challenge is to send a parameter change that. We’ll have to do that first. If that doesn’t work the extra work on defining the clever ‘find my address’ algorithm isn’t really valuable. If it does work, we might escape having to define SysEx changes one by one for each parameter.
Sounds like a solid plan to me. I was certainly curious of the start address and offsets and that does make a bit more sense. It may even work if the preset was only meant to modify a temporary patch, but not really a fully fledged editor that the Electra can do! Let me know how you want to proceed, I’m pretty handy with gathering things/researching as needed.
1 Like
Hi @Cubeinthebox , just to signal I haven’t forgotten you.
But there are 3 presets I desperately want to get finished, so I’m giving these priority. It maye take me a couple of months.
Fyi , I was looking into the MIDI manual of Roland’s Aria TB-3 and to my surprise it has a similar sysex syntax as the older Rolands. That was a bit unexpected.
No problem at all! I’ve been exploring the Proteus 2000 I got (composer and Xtreme Lead ROMs) along with incorporating Reaper into my Renoise workflow, so I certainly have enough things to keep me busy outside of my day job…

Fyi , I was looking into the MIDI manual of Roland’s Aria TB-3 and to my surprise it has a similar sysex syntax as the older Rolands. That was a bit unexpected.
Wouldn’t put it past Roland!!
1 Like
a tip
if you add this to your lua, it’ll show you in the console whatever control you change.
I will use this function in our exercise. Not to show these values, but to select certain controls and convert their data to send appropiate sysEx strings to the XV5080. That way the sysEx can be set up flexibly without having to enter them for each control separately.
The code below will help you understand with you can intercept whenever you turn a knob, or receive a control from elsewhere that changes a control
function parameterMap.onChange (valueObjects, origin, value)-- callback function retrieving MIDI value
local parameterNumber = 0
local parameterType = 0
for i, valueObject in ipairs (valueObjects) do
local control = valueObject:getControl ()
parameterNumber = valueObject:getMessage():getParameterNumber ()
parameterType = valueObject:getMessage():getType ()
print(string.format ("Parameter %d (origin %d, type %d) => Control '%s'.%s with midiValue %d"
, parameterNumber, origin, parameterType, control:getName(), valueObject:getId(),value))
print(string.format (" Control has minimum value %d and maximum value %d"
, control:getValue("min"):getMin(), control:getValue("max"):getMax() ))
break
end
end