metronome/rust/pm-daisy/src/programs.rs
Me Here 802e46f5bb pm-daisy: wire Pod controls (encoder/buttons/knobs/RGB LEDs)
The Daisy Pod hardware arrived (Seed 1.2 / PCM3060). Build the controls
phase on top of the audio spike: encoder turn = tempo, push = play/pause,
buttons step the program list, knob 1 = volume, RGB LED 1 = beat colored
by dynamic, RGB LED 2 = transport. Boot still plays the spike groove so
the spike's decision criteria stay observable.

- pm-synth: add Player::{position,seek,set_volume,last_level} + Synth::
  set_master, with host tests (tests/player.rs). Live tempo/program
  changes rebuild the Player in thread context and swap it in under a
  short critical section, preserving loop phase (seek) on tempo changes.
- pm-daisy: SysTick 1 kHz millis tick, non-blocking beat flash, and
  PLAYING/VOLUME/LAST_LEVEL atomics the audio IRQ honors/publishes.
- New modules controls.rs (buttons/encoder/pots, libDaisy debounce +
  quadrature decode, 1 kHz poll), leds.rs (active-low RGB + boot
  self-test), programs.rs (spike groove at index 0 + pm-grid grooves).
- Pin map verified against libDaisy daisy_pod.cpp + the daisy crate's
  pins.rs. Builds clean for all three Seed revisions; 91 KB/128 KB flash.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 20:04:59 -05:00

25 lines
1.6 KiB
Rust

//! The built-in program list the two Pod buttons step through. Index 0 is the spike pattern, so
//! boot behavior is identical to the original spike (`docs/daisy-spike.md`); the rest are lifted
//! from the Grid firmware's `STYLES` / `PRACTICE` sets (`rust/pm-grid/src/main.rs`) so the editions
//! share one groove vocabulary. All are plain track-format strings — `track_format::parse` handles
//! them and `pm_synth::Player` schedules them at a fixed tempo (any `rmp`/`tr` directives parse but
//! don't animate here; the polyrhythm and odd-meter grooves are the interesting ones for the Pod).
/// `(display name, track-format program)`.
pub const PROGRAMS: &[(&str, &str)] = &[
// Index 0: the spike groove — unchanged boot default (124-BPM 909 four-on-the-floor).
("Spike 909", pm_synth::SPIKE_PROGRAM),
// Styles.
("Four-on-the-floor", "t120;kick:4;snare:4=.x.x;hatClosed:4/2"),
("Swing ride", "t150;ride:4/2s;kick:4=X..x;snare:4=.x.x"),
("Samba (2/4)", "t104;tomLow:2/4=x...X...;hatClosed:2/4;woodblock:2/4=X.xx.xX."),
("Nanigo (6/8 bembe)", "t130;cowbell:4/3=X.xx.x.xx.x.;kick:4/3=X.....X.....;hatClosed:4/3=..x..x..x..x"),
("6/8 groove", "t100;kick:3+3=x..x..;snare:3+3=...x..;hatClosed:3+3/2"),
("7/8 (2+2+3)", "t130;kick:2+2+3=x..x..x;hatClosed:2+2+3/2"),
("5/4 (3+2)", "t112;kick:3+2=x..x.;snare:3+2=..x..;hatClosed:3+2/2"),
// Practice — polyrhythms and subdivisions.
("5 over 4 polyrhythm", "t100;kick:4;claves:5~"),
("3 over 2 hemiola", "t96;woodblock:2;cowbell:3~"),
("2 & 4 & 3 over one bar", "t100;kick:3;cowbell:2~;claves:4~"),
("Triplet hats", "t100;kick:4;snare:4=.x.x;hatClosed:4/3"),
];