| ||||
Передача MIDI данных от Arduino в компьютер
| ||||
|
Передача одиночного потока данных От одного сенсора передать данные от Arduino в Max/MSP очень просто. Для примера возьмем потенциометр и подключим его к pin 0 контроллера Arduino. Контроллер будет считывать состояние потенциометра и передавать данные последовательным потоком в компьютер в ПО Max/MSP. Диапазон чисел от потенциометра будет лежать в пределах 0-127, что как раз подходит для MIDI.
Скетч для Arduino очень прост: byte val; void setup() { Serial.begin(57600); // Открываем последовательный вывод данных } void loop() { val = analogRead(0) / 8; // считываем значение потенциометра и преобразовываем к диапазону 0 - 127 Serial.print(val, BYTE); // отдаем значение в послед. порт delay(5); // задержка } } Патч для Max/MSP: Но что делать, если необходимо передавать данные от 2-х, 3-х, или сразу от 4-х потенциометров? Вот тут сразу начнутся проблемы. Дело в том, что в один промежуток времени может передаваться/приниматься только один байт. И будут возникать неизбежные задержки в передаче данных. В данном варианте в первом байте будет содержаться информация от первого потенциометра, во втором байте - от второго. На стороне ПК, в MIDI-секвенсоре будет трудно разделять эти данные, да и неэффективно. Передача многопоточных данных Одним из решением данной проблемы является преобразование всех данных от потенциометров в MIDI-формат в контроллере Arduino, а затем уже передача MIDI-данных от Arduino в Max/MSP. MIDI структура Структура MIDI кажется сложной только на первый взгляд, на самом деле вы в ней быстро освоитесь. Каждое действие (взятие ноты, снятие ноты, питч-бенд и др.) передается в виде MIDI-событий. Мы будем работать с MIDI-событиями состоящими из трех байт. Соответственно в каждом байте хранится 8 бит и мы охватываем диапазон от 0 до 255. Первый байт - статус, за ним идут 2 байта с данными. В статусном байте содержится информация о типе события, который мы передаем (взятие ноты, снятие ноты, пауза и т.п.) и номер канала от 1 до 16. Байты с данными содержат информацию о действии, к примеру если бы нажали клавишу какой-либо ноты, то данные будут содержать тон ноты и как резко вы ее нажали (velocity): Status Byte; Data Byte #1; Data Byte #2; Байт статуса Статусный байт разделен на два полубайта. Первый полубайт содержит биты 4-7 байта, а второй полубайт биты 0-3. Для удобства, принято использовать шестнадцатеричную систему счисления, т.о. первый полубайт может содержать значение от 0 до F, то же самое и второй 0-F. Первый полубайт указывает на тип события: Второй полубайт указывает на номер канала: Если совместить два полубайта, то мы получим всю необходимую информацию статусного байта о MIDI-действии. К примеру, если необходимо передать информацию о взятии ноты на 1-м канале, то значение статусного байта будет 0x90. Префикс 0x указывает на то, что используется шестнадцатеричная система счисления, 9 - взятие ноты, 0 - 1 канал. Или, если необходимо передать питч-бенд на 3-канале, то значение статус-байта будет 0xE2. Байты данных После того, как передан статусный байт, нужно передать два байта с данными. Для того, чтобы стало более понятно, приведу два примера:в первом будет взятие ноты (note-on), во втором сообщение контроллера (control change). При взятии ноты в байте #1 содержится значение тона (pitch) в диапазоне 0-127. В байте #2 содержится значение velocity также в диапазоне 0-127. К примеру, если необходимо передать взятие ноты на 3 канале с pitch 60 и velocity 123, то последовательность байтов для передачи будет следующая: Если статусный байт передает сообщение контроллера, то в 1-ом байте содержится номер контроллера 0-127, а во втором его значение 0-127. К примеру: Основные контроллеры MIDI Modulation (CC #1) Передача данных с Arduino Итак, после всего вышеописанного мы сможем легко посылать MIDI-данные с Arduino. Затем эти данные поступают в Max/MSP и дальше передаются в virtual MIDI path (IAC Driver Bus 1 под OS X или LooBe1 под Windows), а затем уже в музыкальное ПО или DAW (Live, Logic, ProTools, Reason). Приведу примеры с взятием ноты и с передачей сообщения контроллера. Пример 1. Отсылаем событие взятия ноты, пауза 1 сек, снятие ноты, пауза 1 сек. Скетч Arduino: void setup() { Serial.begin(57600); } void loop() { // посылаем note-on Serial.print(0x90, BYTE); // MIDI Note-on; канал 1 Serial.print(60, BYTE); // MIDI note pitch 60 Serial.print(127, BYTE); // MIDI note velocity 127 delay(1000); // пауза 1 сек // посылаем note-off Serial.print(0x90, BYTE); // MIDI Note-on; канал 1 Serial.print(60, BYTE); // MIDI note pitch 60 Serial.print(0, BYTE); // MIDI note velocity 0 (т.е. note off) delay(1000); // пауза 1 сек } Патч для Max/MSP: Пример 2. Отсылаем событие контроллера каждую секунду Скетч Arduino: void setup() { Serial.begin(57600); } void loop() { // посылаем сообщение контроллера Serial.print(0xB2, BYTE); // MIDI control change; канал 3 Serial.print(1, BYTE); // MIDI controller #1 Serial.print(127, BYTE); // MIDI controller value of 127 delay(1000); // пауза 1 сек } Патч для Max/MSP: Соединяем все воедино Теперь, мы легко можем считает состояние нескольких потенциометров, сформировать и послать MIDI-данные в Max/MSP. Рассмотрим пару примеров. Пример 1. Считываем значение потенциометров, подключенных к аналоговым входам 0 и 1. Эти значения будут посылаться в MIDI канал 1, контроллер 1 и канал 2, контроллер 1. Скетч Arduino: byte val = 0; void setup() { Serial.begin(57600); } void loop() { val = analogRead(0) / 8; // считываем значение потенциометра 1 // let's send a control change message Serial.print(0xB0, BYTE); // MIDI control change; канал 1 Serial.print(1, BYTE); // MIDI controller #1 Serial.print(val, BYTE); // MIDI controller значение потенциометра 1 val = analogRead(1) / 8; // считываем значение потенциометра 2 // let's send a control change message Serial.print(0xB1, BYTE); // MIDI control change; канал 2 Serial.print(1, BYTE); // MIDI controller #1 Serial.print(val, BYTE); // MIDI controller значение потенциометра 2 delay(5); } Патч для Max/MSP: Пример 2. Считываем значение с 6 потенциометров и передаем данные контроллера 1 в канал 1, 2, 3, 4, 5 и 6. Скетч Arduino: byte val = 0; void setup() { Serial.begin(57600); } void loop() { for(int i = 0; i < 6; i ++) { val = analogRead(i) / 8; // считываем значения потенциометров // (на аналоговых входах 0 - 5) // посылаем сообщение контроллера Serial.print(0xB0 + i, BYTE); // MIDI control change; номер канала Serial.print(1, BYTE); // MIDI controller #1 Serial.print(val, BYTE); // MIDI controller значение от потенциометра delay(1); // пауза } } Патч для Max/MSP: Оригинал статьи на английском языке (перевод Колтыков А.В.)
Добавил: Павел (Admin) Автор: Неизвестно Вас может заинтересовать:
|
|||
| ||||
|