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

Initial implementation of system-level, i.e. all TG, MIDI control maps #704

Merged
merged 4 commits into from
Sep 29, 2024

Conversation

diyelectromusic
Copy link
Contributor

@diyelectromusic diyelectromusic commented Aug 21, 2024

As per discussion here: #702 (comment)

Defines the following "CC maps" for use in controlling each individual tone generator over the same MIDI channel:
0 = disabled
1 = CC 16-19, 80-83 - the General Purpose Controllers 1-8
2 = CC 20-27
3 = CC 52-59
4 = CC 102-109
5 = CC 110-117
6 = CC 3, 9, 14-15, 38-31
7 = CC 35, 41, 46-47, 60-63

Note: maps 2-7 utilise various sets of undefined in the MIDI spec MIDI CC numbers.

These can be configured in minidexed.ini for any of the following
MIDISystemCCVol=
MIDISystemCCPan=
MIDISystemCCDetune=

It has only had very, very basic testing but as a concept I think it could work.

This PR is to let people try out the concept and see if it has any merit.

Kevin

Copy link

Build for testing:
MiniDexed_2024-08-21-3ec467f
Use at your own risk.

@diyelectromusic
Copy link
Contributor Author

The question now is what MIDI channel should this be tied to?

At the moment it will respond to any MIDI channel configured for any tone generator (in fact, I ought to ensure it only gets processed once - if all 8 TGs are on the same channel, then this will currently be processed 8 times!).

But we could say it should only be on the PCCH channel. Or it could only be on the TG 1 MIDI channel. Or we could keep it as any listening MIDI channel, but I'll just ensure it is processed once.

This last option would mean that if each TG had its own MIDI channel any of them could still be used to set the parameters for all TGs, so maybe that is the best option?

Thoughts?
Kevin

Copy link

Build for testing:
MiniDexed_2024-08-21-d94d3f5
Use at your own risk.

@iluvsa
Copy link

iluvsa commented Aug 22, 2024

Ok this works as expected for me! It’s really cool! Especially if you have a controller that allows multiple configs to be saved (e.g. Arturia Minilabs, MidiTwister, etc.). You can have one config to adjust all your voices’ volumes and pans or tuning simultaneously, then switch back to your main config to have control over Reverb, Filter, Bank Select. It makes the Minidexed really easy to adjust on the fly!

And yes, we need one instance of it processed, because I do notice hiccups here and there when making volume and pan changes, on a Pi 4, but I bet it’s because they are all on one channel.

Lastly - there’s no way for the screen to track changes as you make them, right?! It’s great to have all this control I just wish it could flip to the parameter being adjusted while receiving MIDI CC for that parameter!

Regardless, amazing work!

@diyelectromusic
Copy link
Contributor Author

diyelectromusic commented Aug 22, 2024

Are you using the first build or the second? The second shouldn't be doing multiples now so I'd hope the performance of that wouldn't be too bad.

It's hard to test things like that, but I'll add in some instrumented code (pun intended) and see if I can work out the performance impact, but I don't have a set up to test this easily at the moment - although I could probably rig something together!

I am thinking about screen updates - again it is something lots of people ask for, but that will have to be its own change I think.

Kevin

@diyelectromusic
Copy link
Contributor Author

Ok, I suspect there is a significant performance hit if the system receives an unsupported CC message as there is a lot of checking required to get to the point of realising it is unsuppported.

I see what I can do - there must be a quicker way to reject unrecognised CCs :)

Kevin

@diyelectromusic
Copy link
Contributor Author

I think that will slimline the processing a little - try this latest build and see how that behaves.

Kevin

Copy link

Build for testing:
MiniDexed_2024-08-22-b94961a
Use at your own risk.

@iluvsa
Copy link

iluvsa commented Aug 23, 2024

The last code works much nicer, nearly immediate volume and pan control for each TG! The setup pictured is so great - individual volume, pan, and detune across all 8 TGs! Stay tuned I think I am gonna stuff it all into the controller and create some vinyl graphics to create a proper DX-56!! Thanks again for the work on this!
IMG_5534

@probonopd
Copy link
Owner

