maximecb / noisecraft

Browser-based visual programming language and platform for sound synthesis.
https://noisecraft.app
GNU General Public License v2.0
1.06k stars 61 forks source link

Figure out why NoiseCraft doesn't work in Safari #28

Closed maximecb closed 2 years ago

maximecb commented 2 years ago

Currently NoiseCraft doesn't produce audio output in Safari when the Play button is pressed. I haven't investigated the specific reason at all. Help would be most appreciated. If a feature is missing in Safari, we might also want to open an issue on their issue tracker.

magicmouse commented 2 years ago

In AudioView.JS, it crashes in Audioview.js, with the following message:

Exception with thrown value: InvalidStateError: No ScriptProcessor was registered with this name

Source code line:

   this.audioWorklet = new AudioWorkletNode(
        this.audioCtx,
        'sample-generator',
        { outputChannelCount: [2] }
    );

AudioWorkletNode is a browser function, they must not have a sample generator script processor in Safari? Safari is a somewhat laggy browser in terms of features, and IMHO is often the source of problems, esp. on mobile, where Apple just doesn't care given how much moolah their App Store generates (or at least used to until Epic won their epic lawsuit)!

maximecb commented 2 years ago

That script processor is registered by us in public/audioworklet.js.

Safari is supposed to be implementing the AudioWorkletNode API so this should presumably work 🤷‍♀️

maximecb commented 2 years ago

On Safari 15.1 I'm not even seeing any error message in the console, it just produces no audio, with no error reported...

magicmouse commented 2 years ago

The error messages show up in the Safari debugger, not the console log, if you turn on trap exceptions. It stops on that line i listed above, so must be the script processor didn't get registered properly. I should have mentioned this was safari 14.1.2 on OSX.

treefrogman commented 2 years ago

according to caniuse, it is supposed to work on safari 14.1 and up. i have 14.1.2 (14611.3.10.1.7), and when i type AudioW into the console, it offers no autocompletions.

last march, christoph guttandin said

at least for the foreseeable future there will be no audioworkers in safari

@chrisguttandin's standardized-audio-context

uses the ScriptProcessorNode internally to create an AudioWorkletProcessor in Safari. This means it will only provide the performance improvements that you would normally expect from using an AudioWorklet in Chrome, Edge, Firefox and Opera.

i'm trying to get standardized-audio-context working, to see if it fixes the issue, but the installation/import is confusing me. the readme says to npm install it and then import { AudioContext } from 'standardized-audio-context'; but then Chrome throws a TypeError: Module specifier, 'standardized-audio-context' does not start with "/", "./", or "../".

i don't know if this is my naivete getting caught between npm and docker, or something @chrisguttandin needs to hear about

maximecb commented 2 years ago

at least for the foreseeable future there will be no audioworkers in safari

Hm. Welp. Thanks for clarifying that treefrogman. I'm pretty confused as to why Safari doesn't produce a clearer error message if it doesn't support audio worklets 🤦‍♀️

For the JS import, you want to add ./filename. I'd rather not add dependencies on other JS packages that are subject to change though. We could either hack something with the ScriptProcessorNode (not too difficult), or be content with just Chrome, Edge and (soon) Firefox support.

chrisguttandin commented 2 years ago

Hi everyone, I hope it's okay to chime in.

What I said in the video didn't age very well. ;-) Safari meanwhile shipped an Audio Worklet implementation as well. However it's still rough around the edges. It does for example suffer from the same bug as Firefox that you mention in your readme. It can't resolve any import statements in the Audio Worklet code.

Unfortunately this not something I could easily fix in standardized-audio-context. But I do at least keep track of it here: https://github.com/chrisguttandin/standardized-audio-context/search?q=%22bug+%23176%22

I think if you want to use the Audio Worklet right now in every browser the only thing you could do is to pre-bundle the audioworklet.js file.

... But there is a way convince standardized-audio-context to use the ScriptProcessorNode instead of the AudioWorklet which makes NoiseCraft work in Firefox and Safari, too.

Do you want me to submit a PR for that?

maximecb commented 2 years ago

Hi @chrisguttandin. Thanks for chiming in :)

if you want to use the Audio Worklet right now in every browser the only thing you could do is to pre-bundle the audioworklet.js file.

That may be the most portable and efficient solution 🤔

there is a way convince standardized-audio-context to use the ScriptProcessorNode instead of the AudioWorklet which makes NoiseCraft work in Firefox and Safari, too.

How does that work? Is it simply a flag to be specified somewhere? If it's that simple, would be happy to get a PR 👍 If it involves writing some kind of shim, we may want to go with pre-bundling.

chrisguttandin commented 2 years ago

Okay, I created a PR. It's not much code but still very hacky. :-) Feel free to close the PR if you don't like it.

maximecb commented 2 years ago

Ok so, thanks to @chrisguttandin we know that the problem with Safari is the same as with Firefox. Seems that bundling the JS files would fix the problem reliably on all platforms (and improve load times).

maximecb commented 2 years ago

I implemented the bundling with esbuild. It fixes the audio problem in Firefox, but not in Safari. I think there might be another problem 🤔

For example, this now works in Firefox: https://noisecraft.app/140 https://noisecraft.app/12

But in Safari 15.2 it only works intermittently. Sometimes it works, sometimes I get no audio on some tabs (???)