ToneCommand GitHub

Docs

Tone Recipes

A recipe is HOW to build a tone, not the tone file itself: a named, cited, replayable list of ToneCommand actions. You share the knowledge; everyone replays it on their own unit against their own base preset.

Finding and sharing them

Reading needs no account. Recipes live in this repository's recipes/ folder, which is public, so the app fetches them straight out of it and browses them in place. Nobody signs in, nobody clicks through a web UI.

Sharing has two paths, because the two halves of this are not equally hard and pretending one route fits everyone is what went wrong first. SHARE RECIPE saves the file into your own recipes/ folder and puts it on the clipboard, so you can pass it on however you already talk to people. If you do use GitHub, it will also open a prefilled new file in recipes/, where one button turns it into a proposal.

It used to open a prefilled GitHub issue. That was wrong three ways at once: an issue is not a container for a recipe, the tracker would silt up with them, and it asked a guitarist to learn a developer's tool before they could give anything back.

Why recipes and not preset files

Format (v1)

{
  "recipe_version": 1,
  "name": "goodbye-yesterday-rock-intro",
  "title": "Goodbye Yesterday: dry crunch intro + produced body",
  "device": "FM9",
  "author": "monzta1",
  "tested_firmware": "11.00",
  "sources": [
    "E Edwards (Elevation Rhythm) official tutorial: heavy OD throughout,
     small room reverb, two-delay staging"
  ],
  "assumes": "an 8-scene preset with amp, drive, delay and reverb blocks",
  "actions": [ ...planner-vocabulary actions... ],
  "ear_checklist": ["soft picking sings, never chokes", "..."]
}

Actions use exactly the planner's vocabulary (set_scene, set_param, set_bypass, set_channel, set_type, set_tempo, add_block, bind_pedal, rename_scene). store is FORBIDDEN in recipes: replay is edit-buffer only, and storing stays a human decision at the console.

Citing a real capture as the tone target (#18)

An optional tone_target says which real, recorded sound a recipe is built to approximate:

"tone_target": {
  "source": "TONE3000",
  "capture_id": 57410,
  "note": "Real capture of a Mesa Boogie Mark V, clean channel."
}

source is currently only ever "TONE3000"; no other capture source is wired up. On an A2-capable device the cited capture IS the tone; on the FM9 the recipe's own steps are the grounded approximation of the same real gear. capture_id must name a capture that is actually on file in config/nam_capture_models.json, the facts-only sidecar harvested from TONE3000's own API by tools/build_nam_captures.py (real title, the capture author's own stated gear identity, creator, licence and a checkable URL, nothing invented). Citing an id that is not in that sidecar is refused before replay does anything else: an AI never invents a citation.

Recommending or ranking captures by evidence (accuracy, provenance tier, creator track record) is not part of this: this pass only checks that a citation someone already chose is real. Presenting ranked, evidence-backed candidates is future work.

Using a capture, by reference (#153)

A recipe whose amp IS a capture (rather than a model approximating one) carries the capture by reference, never the file:

"capture": {
  "source": "TONE3000",
  "tone_id": 57410,
  "model_id": 353891,
  "url": "https://www.tone3000.com/tones/mesa-boogie-mark-v-57410",
  "license": "t3k",
  "sha256": "<sha256 of the .nam the sharer has>",
  "stands_for": {"block": "amp", "type_name": "USA Lead+"}
}

Those are the only keys. sha256 is the file the sharer built with; stands_for names the amp model the recipe builds with when the capture is not available, so the recipe always builds. A recipe whose capture field carries file data (bytes, a data: URI, a long base64 run) is refused by /api/recipes/save before it is saved or queued: captures are other people's work under their licence, and redistribution never happens through ToneCommand.

The recipient's ToneCommand resolves the capture when the recipe is used and says which of four things happened:

In every case but the first the recipe builds with stands_for and the line names the amp the capture stood for. Installing the capture onto a unit is I4's (#147); this is the recipe format and the recipient path.

Replaying

python tools/replay_recipe.py recipes/name.json            # dry-run: validate only
python tools/replay_recipe.py recipes/name.json --apply    # edit buffer
TONECOMMAND_SIM=1 ... --apply                              # simulator

Every action is validated against the connected device's schema first; the run stops at the first failure; the ear checklist prints at the end because read-backs are not proof of tone.

Source: docs/RECIPES.md in the repository.