Port of JUCE for the browser via Emscripten
Based on Dreamtonics/juce_emscripten. Play with JUCE DemoRunner in your browser.
Main goal of this fork is updating juce
to 6.1.6
;
-
Add networking support.
- Create a
juce_core/native/juce_emscripten_Network.cpp
similar to othersjuce_core/native/juce_<platform>_Network.cpp
that use emscripten's fetch api; - Alteratively, use the emscripten fetch API in the client code instead of
JUCE::URL::downloadToFile
;
- Create a
-
Replace
JUCE_EMSCRIPTEN
withJUCE_WASM
(maybe?) -
Proper dark mode detection (See
Desktop::NativeDarkModeChangeDetectorImpl
injuce_emscripten_Windowing.cpp
)
-
Link Error:
wasm-ld: error: --shared-memory is disallowed by sfnt.c.o because it was not compiled with 'atomics' or 'bulk-memory' features.
- Solution (found here):
- Add
-pthread
to/opt/homebrew/Cellar/emscripten/3.1.8/libexec/tools/ports/sdl2.ttf
:33 and/opt/homebrew/Cellar/emscripten/3.1.8/libexec/tools//ports/freetype.py
:91; - Run
emcc --clear-port
;
- Add
- Solution (found here):
-
JS Console error:
SharedArrayBuffer is not defined
- Solution: add the response headers
Cross-Origin-Opener-Policy: same-origin
andCross-Origin-Embedder-Policy: require-corp
in the server. You can "fake" these with a chrome plugin like this one.
- Solution: add the response headers
juce_analytics
: not supportedjuce_audio_basics
: fully supportedjuce_audio_devices
: partial support- Audio input: not supported
- Audio output: supported through Emscripten's OpenAL API (
OpenALAudioIODevice
) - MIDI input/output: supported through Web MIDI by defining
JUCE_WEBMIDI=1
(enabled by default)
juce_audio_formats
: fully supportedjuce_audio_plugin_client
: not supported (with no plan to port)juce_audio_processors
: partial support (no supported plugin format)juce_audio_utils
: fully supportedjuce_box2d
: fully supportedjuce_core
: all except network andMemoryMappedFile
are supported- File: based on Emscripten's memory file system; directories such as
/tmp
and/home
are created on startup. - Logging:
DBG(...)
prints to console (std::cerr
), not emrun console. - Threads: without
-s PROXY_TO_PTHREAD=1
linker flag, threading is subjected to some platform-specific limitations - notably, the program will hang if you spawn new threads from the main thread and wait for them to start within the same message dispatch cycle. Toggle this linker flag to run the message loop on a pthread and you will have full threading support. - SystemStats: operating system maps to browser
userAgent
info; number of logical/physical CPUs isnavigator.hardwareConcurrency
; memory size is javascript heap size, which could be different from what's available to WASM module; CPU speed is set to 1000 MHz.
- File: based on Emscripten's memory file system; directories such as
juce_cryptography
: fully supportedjuce_data_structures
: fully supportedjuce_dsp
: all except SIMD features are supportedjuce_events
: fully supported; the message loop is synchronized with browser repaints.juce_graphics
: fully supported; font rendering is based on freetype.juce_gui_basics
: mostly supported- Clipboard: the first paste will fail due to security restrictions. With the user's permission, following pastes will succeed.
- Input Method: works but without showing the characters being typed in until finish.
- Native window title bar: not supported.
- Native dialogs: not supported. File open/close dialogs are especially tricky. Passing data in and out is not hard if we use HTML5 input, however, interfacing with the in-memory file system is the real problem.
juce_gui_extra
: fully supportedjuce_opengl
: not supportedjuce_osc
: not supportedjuce_product_unlocking
: all supported except features that depend on networking.juce_video
: not supported.
- Download Emscripten
- install Emscripten
# Fetch the latest registry of available tools.
./emsdk update
# Download and install the latest SDK tools.
./emsdk install latest
# Make the "latest" SDK "active"
./emsdk activate latest
# Set the current Emscripten path on Linux/Mac OS X
source ./emsdk_env.sh
- compile the sample
cd examples/DemoRunner/Builds/Emscripten/
emmake make
cd build
python -m SimpleHTTPServer
Note: I had to modify the auto-generated Makefile to get everything to work. So be carefull when you modify and save the jucer project. In the long run, it would be nice to have a emscripten target inside Projucer.
As of late 2019, stable and beta releases of Firefox have SharedArrayBuffer
support removed due to security concerns (brought by Spectre/Meltdown). Nightly builds do have the support but they also require Cross-Origin-Opener-Policy
and Cross-Origin-Embedder-Policy
attributes being set in the HTTP header.
A quick and dirty way to bypass this restriction is to go to about:config
and set dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled
to true. However, this is a bit risky and is not the best way of doing this.
The better way is to (1) set the attributes mentioned above in the server you're hosting the WASM application and (2) enable CORP/COEP flags in Firefox. See this issue in the Emscripten repository for detailed instructions.
[English] https://atsushieno.github.io/2020/01/01/juce-emscripten-the-latest-juce-on-webassembly.html
[Japanese] http://atsushieno.hatenablog.com/entry/2020/01/01/121050
See JUCE licensing below.
Lato (The Font I used for the example) is licensed under SIL Open Font License.
JUCE is an open-source cross-platform C++ application framework used for rapidly developing high quality desktop and mobile applications, including VST, AU (and AUv3), RTAS and AAX audio plug-ins. JUCE can be easily integrated with existing projects or can be used as a project generation tool via the Projucer, which supports exporting projects for Xcode (macOS and iOS), Visual Studio, Android Studio, Code::Blocks, CLion and Linux Makefiles as well as containing a source code editor and live-coding engine which can be used for rapid prototyping.
The JUCE repository contains a master and develop branch. The develop branch contains the latest bugfixes and features and is periodically merged into the master branch in stable tagged releases (the latest release containing pre-built binaries can be also downloaded from the JUCE website).
The repository doesn't contain a pre-built Projucer so you will need to build it for your platform - Xcode, Visual Studio and Linux Makefile projects are located in extras/Projucer/Builds (the minumum system requirements are listed in the System Requirements section below). The Projucer can then be used to create new JUCE projects, view tutorials and run examples. It is also possible to include the JUCE modules source code in an existing project directly, or build them into a static or dynamic library which can be linked into a project.
For further help getting started, please refer to the JUCE documentation and tutorials.
- macOS: macOS 10.11 and Xcode 7.3.1
- Windows: Windows 8.1 and Visual Studio 2015 64-bit
- Linux: GCC 4.8
- macOS: macOS 10.7
- Windows: Windows Vista
- Linux: Mainstream Linux distributions
For bug reports and features requests, please visit the JUCE Forum - the JUCE developers are active there and will read every post and respond accordingly. When submitting a bug report, please ensure that it follows the issue template. We don't accept third party GitHub pull requests directly due to copyright restrictions but if you would like to contribute any changes please contact us.
The core JUCE modules (juce_audio_basics, juce_audio_devices, juce_blocks_basics, juce_core and juce_events) are permissively licensed under the terms of the ISC license. Other modules are covered by a GPL/Commercial license.
There are multiple commercial licensing tiers for JUCE 5, with different terms for each:
- JUCE Personal (developers or startup businesses with revenue under 50K USD) - free
- JUCE Indie (small businesses with revenue under 200K USD) - $35/month
- JUCE Pro (no revenue limit) - $65/month
- JUCE Educational (no revenue limit) - free for bona fide educational institutes
For full terms see LICENSE.md.