# Tonic — Patch Authoring Kit

*Generated from the running parameter tree of Tonic 2.5.4 on 23 Sep 2026. Do not edit by hand:
`python3 ios/tools/gerar-kit-timbres.py` rebuilds it.*

This is everything an assistant — any assistant — needs to read, edit and write Tonic patches so
that they open in the app and actually sound like something. It is deliberately plain text: no
tooling, no account, no API.

---

## 1 · The five rules

**1. Start from a file the app exported.** In Tonic: long-press a preset (or a bank) → *Export*.
You get a `.tpr`. Edit that. Do not build a patch from an empty page — a preset carries fields
beyond the knobs (scenes, sources, arp, chord, MIDI filter), and a file that omits them silently
loses them.

**2. Keep the extension.** Timbres are **`.tpr`**; a full library backup is **`.tbk`**. The app
reads by CONTENT, not by name, so a renamed file still opens — but the extension is the only thing
a person sees before opening, and it decides how the app treats the file: a `.tpr` merges into the
library without asking, a `.tbk` asks first, because restoring a backup is a serious act. Write
`.tpr` and everyone downstream stays compatible.

**3. Never invent an identifier.** Only the identifiers in §4 exist. An unknown key is ignored in
silence — the patch will open, look fine and not sound the way you wrote it.

**4. Keep `id`, `schema` and `isFactory` exactly as they came.** `schema` tells the app which
migrations to run on that patch; dropping it makes an old patch be read with today's rules.
Patches you author are `"isFactory": false` with an id starting `u/`. Never ship one as
`isFactory: true` — that marks it as ours and makes *Reset All* eat it.

**5. Values are not percentages.** Read §3 before writing numbers. This is the difference between a
patch that sounds designed and one that sounds random.

---

## 2 · The file

A `.tpr` is UTF-8 JSON. The envelope:

```json
{
  "format": "tonic",
  "v": 1,
  "kind": "preset",
  "app": "Tonic",
  "appVersion": "v2.5.4 (115)",
  "created": "2026-09-23T12:00:00Z",
  "banks": [ { "id": "u/…", "name": "My Patches", "presets": [ … ] } ]
}
```

`kind` is `preset` · `bank` · `library` · `backup` — exporting a whole bank gives you `bank`, a
single timbre gives `preset`. Only `backup` uses `.tbk`. `appVersion` is a label, not a gate: a
file written by an older app opens fine in a newer one, which is the direction that matters.

Each preset inside `banks[].presets[]`:

| field | type | what it is |
|---|---|---|
| `id` | string | stable. `u/<uuid>` for yours, `f/<bank>/<slug>` for factory. **Never reuse a factory id.** |
| `name` | string | shown in the browser. No brand names — see §5. |
| `values` | object | **the sound**: `{"identifier": number}`. Everything in §4. |
| `schema` | number | format version of this patch. Keep what came. |
| `isFactory` | bool | `false` for yours. |
| `favorite` | bool | the ★. |
| `tags` | array | from a fixed list (Bass, Pad, Lead…); free text is not accepted. |
| `sources` | array | per-layer SF2/DX7/wavetable file references. Keep as they came — a name that does not exist on the other machine loads silently empty. |
| `scenes` | array | A–F snapshots of the whole patch. Optional, and heavy: each one is a full copy of `values`. |
| `lastScene` | number | which scene was active when saved; recalled on load. |
| `macro`, `vectorPath`, `followSources`, `arpPattern`, `arpScenes`, `chordNotes`, `midiFilter`, `midiFilterOff`, `transpose`, `pitchBendRange`, `pitchBendRangeDown`, `modWheelTarget`, `modWheelMin/Max/Amount`, `midiMapName` | — | performance state that is **not** a parameter. If you are not changing it, copy it through untouched. |

A parameter missing from `values` takes its default (the table in §4). A patch only needs to carry
what it changes — but when editing an export, leave the rest alone.

**Layers.** Tonic has three oscillators. A per-layer identifier appears three times: bare for
OSC 1, `_2` for OSC 2, `_3` for OSC 3 (`attack`, `attack_2`, `attack_3`). A few are numbered
instead (`mixVol1/2/3`). The table marks which ones repeat.

---

## 3 · What the numbers mean

**Every value is stored in the parameter's own unit** — the `unit` column in §4. Seconds are
seconds, Hz are Hz. The `travel` column (`log`/`lin`) tells you how the *knob* moves under a
finger; it never transforms the stored value, so nothing needs converting on the way in.

