Tool: read an ear-tweaked patch back into its factory C++ source #99
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
bcox/tymbal#99
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Factory patches are source and blobs are outputs:
patches/*.hisauthoritative,
//patches:blobsbakes the.tympfiles at build time, andediting a factory patch in the editor and saving over its installed file
loses the edit at the next
bazel run //patches:install. That is what"factory" means and it should stay that way.
But tuning a patch by ear is the only way some of these get good, and the
editor is where that happens. We need a path from "I nudged this until it
sounded right" back into the C++ that generates it.
The workflow
bazel run //patches:install, open the patch in the editor, tweak by ear,save the result somewhere that is not the install directory.
.tympagainst the factory patch itcame from and reports what changed, in the vocabulary of the source
rather than of the file format.
patches/<name>.h— by hand, or with the tool'shelp for the subset where that is safe.
Step 2 is the ticket. Step 3 may be manual forever and that is acceptable.
The tension that shapes the design
patches/*.his documentation as much as it is code. These headers carrythe reasoning: why a clarinet's bore is sealed at the reed end, what the
Chowning index law is doing, which of
crash.h's numbers came from alistening spike and how they were measured. A tool that regenerates a patch
header from a blob would produce correct numbers and destroy everything that
makes the file worth reading.
So the deliverable is a diff reporter, not a code generator. Something
that says "
decay_smoved from 3.0 to 3.4, set atcrash.h:88" is worth farmore than something that emits a new
crash.h. If a later version cansurgically rewrite a single literal in place, good — but regenerating the
file is the wrong goal, not a stretch goal.
What makes this harder than a field-by-field diff
The source's parameters sit upstream of the blob's. A patch header
authors a handful of numbers that
materials/expands into mode tables, thatSolveWaveguideConfigturns into line lengths, that the generators expandinto coefficients. That map is not invertible. If someone edits a mode
directly in the editor, there may be no change to a
MaterialSpecthatproduces it.
The tool must therefore be able to say "this change is not expressible in
the source's vocabulary" rather than quietly writing a literal that
bypasses the generator. Three outcomes per changed field:
that would have to move, and by roughly how much, if that can be solved;
written, and either the patch needs a new authored parameter or the edit
needs redoing upstream.
The third outcome is information, not a failure. Knowing that an ear-tweak
wanted something the patch's own vocabulary cannot say is a useful finding
about the patch.
Round-tripping must be idempotent. A value authored as a
doubleisquantized on the way into the blob; read back it is the quantized value.
Writing that back into the source and rebuilding must produce the same blob,
or every tweaking session ratchets the numbers. Whatever the tool reports has
to be a fixed point under apply-and-rebuild, and that is the property to
test first, by round-tripping every factory patch with no edits at all and
asserting that nothing is reported.
Goldens move.
plugin/render_golden_test.ccpins 1024 samples and itsheader records every re-blessing and why. A patch tweak that reaches the
golden patch is a deliberate re-blessing with a written reason, not a
by-product of an ear session.
Identifying which patch a file came from
project::Provenancealready carries a factory patch's name and an FNV-1ahash of its PTCH bytes, and
provenance.hcomputes it (Fnv1a64,PatchHash). A saved patch that started as a factory patch can thereforename its origin, which is how the tool knows what to diff against without
being told. If an edited file carries no usable provenance, asking for the
name on the command line is a fine fallback.
Shape
A
//tools:binary besidepatch_editorandresynth, something like:printing a human-readable report, with a machine-readable mode if it ever
needs one. Whether it can also
--applythe expressible subset is a secondquestion, and a good reason to keep the report format stable and dull.
Open questions
slot indices, asset identity — or does a save-and-reload already perturb
things the diff would then report as changes?
against a freshly built one? They should be identical; if they are not,
that is its own bug and the tool is a good place to notice it.
and reports which of its authored numbers nothing downstream reads?
Adjacent, cheap once the machinery exists, and it would find dead patch
parameters.
Related: #97.