# Chapter 8 · Motifs: Naming and Reusing Material In [Chapter 7](07-progressions) you learned to write *harmony* down as a value — a progression you build once, inspect, shape, and place. This chapter does the same for *melody and rhythm*: you name a short figure as a **Motif**, transform it with a small algebra, and play it under the moving chord. A motif is the smallest unit of musical *material* — a four-note hook, a clave, a bass cell. In Subsequence it's a **value**, exactly like a progression: you store it once at the top of your file, and every transform hands you back a *new* motif instead of changing the one you wrote. That single rule — build once, transform into copies — is what lets a whole part grow from one idea without ever losing the original. It's the same separation you already know: describe the material first, decide how it sounds second. ```{testsetup} ch8 # Hidden per-chapter setup: the imports the first example shows in full, so later # blocks can use these names without repeating them. import subsequence from subsequence import motif, Motif import subsequence.constants.instruments.gm_drums as gm_drums import subsequence.constants.midi_notes as notes ``` (sec-what-a-motif-is)= ## 8.1 What a Motif is (an immutable value) A **`Motif`** is a frozen figure: a handful of timed notes and a length in beats. It is not a pattern, and it makes no sound by itself — just as a progression is not a chord part until something places it. You build a motif, look at it, reshape it, and only then hand it to a pattern to be played. The defining property is that a motif is **immutable**. Once built, it never changes. Every method that "edits" a motif — transpose it, reverse it, vary its last note — leaves the original exactly as it was and returns a *brand-new* motif with the change applied. This is the same contract a `Progression` follows ([§7.3](07-progressions)): transforms return new values, the original is sacred. ```{important} **A motif is a value you store, not a pattern that runs.** You typically build your motifs once, at module level (the top of your file), give them clear names, and reuse them across patterns — precisely the *module-level reusable values* habit from [§2.4](02-rebuild-loop). A pattern function still re-runs every cycle, but the motifs it places are fixed; what changes cycle to cycle is the chord they land on. ``` Like a progression, a motif **prints itself**, so you can check what you wrote before rendering a note. `print(m)` calls its `.describe()`: ```{testcode} ch8 import subsequence from subsequence import motif, Motif import subsequence.constants.instruments.gm_drums as gm_drums import subsequence.constants.midi_notes as notes hook = motif([5, 6, 5, 3]) # a four-note figure in scale degrees print(hook.describe()) ``` ```{testoutput} ch8 Motif 4 beats [^5@0, ^6@1, ^5@2, ^3@3] ``` Read the printout as "a four-beat figure: degree 5 at beat 0, degree 6 at beat 1, degree 5 at beat 2, degree 3 at beat 3." The `^5` is Subsequence's compact label for *scale degree 5* — the figure stores degrees, not fixed pitches, so it's a specification resolved late, the same idea you met for a single pitch in [§5.5](05-pitch-and-scales) and for a whole chord in [§6.5](06-harmony-context). We'll see exactly what those degrees resolve *to* in [§8.5](#sec-placing-motifs). ```{admonition} Reference :class: seealso {py:func}`~subsequence.motifs.motif`, {py:class}`~subsequence.motifs.Motif` ``` (sec-building-a-motif)= ## 8.2 Building one: `motif()`, degrees, notes, steps There are three everyday ways to write a figure down, depending on whether you're thinking in scale degrees, fixed pitches, or a drum grid. Each is a factory that returns a `Motif`. **Scale degrees — `motif([...])`.** The lowercase `motif(...)` is the shortcut you just used: a melody as **1-based scale degrees**, one per beat by default. Degree `1` is the tonic, `8` is the tonic an octave up. This is the *relative-first* form — write the shape, and it transposes to any key for free. ```{testcode} ch8 hook = motif([5, 6, 5, 3]) # one degree per beat print(hook.describe()) ``` ```{testoutput} ch8 Motif 4 beats [^5@0, ^6@1, ^5@2, ^3@3] ``` `motif([5, 6, 5, 3])` is exactly `Motif.degrees([5, 6, 5, 3])` — the lowercase name is just the shortcut, the same way `progression([...])` shortcuts the `Progression` factory. A `None` in the list is a *rest* (the beat slot still advances), and you can pin the timing yourself with a `beats=` list and the lengths with `durations=`: ```{testcode} ch8 # A syncopated figure: a rest in the second slot, the rest on chosen beats. synced = Motif.degrees([5, None, 6, 1], beats=[0, 1, 1.5, 3]) print(synced.describe()) ``` ```{testoutput} ch8 Motif 4 beats [^5@0, ^6@1.5, ^1@3] ``` **Absolute pitches — `Motif.notes([...])`.** When you want *fixed* MIDI note numbers rather than key-relative degrees — a sampled riff, a melody you already know in concrete pitches — use `Motif.notes(...)`. Here `60` is middle C, and again `None` is a rest: ```{testcode} ch8 riff = Motif.notes([64, 65, 64, 60]) # E F E C, exact pitches print(riff.describe()) ``` ```{testoutput} ch8 Motif 4 beats [64@0, 65@1, 64@2, 60@3] ``` ```{important} **Degrees follow the key; absolute notes don't.** A `motif([5, 6, 5, 3])` stores *degrees*, so it plays "the 5th, 6th, 5th, 3rd of whatever key the composition is in" — change the key and it transposes itself. `Motif.notes([64, 65, 64, 60])` stores *MIDI numbers*, so it always plays E–F–E–C regardless of key. Reach for degrees when you want the figure to live inside the harmony, and for notes when you mean those exact pitches. (Degrees above the octave are fine — degree `9` is the 2nd a register up — but paste a MIDI list like `[64, 65]` into `motif()` by mistake and it raises: a value that large can only be a MIDI number, not a scale degree, so the slip fails loudly instead of squealing octaves up.) ``` **A drum/grid figure — `Motif.steps(...)`.** For percussion you think in *grid steps*, exactly like `p.hit_steps` from [§1.4](01-step-grid). `Motif.steps(...)` takes a list of 0-based step indices (sixteenths by default) and the drum to place on them — a rhythmic cell you can name and reuse: ```{testcode} ch8 clave_cell = Motif.steps([0, 3, 6, 10, 12], pitches="side_stick") print(clave_cell.describe()) ``` ```{testoutput} ch8 Motif 4 beats [side_stick@0, side_stick@0.75, side_stick@1.5, side_stick@2.5, side_stick@3] ``` The step indices became beat positions (step 3 of a sixteenth grid is beat `0.75`), and the drum name rides along untouched — drum names resolve through the pattern's drum map at placement, just as they do in a hand-written beat. ```{list-table} Three ways to write a figure :header-rows: 1 :widths: 26 30 44 * - Factory - You write - Reach for it when * - `motif([...])` / `Motif.degrees` - 1-based scale degrees - You want a melody that lives in the key and transposes for free (the default). * - `Motif.notes([...])` - Absolute MIDI numbers - You mean *those* exact pitches, key or no key. * - `Motif.steps([...], pitches=...)` - 0-based grid steps + a drum - You're writing a rhythmic/percussion cell, `hit_steps`-style. ``` ```{admonition} Reference :class: seealso {py:meth}`~subsequence.motifs.Motif.degrees`, {py:meth}`~subsequence.motifs.Motif.notes`, {py:meth}`~subsequence.motifs.Motif.steps` ``` (sec-transforms)= ## 8.3 Transforms return NEW values Here is the heart of working with motifs, and the one idea to hold onto: **every transform returns a new motif and leaves the original untouched.** You never modify a motif in place; you derive variations from it. A whole melody's worth of material comes from one stored figure plus a few of these calls. Watch the original survive a transform: ```{testcode} ch8 hook = motif([5, 6, 5, 3]) higher = hook.transpose(steps=2) # everything up two scale steps print("derived: ", higher.describe()) print("original:", hook.describe()) # ← unchanged ``` ```{testoutput} ch8 derived: Motif 4 beats [^7@0, ^8@1, ^7@2, ^5@3] original: Motif 4 beats [^5@0, ^6@1, ^5@2, ^3@3] ``` `hook.transpose(steps=2)` handed back a *new* figure a third higher; `hook` itself is byte-for-byte what you wrote. That's immutability doing its job — `higher` and `hook` are two independent values, both available, neither aliasing the other. These are the five transforms you'll reach for first. Each takes a motif and returns a fresh one: **`transpose(...)` — move the pitches.** The keyword names the unit: `transpose(steps=2)` moves *diatonically* (along the scale, the sequencing move), while `transpose(semitones=12)` moves *chromatically* (by half-steps, e.g. up an octave). You must pass exactly one. ```{testcode} ch8 hook = motif([5, 6, 5, 3]) print(hook.transpose(steps=2).describe()) # diatonic: degrees shift along the scale ``` ```{testoutput} ch8 Motif 4 beats [^7@0, ^8@1, ^7@2, ^5@3] ``` **`invert(...)` — mirror the contour.** Flip the figure upside-down around a pivot (by default, the first note's pitch): where the original rose, the inversion falls. This is the classic motivic-development move that keeps the *rhythm* and the *intervals* but turns the shape over. ```{testcode} ch8 print(hook.invert().describe()) # mirror around the first note (degree 5) ``` ```{testoutput} ch8 Motif 4 beats [^5@0, ^4@1, ^5@2, ^7@3] ``` **`reverse()` — mirror in time.** Play the figure backwards: the last note becomes the first. The pitches are unchanged; their *order* is flipped. ```{testcode} ch8 print(hook.reverse().describe()) ``` ```{testoutput} ch8 Motif 4 beats [^3@0, ^5@1, ^6@2, ^5@3] ``` **`vary(...)` — the smallest change.** Keep the rhythm, nudge a note or two by a small melodic step. By default it varies the *tail* (the last note) — the loosest possible restatement, the way a player never repeats a lick *quite* identically. Because it makes a random choice, pass a `seed=` so the variation is the same on every run (the repeatability habit from [§4.6](04-generators-euclidean)): ```{testcode} ch8 print(hook.vary(notes=1, seed=4).describe()) # same figure, new last note ``` ```{testoutput} ch8 Motif 4 beats [^5@0, ^6@1, ^5@2, ^2@3] ``` **`answer(...)` — turn a call into a response.** Re-aim the *last* note to a stable degree so the figure sounds like it's coming home. By default it lands on degree `1` (the tonic — a full close); pass `to=5` for a half-close that hangs open. This is the melodic counterpart to a cadence, and it pairs perfectly with the `+` operator below to write a question-and-answer pair. ```{testcode} ch8 print(hook.answer().describe()) # tail re-aimed to the tonic (degree 1) print(hook.answer(to=5).describe()) # tail re-aimed to degree 5 (half-close) ``` ```{testoutput} ch8 Motif 4 beats [^5@0, ^6@1, ^5@2, ^1@3] Motif 4 beats [^5@0, ^6@1, ^5@2, ^5@3] ``` ```{list-table} The five everyday transforms :header-rows: 1 :widths: 26 74 * - Transform - What it returns (a NEW motif) * - `transpose(steps=N)` / `transpose(semitones=N)` - The figure moved — diatonically (`steps=`) or chromatically (`semitones=`). * - `invert(pivot=None)` - The contour mirrored around a pivot (default: the first note). * - `reverse()` - The figure played backwards in time. * - `vary(notes=N, seed=...)` - The same rhythm with a few pitches nudged — the loosest restatement. * - `answer(to=1)` - The tail re-aimed to a stable degree — call becomes response. ``` ```{tip} **These chain, like the progression transforms.** Each call returns a motif, so the next call hangs right off it: `hook.transpose(steps=2).reverse().vary(notes=1, seed=1)` reads left-to-right as a recipe — *raise it, flip it in time, then nudge a note.* It's the same "learn one verb, predict the rest" fluency you met for generators in [§4.5](04-generators-euclidean) and for harmony in [§7.4](07-progressions). And because the source motif is never mutated, you can spin off as many independent variations from it as you like. ``` ```{note} **Why some transforms refuse some content.** `transpose(steps=)`, `invert()`, and `answer()` all work on *scale degrees* — they need a degree to move along the scale or re-aim home. Call them on a drum figure (a `Motif.steps(...)` of `"side_stick"`) and they raise, on purpose: a "transposed" drum name would be a *different instrument*, not a transposition, and a drum has no tonic to answer to. For rhythmic material reach for `reverse()` and the *timing* transforms — `rotate` (shift in time, wrapping), `stretch` (scale the tempo feel), `quantize` (snap onsets to a grid) — which only touch *when* a note sounds, never its pitch. (`transpose(semitones=)` is the chromatic move, but it needs a pitch to shift: it works on absolute-MIDI melodies and degrees, and still raises on drum *names*.) ``` ```{admonition} Reference :class: seealso {py:meth}`~subsequence.motifs.Motif.transpose`, {py:meth}`~subsequence.motifs.Motif.invert`, {py:meth}`~subsequence.motifs.Motif.reverse`, {py:meth}`~subsequence.motifs.Motif.vary`, {py:meth}`~subsequence.motifs.Motif.answer` ``` (sec-combining)= ## 8.4 Combining: `then` / `stack` / `slice` and the `+` / `*` operators A motif is small by design. You build longer and richer material by *combining* motifs — gluing them end to end, layering them, or windowing out a fragment. Three methods and two operators cover it, and they split cleanly into "sequential" (one after another) and "parallel" (at the same time). **`then(other)` — glue end to end into ONE motif.** `a.then(b)` plays `a`, then `b` right after it, fused into a *single* longer motif. Use it when you want one seamless figure built from two cells: ```{testcode} ch8 call = motif([5, 6, 5, 3]) response = call.answer() # same figure, landing on the tonic phrase = call.then(response) # one 8-beat figure: call, then response print(phrase.describe()) ``` ```{testoutput} ch8 Motif 8 beats [^5@0, ^6@1, ^5@2, ^3@3, ^5@4, ^6@5, ^5@6, ^1@7] ``` There's the whole figure in one motif: the call at beats 0–3, then the response shifted to beats 4–7, its tail now on degree `1` (the tonic). Eight beats long, no seam — `then` fused the two cells into a single value. **`+` — sequential, but keeping the seam.** The `+` operator also puts one motif after another, but it produces a **`Phrase`** — a sequence of motifs that *remembers the boundary* between them, rather than fusing them. (A `Phrase` is the subject of [Chapter 9](09-phrases); for now, think "a motif that knows its segments.") ```{testcode} ch8 pair = call + response # a two-segment Phrase, not one fused Motif print(pair.describe()) ``` ```{testoutput} ch8 Phrase 8 beats, 2 segments 1. Motif 4 beats [^5@0, ^6@1, ^5@2, ^3@3] 2. Motif 4 beats [^5@0, ^6@1, ^5@2, ^1@3] ``` ```{important} **`then` fuses; `+` keeps the seam.** Both place `b` after `a`. `a.then(b)` returns one `Motif` with the boundary erased — useful when you want a single indivisible figure. `a + b` returns a `Phrase` that still knows where `a` ends and `b` begins — useful when you'll later develop or reroll the parts independently (Chapter 9). Same musical result on playback; different *handle* on the structure. ``` **`*` — repetition.** Multiply a motif to repeat it. Like `+`, it produces a `Phrase` (a chain of identical segments), so the repeats stay individually addressable: ```{testcode} ch8 vamp = call * 2 # the call, twice — a 2-segment Phrase print("length:", vamp.length, "beats") ``` ```{testoutput} ch8 length: 8.0 beats ``` **`stack(other)` — layer two motifs at once.** Where `then` and `+` are *sequential*, `stack` is *parallel*: it merges two motifs so they sound **together**, returning one motif containing both. This is how you put a counter-line under a melody, or two percussion voices in one cell: ```{testcode} ch8 melody = motif([5, 6, 5, 3]) counter = motif([3, 4, 3, 1]) # a line a third below both = melody.stack(counter) # the two played at the same time print(both.describe()) ``` ```{testoutput} ch8 Motif 4 beats [^3@0, ^5@0, ^4@1, ^6@1, ^3@2, ^5@2, ^1@3, ^3@3] ``` The two figures now share every beat — degree 3 *and* degree 5 at beat 0, and so on. `stack` is also spelled with the `&` operator (`melody & counter`), exactly as `then`'s sequential cousin `+` mirrors it. The length is the *longer* of the two — a short gesture stacked under a long figure plays once and stops, no looping. **`slice(start, end)` — window out a fragment.** Take just part of a motif, with the beats shifted so the window starts at 0. Reach for it to grab the first cell of a longer idea, or to develop only the tail: ```{testcode} ch8 opening = call.slice(0, 2) # just the first two beats print(opening.describe()) ``` ```{testoutput} ch8 Motif 2 beats [^5@0, ^6@1] ``` ```{list-table} Combining motifs :header-rows: 1 :widths: 22 18 60 * - Operation - Result - What it does * - `a.then(b)` - `Motif` - Sequential: glue `b` after `a` into **one fused** figure. * - `a + b` - `Phrase` - Sequential: `b` after `a`, **keeping the seam** (segments preserved). * - `m * n` - `Phrase` - Repeat `m` `n` times (a chain of segments). * - `a.stack(b)` / `a & b` - `Motif` - **Parallel**: `a` and `b` sound at the same time. * - `m.slice(start, end)` - `Motif` - A window onto `m`, re-zeroed to start at beat 0. ``` ```{admonition} Reference :class: seealso {py:meth}`~subsequence.motifs.Motif.then`, {py:meth}`~subsequence.motifs.Motif.stack`, {py:meth}`~subsequence.motifs.Motif.slice` ``` (sec-placing-motifs)= ## 8.5 Placing under harmony: `p.motif`, `root`, `fit` A motif is still just a value — nothing has sounded yet. To play it, hand it to a pattern with **`p.motif(m, beat=...)`**. This is the seam between the *material* (the stored value) and the *performance* (the running pattern), exactly like `p.progression` for harmony. Here is the running arrangement carried forward: the GM drum loop, plus a lead that plays our stored hook under the live chord engine from [Chapter 6](06-harmony-context). The motif is built **once at module level**; the pattern just places it each cycle. ```{testcode} ch8 import subsequence from subsequence import motif import subsequence.constants.instruments.gm_drums as gm_drums import subsequence.constants.midi_notes as notes HOOK = motif([5, 6, 5, 3, 1]) # the named material, built once composition = subsequence.Composition(bpm=120, key="A", scale="minor") composition.harmony(style="aeolian_minor", cycle_beats=4) @composition.pattern(channel=10, beats=4, drum_note_map=gm_drums.GM_DRUM_MAP) def drums(p): p.hit_steps("kick_1", [0, 4, 8, 12], velocity=100) p.hit_steps("snare_1", [4, 12], velocity=95) p.hit_steps("hi_hat_closed", range(16), velocity=70) @composition.pattern(channel=4, beats=4) def lead(p): p.motif(HOOK, beat=0, root=notes.A4) # place the figure, near A4 composition.render(bars=4, filename="motif-lead.mid") ``` Two arguments steer the placement: - **`beat=`** is *where in the bar* the figure starts. `beat=0` is the downbeat; `beat=2` would drop it onto beat 3. - **`root=`** is the *register anchor* for scale-degree resolution. The figure's degrees resolve against the composition's key and scale, voiced near this MIDI note — `notes.A4` puts the melody up in a lead register, `notes.A2` down in the bass. It's the same "give me this, *around here*" idea as `chord.root_note(near)` in [§6.2](06-harmony-context): the degrees decide *which* notes, you decide *where*. ```{note} **This is "a pitch resolved late," one more time.** `HOOK` stores degrees `5 6 5 3 1` — abstract until placed. At render, `p.motif(HOOK, root=notes.A4)` resolves them against A minor near A4, producing concrete MIDI notes. Change the composition's `key=` and the *same* `HOOK` plays a transposed melody, with no edit to the motif — the structural-vs-sonic distinction from [§5.5](05-pitch-and-scales) and [§6.5](06-harmony-context), now for a whole figure instead of one note. ``` ### Snapping melody to the chord: the `fit` dial By default, a hand-written degree plays *exactly* the degree you wrote — it follows the **key**, but it does not bend toward the current **chord**. Sometimes that's what you want; sometimes you'd rather the melody lean into the harmony, landing on chord tones on the strong beats. The **`fit=`** dial does that, with a probability from `0.0` to `1.0`: ```{testcode} ch8 import subsequence from subsequence import motif import subsequence.constants.midi_notes as notes HOOK = motif([5, 6, 5, 3, 1]) composition = subsequence.Composition(bpm=120, key="A", scale="minor") composition.harmony(style="aeolian_minor", cycle_beats=4) @composition.pattern(channel=4, beats=4) def lead(p): # On strong beats, snap to the nearest chord tone — the melody hugs the chord. p.motif(HOOK, beat=0, root=notes.A4, fit=1.0) composition.render(bars=4, filename="motif-fit.mid") ``` With `fit=1.0`, every degree that lands on a strong beat snaps to the nearest tone of the chord sounding *under it*; at `fit=0.5` it snaps about half the time, for a looser feel; at `fit=0.0` (the default for hand-written motifs) it never snaps and your degrees play verbatim. ```{important} **Typed degrees are sacred — `fit` is opt-in.** A degree you wrote by hand defaults to `fit=0.0`: it plays exactly as written, following the key but never silently rewritten by the chord. You *opt in* to chord-snapping with `fit=` at the placement call — it's a deliberate dial, not a default. (Motifs that Subsequence *generates* for you carry a gentle `fit=0.7`, since they have no authored intent to protect. Chord-relative content always tracks the chord regardless of `fit`, because asking for "the third of the chord" is *already* a harmony reading.) ``` ```{tip} **`fit` needs a chord to snap to.** It does nothing without harmony — call `composition.harmony(...)` (a style, or a bound progression) first, exactly as in Chapters 6 and 7. With no chord context, `fit=` is quietly inert and your degrees play as written. ``` ```{admonition} Reference :class: seealso {py:meth}`~subsequence.pattern_builder.PatternBuilder.motif` ``` (sec-capturing)= ## 8.6 Capturing placed notes back: `p.capture` Sometimes you want to go the other way: place a figure, let Subsequence resolve all its degrees and chord-snapping into concrete notes, and then *read those notes back out* as a new motif — to layer them an octave down, hand-edit them, or freeze them. **`p.capture(beat, span)`** does exactly that: it reads the notes placed so far in the current pattern and returns them as a `Motif`. Here the lead places the hook, then captures the resolved notes and doubles them an octave lower as a second voice: ```{testcode} ch8 import subsequence from subsequence import motif import subsequence.constants.midi_notes as notes HOOK = motif([5, 6, 5, 3, 1]) composition = subsequence.Composition(bpm=120, key="A", scale="minor") composition.harmony(style="aeolian_minor", cycle_beats=4) @composition.pattern(channel=4, beats=4) def doubled_lead(p): p.motif(HOOK, beat=0, root=notes.A4) # place the figure up high echo = p.capture(beat=0, span=4) # read those notes back out p.motif(echo, beat=0, root=notes.A3) # play them again, an octave down composition.render(bars=4, filename="motif-capture.mid") ``` `p.capture(beat=0, span=4)` grabs the four-beat window from the start of the bar. What comes back is an **absolute-MIDI** motif — the degrees have already resolved to concrete pitches against the chord, so the captured figure is fixed notes, not degrees. ```{important} **Capture is absolute and lossy — by design.** The degrees, chord tones, and fit-snapping that produced the placed notes have *already resolved* by the time you capture, so the returned motif holds plain MIDI numbers (like `Motif.notes([...])`), not the relative specs you started from. Timing is snapped to the MIDI grid, and control gestures (CC, pitch-bend) aren't captured. The intended round trip is **place → capture → hand-edit → re-place**, not a way to recover your original degree spec. If you want the relative figure, keep the value you built; if you want the *sounded result* as material, capture it. ``` ```{note} **Why capture at all, if it's lossy?** Because the sounded result is sometimes exactly the material you want. A generated or chord-fitted melody resolves to specific notes you couldn't easily have written by hand; capturing freezes that happy accident into a value you can transpose, reverse, or stack like any other motif. It's the melodic echo of `composition.freeze(...)` for harmony in [§7.6](07-progressions): let the system resolve something live, then keep the result. ``` ```{admonition} Reference :class: seealso {py:meth}`~subsequence.pattern_builder.PatternBuilder.capture` ``` (sec-presets)= ## 8.7 Presets & world rhythms You don't have to write every rhythmic cell from scratch. **`Motif.preset(name)`** hands you a famous *world rhythm* — claves, bell patterns, tresillo — as a ready-made motif. These are the timelines that anchor Afro-Cuban and West-African music, placed at their exact canonical pulse positions: ```{testcode} ch8 clave = Motif.preset("son_clave_3_2") # the 3-2 son clave print(clave.describe()) ``` ```{testoutput} ch8 Motif 4 beats [claves@0, claves@0.75, claves@1.5, claves@2.5, claves@3] ``` Each preset comes with a sensible default General-MIDI voice (the son clave uses `"claves"`), so it sounds correct against the standard drum map with no `pitch=`. Override the voice — and play it on a different drum — by passing `pitch=`: ```{testcode} ch8 bembe = Motif.preset("bembe", pitch="cowbell") # the 12-pulse bembé bell print(bembe.describe()) ``` ```{testoutput} ch8 Motif 4 beats [cowbell@0, cowbell@0.666667, cowbell@1.33333, cowbell@1.66667, cowbell@2.33333, cowbell@3, cowbell@3.66667] ``` Notice the bembé's onsets sit on a *12*-pulse cycle (the beats land on thirds: `0.667`, `1.333`, …), where the clave is on the familiar 16-pulse sixteenth grid — each preset declares its own grid, so the geometry is authentic. Because a preset is just a `Motif`, every transform and combiner from this chapter applies. Here the running drum loop gets a son-clave side-stick layered on top — the preset placed straight into a pattern with `p.motif`: ```{testcode} ch8 import subsequence from subsequence import Motif import subsequence.constants.instruments.gm_drums as gm_drums composition = subsequence.Composition(bpm=120, key="A", scale="minor") CLAVE = Motif.preset("son_clave_2_3", pitch="side_stick") # 2-3 son clave @composition.pattern(channel=10, beats=4, drum_note_map=gm_drums.GM_DRUM_MAP) def drums(p): p.hit_steps("kick_1", [0, 4, 8, 12], velocity=100) p.hit_steps("snare_1", [4, 12], velocity=95) p.hit_steps("hi_hat_closed", range(16), velocity=70) p.motif(CLAVE, beat=0) # lay the clave timeline over the beat composition.render(bars=4, filename="motif-clave.mid") ``` The available presets, grouped by family: ```{list-table} World-rhythm presets :header-rows: 1 :widths: 30 70 * - Family - Preset names * - Cuban clave (16-pulse) - `"son_clave_3_2"`, `"son_clave_2_3"`, `"rumba_clave_3_2"`, `"rumba_clave_2_3"`, `"bossa_nova_clave"` * - Tresillo / cinquillo (the 3-3-2 family) - `"tresillo"`, `"tresillo_16"`, `"cinquillo"` * - West-African / Cuban 4-4 bell (16-pulse) - `"shiko"`, `"soukous"`, `"gahu"`, `"samba_necklace"` * - 12-pulse bell timelines - `"bembe"`, `"bembe_euclidean"`, `"fume_fume"` ``` ```{tip} A preset is a *rhythm* with a default voice — so it's the percussion sibling of a degree melody. Want the clave's *timing* but a different sound? Pass `pitch=`. Want its timing on a *pitched* part — a bassline that grooves to the clave? `.pitched(...)` re-aims every onset at one pitch spec (a chord tone like `"root"`, or a MIDI note), turning the rhythm skeleton into a melodic line you can place under the harmony. An unknown preset name raises a `ValueError` listing every valid one, so a typo fails loudly. ``` ```{admonition} Reference :class: seealso {py:meth}`~subsequence.motifs.Motif.preset`, {py:meth}`~subsequence.motifs.Motif.pitched` ``` --- You can now treat melody and rhythm the way [Chapter 7](07-progressions) taught you to treat harmony: name a figure as an immutable `Motif`, transform it into a family of variations that never touch the original, combine those sequentially or in parallel, and place them under the moving chord with `p.motif` — snapping to the harmony with `fit`, or capturing the resolved result back out with `p.capture`. In [Chapter 9](09-phrases) we let these motifs *grow*: stringing them into **phrases** and developing them with a plan, so a whole melodic part unfolds from a single stored idea.