#はじめに
前回はADX2ロボット機能を使ってMIDIを読みこんでみた
今回は
ブロックの長さを調整する時に、BPMとビート数で指定できると良いなと思った時があったので、
ロボット機能でできないか試してみる。
最初は、スクリプトだけで試し、後半はPySimpleGUI でUIつきで操作できるようにしてみる。
#スクリプト
# --Description:[tatmos]ブロックの長さを指定した長さに変更する
import sys
import cri.atomcraft.project
import cri.atomcraft.project as acproject
import cri.atomcraft.debug as acdebug
# --BeginUserVariable
"""
BLOCK_LENGTH:
type:number
comment:ブロックの長さ
"""
BLOCK_LENGTH = 1000
# --EndUserVariable
#選択中のブロックを得る
selected_Block = acproject.get_selected_objects("Block")["data"]
if not selected_Block :
acdebug.warning("長さを変更するブロックを選択してください。")
sys.exit()
#指定した長さに変更する
acproject.set_value(selected_Block[0], "BlockEndPositionMs", BLOCK_LENGTH)
#これで変更はできるが
BPMとビート数で、時間計算するといったUIをつけたいけど、
メニューからの選択系(ローカル動作)だとUIがうまく動かないらしいので、
リモートで設定できるように改良してみる。
#リモート対応版スクリプト
まず、シンプルにリモート化するとこんな感じ。
接続と終了で処理を挟む。
import sys
import cri.atomcraft.project
import cri.atomcraft.project as acproject
import cri.atomcraft.criatomcraft_api_lib as acconnect
import cri.atomcraft.debug as acdebug
# 初期化
result = acconnect.initialize()
if result != 0:
print("initialize error")
sys.exit()
# 接続の実行
result = acconnect.connect("127.0.0.1", 9000)
if result != 0:
print("connection failed")
acconnect.finalize()
sys.exit()
# UI
import PySimpleGUI as sg
# コマンドの送信
BLOCK_LENGTH = 1000
#選択中のブロックを得る
selected_Block = acproject.get_selected_objects("Block")["data"]
if not selected_Block :
acdebug.warning("長さを変更するブロックを選択してください。")
sys.exit()
#指定した長さに変更する
acproject.set_value(selected_Block[0], "BlockEndPositionMs", BLOCK_LENGTH)
# 接続の終了
acconnect.disconnect()
# 終了処理
acconnect.finalize()
これで、リモート経由で動作させて長さが1000になるのを確認した。
#リモートでUI付きのもの
UIを表示するのに、PySimpleGUI を使ってみた。
ちょっと値取得関連がまだうまく動いていないけど(PySimpleGUI の表示更新、表示内容取得のタイミングが悪いのか)
計算結果のLengthを表示したいけど、うまくいかない・・・
とりあえず2回くらいボタン押すと変化するようにはなった
実用上はまぁ、問題ないかな。
実行している様子の動画:
https://twitter.com/tatmos/status/1356933633123127296?s=20
#ADX2 ロボット機能を使ってブロックの長さを変更してみる動画 pic.twitter.com/nbbyPJiiii
— tatmos (@tatmos) February 3, 2021
Craft上で変更したいBlockを選択し、
ダイアログでBPMとビート数を入れて、
Submitを押すと、ブロックの長さが変化します。
#リモートでUI付きスクリプト
import sys
import cri.atomcraft.project
import cri.atomcraft.project as acproject
import cri.atomcraft.criatomcraft_api_lib as acconnect
import cri.atomcraft.debug as acdebug
# 初期化
result = acconnect.initialize()
if result != 0:
print("initialize error")
sys.exit()
# 接続の実行
result = acconnect.connect("127.0.0.1", 9000)
if result != 0:
print("connection failed")
acconnect.finalize()
sys.exit()
# UI
import PySimpleGUI as sg
BLOCK_LENGTH = 1000
layout = [
[sg.Text('BPM', size=(15, 1)), sg.InputText("120",key='Input-BPM'), sg.Button('Set', key='-SetBPM-')],
[sg.Text('BeatNum', size=(15, 1)), sg.InputText("4",key='Input-BeatNum'),sg.Button('Set', key='-SetBeatNum-')],
[sg.Submit(), sg.Cancel()],
[sg.Text("Length: {0}".format(BLOCK_LENGTH),key='Text-Length')]]
window = sg.Window('ChangeBlockLength', layout=layout)
def caliculateLength():
global BLOCK_LENGTH
event, values = window.read()
bpm = str(values["Input-BPM"])
beatNum = str(values["Input-BeatNum"])
BLOCK_LENGTH = 1000 * 60/ float(bpm) * float(beatNum)
def setBpm_func():
pass
def setBeatNum_func():
pass
def submit_func():
# コマンドの送信
global BLOCK_LENGTH
#選択中のブロックを得る
selected_Block = acproject.get_selected_objects("Block")["data"]
if not selected_Block :
acdebug.warning("長さを変更するブロックを選択してください。")
sys.exit()
#指定した長さに変更する
preBlockLength = acproject.get_value(selected_Block[0], "BlockEndPositionMs")["data"]
acproject.set_value(selected_Block[0], "BlockEndPositionMs", BLOCK_LENGTH)
acdebug.log("ブロックの中さを変更。\"{0}\" {1} to {2}".format(acproject.get_object_path(selected_Block[0])["data"] ,preBlockLength,BLOCK_LENGTH))
# 使いたい関数とkeyをセットにして辞書にするだけ
handler = {
'-SetBPM-': setBpm_func,
'-SetBeatNum-': setBeatNum_func,
'Submit': submit_func,
}
while True:
event, value = window.read()
caliculateLength()
if event in [None, 'Cancel']:
break
function = handler[event] # handlerからeventに応じた関数を呼び出す
function()
window['Text-Length'].update("Length: {0}".format(BLOCK_LENGTH))
window.close()
# 接続の終了
acconnect.disconnect()
# 終了処理
acconnect.finalize()