Where a parameter is a plain `number` from 0 to 1, the number by itself does not say what it will
sound like. These are the ones worth knowing before writing a patch:

**Envelope times** (`attack` `decay` `hold` `release`, and the filter-envelope twins) — stored in **seconds**, 0.001–45. `0.3` is 300 ms. The knob's travel is shaped so the useful range is reachable, but that shaping does not touch the stored number — do not pre-warp it.

**Frequencies** (`cutoff`, `lfoRate`, EQ and delay times) — stored in **Hz** (or seconds), in the real unit. `cutoff: 630` is 630 Hz. The `log` column describes how the knob moves, not the value: never convert.

**Sustain** (`sustain`, 0–1) — stored as **amplitude**, and the ear hears decibels: `0.5` = −6 dB, `0.1` = −20 dB, `0.03` = −30 dB. A pad that decays but stays present lives around 0.1–0.3, not 0.45. `0` is special: the voice ends when the decay ends.

**Breath on a wind voice** (`physP2` while the model is Blow) — the useful range is **0.02–0.06** — the factory wind patches sit there. Above ~0.2 it is a gale, not a breath. This one is the most common way an authored wind patch sounds wrong.

**Resonance** (`resonance`, 0–1) — calibrated so the same value gives the same *fraction of that flavour's own range*. The ceilings differ by physics — Snap screams, OTA does not —, so copying a resonance value between voicings does not copy the amount of scream.

**Anything with options** (`mode`, `voicing`, `waveform`, …) — whole numbers only; the names are in the table. `1.4` rounds and may land somewhere you did not intend.


> The rule of thumb: **write the value in the unit the table gives, and treat the plain 0–1 ones as
> perceptual.** Going from `sustain: 0.5` to `0.45` is inaudible; going to `0.1` is a different
> patch.

---

## 4 · The parameters

Generated from the tree. **Range** is what the app accepts; writing outside it is clamped.
**Default** is what you get when the key is absent. `log` marks a logarithmic control.
*Layers* means the identifier repeats as `…_2` and `…_3` for OSC 2 and 3.

