SuperColliderを使って(意識の高い)キックをWOMBのスピーカーで流す

先日開催されたSuperCollider Workshop at WOMB LOUNGEに参加してきました。
内容はかなり濃く、SuperColliderで出来ることを筆頭に外部アプリケーションとの連携や通信を使った講義もあり充実した内容になっていました。
音を鳴らすことから始まり、音の加工やシンセを作りループで再生、シーケンスを作ったりと駆け足ではありましたが出来ることを洗いながらお腹いっぱいな内容でした。
OSCを使ったProcessingやMax/MSPとの通信は初心者にとってはかなり踏み込んだ話しだったのではないかと感じています。
個人的にはインスタレーションやメディアアートと言った分野で非常に有効な手段であると考えているのでワクワクしながら講義をうけていました。

 

五日目最終日には受講者によるSuperColliderを使った発表がありもちろん私も参加しました。
皆さんそれぞれSuperColliderを使ったユニークな音や曲を発表し、幅の広い発表会だったと感じています。
そんな中、私は「どうやったら面白い発表が少しでも出来るだろうか?」 と考え、
せっかくなら普段鳴らすことのできないクラブのスピーカーでキックを鳴らそう!と思い立ったわけです。

 

なのでキックしか作りませんでした。


(
  SynthDef(\SinKick, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      SinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 1)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

  SynthDef(\SawKick, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      Saw.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 1)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

  SynthDef(\FSinKick, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 1)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

  SynthDef(\SquareKick, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 1, 1)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//distortion

  SynthDef(\FSinKick_dist, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 1).distort * Line.kr(2, 0, 0.9)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+noise

  SynthDef(\FSinKick_noise, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 1).distort * Line.kr(2, 0, 0.9)
      + LFNoise0.ar(freq * 6, 0.01, amp)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+ saw

  SynthDef(\FSinKick_saw, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.5).distort * Line.kr(2, 0, 0.9)
      + Saw.ar(freq * 2, 0.0025, 0.25)
      + LFNoise0.ar(freq * 6, 0.01, amp)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+ square

  SynthDef(\FSinKick_square, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.5).distort * Line.kr(2, 0, 0.9)
      + Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 0.03, 0.5)
      + Saw.ar(freq * 2, 0.0025, 0.25)
      + LFNoise0.ar(freq * 6, 0.01, amp)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+ high

  SynthDef(\FSinKick_high, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.5).distort * Line.kr(2, 0, 0.9)
      + Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 0.03, 0.1)
      + Saw.ar(freq * 2, 0.0025, 0.25)
      + LFNoise0.ar(freq * 8, 0.01, 0.05)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+ high++

  SynthDef(\FSinKick_high_saw, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.5).distort * Line.kr(2, 0, 0.9)
      + Saw.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.2, 2), 0.5, 0.05).distort * Line.kr(-2, 0, 0.5)
      + Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 0.03, 0.1)
      + Saw.ar(freq * 2, 0.0025, 0.25)
      + LFNoise0.ar(freq * 8, 0.01, 0.05)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+ release

  SynthDef(\FSinKick_release, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.5).distort * Line.kr(2, 0, 0.9)
      + Saw.ar(EnvGen.kr(Env.adsr(0, 0.5, 0, 0, 1, -20), gate, freq, 0, 0.2, 2), 0.5, 0.005).distort * Line.kr(-2, 0, 0.5)
      + Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 0.03, 0.1)
      + Saw.ar(freq * 2, 0.0025, 0.25)
      + LFNoise0.ar(freq * 8, 0.01, 0.05)
      * EnvGen.kr(Env.perc(0, 0.3, 1, 8));
    );
    Out.ar(0, source);
  }).store;

//+ noise

  SynthDef(\FSinKick_noise2, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.5).distort * Line.kr(2, 0, 0.9)
      + Saw.ar(EnvGen.kr(Env.adsr(0, 0.5, 0, 0, 1, -20), gate, freq, 0, 0.2, 2), 0.5, 0.005).distort * Line.kr(-2, 0, 0.5)
      + Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 0.03, 0.1)
      + LFNoise0.ar(EnvGen.kr(Env.perc(0, 20, 1, 100)), 1, 1)
      * EnvGen.kr(Env.perc(0, 0.1, 1, 12));
    );
    Out.ar(0, source);
  }).store;

