Fix reverse-read timing and add small-buffer safeguard in AccidentalReverse mode#82
Fix reverse-read timing and add small-buffer safeguard in AccidentalReverse mode#82ovelhaaa wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughThe change modifies the reverse-read delay calculation in ChangesReverse-delay windowing
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request updates the OrbitDelayCore::processChannelFast method in the accidental reverse-read path to include channel-dependent offsets (params.offsetSamples) and introduces a safe fallback mechanism when the delay size is too small for the minimum reverse window size. The reviewer identified two issues: first, a 1-sample mismatch between the actual read position and the base read position due to baseReadPos being calculated after reverseCounter is incremented in readReverseWindowed(); second, a dead store where reverseDelaySamples is assigned a value in the fallback branch but never used.
| wet = readReverseWindowed(delay, reverseDelaySamples, writePos, delaySize, invDelaySize, reverseCounter, reverseWindowSize); | ||
| baseReadPos = wrapPosFloat(writePos - reverseDelaySamples + reverseCounter, delaySize, invDelaySize); |
There was a problem hiding this comment.
In the reverse-read path, baseReadPos is calculated using reverseCounter after it has been incremented inside readReverseWindowed(). This causes a 1-sample mismatch between the actual read position used for the wet signal and the base read position used for the feedback tap mixer. Calculating baseReadPos before calling readReverseWindowed() ensures they are perfectly aligned.
| wet = readReverseWindowed(delay, reverseDelaySamples, writePos, delaySize, invDelaySize, reverseCounter, reverseWindowSize); | |
| baseReadPos = wrapPosFloat(writePos - reverseDelaySamples + reverseCounter, delaySize, invDelaySize); | |
| baseReadPos = wrapPosFloat(writePos - reverseDelaySamples + reverseCounter, delaySize, invDelaySize); | |
| wet = readReverseWindowed(delay, reverseDelaySamples, writePos, delaySize, invDelaySize, reverseCounter, reverseWindowSize); |
| reverseCounter = 0.0f; | ||
| reverseWindowSize = 0.0f; | ||
| reverseDelaySamples = guardSamples; | ||
| wet = 0.0f; | ||
| baseReadPos = wrapPosFloat(writePos - guardSamples, delaySize, invDelaySize); |
There was a problem hiding this comment.
The assignment reverseDelaySamples = guardSamples; is a dead store because reverseDelaySamples is a local variable that is not used anywhere else in this fallback branch. Removing it simplifies the code.
| reverseCounter = 0.0f; | |
| reverseWindowSize = 0.0f; | |
| reverseDelaySamples = guardSamples; | |
| wet = 0.0f; | |
| baseReadPos = wrapPosFloat(writePos - guardSamples, delaySize, invDelaySize); | |
| reverseCounter = 0.0f; | |
| reverseWindowSize = 0.0f; | |
| wet = 0.0f; | |
| baseReadPos = wrapPosFloat(writePos - guardSamples, delaySize, invDelaySize); |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
core/src/orbit_delay_core.cpp (1)
725-726: 💤 Low valueConsider extracting the minimum window constant to avoid duplication.
kMinReverseWindowSamples(8.0f) duplicateskMinWindowSamplesinsidereadReverseWindowed()(line 111). If either value changes independently, the fallback threshold here could become inconsistent with the actual minimum window enforced during reverse reading.Suggested approach
Define a shared constant (e.g., in the anonymous namespace or as a class static) and reference it in both locations:
// In anonymous namespace near top of file constexpr float kMinReverseWindowSamples = 8.0f;Then use it in both
readReverseWindowed()and in the fallback check.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/src/orbit_delay_core.cpp` around lines 725 - 726, Define a single shared minimum-window constant and use it in both places to avoid duplication: replace the local constexpr kMinReverseWindowSamples and the hardcoded kMinWindowSamples in readReverseWindowed() with a single constant (e.g., constexpr float kMinWindowSamplesShared or a static member) declared in the anonymous namespace or as a class static, then update both the fallback check (the if using kMinReverseWindowSamples) and the readReverseWindowed() logic to reference that shared symbol so both use the same minimum value.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@core/src/orbit_delay_core.cpp`:
- Around line 725-726: Define a single shared minimum-window constant and use it
in both places to avoid duplication: replace the local constexpr
kMinReverseWindowSamples and the hardcoded kMinWindowSamples in
readReverseWindowed() with a single constant (e.g., constexpr float
kMinWindowSamplesShared or a static member) declared in the anonymous namespace
or as a class static, then update both the fallback check (the if using
kMinReverseWindowSamples) and the readReverseWindowed() logic to reference that
shared symbol so both use the same minimum value.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 243a9a29-7b80-49b9-9601-583af82a5f62
📒 Files selected for processing (1)
core/src/orbit_delay_core.cpp
Motivation
Description
params.offsetSamplesin the reverse delay calculation so the effective reverse delay matches forward-path channel offsets.delaySizecannot accommodate the minimum reverse window plus guard bands and falls back to a safe read position with zeroed reverse window and counter.reverseCounter/reverseWindowSizewhen the computed read distance falls inside guard regions, and ensurewetandbaseReadPosare set consistently.readReverseWindowed().Testing
cmakeandcmake --build .with no build errors.ctestand all tests passed.Codex Task
Summary by CodeRabbit