g200kg > Web Audio API 解説 > 05.ノードのライフタイム
Web Audio API 解説
2019/01/19
05.ノードのライフタイム
« Prev 01.前説 02.とりあえず音を出す 03.オシレーターの使い方 04.ノードの接続 05.ノードのライフタイム 06.バッファソースでワンショットサンプルから音を出す 07.パラメータとオートメーション 08.a-rateパラメーターとk-rateパラメーター 09.スクリプトプロセッサーの使い方 10.フィルターの使い方 11.オシレーターのカスタム波形 12.アナライザーの使い方 13.ディレイの使い方 14.ウェイブシェイパーの使い方 15.コンプレッサーの使い方 16.コンボルバーの使い方 17.パンナーの使い方 19.各ノードのパラメータ一覧 Next »
ノードのライフタイム
さて、「オシレーターの使い方」の例でこんなサンプルを使いましたが・・・
function Start() {
const audioctx = new AudioContext();
const t0 = audioctx.currentTime;
for(let i = 0; i < 10; ++i) {
const osc = new OscillatorNode(audioctx);
osc.connect(audioctx.destination);
osc.start(t0 + i * 0.5 + 0.5);
osc.stop(t0 + i * 0.5 + 0.6);
}
}
よく見るとループ内で作られた osc はループを抜けるとどこからも参照されなくなってしまいます。まだこれから音を出さないといけないのですが、これで破棄されてしまわないのでしょうか?
WebAudio API では各ノードのオブジェクトがいつ破棄されるかについて、次のように JavaScript のルールに加えて幾つかの条件が決まっていて、この内のどれか 1 つでも残っていると破棄されません。この例だと 2 番目の条件で音を出し終わるまでオシレーターは維持されているわけです。
- 通常の Javascript のオブジェクトとしての参照がある
- Oscillator / AudioBufferSource 等の動作時刻を設定できるノードで、今後動作する時刻が設定されている、または動作中
- 他のノードから接続されている
- ノード内部の処理でまだ処理すべきデータが残っている (これは例えばリバーブの残響部分などです)
- MediaStreamAudioSourceNode で、入力となっているストリームが再生中になっている
- MediaElementAudioSourceNode で、対応する HTMLMediaElements が再生可能な状態になっている
更にこういう例もあります。前と同じようにあらかじめスケジュールが設定された 10 個の音を出しますが、オシレーターとゲインの組になっていて音量を 1 音ごとに変化させようとしています。
各 osc と gain の組はマスターボリュームのゲインノードに接続します。 mastervol はグローバルに参照が保持されていますが、Setup() のループ内で作られる osc と gain は、作り終わった後どこからも参照されなくなります (せっかくなので各オシレーターの音程と音量を乱数で適当に設定しています)。
<!DOCTYPE html>
<html>
<body>
<h1>Node Lifetime</h1>
<button onclick="Start()">Start</button><br/>
<script>
let audioctx, mastervol;
function Start() {
if(!audioctx){
audioctx = new AudioContext();
mastervol = new GainNode(audioctx);
mastervol.connect(audioctx.destination);
}
var t0 = audioctx.currentTime;
for(var i = 0; i < 10; ++i) {
const osc = new OscillatorNode(audioctx);
const gain = new GainNode(audioctx);
osc.frequency.value = 100 + Math.random() * 1000;
gain.gain.value = 0.2 + Math.random() * 0.8;
osc.connect(gain).connect(mastervol);
osc.start(t0 + i * 0.5 + 0.5);
osc.stop(t0 + i * 0.5 + 0.6);
}
}
</script>
</body>
</html>
テストページ:ノードのライフタイム
この場合 osc はスケジュールが設定されているので維持され、gain は osc から接続されているために維持されています。osc は音を出し終わると自動的に破棄されますが、するとその osc に繋がっている gain も他のノードからの接続を失って連鎖的に破棄される事になります。
全部音を出し終わると mastervol への接続もなくなりますが、mastervol はグローバルな参照を持っているために消えずに残ります。
« Prev 01.前説 02.とりあえず音を出す 03.オシレーターの使い方 04.ノードの接続 05.ノードのライフタイム 06.バッファソースでワンショットサンプルから音を出す 07.パラメータとオートメーション 08.a-rateパラメーターとk-rateパラメーター 09.スクリプトプロセッサーの使い方 10.フィルターの使い方 11.オシレーターのカスタム波形 12.アナライザーの使い方 13.ディレイの使い方 14.ウェイブシェイパーの使い方 15.コンプレッサーの使い方 16.コンボルバーの使い方 17.パンナーの使い方 19.各ノードのパラメータ一覧 Next »
g200kg