AudioBuffer
と AudioBufferSourceNode
を使ってサンプルデータを再生します。
このページのデモが完成したソースコードになっているので、ブラウザの開発者ツールから読むことができます。
次のコードではJavaScriptの Array
に書き込んだサンプルデータを AudioBuffer
に渡しています。
function toAudioBuffer(ctx, wave) {
var buffer = ctx.createBuffer(channel, frame, ctx.sampleRate)
for (var ch = 0; ch < channel; ++ch) {
buffer.copyToChannel(new Float32Array(wave[ch]), ch, 0)
}
return buffer
}
// channel_0: 1000Hz, channel_1: 2000Hz のサイン波。
function render(ctx, channel, frame) {
var wave = new Array(channel)
for (var ch = 0; ch < channel; ++ch) {
wave[ch] = new Array(frame)
var freq = 1000 * (ch + 1)
var two_pi_f_per_fs = 2 * Math.PI * freq / ctx.sampleRate
for (var i = 0; i < wave[ch].length; ++i) {
wave[ch][i] = 0.1 * Math.sin(i * two_pi_f_per_fs)
}
}
return toAudioBuffer(ctx, wave)
}
var ctx = new AudioContext()
var channel = 2
var duration = 0.5 // 秒
var frame = Math.floor(duration * ctx.sampleRate)
var bufSin = render(ctx, channel, frame)
buffer.copyToChannel()
に渡すために Array
を Float32Array
に変換しています。
サンプルレートは AudioContext
から取得できます。コンピュータで音を扱うとき、 sampleRate / 2
より高い周波数は正しく再生されないので注意してください。
別のアプリケーションで作った .wav
や .mp3
などを XMLHttpRequest
で読み込んで ctx.decodeAudioData()
でデコードします。
function loadSample(ctx, path, callback) {
var request = new XMLHttpRequest()
request.open("GET", path, true)
request.responseType = "arraybuffer"
request.onreadystatechange = () => {
if (request.readyState !== 4) return
ctx.decodeAudioData(request.response, (buffer) => callback(buffer))
}
request.send()
}
var ctx = new AudioContext()
var bufCymbal
loadSample(ctx, "./wavecymbal.wav", (buffer) => { bufCymbal = buffer })
AudioBuffer
を AudioBufferSourceNode
に渡すことでサンプルデータを再生するためのノードを作ることができます。 AudioBufferSourceNode
は一回だけしか start()
できないので、再生を終えたら新しく作り直す必要があります。
function play(ctx, buffer) {
var source = ctx.createBufferSource()
source.buffer = buffer
source.connect(ctx.destination)
source.start()
}
// 使用例
play(ctx, bufSin)
play(ctx, bufCymbal.buffer)
試しに Opus も decodeAudioData
に渡しています。