Sequencing (Score, Part, Pattern)¶
The composition layer: Score holds an arrangement,
Part holds one instrument’s notes, Pattern holds
drum patterns. See the Sequencing and Drums
guides for tutorials.
Rhythm and duration primitives for PyTheory.
- class pytheory.rhythm.Duration(*values)[source]¶
Bases:
EnumNote durations in beats (quarter note = 1 beat).
- WHOLE = 4.0¶
- HALF = 2.0¶
- QUARTER = 1.0¶
- EIGHTH = 0.5¶
- SIXTEENTH = 0.25¶
- DOTTED_HALF = 3.0¶
- DOTTED_QUARTER = 1.5¶
- TRIPLET_QUARTER = 0.6666666666666666¶
- class pytheory.rhythm.TimeSignature(beats: int = 4, unit: int = 4)[source]¶
Bases:
objectA musical time signature like 4/4 or 6/8.
- classmethod from_string(s: str) TimeSignature[source]¶
Parse ‘4/4’, ‘3/4’, ‘6/8’ etc.
- class pytheory.rhythm.Note(tone: object, duration: Duration, velocity: int = 100, bend: float = 0.0, bend_type: str = 'smooth', lyric: str = '', articulation: str = '', _hold: bool = False)[source]¶
Bases:
objectA pairing of a sound (Tone, Chord, or None for rest) with a duration.
The optional
bendfield specifies a pitch bend in semitones applied over the note’s duration. Positive = bend up, negative = down. For example,bend=2bends the note up a whole step by the end.
- pytheory.rhythm.Rest(duration=Duration.QUARTER) Note[source]¶
Create a rest (silent note) with the given duration.
- class pytheory.rhythm.DrumSound(*values)[source]¶
Bases:
EnumGeneral MIDI percussion note numbers (channel 10).
These map to the GM drum map standard supported by virtually all MIDI devices and DAWs.
- KICK = 36¶
- SNARE = 38¶
- RIMSHOT = 37¶
- CLAP = 39¶
- CLOSED_HAT = 42¶
- OPEN_HAT = 46¶
- PEDAL_HAT = 44¶
- LOW_TOM = 45¶
- MID_TOM = 47¶
- HIGH_TOM = 50¶
- CRASH = 49¶
- RIDE = 51¶
- RIDE_BELL = 53¶
- COWBELL = 56¶
- CLAVE = 75¶
- SHAKER = 70¶
- TAMBOURINE = 54¶
- CONGA_HIGH = 63¶
- CONGA_LOW = 64¶
- BONGO_HIGH = 60¶
- BONGO_LOW = 61¶
- TIMBALE_HIGH = 65¶
- TIMBALE_LOW = 66¶
- AGOGO_HIGH = 67¶
- AGOGO_LOW = 68¶
- GUIRO = 73¶
- MARACAS = 70¶
- TABLA_NA = 86¶
- TABLA_TIN = 87¶
- TABLA_GE = 88¶
- TABLA_DHA = 89¶
- TABLA_TIT = 90¶
- TABLA_KE = 91¶
- DHOL_DAGGA = 92¶
- DHOL_TILLI = 93¶
- DHOL_BOTH = 94¶
- DHOLAK_GE = 95¶
- DHOLAK_NA = 96¶
- DHOLAK_TIT = 97¶
- MRIDANGAM_THAM = 98¶
- MRIDANGAM_NAM = 99¶
- MRIDANGAM_DIN = 100¶
- MRIDANGAM_THA = 101¶
- TABLA_GE_BEND = 108¶
- DJEMBE_BASS = 102¶
- DJEMBE_TONE = 103¶
- DJEMBE_SLAP = 104¶
- DOUMBEK_DUM = 112¶
- DOUMBEK_TEK = 113¶
- DOUMBEK_KA = 114¶
- CAJON_BASS = 108¶
- CAJON_SLAP = 109¶
- CAJON_TAP = 110¶
- CAJON_SLAP_SNARE = 111¶
- METAL_KICK = 105¶
- METAL_SNARE = 106¶
- METAL_HAT = 107¶
- MARCH_SNARE = 115¶
- MARCH_RIMSHOT = 116¶
- MARCH_CLICK = 118¶
- QUAD_1 = 119¶
- QUAD_2 = 120¶
- QUAD_3 = 121¶
- QUAD_4 = 122¶
- QUAD_SPOCK = 123¶
- BASS_1 = 124¶
- BASS_2 = 125¶
- BASS_3 = 126¶
- BASS_4 = 127¶
- BASS_5 = 80¶
- RAINSTICK = 81¶
- RAINSTICK_SLOW = 128¶
- OCEAN_DRUM = 82¶
- CABASA = 83¶
- WIND_CHIMES = 84¶
- FINGER_CYMBAL = 85¶
- class pytheory.rhythm.Pattern(name: str, hits: list[_Hit], beats: float = 4.0, time_signature: str = '4/4')[source]¶
Bases:
objectA drum pattern — a repeating rhythmic figure.
Patterns are defined as a list of hits within a fixed number of beats. They can be rendered to a Score for MIDI export, or combined with chord progressions.
Example:
>>> pattern = Pattern.preset("rock") >>> print(pattern) <Pattern 'rock' 4/4 4.0 beats 12 hits>
- to_score(repeats: int = 4, bpm: int = 120) Score[source]¶
Render this pattern to a Score for MIDI export.
- Parameters:
repeats – Number of times to repeat the pattern.
bpm – Tempo in beats per minute.
- Returns:
A Score containing drum hits as MIDI percussion notes.
- classmethod fill(name: str) Pattern[source]¶
Load a named 1-bar drum fill.
Available fills: rock, rock crash, jazz, jazz brush, salsa, samba, funk, metal, blast, buildup, breakdown.
Example:
>>> Pattern.fill("rock") <Pattern 'rock fill' 4/4 4.0 beats ...>
- classmethod preset(name: str) Pattern[source]¶
Load a named drum pattern preset.
Available presets:
rock — standard 4/4 rock beat (kick-snare-hat)
jazz — swing ride pattern with ghost notes
bebop — fast jazz ride with syncopated kick/snare
bossa nova — Brazilian 2-bar pattern with cross-stick
salsa — clave-driven Afro-Cuban pattern
funk — syncopated 16th-note groove
reggae — one-drop pattern (snare on 3)
waltz — 3/4 pattern (oom-pah-pah)
12/8 blues — slow blues shuffle
samba — Brazilian carnival pattern
son clave 3-2 — the Afro-Cuban rhythmic key
son clave 2-3 — reversed clave
Example:
>>> Pattern.preset("salsa") <Pattern 'salsa' 4/4 8.0 beats ...>
- class pytheory.rhythm.Part(name: str, *, synth: str = 'sine', envelope: str = 'piano', volume: float = 0.5, reverb: float = 0.0, reverb_decay: float = 1.0, reverb_type: str = 'algorithmic', delay: float = 0.0, delay_time: float = 0.375, delay_feedback: float = 0.4, highpass: float = 0.0, highpass_q: float = 0.707, lowpass: float = 0.0, lowpass_q: float = 0.707, distortion: float = 0.0, distortion_drive: float = 3.0, legato: bool = False, glide: float = 0.0, chorus: float = 0.0, chorus_rate: float = 1.5, chorus_depth: float = 0.003, swing: float | None = None, humanize: float = 0.0, sidechain: float = 0.0, sidechain_release: float = 0.1, detune: float = 0.0, pan: float = 0.0, spread: float = 0.0, sub_osc: float = 0.0, noise_mix: float = 0.0, filter_attack: float = 0.01, filter_decay: float = 0.3, filter_sustain: float = 0.0, filter_amount: float = 0.0, vel_to_filter: float = 0.0, saturation: float = 0.0, tremolo_depth: float = 0.0, tremolo_rate: float = 5.0, phaser: float = 0.0, phaser_rate: float = 0.5, cabinet: float = 0.0, cabinet_brightness: float = 0.5, analog: float = 0.0, ensemble: int = 1, fm_ratio: float = 2.0, fm_index: float = 3.0, synth_kw: dict = None)[source]¶
Bases:
objectA named voice within a Score, with its own synth, envelope, and effects.
Parts allow layering multiple instruments — lead, bass, pads, etc. — each with independent synth settings and effects, mixed together on playback.
Don’t instantiate directly — use
Score.part()instead.Example:
score = Score("4/4", bpm=140) lead = score.part("lead", synth="saw", envelope="pluck", reverb=0.3, delay=0.25) lead.add("E5", Duration.QUARTER).add("D5", Duration.EIGHTH) bass = score.part("bass", synth="triangle", envelope="pluck") bass.add("A2", Duration.HALF)
- add(tone_or_string, duration=Duration.QUARTER, *, velocity: int = 100, bend: float = 0.0, bend_type: str = 'smooth', lyric: str = '', articulation: str = '') Part[source]¶
Add a note. Accepts Tone/Chord objects or note strings like
"E5".Duration can be a
Durationenum or a raw float (beats). Velocity controls loudness (1-127, default 100). Bend specifies a pitch bend in semitones over the note duration (e.g.bend=2bends up a whole step,bend=-1bends down a half step). Used for guitar bends, sitar meends, slides. Articulation changes how the note is played:"staccato"(short, ~40% duration),"legato"(overlaps next note),"marcato"(heavy accent),"tenuto"(full duration, soft attack),"accent"(velocity bump),"fermata"(held ~50% longer).Returns self for chaining.
- hold(tone_or_string, duration=Duration.QUARTER, *, velocity: int = 100, bend: float = 0.0, bend_type: str = 'smooth', lyric: str = '', articulation: str = '') Part[source]¶
Add a note without advancing the beat position.
The note plays at the current position but the next note starts at the same time — enabling polyphonic overlap on a single part.
Use this for: piano sustain pedal (bass note rings while melody plays above), guitar strumming with individual string timing, held drone notes under a melody.
Example:
>>> piano = score.part("piano", instrument="piano") >>> piano.hold("C3", Duration.WHOLE) # bass rings for 4 beats >>> piano.add("E4", Duration.HALF) # starts at same time as C3 >>> piano.add("G4", Duration.HALF) # starts at beat 2
- hit(sound, duration=Duration.EIGHTH, *, velocity: int = 100, articulation: str = '') Part[source]¶
Add a drum hit to this part.
Places a drum sound into the note stream so it goes through the normal renderer — meaning articulations, humanize, and effects all work on individual hits.
- Parameters:
sound – A
DrumSoundenum member (e.g.DrumSound.KICK) or its name as a string ("kick","snare","closed_hat"— case-insensitive).duration – How long the hit occupies in the timeline (default 8th note).
velocity – Hit loudness 1-127.
articulation –
"accent","staccato","marcato", etc.
Example:
>>> drums = score.part("kit", synth="sine") >>> drums.hit("kick", Duration.QUARTER, articulation="accent") >>> drums.hit(DrumSound.CLOSED_HAT, Duration.EIGHTH)
- flam(sound, duration=Duration.QUARTER, *, velocity: int = 110, gap: float = 0.015, grace_vel: float = 0.3, articulation: str = '') Part[source]¶
Add a flam — a grace note immediately before the main hit.
The grace note is nearly simultaneous with the main hit, thickening the attack. Tighter gap = more like one fat hit, wider gap = audible double.
- Parameters:
sound – A
DrumSoundenum member.duration – Total duration the flam occupies.
velocity – Main hit velocity.
gap – Beats between grace and main (default 0.008 ≈ 4ms at 120).
grace_vel – Grace note velocity as fraction of main (default 0.3).
articulation – Optional articulation for the main hit.
Example:
>>> p.flam(DrumSound.MARCH_SNARE, Duration.QUARTER, velocity=120)
- diddle(sound, duration=Duration.EIGHTH, *, velocity: int = 70) Part[source]¶
Add a diddle — two equal strokes in the space of one note.
A double-stroke roll building block. Two hits split evenly across the duration.
- Parameters:
sound – A
DrumSoundenum member.duration – Total duration (default 8th note). Each stroke gets half.
velocity – Velocity for both strokes.
Example:
>>> p.diddle(DrumSound.MARCH_SNARE, Duration.EIGHTH, velocity=60)
- cheese(sound, duration=Duration.QUARTER, *, velocity: int = 110, gap: float = 0.008, grace_vel: float = 0.3) Part[source]¶
Add a cheese — a flam followed by a diddle.
Common marching rudiment: grace-MAIN-tap-tap.
- Parameters:
sound – A
DrumSoundenum member.duration – Total duration.
velocity – Main hit velocity.
- crescendo(notes, duration=Duration.QUARTER, *, start_vel: int = 40, end_vel: int = 110, articulation: str = '') Part[source]¶
Add notes with velocity ramping up (getting louder).
- Parameters:
notes – List of note strings (e.g.
["C4", "D4", "E4"]).duration – Duration for each note.
start_vel – Starting velocity (quiet).
end_vel – Ending velocity (loud).
articulation – Optional articulation for all notes.
Example:
>>> piano.crescendo(["C4","D4","E4","F4","G4"], Duration.QUARTER, ... start_vel=40, end_vel=110)
- decrescendo(notes, duration=Duration.QUARTER, *, start_vel: int = 110, end_vel: int = 40, articulation: str = '') Part[source]¶
Add notes with velocity ramping down (getting quieter).
- Parameters:
notes – List of note strings.
duration – Duration for each note.
start_vel – Starting velocity (loud).
end_vel – Ending velocity (quiet).
articulation – Optional articulation for all notes.
Example:
>>> piano.decrescendo(["G4","F4","E4","D4","C4"], Duration.QUARTER, ... start_vel=110, end_vel=40)
- dynamics(notes, duration=Duration.QUARTER, *, velocities=None, articulation: str = '') Part[source]¶
Add notes with a velocity curve.
- Parameters:
notes – List of note strings or Tone/Chord objects.
duration – Duration for each note (or list of durations).
velocities – Velocity curve — either a
(start, end)tuple for a linear ramp, or a list of ints (one per note).articulation – Optional articulation for all notes (or list).
Example:
>>> # Linear ramp >>> piano.dynamics(["C4","E4","G4","C5"], Duration.QUARTER, ... velocities=(50, 120)) >>> # Custom curve (swell and fade) >>> piano.dynamics(["C4","D4","E4","F4","G4","F4","E4","D4"], ... Duration.EIGHTH, ... velocities=[50, 70, 90, 110, 110, 90, 70, 50])
- swell(notes, duration=Duration.QUARTER, *, low_vel: int = 40, peak_vel: int = 110, articulation: str = '') Part[source]¶
Add notes that swell up then fade back down (< > shape).
The velocity ramps up to the midpoint then back down, creating the classic orchestral swell.
- Parameters:
notes – List of note strings.
duration – Duration for each note.
low_vel – Velocity at start and end.
peak_vel – Velocity at the peak (midpoint).
articulation – Optional articulation.
Example:
>>> strings.swell(["C4","D4","E4","F4","G4","F4","E4","D4"], ... Duration.QUARTER, low_vel=40, peak_vel=110)
- set(**params) Part[source]¶
Change effect parameters at the current beat position.
Inserts an automation marker — from this point forward, the specified parameters take new values. Use this to open filters, add reverb, kick in distortion, or change volume mid-song.
- Parameters:
**params – Any Part parameter —
lowpass,lowpass_q,reverb,reverb_decay,delay,delay_time,delay_feedback,distortion,distortion_drive,volume,chorus,chorus_rate,chorus_depth.- Returns:
Self for chaining.
Example:
>>> lead = score.part("lead", synth="saw", lowpass=800) >>> lead.add("C5", Duration.WHOLE) # filtered >>> lead.set(lowpass=3000, reverb=0.4) # filter opens >>> lead.add("E5", Duration.WHOLE) # bright + reverb >>> lead.set(distortion=0.6, lowpass=1500) # grit >>> lead.add("G5", Duration.WHOLE)
- ramp(over: float = 4.0, resolution: float = 0.25, curve: str = 'linear', **params) Part[source]¶
Smoothly ramp parameters from their current values to new targets.
Generates interpolated automation points — like turning a knob gradually instead of jumping to a new position. Works for any parameter that
.set()accepts.- Parameters:
over – Duration of the ramp in beats (default 4.0 = 1 bar). Use
Duration.WHOLE * 4for a 4-bar ramp, etc.resolution – How often to insert points, in beats (default 0.25). Lower = smoother but more points.
curve – Interpolation shape —
"linear"(default),"ease_in"(slow start, fast end),"ease_out"(fast start, slow end),"ease_in_out"(slow start and end).**params – Target values for any parameter. The ramp starts from the parameter’s current value at this beat position.
- Returns:
Self for chaining.
Example:
>>> lead = score.part("lead", synth="saw", lowpass=200) >>> # Open the filter over 4 bars >>> lead.ramp(over=Duration.WHOLE * 4, lowpass=8000) >>> # Fade reverb in over 2 bars >>> pad.ramp(over=Duration.WHOLE * 2, reverb=0.5) >>> # Multiple params at once with easing >>> lead.ramp(over=8.0, curve="ease_in", lowpass=6000, distortion=0.4)
- lfo(param: str, *, rate: float = 0.5, min: float = 0.0, max: float = 1.0, bars: float = 4, shape: str = 'sine', resolution: float = 0.25) Part[source]¶
Automate a parameter with an LFO (low-frequency oscillator).
Generates automation points at regular intervals, sweeping a parameter smoothly between min and max values. This is how filter sweeps, tremolo, and auto-wah effects work.
- Parameters:
param – Parameter name to modulate (e.g.
"lowpass","reverb","distortion","volume","chorus","delay").rate – LFO speed in cycles per bar (default 0.5 = one sweep every 2 bars). 0.25 = very slow, 1 = once per bar, 4 = four times per bar.
min – Minimum parameter value.
max – Maximum parameter value.
bars – Number of bars to run the LFO over (default 4).
shape – Waveform shape —
"sine"(smooth),"triangle"(linear),"saw"(ramp up),"square"(on/off).resolution – How often to insert automation points, in beats (default 0.25 = every 16th note). Lower = smoother.
- Returns:
Self for chaining.
Example:
>>> lead = score.part("lead", synth="saw", lowpass=400) >>> # Slow filter sweep: 400→3000 Hz over 8 bars >>> lead.lfo("lowpass", rate=0.125, min=400, max=3000, bars=8) >>> lead.arpeggio("Cm", bars=8, pattern="up", octaves=2)
- arpeggio(chord, *, bars: float = 1, pattern: str = 'up', division=Duration.SIXTEENTH, octaves: int = 1, velocity: int = 100) Part[source]¶
Arpeggiate a chord into a rhythmic pattern.
Takes a chord and sequences through its notes automatically, like a hardware arpeggiator on a synth. Combined with
legato=Trueandglide, this produces classic acid and trance arpeggiated lines.- Parameters:
chord – A Chord object (or string like
"Am").bars – Number of bars to fill (default 1).
pattern – Arpeggio pattern: -
"up"— low to high, repeat -"down"— high to low, repeat -"updown"— up then down (bounce) -"downup"— down then up -"random"— random note orderdivision – Note length for each step (default
Duration.SIXTEENTH).octaves – Number of octaves to span (default 1). With 2, the pattern repeats one octave higher before cycling.
- Returns:
Self for chaining.
Example:
>>> lead = score.part("lead", synth="saw", legato=True, glide=0.03) >>> lead.arpeggio(Chord.from_symbol("Am"), bars=2, pattern="updown")
- strum(chord_name: str, duration=Duration.QUARTER, *, direction: str = 'down', velocity: int = 100, strum_time: float = 0.05) Part[source]¶
Strum a chord using the part’s fretboard fingering.
Looks up the chord on the fretboard, gets the fingering, and adds each string as a rapid sequence with tiny time offsets — like a real guitar strum. Muted strings are skipped.
- Parameters:
chord_name – Chord name (e.g.
"Am","G","D").duration – Total duration of the strum (default QUARTER).
direction –
"down"(low→high, default) or"up"(high→low).velocity – Base velocity (each string gets slight variation).
strum_time – Time in beats for the full strum sweep (default 0.03 = very fast). Larger values = slower, more audible strum. Try 0.1 for a lazy strum.
- Returns:
Self for chaining.
Example:
>>> guitar = score.part("guitar", instrument="acoustic_guitar", ... fretboard=Fretboard.guitar()) >>> guitar.strum("Am", Duration.HALF) >>> guitar.strum("G", Duration.HALF, direction="up")
- roll(tone_or_string, duration=Duration.WHOLE, *, velocity_start: int = 40, velocity_end: int = 100, speed=Duration.SIXTEENTH) Part[source]¶
Play a roll — rapid repeated notes with velocity ramp.
Perfect for timpani rolls, snare rolls, tremolo on any instrument. The velocity ramps from
velocity_starttovelocity_endover the duration for crescendo/decrescendo.- Parameters:
tone_or_string – The note to repeat.
duration – Total duration of the roll.
velocity_start – Velocity of the first hit (default 40).
velocity_end – Velocity of the last hit (default 100).
speed – How fast to repeat (default SIXTEENTH notes).
- Returns:
Self for chaining.
Example:
>>> timp = score.part("timp", instrument="timpani") >>> timp.roll("C3", Duration.WHOLE, velocity_start=30, velocity_end=110)
- to_tab(*, tuning='guitar', frets=24, time_signature=None)[source]¶
Generate ASCII guitar/bass tablature from this part’s notes.
- Parameters:
tuning –
"guitar"(6-string standard),"bass"(4-string),"drop_d"(guitar drop D), aFretboardobject, or a list of MIDI note numbers for custom tuning (low string first).frets – Maximum fret number (default 24).
time_signature – A
TimeSignatureorNonefor 4/4.
- Returns:
A multi-line ASCII tablature string.
- class pytheory.rhythm.Section(name: str, score: Score)[source]¶
Bases:
objectA named section of a Score (verse, chorus, bridge, etc.).
- class pytheory.rhythm.Score(time_signature='4/4', bpm=120, swing: float = 0.0, drum_humanize: float = 0.15, system: str = 'western', temperament: str = 'equal', reference_pitch: float = 440.0)[source]¶
Bases:
objectA multi-part arrangement with drums, chords, and instrument voices.
A Score combines:
Drum patterns via
add_pattern()Chord/tone notes via
add()(backwards-compatible default part)Named parts via
part()— each with its own synth and envelope
Example:
score = Score("4/4", bpm=140) score.add_pattern(Pattern.preset("bossa nova"), repeats=4) chords = score.part("chords", synth="sine", envelope="pad") lead = score.part("lead", synth="saw", envelope="pluck") bass = score.part("bass", synth="triangle", envelope="pluck") for chord in key.progression("i", "iv", "V", "i"): chords.add(chord, Duration.WHOLE) lead.add("E5", Duration.QUARTER).add("D5", Duration.EIGHTH) bass.add("A2", Duration.HALF).add("D2", Duration.HALF) play_score(score)
- set_drum_effects(**kwargs) Score[source]¶
Set effects on all drum parts.
When drums are split, applies to every drum Part (kick, snare, hats, etc.). When not split, applies to the single drums Part.
Example:
score.set_drum_effects(reverb=0.2, reverb_type="plate")
- part(name: str, *, instrument: str = None, synth: str = None, envelope: str = None, volume: float = None, reverb: float = None, reverb_decay: float = None, reverb_type: str = None, delay: float = None, delay_time: float = None, delay_feedback: float = None, highpass: float = None, highpass_q: float = None, lowpass: float = None, lowpass_q: float = None, distortion: float = None, distortion_drive: float = None, legato: bool = None, glide: float = None, chorus: float = None, chorus_rate: float = None, chorus_depth: float = None, swing: float | None = None, humanize: float = None, sidechain: float = None, sidechain_release: float = None, detune: float = None, pan: float = None, spread: float = None, sub_osc: float = None, noise_mix: float = None, filter_attack: float = None, filter_decay: float = None, filter_sustain: float = None, filter_amount: float = None, vel_to_filter: float = None, saturation: float = None, tremolo_depth: float = None, tremolo_rate: float = None, phaser: float = None, phaser_rate: float = None, cabinet: float = None, cabinet_brightness: float = None, analog: float = None, ensemble: int = None, fm_ratio: float = None, fm_index: float = None, fretboard=None) Part[source]¶
Create a named part with its own synth voice and effects.
- Parameters:
name – Part name (e.g.
"lead","bass","pads").instrument – Instrument preset name (e.g.
"piano","violin","808_bass"). SeeINSTRUMENTSfor the full list. When set, the preset’s synth, envelope, and effects are used as defaults; any explicit keyword argument still overrides the preset value.synth – Waveform —
"sine","saw","triangle","square","pulse","fm","noise","supersaw","pwm_slow","pwm_fast".envelope – ADSR preset name —
"piano","pluck","pad","organ","bell","strings","staccato", or"none".volume – Mix level from 0.0 to 1.0 (default 0.5).
reverb – Reverb wet/dry mix, 0.0–1.0 (default 0, off).
reverb_decay – Reverb tail length in seconds (default 1.0).
reverb_type – Reverb algorithm —
"algorithmic"(Schroeder, default) or a convolution IR preset:"taj_mahal","cathedral","plate","spring","cave","parking_garage","canyon".delay – Delay wet/dry mix, 0.0–1.0 (default 0, off).
delay_time – Delay time in seconds (default 0.375, dotted 8th).
delay_feedback – Delay feedback 0.0–1.0 (default 0.4).
lowpass – Lowpass filter cutoff in Hz (default 0, off). Try 800 for muffled bass, 2000 for warm lead, 5000 for subtle brightness rolloff.
lowpass_q – Filter resonance/Q factor (default 0.707, flat). Higher values add a resonant peak at the cutoff — 1.0 = slight peak, 2.0 = pronounced, 5.0+ = aggressive.
distortion – Distortion wet/dry mix, 0.0–1.0 (default 0, off).
distortion_drive – Gain before soft clipping (default 3.0). 0.5–2 = subtle warmth, 3–8 = overdrive, 10+ = fuzz.
legato – If True, notes share a continuous waveform instead of retriggering the envelope on each note (default False).
glide – Portamento time in seconds between consecutive pitches (default 0, instant). 0.03–0.05 = quick 303 slide, 0.1–0.2 = slow glide.
humanize – Random timing and velocity variation, 0.0–1.0 (default 0, off). Adds micro-imperfections that make programmed parts feel like a real player. 0.1 = subtle, 0.3 = natural, 0.5+ = loose/drunk.
sidechain – Sidechain compression amount, 0.0–1.0 (default 0, off). How much the drum hits duck this part’s volume. 0.8 = typical EDM pumping effect.
sidechain_release – How fast the volume comes back after ducking, in seconds (default 0.1).
- Returns:
A
Partobject. Add notes with.add()and.rest().
Example:
lead = score.part("lead", synth="saw", envelope="pluck", reverb=0.3, delay=0.25, lowpass=3000) # Or use an instrument preset: piano = score.part("keys", instrument="piano")
- classmethod list_instruments() list[source]¶
Return a sorted list of available instrument preset names.
Example:
Score.list_instruments() # ['808_bass', 'acid_bass', 'acoustic_guitar', ...]
- add_pattern(pattern, repeats: int = 1) Score[source]¶
Add a drum pattern to this score.
- Parameters:
pattern – A
Patternobject.repeats – Number of times to repeat.
- Returns:
Self for chaining.
- fill(name: str = 'rock') Score[source]¶
Insert a 1-bar drum fill at the current position.
Replaces what would be the next bar of drums with a genre-appropriate fill.
- drums(preset: str, repeats: int = 4, fill: str = None, fill_every: int = None, split: bool = False) Score[source]¶
Add a drum pattern by preset name, with optional auto-fills.
- Parameters:
preset – Pattern preset name (e.g.
"bossa nova","rock").repeats – Number of times to repeat (default 4).
fill – Optional fill name.
fill_every – Replace every Nth bar with a fill.
split – If True, create separate Parts for kick, snare, hats, toms, cymbals, and percussion — each with independent effects. Access via
score.parts["kick"], etc.
- Returns:
Self for chaining.
Example:
>>> score.drums("rock", repeats=4, split=True) >>> score.parts["snare"].reverb_mix = 0.3 >>> score.parts["hats"].lowpass = 6000
- add(tone_or_chord, duration=Duration.QUARTER) Score[source]¶
Add a note to the default (unnamed) part.
For simple scores without named parts. Returns self for chaining.
- rest(duration=Duration.QUARTER) Score[source]¶
Add a rest to the default part. Returns self for chaining.
- set_tempo(bpm: int) Score[source]¶
Insert a tempo change at the current beat position.
The new tempo takes effect from the current total_beats position and remains until the next tempo change.
- Parameters:
bpm – New tempo in beats per minute.
- Returns:
Self for chaining.
- section(name: str) Section[source]¶
Begin a named section. Everything added after this call until the next section() or end_section() belongs to this section.
Example:
score.section("verse") chords.add(chord, Duration.WHOLE) lead.add("C5", Duration.QUARTER) score.section("chorus") chords.add(chord, Duration.WHOLE) score.repeat("verse") score.repeat("chorus", times=2)
- repeat(name: str, times: int = 1) Score[source]¶
Repeat a previously defined section.
Copies all notes, drum hits, and automation from the named section and appends them at the current position.
- Parameters:
name – Name of a section defined with
section().times – Number of times to repeat (default 1).
- Returns:
Self for chaining.
- to_abc(*, title='Untitled', key='C', html=False)[source]¶
Export the score as ABC notation.
- Parameters:
title – Tune title for the
T:field.key – Key signature (e.g.
"C","Gm","D") for theK:field.html – If True, wrap the ABC string in a self-contained HTML page that renders sheet music via abcjs.
- Returns:
An ABC notation string, or a full HTML document string when html is True.
- to_lilypond(*, title='Untitled', key='C', mode='major')[source]¶
Export the score as a LilyPond source string.
- Parameters:
title – Title for the
\headerblock.key – Key signature root (e.g.
"C","D","Bb").mode – LilyPond mode string (
"major","minor", etc.).
- Returns:
A complete LilyPond source string.
- to_musicxml(*, title='Untitled')[source]¶
Export the score as a MusicXML string.
- Parameters:
title – Work title embedded in the
<work-title>element.- Returns:
A MusicXML 4.0 partwise document as a pretty-printed XML string.
- to_tab(part_name=None, **kwargs)[source]¶
Generate ASCII tablature for a part in this score.
- Parameters:
part_name – Name of the part to tab. If None, tabs the first non-drum part that has notes.
**kwargs – Passed through to
Part.to_tab()(e.g.tuning,frets,time_signature).
- Returns:
An ASCII tablature string.
- Raises:
ValueError – If no suitable part is found.
- classmethod from_wav(path, *, bpm=None, quantize=None, split=False, part_name='melody', synth='piano_synth', fmin=50.0, fmax=1500.0) Score[source]¶
Transcribe an audio recording into a Score.
Hum a melody, whistle a hook, record a bass line — load the recording and get editable notes back. Pitch tracking is the YIN algorithm; transcription is monophonic per pass (voice, whistle, a single instrument line), not chords.
Reads WAV directly; .m4a voice memos, .mp3, and anything else convert automatically through afconvert (macOS) or ffmpeg.
- Parameters:
path – Path to an audio file.
bpm – Tempo to interpret the timing against. Default
Noneestimates it from the recording’s onset pattern (falling back to 120 for pulse-free rubato).quantize – Optional grid in beats —
0.25snaps starts and durations to sixteenths. Default keeps the timing as performed.split – If True, separate harmonics from drums first and transcribe a
"bass"part and a"melody"part. For full mixes — the bassline comes out well; the melody only as well as it dominates the mix.part_name – Name of the created part (default “melody”).
synth – Playback synth for the transcription.
fmin/fmax – Pitch search range in Hz. Tighten for better results (e.g.
fmin=60, fmax=350for bass).
- Returns:
A Score of detected notes, rests, and velocities, with
score.bpmset to the estimated (or given) tempo.
Example:
>>> score = Score.from_wav("hum.m4a", quantize=0.25) >>> print(score.to_abc(title="My Hum")) >>> score.save_midi("hum.mid")
- classmethod from_midi(path, synth='sine', envelope='pluck') Score[source]¶
Import a Standard MIDI File into a Score.
Reads notes, tempo, and time signature from any Type 0 or Type 1 MIDI file. Each MIDI channel becomes a named Part. Channel 10 (drums) becomes drum hits.
- Parameters:
path – Path to a .mid file.
synth – Default synth for all parts (default “sine”).
envelope – Default envelope for all parts (default “pluck”).
- Returns:
A Score with Parts populated from the MIDI data.
Example:
>>> score = Score.from_midi("song.mid") >>> score.parts["ch1"].synth = "saw" >>> score.parts["ch1"].reverb_mix = 0.3