RSS Twitter Facebook

2016/11/10 (2016年11月 のアーカイブ)

[WebAudio API] ConstantSourceNodeって何ですか?


前回WebAudio APIの日本語訳を作ったのが2015年12月版になっていてもうすぐ1年経ちます。W3Cのサイトで公開されているWebAudio API仕様のWorking Draft(WD)は相変わらずこれが最新版ではあるのですが、GitHub上などで議論され、日々更新されているEditor's Draftでは、それなりにWDとの差ができてきています。

その中で、つい最近なんですが ConstantSourceNode という新しいノードが定義されています。こういう形になるまでにどういう議論の経緯があったかは私も完全には追い切れていないのですが、これは単に定数値を出力するためのノードです。

インターフェースとしては次のようになっていて、(今までのスタイルでいくなら) audioContext.createConstantSource() で作成できるノードになります。"offset" という名前のパラメータが一つだけ定義されていて、このoffsetに設定した定数値がただ出力される、というものです。
[Constructor(BaseAudioContext context, optional ConstantSourceOptions options)]
interface ConstantSourceNode : AudioNode {
    readonly        attribute AudioParam   offset;
                    attribute EventHandler onended;
    void start (optional double when = 0);
    void stop (optional double when = 0);
};

多分実際にプログラムを作って必要性を感じないと、これは何にどう使うためのものなの? という疑問しか出てこないような代物ですが、実際に割合複雑なノード構成のプログラムを作ろうとすると、定数値のノードが欲しいな、というケースがまま出てきます。

WebAudio APIでノードのパラメータを設定するには、
  • パラメータの値を.valueに直接代入するか、オートメーション機能を使って指定したカーブで自動的に変える
  • 他のノードからのconnect()による接続でパラメータに値が加算される
という2つの手段がありますが、問題はオートメーション機能はAudioParamと1対1にくっ付いているので「オートメーションで作ったカーブを複数加算する事はできない」という点です。そもそもの話をすると、(個人的見解としては)このオートメーションの基本的な設計がちょっとイケてない部分があったという気はするのですが、まあこのConstantSourceNodeがあればこれを充分にカバーする事ができます。

例えばシンセサイザーを作ろうとした時、オシレータの周波数はどうやって決まるでしょうか? 押さえる鍵盤によって変わるのは当然ですが、本格的なものにしようとするとポルタメントやピッチエンベロープやベンドホイールというような機能が欲しくなります。

このポルタメントやピッチエンベロープはそれぞれオートメーション機能を使えば簡単に実現できるのですが、両方同時に実装しようとするとパラメータのオートメーション機能の取り合いになっちゃうんですよね。(※実際にはfrequencyじゃなくてdetuneを使ったりするんですが...)

JavaScriptでごりごり計算して都度.valueを設定すれば同じ事ができますがせっかくの高精度なオートメーションが使えなくてパフォーマンス的にも無駄です。という事でここでConstantSourceNodeがあれば、2種類のオートメーションを出力するノードからターゲットのパラメータにまとめてconnect()すれば、勝手にカーブを合成してくれます。

これに限らず、各ノードのパラメータの操作はノード間のconnect()で実現できれば後はJavaScriptが関与しなくても下のレイヤーが勝手に処理してくれるのでパフォーマンス的に非常に有利になります。

このConstantSourceNodeは既にFirefoxのNightly、ChromeのCanaryで使えるようになっていますので、もうすぐ普通に使えるようになりそうです。期待!

Posted by g200kg : 2016/11/10 00:51:34