| identifier | name | range | default | unit | travel | layers | options |
|---|---|---|---|---|---|---|---|
| `cutoff` | Cutoff | 20 – 20000 | 1000 | Hz | log | yes | — |
| `resonance` | Resonance | 0 – 1 | 0 | number | lin | yes | — |
| `mode` | Mode | 0 – 3 | 0 | index | lin | yes | Lowpass · Highpass · Bandpass · Notch |
| `slope` | Slope | 0 – 1 | 1 | index | lin | yes | 12 dB/oct · 24 dB/oct |
| `voicing` | Voicing | 0 – 7 | 7 | index | lin | yes | Lad · Silk · Snap · Acid · Scrm · 2-Pol · LPG · OTA |
| `drive` | Drive | 0 – 1 | 0 | number | lin | yes | — |
| `mix` | Mix | 0 – 1 | 1 | number | lin | yes | — |
| `envAmount` | Env Amount | -1 – 1 | 0 | number | lin | yes | — |
| `envAttack` | Env Attack | 0.1 – 500 | 10 | ms | log | yes | — |
| `envRelease` | Env Release | 1 – 2000 | 150 | ms | log | yes | — |
| `lfoRate` | LFO Rate | 0.01 – 50 | 1 | Hz | log | yes | — |
| `lfoSync` | LFO Sync | 0 – 6 | 0 | index | lin | yes | Off · 1/1 · 1/2 · 1/4 · 1/8 · 1/16 · 1/32 |
| `lfoDepth` | LFO Depth | 0 – 1 | 0 | number | lin | yes | — |
| `lfoShape` | LFO Shape | 0 – 6 | 6 | index | lin | yes | Sine · Triangle · Saw Up · Saw Down · Square · S&H · Off |
| `oversample` | Oversample | 0 – 3 | 3 | index | lin | yes | 1x · 2x · 4x · Auto |
| `output` | Output | -24 – 12 | 0 | dB | lin | yes | — |
| `mixVol1` | Vol 1 | 0 – 1.14286 | 0.8 | number | lin | — | — |
| `mixPan1` | Pan 1 | -1 – 1 | 0 | number | lin | — | — |
| `mixVol2` | Vol 2 | 0 – 1.14286 | 0 | number | lin | — | — |
| `mixPan2` | Pan 2 | -1 – 1 | 0 | number | lin | — | — |
| `mixVol3` | Vol 3 | 0 – 1.14286 | 0 | number | lin | — | — |
| `mixPan3` | Pan 3 | -1 – 1 | 0 | number | lin | — | — |
| `vecX` | Vector X | 0 – 1 | 0.5 | number | lin | — | — |
| `vecY` | Vector Y | 0 – 1 | 0.667 | number | lin | — | — |
| `vecMode` | Vector Mode | 0 – 4 | 0 | index | lin | — | Off · XY · Env · LFO · Path |
| `vecRate` | Vector Rate | 0.02 – 8 | 0.5 | Hz | log | — | — |
| `vecDepth` | Vector Depth | 0 – 1 | 1 | number | lin | — | — |
| `mixMute1` | Mute 1 | 0 – 1 | 0 | index | lin | — | Off · On |
| `mixSolo1` | Solo 1 | 0 – 1 | 0 | index | lin | — | Off · On |
| `mixMute2` | Mute 2 | 0 – 1 | 1 | index | lin | — | Off · On |
| `mixSolo2` | Solo 2 | 0 – 1 | 0 | index | lin | — | Off · On |
| `mixMute3` | Mute 3 | 0 – 1 | 1 | index | lin | — | Off · On |
| `mixSolo3` | Solo 3 | 0 – 1 | 0 | index | lin | — | Off · On |
| `velFilter` | Vel → Filter | 0 – 1 | 0 | number | lin | — | — |
| `keyTrack` | Key Track | 0 – 1 | 0 | number | lin | — | — |
| `model` | Model | 0 – 8 | 2 | index | lin | yes | Pluck · Mallet · Classic · Blow · Strings · Wavetable · SF2 · DX7 · Granular |
| `waveform` | Waveform | 0 – 35 | 1 | index | lin | yes | Sine · Organ · Saw · Hollow · Square · Bright · Triangle · Soft · Pulse · Nasal · Super Saw · Reed · Noise · Buzz · Bell · Glass · Vocal Ah · Vocal Ee · Vocal Oo · Metallic · Digital · Harmonics · Fifth · Saw · Fat Saw · Reese · Hoover · Square · Pulse 25 · Pulse 10 · Chip · Warm Pad · Glass Pad · Choir · Formant Eh · Formant Oh · Brass · Strings · EP Tine · Pluck · Growl · Sync · Sub |
| `damping` | Damping | 0 – 1 | 0.5 | number | lin | yes | — |
| `attack` | Attack | 0.001 – 45 | 0.005 | seconds | log | yes | — |
| `decay` | Decay | 0.001 – 45 | 0.12 | seconds | log | yes | — |
| `sustain` | Sustain | 0 – 1 | 0.8 | number | lin | yes | — |
| `release` | Release | 0.001 – 45 | 0.25 | seconds | log | yes | — |
| `level` | Level | 0 – 1 | 0.85 | number | lin | yes | — |
| `wtmMode` | Morph Motion | 0 – 4 | 0 | index | lin | — | Off · Env · LFO · Key · Vel |
| `wtmRate` | Morph Rate | 0.02 – 8 | 0.5 | Hz | log | — | — |
| `wtmDepth` | Morph Depth | 0 – 1 | 0.5 | number | lin | — | — |
| `drift` | Drift | 0 – 1 | 0 | number | lin | — | — |
| `phys1` | Model 1 | -1 – 1 | 0 | number | lin | yes | — |
| `phys2` | Model 2 | 0 – 1 | 0 | number | lin | yes | — |
| `phys3` | Model 3 | 0 – 1 | 0 | number | lin | yes | — |
| `arpOn` | Arp | 0 – 1 | 0 | index | lin | — | Off · On |
| `arpMode` | Arp Mode | 0 – 11 | 0 | index | lin | — | Up · Down · Up/Down · Up&Down · ZigZag · Order · Random · Chord · Auto · Gate · Pattern · Sustain |
| `arpSyncDiv` | Arp Sync | 0 – 10 | 5 | index | lin | — | Off · 1/1 · 1/2 · 1/4 · 1/8 · 1/16 · 1/32 · 1/8T · 1/16T · 1/8. · 1/16. |
| `arpRate` | Arp Rate | 0.1 – 40 | 8 | Hz | log | — | — |
| `arpOctaves` | Arp Octaves | 0 – 3 | 0 | index | lin | — | 1 · 2 · 3 · 4 |
| `arpGate` | Arp Gate | 0.05 – 1 | 0.6 | number | lin | — | — |
| `arpSwing` | Arp Swing | 0 – 1 | 0 | number | lin | — | — |
| `arpHold` | Arp Hold | 0 – 1 | 0 | index | lin | — | Off · On |
| `arpModel` | Arp Scene | 0 – 7 | 0 | index | lin | — | 1 · 2 · 3 · 4 · 5 · 6 · 7 · 8 |
| `arpTempo` | Arp Tempo | 40 – 240 | 120 | BPM | lin | — | — |
| `allMacro` | All | 0 – 100 | 0 | number | lin | — | — |
| `arpProb` | Arp Prob | 0 – 1 | 1 | number | lin | — | — |
| `arpProbVel` | Arp Ghost | 0 – 1 | 1 | number | lin | — | — |
| `arpVelMode` | Arp Velocity | 0 – 2 | 0 | index | lin | — | Real · Step · Fixed |
| `arpVelOffset` | Arp Vel Offset | -1 – 1 | 0 | number | lin | — | — |
| `arpKeyLo` | Arp Key Low | 0 – 127 | 0 | note | lin | — | — |
| `arpKeyHi` | Arp Key High | 0 – 127 | 127 | note | lin | — | — |
| `arpKeySync` | Arp Start | 0 – 2 | 0 | index | lin | — | Key · Beat · Measure |
| `arpSwingReso` | Arp Swing Reso | 0 – 1 | 1 | index | lin | — | 1/8 · 1/16 |
| `arpLayerMask` | Arp Layers | 0 – 7 | 7 | index | lin | — | — · 1 · 2 · 1+2 · 3 · 1+3 · 2+3 · All |
| `arpRhythmMask` | Arp Rhythm Mask | 0 – 1 | 0 | index | lin | — | Off · On |
| `arpGateEnv` | Arp Gate Env | 0 – 1 | 0.7 | number | lin | — | — |
| `arpFreeze` | Arp Freeze | 0 – 1 | 0 | index | lin | — | Off · On |
| `main` | Main | -28 – 12 | 0 | dB | lin | — | — |
| `noiseColor` | Noise Color | 0 – 3 | 0 | index | lin | yes | White · Pink · Brown · Blue |
| `allMacro2` | All 2 | 0 – 100 | 0 | number | lin | — | — |
| `chordOn` | Chord Memory | 0 – 1 | 0 | index | lin | — | Off · On |
| `chordDir` | Chord Direction | 0 – 2 | 0 | index | lin | — | Root · Top · Center |
| `follow2` | OSC 2 Follows 1 | 0 – 1 | 0 | index | lin | — | Off · On |
| `follow3` | OSC 3 Follows 1 | 0 – 1 | 0 | index | lin | — | Off · On |
| `ampEnvShape` | Amp Env Curve | 0 – 2 | 2 | index | lin | yes | Linear · Exp · Log |
| `filterEnvShape` | Filter Env Curve | 0 – 2 | 2 | index | lin | yes | Linear · Exp · Log |
| `lfoMode` | LFO Mode | 0 – 2 | 0 | index | lin | yes | Free · Trig · 1-Shot |
| `lfoPhase` | LFO Phase | 0 – 1 | 0 | number | lin | yes | — |
| `lfoFade` | LFO Fade In | 0 – 5 | 0 | seconds | lin | yes | — |
| `modSrc1` | Mod 1 Source | 0 – 11 | 0 | index | lin | yes | Off · LFO · Env · Vel · A.Touch · Wheel · Follower · Key · LFO 2 · CC A · CC B · CC C |
| `modDest1` | Mod 1 Destination | 0 – 12 | 0 | index | lin | yes | None · Filter · Pitch · Amp · Pan · PWM · Morph · Res · Drive · Mix · Out · Vib · Expr |
| `modAmt1` | Mod 1 Amount | -1 – 1 | 0 | number | lin | yes | — |
| `modVia1` | Mod 1 Via | 0 – 11 | 0 | index | lin | yes | Off · LFO · Env · Vel · A.Touch · Wheel · Follower · Key · LFO 2 · CC A · CC B · CC C |
| `modSrc2` | Mod 2 Source | 0 – 11 | 0 | index | lin | yes | Off · LFO · Env · Vel · A.Touch · Wheel · Follower · Key · LFO 2 · CC A · CC B · CC C |
| `modDest2` | Mod 2 Destination | 0 – 12 | 0 | index | lin | yes | None · Filter · Pitch · Amp · Pan · PWM · Morph · Res · Drive · Mix · Out · Vib · Expr |
| `modAmt2` | Mod 2 Amount | -1 – 1 | 0 | number | lin | yes | — |
| `modVia2` | Mod 2 Via | 0 – 11 | 0 | index | lin | yes | Off · LFO · Env · Vel · A.Touch · Wheel · Follower · Key · LFO 2 · CC A · CC B · CC C |
| `modSrc3` | Mod 3 Source | 0 – 11 | 0 | index | lin | yes | Off · LFO · Env · Vel · A.Touch · Wheel · Follower · Key · LFO 2 · CC A · CC B · CC C |
| `modDest3` | Mod 3 Destination | 0 – 12 | 0 | index | lin | yes | None · Filter · Pitch · Amp · Pan · PWM · Morph · Res · Drive · Mix · Out · Vib · Expr |
| `modAmt3` | Mod 3 Amount | -1 – 1 | 0 | number | lin | yes | — |
| `modVia3` | Mod 3 Via | 0 – 11 | 0 | index | lin | yes | Off · LFO · Env · Vel · A.Touch · Wheel · Follower · Key · LFO 2 · CC A · CC B · CC C |
| `lfo2Rate` | LFO 2 Rate | 0.02 – 40 | 1 | Hz | log | yes | — |
| `lfo2Sync` | LFO 2 Sync | 0 – 6 | 0 | index | lin | yes | Off · 1/1 · 1/2 · 1/4 · 1/8 · 1/16 · 1/32 |
| `lfo2Depth` | LFO 2 Depth | 0 – 1 | 0 | number | lin | yes | — |
| `lfo2Shape` | LFO 2 Shape | 0 – 6 | 6 | index | lin | yes | Sine · Tri · Saw Up · Saw Down · Square · S&H · Off |
| `lfo2Mode` | LFO 2 Mode | 0 – 2 | 0 | index | lin | yes | Free · Trig · 1-Shot |
| `lfo2Phase` | LFO 2 Phase | 0 – 1 | 0 | number | lin | yes | — |
| `lfo2Fade` | LFO 2 Fade In | 0 – 5 | 0 | seconds | lin | yes | — |
| `env2Attack` | Pitch Env Attack | 0.001 – 4 | 0.005 | seconds | log | yes | — |
| `env2Decay` | Pitch Env Decay | 0.001 – 8 | 0.2 | seconds | log | yes | — |
| `env2Sustain` | Pitch Env Sustain | 0 – 1 | 0 | number | lin | yes | — |
| `env2Release` | Pitch Env Release | 0.001 – 8 | 0.3 | seconds | log | yes | — |
| `env2Amt` | Pitch Env Amount | -1 – 1 | 0 | number | lin | yes | — |
| `modRate` | Tempo | 40 – 240 | 120 | number | lin | — | — |
| `fxFollowTempo` | FX Follow Tempo | 0 – 1 | 0 | switch | lin | — | — |
| `ringMod` | Ring Mod | 0 – 1 | 0 | switch | lin | yes | — |
| `chordScale` | Chord Scale | 0 – 12 | 0 | index | lin | — | Off · Major · Minor · Harm Minor · Mel Minor · Dorian · Phrygian · Lydian · Mixolydian · Locrian · Maj Pentatonic · Min Pentatonic · Blues |
| `chordKey` | Chord Key | 0 – 11 | 0 | index | lin | — | C · C# · D · D# · E · F · F# · G · G# · A · A# · B |
| `chordSplit` | Chord Split | 0 – 2 | 0 | index | lin | — | Off · Below · Above |
| `chordSplitPt` | Chord Split Point | 0 – 127 | 60 | note | lin | — | — |
| `oscPhase` | Phase | 0 – 2 | 0 | index | lin | yes | Reset · Free · Random |
| `physUnison` | Unison | 0 – 50 | 0 | cents | lin | yes | — |
| `nfxRate` | Motion Rate | 0.05 – 12 | 5 | Hz | log | yes | — |
| `nfxVibrato` | Motion Vib | 0 – 1 | 0 | number | lin | yes | — |
| `nfxTremolo` | Motion Trem | 0 – 1 | 0 | number | lin | yes | — |
| `nfxOnset` | Motion Onset | 0 – 4 | 0 | seconds | lin | yes | — |
| `physBloom` | Bloom | 0 – 1 | 0 | number | lin | yes | — |
| `physCondition` | Condition | 0 – 1 | 0 | number | lin | yes | — |
| `bowLift` | Lift | 1 – 120 | 10.4167 | ms | log | yes | — |
| `windCone` | Cone | 0 – 1 | 0 | number | lin | yes | — |
| `bowSection` | Section | 0 – 1 | 0 | number | lin | yes | — |
| `envKeyTrack` | Key | 0 – 1 | 0 | number | lin | yes | — |
| `envAtkVel` | AtkVel | 0 – 1 | 0 | number | lin | yes | — |
| `oscSync` | Sync | 0 – 24 | 0 | number | lin | yes | — |
| `perfCcA` | CC A | 0 – 127 | 0 | number | lin | — | — |
| `perfCcB` | CC B | 0 – 127 | 0 | number | lin | — | — |
| `perfCcC` | CC C | 0 – 127 | 0 | number | lin | — | — |
| `fenvRetrig` | Retrig | 0 – 1 | 0 | switch | lin | yes | — |
| `bodyAmount` | Body | 0 – 1 | 0 | number | lin | yes | — |
| `bodySize` | Size | 0 – 1 | 0.5 | number | lin | yes | — |
| `keyNoise` | Key Noise | 0 – 1 | 0 | number | lin | yes | — |
| `growl` | Growl | 0 – 1 | 0 | number | lin | yes | — |
| `flutter` | Flutter | 0 – 1 | 0 | number | lin | yes | — |
| `breathyPpp` | Breathy | 0 – 1 | 0 | number | lin | yes | — |
| `windJet` | Air Jet | 0 – 1 | 0 | number | lin | yes | — |
| `windChiff` | Chiff | 0 – 1 | 0.5 | number | lin | yes | — |
| `lfoDelay` | LFO Delay | 0 – 5 | 0 | seconds | lin | yes | — |
| `lfo2Delay` | LFO 2 Delay | 0 – 5 | 0 | seconds | lin | yes | — |
| `vecWT` | Vector → Wavetable | 0 – 3 | 0 | index | lin | — | Off · OSC 1 · OSC 2 · OSC 3 |
| `vecWTLo` | Vector WT From | 0 – 1 | 0 | number | lin | — | — |
| `vecWTHi` | Vector WT To | 0 – 1 | 1 | number | lin | — | — |

