chiptune2.js
chiptune2.js copied to clipboard
web workers
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.
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.
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
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.
ES6 module version of chiptune using AudioWorklet can be found here: https://github.com/DrSnuggles/chiptune Demo: https://DrSnuggles.github.io/chiptune