Skip to content
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

Assign/"learn" MIDI CCs #63

Open
probonopd opened this issue Mar 31, 2022 · 20 comments
Open

Assign/"learn" MIDI CCs #63

probonopd opened this issue Mar 31, 2022 · 20 comments
Labels
enhancement New feature or request

Comments

@probonopd
Copy link
Owner

probonopd commented Mar 31, 2022

Update: See this post below for a concise user story and a rough idea of how to implement this.


It would be nice if we could assign/"learn" MIDI CCs (knobs and sliders on MIDI hardware controllers) to manipulate Dexed voice parameters.

E.g., these guys:

image

(Example shows the Nektar Impact LX61+.)

The sliders and knobs all send CCs with values from 0 to 127, and the buttons toggle between 0 and 127: B0 xx 00 ... B0 xx 7F with xx being different for each slider/knob/button. For xx = 07 it is volume, which is already implemented.

You would select, via the LCD, a voice, then select "Edit params", then scroll through the available Dexed parameters using the rotary encoder, and while one is selected, move a slider/knob/button on the MIDI controller, which would make MiniDexed react to this slider/knob/button (=MIDI CC). Then you would rotate the roraty encoder to go to another parameter, again wiggle another slider/knob/button ont the MIDI congroller, and so on. (The assignment should be written to an INI file in order to survive a reboot.)

Imagine that. A "DX7 with more than one Data Entry slider". Isn't that what people would have wanted already back in the day? ;-)

For those without a fancy MIDI controller with many siders and knobs, you could select a Dexed parameter on the LCD UI, then click the rotary encoder button, and then rotate the rotary encoder to manipulate the value of the selected Dexed parameter that way. (Edit: @rsta2 has implemented this in https://github.com/probonopd/MiniDexed/pull/61)]

@probonopd probonopd changed the title Assign/"learn" Midi CCs to manipulate voice parameters Manipulate voice parameters using rotary encoder and/or MIDI CCs Mar 31, 2022
@probonopd
Copy link
Owner Author

probonopd commented Mar 31, 2022

We'd also need a scaling of 0-127 to whatever each voice parameter has as an acceptable range. E.g., when the physical slider/knob/button says 127 but the parameter only goes up to 99, the value to be used should be 99 even though the slider is set to 127:

http://www.tonmeister.ca/personal/geoff/emusic/dx7iisysex.html lists the acceptable ranges in the last column.

@probonopd
Copy link
Owner Author

Thanks to the awesome work of @rsta2 most of this is implemented. 🥇

Highlight an aspect of the idea bold in the original ticket above. @rsta2 do you think this would be doable?

@probonopd probonopd changed the title Manipulate voice parameters using rotary encoder and/or MIDI CCs Manipulate voice parameters using MIDI CCs Apr 3, 2022
@rsta2
Copy link
Contributor

rsta2 commented Apr 3, 2022

Thanks! :) I will think about, how this can be done.

@probonopd
Copy link
Owner Author

probonopd commented Apr 3, 2022

Similarly, it would be nice if we could manipulate voice parameters using MIDI SYSEX sent over serial/USB.

@rsta2
Copy link
Contributor

rsta2 commented Apr 3, 2022

OK, one after another. I will keep this in mind.

@dcoredump
Copy link
Contributor

I would like to implement both inside Synth_Dexed because both is also needed for MicroDexed. But currently I cannot do everything at the same time 😀.

@rsta2
Copy link
Contributor

rsta2 commented Apr 5, 2022

OK, no problem. Let me know, if you need support for an interface to the UI (info about the currently selected parameter).

@probonopd
Copy link
Owner Author

Continuing from #62:

Also, it would be nice to be able to assign/"learn" Midi CCs

That's also on my task list for MicroDexed. I would try to implement it also in Synth_Dexed later...

Because this effects the UI menu, where the parameter must be selected, which should be assigned to the MIDI CC, for which a message is received, there arises the question, should this be implemented in MiniDexed or Synth_Dexed?

I think the ideal UX would be: You go to the respective parameter in the UI, and then instead of rotating the knob of the rotary encoder, you just wiggle the control you want to assign on the MIDI controller. MiniDexed then knows which CC message to use (from the messages that came from the MIDI controller) and knows which parameter to edit (the one currently on screen). Learning done! Should be written to a file on the SD card in, e.g., mapping.ini so as to survive reboots.

