docs: close out Θ-W1-T3 and Θ-W2-T2/T3 into COMPLETED; add the filter directory to the architecture map
This commit is contained in:
+15
-148
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user