Home » ソフトウェア » プログラミング » Web Audio APIで音源ファイルを使わずにブラウザから音を出す

Web Audio APIで音源ファイルを使わずにブラウザから音を出す

プログラミング

Web Audio APIのAudioWorkletという仕組みを利用して、ブラウザ上でソフトウェア音源を作る方法をサンプルを交えて説明しています。

「モダンブラウザ」と呼ばれる、近年のWebブラウザが音を出すことができるのは、YouTubeなどを見れば明らかですね。

これらは通常、あらかじめ用意されている音源ファイル(動画ファイル)をブラウザで再生しているわけですが、一方で、ブラウザゲームなどをプレイしていると、プレイヤーの操作に応じた効果音が鳴るものがあります。

無数にありうるプレイヤーの操作パターンすべてに対応する音源ファイルを用意してあるわけでもないでしょうし、どうやって音を鳴らしているのだろう? と思ったことはありませんか?

プログラムで音を出すとは?

現在では、テレビゲームソフトなどにおいても、あらかじめ制作しておいた音源ファイルを再生して音楽や効果音を鳴らすのが一般的です。しかし、1980年代ごろまでは、音源ファイルを使わずに、プログラムで音楽や効果音を奏でていました。

プログラムから、各ハードウェアに搭載されている音源に対して、波形(≒音色)や周波数(≒音の高さ)などを指示して音を出していたのです。

1980年代の事情

当時のコンピュータは記憶容量が小さく、音源ファイルを用意することが困難だったほか、そもそもPCM音源を搭載していないことが多かったという事情もあります。音源ファイル(.WAVや.MP3など)とプログラムでは、後者の方が桁違いに小さくなります。

2000年代以降の状況

当時の音源の奏でる音色は独特で、後に「チップチューン」という芸術分野として認知されてきています。

Web Audio APIとAudioWorklet

かつてブラウザで音を鳴らすためには、Flashなどのプラグインが必要でした。しかし、Webの標準規格としてWeb Audio APIが登場し、主要ブラウザがそれをサポートすることで、ユーザーの環境に依存せずに音を制御できるようになってきました。

今回取り上げる、Web Audio APIも、音源ファイルを再生するのが基本的な使い方ですが、それに加えて、プログラムによる制御で音を発生させる仕組みも用意されています。それがAudioWorkletというもので、これを使うと、まさに先ほど述べたように、プログラムで波形を処理できるようになります。いわば、ブラウザ上にソフトウェア音源を作ることができるのです。

Web Audio APIの互換性について

AudioWorkletが規定される前に、ScriptProcessorというインターフェースがありました。Chromeは前者に対応しているものの、Safariは後者にしか対応していない状況が長く続いていました。

そのため、拙作「PSG for Web」は、Safariでも使えるように、ScriptProcessorとAudioWorkletで同じ処理を冗長に記述し、AudioWorkletが使えなかった場合はScriptProcessorを使うようになっています。

しかし、Safariもバージョン14.1でAudioWorkletに対応しました。

なお、W3C勧告の2021年6月17日版では、ScriptProcessor(§1.29)は「DEPRECATED(非推奨)」となり、将来的に廃止される予定です。これを受け、本記事のサンプルもScriptProcessorには対応していません。

任意の周波数(高さ)の音を出すサンプル

サンプルを見てみましょう。次の画面の「開始」ボタンを押してみてください。「プー」という音が出ると思います。

音量にご注意ください。「停止」ボタンを押すと止まります。

これだけだと、そういう音の音源ファイルを再生しているのと変わらない、と思いますよね。

それでは、今度は上の画面の「周波数」欄の値を「1000」に変更して、再び「開始」ボタンを押してみてください。先ほどよりも高い「ピー」という音になりましたね。これは、「周波数」欄の値ごとに別々の音源ファイルを用意しているのではなく、入力値に合わせて、プログラムで周波数(音の高さ)を変化させているのです。

この音(色)について

この音は、俗に「1kHz」と呼ばれる、周波数1,000Hzの正弦波で、テストパターン(下の映像)の音や、一部の音声を消す「ピー音」に使われているものです。

サンプルのソースコードの解説

ここからは、上記のサンプル画面のソースコードを見ていきましょう。このプログラムは4つのファイルに分かれています。

  1. 画面表示ためのHTML(index.html)
  2. 画面に対応するJavaScript(index.js)
  3. Web Audio APIを利用するJavaScript(websound-1.0.1.js)
  4. AudioWorkletとして動作するJavaScript(websoundawp-1.0.1.js)

3と4が別ファイルになっているのは、Webの仕様による制約(後述)です。