This is way over my head. Could someone please write a concise description of what this does, and why one would need this. So that we can put it in the wiki.

This feature seems rather esoteric to me, but I might be mistaken. Do commercial instruments have something like this? Is it worth complicating the code for this? Could the same effect be achieved in another way (e.g., by sending multiple or different MIDI messages to MiniDexed)?

@diyelectromusic
Copy link
Contributor Author

diyelectromusic commented Aug 23, 2024

You can see for yourself how complicated the code is - i.e. not much.

And almost any multi-timbre, multi-instrument out there will give you ways to control the parameters of each individual instrument over MIDI, so I'd say it fits really well with the idea of the MiniDexed as 8 DX7s playing together.

If it helps, think of each TG as an oscillator then one of the most natural things in the world to do is to change the amplitude of each oscillator with respect to each other and to offset the frequency of each oscillator with respect to the core playing frequency. It is just that in this case a single oscillator is an entire 6-op DX7 synth voice.

And when using it as a "performance" instrument when all TGs are on the same channel there is no way for individual control until now, so I think it works really well with performances too.

So maybe the simplest way to think about it is MIDI control for volume, pan and detune for each individual TG in a performance voice.

I looked quite hard at the DX7/DX7II MIDI support for alternative ways to do this (full analysis here: #702 (reply in thread)) but I couldn't find any. I think this is actually now quite neat.

As I say, it is really quite a relatively simple addition compared to some we've had to massage in (cough MIDIAutoVoiceDumpOnPC cough).

Anyway, like all the changes I submit, I'll update the wiki once its complete.

I could do with some people testing their normal configurations with it to ensure no side effects (there shouldn't, but I've been known to miss things in the past :))

Kevin

@iluvsa
Copy link

iluvsa commented Aug 23, 2024

Yes, to re-iterate the comments above, and given as I was the one originally wondering about it - I think the two main uses for 8 instances of a DX-7 would be to have various instances on different MIDI channels, allowing for multiple DX-7's to be doing different things, or the second (and I think more common scenario given the "Performances" that are provided in the code?), which would be to allow just a big, fat, multi-voice patch to be controlled by a single MIDI channel. In the latter case, the only way to previously adjust the volumes, pans, or de-tunes of individual TGs was to go in to the menu (of course, recalling which voice was assigned to each TG) and adjusting them one by one and listening for changes in the performance - cumbersome in the studio, and fairly impossible (oxymoron alert!) during an actual performance.

I think on commercial synths, this kind of control would be achieved to some degree with a "Mix" knob, but of course, with most commercial synths, you'd only be dealing with two (or three) individual synth engines - here we essentially have 8!

And, for me, none of these things showed up in the miniDexed.ini file unless you add them, so it's there if you need it, but out of sight if you don't!

@miotislucifugis
Copy link

miotislucifugis commented Aug 24, 2024

Rather than add another layer of midi control that needs to specify individual settings, perhaps a more versitile and "playable" approach (albeit prob more difficult) would be to to have mididexed be able to link link a stack of TGs, anywhere between 2 and 8 TGs, with the top one being the leader and all the other TG layers following all of the "leaders" parameter changes...using the leader's midi channel AND/OR minidexed menu settings*. For example, if one wanted to create a 4 layer patch using TG 1-4, TG1 would be the leader and TGs2-4 would mirror all of TG1's parameter settings. If a change was made to one of TG1's parameters, volume for example, the change would be reflected on all of the follower TGs. ideally one could go to each layer's individual settings and override the master's default, for example detune and pan, creating a custom setting on each TG, that would unlink them from the master. Changing Detune and pan setting for TG1 then would then have no effect on the other TGs whose detune and pan setting have been "unlinked"... but channel, reverb, volume,... any paramater that has not been altered would still follow TG's lead. Make sense?

extra ideally, there could be multiple groups - 2x 4 TG layers or 4x 2 TG layers... or a 4 layer stack + a 2 layer stack + 2 individual independent TG voices... etc.

extra extra ideally, would be an option to play all the voice in the stack simultaneously where all are played at the same time or sequentially, where each note played triggers the next TG in the stack, round robin style, like how most polyphonic synths operate.

