📖 What Pearson does
Chapter 11 is the second-biggest chapter in the book, after Chapter 3. Pearson teaches you to build step sequencers — circuits that play a sequence of notes in a loop. The chapter introduces:
- The 4051 multiplexer. A chip that selects one of 8 inputs based on a 3-bit address. Used as the heart of an 8-step sequencer.
- Boolean logic. AND, OR, NOT — the basics of how digital circuits “decide” things.
- Binary and the 4051. How to set the 3 address bits using binary counting.
Projects (in increasing complexity):
- The Disco Boole (Part I). A 2-step sequencer using a 4017 decade counter.
- The Disco Boole (Part II). Adding LEDs to the previous so you can see which step is active.
- The Standard Eight-Step Sequencer. The canonical project. Eight steps, each with a pitch knob and a trigger.
- A Pattern-Changing Sequencer. A sequencer that switches between two patterns based on an external input.
- A First-Order Reset Harmonization Sequencer. A sequencer that auto-resets based on the output of another sequencer.
- A Second-Order Reset Harmonization Sequencer. Like the above, but the cascaded resets create complex interlocking patterns.
🎓 Background: our sequencer, end to end
Our firmware has a sequencer that does almost everything Pearson’s
circuits do, plus more. It is implemented in main/sequencer/sequencer.c
and main/sequencer/pattern.{c,h}. The key data structures:
#define PATTERN_COUNT 16
#define STEP_COUNT 16
#define SLOT_COUNT 16
#define CHAIN_LENGTH 128
typedef struct {
uint8_t slot; // which slot to play on this step
uint8_t note; // MIDI note number, 0..127 (0 = step off)
uint8_t fx; // punch-in effect for this step
uint8_t fx_p1, fx_p2; // effect params
uint8_t filter_cutoff; // tweak-filter cutoff, 0..255
uint8_t filter_resonance;// tweak-filter resonance, 0..255
} pattern_step_t;
struct pattern_t {
pattern_step_t steps[STEP_COUNT];
};
struct pattern_t patterns[PATTERN_COUNT];
uint8_t chain[CHAIN_LENGTH];
uint8_t chain_len;
When the sequencer ticks, it:
- Looks up the current step in the active pattern.
- If
note == 0, the step is empty — do nothing. - Otherwise, call
amy_bridge_play_note(step.slot, step.note, step.fx, step.fx_p1, step.fx_p2, step.filter_cutoff, step.filter_resonance). - AMY plays the slot at the given pitch with the given effect and filter.
- Advance to the next step. If we’ve gone past step 16, jump back to step 1 (or move to the next pattern in the chain).
This is Pearson’s Standard Eight-Step Sequencer, with 16 steps instead of 8, no knob per step (we have UART verbs instead), and a chain instead of a single loop.
🔧 Try it on the device
This chapter has the most exercises. Take your time — the sequencer is the heart of the device.
Exercise 1: the Standard Sixteen-Step Sequencer.
Clear pattern 1 and put four notes on steps 1, 5, 9, 13:
> pattern_clear 1
> step_set 1 1 9 60 ; step 1 plays slot 9 at MIDI 60 (C4)
> step_set 1 5 9 64 ; step 5 plays slot 9 at MIDI 64 (E4)
> step_set 1 9 9 67 ; step 9 plays slot 9 at MIDI 67 (G4)
> step_set 1 13 9 72 ; step 13 plays slot 9 at MIDI 72 (C5)
> bpm 120
> play
You should hear a 4-note pattern: C, rest, E, rest, G, rest, C, rest, repeat. That is the Standard Sixteen-Step Sequencer — 16 steps, each with a slot and a pitch.
If you don’t have a recorded slot 9, you can still play — AMY’s default synth will provide a patch on the fly.
Exercise 2: the Pattern-Changing Sequencer.
Add another pattern with different pitches:
> pattern_clear 2
> step_set 2 1 9 67
> step_set 2 5 9 72
> step_set 2 9 9 76
> step_set 2 13 9 79
Append both patterns to the chain:
> chain_clear
> chain_append 1
> chain_append 2
> chain_show
The chain now reads [1, 2]. When you press play, pattern 1 plays
once, then pattern 2 plays once, then the chain wraps back to
pattern 1. That is Pearson’s Pattern-Changing Sequencer — the
hardware version uses an external input to switch patterns; ours
uses a chain.
Exercise 3: chained reorder (live re-ordering).
While the sequencer is playing, swap the two patterns in the chain:
> chain_swap 0 1
You should hear the order reverse immediately. That is Pearson’s “live re-arrangement” — possible in hardware only by physically moving wires; possible in our firmware via two keystrokes.
Exercise 4: the First-Order Reset Sequencer (chain auto-reset).
If you build a chain of patterns where the last pattern is the “reset trigger” pattern, the chain wraps back to pattern 1 after the last. That is the simplest form of Pearson’s auto-reset sequencer. Our firmware does this automatically:
> chain_clear
> chain_append 1
> chain_append 2
> chain_append 1 ; explicitly loop back
> chain_append 2
> play
Plays 1, 2, 1, 2 forever. Or use the loop_chain option (if your
firmware version supports it) to auto-loop without explicit
appends.
Exercise 5: the Disco Boole (binary counter).
The Disco Boole is a sequencer that uses a binary counter to choose the step. Our firmware does this implicitly — the sequencer walks through steps 1, 2, 3, … which is just a binary counter that increments on each clock tick. No special verb needed.
Exercise 6: cascade (Second-Order Reset Harmonization).
Two chains, one driving the other. We don’t expose this directly, but you can approximate it with a long chain of alternating patterns:
> chain_clear
> chain_append 1
> chain_append 2
> chain_append 1
> chain_append 2
> chain_append 1
> chain_append 2
The pattern 1 and 2 will play alternately, creating a “harmonized” effect because they share the same step data but at different pitches.
🛠 Code reference
- The pattern data structure —
main/sequencer/pattern.h.pattern_step_tandpattern_t. About 50 lines of declarations. - The sequencer tick —
main/sequencer/sequencer.c,sequencer_tick(). About 60 lines. Pulls the current step from the active pattern, callsamy_bridge_play_note(), advances the step counter. - The chain —
main/sequencer/sequencer.c.chain[],chain_len,chain_append(),chain_remove(),chain_swap(),chain_insert(). - The UART verbs —
main/main.c. Each shell command (cmd_chain_append,cmd_chain_swap, etc.) is about 15 lines.
🚫 What we can’t simulate
- The 4051 multiplexer chip. It’s a piece of silicon that selects one of 8 inputs based on a 3-bit address. Our firmware has no analog; the sequencer just walks an array index.
- Boolean logic gates. Pearson uses discrete logic gates to
decide “should this step fire?” Our firmware uses C
ifstatements, which compile to conditional branches on the CPU. Same thing.