Synthesizers
============
PyTheory includes 56 built-in waveforms and 10 ADSR envelope presets.
Every sound is generated from scratch -- no samples or external audio
files needed.
Here's the beautiful thing about synthesis: all of it comes from math.
Sine waves, addition, and shaping. That's the entire foundation. Every
legendary synth in history -- the Moog Minimoog, the Sequential Prophet-5,
the Yamaha DX7, the Roland Juno-106, the Roland TB-303 -- uses some
combination of these building blocks. When you choose a waveform in
PyTheory, you're reaching for the same raw materials that defined
decades of music. The difference between a Moog bass and a DX7 bell
isn't magic; it's which waveforms you start with and how you shape them.
Classic Waveforms
-----------------
These four are the fundamentals. Every analog synthesizer ever built
starts here. If you learn nothing else about synthesis, learn these --
they're the primary colors you mix everything else from.
Sine
~~~~
The purest tone possible. Contains only the fundamental frequency with
no harmonics. Sounds smooth, clean, and "electronic." This is the
building block of all other waveforms (Fourier's theorem).
**Use for:** sub bass, clean pads, test tones, blending under other voices.
.. code-block:: python
from pytheory import play, Synth, Tone
tone = Tone.from_string("C4", system="western")
play(tone, synth=Synth.SINE)
.. raw:: html
Sawtooth
~~~~~~~~
Contains all harmonics (both odd and even), each at amplitude 1/n.
The richest of the classic waveforms — bright, buzzy, and aggressive.
Named for its ramp shape.
**Use for:** leads, brass, pads, anything that needs presence and bite.
.. code-block:: python
play(tone, synth=Synth.SAW)
.. raw:: html
Triangle
~~~~~~~~
Contains only odd harmonics, each at amplitude 1/n-squared. Softer and
more mellow than sawtooth — somewhere between sine and saw. Often
described as "woody" or "hollow."
**Use for:** flute-like leads, mellow bass, gentle pads.
.. code-block:: python
play(tone, synth=Synth.TRIANGLE)
.. raw:: html
Square
~~~~~~
Contains only odd harmonics, each at amplitude 1/n. Sounds hollow and
punchy — the classic chiptune / 8-bit sound. A special case of the
pulse wave with a 50% duty cycle.
**Use for:** chiptune, 8-bit game music, hollow leads, sub-octave bass.
.. code-block:: python
play(tone, synth=Synth.SQUARE)
.. raw:: html
Extended Waveforms
------------------
These go beyond the basics into territory that defined specific
instruments and eras. The pulse wave is the sound of the NES. FM
synthesis is the sound of the 1980s. If the classic waveforms are
primary colors, these are the specific pigments that painters actually
reach for.
Pulse
~~~~~
A pulse wave with a variable duty cycle. Narrower pulses sound thinner
and more nasal. At 50% it equals a square wave; at 10--20% it produces
the classic NES-style buzzy tone.
**Use for:** NES/chiptune sounds, nasal leads, retro textures.
.. code-block:: python
lead = score.part("lead", synth="pulse", envelope="pluck")
.. raw:: html
FM Synthesis
~~~~~~~~~~~~
Frequency modulation -- one oscillator (the modulator) modulates the
frequency of another (the carrier), producing complex inharmonic
spectra. This is how the Yamaha DX7 works -- the best-selling
synthesizer of all time. Released in 1983, it was suddenly everywhere:
the electric piano in every Whitney Houston ballad, the bass in every
Depeche Mode track, the bells in a thousand TV jingles. If you heard
pop music in the 80s, you heard FM synthesis.
**Use for:** bells, metallic leads, glassy pads, DX7-style sounds.
.. code-block:: python
bells = score.part(
"bells",
synth="fm",
envelope="bell",
fm_ratio=3.0,
fm_index=5.0,
volume=0.3,
reverb=0.4,
)
.. raw:: html
Noise
-----
White Noise
~~~~~~~~~~~
Equal energy at all frequencies — pure randomness with no pitch.
Useful as a texture layer, a percussion source, or a wind/ocean effect.
**Use for:** snare layers, hi-hats, wind effects, risers, ambient texture.
.. code-block:: python
texture = score.part(
"texture",
synth="noise",
envelope="pad",
volume=0.1,
lowpass=2000,
)
.. raw:: html
Ensemble Waveforms
------------------
These all create "bigger" sounds by layering or modulating multiple
oscillators. Where a single sawtooth wave sounds like one instrument,
these sound like a section -- a string ensemble, a choir, a wall of
synths. They're the pad and atmosphere machines, the sounds that fill
out a mix and make it feel wide and immersive.
Supersaw
~~~~~~~~
Seven detuned sawtooth oscillators stacked together. The slight pitch
differences create a shimmering, massive wall of sound. This is the
Roland JP-8000's gift to the world -- the waveform that launched an
entire genre. Every trance anthem from the late 90s and early 2000s,
every euphoric EDM drop, every J-pop power chord owes something to the
supersaw.
**Use for:** trance pads, EDM leads, massive chords, anthem hooks.
.. code-block:: python
pad = score.part(
"pad",
synth="supersaw",
envelope="pad",
volume=0.4,
chorus=0.3,
reverb=0.5,
)
.. raw:: html
PWM Slow
~~~~~~~~
Pulse width modulation with a slow LFO. The duty cycle sweeps back and
forth, creating a lush, animated pad sound. This is the Roland Juno-106
in a nutshell -- arguably the most recorded synth pad sound in history.
That warm, slowly evolving, slightly chorused wash you hear in everything
from Boards of Canada to Drake? PWM with a slow LFO.
**Use for:** lush analog pads, slow evolving textures, Juno-style warmth.
.. code-block:: python
pad = score.part(
"pad",
synth="pwm_slow",
envelope="pad",
volume=0.35,
reverb=0.4,
)
.. raw:: html
PWM Fast
~~~~~~~~
Pulse width modulation with a fast LFO. The rapid duty cycle sweep
produces a natural chorus/vibrato effect built into the waveform itself.
**Use for:** animated leads, vibrato textures, movement without effects.
.. code-block:: python
lead = score.part("lead", synth="pwm_fast", envelope="pluck", volume=0.5)
.. raw:: html
Analog Synthesis
----------------
These waveforms model the behavior of real analog hardware — the
imperfections, interactions, and nonlinearities that make a room full
of vintage synths sound so much more alive than a room full of VSTs.
Each one is a different approach to the same question: how do you make
a digital oscillator sound like it has a soul?
Hard Sync
~~~~~~~~~
A "slave" oscillator is forced to restart its cycle every time a
"master" oscillator completes one. The abrupt restart creates bright
formant peaks that sweep as the slave ratio changes. This is THE sound
of the Prophet-5, Moog Prodigy, and every screaming analog lead since
1978.
**Use for:** aggressive leads, formant sweeps, cutting solos.
.. code-block:: python
lead = score.part("lead", synth="hard_sync", envelope="pluck")
# Higher slave ratio = more harmonics, brighter
from pytheory import play, Synth, Tone
play(Tone.from_string("C4"), synth=Synth.HARD_SYNC, slave_ratio=2.5)
.. raw:: html
Ring Modulation
~~~~~~~~~~~~~~~
Two oscillators multiplied together, producing sum and difference
frequencies. Unlike FM, ring mod outputs only sidebands — no carrier
or modulator fundamental. The result is metallic, bell-like, and often
inharmonic. Classic Dalek voice, Stockhausen, and every sci-fi
soundtrack.
**Use for:** metallic bells, alien textures, inharmonic percussion.
.. code-block:: python
bells = score.part("bells", instrument="ring_mod_bell",
reverb=0.5, reverb_type="cave")
# Non-integer ratios = more inharmonic
play(Tone.from_string("C4"), synth=Synth.RING_MOD, mod_ratio=2.1)
.. raw:: html
Wavefolding
~~~~~~~~~~~
The heart of west coast synthesis (Buchla, Make Noise, Verbos). A sine
wave is amplified past ±1.0, then "folded" — the overflow bounces back
instead of clipping. Each fold adds new harmonic pairs. At low fold
counts it's warm and round; crank it up and it gets buzzy, gnarly, and
alive.
This sounds completely different from subtractive synthesis — instead of
*removing* harmonics with a filter, you're *generating* them by shaping
the wave. Pairs beautifully with a lowpass filter after the fold.
**Use for:** complex leads, evolving textures, west coast basslines.
.. code-block:: python
# Warm, musical folding
warm = score.part("fold", instrument="wavefold_warm")
# Cranked and aggressive
gnarly = score.part("gnarly", instrument="wavefold_gnarly")
# Direct control over fold amount
play(Tone.from_string("C4"), synth=Synth.WAVEFOLD, folds=3.0)
.. raw:: html
Drift Oscillator
~~~~~~~~~~~~~~~~
Real analog oscillators are never perfectly stable. Capacitor charging,
thermal variations, and component tolerances make the pitch wander
slightly. This is what makes a Minimoog sound "fat" and a VST sound
"thin" — the constant micro-motion of imperfect hardware.
The drift oscillator models slow pitch drift (< 1 Hz wander), fast
jitter (per-cycle randomness), a soft analog noise floor, and slightly
rounded waveform edges. It turns any basic shape into something that
breathes.
**Use for:** analog-style pads, warm basses, vintage leads, any voice
that needs to feel "alive."
.. code-block:: python
# Vintage Minimoog-style saw
pad = score.part("pad", instrument="drift_saw",
reverb=0.35, reverb_type="taj_mahal")
# Hollow square with analog wobble
sq = score.part("sq", instrument="drift_square")
# Control the shape and instability directly
play(Tone.from_string("C4"), synth=Synth.DRIFT,
shape="triangle", drift_amount=0.25)
.. raw:: html
Drift amount controls how unstable the oscillator is:
- **0.05** = studio-grade (Sequential, Oberheim)
- **0.15** = classic vintage (Minimoog, ARP) — the default
- **0.30** = barely-holding-it-together (old SH-101)
ADSR Envelopes
--------------
Here's a question: a piano and an organ can play the exact same note at
the exact same frequency. Why do they sound completely different? The
answer is the envelope -- the *shape* of the sound over time. A piano
hits hard and immediately starts fading. An organ snaps on at full
volume and stays there until you lift the key. A violin swells in
gradually. The frequency is the same; the envelope is what makes each
instrument feel like itself.
ADSR stands for Attack, Decay, Sustain, Release -- four stages that
describe how any sound's volume changes from the moment you press a key
to the moment it falls silent. Understanding ADSR is the single most
important thing you can learn about synthesis, because it's the
difference between a sound that feels like an instrument and a sound
that feels like a test tone.
Raw waveforms click at the start and end of each note. An ADSR envelope
shapes the amplitude over time for natural-sounding notes:
- **Attack** -- how quickly the sound reaches full volume.
- **Decay** -- how quickly it drops to the sustain level.
- **Sustain** -- the held volume while the note is on.
- **Release** -- how quickly it fades to silence after the note ends.
PyTheory includes 10 presets:
.. code-block:: python
from pytheory import play, Envelope, Tone
tone = Tone.from_string("C4", system="western")
play(tone, envelope=Envelope.PIANO) # Quick attack, natural decay
play(tone, envelope=Envelope.PLUCK) # Sharp attack, fast decay
play(tone, envelope=Envelope.PAD) # Slow fade in, lush sustain
play(tone, envelope=Envelope.ORGAN) # Instant on/off, no shaping
play(tone, envelope=Envelope.BELL) # Instant attack, long ring
play(tone, envelope=Envelope.STRINGS) # Gradual bow attack
play(tone, envelope=Envelope.BOWED) # Bow bite into sustain
play(tone, envelope=Envelope.MALLET) # Strike with ringing sustain
play(tone, envelope=Envelope.STACCATO) # Short and punchy
play(tone, envelope=Envelope.NONE) # Raw waveform, no shaping
Envelope Descriptions
~~~~~~~~~~~~~~~~~~~~~
=============== ================================================
Name Character
=============== ================================================
``"piano"`` Quick attack, natural decay -- acoustic piano feel
``"pluck"`` Sharp attack, fast decay -- guitar pick, harp
``"pad"`` Slow fade in, lush sustain -- strings, synth pads
``"organ"`` Instant on/off -- Hammond organ, no shaping
``"bell"`` Instant attack, no sustain -- short metallic ring
``"strings"`` Gradual bow attack -- orchestral strings, slow
``"bowed"`` Bow bite into sustain -- solo strings, brass
``"mallet"`` Strike with ringing sustain -- vibraphone, celesta
``"staccato"`` Short and punchy -- funk stabs, percussive hits
``"none"`` Raw waveform, no amplitude shaping at all
=============== ================================================
Detune
------
Any synth can be fattened with the ``detune`` parameter — it renders
three oscillators per note: the center pitch plus one shifted up and
one shifted down by the specified number of cents. The slight frequency
differences create beating and width, like an analog synth with
oscillator drift.
.. code-block:: python
# Juno-style analog drift — subtle, warm
pad = score.part("pad", synth="saw", detune=15)
# Trance supersaw territory — wide, shimmery
lead = score.part("lead", synth="saw", detune=25)
# Subtle thickening on a bass
bass = score.part("bass", synth="pulse", detune=8)
# Works on any synth — even FM
bells = score.part("bells", synth="fm", detune=12)
Detune values:
- **5–10** = subtle thickening (barely noticeable, just warmer)
- **12–18** = classic analog drift (Juno, Prophet)
- **20–30** = wide and shimmery (trance, EDM)
- **40+** = extreme, almost chorus-like
This is different from the ``chorus`` effect — detune creates
additional oscillators at render time (three per note), while chorus
processes the audio after rendering with a modulated delay line.
Detune is "wider at the source," chorus is "wider after the fact."
Stack both for maximum fatness.
Stereo Placement
----------------
Every part can be placed in the stereo field with ``pan`` and ``spread``.
**Pan** positions a part left or right. Constant-power panning keeps
the perceived loudness even as you move across the field:
.. code-block:: python
rhythm = score.part("rhythm", synth="saw", pan=-0.7) # left
lead = score.part("lead", synth="saw", pan=0.6) # right
bass = score.part("bass", synth="sine", pan=0.0) # center
hats = score.part("hats", synth="noise", pan=0.3) # slightly right
Pan values: -1.0 (hard left), 0.0 (center), 1.0 (hard right).
**Spread** works with ``detune`` — the up-detuned oscillator goes to
the right channel and the down-detuned goes to the left, creating
stereo width at the source:
.. code-block:: python
# Wide pad: detuned + spread across the stereo field
pad = score.part(
"pad",
synth="saw",
detune=20,
spread=1.0, # full L/R separation of detuned voices
reverb=0.4,
)
Spread values: 0.0 (detuned voices stay mono), 1.0 (full L/R split).
Stack with pan to offset the center of the spread.
Reverb is also stereo — the left and right channels get different
early reflection patterns, so the reverb tail occupies real space
in the stereo field rather than sitting dead center.
Physical Modeling
-----------------
Three synths go beyond traditional waveform synthesis into physical
modeling territory — they simulate how real instruments produce sound.
Karplus-Strong Pluck
~~~~~~~~~~~~~~~~~~~~
A burst of noise fed into a short delay line. The delay length sets
the pitch, the feedback filter models the string decaying. This is
how every physical modeling synth since 1983 does plucked strings.
It sounds genuinely like a real guitar, harp, or koto.
.. code-block:: python
guitar = score.part("guitar", synth="pluck_synth")
harp = score.part("harp", instrument="harp") # uses pluck_synth
.. raw:: html
Hammond Organ
~~~~~~~~~~~~~
Additive synthesis with drawbar harmonics — sine waves at the
fundamental plus 2nd, 3rd, 4th, 5th, 6th, and 8th harmonics mixed
at musical levels. Warm, round, unmistakably organ.
.. code-block:: python
organ = score.part("organ", synth="organ_synth")
.. raw:: html
String Ensemble
~~~~~~~~~~~~~~~
Filtered sawtooth with body resonance formants at ~500 Hz and ~1500 Hz,
modeling the way a violin or cello body shapes the sound. Warmer and
more "wooden" than a raw saw wave.
.. code-block:: python
violin = score.part("violin", synth="strings_synth")
.. raw:: html
Dedicated Instrument Synths
--------------------------
Beyond the classic and physical modeling waveforms, PyTheory includes
36 dedicated instrument synths. Each one uses tailored synthesis
techniques -- additive harmonics, formant shaping, body resonance
modeling, and specialized envelopes -- to capture the character of a
specific acoustic instrument. These are the waveforms that bring the
total count to 56.
Piano Synth
~~~~~~~~~~~
Hammer-strike envelope with body resonance and subtle inharmonicity.
Models the way a felt hammer excites steel strings inside a wooden
soundboard.
.. code-block:: python
piano = score.part("piano", synth="piano_synth")
.. raw:: html
Rhodes Electric Piano
~~~~~~~~~~~~~~~~~~~~~
The Fender Rhodes — a rubber-tipped hammer strikes a steel tine
next to a tonebar, picked up by an electromagnetic pickup. Warm,
bell-like, with a bright metallic attack that mellows into a
singing sustain. The sound of jazz clubs, soul, and neo-soul.
.. code-block:: python
rhodes = score.part("rhodes", synth="rhodes_synth")
# Or use the instrument preset (adds tremolo + chorus)
rhodes = score.part("rhodes", instrument="electric_piano")
.. raw:: html
Wurlitzer Electric Piano
~~~~~~~~~~~~~~~~~~~~~~~~
The Wurlitzer uses a vibrating steel reed (not a tine like Rhodes)
picked up by an electrostatic pickup. More nasal, reedy, and biting
— it barks and growls when played hard. Think Supertramp, Ray Charles.
.. code-block:: python
wurli = score.part("wurli", synth="wurlitzer_synth")
wurli = score.part("wurli", instrument="wurlitzer")
.. raw:: html
Mellotron
~~~~~~~~~
The original "sampler" — a 1960s keyboard where each key triggers a
strip of magnetic tape with a pre-recorded instrument. The mechanical
tape transport gives it a haunted, lo-fi quality that no digital
emulation fully captures: pitch wobbles from uneven capstan speed,
bandwidth limited to 300 Hz–6 kHz (like a worn cassette), soft tape
saturation, and tapes that physically run out after 8 seconds.
The Mellotron defined the sound of *Strawberry Fields Forever*,
*Stairway to Heaven*, and every prog rock record from 1969–1977.
Three tape banks are available via the ``tape`` parameter:
- ``"strings"`` (default) — the iconic MkII string section
- ``"flute"`` — breathy, haunting solo flute
- ``"choir"`` — ghostly vocal pad
**Use for:** prog rock, haunted textures, vintage orchestral color.
.. code-block:: python
# Use instrument presets (includes reverb)
strings = score.part("strings", instrument="mellotron_strings")
flute = score.part("flute", instrument="mellotron_flute")
choir = score.part("choir", instrument="mellotron_choir")
# Or select the tape directly
from pytheory import play, Synth, Tone
play(Tone.from_string("C4"), synth=Synth.MELLOTRON, tape="flute", t=3000)
.. raw:: html
Vibraphone Synth
~~~~~~~~~~~~~~~~
Struck aluminum bars with motor-driven tremolo discs. The spinning
motor modulates the sound through the resonator tubes, creating the
signature vibraphone shimmer. Inharmonic bar modes at 1x, 2.76x, 5.4x.
.. code-block:: python
vib = score.part("vib", synth="vibraphone_synth")
vib = score.part("vib", instrument="vibraphone")
.. raw:: html
Pipe Organ Synth
~~~~~~~~~~~~~~~~
Multiple ranks of pipes — principal 8', octave 4', fifteenth 2'.
Constant air pressure means no dynamics. Wind chiff at the attack.
Best with cathedral reverb.
.. code-block:: python
organ = score.part("organ", synth="pipe_organ_synth")
organ = score.part("organ", instrument="pipe_organ")
.. raw:: html
Choir Synth
~~~~~~~~~~~
Voices singing vowels shaped by formant bandpass filters. The glottal
source is filtered through vocal tract resonances — F1, F2, F3, F4 —
which is what makes "ah" sound different from "oo". Use ``lyric=``
to control the vowel. Best with ``ensemble=`` for a full section.
.. code-block:: python
choir = score.part("choir", synth="choir_synth")
choir = score.part("choir", instrument="choir") # ensemble=6 + cathedral reverb
choir.add("C4", Duration.WHOLE, lyric="ah")
.. raw:: html
Bass Guitar Synth
~~~~~~~~~~~~~~~~~
Plucked string model with finger-damped harmonics and low-end warmth.
.. code-block:: python
bass = score.part("bass", synth="bass_guitar_synth")
.. raw:: html
Flute Synth
~~~~~~~~~~~~
Breathy noise excitation through a resonant tube model, with
overblowing behavior at higher velocities.
.. code-block:: python
flute = score.part("flute", synth="flute_synth")
.. raw:: html
Trumpet Synth
~~~~~~~~~~~~~
Brass lip-buzz model with spectral brightness that increases with
velocity, plus a characteristic brassy edge from shaped harmonics.
.. code-block:: python
trumpet = score.part("trumpet", synth="trumpet_synth")
.. raw:: html
Clarinet Synth
~~~~~~~~~~~~~~
Cylindrical bore model producing mostly odd harmonics, giving the
characteristic hollow, woody tone.
.. code-block:: python
clarinet = score.part("clarinet", synth="clarinet_synth")
.. raw:: html
Oboe Synth
~~~~~~~~~~~
Double-reed model with nasal formant shaping and a buzzy, penetrating
timbre.
.. code-block:: python
oboe = score.part("oboe", synth="oboe_synth")
.. raw:: html
Marimba Synth
~~~~~~~~~~~~~
Tuned bar model with a soft mallet attack and a warm, resonant decay
that emphasizes the fundamental.
.. code-block:: python
marimba = score.part("marimba", synth="marimba_synth")
.. raw:: html
Harpsichord Synth
~~~~~~~~~~~~~~~~~
Plucked-string model with a bright, immediate attack and rapid decay
-- the characteristic "plink" of a quill plucking a string.
.. code-block:: python
harpsi = score.part("harpsi", synth="harpsichord_synth")
.. raw:: html
Cello Synth
~~~~~~~~~~~
Bowed string model with body formants at cello resonance frequencies,
producing a rich, warm, sustained tone.
.. code-block:: python
cello = score.part("cello", synth="cello_synth")
.. raw:: html
Harp Synth
~~~~~~~~~~
Plucked string with longer sustain and gentle high-frequency rolloff,
modeling nylon strings on a resonant frame.
.. code-block:: python
harp = score.part("harp", synth="harp_synth")
.. raw:: html
Upright Bass Synth
~~~~~~~~~~~~~~~~~~
Pizzicato double bass with woody body resonance and a thumpy low end.
.. code-block:: python
bass = score.part("bass", synth="upright_bass_synth")
.. raw:: html
Acoustic Guitar Synth
~~~~~~~~~~~~~~~~~~~~~
Steel-string model with pick transient, body resonance, and natural
string decay.
.. code-block:: python
guitar = score.part("guitar", synth="acoustic_guitar_synth")
.. raw:: html
Electric Guitar Synth
~~~~~~~~~~~~~~~~~~~~~
Magnetic pickup model with brighter harmonics and less body resonance
than the acoustic, ready for effects processing.
.. code-block:: python
eguitar = score.part("eguitar", synth="electric_guitar_synth")
.. raw:: html
Sitar Synth
~~~~~~~~~~~~
Sympathetic string resonance with the characteristic buzzy "jawari"
bridge, producing a shimmering, metallic sustain.
.. code-block:: python
sitar = score.part("sitar", synth="sitar_synth")
.. raw:: html
Timpani Synth
~~~~~~~~~~~~~
Large kettle drum with definite pitch. Inharmonic membrane modes
(1.0, 1.5, 1.99, 2.44), felt mallet attack, copper kettle resonance.
Use ``Part.roll()`` for crescendo timpani rolls.
.. code-block:: python
timp = score.part("timp", synth="timpani_synth")
timp.roll("C3", Duration.WHOLE, velocity_start=20, velocity_end=110)
.. raw:: html
Saxophone Synth
~~~~~~~~~~~~~~~
Single reed through a conical brass bore. All harmonics with strong
mids, reed buzz, and brass body warmth. Four presets: ``saxophone``,
``alto_sax``, ``tenor_sax``, ``bari_sax``.
.. code-block:: python
sax = score.part("sax", instrument="tenor_sax")
.. raw:: html
Pedal Steel Synth
~~~~~~~~~~~~~~~~~
The Nashville crying sound — singing harmonics with slow vibrato
and long sustain. Pairs naturally with spring reverb.
.. code-block:: python
steel = score.part("steel", instrument="pedal_steel")
.. raw:: html
Theremin Synth
~~~~~~~~~~~~~~
Pure sine with natural hand wobble — the eerie sci-fi sound.
Best used with legato and glide for continuous pitch.
.. code-block:: python
theremin = score.part("theremin", instrument="theremin")
.. raw:: html
Kalimba Synth
~~~~~~~~~~~~~
Metal tines on a wooden body. Bright, bell-like attack with
inharmonic overtones (modes at 1x, 2.92x, 5.4x).
.. code-block:: python
kalimba = score.part("kalimba", instrument="kalimba")
.. raw:: html
Steel Drum Synth
~~~~~~~~~~~~~~~~
Hammered metal pan with bright, ringing, tropical character.
Inharmonic partials at 2.0x, 3.01x, 4.1x, 5.3x.
.. code-block:: python
pan = score.part("pan", instrument="steel_drum")
.. raw:: html
Accordion Synth
~~~~~~~~~~~~~~~
Musette-tuned doubled reeds — two slightly detuned reed sets
create natural beating. Bellows pressure swell modulates amplitude.
.. code-block:: python
acc = score.part("acc", instrument="accordion")
.. raw:: html
Didgeridoo Synth
~~~~~~~~~~~~~~~~
Deep cylindrical drone with shifting formant overtones. The
overtone singing effect sweeps a resonant peak between 500-1500Hz.
Best with cave reverb.
.. code-block:: python
didg = score.part("didg", instrument="didgeridoo")
.. raw:: html
Bagpipe Synth
~~~~~~~~~~~~~
Bright chanter reed with constant bag pressure. All harmonics
peaked around 3-7 (the piercing brightness). No dynamics — always ff.
.. code-block:: python
pipes = score.part("pipes", instrument="bagpipe")
.. raw:: html
Banjo Synth
~~~~~~~~~~~
Steel strings on a drum-head membrane body. The membrane gives
nasal, ringy resonance with faster decay than guitar.
.. code-block:: python
banjo = score.part("banjo", instrument="banjo")
.. raw:: html
Mandolin Synth
~~~~~~~~~~~~~~
Paired steel strings in 4 courses — natural chorus from the
doubled unison strings. Bright, ringing, fast attack.
.. code-block:: python
mando = score.part("mando", instrument="mandolin")
.. raw:: html
Ukulele Synth
~~~~~~~~~~~~~
Nylon strings on a small body. Mid-heavy resonance (no deep bass),
softer attack than guitar, shorter sustain.
.. code-block:: python
uke = score.part("uke", instrument="ukulele")
.. raw:: html
Granular Synth
~~~~~~~~~~~~~~
Grain cloud synthesis — chops a source waveform into tiny overlapping
grains (10-200ms), each windowed and optionally pitch/time scattered.
Creates textures impossible with other synthesis: frozen tones,
shimmering clouds, evolving pads, glitchy stutters.
.. code-block:: python
# Atmospheric granular pad
pad = score.part("pad", instrument="granular_pad")
# Granular with filter envelope sweep + resonance
texture = score.part("texture", synth="granular_synth", envelope="pad",
filter_amount=4000, filter_attack=0.5,
filter_decay=1.5, filter_sustain=0.3,
lowpass=600, lowpass_q=3.0,
reverb=0.5, reverb_type="taj_mahal")
Parameters (passed as synth kwargs):
- ``grain_size``: Duration per grain in seconds (default 0.04).
- ``density``: Grains per second (default 50). Higher = denser cloud.
- ``scatter``: Random position jitter 0-1 (default 0.5).
- ``pitch_var``: Per-grain pitch randomization in cents (default 12).
- ``source``: Base waveform — ``"saw"``, ``"sine"``, ``"triangle"``,
``"square"``, ``"noise"``.
.. raw:: html
Crotales
~~~~~~~~
Small tuned bronze discs (antique cymbals) struck with brass mallets.
Bright, crystalline, bell-like tone with strong upper harmonics that
rings for a long time. Nearly harmonic partials give crotales their
penetrating brilliance — they cut through any orchestra.
.. code-block:: python
crotales = score.part("crotales", synth="crotales_synth", envelope="none",
reverb=0.3)
.. raw:: html
Tingsha
~~~~~~~
Two small Tibetan cymbals joined by a cord, clashed together. Both discs
ring at slightly different frequencies, producing a bright ping with
pronounced beating — the wavering interference between the two is the
whole character of the sound.
.. code-block:: python
tingsha = score.part("tingsha", synth="tingsha_synth", envelope="none",
reverb=0.4)
.. raw:: html
Singing Bowl (Strike)
~~~~~~~~~~~~~~~~~~~~~
Tibetan/Himalayan singing bowl struck with a mallet. The impact excites
inharmonic partials that ring and slowly beat against each other as
near-degenerate mode pairs interfere. Higher modes fade quickly, leaving
the fundamental shimmering for seconds.
.. code-block:: python
bowl = score.part("bowl", synth="singing_bowl_strike_synth", envelope="none",
reverb=0.4)
.. raw:: html
Singing Bowl (Ring)
~~~~~~~~~~~~~~~~~~~
Rim-rubbed singing bowl — the mallet traces the rim, slowly building the
fundamental into a sustained, pulsing tone. Upper harmonics shimmer in
and out as the bowl resonates.
.. code-block:: python
bowl = score.part("bowl", synth="singing_bowl_ring_synth", envelope="none",
reverb=0.4)
.. raw:: html
Rain Stick
~~~~~~~~~~
Cascading pebbles through a cactus tube with internal pins. Two variants:
steep angle (fast cascade) and shallow angle (slow trickle).
.. code-block:: python
p.hit(DrumSound.RAINSTICK, Duration.WHOLE * 3) # steep — fast cascade
p.hit(DrumSound.RAINSTICK_SLOW, Duration.WHOLE * 4) # shallow — gentle trickle
.. raw:: html
Ocean Drum
~~~~~~~~~~
Steel beads rolling inside a frame drum — tilting produces a smooth surf wash.
.. code-block:: python
p.hit(DrumSound.OCEAN_DRUM, Duration.WHOLE * 3)
.. raw:: html
Cabasa
~~~~~~
Metal bead chain scraped against a textured cylinder — brighter and
more metallic than a shaker.
.. code-block:: python
p.hit(DrumSound.CABASA, Duration.EIGHTH)
.. raw:: html
Wind Chimes
~~~~~~~~~~~
Suspended metal tubes struck by hand or breeze. Each tube rings at
its own pitch with slight time offsets.
.. code-block:: python
p.hit(DrumSound.WIND_CHIMES, Duration.WHOLE * 3)
.. raw:: html
Finger Cymbal
~~~~~~~~~~~~~
Single small cymbal tap (zill) — bright metallic ping.
.. code-block:: python
p.hit(DrumSound.FINGER_CYMBAL, Duration.HALF)
.. raw:: html
Analog Oscillator Drift
~~~~~~~~~~~~~~~~~~~~~~~~
All waveform synths support the ``analog_drift`` parameter, which adds
subtle, slow random pitch variation to each oscillator -- modeling the
voltage instability of vintage analog circuits. This is what makes a
real Minimoog sound slightly different on every note, and why analog
synths feel "alive" compared to their digital counterparts.
.. code-block:: python
# Subtle vintage drift
pad = score.part("pad", synth="saw", analog_drift=0.1)
# More pronounced, wobbly analog character
lead = score.part("lead", synth="square", analog_drift=0.3)
Drift values:
- **0.05--0.1** = subtle warmth (studio-grade analog)
- **0.15--0.25** = noticeable drift (vintage gear warming up)
- **0.3+** = unstable, wobbly (broken tape machine)
Instrument Presets
------------------
Instead of choosing synth + envelope + effects manually, use an
instrument preset — 60+ predefined combinations that approximate real
instruments:
.. code-block:: python
piano = score.part("piano", instrument="piano")
violin = score.part("violin", instrument="violin")
guitar = score.part("guitar", instrument="acoustic_guitar")
organ = score.part("organ", instrument="organ")
bass = score.part("bass", instrument="upright_bass")
Available instruments:
**Keys**: piano, electric_piano, organ, harpsichord, celesta, music_box,
accordion
**Strings**: violin, viola, cello, contrabass, string_ensemble
**Woodwinds**: flute, clarinet, oboe, bassoon, saxophone, alto_sax,
tenor_sax, bari_sax
**Brass**: trumpet, trombone, french_horn, tuba, brass_ensemble
**Plucked**: acoustic_guitar, electric_guitar, clean_guitar, crunch_guitar,
distorted_guitar, orange_crunch, metal_guitar, bass_guitar, upright_bass,
harp, sitar, koto, banjo, mandolin, mandola, ukulele
**World/Exotic**: pedal_steel, theremin, kalimba, steel_drum, didgeridoo,
bagpipe, singing_bowl, singing_bowl_ring, tingsha
**Synth**: synth_lead, synth_pad, synth_bass, acid_bass, 808_bass,
granular_pad, granular_texture, vocal, choir
**Mellotron**: mellotron, mellotron_strings, mellotron_flute, mellotron_choir
**Analog**: sync_lead, sync_lead_bright, ring_mod_bell, ring_mod_metallic,
wavefold_warm, wavefold_gnarly, drift_saw, drift_square, analog_pad,
analog_bass
**Percussion**: vibraphone, marimba, xylophone, glockenspiel, tubular_bells,
timpani, crotales
Explicit kwargs override preset defaults:
.. code-block:: python
# Piano with extra reverb
piano = score.part("piano", instrument="piano", reverb=0.5)
# Violin panned left
violin = score.part("v", instrument="violin", pan=-0.4)
Choosing Synth and Envelope Combos
----------------------------------
The right combination of synth and envelope defines the character of a
voice. This is where you stop thinking about waveforms and start
thinking about *instruments*. Here are some starting points:
- **Funk stabs:** ``saw`` + ``staccato`` -- bright, punchy, rhythmic.
- **Jazz keys:** ``fm`` + ``bell`` -- glassy DX7 electric piano.
- **Ambient pads:** ``supersaw`` + ``pad`` -- massive, slow-building wash.
- **Acid bass:** ``saw`` + ``pluck`` with lowpass and glide -- 303-style.
- **Chiptune lead:** ``square`` + ``none`` -- raw 8-bit.
- **Film strings:** ``triangle`` + ``strings`` -- soft, bowed, organic.
- **Sub bass:** ``sine`` + ``pluck`` with lowpass -- deep and round.
- **Retro synth:** ``pwm_slow`` + ``pad`` -- Juno-style analog warmth.
- **Percussive hit:** ``noise`` + ``staccato`` with lowpass -- snare layer.
- **E-piano ballad:** ``fm`` + ``piano`` with reverb -- intimate jazz club.
Some practical combos worth memorizing:
- ``saw`` + ``staccato`` + legato = **acid 303 line.** Add a resonant
lowpass and some glide and you're in a warehouse in 1988.
- ``fm`` + ``bell`` = **jazz vibraphone.** The glassy, harmonic-rich
attack with a long ring-out. Add reverb for a late-night club feel.
- ``supersaw`` + ``pad`` = **ambient wash.** The slow attack lets the
detuned oscillators build into a shimmering wall. Add chorus and
long reverb and you're scoring a nature documentary.
- ``saw`` + ``pluck`` = **funk stab.** Short, sharp, bright. The
sound of Nile Rodgers' right hand.
- ``hard_sync`` + ``pluck`` = **prophet lead.** Bright formant peak
that cuts through any mix. The opening riff of every 80s synth solo.
- ``wavefold`` + ``organ`` = **west coast bass.** Warm, harmonically
rich sine-derivative that pairs beautifully with a lowpass after.
- ``drift`` + ``pad`` = **analog pad.** A sawtooth that breathes and
wobbles like a real VCO. Add chorus and reverb for Juno vibes.
- ``mellotron_synth`` + ``organ`` = **prog strings.** Haunted tape
machine. Add cathedral reverb and you're in 1972.