Audio Data API
Original Code : https://wiki.mozilla.org/Audio_Data_API
by ethertank
HTML
<input type="text" size="4" id="freq" value="440">
<label for="hz">Hz</label>
<button onclick="start()">play</button>
<button onclick="stop()">stop</button>
JavaScript
function AudioDataDestination(sampleRate, readFn) { // オーディオ出力の初期化
var audio = new Audio();
audio.mozSetup(1, sampleRate);
var currentWritePosition = 0;
var prebufferSize = sampleRate / 2; // バッファ 500ms
var tail = null,
tailPosition;
// The function called with regular interval to populate
// the audio output buffer.
setInterval(function() {
var written;
// Check if some data was not written in previous attempts.
if (tail) {
written = audio.mozWriteAudio(tail.subarray(tailPosition));
currentWritePosition += written;
tailPosition += written;
if (tailPosition < tail.length) {
// Not all the data was written, saving the tail...
return; // ... and exit the function.
}
tail = null;
} // Check if we need add some data to the audio output.
var currentPosition = audio.mozCurrentSampleOffset();
var available = currentPosition + prebufferSize - currentWritePosition;
if (available > 0) { // Request some sound data from the callback function.
var soundData = new Float32Array(available);
readFn(soundData);
// Writting the data.
written = audio.mozWriteAudio(soundData);
if (written < soundData.length) { // Not all the data was written, saving the tail.
tail = soundData;
tailPosition = written;
}
currentWritePosition += written;
}
}, 100);
}
// コントロールと音の作成
var frequency = 0,
currentSoundSample;
var sampleRate = 44100;
function requestSoundData(soundData) {
if (!frequency) { // 音が選択されていない場合
return;
}
var k = 2 * Math.PI * frequency / sampleRate;
for (var i = 0, size = soundData.length; i < size; i++) {
soundData[i] = Math.sin(k * currentSoundSample++);
...