Open mungewell opened 3 years ago
When sending something like f0 00 21 1a 02 03 31 f7 which appearently caused the predecessor to dump the current patch, the response of the Pro looks like F0 00 21 1A 02 03 01 31 00 F7
Feeding this one back results in F0 00 21 1A 02 03 01 01 00 F7 Feeding this back results in the same response.
In the response F0 00 21 1A 02 03 01 31 00 F7
I believe the 01
after the ID is the synth saying 'error'. It does not understand the request... this byte is normally 00
for OK.
This means that the request will need to be 'adjusted'. It could be that the Pro is more like the Drum which separates patches into Kits & Patterns, rather than having 1 item.
You can slowly increase the numbers of bytes (zeros?) you send until the Synth accepts the command, and then figure out what the bytes do.
Another thing to note is that I sometimes saw a response with a lower cmd value - for example CMD 0x33 to change preset would have 0x32 in it's response.
As you saw 0x32 being sent from device perhaps these are async messages, replies without a CMD, I also sees these in my logs from the Drum. Anyhow build confidence that CMD 0x33 is for setting which present is active.
Next suggestion?
Maybe add same bytes from 0x32 to CMD 0x33... ie select patch 5 with
$ amidi -p hw:1,0,0 -S 'f0 00 21 1a 02 03 33 00 05 00 05 f7'
Maybe the two vales are patch & sequence pattern?
Noted the Drum replies (0x32) in double bytes, so maybe the Pro just uses 2 bytes for selecting preset
$ amidi -p hw:1,0,0 -S 'f0 00 21 1a 02 03 33 00 05 f7'
Yes... Pro has 256 presets, so it MUST use 2 bytes. Note Midi is 7 bit, so 01 00
would be preset 128.
Hello from the future! I'm interested in working on reverse engineering the Uno Pro spec assuming it's not been done yet. The data in this thread is about two years old: does anyone know if further progress has been made? Such as identifying the patch-request sysex command?
Hi @SeanLuke personally I never got my hands on a Pro, so haven't done any real investigates. Above was from discussion with another user...
Willing to offer any help/encouragement I can.
Okay, here's what I have ascertained at first glance.
REQUEST PATCH NAME: [Patch names are for some reason independent of patches]
F0 00 21 1A 02 03 24 01 BANK PATCH F7
RESPONSE:
F0 00 21 1A 02 03 24 01 BANK PATCH NAME... ZEROS... F7
NAME... is a non-zero-terminated string of UP to 14 characters, followed by enough zeros to make the entire message 43 bytes long.
WRITE PATCH NAME:
F0 00 21 1A 02 03 23 01 BANK PATCH NAME... F7
NAME... is a non-zero-terminated string of UP to 14 characters.
Thus this message varies in length up to 25 bytes.
REQUEST CURRENT MEMORY:
F0 00 21 1A 02 03 37 00 00 F7
RESPONSE:
F0 00 21 1A 02 03 00 37 00 00 BANK PATCH BANK PATCH DATA... F7
DATA... is 294 bytes long. It appears to be a simple parameter byte encoding. It does seem that the Bank and Patch appear twice
WRITE PATCH:
F0 00 21 1A 02 03 28 BANK PATCH DATA... F7
DATA... is 294 bytes long. It appears to be a simple parameter byte encoding. Patches do not include their names (ugh)
At present I don't know how to request a patch (other than doing a PC, then requesting from current memory, which is suboptimal).
REQUEST PATCH CHUNK: [ Unknown Function. This happens when copying a preset in the librarian but why I don't know ]]
F0 00 21 1A 02 03 29 BANK PATCH CHUNK F7
CHUNK goes 0...4
RESPONSES: [To each chunk request]
F0 00 21 1A 02 03 00 29 BANK PATCHNUM CHUNK DATA... F7 [checksum unknown]
Chunk 0 is 305 bytes total Chunk 1 is 204 bytes total Chunk 2 is 223 bytes total Chunk 3 is 209 bytes total Chunk 4 is 209 bytes total This appears to be a grand total of 1090 data bytes! Why does it need this?
SETTING PARAMETERS:
Parameters are both sent to and received by the device.
Most parameters are set by CC, see IK's "Midi Chart".
The following appear to be set by Sysex instead.
MOD SOURCE FOR A GIVEN SLOT
F0 00 21 1A 02 03 3C 02 SLOT 00 VAL F7
MOD DESTINATION FOR A GIVEN SLOT
F0 00 21 1A 02 03 3C 02 SLOT 01 VAL F7
MOD FADE IN FOR A GIVEN SLOT
F0 00 21 1A 02 03 3C 02 SLOT 03 VAL F7
VOICE MODE
F0 00 21 1A 02 03 35 04 VAL F7 0=Mono 1=Legato 2=Paraphonic
ARP OCTAVES
F0 00 21 1A 02 03 3C 00 01 VAL F7 1 ... 4
ARP MODE
F0 00 21 1A 02 03 3C 00 00 VAL F7 0 ... 9 for Up ... X2D
ARP ON/OFF (not a patch parameter)
F0 00 21 1A 02 03 35 00 VAL F7 0 ... 1
SCALE (not a patch parameter)
F0 00 21 1A 02 03 11 01 05 F7 [unknown purpose]
F0 00 21 1A 02 03 21 00 1D VAL F7 0 ... 14 for scales in order
UNKNOWN: [ This shows up sometimes ]
F0 00 21 1A 02 03 33 00 02 F7
RESPONSE:
F0 00 21 1A 02 03 00 33 F7
Okay, here's what I have ascertained at first glance.
That's some pretty awesome info!
It might be helpful to identify/hilight the 'CMD' byte(s), and if you haven't noticed the response appears to include a 'error' byte (00
is Good, 01
is Bad command). I was able to use this to manually search for other commands.
REQUEST CURRENT MEMORY:
F0 00 21 1A 02 03 37 00 00 F7
RESPONSE:
F0 00 21 1A 02 03 00 37 00 00 BANK PATCH BANK PATCH DATA... F7
DATA... is 294 bytes long. It appears to be a simple parameter byte encoding. It does seem that the Bank and Patch appear twice
Perhaps it's telling you the [current patch], followed by the [patch] for the data. For the original the data was a [count] of the parameters, followed by each [parameter, type, value].
Note: SysEx/Midi is 7bit, so two bytes is actually 128 * 128 max value.
DATA... is 294 bytes long. It appears to be a simple parameter byte encoding. Patches do not include their names (ugh)
Can you provide a hexdump/example?
At present I don't know how to request a patch (other than doing a PC, then requesting from current memory, which is suboptimal).
Did you try replacing the 00 00
in the command?
Original had different CMD for current (0x31) vs specific (0x24).
Chunk 0 is 305 bytes total Chunk 1 is 204 bytes total Chunk 2 is 223 bytes total Chunk 3 is 209 bytes total Chunk 4 is 209 bytes total This appears to be a grand total of 1090 data bytes! Why does it need this?
Why is this more data than the 'request current patch'? Do you see the same data structures? Perhaps into also includes sequencer info.
SETTING PARAMETERS: Parameters are both sent to and received by the device. Most parameters are set by CC, see IK's "Midi Chart". The following appear to be set by Sysex instead.
Note: I found that the SysEx setting of parameters allowed for finer resolution.
F0 00 21 1A 02 03 11 01 05 F7 [unknown purpose]
CMD 0x11 used to enter device mode?
F0 00 21 1A 02 03 21 00 1D VAL F7 0 ... 14 for scales in order
CMD 0x21 write setup parameter?
F0 00 21 1A 02 03 33 00 02 F7
CMD 0x33 = switch to preset?
Some more. When SONG is pressed, this unknown command is emitted by the machine:
F0 00 21 1A 02 03 27 00 15 01 F7
Then this unknown command is emitted
F0 00 21 1A 02 03 32 00 01 00 01 F7
Can you provide a hexdump/example?
Sure. After loading patch 0 bank 0 into memory, here's the current memory dump:
0000 F0 00 21 1A 02 03 00 37 00 00 00 00 00 00 01 00 | ! 7 |
0010 04 00 40 27 00 00 00 01 00 00 00 20 1E 00 00 64 | @' d|
0020 00 3C 5D 4F 09 19 00 6F 12 00 73 02 40 30 00 5C | <]O o s @0 \|
0030 00 54 0B 50 1F 00 00 00 00 7C 08 0C 00 00 00 00 | T P | |
0040 00 00 00 30 06 40 4C 00 00 7C 1B 4A 21 00 00 22 | 0 @L | J! "|
0050 02 00 00 10 00 00 00 64 02 00 00 00 00 00 00 0F | d |
0060 06 00 58 20 66 00 74 0B 70 2E 40 7B 03 10 00 0B | X f t p.@{ |
0070 64 0C 40 3E 01 6E 05 38 3F 00 02 30 41 0C 0F 1F |d @> n 8? 0A |
0080 00 01 30 20 68 44 03 50 41 08 08 70 00 00 32 1E | 0 hD PA p 2 |
0090 3E 00 0A 70 60 00 00 64 00 60 73 71 03 50 00 07 |> p` d `sq P |
00A0 00 10 73 71 03 50 00 07 0E 00 20 06 00 5E 1A 1F | sq P ^ |
00B0 00 05 38 30 00 00 32 00 70 79 78 01 48 4A 00 03 | 80 2 pyx HJ |
00C0 48 75 20 26 40 66 00 29 7E 00 60 03 00 4F 19 01 |Hu &@f )~ ` O |
00D0 08 01 00 00 60 41 02 02 00 00 00 00 00 00 00 00 | `A |
00E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
00F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
0110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
0120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
0130 00 00 08 00 F7 | |
Why is this more data than the 'request current patch'? Do you see the same data structures? Perhaps into also includes sequencer info.
Here's patch 0 bank 0 chunk 0:
0000 F0 00 21 1A 02 03 00 29 00 00 00 00 04 00 40 27 | ! ) @'|
0010 00 00 00 01 00 00 00 20 1E 00 00 64 00 3C 5D 4F | d <]O|
0020 09 19 00 6F 12 00 73 02 40 30 00 5C 00 54 0B 50 | o s @0 \ T P|
0030 1F 00 00 00 00 7C 18 01 00 00 00 00 00 00 00 30 | | 0|
0040 06 40 4C 00 00 7C 1B 4A 21 00 00 22 02 00 00 10 | @L | J! " |
0050 00 00 00 64 02 00 00 00 00 00 00 0F 06 00 58 20 | d X |
0060 66 00 74 0B 70 2E 40 7B 03 10 00 0B 64 0C 40 3E |f t p.@{ d @>|
0070 01 6E 05 38 3F 00 02 30 41 0C 0F 1F 00 01 30 20 | n 8? 0A 0 |
0080 68 44 03 50 41 08 08 70 00 00 32 1E 3E 00 0A 70 |hD PA p 2 > p|
0090 60 00 00 64 00 60 73 71 03 50 00 07 00 10 73 71 |` d `sq P sq|
00A0 03 50 00 07 0E 00 20 06 00 5E 1A 1F 00 05 38 30 | P ^ 80|
00B0 00 00 32 00 70 79 78 01 48 4A 00 01 48 75 20 26 | 2 pyx HJ Hu &|
00C0 40 66 00 29 48 01 60 03 00 4F 19 01 08 01 00 00 |@f )H ` O |
00D0 60 41 02 02 00 00 00 00 00 00 00 00 00 00 00 00 |`A |
00E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
00F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
0110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
0120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 | |
0130 F7 | |
Here's chunk 1:
00 F0 00 21 1A 02 03 00 29 00 00 01 7F 7F 7F 7F 7F | ! ) |
10 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
20 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
30 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
40 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
50 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
60 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
70 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
80 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
90 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
A0 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
B0 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
C0 7F 3F 00 00 00 00 00 00 00 00 00 01 00 00 F7 | ? |
Here's chunk 2:
00 F0 00 21 1A 02 03 00 29 00 00 02 7F 7F 7F 7F 7F | ! ) |
10 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
20 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
30 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
40 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
50 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
60 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
70 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
80 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
90 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
A0 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
B0 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
C0 7F 3F 00 00 00 00 00 00 00 00 00 F7 | ? |
Here's chunk 3
00 F0 00 21 1A 02 03 00 29 00 00 03 7F 7F 7F 7F 7F | ! ) |
10 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
20 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
30 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
40 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
50 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
60 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
70 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
80 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
90 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
A0 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
B0 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
C0 7F 3F 00 00 00 00 00 00 00 00 00 F7 | ? |
Here's chunk 4
00 F0 00 21 1A 02 03 00 29 00 00 04 7F 7F 7F 7F 7F | ! ) |
10 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
20 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
30 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
40 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
50 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
60 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
70 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
80 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
90 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
A0 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
B0 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | |
C0 7F 3F 00 00 00 00 00 00 00 00 00 F7 | ? |
I note that these chunks have different lengths (at least chunks 1-4) than described earlier. I can't explain that.
Did you try replacing the 00 00 in the command? Original had different CMD for current (0x31) vs specific (0x24).
Yeah. I'm guessing that chunk 00 is the patch data.
More.
Why is this more data than the 'request current patch'? Do you see the same data structures? Perhaps into also includes sequencer info.
It appears to be the same structure. So chunk 0 is probably the patch data.
Note: I found that the SysEx setting of parameters allowed for finer resolution.
Thing is, the unit emits CC, and the editor also emits CC. And you're right, they're not fine enough! But I don't know what the sysex equivalents should be.
Also this appears to be NAK:
F0 00 21 1A 02 03 01 COMMAND UNKNOWN F7
UNKNOWN varies: it might be the remaining bytes in the original message? Not clear.. COMMAND is in response to your particular command. So if you sent something like
F0 00 21 1A 02 03 29 00 00 05 F7
["Request Chunk #5 from patch 0 bank 0" -- there is no chunk #5]
You'd get back:
F0 00 21 1A 02 03 01 29 03 F7
Thing is, the unit emits CC, and the editor also emits CC. And you're right, they're not fine enough! But I don't know what the sysex equivalents should be.
On the original you could use the 'write current patch' (CMD 0x30), but only send one (or a few) parameters/values.
$ amidi -p hw:1,0,0 -S 'f0 00 21 1a 02 01 30 00 01 20 22 00 03 f7'
^^ ^^ Param Value
^^ ^^ Param ID/Type
^^ Param count
Also this appears to be NAK:
F0 00 21 1A 02 03 01 COMMAND UNKNOWN F7
Yep, 01
in response (before CMD) tells you it didn't understand. Like I said you can use this to fuzz for new commands.
Can you provide a hexdump/example?
Sure. After loading patch 0 bank 0 into memory, here's the current memory dump:
0000 F0 00 21 1A 02 03 00 37 00 00 00 00 00 00 01 00 | ! 7 | 0010 04 00 40 27 00 00 00 01 00 00 00 20 1E 00 00 64 | @' d| 0020 00 3C 5D 4F 09 19 00 6F 12 00 73 02 40 30 00 5C | <]O o s @0 \| 0030 00 54 0B 50 1F 00 00 00 00 7C 08 0C 00 00 00 00 | T P | | 0040 00 00 00 30 06 40 4C 00 00 7C 1B 4A 21 00 00 22 | 0 @L | J! "|
As you note this is similar format to that from "Chunk 0".
It doesn't really look like Original's format, which was a sequence of parameters/values. as described here: https://github.com/mungewell/uno-synth-utils/blob/master/uno_synth.py#L46
For the UNO Drum they implemented some really weird stuff, and this made it hard to understand what was what.... if you change a single parameter slightly, does that change show in hexdump? Does change in data make logical sense...
A0 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | | B0 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F | | C0 7F 3F 00 00 00 00 00 00 00 00 00 F7 | ? |
The 0x3F is very suspicious.
Midi/SysEx is only 7bit, I've seen multiple different devices pack 8bit data into 7bit to send across Midi. You may need to unpack 7bit->8bit before the patch data makes sense,
Examples: https://github.com/mungewell/zoom-zt2/blob/master/zoomzt2.py#L236 https://github.com/mungewell/circuit_samples/blob/main/circuit_samples.py#L39 https://github.com/mungewell/twinlooper/blob/main/twinlooper.py#L67
Are you able to save a patch (from the editor) to hard-disk? What format does that have?
Hi all, here's »Above was from discussion with another user« :) . Thanks for sharing your findings. I was able to request patch names from my Pro. I also was able to fetch "current memory" by F0 00 21 1A 02 03 37 00 00 F7. Did you have any luck requesting a particular preset (or even request all presets) in order to do a backup?
I now have the editor running on a Mac as well as MIDI monitor. When pressing "Get" in the editor, the Uno Synth Pro sends all 256 preset names as SysEx. 256 preset names.syx.zip
When I select all presets on the Uno Synth Pro in the editor window and press "TO LIB" (which means dumping all presets to the Mac), the Uno transmits 1280 SysEx messages of different sizes, potentially 5 per preset. 1280 SysEx messages, potentially 5 per preset.syx.zip
When I try to fetch presets 1 by 1, e.g. Preset 1, then preset 2, then 3 and then 4, the Uno always sends 5 SysEx messages. However, the length of those messages differs per preset, see hardcopy attached. At least the first one always consists of 305 bytes.
any updates on this? would love a CTRLR panel for the uno pro
Didn't work with my Uno since then, so no news at my end.
ce
On my Mac, I can listen to the SysEx communication between the editor and the Uno Synth Pro. HOwever, it's always multiple SysEx packages and my time and skills are limited to understand the meaning of them.
BTW: The editor uses both MIDI CC (e.g. filter cutoff) and SysEx messages (e.g. mod matrix) to communicate with the hardware.
It seems that the UNO Pro is a least a little similar to the original, obviously the storage size will be a lot bigger. https://cgi.ikmultimedia.com/ikforum/viewtopic.php?f=43&t=27841&p=120259#p120259
The Pro does not respond to the enquiry message: F0 7e 00 06 01 F7
It does respond to the version inquiry: f0 00 21 1a 02 03 12 f7 Response: F0 00 21 1A 02 03 00 12 01 31 2E 30 2E 31 20 23 23 2E 23 23 20 23 23 2E 23 23 00 F7
Interestingly, the Pro emits SysEx when scrolling through presets, like this: F0 00 21 1A 02 03 32 00 01 00 01 F7 F0 00 21 1A 02 03 32 00 02 00 02 F7 F0 00 21 1A 02 03 32 00 03 00 03 F7