websim: extend the web simulator to all logue-SDK platforms - #212
Open
wilvk wants to merge 6 commits into
Open
Conversation
Adds the compile path that lets every logue-SDK platform build its DSP to
WebAssembly:
- websim/wasm.mk shared `wasm` / `wasm-build` / `render` targets for gen-2
- websim/legacy.mk the same for gen-1 (nutekt-digital, minilogue-xd, prologue)
- websim/dsp/** firmware-ROM stand-ins and per-platform bridges
(microKORG2 incl. NEON/SIMD compat, drumlogue, gen-1)
- platform/** a wasm.cc shim + wasm target for each unit
The NTS-1 mkII / NTS-3 projects move from a duplicated inline `wasm:` recipe
to including the shared fragment. microKORG2's SIMD utility headers gain
non-NEON fallbacks so the same sources compile under Emscripten.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A synth unit built around drumlogue-specific capabilities: on-board PCM sample-bank access via the runtime descriptor (get_num_sample_banks / get_num_samples_for_bank / get_sample), the Linux/Cortex-A7 C++ runtime, and gate-based drum triggering with per-hit velocity. Browses sample banks live (showing real on-device sample names), resamples the selected sample with linear interpolation, and shapes it with a decay envelope, pitch-sweep envelope, bit-depth reduction, drive, and pan. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two nutekt-digital (gen-1) units that exercise the legacy build path both on hardware and through websim/legacy.mk. twosaw derives its websim parameter table from manifest.json via gen_legacy_params.py rather than a hand-written macro. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Reworks the three shell pages so a unit compiled by wasm.mk/legacy.mk can be driven from the browser: a playback toggle that survives a reload, master volume, a QWERTY keyboard with octave switching and latch, parameter sliders built from the unit's own descriptor, and time/frequency scopes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
make websim PROJECT=<path|name> build one unit and open it via emrun make list / clean / setup discover projects, clean, bootstrap emsdk make render / render-all headless WAV render + finite-output check make build-all compile every wasm-capable unit (CI gate) WEBSIM.md documents the flow end to end; the GitHub workflow runs build-all and render-all so the wasm build and audio output stay green without a browser. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The comments cited WEBSIM_FOLLOWUP_PLAN.md / WEBSIM_EXPANSION_PLAN.md, which are working notes that live outside the SDK tree. Comment text only; no code or build changes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
This is an incredible contribution. Hopefully the KORG team can find the time to test and approve this as it would greatly increase the value of their products. |
Contributor
|
Thank you for putting this together. I will take some time to review it. |
xiashj24
self-requested a review
August 12, 2026 01:46
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends the existing web simulator so that every logue-SDK platform can build its DSP to
WebAssembly and run in the browser, not just NTS-1 mkII and NTS-3.
Today
websim/supports the two gen-2 NTS platforms via awasm:recipe duplicated inline ineach project Makefile. This PR factors that recipe into a shared build fragment and adds the
host-side bridges needed by the other platforms, so the same
unit.ccthat ships to hardwarealso runs in a browser tab for microKORG2, drumlogue, and the gen-1 targets
(prologue / minilogue xd / NTS-1 mkI).
Nothing about the hardware build changes: no linker scripts, no CMSIS, no
_unit_base.c, andno ARM build flags are touched. The wasm path is additive.
What's here
websim/wasm.mkwasm/wasm-build/rendertargets, extracted from the per-project recipe that was duplicated in every NTS project Makefilewebsim/legacy.mkwebsim/dsp/**platform/**wasm.ccshim and a wasm target for each unitMakefile(new, repo root)make websim PROJECT=…to build and open one unit;make list,make clean,make setupWEBSIM.mdExisting NTS projects
The 8 NTS-1 mkII / NTS-3 project Makefiles lose their inline
wasm:block in favour ofSame emcc invocation, same output — one copy instead of eight.
Bug fixes in
platform/microkorg2/common/utils/Building microKORG2 units without NEON exercised the
#elsebranches of the SIMD helpers,which turn out not to compile as written. These are fixed here because the wasm build needs
them, but they are latent bugs in the non-NEON path regardless of websim:
int_simd.h— six*_strmacros are missing a statement terminator:do { *(int32x4_t *)(ptr) = (v) } while (0);. Any use is a syntax error.Affects
s32x4_str,s32x2x2_str,s32x4x2_strand theu32equivalents.int_simd.h—const int2x2_t tmp = …in the non-NEONcliphelper names a type thatdoes not exist; it should be
int32x2_t.float_simd.h— the non-NEONvtrn/vzip/vuzphelpers declareconst float32x2x2_t v;and then assign tov.val[0], which is an assignment to a constobject. Also switches the
{{…}}aggregate initialisers to the vector constructors.These are worth reviewing on their own merits — happy to split them into a separate PR if you
would prefer to take them independently of the websim work.
The other two files in that directory are guarded so the ARM build is byte-identical:
cortexa7_intrinsics.h— the Cortex-A7 DSP ops are inline ARM assembly that clang cannotassemble for wasm. Portable equivalents with matching saturating semantics are provided under
#ifdef __EMSCRIPTEN__. One caveat:SELdepends on theAPSR.GEflags set by a precedingSIMD instruction, which cannot be reproduced standalone, so the shim returns its first
operand — the same compromise as the existing gen-1
__SELshim.mk2_utils.h—__builtin_prefetchrequires constant arguments under clang/wasm, soPrefetchMemorybecomes a no-op under#ifdef __EMSCRIPTEN__.Example units
Three new units, included because they exercise build paths the existing templates don't:
platform/drumlogue/sample-voice(SmplVox) — a sample-playback drum voice; the firstdrumlogue unit that uses the sample bank API.
platform/nutekt-digital/twosaw— a gen-1 oscillator that derives its websim parametertable from
manifest.jsonrather than a hand-written macro.platform/nutekt-digital/tremolo— a gen-1 modfx example.Happy to drop these from this PR if you'd rather keep it to the build system alone.
Verification
Both gates run from a clean checkout with a pinned Emscripten (4.0.16):
build-allcompiles and links every wasm-capable unit across all six platforms.render-allbuilds each unit in a headless render mode (no AudioWorklet), runs it under node,and asserts the output WAV is finite — catching crashes and numerical blow-ups without a
browser. Both are wired into
.github/workflows/websim.yml.Browser behaviour was checked by hand per unit: page loads cross-origin-isolated, the keyboard
drives pitch for oscillators, input plays through for effects, and every parameter slider
audibly changes the sound.
On the CI workflow: if you would rather not take a GitHub Actions workflow from an outside
contributor, say so and I'll drop
.github/workflows/websim.yml— thebuild-allandrender-alltargets stand on their own and can be run manually or wired up however you prefer.Notes for review
arm_neon.hfor drumlogue, and recentenough to reject
-I …/emscripten/system/include). The workflow pins 4.0.16.vox,MorphEQ,MultitapDelay,Vibrato,breveR)build through a struct-shape SIMD shim rather than SIMDe; see
WEBSIM.md.render checks are tolerance-based rather than golden-file comparisons.
voxopts into 4-voice polyphony viaMK2_OSC_VOICES.