Max for Live とか Live Object Model とか

DSC00213


Max for LiveでLive api使うには専用のMax object(live.object, live.path, live.observer, live.remote~)を使ってPatchでやる方法とMax js objectでjavascriptでやる方法が用意されてる。


PatchでやるほうはHelpも充実してて迷うことも無いけど、javascriptの方はドキュメントにサンプルコードも無くて放置ぎみなので、探り探りやったことまとめ。※以下はLive8.1 b7とb8のもので書いてます。


APIはLive Object Modelとして階層構造になってて、Rootはlive_appとlive_songで、トラック、クリップ、デバイスとかよく使いそうなのはlive_songの中にあります。詳細はMax5.1以降のドキュメントに図があります。Max for LiveのドキュメントはLive側が起動してないと見れないです。


1. API Objectの生成

//空のAPIの生成
var api = new LiveAPI(this.patcher);

//Path指定でAPIの生成(例はトラック1)
var api = new LiveAPI(this.patcher, "live_set", "tracks", 1);
//または
var api = new LiveAPI(this.patcher, "live_set tracks 1");

//ObserverのCallbackを指定してのAPI生成
var api = new LiveAPI(this.patcher, callback);


コンストラクタでPathの引数の書き方が変だと実行時にMaxごと落ちることがあります。API生成後にPath指定することもできます。こっちはPathの書式ミスってもMax落ちないです。


2.Pathの指定

//トラック1の最初のクリップを指定する
api.path = "live_set tracks 0 clip_slots 0 clip";
//または
api.goto("live_set tracks 0 clip_slots 0 clip");


3.Propertyのget/set

//クリップの名前を取得
var name = api.get('name');

//クリップの再生状態を1(つまり再生)にする
api.set('is_playing', 1);


4.Functionの呼び出し

//クリップを再生する
api.call('set_fire_button_state', 1);
//こっちはダメ
//api. set_fire_button_state(1);


ObjectごとのPropertyやFunctionはドキュメントに全部あります。


5.ObserverのCallback

var api = new LiveAPI(this.patcher);
api.path = "live_set tracks 0 clip_slots 0 clip";
//Observerの監視対象にする
api.property = "playing_status";

var callback = function (args) {
	post(args, "\n");
	post("property is", this.property, "\n");
}


上の実装でやると、Callbackが呼ばれるタイミングで2回実行されるのがちょっと謎。根本的に何か間違ってるかも・・・。


6.Children

//トラック1
api.path = "live_set tracks 0";

//戻り値はcanorical_parent ckip_slot devices ......
post(api.children , "\n");

//この戻り値はc
post(api.children[1][0]);

//ということで、戻り値は残念ながらStringです
post(typeof(api.children[1]));

//InstとかEffectをアサインしてるとその数が出ます
post(api.getcount("devices"), "\n");

//デバイスのAPIに対して何かする
var path = "live_set tracks 0";
api.path = path;
for (var i=0; i<api.getcount(api.children[2]); i++) {
	api.path = path + " " + api.children[2] + " " + i;
	//何か処理
	post(api.getcount("parameters", "\n"));
	
	//こっちはダメ。pathのpropertyは「"」入った値になってる
	//api.path += " " + api.children[2] + " " + i;
}


ドキュメントに「Live objects have children identified by name. 」ってあるんですけど、LiveAPIとかその配列が返されると思ったのでちょっと残念。このままだと再帰的に使うときに面倒。

//ソングの再生
var start = function() {
	new LiveAPI(this.patcher, "live_set").call("start_playing");
	//こっちはダメ。goto()の戻り値が0。
	//new LiveAPI(this.patcher).goto("live_set").call("start_playing");
}

//ソングの停止
var stop = function() {
	new LiveAPI(this.patcher, "live_set").call("stop_playing");
}

//トラックのミュート
var mute = function(trackNumber) {
	new LiveAPI(this.patcher, "live_set", "tracks", trackNumber).set("mute", 1);
}