chiptune2.js icon indicating copy to clipboard operation
chiptune2.js copied to clipboard

web workers

Open kiloliter opened this issue 6 years ago • 4 comments

I tried to use chiptune2.js in a web worker, to see if I could speed up the game I'm making, but I'm kind of lost trying to get it to work.

Can it be used inside a web worker?

Thanks.

kiloliter avatar Nov 30 '18 04:11 kiloliter

Short answer no, not without major changes (i believe)

Long answer I don't think it's possible to play audio from a Web Worker. However you could try to render the raw audio in a worker, send the data to the "main thread" via postMessage an play it from there. I'm not sure whether the messaging interface is fast enough, though.

What you probably want to use instead is the AudioWorklet interface which exists to replace the deprecated ScriptProcessorNode used in this project. It's essentially a Web Worker specifically for audio processing. So it should be right for the task. Unfortunately Firefox doesn't implement it yet, but it's available by default in Chrome.

deskjet avatar Nov 30 '18 13:11 deskjet

Firefox has been supporting AudioWorklets for a while now, so I thought I'd spend an evening and attempt to get this to work.

I've gotten quite far (audio output!), but I've kind of hit a design roadblock that I'd like to discuss before investing more time into this.

Namely, the issue that came up: due to the nature of AudioWorklets, the entire libopenmpt module will live in a completely separate context than the user-facing API of chiptune2.

The only avenue of communication between the two is a MessagePort, which isn't obviously suitable for "call style" (think return values) communication. So although I've gotten audio output to work, I haven't implemented anything else (mostly metadata) that's public API. I think it might still be possible to implement easily, I'm just not versed enough in Javascript to figure this out. Overall, it feels weird to call into the AudioWorklet to get things like metadata, but I don't see an alternative solution to this.

I'll try and publish what I have soon, but I want to clean it up a bit first.

Some notes and caveats for anyone who wants to play along:

  • The currently available emscripten builds for libopenmpt won't cut it because they rely on API that's not available in an AudioWorklet's context. The upcoming libopenmpt 0.6 release will have a suitable build target though. make CONFIG=emscripten EMSCRIPTEN_TARGET=audioworkletprocessor should get you there on latest master.
  • Short of concatenating libopenmpt.js with the AudioWorklet code, the only way I've managed to import libopenmpt is as an ES6 module. EMSCRIPTEN_TARGET=audioworkletprocessor is compatible, although the import is slightly weird:
import libopenmpt from './libopenmpt.js';
const libopenmpt_ = libopenmpt();
// libopenmpt_ will be usable from here on

Maybe there's something obvious I'm missing, but at least calling the imported libopenmpt seems to be necessary.

  • Unfortunately, Firefox does not support ES6 modules in Workers yet: https://bugzilla.mozilla.org/show_bug.cgi?id=1572644

fridtjof avatar Oct 21 '21 01:10 fridtjof

https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/createScriptProcessor

Everything chiptune2.js is uses is deprecated at this point - webworkers is the only futureproof way.

Gargaj avatar Mar 11 '23 00:03 Gargaj

ES6 module version of chiptune using AudioWorklet can be found here: https://github.com/DrSnuggles/chiptune Demo: https://DrSnuggles.github.io/chiptune

DrSnuggles avatar Jan 22 '24 18:01 DrSnuggles