ロータリー・ノブのMIDIメッセージまとめ
AKAI MPK mini MK3は、ロータリー・ノブが搭載されている
永遠に回し続けることができるタイプのノブ
今回、ロータリー・ノブを相対モードにしたときのMIDIメッセージについてまとめる
混乱する点
この種のノブの呼び名に決定的なものがないと感じる
AKAIのページやマニュアル内でも、360º knobs(360º 度回転ノブ)、エンドレス・ノブなどの表記がある
細かいことを指摘したいという意図ではなく、情報を探すときの検索ワードに困るという話だ
ロータリー・エンコーダーなどと呼ばれることもありそうだ(どちらかという電子工作・部品の文脈で登場する印象)
(本記事ではロータリー・ノブと呼ぶ)
ロータリー・ノブ内にもモードがある、MPK Mini Mk3 Program EditorではAbsolute、Relativeと表記
Relativeの情報を探してるのに、Absoluteの話が出てくる
Relativeモードの質問をしているのに、Absoluteモード前提の回答をしているQ&Aサイトなどよく見る
RelativeモードのMIDIメッセージのフォーマット(エンコード形式)が複数あり、デバイスが採用しているフォーマットがみつからない
AKAIのページにあるマニュアルをみても"アサイナブル・ノブ:これらの360º 度回転ノブで、MIDI CCメッセージを送信します。"くらいの情報しかみつけられなかった
どこかに書いてあるのかもしれないが
Relativeのデータフォーマットの呼び名が統一されていない
今回は、3つのMIDI関連の機器のページにある情報を閲覧したが呼び名が異なる上、対応しているフォーマットも異なる
MIDIメッセージのCCのData(値)は、7ビットで表現することが多い、一方、2の補数の説明するとき、多くは8bitを前提にしている
2の補数の一覧を列挙してくれているサイトは参考にならない
このように混乱を誘う事項が多くて、今まで情報を整理できていなかったので整理した。
データフォーマット
データフォーマットについて、以下の3つのページで確認してみた
Logic Pro
The choices are:
Unsigned
2's complement
1's complement
Sign Magnitude
Logic Proのページは、それぞれのフォーマットについて詳しく書かれていて助かる。しかし、8ビットのデータを前提とした、2の補数の範囲が書かれている。MIDIメッセージは、7ビットで表現することがあり、7ビットでの表現の場合、データの範囲は-64~63だと思う。
Ableton
There are four types of relative controllers:
Signed Bit
Signed Bit 2
Bin Offset
Twos Complement
https://www.ableton.com/en/manual/midi-and-key-remote-control/
Serato
The different MIDI data types are :
Absolute
Relative - signed bit
Relative - binary offset
Relative - 2's complement
Relative - on/off
https://support.serato.com/hc/en-us/articles/225065768-MIDI-Data-Types
AKAI MPK mini MK3の実機でMIDIメッセージを確認
結局、AKAI MPK mini MK3が、どのフォーマットを採用しているのか、わからないので、メッセージを見て判断するしかなさそう
DAWを操作して、それっぽく動作したものを採用するって手法でもいいのだが
ノブを右に回した場合
以下のメッセージは、MPK mini MK3でノブを回したときのMIDIメッセージ例
USB-MIDIなので、4バイト目にCCの値がくる
0b b0 46は、CC(特定のノブを回したこと)を表現している
0b b0 46 01
0b b0 46 02
0b b0 46 05
ノブを左に回した場合
0b b0 46 7d
0b b0 46 7e
0b b0 46 7f
右に回した場合、1から増えていく(早く回すと値が増加)
左に回した場合、7fから減っていく(早く回すと値が減少)
2の補数っぽいので計算して確かめてみる
以下、筆者の認識
MIDIの値は、7ビット表現なので、最上位ビットは0で固定
最上位ビットの次のビットが符号を表す
残りの6ビットが数値を表す
そう考えた場合、上記のMIDIメッセージは、以下のような値になり、正しそう
早く回すと、-1と-1以外の数値が取れることもわかった
(できれば、この感度を調整したいのだが、アプリでやるしかなさそう)
+1
+2
+5
-3
-2
-1
7ビットの2の補数を計算する
7ビットの2の補数を計算するPythonスクリプトを作る
8ビットの2の補数の場合は、適切な型(signed charなど)を指定すれば、コンピューターが表現してくれるが
7ビットなので、自分で計算する必要がある
符号ビットがマイナスの場合、反転して、最上位ビットを0にして、1を加算して、マイナスにする、などをやってもいいが
「符号ビットが立っていたら、128を減算する」という計算を実装した
以下がプログラム
「ビット演算」より「大小比較」の方が処理が早そうなら、if節を data >= 64 などとする
data = data - 128 if data & 0x40 else data
検算
7bitの2の補数は、はじめて扱って、考え方が合っているか自信がなかったので
他に計算されている方をみつけて、検算した
結果、MIDIのCCが扱う値の範囲(0-127)で一致した
# ----
# https://discourse.ardour.org/t/trick-map-relative-encoders-2s-complement-to-positional-controllers/108577
BIT7_MIN = 0
BIT7_MID = 64
BIT7_MAX = 127
BIT7_MODULO = 128
def twos_complement_to_signed_7bit(num):
return ((num + BIT7_MID) % BIT7_MODULO) - BIT7_MID
# ----
def MY_twos_complement_to_signed_7bit(num):
return num - 128 if num & 0x40 else num
for i in range(128):
a = twos_complement_to_signed_7bit(i)
b = MY_twos_complement_to_signed_7bit(i)
test = a == b
print(f'{i}: {a} {b} {test}')
if test is not True:
raise ValueError("No match")
これで、ロータリー・ノブのRelativeモードも怖くなくなった!