VOLTAreference

Reference / Design a sound

Pulsar synthesis

Design a sound

Open in the workbench →
On this page · 2 sections

Make independent windowed sound particles repeat as rhythm, voice-like tones or bright, broken subharmonics.

mouth = macro 0.4
voice = patch {
  source = (pulsar (freq pitch) (500Hz + mouth * 1000Hz) {
    cycles = 1.5, shape = 0.3, mask = 0, burst = 1, rest = 0,
    window = "blackman"
  }) |> clip 0,
  ampEnv = adsr 5ms 180ms 0.5 120ms,
  gain = vel * 0.4
}
t = play voice !"d3 a3 f3 e3"

Repetition sets the distance between particles. formant sets inverse particle duration, independently: 1000 Hz makes each pulsaret 1 ms long. cycles sets the number of carrier cycles inside that duration, so the carrier center is formant * cycles. These are not recordings or formant filters.

ControlMeaningDefault
rateRepetition in Hz; below 20 Hz, distinct rhythmrequired
formantInverse duration in Hzrequired
cyclesCarrier cycles, 0.25–81
shapeSine to smooth third-harmonic blend, 0–10
maskDeterministic fraction of pulses removed, 0–10
burstConsecutive sounding pulses, rounded 1–321
restSilent pulses following each burst, rounded 0–320
window"hann" or "blackman""hann"
triggerA trigger lane; see belownone (free-running)

All numeric ports accept signals. Repetition is integrated continuously; pulsaret controls are latched at each onset so a sweep never tears an existing particle. A mask of 1 mutes new pulses; existing particles finish. Burst 3/rest 1 makes 1110: at audio rates this adds a subharmonic at one quarter of the repetition rate. Independent notes receive their own reproducible mask sequence.

Triggered pulsars. With trigger the repetition clock stops and the lane decides: each rising edge through 0.5 (or every high sample of a one-sample pulse source such as patternTrig) starts one pulsaret on that sample, including the note's first. Pulsarets already sounding keep sounding, and the mask and burst/rest count advance per trigger, so one held note articulates an irregular syllable rhythm with the same particle pool:

speech = patternTrig !"t*6 ~ t*3 t*8  ~ t*4 ~ ~"
voice  = patch { source = pulsar 0Hz (freq pitch * 1.5) { cycles = 2.5, trigger = speech } |> clip 0 }

rate then only scales the overlap normalization (0 is fine). A triggered render is bit-identical at any callback size (tested). Without trigger the node, its IR and its sound are the free-running train (Coupled Physical Modeling Stage 7, production-gaps AM3).

Try two parallel pulsars at the same repetition with different formant values for a changing vowel. For a stable bass, retain a separate sine fundamental. Narrow high-formant pulses intentionally have little energy at the fundamental; this is the spectrum of the source, not a pitch-tracking error.

The notebook's Pulsar panel edits authored literals and navigates expressions. It shows one isolated pulsaret, duration and carrier frequency before output filtering and pulse scheduling. Geometry is an authored-value preview: it is drawn whenever cycles, shape and window are literals or absent, and a formant expression (the common 520Hz + vowel * 540Hz) only withholds the duration and carrier readouts, since the formant scales duration rather than shape. A signal-owned geometry port asks you to audition rather than drawing invented values. The audition waveform shows real rendered output. The wave card above the panel scrolls a train of the same authored pulsaret (geometry read from the compiled IR; stock geometry where a signal owns a port) with its amplitude peak-held over about 130 ms, so a pulse train's block-by-block level does not flicker it. Each open panel is its own egui grid, keyed by the card: two cells whose pulsar calls sit at the same cell-local offset never share column widths. Rack parameter controls share the source-editing/schema infrastructure.

Ready-to-play instruments#

import "pulsars" (vowel, choir, chrome, rubber, glass, particles) exposes six factory patches. vowel mouth, choir mouth, chrome edge, rubber jaw and glass fracture take a live 0–1 control; particles rate takes repetition Hz. For example: t = play (vowel 0.4) !"d3 a3 f3 e3". These are editable Volta instruments, independent of recorded assets. Their recommended polyphony is included in each patch.

Quality and limits#

Native, browser and plugin use one Rust renderer. It runs four times the output rate and reconstructs through a symmetric 513-tap low-pass FIR. Its exact source latency is 65 output samples, included in mixed-source and envelope alignment. No extra samples of lookahead or sample assets are required.

Rate is bounded to 0–min(12000, sampleRate/4) Hz. Inverse duration is bounded to 1–0.12*sampleRate Hz and raised to rate/8 when needed: steady overlap is at most eight. A fixed sixteen-particle pool accommodates changing rates. If a sudden rate jump fills that pool, new onsets are skipped until a slot becomes free; existing particles are never truncated. Carrier cycles are further reduced when carrier frequency would exceed 0.4*sampleRate. The third harmonic fades out approaching Nyquist. These bounds keep extreme modulation finite rather than pretending unlimited bandwidth is available.

Steady overlap receives 1/max(1, rate/formant) gain. Changing rates can briefly stack particles with different gains; leave mix headroom. The compiler uses a conservative ±40 interval: sixteen unity-bounded pulsarets times FIR absolute coefficient sum below 2.5. The factory patches use clip 0 as an explicit safety ceiling before ordinary per-voice gain; this is the existing ADAA clip processor, with its own one-sample delay, not an unbounded-range assertion. Centered odd-symmetric pulsarets have zero continuous-time area even with fractional carrier cycles. The source obeys the patch's amp envelope: releasing a note can fade a pulsaret.

State is prepared outside rendering and retained across heterogeneous voice reuse. There are no tick/reset allocations. See Pulsar Instrument 2026 09 09 for measured spectral floors, CPU, callback invariance and host evidence.

Examples: examples/songs/pulsar-vowel-architecture.volta and examples/songs/pulsar-chrome-syllables.volta.

Callback partitions produce identical held and non-stealing playback. The shared scheduler can steal a voice while looking ahead to a callback boundary; forced stealing therefore retains the existing small partition dependence, also reproduced with ordinary oscillators. The acceptance record distinguishes that scheduler limitation from pulsar state and resampling tests.