From 9d8049988d47432e31d1da2db585117bb4456c1b Mon Sep 17 00:00:00 2001 From: jorsi Date: Fri, 9 Oct 2020 12:22:06 -0400 Subject: [PATCH] fix safari audio bug where error prevents leaving worldmap locations -- reveals another safari bug where decodeAudioData doesn't return a promise to start playing music immediately --- script/audio.js | 22 ++++++++++++++++++++-- script/engine.js | 27 +++++++++------------------ 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/script/audio.js b/script/audio.js index 58e5cad..819c1db 100644 --- a/script/audio.js +++ b/script/audio.js @@ -136,7 +136,9 @@ var AudioEngine = { var fadeTime = AudioEngine._audioContext.currentTime + AudioEngine.FADE_TIME * 2; // fade out event music and stop - if (AudioEngine._currentEventAudio) { + if (AudioEngine._currentEventAudio && + AudioEngine._currentEventAudio.source && + AudioEngine._currentEventAudio.source.buffer) { var currentEventGainValue = AudioEngine._currentEventAudio.envelope.gain.value; AudioEngine._currentEventAudio.envelope.gain.cancelScheduledValues(AudioEngine._audioContext.currentTime); AudioEngine._currentEventAudio.envelope.gain.setValueAtTime(currentEventGainValue, AudioEngine._audioContext.currentTime); @@ -212,10 +214,26 @@ var AudioEngine = { return AudioEngine._getMissingAudioBuffer(); } - return AudioEngine._audioContext.decodeAudioData(buffer, function (decodedData) { + var decodeAudioDataPromise = AudioEngine._audioContext.decodeAudioData(buffer, function (decodedData) { AudioEngine.AUDIO_BUFFER_CACHE[src] = decodedData; return AudioEngine.AUDIO_BUFFER_CACHE[src]; }); + + // Safari WebAudio does not return a promise based API for + // decodeAudioData, so we need to fake it if we want to play + // audio immediately on first fetch + if (decodeAudioDataPromise) { + return decodeAudioDataPromise; + } else { + return new Promise(function (resolve, reject) { + var fakePromiseId = setInterval(function() { + if (AudioEngine.AUDIO_BUFFER_CACHE[src]) { + resolve(AudioEngine.AUDIO_BUFFER_CACHE[src]); + clearInterval(fakePromiseId); + } + }, 20); + }); + } }); } }, diff --git a/script/engine.js b/script/engine.js index 8eb6c19..3b17e97 100644 --- a/script/engine.js +++ b/script/engine.js @@ -142,17 +142,10 @@ }); } - // Disable this for now - // $('') - // .addClass('volume menuBtn') - // .text(_('sound on.')) - // .click(() => Engine.toggleVolume()) - // .appendTo(menu); - $('') .addClass('volume menuBtn') - .text(_('sound off.')) - .click(Engine.toggleVolume) + .text(_('sound on.')) + .click(() => Engine.toggleVolume()) .appendTo(menu); $('') @@ -222,7 +215,7 @@ $.Dispatch('stateUpdate').subscribe(Engine.handleStateUpdates); $SM.init(); - // AudioEngine.init(); Disable this for now + AudioEngine.init(); Notifications.init(); Events.init(); Room.init(); @@ -246,24 +239,22 @@ Engine.triggerHyperMode(); } - // Disable this for now - // Engine.toggleVolume(Boolean($SM.get('config.soundOn'))); - // if(!AudioEngine.isAudioContextRunning()){ - // document.addEventListener('click', Engine.resumeAudioContext, true); - // } + Engine.toggleVolume(Boolean($SM.get('config.soundOn'))); + if(!AudioEngine.isAudioContextRunning()){ + document.addEventListener('click', Engine.resumeAudioContext, true); + } Engine.saveLanguage(); Engine.travelTo(Room); - // Disable this for now - // setTimeout(notifyAboutSound, 3000); + setTimeout(notifyAboutSound, 3000); }, resumeAudioContext: function () { AudioEngine.tryResumingAudioContext(); // turn on music! - AudioEngine.setMasterVolume($SM.get('config.soundOn') ? 1.0 : 0.0, 0); + AudioEngine.setMasterVolume($SM.get('config.soundOn') ? 1.0 : 0.0, 0); document.removeEventListener('click', Engine.resumeAudioContext); },