//+ Kick!!!!!!

  SynthDef(\FSinKick_last, {
    arg freq = 440, gate = 0.1, amp = 0.5, source, pan = 0.0;
    source = Pan2.ar(
      FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 1, 0.1).distort * Line.kr(2, 0, 0.9)
      + FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq / 2, 0, 0.5, 2), 1, 0.1).distort * Line.kr(2, 0, 0.9)
      + FSinOsc.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq * 2, 0, 0.5, 2), 1, 0.05).distort * Line.kr(2, 0, 0.9)
      + Saw.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.2, 2), 0.5, 0.05).distort * Line.kr(-2, 0, 0.5)
      + Pulse.ar(EnvGen.kr(Env.adsr(0, 1, 0, 0, 1, -20), gate, freq, 0, 0.5, 2), 0.5, 0.03, 0.1)
      + Saw.ar(freq * 2, 0.0025, 0.25)
      + LFNoise0.ar(freq * 8, 0.005, 0.05)
      * EnvGen.kr(Env.perc(0, 0.12, 1, 8));
    );
    Out.ar(0, source);
  }).store;
)

 

~sinKick = Synth(\SinKick);
~sawKick = Synth(\SawKick);
~fsinKick = Synth(\FSinKick);
~aquareKick = Synth(\SquareKick);
~distKick = Synth(\FSinKick_dist);
~noiseKick = Synth(\FSinKick_noise);
~saw2Kick = Synth(\FSinKick_saw);
~square2Kick = Synth(\FSinKick_square);
~highKick = Synth(\FSinKick_high);
~highSawKick = Synth(\FSinKick_high_saw);
~releaseKick = Synth(\FSinKick_release);
~noise2Kick = Synth(\FSinKick_noise2);
~lastKick = Synth(\FSinKick_last);

 

SinやSawでとりあえずそれっぽい音を作り、それに重ねていく形でコーディング。
ただSuperColliderの知識が足りないので、高音域にSawやNoiseを重ねてなんとなくで作るという形で進めました。
抜けが悪いから高音域、中音域に追加しつつ余韻が足りないからReleaseを伸ばしたりと、DAWであればサンプリングしたキックをEQで加工していくところをコードで書くことがとても難しく、どうやったら再現できるのだろうかというところはとても楽しく作ることができました。

ただ満足にいくものが出来ていないので、原理や出力、SuperColliderの機能を理解してまた挑みたいと思ってます。

※発表の最後に、参考としてみんな大好きVengeanceのキックを鳴らしましたがやっぱり良かったです。

Titanium Mobile 勉強会に参加してきました

どうもこんにちは!みなさま iPhone アプリしてますか?!僕は未だにガラケーユーザです (涙) iPhone 5 が出たら本気をだそうかと思ってます。

そんなわけで 2/25 に行われた株式会社コンテンツワンさん主催の勉強会 Titanium Mobileで始めるiPhone / Androidアプリ開発 に参加してきました。

