Tonejs / Tone.js

A Web Audio framework for making interactive music in the browser.
https://tonejs.github.io
MIT License
13.56k stars 989 forks source link

Offline Rendering in iOS #234

Closed softpunch closed 7 years ago

softpunch commented 7 years ago

I'm not sure if this should be considered a bug in Tone or an issue with iOS.

Offline Rendering of Web Audio can't begin in iOS until after a user action.

The Tone examples page contains a solid test case.

https://tonejs.github.io/examples/#offline

On an up-to-date iPhone SE with Chrome & Safari, the button says "Rendering..." and it never changes to "Play." Touching the button has no apparent effect.

(It works as expected on my Pixel using Chrome.)

softpunch commented 7 years ago

It appears the MDN OfflineRendering example produces the same result (silence) on iOS in Chrome and Safari.

That's particularly notable given that it makes an Offline XML/XHR Request rather than generating audio offline. I suppose that makes this an iOS issue rather than a Tone issue.

https://mdn.github.io/webaudio-examples/offline-audio-context-promise/

tambien commented 7 years ago

Thanks for following up. Yeah, i've noticed how it doesn't render until there is a user action. I might try to tackle that in StartAudioContext.

softpunch commented 7 years ago

It may actually be a deeper bug.

I can't get any OfflineAudioContext instances to work on iOS. I tried using both iOS 9.3 and 10.2 in the XCode simulator, to ensure it isn't just the latest version that's having trouble.

Here's my minimal OfflineAudioContext test case: https://jsfiddle.net/softpunch/0hjdp4gb/

And just to ensure Web Audio is working on iOS in general, here's a minimal "play oscillator" script for comparison: https://jsfiddle.net/softpunch/zgpdjwar/

Is it possible that OfflineAudioContext never actually shipped for Safari & Chrome on iOS?

softpunch commented 7 years ago

To be clear: In my test case, I provided two separate user actions for offline rendering and playback.

softpunch commented 7 years ago

It might be possible to shim the OfflineAudioContext into iOS.

@tambien -- Have you seen this pure JS implementation of [most of] the web audio API? https://github.com/mohayonao/web-audio-engine

Here's a list of what has and hasn't been implemented: https://github.com/mohayonao/web-audio-engine/wiki/Compatibility-Comparison

There's also a super useful spec checker: https://github.com/mohayonao/web-audio-api-spec-checker

And a partially-complete shim, with its own compatibility-checker: https://github.com/mohayonao/web-audio-api-shim (Using the supplied checker, I wasn't able to get the Offline shim to validate on my iOS simulator. But either it or the web-audio-engine implementation may still work!)

--

If the OfflineContext implementation doesn't work out, this audio worker shim also looks very promising: https://github.com/mohayonao/audio-worker-compiler

And just for kicks (well... more for strings, heh), here's a really impressive Karplus-Strong implementation: https://github.com/mohayonao/pluck-string-node

Basically, I recommend all of Mohayonao's repos, haha. (Including Mohayonao's framework, Timbre.js!)

If there's any way I could help get an iOS OfflineAudioContext implementation into Tone, faked or shimmed or whatever, just let me know!

tambien commented 7 years ago

@softpunch would be great to file a bug somewhere with Apple.

I looked into the web-audio-engine for the potential of one day supporting Tone in Node.js which would be awesome. all @mohayonao's repos are all pretty amazing.

sedubois commented 7 years ago

I guess safari bugs can be filed at https://bugs.webkit.org.

softpunch commented 7 years ago

Cool. I'll file it!

tomduncalf commented 7 years ago

Hey @softpunch, I've been doing a bit more research into this and seems that offlineAudioContext isn't totally broken in iOS, but it is definitely a bit weird. https://github.com/Tonejs/Tone.js/issues/237 if you are interested or have any thoughts!