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
Add WebAssembly (wasm) target for scsynth #5309
Conversation
- introduce a hypothetical new audio api 'openal' - some EMSCRIPTEN conditionals - ignore missing boost pthreads for now The cmake command for now is: $ emcmake cmake -DSC_WII=no -DSC_EL=no -DSUPERNOVA=no -DSC_HIDAPI=no -DNO_LIBSNDFILE=yes -DSC_QT=no -DNO_AVAHI=yes -DSC_ABLETON_LINK=no -DCMAKE_BUILD_TYPE="Release" -Wno-dev -s USE_PTHREADS=1 -DPTHREADS_LIBRARY=ignore --target scsynth ..
- until the missing audio API is detected
- we have unstaged commits in `external_libraries/nova-tt`; thus next step will be to commit them in a fork of nova-tt
- use nova-tt fork (branch wasm) - I ran `update --remote`; was this a good idea?
- make succeeds now
- seems we had flags on emcmake that were never passed to emcc - we have a strange linker error regarding shared memory - now with shared memory actually enabled, we cannot run in Firefox without user adjustments - in Chromium, there is an error enumerating audio/video devices - some problem now in boost at boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul>::priv_add_segment(void*, unsigned long) (http://0.0.0.0:8000/scsynth.wasm:wasm-function[4452]:0xceebe) This may be a problem due to assuming _no_ shared memory in previous preprocessor tuning; perhaps we need to remove those diversions again
``` abort @ scsynth.js:1475 ___assert_fail @ scsynth.js:2082 boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul>::priv_add_segment(void*, unsigned long) @ scsynth.wasm:1 boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul>::rbtree_best_fit(unsigned long, unsigned long) @ scsynth.wasm:1 boost::interprocess::segment_manager_base<boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul> >::segment_manager_base(unsigned long, unsigned long) @ scsynth.wasm:1 boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul>, boost::interprocess::iset_index>::segment_manager(unsigned long) @ scsynth.wasm:1 boost::interprocess::ipcdetail::basic_managed_memory_impl<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul>, boost::interprocess::iset_index, 16ul>::create_impl(void*, unsigned long) @ scsynth.wasm:1 boost::interprocess::ipcdetail::create_open_func<boost::interprocess::ipcdetail::basic_managed_memory_impl<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul>, boost::interprocess::iset_index, 16ul> >::operator()(void*, unsigned long, bool) const @ scsynth.wasm:1 void boost::interprocess::ipcdetail::managed_open_or_create_impl<boost::interprocess::shared_memory_object, 16ul, true, false>::priv_open_or_create<boost::interprocess::ipcdetail::create_open_func<boost::interprocess::ipcdetail::basic_managed_memory_impl<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul>, boost::interprocess::iset_index, 16ul> > >(boost::interprocess::ipcdetail::create_enum_t, char const* const&, unsigned long, boost::interprocess::mode_t, void const*, boost::interprocess::permissions const&, boost::interprocess::ipcdetail::create_open_func<boost::interprocess::ipcdetail::basic_managed_memory_impl<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul>, boost::interprocess::iset_index, 16ul> >) @ scsynth.wasm:1 boost::interprocess::ipcdetail::managed_open_or_create_impl<boost::interprocess::shared_memory_object, 16ul, true, false>::managed_open_or_create_impl<boost::interprocess::ipcdetail::create_open_func<boost::interprocess::ipcdetail::basic_managed_memory_impl<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul>, boost::interprocess::iset_index, 16ul> > >(boost::interprocess::open_or_create_t, char const* const&, unsigned long, boost::interprocess::mode_t, void const*, boost::interprocess::ipcdetail::create_open_func<boost::interprocess::ipcdetail::basic_managed_memory_impl<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul>, boost::interprocess::iset_index, 16ul> > const&, boost::interprocess::permissions const&) @ scsynth.wasm:1 boost::interprocess::basic_managed_shared_memory<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0ul>, 0ul>, boost::interprocess::iset_index>::basic_managed_shared_memory(boost::interprocess::open_or_create_t, char const*, unsigned long, void const*, boost::interprocess::permissions const&) @ scsynth.wasm:1 detail_server_shm::server_shared_memory_creator::server_shared_memory_creator(unsigned int, unsigned int) @ scsynth.wasm:1 World_New @ scsynth.wasm:1 ```
- somehow it hangs if we call `EventLoop::run([world]() { World_WaitForQuit(world, true); });` so skip that for now
- add a 'boot' button so we don't run into the problem of having an AudioContext that doesn't start
- so all pieces are in place, OSC messages seem to be correctly encoded - audio driver start/stop now in place - but we get these errors: Uncaught TypeError: Failed to execute 'copyToChannel' on 'AudioBuffer': The provided ArrayBufferView value must not be shared. at ScriptProcessorNode.ad.proc.onaudioprocess (scsynth.js:1688) ad.proc.onaudioprocess @ scsynth.js:1688 It seems that because of `-pthread`, the HEAP is now backed by `SharedArrayBuffer`, and that in turn cannot be used in `copyToChannel`. Hopefully, we can just make one additional copy. If not, we're f*cked :-O
- for example, trying to d_recv analog-bubbles, the first UGen encountered, 'Control' is apparently not installed - probably we need to include some binary file for the emscripten virtual file system
- DiskIO is disabled because we currently don't build with libsndfile (perhaps it's possible -- I don't remember why I had to disable it)
- we need to understand how to allocate (and free) the memory for OSC replies. is web_reply_func called from different threads? Can we just use malloc, or should we use rt memory?
- noticed a bug in `NumOutputBuses`
- extraneous constructor argument `int inNumSamples` was causing crashes
- wasm/configure.sh : use release build type (we're still catching exceptions, though)
- probably the originally missing symbols were due to wrong pthread linker settings - go back to timblechmann's repo
- seems the assertion in rbtree_best_fit.hpp does hold now
- build file seems ok for now
- Module.oscDriver is now a dictionary from virtual port number to an object that at least defines the property `receive`, a function taking two arguments: sender's port, and Uint8Array raw OSC packet.
Thank you for this, @Sciss ! |
Not an expert with git submodules: I ran init and update a few times. How would I revert them? And to what commit? |
I'm not an expert either... |
- needed to do anything more involving like allocating larger buffers
Should this be closed in favor of #5571 ? |
Hello @Sciss |
Definitely interested; I mean I'm using scsynth.wasm. I don't have time resources at the moment, though, so it'll have to wait a bit. I'm happy to comment on questions. |
Thanks, got it. Should we close this PR and move the discussion to #5571 (which has all your commits rebased and with resolved conflicts, AFAIU) or should we close that one and keep the discussion here? Just trying to tidy things up a bit. |
Yes, makes sense, thank you |
(continue conversation in #5571) |
Purpose and Motivation
fixes #5224
Types of changes
To-do list