Mackie Control プロトコル
コントロールサーフェス(フィジカルコントローラー)とDAWでやり取りするためのプロトコルです。
Human User Interface Protocol(HUI)が最初に作成され、その後続として出た Mackie Control プロトコルについてまとめます。
- Human User Interface Protocol - Wikipedia
- Mackie Designs Releases HUI
- Mackie Designs HUI
- Mackie Designs HUI Owner's Manual (PDF)
HUI から Mackie Control プロトコルまで作成された流れについて
Mackie社の製品が出た流れです。
Human User Interface(HUI)の誕生
1998年、Mackie社は「Human User Interface」を発売しました。
コンピューターを使用したレコーディングシステムで業界標準となっている有名なものにDigidesign社(現Avid)の「Pro Tools」というものがあります。
このPro Toolsがまだバージョン4.0だった時代に、Mackie社はDigidesign社(現Avid)と共同プロジェクトを立ち上げHuman User Interface(HUI)というコントロールサーフェス(フィジカルコントローラー)を開発しました。
- Mackie HUI - Sound On Sound
- Digidesign Pro Tools - Sound On Sound
- Mackie Tech Support - Discontinued Products
コンピューター上の操作を物理的に行えるようになる操作パネルの役割をしています。
この製品で使用されている通信プロトコルが通称HUIプロトコルと呼ばれるようになりました。
HUIプロトコルは様々なDAWでサポートされることになります。
その後、小型のBaby HUIも発売。
Logic Controlの誕生
2002年、HUIに続き、Emagic社(現Apple社)のLogicに対応するLogic Control発売。
これは独自プロトコルでした。そのためLogic専用となっていました。
- Logic Control
- Logic Control
- Logic Control User’s Manual version 2.0 (PDF)
- Emagic Logic v5 & Logic Control - Sound On Sound
- emagic news - Logic 5 and Logic Control August 31st 2001
- emagic news - Logic 5 and Logic Control — the pricing October 12th 2001
- emagic news - Logic Control — The Original July 24th 2002
その後、Emagic社はすぐにApple社に買収されました。
最終版のファームウェア(Logic Control v1.02)では、Logic Control / Mackie Control(後述) 両方のプロトコルに対応したようです。
Mackie Controlの誕生
2002年、Emagic社の買収に関連してか、Mackie社はLogic Controlから外見はほぼそのままでファームウェアを変更したMackie Controlを発売。
この機種で使用された通信方式が、いわゆる「Mackie Control プロトコル」として幅広く浸透することになります。
こちらも最終版のファームウェア(Mackie Control v1.2)では、Mackie Control / Logic Control 両方のプロトコルに対応したようです。
Mackie Control Universal(MCU)の誕生
2003年になり、こちらも外見はほぼそのまま、アップデートを経てMackie Control Universalという製品になりました。
この際、今まで発売されたMackie Control、Logic Control、HUIと3種類すべてのプロトコルに対応して、Universalと製品名が変化したようです。
電源をONにする際に、チャンネル1と2のSELECTボタンを押し続けることによって、ディスプレイにモード選択画面が現れるようです。
前述のMackie Control / Logic Controlでは有償のアップグレードキットを使用して、Mackie Control Universal相当にしてあるとHUIモードも選択することが可能とのこと。
- Mackie Control Universal Upgrade Center
- How do I swich the Mackie Control to HUI or Logic Control emulation mode?
Mackie Control Universal Proの誕生
2007年、Mackie Control Universal Pro発売。
今でも現行機種として販売されています。
Pro Toolsに対応するコントロールサーフェス(フィジカルコントローラー)用のプロトコルとして、Euphonix社のEUCONもあるようですがこのプロトコルを実装している製品はあまり見かけません。
Mackie Control プロトコルが使用できる製品は各社から販売されています。
マイコンに接続するなど各種工作に使用する上では、MIDIコネクタとして出ているほうがありがたいです。
USB-MIDIになってしまうとUSBホストの実装が必要になります。
PreSonus社のFaderPortシリーズや、Solid State Logic社のUF1、Waves Audio社のFIT ControllerやiCON Pro Audio社の製品ではUSB-MIDIしかないようです。
CM Labs Motormix & DashboardやDigidesign Command 8、M-Audio社のProjectMix I/O、Behringer社のBCF2000は生産終了。
そのため、2023年時点でMIDIコネクタが出ているものとしてはMackie社の「MCU Pro」シリーズかBehringer社の「X-TOUCH」シリーズの2択になってしまうようです。
- MCU Pro Universal Control
- Mackie Control Universal Pro - サウンドハウス
- Behringer X-TOUCH
- X-TOUCH フィジカルコントローラー - サウンドハウス
オープンソースのプロジェクトであれば「MIDIbox LC」や「Control Surface」等が参考になるかもしれません。
(追記)MCU Proを入手したので分解したところMackie Controlの設計流用でLCDのバックライトがELのためどうしても寿命があるようです……
ELシート前提でLCD裏にもスペースが無く、大きさからしても特注なので、バックライトが切れたら修理を頼むしかなさそうです。
個人的にはX-TOUCH一択にはなりそうですが、若干ファームウェアの作り込みが甘い部分が見えてしまっているので、本家MCU Proも捨てがたいですね。
プロトコルの詳細
インターネット上で発見した資料です。
Human User Interface Protocol(HUI)プロトコル
リバースエンジニアリングされた仕様書がネット上に存在しているようです。
theageman氏による解析結果です。
- I FREAKIN FOUND THE HUI DOCS!!!!!
- (ミラー)MACKIE HUI MIDI protocol (PDF)
- (ミラー)MACKIE HUI SMALL DISPLAY CHARACTER SET
- (ミラー)MACKIE HUI MAIN DISPLAY CHARACTER SET
- (ミラー)MACKIE ZONES FOR LEDS/SWITCHES AND FADERS
- (ミラー)MACKIE HUI COMMAND REFERENCE (TRANSMITTING DATA)
- (ミラー)MACKIE HUI COMMAND REFERENCE (RECEIVING DATA)
Logic Control プロトコル
公式のマニュアル(105ページ~)にプロトコル仕様の説明があります。
Logic Proのマニュアル(239ページ~)にも同様の説明があります。
Mackie Controlとは若干の差異があるので参考程度に。
- Logic Control User’s Manual version 2.0 (PDF)
- (ミラー)Logic Control User’s Manual version 2.0 (PDF)
- Logic Pro 7.2.1 Dedicated Control Surface Support (PDF)
- (ミラー)Logic Pro 7.2.1 Dedicated Control Surface Support (PDF)
Mackie Control プロトコル
リバースエンジニアリングされた仕様書がネット上に存在しているようです。
Nicolas Jarnoux氏による解析結果です。
- Mackie Control Protocol (PDF)
- (ミラー)Mackie Control Protocol (PDF)
- Own a Mackie Control? (PDF)
- (ミラー)Own a Mackie Control? (PDF)
- Mackie Control Protocol Software Mappings
- (ミラー)Mackie Control Protocol Software Mappings (PDF)
また、GitHub上の NicoG60 / TouchMCU リポジトリにも情報がまとまっています。
ArduinoからMackie ControlプロトコルでBehringer X-TOUCHを制御
今回はBehringer社のX-TOUCHを用意しました。
MIDIコネクタを装備しています。
Arduinoを使って制御してみます。
X-TOUCH上のMIDIコネクタでMackie Control プロトコルを使用する設定
X-TOUCHのチャンネル1のSELECTボタンを押しながら電源を入れることによってコンフィギュレーションメニューに入れます。
エンコーダーを回して、ModeをMC、IfcをMIDIにします。
これでMIDIコネクタ経由でMackie Controlプロトコル使用する設定になりました。
SELECTボタンを再度押すと設定完了です。
X-TOUCHとArduinoの接続
使用したものは以下。
- Arduino M0(生産終了)→Arduinoは何でも良いと思いますが、ネイティブでUSB(シリアル)が装備されているものだと受信時に便利です。
- MIDI Unit for GROVE
- GROVE - 4ピン - ジャンパオスケーブル(5本セット)
- ジャンパーピン黒(2.54mmピッチ) (25個入)
- ピンヘッダ 1×2 (2P) (10個入)
- デュアルMIDIケーブル(通常のを2本でも)
ピンヘッダのハンダ付けが必要です。
3.3V系のArduinoを使用したため、ピンヘッダでショートさせる必要がありました。(MIDI Unit for GROVEの説明をご覧ください)
MIDI Unit for GROVEにて信号のレベル変換を行い、5Vまたは3.3VのArduinoと接続します。
「SMPTE」「BEATS」「RUDE SOLO LIGHT」LEDを光らせる
Arduino側からMIDIメッセージを送り、LEDを制御する例です。
Arduino上で MIDI Library v5.0.2 を使用しました。
ディスプレイ部の右側に存在する「SMPTE」LEDと「BEATS」LEDを交互に光らせるサンプルコードです。
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
void setup()
{
MIDI.begin(MIDI_CHANNEL_OMNI);
delay(1000);
}
void loop()
{
// SMPTE LED -> ON
MIDI.sendNoteOn(113, 127, 1);
MIDI.sendNoteOff(113, 0, 1);
// BEATS LED -> OFF
MIDI.sendNoteOn(114, 0, 1);
MIDI.sendNoteOff(114, 0, 1);
// Wait 1000ms (=1sec)
delay(1000);
// SMPTE LED -> OFF
MIDI.sendNoteOn(113, 0, 1);
MIDI.sendNoteOff(113, 0, 1);
// BEATS LED -> ON
MIDI.sendNoteOn(114, 127, 1);
MIDI.sendNoteOff(114, 0, 1);
// Wait 1000ms (=1sec)
delay(1000);
// MIDI Read
MIDI.read();
}
MIDI Libraryのサンプルを見るとわかりやすいと思われます。
上記、Mackie ControlプロトコルについてNicolas Jarnoux氏による解析結果を見ると、MIDI API負荷を下げるべく、ノートオンのあとすぐにノートオフを送ることが推奨されるようです。
このことに関しては特に配慮しなくて良いとは思いますが、念の為、そのようなコードにしておきました。
上記コードは簡単な例としてあげたため、受信に関してはケアしていません。
MIDI.readは速いレートで繰り返し実行しないと受信バッファーが詰まる原因になるので、このようなコードは推奨されないと思われます。
0x71(0d113)がSMPTE LED、0x72(0d114)がBEATS LED、0x73(0d115)がRUDE SOLO LIGHT LEDです。
上記プログラムでは10進数(0d~)で指定していますが、16進数(0x~)での指定でも大丈夫です。
その他ボタンのLEDを光らせる
他のボタンやLEDなどを光らせるには以下のIDを使用します。
ID(0x) | LED | X-TOUCH LED COLOR |
---|---|---|
00 | REC/RDY Ch. 1 | RED |
01 | REC/RDY Ch. 2 | RED |
02 | REC/RDY Ch. 3 | RED |
03 | REC/RDY Ch. 4 | RED |
04 | REC/RDY Ch. 5 | RED |
05 | REC/RDY Ch. 6 | RED |
06 | REC/RDY Ch. 7 | RED |
07 | REC/RDY Ch. 8 | RED |
08 | SOLO Ch. 1 | ORANGE |
09 | SOLO Ch. 2 | ORANGE |
0A | SOLO Ch. 3 | ORANGE |
0B | SOLO Ch. 4 | ORANGE |
0C | SOLO Ch. 5 | ORANGE |
0D | SOLO Ch. 6 | ORANGE |
0E | SOLO Ch. 7 | ORANGE |
0F | SOLO Ch. 8 | ORANGE |
10 | MUTE Ch. 1 | RED |
11 | MUTE Ch. 2 | RED |
12 | MUTE Ch. 3 | RED |
13 | MUTE Ch. 4 | RED |
14 | MUTE Ch. 5 | RED |
15 | MUTE Ch. 6 | RED |
16 | MUTE Ch. 7 | RED |
17 | MUTE Ch. 8 | RED |
18 | SELECT Ch. 1 | GREEN |
19 | SELECT Ch. 2 | GREEN |
1A | SELECT Ch. 3 | GREEN |
1B | SELECT Ch. 4 | GREEN |
1C | SELECT Ch. 5 | GREEN |
1D | SELECT Ch. 6 | GREEN |
1E | SELECT Ch. 7 | GREEN |
1F | SELECT Ch. 8 | GREEN |
28 | ASSIGNMENT: TRACK | ORANGE |
29 | ASSIGNMENT: SEND | ORANGE |
2A | ASSIGNMENT: PAN/SURROUND | ORANGE |
2B | ASSIGNMENT: PLUG-IN | ORANGE |
2C | ASSIGNMENT: EQ | ORANGE |
2D | ASSIGNMENT: INSTRUMENT | ORANGE |
2E | FADER BANK Left | ORANGE |
2F | FADER BANK Right | ORANGE |
30 | CHANNEL Left | ORANGE |
31 | CHANNEL Right | ORANGE |
32 | FLIP | ORANGE |
33 | GLOBAL VIEW | ORANGE |
36 | FUNCTION: F1 | ORANGE |
37 | FUNCTION: F2 | ORANGE |
38 | FUNCTION: F3 | ORANGE |
39 | FUNCTION: F4 | ORANGE |
3A | FUNCTION: F5 | ORANGE |
3B | FUNCTION: F6 | ORANGE |
3C | FUNCTION: F7 | ORANGE |
3D | FUNCTION: F8 | ORANGE |
3E | MIDI TRACKS | ORANGE |
3F | INPUTS | ORANGE |
40 | AUDIO TRACKS | ORANGE |
41 | AUDIO INSTRUMENTS | ORANGE |
42 | AUX | ORANGE |
43 | BUSES | ORANGE |
44 | OUTPUTS | ORANGE |
45 | USER | ORANGE |
46 | MODIFY: SHIFT | ORANGE |
47 | MODIFY: OPTION | ORANGE |
48 | MODIFY: CONTROL | ORANGE |
49 | MODIFY: ALT | ORANGE |
4A | AUTOMATION: READ/OFF | GREEN |
4B | AUTOMATION: WRITE | RED |
4C | AUTOMATION: TRIM | ORANGE |
4D | AUTOMATION: TOUCH | ORANGE |
4E | AUTOMATION: LATCH | ORANGE |
4F | AUTOMATION: GROUP | GREEN |
50 | UTILITIES: SAVE | RED |
51 | UTILITIES: UNDO | GREEN |
52 | UTILITIES: CANCEL | ORANGE |
53 | UTILITIES: ENTER | ORANGE |
54 | TRANSPORT: MARKER | GREEN |
55 | TRANSPORT: NUDGE | GREEN |
56 | TRANSPORT: CYCLE | GREEN |
57 | TRANSPORT: DROP | RED |
58 | TRANSPORT: REPLACE | RED |
59 | TRANSPORT: CLICK | GREEN |
5A | TRANSPORT: SOLO | ORANGE |
5B | TRANSPORT: REWIND | ORANGE |
5C | TRANSPORT: FAST FWD | ORANGE |
5D | TRANSPORT: STOP | ORANGE |
5E | TRANSPORT: PLAY | GREEN |
5F | TRANSPORT: RECORD | RED |
60 | Cursor Up | ORANGE |
61 | Cursor Down | ORANGE |
62 | Cursor Left | ORANGE |
63 | Cursor Right | ORANGE |
64 | Cursor Zoom | BLUE |
65 | Scrub | RED |
71 | DISPLAY: SMPTE LED | RED |
72 | DISPLAY: BEATS LED | RED |
73 | DISPLAY: RUDE SOLO LIGHT | ORANGE |
0x34にNAME/VALUE、0x35にSMPTE/BEATSがあるはずですが、光らないボタンのようです。
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
void setup()
{
MIDI.begin(MIDI_CHANNEL_OMNI);
delay(1000);
}
void loop()
{
// SOLO Ch. 1 LED -> ON
MIDI.sendNoteOn(0x8, 0x7F, 1);
MIDI.sendNoteOff(0x8, 0, 1);
// SELECT Ch. 1 LED -> OFF
MIDI.sendNoteOn(0x18, 0, 1);
MIDI.sendNoteOff(0x18, 0, 1);
// Wait 1000ms (=1sec)
delay(1000);
// SOLO Ch. 1 LED -> OFF
MIDI.sendNoteOn(0x8, 0, 1);
MIDI.sendNoteOff(0x8, 0, 1);
// SELECT Ch. 1 LED -> ON
MIDI.sendNoteOn(0x18, 0x7F, 1);
MIDI.sendNoteOff(0x18, 0, 1);
// Wait 1000ms (=1sec)
delay(1000);
// MIDI Read
MIDI.read();
}
SOLO Ch. 1のLEDとSELECT Ch. 1のLEDを交互に光らせるサンプルコードです。
上記の表の通り、16進数で指定しています。
タイムコード7セグディスプレイを制御
7セグメントのディスプレイは左のASSIGNMENT部から右端のTICKSまで合計12桁並んでいます。
これらはコントロールチェンジメッセージにて桁ごとに制御が可能です。
手元のFL Studioの通信内容をキャプチャすると1チャンネルのメッセージとして送られているようですが、解析資料を見ると16チャンネルのメッセージを使用とあります。
どちらでも反応するようですが、要検証です。(たぶん1チャンネルで良いとは思います)
ID(0x) | Digit |
---|---|
4B | ASSIGNMENT: 1/2 Digit |
4A | ASSIGNMENT: 2/2 Digit |
49 | BARS: 1/3 Digit |
48 | BARS: 2/3 Digit |
47 | BARS: 3/3 Digit |
46 | BEATS: 1/2 Digit |
45 | BEATS: 2/2 Digit |
44 | SUB DIVISION: 1/2 Digit |
43 | SUB DIVISION: 2/2 Digit |
42 | TICKS: 1/3 Digit |
41 | TICKS: 2/3 Digit |
40 | TICKS: 3/3 Digit |
各桁に対するデータは以下のように指定します。
ビット | 概要 |
---|---|
7 [MSB] | 未使用、常に0 |
6 | ドット表示 |
5 | 未使用、常に1 |
4 | 桁 ON/OFF |
3 | 表示値 [MSB] |
2 | 表示値 |
1 | 表示値 |
0 [LSB] | 表示値 [LSB] |
表示値は0(0b0000)~9(0b1001)が表示可能です。
例えば、BARSの一番右の桁(0x47)に対して数字の1をドットなしで表示する場合、送るデータは 0b00110001(0x31) となります。
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
void setup()
{
MIDI.begin(MIDI_CHANNEL_OMNI);
delay(3000);
}
void loop()
{
for (uint8_t i=0; i<10; i++) {
MIDI.sendControlChange(0x47, 0x30 + i, 1);
delay(1000);
}
MIDI.read();
}
このサンプルコードはBARSの一番右の桁(0x47)に対して0~9の数字を1秒間隔で繰り返し表示するコードです。
表示値がLSB側の4bitとなっているため、0x30の固定値にfor文で加算される変数iを足すことによって、0x30~0x39で値を変化させています。
エンコーダーノブ・V-Pot LEDを制御
ノブの円周に13個のLEDが配置されています。
Mackie Controlの解析資料によると、11個のLEDと、ノブ下部のLEDも存在します。
X-TOUCHでは13個のLEDがありますが、下部のLED2つがMackie Controlで言うノブ下部のLEDに相当するようです。
コントロールチェンジでチャンネル1に対して送ることで制御が可能です。
コントロールナンバー0x30~0x37がチャンネル1~8に対応しています。
ビット | 概要 |
---|---|
7 [MSB] | 未使用、常に0 |
6 | V-Pot 下部LED ON/OFF |
5 | V-Potモード設定値 [MSB] |
4 | V-Potモード設定値 [LSB] |
3 | V-Pot表示値 [MSB] |
2 | V-Pot表示値 |
1 | V-Pot表示値 |
0 [LSB] | V-Pot表示値 [LSB] |
解析情報からの表です。
「-」が消灯、「*」が点灯でノブ円周のLEDの表示例です。
データを送る際に、5,4ビット目でモードを指定します。
値(0x) | Mode 00 (0x0) | Mode 01 (0x1) | Mode 10 (0x2) | Mode 11 (0x3) |
---|---|---|---|---|
0 | ----------- | ----------- | ----------- | ----------- |
1 | *---------- | ******----- | *---------- | -----*----- |
2 | -*--------- | -*****----- | **--------- | ----***---- |
3 | --*-------- | --****----- | ***-------- | ---*****--- |
4 | ---*------- | ---***----- | ****------- | --*******-- |
5 | ----*------ | ----**----- | *****------ | -*********- |
6 | -----*----- | -----*----- | ******----- | *********** |
7 | ------*---- | -----**---- | *******---- | *********** |
8 | -------*--- | -----***--- | ********--- | *********** |
9 | --------*-- | -----****-- | *********-- | *********** |
A | ---------*- | -----*****- | **********- | *********** |
B | ----------* | -----****** | *********** | *********** |
X-TOUCHでは以下のようになり、モード0b11(0x3)での挙動が若干違うようです。
値(0x) | Mode 00 (0x0) | Mode 01 (0x1) | Mode 10 (0x2) | Mode 11 (0x3) |
---|---|---|---|---|
0 | ----------- | ----------- | ----------- | ----------- |
1 | *---------- | ******----- | *---------- | -----*----- |
2 | -*--------- | -*****----- | **--------- | ----***---- |
3 | --*-------- | --****----- | ***-------- | ---*****--- |
4 | ---*------- | ---***----- | ****------- | --*******-- |
5 | ----*------ | ----**----- | *****------ | -*********- |
6 | -----*----- | -----*----- | ******----- | *********** |
7 | ------*---- | -----**---- | *******---- | ----------- |
8 | -------*--- | -----***--- | ********--- | ----------- |
9 | --------*-- | -----****-- | *********-- | ----------- |
A | ---------*- | -----*****- | **********- | ----------- |
B | ----------* | -----****** | *********** | ----------- |
また、13個のLEDのうち、一番端の2個のLEDがノブ下部のLEDと同じ扱いですので、6ビット目を指定すると、下部LED2個は常に光ります。
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
void setup()
{
MIDI.begin(MIDI_CHANNEL_OMNI);
delay(3000);
}
void loop()
{
for (uint8_t i=0; i<12; i++) {
// V-Pot 1 (0x30), Under LED OFF, Mode 0b00
MIDI.sendControlChange(0x30, i, 1);
// V-Pot 2 (0x31), Under LED OFF, Mode 0b01
MIDI.sendControlChange(0x31, (0b00010000 | i), 1);
// V-Pot 3 (0x32), Under LED OFF, Mode 0b10
MIDI.sendControlChange(0x32, (0b00100000 | i), 1);
// V-Pot 4 (0x33), Under LED OFF, Mode 0b11
MIDI.sendControlChange(0x33, (0b00110000 | i), 1);
// V-Pot 5 (0x34), Under LED ON, Mode 0b00
MIDI.sendControlChange(0x34, (1<<6 | 0<<4 | i), 1);
// V-Pot 6 (0x35), Under LED ON, Mode 0b01
MIDI.sendControlChange(0x35, (1<<6 | 1<<4 | i), 1);
// V-Pot 7 (0x36), Under LED ON, Mode 0b10
MIDI.sendControlChange(0x36, (1<<6 | 2<<4 | i), 1);
// V-Pot 8 (0x37), Under LED ON, Mode 0b11
MIDI.sendControlChange(0x37, (1<<6 | 0b11<<4 | i), 1);
delay(1000);
}
MIDI.read();
}
チャンネル1~8のノブLEDを制御する例です。
4種類のモード、ノブ下部のLEDを点灯させた上での4種類のモードと、8つすべてのノブLEDを光らせるサンプルです。
VUメーターLEDを制御
アフタータッチでチャンネルプレッシャーを送れば光ります。
Mackie Controlの解析資料によると、VUメーターは12個のLEDがあり、以下のようにアサインされているようです。
Value | Signal | Leds |
---|---|---|
C | >= 0dB | Red (clip) |
B | >= -2dB | Yellow |
A | >= -4dB | Yellow |
9 | >= -6dB | Yellow |
8 | >= -8dB | Green |
7 | >= -10dB | Green |
6 | >= -14dB | Green |
5 | >= -20dB | Green |
4 | >= -30dB | Green |
3 | >= -40dB | Green |
2 | >= -50dB | Green |
1 | >= -60dB | Green |
0 | < -60dB | All leds off |
しかしながら、X-TOUCHの場合、LEDは8個です。(上:赤LED4個・下:緑LED4個)
実際に試してみると、0~12の値では全部のLEDが点灯しませんでした。
X-TOUCHの場合は、0~14の値にアサインされているようです。
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
void setup()
{
MIDI.begin(MIDI_CHANNEL_OMNI);
delay(3000);
}
void loop()
{
for (uint8_t i=0; i<15; i++) {
// VU Channel 1
MIDI.sendAfterTouch(i, 1);
// VU Channel 2
MIDI.sendAfterTouch((0b00010000 | i), 1);
// VU Channel 7
MIDI.sendAfterTouch((6<<4 | i), 1);
// VU Channel 8
MIDI.sendAfterTouch((7<<4 | i), 1);
delay(1000);
}
MIDI.read();
}
0~14のアフタータッチ値をチャンネル1に送っています。
データの上位4ビットがVUメーターのチャンネル指定、下位4ビットが値の指定です。
ビット | 概要 |
---|---|
7 [MSB] | 未使用、常に0 |
6 | VUチャンネル値 [MSB] |
5 | VUチャンネル値 |
4 | VUチャンネル値 [LSB] |
3 | VU表示値 [MSB] |
2 | VU表示値 |
1 | VU表示値 |
0 [LSB] | VU表示値 [LSB] |
アフタータッチを送ると、VUメーターが指定値まで一気に上昇して光り、徐々に下がってくるような挙動をします。
値(0x) | VU LED |
---|---|
F | 光らず |
E | 下から8個全点灯 [CLIP] |
D | 下から7個点灯 |
C | 下から7個点灯 |
B | 下から6個点灯 |
A | 下から5個点灯 |
9 | 下から5個点灯 |
8 | 下から4個点灯 |
7 | 下から4個点灯 |
6 | 下から3個点灯 |
5 | 下から3個点灯 |
4 | 下から2個点灯 |
3 | 下から2個点灯 |
2 | 下から1個点灯 |
1 | 下から1個点灯 |
0 | 光らず |
X-TOUCHの場合は、このような挙動となりました。
なお、Logic Controlプロトコル仕様書では、0xEがオーバーロードのセット、0xFがオーバーロードのクリアとされていて、0x0~0xCでレベルメーターが0~100%で可変すると書かれています。
オーバーロードはクリアされないとも書かれているので、0xEを送ったあとにそのまま光り続けているのが本来の動作なのでしょうか?
LCDディスプレイの制御
Mackie Controlでは55文字の2行、合計110文字で構成。(チャンネルあたり6文字で間に1文字空白想定のようです)
X-TOUCHでは56文字の2行、合計112文字で構成され、DAWから送信されるシステムエクスクルーシブメッセージに反応するようです。
MIDIでの可変長メッセージとなり、0xF0で始まって0xF7で終わるメッセージとなります。
SysEXメッセージ内、メーカーIDは 0x00 0x00 0x66(Mackie社)、製品指定が0x14、LCD指定のIDが0x12、続けてカーソル(文字)位置を送ります。(0x00~0x6F)
カーソル(文字)位置は0x00で左上開始、0x37が右上の文字、0x38が左下の文字(2行目開始)、0x6Fが右下の文字位置となります。
指定した位置から送った文字を埋める動作になり、アスキーコードで文字を指定すればその通りに表示されます。
F0 00 00 66 14 12 38 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A F0
このようなメッセージを送れば、2行目の開始位置(0x38)より、アスタリスク(* : 0x2A)で10文字表示されます。
X-TOUCHの場合、小型のディスプレイが各チャンネルごとに8個並んでいる形ですが、Mackie Controlと同様に横長のLCDディスプレイとして扱えば良いです。
単純に7文字2行のLCDディスプレイに別れているというだけで、それが8個チャンネル数分並んでおり、合計56文字2行のLCDディスプレイとして制御可能です。
そのため、各チャンネルごとに表示内容を変えたい場合、7文字単位での文字送信が必要でしょう。
Mackie Controlとの互換性を考えると7文字送信のうち、6文字を使用する形にしておかないと、8ch目が1文字欠けてしまうので注意が必要です。
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
void setup()
{
MIDI.begin(MIDI_CHANNEL_OMNI);
delay(3000);
}
void loop()
{
writeLCD(0, 0, 4, "hoge");
delay(1000);
writeLCD(0, 0, 4, "fuga");
delay(1000);
writeLCD(0, 0, 4, "piyo");
delay(1000);
MIDI.read();
}
void writeLCD(uint8_t setChannel, uint8_t setLine, uint8_t strLength, const char* strArray) {
if (setChannel > 7) {setChannel = 7;}
if (setLine > 1) {setLine = 1;}
if (strLength > 7) {strLength = 7;}
if (strLength > strlen(strArray)) {strLength = strlen(strArray);}
uint8_t cmd[14] = {0x00, 0x00, 0x66, 0x14, 0x12, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00};
cmd[5] = (setChannel * 7) + (setLine * 56);
for (uint8_t i = 0; i < strLength; i++) {
cmd[6 + i] = strArray[i];
}
MIDI.sendSysEx(13, cmd, false);
}
簡単に書いたサンプルコードです。
writeLCD関数の引数は、1個目が表示するチャンネル(0~7)指定、2個目が行指定(0~1)、表示する文字数、文字配列となっています。
LCDディスプレイのバックライト色制御
これはX-TOUCHに限定された制御についてです。
Mackie Controlでは横長の一体型LCDディスプレイを使用しているので不可能ですが、X-TOUCHの場合はチャンネル単位で小型のLCDを使用しているためバックライトの色が変更可能なようです。
以下のシステムエクスクルーシブメッセージを送れば即時バックライト色が変更されます。
F0 00 00 66 14 72 [Ch1] [Ch2] [Ch3] [Ch4] [Ch5] [Ch6] [Ch7] [Ch8] F7
8チャンネル分、一気に色指定をします。
Color(0x) | LCD COLOR |
---|---|
00 | BLANK (Backlit Off) |
01 | RED |
02 | GREEN |
03 | YELLOW |
04 | BLUE |
05 | PURPLE |
06 | CYAN |
07 | WHITE (Default) |
初期状態(白色)に戻すには以下のシステムエクスクルーシブメッセージを送ります。
F0 00 00 66 14 72 07 07 07 07 07 07 07 07 F7
MIDI.sendSysEx(13, (const uint8_t[]){0x00, 0x00, 0x66, 0x14, 0x72, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}, false);
このようなコードで初期状態に戻ります。
フェーダー位置の制御
Mackie Controlで特徴的なのは電動で動くモーターフェーダーです。
Mackie ControlからDAWへの通知では、ピッチベンドメッセージとノートONメッセージを使用します。
DAWからMackie Controlでのフェーダー制御では、ピッチベンドメッセージを使用します。
フェーダー位置に関してはピッチベンド値で表現され、14bitの値で制御します。
DAWのMIDI API実装によって異なりますが、 -8192~8191 または 0~16383 の値としてフェーダー位置を制御できるということです。
Mackie Controlからの通知では、以下のような順序で通知されます。
- 指がフィーダーに触れる(ノートONで移動し始め通知)
- フィーダーが動く(ピッチベンドで値が送信)
- フィーダーが動く(ピッチベンドで値が送信)
- ・・・・・
- フィーダーが動く(ピッチベンドで値が送信)
- 指がフィーダーから離れる(ノートOFFで移動し終わり通知)
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
void setup()
{
MIDI.begin(MIDI_CHANNEL_OMNI);
delay(3000);
}
void loop()
{
MIDI.sendPitchBend(-8192, 1);
delay(2000);
MIDI.sendPitchBend(0, 1);
delay(2000);
MIDI.sendPitchBend(8191, 1);
delay(2000);
MIDI.read();
}
フェーダーを動かすサンプルです。
ArduinoのMIDIライブラリでは、中央が0での値指定ができるようです。
つまり、-8192~8191の14bitで値を指定することになります。
Mackie Controlの場合、フェーダーにタッチした時点でSIGNAL LEDが点灯してしまうようです。
消したままにする場合は、0x68~0x70に対して消灯の命令を送る必要がありそうです。
値の読み込み
Arduino側での値の読み込みは、ノートオン、ノートオフ、コントロールチェンジ、ピッチベンドの各イベントを拾えばOKです。
以下に例を示します。
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
// Mackie Control ID List
// === START ===
char *mcIDs[] = {
"REC/RDY Ch. 1", // 0x00
"REC/RDY Ch. 2", // 0x01
"REC/RDY Ch. 3", // 0x02
"REC/RDY Ch. 4", // 0x03
"REC/RDY Ch. 5", // 0x04
"REC/RDY Ch. 6", // 0x05
"REC/RDY Ch. 7", // 0x06
"REC/RDY Ch. 8", // 0x07
"SOLO Ch. 1", // 0x08
"SOLO Ch. 2", // 0x09
"SOLO Ch. 3", // 0x0A
"SOLO Ch. 4", // 0x0B
"SOLO Ch. 5", // 0x0C
"SOLO Ch. 6", // 0x0D
"SOLO Ch. 7", // 0x0E
"SOLO Ch. 8", // 0x0F
"MUTE Ch. 1", // 0x10
"MUTE Ch. 2", // 0x11
"MUTE Ch. 3", // 0x12
"MUTE Ch. 4", // 0x13
"MUTE Ch. 5", // 0x14
"MUTE Ch. 6", // 0x15
"MUTE Ch. 7", // 0x16
"MUTE Ch. 8", // 0x17
"SELECT Ch. 1", // 0x18
"SELECT Ch. 2", // 0x19
"SELECT Ch. 3", // 0x1A
"SELECT Ch. 4", // 0x1B
"SELECT Ch. 5", // 0x1C
"SELECT Ch. 6", // 0x1D
"SELECT Ch. 7", // 0x1E
"SELECT Ch. 8", // 0x1F
"V-Pot Knob Ch. 1", // 0x20
"V-Pot Knob Ch. 2", // 0x21
"V-Pot Knob Ch. 3", // 0x22
"V-Pot Knob Ch. 4", // 0x23
"V-Pot Knob Ch. 5", // 0x24
"V-Pot Knob Ch. 6", // 0x25
"V-Pot Knob Ch. 7", // 0x26
"V-Pot Knob Ch. 8", // 0x27
"ASSIGNMENT: TRACK", // 0x28
"ASSIGNMENT: SEND", // 0x29
"ASSIGNMENT: PAN/SURROUND", // 0x2A
"ASSIGNMENT: PLUG-IN", // 0x2B
"ASSIGNMENT: EQ", // 0x2C
"ASSIGNMENT: INSTRUMENT", // 0x2D
"FADER BANK Left", // 0x2E
"FADER BANK Right", // 0x2F
"CHANNEL Left", // 0x30
"CHANNEL Right", // 0x31
"FLIP", // 0x32
"GLOBAL VIEW", // 0x33
"DISPLAY: NAME/VALUE", // 0x34
"DISPLAY: SMPTE BEATS", // 0x35
"FUNCTION: F1", // 0x36
"FUNCTION: F2", // 0x37
"FUNCTION: F3", // 0x38
"FUNCTION: F4", // 0x39
"FUNCTION: F5", // 0x3A
"FUNCTION: F6", // 0x3B
"FUNCTION: F7", // 0x3C
"FUNCTION: F8", // 0x3D
"MIDI TRACKS", // 0x3E
"INPUTS", // 0x3F
"AUDIO TRACKS", // 0x40
"AUDIO INSTRUMENTS", // 0x41
"AUX", // 0x42
"BUSES", // 0x43
"OUTPUTS", // 0x44
"USER", // 0x45
"MODIFY: SHIFT", // 0x46
"MODIFY: OPTION", // 0x47
"MODIFY: CONTROL", // 0x48
"MODIFY: ALT", // 0x49
"AUTOMATION: READ/OFF", // 0x4A
"AUTOMATION: WRITE", // 0x4B
"AUTOMATION: TRIM", // 0x4C
"AUTOMATION: TOUCH", // 0x4D
"AUTOMATION: LATCH", // 0x4E
"AUTOMATION: GROUP", // 0x4F
"UTILITIES: SAVE", // 0x50
"UTILITIES: UNDO", // 0x51
"UTILITIES: CANCEL", // 0x52
"UTILITIES: ENTER", // 0x53
"TRANSPORT: MARKER", // 0x54
"TRANSPORT: NUDGE", // 0x55
"TRANSPORT: CYCLE", // 0x56
"TRANSPORT: DROP", // 0x57
"TRANSPORT: REPLACE", // 0x58
"TRANSPORT: CLICK", // 0x59
"TRANSPORT: SOLO", // 0x5A
"TRANSPORT: REWIND", // 0x5B
"TRANSPORT: FAST FWD", // 0x5C
"TRANSPORT: STOP", // 0x5D
"TRANSPORT: PLAY", // 0x5E
"TRANSPORT: RECORD", // 0x5F
"Cursor Up", // 0x60
"Cursor Down", // 0x61
"Cursor Left", // 0x62
"Cursor Right", // 0x63
"Cursor Zoom", // 0x64
"Scrub", // 0x65
"USER SWITCH: 1", // 0x66
"USER SWITCH: 2", // 0x67
"Fader Ch. 1", // 0x68
"Fader Ch. 2", // 0x69
"Fader Ch. 3", // 0x6A
"Fader Ch. 4", // 0x6B
"Fader Ch. 5", // 0x6C
"Fader Ch. 6", // 0x6D
"Fader Ch. 7", // 0x6E
"Fader Ch. 8", // 0x6F
"Fader Ch. MAIN", // 0x70
"DISPLAY: SMPTE LED", // 0x71
"DISPLAY: BEATS LED", // 0x72
"DISPLAY: RUDE SOLO LIGHT", // 0x73
"=====", // 0x74
"=====", // 0x75
"=====", // 0x76
"=====", // 0x77
"=====", // 0x78
"=====", // 0x79
"=====", // 0x7A
"=====", // 0x7B
"=====", // 0x7C
"=====", // 0x7D
"=====", // 0x7E
"=====", // 0x7F
};
// === END ===
// Mackie Control ID List
// Mackie Control LED List
// === START ===
bool mcLEDs[] = {
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, //0x0*
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, //0x1*
false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, //0x2*
true, true, true, true, false, false, true, true, true, true, true, true, true, true, true, true, //0x3*
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, //0x4*
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, //0x5*
true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, //0x6*
false, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, //0x7*
};
// === END ===
// Mackie Control LED List
// Mackie Control Button LED State
bool mcState[128];
void setup()
{
MIDI.begin(MIDI_CHANNEL_OMNI);
SerialUSB.begin(9600);
delay(3000);
SerialUSB.println("Start");
}
void loop()
{
if (MIDI.read())
{
switch(MIDI.getType())
{
case midi::NoteOn:
handleNoteOn(MIDI.getChannel(), MIDI.getData1(), MIDI.getData2());
break;
case midi::NoteOff:
handleNoteOff(MIDI.getChannel(), MIDI.getData1(), MIDI.getData2());
break;
case midi::ControlChange:
handleControlChange(MIDI.getChannel(), MIDI.getData1(), MIDI.getData2());
break;
case midi::PitchBend: // -8192 - 8191 (X-TOUCH: 0d8188 [0b11111111111100] Max?)
handlePitchBend(MIDI.getChannel(), ((uint16_t)MIDI.getData2()<<7 | (MIDI.getData1() & 0b01111111)) - 8192);
break;
default:
break;
}
}
}
void handleNoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
{
if (channel == 1 && velocity == 127)
{
SerialUSB.print("Push: ");
SerialUSB.print(mcIDs[note]);
// Fader is Non-State
if (note < 0x68 || 0x70 < note)
{
SerialUSB.print(" @ State: ");
if (mcState[note])
{
mcState[note] = false;
SerialUSB.println("Off");
if (mcLEDs[note])
{
sendLedOff(note);
}
} else {
mcState[note] = true;
SerialUSB.println("On");
}
} else {
SerialUSB.println();
}
}
}
void handleNoteOff(uint8_t channel, uint8_t note, uint8_t velocity)
{
if (channel == 1 && velocity == 0)
{
SerialUSB.print("Release: ");
SerialUSB.print(mcIDs[note]);
SerialUSB.println();
}
}
void handleControlChange(uint8_t channel, uint8_t number, uint8_t value)
{
if (channel == 1)
{
if (number == 0x2E)
{
SerialUSB.print("Foot");
}
if (number == 0x3C)
{
SerialUSB.print("Jog");
}
else if (0x10 <= number && number <= 0x17)
{
SerialUSB.print("V-Pot Knob Ch. ");
SerialUSB.print(number - 0x0F);
}
if ((value>>6 & 0b1) == 1) {
SerialUSB.print(" Left @ Speed: ");
SerialUSB.println(value & 0b00111111);
} else {
SerialUSB.print(" Right @ Speed: ");
SerialUSB.println(value & 0b00111111);
}
}
}
void handlePitchBend(uint8_t channel, int16_t bend)
{
SerialUSB.print("Fader Ch. ");
SerialUSB.print(channel);
SerialUSB.print(" : ");
SerialUSB.print(bend);
SerialUSB.println();
}
void sendLedOff(uint8_t id)
{
MIDI.sendNoteOn(id, 0, 1);
MIDI.sendNoteOff(id, 0, 1);
}
(※Arduino M0以外だと、コード中のSerialUSBをSerialに書き換える必要があります。)
受信した内容をUSB経由でArduino IDEのシリアルモニタに表示するサンプルコードです。
これは、ArduinoのD0/D1ピンがUSBに割り当てられていないArduino M0を使用しているため、MIDIのシリアル通信を送受信しながらコンピューターにもUSB経由で送ることができるのです。
Arduino Uno R3等であると共用となっているので、別途ソフトウェアシリアルでの通信の必要性が出てくると思います。
Arduino UNO R4 Minima, Micro, Zero, Leonardo, MKR ZERO, Due, Nano Everyであるとシリアル通信でのUSBとハードウェアピンが別になっているため便利です。
ボタンやV-Potのノブを押した際、また、フェーダーに触れた際にノートオンが送られてきます。
その後、ボタンを離したタイミングでノートオフが送られてきます。
X-TOUCHは各種ボタンを押した際に勝手にボタンのLEDが点灯します。
よって、ボタンを使用する上では逆に消灯させる必要が出てきます。
上記サンプルコードでは、配列でボタンのステートを保持し、押すたびにLEDの点灯・消灯が切り替わります。
消灯する場合は、ノートオフコマンドを送っています。(sendLedOff関数)
最初から点灯させたくない場合はノートオンを受信した際に、瞬時にノートオフで消灯コマンドを送ることで実質点灯しない状態となります。
ちなみに、ジョグダイヤルとV-Potのノブはコントロールチェンジで回転方向のイベントが発生します。
6bit値で回転スピードも取れるようですが、ジョグダイヤルはスピードが1固定のようです。
V-Potのノブはゆっくり回すと1~2、速く回すと7前後の数値でスピードが通知されるようです。
頑張って速く回してみても10が限界でした。
6bitであれば最大63で値が取れそうですが、10程度まででとどまるようです。
X-TOUCHのフェーダーは、ピッチベンドで通知されるのですが、下位2bitは0固定のようです。
実際に試すと最大値が0d8188(0b11111111111100)として通知されてきます。
12bitの値として通知されますが、実際に12bitの解像度があるのかは不明です。
一応、通知される値から統計を取ると約900種の値が通知されているようなので、現実的には10bit程度の値として扱えそうです。
なお、変化量の統計では、ログ取り時に16が72%、20が15%、32が5%、36が4%他、48、52、64、24と値が続きます。
フェーダーの動かし方によって変わると思いますので参考までに。
実際の値としては、0→16→32→48→64→80→・・・・・→16356→16380のような感じになります。
下位2bit以外の変化があるため、ビットシフトではなく、出てきた値÷16として10bitとしての値を取り出すのが良いかとは思います。
実際、この方法で値の統計を取ると、1もしくは2の値の変化で、900種以上の値が取れているので、実質10bitで扱えると思います。
その他コマンド(ファームウェアバージョンリクエスト)
ファームウェアのバージョン情報を要求することができます。
システムエクスクルーシブメッセージでのやり取りが必要です。
※Logic Controlプロトコル仕様書参照
(ヘッダのみ解析情報を使用して書き換えてあります。X-TOUCHでのみ動作確認済み。)
F0 00 00 66 14 13 00 F7
を送ることによって、対する応答もシステムエクスクルーシブメッセージで帰ってきます。
X-TOUCHでは以下の12バイトでの返答になるようです。
F0 00 00 66 14 14 56 31 2E 32 32 F7
データ部分のペイロード、5バイトのデータ(0x56~0x32まで)です。
つまり「V1.22」という文字列のアスキーコード5桁の返答になり、このバージョン情報は、X-TOUCH起動時にも本体のHOURS/BARSディスプレイ部に表示されます。
以下、Arduinoで動かすためのサンプルコードです。
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
void setup()
{
MIDI.begin(MIDI_CHANNEL_OMNI);
SerialUSB.begin(9600);
delay(3000);
SerialUSB.println("Start");
}
void loop()
{
if (SerialUSB.available() > 0)
{
while(SerialUSB.read() > 0);
SerialUSB.println("Read!");
uint8_t cmd[6] = {0x00, 0x00, 0x66, 0x14, 0x13, 0x00};
MIDI.sendSysEx(6, cmd, false);
}
if (MIDI.read())
{
uint8_t length;
uint8_t data[128];
length = MIDI.getSysExArrayLength();
memcpy(data, MIDI.getSysExArray(), length);
SerialUSB.print("DataLength: ");
SerialUSB.println(length);
SerialUSB.print("Data: ");
for (uint8_t i=0; i<length; i++)
{
if (data[i] < 0x10) SerialUSB.print("0");
SerialUSB.print(data[i], HEX);
SerialUSB.print(" ");
}
SerialUSB.println();
}
}
(※Arduino M0以外だと、コード中のSerialUSBをSerialに書き換える必要があります。)
ファームウェアバージョンをUSB経由でArduino IDEのシリアルモニタに表示するサンプルコードです。
シリアルモニタ上でなにか適当な文字列(改行だけでも可)を送ると以下のような応答があります。
Read!
DataLength: 12
Data: F0 00 00 66 14 14 56 31 2E 32 32 F7
その他コマンド(リセットメッセージ)
※Logic Controlプロトコル仕様書参照
リセット関係のコマンドですがMackie Controlプロトコル中には定義がないのか動作しませんでした。
(追記:X-TOUCHに実装されていないだけで、Mackie Controlでは動作するようです)
フェーダーを最小にするコマンド
F0 00 00 66 14 61 F7
LEDをすべてオフにするコマンド
F0 00 00 66 14 62 F7
リセットコマンド
F0 00 00 66 14 63 F7
すべて、X-TOUCHでは動作しませんでした。
よってArduinoサンプルも無しです。
その他コマンド(初期化メッセージ)
※Logic Controlプロトコル仕様書参照
F0 00 00 66 14 00 F7
一連の流れで、MackieControl側の応答から300ms以内にレスポンスを返さないといけません。
Logic Controlプロトコル仕様書を参考に実装すると以下のようなコード例になります。
if (length == 18 && data[5] == 0x01) {
uint8_t challenge[4] = {data[13], data[14], data[15], data[16]};
uint8_t response[4];
response[0] = 0x7F & (challenge[0] + (challenge[1] ^ 0xA) - challenge[3]);
response[1] = 0x7F & ((challenge[2] >> 4) ^ (challenge[0] + challenge[3]));
response[2] = 0x7F & (challenge[3] - (challenge[2] << 2) ^ (challenge[0] | challenge[1]));
response[3] = 0x7F & (challenge[1] - challenge[2] + (0xF0 ^ (challenge[3] << 4)));
uint8_t cmd[16] = {0x00, 0x00, 0x66, 0x14, 0x02, data[6], data[7], data[8], data[9], data[10], data[11], data[12], response[0], response[1], response[2], response[3]};
MIDI.sendSysEx(16, cmd, false);
}
しかし、X-TOUCHではレスポンスを返してもその後の応答がありませんでした。
(後にMackie Controlで試した結果、きちんと動作していることがわかりました。以下のような応答がありますが、X-TOUCHには実装されていないようです。)
18:43:48.642 -> DataLength: 18
18:43:48.642 -> Data: F0 00 00 66 14 01 58 59 5A 4D 03 43 5A 4D 03 43 5A F7
18:43:48.642 -> Send Response
18:43:48.642 -> DataLength: 14
18:43:48.642 -> Data: F0 00 00 66 14 03 58 59 5A 4D 03 43 5A F7
19:00:43.766 -> DataLength: 18
19:00:43.766 -> Data: F0 00 00 66 14 01 58 59 5A 11 3B 43 59 11 3B 43 59 F7
19:00:43.802 -> Send Response
19:00:43.802 -> DataLength: 14
19:00:43.802 -> Data: F0 00 00 66 14 03 58 59 5A 11 3B 43 59 F7
19:05:59.456 -> DataLength: 18
19:05:59.456 -> Data: F0 00 00 66 14 01 58 59 5A 69 2F 42 79 69 2F 42 79 F7
19:05:59.510 -> Send Response
19:05:59.510 -> DataLength: 14
19:05:59.510 -> Data: F0 00 00 66 14 03 58 59 5A 69 2F 42 79 F7
※MCU Proでは動作しないようです?エラー表示でイニシャライズがうまくいかず本体がシャットダウンします。
その他コマンド(コンフィギュレーションメッセージ)
※Logic Controlプロトコル仕様書参照
トランスポートボタンクリック(0x0A)
7バイト目で挙動が変わるようです。
F0 00 00 66 14 0A 00 F7 // no trasnport button click
F0 00 00 66 14 0A 01 F7 // transport button click (default)
FL Studioではデフォルト値が送信されるようですが、特に挙動が変わらないように見えます。
LCDバックライトセーバー(0x0B)
7バイト目で挙動が変わるようです。
F0 00 00 66 14 0B 00 F7 // LCD back light off
F0 00 00 66 14 0B 0F F7 // LCD back light on, with time out in minutes (default: 0F = 15minutes)
送信してもX-TOUCHではLCDバックライトをオフにできませんでした。
FL Studioではデフォルト値が送信されるようです。
タッチレスムーバブルフェーダー(0x0C)
F0 00 00 66 14 0C 00 F7 // fader movements are only transmitted if the fader has been recognized as touched
F0 00 00 66 14 0C 01 F7 // fader movements are also transmitted if the fader has not been recognized as touched (e. g. with fingernail or pen)
フェーダーはモーターフェーダーの都合があり、タッチセンサーが入っています。
そのため、タッチを検出しなかった場合(指以外で動かした場合)に、動きを通知するかという設定です。
FL Studioでは設定値として01が送信されているようで、指以外で動かした場合も通知されるようになっています。
フェーダー感度(0x0E)
F0 00 00 66 14 0E 00 03 F7 // 0 Chan Fader touch sensitivity (00 to 05; default:03)
F0 00 00 66 14 0E 07 03 F7 // 7 Chan Fader touch sensitivity (00 to 05; default:03)
F0 00 00 66 14 0E 08 03 F7 // Master Fader touch sensitivity (00 to 05; default:03)
このコマンドの使用はFL Studio上では確認できませんでした。
その他コマンド(メーター)
※Logic Controlプロトコル仕様書参照
チャンネルメーターモード
F0 00 00 66 14 20 ii mm F7
ii = Channel ID (0 to 7)
mm = mode bit map in the form of (0 0 0 0 0 l p s):
l Enable level meter on LCD
p Enable peak hold display (horizontal only)
s Enable Signal LED
FL Studioでは接続時に各チャンネルに対してモードを0x0として送信し、グローバルLCDメーターモード設定直後に、各チャンネルに対してモードを0x3として設定を送っているようです。
0x3では、0b00000011となるため、ピークホールドディスプレイとシグナルLEDを有効にしている設定のようです。
切断時には各チャンネルを0x0で設定しているようです。
グローバルLCDメーターモード
F0 00 00 66 14 21 00 F7 // Global LCD meter mode: horizontal
F0 00 00 66 14 21 01 F7 // Global LCD meter mode: vertical
FL Studioでは、0x00が設定されるようです。
レベルメーターはチャンネルごとに1つだけあります。
ステレオトラックの場合は左右のレベルの最大値を使用します。
ピークレベルのみ送信を行えば良く、時間の経過と共にレベルメーターのバーを自動的に減らし、LEDをオフにします。
そのためMIDIの帯域幅を圧迫しません。
レベルメーターの減衰率は1目盛りあたり300msで、100%から0%に低下するのに1.8秒かかります。
LCDを水平、垂直でモード切替を行う場合、切り替わる間はLCDメッセージは無視されます。
モード変更後はLCDメッセージを送るまでに最低でも600ms待機する必要があります。
FL Studioで実際にやり取りされる内容(接続時)
接続時の通信内容をMIDI-OXでモニターした結果が以下の通りです。
すべて、DAWからMackie Control(X-TOUCH)側への通信です。
コマンド | データ | 概要 |
---|---|---|
SystemExclusive | F0 00 00 66 14 0C 01 F7 | タッチレスムーバブルフェーダー設定 |
SystemExclusive | F0 00 00 66 14 0B 02 F7 | LCDバックライトセーバー設定 |
SystemExclusive | F0 00 00 66 14 0A 01 F7 | トランスポートボタンクリック設定 |
ChannelPressure | D0 0F | VUメーター1:最大値0xF(X-TOUCHでは光らず) |
ChannelPressure | D0 1F | VUメーター2:最大値0xF(X-TOUCHでは光らず) |
ChannelPressure | D0 2F | VUメーター3:最大値0xF(X-TOUCHでは光らず) |
ChannelPressure | D0 3F | VUメーター4:最大値0xF(X-TOUCHでは光らず) |
ChannelPressure | D0 4F | VUメーター5:最大値0xF(X-TOUCHでは光らず) |
ChannelPressure | D0 5F | VUメーター6:最大値0xF(X-TOUCHでは光らず) |
ChannelPressure | D0 6F | VUメーター7:最大値0xF(X-TOUCHでは光らず) |
ChannelPressure | D0 7F | VUメーター8:最大値0xF(X-TOUCHでは光らず) |
SystemExclusive | F0 00 00 66 14 20 00 00 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 01 00 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 02 00 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 03 00 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 04 00 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 05 00 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 06 00 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 07 00 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 12 38 20 20 20 20 20 20 2E 20 20 20 20 20 20 2E 20 20 20 20 20 20 2E 20 20 20 20 20 20 2E 20 20 20 20 20 20 2E 20 20 20 20 20 20 2E 20 20 20 20 20 20 2E 20 20 20 20 20 20 F7 |
LCD2行目書き換え " ." の繰り返し表示 |
SystemExclusive | F0 00 00 66 14 21 00 F7 | グローバルLCDメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 00 03 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 01 03 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 02 03 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 03 03 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 04 03 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 05 03 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 06 03 F7 | チャンネルメーターモード設定 |
SystemExclusive | F0 00 00 66 14 20 07 03 F7 | チャンネルメーターモード設定 |
ControlChange | B0 30 16 | V-Pot LED設定 Ch 1, モード01 / 値6(中央) |
NoteOff | 90 00 00 | ボタン REC/RDY Ch. 1 消灯 |
NoteOff | 90 08 00 | ボタン SOLO Ch. 1 消灯 |
NoteOff | 90 10 00 | ボタン MUTE Ch. 1 消灯 |
PitchBend | E0 10 66 | フェーダー Ch. 1 設定 4880 (0dB) |
ControlChange | B0 31 16 | V-Pot LED設定 Ch 2, モード01 / 値6(中央) |
NoteOff | 90 01 00 | ボタン REC/RDY Ch. 2 消灯 |
NoteOff | 90 09 00 | ボタン SOLO Ch. 2 消灯 |
NoteOff | 90 11 00 | ボタン MUTE Ch. 2 消灯 |
PitchBend | E1 10 66 | フェーダー Ch. 2 設定 4880 (0dB) |
ControlChange | B0 32 16 | V-Pot LED設定 Ch 3, モード01 / 値6(中央) |
NoteOff | 90 02 00 | ボタン REC/RDY Ch. 3 消灯 |
NoteOff | 90 0A 00 | ボタン SOLO Ch. 3 消灯 |
NoteOff | 90 12 00 | ボタン MUTE Ch. 3 消灯 |
PitchBend | E2 10 66 | フェーダー Ch. 3 設定 4880 (0dB) |
ControlChange | B0 33 16 | V-Pot LED設定 Ch 4, モード01 / 値6(中央) |
NoteOff | 90 03 00 | ボタン REC/RDY Ch. 4 消灯 |
NoteOff | 90 0B 00 | ボタン SOLO Ch. 4 消灯 |
NoteOff | 90 13 00 | ボタン MUTE Ch. 4 消灯 |
PitchBend | E3 10 66 | フェーダー Ch. 4 設定 4880 (0dB) |
ControlChange | B0 34 16 | V-Pot LED設定 Ch 5, モード01 / 値6(中央) |
NoteOff | 90 04 00 | ボタン REC/RDY Ch. 5 消灯 |
NoteOff | 90 0C 00 | ボタン SOLO Ch. 5 消灯 |
NoteOff | 90 14 00 | ボタン MUTE Ch. 5 消灯 |
PitchBend | E4 10 66 | フェーダー Ch. 5 設定 4880 (0dB) |
ControlChange | B0 35 16 | V-Pot LED設定 Ch 6, モード01 / 値6(中央) |
NoteOff | 90 05 00 | ボタン REC/RDY Ch. 6 消灯 |
NoteOff | 90 0D 00 | ボタン SOLO Ch. 6 消灯 |
NoteOff | 90 15 00 | ボタン MUTE Ch. 6 消灯 |
PitchBend | E5 10 66 | フェーダー Ch. 6 設定 4880 (0dB) |
ControlChange | B0 36 16 | V-Pot LED設定 Ch 7, モード01 / 値6(中央) |
NoteOff | 90 06 00 | ボタン REC/RDY Ch. 7 消灯 |
NoteOff | 90 0E 00 | ボタン SOLO Ch. 7 消灯 |
NoteOff | 90 16 00 | ボタン MUTE Ch. 7 消灯 |
PitchBend | E6 10 66 | フェーダー Ch. 7 設定 4880 (0dB) |
ControlChange | B0 37 16 | V-Pot LED設定 Ch 8, モード01 / 値6(中央) |
NoteOff | 90 07 00 | ボタン REC/RDY Ch. 8 消灯 |
NoteOff | 90 0F 00 | ボタン SOLO Ch. 8 消灯 |
NoteOff | 90 17 00 | ボタン MUTE Ch. 8 消灯 |
PitchBend | E7 10 66 | フェーダー Ch. 8 設定 4880 (0dB) |
PitchBend | E8 10 66 | フェーダー Ch. MAIN 設定 4880 (0dB) |
ControlChange | B0 4B 20 | 7セグ書き換え ASSIGNMENT: 1/2 Digit 表示なし |
ControlChange | B0 4A 31 | 7セグ書き換え ASSIGNMENT: 2/2 Digit 値 1 表示 ドット無し |
NoteOn | 90 5D 7F | ボタン TRANSPORT: STOP 点灯 |
NoteOn | 90 5A 7F | ボタン TRANSPORT: SOLO 点灯 |
NoteOff | 90 5F 00 | ボタン TRANSPORT: RECORD 消灯 |
NoteOff | 90 71 00 | ボタン DISPLAY: SMPTE LED 消灯 |
NoteOn | 90 72 7F | ボタン DISPLAY: BEATS LED 点灯 |
NoteOn | 90 28 7F | ボタン ASSIGNMENT: TRACK 点灯 |
NoteOff | 90 29 00 | ボタン ASSIGNMENT: SEND 消灯 |
NoteOff | 90 2A 00 | ボタン ASSIGNMENT: PAN/SURROUND 消灯 |
NoteOff | 90 2B 00 | ボタン ASSIGNMENT: PLUG-IN 消灯 |
NoteOff | 90 2C 00 | ボタン ASSIGNMENT: EQ 消灯 |
NoteOff | 90 2D 00 | ボタン ASSIGNMENT: INSTRUMENT 消灯 |
NoteOn | 90 50 7F | ボタン UTILITIES: SAVE 点灯 |
NoteOff | 90 57 00 | ボタン TRANSPORT: DROP 消灯 |
NoteOff | 90 58 00 | ボタン TRANSPORT: REPLACE 消灯 |
NoteOff | 90 65 00 | ボタン Scrub 消灯 |
NoteOff | 90 73 00 | ボタン DISPLAY: RUDE SOLO LIGHT 消灯 |
NoteOn | 90 33 7F | ボタン GLOBAL VIEW 点灯 |
NoteOff | 90 32 00 | ボタン FLIP 消灯 |
NoteOn | 90 56 7F | ボタン TRANSPORT: CYCLE 点灯 |
NoteOff | 90 4A 00 | ボタン AUTOMATION: READ/OFF 消灯 |
NoteOff | 90 4B 00 | ボタン AUTOMATION: WRITE 消灯 |
NoteOff | 90 18 00 | ボタン SELECT Ch. 1 消灯 |
NoteOff | 90 19 00 | ボタン SELECT Ch. 2 消灯 |
NoteOff | 90 1A 00 | ボタン SELECT Ch. 3 消灯 |
NoteOff | 90 1B 00 | ボタン SELECT Ch. 4 消灯 |
NoteOff | 90 1C 00 | ボタン SELECT Ch. 5 消灯 |
NoteOff | 90 1D 00 | ボタン SELECT Ch. 6 消灯 |
NoteOff | 90 1E 00 | ボタン SELECT Ch. 7 消灯 |
NoteOff | 90 1F 00 | ボタン SELECT Ch. 8 消灯 |
NoteOff | 90 50 00 | ボタン UTILITIES: SAVE 消灯 |
NoteOn | 90 4B 7F | ボタン AUTOMATION: WRITE 点灯 |
ChannelPressure | D0 00 | VUメーター1:最小値0x0 |
ChannelPressure | D0 10 | VUメーター2:最小値0x0 |
ChannelPressure | D0 20 | VUメーター3:最小値0x0 |
ChannelPressure | D0 30 | VUメーター4:最小値0x0 |
ChannelPressure | D0 40 | VUメーター5:最小値0x0 |
ChannelPressure | D0 50 | VUメーター6:最小値0x0 |
ChannelPressure | D0 60 | VUメーター7:最小値0x0 |
ChannelPressure | D0 70 | VUメーター8:最小値0x0 |
ControlChange | B0 49 20 | 7セグ書き換え BARS: 1/3 Digit 表示なし |
ControlChange | B0 48 20 | 7セグ書き換え BARS: 2/3 Digit 表示なし |
ControlChange | B0 47 31 | 7セグ書き換え BARS: 3/3 Digit 値 1 表示 ドット無し |
ControlChange | B0 46 30 | 7セグ書き換え BEATS: 1/2 Digit 値 0 表示 ドット無し |
ControlChange | B0 45 31 | 7セグ書き換え BEATS: 2/2 Digit 値 1 表示 ドット無し |
ControlChange | B0 44 20 | 7セグ書き換え SUB DIVISION: 1/2 Digit 表示なし |
ControlChange | B0 43 20 | 7セグ書き換え SUB DIVISION: 2/2 Digit 表示なし |
ControlChange | B0 42 30 | 7セグ書き換え TICKS: 1/3 Digit 値 0 表示 ドット無し |
ControlChange | B0 41 30 | 7セグ書き換え TICKS: 2/3 Digit 値 0 表示 ドット無し |
ControlChange | B0 40 30 | 7セグ書き換え TICKS: 3/3 Digit 値 0 表示 ドット無し |
SystemExclusive | F0 00 00 66 14 12 00 4C 69 6E 6B 65 64 20 74 6F 20 46 4C 20 53 74 75 64 69 6F 20 31 31 20 28 50 72 6F 64 75 63 65 72 20 45 64 69 74 69 6F 6E 20 76 31 31 2E 31 2E 31 29 20 20 20 20 20 20 F7 |
LCD1行目書き換え "Linked to FL Studio 11 (Producer Edition v11.1.1) " の表示 |
SystemExclusive | F0 00 00 66 14 12 00 49 4E 53 20 31 20 20 49 4E 53 20 32 20 20 49 4E 53 20 33 20 20 49 4E 53 20 34 20 20 49 4E 53 20 35 20 20 49 4E 53 20 36 20 20 49 4E 53 20 37 20 20 49 4E 53 20 38 F7 |
LCD1行目書き換え "INS 1 INS 2 INS 3 INS 4 INS 5 INS 6 INS 7 INS 8" の表示 |
初期化処理は特にないようで、いくつかのボタンを光りっぱなしにしたあとに接続しても、そのボタンは光りっぱなしになってしまうようです。
フェーダー位置は、 0x66, 0x10 から 0b01100110, 0x00010000 となり、7bitで結合すると 0b11001100010000 = 0d13072 (0~16383中)となり、Arduino MIDI Libraryに -8192~8191 で渡すため 13072-8192 を計算すると 4880 となります。
MIDI.sendPitchBend(4880, 1);
とするのがフェーダーの0dB位置で初期化されるようです。
FL Studioで実際にやり取りされる内容(切断時)
切断時の通信内容をMIDI-OXでモニターした結果が以下の通りです。
X-TOUCHを起動したまま、FL Studioを終了したときの内容です。
コマンド | データ | 概要 |
---|---|---|
SystemExclusive | F0 00 00 66 14 20 00 00 F7 | チャンネルメーターモード |
SystemExclusive | F0 00 00 66 14 20 01 00 F7 | チャンネルメーターモード |
SystemExclusive | F0 00 00 66 14 20 02 00 F7 | チャンネルメーターモード |
SystemExclusive | F0 00 00 66 14 20 03 00 F7 | チャンネルメーターモード |
SystemExclusive | F0 00 00 66 14 20 04 00 F7 | チャンネルメーターモード |
SystemExclusive | F0 00 00 66 14 20 05 00 F7 | チャンネルメーターモード |
SystemExclusive | F0 00 00 66 14 20 06 00 F7 | チャンネルメーターモード |
SystemExclusive | F0 00 00 66 14 20 07 00 F7 | チャンネルメーターモード |
SystemExclusive | F0 00 00 66 14 12 00 46 4C 20 53 74 75 64 69 6F 20 31 31 20 73 65 73 73 69 6F 6E 20 63 6C 6F 73 65 64 20 61 74 20 32 3A 32 32 3A 30 32 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 F7 |
LCD1行目書き換え "FL Studio 11 session closed a 2:22:02 " の表示 |
SystemExclusive | F0 00 00 66 14 12 3E 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 F7 |
LCD2行目書き換え " " の表示 |
ControlChange | B0 47 20 | 7セグ書き換え BARS: 3/3 Digit 表示なし |
ControlChange | B0 46 20 | 7セグ書き換え BEATS: 1/2 Digit 表示なし |
ControlChange | B0 45 20 | 7セグ書き換え BEATS: 2/2 Digit 表示なし |
ControlChange | B0 42 20 | 7セグ書き換え TICKS: 1/3 Digit 表示なし |
ControlChange | B0 41 20 | 7セグ書き換え TICKS: 2/3 Digit 表示なし |
ControlChange | B0 40 20 | 7セグ書き換え TICKS: 3/3 Digit 表示なし |
ControlChange | B0 4B 20 | 7セグ書き換え ASSIGNMENT: 1/2 Digit 表示なし |
ControlChange | B0 4A 20 | 7セグ書き換え ASSIGNMENT: 2/2 Digit 表示なし |
0x1A のコマンドは何?
F0 00 00 66 14 1A 00 F7
のコマンドが謎です。
F0 00 00 66 14 1B 58 59 5A 22 44 0A 31 F7
で応答があるようです。
- Mackie C4 Pro and Cubase
- Sonar / Cakewalk Mackie SysEx
- GitHub - Cakewalk-Control-Surface-SDK/Surfaces/MackieControl/MackieControlBase.cpp
QuerySerialNumber とあることから非公開の仕様でシリアルナンバーを要求するコマンドなのではないでしょうか?
つまり、応答があった「58 59 5A 22 44 0A 31」がシリアルナンバーでしょうか?
しかし、同じ装置(MCU Pro)に対して、以下のコマンド
F0 00 00 66 14 00 F7
にて初期化を実行すると
Serial: 58 59 5A 18 77 09 70
が帰ってきます。
(その後、レスポンスコードを応答しても初期化に失敗します)
どういうことだ~~~???
MCU Proを調べていて気付いたことがあります。
コマンド0x00を送らなくても、MCU Pro側から起動時に0x01が送られているようです。
しかも、毎回シリアル末尾が異なります。
[RCV] midi::SystemExclusive
[DATA] SysExArrayLength = 18
[DATA] SysExArray = F0 00 00 66 14 01 58 59 5A 2F 2A 0C 25 79 33 5A 73 F7
[RCV] midi::SystemExclusive
[DATA] SysExArrayLength = 18
[DATA] SysExArray = F0 00 00 66 14 01 58 59 5A 7D 08 29 2A 7F 47 55 6A F7
[RCV] midi::SystemExclusive
[DATA] SysExArrayLength = 18
[DATA] SysExArray = F0 00 00 66 14 01 58 59 5A 5E 48 15 65 78 5D 5C 38 F7
[RCV] midi::SystemExclusive
[DATA] SysExArrayLength = 18
[DATA] SysExArray = F0 00 00 66 14 01 58 59 5A 38 08 29 6C 50 15 20 73 F7
[RCV] midi::SystemExclusive
[DATA] SysExArrayLength = 18
[DATA] SysExArray = F0 00 00 66 14 01 58 59 5A 38 04 6F 7E 0C 72 68 4C F7
[RCV] midi::SystemExclusive
[DATA] SysExArrayLength = 18
[DATA] SysExArray = F0 00 00 66 14 01 58 59 5A 5F 38 28 7A 78 1B 07 5E F7
[RCV] midi::SystemExclusive
[DATA] SysExArrayLength = 18
[DATA] SysExArray = F0 00 00 66 14 01 58 59 5A 32 6F 1F 2E 3B 02 00 54 F7
[INFO] IO_Control::_LC_Send_Initialize_Request
[DATA] model = 0x14
[INFO] IO_Control::begin()
[RCV] midi::SystemExclusive
[DATA] SysExArrayLength = 18
[DATA] SysExArray = F0 00 00 66 14 01 58 59 5A 32 6F 1F 2E 3B 02 00 54 F7
[INFO] 0x01: Connection Query
F0 0 0 66 14 1 58 59 5A 32 6F 1F 2E 3B 2 0 54 F7
Serial: 58 59 5A 32 6F 1F 2E
Challenge: 3B 2 0 54
[INFO] IO_Control::_LC_Send_Initialize_Reply
[DATA] model = 0x14
[TIMEOUT] E_MIDI_LC_INITIALIZE_REPLY_BEGIN
ArduinoからMackie ControlプロトコルでMackie Control C4を制御
Mackie Control C4を入手したのでこちらも動作テストしてみます。
ファームウェアは最終版のv1.02です。
ボタン一覧
ボタンはMackie Controlと同様にノートオン、ノートオフでボタンを押した瞬間と離した瞬間が通知されるようです。
ID(0x) | BUTTON | LED COLOR |
---|---|---|
00 | FUNCTION: SPLIT | YELLOW(1/3 LED) |
01 | --- | YELLOW(2/2 LED) |
02 | --- | YELLOW(3/1 LED) |
03 | FUNCTION: LOCK | YELLOW |
04 | FUNCTION: SPOT ERASE | RED |
05 | ASSIGNMENT: MARKER | YELLOW |
06 | ASSIGNMENT: TRACK | YELLOW |
07 | ASSIGNMENT: CHAN STRIP | YELLOW |
08 | ASSIGNMENT: FUNCTION | YELLOW |
09 | PARAMETER: BANK Left | --- |
0A | PARAMETER: BANK Right | --- |
0B | PARAMETER: SINGLE Left | --- |
0C | PARAMETER: SINGLE Right | --- |
0D | MODIFIERS: SHIFT | --- |
0E | MODIFIERS: OPTION | --- |
0F | MODIFIERS: CONTROL | --- |
10 | MODIFIERS: ALT | --- |
11 | SLOT UP | --- |
12 | SLOT DOWN | --- |
13 | TRACK L | --- |
14 | TRACK R | --- |
--- | --- | --- |
20 | V-Pot Knob (Row 1) Ch. 1 | --- |
21 | V-Pot Knob (Row 1) Ch. 2 | --- |
22 | V-Pot Knob (Row 1) Ch. 3 | --- |
23 | V-Pot Knob (Row 1) Ch. 4 | --- |
24 | V-Pot Knob (Row 1) Ch. 5 | --- |
25 | V-Pot Knob (Row 1) Ch. 6 | --- |
26 | V-Pot Knob (Row 1) Ch. 7 | --- |
27 | V-Pot Knob (Row 1) Ch. 8 | --- |
28 | V-Pot Knob (Row 2) Ch. 1 | --- |
29 | V-Pot Knob (Row 2) Ch. 2 | --- |
2A | V-Pot Knob (Row 2) Ch. 3 | --- |
2B | V-Pot Knob (Row 2) Ch. 4 | --- |
2C | V-Pot Knob (Row 2) Ch. 5 | --- |
2D | V-Pot Knob (Row 2) Ch. 6 | --- |
2E | V-Pot Knob (Row 2) Ch. 7 | --- |
2F | V-Pot Knob (Row 2) Ch. 8 | --- |
30 | V-Pot Knob (Row 3) Ch. 1 | --- |
31 | V-Pot Knob (Row 3) Ch. 2 | --- |
32 | V-Pot Knob (Row 3) Ch. 3 | --- |
33 | V-Pot Knob (Row 3) Ch. 4 | --- |
34 | V-Pot Knob (Row 3) Ch. 5 | --- |
35 | V-Pot Knob (Row 3) Ch. 6 | --- |
36 | V-Pot Knob (Row 3) Ch. 7 | --- |
37 | V-Pot Knob (Row 3) Ch. 8 | --- |
38 | V-Pot Knob (Row 4) Ch. 1 | --- |
39 | V-Pot Knob (Row 4) Ch. 2 | --- |
3A | V-Pot Knob (Row 4) Ch. 3 | --- |
3B | V-Pot Knob (Row 4) Ch. 4 | --- |
3C | V-Pot Knob (Row 4) Ch. 5 | --- |
3D | V-Pot Knob (Row 4) Ch. 6 | --- |
3E | V-Pot Knob (Row 4) Ch. 7 | --- |
3F | V-Pot Knob (Row 4) Ch. 8 | --- |
0x01と0x02はLEDだけしか存在しません。
ボタンは0x00のSPLITだけです。
切り替え表示のための実装のようです。
V-Potのノブの位置に対するノート番号の一覧表。
行 | Ch. 1 | Ch. 2 | Ch. 3 | Ch. 4 | Ch. 5 | Ch. 6 | Ch. 7 | Ch. 8 |
---|---|---|---|---|---|---|---|---|
1行目(一番上) | 0x20 | 0x21 | 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 |
2行目 | 0x28 | 0x29 | 0x2A | 0x2B | 0x2C | 0x2D | 0x2E | 0x2F |
3行目 | 0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 |
4行目(一番下) | 0x38 | 0x39 | 0x3A | 0x3B | 0x3C | 0x3D | 0x3E | 0x3F |
V-Potのノブも押し込んだ際にボタンと同様の動作をします。
エンコーダーノブ・V-Potの読み込み
基本的には前述の通りで読み込み方法は変わりません。
V-Potのノブはコントロールチェンジで回転方向のイベントが発生します。
コントロールチェンジを読めばOKです。
チャンネルは1に対して、コントロール番号が0x00~0x1Fで割り当てられているようです。
6bit値で取れる回転スピードについては、X-TOUCHと異なりかなりリニアに変化するようです。
しかしビット数は低いようです。
具体的には、ゆっくり回すと1ですが、その後、4、8、12、15と変わっていきます。
合計5パターンでの値の出力です。
15が値として最大のようです。どれだけ速く回してみてもそれ以上の数値は見られませんでした。
V-Potのノブの位置に対するコントロール番号の一覧表。
行 | Ch. 1 | Ch. 2 | Ch. 3 | Ch. 4 | Ch. 5 | Ch. 6 | Ch. 7 | Ch. 8 |
---|---|---|---|---|---|---|---|---|
1行目(一番上) | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
2行目 | 0x08 | 0x09 | 0x0A | 0x0B | 0x0C | 0x0D | 0x0E | 0x0F |
3行目 | 0x10 | 0x11 | 0x12 | 0x13 | 0x14 | 0x15 | 0x16 | 0x17 |
4行目(一番下) | 0x18 | 0x19 | 0x1A | 0x1B | 0x1C | 0x1D | 0x1E | 0x1F |
エンコーダーノブ・V-Pot LEDを制御
基本的には前述の通りで読み込み方法は変わりません。
コントロールチェンジを送ればそれに対応して光ります。
LEDの色は赤色なので明るいところだと見づらいです。
V-PotのLEDの位置に対するコントロール番号の一覧表。
行 | Ch. 1 | Ch. 2 | Ch. 3 | Ch. 4 | Ch. 5 | Ch. 6 | Ch. 7 | Ch. 8 |
---|---|---|---|---|---|---|---|---|
1行目(一番上) | 0x20 | 0x21 | 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 |
2行目 | 0x28 | 0x29 | 0x2A | 0x2B | 0x2C | 0x2D | 0x2E | 0x2F |
3行目 | 0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 |
4行目(一番下) | 0x38 | 0x39 | 0x3A | 0x3B | 0x3C | 0x3D | 0x3E | 0x3F |
LCDディスプレイの制御
基本的には前述の通りで表示方法は変わりませんが、システムエクスクルーシブメッセージのヘッダーが若干変わります。
Mackie Control C4の場合、製品指定が0x14ではなく、0x17を使用するようです。
現在わかっている範囲では以下のようになります。
ID | 機種 |
---|---|
0x10 | Logic Control |
0x11 | Logic Control XT |
0x14 | Mackie Control |
0x15 | Mackie Control XT |
0x17 | Mackie Control C4 |
また、LCD指定のIDについては以下のようになります。
行 | ID |
---|---|
1行目(一番上) | 0x12 |
2行目 | 0x31 |
3行目 | 0x32 |
4行目(一番下) | 0x33 |
したがって、一番上のLCDに表示するならば、以下のようなシステムエクスクルーシブメッセージ。
F0 00 00 66 17 12 [位置] [内容] F0
一番下のLCDに表示するならば、以下のようなシステムエクスクルーシブメッセージ。
F0 00 00 66 17 33 [位置] [内容] F0
なお、一番上のLCDには起動時にバージョン情報含めて表示が行われるために、任意の文字を表示する前にスペースで埋めて消す処理を行ったほうが良いと思われます。
その他コマンド(ファームウェアバージョンリクエスト)
基本的には前述の通りで取得方法は変わりませんが、LCDと同様に製品指定のIDだけ0x17に変化します。
F0 00 00 66 17 13 00 F7
以上のシステムエクスクルーシブメッセージを送ると以下の様な返答があります。
F0 00 00 66 17 14 56 31 2E 30 32 F7
データ部分のペイロード、5バイトのデータ(0x56~0x32まで)です。
つまり「V1.02」という文字列のアスキーコード5桁の返答になり、このバージョン情報はLCDディスプレイ部に表示されています。
製品指定のIDが異なると反応しないため、繋がっている機器の判定ができると思われます。
その他コマンド(リセットメッセージ)
基本的には前述の通りです。
製品指定のIDだけ0x17に変化します。
LEDをすべてオフにするコマンド
F0 00 00 66 17 62 F7
ボタンとV-PotのLEDが消灯しました。
リセットコマンド
F0 00 00 66 17 63 F7
リセットがかかり、LCD表示内容も初期化されました。
その他コマンド(コンフィギュレーションメッセージ)
基本的には前述の通りです。
製品指定のIDだけ0x17に変化します。
LCDバックライトセーバー(0x0B)
7バイト目で挙動が変わるようです。
F0 00 00 66 17 0B 00 F7 // LCD back light off
F0 00 00 66 17 0B 0F F7 // LCD back light on, with time out in minutes (default: 0F = 15minutes)
バックライトの制御が可能でした。
15分経過するとバックライトが消えます。(ボタン等に触れるとバックライトが点灯します)