Web Audio API 解説
09.スクリプトプロセッサーの使い方
スクリプトプロセッサとは
ScriptProcessorノードは生の音声データを Javascript で自由に操作できるノードです。自分のやりたい事が自由に書けるので信号処理の中身に覚えのある人なら ScriptProcessor だけ使えれば、全部その中で処理してしまうという方法もあります。
ただし残念ながらこのノードは既に非推奨となっており、将来的には削除される予定です。 メインスレッド上で動作するためあまり重い処理をさせられないというのがその理由で、代替としてオーディオレンダリングスレッドで動作する AudioWorklet ノードが定められています。ただしこれに対応しているのは現在 Chrome のみです。
ScriptProcessorを作るのは
audioctx.createScriptProcessor([buffersize [,inputch [,outputch]]])
という書式で、inputch、outputch はそれぞれ入力と出力のチャンネル数(デフォルトは 2 )を指定します。
ですが、「出力するだけでいいから」と inputch に 0 を指定したりするとモバイルデバイスなど環境によっては動作しない場合があります。
buffersize は 256 から 16384 の 2 の累乗の値で、指定すればその値になりますが、省略または 0 を渡すとシステムが最適な値を適当に選んでくれます。
スクリプトプロセッサのパラメータ
スクリプトプロセッサの onaudioprocess には実際に音声データを処理する関数名設定します。bufferSize はノード作成時に指定したバッファサイズで作成後の変更はできません。
パラメータ | 型 | 単位 | デフォルト値 | 値の範囲 | 内容 |
---|---|---|---|---|---|
onaudioprocess | EventListener | - | - | - | Javascirptの関数を指定 |
bufferSize | 数値 | - | 環境による | 256 ~ 16384 | リードオンリー。作成時に指定されたオーディオデータの受け渡しのバッファサイズ。256, 512, 1024, 2048, 4096, 8192, 16384のどれか |
スクリプトプロセッサ使用例
この ScriptProcessor を使って何か音の出るものを作ってみます。
なお iOS デバイスなど一部の環境で ScriptProcessor の入力が未接続の場合、動作しないという現象があり、それを避けるため、このデモでは入力にダミーのオシレーターを接続してボタンを押すとそれをスタートさせています。
<!DOCTYPE html>
<html>
<body>
<h1>Script Processor</h1>
<button id="play">Play</button> <button id="stop">Stop</button>
<script>
window.addEventListener("load", ()=>{
const bufsize = 1024;
const audioctx = new AudioContext();
const scrproc = audioctx.createScriptProcessor(bufsize);
scrproc.onaudioprocess = Process;
scrproc.connect(audioctx.destination);
let osc = null;
let play = 0;
function Process(ev) {
const buf0 = ev.outputBuffer.getChannelData(0);
const buf1 = ev.outputBuffer.getChannelData(1);
for(let i = 0; i < bufsize; ++i)
buf0[i] = buf1[i] = (Math.random() - 0.5) * play;
}
document.getElementById("play").addEventListener("click", ()=>{
if(osc==null){
osc = new OscillatorNode(audioctx);
osc.start();
}
play = 1;
});
document.getElementById("stop").addEventListener("click", ()=>{
play = 0;
});
});
</script>
</body>
</html>
ノードの接続としては ScriptProcessor を作って destination に繋いでいます。スクリプトプロセッサーの onaudioprocess プロパティ に Javascript の関数を指定すると必要に応じて関数がコールバックされますのでその中で音声データを直接出力バッファに書き込みます。
出力バッファはコールバック関数の引数から ev.outputBuffer.getChannelData()という形で取ってきますが、チャンネル数がデフォルトでは 2 になっていますのでバッファは2つあります。
ここでは両方のバッファを乱数 (-0.5 ~ +0.5) で埋めていますので音としてはノイズになります。また、[Play] [Stop]のボタンで音を出したり止めたりをコントロールする事ができます。
テストページ:スクリプトプロセッサーの使い方