jit.leapmotion リープモーションのステレオ赤外線カメラ画像取得できるExternalオブジェクト #maxmsp #jitter
Jitter Externalの勉強がてらLeap Motionのステレオ赤外線カメラ画像を取得できるExternalオブジェクトを書いてみました。Mac OSX Yosemite環境にて開発してるので、それ以外で動くかは謎です。
ダウンロード
Cycling74 Max Tool。パッケージにまとめてあるので、Application/Max6.1/packages 以下に落としたファイルを置けば使えると思います。
注意点
- Leap Motionをインストールするとメニューバーに出てくるLeap Motionコントロールパネルにて、イメージを許可するにチェックをしないと動かないです。
- 解像度は640×240で固定。Leap Motion SDKの仕様で、動作が重くなると自動的に640×120に変更されてしまう事があるのですが、その場合は縦に引き伸ばしています。
Max External開発 simplemaxオブジェクトのサンプルコードを読み解く #maxmsp
MaxでもopenFrameworksみたいにCやC++の資産を活用したい!aka.leapmotionを参考にLeapMotion v2.のオブジェクトも開発してるので、そのうち公開したい!ということで、久しぶりにMax External勉強してます。
今回は、MaxSDKをダウンロードすると付いて来るXcodeプロジェクトサンプルから、simplemaxのコードを読んでみます。ちなみに Yosemite / Xcode6でやってます。
インクルード
#include "ext.h" // standard Max include, always required #include "ext_obex.h" // required for new style Max object
この2つは大抵のオブジェクトでインクルードします。C言語の入門書におまじないって書いてあるやつですね。
Maxオブジェクトの構造体定義
////////////////////////// object struct typedef struct _simplemax { t_object ob; // the object itself (must be first) } t_simplemax;
プライベート変数やプロキシを利用する場合は、構造体メンバとして定義する必要があるそうです。MaxAPI Document参照。
関数プロトタイプ宣言
///////////////////////// function prototypes //// standard set void *simplemax_new(t_symbol *s, long argc, t_atom *argv); void simplemax_free(t_simplemax *x); void simplemax_assist(t_simplemax *x, void *b, long m, long a, char *s);
(Max側から呼び出したい)登録したいメソッドは、ここでプロトタイプ宣言しといてmain関数で登録する。maxsimpleがインスタンス化する時に必要なnewと解放する(消す)時に必要なfreeは必須。assist関数は、必ず必要なものでは無いようです。
クラスの登録
//////////////////////// global class pointer variable void *simplemax_class; int C74_EXPORT main(void) { // object initialization, NEW STYLE t_class *c; c = class_new("simplemax", (method)simplemax_new, (method)simplemax_free, (long)sizeof(t_simplemax), 0L /* leave NULL!! */, A_GIMME, 0); /* you CAN'T call this from the patcher */ class_addmethod(c, (method)simplemax_assist,"assist",A_CANT, 0); class_register(CLASS_BOX, c); /* CLASS_NOBOX */ simplemax_class = c; post("I am the simplemax object"); return 0; }
C74_EXPORTは、おまじないでMaxからこのmain関数が呼べるようになるマクロのようです。t_class *cのポインタにclass_newでクラスを生成しています。simplemax_new / simplemax_free は、プロトタイプ宣言してあるのでここで関数ポインタを渡してクラスメソッドとして登録していますね。さらにそのclassインスタンスにsimplemax_assistメソッドを登録しています。このメソッドは、inletやoutletにマウスポインタを合わせるとポップアップで説明がでてくるタイプのメソッド。class_registerでCLASS_BOXへクラスの登録をすることでMaxからsimplemaxクラスが探せるようになります。このmain関数で一度作成し登録したクラスは、グローバル変数のsimplemax_classにポインタを保存しておくみたい。たぶんMax起動時に一度だけこのMain関数が呼ばれてクラスだけ登録しておいて、simplemaxがインスタンス化される場合は使いまわしている。
メソッドの実装
void *simplemax_new(t_symbol *s, long argc, t_atom *argv) { t_simplemax *x = NULL; long i; // object instantiation, NEW STYLE if ((x = (t_simplemax *)object_alloc(simplemax_class))) { object_post((t_object *)x, "a new %s object was instantiated: %p", s->s_name, x); object_post((t_object *)x, "it has %ld arguments", argc); for (i = 0; i < argc; i++) { if ((argv + i)->a_type == A_LONG) { object_post((t_object *)x, "arg %ld: long (%ld)", i, atom_getlong(argv+i)); } else if ((argv + i)->a_type == A_FLOAT) { object_post((t_object *)x, "arg %ld: float (%f)", i, atom_getfloat(argv+i)); } else if ((argv + i)->a_type == A_SYM) { object_post((t_object *)x, "arg %ld: symbol (%s)", i, atom_getsym(argv+i)->s_name); } else { object_error((t_object *)x, "forbidden argument"); } } } return (x); } void simplemax_free(t_simplemax *x) { ; } void simplemax_assist(t_simplemax *x, void *b, long m, long a, char *s) { if (m == ASSIST_INLET) { // inlet sprintf(s, "I am inlet %ld", a); } else { // outlet sprintf(s, "I am outlet %ld", a); } }
simplemax_newはオブジェクトがインスタンス化される場合に呼ばれる。このサンプルは、渡された引数をひたすらMaxWindowにポストしてくれてる。argvにアーギュメントがargc個入っていて、t_atom型はa_typeメンバをみると型が書いてあるよう。atom型はゲット関数が用意されている。メンバ変数などの初期化は、ここに書けば良さそう。
simplemax_freeの方は特に何もしてないけど、インスタンス化したオブジェクト自体は裏で勝手に開放してくれているのかな?。自分でインスタンス化したオブジェクトがあればここで開放したい。simplemax_assistは、アシスト表示を使うときのテンプレートのようです。
メソッド追加(余談)
void simplemax_bang(t_simplemax*x) { post("bang"); } class_addmethod(c,(method)simplemax_bang,"bang", A_SYM,0);
このsimplemaxオブジェクトは、どんなメッセージにも反応しないサンプルとしてはかなり駄目な子です。そこでメソッドを定義して、クラスに登録してみたらちゃんと動きました。トップ絵はbangを送って動作させてる様子です。C言語だけどオブジェクト思考の匂いがする。
Gen codebox内でfor文を使った平滑化フィルター #maxmsp #jitter
Codebox / genexpr
size = 10; offset = floor(size/2); scale = 1/(dim+1); pix = 0; for(x = 0 ; x < size ; x = x + 1){ for(y = 0 ; y < size ; y = y+1){ delta = (vec(x,y) - offset) * scale; pix = pix + sample(in1,norm + delta,boundmode="clamp")/(size*size); } } out1 = pix;
サンプルパッチ
----------begin_max5_patcher---------- 2564.3oc6bkziaibE9r5eEETBP5drFYVUwEw3X.m3rcI.AAAIHv8fFTjkjoM 2FRp1cGCeXbirAjKIHYtFDLmBliA4PPbv7iQwCxs4uPpERJRItI0TzRwsMZx lUUrp26qdupdKE6WdxfgS8uhDMD7MAOALXvKOYv.dQrBFj77fgtFWY5XDwa1 PSeWWhW7vQh5hIWEyKeNwCX5aQnuM3buY9ge4m9aV95+3+4e+EK+jOa4m7Wd 6+7u+k+q+va+8e5xa9yKe8ms7lOe4q+hk27lzNxw1iX5uvi2anjBCLhMeps2 7KBIlwBpTVcrzH.FwtJqqvtoJMVB7QIuxrv4SYsjVVRI1VbBze5y9PHLc3l4 6E6Y3R3U8sCsMbRqwagqsmCIlytvbMOx9WxaNRNqqos0eQbZikXE9pSNgcYT KgSOxKnD1FnY.3RKxk221KXQFTWFXHIMVYD.onwtA0XLM.AyAG4Yd0lYdA2D ec.QL.CGNh9SVu0H1.wUfMElQIgIHRBjP6CaGxkjvHaeubc8fgFAA4JdPtWg giOym2QpixJx1STDLqnPxk1ouudVoFgTnLlhiKBEnvUSTGJpjN2cR5qlhyHg blNWzah3lTNoN5r7bGeymS3nsTZg9ADO5TXHIhpwXDmPEYUaQlYrvI9hB.HZ bo0OyvjT4KW5b4fgyCss78XDQg2jUb5v8D.jyZrqqXFdK7LBJ4kin7whnoFg LTcpCI2bKU7022oXUYSjTs.COaWiXRrsfXQRYcpsaPnsPyOqLhmAsOdZjYnu iSgtRTykkTCUkw1j7Baq3mVXI.VMzlaGjNELLCirrmShhKVVrw7nhkTXUx7B g4UuKTdcp4EU0ohgg4qnD0bEtdMjtnGSYWack70UzQv78W0BHkqvWnWKSguF k9RT7goUvWXLQAq6QwXfoCwnIfDp.ygjhsRpEIw2BjTPP++LbhkPB3D1R3T9 8T3jtE.cgTK.c6L5sFPUjjPHUQguotTy56Zu+ou2hUMSwwVur4j2+fwsRvLY anVKWhQu+AngzgjvMd2wNJFvMfm8asCZkD2jaFZuMaLwsoeTsPLdWfXbGBwb RoUflrvoGkzqUAYvcUbqFYpb0j5WL2twNDHDCWCHgNWkDgUEdC1DTnLrMpVq 4b6gBuhjU2JlEh2yb6J+lXwvnB2D3LBq9xggH+EgloxhoJ3.XAdh5CSrsWla jOY0tVfhL+SssrJ51lv2Xq.epWVIDHDg4Kiij4vHTJ6ohCpcDyaKqr3az3T8 9iSk6BNECguS4To1vo3ciSUzEr1D9MUormNXYTXKYzdflQsjlUNXH4RT8q.l 0NbnYsVRyP7gCMKeDRy3iOwYXKI4RTUeWQyslj6JICvGcR9fTOLx3Rh0Ezgf ZezEFwwg1SoNfDsd70usgRt4PUuEwWsThnlAupActi+TCmjLJj8tkDF2SVAh aY5YbIQQFyIajelKEgZF70gMmclDKNzvbe6zKO4LXocI4LkmXFz1jXF3NfJK n1CunEokZhHRA5p0kVJbKxIWfQHs7XR3Ehf+mSxYSTgkIgQcWlqvojbLwMwN qgeepz6O01k.9geWvxW+4Ku4ut7l+1W8le6a+0+p+6e5e7Uu42wF7QrKzF7i C8A+bxTSCWvi0QRfuFJq1ejg20OlV9OyNLdggSZyN8m7C9Nm0Xi9EeiGO8wg qZ22Kv2j1tghkH5HAcSG+HRMS0vj4XEt2XxnZkwUNhjwqBP3YDqZ7.g0yiGR 0gGpGQvAaqkE1YIq22744UjJCHR7yZhvYDXsqAjkXfZfB1LvEY41CmsOPqwn sRqOswL9lSKV1tC6Pwn4j3zfDVmzjtrHjqboIsZ0tPGS6fTwwd3Y1wimGZLk 40pDPSUB7nEd1e7BB.17ZPHjHRfX45D0z2kEgnz0EtFTiqtpyNODcnrzrENN TyuHDu5sGQiKEonqMFof0kTGAlnUqD0wz50w9ym6PZl6UVw8IxKRUv8p6r0G 0Ker2zdB.TqvqAAz4Gbk7HfX+5JWUVaGl+mZ3MuB.PZWV.93+.CoJrBPdxcG Xn6NvPcapPlH1pCI2tTfM4.MuO0jO0HhCn34anZb.h4amIiWeY8MVX6Vj7T9 5a0m7TTUIOEUSxSQ8Cd9bx0sDLg7UsDoTnNv71bXyRbUeyasKarsFbk6qz10 1jHL4nKBln6Bf4wX.LqwQqWX6Y4+BPxsGMKhEUO5twzo4GwnVlgK.LyGro9g VjP.j0HCCw8rFusGfegc3pH8LqPwJbyPw3JN25S1UyP2Re0PcnuZEiWRYNsp l3M1Jb.pTqCIxcX7h1J9eiXgHjG1kvgvj6lEDMuVnQbPRkEFZNgiIXkJbQoG 9jF5Rwh5h6gy3KssH9ANFdjLsRiEw9TifsMYZkwgFdQy7Ccuf4gPL.0bPQRP QbhIhUHZAk60fhzeHZ.i3ZBivZbvQb1vqBhz2QDZtyELhh41XWgRG0dFC0Dg gfEXX92tkv4Xk0bN1z2QL7Og5Ul9nbWf24E8cdQ2RGgR9fDa04HUjkRErvKZ Uk8i6i6xwZtNOaJdDTsDjA25sGBfRO37vy87mMisYwCAyb78COkU48QmwqJx zvg2x6epks68fhRoKZRKS7xren63bJuDvC.WA9V.d2y90GR+4d.3Yuj2xXwU VquNo0Wup0rht9dq01yisHNwFzpN8Rh4oWM55y.eHPPvmA9..m9dPZaEzE65 8.QFtANjSs8finqS4RKg2SilRs.0xkBDO77gT4.2fyGd18477GvtbVRm8J1s WkxfT7DJ54GzSg0v1C.a2QBWV7wF1THM1SexW6j218zQsmNhsDDkEgFSDdn5 Pws36S51q5JcnETB46BJQma.ZHwi45rvb9F84AimHh8FtNSQOF8GtBTJFLk+ eRnQsGyjD3Q78FpoUG5ncKPm0uKHqN.xj6NH6icIwg9.nZivERkCWpJ0FUgt MGensJvB6i77lv6qRta07txwVFdc7MrDxlMv9PX1eYLpwq+tcpGtum5aNlZI 9yKmbpYpk6wGJQSi+F4fC9XTb+eA5r9tnIXzleJC42UrhcN0KzlM10bycL2X tpsTCrETiZuQMrSIUyfiRCzyZe2MXIwWXjl3r+I9qRC+oUCT2wAx6AN.gDA+ BhywA7m1Cb.deLGHKxWIVVI2g.q3SHXxwwTI6o8A2ozEbW2QOp6CwE4jX3IM FkShm+3d.RYeyPnNlEzkGCUo+SlY0s3OT.zsMTlfo6dTZQ8izCmMfMvqv9a8 RckCpMSzaA0.k6MxYRKHGTuQMZsfZlzqTC9fhZf2VAm0VBQSdLcsALlcPJkv 4Vbf+zdXwg1nK1eB+xsYmEX+ME2F6hz5MpA2F6dWyRn8pgusY0ATOZHdajdP 8mYRHkCKoYXavm0DxdW6F2tNaI73csDTyHj0RL8ZIkdyDRWUxnoiyqN4+AH0 luRB -----------end_max5_patcher-----------
東京デザイナーズウィーク2014にて、音楽をより楽しむための照明を出展します
ゼロバイゼロは、10/25〜11/3に開催される東京デザイナーズウィーク Creative Life展にて、現在開発中の、音楽をより楽しんでいただくための照明プロトタイプを展示いたします。
ぜひご来場ください!
会期中の祝祭日および、10/30、31日は説明員がいる予定です。このタイミングでぜひ!
東京デザイナーズウィーク
クリエイティブライフ展会期 10月25日(土)ー11月3日(月・祝) 10日間
時間 11:00-21:00(最終日:20:00まで)
会場 〒160-0013 東京都新宿区霞ヶ丘町2-3
明治神宮外苑絵画館前(中央会場)、都内サテライト会場
来場者数 12万人(予定)
Tokyo Designers Week 2014
http://www.tdwa.com/
M3-2014秋に参加します
音系メディアミックス同人即売会「M3-2014秋」に参加します。
最新3rd Album「RAPiD MODE」、旧譜2点を頒布予定です。
当日の出展スペースは”第一展示場 D-06a”となります。
会場でお待ちしています!
【開催日時】
2014年10月26日(日) 11:00~15:30
【会場】
東京流通センター(TRC)
【入場料】
当日 1,000円 (当日会場で販売) 前売 1,050円 ※いずれもカタログ代含む
イベントの詳細はこちらの公式サイトでチェック!
Recent entries
- jit.gl.gridshape の matrixoutput についてのメモ #max8
- jit.gl.pix で簡易モーションブラー #max8 #jitter
- jit.gl.pix で Gold Noise #max8 #jitter
- Gen で配列をつくる検討 #Max8
- Package Managerで配布されているease objectを使いやすくしてイージング #max8
- Node for Max を用いて、定形外のUDPデータを受信 #Max8 #n4m
- 平ハウス物語 – 山田尚子監督作品 非公式ファンイベント
- The Splendid Expression – GITADORA×NOSTALGIA
- ghost in my place【from DEEMO II】
- EP “Boys O’Clock”
- 7th Album “多次元宇宙論”
- LEON.jpのWEB特集「大人のいい時間」にAromが紹介されました。
- 音できらめくキャンドルライト Arom(第2世代)発売開始
- EP “Strange Story”
- 都市の呼吸【from Cytus II】