*i guess midi cc commands would apply by default to all TGs on the same midi channel... and this presents a challenge to how they are applied to the "unlinked" parameters. Maybe the custom setting values could be applied as an offset to the incoming CC messages... the levels would change relative to the original settings. another example: unlinked parameter settings of 10, 20, 30 (on different TGs) would become 60, 70, and 80 respectively with an incoming CC message with the value of 50.

@probonopd
Copy link
Owner

probonopd commented Aug 25, 2024

I guess what I am not understanding is why don't we send MIDI messages to OMNI if we want to steer all TGs. Is it because some controllers can't send to OMNI? Wouldn't it be conceptually easier then to have an option to say "Interpret channel 1 as OMNI" or something like that?

@miotislucifugis
Copy link

miotislucifugis commented Aug 25, 2024

Well, yes some controllers do not send omni...(also many commercial synths do not offer to receive omni) but even so, omni is not ideal because it responds to ALL incoming midi messages. Maybe not a issue if your set up is just minidexed and a controller, but if you want to use a multitrack sequencer and other midi instruments, it quickly becomes problematic. you dont want the lead droning away because it also responding to all the drum, bass, and pad parts.

@diyelectromusic
Copy link
Contributor Author

I guess what I am not understanding is why don't we send MIDI messages to OMNI if we want to steer all TGs. Is it because some controllers can't send to OMNI? Wouldn't it be conceptually easier then to have an option to say "Interpret channel 1 as OMNI" or something like that?

No controllers can "send to OMNI" - that isn't a thing in MIDI. If they say they are doing it, they are sending to each channel 1 to 16 in turn rather than an actual "omni broadcast".

The OMNI concept is really just a MIDI way of saying "whatever channel is used in the message, ignore it and respond as if it was sent to you" in a receiver.

The key issue is that either all TGs are treated as separate instruments for both control AND notes (by being on different channels) or they are treated as the same instruments for both control AND notes (by being on the same channel).

This change is about letting them be the same instrument by being on the same channel, but still allowing some individual control.

Any talk of changing all TG parameters at the same time, or stacking specific numbers of TGs, whilst a valid request is different to the aim here and there are other issues/discussions relating to that elsewhere.

To be honest, given the cost of Pi Zero 2 or Pi 3A+, on the issue of stacking/layering/splitting TGs I'd be tempted to say just make several MiniDexeds and use each as its own multi-TG single instrument :)

Kevin

@diyelectromusic
Copy link
Contributor Author

Is this something we can merge in now? Any objections from anywhere?

Kevin

@probonopd
Copy link
Owner

The main issue is that I still don't fully understand this. It seems rather complicated to me, and it doesn't seem to have an eqivalent in the DX/TX... series of instruments.

Wouldn't this kind of functionality be better solved in a separate external box that could do all kinds of user-defined MIDI translations?

@diyelectromusic
Copy link
Contributor Author

The main issue is that I still don't fully understand this. It seems rather complicated to me, and it doesn't seem to have an eqivalent in the DX/TX... series of instruments.

With our performance system, we deviated from the original DX/TX series a long time ago...

Wouldn't this kind of functionality be better solved in a separate external box that could do all kinds of user-defined MIDI translations?

The problem is that at the moment this is /impossible/ to do over MIDI at all. This change exposes the parameters to MIDI to allow exactly what you suggest. In theory a complex, magic MIDI box could redirect on an individual message basis, but only when all TGs are on their own MIDI channel which completely breaks all the performances and makes playing them all at the same time very problematic.

As we've discussed several times before, MiniDexed is one of two things depending on the viewpoint (and thus configuration) of the user.

It is either 8 DX7s or a single multi-TG instrument.

When 8 DX7s it will typically have TGs on different MIDI channels, will allow full individual control of TGs over MIDI and be in a world of banks and voices. BUT it is not possible to play all TGs at the same time unless notes are sent to all MIDI channels, which is very inefficient in MIDI terms (and essentially not usable for serial MIDI).

