SonicPiをMIDIで制御してライブっぽく演奏したい
外部から指示することでSonicPiの音を鳴らすループを動かす(止める)を自由にやりたいなと思いまして、今回はMIDIを使って制御するやり方を試行錯誤してみました。
実例(動画)
概要
キーボードを押したときのnote
(C3~F3)にそれぞれLiveLoopを対応づけておきます。
対応するキーを押すと 対応する音楽が鳴り始める、止める、を実現したいと思います。
MIDIキーボードのキーを押すことでリズムを奏でたり停止したり、少しだけですがライブ演奏の感覚を味わうことができます。
構成(Windows11)
- SonicPi
- Pocket MIDI
- loopMIDI
やってみてわかったこと
MIDIとの同期
sync midi:~
:MIDIから通信と同期させることで、MIDI通信が来るまで次のステップには進まずに待ちが発生します。
live_loop :midi01 do
note, velocity = sync_bpm "/midi:loopmidi_port_0:1/note_on"
# MIDI通信が来るまで次のステップには進まずに待つ。
end
MIDI参照(GET)
get midi:~
は、直近で受信したMIDIの情報を取り出すだけであり、待ちが発生しません。
そのため、loop の中で sleep がないと SonicPiの処理でエラーになります。
live_loop :midi02 do
program,_ = get "/midi:loopmidi_port_0:1/program_change"
# MIDI通信を待たずにGETする
# loop内でsleepを必要とする。
sleep 0.5
end
liveLoopを手動で開始する
live_loop
は自動的に開始してしまうループであり、止めることができますが、再開させるには一工夫が必要です。自動で開始させず手動指示のタイミングによりlive_loop
を開始するためには、次のやり方がよいみたいです。
# loop do-end の中に live_loopを作る
# loop は threadの中で起動させる
# loop の中では `sync`で待ちを作り、live_loopの開始を抑止する
in_thread do
loop do
sync :SYNC01 # <=== ★ cue SYNC01 が発生するまで待つ。
live_loop :LOOP01 do
# 何か音を鳴らす。
sleep 4 # 適宜 休止
stop if get[:ACTIVE01] # 停止条件が成り立てばliveLoopを止める
end
end
end
上の作りとすることで、liveLoopをSTOPした後に、再度のcue SYNC01
により同じliveLoopを開始することができます。