2026-11-06 18:29:35 +01:00
|
|
|
|
# JUCE integration (Phase 107)
|
|
|
|
|
|
|
|
|
|
|
|
JUCE is used by optional, runnable examples alongside xtc's C99 engine and FLTK
|
|
|
|
|
|
application. It is an external SDK dependency, not vendored, fetched, linked by
|
|
|
|
|
|
normal builds or automatically installed. The integration uses:
|
|
|
|
|
|
|
|
|
|
|
|
| JUCE capability | Implemented use |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| AudioProcessor and plugin clients | mono/stereo VST3 instrument and standalone application |
|
|
|
|
|
|
| Audio/MIDI devices | standalone wrapper's device selection and MIDI routing UI |
|
|
|
|
|
|
| AudioProcessorValueTreeState | stable host parameters and validated versioned presets |
|
|
|
|
|
|
| GUI, graphics, events | custom native editor, parameter attachments, keyboard, meters and asynchronous preset chooser |
|
|
|
|
|
|
| DSP | low-pass filter, stereo reverb and smoothed output gain |
|
|
|
|
|
|
| MIDI | host event offsets, GUI event FIFO, Standard MIDI File parsing and tempo conversion |
|
|
|
|
|
|
| Audio formats | stereo float32 WAV export |
|
|
|
|
|
|
| Plugin hosting | explicit VST3 inspection, parameter discovery and state/processing qualification |
|
|
|
|
|
|
|
|
|
|
|
|
Synthesis is the real xtc **Soft Keys** implementation, called through
|
|
|
|
|
|
`xtc_plugin_*`. C++ remains confined to the optional integration. The SDK build
|
2026-11-06 19:05:14 +01:00
|
|
|
|
links the root CMake PIC C archive through target dependencies; standalone SDK
|
|
|
|
|
|
configuration adds the same CMake core with JACK/FLTK disabled. SDK targets do
|
|
|
|
|
|
not install plugins or modify other binary directories.
|
2026-11-06 18:29:35 +01:00
|
|
|
|
|
2026-11-06 18:32:25 +01:00
|
|
|
|
## Screenshots
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
The native editor rendered at 2× scale, with effects enabled and -6 dB output;
|
|
|
|
|
|
no audio device is opened for this capture. Also see
|
|
|
|
|
|
[the JUCE VST3 in xtc's instrument chooser](../screenshots/juce-vst3-instrument.png)
|
|
|
|
|
|
and [capture commands and context](../screenshots/README.md#steinberg-and-juce-sdk-integration-phases-106107).
|
|
|
|
|
|
The editor image is separate from xtc's FLTK host, which does not embed it.
|
|
|
|
|
|
|
2026-11-06 18:29:35 +01:00
|
|
|
|
## Licensing and dependency impact
|
|
|
|
|
|
|
|
|
|
|
|
The inspected JUCE checkout is 9.0.4, revision
|
|
|
|
|
|
`3fb5cbc0340758596dac39f7c8de47d562b4896e`. Its modules are dual-licensed under
|
|
|
|
|
|
**AGPLv3 and the commercial JUCE licence**. A commercial JUCE licence may be
|
|
|
|
|
|
required for distribution; choose and comply with the applicable SDK licence.
|
|
|
|
|
|
xtc's MIT licence for original integration code does not relicense JUCE or a
|
|
|
|
|
|
combined binary. Read the actual SDK `LICENSE.md`, its third-party inventory
|
|
|
|
|
|
`JUCE.spdx.json`, and [JUCE licensing](https://juce.com/legal/juce-9-licence/)
|
|
|
|
|
|
before distributing those binaries. No SDK source or JUCE-linked binary is added
|
|
|
|
|
|
to the normal xtc install/package targets.
|
|
|
|
|
|
|
|
|
|
|
|
JUCE requires C++17 and its Linux development dependencies, including ALSA,
|
2026-11-06 19:05:14 +01:00
|
|
|
|
Fontconfig/FreeType and X11 libraries. CMake >= 3.25 and a backend such as Ninja build these
|
2026-11-06 18:29:35 +01:00
|
|
|
|
examples. Xvfb runs automated checks without a desktop. The SDK's `juceaide`
|
|
|
|
|
|
tool is compiled at configure time. Builds are substantially heavier than the
|
2026-11-06 19:05:14 +01:00
|
|
|
|
C-only core. JUCE’s bundled codec C sources use GNU C11; the xtc core stays
|
|
|
|
|
|
strict C99. Browser/network features are disabled; normal builds never fetch
|
2026-11-06 18:29:35 +01:00
|
|
|
|
SDKs or install system packages. Only the inspected SDK revision has been
|
|
|
|
|
|
qualified; use the documented revision for reproducibility.
|
|
|
|
|
|
|
|
|
|
|
|
## Processing and ownership
|
|
|
|
|
|
|
|
|
|
|
|
The processor creates/destroys its C synth and prepares JUCE DSP in quiescent
|
|
|
|
|
|
`prepareToPlay`/`releaseResources`. Host calls must obey AudioProcessor's lifecycle
|
|
|
|
|
|
contract. The callback splits arbitrary host buffers into 256-frame C blocks.
|
|
|
|
|
|
MIDI note, controller, pitch-bend and all-notes-off messages keep their sample
|
|
|
|
|
|
offsets; other messages, including SysEx/program change, are ignored. Events
|
|
|
|
|
|
outside the block are not rendered. More than 256 supported events in a chunk
|
|
|
|
|
|
silences the whole host block and clears voices. GUI notes enter a bounded
|
|
|
|
|
|
single-producer/single-consumer FIFO at offset zero in the next callback;
|
|
|
|
|
|
GUI queue overflow requests panic and discards queued notes. No keyboard-state
|
|
|
|
|
|
locks or GUI calls occur in the callback.
|
|
|
|
|
|
|
|
|
|
|
|
Five APVTS parameters control output gain, low-pass cutoff, room size, wet mix
|
|
|
|
|
|
and effect enable. Values are read atomically per host block; output gain ramps
|
|
|
|
|
|
for 10 ms. This is block-level parameter adoption, not sample-accurate automation.
|
|
|
|
|
|
Effects default off, making the wrapper output identical to the C synth at
|
|
|
|
|
|
unity gain. Mono/stereo work at 8–192 kHz; float64 is not exposed. The synth has
|
|
|
|
|
|
32 voices, attack/release, sustain and pitch bend from the C implementation.
|
|
|
|
|
|
The keyboard shows local GUI notes; it does not mirror external MIDI notes.
|
|
|
|
|
|
|
|
|
|
|
|
Presets contain the five parameter values and schema version 1, not voices,
|
|
|
|
|
|
plugin binaries, device choices, project arrangements or reverb history. Restore
|
|
|
|
|
|
validates the complete state before adoption (64 KiB maximum). Saving uses a
|
|
|
|
|
|
same-directory temporary file; the chooser asks about replacing an existing
|
|
|
|
|
|
preset. Host state APIs use the same schema. The wrapper's `.xtcjuce` presets
|
|
|
|
|
|
are separate from xtc project/chain presets.
|
|
|
|
|
|
|
|
|
|
|
|
## Limits and qualification
|
|
|
|
|
|
|
|
|
|
|
|
See [build and example commands](../examples/juce/README.md). These examples do
|
|
|
|
|
|
not migrate the main DAW to JUCE, add a new public backend, extend the C VST3
|
|
|
|
|
|
host's editor/controller support, or finish Phase 106's native ASIO work.
|
|
|
|
|
|
The JUCE VST3 can be loaded by xtc's existing instrument workflow in default
|
|
|
|
|
|
configuration. The C host translates all-off into individual note-offs, allowing
|
|
|
|
|
|
the synth release tail rather than an immediate hard stop. Its custom editor/parameters require a capable JUCE/VST3 host or
|
|
|
|
|
|
the standalone example. Explicit plugin inspection executes trusted plugin code;
|
|
|
|
|
|
it is not a scanner sandbox and must not run inside an audio callback.
|
|
|
|
|
|
|
|
|
|
|
|
Linux build/offline/editor/plugin results are recorded in Phase 107. Physical
|
|
|
|
|
|
audio/MIDI devices, Windows/macOS, ASIO and AU/AAX/LV2/VST2 exports require their
|
|
|
|
|
|
own platform, SDK, license and hardware qualification. Unrelated JUCE modules
|
|
|
|
|
|
such as video, network services and mobile UI are outside this audio phase.
|