Skip to content

audioecho.FeedbackDelay: a splice on a fading repeat does not search on - #291

Merged
bdbarnett merged 1 commit into
mainfrom
fix/feedback-repeats-290
Oct 20, 2026
Merged

bdbarnett merged 1 commit into
mainfrom
fix/feedback-repeats-290

Conversation

@bdbarnett

Copy link
Copy Markdown
Contributor

Fixes #290.

#284 let a splice search out to a whole window when nothing within half a window matched the other tap. It also did that where the other tap read only the last few LSB of a fading repeat, or silence. There, rounding alone makes every match look poor, so the search went the whole way out and left the starting tap a window off the material that came next. Through a pitch shifter with feedback, the third pass of a short burst came back 19 dB under what Feedback leaves it.

Now the far search also needs the other tap to read more than 8 LSB on average over the compared stretch. A held chord reads far above that, so everything #284 fixed stays fixed. Nothing changes in the API.

Regression, not a corrected artefact

audioeffects' PitchShifter at 22,050 Hz, -5 semitones, a 30 ms window and Feedback 0.3, pass 3 against Feedback² of pass 1:

before #284 (9321f25) #284 (c03a357) this branch
pass 2 +1.2 dB +1.2 dB +1.2 dB
pass 3 +2.5 dB -19.0 dB +2.5 dB
PitchShifter's repeats check, all 560 cells and seeds 0 fail, worst -8.3 dB 16 fail, worst -19.0 dB 0 fail, worst -5.3 dB

The old reading was not inflated: each trip gains the same 1.2 dB, so +2.5 on pass 3 is two trips of it. Under #284 the energy of pass 3 had gaps in it. A trace of the splices showed why. When the far search fired, the other tap read 42 to 84 in total over 48 frames (about 1 to 2 LSB each), and once it read 0. Each time it moved the tap 660 frames.

The check also passes with the burst 20 and 40 dB quieter, where #284 still failed at -20 dB.

#246 stays fixed

before #284 #284 this branch
E19, worst note of the seven cases -60.2 dB -1.4 dB -1.4 dB
E18 A2 and A#2 -5.2, -5.7 dB -5.3, -5.3 dB -5.3, -5.3 dB
E18 C3 triad -2.9 dB -0.8 dB -0.8 dB
450 random chords (+12 at 48 kHz, +5 at 44.1, -7 at 32), worst note: median / 10th pct / more than 10 dB down / worst -4.5 / -14.9 / 117 / -56.2 -1.4 / -11.7 / 61 / -41.9 -1.4 / -11.7 / 61 / -41.9

Every E19 note reads the same to 0.01 dB as under #284, and so does the 450-chord sweep. The options rows that #284 moved (audioecho.FeedbackDelay@options, with and without damping) render byte for byte as they do under #284.

Tests

  • New trait E20 in tests/test_cpython_audioecho.py: a 40 ms burst through audiodelays.PitchShift and then the loop shifter, with feedback, as a pitch shifter wires them, at 14 onsets across one splice period. Each repeat must be within 6 dB of Feedback² of the one before. It fails on c03a357 (-17.6 and -20.0 dB at two onsets) and passes here (-3.7 dB at worst).
  • tests/test_cpython_audioecho.py, test_cpython_free_threading, test_binding_parity, test_cpython_audiomodal and test_cpython_audioshaper pass (117 tests).
  • verify_dsp.py, CPython against a standalone MicroPython v1.29.0 unix build from this branch: 58 comparisons, 0 failures. The E20 chain renders byte for byte the same on both at all 14 onsets.

What's left

CircuitPython wasn't built for this change, so the three-way run is still to do. The change is one integer comparison, made before the search widens.

The far search from #284 also ran where the other tap read only the last
few LSB of a fading repeat, or silence. Rounding alone makes every match
look poor there, so the splice moved the starting tap a whole window off
the material that came next. A burst shifted once and repeated through the
loop at 22.05 kHz, -5 semitones, a 30 ms window and Feedback 0.3 came back
17.6 to 20.0 dB under what Feedback leaves a repeat; through a pitch
shifter with feedback, its third pass read 19 dB under, where before the
far search it read 2.5 dB over.

The far search now needs the other tap to read more than 8 LSB on average
over the compared stretch. New trait E20 holds the burst's repeats within
6 dB of Feedback squared across one whole splice period (red before at two
onsets, 3.7 dB at worst now). E18, E19 and a 450-chord sweep read the same
as before: a held chord reads far above the floor.

Fixes #290
@bdbarnett
bdbarnett merged commit f98eb17 into main Oct 20, 2026
57 of 58 checks passed
@bdbarnett
bdbarnett deleted the fix/feedback-repeats-290 branch October 20, 2026 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

FeedbackDelay's splice search (#284) drops PitchShifter's third repeat by about 21 dB at 22.05 kHz

1 participant