Repository navigation
Rendered instrument UI on the shared Affine design language - #38
Merged
Merged
Conversation
Vendor the affine_ui JUCE module, its bundled OFL typefaces and the design language it implements. The folder is identical in every Affine plug-in and renders knobs, faceplates, meters and displays procedurally at the display's physical scale.
The editor now shows the frequency the carrier oscillator actually runs at, zero while the effect is dry, instead of estimating it from the detected pitch, and treats readings as stale once blocks stop arriving. Audio processing is unchanged.
Replace the flat editor with the Affine family instrument: a VFD input display with lock lamp and confidence bar marked at the Sensitivity threshold, a Nixie counter for the running carrier with a trace of the selected waveform, calibrated knobs in Tracking, Carrier and Output frames, and lit Source and Waveform keys. Controls that do not act in the current source show an unlit activity lamp but stay editable. Editor tests cover control mapping, focus order, exact entry, gestures, selector keys, mode presentation, display states and the processor's carrier telemetry. HDN_UI_CAPTURE_DIR renders every display state, and CI uploads the captures.
The pitch detector analyses on its own thread and resets when its input queue overflows. Feeding blocks in a tight loop could overflow it on slow CI runners, so the carrier telemetry test and the state captures could see a reset tracker. Pace the audio as a host would and wait for a steady lock before asserting or capturing.
Add the Broadcast, Hi-Fi and Stealth finishes alongside Laboratory: hammertone, powder-coat and black-glass faceplates; bakelite and polished aluminium knob materials, ribbed skirts and LED rings; piano-key, toggle, polished-square and soft-key buttons; moulded, chrome and flush meter housings with coloured zones and a centre rest; horizontal ladders; alphanumeric Nixie tubes; a tuning dial and illuminated legends; jewel lamps, lit windows, rack ears, name plates, end caps and screen glass. The design language now describes each finish and shows both products in all four.
Matte black hardware with LED-ring knobs, soft keys and one amber screen: the input note, its tuning in cents and the signal against the Sensitivity mark; the carrier waveform drawn at its running frequency across two input periods; and the carrier's frequency, note and ratio to the input.
Describe the Stealth displays and replace the screenshot with a capture from the editor tests.
This was referenced Sep 28, 2026
Keep the matte black hardware the products use and remove the other three finishes: their panel textures, knob materials, key styles, meters, tubes, dials, panel hardware and two fonts. The Stealth values become the kit defaults, so a product sets only its screen colour. Add screen helpers for captions, lit numerals and segmented bars, and a section title for control groups, and move both editors onto them. The design language is rewritten around the one finish as version 3.0.
The design language now has a single finish, so the notes and screenshot descriptions no longer name one.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rebuilds the HDN Ring Modulator editor as rendered matte black hardware on the shared Affine design language. Suppressor adopts the same kit in affinedsp/suppressor#3 (companion PR).
Real capture from the test suite: a 110 Hz sine tracked as A2 and locked, with the carrier running at 220 Hz at a 2× rate multiplier, drawn as four sine cycles across two input periods.
This design was chosen from four alternatives (#39, #40 and #41, plus the original design first proposed here). The chosen one, Stealth (#41), is merged into this branch, and the shared kit is reduced to it.
What changed
libs/affine-ui(new, identical in both repos): theaffine_uiJUCE module (v3.0), bundled OFL fonts, andDESIGN_LANGUAGE.md. The powder-coat panel and the knobs are shaded per pixel at the display's physical scale and cached. A product sets only its screen colour.currentCarrierHz, the frequency the oscillator actually ran at (0 while dry), andprocessedBlocks, so the UI never shows a stale reading as live. Previously the UI treatedconfidence > 0.1as locked, which could disagree with the DSP's Sensitivity gate and 50 ms hold.PluginLookAndFeel.*,tests/TestPluginLookAndFeel.cpp,assets/fonts.tests/TestEditor.cppcovers theme contrast (including the screen colour), bundled fonts, control-to-parameter mapping, unique focus order, exact entry (commit, cancel, malformed text), single-gesture drags, keys and resets, selector keys, mode presentation, display states, and the processor's carrier telemetry.HDN_UI_CAPTURE_DIRset, the tests render every display state and scale; CI uploads them asui-evidence-macOS/ui-evidence-Windows.affinedsp/hdn-ringmod, and the localoriginremote was updated to match.The family side by side:
Verification (macOS, arm64)
ctest: 68/68 pass.SUCCESSfor the VST3.auval), because it needs the component installed. The AU wrapper is untouched.