tttapa / MIDI_controller

This is a library for creating a MIDI controller using an Arduino or Teensy board.
GNU General Public License v3.0
404 stars 69 forks source link

Midi Controller.h - Analog.cpp - Potentiometer to Send Midi Note with Velocity #91

Closed nickho74 closed 5 years ago

nickho74 commented 5 years ago

Hi Pieter,

First of all, Thank you for the Midi Controller Sketch. It have been very useful for my project !

I have been using it for my new Midi Project 2019.

It consists of 1 - Mega2560 8 - Multiplexer, 96 - Buttons 32 - Faders (Linear Potentiometer).

I have tested uploaded your code and all works.

At the moment for Analog.cpp , it will send a Midi CC.

Here is what I would like to request.

Because I will be using as a Midi device for a lighting Controller that only reads Midi Notes On/Off and

Velocity. Some of the software did not implement Midi CC yet. I am having trouble using the Fader to

send Midi Note On with Velocity.

When Faders is to Full %, It needs to send MIDI Note On at Velocity 127. When Faders to Zero %, It needs to send MIDI Note Off at Velocity 0. When Faders is at certain level - 38 % or 64%, It needs to be at MIDI Note On at Velocity 38 or 64.

1) Is there a way to modify the Analog.cpp and Analog.h to also sent Midi Notes On/Off with

Velocity?

Some reading issue from Midi output -

2) When using 'MIDI Monitor' in mac to read the Midi output, I have seen some strange random trigger

of other Notes (with random velocity values but not 127 or 0 and random Notes On values) when pressing some of the buttons or repeatedly pressing same button.

Here is another request for my next MIDI project.

3) Can suggest to add in a KY-023 Joystick.cpp, Joystick.h ?

When Joystick is 'rest' position values at X-axis & Y-axis which is around 512 & 512 respectively.

Depending on the wiring of the pins,

On my tested Joystick sketch,

X-axis to LEFT - 0, RIGHT - 1023 Y-axis to UP - 0, Down - 1023

When is at 0 value, It will send a MIDI Note Off at Velocity 0. When is at 1023, It will send a MIDI Note On at Velocity 127. When is at 'rest' position 512, It will send a MIDI Note On at around Velocity 64.

Waiting for your reply.

Thanks Nick Ho

tttapa commented 5 years ago
  1. Basically you just inherit from the AnalogBase class, and implement the send method: https://github.com/tttapa/MIDI_controller/blob/5781d45369ffa3c4add30258b94d6221071122f5/src/MIDI_Outputs/Analog.h#L55

I think you can mostly copy the AnalogCC class, (keep the old value, hysteresis etc.) and just replace the control change with note on: https://github.com/tttapa/MIDI_controller/blob/5781d45369ffa3c4add30258b94d6221071122f5/src/MIDI_Outputs/Analog.cpp#L29-L40

void AnalogNote::send(unsigned int input)
{
  uint8_t value = hysteresis.getOutputLevel(input); // map from the 10-bit analog input value [0, 1023] to the 7-bit MIDI value [0, 127] with hysteresis
  if (value != oldVal)                              // if the value changed since last time
  {
    MIDI_Controller.MIDI()->send(NOTE_ON,
                                 channel + channelOffset * channelsPerBank,
                                 note + addressOffset * channelsPerBank,
                                 value); // send a MIDI Note On event
    oldVal = value;
  }
}

According to the MIDI standard, Note On with a velocity of zero is equivalent to Note Off, so I think this should work. If the software you're using doesn't follow the standard, you might have to add an if statement to send a Note Off if the value is zero.

  1. I don't know why this is happening, and I haven't encountered this problem yet. Could you post your complete code? Are you using Hairless MIDI? Is the baud rate correct (115200 baud)? Does Hairless show any warnings or errors?

  2. This should be equivalent to two separate AnalogNote instances, one for x and one for y.

nickho74 commented 5 years ago

Ok thanks, I will try out the modification code and see the result.

Anything not sure or questions , I will ask your help again.

As for the Random Note triggering, I will send you the result that I have found.

nickho74 commented 5 years ago

Hi Pieter,

All modification code works properly. Thanks !

Now to next questions, I will open a new issue.

penglinek commented 6 months ago

Hello, i have same thing to do but my programing skills is not enoguh good to do is i try add this to Analog.cpp:

void AnalogNote::send(unsigned int input)
{
  uint8_t value = hysteresis.getOutputLevel(input); // map from the 10-bit analog input value [0, 1023] to the 7-bit MIDI value [0, 127] with hysteresis
  if (value != oldVal)                              // if the value changed since last time
  {
    MIDI_Controller.MIDI()->send(NOTE_ON,
                                 channel + channelOffset * channelsPerBank,
                                 note + addressOffset * channelsPerBank,
                                 value); // send a MIDI Note On event
    oldVal = value;
  }
}

and add this to Analog.h:

#define Analog _Pragma("GCC warning \"'Analog' is deprecated\"") AnalogCC

/**
 * @brief A MIDI_Control_Element that reads an analog input and sends it over MIDI as a 7-bit Control Change event. 
 */
class AnalogNote : public AnalogBase
{
public:
  /**
   * @brief Construct a new AnalogCC object.
   * \
   * @param analogPin 
   *        The analog pin to read from.
   * @param note 
   *        //The MIDI Controller number [0, 119].
   * @param channel
   *        The MIDI channel [1, 16].
   */
  AnalogCC(pin_t analogPin, uint8_t note, uint8_t channel)
      : AnalogBase(analogPin), note(note), channel(channel) {}

protected:
  /**
   * @brief Send the analog value over MIDI as a 7-bit Control Change event.
   * 
   * Only sends a MIDI message if the value has changed.
   * 
   * @param value 
   *        The 10-bit analog value to be sent.
   */
  virtual void send(unsigned int value);
  uint8_t oldVal = -1;

  const uint8_t controller;
  const uint8_t channel;

  Hysteresis hysteresis;
};

but arduino print errors: screen errors