A microsound technique for generating pitched tones, noise bands, and rhythmic textures from trains of electronically generated sonic particles.

Overview

Pulsar synthesis generates electronic sound from trains of sonic particles called pulsarets. Each pulsaret is a brief waveform, typically lasting between a tenth of a millisecond and around ten milliseconds, shaped by an amplitude envelope. These particles are emitted in periodic or stochastic trains. When the train rate enters the audio frequency range (above roughly 20 Hz), the result is a pitched tone whose timbre is determined by the waveform and envelope of the individual pulsaret. Below audio rate, the train is perceived as a rhythm.

The name is borrowed from astronomy. An astrophysical pulsar is a rapidly rotating neutron star whose beamed radio emission sweeps past the Earth once per rotation, arriving as a periodic signal. The slowest known pulsars turn about once every four seconds, the fastest at over seven hundred rotations per second, so the emission spans roughly 0.25 Hz to 700 Hz (Pietruszewski 2022). That range crosses the boundary between heard pulse and heard tone, which is the boundary the fundamental frequency parameter traverses. Pulsars were discovered by Jocelyn Bell Burnell in 1967 (Hewish et al. 1968).

A boxed plot on warm paper. A flat noise trace runs the width of one rotation; near the centre a narrow double-peaked pulse rises sharply. A bracket above the pulse is labelled d; the axis below is labelled as one rotation.
Fig. 01. Where the name comes from. A pulsar is a rotating neutron star whose beamed radio emission sweeps past the Earth once per rotation, so a receiver registers a periodic train of pulses; astronomers read those trains to time the star, and the objects are precise enough to serve as clocks. This is PSR B1919+21, the first discovered, shown as an integrated pulse profile: one rotation of 1.3373 s in which the beam faces the Earth for 2.5% of the period and the rest is silence. The synthesis technique borrows the name because it borrows the structure, a brief particle followed by a silence, repeated. It writes that p = d + s, and then makes the period a musical parameter, which is the one thing the star does not permit. Plotted from Johnston and Kerr (2017), 1369 MHz, Parkes, via the EPN Database of Pulsar Profiles, CC BY 4.0.
The technique was proposed by Curtis Roads in the late 1990s and formalised in *Microsound* (2001). It belongs to the broader family of particle-based synthesis methods that descend from Dennis Gabor's acoustical quanta▸ (1946, 1947) and Iannis Xenakis's work on granular synthesis▸. Roads took the borrowing from astronomy literally enough to include, among his typical pulsaret waveforms, a "cosmic pulsar waveform emitted by the neutron star Vela X-1" (Roads 2001a, fig. 4.11e), so a rotation profile enters the technique as a table like any other.

Pulsar synthesis differs from granular synthesis in several respects. Where granular synthesis typically works with stored sound samples or sustained grains of synthetic waveforms, pulsar synthesis operates with electronically generated particles whose waveform and envelope are independently variable parameters. The separation of pulsaret waveform (which determines spectral content) from pulsaret envelope (which determines bandwidth and formant structure, the resonant peaks that give a sound its vocal or instrumental character) gives the technique a distinctive parametric architecture.

Genealogy

Roads describes pulsar synthesis as a method that "melds established principles within a new paradigm" (Roads 2001a). Its lineage runs along three distinct threads: the filtered pulse trains of analog electronic music, the particle-based formant synthesis techniques of the 1970s and 1980s, and the microsound paradigm descending from Gabor.

Filtered pulse trains (1950s-1960s). In its basic form, pulsar synthesis "generates electronic pulses and pitched tones similar to those produced by analog instruments such as the Ondioline (Jenny 1958) and the Hohner Elektronium (introduced in 1950), which were designed around the principle of filtered pulse trains" (Roads 2001a). The same principle was central to studio practice in the elektronische Musik▸ of the Cologne studio: Karlheinz Stockhausen and Gottfried Michael Koenig used filtered impulse generation as a staple of their craft. Stockhausen's theoretical essay . . . wie die Zeit vergeht . . . (1957) articulated the continuity between rhythm and pitch as a single temporal continuum traversed by acceleration. That is the perceptual territory pulsar synthesis makes directly playable through its fundamental frequency parameter.

Particle-based formant synthesis (1970s-1980s). A pulsaret with a sharp attack and exponential decay reproduces "a well-known configuration for formant synthesis, as seen in techniques such as window function synthesis, VOSIM (Kaegi and Tempelaars 1978), and FOF (Rodet 1984)" (Roads 2001a). Roads positions these formant synthesis▸ techniques as special cases of pulsar synthesis: where FOF fixes the waveform (a sine) and constrains the envelope, pulsar synthesis leaves both freely variable.

Microsound (1946-2001). Gabor proposed that any sound can be decomposed into elementary acoustical quanta▸: short time-frequency atoms, finite in both time and frequency, occupying a cell in the joint time-frequency plane whose minimum area is bounded by the uncertainty principle (Gabor 1946, 1947). Iannis Xenakis gave the particle paradigm its first compositional framework with granular synthesis▸. Pulsar synthesis "belongs to a larger family of microsonic or particle synthesis techniques" (Roads 2001a), but within this family its parentage is specific: it descends from the impulse and formant traditions above, not from the granulation of sampled sound.

Roads's synthesis of these strands (1991-2001). Roads developed pulsar synthesis from an initial implementation in James McCartney's Synth-O-Matic (1991), used to compose Clang-Tint (1994), through a SuperCollider 1 instrument coded with Stephen T. Pope in 1997 (Pope 1997), to the PulsarGenerator application built with Alberto de Campo in SuperCollider 2 (1999-2001). His contribution was to identify a parametric space these traditions had left unexplored: the independent control of pulsaret waveform, pulsaret envelope, and train characteristics (fundamental frequency, formant frequency, density), reconfigured as digital wavetables within the microsound▸ framework. As a digital technique it "accrues the advantages of precise programmable control, waveform flexibility, graphical interface, and extensibility" (Roads 2001a). The model predates its publication: the earliest surviving scripts are from 1997, and Roads points to conversations with Aldo Piccialli and colleagues in the Physics Department of the Università di Napoli "Federico II", and to three texts from that circle, as a source of inspiration (Pietruszewski 2024, p. 38, n. 7).

The following SC2 code is the original basic pulsar synthesis instrument created by Curtis Roads with Stephen T. Pope (1997). It declares wavetables for the pulsaret waveform, amplitude, fundamental frequency, formant frequency, and spatial position. Each parameter is read from a control table via Ktransient, and Apulse generates the pulsarets. The binary .Synth file also contains the wavetable data itself (waveform, envelopes, control trajectories) as embedded float arrays.

-- P U L S A R  S Y N T H E S I S
-- Copyright 1997 Curtis Roads

-- A basic pulsar generator, with envelopes for:
--  overall amplitude of a pulsar train
--  fundamental frequency
--  formant frequency
--  spatial envelope
-- The pulsaret waveform is arbitrary and can be changed.

-- Declare the outputs
defaudioout L, R;

-- Declare the wave tables and envelopes
deftable wave, ampl, fundamental, formant, spatial_position;

start {

    -- Declare local variables
    var pulsar, a_env, fun_env, form_env, pos_env, dur;

    dur = 10.0;

    a_env = Ktransient(ampl, dur, 1, 0, `dspRemove);
    fun_env = Ktransient(fundamental, dur, 1, 0, `dspRemove);
    form_env = Ktransient(formant, dur, 1, 0, `dspRemove);
    pos_env = Ktransient(spatial_position, dur, 1, 0, `dspRemove);

    pulsar = Apulse(wave, 0, 0);

    {   (pulsar.value(fun_env.value, form_env.value) *! a_env.value)
                .pan2out(pos_env.value, L, R);
    }.dspAdd;
}
Fig. 02. Basic pulsar synthesis instrument in SuperCollider 2. The Apulse UGen reads an arbitrary pulsaret waveform and is controlled by wavetable-driven envelopes for fundamental frequency, formant frequency, amplitude, and spatial position. Source: Curtis Roads (1997).

The pulsaret is related to but distinct from several precursors: the Klangbaustein▸ (sound building block) concept in early German electronic music; the grain in Xenakis and Roads's granular synthesis; and the wavelet in mathematical signal analysis. Roads explicitly positions the pulsaret as a particle that is neither a grain (too long, too tied to stored samples) nor a sample (too short, no envelope shaping). In advanced practice, both the waveform and envelope tables can be loaded from a sound sample; the pulsaret waveform and envelope remain architecturally distinct, but the resulting pulsaret begins to resemble the windowed grain of granular synthesis, and the boundary between the two techniques blurs. What to call the micro-element is itself a substantive question rather than a matter of taste. Atom▸, grain▸, quantum▸, unit▸, sample▸, dictionary entry▸ and event▸ each carry a different lineage, and each commits the work that uses it to different conceptual operations.

Commitments

Pulsar synthesis sits apart from most other synthesis techniques. It emerged from the microsound▸ paradigm, which sought to theorise electronic sound at temporal scales below the note and above the sample, and that tradition is itself marked by the disciplinary crossings SYNCULTURE investigates: mathematics (quantum theory, stochastic processes), engineering (signal processing, filter design), and musical composition (electroacoustic and computer music).

Four features follow from that inheritance. They are set out here, before the mechanism, because each is a commitment rather than a feature in the ordinary sense, and each is audible in the instrument below. Together they are what make the technique a productive case study for the analysis of synthesis as a cultural technique.

The particle as compositional primitive. Pulsar synthesis foregrounds the particle rather than the waveform, the note, or the sample as the basic unit of musical material. This represents a specific epistemological commitment: that sound is best understood and manipulated not as a continuous wave but as a stream of discrete events. The commitment has roots in Gabor's information theory, but its musical interpretation is not determined by the physics. Composers have made very different aesthetic choices within it.

