{
  "id": 9307933,
  "title": "Your LFO runs at the buffer size: auditing the control rate of my own synth",
  "url": "https://urgent.news/2026/09/23/your-lfo-runs-at-the-buffer-size-auditing-the-control-rate-of-my-own",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-09-23T09:33:28.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/lluisestape/your-lfo-runs-at-the-buffer-size-auditing-the-control-rate-of-my-own-synth-5cd0"
  },
  "original_language": "en",
  "account": "The oscillator in the synth has been measured and rewritten several times, with the measurements revealing that several control rate paths had errors, some as high as a factor of thirteen. This post is about the audit of the control rate of the wavetable synth, SYNTH/1. The LFO, portamento, unison summing, and phase warp are all control-rate code that was written by feel and shipped without being measured. The LFO runs once per processBlock, but this has not been measured until now. The problem is that the LFO's frequency can change based on the buffer size, causing it to fold and run at a slower frequency than intended. The LFO is sampled at the buffer size, and its phase advances by rate * N / fs each time. However, the modulation produced by the LFO is not equal to the rate because the sine is only evaluated fs/N times a second. The LFO runs at 20 Hz, and when the buffer size is 2048, it produces a modulation frequency of 21.5 Hz, which is a fold. The issue is worsened by the host dependency of the rate knob and the smoothing of the cutoff modulation, which hides the staircase effect of the fold. The fix is to advance the LFO on a fixed sub-block, so its rate is no longer dependent on the host. This ensures that the LFO runs at the intended frequency and produces the correct modulation.",
  "summary": "A follow-up audit of SYNTH/1, my JUCE wavetable synth. The oscillator has been measured, rewritten and measured again. Everything that modulates it had never been measured once. I pointed a meter at five of those paths and all five were wrong, one of them by a factor of thirteen. In the plugin post I wrote about finding that my oscillator had been aliasing over most of the keyboard for a year,…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}