2012年12月14日金曜日

緊急車両通りますよ〜っと!「Web Audioでドップラー効果」

Web Music Developers JPのアドベントカレンダーの記事です。(12月14日)

ネタは「緊急車両通りますよ〜っと!「Web Audioでドップラー効果」」です。
物理の授業で出てくる定番かな、って思います。
ドップラー効果は19世紀半ばにオーストリアの物理学者ドップラーさんが発見しました。簡単に説明すると、音は音源を中心に球状に音波の速度で伝わります。聞き手が音源に向けて一定の速度で近づくとき、音波の速度は (音波の速度)+(聞き手の速度) となりますが、音源から遠ざかる時は (音波の速度)-(聞き手の速度) となり、この音波の速度が異なることで音程が変わる、というのが原理です。



さて、ここからWeb Audioへの実装の下準備です。
今回は音は固定、聞き手(針金人間)が動くという想定で実装していきます。
変数と式はそれぞれ以下のようになります。
   音波の速度:340(m/s) で固定します。(14.17℃の時の音波の速度です)
   波周波数: F0 = V340 / Lambda
   初期状態において聞き手から音までの距離:d(m)
   聞き手の速度: v0 (m/s)
   聞き手の周波数:F1
     (a) 音よりも右の場合:F1 = (V340 + v0) / Lambda = F0 ( V0 + U1 ) / V0
 var tune = (V340+v0)/V340; // L32: js/dopplerEffect.js
     (b) 音よりも左の場合F1 = (V340 - v0) / Lambda = F0 ( V0 - U1 ) / V0
 var tune = (V340+v0)/V340; // L32: js/dopplerEffect.js
     (a)と(b)の分岐は、
 d-v0*(i*interval)/1000 // L31: js/dopplerEffect.js
     が、0より大きい場合は(a)、0より小さい場合は(b)となります。

このとき interval は   JavaScriptのSetIntervalが呼ばれる間隔(ミリ秒)です。iはSetIntervalを何回通ったか、という変数にしていますので
 (i*interval)/1000
は今までに聞き手が初期状態から動いた距離になります。

あとせっかくなので、PanとVolume(Gain)を変えてより臨場感を出します。
WebAudioでのPanは3次元で設定できますが、今回はその1次元だけを使います。最大値は1.0、最小値は-1.0、中央は0.0となっていますのでそのように動くように式を作ります。Volumeは最大値は1.0、最小値は0.0ですが、今回は音が大きくなり過ぎるのを避けるために最大値は0.5と設定しました。
音源は定番の救急車の「ピーポーピーポー」にしました。ヘッドホンで聞くとより臨場感のあるドップラー効果を聞けると思います。
実装したモノはこちらです。

1つもヒネリがなかった訳ですが、Web AudioってHTML5なのでテキストエディタとブラウザがあれば実装できるので、教育現場で使えたりするんじゃないかな〜、なんて密かに思っています。科学って実際に肌で触れるとより理解できると個人的には思っているので、特にWeb Audioに関してはそっちでも使われるといいな〜、なんて抱いています。