Pulsar Synthesis Engine — v1.0 User Guide

Advanced implementation of Curtis Roads' pulsar synthesis technique (Roads, 2001). Generates sounds ranging from pitched tones through rhythmic pulsing to complex noise textures by controlling the ratio of pulsaret duty‑cycle to inter‑onset interval.

Author: Shai Cohen Affiliation: Department of Music, Bar‑Ilan University, Israel Version: 1.0 (2025) License: MIT License Repo: GitHub
Contents:

What this does

Pulsar Synthesis Engine implements the classic pulsar synthesis technique described by Curtis Roads in Microsound (2001). A pulsar is a short waveform (pulsaret) that repeats with a given period. By controlling the ratio of the pulsaret's duration (duty cycle) to the inter‑onset interval, the synthesis spans a continuum from pitched tones (short period, high overlap) to rhythmic pulses (long period) to granular noise (stochastic onsets).

Two core modes:
  • Mode A – Periodic Pulsar Train – regular inter‑onset intervals (constant or chirped).
  • Mode B – Stochastic Pulsar Cloud – Poisson‑distributed onsets, creating clouds and textures.

The pulsaret waveform is taken from a Sound object selected in Praat – any sound can become the grain. The engine then builds a pulse train, shapes each pulse with a Hanning window (duty‑cycle control), convolves with the pulsaret, applies envelope, AM, and chirp.

Quick start

  1. In Praat, select exactly one Sound object (this will be the pulsaret waveform – can be anything from a sine tone to a field recording).
  2. Run script…Pulsar_Synthesis_Engine.praat.
  3. Choose a Preset:
    • Periodic Tone, Rhythmic Pulse, Stochastic Cloud, Chirp Sweep, Tremolo Web, Noise Burst
  4. For custom mode (preset = Custom), adjust parameters as desired:
    • Synthesis_mode – Periodic (Mode A) or Stochastic (Mode B).
    • Duration_s, Period_s (Mode A), Density_pulses_per_s (Mode B).
    • Duty_cycle – fraction of period occupied by the pulsaret.
    • Period_jitter_ratio – random variation of onset times.
    • Enable_chirp (Mode A) – glide from base period to chirp_end_period.
    • Enable_am – amplitude modulation (tremolo) with rate and depth.
    • Fade_in_s / Fade_out_s – cosine fades.
  5. Click OK. The engine builds the pulse process, shapes the pulsarets, convolves with the selected sound, and creates a new Sound object named Pulsar_presetname_mode.
Tip: Start with Periodic Tone (period 10 ms → 100 Hz) and a simple source like a sine wave. Then explore Stochastic Cloud to hear the granular texture. The visualisation shows pulse onsets (orange ticks) and, if chirp is enabled, the chirp frequency curve.
Important: This effect is implemented entirely in Praat – no Python required. The convolution step can be slow for long durations with many pulses. The duty‑cycle gate is built by iterating over each pulse and adding a Hanning window – for thousands of pulses, this may take a few seconds.

The 6 presets (+ Custom)

PresetModePeriod/densityDutySpecialDescription
Periodic ToneA10 ms (100 Hz)0.5Clean pitched tone – harmonic fundamental.
Rhythmic PulseA250 ms (4 Hz)0.15jitter 0.05Sub‑audio rhythm, percussive.
Stochastic CloudBdensity 100 /s0.5Poisson cloud – granular texture.
Chirp SweepA20→2 ms (50→500 Hz)0.5chirpGliding pitch – sweeping tone.
Tremolo WebBdensity 150 /s0.4AM 6 Hz, depth 0.7Cloud with amplitude modulation.
Noise BurstBdensity 400 /s0.8Very dense, near‑noise burst.

The perceptual continuum

Pulsar synthesis spans a full perceptual continuum based on period and duty cycle:

  • Short period (< 20 ms) → pitched tone region (fundamental frequency = 1/period).
  • Medium period (20–200 ms) → transition texture – between pitch and rhythm.
  • Long period (> 200 ms) → rhythmic pulse / rhythm.
  • Duty cycle < 0.2 → sparse clicks / sparser texture.
  • Duty cycle > 0.7 → overlapping, washy texture.
  • Poisson mode (B) → stochastic cloud / granular noise.
  • Chirp sweep → gliding pitch / spectral smear.
  • Combine with AM → tremolo / formant‑like modulation.

Suggested uses:

Synthesis modes

