You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
keep ChannelState gain slew at one constant sample-time rate across callback boundaries
clamp only after the target is actually reached instead of dilating the last gain fraction to the callback edge
carry the same start/rate/end segment into binaural rendering, so the headphone path no longer applies block-end gain as a callback-rate step
add an adversarial regression that renders one continuous fade under two radically different callback partitions and requires sample-equivalent output
Why
Host callback boundaries are transport artifacts. The current slew computes the final partial step as remaining_delta / sample_length, so a callback that straddles the target changes the audible gain trajectory. In binaural mode, the block-end gain is also applied to the whole block, making the trajectory even more directly callback-size dependent.
The regression uses the direct LFE headphone route to avoid HRTF/reverb differences and compares the same 1200-sample fade under 40-sample blocks versus an irregular partition that crosses the 960-sample slew endpoint inside a 273-sample callback.
Validation
The branch is based directly on upstream b1b78a89bb83417d7ff6ae73a617983269bd12a8. This PR is opened as draft so upstream CI can run the repository's format/build/test gates before it is marked ready.
Thanks — the fix is sound and the adversarial partition test is exactly the kind of regression we want pinned. I ran the branch locally on top of b1b78a8: the new test passes, but two golden null tests fail, which is the expected consequence of the intended trajectory change:
null_binaural_kemar — peak residual −24.8 dBFS, RMS −44.6 dBFS (the binaural path moving from block-end constant gain to per-sample interpolation)
null_crossover_bands — the speaker path's end-of-ramp clamp behaviour
Two requests before marking this ready:
Re-bless the goldens with OMNIPHONY_BLESS_GOLDENS=1 cargo test -p renderer and quote the printed residuals in the PR description, as the harness instructs. CI runs the full suite, so it will stay red until then.
Make GainSlew::at() branchless. It sits in the per-sample hot loops of the speaker stage, and this repo's convention is to keep per-sample work branch-free. The sign test on step is loop-invariant, so cheap in practice, but it can block auto-vectorisation. Since the ramp is monotonic from start toward end, hoisting the bounds once per block does it:
let lo = self.start.min(self.end);let hi = self.start.max(self.end);// per sample:(self.start + self.step* sample_idx asf32).clamp(lo, hi)
which compiles to fma + minss/maxss. Same pattern applies to the two inlined gain computations in binaural/mod.rs (hoist lo/hi out of the for s in 0..span loops).
One nit, no change needed: with ramp_samples <= 0.0 the new code jumps to the target at the first sample instead of ramping over one block. Unreachable today (GAIN_SLEW_SECS is a positive constant), just noting it's a deliberate semantic.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
ChannelStategain slew at one constant sample-time rate across callback boundariesWhy
Host callback boundaries are transport artifacts. The current slew computes the final partial step as
remaining_delta / sample_length, so a callback that straddles the target changes the audible gain trajectory. In binaural mode, the block-end gain is also applied to the whole block, making the trajectory even more directly callback-size dependent.The regression uses the direct LFE headphone route to avoid HRTF/reverb differences and compares the same 1200-sample fade under 40-sample blocks versus an irregular partition that crosses the 960-sample slew endpoint inside a 273-sample callback.
Validation
The branch is based directly on upstream
b1b78a89bb83417d7ff6ae73a617983269bd12a8. This PR is opened as draft so upstream CI can run the repository's format/build/test gates before it is marked ready.