timbre.js の使い方メモ: ended イベント
あたらしい timbre.js のドキュメントのドラフトみたいな感じで書く。第三弾。
あたらしいtimbre.jsではいくつかインターフェイスの変更があったのだけど、そのひとつが on
メソッドで、以前の timbre.js は off
と組み合わせてオブジェクトの ON/OFF(エフェクターの効果を有効にしたり無効にしたりとか)に使っていたのだけど、あたらしいtimbre.js では jQuery や node.js にならってイベントエミッター用のインターフェイスになった。
on
以外には以下のものがある( off
はなくなった。)
- addListener(type, function)
- removeListener(type, function)
- removeAllListeners(type)
* on と addListener は同じ
その中で最も使うのが ended
イベントで、使い方を知らないと困る場合があるので書く。
ended: 終わった時に呼び出される
何が終わったときかというと、音の持続とかそういう非常に長い非同期処理が終わった時に呼ばれて待機状態になる。オブジェクトは待機になった後も動作し続けるので、停止させたいときは明示的に書かないといけない。でないと処理が非常に重たくなる場合がある。
主だったものを列挙する。
T("timeout") / T("interval")
timeout
プロパティに設定した時間(msec) 後に ended
イベントが呼ばれて待機状態になる。きちんと停止するには stop()
を実行する。ちなみに待機中に bang()
を呼ぶと初期状態から処理を再開する。
T("interval", {interval:100, timeout:10000}).on("ended", function() { this.stop(); }).start();
T("env")
エンベロープが終端に達したときに ended
イベントが呼ばれて待機状態になる。きちんと停止するには puase()
を実行する。ちなみに待機中に bang()
を呼ぶと初期状態から処理を再開する。
T("perc", T("sin")).on("ended", function() { this.pause(); }).bang().play();
T("buffer") / T("audio") / T("tape")
バッファの再生が終わると ended
イベントが呼ばれて待機状態になる。きちんと停止するには pause()
を実行する。ちなみに待機中に bang()
を呼ぶと初期状態から処理を再開する。
T("audio", {load:"sample.wav"}).on("ended", function() { this.pause(); }).play();
T("param")
linTo
などで値を移動し終えたときに ended
イベントが呼ばれて最終値を出力し続ける。
var sin = T("sin").play(); var param = T("param").on("ended", function() { param.linTo(Math.random() * 2000 + 200, 500); }).setAt(440); sin.freq = param;
T("mml")
MMLの終端が終わると(たとえば最後の2分音符がおわったときとか) ended
イベントが呼ばれて待機状態になる。きちんと停止するには pause()
を実行する。ちなみに待機中に bang()
を呼ぶと初期状態から処理を再開する。
T("mml", {mml:"cegec2"}, T("OscGen").play()).on("ended", function() { this.stop(); this.inputs[0].pause(); // OscGenの停止 }).start();
T("rec")
録音が終わると ended
イベントが呼ばれて待機状態になる。きちんと停止するには pause()
を実行する。ちなみに待機中に bang()
を呼ぶと初期状態から処理を再開する。イベント時に渡される引数は録音した内容の SoundBuffer オブジェクト。
T("rec", T("noise")).on("ended, function(buffer) { this.stop(); }).start();
自動で止まれば良いんじゃないの?
なぜ自動で止まらないかというと、たとえば以下のようなコードの場合 perc
の処理を終えたあと、コードの意図までは判断できないので、どうしたら良いのか判断できない。
var perc= T("perc", T("sin")).bang(); T("delay", perc).play();
そのため特に処理せず 0 で埋まったバッファを返したりするのだけど、そういうのがたまってくると 0 を 100回足し算して 0 を出力するみたいな状態になって処理が重たくなってしまうので、明示的に停止してやる。
T("audio").load("naruhodius.wav", function() { var audio= this; T("interval", {interval:1000}, function() { audio.clone().play().on("ended", function() { this.pause(); }); }).start(); });
ちなみに上記の場合、下記コードも似たような動作をするし、pause
も使わないし、より軽量だけどモノフォニックになる。
T("audio").load("naruhodius.wav", function() { var audio= this.play(); T("interval", {interval:1000}, function() { audio.clone().bang(); }).start(); });
以前の on/off は?
以前の on
/ off
に相当するものもあれば便利なはずだけど、どういう名前にするか迷っている。bypass
とか through
とかかなぁと思っているのだけど。。あと enabled
とか。