Mode A – Periodic Pulsar Train

Pulse onsets are generated with a constant base period, optionally modified by:

The engine builds the pulse train by placing points in a PointProcess (manual placement when chirp/jitter are active; otherwise uses built‑in Fill).

Mode B – Stochastic Pulsar Cloud

Pulse onsets follow a Poisson process with mean rate density_pulses_per_s. The inter‑onset intervals are exponentially distributed, creating a natural cloud texture.

Jitter is not used in this mode (the Poisson process already provides randomness).

Pulsaret shaping

After the pulse train is created, each pulse is shaped with a Hanning window of width duty_cycle × IOI. This is implemented by building a gate sound that sums raised‑cosine windows for each pulse, then multiplying with the pulse train. This windowing smooths the pulsaret and controls the spectral spread.

Parameters & defaults

Timing

ParameterRangeDefaultDescription
Duration_sany positive3 sTotal duration of the synthesized sound.
Period_s (Mode A)≥ 0.00050.01 sBase period between pulses (in seconds).
Density_pulses_per_s (Mode B)≥ 1100Mean pulse density for Poisson process.

Pulsaret shape

ParameterRangeDefaultDescription
Duty_cycle0.01–0.990.5Fraction of the IOI occupied by the pulsaret (Hanning window).
Period_jitter_ratio≥00.0Gaussian jitter added to each period (standard deviation = ratio × base period).

Chirp (Mode A only)

ParameterRangeDefaultDescription
Enable_chirpyes/no0Enable linear glide of period.
Chirp_end_period_s≥0.00050.005 sPeriod at the end of the duration (linear interpolation).

Amplitude modulation

ParameterRangeDefaultDescription
Enable_amyes/no0Enable amplitude modulation (tremolo).
Am_rate_hz≥04.0 HzModulation frequency.
Am_depth0–10.5Modulation depth (1 = full tremolo).

Envelope

ParameterRangeDefaultDescription
Fade_in_s≥0.005, ≤ duration×0.40.05 sCosine fade‑in duration.
Fade_out_s≥0.005, ≤ duration×0.40.10 sCosine fade‑out duration.

Output

ParameterDefaultDescription
Sample_rate44100 HzOutput sample rate.
Show_visualizationyesDraw detailed 8‑panel visualisation (waveform, spectrogram, zooms, stats).

Visualization (8 × 5.9 inch canvas)

When Show_visualization = 1, the script draws a comprehensive multi‑panel plot matching the layout of the Grisey Spectral Becoming Engine:

Tip: The visualisation is designed to reveal the inner structure of the pulsar: the waveform overview shows the pulse train, the spectrogram reveals harmonic development, and the zooms allow inspection of individual pulsarets. The chirp curve (if active) is overlaid on the spectrogram.

FAQ / troubleshooting

No sound / output is silent

Check that you have selected a Sound object before running the script – this becomes the pulsaret waveform. If the selected sound is extremely quiet, the convolution may produce low output. Also verify that Duty_cycle is not too small – if the pulsaret window is shorter than one sample, it may be skipped.

Processing is slow for many pulses

The duty‑cycle gate is built by iterating over each pulse and adding a Hanning window via Formula (part). For thousands of pulses (e.g., Noise Burst with 400 pulses/s × 2 s = 800 pulses), this can take a few seconds. Progress is printed every 50 pulses – be patient.

Chirp doesn't sound as expected

The chirp linearly interpolates the period, not frequency. Frequency = 1/period. A linear glide from period 0.02 s (50 Hz) to 0.002 s (500 Hz) produces a non‑linear frequency glide (accelerating upward). This is intended and matches Roads' descriptions of chirped pulsars.

Understanding duty cycle

The duty cycle determines how much of the inter‑onset interval is filled by the pulsaret. A low duty cycle (e.g., 0.1) gives isolated clicks; a high duty cycle (e.g., 0.8) causes overlap and a washy texture. When duty cycle > 0.5, pulsarets may overlap, creating complex interference patterns.

Jitter in Mode A

Jitter adds Gaussian noise to each period (p_jitter = period + Gauss(0, period × jitter_ratio)). This slightly randomises the onset times, broadening the spectrum and softening the pitch. Values up to 0.2 are typical.

Stochastic Mode B density

In Poisson mode, the mean pulse density is set by density_pulses_per_s. The actual number of pulses may vary around duration × density. The Info window reports the exact pulse count after generation.