Files
seedbox/docs/superpowers/specs/2026-10-11-scale-root-design.md
Gee 2196633ed5
Some checks failed
check / check (push) Has been cancelled
Seedbox v0.1 + firmware, generic kit/synth, ROOT/SCALE pages
First commit of the repo. Contents beyond the v0.1 simulator and layout:

- Full Pico 2 W firmware (firmware/app, drivers, engine port, host test).
- BANK page and 404 mode A/B removed; learned pads play exactly what was learned.
- 404/MiniFreak renamed to KIT/SYNTH throughout (jacks, code, sim, docs,
  layout labels; wiring rebuilt).
- ROLL returns to page select after a re-roll; a freshly learned track turns on.
- LCD contrast 66.
- ROOT and SCALE pages: 21 scales, AUTO = the seed picks; global and sticky.

Intended music change: the scale table grew from 8 to 21 and AUTO picks from
all of them, so every seed's scale changed. Vectors regenerated with
npm run vectors, plus new key-override cases. Flash record is now version 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 20:39:36 +03:00

3.7 KiB

Scale and root selection

2026-10-11. Status: draft for review.

Goal

Let Gee lock the line (bass, melody, pad) to a chosen root and scale, so Seedbox can play along with an existing musical idea. The seed still makes everything else.

Decisions

Question Answer
Scope Global and sticky. SEED, ROLL and loading a slot don't change it. Slots don't store it.
Pages Two: ROOT and SCALE, each with AUTO.
AUTO The seed picks from all 21 scales and 12 roots. Every existing seed changes scale (an intended music change).
Old data None kept. It's a prototype, so the flash record starts fresh.

Scales

The menu order is also the table index.

# Screen name Steps
0 MAJOR 0 2 4 5 7 9 11
1 MINOR 0 2 3 5 7 8 10
2 DORIAN 0 2 3 5 7 9 10
3 MIXOLYDIAN 0 2 4 5 7 9 10
4 LYDIAN 0 2 4 6 7 9 11
5 PHRYGIAN 0 1 3 5 7 8 10
6 HARM MINOR 0 2 3 5 7 8 11
7 MINOR PENT 0 3 5 7 10
8 MAJOR PENT 0 2 4 7 9
9 PHRYG DOM 0 1 4 5 7 8 10
10 DBL HARM 0 1 4 5 7 8 11
11 HUNG MINOR 0 2 3 6 7 8 11
12 UKR DORIAN 0 2 3 6 7 9 10
13 LYD DOM 0 2 4 6 7 9 10
14 HIRAJOSHI 0 2 3 7 8
15 IN SEN 0 1 5 7 10
16 IWATO 0 1 5 6 10
17 PROMETHEUS 0 2 4 6 9 10
18 WHOLE TONE 0 2 4 6 8 10
19 OCTATONIC 0 1 3 4 6 7 9 10
20 LOCRIAN 0 1 3 5 6 8 10

Scales have 5 to 8 notes. Chords stay "every other scale note" (0, 2, 4 from the chord degree), so:

  • 5-note scales give open chords;
  • the 6-note whole tone gives augmented chords;
  • the 8-note octatonic gives diminished chords.

Engine (sim/engine.js, then firmware/engine/engine.c)

  • SCALES and SCALE_NAMES become the 21-entry table above. In C, SCALES[21][8] and SCALE_LEN[21].
  • genome(): g.scale = r.below(21). It's still one draw, so every later draw in the genome is unchanged.
  • The params get scale (-1 = AUTO, 0..20) and root (-1 = AUTO, 0..11). renderBar overrides g.scale and g.root when they're ≥ 0, right after genome(), the same way AMENIZER overrides steps. In C this is sb_params.scale and sb_params.root.
  • describe() and the simulator's "Key" fact show the effective scale and root.
  • Integer-only and deterministic, as before.

Vectors

  • Run npm run vectors (an intended music change; the commit message says so).
  • Add cases to test/cases.js with a fixed scale and root, so the C port is tested on overrides. Cover at least:
    • a 5-note scale;
    • the 8-note OCTATONIC;
    • a root that isn't C;
    • AUTO.

Panel (firmware app/main.c, simulator app.js)

  • Pages: SEED · GEN · ROOT · SCALE · BPM · SLOT · ROLL · LEARN.
  • ROOT turns through AUTO, C, C#, …, B. SCALE turns through AUTO, MAJOR, …, LOCRIAN. Edit them like GEN: push, turn, push.
  • Screen when set: label ROOT / SCALE, value D / HIRAJOSHI.
  • Screen on AUTO: label ROOT AUTO / SCALE AUTO, value is what the seed picked.
  • A change is heard from the next rendered bar, the same as GEN.

Storage

  • live_t gains scale and root, saved in flash. The record version goes to 2. Old records are ignored and defaults load.
  • The leftovers from BANK go: the unused record field and pad_t.spare.
  • Defaults: both AUTO.
  • The simulator keeps them in localStorage next to gen.

Docs

  • docs/controls.md: add ROOT and SCALE to the pages table.
  • docs/concept.md: the scale list.
  • docs/decisions.md: add one line on global sticky key, AUTO over all 21.

Testing

  1. npm test passes with the new vectors.
  2. cd firmware/test && make test passes.
  3. Bench checks:
    • set ROOT D and SCALE HIRAJOSHI, and check the MiniFreak notes stay in D Hirajoshi across several SEEDs;
    • check that AUTO shows the seed's own pick.