If we agree that we want to do it that way, my question is: Can this even be done in Synth_Dexed (or which portion of it)? or does it need to be done in MiniDexed (because only it has the menu structure and SD writing capabilities)?

@probonopd probonopd changed the title Manipulate voice parameters using MIDI CCs Assign/"learn" MIDI CCs Apr 5, 2022
@probonopd probonopd added the enhancement New feature or request label Apr 8, 2022
@probonopd
Copy link
Owner Author

Worth seeing!
https://www.youtube.com/watch?v=GIE3WfrEEX0

@probonopd
Copy link
Owner Author

probonopd commented Apr 17, 2022

For example, a Korg nanoKONTROL 2 could be (ab)used to set the level (volume) of each operator with the slider, and the frequency (ratio) with the knob. Something like that.

image

Kinda like the Korg Opsix does it:
https://www.youtube.com/watch?v=CKBr9HjdJr4

Makes this whole FM thing a lot more accessible imho.

@maks
Copy link

maks commented Apr 18, 2022

Very cool project!

I was wondering if you would consider adding support for something like the Akai Fire:
image

For not much more than the price of a small midi keyboard controller plus the existing electronics parts list (lcd,encoder, breadboard,etc) you get a 128x64 OLED, rotary+push button encoder, 4 capacitive touch encoders, multitude of buttons most of which are red/yellow or green leds and full RGB leds pads. And all of it is controllable via Midi Sysex (midi implementation already rev eng'd: https://blog.segger.com/decoding-the-akai-fire-part-1/) so all a user would need to do is plug it into a RPI along with a DAC.

I think this would need to be a bit more "baked in" than just usual DAW-style midi mapping to get the benefit of using the OLED, LED colors feedback etc.

I've already done midi implementations for the Fire in Dart and TS so there are already existing code bases for reference.

I would be happy to collaborate on this if its something you would be interested in doing in MiniDexed.

@probonopd
Copy link
Owner Author

probonopd commented Apr 18, 2022

Hello @maks, interesting device. If this ticket gets implemented, knobs and faders could be easily assigned to MiniDexed parameters. We are looking for a solution that works with any MIDI controller that has knobs and/or sliders. Which imho would already be a huge usability improvement over the original DX7.

We don't want to hardcode MiniDexed for certain MIDI controllers. Besides, without having that piece of hardware the effort is futile. So unless we find a solution purely using configuration files and/or scripts (and someone is willing to implement them) it is unlikely that there will be special support for the Akai Fire.

@maks
Copy link

maks commented Apr 18, 2022

@probonopd yes, very fair point and I think you are right about avoiding hardcoding support for specific midi controllers. I opened a separate issue for scripting support that I realised after I made the comment here would be the better way to approach this so I'll follow up on that issue.

@probonopd
Copy link
Owner Author

probonopd commented Apr 19, 2022

User Story:

"As a user, I would like to assign a "random" knob on my MIDI controller (that happens to send CC 127 with values 0...127) to edit the Freq Coarse parameter. To assign ("learn") the knob, while the display is showing image I would turn the knob in question. Assigned! From that point on, whenever I turned that knob, it would change the Freq Coarse parameter."


The way I imagine this to work is roughly as follows:

We need a global data structure (a map?) that can hold, for each CC number, (the pointer to) a parameter. Optionally (later), this data structure could be loaded from cc.ini and it should be possbile to save it there.

Something like this (just for illustration filled with some values; initially it would be empty):

cc_map = {{1, DEXED_OP_FREQ_COARSE,},
  {2, DEXED_OP_FREQ_FINE,},
  {3, DEXED_OP_FREQ_FINE,}};

Somewhere around the code that is reposible for showing the parameter edit screen, possibly

void CUserInterface::DisplayWrite (const char *pMenu, const char *pParam, const char *pValue,
bool bArrowDown, bool bArrowUp)
{
assert (pMenu);
assert (pParam);
assert (pValue);

we should listen for incoming CC messages. Whenever a CC message comes in, we would update the entry in cc_map for that CC to contain the parameter that is currently being edited.

For example, if while the display is showing image we turn a knob that results in a MIDI message with CC 127 coming in, then we would update cc_map to contain {127, DEXED_OP_FREQ_COARSE,}.

Learning complete!

Somewhere around

default:
break;

we would go though cc_map to see if it has an entry for the cc_number that has been played. If yes, we would retrieve its param and use it:

We would then scale the incmoing value which is in the range 0-127 with scaled_value = constrain(incoming_cc_value, param.Minimum, param.Maximum) to the range allowable by the respective parameter. (#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) is the definition used by Arduino for constrain().)

Finally, we would call SetParameter (parameter, scaled_value);.

In the example, whenever we turn the knob, we would change Freq Coarse. Mission accomplished!

@dcoredump @rsta2 wdyt, does this make sense? If yes, then wouldn't this have to be implemented in MiniDexed rather than in Synth_Dexed? Or is there an entirely different way to achieve this behavior?

@probonopd probonopd pinned this issue Apr 19, 2022
@rsta2
Copy link
Contributor

rsta2 commented Apr 19, 2022

As I understand it, @dcoredump wants to implement most of the functionality in Synth_Dexed. I don't want to interfere with that, but already offered my help, e.g. for determining the current parameter in the UI, when a MIDI CC message comes in.

@dcoredump
Copy link
Contributor

My thought of implementing this was:

I wanted to give the Dexed class methods for processing SYSEX and MIDI-CC. The MIDI-CC methods should internally get a mapping from the CC number to any function (so also for changing sound parameters) and a scaling (e.g. CC-7 0..127 -> Parameter[42] 95..43 (so also allow a flip of the values)). The target could be any method to change the sound, but also existing CC values.

The biggest problem is that I can't keep up with the fast development of MiniDexed. In this respect: If someone has desire to implement this: Ideally then in Synth_Dexed, otherwise just directly in MiniDexed. I will definitely implement this in Synth_Dexed, but currently I can't say when.

@probonopd
Copy link
Owner Author

probonopd commented Apr 19, 2022

If we want to load and save those assignments in .ini files, wouldn't we need to do at least parts of the logic in MiniDexed anyways?

I know it's a big ask, but I see this one as the last remaining "killer" feature that I'd love to see implemented while @rsta2 still has some time.

@rsta2
Copy link
Contributor

rsta2 commented Apr 20, 2022

Yes, there is still some time. Accessing the MIDI CC assignments in an .ini file can be done similar to performance.ini.

@probonopd
Copy link
Owner Author

Imagine this together with the ROLI Seaboard Block:
https://twitter.com/littlescale/status/1532954508015202304

Would allow us to do things like
https://www.youtube.com/watch?v=6SCug5kUsBs

@RK11111111111
Copy link

Continuing from #62:

Also, it would be nice to be able to assign/"learn" Midi CCs

That's also on my task list for MicroDexed. I would try to implement it also in Synth_Dexed later...

Because this effects the UI menu, where the parameter must be selected, which should be assigned to the MIDI CC, for which a message is received, there arises the question, should this be implemented in MiniDexed or Synth_Dexed?

I think the ideal UX would be: You go to the respective parameter in the UI, and then instead of rotating the knob of the rotary encoder, you just wiggle the control you want to assign on the MIDI controller. MiniDexed then knows which CC message to use (from the messages that came from the MIDI controller) and knows which parameter to edit (the one currently on screen). Learning done! Should be written to a file on the SD card in, e.g., mapping.ini so as to survive reboots.

If we agree that we want to do it that way, my question is: Can this even be done in Synth_Dexed (or which portion of it)? or does it need to be done in MiniDexed (because only it has the menu structure and SD writing capabilities)?

I really like the idea of adding additional sliders. However, I think this would be extremely voice dependent, as to which parameters would be modulated. I think the tone generator section of a performance would be a good section to store the midi mappings.

For example, if you load Dexed into a Daw like Reaper then learn some mappings. It's pretty difficult to find a parameter that you would want to tweak live. As compared to other FM VST synths like Exact or FM8. I think it is because with Dexed, the emphasis is on automated envelopes, where as VSTs use more of the DAW support.

I also like the idea of a ribbon controller, the other issue with mapping midi controllers is that they often times are not precise enough. For example, if you map a controller 1...127 to a frequency, unless you do something to map those frequencies to musical notes, its going to be out of tune most the time ratios can also suffer from this. Even, things like delay times or envelope attack times. How do you go from a scale of fractions of millisecond to seconds in any precise manner.

The point is it will take some thought to come up with units and mappings that make musical sense. One that is especially important is the amplitude of the modulating operators, those really need to be tuned precisely.

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

No branches or pull requests

5 participants