Max for Liveのデバイス内でトラック番号を取得 : #maxforlive

スクリーンショット 2014-05-11 2.35.33

目的

Max for Live のデバイス .amxd 内で自信 が挿入されているトラック番号を、jsオブジェクトで取得してみます。

jsオブジェクトコード

//init
"use strict";
inlets = 1;
outlets = 1;
autowatch = 1;

function bang(){
    var api = new LiveAPI(this.patcher);
    api.path = "this_device";
    var pathStr = api.path;
    var paths = pathStr.split(" ");
    outlet(0,parseInt(paths[2]));
}

解説

LiveAPIのインスタンスへ”this_device”を指定する事で、api.pathはLive Object Modelにおける自信が挿入されている箇所の絶対パスを返します (例えば “live_set tracks 2 devices 1” になり、.amxdのパスが2番めのトラックの1番目のデバイスと分かる)。pathをスプリットしてトラック番号をゲットできました!

Max6 jsuiオブジェクト mgraphicsクラスを用いた描画メモ

スクリーンショット 2014-02-28 18.24.06

Max6のjsuiオブジェクトで背景透過のUIをつくるときに使えるmgraphicsの使い方をメモしておきます。

クラスリファレンス

http://max-javascript-reference.tim-schenk.de/symbols/#gsc.tab=0

初期化

//mgraphics initialize
mgraphics.init();
mgraphics.relative_coords = 1;
mgraphics.autofill = 0;

描画

function paint(){
mgraphics.set_source_rgba(1,0.5,0.5,1);
mgraphics.ellipse(0, 0, 10, 10); // y座標は、上向きが正の方向なので注意
mgraphics.fill();
}

paint関数の中じゃないと、mgraphics: no jgraphics context というエラーが出て描画できないようです。

描画命令

refresh();

枠線を消したい

cmd + i で出てくるインスペクタのborder を 0 に設定

Max6 jsuiオブジェクトで Task / MGraphics を用いて長押しボタンを実装してみた

スクリーンショット 2014-02-02 02.08.25某試作の開発にどうしても長押しボタンが必要だったのですが、MaxのUIには長押しに対応したtoggleのUIオブジェクト(長押しでON / OFF を切り替え)が無いようだったので、jsuiで実装してみました。

ポイント

  • jsオブジェクトに標準でついてくるTaskクラスのrepeat間隔(ms単位)の指定とコールバック関数を用いることで、長押しの判定を行う
  • 背景透過で描画するために、MGraphicsクラスで描画
  • MGraphicsクラスは、Quartz や Flash の Graphics に近いAPIなので取っ付きやすい
  • MGraphics Reference を見ながらpaintの部分を書き換えれば、見た目を変更可能
  • Sketchクラスを用いた描画では背景透過は非対応 → Forum

jsui – javascript


"use_strict";

outlets = 1;
setoutletassist(0,'"OFF":0,"OFF_DOWN":1,"ON":2,"ON_DOWN":3');

//mgraphics initialize
mgraphics.init( );
mgraphics.relative_coords = 1;
mgraphics.autofill = 0;

//Color
var offColor = [220/256,220/256,220/256,1.0];
var downColor = [0.7,0.7,0.7,1];
var onColor = [.99, .99, .99, 1.];

//State
var state = "OFF";
var states = {"OFF":0,"OFF_DOWN":1,"ON":2,"ON_DOWN":3};
var isSelected = false;

//Task
var tsk = new Task(longPressedHandler,this);
tsk.interval = 1000;

function longPressedHandler()
{
 if(arguments.callee.task.iterations > 1)
 {
 arguments.callee.task.cancel();
 isSelected = (isSelected) ? false : true ;
 out();
 }
}
longPressedHandler.local = 1;

function paint(){

if(states[state] == states["OFF"]){

mgraphics.set_source_rgba(offColor);

}else if(states[state] == states["ON"]){

mgraphics.set_source_rgba(onColor);

}else{
 mgraphics.set_source_rgba(downColor);
 }

 with(mgraphics){

ellipse(-1.0,1.0,2,2);
 fill()
 stroke();
 }
}
paint.local = 1;

function out(){

 outlet(0,states[state]);
}
out.local = 1;

//Mouse Event
function onclick(x,y,but,cmd,shift,capslock,option,ctrl)
{
 ondrag(x,y,but,cmd,shift,capslock,option,ctrl);
}
onclick.local = 1; //private