下書きのまま放置してしまい今更感もあるのですが、会場で取ったメモにちょっと加筆したものを公開します。


  • 講師 masuidrive (blog)
  • Titanium Mobie の実績
    • WikiWalker (iPhone)
      • 位置情報からゆかりの地を Wikipedia から検索してくれる
    • なごや乗換ブラウザ (iPhone)
      • 乗り換え案内アプリ
    • Android 映画情報「myシアター」 (Android)
      • もともとは iPhone 向けに Objective-C で書かれた
      • Android 版を製作するに当たって Titanium Mobile で書かれる (3 週間で完成)
    • TOKINOWA
      • ちょっとおしゃれな時計アプリ
    • はてなカウンティング
      • はてな謹製
    • MogSnap: 食べ物の写真を投稿
      • 食べ物の写真を撮影して投稿
      • ソーシャルゲームっぽい
      • 相手に食べたいなあと同調してもらえるとポイントアップ
      • アニメーションがリッチ
    • AKB前田敦子 Maeda-1 グランプリ (Android)
    • Follow me now (iPhoneAndroid)
      • 位置情報を使ってアプリを起動しているユーザ同士をフォローできる
      • masuidrive 謹製
      • 本当は今日のデモ向けにつくっていたが作り込みしていって話しきれない量になってしまった
      • 近々オープンソース化する予定
  • Titanium Developer
    • JavaScript で iPhone/Android クロス開発
    • IDE じゃないよ
    • Aptana 社買収して Full feature IDE を 3 月後半リリース予定
    • 今は printf デバッグぐらいしかできない。今後 IDE にデバッガが搭載される予定 (時期未定)
    • 原則 iPhone SDK の Beta 版には対応しない
    • SDK 複数バージョン入れてる場合は xcode-select で最新版を選んで
    • Android SDK Tools R8 以降では adb をコピー
    • C/Java で書かれたモジュールをロードする場合 manifest, tiapp.xml を編集
  • JavaScript を Objective-C/Java にトランスレートしているわけではなくインタプリタで実行している
    • OS の機能を JavaScript から簡単に呼び出せるところが Titanium のコアとなる技術
    • iPhone 版のインタプリタは WebKit 由来の JavaScriptCore (規約避けの意味もあった)
    • Android のインタプリタは Rhino を搭載
  • Titanium SDK 1.6
    • つい先日出た
    • 1.5 以前は iPhone に比べると Android のサポートはいまいちだった
    • Titanium SDK 1.6 から Android サポートがかなり良くなった、おすすめ
  • MogSnap の事例
    • 99% は JavaScript のコード
    • 残りは JPEG の圧縮率を変える処理 (Objctive-C で 10 行ぐらいのコード)
    • アニメーション・エフェクトは 2D Transform, 3D Transform が使える
    • Ti.UI.createAnimation(); / Ti.UI.create2DMatrix();
    • Ti.UI.createView() div タグみたいなやつ
  • Titanium Mobile の弱点
    • サンプル不足
      • リファレンスは比較的充実しているがチュートリアルがあまり無い
      • デモアプリの KitchenSink のコードが参考になる
    • リアルタイム性の高いものは厳しい
      • ゲームなどで大量のパーティクル飛ばすとか将棋の思考ルーチンとか
    • 画像処理 API が無かったり
      • ない部分、苦手な部分は Java/Objective-C で Module として書けば OK
      • masuidrive 氏が以前作ったコミックビュアーは通信部分などは JavaScript, UI は Objective-C で書いた
      • モジュールとして作れば JavaScript から Objective-C を呼び出したりその逆も出来る
  • 開発スタイル
    • 1 Window = 1 Source: Window 間の連携は苦手。複数人開発だと有利。変数の共有は Ti.App で。
      • Ti.UI.createWindow({ title: “..”, url: “hoge.js” }); で hoge.js に書いた Window のコードを呼び出し
    • 1 Project = 1 Source: 変数の共有や Window 間の連携が得意。複数人開発には向かない。
    • 併用も出来るっぽい?
  • 通信系
    • XHR のクローンとして Ti.Network.HTTPClient というものが用意されている
    • YQL 標準搭載 (XML -> JSON の変換も容易)
    • 余談: Echofon とかの引っ張ってリロードするやつは Pull to Refresh というらしい
  • Android と iPhone ではアイコンのサイズが違う
    • それぞれ専用で作ってあげると良い
    • フリーの Android アイコン配布サイト Android Icons
  • ローカルストレージ
    • SQL Database (SQLIte)
    • ファイルにも保存できる
  • コーティングインジケータを通信していない時でも回したい → モジュールを書く
  • RouteMe オフラインで地図見れる
  • AirPrint 対応したい → Titanium でサポートしていない → モジュールを書く
  • 足りない機能はモジュールを書く
  • Modern JavaScript
    • Titanium Mobile は JavaScript 1.6 が使える
    • CommonJS
      • hoge.js: exports.foo = function() { … }
      • var hoge = require(“hoge”); hoge.foo();
      • createHogehoge = function() { if (android) return new createAndroidHogehoge(); else if (iphone) return new …
    • Deferred, Promise, Emitter
      • callback でもネストが深くならない
      • でぃふぁーれっど (でぃふぁーどじゃないらしい)
      • JSDeferred は Titanium でも使えるらしい
  • ドキュメントやリソースなど
    • http://code.google.com/p/titanium-mobile-doc-ja/
      • API ドキュメントの日本語の翻訳
      • 何故か本家のコードの間違いが翻訳では直っていることがある
      • 何故か本家よりスクリーンショットが充実していることもある
    • http://tidocs.com/
    • WebDB Press Vol. 61 の特集
    • ぐぐる
      • 情報の賞味期限は 4〜6ヶ月
      • それより古い情報は食べたらおかなをこわします (笑)
  • Q. jQuery の便利な機能を使うことはできるか。jQuery.each(), 等の DOM に依存しないものとか。
    • A. Titanium の JavaScript は 1.6 相当なので、Array.prototype.filter (jQuery.grep に相当), Array.prototype.map (jQuery.map に相当) など、標準化されているものを使えば OK
  • Q. 描画系でリアルタイム処理するときはどうする?
    • A. Objective-C で UIView を継承したクラスに描画してモジュールにして Titanium から呼び出せば良い
    • コミックビュアーを作ったときはそうした

懇親会のかつサンド美味かった!というわけで以上!

Kinect 勉強会 Vol.1 に参加してきました

RDDブログひさしぶりの小松です、

今日は、Kinect 勉強会に参加してきました

導入から丁寧に説明してもらえたので、だいぶ分かった気になりました

以下、自分のメモ。。
・最初のドライバはlibfreenect。賞金がついてオープンソースのドライバが開発された。
・今の主流はOpenNIのやつ。Macにも対応しているが、stableはwin/linux向けのもの。
・ C++/Python向けのバインディングが用意されている。
・深度画像と光学(RGB)画像が得られる。
・骨格トラッキングをすると、関節部分の座標と角度が取れる。
・primesense社のSDKというのも使えるらしい

・事例まとめ
http://www.openni.org/gallery
http://www.kinect-hacks.com/openni
・openFrameworks には、libfreenect / OpenNI のドライバが同梱されていてらくちん
・@hagino3000さんの発表スライドは、ハンドジェスチャーでページ送りしてた
・手が疲れるので途中でやめる
・画像処理はOpenCV使うとらくちん
・左右のカメラの視差で3D認識をしているんだと思っていたが、どうやら赤外線カメラで深度情報を取っているっぽい?
・@ndrugerさんの発表は、node.jpと、WebGLと、HMDを組み合わせてゲームを作る
・node.jsは、座標情報を右から左に流すだけのシンプルな物
・kinectからきた座標情報をTCPで送るコードも、OpenNIのサンプルコードに少し手を加えた程度の簡単なもの
・深度情報は、0-255の256段階、640×480の解像度
・深度は赤外線カメラで、映像はRGBカメラで撮影していて、カメラがついている位置が少し離れているためKinectに近づくと映像と、深度情報がずれる現象が起こる
・HMD楽しそうVR920 5万円ぐらいで、加速度センサ付きのHMDがかえるらしい。キネクト界隈でいろんな人が遊んでいるらしい。解像度はVGAぐらい

さて、あとは作るだけ!C++久しぶりに触ってみるのも、わくわくしますねー。

Ktai Library for CakePHP 勉強会@関東 第二回 に参加しました

はいどうもこんにちは。

社内でも CakePHP 熱が上がってきていたり (?) モバイルの案件も増えてきているところに丁度良いタイミングで勉強会のお知らせがあったので参加してきました。

当方、Ethna がほとんどで CakePHP はちょっとだけかじったレベルでの参加で、書籍持参でコーディングするスタイルの勉強会にはきっと屈強なお兄さんたちが集まっているんじゃないかとイメージしていたのですが、そんなことはなく終始和やかな雰囲気が流れていた勉強会だったなあと思います。

最初はコーディング中心で、管理画面の実装を通して CakePHP の基礎をつかむ感じでした。管理画面の分量が結構多かったため、モバイルのところまでは到達できませんでしたが CakePHP の取っ掛かりとしては良かったと思います。

後半は皆さんと歓談して色々と興味深い話を聞かせていただきました。得に印象に残っているのがテストの話と git の話。あとは別のフレームワークの話もあったり。 events.php.gr.jp が Ethna から CakePHP に書き直されたことを知って、ちょっと寂しくなったり (笑)

最後に、いろいろと (主にコーディングと関係ないところばかりで) サポートしてくださった滝下さんに感謝です。そして主催者の穴澤さん、お疲れさまでした!今後ともよろしくお願いします。

preload preload preload