Web Audio APIのモジュラー接続デモを作ってみる(8)

公開:2015-10-31 04:39
更新:2017-09-22 05:40
カテゴリ:web audio api,javascript,html5,audio,webaudiomodular

EGはサクッと作ってしまおうと思っていたが、モジュラー・グラフを考えると結構やることが多いことが分かった。

EGは他のオーディオ・ノードと見た目は同じに見える。しかしオーディオ・グラフ(いわゆるconnect()で結んでいくやつ)上のノードに含むことはできない。scriptProcessorを使えばオーディオ・グラフ上に乗るEGを作れそうだけど、非推奨だし、まだAudioWorkerは実装されていないしね。まあ機能を考えるとAudioWorkerでEGを実装するのは割に合わない感じがする。

でいろいろ考えてオーディオ・グラフとは別に、パラメータ・グラフを採用することにする。パラメータは以下のように定義する。

Parameter ::= [time,param];

このBNFの表記のような表記でないようなあいまいな感じがなんとも。 それはさておき、パラメータは時間とパラメータの配列とする。これをパラメータグラフ間で受け渡しをする。

background Layer 1 [time,param] from to parameter graph
1つ目をシーケンサー、2つ目をEG、3つ目をゲインとして、接続すると以下のようになる。ちなみにはAudioParam、はoutput、はinput。
background Layer 1 [time,param] from to parameter graph Seq EG Gain OSC Out Gain.gain.setTargetAtTime(param,time) gain Audio Graph

パラメータ・グラフは上図のようにパラメータ間はデータを受け渡し、最終的にはAudioParamのメソッドを呼び出すようにする。EGはSEQから受け取るのはGateとなる。paramはベロシティーで、time時間になったらベロシティーを考慮してエンベロープに沿った値をgainパラメータにセットする。意識しなくてはいけないのは、ここで渡されるパラメータは少し未来の(100msくらい先の)パラメータだということだ。オーディオ・グラフは実時間での処理を扱うのでその点注意が必要かもしれない。

パラメータ・グラフにおいてもオーディオ・グラフと同様な接続ができたほうがいいなと思う。

background Layer 1 Seq EG Gain OSC Out gain Filter freq EG

パラメータ・グラフの実際に処理についても少し考えないといけない。コネクトさえしてしまえば、オーディオ・グラフは放っておいてもAPIが処理してくれるが、パラメータ・グラフはグラフに沿った処理を自分で書かなくてはいけないからだ。図を書いてみると、パラメータ・グラフの起点はSeq(uencer)だから、そこから順番にグラフをたどっていけばうまく処理できそうだ。起点が2つ以上になるかもしれないけれども、起点は上位にノードが接続されていないかどうかで判別できるから、まあ難しくはないかなと思う。

background Layer 1 Seq EG1 Gain gain Filter freq EG2 1 2 3 4 5

それぞれのステップでは以下の処理を行う。

  1. Seq(uencer)は[時間,パラメータ]をEG1に引き渡す。
  2. EG1は[時間,パラメータ]を受け取ると、EG1が内部的に持っているパラメータ(ADSR)に基づき受け取ったパラメータを変換し、接続されたGainノードのgain AudioParamに値をセットする。
  3. EG1は[時間,パラメータ]を受け取ると、EG1が内部的に持っているパラメータ(ADSR)に基づき受け取ったパラメータを変換し、接続されたFilterノードのFreq AudioParamに値をセットする。
  4. Seq(uencer)は[時間,パラメータ]をEG2に引き渡す。
  5. EG2は[時間,パラメータ]を受け取ると、EG2が内部的に持っているパラメータ(ADSR)に基づき受け取ったパラメータを変換し、接続されたGainノードのgain AudioParamに値をセットする。

で、気になるのは2.,5.の処理によって、gainパラメータがどうなるのかということ。例えば2.の処理の指定時間が後で、5.のほうが指定時間が前の場合はどうなるのか。仕様上はどうなるのかを調べないといけないな。そのまま実装してみてどうなるかを確かめてもよいとも思うが、早い->遅いとなるようにソートすべきなのだろうな。