0

Hi so i would like to send CC messages to different MIDI Channel (volume control). The CC messages are coming from one knob.

The solution i found kind of work but i'm pretty sure is not ideal and seems to introduce drift or lag: the volume isn't getting the same value from one channel to another.

My question is: is there a better way to do it than what i have done.

I use and tweak the following exemple provided in the Teensy Exemple library "USB MIDI AnalogControlChange Example"

The exemple was using this line of code to send CC (controlChange) to a specific channel:

MIDI.sendControlChange(controlNumber, controlValue, channel);

As i wanted to have multiple target channels for the third parameter i tried things like this:

MIDI.sendControlChange(controlNumber, controlValue, 1-2-3);

or

MIDI.sendControlChange(controlNumber, controlValue, (1,2,3));

or

MIDI.sendControlChange(controlNumber, controlValue, 1+2+3);

But it didn't worked. I didn't find in the documentation if this parameter could accept more than one number.

What worked is to multiply analog read of the same knob and multiply the sent message. It's not elegant (i'm new to programing of course) but also i noticed i strange latency or drift if you will: the volume of the channel did went from 0 to full volume but the one on channel 2 didn't go to zero, so the purpose failed. The idea here is to have all the midi channels (1 to 8) but the 11 to be affected by the volume knob.

Hope you can help, in advance, thanks

    /* USB MIDI AnalogControlChange Example

   You must select MIDI from the "Tools > USB Type" menu
   http://www.pjrc.com/teensy/td_midi.html

   This example code is in the public domain.
*/

#include <Bounce.h>

// the MIDI channel number to send messages
const int channel = 11;


// the MIDI continuous controller for each analog input
const int controllerA9 = 1; // param 1
const int controllerA8 = 2; // param 2
const int controllerA7 = 3; // cutoff
const int controllerA6 = 4; // reso
const int controllerA5 = 16; // volume (for channel 11)
const int controllerA4 = 16; // volume (for other channels exept 11

void setup() {

}

// store previously sent values, to detect changes
int previousA9 = -1;
int previousA8 = -1;
int previousA7 = -1;
int previousA6 = -1;
int previousA5 = -1;
int previousA4 = -1;

elapsedMillis msec = 0;

void loop() {
  // only check the analog inputs 50 times per second,
  // to prevent a flood of MIDI messages
  if (msec >= 20) {
    msec = 0;
    int n0 = analogRead(A9) / 8;
    int n1 = analogRead(A8) / 8;
    int n2 = analogRead(A7) / 8;
    int n3 = analogRead(A6) / 8;
    int n4 = analogRead(A5) / 8;
    int n5 = analogRead(A4) / 8;
    int n6 = analogRead(A4) / 8; //i duplicated this to be able to have a different channel target
    // only transmit MIDI messages if analog input changed
    if (n0 != previousA9) {
      usbMIDI.sendControlChange(controllerA9, n0, channel);
      previousA9 = n0;
    }
    if (n1 != previousA8) {
      usbMIDI.sendControlChange(controllerA8, n1, channel);
      previousA8 = n1;
    }
    if (n2 != previousA7) {
      usbMIDI.sendControlChange(controllerA7, n2, channel);
      previousA7 = n2;
    }
    if (n3 != previousA6) {
      usbMIDI.sendControlChange(controllerA6, n3, channel);
      previousA6 = n3;
    }
    if (n4 != previousA5) {
      usbMIDI.sendControlChange(controllerA5, n4, channel);
      previousA5 = n4;
    }

    if (n5 != previousA4) {
      usbMIDI.sendControlChange(controllerA4, n5, 1);
      previousA4 = n5;
    } // 1 here is the channel who's different from the int channel = 11

     if (n6 != previousA4) {
      usbMIDI.sendControlChange(controllerA4, n6, 2);
      previousA4 = n6;
    } // 2 here is the channel who's different from the int channel = 11

  }

  // MIDI Controllers should discard incoming MIDI messages.
  // http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
  while (usbMIDI.read()) {
    // ignore incoming messages
  }
}
0

A single CC message applies to a single channel. If you want to affect multiple channels, you have to send multiple messages:

usbMIDI.sendControlChange(controllerAx, nx, 0);
usbMIDI.sendControlChange(controllerAx, nx, 1);
usbMIDI.sendControlChange(controllerAx, nx, 2);
usbMIDI.sendControlChange(controllerAx, nx, 3);
...

And this should of course be done in a loop:

for (int c = 0; c < 16; c++)
    if (c != 10)
        usbMIDI.sendControlChange(controllerAx, nx, c);
| improve this answer | |
  • Thanks a lot for your answer. I'll try both of your solution. On your loop exemple C is getting all the channel between 0 to 16 except the channel 10 right ? – coolquentin Mar 29 at 18:55
  • Thanks again, it behave as expected like that: if (n5 != previousA4) { for (int c = 1; c < 8; c++){ usbMIDI.sendControlChange(controllerA4, n5, c); } previousA4 = n5; } – coolquentin Mar 31 at 7:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.