#BTH2018に参加しました

先日、10/20,21と東京ビックサイトで開催されたTOKYO BLOCKS HACKATHON (#BTH2018)に参加しました。
https://blockshackathon2018.peatix.com/

Maxアカウントメールにハッカソンしますってメールが来て知りました。
知ったのが開催の週の水曜日とか結構直前だったのでエイヤーって感じで参加しました。
一応ROLIという楽器を見たことがあったのと、個人的にも新しい楽器というものに少し興味があったので。

 

チームビルディング

心拍を使うアイデアの方がいて、とても興味があったので、なんとかかんとか仲間に入れてもらいました。
個人的には久々にMaxMSPを触って勉強したかったので、Maxを使ってBlocksをハックする部分を担当させていただきました。🙏

1日目終了時点でコンセプト的なものは決まっていたものの、具体的な作戦が決まっておらず、割と遅くまで残ってメンバー全員で作戦会議しました。
こういった経験は個人的にはとても貴重で楽しかった。

最終的には、
①AppleWatchから心拍を取って、
②JUCEで作ったアプリにOSCで心拍数を送り、AbletonLinkで共有、
③Maxで受け取ってBlocksへ表示
④別Maxで受け取ってリズムトラックのテンポへ反映・音を出力
⑤別Blocksを使って、変化するリズムトラックに合わせてリアルタイムに演奏
といった形。
僕が担当したのは③の部分。

AbletonLinkで受け取った拍からBPM計算して、数字を表示、拍に合わせてハートのイラストを伸縮(イメージ2枚を切り替え)ということをしています。

BlocksとMaxでの開発について

備忘録兼ねて技術的な話。

BlocksとMaxはBluetoothで接続します。
Blocksの電源入れて、Macのシステム環境設定からAudioMIDI設定からペアリングしました。
環境内にあるBluetooth端末が表示されているので、その中から手元のBlocksのIDと同じものを選択。
IDはBlocksの裏面に小さい文字で書いてありました。

MaxでFile > ShowPackageManagerからBlocksのパッケージをインストールすると、Maxからblocksのオブジェクトを作れるようになります。
blocks.button とか blocks.jit.matrixなどいろいろ用意されているのでヘルプから試してみると楽しい。

表示で重要なのはblocks.padというオブジェクト。
blocks.imageや、blocks.jit.matrixでBlocksのLEDを変化させることができるのですが、その際にblocks.padが必要になります。
Maxでプレゼンテーションモードにしたときに、このpadオブジェクトの上にblocks.jit.matrixなどサイズを合わせて配置する必要があり、これがズレるとBlocksの表示もズレてしまいます。

あとは、ヘルプにも書いてありますが、padオブジェクトの左上の三角をクリックしてオンにする必要があります。Max上で複数プロジェクトからblocksオブジェクトを操作している場合にどのオブジェクトを有効にするかはっきりさせるための操作のようです。

はじめ上の手順を踏んだはずにもかかわらずBlocks実機に表示されないことがありましたが、Max再起動やBluetooth接続し直しなどいろいろ見直すと無事繋がりました。

Max使ってBlocksで文字を表示する際にはjit.lcdを使うといいと@tatmosさんに教えていただきました。
Blocksが15×15のLEDで解像度が低いため、文字の表示はかなり厳しく、今回必要だった数字三桁程度の表示がギリギリな印象でした。
また、おそらくLED間は特にパーテーション的な区切りはなさそうで、黒字を出そうとすると、背景となる色に侵食されて可読性はほぼなしでした。
少しでも可読性確保するため、背景となるハートの画像は明るさを抑え、文字はできるだけ明るく、的なことを簡易的にしてました。

 

最終的なパッチはこんな感じ。(ハッカソン後、若干修正しました。)


heartbeat015.zip

 

感想

ハッカソンでは、メンバーにも恵まれて、なんだかんだ(謎の)特別賞をいただくことができました。
最後の発表前には、ネットワークが切断されてしまい、心臓が止まった状態となってしまいましたが、なんとかギリギリで動く状態に復帰でき、事なきを得ました。
ネットワーク改善のためうっかりMaxを再起動したので、いろんなパラメータの初期値が変わってしまってました。(後日修正しました)

久しぶりにMaxを触れて楽しかったと同時に、個人的な制作では使えても、仕事として利用することはなかなかないだろうなあと思ったり。

 

今回思い立ってハッカソンに参加させていただきましたが、とても学びが多かったです。
現場力とかつけるためにも、今後もハッカソンなどちょくちょく参加したいなあと思います。

 

ofxGLSLSandboxファイル監視して更新したら自動で反映

openFrameworksでshaderを使いこなせるように勉強中です。

いろいろ試すのに、yoppa先生製のofxGLSLSandboxってアドオンがとても便利そうです。( https://github.com/tado/ofxGLSLSandbox
GLSL Sandbox( http://glslsandbox.com/ )ってサイトで誰かが描いたシェーダーをコピペでポンで動くみたいです。

 

至極恐縮ですが、ofxGLSLSandboxを少し改造して、自動でファイル監視してcmd+sとかでファイルを更新したら自動で描画に反映されるようにしました。https://github.com/shiyuugohirao/ofxGLSLSandbox

取り急ぎ、OSX oF0.10.0でのみテストしました。

以下シェーダー勉強しながら思ったことをメモしておきます。📝

openFrameworksでshaderを書く際は、bin/dataフォルダにshaderフォルダを作って、そこに.fragや.vertを置いておくことが多いと思います。私の場合は。

雑な紹介ですが、
以下みたいにXcode上でファイルを紐付けると同じプロジェクトファイル内でshaderも編集できるのでいい感じでおすすめです。


srcで右クリックー> Add Files to ~~~


shaderフォルダなどをAdd


oFのプロジェクト内で .frag .vertなど編集できる!

他にもっといいやりかたあるかもだけど。

 


ついでにopennFrameworksでファイル更新の監視プログラムについても。

調べてみたらC++のfilesystemライブラリの中にファイル更新時の取得ができる関数がありました。

string fileName =  ofToDataPath("absolutePath.ooo", true);
long latestUpdate = std::filesystem::last_write_time(fileName);

ポイントは絶対パスを指定するところ。恐らくこうしたほうが確実に更新日時取得できるはず。
ファイルパスをうまく指定できないと、last_write_timeが実行されたときに、ファイルが見つからず落ちてしまうので、パスが正しいかどうかのチェックを入れてから実行するべき。
今回は、ofFile::doesFileExist(fileName)) で一応チェックしてから更新日時取得するようにしてます。

あとは、update()のなかで毎フレームチェックするか、重そうならif(ofGetFramerate()%10==0) みたいにして数フレームごとにチェックするかすればよき。

ちなみに、last_write_time の戻り値は 例えば 1234205545 みたいな整数が返ってくる。
どうやら「1970-01-01 00:00:00からの経過秒数で最終ファイル更新日時」とのこと。(参考)

今回は更新日時に変化があるかどうかだけ見れば良いので、整数のまま比較して〜ごにょり。

詳しくは、改造しましたソースコード を見ていただけると。
ぇぃゃーで公開しているので何かあればコメントいただけると🙏

shaderいっぱい試してがんばります👩‍🎨

http://glslsandbox.com/e#45998.0