概要
M5stackのBLE MIDIでNote On/Note Offを行うデモです。
有線のMIDI
MIDIのNote On/Note Offデモ
M5stackのBLE MIDIのデモの前に、有線MIDIのNote On/Note Offのデモです。
Arduino Uno x GarageBand
(YouTube)
構成
- Arduino UNOにMIDIシールドを載せたもの
- iPhone用 MIDI I/F(デモでは、諸々、昔の製品の組み合わせで動かしていますが、今ならiRig MIDI 2などが利用できると思います。
- GarageBand for iPhone
ソース
Arduino IDEの「ファイル > スケッチ例 > 04.Communication >Midi」そのものです。(一部、コメント削除)
void setup() {
// Set MIDI baud rate:
Serial.begin(31250);
}
void loop() {
// play notes from F#-0 (0x1E) to F#-5 (0x5A):
for (int note = 0x1E; note < 0x5A; note ++) {
//Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
noteOn(0x90, note, 0x45);
delay(100);
//Note on channel 1 (0x90), some note value (note), silent velocity (0x00):
noteOn(0x90, note, 0x00);
delay(100);
}
}
// plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that
// data values are less than 127:
void noteOn(int cmd, int pitch, int velocity) {
Serial.write(cmd);
Serial.write(pitch);
Serial.write(velocity);
}
簡単な解説
MIDI信号は、実はFlow制御なし、BaudRate=31250bpsのUART信号そのものです。
そして、中身の多くは、UARTで3バイトの信号を送るだけになります。
1バイト目: 信号の内容
今回の0x90は、Note Onを示します。(正確には、Channel1へのNote On)
2バイト目: 音程
1バイト目にNote Onを設定すると、2バイト目は、音程を示します。
3バイト目: べロシティ
1バイト目にNote Onを設定すると、3バイト目は、ベロシティ(音の強さ)を示します。
多くの機器は、ベロシティの値を0x00にしてNoteOnを送信すると、NoteOffの信号として扱われます。
MIDI信号の詳細
MIDI1.0規格書のp2-9~p2-11を参考にしてみてください。
BLE MIDI
BLE MIDIのNote On/Note Offデモ
M5Stack x GarageBand
(YouTube)
構成
- M5Stack(デモではM5stack Grayですが、M5stack Basicでも動くと思います。)
- GarageBand for iPhone
ソース
# define LOAD_FONT4
# include <M5Stack.h>
# include <BLEDevice.h>
# include <BLEServer.h>
//BLE関連
//デバイス名
const char *DEVICE_NAME = "m5-stack-ble-midi";
//BLE MIDIのサービスとキャラクタラスティック
const char *SERVICE_UUID = "03B80E5A-EDE8-4B33-A751-6CE34EC4C700";
const char *CHAR_UUID = "7772E5DB-3868-4112-A1A9-F2669D106BF3";
//BLEデータ
BLEServer *pServer;
BLECharacteristic *pCharacteristic;
bool isConnected = false;
//BLE MIDIデータ
unsigned char buff[] = {0x80, 0x80, 0xB0, 0x01, 0x64};
//BLE関連関数
// サーバーのコールバック関数
class cbServer: public BLEServerCallbacks {
void onConnect(BLEServer *pServer) {
isConnected = true;
M5.Lcd.clear();
M5.Lcd.drawCentreString(" BLE Connected ", 160, 120, 4);
};
void onDisconnect(BLEServer *pServer) {
isConnected = false;
M5.Lcd.clear();
M5.Lcd.drawCentreString(DEVICE_NAME, 160, 120, 4);
}
};
void setup(){
int i;
// M5Stackの初期化
M5.begin();
// BLE初期化
BLEDevice::init(DEVICE_NAME);
// サーバーの作成
BLEServer *pServer = BLEDevice::createServer();
// コールバック関数の設定
pServer->setCallbacks(new cbServer());
// サービスの作成
BLEService *pService = pServer->createService(SERVICE_UUID);
// キャラクタリスティックの作成
pCharacteristic = pService->createCharacteristic(
CHAR_UUID,
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY
);
// サービスの開始
pService->start();
//アドバタイジングの開始
pServer->getAdvertising()->addServiceUUID(SERVICE_UUID);
pServer->getAdvertising()->start();
//ディスプレイにデバイスネームを表示
M5.Lcd.drawCentreString("m5-stack-ble-midi", 160, 120, 4);
}
void loop() {
if (isConnected)
{
for (int note = 0x1E; note < 0x5A; note ++)
{
notifyNote(note, 0x45);
delay(100);
notifyNote(note, 0x00);
delay(100);
}
}
}
//MIDI関連関数
//BLE Noteを送信
void notifyNote(int note, int velocity)
{
//noteをvelcityの強さで送信
buff[2] = 0x90;
buff[3] = note;
buff[4] = velocity;
//MIDIデータをNotify
pCharacteristic->setValue(buff, 5);
pCharacteristic->notify();
}
簡単な解説
細かいBLEの仕組みの話をすっ飛ばすと、BLE MIDI対応機器に5バイトの信号を送るだけになります。
1バイト目、2バイト目: タイムスタンプ
正直、よく分かっていません...。とりあえず、今のデモでは、0で問題なさそうなので、0のままにしてあります。タイムスタンプを0に設定するには、1バイト目、2バイト目、共に0x80にしておきます。
3バイト目~5バイト目: MIDI信号の1バイト目~3バイト目
今回のNote Onのデモでは、
- 3バイト目: Note On("0x90")
- 4バイト目: 音程
- 5バイト目: ベロシティ
を設定しています。
最後に...
MIDI信号は、非常にシンプルな規格で、BLE MIDIもそれに準じた非常にシンプルな規格です。いろんなセンサの出力をBLE MIDI信号に乗せて、新たな音を探してみてはいかがでしょうか?