ReferenceRuntime
Defined in: packages/runtime/src/reference-runtime.ts:1021
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new ReferenceRuntime(
program,options?):ReferenceRuntime
Defined in: packages/runtime/src/reference-runtime.ts:1534
Parameters
Section titled “Parameters”program
Section titled “program”options?
Section titled “options?”eliminateBlocks?
Section titled “eliminateBlocks?”ReadonlySet<string>
Returns
Section titled “Returns”ReferenceRuntime
Accessors
Section titled “Accessors”supplyRebuilds
Section titled “supplyRebuilds”Get Signature
Section titled “Get Signature”get supplyRebuilds():
number
Defined in: packages/runtime/src/reference-runtime.ts:2140
Block base-matrix rebuilds performed by setSupply so far. Read-only:
re-applying the values a stamp already has rebuilds nothing and leaves this
unchanged.
Returns
Section titled “Returns”number
Methods
Section titled “Methods”branchCurrentSnapshot()
Section titled “branchCurrentSnapshot()”branchCurrentSnapshot(): readonly
RuntimeBranchCurrent[]
Defined in: packages/runtime/src/reference-runtime.ts:2016
Read-only solved branch currents after prepare/process. See RuntimeBranchCurrent for
the sign convention.
Ordered by block, then by the stamp order within it, so a caller pairing these against
program.blocks[].stamps sees the same sequence.
Returns
Section titled “Returns”readonly RuntimeBranchCurrent[]
getLedBrightness()
Section titled “getLedBrightness()”getLedBrightness(
deviceId):number
Defined in: packages/runtime/src/reference-runtime.ts:2053
Get the physical, causal brightness of any LED or indicator in the circuit.
Brightness is a normalized value between 0.0 (completely dark) and 1.0 (fully glowing), calculated in real-time from the physical forward current flowing through the LED diode junction.
Parameters
Section titled “Parameters”deviceId
Section titled “deviceId”string
Returns
Section titled “Returns”number
getSupplies()
Section titled “getSupplies()”getSupplies(): readonly
SupplyInfo[]
Defined in: packages/runtime/src/reference-runtime.ts:2149
Every addressable dc-source stamp in program.blocks order, then stamp
order within each block. blockIndex is the index into program.blocks;
pass infos.map((info) => info.address) straight to setSupply.
Returns
Section titled “Returns”readonly SupplyInfo[]
hostSampleRate()
Section titled “hostSampleRate()”hostSampleRate():
number|null
Defined in: packages/runtime/src/reference-runtime.ts:2578
The rate the caller passed to prepare, as opposed to the solver’s sub-sample rate.
this.sampleRate is the rate the circuit is actually solved at; a console that needs to
know what it asked for — to size a buffer, or to report — wants this one.
Returns
Section titled “Returns”number | null
nodeVoltageSnapshot()
Section titled “nodeVoltageSnapshot()”nodeVoltageSnapshot(): readonly
RuntimeNodeVoltageSnapshot[]
Defined in: packages/runtime/src/reference-runtime.ts:1990
Read-only solved MNA node voltages for diagnostics after prepare/process.
Returns
Section titled “Returns”readonly RuntimeNodeVoltageSnapshot[]
prepare()
Section titled “prepare()”prepare(
sampleRate,options?):void
Defined in: packages/runtime/src/reference-runtime.ts:1575
The only entry point that accepts a sample rate. No default exists.
The Newton iteration cap is a real CPU-versus-accuracy knob, the same role SPICE’s ITL settings play, so a host may lower it. Lowering it does not make the runtime lie: samples that then fail to converge are held and counted.
realtimeBudget is the real-time admission gate (see ./admission.ts): supplying
one asks “can this program be shown to fit”, refusing by name and by number when it
cannot. Omitting it opts out of the gate entirely — this runtime has no honest
per-machine default to fall back on.
Parameters
Section titled “Parameters”sampleRate
Section titled “sampleRate”number
options?
Section titled “options?”inputSourceOhms?
Section titled “inputSourceOhms?”number
Series impedance of whatever drives the input jack, in ohms. A console setting, not a program one — the same compiled pedal is driven by a guitar (~5-15 kOhm plus pickup inductance), a buffered board (~100 Ohm), or a stiff test source (0), and none of that belongs in the ROM.
Defaults to 0, the historical stiff-drive behavior. It exists because a fuzz face’s defining dynamics ARE the loading interaction between its low, nonlinear input impedance and the pickup’s source impedance; driven from an ideal source it renders at constant maximum harshness — found by ear on the 2026-08-18 listening pass, twice, either side of the cabinet IR landing.
maxNewtonIterations?
Section titled “maxNewtonIterations?”number
oversample?
Section titled “oversample?”number
Solver sub-samples per host sample. A console setting, not a program one, for
the same reason inputSourceOhms is: the rate a host runs at is not a property of
the circuit, and decision 3 already puts sample rate on this side of the
boundary.
Why it earns its place, measured 2026-09-07. At 4x,
report:compiler-spice-parity goes from 47 to 50 agrees over 118 packets, five
packets move and every one improves, and none loses agreement. It also removes
boss-ce-5’s full-scale limit cycle — 4.000 V of AC from silence at 48 kHz,
1.01e-3 at 96 kHz — and that cycle is gone rather than folded down, so raw,
zero-order- and boxcar-decimated output are identical at every rate.
Why it is not on by default. Cost is about 3.2x the solver work at the corpus
median (2.6 iterations per output sample against 8.3), because everything floors
at 2.0-2.4 iterations per sub-sample whatever the rate and only packets above that
floor save anything. Those are the stiff ones: boss-ce-5 costs 1.23x and has the
limit cycle, mxr-phase-45 costs 3.84x and already agrees at 0.9710. A global
multiplier spends the most where it buys least, so the factor belongs with whoever
knows the packet — report-newton-deadline computes the stiffness signal.
What it does not do. Decimation here is zero-order: the last sub-sample of each host sample is the output. That is what the 47-to-50 measurement was taken with. A band-limiting decimator is a real improvement for broadband content and is not implemented, because a single 1 kHz tone cannot justify a filter choice.
realtimeBudget?
Section titled “realtimeBudget?”Returns
Section titled “Returns”void
process()
Section titled “process()”process(
input):Float64Array
Defined in: packages/runtime/src/reference-runtime.ts:2491
Parameters
Section titled “Parameters”Float64Array
Returns
Section titled “Returns”Float64Array
setControl()
Section titled “setControl()”setControl(
id,position):void
Defined in: packages/runtime/src/reference-runtime.ts:2095
Parameters
Section titled “Parameters”string
position
Section titled “position”number
Returns
Section titled “Returns”void
setSupply()
Section titled “setSupply()”setSupply(
addresses,volts,sourceOhms):void
Defined in: packages/runtime/src/reference-runtime.ts:2208
Retarget one or more supply stamps between process() calls: every named
dc-source stamp solves V(positive) - V(negative) - sourceOhms * i = volts with the new values from the next sample on.
Call between process() calls, never concurrently with one — the same
contract as setControl. Effect starts at the next sample: the affected
blocks’ cached base matrices are rebuilt exactly the way prepare()
builds them, and controlGeneration is bumped so the eliminated-path
factorisation, Z, and K_reduced rebuild on next use. The sparse schedule is
untouched: its pattern is value-independent.
Reactive state (capacitor and op-amp pole memory) carries over, which is
the physically honest response to hot-swapping a battery, and the DC
operating point is deliberately NOT re-solved — same transient-following
rule as setControl’s operatingPointPending comment.
Validation mirrors setControl and is atomic: volts must be finite,
sourceOhms must be finite and non-negative (a negative resistance is
gain, not sag), and every address must name an existing dc-source stamp
(unknown block index, non-MNA block, or a sourceIndex with no
dc-source all throw RuntimeError). All addresses are validated before
any state is touched, so a bad address leaves even the valid ones in the
same call unchanged. An empty address list changes nothing, and a call
whose values already match the stamps rebuilds nothing (supplyRebuilds
unchanged).
Never mutates the caller’s Program: the touched stamp objects are
replaced on this runtime’s own copies (copy on write), so two runtimes
built from one program, or a frozen program, never interact.
NOTE (cross-repo, gated by the extraction plan): the C++ console needs the
same setter — update its loaded program’s supply fields and re-derive
whatever it caches from them, with parity rows in the workbench harness.
This method changes no Program or Stamp shape, so it triggers no
format bump.
Parameters
Section titled “Parameters”addresses
Section titled “addresses”readonly SupplyAddress[]
number
sourceOhms
Section titled “sourceOhms”number
Returns
Section titled “Returns”void
solverPlan()
Section titled “solverPlan()”solverPlan():
object
Defined in: packages/runtime/src/reference-runtime.ts:2467
Which blocks took the static schedule and which kept the dense solve, and how often the pivot guard sent a solve back to the dense path.
Exists so “the sparse solver landed” is never read as “every block got faster”. Valid
only after prepare().
Returns
Section titled “Returns”abandoned
Section titled “abandoned”
readonlyabandoned: readonlystring[]
Blocks that gave the schedule up mid-run after a run of pivot-guard trips.
blocks
Section titled “blocks”
readonlyblocks: readonlyobject[]
scheduleFallbacks
Section titled “scheduleFallbacks”
readonlyscheduleFallbacks:number
scheduleSolves
Section titled “scheduleSolves”
readonlyscheduleSolves:number
telemetry()
Section titled “telemetry()”telemetry():
RuntimeTelemetry
Defined in: packages/runtime/src/reference-runtime.ts:1968
Read after processing. Non-zero failure counts mean the audio is not trustworthy.