The duty cycle as timbral continuum. The duty cycle parameter exposes a continuous transition between pitched tone and broadband noise within a single synthesis mechanism. In classical synthesis, these are typically separate domains (oscillators vs noise generators). Pulsar synthesis dissolves this boundary, suggesting that pitch and noise are endpoints of a single parametric axis rather than categorically different phenomena.

Formant structure without physical models. The decoupled formant frequency parameter produces spectral resonances reminiscent of vocal or instrumental formants without any reference to a physical source. This is a form of nonstandard synthesis▸ in the sense defined by Holtzman (1978): the sound is specified algorithmically rather than by modelling a physical system. The resulting timbres evoke vocal qualities while remaining irreducibly synthetic.

Micro-macro temporal bridging. Because the fundamental frequency parameter can span from sub-audio rhythmic rates to audio-frequency pitches, pulsar synthesis makes audible the continuity between rhythm and pitch that is central to the microsound thesis. A single parameter sweep can traverse the perceptual boundary between discrete pulses and fused tone, demonstrating what Roads calls the time scale continuum▸.

How it works

Roads gives the formal definition in Microsound. "A single pulsar is a particle of sound. It consists of an arbitrary pulsaret waveform w with a period d followed by a silent time interval s" (Roads 2001a, 138). The two intervals together fix the period of the train:

p = d + s

"where p is the pulsar period, d is the duty cycle, and s is silent" (Roads 2001a, 138).

fp = 1/p    fd = 1/d

"Let us define the frequency corresponding to the repetition period as fp = 1/p and the frequency corresponding to the duty cycle as fd = 1/d. Typical ranges of fp are between 1 Hz and 5 kHz, the typical range of fd is from 80 Hz to 10 kHz" (Roads 2001a, 138).

Two consequences follow, and both are audible in the instrument below. Because p is fixed by d + s, "lowering the fundamental means increasing s, and raising the fundamental means decreasing s" (Roads 2001a, 140). And because fp and fd are separately controllable, the rate of emission and the spectral peak move independently: this decoupling is what gives pulsar tones their formant▸ structure. In the cells below fp is the argument fund and fd is form, which sets the particle's duration as form.reciprocal, that is d.

A pulsaret is the product of two lookup tables: a pulsaret waveform table and a pulsaret envelope table. In the original Pulsar Generator program by Roads and de Campo, each is a wavetable▸ of 2048 floating-point values that can hold any arbitrary shape. The synthesiser reads through both in parallel and multiplies them sample by sample. The waveform determines the spectral content of the particle; the envelope shapes its amplitude over time. Their product is the pulsaret, the elementary sonic particle emitted at each period of the train.

A catalogue of standard pulsaret envelopes: (a) Rectangular, (b) Gaussian, (c) Linear Decay, (d) Exponential Decay, (e) Linear Attack with duty cycle, (f) Exponential Attack, (g) FOF envelope, (h) Bipolar modulator.
Fig. 03. A standard catalogue of pulsaret envelopes. (a) Rectangular. (b) Gaussian. (c) Linear Decay. (d) Exponential Decay. Here b is the steepness of an exponential curve. (e) Linear attack with duty cycle d. (f) Exponential attack, where g is the steepness of the curve. (g) FOF envelope. (h) Bipolar modulator. Source: Roads (2020), figures conversion Marcin Pietruszewski.
Examples of pulsaret waveforms: (a) Sine, (b) Multicycle Sine, (c) Gaussian Limited Sine, (d) Saw, (e) Gray Noise.
Fig. 04. Examples of pulsaret waveforms. In practice, any waveform can be used. (a) Sine. (b) Multicycle Sine. (c) Gaussian Limited Sine. (d) Saw. (e) Gray Noise. Source: Roads (2020), figures conversion Marcin Pietruszewski.

The choice of envelope determines the spectral bandwidth of the pulsaret: a narrow envelope such as a Gaussian or exponential decay concentrates energy around the formant frequency and produces a sharp resonant peak, while a wide envelope approaching the full period yields a nearly pure tone. The choice of waveform determines the fine spectral structure within that bandwidth: a sine produces a single formant peak, a sawtooth fills in the harmonics, and a noise waveform distributes energy stochastically. Because the two tables are multiplied sample by sample, every combination produces a distinct spectral profile. The catalogues above show standard shapes, but in practice both tables can hold any arbitrary curve, hand-drawn or algorithmically generated.

A single pulsar consisting of an arbitrary pulsaret waveform w with a duration d followed by an interval of silence s, within a period p.
Fig. 05. A single pulsar consists of an arbitrary pulsaret waveform w with a duration d followed by an interval of silence s. Source: Roads (2020), figures conversion Pietruszewski.
The succession of pulses forming a pulsar train, showing three pulsarets with varying duty cycles within successive periods.
Fig. 06. The succession of pulses is called the pulsar train. As the duty cycle d decreases relative to the period p, the spectrum broadens. Source: Roads (2020), figures conversion Pietruszewski.

As the duty cycle shrinks relative to the period, more silence enters the signal and the spectrum broadens. At the limit, an infinitely narrow pulsaret gives a click train with a flat spectrum; at the other extreme, an envelope that fills the whole period leaves no silence at all and the result approaches a conventional oscillator.

Table 01. Core parameters of a pulsar synthesiser and their perceptual correlates.
ParameterRangePerceptual effect
Fundamental frequency (f)sub-audio to audio, 0.1 Hz to 5 kHz and abovePitch (audio rate) or rhythm (sub-audio)
Pulsaret waveformsine, arbitrary wavetableSpectral content, timbre character
Pulsaret envelopeGaussian, raised cosine, exponential, arbitraryBandwidth, formant shape
Duty cycle (width)0.0 to 1.0Spectral bandwidth: narrow = broadband, wide = tonal
Formant frequencyindependent of fResonant peak in the spectrum
Train density0.0 to 1.0Proportion of periods containing a pulsaret vs silence

Fundamental and formant frequency are decoupled, which permits effects analogous to the source-filter model▸ of speech: pitch varies independently of resonant structure. Train density is the odd one out in this table. The Pulsar Generator implements it as pulsar masking and nuPG as a pulse probability mask, but the browser instrument below has no control for it, so in the cells that follow every period carries a pulsaret. The downloadable file at the end of the entry does have one, in the two forms the PG implements for a single train, burst and stochastic.

Web implementation

Up to this point the entry has described the technique. From here it runs it, and the writing turns to the second person accordingly: the cells below are things to evaluate rather than things to read.

The synthesis described above runs here, in the browser. The language▸ and the synthesis server▸ are both SuperCollider compiled to WebAssembly, so the examples are not illustrations of the technique but the technique itself, running. Every cell shares one session: the definitions, buffers, and variables persist between them, and the pulsaret drawn below is the one every cell reads.

Construct the particle first. The waveform table sets the spectral content of the pulsaret, the envelope its bandwidth and formant shape; their product is the pulsaret itself. Drawing on either canvas writes that table straight into the session buffers ~wave and ~envelope.

pulsaret builder
draw directly on the waveform and envelope canvases, or select a preset from the dropdown
The pulsaret builder: two side-by-side plots, one headed pulsaret waveform showing a sine-like trace, one headed pulsaret envelope showing a bell curve, and beneath them a third plot of the two multiplied together.
The pulsaret builder, shown as it stands. Open the session to draw on it.
Demo 01. Interactive pulsaret construction. Each table stores 2048 floating-point values representing one cycle of an arbitrary shape. The pulsaret waveform (left) is multiplied sample-by-sample with the pulsaret envelope (right) to produce the resulting pulsaret (below). Draw on either canvas or select from the presets. The vela X-1 preset is traced from Roads (2001, fig. 4.11e), "cosmic pulsar waveform emitted by the neutron star Vela X-1", sampled from the printed trace rather than from observational data.

Evaluate the definition first. GrainBuf reads the waveform and envelope tables and emits one pulsaret per trigger; the trigger rate is the fundamental f, and the formant sets particle duration independently of it. The definition follows figure 16.17 of de Campo and Pietruszewski (2025), where Impulse.ar runs at the fundamental while grain duration and playback rate are both derived from the formant: grdur = form.reciprocal and rate = form * BufDur.kr(wavebuf). Two things are added here that the figure does not need, since it drives a node proxy rather than a held synth: Lag on the controls, so a slider move glides instead of stepping, and a gated envelope, so one node can be created and released.

01

Build the synthesis

no sound

Emit the pulsaret as a train. The trigger rate is the fundamental; the formant sets particle duration independently of it. Wait for “Instrument ready”.

(
Routine({
    // After de Campo and Pietruszewski, "Microsound", in The SuperCollider
    // Book, 2nd ed. (MIT Press, 2025), fig. 16.17: the trigger runs at the
    // fundamental, while grain duration and playback rate both follow the
    // formant. ~wave and ~envelope are allocated with the session and hold
    // whatever the pulsaret builder above currently draws.
    SynthDef(name: \handbook_live, ugenGraphFunc: {
        |out = 0, wavebuf = 0, envbuf = 1,
         fund = 100, form = 400, amp = 0.5, pan = 0, gate = 1|
        // Added here, not in the figure: smoothing, so a slider move
        // glides, and a gate, so one node can be held and released.
        var fundSmooth = Lag.kr(in: fund, lagTime: 0.05);
        var formSmooth = Lag.kr(in: form, lagTime: 0.05);
        var ampSmooth = Lag.kr(in: amp, lagTime: 0.05);
        // One pulsaret per trigger; silence fills the rest of the period.
        var trig = Impulse.ar(freq: fundSmooth);
        var grdur = formSmooth.reciprocal;
        var rate = formSmooth * BufDur.kr(bufnum: wavebuf);
        var signal = GrainBuf.ar(
            numChannels: 2, trigger: trig, dur: grdur,
            sndbuf: wavebuf, rate: rate, pos: 0,
            interp: 4, pan: pan, envbufnum: envbuf
        );
        var envelope = EnvGen.kr(
            envelope: Env.asr(releaseTime: 0.1),
            gate: gate, doneAction: 2
        );
        Out.ar(bus: out, channelsArray: signal * ampSmooth * envelope);
    }).add;
    s.sync;
    "Instrument ready. Evaluate cell 02 to play.".postln;
}).play(clock: AppClock);
)

