Control-Surface icon indicating copy to clipboard operation
Control-Surface copied to clipboard

control change callback

Open TomW1605 opened this issue 3 years ago • 10 comments

Is your feature request related to a problem? Please describe. i am building a midi controller that has LEDs to show mute status. as it will be in my bedroom i don't want the leds on all the time. as such i am writing a time out for them. the problem is i want them to turn back on with any input. that means that not only do i have to setup all 7 buttons and 14 pots with the midi library but i also have to poll them in the main loop to know weather to turn the lights on.

Describe the solution you'd like i think the beast solution to this would be a call back that is fired when a change is made to the inputs.

Describe alternatives you've considered setup all 7 buttons and 14 pots with the midi library and poll them in the main loop to know weather to turn the lights on.

TomW1605 avatar Apr 26 '21 12:04 TomW1605

is my other issue of any help? https://github.com/tttapa/Control-Surface/issues/456

emalihin avatar Apr 26 '21 15:04 emalihin

not sure how i missed that. it is basically what i am after. unfortunately once i have done this project i will be sharing it with some friends so i dont want to mod the library so i will need to wait for it to be implemented natively.

TomW1605 avatar Apr 26 '21 15:04 TomW1605

I am yet to receive feedback on that issue, so I am not sure if it's possible to implement this in the lib/make it portable. A user may want to register multiple callbacks, rn I am not positive this can be accounted for in the lib? Moreover it's not clear if/what needs to be passed in the callback 🤔

emalihin avatar Apr 26 '21 15:04 emalihin

for multiple callbacks that is already an issue with the midi callbacks and the solution to that is just an if statement in the call back. as for what to pass. i would say everything it can maybe in an object so it is a single parameter.

TomW1605 avatar Apr 27 '21 09:04 TomW1605

Describe the solution you'd like i think the beast solution to this would be a call back that is fired when a change is made to the inputs.

Describe alternatives you've considered setup all 7 buttons and 14 pots with the midi library and poll them in the main loop to know weather to turn the lights on.

You would have to poll all inputs either way, either in your main code or in the library. Adding a callback to each MIDI element would add unnecessary complexity for the majority of use cases so that's unlikely to make it into the library, but you can still use your own Custom MIDI Output Elements which you could add as many callbacks to as you like.

An alternative approach could be to monitor the MIDI activity in and out of Control Surface, you can do this by implementing a custom MIDI Pipe, so you'll get a “callback” whenever any MIDI messages passes through it.

tttapa avatar May 13 '21 15:05 tttapa

You would have to poll all inputs either way, either in your main code or in the library.

I assumed you are already polling all inputs in the library. How else are you detecting a change in state? I was hoping that by implementing it in the library, instead of the main code, the polling, filtering and change detection code could be reused.

An alternative approach could be to monitor the MIDI activity in and out of Control Surface, you can do this by implementing a custom MIDI Pipe, so you'll get a “callback” whenever any MIDI messages passes through it.

That would be an acceptable alternative, but I can’t work out how to do it. The docs you linked mention that a pipe can be "filtered”, and I assume this is where I would put my call back code, but I can’t work out how to add a filter. Also, I can’t find any use of the functions in those docs anywhere in the example code.

TomW1605 avatar May 14 '21 01:05 TomW1605

I think it would help if the inbuilt midi elements (such as CCPotentiometer) were easier to extend upon. For example, in CCPotentiometer, the FilteredAnalog is private, so there is no way to execute some custom code when the pot has updated. Maybe an easy solution would be to keep track of a hasUpdated field. Then subclasses can call the superclass update method and execute their own code when hasUpdated is true. What do you think of this idea?

dennism1997 avatar Jun 04 '21 10:06 dennism1997

that would suit my needs pretty well.

TomW1605 avatar Jun 04 '21 11:06 TomW1605

For example, in CCPotentiometer, the FilteredAnalog is private, so there is no way to execute some custom code when the pot has updated.

I'd argue that that's not the purpose of CCPotentiometer. I don't think adding extra complexity and overhead to a simple class like CCPotentiometer would be a good design choice.

If you need more flexibility, the best solution is to create a custom MIDI element:

 class CustomCCPot : public MIDIOutputElement {
     AH::FilteredAnalog<7> filteredAnalog;
     MIDIAddress address;

   public:
     CustomCCPot(pin_t analogPin, MIDIAddress address)
      : filteredAnalog(analogPin), address(address) {}

     void begin() final override { filteredAnalog.resetToCurrentValue(); }
  
     void update() final override {
         if (filteredAnalog.update()) {
             // something extra here
             Control_Surface.sendCC(address, filteredAnalog.getValue());
         }
     }
 };

This is a much simpler and more flexible approach than adding features to CCPotentiometer.

tttapa avatar Jun 04 '21 23:06 tttapa

 class CustomCCPot : public MIDIOutputElement {
     AH::FilteredAnalog<7> filteredAnalog;
     MIDIAddress address;

   public:
     CustomCCPot(pin_t analogPin, MIDIAddress address)
      : filteredAnalog(analogPin), address(address) {}

     void begin() final override { filteredAnalog.resetToCurrentValue(); }
  
     void update() final override {
         if (filteredAnalog.update()) {
             // something extra here
             Control_Surface.sendCC(address, filteredAnalog.getValue());
         }
     }
 };

is that all i would need to replicate the basic function of the standard pot control?

TomW1605 avatar Jun 06 '21 06:06 TomW1605