Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

scoredata-forge

Deterministic sample-library foundry: turns a TOML recipe into a complete, CC0, SFZ sample library (wav + sfz + checksums + provenance) ready for adoption into the ScoreData corpus.

This tool exists because the scorekit roadmap adjudicated a small set of instrument assets (music box, whistle, a dedicated Dubstep growl/talking bass, and the adjudicated Disco drum-machine, Clavinet, synth-brass, and House-stab gaps) as first-party synthesized — either structurally simple timbres with no license-clean recorded source, or a source-neutral control-response gap the open sample corpus cannot fulfill. scorekit itself must never grow creative DSP (an iron rule); this repo is the separate home where that synthesis lives.

The seam contract

forge is outside scorekit's iron-rule jurisdiction, but the boundary is a hard contract, enforced by tests (tests/test_boundary.py):

  1. Output-only coupling. forge never imports scorekit; scorekit never invokes forge. The only shared vocabulary is data: DSL instrument-name strings and the SFZ/wav formats.
  2. No pipeline bypass. Built libraries enter ScoreData exactly like any downloaded library: manifest → license + checksum → catalog → scorekit profile check. Nothing forge emits is trusted implicitly.
  3. CC0 self-published. Every built library carries a CC0-1.0 dedication and a generator.json provenance record (first-party-synthesized).
  4. Allowlist mirrors the roadmap. forge build refuses any instrument not listed in forge/allowlist.toml; that list mirrors the adjudication in scorekit's docs/roadmap.md. Adding an instrument requires amending the roadmap first — synthesis is not an escape hatch around sample acquisition.
  5. Hermetic. stdlib-only Python (≥ 3.11), no network access, no timestamps in output.

Quickstart

# no dependencies to install — Python ≥ 3.11 stdlib only
python3 -m forge build recipes/music-box.toml -o out
python3 -m forge build recipes/whistle.toml -o out
python3 -m forge build recipes/dubstep-growl.toml -o out
python3 -m forge build recipes/drum-machine-modern.toml -o out
python3 -m forge build recipes/drum-machine-80s.toml -o out
python3 -m forge build recipes/drum-machine-house.toml -o out
python3 -m forge build recipes/clavinet.toml -o out
python3 -m forge build recipes/synth-brass.toml -o out
python3 -m forge build recipes/house-stab.toml -o out

python3 -m forge lint out/music-box/1.0.0
python3 -m forge lint --strict-loop out/whistle/1.0.0   # sample-exact loop seams
python3 -m forge lint --strict-loop out/dubstep-growl/1.0.0
python3 -m forge verify out/whistle/1.0.0               # rebuild + checksum diff
python3 -m forge verify out/dubstep-growl/1.0.0

(Or pip install -e . for a forge console script.)

A built library looks like:

out/whistle/1.0.0/
├── whistle.sfz            # velocity layers, loop points, pitch mapping
├── samples/*.wav          # mono 16-bit PCM
├── SHA256SUMS             # per-file checksums (the golden identity)
├── recipe.toml            # byte-copy of the input recipe
├── generator.json         # tool version, recipe hash, seed, python, platform
├── manifest-fragment.yaml # paste-helper for a ScoreData manifest
├── LICENSE.txt            # CC0-1.0 dedication
└── README.md              # regeneration instructions

Determinism stance

Same recipe + same forge version + same platform + same Python build ⇒ byte-identical output (forge verify proves it; SHA256SUMS is the identity). All randomness is derived from the recipe seed via SHA-256-keyed streams — build order, machine, and wall clock never matter.

Bit-exactness across platforms is not promised (libm differences); cross-platform equivalence is validated downstream by scorekit profile check, which is the gate that matters for adoption.

The whistle's loop is sample-exact by construction: the fundamental is quantized to integer cycles per loop (residual exported as an SFZ tune offset), vibrato is integer-cycle phase modulation, breath noise is an exactly-periodic buffer, and envelopes complete before loop_start — so sample[n + L] == sample[n] holds exactly, enforced by tests/test_loop.py and forge lint --strict-loop.

SFZ lint

forge lint encodes defect classes found in real corpus repair work:

  • reversed paired opcodes (lokey>hikey, lovel>hivel, loop_start>loop_end) — the Polyphone-export bug that silenced an entire upstream library;
  • missing sample files (default_path-aware, full header cascade);
  • loop_end beyond the wav's last frame;
  • --strict-loop: exact seam verification for forge-built libraries.

It works on any .sfz, not just forge output.

Adopting a build into ScoreData

  1. forge build + forge lint --strict-loop + forge verify.
  2. Copy the library directory into the corpus and write a manifest (start from the emitted manifest-fragment.yaml); record checksums.
  3. Map it in a renderer profile and run scorekit profile check — the same deterministic, non-silent gate every sampled library passes.
  4. Rebuild the catalog. The library is now a normal corpus citizen; its recipe here is its source code.

Working across the whole constellation (scorekit, scorebench, samples, ScoreData)? The committed multi-repo map is scorekit-workspace.json in the scorekit repo; run python3 scripts/workspace.py doctor there to check/bootstrap the layout.

Tests

python3 -m unittest discover -s tests -v

Golden-hash tests are opt-in and pinned to the recorded platform and exact Python patch release: FORGE_GOLDEN=1 runs them only on that matching runtime.

License

  • Tool code: MIT (see LICENSE).
  • Recipes and all built sample libraries: CC0-1.0 (public domain dedication).

About

Deterministic sample-library foundry: TOML recipes -> CC0 SFZ libraries for the ScoreData corpus

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages