Отправка MIDI CC на несколько миди-каналов
Здравствуйте, я хотел бы отправлять сообщения CC на другой MIDI-канал (регулятор громкости). Сообщения CC поступают с одной ручки.
Решение, которое я нашел, похоже на работу, но я уверен, что оно не идеальное и, похоже, приводит к дрейфу или задержке: громкость не получает одинаковое значение от одного канала к другому.
Мой вопрос: есть ли лучший способ сделать это, чем то, что я сделал.
Я использую и настраиваю следующий пример из библиотеки Teensy Exemple "Пример USB MIDI AnalogControlChange"
В примере использовалась эта строка кода для отправки CC (controlChange) на определенный канал:
MIDI.sendControlChange(controlNumber, controlValue, канал);
Поскольку я хотел иметь несколько целевых каналов для третьего параметра, я попробовал следующее:
MIDI.sendControlChange(controlNumber, controlValue, 1-2-3);
или
MIDI.sendControlChange(controlNumber, controlValue, (1,2,3));
или
MIDI.sendControlChange(controlNumber, controlValue, 1+2+3);
Но это не сработало. Я не нашел в документации, может ли этот параметр принимать более одного числа.
Что сработало, так это умножение аналогового считывания одной и той же ручки и умножение отправленного сообщения. Это не элегантно (конечно, я новичок в программировании), но также я заметил странную задержку или дрейф, если хотите: громкость канала действительно увеличилась с 0 до полной громкости, но громкость на канале 2 не уменьшилась до нуля , так что цель не удалась. Идея состоит в том, чтобы все миди-каналы (с 1 по 8), но 11 каналов регулировались ручкой громкости.
Надеюсь, вы поможете, заранее спасибо
/* 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>
// номер MIDI-канала для отправки сообщений
const int channel = 11;
// непрерывный MIDI-контроллер для каждого аналогового входа
const int controllerA9 = 1; // параметр 1
const int controllerA8 = 2; // параметр 2
const int controllerA7 = 3; // отрезать
const int controllerA6 = 4; // резо
const int controllerA5 = 16; // громкость (для канала 11)
const int controllerA4 = 16; // громкость (для остальных каналов кроме 11
void setup() {
}
// сохраняем ранее отправленные значения для обнаружения изменений
int previousA9 = -1;
int previousA8 = -1;
int previousA7 = -1;
int previousA6 = -1;
int previousA5 = -1;
int previousA4 = -1;
elapsedMillis msec = 0;
void loop() {
// проверяем аналоговые входы только 50 раз в секунду,
// для предотвращения потока MIDI-сообщений
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; // я продублировал это, чтобы иметь другую цель канала
// передавать MIDI-сообщения только при изменении аналогового входа
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 здесь канал отличный от int channel = 11
if (n6 != previousA4) {
usbMIDI.sendControlChange(controllerA4, n6, 2);
previousA4 = n6;
} // 2 здесь канал, который отличается от int channel = 11
}
// MIDI-контроллеры должны отбрасывать входящие MIDI-сообщения.
// http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
while (usbMIDI.read()) {
// игнорировать входящие сообщения
}
}
@coolquentin, 👍0
1 ответ
Лучший ответ:
Одно сообщение CC относится к одному каналу. Если вы хотите повлиять на несколько каналов, вам нужно отправить несколько сообщений:
usbMIDI.sendControlChange(controllerAx, nx, 0);
usbMIDI.sendControlChange(controllerAx, nx, 1);
usbMIDI.sendControlChange(controllerAx, nx, 2);
usbMIDI.sendControlChange(controllerAx, nx, 3);
...
И это, конечно, должно быть сделано в цикле:
for (int c = 0; c < 16; c++)
if (c != 10)
usbMIDI.sendControlChange(controllerAx, nx, c);
- Teensy 2.0 MIDI: количество нот в аккорде ограничено 6?
- Как найти индекс максимального значения в массиве?
- Вложенный цикл
- Как правильно получить MIDI с Arduino, с 6n138?
- В чем разница между выводами SCLK и CLK?
- Как прервать соединение HM10 Bluetooth?
- C++ Undefined reference to 'Class:Function()'
- exit status 1 - expected primary-expression before '(' token
Большое спасибо за ваш ответ. Я попробую оба ваших решения. В вашем примере петли C получает все каналы от 0 до 16, кроме канала 10, верно?, @coolquentin
Еще раз спасибо, он ведет себя так, как ожидалось:
если (n5 != предыдущийA4) { для (int c = 1; c < 8; c++) { usbMIDI.sendControlChange(controllerA4, n5, c); } предыдущийA4 = n5; }
, @coolquentin