Firefox Audio Data API - How to stop/pause raw audio smoothly (with no pop)?
I am generating raw audio with the Firefox Audio Data API and I need to stop/pause this audio without a pop occurring. Here is the tone generator example from the Audio Data API:
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Audio Write Example</title>
</head>
<body>
<input type="text" size="4" id="freq" value="440"><label for="hz">Hz</label>
<button onclick="start()">play</button>
<button onclick="stop()">stop</button>
<script type="text/javascript">
var timerID, audio;
function AudioDataDestination(sampleRate, readFn) {
// Initialize the audio output.
audio = new Audio();
audio.mozSetup(1, sampleRate);
var currentWritePosition = 0;
var prebufferSize = sampleRate / 2; // buffer 500ms
var tail = null;
// The function called with regular interval to populate
// the audio output buffer.
timerID = setInterval(function() {
var written;
// Check if some data was not written in previous attempts.
if(tail) {
written = audio.mozWriteAudio(tail);
currentWritePosition += written;
if(written < tail.length) {
// Not all the data was written, saving the tail...
tail = tail.slice(written);
return; // ... and exit the function.
}
tail = null;
}
// Check if we need add some data to the audio output.
var currentPosition = audio.mozCurrentSampleOffset();
v开发者_如何学Pythonar 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.slice(written);
}
currentWritePosition += written;
}
}, 100);
}
// Control and generate the sound.
var frequency = 0, currentSoundSample;
var sampleRate = 44100;
function requestSoundData(soundData) {
if (!frequency) {
return; // no sound selected
}
var k = 2* Math.PI * frequency / sampleRate;
for (var i=0, size=soundData.length; i<size; i++) {
soundData[i] = Math.sin(k * currentSoundSample++);
}
}
var audioDestination = new AudioDataDestination(sampleRate, requestSoundData);
function start() {
currentSoundSample = 0;
frequency = parseFloat(document.getElementById("freq").value);
}
function stop() {
frequency = 0;
//audio.volume = 0;
//clearInterval(timerID);
}
</script>
</body>
</html>
When the stop button is clicked I have tried setting the audio volume to 0 and stopping the timer interval but both of those still cause a pop to occur. How can I smoothly stop the audio?
精彩评论