khodowany 85cab9d6f6
ci / checks (push) Successful in 2h10m42s
Fix
2026-09-19 08:18:45 -05:00
2026-09-16 22:54:03 -05:00
Fix
2026-09-19 08:17:25 -05:00
Fix
2026-09-19 07:57:19 -05:00
Fix
2026-09-19 08:17:25 -05:00
Fix
2026-09-19 08:17:25 -05:00
2026-09-04 19:30:11 -05:00
Fix
2026-09-19 08:17:25 -05:00
Fix
2026-09-19 08:17:25 -05:00
Fix
2026-09-19 08:17:25 -05:00
2026-09-15 00:06:02 -05:00
2026-09-11 00:02:36 -05:00
2026-09-04 19:30:11 -05:00
2026-09-16 22:54:03 -05:00
2026-09-04 19:30:11 -05:00
2026-09-17 00:44:19 -05:00
2026-09-16 22:54:03 -05:00
Fix
2026-09-19 08:17:25 -05:00
2026-09-04 19:30:11 -05:00
Fix
2026-09-19 08:18:45 -05:00

Product Vamp

Product Vamp is a two-device sheet-music appliance.

  • Raspberry Pi Zero 2 W hosts the control Wi-Fi AP, runs the display/control service in Docker, and drives a Waveshare Zero-DISP-7A 1024x600 touch display.
  • Raspberry Pi Pico 2 W runs UF2 firmware for a Waveshare 2-inch capacitive touch LCD and sends menu/page commands over the Zero-hosted AP.

Python builds the complete SQLite catalogue with the score assets. The Zero opens that packaged catalogue read-only through Noto, without creating a database, migrating schemas, or importing JSON at startup. Runtime navigation and rendering use Ligo for the HTTP API, Luma for touch UI rendering, and Modulus for shared build/runtime utilities.

The catalogue stores shared, immutable menu metadata. Complete score bundles stay in SQLite and are loaded individually when selected; snapshots and Pico heartbeats do not copy the catalogue's musical JSON.

Pico controls:

  • Tap: next menu item or next score page.
  • Double tap: previous menu item or previous score page.
  • Tap and hold: select the highlighted mode/song/part/practice row/key, or return from score view to the previous menu.

Build

Configure and build the native development target:

python3 modulus.py configure
python3 modulus.py build

Release verification:

python3 modulus.py configure --target x86_64_gcc12_release
python3 modulus.py build --target x86_64_gcc12_release

python3 modulus.py run uses package/config/vamp.development.json for a headless readiness check against native build assets. vamp-zero --once checks the packaged database and referenced page/audio assets, checks runtime writes and the server bind, then exits without opening audio or display hardware. Missing or incompatible catalogues require rebuilding or reinstalling; they are never repaired at runtime. --check-config only validates configuration; --health-check probes the running service's /api/health endpoint without modifying files.

Configure/build can read public packages anonymously from the khodo Conan registry.

Refresh clangd compile databases, including the Pico firmware database, with:

python3 modulus.py lsp

When running directly outside the generated Modulus Docker image, set PICO_SDK_PATH before refreshing the Pico database.

Editor settings live in modulus.json under tooling.editor. Modulus generates the ignored .clangd, .clang-format, and pyrightconfig.json files; edit the JSON settings rather than these outputs. The clangd configuration routes Zero/shared code to the native compile database and Pico code to its firmware database.

Modulus also generates .nvim.lua for Neovim 0.11+ with exrc enabled. Review and trust it when Neovim asks; it preserves the existing LSP capabilities/keybindings and runs clangd 19 in the build container for this repo. Run python3 modulus.py lsp once to prepare both databases and the shared read-only header cache. Other editors can use python3 modulus.py clangd as their language-server command. Startup never downloads or builds anything, and never falls back to host clangd.

tooling.lsp.clangd configures the server executable, arguments, trusted compiler paths, and additional header roots. Product Vamp adds the bare-metal ARM compiler and /opt/pico-sdk; standard-library and SDK definitions open from an image-keyed cache under $XDG_CACHE_HOME/modulus/clangd (default ~/.cache/modulus/clangd). Set tooling.editor.nvim.enabled to false for a hand-managed editor setup. Existing unowned .nvim.lua files are preserved.

Package

Product packaging targets Raspberry Pi OS/Debian trixie on ARM64 and optionally builds Pico firmware. Set PICO_SDK_PATH when building the firmware artifact:

PICO_SDK_PATH=/path/to/pico-sdk python3 modulus.py package --version latest --update

The package command creates:

build/packages/product-vamp-latest-arm_64_gcc12_release.tar.gz
build/packages/product-vamp-latest-arm_64_gcc12_release.tar.gz.sha256

