Band-limit batch resampling (Stage 17) - #42
Open
robmorgan wants to merge 1 commit into
Open
Conversation
resample_sinc now scales its kernel cutoff when downsampling — stopband at the OUTPUT Nyquist with the same margin policy as the streaming kernel (stopband edge at the fold, not the -6 dB point; a cutoff exactly at the fold left near-Nyquist content in the transition band at ~-10 dB). Tap span widens to keep the zero-crossing count under the dilated kernel, and the Kaiser window moved to a per-call lookup table so bessel_i0 leaves the per-tap loop. AudioBuffer::resample switches from unfiltered cubic to the band-limited sinc. Measured: 18 kHz tone downsampled 2:1 folded at essentially full level before (1.9 dB rejection) and measures 89.8 dB down after; a 23 kHz tone through 48 -> 44.1 kHz conversion no longer images into the audible band. Honest scope note: pitch_shift itself measured 69.3 dB SFDR before AND after on in-band content - its pipeline only downsamples on pitch-up, where foldable content maps above Nyquist anyway - so the audible beneficiaries are the public resample APIs (review finding D5's practical weight was there, not in the shifter). New gates: downsample alias rejection >= 60 dB (resample.rs), 48->44.1 ultrasonic-fold bound (types.rs). Full suites, clippy, docs, desktop green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Closes the last confirmed defect from the 2026-08-05 quality review (D5): the batch windowed-sinc resampler had no anti-aliasing on downsample.
Changes
resample_sinccutoff-scales when downsampling: stopband at the output Nyquist, using the streaming kernel's margin policy (stopband edge at the fold, not the −6 dB point — the first attempt put the cutoff exactly at the fold and left 23 kHz content in the transition band at ~−10 dB, re-learning the lessoncutoff_for_stepalready encodes). Tap span widens to keep the zero-crossing count under the dilated kernel.bessel_i0leaves the per-tap loop.AudioBuffer::resample: unfiltered cubic → the band-limited sinc.Measured
pitch_shiftSFDR, in-band contentHonest scope note on the last row:
pitch_shift's pipeline only downsamples on pitch-up, where foldable content maps above Nyquist anyway — D5's practical weight was in the public resample APIs (resample_sinc,AudioBuffer::resample), not the shifter. Recorded in the ROADMAP Stage 17 note.Gates
test_resample_sinc_antialiases_downsampling(≥ 60 dB, fails pre-fix at 1.9) inresample.rs;test_resample_rejects_above_target_nyquistintypes.rs. Full suites, clippy-D warningsincl. qa-harnesses, fmt, docs, desktop all green.🤖 Generated with Claude Code