@vessel-dsp/compiler 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -2
- package/dist/bake.d.ts +38 -0
- package/dist/bake.d.ts.map +1 -0
- package/dist/bake.js +101 -0
- package/dist/bake.js.map +1 -0
- package/dist/bbd-clock.d.ts +171 -0
- package/dist/bbd-clock.d.ts.map +1 -0
- package/dist/bbd-clock.js +1750 -0
- package/dist/bbd-clock.js.map +1 -0
- package/dist/block-row.d.ts +51 -0
- package/dist/block-row.d.ts.map +1 -0
- package/dist/block-row.js +17 -0
- package/dist/block-row.js.map +1 -0
- package/dist/bypass.d.ts +3 -0
- package/dist/bypass.d.ts.map +1 -0
- package/dist/bypass.js +228 -0
- package/dist/bypass.js.map +1 -0
- package/dist/compile.d.ts +24 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +348 -0
- package/dist/compile.js.map +1 -0
- package/dist/converter-scale.d.ts +14 -0
- package/dist/converter-scale.d.ts.map +1 -0
- package/dist/converter-scale.js +133 -0
- package/dist/converter-scale.js.map +1 -0
- package/dist/couple.d.ts +28 -0
- package/dist/couple.d.ts.map +1 -0
- package/dist/couple.js +567 -0
- package/dist/couple.js.map +1 -0
- package/dist/dangling-active-terminal.d.ts +47 -0
- package/dist/dangling-active-terminal.d.ts.map +1 -0
- package/dist/dangling-active-terminal.js +542 -0
- package/dist/dangling-active-terminal.js.map +1 -0
- package/dist/declared-program.d.ts +23 -0
- package/dist/declared-program.d.ts.map +1 -0
- package/dist/declared-program.js +387 -0
- package/dist/declared-program.js.map +1 -0
- package/dist/denomination.d.ts +48 -0
- package/dist/denomination.d.ts.map +1 -0
- package/dist/denomination.js +27 -0
- package/dist/denomination.js.map +1 -0
- package/dist/device-laws.d.ts +237 -0
- package/dist/device-laws.d.ts.map +1 -0
- package/dist/device-laws.js +3513 -0
- package/dist/device-laws.js.map +1 -0
- package/dist/diagnostics.d.ts +13 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +19 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/emit.d.ts +8 -0
- package/dist/emit.d.ts.map +1 -0
- package/dist/emit.js +43 -0
- package/dist/emit.js.map +1 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/firmware-class.d.ts +69 -0
- package/dist/firmware-class.d.ts.map +1 -0
- package/dist/firmware-class.js +20 -0
- package/dist/firmware-class.js.map +1 -0
- package/dist/fixtures/circuits.d.ts +1742 -0
- package/dist/fixtures/circuits.d.ts.map +1 -0
- package/dist/fixtures/circuits.js +13896 -0
- package/dist/fixtures/circuits.js.map +1 -0
- package/dist/fixtures/expected.d.ts +261 -0
- package/dist/fixtures/expected.d.ts.map +1 -0
- package/dist/fixtures/expected.js +315 -0
- package/dist/fixtures/expected.js.map +1 -0
- package/dist/fixtures/index.d.ts +4 -0
- package/dist/fixtures/index.d.ts.map +1 -0
- package/dist/fixtures/index.js +8 -0
- package/dist/fixtures/index.js.map +1 -0
- package/dist/fixtures/registry.d.ts +52 -0
- package/dist/fixtures/registry.d.ts.map +1 -0
- package/dist/fixtures/registry.js +341 -0
- package/dist/fixtures/registry.js.map +1 -0
- package/dist/generic-tube-fit.d.ts +12 -0
- package/dist/generic-tube-fit.d.ts.map +1 -0
- package/dist/generic-tube-fit.js +45 -0
- package/dist/generic-tube-fit.js.map +1 -0
- package/dist/grounded-clock-supply.d.ts +13 -0
- package/dist/grounded-clock-supply.d.ts.map +1 -0
- package/dist/grounded-clock-supply.js +45 -0
- package/dist/grounded-clock-supply.js.map +1 -0
- package/dist/identify.d.ts +50 -0
- package/dist/identify.d.ts.map +1 -0
- package/dist/identify.js +319 -0
- package/dist/identify.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/inert-controls.d.ts +15 -0
- package/dist/inert-controls.d.ts.map +1 -0
- package/dist/inert-controls.js +266 -0
- package/dist/inert-controls.js.map +1 -0
- package/dist/latch-seed.d.ts +53 -0
- package/dist/latch-seed.d.ts.map +1 -0
- package/dist/latch-seed.js +257 -0
- package/dist/latch-seed.js.map +1 -0
- package/dist/link.d.ts +7 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +270 -0
- package/dist/link.js.map +1 -0
- package/dist/lower.d.ts +79 -0
- package/dist/lower.d.ts.map +1 -0
- package/dist/lower.js +1855 -0
- package/dist/lower.js.map +1 -0
- package/dist/netlist.d.ts +79 -0
- package/dist/netlist.d.ts.map +1 -0
- package/dist/netlist.js +4746 -0
- package/dist/netlist.js.map +1 -0
- package/dist/non-executable-clock-drivers.d.ts +8 -0
- package/dist/non-executable-clock-drivers.d.ts.map +1 -0
- package/dist/non-executable-clock-drivers.js +33 -0
- package/dist/non-executable-clock-drivers.js.map +1 -0
- package/dist/open-category.d.ts +98 -0
- package/dist/open-category.d.ts.map +1 -0
- package/dist/open-category.js +111 -0
- package/dist/open-category.js.map +1 -0
- package/dist/over-driven-node.d.ts +33 -0
- package/dist/over-driven-node.d.ts.map +1 -0
- package/dist/over-driven-node.js +188 -0
- package/dist/over-driven-node.js.map +1 -0
- package/dist/part-catalog.d.ts +15 -0
- package/dist/part-catalog.d.ts.map +1 -0
- package/dist/part-catalog.js +6712 -0
- package/dist/part-catalog.js.map +1 -0
- package/dist/part-number.d.ts +32 -0
- package/dist/part-number.d.ts.map +1 -0
- package/dist/part-number.js +80 -0
- package/dist/part-number.js.map +1 -0
- package/dist/partition.d.ts +7 -0
- package/dist/partition.d.ts.map +1 -0
- package/dist/partition.js +242 -0
- package/dist/partition.js.map +1 -0
- package/dist/port-full-scale.d.ts +70 -0
- package/dist/port-full-scale.d.ts.map +1 -0
- package/dist/port-full-scale.js +235 -0
- package/dist/port-full-scale.js.map +1 -0
- package/dist/pot-orientation.d.ts +114 -0
- package/dist/pot-orientation.d.ts.map +1 -0
- package/dist/pot-orientation.js +551 -0
- package/dist/pot-orientation.js.map +1 -0
- package/dist/power-domain-control.d.ts +40 -0
- package/dist/power-domain-control.d.ts.map +1 -0
- package/dist/power-domain-control.js +142 -0
- package/dist/power-domain-control.js.map +1 -0
- package/dist/proxy-declaration.d.ts +121 -0
- package/dist/proxy-declaration.d.ts.map +1 -0
- package/dist/proxy-declaration.js +50 -0
- package/dist/proxy-declaration.js.map +1 -0
- package/dist/registry.d.ts +323 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +192 -0
- package/dist/registry.js.map +1 -0
- package/dist/sparse-schedule.d.ts +65 -0
- package/dist/sparse-schedule.d.ts.map +1 -0
- package/dist/sparse-schedule.js +421 -0
- package/dist/sparse-schedule.js.map +1 -0
- package/dist/speaker-load.d.ts +38 -0
- package/dist/speaker-load.d.ts.map +1 -0
- package/dist/speaker-load.js +97 -0
- package/dist/speaker-load.js.map +1 -0
- package/dist/stage-coverage.d.ts +21 -0
- package/dist/stage-coverage.d.ts.map +1 -0
- package/dist/stage-coverage.js +124 -0
- package/dist/stage-coverage.js.map +1 -0
- package/dist/stamp-partition.d.ts +314 -0
- package/dist/stamp-partition.d.ts.map +1 -0
- package/dist/stamp-partition.js +472 -0
- package/dist/stamp-partition.js.map +1 -0
- package/dist/supply-reference.d.ts +19 -0
- package/dist/supply-reference.d.ts.map +1 -0
- package/dist/supply-reference.js +66 -0
- package/dist/supply-reference.js.map +1 -0
- package/dist/supply-short.d.ts +32 -0
- package/dist/supply-short.d.ts.map +1 -0
- package/dist/supply-short.js +118 -0
- package/dist/supply-short.js.map +1 -0
- package/dist/supply-stamps.d.ts +51 -0
- package/dist/supply-stamps.d.ts.map +1 -0
- package/dist/supply-stamps.js +363 -0
- package/dist/supply-stamps.js.map +1 -0
- package/dist/terminal-role.d.ts +109 -0
- package/dist/terminal-role.d.ts.map +1 -0
- package/dist/terminal-role.js +46 -0
- package/dist/terminal-role.js.map +1 -0
- package/dist/terminal-roles.d.ts +59 -0
- package/dist/terminal-roles.d.ts.map +1 -0
- package/dist/terminal-roles.js +92 -0
- package/dist/terminal-roles.js.map +1 -0
- package/dist/transformer.d.ts +181 -0
- package/dist/transformer.d.ts.map +1 -0
- package/dist/transformer.js +476 -0
- package/dist/transformer.js.map +1 -0
- package/dist/types.d.ts +3157 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/unbounded-operating-point.d.ts +35 -0
- package/dist/unbounded-operating-point.d.ts.map +1 -0
- package/dist/unbounded-operating-point.js +181 -0
- package/dist/unbounded-operating-point.js.map +1 -0
- package/dist/unexecuted-region.d.ts +3 -0
- package/dist/unexecuted-region.d.ts.map +1 -0
- package/dist/unexecuted-region.js +122 -0
- package/dist/unexecuted-region.js.map +1 -0
- package/dist/unimplemented-control-role.d.ts +3 -0
- package/dist/unimplemented-control-role.d.ts.map +1 -0
- package/dist/unimplemented-control-role.js +61 -0
- package/dist/unimplemented-control-role.js.map +1 -0
- package/dist/unreachable-output.d.ts +3 -0
- package/dist/unreachable-output.d.ts.map +1 -0
- package/dist/unreachable-output.js +97 -0
- package/dist/unreachable-output.js.map +1 -0
- package/dist/unreadable-terminal-role.d.ts +67 -0
- package/dist/unreadable-terminal-role.d.ts.map +1 -0
- package/dist/unreadable-terminal-role.js +409 -0
- package/dist/unreadable-terminal-role.js.map +1 -0
- package/dist/unverified-pinout.d.ts +27 -0
- package/dist/unverified-pinout.d.ts.map +1 -0
- package/dist/unverified-pinout.js +121 -0
- package/dist/unverified-pinout.js.map +1 -0
- package/package.json +75 -5
package/dist/couple.js
ADDED
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
// Stage 5.5: wire a macro's `coupled` and `parameter` ports across the blocks `lower` already
|
|
2
|
+
// produced.
|
|
3
|
+
//
|
|
4
|
+
// Why a separate stage rather than something `lowerRegion` does. A macro's ports reference
|
|
5
|
+
// OTHER blocks entirely -- the region sharing its audio-in node, the region sharing its
|
|
6
|
+
// audio-out node, the region whose solved state sets its delay time -- and `lowerRegion` lowers
|
|
7
|
+
// one region at a time with no visibility into the rest. This stage runs after every region has
|
|
8
|
+
// a block, and rewires three things: the macro block itself (so it carries real ports where
|
|
9
|
+
// `Block`'s macro variant used to carry none at all), the block that shares the macro's audio-in
|
|
10
|
+
// node (an added `conductance` stamp: the macro's own declared admittance, so its driver is
|
|
11
|
+
// genuinely loaded rather than driving an open circuit), and the block that shares its audio-out
|
|
12
|
+
// node (an added `macro-audio-source` stamp: a same-sample voltage source behind the macro's
|
|
13
|
+
// declared output impedance, whose *value* the runtime reads from the macro's own delay-line
|
|
14
|
+
// state each sample rather than from a number baked in at compile time).
|
|
15
|
+
//
|
|
16
|
+
// **Why the `coupled` port needs no per-iteration exchange here.** Both stamps this stage adds
|
|
17
|
+
// are linear (`conductance`, `macro-audio-source`) and the macro's own core -- a delay line, per
|
|
18
|
+
// the plan's "a microblock is compiled, not called" decision -- has no same-sample algebraic
|
|
19
|
+
// dependence on the node it taps: what it writes back this sample was computed from history, not
|
|
20
|
+
// from this sample's still-unknown solution. So the driver's and downstream's own blocks solve
|
|
21
|
+
// exactly as they always did, with one extra linear term each, and gate 1d's per-iteration rule
|
|
22
|
+
// (mandatory the moment either side of a seam is nonlinear) simply does not apply -- there is no
|
|
23
|
+
// seam left needing it, because the loading is inside the matrix. This is the fixture's only
|
|
24
|
+
// case, not a general answer: a macro whose *core itself* were nonlinear and zero-delay would
|
|
25
|
+
// still need the interface gate 1d validated, and this stage does not build one.
|
|
26
|
+
//
|
|
27
|
+
// **Spec clause 3, the region schedule, landed 2026-08-14 -- the write-back edge is now real,
|
|
28
|
+
// and the one-sample lag build-order step 1 had to accept is gone.** `partition.ts`'s existing
|
|
29
|
+
// dependency computation only ever expressed one direction: "a macro depends on every analog
|
|
30
|
+
// region sharing a node with it", built for a macro's PARAMETERS being set by an analog region.
|
|
31
|
+
// That rule is too coarse once audio also flows *through* a macro, because it points the wrong
|
|
32
|
+
// way for the audio-out side -- the block receiving a `macro-audio-source` stamp does not set
|
|
33
|
+
// the macro's inputs, it *consumes* the macro's write-back, so it must run AFTER the macro, not
|
|
34
|
+
// before it. `coupleSchedule` below corrects exactly that one edge: the blanket
|
|
35
|
+
// "macro depends on downstream" from stage 4 is replaced with "downstream depends on macro" for
|
|
36
|
+
// the specific region wired as this macro's audio-out, leaving every other shared-node edge
|
|
37
|
+
// (audio-in, `parameter`, and any region with no port role at all, like `hybridDelayPedal`'s bias
|
|
38
|
+
// network) exactly as `partition.ts` already computed it -- those are genuine reads, and the
|
|
39
|
+
// existing direction is already correct for them.
|
|
40
|
+
//
|
|
41
|
+
// **This is a graph edit, not a new solving primitive.** The corrected dependency graph is
|
|
42
|
+
// still exactly what `link.ts`'s existing `topologicalOrder` consumes, unchanged; a schedule
|
|
43
|
+
// this stage cannot satisfy surfaces as `link.ts`'s own `LinkError` -- the "no valid order
|
|
44
|
+
// exists" refusal clause 3 asks for was already built for the macro-parameter graph, and
|
|
45
|
+
// generalizes to this edge for free once the edge is in the same graph.
|
|
46
|
+
//
|
|
47
|
+
// **The coincident case -- driver and downstream the SAME region -- is no longer one of those
|
|
48
|
+
// refusals, corrected 2026-08-14.** Measured against the real corpus (not assumed): all three
|
|
49
|
+
// real delay/BBD packets that clear device-law identification (`pt2399-delay`, `boss-ce-2`,
|
|
50
|
+
// `boss-ce-5`) wire an UNBUFFERED resistor network directly between the chip's audio-out and
|
|
51
|
+
// audio-in -- a dry blend or regen path with no op-amp between them, which `partition.ts` merges
|
|
52
|
+
// into one region because that is what a region is (devices sharing a non-ground node). Adding
|
|
53
|
+
// both directional edges unconditionally, as the first landing of clause 3 did, makes this case
|
|
54
|
+
// a 2-cycle: the region must run before the macro (audio-in) and after it (audio-out) in the
|
|
55
|
+
// same sample, which `link.ts` correctly refused. The resolution is neither same-sample
|
|
56
|
+
// resolution (gate 1a's premise -- a macro's write-back is delayed by construction, computed
|
|
57
|
+
// from history alone, so a same-sample edge is a strengthening this format can afford not to
|
|
58
|
+
// have here, not a correctness requirement) nor a refusal: it is a documented one-sample lag on
|
|
59
|
+
// the write-back side ONLY in this exact case, chosen over the audio-in direction because stage
|
|
60
|
+
// 4's own blanket rule already produces "macro after region" for free, so keeping it costs no
|
|
61
|
+
// new edge, where the reverse would have to invent one. See the coincident-case comment in
|
|
62
|
+
// `couple` below for the mechanism and `thoughts/shared/experiments/
|
|
63
|
+
// coincident-region-schedule-lag/README.md` for the measured cost -- a different topology from
|
|
64
|
+
// gate 1a's buffered fixture, so a different number, measured rather than reused. See
|
|
65
|
+
// `hybridDelayPedalCyclicSchedule` in the tests: it now compiles (this is what changed), and a
|
|
66
|
+
// separate, still-uncovered fixture would be needed to exercise a genuine multi-region cycle
|
|
67
|
+
// (chained macros whose driver/downstream form a longer loop through DISTINCT regions), which
|
|
68
|
+
// this correction does not resolve and `link.ts` still correctly refuses.
|
|
69
|
+
//
|
|
70
|
+
// **`Program.order` is the "region schedule as first-class program data" clause 3 asks for**,
|
|
71
|
+
// not a new field beside it. It already satisfies both halves of the requirement -- computed by
|
|
72
|
+
// the compiler from a dependency graph, iterated by the runtime with no graph walk of its own --
|
|
73
|
+
// so the gap clause 3 closes is in what feeds that computation, not in `order`'s own shape. A
|
|
74
|
+
// second, parallel `Program.schedule` field would only duplicate it.
|
|
75
|
+
//
|
|
76
|
+
// **The `parameter` port's purity gate, and where it diverges from the census's own check.**
|
|
77
|
+
// Spec clause 1 names two checks: node-equality between the derivation's supply and an
|
|
78
|
+
// audio-path active device's supply pin (the "sag" failure), and reachability of a
|
|
79
|
+
// modulation-role control from the derivation's own control pin (the "lfo" failure). Neither
|
|
80
|
+
// check is representable here exactly as worded, for reasons specific to this compiler's own
|
|
81
|
+
// architecture rather than a disagreement with the measurement:
|
|
82
|
+
//
|
|
83
|
+
// - `partition.ts` merges any devices sharing a non-ground node into ONE region -- that is
|
|
84
|
+
// what a region *is*. So two DIFFERENT regions can never share a non-ground node; if a real
|
|
85
|
+
// shared supply existed, the clock network and the active device would already be one
|
|
86
|
+
// region, not two, and the cross-region check gate 1b's census runs on raw source documents
|
|
87
|
+
// would be comparing something that cannot occur post-partition. The check this stage runs
|
|
88
|
+
// instead is the one that IS representable and catches the same class of defect: the
|
|
89
|
+
// derivation's own region must be `linear`, i.e. contain no nonlinear device at all -- an
|
|
90
|
+
// active device reacting to the passing audio from *inside* the derivation's own region is
|
|
91
|
+
// exactly the impurity gate 1b's `sag` row measures, and unlike cross-region sharing, this
|
|
92
|
+
// is a real, checkable, single-region fact.
|
|
93
|
+
// - This compiler's `Control` type carries no role at all (`{id, taper, defaultPosition}`) --
|
|
94
|
+
// `deviceInterface.controls[].role` is read by stage 1 for jack classification only and
|
|
95
|
+
// never reaches this type. So "a modulation-role control is reachable" narrows to "any
|
|
96
|
+
// control is reachable", which is a STRICTER superset of the census's check, not a weaker
|
|
97
|
+
// one: refusing on any control is safe in the direction that matters (never wrongly admits
|
|
98
|
+
// an impure derivation), even though it will also refuse some genuinely-pure knob-rate cases
|
|
99
|
+
// a role-aware check would admit. Recorded as a dated correction against the spec, not a
|
|
100
|
+
// silent narrowing: see the plan's clause 1 annotation.
|
|
101
|
+
//
|
|
102
|
+
// Both checks read `Partitioning.Region`, already computed by `partition.ts` and already exact
|
|
103
|
+
// for this purpose -- `region.kind` is `linear` only when nothing in it needs Newton, and
|
|
104
|
+
// `region.controls` is already the exhaustive list of controls the region's own devices carry.
|
|
105
|
+
import { blockNodeIndex, stampControl, stampNeedsNewton, } from "./lower.js";
|
|
106
|
+
import { computeSparseSchedule } from "./sparse-schedule.js";
|
|
107
|
+
import { computeStampPartition, shouldEliminate, stampShape, } from "./stamp-partition.js";
|
|
108
|
+
import { GROUND } from "./types.js";
|
|
109
|
+
/**
|
|
110
|
+
* Record that this block reads a solved node of another, so the order puts the writer first.
|
|
111
|
+
*
|
|
112
|
+
* **A port is a data dependency and the partitioner cannot see this one.** Stage 4 draws an
|
|
113
|
+
* edge where two regions *share a node*; a router reads the wiper of a pot the chip never
|
|
114
|
+
* touches, so no shared node exists and no edge is drawn. Without this the composed block can
|
|
115
|
+
* be ordered first and read a stale operating point.
|
|
116
|
+
*
|
|
117
|
+
* Measured 2026-09-22, and it is why this exists: with the edge missing, the C++ console read
|
|
118
|
+
* the router's node as its prepare-time value and played one program at both ends of the knob,
|
|
119
|
+
* while the TypeScript console read its live map and switched correctly. Two consoles
|
|
120
|
+
* disagreeing is the symptom; the missing edge is the defect.
|
|
121
|
+
*/
|
|
122
|
+
function dependOn(dependencies, blockId, sourceId) {
|
|
123
|
+
if (sourceId === blockId)
|
|
124
|
+
return;
|
|
125
|
+
const list = dependencies[blockId];
|
|
126
|
+
if (list === undefined) {
|
|
127
|
+
dependencies[blockId] = [sourceId];
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (!list.includes(sourceId))
|
|
131
|
+
list.push(sourceId);
|
|
132
|
+
}
|
|
133
|
+
export function couple(blocks, partitioning, lawed) {
|
|
134
|
+
const deviceById = new Map(lawed.netlist.devices.map((device) => [device.id, device]));
|
|
135
|
+
const byId = new Map(blocks.map((block) => [block.id, block]));
|
|
136
|
+
// A working copy, corrected in place as each macro's audio-out edge is found. Every other
|
|
137
|
+
// edge `partition.ts` computed -- audio-in, `parameter`, and any node with no port role at
|
|
138
|
+
// all -- is a genuine read and stays exactly as stage 4 left it.
|
|
139
|
+
const dependencies = Object.fromEntries(Object.entries(partitioning.dependencies).map(([id, deps]) => [id, [...deps]]));
|
|
140
|
+
for (const region of partitioning.regions) {
|
|
141
|
+
if (region.kind !== "macro" || region.macro === null) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const macroBlock = byId.get(region.id);
|
|
145
|
+
if (macroBlock === undefined || macroBlock.kind !== "macro") {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const device = deviceById.get(region.devices[0] ?? "");
|
|
149
|
+
if (device === undefined) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const macro = region.macro;
|
|
153
|
+
let next = macroBlock;
|
|
154
|
+
// The `coupled` port. Wired only when the part declares an audio boundary at all
|
|
155
|
+
// (`audioPortImpedanceOhms`) and names enough port terminals to locate both nodes --
|
|
156
|
+
// the safe default for a part that declares neither is the port staying absent, not an
|
|
157
|
+
// assumed ideal (zero-impedance, or an unwritten sample) boundary nothing measured.
|
|
158
|
+
if (macro.audioPortImpedanceOhms !== null && macro.portTerminals.length >= 2) {
|
|
159
|
+
const inNode = device.nodes[macro.portTerminals[0]];
|
|
160
|
+
const outNode = device.nodes[macro.portTerminals[1]];
|
|
161
|
+
// Hoisted out of the `inNode` block: the audio-out side needs to know the driver's
|
|
162
|
+
// id too, because the driver and the downstream region can be the SAME region (a
|
|
163
|
+
// direct wire loops the macro's audio-out back toward its own audio-in side) --
|
|
164
|
+
// `hybridDelayPedalCyclicSchedule` is exactly this. Rewriting the dependency edge
|
|
165
|
+
// from "downstream" alone, without knowing whether it coincides with "driver",
|
|
166
|
+
// dropped the audio-in edge entirely in that case on this file's first version --
|
|
167
|
+
// caught by the negative control below expecting a refusal and silently compiling a
|
|
168
|
+
// wrongly-scheduled program instead. Both edges are added explicitly now, and
|
|
169
|
+
// removal only ever targets the specific stale edge this stage means to correct.
|
|
170
|
+
const driver = inNode === undefined ? undefined : ownerOf(inNode, partitioning);
|
|
171
|
+
if (inNode !== undefined && driver !== undefined) {
|
|
172
|
+
const driverBlock = byId.get(driver.id);
|
|
173
|
+
// `inNode` and `outNode` are the source ids `partition.ts` works in, and a block's
|
|
174
|
+
// rows are numbered independently of those (see `Block.nodeIds`), so every node
|
|
175
|
+
// crossing into a block from here goes through that block's own map. `ownerOf` has
|
|
176
|
+
// already proved the node belongs to the region, so `null` would be a compiler
|
|
177
|
+
// defect rather than an absent port -- but it is checked rather than asserted,
|
|
178
|
+
// because the failure it would otherwise produce is a stamp on row 0, which is
|
|
179
|
+
// ground, and a macro seam quietly shorted to ground still renders.
|
|
180
|
+
const driverRow = driverBlock?.kind === "mna" ? blockNodeIndex(driverBlock, inNode) : null;
|
|
181
|
+
if (driverBlock?.kind === "mna" && driverRow !== null) {
|
|
182
|
+
byId.set(driver.id, withStamp(driverBlock, {
|
|
183
|
+
kind: "conductance",
|
|
184
|
+
a: driverRow,
|
|
185
|
+
b: GROUND,
|
|
186
|
+
siemens: 1 / macro.audioPortImpedanceOhms.input,
|
|
187
|
+
}));
|
|
188
|
+
next = { ...next, audioIn: { block: driver.id, node: driverRow } };
|
|
189
|
+
// The macro reads this region's solved node every sample, so it must run
|
|
190
|
+
// after it -- made explicit here rather than left to whatever stage 4's
|
|
191
|
+
// blanket shared-node rule happened to produce.
|
|
192
|
+
if (!(dependencies[region.id] ?? []).includes(driver.id)) {
|
|
193
|
+
dependencies[region.id] = [...(dependencies[region.id] ?? []), driver.id];
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (outNode !== undefined) {
|
|
198
|
+
const downstream = ownerOf(outNode, partitioning);
|
|
199
|
+
const downstreamBlock = downstream === undefined ? undefined : byId.get(downstream.id);
|
|
200
|
+
const downstreamRow = downstreamBlock?.kind === "mna"
|
|
201
|
+
? blockNodeIndex(downstreamBlock, outNode)
|
|
202
|
+
: null;
|
|
203
|
+
if (downstream !== undefined &&
|
|
204
|
+
downstreamBlock?.kind === "mna" &&
|
|
205
|
+
downstreamRow !== null) {
|
|
206
|
+
byId.set(downstream.id, withStamp(downstreamBlock, {
|
|
207
|
+
kind: "macro-audio-source",
|
|
208
|
+
node: downstreamRow,
|
|
209
|
+
macroId: region.id,
|
|
210
|
+
sourceOhms: macro.audioPortImpedanceOhms.output,
|
|
211
|
+
sourceIndex: downstreamBlock.auxCount,
|
|
212
|
+
}));
|
|
213
|
+
next = { ...next, audioOut: true };
|
|
214
|
+
// The schedule correction: this region no longer *sets* the macro's inputs
|
|
215
|
+
// (drop it from the macro's own dependency list, if stage 4 put it there via
|
|
216
|
+
// the shared-node rule) and now *consumes* the macro's write-back instead, so
|
|
217
|
+
// it must run after the macro -- UNLESS this region is also the driver, the
|
|
218
|
+
// coincident case an unbuffered dry/wet blend produces (`R13` straight from a
|
|
219
|
+
// BBD's `in` to `out1`, no op-amp between them -- measured 2026-08-14 as the
|
|
220
|
+
// common case for this corpus's real delay/BBD-chorus pedals, not the
|
|
221
|
+
// exception gate 1a's own buffered fixture tested). There, adding this edge
|
|
222
|
+
// on top of the audio-in edge already added above (macro depends on driver,
|
|
223
|
+
// same region) is a same-sample lag AND a same-sample read of the same pair,
|
|
224
|
+
// which is exactly the 2-cycle `link.ts` correctly refuses -- this file's
|
|
225
|
+
// first version created that cycle by *also* deleting the audio-in edge here,
|
|
226
|
+
// which was wrong the other way (a silently stale schedule). Neither wrong is
|
|
227
|
+
// necessary: the coincident case has a genuinely different, honest resolution
|
|
228
|
+
// -- see "the coincident case" below -- so this branch simply does not add
|
|
229
|
+
// the reverse edge, leaving the one already-correct direction (region before
|
|
230
|
+
// macro) as the schedule.
|
|
231
|
+
const isFeedback = driver !== undefined &&
|
|
232
|
+
(downstream.id === driver.id ||
|
|
233
|
+
reaches(driver.id, downstream.id, dependencies));
|
|
234
|
+
if (!isFeedback) {
|
|
235
|
+
dependencies[region.id] = (dependencies[region.id] ?? []).filter((id) => id !== downstream.id);
|
|
236
|
+
if (!(dependencies[downstream.id] ?? []).includes(region.id)) {
|
|
237
|
+
dependencies[downstream.id] = [
|
|
238
|
+
...(dependencies[downstream.id] ?? []),
|
|
239
|
+
region.id,
|
|
240
|
+
];
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// **The coincident case, resolved 2026-08-14: a documented one-sample lag,
|
|
244
|
+
// not same-sample resolution and not a refusal.** When driver and downstream
|
|
245
|
+
// are the SAME region (an unbuffered regen/dry-blend network), that region
|
|
246
|
+
// cannot run both before the macro (to supply this sample's audio-in) and
|
|
247
|
+
// after it (to consume this sample's write-back) -- both cannot be same-
|
|
248
|
+
// sample. The audio-in direction wins, kept exactly as added above: the
|
|
249
|
+
// macro reads this sample's driven node, because that is the read the
|
|
250
|
+
// `parameter` port and every other macro-parameter dependency already assume
|
|
251
|
+
// and because it is the direction stage 4's own blanket rule already
|
|
252
|
+
// produces for this region regardless (a macro sharing a node with an analog
|
|
253
|
+
// region runs after it), so choosing it costs no new edge. The write-back
|
|
254
|
+
// stays exactly where build-order step 1 already had it before clause 3: the
|
|
255
|
+
// region's `macro-audio-source` stamp reads last sample's `macroOutputVolts`,
|
|
256
|
+
// not this sample's -- unchanged from what stage 4 alone already schedules,
|
|
257
|
+
// since no edge is added here. This is honest exactly because it is
|
|
258
|
+
// documented and its cost is measured rather than assumed: see
|
|
259
|
+
// `docs/troubleshootings/` and `thoughts/shared/experiments/
|
|
260
|
+
// coincident-region-schedule-lag/README.md` for the measured fraction on
|
|
261
|
+
// this exact topology (a resistor bridging a macro's own audio-in and
|
|
262
|
+
// audio-out nodes), which is a different topology from gate 1a's buffered
|
|
263
|
+
// regen path and therefore a different number. **Not same-sample
|
|
264
|
+
// resolution**: that would need the macro's per-sample step split into a
|
|
265
|
+
// publish half (before the region, from history alone) and a consume half
|
|
266
|
+
// (after the region) as two schedule nodes, which is a new scheduling
|
|
267
|
+
// primitive this program format does not have and neither `Program.order`
|
|
268
|
+
// nor `costPredictors`' `executedBlockCount` (computed as `order.length`,
|
|
269
|
+
// spec build-order step 6) is built to carry -- recorded as what remains,
|
|
270
|
+
// not implemented speculatively here. **Not a refusal**: gate 1a's own
|
|
271
|
+
// premise is that a macro's write-back is delayed by construction (a delay
|
|
272
|
+
// core's output depends only on past samples), so a same-sample edge here is
|
|
273
|
+
// a strengthening this format can afford to not have, not a correctness
|
|
274
|
+
// requirement -- unlike a truly algebraic (zero-delay) coupled boundary,
|
|
275
|
+
// which this is not.
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// **The second audio output, for a part that has two.**
|
|
279
|
+
//
|
|
280
|
+
// A BBD brings out two taps and a design puts a balance trimmer across them, because
|
|
281
|
+
// the audio appears on both while the clock feedthrough appears in antiphase. Driving
|
|
282
|
+
// only the first left the second an undriven node, so the trimmer stopped being a
|
|
283
|
+
// balance control and became an attenuator against whatever bled through its own
|
|
284
|
+
// track: measured on `mxr-carbon-copy` as **6.0 dB lost across four brigades at the
|
|
285
|
+
// trimmers' centre default, against 0.67 dB with each wiper on the driven pin** -- and
|
|
286
|
+
// a compandor downstream squared it.
|
|
287
|
+
//
|
|
288
|
+
// The same write-back value is published on both taps, which is what the *audio* does:
|
|
289
|
+
// both outputs carry the signal, and the trimmer exists to null a clock feedthrough
|
|
290
|
+
// this model does not represent at all. So a centred wiper now recovers the signal
|
|
291
|
+
// instead of half of it, and the trimmer is inert for audio -- honest, because nothing
|
|
292
|
+
// here models the thing it trims.
|
|
293
|
+
//
|
|
294
|
+
// **No schedule edge is added.** The dependency direction was settled by the first
|
|
295
|
+
// output above, and this stamp reads the same `macroOutputVolts` entry; a second edge
|
|
296
|
+
// for the same producer/consumer pair would either duplicate that or, where the second
|
|
297
|
+
// tap lands in another region, assert an ordering this stage has not measured. A tap
|
|
298
|
+
// whose node is not in an MNA block is skipped, exactly as the first output is.
|
|
299
|
+
const out2Terminal = macro.portTerminals[2];
|
|
300
|
+
const out2Node = out2Terminal === undefined ? undefined : device.nodes[out2Terminal];
|
|
301
|
+
const out2Owner = out2Node === undefined ? undefined : ownerOf(out2Node, partitioning);
|
|
302
|
+
const out2Block = out2Owner === undefined ? undefined : byId.get(out2Owner.id);
|
|
303
|
+
const out2Row = out2Block?.kind === "mna" && out2Node !== undefined
|
|
304
|
+
? blockNodeIndex(out2Block, out2Node)
|
|
305
|
+
: null;
|
|
306
|
+
if (out2Owner !== undefined && out2Block?.kind === "mna" && out2Row !== null) {
|
|
307
|
+
byId.set(out2Owner.id, withStamp(out2Block, {
|
|
308
|
+
kind: "macro-audio-source",
|
|
309
|
+
node: out2Row,
|
|
310
|
+
macroId: region.id,
|
|
311
|
+
sourceOhms: macro.audioPortImpedanceOhms.output,
|
|
312
|
+
sourceIndex: out2Block.auxCount,
|
|
313
|
+
}));
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// The router: which program a declared composition runs, and at which detent. Wired
|
|
317
|
+
// exactly like `parameter` below, from the same evidence, because it is the same
|
|
318
|
+
// mechanism -- a solved node voltage driving the block. Unlike `parameter` it is not
|
|
319
|
+
// purity-gated: a mode control is a control, and demanding its node be a control-free
|
|
320
|
+
// derivation would refuse the one topology it always has.
|
|
321
|
+
const plan = macro.declaredRouter;
|
|
322
|
+
if (plan !== null && plan !== undefined && plan.node === null) {
|
|
323
|
+
// A scanned control: the runtime reads its position directly, so there is no node to
|
|
324
|
+
// own, nothing to resolve across blocks, and no ordering edge to record.
|
|
325
|
+
next = {
|
|
326
|
+
...next,
|
|
327
|
+
router: {
|
|
328
|
+
controlId: plan.controlId,
|
|
329
|
+
port: null,
|
|
330
|
+
positions: plan.positions,
|
|
331
|
+
routes: plan.routes,
|
|
332
|
+
},
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
else if (plan !== null &&
|
|
336
|
+
plan !== undefined &&
|
|
337
|
+
plan.node !== null &&
|
|
338
|
+
plan.referenceVolts !== null) {
|
|
339
|
+
const node = plan.node;
|
|
340
|
+
const referenceVolts = plan.referenceVolts;
|
|
341
|
+
const source = ownerOf(node, partitioning);
|
|
342
|
+
const sourceBlock = source === undefined ? undefined : byId.get(source.id);
|
|
343
|
+
const sourceRow = sourceBlock?.kind === "mna" ? blockNodeIndex(sourceBlock, node) : null;
|
|
344
|
+
if (source !== undefined && sourceRow !== null) {
|
|
345
|
+
dependOn(dependencies, next.id, source.id);
|
|
346
|
+
next = {
|
|
347
|
+
...next,
|
|
348
|
+
router: {
|
|
349
|
+
controlId: plan.controlId,
|
|
350
|
+
port: {
|
|
351
|
+
block: source.id,
|
|
352
|
+
node: sourceRow,
|
|
353
|
+
referenceVolts,
|
|
354
|
+
},
|
|
355
|
+
positions: plan.positions,
|
|
356
|
+
routes: plan.routes,
|
|
357
|
+
},
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
// A declared program's cited parameter, resolved from its planned node. Same path as the
|
|
362
|
+
// router above; not purity-gated, for the same reason.
|
|
363
|
+
const parameterPlan = macro.declaredParameter;
|
|
364
|
+
if (parameterPlan !== null &&
|
|
365
|
+
parameterPlan !== undefined &&
|
|
366
|
+
parameterPlan.node !== null &&
|
|
367
|
+
parameterPlan.referenceVolts !== null) {
|
|
368
|
+
const planNode = parameterPlan.node;
|
|
369
|
+
const source = ownerOf(planNode, partitioning);
|
|
370
|
+
const sourceBlock = source === undefined ? undefined : byId.get(source.id);
|
|
371
|
+
const sourceRow = sourceBlock?.kind === "mna" ? blockNodeIndex(sourceBlock, planNode) : null;
|
|
372
|
+
if (source !== undefined && sourceRow !== null) {
|
|
373
|
+
dependOn(dependencies, next.id, source.id);
|
|
374
|
+
next = {
|
|
375
|
+
...next,
|
|
376
|
+
parameter: {
|
|
377
|
+
block: source.id,
|
|
378
|
+
node: sourceRow,
|
|
379
|
+
referenceVolts: parameterPlan.referenceVolts,
|
|
380
|
+
},
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
// The `parameter` port, purity-gated -- see this file's header for the two checks and
|
|
385
|
+
// where they diverge from the census's own. Missing or negative evidence leaves
|
|
386
|
+
// `parameter` at its `null` default from `lower.ts`, which is the spec's safe default:
|
|
387
|
+
// no pedal is refused for lacking this port, and the macro falls back to its own
|
|
388
|
+
// `parameters` alone.
|
|
389
|
+
if (macro.parameterTerminal !== null && macro.parameterReferenceVolts !== null) {
|
|
390
|
+
const node = device.nodes[macro.parameterTerminal];
|
|
391
|
+
const source = node === undefined ? undefined : ownerOf(node, partitioning);
|
|
392
|
+
const sourceBlock = source === undefined ? undefined : byId.get(source.id);
|
|
393
|
+
// Through the owning block's map, as the `coupled` port above: this port names a row
|
|
394
|
+
// the runtime reads out of another block's solution every sample.
|
|
395
|
+
const sourceRow = sourceBlock?.kind === "mna" && node !== undefined
|
|
396
|
+
? blockNodeIndex(sourceBlock, node)
|
|
397
|
+
: null;
|
|
398
|
+
if (source !== undefined &&
|
|
399
|
+
sourceRow !== null &&
|
|
400
|
+
isPureDerivation(source)) {
|
|
401
|
+
next = {
|
|
402
|
+
...next,
|
|
403
|
+
parameter: {
|
|
404
|
+
block: source.id,
|
|
405
|
+
node: sourceRow,
|
|
406
|
+
referenceVolts: macro.parameterReferenceVolts,
|
|
407
|
+
},
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
// The registry declared this part's modulation input and the document wired it,
|
|
412
|
+
// and admission still refused it. That is not a silent condition: it is the
|
|
413
|
+
// difference between a flanger and a fixed comb filter, and until now the two
|
|
414
|
+
// compiled to the same program.
|
|
415
|
+
//
|
|
416
|
+
// Refusing is correct here rather than a limitation to route around. Gate 1b
|
|
417
|
+
// measured this exact case -- see
|
|
418
|
+
// `thoughts/shared/experiments/clock-parameter-port-gate/README.md` -- and found
|
|
419
|
+
// that an LFO-swept clock "turns the `parameter` port into a `signal` by
|
|
420
|
+
// definition". The port carries a value re-derived when a control moves; a swept
|
|
421
|
+
// clock has no such moments. Admitting it anyway would read the clock pin's own
|
|
422
|
+
// square wave as though it were a control voltage, which slams the delay between
|
|
423
|
+
// zero and full scale at the clock rate: audible garbage in place of a quiet
|
|
424
|
+
// wrong answer.
|
|
425
|
+
next = {
|
|
426
|
+
...next,
|
|
427
|
+
// The CAUSE only. What it costs depends on whether the delay has any other
|
|
428
|
+
// derivation, which this stage cannot see and `compile` can -- a packet whose
|
|
429
|
+
// delay follows a knob loses only the sweep, one with no derivation at all is
|
|
430
|
+
// a fixed comb filter. Stating the wrong one of those was a real misfire:
|
|
431
|
+
// `pt2399-delay` derives its delay from its own resistor network and was being
|
|
432
|
+
// told its delay was fixed.
|
|
433
|
+
modulationRefusal: source === undefined || sourceRow === null
|
|
434
|
+
? "its modulation input is not owned by any solved analog block"
|
|
435
|
+
: `its modulation input is driven by ${source.id}, a ${source.kind} region with ` +
|
|
436
|
+
`${source.controls.length} control(s), which is a signal rather than a ` +
|
|
437
|
+
`control-rate parameter (compiler gate 1b)`,
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
// The `modulation` port. Unlike `parameter` above, the node is **not on this device** --
|
|
442
|
+
// it is a transistor's control terminal elsewhere in the clock circuit -- so it arrives
|
|
443
|
+
// as a source node rather than a terminal index and is mapped to a row here.
|
|
444
|
+
//
|
|
445
|
+
// No purity gate, deliberately, and the reason is the inverse of gate 1b's. That gate
|
|
446
|
+
// exists because a `parameter` is cached until a control moves, so an impure derivation
|
|
447
|
+
// silently serves a stale value. This port is read every sample and caches nothing, so
|
|
448
|
+
// there is no staleness to guard. What it needs instead is that the node carry a
|
|
449
|
+
// modulation rather than the oscillator itself, and `resolveClockModulationSource` has
|
|
450
|
+
// already established that by refusing any control terminal sitting on the timing
|
|
451
|
+
// network.
|
|
452
|
+
if (macro.modulationNode !== null &&
|
|
453
|
+
macro.modulationNode !== undefined &&
|
|
454
|
+
macro.modulationSteeredBy != null) {
|
|
455
|
+
const modNode = macro.modulationNode;
|
|
456
|
+
const modSource = ownerOf(modNode, partitioning);
|
|
457
|
+
const modBlock = modSource === undefined ? undefined : byId.get(modSource.id);
|
|
458
|
+
const modRow = modBlock?.kind === "mna" ? blockNodeIndex(modBlock, modNode) : null;
|
|
459
|
+
if (modSource !== undefined && modRow !== null) {
|
|
460
|
+
next = {
|
|
461
|
+
...next,
|
|
462
|
+
modulation: {
|
|
463
|
+
block: modSource.id,
|
|
464
|
+
node: modRow,
|
|
465
|
+
steeredBy: macro.modulationSteeredBy,
|
|
466
|
+
},
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
// The `clock-law` port. Same road as `modulation` above: the slow node
|
|
471
|
+
// is a divider node elsewhere in the clock circuit, so it arrives as a
|
|
472
|
+
// source node and is mapped to a row here. Read every sample, caches
|
|
473
|
+
// nothing, for the same reason.
|
|
474
|
+
if (macro.clockLawNode !== null &&
|
|
475
|
+
macro.clockLawNode !== undefined &&
|
|
476
|
+
macro.clockLawSteeredBy != null) {
|
|
477
|
+
const lawNode = macro.clockLawNode;
|
|
478
|
+
const lawSource = ownerOf(lawNode, partitioning);
|
|
479
|
+
const lawBlock = lawSource === undefined ? undefined : byId.get(lawSource.id);
|
|
480
|
+
const lawRow = lawBlock?.kind === "mna" ? blockNodeIndex(lawBlock, lawNode) : null;
|
|
481
|
+
if (lawSource !== undefined && lawRow !== null) {
|
|
482
|
+
next = {
|
|
483
|
+
...next,
|
|
484
|
+
clockLaw: {
|
|
485
|
+
block: lawSource.id,
|
|
486
|
+
node: lawRow,
|
|
487
|
+
steeredBy: macro.clockLawSteeredBy,
|
|
488
|
+
},
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
byId.set(region.id, next);
|
|
493
|
+
}
|
|
494
|
+
return {
|
|
495
|
+
blocks: blocks.map((block) => byId.get(block.id) ?? block),
|
|
496
|
+
dependencies,
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
/** The analog region owning `node`, if any -- never a macro region. */
|
|
500
|
+
function ownerOf(node, partitioning) {
|
|
501
|
+
return partitioning.regions.find((region) => region.kind !== "macro" && region.nodes.includes(node));
|
|
502
|
+
}
|
|
503
|
+
/** See this file's header for what these two checks are proxies for and why. */
|
|
504
|
+
function isPureDerivation(region) {
|
|
505
|
+
return region.kind === "linear" && region.controls.length === 0;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* A new stamp, added to a block whose `linear`/`controlFree` are re-derived rather than
|
|
509
|
+
* assumed unchanged -- the same rule `lowerRegion` itself follows, so a stamp this stage adds
|
|
510
|
+
* cannot silently leave a block claiming a solver cost or a control independence its own
|
|
511
|
+
* stamps contradict.
|
|
512
|
+
*
|
|
513
|
+
* Exported for `dangling-active-terminal.ts`'s implicit op-amp bias synthesis, which adds a
|
|
514
|
+
* stamp to an already-linked block for the same reason this stage does: a block's derived
|
|
515
|
+
* fields must never describe a stamps array it does not have.
|
|
516
|
+
*/
|
|
517
|
+
export function withStamp(block, stamp) {
|
|
518
|
+
const stamps = [...block.stamps, stamp];
|
|
519
|
+
// The stamp's own auxiliary-row count, from the shape table, rather than a second local
|
|
520
|
+
// list of which kinds need one. The two had already drifted: the local list omitted
|
|
521
|
+
// `logic-divider`, `spring-reverb` and `clock-driver`, and added a flat 1 where
|
|
522
|
+
// `clock-driver` owns 3. Unreachable today -- this stage only ever adds `conductance` and
|
|
523
|
+
// `macro-audio-source` -- but wrong for any kind it is later asked to add.
|
|
524
|
+
const auxCount = block.auxCount + stampShape(stamp).aux;
|
|
525
|
+
const stampPartition = computeStampPartition(stamps, block.nodeCount);
|
|
526
|
+
const sparseSchedule = computeSparseSchedule({
|
|
527
|
+
nodeCount: block.nodeCount,
|
|
528
|
+
auxCount,
|
|
529
|
+
stamps,
|
|
530
|
+
});
|
|
531
|
+
const linear = !stamps.some(stampNeedsNewton);
|
|
532
|
+
const controlFree = stamps.every((candidate) => stampControl(candidate) === null);
|
|
533
|
+
const eliminate = shouldEliminate(block.nodeCount + auxCount, stampPartition.portRows.length, linear, block.convergenceOptIn === true);
|
|
534
|
+
return {
|
|
535
|
+
...block,
|
|
536
|
+
stamps,
|
|
537
|
+
stampPartition,
|
|
538
|
+
sparseSchedule,
|
|
539
|
+
auxCount,
|
|
540
|
+
linear,
|
|
541
|
+
controlFree,
|
|
542
|
+
eliminate,
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
/** Whether target is reachable from from in the dependency graph. */
|
|
546
|
+
function reaches(from, target, dependencies) {
|
|
547
|
+
if (from === target) {
|
|
548
|
+
return true;
|
|
549
|
+
}
|
|
550
|
+
const visited = new Set();
|
|
551
|
+
const queue = [from];
|
|
552
|
+
while (queue.length > 0) {
|
|
553
|
+
const current = queue.shift();
|
|
554
|
+
if (current === target) {
|
|
555
|
+
return true;
|
|
556
|
+
}
|
|
557
|
+
if (visited.has(current)) {
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
visited.add(current);
|
|
561
|
+
for (const next of dependencies[current] ?? []) {
|
|
562
|
+
queue.push(next);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return false;
|
|
566
|
+
}
|
|
567
|
+
//# sourceMappingURL=couple.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"couple.js","sourceRoot":"","sources":["../src/couple.ts"],"names":[],"mappings":"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"}
|