docs: record GA DAW-fix pass (Preserve SOLA, voice declick, stereo bus-pin+v9, .vstpreset drop-fx, drag-out, panel toggle); correct stale vst_chunk mechanism
This commit is contained in:
+82
-12
@@ -2256,16 +2256,18 @@ is dragged from the `bank_panel`, a track's TCP **FX button** lights as a drop z
|
||||
and dropping there instantiates a **ReaSampler 9000** on that track with the dragged
|
||||
capture **already loaded and selected** for playback. A third `DragGesture` —
|
||||
`InstrumentDrop` — added to the `drag_out` pure module. Mechanism: `TrackFX_AddByName` +
|
||||
VST3 component-state injection via `TrackFX_SetNamedConfigParm(..., "vst_chunk", blob)`.
|
||||
The shared `instrument_drop` pure module constructs the blob via the instrument's own
|
||||
`sample_map::serializeComponentState`/`deserializeComponentState` — one serializer called
|
||||
from both artifacts, so the blob format cannot drift. CONTEXT-ARCHIVE.md §Phase S (drop-and-load).
|
||||
VST3 component-state injection via a Steinberg-format `.vstpreset` file built by
|
||||
`instrument_drop` (applied via `TrackFX_SetPreset`). The `instrument_drop` pure module
|
||||
constructs the `.vstpreset` image from the instrument's own
|
||||
`sample_map::serializeComponentState` — one serializer called from both artifacts, so the
|
||||
byte format cannot drift. CONTEXT-ARCHIVE.md §Phase S (drop-and-load). (`vst_chunk` write
|
||||
was the original planned mechanism but is silently unappliable for VST3 — replaced by
|
||||
`.vstpreset` + `TrackFX_SetPreset`, GA DAW-fix pass 2026-07-28.)
|
||||
**Verify (in DAW):** dragging a single capture from the dock over a track's FX button
|
||||
highlights it; dropping instantiates ReaSampler 9000 on that track with the dragged
|
||||
capture loaded, selected, and MIDI-playable immediately; OS drag-out to Explorer still works
|
||||
unchanged; internal bank-to-bank drag still works unchanged; no media item ever inserted
|
||||
into the arrange. DAW-verify: whether REAPER's `vst_chunk` write-parm expects the plugin's
|
||||
raw IComponent-state bytes or wraps them in a REAPER container header.
|
||||
into the arrange. **VERIFIED (GA DAW-fix pass 2026-07-28).**
|
||||
**Depends on:** M11 (`drag_out` gesture machinery), Phase S S4, the load-capture seam
|
||||
(VST3 component-state injection — the shared blob contract).
|
||||
|
||||
@@ -2290,18 +2292,21 @@ raw IComponent-state bytes or wraps them in a REAPER container header.
|
||||
- [x] **ReaSampler 9000 load-capture seam:** the instrument's existing `setState`/`getState`
|
||||
already round-trip the full `ComponentState` via
|
||||
`sample_map::serializeComponentState`/`deserializeComponentState` (S10). The extension
|
||||
REUSES that exact serializer through the new pure `instrument_drop` module
|
||||
(`buildInstrumentDropChunk` → `serializeComponentState` → base64). The shared-writer
|
||||
REUSES that exact serializer through the new pure `instrument_drop` module (builds a
|
||||
Steinberg-format `.vstpreset` image: 'VST3' header + 'Comp' chunk = serialized component
|
||||
state, addressed to `vstClassIdHex()`; applied via `TrackFX_SetPreset`). The shared-writer
|
||||
requirement is met STRUCTURALLY — the blob format cannot drift. Pure round-trip test decodes
|
||||
back through the instrument's own reader and asserts the capture is selected.
|
||||
**`instrument_drop` lives at `src/instrument_drop.{h,cpp}`** (extension-side pure module);
|
||||
CTest target `instrument_drop_tests`.
|
||||
CTest target `instrument_drop_tests`. (`TrackFX_SetNamedConfigParm` "vst_chunk" was the
|
||||
original mechanism but is silently unappliable for VST3 — REAPER's wrapper cannot apply
|
||||
unframed raw component-state bytes; replaced by the `.vstpreset` path, S-GA-DropFX.)
|
||||
- [x] Tests: gesture disambiguation (inside-panel / over-REAPER-UI / left-REAPER) across
|
||||
single- and multi-capture payloads; M11 OS drag-out and internal bank-to-bank drag both
|
||||
unchanged. `test_drag_out.cpp` adds the InstrumentDrop cases with M11 cases retained as
|
||||
the non-regression guard; `test_instrument_drop.cpp` is the blob round-trip + base64 codec
|
||||
coverage. FX hit resolution is REAPER-API-bound (`GetThingFromPoint`) — DAW-verified in the
|
||||
shell, not pure-tested (noted honestly).
|
||||
the non-regression guard; `test_instrument_drop.cpp` covers the `.vstpreset` image
|
||||
round-trip (structure, class-ID, chunk offset/size). FX hit resolution is REAPER-API-bound
|
||||
(`GetThingFromPoint`) — DAW-verified in the shell, not pure-tested (noted honestly).
|
||||
|
||||
**Notes/decisions:**
|
||||
- `resetDragState()` consolidation in `bank_panel` (prior drift cleaned up this wave).
|
||||
@@ -2773,3 +2778,68 @@ Zone-authoring affordances intact; no regression on the Sample face.
|
||||
- **Phase S editor Wave B complete.** S-VIEW-11 (knob deck + curve popup, FB1), S-VIEW-12
|
||||
(full-width hero + master gain, FB1), and S-VIEW-13 (Zone-panel parity, FB2) are all landed.
|
||||
No open r11 or S-VIEW Wave B items remain in PLAN.md.
|
||||
|
||||
---
|
||||
|
||||
## GA post-launch DAW-fix pass (2026-07-28)
|
||||
|
||||
> **Merged to dev 2026-07-28. Integrated suite 55/55 green.** Six fixes found during
|
||||
> GA DAW testing — not tracked as PLAN points. PLAN.md has no corresponding entries to move.
|
||||
|
||||
**Preserve pitch engine (SOLA rewrite):** `pitch_shift` rewritten from a dual-tap OLA (taps hard-locked
|
||||
half a window apart — fixed relative phase causes anti-phase cancellation on many source frequencies,
|
||||
producing spectral garbage on repitched notes) to **correlation-aligned SOLA splices**: one active read
|
||||
tap chases the write head at the shift ratio; each splice jump is refined by a cross-correlation search
|
||||
so the new read point is waveform-aligned, then old and new taps are crossfaded with a raised-cosine,
|
||||
amplitude-complementary fade. Clean pitch shift past +24 st; a repitched pure sine stays a single tone.
|
||||
|
||||
**Voice takeover declick:** `Voice::start` gained a `takeoverDeclick` parameter (gated on the envelope
|
||||
complement, applied when the flag is true) to remove the click at mono retrig/fallback and poly at-cap
|
||||
steal boundaries. The "steal-all" symptom observed in DAW was diagnosed as no-loop sample exhaustion
|
||||
under Preserve (voices played to silence, not stolen); the engine steals exactly one voice per note-on
|
||||
as designed.
|
||||
|
||||
**Stereo bus pin + channel-mode auto-default:** The output bus is now **permanently stereo** — the
|
||||
dynamic mono↔stereo bus renegotiation that hard-panned dual-mono is deleted. `ChannelMode` is
|
||||
decode-only (controls downmix vs. dual-mono on WAV decode). Channel mode **auto-defaults from the
|
||||
loaded capture's channel count** via `channelModeFor()` (pure helper in `sample_map`) when the user
|
||||
has not explicitly toggled it; explicit toggle latches the preference. `ComponentState` bumped **v8→v9**:
|
||||
`channelModeExplicit` bool added; pre-v9 blobs treat the stored mode byte as an explicit preference
|
||||
(no auto-override).
|
||||
|
||||
**Drop-to-FX injection fix:** Injection switched from `TrackFX_SetNamedConfigParm(..., "vst_chunk",
|
||||
<base64>)` (silently unappliable for VST3 — REAPER's wrapper cannot accept unframed component-state
|
||||
bytes) to a **Steinberg-format `.vstpreset` file** whose 'Comp' chunk is the serialized component
|
||||
state, applied via `TrackFX_SetPreset`. The `instrument_drop` pure module builds the `.vstpreset`
|
||||
image; `instrument_drop_win` writes a transient temp file and calls `TrackFX_SetPreset`. FX hotspot
|
||||
now prefix-matches `tcp.fx*`/`mcp.fx*`/`fx_*` (embed strip tokens excluded). `reasampler_uid.h`
|
||||
split out of `reasampler_vst.h` as an SDK-free header so `instrument_drop` can derive the class-ID
|
||||
hex string without the VST3 SDK.
|
||||
|
||||
**Drag-out arm fix:** `SetCapture` moved to drag-arm (the `dragArmed` branch of `handleClick` in
|
||||
`bank_panel`) so a first straight-out drag — pointer leaving the client rect before a second click
|
||||
— correctly arms and fires the OS drag-out. Previously `SetCapture` was called only after the drag
|
||||
threshold was crossed inside the panel, so a fast straight-out drag on the first attempt received no
|
||||
`WM_MOUSEMOVE` messages outside the client rect and the gesture never transitioned to the OS drag.
|
||||
|
||||
**Panel mode-toggle repaint:** The Design/Arrange mode-toggle actions (`doToggleMode` /
|
||||
`doActivateMode` in `actions.cpp`) now call `bankPanelInvalidate()` after applying the mode switch.
|
||||
Previously the panel footer `[Arrange|Design]` toggle only repainted on a button click inside the
|
||||
panel, not when the mode was changed via the registered action (e.g. from the Actions list or a
|
||||
keybinding).
|
||||
|
||||
- [x] `pitch_shift`: dual-tap OLA replaced by correlation-aligned SOLA; CTest `pitch_shift_tests`
|
||||
updated to assert single-tone output on repitched sine.
|
||||
- [x] `sampler_core` `Voice::start`: `takeoverDeclick` parameter added; mono retrig/fallback + poly
|
||||
at-cap steal pass `true`; `PreviewCard` and standard voices pass the flag correctly.
|
||||
- [x] `reasampler_processor`: output bus permanently stereo; `channelModeExplicit_` member added;
|
||||
`channelModeFor()` called on `reloadFromBank` when not explicit; `ComponentState` v8→v9
|
||||
(`channelModeExplicit` byte); pre-v9 lift treats stored mode as explicit.
|
||||
- [x] `instrument_drop`: `.vstpreset` image builder replacing `vst_chunk` base64 path; `vstClassIdHex()`
|
||||
sourced from `reasampler_uid.h`; `instrument_drop_tests` covers preset image structure round-trip.
|
||||
- [x] `reasampler_uid.h`: new SDK-free header in `src/vst/` owning the frozen class-UID macros;
|
||||
`reasampler_vst.h` and `instrument_drop` both source from it.
|
||||
- [x] `instrument_drop_win`: FX hotspot prefix-set extended (`tcp.fx*`/`mcp.fx*`/`fx_*`); transient
|
||||
`.vstpreset` write + `TrackFX_SetPreset` call replaces `TrackFX_SetNamedConfigParm` "vst_chunk".
|
||||
- [x] `bank_panel`: `SetCapture` moved to drag-arm branch; `bankPanelInvalidate()` called from
|
||||
`actions.cpp` after mode-toggle actions.
|
||||
|
||||
Reference in New Issue
Block a user