Nothing sounds yet. A SynthDef is a description of a signal graph, compiled and sent to the server to be held there under a name; it is the account of an instrument rather than an instance of one. Cell 02 creates the instance.

What the definition says, in order. Impulse.ar emits a single-sample click fund times a second, which is the train of triggers. Each trigger starts one pulsaret. GrainBuf makes that pulsaret by reading the waveform table once through, multiplying it by the envelope table as it goes, and placing the result in the stereo field. The particle lasts 1/form seconds, so raising the formant shortens the particle and changes nothing else. EnvGen holds the whole thing open while the gate is 1 and lets it go when the gate closes. The rest is arithmetic tying those parts together.

For readers who already write SuperCollider, the rate calculation is the line worth pausing on. rate = form * BufDur.kr(wavebuf) sets playback speed so that the table is traversed exactly once per grain whatever the grain's length: BufDur is the table's duration at unity rate, and multiplying by the formant frequency makes the read complete in 1/form seconds. interp: 4 is cubic interpolation, which earns its cost when the table is short and the rate high. Lag.kr at 50 ms is not in the figure; it is here because the sliders write to these controls over OSC, and unsmoothed jumps in fund and form are audible as steps. doneAction: 2 frees the node once the release finishes, which is why Stop instrument leaves nothing behind on the server.

Creating the synth makes the parameter table above audible. The controls address that node, ~handbookSynth, directly over OSC, so a slider move takes effect without recompiling anything.

02

Play and transform

makes sound

Create the synth controlled by the instrument panel. Re-evaluating replaces the current voice. Unmute output after using Stop all.

(
if(SynthDescLib.global.at(\handbook_live).isNil, {
    "Evaluate cell 01 first: it compiles the definition.".postln;
}, {
    ~handbookSynth.tryPerform(\free);
    if(~handbookGroup.isNil, {
        ~handbookGroup = Group.head(aGroup: s.defaultGroup);
    });
    ~handbookSynth = Synth(
        defName: \handbook_live,
        args: [\wavebuf, ~wave, \envbuf, ~envelope,
            \fund, 100, \form, 400, \amp, 0.5],
        target: ~handbookGroup,
        addAction: \addToTail
    );
});
)

Instrument / pulsar

01

Evaluate the synth above to play. These controls address ~handbookSynth in the same session. The pulsaret builder (above ) stays live while it plays: draw on either canvas and the particle changes shape on the next pulsar emitted, without the instrument being restarted.

Pulsar parameters
100 Hz

Particle repetition rate

400 Hz

Inverse of particle duration

0.50

Controls send values to the named synth. Changes made in code are not reflected in the sliders. Stop instrument closes the gate on whichever instrument is sounding, so it releases rather than cuts.

Control by table

The instrument above is played the way instruments are usually played: a hand moves a control, the sound follows. That is not how pulsar synthesis was conceived. De Campo and Pietruszewski (2025) put the point plainly: pulsar synthesis "was designed by Curtis Roads in conjunction with a special control model: a set of tables which can be edited by drawing is used for designing both waveforms (for pulsaret and envelope) and a group of control functions for synthesis parameters over a given time."

Two claims are folded together there: that the table is the object of composition, and that the loop is the process that makes it sound. The section after this one takes both apart. What matters here is that the cells below are the first place either becomes audible.

The cell below follows figure 16.16 of de Campo and Pietruszewski (2025) and the closing step of their figure 16.17. It generates four control tables and creates a synth that reads them. BufDur.kr(bufnum) / fundtime sets the traversal so a table is read once per its own number of seconds, and PlayBuf with loop: 1 repeats it. Evaluate it a second time while it sounds: the trajectories are rewritten under the instrument, which never stops.

03

Build the tables and hand the instrument to them

makes sound

Every parameter becomes a table, and a synth is created to read them. These are generated here, but they can equally be drawn: the plots below the cell are editable, and a pointer press writes into the same buffer the instrument reads. The panel's voice is released as the tables take over. Re-evaluate while it plays: the tables are rewritten under the instrument rather than restarting it.

