bvibber / audio-feeder

Small JS library to abstract Web Audio raw PCM output
Other
53 stars 7 forks source link

onstarved never called in Flash path #13

Closed bvibber closed 8 years ago

bvibber commented 8 years ago

Hmm, since there's no way to get more samples back from the app in time, not sure how useful it will be.

bvibber commented 8 years ago

Maybe better to add an intended event...

bvibber commented 8 years ago

On ended

dy commented 8 years ago

+1. Tested in win7/IE11. Initial buffer plays, but onstarved never called, so for now it is impossible to stream anything into it.

I am thinking to switch to audio-feeder in audio-speaker, your package looks very promising. There is also a different way to organize web-audio-api backend via AudioBufferSource node, see implementation. That approach looks more reliable due to the fact that buffer (in principle) keeps playing even if GC hits (though scriptProcessor seem to do the same), and also scriptProcessorNode is deprecated in WAA.

bvibber commented 8 years ago

Clever use of AudioBufferSource! Definitely worth trying that as an alternate backend. One downside I see is that the timer will get throttled if the tab is in the background, which could lead to the tick function not getting called often enough to fill data.

With a scriptProcessorNode, by hooking a callback into the audioprocessing event we get called on time even in a background tab. I think we can bounce that event asynchronously via window.postMessage (or setImmediate in Edge) to keep the callback out of the critical audio output path, but will have to confirm that that doesn't get throttled either.

(For Flash I may have to use a primitive setTimeout(callback, 0) but I don't think IE 11 throttles background tabs so that's fine.)

If browsers are actually supporting the AudioWorker interface that's supposed to replace scriptProcessorNode I'd be happy to support that as well, though need to double-check the docs for details...

I think what I'm going to do with the onstarved event is to supplement it with an onprogress event that's called asynchronously, either every output buffer boundary or when the buffer depth reaches a given low-water threshold. That should cover streaming cases -- for instance in ogv.js that can drive continued audio decoding even in background tabs, where currently I rely too much on timers that get throttled.