aboutsummaryrefslogtreecommitdiff
path: root/src/library_sdl.js
diff options
context:
space:
mode:
authorJukka Jylänki <jujjyl@gmail.com>2013-06-16 18:30:27 +0300
committerAlon Zakai <alonzakai@gmail.com>2013-09-24 16:56:44 -0700
commit257d5f4d0b4932817b2bbf9071134346ed7f6392 (patch)
treecc8882197e6acfe7a3675d560ae8327891e72965 /src/library_sdl.js
parent84c042143b57382e07d1af137d47fd36288b34dd (diff)
Fix audio callback overflow problems by avoiding using Browser.safeSetTimeout, and instead calling safeSetInterval to control the timing drift explicitly.
Diffstat (limited to 'src/library_sdl.js')
-rw-r--r--src/library_sdl.js34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 55e9aa49..3851caaf 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -1523,6 +1523,7 @@ var LibrarySDL = {
if (typeof(SDL.audio.audioOutput['mozSetup'])==='function') { // Primarily use Mozilla Audio Data API if available.
SDL.audio.audioOutput['mozSetup'](SDL.audio.channels, SDL.audio.freq); // use string attributes on mozOutput for closure compiler
SDL.audio.mozBuffer = new Float32Array(totalSamples);
+ SDL.audio.nextPlayTime = 0;
SDL.audio.pushAudio = function(ptr, size) {
var mozBuffer = SDL.audio.mozBuffer;
// The input audio data for SDL audio is either 8-bit or 16-bit interleaved across channels, output for Mozilla Audio Data API
@@ -1537,7 +1538,19 @@ var LibrarySDL = {
mozBuffer[i] = ((v >= 0) ? v-128 : v+128) /128;
}
}
+ // Submit the audio data to audio device.
SDL.audio.audioOutput['mozWriteAudio'](mozBuffer);
+
+ // Compute when the next audio callback should be called.
+ var curtime = Date.now() / 1000.0 - SDL.audio.startTime;
+ if (curtime > SDL.audio.nextPlayTime && SDL.audio.nextPlayTime != 0) {
+ console.log('warning: Audio callback had starved sending audio by ' + (curtime - SDL.audio.nextPlayTime) + ' seconds.');
+ }
+ var playtime = Math.max(curtime, SDL.audio.nextPlayTime);
+ var buffer_duration = SDL.audio.samples / SDL.audio.freq;
+ SDL.audio.nextPlayTime = playtime + buffer_duration;
+ // Schedule the next audio callback call.
+ SDL.audio.timer = Browser.safeSetTimeout(SDL.audio.caller, 1000.0 * (playtime-curtime));
}
} else {
// Initialize Web Audio API if we haven't done so yet. Note: Only initialize Web Audio context ever once on the web page,
@@ -1598,14 +1611,10 @@ var LibrarySDL = {
}
var playtime = Math.max(curtime, SDL.audio.nextPlayTime);
SDL.audio.soundSource[SDL.audio.nextSoundSource]['start'](playtime);
- var buffer_duration = SDL.audio.soundSource[SDL.audio.nextSoundSource]['buffer']['duration'];
+ var buffer_duration = sizeSamplesPerChannel / SDL.audio.freq;
SDL.audio.nextPlayTime = playtime + buffer_duration;
SDL.audio.nextSoundSource = (SDL.audio.nextSoundSource + 1) % 4;
- // Make sure we are always more than one sample block ahead of the current time to avoid starving.
- if (curtime + buffer_duration + buffer_duration >= SDL.audio.nextPlayTime) {
- // Immediately queue up an extra buffer to force the sound feeding to be ahead by more than one sample block:
- Browser.safeSetTimeout(SDL.audio.caller, 1);
- }
+ SDL.audio.timer = Browser.safeSetTimeout(SDL.audio.caller, 1000*(playtime-curtime));
} catch(e) {
console.log('Web Audio API error playing back audio: ' + e.toString());
}
@@ -1648,10 +1657,15 @@ var LibrarySDL = {
if (!SDL.audio) {
return;
}
- if (SDL.audio.paused !== pauseOn) {
- SDL.audio.timer = pauseOn ? SDL.audio.timer && clearInterval(SDL.audio.timer) : Browser.safeSetInterval(SDL.audio.caller, 1000 * SDL.audio.samples / SDL.audio.freq);
- // Immediately queue up a buffer to make the sound feeding to be ahead by one sample block.
- Browser.safeSetTimeout(SDL.audio.caller, 1);
+ if (pauseOn) {
+ if (SDL.audio.timer !== undefined) {
+ clearTimeout(SDL.audio.timer);
+ SDL.audio.timer = undefined;
+ }
+ } else {// if (SDL.audio.timer === undefined) {
+ // Start the audio playback timer callback loop.
+ SDL.audio.timer = Browser.safeSetTimeout(SDL.audio.caller, 1);
+ SDL.audio.startTime = Date.now() / 1000.0;
}
SDL.audio.paused = pauseOn;
},