(
Routine({
    // Cell 02's voice, if it is still held, is released here. The tables are
    // about to drive the same instrument, and leaving the panel's node running
    // would put two voices in the air instead of showing control move from the
    // hand to the table. Closing the gate lets it release rather than cut.
    if(~handbookSynth.notNil, {
        ~handbookSynth.set(\gate, 0);
        ~handbookSynth = nil;
        "Panel voice released: control moves to the tables.".postln;
    });

// ---- Tables ---- // Held in a function so the cell below can regenerate them without // recompiling the definition or restarting the instrument. // After fig. 16.16 in the SuperCollider Book, ch. 16: the exponents map a // 0..1 curve onto useful ranges. 2048 values per table, as in the Pulsar // Generator, where every control object is a wavetable of that length // whatever its time scale. ~tableSize = 2048; ~newTables = { ~curves = (); ~curves.fund = 200 Env(levels: { 1.0.rand } ! 8, times: { 1.0.rand } ! 7, curve: \sin).discretize(n: ~tableSize).as(Array); ~curves.form = 100 (0.5 + Env(levels: { rrand(0.0, 1.0) } ! 8, times: { 1.0.rand } ! 7, curve: \sin).discretize(n: ~tableSize).as(Array)); // Figure 16.16 uses a constant here (0.2 repeated). A trajectory is // used instead, so that amplitude reads as a table like the others. ~curves.amp = 0.05 + (0.9 * Env(levels: { 1.0.rand } ! 6, times: { 1.0.rand } ! 5, curve: \sin).discretize(n: ~tableSize).as(Array)); ~curves.pan = Signal.sineFill(size: ~tableSize, amplitudes: { 1.0.rand } ! 7).as(Array);

// Allocate once, then write into the same buffers. A synth already // reading them takes up the new tables without being restarted. if(~fundTab.isNil or: { ~fundTab.numFrames != ~tableSize }, { [~fundTab, ~formTab, ~ampTab, ~panTab].do({ |buf| buf.tryPerform(\free); }); ~fundTab = Buffer.alloc(server: s, numFrames: ~tableSize, numChannels: 1); ~formTab = Buffer.alloc(server: s, numFrames: ~tableSize, numChannels: 1); ~ampTab = Buffer.alloc(server: s, numFrames: ~tableSize, numChannels: 1); ~panTab = Buffer.alloc(server: s, numFrames: ~tableSize, numChannels: 1); s.sync; }); ~fundTab.sendCollection(collection: ~curves.fund); ~formTab.sendCollection(collection: ~curves.form); ~ampTab.sendCollection(collection: ~curves.amp); ~panTab.sendCollection(collection: ~curves.pan); s.sync; ~tableBufs = (fund: ~fundTab, form: ~formTab, amp: ~ampTab, pan: ~panTab);

// Publish every eighth value for plotting under this cell, together // with the buffer it came from and that stride: the page needs both to // write back into the same buffer when a reader draws on the plot. The // string is joined rather than posted as an array: posting truncates // long collections with "...etc...", which would cut the values short. ~tableStep = 8; [\fund, \form, \amp, \pan].do({ |name| var curve = ~curves[name]; var points = curve[(0, ~tableStep .. curve.size - 1)].round(0.0001); ("HB_TABLE " ++ name ++ " " ++ ~tableBufs[name].bufnum ++ " " ++ ~tableStep ++ " [" ++ points.join(",") ++ "]").postln; }); }; ~newTables.value;

// ---- Setting the traversal ---- // One value per table: the seconds a full traversal takes. It is signed, // and a negative value crosses the table backwards in that same time, so // -60 is a minute in reverse. Each call tells the page as well as the // server, so the playheads follow. ~looptime = ~looptime ? 10; ~loops = ~loops ? (fund: ~looptime, form: ~looptime, amp: ~looptime, pan: ~looptime); // The page draws a playhead per table from these announcements: one line // per table while they are drifting, and a single line for all four when // they are put back on one loop and read from the start together. ~announce = { [\fund, \form, \amp, \pan].do({ |name| ("HB_LOOP " ++ name ++ " " ++ ~loops[name]).postln; }); }; // All four together. The reading position is reset with them: one loop // means one position and not merely one period, so what is heard is a // single traversal rather than four that happen to share a length. ~setLoop = { |seconds| ~looptime = seconds; ~loops = (fund: seconds, form: seconds, amp: seconds, pan: seconds); ~tableSynth.tryPerform(\set, \fundtime, seconds, \formtime, seconds, \amptime, seconds, \pantime, seconds, \t_sync, 1); ("HB_LOOP " ++ seconds).postln; }; // One each, in table order: fundamental, formant, amplitude, pan. Nothing // is reset here: they are meant to come apart. ~setLoops = { |fund = 10, form = 10, amp = 10, pan = 10| ~loops = (fund: fund, form: form, amp: amp, pan: pan); ~tableSynth.tryPerform(\set, \fundtime, fund, \formtime, form, \amptime, amp, \pantime, pan); ~announce.value; };

// ---- The instrument that reads them ---- // One traversal of each table per its own number of seconds: the loop is // the process. SynthDef(name: \handbook_tables, ugenGraphFunc: { |out = 0, wavebuf = 0, envbuf = 1, fundbuf = 2, formbuf = 3, ampbuf = 4, panbuf = 5, fundtime = 10, formtime = 10, amptime = 10, pantime = 10, gate = 1, t_sync = 0| // One traversal of a table per its own number of seconds. The value is // signed: PlayBuf with loop: 1 reads backwards at a negative rate and // wraps at the start of the buffer, so -60 crosses the table the other // way in the same minute, without a value being rewritten. A trigger on // t_sync sends all four readers back to the first frame together. var read = { |bufnum, seconds| A2K.kr(PlayBuf.ar(numChannels: 1, bufnum: bufnum, rate: BufDur.kr(bufnum: bufnum) / seconds, trigger: t_sync, startPos: 0, loop: 1)); }; var fund = read.value(fundbuf, fundtime); var form = read.value(formbuf, formtime); var amp = read.value(ampbuf, amptime); var pan = read.value(panbuf, pantime); var signal = GrainBuf.ar( numChannels: 2, trigger: Impulse.ar(freq: fund), dur: form.reciprocal, sndbuf: wavebuf, rate: form BufDur.kr(bufnum: wavebuf), pos: 0, interp: 4, pan: pan, envbufnum: envbuf ); var envelope = EnvGen.kr( envelope: Env.asr(releaseTime: 0.1), gate: gate, doneAction: 2 ); Out.ar(bus: out, channelsArray: signal amp * envelope); }).add; s.sync;

// Only created if one is not already playing. Re-evaluate this cell while // it sounds and the trajectories are recomposed underneath it; the synth // is never restarted, because the server keeps reading the same buffers. if(~tableSynth.isNil, { ~tableSynth = Synth( defName: \handbook_tables, args: [\wavebuf, ~wave, \envbuf, ~envelope, \fundbuf, ~fundTab, \formbuf, ~formTab, \ampbuf, ~ampTab, \panbuf, ~panTab, \fundtime, ~loops.fund, \formtime, ~loops.form, \amptime, ~loops.amp, \pantime, ~loops.pan], target: ~handbookGroup, addAction: \addToTail ); // Tell the page where the traversal starts, how long it takes and in // which direction, so it can draw a playhead across each table. ("HB_LOOP " ++ ~looptime).postln; "Control tables ready. The instrument now reads them.".postln; }, { "Tables rewritten under the instrument already playing.".postln; }); }).play(clock: AppClock); )

fundamentalHz
formantHz
amplitude
pan
draw on any of the four plots: a drawn value is written straight into the buffer the instrument is reading
The four control tables, each normalised to its own range. These are the curves the instrument traverses once per traversal time. Every evaluation of the cell generates a new set: the levels and times of each envelope are drawn at random, so no two runs give the same trajectories. Re-evaluate while the instrument is sounding and the new values are written into the same buffers, which the server keeps reading. The tables change under the sound rather than the sound being restarted. The plots are also editable: drag across one and the values under the pointer are written into the same buffer, within the range the procedure set, which the head states. A table that has been drawn on says so in its head until the next generation writes over it. The four ways of arriving at a table meet in the one buffer. It can be drawn here by hand; generated by procedure, as the cell above does; written by an expression while it sounds, as cell 05 does; or filled from an analysis of a recorded sound. Nothing in the instrument distinguishes them: it reads 2048 values, however they got there.

Evaluating that cell releases the panel's voice as it takes over. The two would otherwise sound together, and the point of the section is that control has moved rather than been doubled: from here the sliders address nothing, and the tables are the instrument.

How fast the tables are read, and in which direction, is a separate decision from what they contain, and the definition takes it as a control rather than as a property of the material. There is one value for it, the seconds a traversal takes, and it is signed: PlayBuf with loop: 1 reads backwards at a negative rate and wraps at the start of the buffer, so -60 crosses a table in a minute the other way without a value being rewritten. Each of the four tables has its own, which is the more consequential move: given different times they stop being one loop, each returning to its start after its own number of seconds, and they coincide only where those periods do. Setting the four together puts them back in step as well as on one period: the call resets the reading position with the time, since a shared length between readings that started at different moments is not one loop but four of equal size.

The cell below is calls on that, one line at a time. Nothing is recompiled, no synth is replaced, and the sound continues across every one of them.

04a

Change the traversal while it runs

makes sound

Single calls on the setters cell 03 defined. The traversal time is the only control over the reading, and it is signed: -60 crosses the tables backwards in a minute. Nothing is recompiled and the instrument is never restarted. Each call stands in a box of its own, because running them together would set the traversal a dozen times over in one go. Each box below runs on its own: change a value and press Evaluate again.

Faster: the same trajectories, two seconds end to end.

~setLoop.value(2);
04b

Slower: a minute to cross the tables.

~setLoop.value(60);
04c

The same minute, backwards. The value is signed, and the rate with it, so the tables are read from the end and wrap at the start: nothing is rewritten, the particle is unchanged, and only the order of the reading reverses.

~setLoop.value(-60);
04d

Back to ten seconds, forwards.

~setLoop.value(10);
04e

A traversal time each, in table order: fundamental, formant, amplitude, pan. The four stop being a single loop. Each returns to its start after its own number of seconds, and they coincide only where those periods do.

~setLoops.value(10, -20, 5, 40);
04f

Back to one loop for all four, and back in step with it: setting the four together returns them to the same position as well as the same period.

~setLoop.value(10);

Neither this cell nor the next is meant to be run whole, and so the two are the cells with no Evaluate button. They are pages of separate calls, and running all of them at once would set the traversal a dozen times over. Put the cursor on one line and press Shift Enter to run that line by itself; the lines that run flash briefly so you can see what went. This follows SuperCollider's own rule. If text is selected, the selection runs. If not, and the cursor sits inside a block whose brackets each begin a line, the whole block runs as one expression, which is how the multi-line cells above are evaluated. Otherwise the single line under the cursor runs.

This is why two of the calls in the next cell are wrapped in bare brackets on their own lines. Writing a table takes more than one line, and without the brackets a reader would have to select all of them by hand before pressing the key. With them, the cursor anywhere inside is enough. The convention is not decoration: in SuperCollider a bracketed block is the unit of evaluation, and putting one around a multi-line expression is how you say that these lines are one act. Elsewhere the Evaluate button runs the entire cell, as does Shift Cmd Enter.

The pulsaret builder (above ) stays live throughout. Draw on either canvas while the tables are playing and the waveform and envelope are read from the same two buffers the builder writes into, so the particle changes shape under the trajectories without anything being restarted. Four tables govern the train, two govern the particle, and all six can be rewritten while it sounds.

A red playhead crosses each plot as the instrument reads, one per table, each following that table's own traversal time and direction. It is drawn from the page clock rather than measured on the server, so it shows where in the tables the traversal has reached rather than reporting it; over a long session it will drift. Every call that sets the traversal resynchronises it.

05a

Rewrite the tables and the particle while they sound

makes sound

Where cell 04 changes how the tables are read, these calls change what is read: fresh trajectories, then the pulsaret itself. Each writes into a buffer the server is already reading, so nothing is recompiled and the instrument is never restarted. Each call stands in a box of its own; where one runs over several lines it is wrapped in brackets and the box holds the whole block. The pulsaret builder above stays live throughout: draw on either canvas while the tables are playing and the new shape is heard on the next pulsar emitted. Each box below runs on its own: change a value and press Evaluate again.

New trajectories, written under the sounding instrument.

Routine({ ~newTables.value; "Tables rewritten.".postln; }).play(clock: AppClock);
05b

The pulsaret is a table as well, and nothing says it has to be drawn. These write straight into the buffers the builder writes into, so the change is heard on the next pulsar emitted. The canvases above will no longer show what the instrument is reading; draw on one to take it back.

(
~wave.sendCollection(collection: Array.fill(~wave.numFrames, { |i|
    var x = i / ~wave.numFrames;
    (sin(2pi * x) + (0.4 * sin(2pi * 7 * x)) + (0.2 * sin(2pi * 11 * x))) / 1.6;
}));
)
05c

A rectangular envelope: no taper at the edges, so the widest spectrum.

~envelope.sendCollection(collection: Array.fill(~envelope.numFrames, { 1.0 }));
05d

Back to something smoother: a Gaussian, which narrows the band again.

(
~envelope.sendCollection(collection: Array.fill(~envelope.numFrames, { |i|
    exp(-0.5 * (((i / ~envelope.numFrames) - 0.5) / 0.15).squared);
}));
)
05e

Stop, and let the playhead stop with it.

~tableSynth.tryPerform(\set, \gate, 0); ~tableSynth = nil; "HB_LOOP stop".postln;

Once the tables are driving the instrument, the panel above addresses nothing: its voice was released when cell 03 took over. Nothing is broken, control has moved. The reader who wants the sliders back can evaluate cell 02 and take it, which puts a played voice alongside the read one; Stop instrument releases both. That exchange is the whole argument of this section in one gesture. De Campo and Pietruszewski (2025) go further still in figure 16.18, sending fresh tables to the buffers while the sound continues, so that editing a curve and hearing its consequence are the same act. That is the condition the PulsarGenerator was built to inhabit.

The table and the loop

A table does nothing. It is an array of numbers held in memory, and it makes no sound until something reads it. Pietruszewski (2024, p. 78) describes this condition as potential rather than inert: the loop-form "functions at first as a proposal, or to use Michael Koenig's term 'variant-form'. Whether as a graphic shape or as a description of an algorithmic procedure, its existence is potential. It exists 'outside of time', waiting to be hooked up to the actual synthesis model and sound out." Xenakis states the underlying position flatly: "music is outside of time and time serves only for it to manifest itself" (Xenakis and Varga 1996, p. 83).

What converts the one state into the other is the reading. Wolfgang Ernst supplies the term: "The elementary unit of a technological being-in-time is the time-varying signal. When not in motion, a phonographically recorded acoustic signal is not in its signal state but frozen in a state of graphic storage. It becomes an operative media diagram only when turned back into a time object once again, un-frozen and transduced by the movement of the apparatus and the sonic pickup" (Ernst 2019, p. 684). In the Pulsar Generator the apparatus doing the un-freezing is the emission clock. "Iterations over shapes as data structures project structural into temporal order. Iteration counts and yields outside-of-time structures in time" (Pietruszewski 2024, p. 79). The rate of that counting is the pulsar emission rate itself, running "usually 1 to 3000, with values between 35-60 functioning at the threshold of discrete pulses and a continuous tone texture" (ibid.), and it is also the update clock: the program reads every synthesis parameter once per iteration and not otherwise.

This is what makes a uniform table structure coherent rather than merely economical, and it is the design decision the two programs below are built on: tables of identical length, edited through identical graphic editors, spanning the micro scale of the pulsaret and the meso scale of the train. "While there is no visual difference between, for example, the 'pulsaret table' and 'fundamental frequency table', their role in the circuit differs significantly" (Pietruszewski 2024, p. 79). The arrangement is object-oriented polymorphism: "each of these loops represents the same basic unit, a sequence of floating point values distributed horizontally along the x-axis... While its function changes depending on the place in the synthesis circuit's logical structure, the shape's basic form remains unchanged" (Pietruszewski 2024, p. 80). The identity is not rhetorical. It licenses a shared vocabulary of operations, "resampling to a new range, reversing, scaling, morphing with other values, and erasing", which applies to a waveform and to a minute-long amplitude contour alike, because both are the same kind of object until something reads them. The point is pressed to its literal limit in an appendix that prints all 2048 values of a single table across fourteen pages (Pietruszewski 2024, pp. 139-152).

None of this begins with sound synthesis. The table is among the oldest objects in computation, and it turns up in the nineteenth-century instruments that precede electronic sound already doing this work. In the 1881 discussion of Thomson's tide predictor before the Institution of Civil Engineers, the Astronomer Royal George Biddell Airy described a table he had built with his assistant Mr Ellis: all vulgar fractions with numerators and denominators not exceeding 100, together with their logarithms, "arranged, not in the order of numerators or in the order of denominators, but in the order of the ultimate value of the fractions" (Thomson 1881, discussion, p. 40). It was for choosing gear ratios. Given a required proportion between two tidal arguments, one took its logarithm, ran an eye along the table, and found every fraction near that value gathered in one place; the numbers "were taken at sight from the table". The whole design is in the sort order, and the same values ordered by numerator would have been useless. Computation ran on this trade for centuries, storage against arithmetic, and it is the trade a wavetable oscillator still makes: Mathews's stored function tables in MUSIC III and its successors exist because computing a sine every sample was ruinous and reading one was not (Mathews 1969). A pulsaret table is a machine part of that kind. What distinguishes it is that the rate of reading was made a musical parameter rather than fixed in the gearing.

The predictor sits between tables. It reads one, Airy's fractions cut into the teeth of its wheels, and it writes another, since what a tide-predicting machine finally produces is a printed tide table. Both are in the same discussion. Mr Law set prediction against record, comparing "the tables of the late Sir John Lubbock" with the height the tide actually reached at the Shadwell entrance of the London docks through January and February 1836, and where the two diverged he named the residual by a third table, giving the force of the wind on that day "according to the Admiralty table" (Thomson 1881, discussion, pp. 46-47). Three tables doing three jobs: one read by a mechanism, one written for a reader, one supplying a scale against which the unexplained could be measured. None of them is simply a set of numbers. Each is a set of numbers together with a way of being read, and the second half is where the work is done.

The cells above make the difference audible. ~setLoop.value(2) and ~setLoop.value(60) traverse the same four tables at rates thirty times apart. At two seconds the fundamental table is a gesture, a sweep across the boundary between rhythm and pitch; at sixty the same curve is a slow drift, and what was a gesture has become a form. None of the stored values changed. Only the reading did. In these terms the loop "institutes a mediation between an inter-elementary, macro-temporal whole and an intra-elementary micro-temporal fragment", where "the focus is not on form as a fixed entity but on form as a transforming modulator or a cascade of nested loops" (Pietruszewski 2024, p. 80).

Because the table and its reader are separate, the table can be rewritten while the reading continues. This is "an essential generalisation within the nuPG program... the ability to formalise a new loop at a run time of the program" (Pietruszewski 2024, p. 81). In the Pulsar Generator it appears as a bank of settings crossfaded at a variable rate, and in de Campo and Pietruszewski (2025, fig. 16.18) as fresh tables sent to the buffers while the sound goes on. Here ~newTables.value replaces all four trajectories under an instrument that never stops. This is not interrupting a sound in order to change it. It is editing the memory the sound is reading from, which puts a composer in a different relation to a running process than starting and stopping it does.

Four tables and a loop are already the whole control model. What the Pulsar Generator and nuPG add, in the section that follows, is scale and an interface: thirteen tables rather than four, drawn by hand rather than filled by code, with the same 2048 values behind each one. Read in this order, their design reads less as a set of engineering choices than as a position on where musical time comes from.

Instrumental implementations

Pulsar Generator (PG)

The Pulsar Generator was developed by Curtis Roads and Alberto de Campo in SuperCollider 2 at the University of California, Santa Barbara, and distributed by CREATE. It is the first instrumental encapsulation of the pulsar synthesis technique, providing wavetable-driven control over all core parameters: pulsar train duration, fundamental and formant frequency envelopes, pulsaret waveform and envelope, amplitude, and spatial path. The interface extends the basic synthesis engine with pulsar masking (burst, channel, and stochastic masking modes), convolution with sampled sounds, and multi-channel mixing (Fig. 08).

The program generates three simultaneous pulsar trains sharing one fundamental frequency table, each with independent formant, panning, and amplitude tables. This design dates back to Roads's first SuperCollider 1 sketches of 1997, where the configuration was called "additive": a unified clocking mechanism synchronises all three trains from a single fundamental frequency cycle, which around 2000 also kept processing costs low. The result is a conception of polyphony specific to pulsar synthesis: not multiple independent voices but multiple spectral-spatial interpretations of a single temporal stream (Pietruszewski 2024, 2026). The original SC1 script survives (Fig. 07): three Apulse generators read the same pulsaret waveform and are driven by one shared fundamental frequency envelope, while each follows its own formant and spatial position envelope.

-- P U L S A R  S Y N T H E S I S
-- Copyright 1997 Curtis Roads

-- An additive pulsar generator. The pulsar streams share a common
-- fundamental frequency and waveform, but follow different formant
-- and spatial envelopes.

-- Declare the stereo output channels
defaudioout L, R;

-- Declare the wavetable and envelopes
deftable wave, ampl, fundamental, formant1, formant2, formant3,
    spatial_position1, spatial_position2, spatial_position3;

 -- Pulsar instrument
start {

    -- Declare local variables
    var osc, a_env, fun_env,
        form_env1, form_env2, form_env3,
        pos_env1, pos_env2, pos_env3,
        dur;

    dur = 30.0;

    -- Overall amplitude envelope
    a_env = Ktransient(ampl, dur, 1, 0, `dspRemove);

    -- Fundamental frequency envelope
    fun_env = Ktransient(fundamental, dur, 1, 0, `dspRemove);

    -- Formant envelopes
    form_env1 = Ktransient(formant1, dur, 1, 0, `dspRemove);
    form_env2 = Ktransient(formant2, dur, 1, 0, `dspRemove);
    form_env3 = Ktransient(formant3, dur, 1, 0, `dspRemove);

    pos_env1 = Ktransient(spatial_position1, dur, 1, 0, `dspRemove);
    pos_env2 = Ktransient(spatial_position2, dur, 1, 0, `dspRemove);
    pos_env3 = Ktransient(spatial_position3, dur, 1, 0, `dspRemove);

    osc1 = Apulse(wave, 0, 0);
    osc2 = Apulse(wave, 0, 0);
    osc3 = Apulse(wave, 0, 0);

    {  (osc1.value(fun_env.value, form_env1.value) *! a_env.value)
                .pan2out(pos_env1.value, L, R);
       (osc2.value(fun_env.value, form_env2.value) *! a_env.value)
                .pan2out(pos_env2.value, L, R);
       (osc3.value(fun_env.value, form_env3.value) *! a_env.value)
                .pan2out(pos_env3.value, L, R);

    }.dspAdd;

}
Fig. 07. Additive pulsar generator in SuperCollider 1 (Pulsar_additive.sc, 1997). Three pulsar streams share a common fundamental frequency envelope and pulsaret waveform but follow different formant and spatial envelopes. This is the three-train architecture later encapsulated in the PulsarGenerator application. Source: Curtis Roads (1997).

Every control object in the PG is a wavetable: thirteen tables in all, each stored as an array of 2048 floating-point values and presented through an identical graphic editor regardless of its temporal level of operation. The pulsaret waveform and envelope operate at the micro scale; the formant, panning, and amplitude tables shape the train over durations of seconds to a minute. The uniform table structure offers a single control model across time scales, mobilising a view of composition as creative grafting between temporal resolutions (Pietruszewski 2024). Roads calls this concept "graphical synthesis", and it connects the PG to earlier experiments in optical sound synthesis and to Xenakis's UPIC. Editing operations reinforce the cross-scale identity: de Campo implemented clipboard functions that mix or multiply the contents of one wavetable into another with automatic range scaling, so an amplitude envelope can be imposed directly onto a formant trajectory (Roads 2001c). Parameter states are stored as settings in a bank of sixteen slots, with variable-rate crossfading between them, a scheme that, as Roads notes, "takes performance with PulsarGenerator to another level of musical complexity" (Roads 2001a).

Masking is the PG's own contribution to the technique, and the one part of the program that is not a way of drawing a parameter. A pulsar generator "emits a metronomic sequence of pulsars"; masking "breaks up the stream by introducing intermittancies (regular or irregular) into the metronomic sequence. It deletes individual pulsarets, leaving an interval of silence in their place" (Roads 2001a, 149). Three kinds are implemented. Burst masking "models the burst generators of the classic electronic music studios", alternating b pulsarets with r silent periods, so a ratio of 4:2 gives 111100111100111100. Channel masking "selectively masks pulsars in two channels, creating a dialog within a phrase by articulating each channel in turn", generalisable to any number of channels. Stochastic masking "introduces random intermittancy", implemented "as a weighted probability that a pulsar will be emitted at a particular point in a pulsar train", drawn as an envelope over the train: at 1 every pulsar sounds, at 0 none do, and Roads notes that "values between 0.9 and 0.8 produce an interesting analog-like intermittancy, as if there were an erratic contact in the synthesis circuit".

What makes masking more than a mute is that it changes what is heard rather than how much. Below the rhythm threshold the effect is rhythmic, a figure cut out of a steady pulse. Above it, burst masking imposes amplitude modulation on the timbre and divides the fundamental by a subharmonic factor of b + r, so a 2:1 ratio on a 100 Hz fundamental with a 400 Hz formant puts subharmonics at 133 Hz and 266 Hz. Push the factor far enough and "the subharmonic crosses through the threshold separating tone and rhythm", giving "a series of alternating long tone pulses and silent intervals" (Roads 2001a, 149-51). Subtraction from the train turns into addition to the spectrum, which is the clearest case in the whole technique of an operation meaning different things at different time scales.

The implementation is compact: the entire program, including the graphical interface, required fewer than 1,500 lines of SuperCollider 2 code, with McCartney's real-time engine calculating the samples. Pulsar scheduling dominates the computational cost. At infrasonic emission rates the PG used under 4% of a 500 MHz PowerPC G4; a three-formant instrument at a 2 kHz fundamental, emitting six thousand pulsars per second, consumed roughly 45% (Roads 2001a).

The PG was thus shaped by the material conditions of computing circa 2000: the processing limits of Mac OS 9 and the buffer management strategies of that era. The 2048-point table and the quantization of parameter updates to the emission rate were pragmatic responses to these constraints, but they simultaneously encode a specific temporal ontology, musical time as discrete, recursive and quantized, in which the basic unit of temporal organization is not the continuous signal but the discrete event (Pietruszewski 2026). The design also embeds a compositional stance: the PG emphasises micro- and meso-temporal organisation and was conceived as a generator of sound material to be edited, transformed, and mixed in later stages, rather than a composer of finished macroform. Haworth (2015) reads the PG, alongside GENDYN, as a cultural object: a synthesis procedure functioning as a text within the discursive and aesthetic practices of electroacoustic music. Its recorded traces bear this out, from Marcus Schmickler's transformation of PG material on Altars of Science (2007) to Florian Hecker's presentation of raw, unprocessed PG output in Pulsar Wg'lett (2006).

Diagrammatic representation of the Pulsar Generator program showing signal flow from envelope generators and pulsaret waveform through the Pulsar Generator, pulsar masking, and convolution with sampled sounds to output.
Fig. 08. The Pulsar Generator program by Curtis Roads and Alberto de Campo. The system combines amplitude, fundamental frequency, and formant envelope generators with pulsaret waveform and envelope selection, pulsar masking (burst, channel, stochastic), convolution with sampled sounds, and mixing. Source: Roads (2020), figures conversion Pietruszewski.
Pulsar Generator main interface showing a generalised table type control over pulsaret fundamental frequency with three separate tables for formant frequency, spatial position and amplitude.
Fig. 09. Pulsar Generator, a global view of the graphic interface. Notice a generalised table type control over pulsaret fundamental frequency with three separate tables for formant frequency, spatial position and amplitude. The colour scheme and basic layout of the interface were inspired by the look of audio measurement equipment by Brüel&Kjær.
A small Mac OS 9 window titled fundFreq. Fields for min 0 and max 200 sit above a plot of a curve that falls and rises three times. A column of single-letter buttons runs down the right edge: E, S, L, I, A, D.
Fig. 10. One table editor from the Pulsar Generator, here holding the fundamental frequency. The curve is drawn by hand and read between the stated minimum and maximum. The buttons down the right edge are the same on every table in the program: E opens the range editor, S saves the data, L loads it, I imports the first 2048 samples of the left channel of almost any sound file, A rescales the view so the table is centred, and D restores the default range. Source: Pietruszewski (2024), fig. 2.3.

Every table in the program looks like this and answers to the same six commands, whether it holds a waveform lasting a few milliseconds or an amplitude contour lasting a minute. That uniformity is not a saving in interface work. It is the object-oriented paradigm surfacing in the design. Object orientation should be seen "beyond its computational realm as an embodiment of a specific compositional approach where concepts of encapsulation, inheritance and polymorphism become operational as practical tools applied within the process of composition" (Vaggione 1991, cited in Pietruszewski 2024, p. 54).

Polymorphism is the operative one here. Vaggione describes it as an arrangement in which "the names of objects are handled in such a way that inside the common network, objects receiving identical messages, when activating their specific properties and methods, can on account of the latter produce uniquely different results" (Vaggione 1991, p. 213). A table in these programs is exactly that. In its basic form it is a list of 2048 values between 0 and 1, and nothing more. Only after passing a graph object into a context, pulsaret or envelope or sequencer, does the range of its values get updated to a new state, and how those values are read changes with the context too (Pietruszewski 2024, p. 54). The I button makes the point plainly: it will take the first 2048 samples of the left channel of almost any sound file and put them in any table, so a fragment of a recording can become a waveform, an envelope or a minute-long frequency trajectory depending only on which window you pressed it in.

New Pulsar Generator (nuPG)

The New Pulsar Generator (nuPG) is a reimplementation and extension of the Pulsar Generator developed by Marcin Pietruszewski (2021). Built in SuperCollider 3, nuPG preserves the core parametric architecture of the original while expanding the synthesis engine and interface.

The reimplementation retains the PG's 2048-point table structure and emission-rate quantization even though contemporary systems could support arbitrary table sizes and sub-sample precision. These constraints persist as conceptual commitments rather than technical necessities: to discard them would be to discard the conception of digital temporality that makes pulsar synthesis distinctive (Pietruszewski 2026). Where the original PG was a closed application whose synthesis logic sat behind a graphical interface, nuPG exposes that logic as readable, modifiable code, making the historical design decisions available for inspection through use. The design lineage connecting Xenakis's UPIC, the PulsarGenerator, and nuPG shows digital instruments carrying their design histories as active artifacts (Pietruszewski 2020b). The extensions carry it furthest from the original: a Fourier window, a masking window inherited from the PG, group offsets for phase-shifting the trains against one another, a modulation matrix routing four modulators to any parameter, a sieve editor that builds Xenakian sieves from logical combinations of residue classes and hands the result back as a table, and a neural synthesis network of sixteen units in four clusters whose activations become eleven further modulation sources. All of it terminates in the same place: a table of values read at a settable rate (Fig. 11).

The program is a class library rather than a patch. An application object boots a chosen number of trains across a chosen number of channels, and the state of every parameter lives in control values wired to the interface through the Connection quark, so a slider, a table, a modulator and a MIDI message all reach the same target by the same route. Alongside the synthesis classes sit analysis and corpus classes, an MLP regressor, spectral delay, flux and freeze, wavelet gating, and the neural table generator that writes tables rather than reading them. The synthesis engine itself is switchable at startup. \classic is the GrainBuf lineage the entry has been describing, one grain per trigger, the pulsaret read once per emission. \oscos replaces it with PulsarOS, an oversampling pulsar generator written by Jan-Lars Kleine-Tebbe and distributed in the GrainUtils plugin, which takes separate buffers for pulsaret, envelope and modulator and reads each at an oversampled rate so that high formant settings do not fold aliases back down into the spectrum.

That mode also changes where a pulsar begins. Impulse.ar can only fire on a sample boundary, so at high emission rates the train is quantized to the sample grid and its period jitters. nuPG instead runs a phase ramp at the fundamental, detects the wrap, and recovers from the ramp's slope how far past the boundary the true trigger fell; that fraction is latched and passed to PulsarOS as a sub-sample offset, so each pulsaret starts at the moment the phase actually crossed rather than at the next sample. The emission clock stops being the sample rate.

That method is not nuPG's own, and it reaches well past pulsar synthesis. It comes from a long line of work by Kleine-Tebbe, posting as dietcv, on deriving events from phase ramps rather than from Impulse. The thread that works it out (2024) builds the rampToSlope and rampToTrig abstractions from Wakefield and Taylor's Generating Sound & Organizing Time (2022) in SuperCollider, and the GrainUtils thread that followed runs to well over a hundred posts, working through an event scheduler, a dynamic voice allocator that reuses free channels instead of cycling through them, and the oversampled readers. Anyone granulating in SuperCollider stands to gain from it, whether or not they ever emit a pulsar. Read alongside the entry, it also shows how a technique gets maintained now: not in a manual or a paper but in a forum thread, in public, over years. It is worth noticing what this does to the argument above: the Pulsar Generator's quantization of updates to the emission rate was a constraint of its time that hardened into a temporal commitment, and here that commitment is held while the quantization underneath it is dissolved.

The nuPG interface: dozens of windows across the screen, each holding a graphic table editor for one synthesis parameter, with a central panel of sliders, an extensions panel, and further windows for sieves, a neural network, a modulation matrix and an xy trajectory recorder.
Fig. 11. The New Pulsar Generator (nuPG). Every synthesis parameter has its own table window: fundamental frequency, three formants, three overlaps, three pan and three amplitude trajectories, the pulse probability mask, and the pulsaret waveform and envelope themselves. Each is loaded from a wavetable file, edited in place, and scaled between an explicit max and min. The central _main panel sets a single value for each; the surrounding windows set its trajectory across the train. The extensions add frequency modulation, Fourier operations, masking, sieves, group offsets, a modulation matrix and a neural synthesis network: _sieves builds Xenakian sieves from logical combinations of residue classes and converts the result to a table, and _mlp regressor records trajectories drawn through an xy space and trains a network on them. Source: Marcin Pietruszewski.

PdPG (Pure Data)

Both programs so far assume SuperCollider. PdPG, by Ben Mason, is a Pure Data implementation of the Pulsar Generator, released at v1.0.0 in October 2024 under GPL-3.0 and still described by its author as work in progress; it needs Pd 0.54 or newer and the FluCoMa toolkit. Its synthesis strategy differs from both SuperCollider versions. Rather than scheduling one grain per pulsar, the train is computed continuously and gated whenever the phase runs past the duty cycle. The released version does this in a single fexpr~, sample by sample, with linear interpolation on the table reads written out by hand; newer versions replace it with tabread4~, trading sample-wise accuracy for greater efficiency with vanilla objects. Masking offers a choice between Schillinger-style interference of three ratios and a stochastic probability test. The table argument survives the port, and in one respect is put more plainly: the nine meso-scale modulator tables, among them fundamental, formant, amplitude and pan, are filled from the same folder of wavetable files as the pulsarets, each read by its own phasor~ at its own rate. A waveform and a minute-long parameter trajectory are the same kind of file here, and nothing but the speed of reading distinguishes them. The tables are audio files of any length rather than a fixed 2048 points, which makes the choice visible as a choice. The FluCoMa dependency is what makes the pulsaret itself continuously variable: a fluid.knnregressor, from the Fluid Corpus Manipulation toolkit (Tremblay, Roma and Green 2021), interpolates smoothly between four stored pulsarets at control rate, selected by the per-train net switch. Where the PG crossfades between whole stored settings, PdPG moves through the space between four tables and arrives at ones that were never stored (Fig. 12).

The PdPG main window: three columns, each with a pulsaret and an envelope plotted in its own graph above sliders for scan position, formant frequency, cross modulation, feedback, delay and pan. A second window, network1win, shows four pulsarets and four envelopes with train and randomise buttons.
Fig. 12. PdPG, a Pure Data implementation of the Pulsar Generator. Three pulsaret and envelope pairs, as in the original PG, each read from a file and scanned by its own control, with per-train formant frequency, cross modulation, feedback, delay and pan; masking switches between Schillinger ratios and a stochastic test. The network window holds four pulsarets and four envelopes; a FluCoMa knnregressor interpolates between them at control rate, which the per-train net switch draws on. Source: Ben Mason.

Music with pulsar synthesis

The astrophysical object has entered music by more than one route, and not always through the technique named after it. Gérard Grisey's Le Noir de l'Étoile (1989-90) for six percussionists predates all of the computer music here and synthesises nothing: it uses recordings of the pulsars Vela and 0359-54 detected by the Nançay radio telescope as integral elements, played back over twelve loudspeakers ringed around the audience, sounding in two sections at 22'07-24'53 and 35'53-37'59 against Les Percussions de Strasbourg. At the 1992 Brussels premiere the intention had been to stream the signal live from Nançay; it was not technically feasible, so a recording stood in. The work is nonetheless the clearest case of the question pulsar synthesis formalises, which is what happens to a periodicity when it is placed among others: Grisey sets the star's period against the players' and lets the two run.

Marcus Schmickler's Bonner Durchmusterung (2009) takes the numerical route. Made with the programmer Alberto de Campo and the astronomers Michael Geffert of Bonn University's Argelander Institute and Kerstin Jaunich of the Deutscher Musikrat, commissioned for the International Year of Astronomy and premiered at the Bundeskunsthalle in Bonn, it comprises ten compositions of three and a half minutes each, sonifying different sets of astrophysical data. One of them, Pulsars/Neutron Stars, takes sixteen rotation profiles and renders them with Tommi Keränen's PG (2004), mapping each profile onto "dynamic, fundamental frequency, formant frequency and spatialization". The arrangement lets several profiles sound at once, which Schmickler calls a form of "auditory comparability" (quoted in Pietruszewski 2024, p. 116).

Pietruszewski's Synthetic Pulsar (Speculative Sonification) (2021) runs the data through nuPG. The source is the European Pulsar Network database, the cataloguing undertaken by the Max Planck Institute for Radioastronomy at Effelsberg with seven partner institutions, whose raw sets "consist of a timing index and rotational profile of selected pulsars" and arrive as comma-separated values. Those profiles are not mapped onto sound directly but used as one term in what the accompanying paper calls "augmented sonification where an auditory stream becomes modulated by an additional process or data". The additional process is a model of attraction and repulsion "within a digital model of a world with its own size, dimensions and gravity". Speculative sonification is Pietruszewski's own coinage, and the word marks a double position: the pairing of measured rotation profiles with that model is "conjectural rather than relational in regard to observed and measured phenomena", and by sonifying "impossible" objects the work treats intuition and spatial experience as part of how knowledge is formed rather than as its decoration (Pietruszewski 2022). The work was commissioned by CTM Festival Berlin and Deutschlandradio Kultur and first presented as an installation on a purpose-built 64-channel system at Vollgutlager in Berlin, with the performance artist and vocalist Alex Freiheit as narrator and the synthetic-voice collective Birds on Mars; a binaural version was broadcast in Deutschlandradio Kultur's Klangkunst series. Jocelyn Bell Burnell, who discovered pulsars in 1967, served as scientific advisor. The loop closes on itself there: the person who first read a periodic signal off a chart recorder advising on a work that reads rotation profiles back out through a synthesis technique named after what she found.

The technique itself was developed inside a composition rather than before one. Roads built pulsar synthesis while realising Clang-Tint, commissioned by the Japanese Ministry of Culture and Kunitachi College of Music, Tokyo; its second movement, Organic (1994), "combines bursts of insect noise and animal and bird calls with electronic pulse-tones", and its asynchronous pulsar clouds were made by mixing several infrasonic trains beating between 6 and 18 Hz (Roads 2001a). Half-life (1998-99) narrows the source to a single gesture: "the raw material ... is a one-minute pulsar train that is wildly varied", from which most of the rest of the work is derived by granulation, microfiltration, pitch-shifting, recirculating echo, per-pulsar amplitude shaping and selective reverberation. Its first movement is called Sonal Atoms. Tenth vortex (2000) and Eleventh vortex (2001) continue in that direction, the former built from a constant-Q granulation of a stream of synthetic pulsars.

The Pulsar Generator's recorded traces run in two directions. Marcus Schmickler transformed PG material into the dense assemblages of Altars of Science (Editions Mego, 2007); Florian Hecker presented raw, unprocessed PG output as Pulsar Wg'lett on Recordings for Rephlex (Rephlex, 2006). One treats the program as a source of material for later work, which is what its designers expected; the other treats its unedited output as finished, which they did not.

The New Pulsar Generator Recordings Volume 1 (Fancyyyyy, 2020) collects fifteen pieces made with nuPG, four of them composed at ZKM Karlsruhe in 2018, mastered by Russell Haswell and issued with a thirty-page book, Sound Composition with Pulsars, written by Roads for the release.

Jung An Tagen and Eric Frye put nuPG to a purpose the technique's own literature does not anticipate, and take their titles seriously. On Pulsar Acid (2020), twelve tracks make pulsar trains behave like a sequencer's bassline; on Phantom Acid (Superpang, 2022), textures "from Marcin Pietruszewski's nuPG" are cut into twenty-four tracks of exactly a minute and a half each, "laid out in enumerative fashion". The grid is the form. A technique built to make the boundary between rhythm and pitch continuous is here used to service a fixed metre, which is a sharper test of it than any sympathetic application would be.

Pulsar.scramble (2020) and its second (2020) and third (2021) volumes, released by $ pwgen 20, gather new work by more than thirty other composers, most of it made with nuPG, among them Farmers Manual, EVOL, Russell Haswell, Ben Vida, Lauren Sarah Hayes and Felisha Ledesma. Three volumes over two years is a small corpus, but it is the point at which the technique stops being one composer's method and becomes something a scene uses. Victor Moragues's Scan Pulsar Detours came out of the same circle.

Jules Rawlinson has taken it in a direction of his own, across Pulsar Retcon (Superpang SP63, 2021), Pulsar Hexerei, Pulsar Threading and a run of live performances. His method inverts the usual order. Rather than composing with the program, he records improvisations from it and then treats the result as a corpus to be played: "improvised buffer scratching, corpus scrubbing and waveform scuffing of material sourced from New Pulsar Generator". The recordings are analysed with the FluCoMa toolkit and navigated by descriptor with multitouch controllers, so the instrument being performed is a sound bank rather than a synthesiser, and pulsar synthesis becomes the thing that fills it.

The nine titles on Pulsar Retcon are worth a moment. Lotus Prancer, Protean Curls, Neutral Crops, Cursor Planet, Learnt Corpus, Nuclear Strop, Tonal Sprucer, Near Sculptor, Opal Currents: every one is an anagram of Pulsar Retcon, the same twelve letters permuted nine ways. It is the record's method stated in its own index. A fixed set of material, reordered, is what the album does to the sound bank and what the technique does to a table, and retcon, for retroactive continuity, names the operation exactly: going back into something already made and reading it differently.

Kayon Choi's Order and Interstices (Rope Editions, 2026) shows where that leads. Its opening track is built on Xenakis's GENDYN; the rest begin from material made with "Marcin Pietruszewski's 'nuPG (New Pulsar Generator)'" and are then morphed, with Antoine Caillon's RAVE among the credited tools. Pulsar synthesis appears there not as the subject of the record but as one supplier of material among several, which is the ordinary fate of a technique that has been absorbed.

Code download

pulsar-synthesis.scd

The cells above run in the browser, where the language and the synthesis server are compiled to WebAssembly and the page owns part of the session. They carry things that mean nothing outside it. The ~wave and ~envelope buffers are allocated by the page and filled by the pulsaret builder rather than by any cell, and lines such as ("HB_TABLE " ++ name ++ " [" ++ points.join(",") ++ "]").postln are a private protocol: the page watches its own post window for those markers and uses them to plot the tables and move the playhead across them. Pasted into a local SuperCollider they would post noise and then fail on the buffers that were never allocated.

The file above is the same instrument with that scaffolding replaced by its local equivalents, plus what the browser cannot offer. It boots and allocates its own buffers, carries a catalogue of pulsaret waveforms and envelopes after Roads's figures 4.11 and 4.12 that can be swapped under a sounding instrument, plots the tables with .plot, opens a slider panel, and records to disk.

It also carries the one part of the technique the cells leave out: pulsar masking, in the two forms the Pulsar Generator implements for a single train. Burst masking alternates b emitted periods with r silent ones, and stochastic masking throws a weighted coin once per period, its probability held as a fifth control table alongside the four the cells use. Both delete pulsarets rather than quieten them, so the train keeps the period it would have had and loses emissions from it: at a 100 Hz fundamental a ratio of 1:7 leaves one pulsaret every 80 ms, which is the subharmonic at f/(b + r) described above.

References

  • Cavaliere, S., and Piccialli, A. (1997). Granular synthesis of musical signals. In Musical Signal Processing, 155-186.
  • Choi, K. (2026). Order and Interstices. Rope Editions.
  • De Campo, A. (2004). Microsound. In N. Collins and J. d'Escrivan (eds.), The Cambridge Companion to Electronic Music. Cambridge University Press.
  • De Campo, A., and Pietruszewski, M. (2025). Microsound. In S. Wilson, D. Cottle, and N. Collins (eds.), The SuperCollider Book, 2nd ed. Cambridge, MA: MIT Press.
  • De Poli, G., and Piccialli, A. (1991). Pitch-synchronous granular synthesis. In G. De Poli, A. Piccialli and C. Roads (eds.), Representations of Musical Signals. Cambridge, MA: MIT Press.
  • Ernst, W. (2019). As slow as possible? On the machinic (non-)sense of the sonic present and digital indifference toward time. ASAP/Journal, 4(3), 671-688.
  • Gabor, D. (1946). Theory of communication. Part 1: The analysis of information. Journal of the Institution of Electrical Engineers, 93(26), 429-441.
  • Gabor, D. (1947). Acoustical quanta and the theory of hearing. Nature, 159(4044), 591-594.
  • Grisey, G. (1989-90). Le Noir de l'Étoile, for six percussionists, tape and transmission of pulsar signals.
  • Haworth, C. (2015). Sound synthesis procedures as texts: an ontological politics in electroacoustic and computer music. Computer Music Journal, 39(1), 41-58.
  • Hecker, F. (2006). Pulsar Wg'lett. On Recordings for Rephlex. Rephlex.
  • Hewish, A., Bell, S. J., Pilkington, J. D. H., Scott, P. F., and Collins, R. A. (1968). Observation of a rapidly pulsating radio source. Nature, 217, 709-713.
  • Holtzman, S. R. (1978). A Description of an Automatic Digital Sound Synthesis Instrument. DAI Research Report No. 59. Edinburgh: Department of Artificial Intelligence, University of Edinburgh.
  • Jenny, G. (1958). L'Ondioline: conception et réalisation. Toute la radio.
  • Johnston, S., and Kerr, M. (2017). Polarimetry of 600 pulsars from observations at 1.4 GHz with the Parkes radio telescope. Monthly Notices of the Royal Astronomical Society, 474, 4629. Data via the EPN Database of Pulsar Profiles, CC BY 4.0.
  • Jung An Tagen, and Frye, E. (2020). Pulsar Acid.
  • Jung An Tagen, and Frye, E. (2022). Phantom Acid. Superpang.
  • Kaegi, W., and Tempelaars, S. (1978). VOSIM: a new sound synthesis system. Journal of the Audio Engineering Society, 26(6), 418-425.
  • Kleine-Tebbe, J.-L. (2024). Sub-sample accurate events from phasor ramps. scsynth.org forum thread. scsynth.org/t/8856
  • Kleine-Tebbe, J.-L. (2025a). GrainUtils. SuperCollider plugin, GPL-3.0. github.com/dietcv/GrainUtils
  • Kleine-Tebbe, J.-L. (2025b-). GrainUtils: sub-sample accurate EventScheduler and dynamic VoiceAllocator. scsynth.org forum thread. scsynth.org/t/12197
  • Koenig, G. M. (1959). Studium im Studio. die Reihe, 5. English ed. (1961). Bryn Mawr: Theodore Presser.
  • Koenig, G. M. (1987). Genesis of form in technically conditioned environments. Journal of New Music Research, 16(3), 165-175.
  • Mason, B. (2024). PdPG: Pure Data implementation of Curtis Roads' Pulsar Generator, v1.0.0. Software. github.com/whosebodyisthis/PdPG
  • Mathews, M. V. (1969). The Technology of Computer Music. Cambridge, MA: MIT Press.
  • Pietruszewski, M. (2020a). The New Pulsar Generator Recordings Volume 1. Fancyyyyy, FCY0003. CD and book.
  • Pietruszewski, M. (2020b). The digital instrument as an artifact. In P. Weibel, L. Brümmer, and S. Kanach (eds.), From Xenakis's UPIC to Graphic Notation Today, 613-627. Berlin: Hatje Cantz / Karlsruhe: ZKM.
  • Pietruszewski, M. (2021). New Pulsar Generator (nuPG). Software.
  • Pietruszewski, M. (2022). Synthetic Pulsar (Speculative Sonification). In xCoAx 2022: Proceedings of the 10th Conference on Computation, Communication, Aesthetics & X, 375-378. DOI 10.24840/xCoAx_2022_56.
  • Pietruszewski, M. (2024). The New Pulsar Generator (nuPG): Compositional Practice, Digital Sound Synthesis Model and Their Temporalities. PhD thesis, University of Edinburgh.
  • Pietruszewski, M. (2026). Media-archaeological synthesis. Manuscript in review.
  • Pope, S. T. (1997). Sound and Music Processing in SuperCollider. Santa Barbara: CREATE.
  • Pulsar.scramble, vols. 1-3 (2020-2021). Various artists. $ pwgen 20.
  • Rawlinson, J. (2021). Pulsar Retcon. Superpang, SP63.
  • Roads, C. (2001a). Microsound. Cambridge, MA: MIT Press.
  • Roads, C. (2001b). Sound composition with pulsars. Journal of the Audio Engineering Society, 49(3), 134-147.
  • Roads, C. (2001c). PulsarGenerator Manual of Operation. Document version 1, 24 March 2001. Santa Barbara: CREATE.
  • Roads, C. (2004). Point, line, cloud: the legacy of Iannis Xenakis. In Presences of Iannis Xenakis, ed. M. Solomos. Paris: CDMC.
  • Roads, C. (2020). Composing Electronic Music: A New Aesthetic. Rev. ed. New York: Oxford University Press.
  • Rodet, X. (1984). Time-domain formant-wave-function synthesis. Computer Music Journal, 8(3), 9-14.
  • Schmickler, M. (2007). Altars of Science. Editions Mego.
  • Schmickler, M. (2009). Bonner Durchmusterung. Sonification by Alberto de Campo, projections by Carsten Goertz, supervision by Michael Geffert. Premiered May 2009, Kunst- und Ausstellungshalle der Bundesrepublik Deutschland, Bonn.
  • Stockhausen, K. (1957). . . . wie die Zeit vergeht . . . die Reihe, 3, 10-43. English ed. (1959): . . . How Time Passes . . . Bryn Mawr: Theodore Presser.
  • Thomson, W. (1881). The tide gauge, tidal harmonic analyser, and tide predicter. Minutes of Proceedings of the Institution of Civil Engineers, 65, 2-10; discussion 26-72.
  • Tremblay, P. A., Roma, G., and Green, O. (2021). Enabling programmatic data mining as musicking: the Fluid Corpus Manipulation toolkit. Computer Music Journal, 45(2), 9-23.
  • Vaggione, H. (1991). A note on object-based composition. In G. De Poli, A. Piccialli and C. Roads (eds.), Representations of Musical Signals. Cambridge, MA: MIT Press.
  • Wakefield, G., and Taylor, G. (2022). Generating Sound & Organizing Time: Thinking with gen~, Book 1. San Francisco: Cycling '74.
  • Xenakis, I. (1971). Formalized Music: Thought and Mathematics in Composition. Bloomington: Indiana University Press.
  • Xenakis, I. (1992). Formalized Music. Rev. ed. Stuyvesant, NY: Pendragon Press.
  • Xenakis, I., and Varga, B. A. (1996). Conversations with Iannis Xenakis. London: Faber & Faber.

Cite this entry

Entries are signed and dated. Cite the author and the edition you read, not the Handbook or an access date. Why this form.

Chicago

Pietruszewski, Marcin. 2026. “Pulsar Synthesis.” The Synthesis Handbook, edition of October 1, 2026. SYNCULTURE. https://synculture.net/handbook/pulsar-synthesis/

Harvard

Pietruszewski, M. (2026) ‘Pulsar Synthesis’, The Synthesis Handbook, edition of 1 October 2026. SYNCULTURE. Available at: https://synculture.net/handbook/pulsar-synthesis/

APA

Pietruszewski, M. (2026). Pulsar synthesis. In The Synthesis Handbook (October 1, 2026 ed.). SYNCULTURE. https://synculture.net/handbook/pulsar-synthesis/

MLA

Pietruszewski, Marcin. “Pulsar Synthesis.” The Synthesis Handbook, 1 Oct. 2026 ed., SYNCULTURE, https://synculture.net/handbook/pulsar-synthesis/

BibTeX

@incollection{pietruszewski2026pulsar,
  author    = {Marcin Pietruszewski},
  title     = {Pulsar Synthesis},
  booktitle = {The Synthesis Handbook},
  edition   = {1 October 2026},
  publisher = {SYNCULTURE},
  year      = {2026},
  url       = {https://synculture.net/handbook/pulsar-synthesis/}
}