Closed probonopd closed 1 year ago
I'm sure something like this could be worked in, but I'm not quite sure how it would work with the long/short press timings.
One thing I've been missing when looking through the code (as was evident in the polling/interrupt question) is any picture of the design of the scheduling in MiniDexed. How did you put it all together at the top level? What is the "main loop" and what is already interrupt driven? And so on?
The trick for something like MIDI buttons will be ensuring the MIDI handling and UI code interact in a neat way and not get stuck waiting for each other, and things like that...
Ideally MIDI control would be some kind of internal triggers that map over to buttons, but the actual MIDI events that trigger them would be configurable. Some people might wish to use MIDI CC messages, but some might rather map them on to NoteOn/NoteOff events (for example) and it would be nice to be able to do something with continuous controllers for values too eventually that allows the "encoder" style menu handling too (although MIDI CC values are more like pots than encoders, but we could have a think).
I think the best way to achieve this would be to do a bit of refactoring.
At the moment uibuttons.cpp has code to handle polling the buttons, and also handling the timings. This then calls an event handler in userinterface.cpp.
If you want the buttons and the midi controls to share the same timing code, I think we would need to add another layer in the middle, so there would be a first layer that handles the polling and the midi messages, which then sends some simple messages (basically button pressed, button released) to an intermediate layer which handles the timings. This middle layer would then call the event handlers in the UI.
Alternatively, a simpler but maybe messier way to implement this would just be to have some new code to handle the midi messages with its own timing code. This would mean duplicating the timing logic in the midi handler, but would mean we wouldn't need to add that middle layer.
EDIT:
The other option is to not allow long press / double click on controller buttons. I don't know how many buttons midi controllers tend to have, but if there are normally at least 7 buttons available then you could just map everything to a separate button.
IMHO, midi handling superseeds anything else and must have their own timing logic
Button handling can be done using a very small fraction of available time slot. Maybe once per every eight midi message handling cycles.
Maybe @rsta2 can give us some guidance/recommendations here?
As I say, I think we should try to document the current "loop" and scanning in the system to help with conversations like this. If you don't have it already to hand @probonopd then I'll take a wander through the code and see if I can work it out...
As I say, I think we should try to document the current "loop" and scanning in the system to help with conversations like this. If you don't have it already to hand @probonopd then I'll take a wander through the code and see if I can work it out...
Ok, I've had a first go at documenting how I think it all starts up and then runs. Maybe those who know more than me could take a look: https://github.com/probonopd/MiniDexed/wiki/Development
Aside: I have that graphic in an OpenOffice odp file at present - is there somewhere useful to store it?
@diyelectromusic That's very helpful, especially the bullets giving an overview of how it works. I think this also shows that on a multi-core raspberry pi the discussions we've had about polling vs interrupts and having an inconsistent running time of the polling algorithm aren't that applicable. We probably need to try to test everything on a single core pi to make sure there are no issues with stuttering!
I've started taking a look at some possibilities of having MIDI buttons. It's just experimenting at this stage, but you'll be able to track progress here: https://github.com/diyelectromusic/MiniDexed/tree/buttonmidi
I've started taking a look at some possibilities of having MIDI buttons. It's just experimenting at this stage, but you'll be able to track progress here: https://github.com/diyelectromusic/MiniDexed/tree/buttonmidi
Ok, I now have a "it seems to work for me" version on the above link... Do take a look! :)
There are some new minidexed.ini entries (see the new sample ini file) to define the MIDI CC numbers to use and the MIDI channel to listen on for the UI.
I've only assigned a single-click action to MIDI buttons. I'm not sure if it makes sense to do things like try to time a double click or long press over MIDI? But in principle I haven't ruled it out in the future, but tried to keep things relatively simple for now.
I've basically invented a pseudo-GPIO pin called a "midipin" whose status can be set from the MIDI subsystem, but then can be read just like a regular IO pin. That way most of the button handling is actually still the same (hence long press and double click could be added if we really want to try it!).
I had hoped to have my CMIDIPin inherit from the Circle CGPIOPin class, so actually almost all the button code was ignorant of if it was using a GPIO or MIDI pin, but my C++ wasn't up to the job! So it is an either/or at present, but there are only a couple of places where it matters anyway, so I'm not worrying about it! Fixing this in a nicer C++ way is left as an exercise for the more competent-than-I reader!
Note: I've only implemented buttons. I can't really see how we'd map MIDI CCs (with a 0-127 range) onto a rotary encoder, so I've not even gone there... but in theory now the MIDI devices can trigger events in the UI we could take a look if someone can suggest a good mapping...
Ok, I've had a first go at documenting how I think it all starts up and then runs.
Thanks @diyelectromusic, this is really helpful. As for storing the OpenOffice odp, if you attach it zipped to this thread then we can link to the attachment from the Wiki page.
Ok, I now have a "it seems to work for me" version on the above link... Do take a look! :)
Cool, will do! :+1:
If anyone is interested in giving my branch that does this a go, I'd be very happy to hear what you think about it and if you think this is responsive/useful enough to move forward... :)
I think this issue is resolved now?
Yes, thanks a lot @diyelectromusic :+1:
It would be nice if we could use buttons on MIDI controllers instead of GPIO buttons on the Raspberry Pi. This way, one would not have to deal with connecting physical buttons to Raspberry Pi pins but could use the buttons built into many MIDI controllers.
E.g., these guys:
(Example shows the Nektar Impact LX61+.)
The buttons toggle between 0 and 127:
B0 xx 7F
(key down),B0 xx 00
(key up) withxx
being different for each button.Maybe we could have in
minidexed.ini
something like this:Value
0x7F
means "button down", value0x00
means "button up".@diyelectromusic and @stevelittlefish do you think this could be wired into the existing logic for interpreting clicks, double-clicks, and long-presses?