coolquentin
Member
Hi, so i would like to send a CC message to multiple MIDI Channels at once (volume control).
The purpose is to have one knob that set the volume level of channel 1 to 8. I'm using Teensy 3.6 as a usb midi controller directly into my instrument which is an OP-Z.
The solution i found kind of work but i'm pretty sure is not ideal and seems to introduce drift or lag (sorry for the lack of proper terms): the volume doesn't seems getting the same value from one channel to another (see below for more explanation).
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);
I guess it's naive 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.
Below there's my code, hope you can help, in advance, thanks.
The purpose is to have one knob that set the volume level of channel 1 to 8. I'm using Teensy 3.6 as a usb midi controller directly into my instrument which is an OP-Z.
The solution i found kind of work but i'm pretty sure is not ideal and seems to introduce drift or lag (sorry for the lack of proper terms): the volume doesn't seems getting the same value from one channel to another (see below for more explanation).
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);
I guess it's naive 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.
Below there's my code, hope you can help, in advance, thanks.
Code:
/* USB MIDI AnalogControlChange Example
You must select MIDI from the "Tools > USB Type" menu
[url]http://www.pjrc.com/teensy/td_midi.html[/url]
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.
// [url]http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash[/url]
while (usbMIDI.read()) {
// ignore incoming messages
}
}