Motifs and phrases
By the end of this chapter, a hook you wrote, eight notes long, plays above the melody as a question and its answer: once ending open, on the fifth note of the scale, then again ending at home, on the first.
The piece so far
Everything A melody that remembers built, without its render. This chapter adds a pattern and changes none.
import subsequence
import subsequence.constants.instruments.gm_drums as gm_drums
import subsequence.constants.midi_notes as notes
composition = subsequence.Composition(bpm=120, key="E", scale="minor", seed=1)
swing = subsequence.Groove.swing(percent=57)
@composition.pattern(channel=10, beats=4, drum_note_map=gm_drums.GM_DRUM_MAP)
def drums (p):
p.hit_steps("kick", [0, 4, 8, 12], velocity=110)
p.hit_steps("snare", [4, 12], velocity=100)
p.ghost_fill("snare", density=0.5, velocity=(20, 40), bias="before")
p.groove(swing)
@composition.pattern(channel=10, beats=4, drum_note_map=gm_drums.GM_DRUM_MAP)
def hats (p):
p.hit_steps("hi_hat_closed", range(16))
p.velocity_shape(low=40, high=90)
p.groove(swing)
@composition.pattern(channel=10, beats=4, drum_note_map=gm_drums.GM_DRUM_MAP)
def euclidean_snare (p):
p.euclidean("snare_2", pulses=5, velocity=60).rotate(2).groove(swing)
@composition.pattern(channel=10, beats=4, drum_note_map=gm_drums.GM_DRUM_MAP)
def fill (p):
if p.bar_cycle(4).last:
p.sequence(steps=[12, 13, 14, 15], pitches=["high_tom", "high_mid_tom", "low_tom", "low_floor_tom"], velocities=[100, 90, 90, 110])
p.groove(swing)
@composition.pattern(channel=10, beats=0.75, reschedule_lookahead=0.75, drum_note_map=gm_drums.GM_DRUM_MAP)
def pedal_hats (p):
p.hit_steps("hi_hat_pedal", [0], velocity=80)
composition.harmony(style="aeolian_minor")
@composition.pattern(channel=3, beats=4, voice_leading=True)
def pad (p, chord):
p.chord(chord, root=notes.E3, sustain=True, velocity=70)
@composition.pattern(channel=2, beats=4)
def bass (p, chord):
p.arpeggio(chord, root=notes.E1, count=4, spacing=0.25)
p.groove(swing)
melody_state = subsequence.MelodicState(low=notes.E4, high=notes.E5, rest_probability=0.2)
@composition.pattern(channel=4, beats=4)
def melody (p, chord):
p.melody(melody_state, spacing=0.5, chord_tones=chord.tones(notes.E4))
A motif, in scale degrees
A generated melody is one way to write a line. The other is to write it yourself. subsequence.motif takes a melody as scale degrees, the notes of the scale counted from 1:
hook = subsequence.motif([5, 6, 5, 3, None, 1, 2, 3])
- In E minor, 1 is E, 3 is G, 5 is B and 6 is C, so the hook is B, C, B, G, a rest, then E, F sharp and G.
Noneis a rest. It still takes its place in the line.- Each note, and the rest, lasts a beat, so the hook is two bars long.
- Written in degrees, the hook is in whatever key the piece is in. Change the composition's key and it moves with it.
hook is a Motif: a value, like the groove, that plays nothing by itself. A pattern places it with p.motif, and it can be changed, transposed or joined to another motif as a value first.
A question and its answer
Classical composers built phrases from ideas like this in a few standard shapes. One is the period: the idea stated twice, the first time ending open, as a question, and the second time ending at home, as its answer. subsequence.period makes one from the hook, changing only its last note each time. That makes a Phrase, a line of motifs in order, four bars long. Give it a pattern of its own, on MIDI channel 5:
answered = subsequence.period(hook)
@composition.pattern(channel=5, bars=4)
def hook_line (p):
p.phrase(answered, root=notes.E5)
composition.render(bars=8, filename="motifs-and-phrases.mid")
In piece.py, put hook and answered above the patterns and add hook_line below them. Give an instrument that can sit above the melody, such as a bell or a pluck, MIDI channel 5.
bars=4makes the pattern as long as the phrase, so the whole phrase plays each time the pattern comes round.p.phraseplaces the part of the phrase that falls in this cycle, which here is all of it.root=notes.E5puts the key note at E5, so the hook sits above the melody's E4 to E5.
The question ends on B, the fifth note of the scale, and the answer on E:
2 2.000 note E5 (76) velocity 100 length 1.000
2 3.000 note F#5 (78) velocity 100 length 1.000
2 4.000 note B5 (83) velocity 100 length 1.000
4 2.000 note E5 (76) velocity 100 length 1.000
4 3.000 note F#5 (78) velocity 100 length 1.000
4 4.000 note E5 (76) velocity 100 length 1.000
Other shapes, and more of the same idea
subsequence.sentenceis the other classical shape: the idea twice, then new material driving to a close. It takes a seed, because it writes the new material itself.Phrase.developgrows a motif into a phrase by a plan you give, such as["a", "a", "a", "b"].Motif.presetgives rhythms from music around the world as motifs, such as the son clave, taken from Godfried Toussaint's The Geometry of Musical Rhythm.