docs: close out Θ-W1-T3 and Θ-W2-T2/T3 into COMPLETED; add the filter directory to the architecture map

This commit is contained in:
2026-07-30 11:16:21 -04:00
parent b9d85161e5
commit 25c63fb807
3 changed files with 98 additions and 150 deletions
+15 -148
View File
@@ -140,65 +140,13 @@ collision is real and the serialization is the correct answer.
### Θ-W1 — Collapse and re-seam
**Θ-W1-T1 (`zone-retirement`) and Θ-W1-T2 (`capture-handoff-bugs`) have landed** — see
`docs/COMPLETED.md`. Between them: the zone subsystem is retired and the wave's two
responsibility seams (the `sampler_core` split, the Sample-face band split) are in place;
the two extension-side capture-handoff defects are fixed. **One track remains:**
Θ-W1-T3 (`filter-dsp-port`), which lands the filter DSP as a standalone pure module —
so that from W2 on, tracks fill bands and call modules rather than fighting over
god-TUs.
---
#### Θ-W1-T3 — `filter-dsp-port`
**Goal.** Land Daniel's Cortex-M4 resonant high/low-pass filter as a pure, tested
module with the settled parameter ranges — **no call site**, so it is disjoint from
every other track by construction.
**Consolidates item 2 (DSP half).** The integration half is Θ-W2-T1.
**Surface boundary — owns:** a new `src/core/instrument/engine/filter.{h,cpp}` (name
[propose]) plus its `filter_tests` target and the CMake row. No existing file is edited
except `CMakeLists.txt`.
**EXTERNAL PREREQUISITE — this track cannot start without it.** The filter processor is
based on Daniel's own Cortex-M4 resonant high/lowpass filter code. **That code is an
input Daniel supplies at implementation time** — it is not in this repo, and neither
this plan nor `TODO-1.0.md` characterizes it beyond "resonant high and lowpass."
Dispatching this track before the source is in hand is a stall, not a start.
**Behavior.**
- **Modes:** high-pass and low-pass now. **Modes beyond the pass filters are explicitly
deferred to later** — do not build a mode-extension framework for them.
- **Cutoff:** the full audio spectrum, **log scaled**, from fully open to fully closed.
- **Q:** **0.1 to 10** (the same range as the curve exponent), scaled so **√2 sits at
the center** of the control.
- **State is per-voice.** The module carries no shared/instance-wide state; each
sounding voice runs its own instance with its own coefficients and history.
- **Concrete type, no interface.** Two modes select by branch or compile-time-known
dispatch. No `IFilter`, no virtual `tick()` — this lands directly on the per-voice
per-sample path.
- Sample-rate-aware by parameter, not by hardcoded constant (the standing
no-hardcoded-sample-rates ruling).
**Acceptance criteria.**
- The module builds and tests without REAPER, VST3, or a DAW.
- Cutoff sweeps the full audio spectrum on a log scale, from fully open to fully closed,
with the mapping asserted in tests at the endpoints and the decade midpoints.
- Q spans 0.1 → 10 with √2 at the control's center — asserted, not eyeballed.
- High Q measurably emphasizes the cutoff region (resonance) in **both** HP and LP
modes; the test asserts the resonant peak, not just monotone rolloff.
- Coefficient updates are stable across a full-range cutoff sweep at audio rate — no
blow-up, no NaN, no denormal stall.
- No virtual dispatch and no allocation in the per-sample entry point.
**Open questions.**
- **Module name and file placement [propose]** — `core/instrument/engine/filter` is the
obvious home; confirm at review.
- **Whether mode is a runtime branch or a compile-time-known dispatch [propose]** —
decided by what the ported DSP actually costs per sample; the constraint is
"no vtable," not "no branch."
**All three tracks have landed**Θ-W1-T1 (`zone-retirement`), Θ-W1-T2
(`capture-handoff-bugs`), and Θ-W1-T3 (`filter-dsp-port`) — see `docs/COMPLETED.md` for
the full narrative of each. Between them: the zone subsystem is retired, the wave's two
responsibility seams (the `sampler_core` split, the Sample-face band split) are in
place, the two extension-side capture-handoff defects are fixed, and the filter DSP has
landed as a standalone pure module with no call site — Θ-W2-T1 integrates it into the
voice path.
---
@@ -210,9 +158,14 @@ band-stack allocator that T2 and T3 fill; and W1-T1's key-range answer, which de
what T3's piano strip displays. Authoring any of this against the per-zone model means
writing storage plumbing W1 deletes.
**Three tracks, in priority order.** They are disjoint by band: T1 owns the parameter
model and the deck band, T2 the waveform band, T3 the chrome band. None re-allocates the
band stack.
**Θ-W2-T2 (`stereo-waveform-lanes`) and Θ-W2-T3 (`toolbar-and-piano-strip`) have
landed** — see `docs/COMPLETED.md`. Between them: the waveform band now shows both
channels in stereo mode behind a type-enforced full-height overlay contract, and the
chrome band's toolbar and piano strip are cleaned up per spec. **One track remains:**
Θ-W2-T1 (`filter-voice-path`), which puts the filter into the per-voice signal path and
gives it its deck. The three tracks were disjoint by band — T1 owns the parameter model
and the deck band, T2 owned the waveform band, T3 the chrome band — and none
re-allocates the band stack.
#### Θ-W2-T1 — `filter-voice-path`
@@ -279,92 +232,6 @@ mod sources, parameter storage side, neutral default) closed in the source doc.
---
#### Θ-W2-T2 — `stereo-waveform-lanes`
**Goal.** Show both channels in the waveform visual when the instrument is in stereo
mode, without duplicating any overlay.
**Consolidates item 7.**
**Surface boundary — owns:** `core/instrument/ui/waveform_view` and the **waveform
band** of the Sample face (geometry, paint, input). Reads channel mode; does not own
the mono/stereo control (that widget relocates in T3 — coordinate on state, not on
layout).
**Behavior.**
- In **stereo mode**, the waveform visual shows **both L and R channels, left on top**
— two stacked lanes.
- In **mono mode**, a single channel shows — no redundant duplicate lane.
- The display keys off the active channel mode.
- **Overlays draw once, at full height.** Overlays that ride the waveform — the envelope
overlay, markers, and item 9's loop region when it lands — draw **once at full height
across both stacked lanes**, not per lane. Land the full-height overlay contract now
even though the envelope overlay is reworked in W3 and the loop region arrives in W4;
both consume this contract.
- **Stereo processing is linked.** One editor, one set of controls governing both
channels — no per-channel parameter divergence, no per-channel editing surface.
**Acceptance criteria.**
- A stereo capture in stereo mode shows two stacked lanes, L above R, each a true view
of its channel's content — an asymmetric-channel capture visibly differs between lanes.
- Mono mode shows exactly one lane. Switching modes updates the display accordingly.
- In stereo mode, waveform-riding overlays render **once** at full stacked height — no
duplicated per-lane copies — and stay legible across both lanes.
- No per-channel controls appear; every edit applies identically to both channels.
**Open questions.** None — item 7's overlay-layout question closed in the source doc
("one full height; stereo linked processing, one editor").
---
#### Θ-W2-T3 — `toolbar-and-piano-strip`
**Goal.** Clean up the top toolbar, free the note-range piano strip to full width, and
make the key pattern uniform and self-describing.
**Consolidates item 12.**
**Surface boundary — owns:** `core/instrument/ui/keyboard_strip`, `core/ui/tooltip` (as
consumer), and the **chrome band** of the Sample face (toolbar layout, title, piano
strip — geometry, paint, input). Reads the band allocator; does not change it.
**Behavior.**
- **Font cleanup.** One consistent font treatment across the top toolbar text.
- **Zone count label removed** from the title. (Doubly settled — item 16 removed its
referent in W1.)
- **Preview and mono/stereo controls relocate** next to the browse and zoom buttons,
freeing the **note-range piano strip to take the full width**.
- **Uniform piano keys.** Some keys currently render skinnier than others — Daniel
suspects pixel aliasing, but the requirement stands regardless of cause: keys of the
same class render at uniform width. (If aliasing turns out to be the cause, the
*general* audit is item 13 — Θ-W6; the uniform-width requirement is this track's
regardless.)
- **Note-name tooltips.** Hovering a piano key shows its note value (C4 etc., DAW
convention), following the instrument's existing tooltip conventions.
- **What the strip means with no zones.** With zone bars gone, the strip's surviving
jobs are the **root display/affordance** (item 15's answer round makes root explicitly
resample-stable, so it must remain visible and settable here) and the note-name
tooltips — plus a range display only if W1-T1's key-range answer kept one.
**Acceptance criteria.**
- Top toolbar text renders in one consistent font treatment; the title carries no zone
count.
- Preview and mono/stereo sit adjacent to browse/zoom; the piano strip spans the full
editor width.
- **Same-class keys are equal pixel width at any window width and at any DPI scale.**
- Hovering any piano key shows its note name in a tooltip.
- The root note is displayed on and settable from the strip.
**Open questions.**
- **The strip's exact contents [propose]** — jointly owned with item 16's key-range
answer, which W1-T1 delivers. Propose the final inventory (root affordance +
tooltips, ± range display) at this track's review.
- **The preview button's glyph is not this track's** — item 11 (Θ-W4-T2) replaces its
inner text with a glyph in the position this track gives it. Ship the button with its
current text; do not pre-empt the glyph.
---
### Θ-W3 — The staged envelope system
**Depends on W2 for:** the filter envelope's existence — items 1, 8, and 14 govern