2026-03-19
What happened
Spent the day porting fast-vj to WebAssembly via Emscripten. It works — video clips play, shaders run, OSC arrives over a WebSocket bridge — but there's an unresolved slowdown over time that I never tracked down. The port lives on the wasm-port branch and isn't merged into main.
Phase 1 — build scaffolding: The CMakeLists.txt gained an if(EMSCRIPTEN) branch that gates out everything that doesn't exist in the browser: ALSA, libjpeg-turbo, pthreads, UDP sockets. Lua 5.4 source is compiled from scratch (LuaJIT doesn't support WASM). osc.c and mic.c get #ifndef __EMSCRIPTEN__ stubs so the file structure stays uniform. stb_image replaces libjpeg-turbo for frame decode in the WASM path. Native build still compiles cleanly.
OSC via WebSocket: The browser can't open UDP sockets. Built a small stdlib-only Python proxy (tools/osc_proxy.py) that listens on a UDP port and forwards raw OSC binary frames over a WebSocket. On the WASM side, emscripten_websocket_* receives the frames and feeds them into the same tinyosc dispatch path as the native UDP listener. CMakeLists preloads shaders/ and media/ into the Emscripten virtual FS.
Texture and shader fixes: Image textures needed trilinear filtering and repeat wrap mode set explicitly — the defaults that work fine on desktop GLES3 produced artifacts in the browser. Added /vj/pN OSC handlers for shader parameters so the osc_control.lua workflow is accessible from the browser too.
The slowdown: The port runs fine at launch but degrades over time — frame times creep up and eventually the whole thing crawls. I spent a while instrumenting and couldn't find the cause. Most likely a WebGL resource not being freed correctly (streaming texture uploads, or the audio ring buffer), but I didn't nail it. Given the amount of conditional compilation the port introduced, I decided not to merge it into main. The experiment was worth it — the OSC-over-WebSocket design is clean and the build system split is reusable if someone wants to pick it up.
commits: dc29b1d, 4306b74, 24e5538, 3a97a10, 7d3c7e2