Files
seedbox/firmware/app/app.h
Gee 346c820b10
Some checks failed
check / check (push) Has been cancelled
Split kit and keys; KEYS GEN with MOTIF, 303, TURING, ARP
- genome(seed, salts) now has three parts with their own RNG streams:
  shared (steps, form, swing, arc, layback, fill odds, phase offset),
  kit (density, frame, accent cycle, free snare) and keys (scale/root,
  progression, motif, hocket, bass tone, note lengths, range). ROLL KEYS
  now renews the harmony too; ROLL KIT leaves the keys alone.
- Keys generators share one signature and can fix note lengths:
  MOTIF (the old line), 303 (acid bass, answers in the rests, drone or
  silent pad), TURING (8/16-bit shift register, DRIFT flips bits, 16-bar
  window), ARP (triad/7th arpeggio, roots on kicks).
- Pages: KIT GEN, KEYS GEN; ROLL shows KIT / KEYS; slots keep both gens.
- Flash record v3 (old settings ignored). Bring-up golden checksums updated.
- C port matches; host test and ASan/UBSan pass.

Intended music change: every seed sounds different (genome split, new
generators). Vectors regenerated with npm run vectors; the case grid now
crosses all kit and keys generators, with TURING runs past its window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:50:41 +03:00

46 lines
1.6 KiB
C

/* Seedbox firmware: state shared between core 0 (UI) and core 1 (sequencer). Mirrors sim/app.js. */
#ifndef SEEDBOX_APP_H
#define SEEDBOX_APP_H
#include <stdint.h>
#include "pico/critical_section.h"
#include "pico/util/queue.h"
#include "engine.h"
#define NKIT 7 /* kit tracks are 0..6 (lane 0); LEARN index = track index */
#define NSLOTS 8
typedef struct { uint8_t used, ch, note; } pad_t; /* learned pad: ch 0..15 */
/* Everything the sequencer reads. Core 0 writes it under g_live_lock; core 1 copies it under the same lock. */
typedef struct {
sb_state state;
int gen, keys, energy, drift, bpm; /* gen = KIT GEN, keys = KEYS GEN */
int scale, root; /* ROOT / SCALE pages: -1 = AUTO (the seed picks) */
uint8_t on[SB_NT], inv[SB_NT]; /* inv: flipped while the button is held */
pad_t learn[NKIT];
int mono_ch; /* synth channel 1..16 */
int mono_oct; /* -3..3 */
int clock; /* send clock + start/stop */
} live_t;
extern live_t g_live;
extern critical_section_t g_live_lock;
/* core 0 -> core 1 */
enum { CMD_START, CMD_STOP, CMD_RELEASE_TRACK, CMD_BPM };
typedef struct { uint8_t cmd; int16_t arg; } cmd_t;
extern queue_t g_cmdq;
/* core 1 -> core 0, for the screen */
extern volatile int g_running;
extern volatile int g_cur_bar; /* bar being heard, -1 if none */
extern volatile uint32_t g_hit_until_ms[SB_NT];
void seq_core1_main(void);
/* app.js learned(): the channel and note a kit track was learned with. Returns 0 if not learned. */
int learned(const live_t *L, int tr, int *ch, int *note);
#endif