### The three knobs that change name with the model

`phys1` `phys2` `phys3` are the physical model's own controls, and **what they are depends on
`model`** — same identifier, different instrument. The table above can only call them "Model 1/2/3";
this is what they become:

| model | `phys1` | `phys2` | `phys3` | `phys1` range |
|---|---|---|---|---|
| Pluck (`model: 0`) | Stiff | Excite | Pick | -1 – 1 |
| Mallet (`model: 1`) | Stretch | Hard | Strike | -1 – 1 |
| Blow (`model: 3`) | Reed | Breath | Horn | 0 – 1 |
| Strings (`model: 4`) | Rasp | Press | Bow | -1 – 1 |
| DX7 (`model: 7`) | Tone | — | — | -1 – 1 |

⚠️ On **Blow**, `phys1` (Reed) lives in **0–1**: the spec accepts −1, the voice ignores anything
below zero, and the knob on screen never goes there. Writing a negative Reed is writing silence
into a control. On the other models the full −1…1 is real.

⚠️ Models absent from this table — Classic, Wavetable, SF2 and Granular — do not use these three
knobs at all; writing them is harmless and does nothing. DX7 uses only `phys1` (Tone, the modulation
index that opens the brightness), which is why its other two read "—".

---

## 5 · Editing, end to end

1. Export a patch you like from the app → `Windy.tpr`.
2. Open it, find `banks[0].presets[0]`.
3. Change `name` and give it a new `id` (`u/` plus any unique string) if you want a second patch
   instead of replacing the first.
4. Edit numbers inside `values`, using §3 and §4.
5. Save as **`.tpr`**.
6. Open it on the device (Files, AirDrop, email). It merges into your library.

**Things that will bite:**

- **No brand names** in `name` or anywhere that gets published — no synth models, no artists, no
  song titles. Describe the sound instead ("Warm 80s Brass"). Patches published to the community
  browser are moderated under this rule.
- **Do not hand-write `scenes`.** They are whole snapshots; an inconsistent scene is worse than no
  scene. Save scenes in the app.
- **Do not change `sources` file names** unless the file exists on the target device.
- Keep an ear on polyphony: three layers with long releases is three times the voices.

---

## 6 · What this kit does not give you

The factory sound library is not part of this document: those patches are the instrument's own
voice, and they ship inside the app. This kit is the format, the ranges and the laws — enough to
build your own, and enough for an assistant to do it with you without guessing.
