Seedbox v0.1 + firmware, generic kit/synth, ROOT/SCALE pages
Some checks failed
check / check (push) Has been cancelled
Some checks failed
check / check (push) Has been cancelled
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>
This commit is contained in:
95
docs/superpowers/specs/2026-10-11-scale-root-design.md
Normal file
95
docs/superpowers/specs/2026-10-11-scale-root-design.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user