【Web Audio API】サンプルどおりにプログラムしても音が出ない時には…。

JavaScriptでサウンドをごにょごにょしてみよう…と思います。HTML5やJavaScript関連の解説ドキュメントでは日頃からMDN(Mozilla Developer Network)あたりを頼りにしているわけですが、ここのサンプルコードをそのまんま走らせてみても、デバイスやブラウザによってはなかなか上手く動きません。

やりたいこと

  • とりあえずオシレータで音を出す。

実装は…

  • AudioContextを作成。
  • Oscillatorを作成。
  • OscillatorをAudioContextの出力に接続。
  • Oscillatorのパラメータを設定して音声出力スタート。
<script>
var AudioContext = window.AudioContext || window.webkitAudioContext;
var acx = new AudioContext();
var osc = acx.createOscillator();

osc.connect(acx.destination);
osc.type="sine";
osc.frequency.value = 1000;
osc.start();
</script>

音が鳴らない…

  • デスクトップ版Safariで音が鳴らない。
  • iOS版Safariでも音が鳴らない。

原因・回避方法

  • OscillatorNode.startメソッドの引数を省略しないようにする。
  • iOSでは音の再生処理をユーザのアクションから呼ぶ必要がある。上の例のように OscillatorNode.startメソッドをページロード時に呼び出しても音は出ない。
  • iOSデバイスのサイレントスイッチがオンになっているとスピーカからは音が出ない。イヤホンからは大丈夫。

…というわけで、こんな感じでコードを書くとiOSデバイスやSafariでもちゃんと音が出ます。

<div id="start">Start</div>
<div id="stop">Stop</div>
<script>
var AudioContext = window.AudioContext || window.webkitAudioContext;
var acx = new AudioContext();
var osc = acx.createOscillator();

osc.connect(acx.destination);
osc.type="sine";
osc.frequency.value = 1000;
//osc.start();
document.getElementById('start').addEventListener('click',function(){osc.start(0);},false);
document.getElementById('stop').addEventListener('click',function(){osc.stop(0);},false);
</script>

サンプルページはこちら。"Start" を押すと1kHzの純音が再生され、"Stop" で停止します。

で、OscillatorNode.stop で音声再生を止めると、このOscillatorNode は破棄されてしまうのですね。なので音を停止した後にもう一度 "Start" をクリックしても音が出ずにエラーが出ます。

これを回避するためには…

  • Startボタンが押される('click'イベントを検知する)たびに「OscillatorNodeを作成して、パラメータを設定して、音を出す」という一連の作業を行う。
  • 音の再生中にはStartボタンの機能を無効にして、音が止まっている時にはStopボタンの機能を無効にするような処理を組み込む。

…のように書き換えると、何度でも再生→停止を繰り返すことができます。そんな動作をするサンプルはこちら

ということで。

カテゴリ: