docs: record the three noise-rejection controls and their invariants
README gains the three controls where each lives -- the trigger's `band`/`reject`, the measurement's `noise`/`hf`, and the math channel's `de-noise` node -- each with its unit, what "off" is, and what it costs, plus the two deliberate deviations from the design spec next to the features they belong to: the band applies to `edge` and `window` only (a pulse's width is measured from a crossing to its return, so a band there changes the measured width rather than rejecting noise; a dropout is an absence with no level to compare), and the band is verified through `BufferSearch` hit counts rather than `[condition-probe]` latch times, because probe-readings.md states that a `t0` is not an assertion. The invariant docs gain the rules a later change must not break: `EventCondition`'s two new fields and the once-per-packet `configure(dt)` that must not reset; the crossing rule that a change is between two *decided* sides; the measurement path's exception to "a readout quotes a stored sample", why the band moves the edge decision only, why `measure_accumulate` loops samples outer, and why a filtered window disables both bucket fast paths; that `MathOp` is append-only (the index *is* the serialisation), that the median window is pooled in the runtime rather than held per node, why the pole reuses `b0`/`z1`, and that median-then-pole is the design; the session's named `noise`/`hf` keys and its thirteen-field node string that still reads twelve; and the two GTK traps -- positionally brace-initialised dialogs, and a control that cannot apply being hidden rather than disabled.
This commit is contained in:
1 parent
c38630643d
commit
749b34a2cb
7 files changed
+114
-1
No files matched your search
@@ -241,6 +241,24 @@ and reading values off the widgets *inside* the editor cannot see that. It is th
|
||||
* **A `Delete` key removes the selected *wire* and never falls through to the selected node.**
|
||||
A key whose target depends on an invisible selection state is how a graph gets destroyed by
|
||||
accident; the `delete node` button stays the only way to remove a node.
|
||||
- **`MathOp` is append-only, because `math_op_at()` *is* the serialisation.** A session stores a node's op
|
||||
as its index through that accessor, so an op inserted in the middle reinterprets every node in every file
|
||||
written before it; `DeNoise` is therefore index 12, after `Div`, and sits last in the dropdown.
|
||||
`math_op_uses_filter()` keeps its meaning of *a biquad* -- `math_op_uses_fc()` is the wider question
|
||||
("does this op read `fc` at all") and is what the dialog's corner row asks.
|
||||
- **The de-noise node's median window is *pooled* in `MathRuntime::median`, not held in `MathNodeRt`**, so a
|
||||
node's state stays on one cache line; nine doubles per node would push every node in the graph, filter or
|
||||
not, across two. `MathNodeRt::med_at` / `::med_n` / `::med_pos` / `::med_have` are that pool's slice,
|
||||
length, write position and fill, and the pool is sized in `math_prepare()`.
|
||||
- **Median *then* pole, and the order is the design.** The median kills an impulse outright -- one shorter
|
||||
than half its window cannot move it at all -- and the pole takes the broadband hash it leaves behind. The
|
||||
other order feeds the pole the impulse, which smears it over the pole's whole settling time and leaves the
|
||||
median a wide bump it cannot reject.
|
||||
- **The de-noise pole reuses `b0` and `z1`, deliberately.** `math_prepare()` carries `z1` across a
|
||||
re-prepare, so the pole keeps its history through a decimation change exactly as the biquads do -- while the
|
||||
median window starts from rest, the same choice the biquads' `z2` makes. `median_n()` rounds *up* to odd and
|
||||
caps at 9, and it is what enforces the window rather than the dialog: a session file holding 4 or 40 still
|
||||
loads. The cap is what `double sorted[9]` in the step is sized for.
|
||||
- **The math channels' cost is the *producer's*, and the instrument must not be part of it.**
|
||||
`push_math_sample()` runs once per stored slot -- up to the wire rate -- so what a regression
|
||||
here looks like is `gaps`, never a frame time. Three things were taken off that path and must
|
||||
|
||||
Reference in new issue
Block a user