Tutorial: Players in Practice¶
File: data/banks/tutorial/lesson04_players.yaml
This tutorial demonstrates all four player types supported by FluidPatcher:
- Sequences – timed, repeating MIDI patterns
- Arpeggios – patterns generated from held notes
- MIDI Loops – live recording and overdubbing
- MIDI Files – playback of
.midfiles
Each player is defined at the root level, so it can continue running while patches are changed. All players are synchronized to the same tempo to make it easy to combine them.
Root-Level Presets¶
The patches in this bank are used for choosing which player to control, rather than selecting sounds. The root-level presets in this bank apply to all patches, so they are always available to the root-level players. For clarity, presets are placed in the bank file near the players that use them.
- Channel 1 is set to E.Piano 1 near the root-level
noterule, since it is for live playing, arpeggios, and looping.
1: test.sf2:000:004
rules:
- {type: note, chan: 1}
- Channels 2 and 10 are used by the sequences for keys and drums.
2: test.sf2:000:005
10: test.sf2:128:000
- Channels 4 and 12 are used by the MIDI file player for bass and drums.
4: test.sf2:000:033
12: test.sf2:128:000
Sequences¶
Sequences play predefined MIDI events on a clock.
Two sequences are defined here: a melodic pattern (montuno) and a drum
pattern (disco).
Pattern-Based Sequence: montuno¶
sequences:
montuno:
tdiv: 16
tempo: 110
events:
- - nt:2:A3:100, nt:2:C3:100, nt:2:E3:100, nt:2:A1:100
- - _, nt:2:C3:100, nt:2:E3:100, nt:2:A1:100
- - _, nt:2:C3:100, nt:2:E3:100, +
order: 1, 2, 2, 3
Key ideas demonstrated here:
- A sequence can contain multiple patterns
- Each pattern can contain one or more tracks
- The
orderlist controls how patterns are played and repeated +sustains the previous notentis an alias fornote
This format is compact and good for algorithmic or harmonic material.
Grid-Style Sequence: disco¶
disco:
tdiv: 16
tempo: 110
events: |
nt:10:36:100 _ nt:10:42:100
_ _ nt:10:46:100
nt:10:36:100 nt:10:39:100 nt:10:42:100
_ _ nt:10:46:100
This alternate format treats columns as tracks and rows as steps. It’s especially readable for drum patterns and is visually similar to a step sequencer or tracker. Multiple patterns can be defined in the grid by separating them with blank lines.
Controlling Sequences¶
The Sequencer Control patch starts and stops each sequence using a toggle button.
Sequencer Control:
rules:
- {type: ctrl, num: button1, val: 0-127=0-1, play: montuno}
- {type: ctrl, num: button2, val: 0-127=0-1, play: disco}
The transformed value determines playback:
0→ stop1→ play (at step 1 of the playbackorder)
Arpeggios¶
Arpeggios generate notes from what you play, rather than from a fixed pattern.
arpeggios:
fastpattern: {style: manual, tempo: 110, tdiv: 16}
This arpeggio:
- Plays notes in the order they were received
- Advances quickly (16 steps per bar)
- Shares the same tempo as the sequences
- Is defined using the optional flow style for compactness
Using the Arpeggio¶
Play Arpeggios:
rules:
- {type: note, chan: 1, arpeggio: fastpattern}
When the Play Arpeggios patch is applied, any notes played on channel 1 are captured and replayed by the arpeggiator as long as they’re held.
MIDI Loops¶
MIDI loops record what you play and repeat it continuously.
midiloops:
loop1: {beats: 4, tempo: 110}
This creates a four-beat loop synchronized with the other players.
Recording and Playback¶
Looper Control:
rules:
- {type: note, loop: loop1}
- {type: ctrl, num: button1, val: 0-127=0-1, play: loop1}
- {type: ctrl, num: pad1, val: 127=1, record: loop1}
- {type: ctrl, num: pad2, val: 127=0, record: loop1}
- {type: ctrl, num: pad3, val: 127=-1, record: loop1}
To start recording in the Looper Control patch, either:
- Press
pad1. This primes recording, but doesn't begin until a note is played. - Activate
button1to start playback, thenpad1. This starts recording events relative to whenbutton1was pressed.
Either method can be used to synchronize loops to the start of a measure when one of the other players is running.
Pressing pad1 again will start recording a new overdub layer.
Pressing pad2 will stop recording but playback will continue.
Pressing pad3 at any time will undo the most recent layer.
MIDI File Playback¶
MIDI files are played using midifiles.
midifiles:
funktrack:
file: funkjam2.mid
barlength: 1000
jumps: 9>2
shift: 2
tempo: 110
Features demonstrated here:
-
Setting the
barlength(length of a measure) in ticks. The file used in this example uses 250 ticks per beat, so 1000 corresponds to a measure of four beats. -
Looping between arbitrary bars - when playback reaches the end of measure 9 it will loop back to the start of measure 2
-
Shifting channels - The MIDI file has keys, drum, and bass tracks on channels 1, 2, and 10. Shifting these channels by 2 avoids conflicts with other players, and effectively silences the keys since there is no preset assigned to channel 3.
Controlling Playback¶
patches:
Backing Tracks:
rules:
- {type: ctrl, num: button1, val: 127=-1, play: funktrack}
- {type: ctrl, num: button1, val: 0, play: funktrack}
The Backing Tracks patch enables simplistic playback control.
A negative play value restarts playback from the last postion and 0
pauses it, so button1 acts a toggling play/pause control.
Performance Design¶
This bank is designed so you can:
- Start a drum and bass groove
- Layer arpeggiated chords
- Record live loops
- Bring in a backing track
Switching patches effectively selects which player to control at a given moment. This demonstrates that bank files can be used not just for constructing sets of sounds, but also for creating varied performance modes.
Complete Bank File¶
names:
button1: 53
button2: 54
pad1: 50
1: test.sf2:000:004
rules:
- {type: note, chan: 1}
sequences:
montuno:
tdiv: 16
tempo: 110
events:
- - nt:2:A3:100, nt:2:C4:100, nt:2:E4:100, nt:2:G#3:100
- - _, nt:2:C4:100, nt:2:E4:100, nt:2:G3:100
- - _, nt:2:C4:100, nt:2:G#3:100, +
order: 1, 2, 2, 3
disco:
tdiv: 8
tempo: 110
events: | # alternate form; columns=tracks
nt:10:36:100 _ nt:10:42:100
_ _ nt:10:46:100
nt:10:36:100 nt:10:39:100 nt:10:42:100
_ _ nt:10:46:100
2: test.sf2:000:005
10: test.sf2:128:000
arpeggios:
fastpattern: {style: manual, tempo: 110, tdiv: 16}
midiloops:
loop1: {beats: 4, tempo: 110}
midifiles:
funktrack:
file: funkjam2.mid
barlength: 1000
jumps: 9>2
shift: 2
tempo: 110
4: test.sf2:000:033
12: test.sf2:128:000
patches:
Sequencer Control:
rules:
- {type: ctrl, num: button1, val: 0-127=0-1, play: montuno}
- {type: ctrl, num: button2, val: 127=1, play: disco}
- {type: ctrl, num: button2, val: 0, play: disco}
Play Arpeggios:
rules:
- {type: note, chan: 1, arpeggio: fastpattern}
Looper Control:
rules:
- {type: note, loop: loop1}
- {type: ctrl, num: button1, val: 0-127=0-1, play: loop1}
- {type: ctrl, num: button2, val: 0-127=0-1, record: loop1}
- {type: ctrl, num: pad1, val: 127=-1, record: loop1}
Backing Tracks:
rules:
- {type: ctrl, num: button1, val: 127=-1, play: funktrack}
- {type: ctrl, num: button1, val: 0, play: funktrack}