あらすじ
MBPにMidiコントローラーを2つつなげてマッピングしていたら、チャンネルやノートがかぶってしまい、どちらからも操作可能になってしまう事態が発生しました。こういうやつの取扱はProcessingと相場が決まっています。で、The MidiBusなるライブラリを使ってみたのですが…スライダーの値は取れるのですがパッドとフェーダーが反応しない!!という問題が・・・
異なる信号を割り振るとかをやりたかったわけではなく、とりあえずいじっている機器とその信号だけ表示できればよかったのでこの問題については一切調べてません。既にブラウザでMidiできる時代ですし、Midiのことはまったく知りませんが、自分でもなんとかできるんじゃね?と思い、ちょっと調べてみることにしました。
rtmidi2
ちなみに当然フルスクラッチは自分には不可能なことがわかりきっているのでふつうにライブラリを使います。ググるとrtmidi2とかいうモジュールを使えばいいそうです。唯一の日本語情報がQiitaにありました。
ということで気軽にかまえていたのですが、適当にコピペしただけでは動きませんでした・・・。どうやらわたしの場合、複数の機器をつなげていたせいでしょう。
とりあえずソースを眺めてみたのですが、
なんか見たことない形式でした。たぶんこれが悪名高いCythonとうやつなのでしょう、意味不明でした。READMEも「わかっているひと」向けっぽいです。少なくともわたしにはなにがなにやら、でした。
rtmidi2.pyx
なるファイルが中核っぽいので嫌々みてみながら試行錯誤して、なんとなくほしい情報は取れるようになったので置いておきます。ちなみにこの水平線のあいだに10時間くらいかかりました。あと自分でもなんでこれでいいのかさっぱりわからん代物なのでたぶんマネないほうがいいと思います。。がんばったから痕跡でも残しておきたいという思いです。
import rtmidi2, time midi_in = rtmidi2.MidiInMulti().open_ports("*") print(midi_in.ports) print(rtmidi2.get_in_ports()) deviceID, Val, vel = 0, [], 0 def callback_with_source(src, msg, time): global deviceID, Val, vel deviceID, Val, vel = src, msg, time midi_in.set_callback(callback_with_source, src_as_string=False) i = 0 print("start") while True: time.sleep(0.05) if len(Val) is not 0: i+=1 print(deviceID, Val, vel, flush=True) time.sleep(0.01) deviceID, Val, vel = 0, [], 0 if i>100: #とりあえず20回分だけテスト break print("end")
ちなみにprint()
のflushオプションなんて初めて知りました。ある意味収穫はあったといえましょう(と、必死に自己肯定)