feat: render bounded effect tails and reset internal history on transport changes
This commit is contained in:
parent
7a01e2d2f3
commit
836cdedc6b
22 changed files with 284 additions and 18 deletions
|
|
@ -152,3 +152,39 @@ energy, bounded extreme feedback/diffusion and graph/direct stereo output
|
|||
(including the engine's subnormal-to-zero policy). GUI tests save/reopen both
|
||||
identities; callback guards and ASan/UBSan cover processing. `make builtin-preview`
|
||||
also writes files 5/6 for repeatable listening; human listening remains pending.
|
||||
|
||||
## Phase 44 history and tails
|
||||
|
||||
Internal effects reset on a transport discontinuity (seek/loop wrap), stopped
|
||||
backend, or newly prepared plan. Pause uses backend Stop and therefore also
|
||||
resets history. Continuous playback retains tails. Reset invalidates delay
|
||||
history with a valid-frame counter and clears only fixed-size filter/voice state;
|
||||
it neither allocates nor clears a large delay buffer in the callback. External
|
||||
plugins retain their existing history contract. MIDI discontinuities continue
|
||||
to chase notes with fresh envelopes.
|
||||
|
||||
**File → Export WAV** renders the song plus the Preferences / transport
|
||||
`tail_ms` duration (0..60000, default 3000). Output is stereo float32 WAV at the
|
||||
offline sample rate. The destination must be a new absolute path. Rendering
|
||||
prepares an independent snapshot, then advances in 256-frame control-thread
|
||||
steps with a Cancel button; the project and playback instance stay independent.
|
||||
Only a complete synced file is published, without replacing an existing file.
|
||||
Cancellation/errors remove the temporary. Missing media rejects export.
|
||||
RIFF's 32-bit size limit is enforced before rendering. Rendering does not apply
|
||||
loop preferences, normalize, automatically detect silence or stop infinite
|
||||
oscillator/feedback sources early: the configured endpoint always bounds work.
|
||||
|
||||
The public `xtc_export_create/step/progress/destroy` API supports incremental
|
||||
rendering and cancellation by destruction. A failed step must be followed by
|
||||
destruction. `xtc_project_render_length` returns the exact sample endpoint.
|
||||
|
||||
Set `stop_after_tail=1` in Preferences to stop ordinary playback after the song
|
||||
and configured tail. Looping and recording disable this automatic stop. Playback
|
||||
stop is serviced by the GUI refresh timer and normal stop fade, so it can exceed
|
||||
the endpoint by a refresh interval plus fade; export has the exact sample length.
|
||||
Uncheck the setting to retain indefinite playback. Stop always remains available.
|
||||
|
||||
Tests compare stereo export against direct rendering in 31-frame blocks, verify
|
||||
nonzero tails, exact length, cancellation, existing-file retention, tail bounds,
|
||||
history reset and callback-safe reset. Preview generation and manual listening
|
||||
procedures remain available; no human listening result is claimed.
|
||||
|
|
|
|||
|
|
@ -66,3 +66,8 @@ Validation covers settings roundtrips, malformed/duplicate/overflow/NUL input,
|
|||
private permissions, save failure, GUI Apply/Close/reload and plugin listing,
|
||||
plus JACK callback wrap positions and existing GUI/core regressions. Tests use
|
||||
temporary configuration paths and do not write the user's configuration.
|
||||
|
||||
Phase 44 adds `[transport] tail_ms=3000` (0..60000) and
|
||||
`stop_after_tail=0` (0/1). Export always includes the configured tail; optional
|
||||
playback stopping uses the GUI timer and is disabled during looping/recording.
|
||||
See BUILTIN_DEVICES.md for endpoint, cancellation and reset semantics.
|
||||
|
|
|
|||
|
|
@ -1239,15 +1239,19 @@ documented; human listening is unverified. See BUILTIN_DEVICES.md.
|
|||
Make discontinuities and effect tails explicit in playback and export.
|
||||
|
||||
### Tasks and acceptance criteria
|
||||
- [ ] Define retained/reset effect history for seek, stop, loop wrap and project/plan replacement.
|
||||
- [ ] Implement the chosen history policy without callback allocation or unsafe state sharing.
|
||||
- [ ] Add bounded automatic or user-configurable tail rendering after the arrangement/export endpoint.
|
||||
- [ ] Expose tail limits and cancellation, including silent input and non-decaying/high-feedback cases.
|
||||
- [ ] Test seek/loop reproducibility and complete delay/reverb tails across processing block sizes.
|
||||
- [x] Define retained/reset effect history for seek, stop, loop wrap and project/plan replacement.
|
||||
- [x] Implement the chosen history policy without callback allocation or unsafe state sharing.
|
||||
- [x] Add bounded automatic or user-configurable tail rendering after the arrangement/export endpoint.
|
||||
- [x] Expose tail limits and cancellation, including silent input and non-decaying/high-feedback cases.
|
||||
- [x] Test seek/loop reproducibility and complete delay/reverb tails across processing block sizes.
|
||||
|
||||
### Implementation status
|
||||
Planned. Seeks currently retain effect history; tails need continued rendering
|
||||
and do not automatically extend playback/export.
|
||||
Implemented: constant-cost internal history invalidation on discontinuity/stop,
|
||||
plus incremental stereo WAV export with 0..60-second tails, progress/cancel and
|
||||
no-clobber publication. Preferences optionally stop playback after the tail
|
||||
(with GUI-timer/fade precision); loops/recording retain their existing behavior.
|
||||
Core, reliability, export/direct partition, GUI and sanitizer checks pass.
|
||||
External-plugin history remains retained. See BUILTIN_DEVICES.md for limits.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue