@kreijstal/audacity-wasm
v2026.10.14-build.1
Published
Audacity 4 (master, commit afc26c2, 2026-10-14) for the browser: Qt 6.11 for WebAssembly with threads; opens and saves projects, imports audio (no sound output yet)
Readme
@kreijstal/audacity-wasm
Audacity 4 (master, commit afc26c2, 2026-10-14) for the browser: Qt 6.11 for WebAssembly with threads; opens and saves projects, imports audio (no sound output yet)
Upstream: https://github.com/audacity/audacity
Use
Pinned to this version, from a CDN:
https://cdn.jsdelivr.net/npm/@kreijstal/[email protected]/<file>
https://unpkg.com/@kreijstal/[email protected]/<file>The page
Open index.html (cross-origin isolated, see Steps). ?file=<path> opens that project (.aup3, .aup4) or imports that audio file
into a new project, fetched from <fileUrl><path> (?fileUrl=, default /workspace-file?path=). When Audacity writes an opened
project, the page posts it to the page that embeds it ({type: "audacity-saved", path, bytes}), or offers it as a download.
Sound does not play or record yet: Audacity reaches audio devices through PortAudio, which has no browser backend.
Reproducing this build
Audacity and the libraries it links (muse_deps' recipes: wxWidgets' base library, SQLite, libsndfile, FLAC, Ogg/Vorbis, Opus, mpg123, LAME, TwoLAME, WavPack, soxr, SoundTouch, SBSMS, PortAudio, expat, FreeType, HarfBuzz, zlib) are built from source. Qt is not: its static WebAssembly libraries are The Qt Company's prebuilt wasm_multithread binaries of Qt 6.11.3, installed by aqtinstall and linked in unchanged. The script that produced these files is included as build/build-wasm.sh, with the patches it applies in build/patches/.
Toolchain
- emscripten:
emcc 4.0.7from emsdk (./emsdk install 4.0.7; LLVMclang version 21.0.0git, Binaryenwasm-opt version 123 (version_123-52-ge6f1c53a2)), the version Qt 6.11's WebAssembly build is made with - Qt 6.11.3 for WebAssembly (
wasm_multithread) and the host Qt 6.11.3 (linux_gcc_64, its build tools: moc, rcc, qmlcachegen...) from aqtinstall 3.3.0 - Node.js v22.23.2, CMake 4.4.3, Ninja 1.13.2, Arch Linux
Sources
| Source | Pin |
|---|---|
| audacity/audacity | branch master, commit afc26c22ab4fc1dd27b21b5c86bf410d9a95ac7c (2026-10-14), plus build/patches/audacity-wasm.patch |
| its submodule muse (the MuseScore framework) | commit 1192c1cb14b8c11bf1364610156452b17c2aab44, plus build/patches/muse-wasm.patch |
| its submodule muse_deps (dependency recipes) | commit 436c667326379f78714d8ac703532d77182e70f4, plus build/patches/muse_deps-wasm.patch; each library is fetched and pinned by its recipe |
| Qt for WebAssembly | 6.11.3 wasm_multithread via aqt install-qt all_os wasm 6.11.3 wasm_multithread -m qt5compat qtscxml qtshadertools |
| Host Qt | 6.11.3 linux_gcc_64 via aqt install-qt linux desktop 6.11.3 linux_gcc_64 -m qt5compat qtscxml qtshadertools |
The patches: the Emscripten compiler recognised and every object built with -pthread (Qt is threaded); muse_deps builds every library from source, static, for wasm (wxWidgets without its GUI, iconv from libc, one libz, Nyquist's byte order); the desktop-only parts left out (QProcess, multi-process windows, the single-instance hand-off, PortMixer, VST3, audio.com); muse uses emscripten's filesystem (where SQLite and libsndfile read and write) rather than its in-memory store; Qt5Compat's glow and blur effects drawn with Qt Quick's (their shaders don't link under WebGL 2); Asyncify for the dialogs that wait for an answer; and the page itself (buildscripts/wasm/).
Steps
On Arch Linux. Lay the tree out next to build-wasm.sh (~/git/au4wasm here):
git clone https://github.com/audacity/audacity && git -C audacity checkout afc26c22ab4fc1dd27b21b5c86bf410d9a95ac7c
git -C audacity submodule update --init
git -C audacity apply /path/to/this/package/build/patches/audacity-wasm.patch
git -C audacity/muse apply /path/to/this/package/build/patches/muse-wasm.patch
git -C audacity/muse_deps apply /path/to/this/package/build/patches/muse_deps-wasm.patch
git clone --depth 1 https://github.com/emscripten-core/emsdk && emsdk/emsdk install 4.0.7 && emsdk/emsdk activate 4.0.7
python -m venv venv && venv/bin/pip install aqtinstall==3.3.0
venv/bin/aqt install-qt all_os wasm 6.11.3 wasm_multithread -O qt -m qt5compat qtscxml qtshadertools
venv/bin/aqt install-qt linux desktop 6.11.3 linux_gcc_64 -O qt -m qt5compat qtscxml qtshadertools
./build-wasm.shThe output lands in site/. Linking with Asyncify takes about 11 minutes and 13 GB of memory. Serve the page with cross-origin isolation (Cross-Origin-Opener-Policy: same-origin, Cross-Origin-Embedder-Policy: require-corp or credentialless): its threads need SharedArrayBuffer.
The comment at the top of the build script, verbatim:
Builds Audacity 4 for the browser (Qt for WebAssembly, threads) into site/:
the page (index.html, audacity-web.js, from buildscripts/wasm/ of the patched tree),
audacity.js, audacity.wasm and Qt's qtloader.js.
Expects, next to this script:
audacity/ github.com/audacity/audacity with its submodules (muse, muse_deps),
the wasm patches applied
emsdk/ emsdk with 4.0.7 installed and activated (Qt 6.11's wasm toolchain)
qt/6.11.3/wasm_multithread and qt/6.11.3/gcc_64 Qt from aqtinstall (the wasm build
and the host tools it needs)
muse_deps builds the dependencies (wxWidgets' base library, SQLite, libsndfile,
codecs...) from source as static wasm libraries with -pthread, under build/_deps.Checksums of the published files
e4f482db1a029eb7d61393b6168535159e9525c67669afb7fc68a67552def5e0 audacity.js
595365fe42fa31828f0a390f24192c98e42f8b96a1e7c57052798ee2e4c0d50e audacity.wasm
90dc28d849d5c5dff43eecbbba7c0850386bef7b5d9013a734c5792d62b5cb23 audacity-web.js
47290b02f9fe64e319c7bb0072b5b653199b8c825d5b04e544932617b785b581 index.html
6c29094d01932a6fc4b22051139b47aa84c33653902f6a2d8b2043316b077be9 qtloader.jsLicenses
GPL-3.0-or-later. The license texts of everything compiled in are in LICENSES/.
