Measured demand (DeslanStudio, N3350)
Importing a 50 s stereo 48 kHz WAV spends 3.9 s in resampling — ab_resample_linear (src/daw/audio_buf.eigs) is a per-sample interpreted linear interpolation over ~2.2 M output samples per channel pair. Third leg of the DAW audio-I/O train (#597 mix kernels, PCM codec issue).
Builtin
buf_resample_linear of [src, dst_len] → NEW buffer of dst_len samples, matching ab_resample_linear's mapping exactly (endpoint-inclusive):
pos = i * (n - 1) / (dst_len - 1) (pos = 0 when dst_len == 1)
lo = floor(pos); hi = min(lo + 1, n - 1); frac = pos - lo
out[i] = src[lo] * (1 - frac) + src[hi] * frac
num_guard per step in VM evaluation order, so the result is bit-identical to the interpreted loop. Edges: dst_len 0 → empty buffer; negative/non-numeric dst_len raises value; empty src with dst_len > 0 raises value (the consumer's own wrapper already guards n == 0 before the loop). Pure compute → sandbox allowlist, freestanding, deterministic.
Doc note for BUILTINS.md: the kernel is linear interpolation — DeslanStudio's consumer-documented divergence from the Python original's scipy Fourier resample (scipy.signal.resample); anti-aliased/Fourier resampling is out of scope.
DoD
- Differential leg: builtin exactly equals the interpreted ab_resample_linear inner loop on seeded pseudo-random buffers across shapes (upsample, downsample, dst_len 1, dst_len == n, n == 1).
- Loud-bounds leg + sandbox allowlist entry.
- n=5 micro-bench (interp vs builtin) in the PR body.
- Full release + ASan suites; BUILTINS.md row with the linear-kernel note.
Measured demand (DeslanStudio, N3350)
Importing a 50 s stereo 48 kHz WAV spends 3.9 s in resampling —
ab_resample_linear(src/daw/audio_buf.eigs) is a per-sample interpreted linear interpolation over ~2.2 M output samples per channel pair. Third leg of the DAW audio-I/O train (#597 mix kernels, PCM codec issue).Builtin
buf_resample_linear of [src, dst_len]→ NEW buffer ofdst_lensamples, matching ab_resample_linear's mapping exactly (endpoint-inclusive):num_guard per step in VM evaluation order, so the result is bit-identical to the interpreted loop. Edges:
dst_len0 → empty buffer; negative/non-numericdst_lenraisesvalue; emptysrcwithdst_len > 0raisesvalue(the consumer's own wrapper already guardsn == 0before the loop). Pure compute → sandbox allowlist, freestanding, deterministic.Doc note for BUILTINS.md: the kernel is linear interpolation — DeslanStudio's consumer-documented divergence from the Python original's scipy Fourier resample (
scipy.signal.resample); anti-aliased/Fourier resampling is out of scope.DoD