eclab / edisyn

Synthesizer Patch Editor
Apache License 2.0
550 stars 51 forks source link

Add Behringer UB-Xa #81

Open grav opened 2 months ago

grav commented 2 months ago

First iteration of the Behringer UB-Xa(d) editor.

The editor consists of multiple tabs, with the first containing the parameters accessible on the keyboard version, and the rest of the tabs containing all additional parameters.

Screenshot

image

Details

The editor is using MIDI NRPNs for transmitting and receiving datga from the UB-Xa.

All parameters in the manual (starting on page 24) are supported.

To send values to the UB-Xa, the synth's default settings must be changed:

To receive values from the synth, two changes are required to the settings:

I've been mainly looking at the DSI Prophet '08 / Tetra / Mopho editor for inspiration, as it is also using NRPN.

Status of SysEx support

The editor is able to request patches via SysEx from the UB-Xa but still cannot interpret them.

I've been able to decode the SysEx data as specified in the refernce guide, but there's something I'm not fully understanding about the layout. I'll see if Behringer can help me, or if I can get further on reverse-engineering the data.

eclab commented 2 months ago

Congratulations at this effort so far!

Implementing the sysex will be a significant effort as it appears to have a lot of bitpacking (search for "bitmask") but at least the bitpacking is rational I guess.

I have not looked at your code or editor yet -- and it'll be a bit before I can do so -- but I'm wondering how you're handling the bitmasks. So if you change, say, Voice Toggle 1, you have to send out "VoiceToggle1to8", which packs 8 parameters (voice toggles 1 through 8) together into a single NRPN value. I presume in Edisyn you have separate voice toggles for 1 through 8, rather than a single widget called "VoiceToggle1to8", and you're packing?

You can get Edisyn to dump all its parameters using NRPN, but it's gonna be slow.

On the other hand, dumping the patch like Behringer's doing it with the MIDI File Dump Standard is pretty stupid. It's extremely complex and nonstandard. :-( And it's not adequately documented. So get ready for some annoyance....

Sean

eclab commented 2 months ago

Unsubscribing for the time being (too many commit emails!). When you think the code is ready for prime time, or you need to get ahold of me for suggestions or help, just send mail to my standard email address (see the front page of the manual).

grav commented 1 month ago

but I'm wondering how you're handling the bitmasks. So if you change, say, Voice Toggle 1, you have to send out "VoiceToggle1to8", which packs 8 parameters (voice toggles 1 through 8) together into a single NRPN value. I presume in Edisyn you have separate voice toggles for 1 through 8, rather than a single widget called "VoiceToggle1to8", and you're packing?

Yes, I'm collecting all relevant parameters in a "group" and sending them in one go. Works well!

You can get Edisyn to dump all its parameters using NRPN, but it's gonna be slow. On the other hand, dumping the patch like Behringer's doing it with the MIDI File Dump Standard is pretty stupid. It's extremely complex and nonstandard. :-( And it's not adequately documented. So get ready for some annoyance.... Sean

Yeah, the SysEx File Dump structure is a mystery to me!

I initially thought that the sysex data was trivial to map to specific parameters, but it's still not obvious to me. For instance "Loudness attack" is sometimes altering 4 different bytes in the sysex data, as opposed to the two that the sysex guide refers to.

As an example, here is a dump of 4 specific bytes that are changed when altering the loudness attack. The bytes are at index 28 and 29, as the sysex guide says, but then also at index 33 and 34 which, according to the guide, relate to other parameters. There's most definitely a pattern in how they change, but not a simple one. If you have any pointers, I'd be grateful :)


Edit, just to clarify the structure of the dump, [62,[120,0,109,33]] means that for loudness attack set to 62/16.383 via NRPN, when retrieving the sysex dump and unpacking ("7-bit'izing"), data[28] = 120, data[29] = 0, data[33]=109 and data[34]=33. The dump contains the whole range of this specific parameter (0 ... 2^14-1 ).

grav commented 1 month ago

I think this is already useful enough to be merged (modulo any comments that you might have).

File Dump support will have to be retrofitted :)

eclab commented 1 month ago

I haven't tried out the code yet -- but just looking at the screenshot, I think it might do for some rearranging and compression. I try hard to keep the window proportions under a certain size so people can use Edisyn on their laptops. I might be able to help with some suggestions there... Do you have librarian support yet? Individual parameters in and out? Writing/Updating/Loading/Saving? Banks? Just wondering.

