mattgodbolt / jsbeeb

Javascript BBC micro emulator
GNU General Public License v3.0
351 stars 68 forks source link

No sound in Safari browser on Mojave #186

Closed lurkio closed 5 years ago

lurkio commented 5 years ago

As per the subject. JSBeeb produces no sound of any kind in Safari v12.1.1 on macOS Mojave v10.14.5.

Sound works on Mojave in Firefox though.

mattgodbolt commented 5 years ago

Thanks! Is there anything obvious in the Javascript console? Does clicking in the jsbeeb display "fix" it? Some browsers are starting to make sure the user interacts with the site before they allow it to make annoying noises. e.g. #184

lurkio commented 5 years ago

Thanks! Is there anything obvious in the Javascript console?

I'll have a look.

Does clicking in the jsbeeb display "fix" it? Some browsers are starting to make sure the user interacts with the site before they allow it to make annoying noises. e.g. #184

Doesn't make any difference. :-(

lurkio commented 5 years ago

Here's the JS console output in the Safari browser on macOS 10.14.6 Mojave:

[Log] GL Canvas set up (main-e45ea3536538dc7654fe22627f2d1af01c926b08.js, line 11533) [Log] Loading OS from roms/os.rom (main-e45ea3536538dc7654fe22627f2d1af01c926b08.js, line 8260) [Log] 1.382716049382716 – 1.382716049382716 (main-e45ea3536538dc7654fe22627f2d1af01c926b08.js, line 12930) [Log] Loading ROM from roms/BASIC.ROM (main-e45ea3536538dc7654fe22627f2d1af01c926b08.js, line 8243) [Log] Loading ROM from roms/b/DFS-0.9.rom (main-e45ea3536538dc7654fe22627f2d1af01c926b08.js, line 8243) [Log] Using physical key layout (main-e45ea3536538dc7654fe22627f2d1af01c926b08.js, line 6556) [Error] The source list for Content Security Policy directive 'script-src' contains an invalid source: ''report-sample''. It will be ignored. [Error] The source list for Content Security Policy directive 'script-src' contains an invalid source: ''strict-dynamic''. It will be ignored. [Error] [Report Only] Refused to execute a script because its hash, its nonce, or 'unsafe-inline' does not appear in the script-src directive of the Content Security Policy. (proxy.html, line 0) [Log] Google Drive: available (main-e45ea3536538dc7654fe22627f2d1af01c926b08.js, line 10128) [Log] Authorizing – true (main-e45ea3536538dc7654fe22627f2d1af01c926b08.js, line 10137) [Error] The source list for Content Security Policy directive 'script-src' contains an invalid source: ''strict-dynamic''. It will be ignored. [Error] Refused to execute a script because its hash, its nonce, or 'unsafe-inline' does not appear in the script-src directive of the Content Security Policy. (iframe, line 0) [Log] Loading disc from discs/elite.ssd (main-e45ea3536538dc7654fe22627f2d1af01c926b08.js, line 8943) [Log] Google Drive: Need to auth (main-e45ea3536538dc7654fe22627f2d1af01c926b08.js, line 10149) [Log] authed = – false (main-e45ea3536538dc7654fe22627f2d1af01c926b08.js, line 12501) [Log] 1.382716049382716 – 1.382716049382716 (main-e45ea3536538dc7654fe22627f2d1af01c926b08.js, line 12930)

mattgodbolt commented 5 years ago

Thanks @lurkio . Sadly nothing obvious in there...I was hoping to see some web audio errors. But it seems like jsbeeb thinks it's making noises, but nothing's happening!

lurkio commented 5 years ago

Thanks @lurkio . Sadly nothing obvious in there...I was hoping to see some web audio errors. But it seems like jsbeeb thinks it's making noises, but nothing's happening!

