EGはサクッと作ってしまおうと思っていたが、モジュラー・グラフを考えると結構やることが多いことが分かった。
EGは他のオーディオ・ノードと見た目は同じに見える。しかしオーディオ・グラフ(いわゆるconnect()
で結んでいくやつ)上のノードに含むことはできない。scriptProcessorを使えばオーディオ・グラフ上に乗るEGを作れそうだけど、非推奨だし、まだAudioWorkerは実装されていないしね。まあ機能を考えるとAudioWorkerでEGを実装するのは割に合わない感じがする。
でいろいろ考えてオーディオ・グラフとは別に、パラメータ・グラフを採用することにする。パラメータは以下のように定義する。
Parameter ::= [time,param];
このBNFの表記のような表記でないようなあいまいな感じがなんとも。 それはさておき、パラメータは時間とパラメータの配列とする。これをパラメータグラフ間で受け渡しをする。
パラメータ・グラフは上図のようにパラメータ間はデータを受け渡し、最終的にはAudioParamのメソッドを呼び出すようにする。EGはSEQから受け取るのはGateとなる。paramはベロシティーで、time時間になったらベロシティーを考慮してエンベロープに沿った値をgainパラメータにセットする。意識しなくてはいけないのは、ここで渡されるパラメータは少し未来の(100msくらい先の)パラメータだということだ。オーディオ・グラフは実時間での処理を扱うのでその点注意が必要かもしれない。
パラメータ・グラフにおいてもオーディオ・グラフと同様な接続ができたほうがいいなと思う。
- Seq(uencer)は[時間,パラメータ]をEG1に引き渡す。
- EG1は[時間,パラメータ]を受け取ると、EG1が内部的に持っているパラメータ(ADSR)に基づき受け取ったパラメータを変換し、接続されたGainノードのgain AudioParamに値をセットする。
- EG1は[時間,パラメータ]を受け取ると、EG1が内部的に持っているパラメータ(ADSR)に基づき受け取ったパラメータを変換し、接続されたFilterノードのFreq AudioParamに値をセットする。
- Seq(uencer)は[時間,パラメータ]をEG2に引き渡す。
- EG2は[時間,パラメータ]を受け取ると、EG2が内部的に持っているパラメータ(ADSR)に基づき受け取ったパラメータを変換し、接続されたGainノードのgain AudioParamに値をセットする。
で、気になるのは2.,5.の処理によって、gainパラメータがどうなるのかということ。例えば2.の処理の指定時間が後で、5.のほうが指定時間が前の場合はどうなるのか。仕様上はどうなるのかを調べないといけないな。そのまま実装してみてどうなるかを確かめてもよいとも思うが、早い->遅いとなるようにソートすべきなのだろうな。