Skip to content

wasm: enable AudioWorklets with JSPI to fix no-sound on web#88

Closed
Copilot wants to merge 2 commits intomasterfrom
copilot/fix-web-version-sound-issue
Closed

wasm: enable AudioWorklets with JSPI to fix no-sound on web#88
Copilot wants to merge 2 commits intomasterfrom
copilot/fix-web-version-sound-issue

Conversation

Copy link

Copilot AI commented Mar 25, 2026

Web audio was broken because miniaudio's AudioWorklet initialization calls emscripten_sleep() in a spin-wait, which requires JSPI — but sokol's RAF callback (_sapp_emsc_frame_animation_loop) was not wrapped with WebAssembly.promising, causing SuspendError: trying to suspend without WebAssembly.promising.

Changes

  • make.lua

    • Add MA_ENABLE_AUDIO_WORKLETS (switches miniaudio from deprecated ScriptProcessorNode to AudioWorklets)
    • Add -sJSPI, -sAUDIO_WORKLET=1, -sWASM_WORKERS=1
    • Remove -sMAIN_MODULE=1 — incompatible with -sWASM_WORKERS=1
  • src/platform/wasm/soluna_audio_wasm.js (new)
    Overrides emscripten_request_animation_frame_loop to wrap the WASM frame callback with WebAssembly.promising(), making it a valid JSPI suspension point. Falls back to a synchronous call when JSPI is unavailable.

    emscripten_request_animation_frame_loop: function(cb, userData) {
      var fn = getWasmTableEntry(cb);
      var promisingFn = WebAssembly.promising?.(fn) ?? null;
      function tick(rAF_time) {
        if (promisingFn) {
          promisingFn(rAF_time, userData).then(keepGoing => {
            if (keepGoing) requestAnimationFrame(tick);
          });
        } else {
          if (fn(rAF_time, userData)) requestAnimationFrame(tick);
        }
      }
      requestAnimationFrame(tick);
    }

    During the first frame where render_init runs, the audio worklet thread initializes asynchronously; each emscripten_sleep(1) in miniaudio's spin-wait suspends the WASM stack via JSPI and yields to the browser event loop until initResult transitions from MA_BUSY to MA_SUCCESS. Subsequent frames are unaffected.

Note: Removing MAIN_MODULE=1 breaks the extlua dynamic-loading demo on web until that module is ported to static linking.


📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.

- Add MA_ENABLE_AUDIO_WORKLETS define to enable miniaudio's AudioWorklet
  path for WASM builds
- Add -sJSPI, -sAUDIO_WORKLET=1, -sWASM_WORKERS=1 emscripten flags
- Remove -sMAIN_MODULE=1 (incompatible with -sWASM_WORKERS=1)
- Remove emscripten_builtin_memalign exports (no longer needed without MAIN_MODULE)
- Create src/platform/wasm/soluna_audio_wasm.js: override
  emscripten_request_animation_frame_loop to wrap the RAF callback with
  WebAssembly.promising() so that emscripten_sleep() called during
  miniaudio's audio worklet initialization uses JSPI suspension instead
  of throwing a SuspendError

Co-authored-by: cloudwu <729648+cloudwu@users.noreply.github.com>
Agent-Logs-Url: https://github.com/cloudwu/soluna/sessions/21adb45c-8735-4dda-8cd7-3ce5749dcbff
Copilot AI changed the title [WIP] Fix sound issue in web version wasm: enable AudioWorklets with JSPI to fix no-sound on web Mar 25, 2026
Copilot AI requested a review from cloudwu March 25, 2026 15:25
@yuchanns
Copy link
Contributor

我尝试部署了这个分支, 结果一样有

VM56 soluna.wasm:1  Uncaught (in promise) SuspendError: trying to suspend JS frames
    at VM56 soluna.wasm:1:494979
    at VM56 soluna.wasm:1:542218
    at VM56 soluna.wasm:1:560058
    at VM56 soluna.wasm:1:621739
    at VM56 soluna.wasm:1:620623
    at VM56 soluna.wasm:1:508042
    at VM56 soluna.wasm:1:544631
    at VM56 soluna.wasm:1:611598
    at VM56 soluna.wasm:1:362522
    at VM56 soluna.wasm:1:209337

@yuchanns yuchanns mentioned this pull request Mar 25, 2026
@cloudwu
Copy link
Owner

cloudwu commented Mar 26, 2026

问题已解决,并不需要这个方案。

@cloudwu cloudwu closed this Mar 26, 2026
@cloudwu cloudwu deleted the copilot/fix-web-version-sound-issue branch March 26, 2026 03:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants