Skip to content

perf: per-frame pitch stepping and shared chorus sin/cos - #7

Merged
YueyuHoshizora merged 1 commit into
mainfrom
claude/project-thread-jmbioj
Oct 21, 2026
Merged

YueyuHoshizora merged 1 commit into
mainfrom
claude/project-thread-jmbioj

Conversation

@YueyuHoshizora

Copy link
Copy Markdown
Collaborator

Requested by 小語 · project thread

Summary

Dynamic pitch (src/core/synth.ts, renderVoice). While a voice glides, follows a pitch envelope or ramps ratios/fixed Hz, the old code ran 2 **, pitchAt, pitchEnvelopeAt and two rampAt per operator on every oversampled substep. Now:

  • The pitch exponent e = glide/12 + envelope/1200 is piecewise linear, so it is evaluated at both ends of the output frame and stepped multiplicatively: 2^e(n + s/O) = 2^e(n) · r^s, r = 2^((e(n+1) − e(n))/O). That is two pows per frame (one when the exponent is flat).
  • Ramped Hz is linear, or quadratic while a Hz ramp chases a ratio ramp. The parabola through x = 0, ½, 1 (hz = h0 + x(b + cx)) is exact in both cases. A first version with linear interpolation failed the Fourier phase-reference test in engine-v6.test.ts (2e-6 error), so the quadratic is required.
  • Only a frame that holds a segment corner is smoothed, over that single frame.
  • The duplicated ratio/Hz ramp code is now in one rampedFrequency helper.

Chorus (src/core/fx.ts). The four voices are π/2 apart and the right tap leads by π/2, so one sin/cos pair gives all eight taps: left [s, c, −s, −c], right [c, −s, −c, s]. Voices whose weight is exactly 0 skip their delay reads, and their contribution is exactly zero anyway.

The LFO was already evaluated once per output frame, so it is unchanged.

Output equivalence (vs main, 8 voices, 2000 blocks × 128 frames, 48 kHz)

Scenario Max abs diff
chorus with 1/2/4 voices 0 (bit-identical)
ratio ramps, fixed-Hz + ratio ramps, pitch envelope, static 0 (bit-identical)
glide, standard / high 3.7e-9 / 3.0e-8: isolated 1-ULP Float32 rounding flips (−147 dB re peak)

Benchmark (5 interleaved base/new process pairs, median of per-block medians)

Scenario main (ms/block) this PR Δ
glide, standard 0.737 0.644 −12.6%
glide, high 1.300 1.027 −21.0%
pitch envelope 0.723 0.640 −11.6%
ratio ramps 0.667 0.638 −4.2%
fixed-Hz + ratio ramps 0.689 0.639 −7.4%
static (no dynamic pitch) 0.475 0.471 noise
chorus 2 voices (default) 0.0372 0.0253 −32%
chorus 4 voices 0.0376 0.0274 −27%

Checks

  • npm run typecheck: pass
  • npm test: 443/443 pass
  • npm run sound-quality: passed
  • npm run security: passed
  • dist/ rebuilt with npm run build

Generated by Claude Code

renderVoice evaluated 2 ** and the glide/envelope/ratio/Hz ramps once per
oversampled substep while pitch was moving. The pitch exponent is piecewise
linear, so it is now evaluated at both ends of the output frame and stepped
multiplicatively (two pows per frame); ramped Hz uses the parabola through
x = 0, 1/2, 1, which is exact for both the linear and the quadratic
(Hz ramp chasing a ratio ramp) cases. Output is bit-identical for ratio,
fixed-Hz and pitch-envelope runs and within one Float32 ULP for glides.

The chorus derived its eight LFO taps from one sin/cos pair (voices are
pi/2 apart) and skips voices whose weight is exactly zero; its output is
bit-identical.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014NSFwhZm5KbGGm7vXyfCtS
@YueyuHoshizora YueyuHoshizora self-assigned this Oct 21, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-21T20:02:30.538911Z b538ef2 PR opened
🔒 Security Review ✅ Completed 2026-10-21T20:04:57.613544Z b538ef2 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@YueyuHoshizora
YueyuHoshizora merged commit 88e55a2 into main Oct 21, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants