Oscillators, envelopes and voices

Build instruments from oscillators, envelopes, voice engines and physical resonators.

An instrument turns note events into sound. You can compose an oscillator, envelope and filter yourself, reuse a prepared voice engine, or excite a physical resonator. The module still owns its identity, parameters, presets, MIDI ports and face.

Start with a sound source

ts
import {
  initOscillatorNode, setOscillatorNodeFrequency,
  setOscillatorNodeWaveform, oscillatorNodeTick,
} from "maruaudio/dsp/oscillators/polyblep"

const oscillator = initOscillatorNode(48_000)
setOscillatorNodeWaveform(oscillator, 1) // 0 sine, 1 saw, 2 square, 3 triangle
setOscillatorNodeFrequency(oscillator, 220)
// Call once per audio frame, after preparation:
const sample = 0.2 * oscillatorNodeTick(oscillator)

This is a continuous source. For a played instrument, add an amplitude envelope, voice allocation and note-on/off handling. envelopes/adsr exposes initAdsrNode, attack/decay/sustain/release setters, adsrNodeGateOn, adsrNodeGateOff and adsrNodeTick; multiply the oscillator by the envelope. Gate-off begins release, so keep rendering until the voice finishes.

The Processor instrument starter connects these responsibilities in a runnable project. Start there when your goal is an instrument you can play and publish.

Pick the level of reuse

ApproachUseful starting pointsYour responsibility
Oscillator-based synthPolyBLEP, wavetable, variable-shape or formant oscillatorsPitch, envelopes, filters, notes, allocation and mix.
Reusable voice engineSubtractive, FM, pluck, modal-struck or sampler voicesMap product controls/events/resources into that engine’s lifecycle.
Physical modelModal resonators, struck exciters, felt contact and string recipesExcitation, model data, decay, radiation/readout and musical calibration.

Unison is a stack of oscillator lanes for one note; polyphony is the number of simultaneous notes. Use voices/unison for lane detune/spread and the prepared voice pools for note allocation. voices/mono-performance and voices/portamento supply note priority, articulation and glide decisions. The sampling reference covers sample-based voices separately.

Prepare for musical transitions

Allocate every voice’s state before rendering. Decide how repeated notes, sustain, release, stealing and a changing voice limit behave. Retire a stolen voice through a short transition rather than cutting a nonzero sample. Use phase-aware oscillator reset when a note restart needs matching triangle history. Resetting all voices on every note loses overlapping notes and tails.

Firmware-derived engines have specific model selections, rates and block formats. In particular, the Warps core is fixed to 96 kHz/60-frame PCM16; its stream adapter adds cadence buffering, not host-rate conversion. Clouds still has pending target qualification, and Plaits exposes only its listed engines. Choose these deliberately rather than assuming a generic oscillator interface.

Toolkit reference

Import paths below are suffixes of maruaudio/dsp/. Use the exported types and setters in your installed version for complete signatures and defaults.

Oscillators

Import suffixPurposeSelected API
oscillators/polyblepSine, saw, square and triangle source with pitch offsets and band-limited discontinuity treatment.initOscillatorNode, oscillatorNodeTick
oscillators/lissajous-duoStereo dual oscillator with an integer frequency ratio driven by one master phase.initLissajousDuoNode, setLissajousDuoNodeWaveform
oscillators/daisysp-blepDaisySP polynomial step/integrated-step corrections, turn-based sine and clamp helpers.daisyClamp, daisyThisBlepSample
oscillators/band-limited-tableBand-limited wavetable playback: per-frame FFT into a sixteen-level half-octave pyramid (256 down to 1 harmonic, like PeriodicWave), Nyquist-safe level crossfading, cubic cycle interpolation, and linear frame morphing.initBandLimitedTable, bandLimitedLevelOffset
oscillators/variable-shapeDaisySP VariableShapeOscillator port: a hard-syncable saw/triangle/square morph with band-limited pulse-edge and wrap transitions bounded to two per sample.initVariableShapeOscillatorNode, variableShapeOscillatorNodeTick
oscillators/zDaisySP ZOscillator port: a phase-distortion carrier contour multiplied by a formant discontinuity, with the discontinuity reset band-limited and shape/mode double-buffered.initZOscillatorNode, zOscillatorNodeTick
oscillators/formantDaisySP FormantOscillator port: a windowed-sine formant generator whose carrier reset is band-limited, with the phase shift applied as an explicit per-sample increment.initFormantOscillatorNode, formantOscillatorNodeTick

Envelopes

Import suffixPurposeSelected API
envelopes/adsrExponential ADSR envelope state machine in VCA form over the shared one-pole coefficient/step and stage thresholds: gate-on is a full retrigger, gate-off releases from the current level.initAdsrNode, adsrNodeTick
envelopes/linear-arLinear attack/release and optional AHDSR amplitude envelope; release starts from the current level.createLinearArState, linearArTick
envelopes/grain-windowsHann, Tukey, exponential, reversed exponential and triangle grain windows, plus curve rendering and reading.grainWindowValue, fillGrainWindowCurve
envelopes/overshoot-adsrDaisySP exponential-style ADSR with overshooting stage targets and soft/hard retrigger.initOvershootAdsrNode, overshootAdsrNodeTick

Noise

Import suffixPurposeSelected API
noise/colouredDeterministic coloured-noise source: seed policy, [-1,1) white mapping, pink/brown colour filters, fixed-crossover signed tone tilt and output level.initNoiseNode, noiseNodeTickWhite
noise/xorshift32Unsigned xorshift32 transition and conversion to white noise; caller retains the seed/state.xorshift32NextU32, rawU32ToBipolar
noise/newlib-randSeeded newlib-compatible integer random sequence for firmware-derived engines.initNewlibRand, seedNewlibRand
noise/record-textureDeterministic crackle, dust and mains-hum generators with prepared scalar/filter state.initRecordTexture, recordTextureTick

Physical models

Import suffixPurposeSelected API
physical/modalTwo-pole modal recurrence with displacement/velocity taps, mode roll-off and excitation shaping.exciterLowpassTick, modalPoleRadius
physical/modal-radiationBounded radiation weighting and displacement/velocity readout with stereo gain.modalRadiationFrequencyWeight, modalRadiationReadout
physical/modal-tablePrepare modal recipe tables with bounded mode counts, pitch-scaled frequencies and decay.modalTableSlot, modalTableBoundedModeCount
physical/modal-resonatorSingle two-pole resonator with T60 decay, excitation and gain/readout.initModalResonatorNode, modalResonatorNodeTick
physical/modal-resonator-bankPrepared 16-mode resonator banks and packed multi-bank pools; common excitation and displacement/velocity/radiation outputs.initModalResonatorBank, modalResonatorBankTick
physical/piano-scaleProvisional per-key string/hammer geometry, mass, tension and tuning equations for piano models.createPianoKeyScale, pianoHammerContactDuration
physical/felt-hammerNonlinear felt contact and hammer momentum against a passive load; no returning-wave feedback or hysteresis.createFeltHammer, feltHammerTickRealtime
physical/struckReusable struck-instrument excitation: velocity, hardness, contact time, noise, seeding and size-to-decay laws.struckVelocityGain, struckEffectiveHardness
physical/strikePer-mode excitation gains at the moment of contact: free-free bar and gong/kettle mode-shape weights with a mallet-width floor, plus the contact-time velocity tilt across the bank.strikeBarShape, strikeGongShape
physical/malletBeater contribution to a struck plate's spectrum: softness-driven per-mode spectral tilt, a bounded normalized half-sine contact-force pulse, and the constant-energy roughness residual gain.malletModeRolloff, malletContactForce
physical/bloomTam-tam nonlinear upward energy cascade as a per-mode arrival-time split: deferred excitation fraction, one-pole rise coefficient, envelope step and the audible per-mode gain recombination.bloomModeFraction, bloomRiseCoefficient

Voice engines and performance

Import suffixPurposeSelected API
voices/stagesOscillator, envelope and filter stages used to compose a subtractive voice.polyBlep, oscSineSample
voices/note-stackHeld-note stack for mono and legato play modes: held flags, per-note velocity, press order and last-note priority lookup.initNoteStack, noteStackPush
voices/grain-poolBounded granular voice storage and scheduling over prepared sample data.initGrainPool, grainPoolRenderFrame
voices/polyphonic-poolBounded note-slot allocation with same-note retrigger and voice-stealing policy.initPolyphonicVoicePool, boundedPolyphonicCapacity
voices/subtractiveSubtractive synth voice composition over shared oscillators, envelopes and filters.initSubtractiveVoice, voiceTick
voices/oscilloPrepared Oscillo synthesis voice; use its own parameter and note lifecycle.initOscilloVoice, oscilloLfoTick
voices/gamelanPrepared gamelan-style struck voice with modal synthesis and a caller-owned stereo output bus.initGamelanVoice, gamelanExciterTick
voices/gongPrepared gong voice with modal synthesis and a caller-owned stereo output bus.initGongVoice, gongExciterTick
voices/fm-keysFour-operator phase-modulation keyboard: six routings, per-operator envelopes, eight voices and feedback shaping.initFmKeysVoice, fmKeysRenderFrame
voices/fm-algorithmsShared FM operator-routing algorithms and stable algorithm lookup.fmWiringFromMatrix, dx7Algorithm
voices/drum-kit-modelShared drum-kit model data and contracts for percussion consumers.drumVoiceForNote, drumVoiceById
voices/fm-corePrepared operator-count-flexible phase-modulation graph with weighted source-to-target routes, deterministic one-sample feedback for cyclic connections, and independent carrier output gains.createFmCoreState, resetFmCoreState
voices/mouthMonophonic glottal source and vocal-tract waveguide with nasal branch, constrictions, turbulence and a reverb tail. Caller supplies noise.initMouthVoice, mouthTick
voices/modal-struckTwelve-slot stereo struck-resonator pool with recipe/note tables, velocity-sensitive excitation, release and bounded tail retirement.initModalStruckState, modalStruckV2VoiceTick
voices/phase-7Six-operator FM instrument: 32 routings, operator/pitch envelopes, LFO, unison, mono/poly modes, portamento and pitch bend.phase7Tick, phase7Ratio
voices/ringsRings modal-model resonator core with original parameter laws, bounded polyphony, separate odd/even taps and independent signal inputs; qualification remains module-owned.initRingsState, tickRings
voices/pluckTwelve-voice extended Karplus–Strong strings with pick/noise excitation, stiffness, loss, body resonances and stereo detune.createPluckVoiceState, pluckTick
voices/stiff-string-pianoRegister-scaled modal/shared-load/waveguide piano recipe with felt contact and reduced secondary resonances.createStiffStringPiano, stiffStringPianoTick
voices/chord-voicingRoot-position, voice-led, drop-2 and spread MIDI voicings with an optional bass note.sortAscending, voiceChord
voices/chord-colourScale-aware added chord tones, avoid-note rules and a decaying pitch-class histogram.createChordColour, colourIntervalClassConsonance
voices/portamentoExact-duration semitone glide with an explicit preparation and note-transition lifecycle.initPortamento, tickPortamento
voices/mono-performanceHeld-note selection, note priority and mono/legato retrigger decisions.initMonoPerformance, resetMonoPerformanceConfiguration
voices/unisonSymmetric detune/stereo lanes, bounded peak gain, smooth lane-count transitions and optional deterministic phase seeds.initUnison, tickUnison
voices/cloudsOriginal Clouds engine translation; only the initial model is supported and target qualification is pending.initCloudsState, processCloudsBlock
voices/peaksFirmware-derived Twin ADSR/Split AD envelope function with independent gates; other modes are explicitly unsupported.initPeaksState, tickPeaksRaw
voices/warpsFirmware-derived crossmodulation/vocoder and frequency/phase-shifter core; requires 96 kHz, 60-frame interleaved PCM16 processing.createWarpsState, processWarpsBlock
voices/warps/controlsWarps ADC-domain control scaling and smoothing, with explicit connection presence; no physical voltage/jack interface.createWarpsControlState, resetWarpsControlState
voices/warps/streamCadence adapter for the 96 kHz PCM16 Warps core, retaining MAIN/AUX outputs and adding 60 frames; does not resample.createWarpsStreamState, processWarpsStream
voices/plaitsFirmware-derived Voice supporting the virtual-analog and additive engines; other engine selections are silent.initPlaitsState, tickPlaits

Return to DSP fundamentals for I/O, lifecycle, units and the category map.