Anything else I can do to try and diagnose the problem? (I haven't a clue when it comes to JS, sadly.)

lurkio commented 5 years ago

@mattgodbolt Does this attached screenshot mean anything to you? The audioContext object seems to have a "state" property with a value of "suspended", which seems a bit suspicious..? (Caveat: again, I don't really have a clue what I'm talking about.)

Screenshot 2019-08-13 at 18 19 27
richtw1 commented 5 years ago

@lurkio: Does typing soundChip.jsAudioNode.context.resume() on the console bring the sound back for you?

lurkio commented 5 years ago

@lurkio: Does typing soundChip.jsAudioNode.context.resume() on the console bring the sound back for you?

No. There's still no sound.

lurkio commented 5 years ago

@lurkio: Does typing soundChip.jsAudioNode.context.resume() on the console bring the sound back for you?

No. There's still no sound.

See attached screenshot.

Screenshot 2019-08-14 at 16 33 37
richtw1 commented 5 years ago

Your system has instanced webkitAudioContext instead of AudioContext (as per mine). Maybe webkitAudioContext isn't working properly? No idea about this API unfortunately.

lurkio commented 5 years ago

@richtw1:

Your system has instanced webkitAudioContext instead of AudioContext (as per mine). Maybe webkitAudioContext isn't working properly? No idea about this API unfortunately.

Through an amazing process of blindly typing things that I don't understand into the console, I managed to get sound working! I referred to this webpage:

https://www.mattmontag.com/web/unlock-web-audio-in-safari-for-ios-and-macos

I modified the code there, and then pasted it into the console of a new running instance of JSBeeb:

const audioCtx = soundChip.jsAudioNode.context;

function unlockAudioContext(audioCtx) {
  if (audioCtx.state !== 'suspended') return;
  const b = document.body;
  const events = ['touchstart','touchend', 'mousedown','keydown'];
  events.forEach(e => b.addEventListener(e, unlock, false));
  function unlock() { audioCtx.resume().then(clean); }
  function clean() { events.forEach(e => b.removeEventListener(e, unlock)); }
}

unlockAudioContext(audioCtx);

I was then able to type VDU 7 into the emulator and get a beep out of it for the first time ever!

1
richtw1 commented 5 years ago

Nice! Sounds as if maybe adding a resume() into keyDown() might well fix your issue, as well as Chrome's, as per my suggestion in #184 .

scarybeasts commented 5 years ago

@mattgodbolt @richtw1 I don't have Safari so if one of you could check Safari (on Mojave I suppose) before approving, that would be great. It should work because the standard here is pretty clear but Firefox was a bit finicky so you never know.

lurkio commented 5 years ago

@scarybeasts I just tested by deploying your branch on Netlify. It works in Safari on Mojave.

Orange no-sound warning banner comes up at first but goes away on click/keypress, and then sound is on! Many thanks!

scarybeasts commented 5 years ago

@lurkio Thanks for checking! That's awesome that it works. Out of curiosity, does Safari remember this "preference" at all?

Chrome has all sorts of rules: https://developers.google.com/web/updates/2018/11/web-audio-autoplay

Reading Chrome's rules, the good news is that a site structured like bbcmicro.co.uk might work without user interaction in the first place, since the user launches a game by interacting with the site, with jsbeeb hosted same origin.

lurkio commented 5 years ago

Out of curiosity, does Safari remember this "preference" at all?

No, the warning banner comes up every time.

scarybeasts commented 5 years ago

@lurkio Interesting! Perhaps annoying if it persists.

On Chrome, the warning was coming up every time for me but then it stopped. I think what may have happened is that a new day rolled over, and Chrome now has metadata that I sort of "liked" (permitted and didn't closed sound for) the web origin yesterday so it should be permitted to autoplay going forward.

lurkio commented 5 years ago

@scarybeasts Just to mention that your fix seems to have enabled sound in Safari on iOS too, where there was previously no sound at all, just as on Mojave.

So now JSBeeb can produce sound on iOS although there's obviously still no keyboard support.