音が出せるだけじゃないはず
MIDIキーボードは音楽活動に使われるイメージが大きいですが、仕組みを考えるともっと幅広い使い方ができるように思えます。一つ一つの鍵盤がスイッチだと考えれば、押したらオン、離せばオフのようなシンプルな仕組みと捉えられるはずです!
そこで今回は、実際にPythonを使ってMIDIキーボードの入力を取得して、いろいろと遊んでみました。
MIDI入力を取得する
まずはとにかく入力を見てみたいですよね。どんな仕組みでキーボードが動いているのか確認してみます。
pygame.midi
pygame.midi
を使うと、PythonでMIDI入力を取得できるらしいです。
pygame自体はPythonではおなじみのゲーム制作ライブラリですが、その中にmidiを取得できる機能が付属していました。早速動作確認。
import pygame.midi as m
### midiキーボードを初期化
m.init()
i = m.Input( m.get_default_input_id() )
while True:
if i.poll(): # MIDIを受信するとTrue
# MIDI入力を取得
midi_events = i.read(4)
print(f'events: {midi_events}')
こんな感じに書くと、midi_eventsの中に取得したMIDI入力が入るらしい。
events:[[[status, data1, data2, data3], timestamp]]
events: [[[144, 67, 45, 0], 10]]
events: [[[248, 0, 0, 0], 20]]
events: [[[248, 0, 0, 0], 40]]
events: [[[144, 67, 0, 0], 55]]
...
status
: オン(144)かオフ(248)
data1
: ノート番号(C:60 C♯:61 D:62 ...)
data2
: 音量(0 ~ 127)
data3
: チャンネル
timestamp
: 経過時間
と意外にもいろんな情報が入ってました。それぞれ何か使えそうですね。
特定のキーをスイッチにしてみる
先ほど確認した入力をもとに、特定のキーをスイッチにしてprintさせてみます。
note = midi_events[0][0][1] # ノート番号
if note == 60: # C3
print('hello')
hello
hello
設定したノート番号60、C3を一回だけ押してみました。あれ?
押した時に1回、離した時にもう1回反応しました。出力を確認すると、
events:[[[status, data1, data2, data3], timestamp]]
events:[[[144, 60, 50, 0], 10]]
events:[[[144, 60, 0, 0], 40]]
キーを離した時、同じ音を音量0で入力した扱いになっていることが分かりました。また気になるのが、status
は144でオン。ややこしい。
MIDIではキーを離した時も1つのイベントと捉えられるようです。はえー。
コードを修正
note, vol = midi_events[0][0][1:2] # 情報を取得
if vol != 0 and note == 60: # C3
print('hello')
hello
キーを離した時音量は0になるので、音量が0でないことを確認するように修正したら、無事スイッチの形ができました。
コントローラーを作れるのでは
PCゲームは、マウスでの視点移動が必要なゲームを除けば、操作の全てがキーボードで完結します。またキーボードの操作も、wキーを長押しして前に移動、spaceキーでジャンプ、xキーで何かを発動するなど、キーの押し離しのみで非常にシンプルです。
ということは、midiキーボードはコントローラーとして使うことができるのでは...?と思いました。
仕組みを考える
PyAutoGUIを使って、PCのキーボードを直接制御することができます。
例えばpyautogui.press('x')
でxキーを押せたり。
MIDIキーボードのキー1つ1つを新しいキーとしてPCに認識させるのは難しいので、今回はこれを使うことにしました。
# ド
if note == 60:
key = 'x'
if note == 61:
...
# 長押し判定
try:
if vol != 0:
pyautogui.keyDown(key)
else:
pyautogui.keyUp(key)
except ValueError: # 何も押してない時
pass
流石にコードを直す
1つ1つのキーで条件分岐していたらキリがないので、こんな感じのjsonで設定できるようにしました。
[
{
"midi" : 60,
"key" : "f"
},
{
"midi" : 61,
"key" : "r"
}
]
できた
完成した全コードはGitHubで配布してます。
使い方も記載したので、是非使ってみてください!
追記(2024/3/21): 全体的に動かなくなっていたので、仕様含め更新しました。
実際に動かしてみる(ゲームはMuseDash)
シンプルな操作の音ゲーなら簡単に対応できました。遅延も無く(ここすごい)長押しも問題なくゲームセンターの筐体のような感覚で遊べました!楽しい!
(マイクラにも挑戦中ですが、キー配置に苦戦中です...)
おわりに
意外にも操作性はかなり高く、音楽関係を超えた場面でのMIDIの可能性を感じました。もっといろんな使い方が見つかりそうです。
今家にあるMIDIキーボードは音の強弱にも対応しているので、その機能と組み合わせたゲームを自作するのもまた面白そうですね。
以上、ロマンをお届けしました!