function ondrag(x,y,but,cmd,shift,capslock,option,ctrl)
{
 if(but == 1){

 if(isSelected == true){
 state = "ON_DOWN";
 }else{
 state = "OFF_DOWN";
 }

 tsk.repeat(2);

 }else{

 if(isSelected == true){

 state = "ON";
 }else{
 state = "OFF";
 }

 tsk.cancel();
 }

mgraphics.redraw()
 out();
}
ondrag.local = 1; //private

wordpressにコード貼るとインデントや改行が総崩れするのどうにかしたい!WEB系のコーディングをしたことない独学javascriptすぎるので、もうちょっとお作法を勉強したい。あとWordpressレイアウトもう少しまともにしたいんだけど、どうしたらいいものか

値の差分を出力するMax6のjsオブジェクト


"use_strict"

autowatch = 1;
inlets = 1;
autowatch = 1;

var _preValue = null;

function msg_int(value){

	msg_float(value);
}

function msg_float(value){

	if(_preValue != null){
		
		var outValue = value - _preValue;
		outlet(0,outValue);
	}
	
	_preValue = value;
	
}

function clear(){
	
	_preValue = null;
}

どんどん入力される値と値の差分を取得できます。たとえば速度を計算したりする時に有効です。clearで区切れるのもポイントです。

動的に生成したパッチを繋ぐサンプル2:Max6,JavaScript

スクリーンショット 2014-01-26 17.53.54

大量のパッチを繋ぐの面倒くさい!のでjsパッチで書いてみました。[generate 200]を押すと、一気に200個のcounterオブジェクトが生成され、かつrouterオブジェクトに繋ぐ事が可能です。function patch の内容を変えて使ってみてください。ようやくjsパッチのお作法が掴めてきたかなという感じです。JSパッチによる自動生成は、失敗するとパッチが全部見えなくなったり、Maxが落ちたりするので、気をつけてご利用ください。

JSパッチのメモ

  • this は jsthis のインスタンス
  • jsthis は maxobject を継承してる
  • patcher は maxobject を継承している。maxobjectのコンテナな扱い。
  • maxobject は、それを含んでいるpatcherへの参照を保持してるので辿れる。
"use_strict"

autowatch = 1;
inlets = 1;
outlets = 0;

var p = this.patcher;
var generatedObjects = [];
var GENERATE_CLASS_NAME = "counter"
var CONNECT_OBJECT_CLASS_NAME = "route";

function generate(num){

 if(num <= 0) return;

 var windWidth = p.wind.size[0];
 var windHeight = p.wind.size[1];

 var rect = this.box.rect;
 var width = rect[2] - rect[0];
 var height = rect[3] - rect[1];

 var x = rect[0];
 var y = rect[1];

 for(var index = 0 ; index < num ; index++){

 var numRow = Math.floor(windWidth / width);
 var column = Math.floor(index / numRow);
 post("numRow:" + numRow);
 var row = index % numRow;
 generatedObjects.push(p.newdefault(width * row,y + height * (2 * (1 + column)),GENERATE_CLASS_NAME));
 }

 patch()
}

function remove(){

 for ( var index = generatedObjects.length-1; index >= 0; index--)
 {
 p.remove(generatedObjects[index]);
 }

 generatedObjects = [];
}

function patch(){

//find object for outlet
 var connectOutletObject = findObjectFromClass(CONNECT_OBJECT_CLASS_NAME);
 post("find:" + connectOutletObject.maxclass);
 post();

 //connecting
 for(var index = 0 ; index < generatedObjects.length ; index++){

 if(generatedObjects[index].valid == 1){

 p.connect(connectOutletObject,0,generatedObjects[index],0);
 }
 }
}
patch.local = 1;
//varname tsu kau
function findObjectFromClass(className){

 post("objectCount:" + p.count);
 post();

 var object = p.firstobject;

 while(object){

 post(object.maxclass);
 post();

 if(object.maxclass == className){

 return object;
 }

 object = object.nextobject;
 }

 return nil;
}
findObjectFromClass.local = 1;

JSオブジェクトのエディタで、文字カラーは無視しても大丈夫:Max/MSP, JavaScript

スクリーンショット 2013-12-18 03.34.00

