RSS Twitter Facebook
g200kg > Web Audio API 解説 > 06.バッファソースでワンショットサンプルから音を出す

Web Audio API 解説

2016/11/14

06.バッファソースでワンショットサンプルから音を出す



AudioBufferSourceの使い方

ワンショットのサンプルを保持しておいて鳴らす場合は AudioBuffer と AudioBufferSourceNode の組み合わせを使用します。

AudioBuffer にはサンプルの元データを保持し、実際に音を出す時に AudioBufferSourceNode を作成して、鳴らした後はそのまま捨てます。Oscillator ノードと同じように AudioBufferSource ノードも一度音を出した後の再使用はできません。

音の元データになる AudioBuffer は AudioContext.createBuffer() や new AudioBuffer() により、指定サイズの空のバッファが作成できますが、.wav や .mp3などのデータから作成する場合は、AudioContext.decodeAudioData() を使用します。

ファイルのフォーマットとしては wav / mp3 / ogg 等、基本的にはそのブラウザで再生可能なオーディオファイル形式が使用できます。


AudioBufferSourceのパラメータとメソッド

パラメータ単位デフォルト値値の範囲内容
bufferAudioBuffer-null-再生するオーディオバッファ
playbackRateAudioParamなし1-∞ ~ +∞再生速度。このパラメータは k-rate です。
detuneAudioParamセント0-∞ ~ +∞再生速度に対するデチューン。このパラメータは k-rate です。
loopブール値-false-ループ再生の指定
loopStart数値00~バッファ長ループ開始位置
loopEnd数値00~バッファ長ループ終了位置。0の場合、バッファ全体がループ対象となる
start([when [,offset [,duration]]])関数---再生開始。whenは開始時刻(秒)。offset/durationはバッファ中の再生位置指定(単位は秒)。
stop([when])関数---再生停止。whenは停止時刻(秒)

AudioBufferSourceの使用例

ワンショットの音声ファイルを鳴らす例を下に示します。

起動後、LoadSample() 関数では、「./snare.wav」というファイルを fetch() で取ってきて decodeAudioData() に渡しています。 デコードにはある程度の時間がかかる事に注意してください。歴史的経緯からデコード終了時のコールバックを使う事もできますが、戻り値は Promise になっていますのでそちらを使った方が良いでしょう。

この例では、fetch、arrayBuffer への変換、decodeAudioData() がそれぞれ Promise で順次結果を返してゆき、最終的に LoadSample() 関数の戻り値の Promise が解決するまで async / await で待っています。このアプリケーション全体を囲む関数に async が付いている事に注意してください。

その後「Play」ボタンが押される度に AudioBufferSource ノードを作成して、buffer を鳴らします。作成した AudioBufferSource ノードは音の再生が終わると自動的に破棄されます。


<!DOCTYPE html>
<html>
<body>
<h1>Buffer source</h1>
<button id="playbtn">Play</button><br/>
<script>

window.addEventListener("load", async ()=>{
    const audioctx = new AudioContext();
    const sound = await LoadSample(audioctx, "./snare.wav");

    document.getElementById("playbtn").addEventListener("click",()=>{
        const src = new AudioBufferSourceNode(audioctx, {buffer:sound});
        src.connect(audioctx.destination);
        src.start();
    });

    function LoadSample(actx, url) {
        return new Promise((resolv)=>{
            fetch(url).then((response)=>{
                return response.arrayBuffer();
            }).then((arraybuf)=>{
                return actx.decodeAudioData(arraybuf);
            }).then((buf)=>{
                resolv(buf);
            })
        });
    }
});
</script>

</body>
</html>
テストページ:BufferSourceからワンショットの音を鳴らす




g200kg