Tools to help your sightreading, tune, tone, and more.
Local-first Raspberry Pi tools for single-note music practice.
NOTEMACHINE= overall projectseton2= flashcard deck generatortonewatch= instrument/intonation tunerTreblingTuner= flashcard display on "heard" notes
Entrypoint scripts:
src/notemachine/seton2_generate.pysrc/notemachine/tonewatch.pysrc/notemachine/notemachine.py(TreblingTuner launcher)
tonewatch.py listens to live audio, filters noise, stabilizes pitch, and reports notes in real time. This can be used to tune an instrument, practice pitch, steady tonality with breath control, and skill across a range.
notemachine.py builds on the same detector but displays flashcards. In relative mode, it keeps notes readable in a fixed treble-staff window (C4..D6) and uses arrows for out-of-range octaves.
Seton2 (version 2 of the project "notes" spelled backward) generates the flashcard assets used by TreblingTuner. In addition to avoiding using copyright assets, this allows a developer to generate note ranges on demand at different resolution, layouts, or colors. A second "ghost" deck can be generated where pale same-letter note locations are baked into each card.
./install_pi.sh
# Optional Whisplay stack
bash scripts/pi/install_whisplay_driver.sh
source .venv/bin/activate
python src/notemachine/tonewatch.py
python src/notemachine/notemachine.py --mode followThe guided installer lets users choose whether to install/enable a systemd service. The systemd service is especially helpful for Raspberry Pi Zero 2 projects with batteries.
For developing on a separate machine and deploying to a remote Pi:
-
Sync code to the Pi (use rsync, scp, git, or your preferred method):
rsync -az --exclude '.venv/' --exclude '__pycache__/' . user@hostname:~/notemachine/
-
SSH to Pi and run guided install:
ssh user@hostname cd ~/notemachine ./install_pi.sh --no-service
-
Optional: install and enable background service on boot:
./install_pi.sh --with-service
Sync changes and run:
rsync -az --exclude '.venv/' --exclude '__pycache__/' . user@hostname:~/notemachine/
ssh user@hostname "cd ~/notemachine && source .venv/bin/activate && python -m notemachine.tonewatch"Or develop directly on the Pi if you prefer local workflows. The nicest environment used in initial development was vscode in Raspberry Pi Desktop, with the Pisugar Whisplay plugged into the GPIO port.
# Interactive (asks whether to install service)
./install_pi.sh
# Explicitly install + enable service
./install_pi.sh --with-service
# Explicitly skip service
./install_pi.sh --no-service
# Fast path: refresh service unit/env/config only (no apt/pip reinstall)
bash scripts/pi/refresh_service.shService behavior can be customized in /etc/default/notemachine:
APP_MODULE=notemachine.notemachine(default main app)APP_ARGS=--mode follow(default args)
This is intended to support future hardware/runtime variants without replacing the installer.
Use notemachine.toml.example as the baseline config.
Config lookup order:
- CLI:
--config /path/to/notemachine.toml - Env:
NOTEMACHINE_CONFIG=/path/to/notemachine.toml ./notemachine.toml~/.config/notemachine/notemachine.toml/etc/notemachine.toml
The installer seeds /etc/notemachine.toml on first service install.
Current runtime consumers:
notemachine.notemachine([runtime]+[notemachine])notemachine.tonewatch([runtime]+[tonewatch])
# ToneWatch tuner
python src/notemachine/tonewatch.py
python src/notemachine/tonewatch.py --no-whisplay
python src/notemachine/tonewatch.py --list-devices
# TreblingTuner
python src/notemachine/notemachine.py --mode follow
python src/notemachine/notemachine.py --mode follow --instrument recorder
python src/notemachine/notemachine.py --mode follow --instrument other
python src/notemachine/notemachine.py --mode target
# Audio loop diagnostics
python src/notemachine/looptest.py --freq 440 --input-device 1 --output-device 1
python src/notemachine/zelda_tuning.pyTested baseline:
- Raspberry Pi 5 (Bookworm and Trixie tested)
- WM8960 audio codec input path (included on Whisplay board)
- Whisplay LCD/RGB board
Supported modes:
- With Whisplay: full LCD + RGB output
- Without Whisplay: terminal-only output (
--no-whisplay). This is useful for development and porting to new hardware.
Where to adapt hardware behavior:
- Input device selection heuristics:
src/notemachine/tonewatch.py(resolve_input_device) - Whisplay init / fallback:
src/notemachine/tonewatch.py(maybe_init_whisplay) - LCD rendering:
src/notemachine/tonewatch.py+src/notemachine/trebling_tuner.py - Pi setup/install scripts:
scripts/pi/bootstrap_pi.sh,scripts/pi/install_whisplay_driver.sh
Seton2 is integrated in src/notemachine/seton2/.
Default generation config:
assets/seton2/seton2.toml- Default range is instrument-practical:
C4..D7 - Default outputs:
assets/seton2/default_cards/assets/seton2/ghost_cards/
Generate cards:
python src/notemachine/seton2_generate.py
python src/notemachine/seton2_generate.py --force-rebuild
python src/notemachine/seton2_generate.py --min-note C4 --max-note D7
python src/notemachine/seton2_generate.py --no-ghostsNote: lilypond is required when Seton2 cards are regenerated. This and other dependencies can take a long time to install on Raspberry Pi Zero 2/2W.
Ghosts explained:
- A ghost card is a normal flashcard plus pale same-letter notes at alternate octaves in the staff window.
- Example: a displayed
C5card can include paleC4andC6note locations. - TreblingTuner prefers ghost cards by default when the ghost manifest exists.
The original Mermaid flowchart was removed for readability. A rewritten flow overview can be added back as a plain-language sequence diagram.
src/notemachine/runtime apps, diagnostics, Seton2 integrationsrc/notemachine/seton2/flashcard generation internalsassets/seton2/generated card assets + Seton2 configscripts/pi/Pi bootstrap, driver install, runtime verificationdocs/setup notes and design referencesrequirements.txtPython dependenciesrequirements/pi-apt.txtRaspberry Pi system package dependencies
docs/dev-environment.mddocs/whisplay-rebuild.mddocs/seton2.mddocs/seton2_config.mdPROCESS.md(development narrative)