eclab commented 1 month ago

I have NO IDEA why bytes 33 and 34 would be modified as well -- 33 is a byte for VCA sustain and 34 is a byte for VCA decay. You might check to see if those values are changing on the machine's front panel? It seems mysterious.

eclab commented 3 weeks ago

I'm trying to think about how to integrate this editor. I tend only to add editors that are fully formed, but you've clearly put a lot of work into this and it might be useful as is. I would however suggest some UI changes. First off, you've got dials with long names. Try using addAdditionalLabel(...) to break a name into two or even three rows so the labels sit more closely next to one another. Second, I would stack choosers vertically using VBox, then put multiple VBoxes into an HBox, rather than the other way around; this would cause them to line up in width and look much better. I'd also absolutely stack your checkboxes in VBoxes. Third, Edisyn almost universally has stacked choosers and checkboxes to the left, followed by dials to the right. If you have lots of choosers, you might put them below perhaps. Fourth, Edisyn tries to keep its window sizes small enough for medium-resolution-screen laptops. I know you have a billion parameters, but surely there's gotta be a way to shrink this window, it's enormous. I don't like additional tabs but they might be needed. Fifth, some color stuff. Edisyn always uses white for a single category at top left of the first tab, with the name of the synth, with some general-purpose stuff in it like patch names. The others need to be the three other colors. Sixth and last (for the moment!) why do you have oscillator and filter categories on the "Main" tab? Why aren't they in the oscillator and filter tabs? Etc.

grav commented 2 weeks ago

@eclab Thanks for all your feedback! I'll try to address them here:

why do you have oscillator and filter categories on the "Main" tab? Why aren't they in the oscillator and filter tabs

Since there are a gazillion parameters (as you mention), I thought it would be nice to have the ones that Behringer placed on the front panel in a tab by itself. This way, the UI should appear more familiar to the user.

surely there's gotta be a way to shrink this window, it's enormous

Agree, it definitely did not fit on a Laptop screen. In the following screen dump, I've re-arranged the controls on the main tap a lot, to fit everything with in something like a ~16:9~ screen-sized rectangle. Additionally, I've tried to address your concerns regarding alignment of the choosers, and I've added colors.

Overall I think it improves the UI a great deal. I've attached a screenshot (not yet merged), what do you think?

image
eclab commented 2 weeks ago

I think the big issue here is that it's not consistent with Edisyn's other patch editor layouts, which try (not always successfully) to put choosers (combo boxes) to the left of dials and stacked vertically in lined-up groups, and check boxes either to the left of that or under them in some way. There's some value in consistency, and I break it only when I really need to cram things in or when there is really strong value for arranging things differently from the user's perspective -- but I think this isn't the case here maybe? For example you might try something laid out like this:

Layout

grav commented 2 weeks ago

@eclab Thanks for the mock-up, tried replicating it below.

I moved the filter dials below the combos, in order to have the rows be approx. the same width.

I haven't got anything for the patch names yet in the "Behringer UB-Xa" category, as this requires supporting the sysex format. If I get to that at some point, it can be fitted into that spot.

WDYT?

image

Edit: I think I'm missing something in the modulation category, will add that later.

eclab commented 2 weeks ago

Definitely getting closer now! Here's what you might try:

  1. Make the dials for Oscillators a 2x2 layout rather than 1x4. Normally in Edisyn it's 1xn but you have so many Choosers (combo boxes) that we might try 2x2 to save some space.

  2. Push the Filter combo boxes to the left of the dials. You might have enough space now with the change to the Oscillators. If not, you could do a 2x2 dials here too if absolutely necessary.

  3. Push the checkboxes to the left of the dials in the envelopes. You'll probably have enough space now. But it's not a disaster if you keep them the way they are.

  4. I'm confused by the LFO comboboxes in Modulation. Are the two LFO comboboxes below the C1 and C2 related to the C1 and C2? If so, why is LFOEnv2 not there? You might try moving all the LFO Comboboxes to one vertical stack by themselves.

  5. You MIGHT have enough space now to move the checkboxes in Modulation to the far left; you could try stacking the dials as a 3x2 perhaps if you don't have enough space.

  6. You can get the categories to line up on the right hand side by using HBox.addLast() rather than HBox.add() for them.

