女子小学生と××したい

Webフロントエンド界のゴミクソメンヘラであり続けたい

web audio APIのpannerNodeのsetPositionについて思うこと

この話題、まだ続きます。ごめんなさい。
この記事は少し前の記事をちょこちょこ読まないとわからない感じになっています。

ざっくり要旨を語りますと、「web audio APIのpannerNodeのsetPositionは恐らく様々な角度からの音のインパルス応答を対象音の音源に畳み込み演算して出力しているが、補間を行なっていないので測定データの無い角度からの音を完全に再現はできない」ということです。

あれ?

大体説明し終えたぞ?ま、まぁ、ちゃんと書くか。
web audio APIってのは「ノード」と呼ばれる、各機能を持ったモジュールをつないで、色んな効果や音色を持った音を出力します。
その中に、Pan(パン。「定位」つまり音源の位置を定めること)に関するpannerNodeというものがあります。

Web Audio API

ざっくり読むと、音源の位置変えたり、音源の方向、音源自体が向いている方向を変えたりできるようですね(適当)。で、何回か紹介しているiOS6 safari対応 擬似立体音響 - jsdo.it - Share JavaScript, HTML5 and CSSではこのpannerNodeのsetPositionというメソッドで仮想音源の座標を決定しています。
で、↑のjsdo.itを走らせていて分かったのですが、仮想音源位置を上下に動かしていくと、なんか境界があるというか、段階的に音が変わるのが分かってしまいます。最初は僕の実装の問題かと思い、setPositionを行なっているタイマーのインターバルを10msにしたんですが結果変わらずでした。

で、この挙動に対する素人目線な仮説を書こうって話です

このメソッドの内部処理までしっかり読んだわけではないんですが、この手の処理は大体、「インパルス応答の畳み込み演算」というもので行なっています。この辺の詳しい話をし始めると厳密なところで間違ってて、空間音響の方々から刺されかねないのでざっくり説明します。

ざっくり説明しますと、ダミーヘッドと呼ばれる人型マネキンみたいな人形の鼓膜付近にマイクロホンを仕込み、ある角度から出力したインパルス音という非常に短い音をそのマイクで録音したものをインパルス応答と呼びます。

インパルス応答 - Wikipedia

これを様々な角度から同様に測定していきます
ちなみにこんな機械で測定します

http://www.ais.riec.tohoku.ac.jp/Lab2/sp-array/newimg/speaker_array_small.jpg

こうして測定したインパルス応答を、「畳み込み演算」という方法でごにょごにょ(参考:FIR型とインパルス応答の畳み込み : ソフトウェアと音響のデジタル信号処理)すると、↑のjsdo.itでやっているような様々な角度からの仮想音源を再現することができます。

さて、では上下に音源を徐々に移動させた場合に起きている途切れの原因の予想についてなのですが
↑の画像を見ていただくと分かる通り、当然スピーカーとスピーカーには間隔が空いており、測定できない角度というのが出現してきます。
これが原因、と言ってしまえばまぁ、そういうことです。例えば測定が10°おきに行われたインパルス応答を用いれば、45°方向のインパルス応答はないので、例えば40°から50°の間は40°のインパルス応答で代用しているような実装になっているとすれば、今回起きているような途切れの原因として十分考えられると思います。

ちなみに、このようにならない方法として、インパルス応答を補間するという手法が考えられます。ざっくり言えば、40°のインパルス応答の特徴と50°のインパルス応答の特徴から45°のインパルス応答を近似する手法です。この手法がどの程度精度が高く、どの程度実用段階かというのはちょっと失念してしまいましたが、少なくとも現在も研究が行われ続けているというのは事実です。

というわけでまとめますと

  • web audio APIのpannerNodeのsetPositionメソッドには、仮想音源位置を上下(前後)をなめらかに移動させた場合に途切れが発生する
  • このメソッドは恐らく、室インパルス応答の畳み込み演算によって実装されている
  • そして、データの存在しない角度のインパルス応答については補間を行わず、不完全な実装となっている可能性がある

ってことです。あくまで予想に過ぎませんし、ちゃんと実装読んでから書けやクソがぁああって意見も大募集なのですが、間違ってたら消しますので、ご勘弁を。それでは~