docs: close out Θ-W1-T3 and Θ-W2-T2/T3 into COMPLETED; add the filter directory to the architecture map
This commit is contained in:
@@ -84,3 +84,83 @@ FX-button drop path.
|
||||
explicitly a soak ("a single pass is not a gate") and item 6 needs a live container
|
||||
drop; both require REAPER and are outstanding. The code is merged; the acceptance
|
||||
gates are not closed.
|
||||
|
||||
### Θ-W1-T3 — filter-dsp-port
|
||||
|
||||
Lands the per-voice resonant filter as a standalone pure module
|
||||
(`core/instrument/engine/filter/`, five files: `filter_params`, `filter_coeffs`,
|
||||
`filter_morph`, `filter_saturate`, `voice_filter`) — concrete `VoiceFilter` type, no
|
||||
vtable, no allocation in `process()`. **No call site**; Θ-W2-T1 wires it into the voice
|
||||
path.
|
||||
|
||||
**Deviations from spec — the spec itself changed mid-flight, headline first:**
|
||||
- **The Cortex-M4 biquad port was superseded entirely by a TPT/SVF topology, Daniel's
|
||||
call.** Measurement found the firmware's high-pass resonance feedback tap vestigial:
|
||||
its stated rationale was inverted (the HP numerator approaches 1 as cutoff falls, not
|
||||
zero — it's the LP numerator that collapses), it *reduced* HP resonance everywhere it
|
||||
ran, and it carried unwanted sample-rate and input-level dependence. It was a Q15
|
||||
fixed-point workaround for a ~17-bit cancellation float32 doesn't suffer. Daniel's
|
||||
ruling on the resulting level-dependent resonance bloom: *"was a feature on the
|
||||
hardware (one knob colorful HP for master FX), wrong choice for this approach."*
|
||||
- **Two discrete modes (HP/LP) became a continuous morph, with two selectable morph
|
||||
laws** — HP→BP→LP (default) and HP→notch→LP (Oberheim SEM) — chosen at `prepare()`
|
||||
via a `MorphLaw` enum on `FilterSettings`. Zero per-sample cost, verified by diffing
|
||||
emitted assembly (byte-identical between laws).
|
||||
- **A configurable drive stage was added:** an in-loop soft limiter on the band-pass
|
||||
integrator state, normalized 0..1, with a radial dial planned for Θ-W2. Drive at 0 is
|
||||
bit-exact linear.
|
||||
- **`Biquad1PoleLP` was struck (Daniel's call) and never ported.**
|
||||
- **Q spans the full 0.1–10 with √2 at the control centre**, replacing the firmware's
|
||||
0.707-floored mapping — as originally specified.
|
||||
- **No reference sample rate exists anywhere in the module** — rate reaches the DSP
|
||||
only via `g = tan(π·fc/sr)`. An interim fix that anchored a feedback tap to a
|
||||
`1/48000` constant was superseded by the rewrite.
|
||||
- **The rewrite fixed a float32 conditioning defect the biquad carried:** Direct Form I
|
||||
measured −27% peak error at 20 Hz / 192 kHz; TPT measures +0.034%.
|
||||
- **Still open, deliberately:** drive's maximum depth (4.0, set by measurement — at 64
|
||||
the resonant peak inverted below passband) and the absence of makeup gain both await
|
||||
an ear pass against the real dial.
|
||||
- **The module has no call site** — integration is Θ-W2-T1, which also carries three
|
||||
recorded decisions of its own: the envelope-order choice (drive is level-dependent, so
|
||||
pre- vs post-envelope placement is sound-defining), the drive dial's calibration, and
|
||||
the fact that drive authority varies ~11 dB across the morph sweep.
|
||||
|
||||
### Θ-W2-T2 — stereo-waveform-lanes
|
||||
|
||||
Delivered as specified: two stacked lanes, L above R, in stereo mode; one lane in mono;
|
||||
overlays draw once at full stacked height.
|
||||
|
||||
**Deviations from spec:**
|
||||
- **A mono source under stereo mode draws one lane**, not two — lane count keys off
|
||||
`stereoMode && sourceChannels >= 2`, not channel mode alone, since a mono capture in
|
||||
stereo mode is dual-mono and a second lane would be the redundant duplicate the spec
|
||||
forbids. Review confirmed this is the only reading consistent with the decode path.
|
||||
- The full-height overlay contract Θ-W3 and Θ-W4 consume is **type-enforced, not
|
||||
merely documented**: an `OverlayArea` wrapper type that lane rects cannot satisfy.
|
||||
- A single-slot per-channel PCM cache was added to the editor session, invalidating
|
||||
alongside the existing PCM cache.
|
||||
|
||||
### Θ-W2-T3 — toolbar-and-piano-strip
|
||||
|
||||
Delivered as specified: one toolbar font, no zone-count label, full-width piano strip,
|
||||
uniform key widths, note-name tooltips, root displayed and settable.
|
||||
|
||||
**Deviations from spec:**
|
||||
- **The non-uniform key widths were integer quantisation, not aliasing** — the old
|
||||
`keyEdgeToX` truncated an exact rational, alternating 6px/7px. Θ-W6's general
|
||||
antialiasing audit inherits nothing on key *widths* as a result, though key *edges*
|
||||
are still drawn unantialiased.
|
||||
- **Uniform integer key widths and gap-free edge-to-edge tiling are mutually
|
||||
exclusive** — 75 white keys do not divide an arbitrary width. The residue now lands
|
||||
in symmetric end gutters, 37px each side at the shipped 840px default — the maximum
|
||||
of a sawtooth with period 75px of window width. Daniel accepted this provisionally,
|
||||
pending how it looks in REAPER.
|
||||
- The whole control run moved into the toolbar row, not just preview and mono/stereo —
|
||||
the full-width strip left the velocity knob and curve button nowhere else to go.
|
||||
- Root drag became absolute-tracking rather than pixel-delta, since black keys
|
||||
overlaying white give no single pixels-per-semitone rate.
|
||||
- **Width uniformity is guaranteed in client pixels only.** Nothing in the instrument
|
||||
consumes a DPI scale factor, so host-side scaling is unverified — Θ-W6 already
|
||||
carries a "confirm the fix survives DPI scaling" item and now genuinely inherits it.
|
||||
- A stale-hover latch was fixed across **all** drag kinds and both drag-termination
|
||||
paths, wider than the strip work that surfaced it.
|
||||
|
||||
Reference in New Issue
Block a user