diff options
author | Jukka Jylänki <jujjyl@gmail.com> | 2014-05-21 08:54:19 +0300 |
---|---|---|
committer | Jukka Jylänki <jujjyl@gmail.com> | 2014-05-21 08:54:19 +0300 |
commit | b07f7e9a86338f468d6ddc2c3d52b0e0a58c331c (patch) | |
tree | 1c7f75cf6d9a3b2af6b120f4daec80296a255650 | |
parent | 57ed92d565981c4f6d796c980b2530f0b47ee72b (diff) |
Don't allow exceptions in SDL audio backend with Web Audio to leak and abort rAF loops.
-rw-r--r-- | src/library_sdl.js | 70 |
1 files changed, 41 insertions, 29 deletions
diff --git a/src/library_sdl.js b/src/library_sdl.js index d9639907..df0b1306 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -942,10 +942,14 @@ var LibrarySDL = { if (!info) return 0; var ret = info.volume * 128; // MIX_MAX_VOLUME if (volume != -1) { - info.volume = volume / 128; + info.volume = Math.min(Math.max(volume, 0), 128) / 128; if (info.audio) { - info.audio.volume = info.volume; // For <audio> element - if (info.audio.webAudioGainNode) info.audio.webAudioGainNode['gain']['value'] = info.volume; // For WebAudio playback + try { + info.audio.volume = info.volume; // For <audio> element + if (info.audio.webAudioGainNode) info.audio.webAudioGainNode['gain']['value'] = info.volume; // For WebAudio playback + } catch(e) { + Module.printErr('setGetVolume failed to set audio volume: ' + e); + } } } return ret; @@ -956,39 +960,47 @@ var LibrarySDL = { if (!audio) return; if (audio.webAudioNode) return; // This instance is already playing, don't start again. if (!SDL.webAudioAvailable()) return; - var webAudio = audio.resource.webAudio; - audio.paused = false; - if (!webAudio.decodedBuffer) { - if (webAudio.onDecodeComplete === undefined) abort("Cannot play back audio object that was not loaded"); - webAudio.onDecodeComplete.push(function() { if (!audio.paused) SDL.playWebAudio(audio); }); - return; + try { + var webAudio = audio.resource.webAudio; + audio.paused = false; + if (!webAudio.decodedBuffer) { + if (webAudio.onDecodeComplete === undefined) abort("Cannot play back audio object that was not loaded"); + webAudio.onDecodeComplete.push(function() { if (!audio.paused) SDL.playWebAudio(audio); }); + return; + } + audio.webAudioNode = SDL.audioContext['createBufferSource'](); + audio.webAudioNode['buffer'] = webAudio.decodedBuffer; + audio.webAudioNode['loop'] = audio.loop; + audio.webAudioNode['onended'] = function() { audio.onended(); } // For <media> element compatibility, route the onended signal to the instance. + + // Add an intermediate gain node to control volume. + audio.webAudioGainNode = SDL.audioContext['createGain'](); + audio.webAudioGainNode['gain']['value'] = audio.volume; + audio.webAudioNode['connect'](audio.webAudioGainNode); + audio.webAudioGainNode['connect'](SDL.audioContext['destination']); + audio.webAudioNode['start'](0, audio.currentPosition); + audio.startTime = SDL.audioContext['currentTime'] - audio.currentPosition; + } catch(e) { + Module.printErr('playWebAudio failed: ' + e); } - audio.webAudioNode = SDL.audioContext['createBufferSource'](); - audio.webAudioNode['buffer'] = webAudio.decodedBuffer; - audio.webAudioNode['loop'] = audio.loop; - audio.webAudioNode['onended'] = function() { audio.onended(); } // For <media> element compatibility, route the onended signal to the instance. - - // Add an intermediate gain node to control volume. - audio.webAudioGainNode = SDL.audioContext['createGain'](); - audio.webAudioGainNode['gain']['value'] = audio.volume; - audio.webAudioNode['connect'](audio.webAudioGainNode); - audio.webAudioGainNode['connect'](SDL.audioContext['destination']); - audio.webAudioNode['start'](0, audio.currentPosition); - audio.startTime = SDL.audioContext['currentTime'] - audio.currentPosition; }, // Pausea an SDL audio resource that was played with Web Audio.. pauseWebAudio: function(audio) { if (!audio) return; if (audio.webAudioNode) { - // Remember where we left off, so that if/when we resume, we can restart the playback at a proper place. - audio.currentPosition = (SDL.audioContext['currentTime'] - audio.startTime) % audio.resource.webAudio.decodedBuffer.duration; - // Important: When we reach here, the audio playback is stopped by the user. But when calling .stop() below, the Web Audio - // graph will send the onended signal, but we don't want to process that, since pausing should not clear/destroy the audio - // channel. - audio.webAudioNode['onended'] = undefined; - audio.webAudioNode.stop(); - audio.webAudioNode = undefined; + try { + // Remember where we left off, so that if/when we resume, we can restart the playback at a proper place. + audio.currentPosition = (SDL.audioContext['currentTime'] - audio.startTime) % audio.resource.webAudio.decodedBuffer.duration; + // Important: When we reach here, the audio playback is stopped by the user. But when calling .stop() below, the Web Audio + // graph will send the onended signal, but we don't want to process that, since pausing should not clear/destroy the audio + // channel. + audio.webAudioNode['onended'] = undefined; + audio.webAudioNode.stop(); + audio.webAudioNode = undefined; + } catch(e) { + Module.printErr('pauseWebAudio failed: ' + e); + } } audio.paused = true; }, |