Max6のjsオブジェクトでスラッシュとバックスラッシュの文字列置換を、正規表現で書きました。その時に少し困った事があったのでメモ。


tempStr = tempStr.replace(/\//g,"\\");

\で、その後に続く特殊文字(例えばスラッシュ)のもつ特別な機能を無効にできるのですが、エディタで見るとスラッシュが2回でてくる所で、コメントアウトの緑色に変わってしまっています。本来ならバックスラッシュの後ろのスラッシュは、コメントアウトする機能は無いはずです。

当然動作させると問題なく スラッシュ → バックスラッシュ と置換されたので、エディタの色付けが間違っているようです。エディタは、jsの文法を解釈して色つけてるわけではないのですね。皆様も惑わされないようにお気をつけて!

Max から Javascript の Date クラスを使ってみる:Cycling’74 Max/MSP, JavaScript

スクリーンショット 2013-10-06 21.59.41

Maxで現在の年・月・日時等の取得の仕方がわからなかったのでjsオブジェクトで作成してみました。

Date.js


"use_strict";
autowatch = 1;


function anything(){
    var date = new Date();
    outlet(0,messagename,date[messagename]());
}

Javascriptには元々Dateクラスが容易されているので、それを利用したいです。そこでanythingやmessagenameプロパティを使い、dateクラスのファンクションを動的に呼び出しております。

ひとまずjsのクラスをMaxパッチに公開する事ができました。

JSオブジェクトにて、list関数を呼び出す場合は、引数listの1つ目の要素は数値にする:Cycling’74 Max, JavaScript

スクリーンショット 2013-09-24 23.45.53

jsオブジェクトで1つハマりました。

デフォルトで使えるlist関数を呼びだそうとしても、どうしてもanything関数しか呼んでくれない。どうしてだと調べてみると、jsパッチでlist関数を呼ぶには、引数listの1つ目の要素は数値にする必要があったようです。先頭が文字列のリストは、単なるメッセージ扱いになってしまうみたいです。たぶんmessageによる関数呼び出しと区別つかないから仕方ない事だと思われます。皆様もお気をつけなすって!

jsオブジェクト コード

</pre>
autowatch = 1;
inlets = 1;

function list(){

post("list:" + arrayfromargs(messagename,arguments));
 post();
}

function anything(){

 post("anything:" + arrayfromargs(messagename,arguments));
 post();
}
<pre>

JavaScript in Max の Templete : Max/MSP, JavaScript

"use_strict";
inlets = 2;
outlets = 1;
autowatch = 1;
 
var foo = 100;
declareattribute("foo",null,null,1);


function loadbang(){
     	
	out(messagename);
}


function bang(){

	if(inlet == 0){

		out(messagename);		
	}
	
	foo++;
	post("foo: " + foo);
	post();
}


function msg_int(num){

	out(num);
}

function msg_float(num){

	out(num);
}

function message(){
	
  var a = arrayfromargs(messagename,arguments);

  out(a);	
	
}

function list(){

  var a = arrayfromargs(messagename,arguments);

  out(a);
};

function anything()
{
  var a = arrayfromargs(messagename,arguments);

  out(a);
}


//////////////////////////////////////////////////////////////////////////////////////////

function init(){
		
	post("jsarguments:");	
	for(var i = 0 ; i < jsarguments.length ; i++){
	
		post(jsarguments[i]);
		post();
	}
}


function out(){
		
	post(messagename + " :");
	
	for(var i = 0 ; i < arguments.length ; i++){

		post(arguments[i] + " ");
		outlet(0,arguments[i]);
	}
	
	post();
}


//////////////////////////////////////////////////////////////////////////////////////////

function save(){
	
	post("save");
	post();
	
	//When the js object containing this script is recreated, the function numchairs will be called
	embedmessage("init");
}


//Assistance for Inlet
function describe_inlet(num){
	
	assist("this is inlet number : " + num,num);
}
setinletassist(-1,describe_inlet);


//Assistance for Outlet
function describe_outlet(num){
	assist("this is outlet number : " + num,num);
}
setoutletassist(-1,describe_outlet);

jsオブジェクト内で記述する JavaScript in Max の書き方を忘れがちなので、自分用にTempleteをつくりました。jsオブジェクトをダブルクリックで開くエディタにコピペして、ご利用ください。