- Pace dropdown REMOVED from Phrase setup — replaced by a 'Sync to
exercise' checkbox in the Metronome widget (analog to 'Auto' in
single-note modes). pace is derived from the checkbox (checked = tempo,
unchecked = step).
- Preview clicks now registered in PREVIEW_GROUP: stopping/abandoning a
preview cancels its scheduled clicks — no more parallel ghost
metronomes after preview->stop->next exercise.
- Chord pool replaces the chord dropdown entirely (single chord AND
sequences): togglable degree list, empty = all 7.
- Giuliani figures corrected to NOTE sequences (p always takes the bass/
root): p-i-m, p-i-m-a, p-a-m-i, a-i-m, p-i-m-a-m-i, p-m-a-m-i-m,
p-e-a-m-a-m (replaced the fingering-driven patterns that made no
musical sense).
- 'Limit notes' is now one bordered section like Tuner/Metronome, with a
header, Clear-all link, and Strings behind a toggle (row hidden until
restricted).
- 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).