As Synth_Dexed is fundamentally a DX7 emulator, not a DX7II or anything else, the "multi-DX7" view originally made the most sense and was (arguably) the original purpose of MiniDexed, but nothing stands still, and then performances came along.

When used as a single-multi-TG instrument, this brings in the world of performances. In this world, banks/voices are irrelevant unless you are making your own performances (and even then are ignored once saved); TGs typically all have the same MIDI channel (all our performances use channel 1); and all TGs respond together to notes and MIDI messages as if it was one large instrument.

However, there is NO means of individual control of the TGs when used like this. There are some bespoke SysEx ways to do it for a DX7II based instrument, but not ours (I looked quite hard - see #702 (reply in thread)).

If someone bought a commercial instrument with 8 individual sound sources, intended to be played together but had no means (over MIDI) to control the mixing parameters between them (volume, pan, tuning) we'd all agree that was a bug and a missing feature that limits its use.

This relatively simple change adds that control.

The alternative is either a full DX7II style implementation of the bespoke SysEx messages (which might come at some point, but needs to basically upgrade Synth_Dexed to a DX7II), or exposing our menu system to MIDI (e.g. something like this proposal for using NRPNs: #604) or my original proposal to expose TG parameters directly over MIDI which you weren't keen on as I'd used to allow several MiniDexeds to share the same UI (#557 (comment)).

Considering what functionality this change enables, for very little additional complications in the code, and considering how it fits a lot more with how people are coming to see MiniDexed (as a single-8-TG-instrument), I see no reason not to do it.

Kevin

@probonopd
Copy link
Owner

Thanks for your explanation. Now I begin to understand the necessity for this, but I am still wondering whether the intended result could be achieved in a much more straightforward way.

Wouldn't a simple solution be to a) have each TG use its own MIDI channel in a performance, and e.g., define one of our MIDI channels as "send to all TGs"? So, if you want to make a change that affects all TGs in the performance, you use that special MIDI channel. Otherwise, you use the respective TG's MIDI channel.

In other words, since there is no "OMNI channel" in MIDI, what prevents us from using one of the regular MIDI channels in such a way that messages sent to it are sent to all TGs?

@diyelectromusic
Copy link
Contributor Author

So you'd rather us not implement a common MIDI idea (multiple controllers for different sound sources) but instead re-invent the mental model about how MIDI itself works by redefining what a channel actually means, going against the MIDI spec (and 40+ years of established behaviour in other devices)?

And while we're at it rewrite each and every performance file we have to a hard-coded MIDI scheme...?

:)

I tend to assess these things by "principle of least surprise". What is the least surprising to someone using the system:

  • Knowing that we can put all TGs on the same or individual channels as we required, but with an option to have MIDI CC values for a few extra parameters in addition to all the MIDI CC values we already support? But fundamentally knowing that what channels are configured is how the device will respond.
  • Or to have a special MIDI channel that works outside of the MIDI spec and means TGs will be responding to notes and messages you might not expect them to be responding to regardless of the channel settings in your configuration?

As I said above, MiniDexed is fundamentally two mental-models built into one system. Your suggestion (to me) conflates the two and I think would just cause major confusion, whereas this change is working well within both mental models, and is also a common pattern for MIDI control when compared to other devices.

Kevin

@probonopd
Copy link
Owner

Well, I think rewriting the performances sounds worse than it is, because we could automate it.

outside of the MIDI spec

OK, we should of course not do something that is outside of the MIDI spec. If I understand you correctly, you are saying that what this PR is doing is what other off-the-shelf instruments are doing in a similar way. Then we should go with it.

But please add extensive documentation to the wiki, including an example ("explain this to a five year old"). Thanks!

@probonopd probonopd merged commit 8c18e60 into probonopd:main Sep 29, 2024
1 check passed
@diyelectromusic diyelectromusic deleted the MultiTGCtrl branch September 29, 2024 11:01
@diyelectromusic
Copy link
Contributor Author

Wiki updated.

Remember this is disabled by default, so doesn't have to be used by anyone not wanting it. And the best way to realise the usefulness is to give it a try. Detune is particularly splendid to try...

Kevin

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