- Sequence mode: bars (2/4/6/8) with one chord per bar, chosen by
functional rules (I->IV/V/vi...), diatonic cycle, or random (no immediate
repeats); deterministic via melody seed. Chord symbols per bar in the
score model (chordSymbols) rendered above the staff via setSection.
- Rhythm: quarters or eighths (cycling up/down through the pattern).
- Single-chord mode unchanged (whole path, overflow bars if needed).
- Auto-start: 'Start on first note (no count-in)' — step pace begins the
run as soon as the mic detects the first note; no start press needed.
- 'New' button re-rolls the progression (new seed).
- Tests 174/174.
- music/arpeggioGenerator.ts: diatonic triads (I-vii*) built from the
selected key/mode via the shared degree spelling; patterns up / down /
up-down / 1-2-3-5; one or two octaves (cycle ends on the octave; two-
octave path continues from the turning root). Quarter-note rhythm with
final note extended to fill the bar; title is labeled 'Arpeggio -
<tonic> <degree> (pattern, coverage)'.
- Settings: PhraseMaterial 'arpeggio' + arpeggioDegree/Pattern/Coverage
(defaults I / up / one-octave).
- PhraseTrainer: material option 'Arpeggios (generated)' + Chord/Pattern/
Coverage/Meter selects; key/mode reuse the shared Target key controls.
- Tests: 9 arpeggio cases (170 total).
- Metronome/phrase: 'With tempo' renamed to 'Sync to metronome' (auto-enables
the metronome when selected); phrase click now yields to the metronome
click (no more double clicks) with an explicit opt-out checkbox.
- Count-in: subtle numeric badge next to the status line (muted pill, 11px).
- Melody rhythm level 3 'Elaborate': sixteenth/dotted-eighth templates for
4/4 and 3/4; renderer supports 120/360-tick codes and beams 16th pairs.
- Transpose control for library/import material widened to ±2 octaves.
- Tests 161/161 (bar-total invariants hold over 500 seeds at level 2).
- Strings filter: per-string toggle buttons (replaces fret-window-only
semantics as a third 'limits notes' control); combines with fret window
and key filter in targetPool (fretted instruments).
- Key sync checkbox: display key signature can follow the target key
(major/minor mapping), default off — both remain independently settable.
- LiveNoteStaff: optional fixed clef — guitar/bass now keep their usual
clef instead of flipping at middle C; octave markers handle range.
- Unified metronome widget (MetronomeWidget) with animated linear pendulum
synced to the audible click; shown in ALL modes next to the tuner.
Phrase BPM now reads from settings.rhythm.bpm (single source); the
phrase-local BPM control was removed from the setup panel.
- Tests: 160/160; tsc + eslint clean; build ok.
- New shared PracticeFilter settings (keyTonic/keyMode/fretWindow), persisted
via AppSettings.practice, defaults off (behavior unchanged).
- music/targetPool.ts: single source for the effective target pool —
base playable range ∩ fret window ∩ key/mode pitch classes (9 modes incl.
pentatonic, same scale machinery as Phrase Mode).
- useGameLogic now builds validNotes via computeTargetPool.
- TargetNoteControls component (key on/off + tonic/mode, fret window on/off +
min/max) rendered in Controls for all game modes; key is independent of the
displayed key signature.
- Phrase Mode binds its key/fret-window setup to the same shared filter
(read/write mirror) and drops the duplicate controls in its setup panel.
- Tests: targetPool.test.ts (7 cases); suite 156/156 green, build ok.
- Pick detector per instrument range: ACF2PLUS (robust down to ~40 Hz) for
normal instruments, YIN only for the whistle register. pitchfinder's YIN
latches onto tau=2 (~20 kHz garbage) below ~100 Hz and for quiet input;
the old fixed 4096 window masked this, the smaller window exposed it.
- RMS-normalize analysis input for the YIN path only; ACF2PLUS keeps the raw
signal so its internal unpitched gate rejects quiet decayed audio instead
of amplifying noise into confident wrong pitches (tuner stuck on 'a note').
- Adaptive analysis window sized to the instrument's lowest note (~2 periods):
half the latency, a quarter of the CPU for guitar/piano/voice; bass keeps
the full window for E1.
- Reject detections implausibly below the instrument floor (mains hum).
- Clear stale pitch readings after 200 ms instead of keeping them forever.
- Shared AudioEngine singleton for all playback (was: two AudioContexts);
tracks audibility so the app stops hearing its own speaker (ear-training
self-scoring) and gates matching plus display during playback.
- MatchTracker: grace-period based note hold instead of reset-on-every-flicker
(YIN flickers during attacks/decays; the old hard reset made the 50 ms
threshold fire unreliably).
- Display damping in the producer (EMA for cents/level, 3-frame note-name
hysteresis); display components render directly without CSS transitions.
- Regression tests: synthetic signals through the exact pipeline helpers
(MatchTracker + pitchDetection test suites).