mirror of
https://github.com/kennethreitz/pytheory.git
synced 2026-07-21 18:19:30 +00:00
33b0636cc4
A full freshness + quality pass across the documentation, with every code example verified by actually running it against v0.57.8. Content / accuracy: - Fixed stale and broken examples throughout: SymPy-based "symbolic pitch" (SymPy was removed), the case-sensitive progression parser (I/V/vi/IV vs i/iv), analog_drift -> analog, Key.relative/parallel returning Key objects, Tone.from_string validation needing a system, stale tab()/scale_diagram() output, and many counts (74 drum sounds, 100 patterns, 37 fills, 19 chord types, 16 systems, 25 fretboard instruments, 56 waveforms, 83 presets). - Documented major recent features that were missing: Maqam (quarter-tone Arabic maqamat) and Raga (Hindustani + Carnatic, shruti just intonation) in the systems guide and the CLI; SVG/PNG diagram export; progression / cadence / secondary-dominant analysis and reharmonization; notation export to LilyPond/MusicXML/ABC incl. lyrics; from_wav transcription; render_scores batch rendering; CLI raga/maqam and `analyze song.mid`. Navigation / presentation: - Added sphinx-design + sphinx-copybutton to the docs deps and conf. - Rebuilt the homepage "Why would I want this?" into a sphinx-design persona card grid with CTA buttons and a badge row; wired the brand logo into the sidebar (and suppressed the now-redundant project-name text). - Added API-reference pages for the public Raga and Maqam classes. Also: removed a duplicate `jati` attribute line from the Raga docstring so autodoc no longer double-documents it. Sphinx build is clean (0 warnings).
816 lines
29 KiB
ReStructuredText
816 lines
29 KiB
ReStructuredText
Drums
|
|
=====
|
|
|
|
Drums are the foundation of almost everything. Change the drum pattern
|
|
and you change the genre. The same four chords over a bossa nova
|
|
pattern sound like you're in a cafe in Rio. Put those same chords over
|
|
a rock beat and you're in a garage in Seattle. Over a trap beat, you're
|
|
in Atlanta. Over a dancehall pattern, you're in Kingston. The drums ARE
|
|
the genre -- they tell the listener's body how to move before a single
|
|
melodic note is played.
|
|
|
|
PyTheory includes a complete drum system -- 74 synthesized percussion
|
|
sounds, 100 pattern presets across dozens of genres, and 37 fill presets.
|
|
Every sound is generated from waveforms; no samples needed.
|
|
|
|
Drum Sounds
|
|
-----------
|
|
|
|
Drum hits are **humanized by default** — each hit gets a tiny random
|
|
timing offset and velocity wobble, just like a real drummer who's never
|
|
perfectly on the grid. Control the amount with ``drum_humanize`` on the
|
|
Score:
|
|
|
|
.. code-block:: python
|
|
|
|
score = Score("4/4", bpm=120, drum_humanize=0.4) # natural feel
|
|
score = Score("4/4", bpm=120, drum_humanize=0.0) # perfectly quantized
|
|
score = Score("4/4", bpm=120, drum_humanize=0.1) # studio tight
|
|
|
|
The default is 0.15 — just enough to feel alive without sounding loose.
|
|
|
|
Drums Are Parts
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
Drums are a real Part — the same as any melodic voice. You can set
|
|
effects on them the same way:
|
|
|
|
.. code-block:: python
|
|
|
|
score.drums("rock", repeats=4)
|
|
score.parts["drums"].reverb_mix = 0.2
|
|
score.parts["drums"].reverb_type = "plate"
|
|
|
|
Or use the shorthand:
|
|
|
|
.. code-block:: python
|
|
|
|
score.set_drum_effects(reverb=0.2, reverb_type="plate", lowpass=8000)
|
|
|
|
Every effect a melodic voice supports works on drums too -- see
|
|
:doc:`effects` for the full set of reverb types, delays, and filters,
|
|
and :doc:`sequencing` for everything else a Part can do.
|
|
|
|
Split Drums
|
|
~~~~~~~~~~~
|
|
|
|
For maximum control, split the kit into separate Parts — kick, snare,
|
|
hats, toms, cymbals, and percussion — each with independent effects:
|
|
|
|
.. code-block:: python
|
|
|
|
score.drums("rock", repeats=4, split=True)
|
|
|
|
# Now each group is its own Part
|
|
score.parts["snare"].reverb_mix = 0.3
|
|
score.parts["snare"].reverb_type = "plate"
|
|
score.parts["hats"].lowpass = 7000
|
|
score.parts["kick"] # dry, no effects
|
|
|
|
# set_drum_effects still works — applies to all drum Parts
|
|
score.set_drum_effects(reverb=0.1)
|
|
|
|
This is how real studios work — the snare gets its own reverb send,
|
|
the hats get their own EQ, the kick stays dry and punchy. Now you
|
|
can do the same thing in Python.
|
|
|
|
Sidechain compression triggers on kick hits only — hi-hats and snares
|
|
don't duck the pad.
|
|
|
|
Every drum sound is stereo-panned like a real kit — kick and snare
|
|
center, hi-hat right, crash left, toms spread across the field,
|
|
percussion instruments placed naturally. Put on headphones and you'll
|
|
hear the kit in front of you.
|
|
|
|
The ``DrumSound`` enum maps to General MIDI percussion note numbers:
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> from pytheory import DrumSound
|
|
|
|
>>> DrumSound.KICK.value
|
|
36
|
|
>>> DrumSound.SNARE.value
|
|
38
|
|
>>> DrumSound.CLOSED_HAT.value
|
|
42
|
|
|
|
All 74 sounds, organized by type:
|
|
|
|
**Kicks:** KICK (36)
|
|
|
|
**Snares:** SNARE (38), RIMSHOT (37), CLAP (39)
|
|
|
|
**Hi-hats:** CLOSED_HAT (42), OPEN_HAT (46), PEDAL_HAT (44)
|
|
|
|
**Toms:** LOW_TOM (45), MID_TOM (47), HIGH_TOM (50)
|
|
|
|
**Cymbals:** CRASH (49), RIDE (51), RIDE_BELL (53)
|
|
|
|
**Percussion:** COWBELL (56), CLAVE (75), SHAKER (70, also MARACAS),
|
|
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)
|
|
|
|
**Tabla:** TABLA_NA (86), TABLA_TIN (87), TABLA_GE (88), TABLA_DHA (89),
|
|
TABLA_TIT (90), TABLA_KE (91), TABLA_GE_BEND (108 -- bayan with upward
|
|
pitch bend from palm pressing into the head)
|
|
|
|
**Dhol:** DHOL_DAGGA (92), DHOL_TILLI (93), DHOL_BOTH (94)
|
|
|
|
**Dholak:** DHOLAK_GE (95), DHOLAK_NA (96), DHOLAK_TIT (97)
|
|
|
|
**Mridangam:** MRIDANGAM_THAM (98), MRIDANGAM_NAM (99), MRIDANGAM_DIN (100),
|
|
MRIDANGAM_THA (101)
|
|
|
|
**Djembe:** DJEMBE_BASS (102), DJEMBE_TONE (103), DJEMBE_SLAP (104)
|
|
|
|
**Doumbek:** DOUMBEK_DUM (112), DOUMBEK_TEK (113), DOUMBEK_KA (114)
|
|
|
|
**Cajón:** CAJON_BASS (108, shares its note with the tabla bayan-bend),
|
|
CAJON_SLAP (109), CAJON_TAP (110), CAJON_SLAP_SNARE (111)
|
|
|
|
**Metal Kit:** METAL_KICK (105), METAL_SNARE (106), METAL_HAT (107)
|
|
|
|
**Marching Snare:** MARCH_SNARE (115), MARCH_RIMSHOT (116), MARCH_CLICK (118)
|
|
|
|
**Quads (Tenors):** QUAD_1 (119), QUAD_2 (120), QUAD_3 (121), QUAD_4 (122),
|
|
QUAD_SPOCK (123)
|
|
|
|
**Marching Bass:** BASS_1 (124), BASS_2 (125), BASS_3 (126), BASS_4 (127),
|
|
BASS_5 (80)
|
|
|
|
**Texture / Hand:** RAINSTICK (81), RAINSTICK_SLOW (128), OCEAN_DRUM (82),
|
|
CABASA (83), WIND_CHIMES (84), FINGER_CYMBAL (85)
|
|
|
|
Drum Synthesis
|
|
--------------
|
|
|
|
Every drum sound here is synthesized from scratch using the same
|
|
techniques that real drum machines use. This isn't a shortcut -- it's
|
|
the real thing. The 808 kick that defined hip hop is literally a sine
|
|
wave with a pitch envelope sweeping from 150 Hz down to 50 Hz. The 909
|
|
snare that powered techno is a sine wave body mixed with white noise
|
|
rattle. The hi-hat is just filtered noise with a short decay. When
|
|
Roland built the TR-808 and TR-909, they weren't sampling real drums;
|
|
they were synthesizing them from basic waveforms. PyTheory does the
|
|
same thing.
|
|
|
|
Each sound has a dedicated synthesizer:
|
|
|
|
- **KICK** -- sine wave with pitch envelope sweep (150 to 50 Hz) + sub click
|
|
- **SNARE** -- pitched body (180 Hz) + white noise rattle
|
|
- **CLOSED_HAT** -- high-frequency noise, 50ms decay
|
|
- **OPEN_HAT** -- high-frequency noise, 250ms decay
|
|
- **CLAP** -- layered noise bursts with spacers
|
|
- **RIMSHOT** -- bright 800 Hz click + noise
|
|
- **TOMS** -- pitched sine with sweep (low=100, mid=150, high=200 Hz)
|
|
- **CRASH** -- long noise decay (1.5s)
|
|
- **RIDE** -- metallic ring (3500+5100 Hz) + noise
|
|
- **RIDE_BELL** -- brighter ring, more sustain
|
|
- **COWBELL** -- two detuned tones (545+815 Hz)
|
|
- **CLAVE** -- short 2500 Hz click
|
|
- **CONGAS/BONGOS** -- pitched membrane with slap transient
|
|
- **TIMBALES** -- bright metallic ring with overtones
|
|
- **AGOGO** -- pitched bell with harmonics
|
|
- **SHAKER/MARACAS** -- short noise burst
|
|
- **TAMBOURINE** -- noise + 7000 Hz jingle ring
|
|
- **GUIRO** -- scraped noise bursts
|
|
|
|
Pattern Presets
|
|
---------------
|
|
|
|
100 patterns spanning genres from rock to Afro-Cuban to electronic to
|
|
world percussion. Load them with ``Pattern.preset()``:
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> from pytheory import Pattern
|
|
|
|
>>> len(Pattern.list_presets())
|
|
100
|
|
>>> Pattern.list_presets()[:6]
|
|
['12/8 blues', '6/8 afro-cuban', 'adi talam', 'afrobeat', 'ayoub', 'baiao']
|
|
|
|
>>> rock = Pattern.preset("rock")
|
|
>>> rock
|
|
<Pattern 'rock' 4/4 4.0 beats 12 hits>
|
|
|
|
**Rock/Pop:** rock, half time, double time, disco, motown, train beat
|
|
-- The backbone of Western popular music. Kick on 1 and 3, snare on 2
|
|
and 4. Simple, effective, universal.
|
|
|
|
**Jazz:** jazz, bebop, shuffle, swing, linear, paradiddle -- The ride
|
|
cymbal drives everything. The kick and snare comp and converse rather
|
|
than keeping strict time. These patterns swing.
|
|
|
|
**Latin:** salsa, bossa nova, samba, cumbia, merengue, baiao, maracatu,
|
|
bolero, tango -- Rich, layered patterns built on clave rhythms, with
|
|
congas, timbales, and shakers creating interlocking polyrhythmic webs.
|
|
Some of the most sophisticated drumming traditions on the planet.
|
|
|
|
**Afro-Cuban:** son clave 3-2, son clave 2-3, rumba clave 3-2,
|
|
rumba clave 2-3, cascara, guaguanco, mozambique, nanigo, bembe,
|
|
6/8 afro-cuban, tresillo, habanera -- The clave is the key that
|
|
unlocks all Latin and Afro-Cuban music. It's a five-note rhythmic
|
|
cell that everything else revolves around. If you learn one concept
|
|
from world music, learn the clave.
|
|
|
|
**African:** afrobeat, highlife -- Born in West Africa. Fela Kuti's
|
|
afrobeat layers multiple percussion voices into hypnotic,
|
|
polyrhythmic grooves that can go on for twenty minutes.
|
|
|
|
**Caribbean:** reggae, dancehall, ska, dub -- The offbeat is king.
|
|
Reggae flips rock drumming inside out by emphasizing the "and" of each
|
|
beat instead of the beat itself. Ska doubles the tempo, dancehall
|
|
adds syncopation.
|
|
|
|
**Electronic:** house, techno, trap, drum and bass, breakbeat, jungle
|
|
-- Machine music. The four-on-the-floor kick of house and techno, the
|
|
rattling hi-hats of trap, the breakneck tempo of drum and bass. These
|
|
patterns were born in drum machines and they still live there.
|
|
|
|
**Metal/Punk:** metal, blast beat, punk, double kick, metal blast,
|
|
metal groove, metal gallop -- Speed and aggression. The blast beat is
|
|
both feet and both hands going as fast as humanly possible. Punk strips
|
|
everything to its essentials. The metal kit adds 3 dedicated sounds
|
|
(double kick, china cymbal, stack) and 4 patterns for extreme metal
|
|
subgenres.
|
|
|
|
**World Percussion:** tabla, dhol, dholak, mridangam, djembe, cajón --
|
|
Deep traditions from across the globe, each with authentic sound sets and
|
|
idiomatic patterns. See the World Percussion section below for details.
|
|
|
|
**Other:** funk, hip hop, bo diddley, second line, new orleans, waltz,
|
|
12/8 blues, country, gospel, flamenco -- Everything else. The syncopated
|
|
groove of funk, the sampled feel of hip hop, the street-parade swing
|
|
of New Orleans second line.
|
|
|
|
Playing Patterns
|
|
----------------
|
|
|
|
``play_pattern()`` synthesizes every drum sound in real-time:
|
|
|
|
.. code-block:: python
|
|
|
|
from pytheory import Pattern, play_pattern
|
|
|
|
play_pattern(Pattern.preset("rock"), repeats=4, bpm=120)
|
|
play_pattern(Pattern.preset("bossa nova"), repeats=4, bpm=140)
|
|
play_pattern(Pattern.preset("salsa"), repeats=4, bpm=180)
|
|
play_pattern(Pattern.preset("afrobeat"), repeats=8, bpm=110)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.3em 0 0.5em"><source src="../_static/audio/rock_beat.wav" type="audio/wav"></audio>
|
|
<audio controls style="width:100%;margin:0.3em 0 0.5em"><source src="../_static/audio/bossa_nova_pattern.wav" type="audio/wav"></audio>
|
|
<audio controls style="width:100%;margin:0.3em 0 0.5em"><source src="../_static/audio/salsa_pattern.wav" type="audio/wav"></audio>
|
|
<audio controls style="width:100%;margin:0.3em 0 1.5em"><source src="../_static/audio/afrobeat_pattern.wav" type="audio/wav"></audio>
|
|
|
|
Fills
|
|
-----
|
|
|
|
A fill is the drummer's way of saying "something's about to change."
|
|
It's that moment at the end of a verse where the drummer breaks the
|
|
pattern and rolls around the toms before crashing into the chorus. Fills
|
|
signal transitions -- they tell the listener's ear that the section is
|
|
ending and a new one is about to begin. Without fills, a drum pattern
|
|
just loops. With them, it breathes and has structure.
|
|
|
|
``Pattern.fill()`` loads a 1-bar drum fill -- a short break that
|
|
transitions between sections. 37 fill presets are available:
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> len(Pattern.list_fills())
|
|
37
|
|
>>> Pattern.list_fills()
|
|
['afrobeat', 'bayan', 'blast', 'bossa nova', 'breakdown', 'buildup',
|
|
'cajon breakdown', 'cajon flam', 'cajon rumble', 'chakkardar',
|
|
'cumbia', 'disco', 'djembe break', 'djembe call', 'djembe roll',
|
|
'doumbek accent', 'doumbek roll', 'funk', 'highlife', 'hip hop',
|
|
'house', 'jazz', 'jazz brush', 'metal', 'metal blast',
|
|
'metal cascade', 'metal triplet', 'reggae', 'rock', 'rock crash',
|
|
'salsa', 'samba', 'second line', 'tabla call', 'tihai',
|
|
'tiri kita', 'trap']
|
|
|
|
>>> fill = Pattern.fill("rock")
|
|
>>> fill
|
|
<Pattern 'rock fill' 4/4 4.0 beats 8 hits>
|
|
|
|
Score Integration
|
|
-----------------
|
|
|
|
The ``score.drums()`` shorthand attaches a drum pattern to a score:
|
|
|
|
.. code-block:: python
|
|
|
|
from pytheory import Score
|
|
|
|
score = Score("4/4", bpm=140)
|
|
score.drums("bossa nova", repeats=4)
|
|
|
|
Auto-Fills
|
|
~~~~~~~~~~
|
|
|
|
The ``fill`` and ``fill_every`` parameters automatically insert drum
|
|
fills at regular intervals:
|
|
|
|
.. code-block:: python
|
|
|
|
score = Score("4/4", bpm=120)
|
|
score.drums("rock", repeats=8, fill="rock", fill_every=4)
|
|
|
|
This plays the rock pattern for 8 bars, replacing every 4th bar with
|
|
a rock fill. Useful for adding natural phrasing to longer sections.
|
|
|
|
.. code-block:: python
|
|
|
|
# Jazz with brush fills every 8 bars
|
|
score.drums("bebop", repeats=16, fill="jazz brush", fill_every=8)
|
|
|
|
# Salsa with fills every 4 bars
|
|
score.drums("salsa", repeats=8, fill="salsa", fill_every=4)
|
|
|
|
Layering Patterns
|
|
-----------------
|
|
|
|
Combine drum patterns with melodic parts for full arrangements. The
|
|
drum pattern and all named parts are mixed together by ``play_score()``
|
|
(see :doc:`playback`):
|
|
|
|
.. code-block:: python
|
|
|
|
from pytheory import Score, Key, Duration, play_score
|
|
|
|
score = Score("4/4", bpm=180)
|
|
score.drums("salsa", repeats=4, fill="salsa", fill_every=4)
|
|
|
|
pads = score.part("pads", synth="sine", envelope="pad", volume=0.3)
|
|
lead = score.part("lead", synth="saw", envelope="pluck", volume=0.4)
|
|
bass = score.part("bass", synth="sine", envelope="pluck", volume=0.45)
|
|
|
|
for chord in Key("D", "minor").progression("ii", "V", "i", "i") * 2:
|
|
pads.add(chord, Duration.WHOLE)
|
|
|
|
lead.add("A5", 0.67).add("G5", 0.33).add("F5", 0.67).add("E5", 0.33)
|
|
|
|
for n in ["D2", "A2", "D2", "F2"] * 2:
|
|
bass.add(n, Duration.QUARTER)
|
|
|
|
play_score(score)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.5em 0 1.5em"><source src="../_static/audio/salsa_layered.wav" type="audio/wav"></audio>
|
|
|
|
World Percussion
|
|
----------------
|
|
|
|
PyTheory includes dedicated sound sets and pattern presets for
|
|
traditional percussion instruments from around the world. Each
|
|
instrument has its own synthesized sounds that capture the timbral
|
|
character of the real instrument, plus idiomatic rhythmic patterns
|
|
drawn from their musical traditions.
|
|
|
|
Tabla
|
|
~~~~~
|
|
|
|
The tabla is a pair of hand drums from the Indian subcontinent -- the
|
|
smaller, higher-pitched *dayan* and the larger, bass *bayan*. It is
|
|
the rhythmic backbone of Hindustani classical music, and one of the
|
|
most expressive percussion instruments ever created. A single tabla
|
|
player can produce an astonishing range of tones by varying finger
|
|
placement, pressure, and striking technique.
|
|
|
|
**7 sounds** -- the primary tabla strokes (na, tin, ge, dha, tit, ke)
|
|
plus a bayan pitch-bend sound (TABLA_GE_BEND) that models the technique
|
|
of pressing the palm into the bayan head to bend the pitch upward.
|
|
|
|
**8 patterns:** teental (16 beats, the most common taal), jhaptaal
|
|
(10 beats), rupak (7 beats), dadra (6 beats), keherwa (8 beats, folk
|
|
and light classical), tabla solo, tiri kita (fast ornamental pattern),
|
|
and chakradar (a 16-beat composed cadence).
|
|
|
|
**5 fills:** tihai (3x crescendo landing on sam), chakkardar (32nd
|
|
triplet cascade into slam), tiri kita (rapid 16th-note dayan burst),
|
|
bayan (deep bass bends showcase), tabla call (dayan/bayan call-and-response).
|
|
|
|
.. code-block:: python
|
|
|
|
score.drums("teental", repeats=4, fill="tihai")
|
|
score.drums("keherwa", repeats=4, fill="chakkardar")
|
|
|
|
.. code-block:: python
|
|
|
|
score = Score("4/4", bpm=80)
|
|
score.drums("teental", repeats=4)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.3em 0 0.5em"><source src="../_static/audio/tabla_teental.wav" type="audio/wav"></audio>
|
|
<audio controls style="width:100%;margin:0.3em 0 0.5em"><source src="../_static/audio/tabla_keherwa.wav" type="audio/wav"></audio>
|
|
<audio controls style="width:100%;margin:0.3em 0 1.5em"><source src="../_static/audio/tabla_chakradar.wav" type="audio/wav"></audio>
|
|
|
|
Dhol
|
|
~~~~
|
|
|
|
The dhol is a double-headed barrel drum from Punjab, played with
|
|
sticks. It is the driving force behind bhangra music -- loud,
|
|
energetic, and physically impossible to sit still to.
|
|
|
|
**3 sounds** -- bass stroke, treble stroke, and rimshot.
|
|
|
|
**2 patterns:** bhangra (the classic bhangra groove) and dhol chaal
|
|
(a processional rhythm).
|
|
|
|
.. code-block:: python
|
|
|
|
score = Score("4/4", bpm=160)
|
|
score.drums("bhangra", repeats=4)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.5em 0 1.5em"><source src="../_static/audio/dhol.wav" type="audio/wav"></audio>
|
|
|
|
Dholak
|
|
~~~~~~
|
|
|
|
The dholak is a smaller, lighter two-headed drum used across South
|
|
Asia in folk music, qawwali, and Bollywood. Played with bare hands,
|
|
it produces a warm, melodic tone.
|
|
|
|
**3 sounds** -- bass, treble, and slap.
|
|
|
|
**2 patterns:** qawwali (the rhythmic foundation of Sufi devotional
|
|
music) and dholak folk (a general folk groove).
|
|
|
|
.. code-block:: python
|
|
|
|
score = Score("4/4", bpm=120)
|
|
score.drums("qawwali", repeats=4)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.5em 0 1.5em"><source src="../_static/audio/dholak.wav" type="audio/wav"></audio>
|
|
|
|
Mridangam
|
|
~~~~~~~~~
|
|
|
|
The mridangam is a double-headed drum from South India, the
|
|
rhythmic anchor of Carnatic classical music. Its tuning system is
|
|
extraordinarily precise, and its rhythmic vocabulary is among the
|
|
most mathematically complex in the world.
|
|
|
|
**4 sounds** -- tha, thom, nam, and din.
|
|
|
|
**2 patterns:** adi talam (the most common Carnatic talam, 8 beats)
|
|
and mridangam korvai (a rhythmic cadence pattern).
|
|
|
|
.. code-block:: python
|
|
|
|
score = Score("4/4", bpm=90)
|
|
score.drums("adi talam", repeats=4)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.5em 0 1.5em"><source src="../_static/audio/mridangam.wav" type="audio/wav"></audio>
|
|
|
|
Djembe
|
|
~~~~~~
|
|
|
|
The djembe is a rope-tuned goblet drum from West Africa, capable of
|
|
producing a wide range of tones from deep bass to sharp slaps. It is
|
|
central to the drum ensemble traditions of Mali, Guinea, and Senegal.
|
|
|
|
**3 sounds** -- bass (open center strike), tone (edge strike), and
|
|
slap (sharp edge strike).
|
|
|
|
**8 patterns:** djembe (basic accompanying rhythm), kuku (Guinean harvest
|
|
dance), soli (powerful Mandinka rhythm), dununba (heavy bass-driven),
|
|
tiriba (joyful Susu rhythm), yankadi (gentle greeting/welcome), djansa
|
|
(fast Malinke dance), mendiani (women's celebratory dance).
|
|
|
|
**3 fills:** djembe call (bass-tone-slap conversation building to climax),
|
|
djembe roll (rapid slaps accelerating into bass), djembe break (syncopated
|
|
West African-style break).
|
|
|
|
.. code-block:: python
|
|
|
|
score = Score("4/4", bpm=120)
|
|
score.drums("djembe", repeats=8, fill="djembe call", fill_every=4)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.5em 0 1.5em"><source src="../_static/audio/djembe.wav" type="audio/wav"></audio>
|
|
|
|
Metal Kit
|
|
~~~~~~~~~
|
|
|
|
A dedicated percussion kit for extreme metal subgenres, with
|
|
specialized sounds and patterns that go beyond the standard drum kit.
|
|
|
|
**3 sounds** -- double kick (triggered, tight attack), china cymbal,
|
|
and stack (a short, trashy cymbal choke).
|
|
|
|
**4 patterns:** double kick (relentless double bass drum pattern),
|
|
metal blast (blast beat with china cymbal accents), metal groove (a
|
|
half-time groove with double kick fills), and metal gallop (the
|
|
classic triplet-feel gallop rhythm).
|
|
|
|
**4 fills:** metal (double kick 16ths with descending toms), metal triplet
|
|
(double kick triplets with snare accents), metal blast (alternating
|
|
snare/kick 32nds into half-time crash), metal cascade (descending snare
|
|
roll → kick roll → alternating → crash ending).
|
|
|
|
.. code-block:: python
|
|
|
|
score = Score("4/4", bpm=200)
|
|
score.drums("metal blast", repeats=8, fill="metal cascade", fill_every=4)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.5em 0 1.5em"><source src="../_static/audio/metal_blast.wav" type="audio/wav"></audio>
|
|
|
|
Cajón
|
|
~~~~~
|
|
|
|
The cajón is a box-shaped percussion instrument from Peru, now
|
|
ubiquitous in acoustic and unplugged settings worldwide. Players sit
|
|
on the box and strike the front face with their hands.
|
|
|
|
**4 sounds** -- bass (deep center thump), slap (sharp wood crack on the
|
|
top edge, no snare wires), tap (light finger tap), and CAJON_SLAP_SNARE
|
|
-- the same edge slap with the internal snare wires engaged for an
|
|
extra buzz.
|
|
|
|
**3 patterns:** cajon (basic groove), cajon rumba (flamenco-style rumba),
|
|
and cajon folk (folk/acoustic pattern).
|
|
|
|
**3 fills:** cajon flam (slaps accelerating into bass hits), cajon rumble
|
|
(fast taps building to slap accents), cajon breakdown (syncopated
|
|
bass-slap groove).
|
|
|
|
.. code-block:: python
|
|
|
|
score = Score("4/4", bpm=100)
|
|
score.drums("cajon", repeats=8, fill="cajon flam", fill_every=4)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.5em 0 1.5em"><source src="../_static/audio/cajon.wav" type="audio/wav"></audio>
|
|
|
|
Doumbek (Darbuka)
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
The doumbek -- also called the darbuka -- is a goblet-shaped hand drum
|
|
heard across the Middle East and North Africa. A crisp, ringing *tek*
|
|
on the rim played against a deep *dum* in the center gives it the
|
|
snappy, conversational voice at the heart of Arabic and belly-dance
|
|
rhythm.
|
|
|
|
**3 sounds** -- dum (deep center bass), tek (sharp ringing rim hit),
|
|
and ka (muted edge slap, often the left hand answering a right-hand
|
|
tek).
|
|
|
|
**4 patterns:** maqsoum (the most common Arabic rhythm), baladi (heavy
|
|
and earthy, the belly-dance staple), saidi (Upper Egyptian, strong and
|
|
driving), and ayoub (a hypnotic 2/4 trance groove).
|
|
|
|
**2 fills:** doumbek roll (rapid teks building into a dum) and doumbek
|
|
accent (a syncopated dum-tek-ka flourish).
|
|
|
|
.. code-block:: python
|
|
|
|
score = Score("4/4", bpm=100)
|
|
score.drums("maqsoum", repeats=8, fill="doumbek accent", fill_every=4)
|
|
|
|
Texture and Hand Percussion
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Atmosphere makers — long washes and small metallic accents you
|
|
sprinkle over a groove rather than build one from.
|
|
|
|
**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) # fast cascade
|
|
p.hit(DrumSound.RAINSTICK_SLOW, Duration.WHOLE * 4) # gentle trickle
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.3em 0 0.5em"><source src="../_static/audio/rainstick.wav" type="audio/wav"></audio>
|
|
<audio controls style="width:100%;margin:0.3em 0 0.5em"><source src="../_static/audio/rainstick_slow.wav" type="audio/wav"></audio>
|
|
|
|
**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
|
|
|
|
<audio controls style="width:100%;margin:0.3em 0 0.5em"><source src="../_static/audio/ocean_drum.wav" type="audio/wav"></audio>
|
|
|
|
**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
|
|
|
|
<audio controls style="width:100%;margin:0.3em 0 0.5em"><source src="../_static/audio/cabasa.wav" type="audio/wav"></audio>
|
|
|
|
**Wind chimes** — suspended metal tubes struck by hand or breeze, each
|
|
ringing at its own pitch with slight time offsets:
|
|
|
|
.. code-block:: python
|
|
|
|
p.hit(DrumSound.WIND_CHIMES, Duration.WHOLE * 3)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.3em 0 0.5em"><source src="../_static/audio/wind_chimes.wav" type="audio/wav"></audio>
|
|
|
|
**Finger cymbal** — a single small cymbal tap (zill), a bright
|
|
metallic ping:
|
|
|
|
.. code-block:: python
|
|
|
|
p.hit(DrumSound.FINGER_CYMBAL, Duration.HALF)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.3em 0 0.5em"><source src="../_static/audio/finger_cymbal.wav" type="audio/wav"></audio>
|
|
|
|
Marching Percussion
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
A full drumline — snare, quads (tenors), and pitched bass drums.
|
|
Every sound is synthesized: kevlar snare heads, aluminum shell ting
|
|
on the quads, felt-beater thwack on the basses.
|
|
|
|
**Snare** -- 3 sounds: MARCH_SNARE (tight kevlar tap), MARCH_RIMSHOT
|
|
(woody-metallic crack), MARCH_CLICK (stick click for count-offs).
|
|
|
|
**Quads** -- 5 sounds: QUAD_1 through QUAD_4 (high to low pitched
|
|
tenors) plus QUAD_SPOCK (rim click on the shell).
|
|
|
|
**Bass drums** -- 5 pitched drums: BASS_1 (highest/smallest) through
|
|
BASS_5 (lowest/biggest), each with a prominent felt-beater thwack.
|
|
|
|
**9 patterns:** march (basic 4/4), cadence (8-beat street beat),
|
|
march paradiddle, march roll (buzz crescendo), quad sweep (run across
|
|
all 4 drums), quad groove, bass split (cascading across the line),
|
|
bass unison (all 5 hit together), drumline (snare + quads + bass).
|
|
|
|
**Rudiment methods:** ``Part.flam()``, ``Part.diddle()``, and
|
|
``Part.cheese()`` for marching rudiments on any drum sound.
|
|
|
|
**Ensemble rendering:** ``ensemble=N`` on any Part duplicates the
|
|
voice with per-player timing tendencies and micro pitch drift.
|
|
``ensemble=8`` for a snare line, ``ensemble=20`` for a massive section.
|
|
|
|
.. code-block:: python
|
|
|
|
# Full drumline with ensemble
|
|
snares = score.part("snares", synth="sine", volume=0.9,
|
|
reverb=0.2, ensemble=8)
|
|
quads = score.part("quads", synth="sine", volume=0.5,
|
|
reverb=0.2, ensemble=4)
|
|
basses = score.part("basses", synth="sine", volume=0.55,
|
|
reverb=0.2, ensemble=5)
|
|
|
|
snares.flam(DrumSound.MARCH_SNARE, Duration.QUARTER, velocity=120)
|
|
snares.diddle(DrumSound.MARCH_SNARE, Duration.EIGHTH, velocity=60)
|
|
|
|
# Or use patterns
|
|
score.drums("drumline", repeats=4)
|
|
|
|
.. raw:: html
|
|
|
|
<audio controls style="width:100%;margin:0.5em 0 1.5em"><source src="../_static/audio/march_snare.wav" type="audio/wav"></audio>
|
|
|
|
**Sympathetic resonance:** The marching snare builds up snare wire
|
|
buzz as hits accumulate, and the buzz decays during rests — just like
|
|
a real drum.
|
|
|
|
Programming Your Own Beats
|
|
--------------------------
|
|
|
|
When no preset fits, program hits directly. ``Part.hit()`` places a
|
|
drum sound in a part's note stream, so everything that works on notes
|
|
— articulations, velocity, humanize, effects, ensemble — works on
|
|
individual drum hits. Sounds can be named with plain strings or
|
|
:class:`DrumSound` members:
|
|
|
|
.. code-block:: python
|
|
|
|
score = Score("4/4", bpm=95)
|
|
kit = score.part("kit", volume=0.8, humanize=0.15)
|
|
|
|
for bar in range(4):
|
|
kit.hit("kick", 0.75)
|
|
kit.hit("kick", 0.25)
|
|
kit.hit("snare", 1, articulation="accent")
|
|
kit.hit("kick", 1)
|
|
kit.hit("snare", 0.5)
|
|
kit.hit("open_hat", 0.5)
|
|
|
|
Strings match the :class:`DrumSound` member names, case-insensitive:
|
|
``"kick"``, ``"snare"``, ``"closed_hat"``, ``"ride_bell"``,
|
|
``"conga_high"``, and so on — all 74 sounds.
|
|
|
|
Reusable Custom Patterns
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
To package a groove you can repeat, reuse, or export, build a
|
|
:class:`Pattern` from a list of :class:`Hit` objects. Each :class:`Hit`
|
|
names a sound, its position in beats (``0.0`` is beat 1, ``0.5`` the
|
|
following eighth, ``0.25`` a sixteenth), and an optional velocity for
|
|
ghost notes:
|
|
|
|
.. code-block:: python
|
|
|
|
from pytheory import Score, Pattern, Hit, DrumSound
|
|
|
|
K, S, CH = DrumSound.KICK, DrumSound.SNARE, DrumSound.CLOSED_HAT
|
|
|
|
beat = Pattern("my beat", [
|
|
Hit(K, 0.0), Hit(CH, 0.0), Hit(CH, 0.5),
|
|
Hit(S, 1.0), Hit(CH, 1.0), Hit(CH, 1.5),
|
|
Hit(K, 2.0), Hit(CH, 2.0), Hit(K, 2.5), Hit(CH, 2.5),
|
|
Hit(S, 3.0), Hit(CH, 3.0), Hit(S, 1.75, velocity=35), # ghost
|
|
], beats=4.0)
|
|
|
|
score = Score("4/4", bpm=120, drum_humanize=0.15)
|
|
score.drums(beat, repeats=4)
|
|
|
|
``score.drums()`` accepts a :class:`Pattern` object anywhere it accepts
|
|
a preset name, so your own grooves get the same ``repeats``, ``fill``,
|
|
``split``, and ``layer`` options as the built-ins.
|
|
|
|
Mixing and Layering Patterns
|
|
----------------------------
|
|
|
|
``score.add_pattern()`` is the lower-level cousin of ``score.drums()``
|
|
— it takes a :class:`Pattern` object, so you can chain different grooves
|
|
back to back:
|
|
|
|
.. code-block:: python
|
|
|
|
from pytheory import Pattern
|
|
|
|
score.add_pattern(Pattern.preset("rock"), repeats=3)
|
|
score.add_pattern(Pattern.fill("rock"), repeats=1)
|
|
score.add_pattern(Pattern.preset("half time"), repeats=4)
|
|
|
|
By default each call lands *after* the previous one, so they play in
|
|
sequence. To stack grooves so they sound at the same time — a clave
|
|
over a backbeat, or a polyrhythm — pass ``layer=True``. The layered
|
|
pattern is laid down from the start, in parallel with what's already
|
|
there:
|
|
|
|
.. code-block:: python
|
|
|
|
score = Score("4/4", bpm=120)
|
|
score.drums("rock", repeats=4)
|
|
score.drums("son clave 3-2", repeats=4, layer=True) # on top, not after
|
|
|
|
For a true polyrhythm, put both voices in one pattern at their
|
|
fractional positions — three evenly-spaced congas against four kicks
|
|
across the same four beats:
|
|
|
|
.. code-block:: python
|
|
|
|
from pytheory import Pattern, Hit, DrumSound
|
|
|
|
three = [Hit(DrumSound.CONGA_HIGH, i * 4 / 3) for i in range(3)]
|
|
four = [Hit(DrumSound.KICK, i * 1.0) for i in range(4)]
|
|
poly = Pattern("3-against-4", three + four, beats=4.0)
|
|
|
|
score = Score("4/4", bpm=120)
|
|
score.add_pattern(poly, repeats=4)
|
|
|
|
MIDI Export
|
|
-----------
|
|
|
|
Convert any pattern to a Score, then export to MIDI (drums are written
|
|
to channel 10):
|
|
|
|
.. code-block:: python
|
|
|
|
pattern = Pattern.preset("bossa nova")
|
|
score = pattern.to_score(repeats=8, bpm=140)
|
|
score.save_midi("bossa.mid")
|
|
|
|
Pattern.preset("afrobeat").to_score(repeats=8, bpm=110).save_midi("afrobeat.mid")
|
|
|
|
Drums are the foundation. The same chords over a bossa nova feel like a different song than over a rock beat -- change the pattern and you change the genre. Try swapping presets under the same progression and hear how much the drums are really doing.
|