The tarball contains the Zero Docker archive, Pi install scripts, generated catalogue database, pages, audio, fonts, and Pico UF2 firmware. Complete score JSON is stored inside catalogue.db; individual JSON files remain build intermediates and are not deployed.

Run sudo zero/install-zero.sh from an extracted bundle on the Zero. Every installation resets all Product Vamp data and settings, including the control Wi-Fi profile, to the new bundle defaults. No previous database rows or configuration are migrated. Unrelated OS data and networks are untouched. Installing through the control Wi-Fi can disconnect your session; use a local console or an independent connection.

The installer probes the incoming image before removing existing application data. A failed replacement leaves Product Vamp stopped and reports an error; rerun the installer after fixing the cause. Normal service restarts do not perform installation cleanup. No automatic backup of the previous installation is retained.

Publishing the rolling generic package requires credentials only for upload:

PACKAGE_REGISTRY_USER=<user> \
PACKAGE_REGISTRY_TOKEN=<token> \
python3 package/scripts/publish_latest_generic_package.py

Artifacts are published to the khodo generic package registry.

Score Assets

Uncompressed MusicXML 3.1/4.0 scores exported from MuseScore live in data/. Generated score JSON is not committed. To inspect generated assets without building the full package, run:

python3 -m generator --data-dir data --output-dir /tmp/product-vamp-generated --static-assets-dir package/assets --clean --check

The --check path compares generation invariants against data/expected/performance_summary.json. The pinned build-only dependencies are in generator/requirements.txt. Configure/build automatically refresh the project build image when this file changes; direct builds must install it in their Python environment.

The build-time pipeline is MuseScore -> .xml -> musical model -> automatic arranger/transposer -> schema-v3 JSON, engraved PNG pages, and generated-tone audio assets. The Pi displays pages without interpreting notation. Performance sources produce acoustic, electric, and vocal parts; melody and chord exercises produce twelve tonic variants relative to their authored key. Independent voices and exact pitch/rhythm remain in the semantic JSON. Chord practice preserves the authored voicings, shifting the entire exercise by an octave only when needed for guitar. Chord practice and generated guitar voicings use standard tuning, frets 0-15 inclusive, and a maximum four-fret span excluding open strings.

Practice notation supports repeat bars and numbered endings. Python expands the performed order for playback and before automatic performance arrangement. The main menu's Playback toggle plays the selected key variant or performance part at the menu BPM, suppresses the metronome, and returns to its selection menu after natural completion. Manual page turns do not seek or restart audio. Playback is off by default. Python generates shared PCM tones and exact beat timelines; C++/Sonus only loads, schedules, and mixes them. No SoundFonts or runtime synthesizer are required. The practice category layout is unchanged.

Code style is managed by Modulus. Run ./modulus.py format to format C++ and Python, or ./modulus.py format --check to check formatting and prohibited aliases. The project-local Neovim integration routes Conform formatting through the same container tools, including format on save and existing LazyVim toggles. Run configure first when the image or exported tooling needs updating. Use tooling.editor.clang_format for C++ overrides and tooling.format.exclude for project-relative exclusion globs; do not edit generated .clang-format files.

See Score Generation for supported MusicXML notation, Vamp properties, schema details, and diagnostics. There is no compact-JSON source format or legacy runtime adapter. Unsupported notation fails generation before existing assets are replaced.

Build-time engraving is implemented in Python in generator/engraving, using the bundled Petaluma OTF fonts and SMuFL metadata. MuseScore is an optional authoring tool, not a build dependency or rendering backend. The managed image and CI install the pinned Python requirements automatically; direct host builds use pip install -r generator/requirements.txt. Exact musical timing is retained through layout, and dense measures can continue across systems without shrinking the notation. Missing glyphs, unrepresentable page geometry, and failed notation audits stop generation before replacing existing assets.

Petaluma is from Steinberg under the SIL Open Font License. Runtime packages include PNG score pages, PetalumaScript.otf for UI text, and OFL.txt; the music font and engraver stay build-only.

Font generation requires Pillow's Raqm layout support to preserve kerning. On Debian/Ubuntu, install libfribidi0 alongside the pinned Python requirements. The build image and CI install both. See Pillow's installation requirements.

Native and Pico builds generate their bitmap font implementation under generated/vamp_style/font.cpp in the build directory. The generated implementation is not checked in. The build image and CI install the pinned generator dependency automatically. For a direct build, first run:

python3 -m pip install -r generator/requirements.txt

To check a generated atlas, run python3 generator/generate_pico_font.py --output build/build_x86_debug/generated/vamp_style/font.cpp --check. Changing the source OTF or generator rebuilds the atlas automatically.

License

Product Vamp is released under the MIT License. Bundled third-party fonts keep their own licenses next to the font files.

S
Description
No description provided
Readme MIT 123 MiB
Languages
Python 70.6%
C++ 26.7%
CMake 1.6%
Shell 1%
C 0.1%