1

音楽アプリの場合、Web オーディオ API を使用して未加工のオーディオ サンプルを継続的かつシームレスに生成できる必要があります。検索した結果、AudioBuffer ( https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer ) について知りましたが、それが必要なようです。ただし、オーディオ バッファは 1 回しか再生できないため ( https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode )、連続して再生することはできません。この回避策を試しました:

                    const buffer = audioCtx.createBuffer(1, 10000, audioCtx.sampleRate);
                    for(let i = 0; i < buffer.length; i++)
                        buffer.getChannelData(0)[i] = ((i / audioCtx.sampleRate) * 440) % 1;
                    
                    const source = audioCtx.createBufferSource();
                    source.buffer = buffer;
                    source.onended = function() {
                        console.log(this);
                        const newSource = audioCtx.createBufferSource();
                        for(let i = 0; i < buffer.length; i++)
                            buffer.getChannelData(0)[i] = ((i / audioCtx.sampleRate) * 440) % 1;
                        newSource.buffer = buffer;
                        newSource.connect(audioCtx.destination);
                        newSource.onended = (this.onended as Function).bind(newSource);
                        newSource.start();
                    }
                    source.connect(audioCtx.destination);
                    source.start();

本質的に、このコードはバッファとソース ノードを作成し、バッファを再生し、バッファが終了すると、新しいソースとバッファを作成して再生を続けます。ただし、この方法では、バッファーの再生が終了すると、顕著な無音が生成されます。これは JS イベント ループと関係があると思いますが、よくわかりません。

理想的には、次のようなものが必要です。

audioCtx.createSampleStream(() => {
    // generate samples here.
    return Math.random() * 2 - 1;
})

うまくいけば、私はこれを機能させることができるでしょう。そうでない場合は、おそらくこれを行うために c++ バインディングを使用して npm パッケージを作成してみます。

4

1 に答える 1