Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/tomduncalf/tomduncalf_juce_web_ui

WIP: a JUCE module providing helper classes to make it easy to integrate a web-based UI with a JUCE application.
https://github.com/tomduncalf/tomduncalf_juce_web_ui

Last synced: about 1 month ago
JSON representation

WIP: a JUCE module providing helper classes to make it easy to integrate a web-based UI with a JUCE application.

Lists

README

        

# tomduncalf_juce_web_ui

tomduncalf_juce_web_ui is a JUCE module providing helper classes to make it easy to integrate a web-based UI (running in a JUCE WebBrowserComponent) with a JUCE application (e.g. an audio engine).

**Please see https://github.com/tomduncalf/WebUISynth for an example integration with a simple synth engine.**

Ultimately the integration will be cross-platform on both desktop and mobile, but right now it has only been tested on macOS and iOS.

## Status

Experimental, Work in progress - I have a [basic example](https://github.com/tomduncalf/WebUISynth) working, but need to add more features, documentation and a tutorial. Should not be considered stable in terms of APIs.

See [the project board](https://github.com/tomduncalf/tomduncalf_juce_web_ui/projects/2) for a list of tasks.

## Features

- "Batteries included" defaults, using [MobX](https://mobx.js.org/) and [React](https://reactjs.org/) to make working with your audio engine as straightforward as possible – for example, Parameters are exposed in a reactive manner via React Context, making hooking up your parameters [easy](https://github.com/tomduncalf/WebUISynth/blob/main/ui/src/components/Parameters.tsx).

- Great developer experience – integration and communication is made as straightforward as possible on both the JUCE and browser sides (see [below](#key-components)), and features web developers love such as hot reloading and developer tools are all available. As the UI is "just a web page", your favourite libraries can be reused for functionality and styling too.

- Good performance – in my initial tests, a web based UI seemed to perform similarly to a native JUCE UI in terms of CPU usage when playing back a sequence in a host with automation and a scope visualiser open. This area needs more research however!

- Cross-platform (planned, currently Mac/iOS only) – every platform supported by JUCE now provides a mature WebView component, so web UIs should perform well across all platforms, both standalone and as a hosted plugin.

## Key components:

- A [browser component](https://github.com/tomduncalf/tomduncalf_juce_web_ui/blob/main/BrowserComponent.h) which supports sending messages to and from a web browser, using JUCE's support for calling Javascript functions directly to call into the browser, and custom additions to JUCE to allow sending messages directly back to C++ (needs to be integrated into JUCE - for now, requires using my fork and is Mac/iOS only - but greatly improves performance e.g. with multi touch updates).

- A [base class](https://github.com/tomduncalf/tomduncalf_juce_web_ui/blob/main/BrowserIntegrationClient.h) for any classes which want to communicate with the browser, allowing sending messages and registering callbacks in a namespaced way.

- Automatic one-way state synchronisation from JUCE ValueTrees to a JS representation using a [ValueTreeSynchroniser](https://github.com/tomduncalf/tomduncalf_juce_web_ui/blob/main/BrowserValueTreeSynchroniser.h) and a [TypeScript implementation](https://github.com/tomduncalf/WebUISynth/tree/main/ui/src/juceIntegration/valueTree) of the ValueTreeSynchroniser protocol and [ValueTree class](https://github.com/tomduncalf/WebUISynth/blob/a49c101dc078e8d41d63fed16fb40570db49bdcd/ui/src/juceIntegration/valueTree/ValueTree.ts).

The synchronisation is batched into one message per frame (at 60hz) to reduce redundant messages back and forth - however, there's room for more optimisation here!

- A [base class](https://github.com/tomduncalf/tomduncalf_juce_web_ui/blob/main/BrowserIntegrationPluginClient.h) for plugins which automatically handles synchonising the plugins AudioProcessorValueTreeState to the browser, and [corresponding models](https://github.com/tomduncalf/WebUISynth/blob/main/ui/src/juceIntegration/models/) on the JS side which provide a representation of the parameters, with getters and setters for easy modification.

[Auto-generated TypeScript definitions](https://github.com/tomduncalf/WebUISynth/blob/main/ui/src/config/autogenerated/parameters.ts) for your parameters (generated when run in debug mode) reduces the amount of manual integration to a minimum, and the use of MobX means keeping your UI reactive is simply a case of adding [observer](https://github.com/tomduncalf/WebUISynth/blob/main/ui/src/components/ParameterSlider.tsx#L13) to React components and accessing `Parameters` [from React's Context API](https://github.com/tomduncalf/WebUISynth/blob/a49c101dc078e8d41d63fed16fb40570db49bdcd/ui/src/components/Parameters.tsx#L7).

- Lightweight mechanism for communicating between [TypeScript](https://github.com/tomduncalf/WebUISynth/blob/main/ui/src/juceIntegration/juceCommunication.ts#L8) and [C++](https://github.com/tomduncalf/tomduncalf_juce_web_ui/blob/main/BrowserIntegrationClient.h#L21) by sending messages and registering callbacks.

For an example of C++ to browser communication, see the implementation of the Scope in [C++](https://github.com/tomduncalf/WebUISynth/blob/a49c101dc078e8d41d63fed16fb40570db49bdcd/Source/ScopeDataSender.h#L61) and [TypeScript](https://github.com/tomduncalf/WebUISynth/blob/a49c101dc078e8d41d63fed16fb40570db49bdcd/ui/src/components/Scope.tsx#L7).

For an example of browser to C++ communication, see the implementation of setting parameters in [C++](https://github.com/tomduncalf/tomduncalf_juce_web_ui/blob/862a2706417f8acc568a0c62a2b028d8b8dfc699/BrowserIntegrationPluginClient.cpp#L27) and [TypeScript](https://github.com/tomduncalf/WebUISynth/blob/a49c101dc078e8d41d63fed16fb40570db49bdcd/ui/src/juceIntegration/messages/pluginMessages.ts#L4).

## Documentation

Documentation is still TODO – once I am happy with the APIs and functionality, I will provide documentation and a tutorial but for now, there are some code comments in the source code and the example [WebUISynth](https://github.com/tomduncalf/WebUISynth) integration.

## Motivation

Building user interfaces in C++ can be challenging, especially for developers coming from a web background. Advances in the web world over the last decade including declarative UI frameworks such as [React](https://reactjs.org/), hot reloading, and the ever expanding capabilities of both CSS and JavaScript have made developing complex UIs considerably easier – going back to imperative code updating a UI and a full compile cycle each time you make a change can feel like quite a step backwards.

If you are happy to build for just one platform, native frameworks offer a better experience (on MacOS/iOS at least), but if you are building a cross-platform app, options are more limited. I have worked extensively with React Native in combination with JUCE (see my [talk from ADC'19](https://www.youtube.com/watch?v=bsy0-mHcS4Y) about building an app with this stack), but on desktop React Native is still quite an immature option. Flutter is an interesting option in many ways, but it requires learning a new framework and language.

JavaScript (and in particular React) is widely known and fairly easy to learn. Browser engines are incredibly powerful and remarkably performant, so in theory there's no reason why they shouldn't be suitable for building UIs for audio apps and plugins – indeed, a developer from Output spoke about their experiences building their Arcade plugin using web UI at [ADC'20](https://www.youtube.com/watch?v=XvsCaQd2VFE]).

The difficulty often comes with combining and interacting between two separate worlds – you have to worry about keeping state in sync, how to pass messages between JS and C++, etc. This module aims to solve those problems as elegantly as possible, so you can focus on writing great software.