Goal: stand up the environment the rest of the contract runs on, and prove a plugin can load and make sound. Done: the JUCE framework on a reproducible CMake build, version control, a first read of the CLAP spec, and a minimal sine-tone plugin loading as a VST3 in Ableton Live, playing from MIDI. Evidence below.
Design study
Eidolon is a hybrid synthesizer: subtractive, additive, and wavetable in one instrument. The idea comes from hardware modular systems (Eurorack, Buchla 200 series), where signal flow is physical and audible; the contract translates that into real-time C++. The sound target is fixed before any code, in a sound-design reference and a set of concept renders; the build's architecture follows from the sound it has to make.
Build environment and toolchain
CMake with JUCE vendored as a git submodule, not the Projucer GUI; the whole toolchain rebuilds from a recursive clone and two commands, with nothing machine-specific to sync. CMake exports compile_commands.json, so CLion and any clangd-based editor get accurate navigation. One juce_add_plugin target emits VST3, AU, and Standalone; the CLAP build (via clap-juce-extensions) was expected later in the contract and in fact landed earlier, shipping in all subsequent builds.
The minimal plugin and the AudioProcessor lifecycle
The week's core study is the JUCE AudioProcessor lifecycle, the contract every host calls, in every format:
constructor: declares the bus layout, no input and one stereo output. No audio work.prepareToPlay: receives the sample rate and block size; the only place allocation belongs.processBlock: runs on the real-time audio thread; no allocation, locks, or file access, since any of them can block and cause a dropout.releaseResources: frees whatprepareToPlayset up.
The minimal plugin implements all four. Polyphony uses JUCE's Synthesiser / SynthesiserVoice model: the synthesiser holds a voice pool, walks the MIDI buffer, dispatches note-on/off to free voices, and sums them. Same structure the full instrument uses, so Week 2 swaps the sine render for a real oscillator base class without touching the lifecycle around it.
One detail carries forward: switching a full-amplitude sine on or off clicks, so the voice ramps its level over a few milliseconds at note edges, the first reason envelopes exist, ahead of the ADSR work in Week 5.
The code in code/ is a minimal teaching artifact, not an excerpt of the full engine, but a complete, buildable plugin, compiled against the same vendored JUCE, and what the evidence below shows.
CLAP specification
A first read of the CLAP spec headers (the open C plugin standard from Bitwig and u-he) with notes for the format comparison, which is reported in Week 7. CLAP is a plain C ABI built on extensions: instead of a large base class, a plugin exposes named extension structs the host queries for parameters, audio ports, and note ports. Its threading contract is explicit: each extension states main thread or audio thread, mapping straight onto the lifecycle above. One point carries forward: the JUCE-to-CLAP bridge must report actual parameter ranges, not normalized ones, or parameters stick on the host round-trip.
Version control and status
Git, with JUCE and clap-juce-extensions pinned as submodules at fixed commits, so any checkout builds the same code. Conventional commit messages; a pre-commit gate runs formatting and the verification pipeline before a commit lands.
Milestone met: the plugin loads and plays in Ableton Live (VST3), shown below. The same target also builds AU and Standalone, not separately host-tested.
Evidence
The Week 1 plugin in a host: loaded as a VST3 in Ableton Live, editor open, a MIDI clip playing. The audio is a short bounce of it.
Reflection
Most of the week went not into code but into the JUCE lifecycle: learning which method the host calls when, and why the real-time thread forbids allocation, took longer than writing the minimal plugin that finally used it. The CMake toolchain was the other demand on my time, less for difficulty than for insisting the whole build reproduce from a clean clone with nothing machine-specific left behind. The design study and the first read of the CLAP spec were lighter, more reading than building, but they set the frame the later weeks fill in. What stayed with me is how much of a synthesizer is decided before any sound: the hosting contract and the build are as much the instrument's foundation as any oscillator.
References
- JUCE: the AudioProcessor, Synthesiser, and SynthesiserVoice class references
- JUCE: CMake API documentation (juce_add_plugin)
- CLAP: specification and extension headers
- CLAP: clap-juce-extensions, the JUCE-to-CLAP bridge