The goal here is to strike a balance between similarity with other patch editors (so the musician can rely on muscle memory and doesn't have to rely on memorizing location per-editor -- familiarity is very useful when you have this number of editors! See the mess that is CTRLR...) and space saving and window size. And also relationship to how the synth itself is laid out.... It can be a real challenge.

grav commented 2 weeks ago

Great feedback. I've tackled 1-3 as well as 6.

Re 4 + 5 (modulation), honestly I wasn't doing a good job there, probably since I didn't have a good enough understanding of it yet.

I've spent a bit of time fiddling, reading docs and understanding the architecture, and there are essentially two channels with each their gain and destinations. I've tried creating a category for each one.

Wrt LFOEnv2 Rate, I couldn't find anything in the manual, but it simply seems to double the LFO rate. Not sure why it's named something with "env"?

In general, the labels are not great in the Modulation section, so I'll work on improving those. But for now, I've re-arranged the modulation section. What do you think about the altered layout?

image
eclab commented 2 weeks ago

Thinking of ways to reduce the height of the window. I'd probably:

  1. Put the 2x2 oscillators dials back to 1x4, there's enough room, and it'd save some vertical space.
  2. Put the Filter checkbox underneath the combo box.
  3. Change "LFO\nTrig\nPoint\n" to "LFO Trig\nPoint"
  4. Put "FlipSquare" and "FlipVCFMod" directly under the dials, laid horizontally.
  5. Move the third Arpeggiator combo box to the right of the other two, and change "Gate\nTime" to "Gate Time".

That'd reduce the height by a lot without increasing the width at all or looking odd. What do your other tabs look like? We've just been focusing on the first tab, I guess as a Hello World.

eclab commented 2 weeks ago

While we're at it, you've got a lot of lower-case stuff like "f-env" and "Osc2 half" or "Osc2 sync" (while elsewhere you have "OSC2"). It'd be good to have things consistent -- I tend to make everything mixed case, like "Filter Envelope" instead of "f-env" , or "Osc 2 Sync" instead of "Osc2 sync", but you can also try to be consistent with how Behringer labels it.

Some more items. All combo boxes ought to be labeled. Your filter combo isn't labeled, instead it says "2-Pole Filter" and I presume "4-Pole Filter" or whatnot. Instead, you might label it "Type" and the values would be "2-Pole" and "4-Pole" etc.

I can also help stretch at least the second envelope display to the end of the screen (just add it to the category using addLast).

eclab commented 2 weeks ago

BTW, is the OSC1 chooser actually a boolean option (on/off?) and should that be a checkbox? Why is there no equivalent OSC2 chooser? There's one called OSC2 State...

grav commented 6 days ago

Latest version:

image
grav commented 6 days ago

BTW, is the OSC1 chooser actually a boolean option (on/off?) and should that be a checkbox? Why is there no equivalent OSC2 chooser? There's one called OSC2 State...

I've changed the OSC1 chooser's label to "Osc 1 State", so that the two matches.

These are the options:

image image

So I think choosers make sense for Osc 1 state.

grav commented 6 days ago

What do your other tabs look like? We've just been focusing on the first tab, I guess as a Hello World.

A valid point! All additional tabs are auto-generated via a data structure (table) that I copied from the specification in the manual. For now, there are no manual adjustments made by me, and the order and structure of the labels are just directed by the specification.

It's of course not optimal, but there are just so many options, so it's a lot of work to cover all. On the other hand, I think that if the user wants to edit them, this is much better than the menu diving on the synth.

My hope is to cover the other tabs little by little, once I start messing more with the synth.

eclab commented 5 days ago

I agree that if OSC2 state is off/half/full, then even though OSC1 state is off/full, it oughta be a chooser to be consistent.

eclab commented 5 days ago

What do your other tabs look like? We've just been focusing on the first tab, I guess as a Hello World.

A valid point! All additional tabs are auto-generated via a data structure (table) that I copied from the specification in the manual. For now, there are no manual adjustments made by me, and the order and structure of the labels are just directed by the specification.

It's of course not optimal, but there are just so many options, so it's a lot of work to cover all. On the other hand, I think that if the user wants to edit them, this is much better than the menu diving on the synth.

My hope is to cover the other tabs little by little, once I start messing more with the synth.

Could you provide a screenshot or two so we know what we're looking like?

grav commented 5 days ago

Could you provide a screenshot or two so we know what we're looking like?

Sure, here you go:

image image image
grav commented 13 hours ago

@eclab Any thoughts on next steps? My hope is that we can get this PR merged, and I'll start focusing on parsing the sysex dump :)