Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port Mixxx to Emscripten/WebAssembly #69

Open
11 of 13 tasks
fwcd opened this issue Mar 1, 2024 · 3 comments
Open
11 of 13 tasks

Port Mixxx to Emscripten/WebAssembly #69

fwcd opened this issue Mar 1, 2024 · 3 comments
Labels
enhancement New feature or request help wanted Extra attention is needed port Porting Mixxx and vcpkg dependencies to a new platform

Comments

@fwcd
Copy link
Owner

fwcd commented Mar 1, 2024

Status

The wasm branch contains experimental forks of mixxx and vcpkg for targeting wasm32-emscripten.

You can try it out, there is a GitHub Pages-hosted build at https://fwcd.github.io/m1xxx, but be warned: It may take a while to load (the Wasm binary is ~300 MB, the assets are ~90 MB) and there is no audio (the experimental "Web Audio" backend is not functional yet, hence why it is disabled by default).

Screenshot

On the technical side, there are still some major roadblocks to be resolved:

Something to investigate would be whether we could replace -sASYNCIFY entirely with -sPROXY_TO_PTHREAD, i.e. move the "main" thread to a Web Worker where we can block synchronously. Unfortunately, there seem to be some complexities involved in making this work with Qt:

We may have to check whether setting USE_PTHREADS=1 for Qt would help here (or whether that would be redundant because our vcpkg triplet already sets -pthread).

Another option would be the recently-added C++20 co_await integration, which uses native LLVM coroutines and thus hopefully shouldn't be bound to the same limitations as Asyncify: emscripten-core/emscripten#20413

Given that PortAudio exposes a C interface, I am not sure how well we could integrate C++ coroutines there, however.

Motivation

Being able to run Mixxx on the web would be pretty cool. Qt supports WebAssembly, we would however also have to compile all of the other dependencies. This would probably take some work, but should not be impossible.

We take a similar approach to the iOS port (#16) and use custom WASM branches for mixxx and vcpkg, along with an integration branch in m1xxx, then gradually upstream the required changes.

Porting the dependencies to WebAssembly

  • Configure Qt correctly with GL ES 3.0 and without dbus
  • Fix libflac, libmad and libmodplug
  • Fix sleef build by using fftw as an alternative FFT backend
  • Fix qttools build (or figure out how to remove non-host qttools dependency from qttranslations)
  • Fix undefined _qt_test_emscripten_version in Qt6WasmMacros.cmake during Mixxx configure
    • Patched out in fwcd/vcpkg@e80fbb4, though we may want to look for a better solution before we attempt to upstream this
  • Update Qt to 6.6.2
    • This provides WASM stack traces in log messages and exceptions, which is really useful for debugging

Porting Mixxx to WebAssembly

  • Figure out why WrapRt cannot be found when configuring Mixxx:
    Qt6Core could not be found because dependency WrapRt could not be found.
    
    Digging into FindWrapRt.cmake shows that the check_cxx_source_compiles failed, which (as build/CMakeFiles/CMakeConfigureLog.yaml revealed), failed due a missing clang-scan-deps binary:
    "CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS-NOTFOUND" -format=p1689 -- /opt/emsdk/upstream/emscripten/em++ -DHAVE_STDATOMIC_WITH_LIB  -fdiagnostics-color=auto  -std=gnu++20 -x c++ /Users/fredrik/git/m1xxx-wasm/mixxx/build/CMakeFiles/CMakeScratch/TryCompile-QIjor4/src.cxx -c -o CMakeFiles/cmTC_0948e.dir/src.cxx.o -MT CMakeFiles/cmTC_0948e.dir/src.cxx.o.ddi -MD -MF CMakeFiles/cmTC_0948e.dir/src.cxx.o.ddi.d > CMakeFiles/cmTC_0948e.dir/src.cxx.o.ddi.tmp && mv CMakeFiles/cmTC_0948e.dir/src.cxx.o.ddi.tmp CMakeFiles/cmTC_0948e.dir/src.cxx.o.ddi
    /bin/sh: CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS-NOTFOUND: command not found
    ninja: build stopped: subcommand failed.
    
    Presumably we hit clang-scan-deps is required for CMake 3.28 C++ 20 module support emscripten-core/emscripten#21042, possibly because Mixxx uses C++20 (this would also explain why vcpkg builds of Qt passed, despite running the same FindWrapRt check).
  • Solve this linker error
    wasm-ld: error: --shared-memory is disallowed by sqlite3.c.o because it was not compiled with 'atomics' or 'bulk-memory' features.
    
    The issue is likely that we have to compile (all?) our dependencies with -pthread (as per this discussion). This should in principle be possible via the triplet, just setting VCPKG_C(XX)_FLAGS does not work, however:
    How do I pass compiler/linker arguments to Emscripten? microsoft/vcpkg#30108
    • Fixed by introducing new triplets (wasm32-emscripten-pthread(-release)) and setting
      set(ENV{EMCC_CFLAGS} "$ENV{EMCC_CFLAGS} -pthread")

Upstreaming the Mixxx patches

Upstreaming the vcpkg patches

to microsoft/vcpkg

to mixxxdj/vcpkg

TBD:

to upstream projects

Nice to have

  • CI for Emscripten/WebAssembly
  • Support for local files/persistence
  • Updating the install logic in CMakeLists to produce a proper archive when e.g. cpack -G TGZ is used
    • Currently we get a desktop-like file structure with bin etc.
    • Instead we want a flat directory with mixxx.{data,html,js,wasm,worker.js}, qtloader.js and qtlogo.svg
      • From there, emrun mixxx.html can be used to launch the web app locally

Useful resources

@fwcd fwcd added enhancement New feature or request help wanted Extra attention is needed port Porting Mixxx and vcpkg dependencies to a new platform labels Mar 1, 2024
@fwcd fwcd changed the title Investigate whether we can build Mixxx for WebAssembly Port Mixxx to Emscripten/WebAssembly Mar 4, 2024
@fwcd fwcd pinned this issue Mar 4, 2024
@owlandfox
Copy link

This is awesome! I suggested/requested a web version of MIxxx a couple years ago so its great to see it in progress! I see there are still a couple tasks needed to get it fully operational?

@fwcd
Copy link
Owner Author

fwcd commented Aug 7, 2024

Yes, the UI mostly works (you can try it online), the biggest missing piece is currently the Web Audio backend. Mixing that, Qt and Asyncify seems to be a lot more complicated than I had hoped for, so I've put this project on hold until Qt/Emscripten hopefully work out these interactions.

@owlandfox
Copy link

Wow yes it looks like its all working pretty smoothly otherwise. Hopefully they can solve this soon as I know a lot of users including me will have a great use case for Mixxx in the browser

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed port Porting Mixxx and vcpkg dependencies to a new platform
Projects
None yet
Development

No branches or pull requests

2 participants