Skip to content

Instantly share code, notes, and snippets.

@juj
Created February 28, 2023 16:44
Show Gist options
  • Save juj/f04505d5af0a32580a8d9341c7cbbfb8 to your computer and use it in GitHub Desktop.
Save juj/f04505d5af0a32580a8d9341c7cbbfb8 to your computer and use it in GitHub Desktop.
Emscripten WebAssembly Audio Worklets example
#include <emscripten/webaudio.h>
#include <emscripten/em_math.h>
float phase = 0.f;
EM_BOOL ProcessAudio(int numInputs, const AudioSampleFrame *inputs,
int numOutputs, AudioSampleFrame *outputs,
int numParams, const AudioParamFrame *params, void *userData) {
for(int i = 0; i < 128; ++i) {
outputs[0].data[i] = emscripten_math_sin(phase);
phase = emscripten_math_fmod(phase + 0.05f, 2.f * EM_MATH_PI);
}
return EM_TRUE;
}
char stack[4096];
int main() {
EMSCRIPTEN_WEBAUDIO_T context = emscripten_create_audio_context(0);
emscripten_start_wasm_audio_worklet_thread_async(context, stack, sizeof(stack), [](EMSCRIPTEN_WEBAUDIO_T context, EM_BOOL success, void *userData) {
WebAudioWorkletProcessorCreateOptions opts = { .name = "my-processor-class" };
emscripten_create_wasm_audio_worklet_processor_async(context, &opts, [](EMSCRIPTEN_WEBAUDIO_T context, EM_BOOL success, void *userData){
int outputChannelCounts[1] = { 1 };
EmscriptenAudioWorkletNodeCreateOptions options = {
.numberOfInputs = 0,
.numberOfOutputs = 1,
.outputChannelCounts = outputChannelCounts
};
EMSCRIPTEN_AUDIO_WORKLET_NODE_T workletNode = emscripten_create_wasm_audio_worklet_node(context, "my-processor-class", &options, &ProcessAudio, 0);
EM_ASM({
let context = emscriptenGetAudioObject($0);
let workletNode = emscriptenGetAudioObject($1);
workletNode.connect(context.destination);
let button = document.body.appendChild(document.createElement('button'));
button.innerHTML = 'Start';
button.onclick = () => { context.resume(); };
}, context, workletNode);
}, 0);
}, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment