@vessel-dsp/chain 0.1.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.
Files changed (58) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +230 -0
  3. package/dist/chain.d.ts +31 -0
  4. package/dist/chain.d.ts.map +1 -0
  5. package/dist/chain.js +208 -0
  6. package/dist/chain.js.map +1 -0
  7. package/dist/index.d.ts +14 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +13 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/ir-resample.d.ts +2 -0
  12. package/dist/ir-resample.d.ts.map +1 -0
  13. package/dist/ir-resample.js +41 -0
  14. package/dist/ir-resample.js.map +1 -0
  15. package/dist/nam/engine.d.ts +73 -0
  16. package/dist/nam/engine.d.ts.map +1 -0
  17. package/dist/nam/engine.js +89 -0
  18. package/dist/nam/engine.js.map +1 -0
  19. package/dist/nodes/amp-shaper-node.d.ts +37 -0
  20. package/dist/nodes/amp-shaper-node.d.ts.map +1 -0
  21. package/dist/nodes/amp-shaper-node.js +134 -0
  22. package/dist/nodes/amp-shaper-node.js.map +1 -0
  23. package/dist/nodes/gain-node.d.ts +19 -0
  24. package/dist/nodes/gain-node.d.ts.map +1 -0
  25. package/dist/nodes/gain-node.js +49 -0
  26. package/dist/nodes/gain-node.js.map +1 -0
  27. package/dist/nodes/input-profile-node.d.ts +38 -0
  28. package/dist/nodes/input-profile-node.d.ts.map +1 -0
  29. package/dist/nodes/input-profile-node.js +245 -0
  30. package/dist/nodes/input-profile-node.js.map +1 -0
  31. package/dist/nodes/ir-node.d.ts +56 -0
  32. package/dist/nodes/ir-node.d.ts.map +1 -0
  33. package/dist/nodes/ir-node.js +438 -0
  34. package/dist/nodes/ir-node.js.map +1 -0
  35. package/dist/nodes/master-node.d.ts +23 -0
  36. package/dist/nodes/master-node.d.ts.map +1 -0
  37. package/dist/nodes/master-node.js +93 -0
  38. package/dist/nodes/master-node.js.map +1 -0
  39. package/dist/nodes/nam-node.d.ts +81 -0
  40. package/dist/nodes/nam-node.d.ts.map +1 -0
  41. package/dist/nodes/nam-node.js +234 -0
  42. package/dist/nodes/nam-node.js.map +1 -0
  43. package/dist/nodes/runtime-node.d.ts +66 -0
  44. package/dist/nodes/runtime-node.d.ts.map +1 -0
  45. package/dist/nodes/runtime-node.js +247 -0
  46. package/dist/nodes/runtime-node.js.map +1 -0
  47. package/dist/supply-profile.d.ts +56 -0
  48. package/dist/supply-profile.d.ts.map +1 -0
  49. package/dist/supply-profile.js +139 -0
  50. package/dist/supply-profile.js.map +1 -0
  51. package/dist/types.d.ts +66 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +22 -0
  54. package/dist/types.js.map +1 -0
  55. package/nam-engine/NOTICE.md +32 -0
  56. package/nam-engine/nam-engine.js +2 -0
  57. package/nam-engine/nam-engine.wasm +0 -0
  58. package/package.json +67 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nam-node.d.ts","sourceRoot":"","sources":["../../src/nodes/nam-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC7B,gGAAgG;IAChG,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8FAA8F;IAC9F,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC3B,+FAA+F;IAC/F,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,gGAAgG;IAChG,QAAQ,CAAC,oBAAoB,EAAE,MAAM,EAAE,CAAC;CACxC;AAOD;;;;;;;;;;GAUG;AACH,qBAAa,OAAQ,YAAW,SAAS;IACxC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,SAAS;IACtB,uFAAuF;IACvF,QAAQ,CAAC,cAAc,KAAK;IAC5B,QAAQ,UAAS;IACjB,GAAG,SAAO;IAEV,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAS;IAE7B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,IAAI,CAA6B;IAEzC,OAAO,CAAC,QAAQ,CAA0D;IAC1E,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,oBAAoB,CAAgB;gBAEhC,EAAE,oBAAY,EAAE,IAAI,oBAAY,EAAE,MAAM,EAAE,aAAa;IAUnE,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAMjC,KAAK,IAAI,IAAI;IAMb,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAexC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAmBzC,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IASnC,OAAO,IAAI,WAAW;IAStB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAQjC,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,GAAG,YAAY;IAkCzD,OAAO,IAAI,IAAI;IAIf;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA2B5B,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,eAAe;CAYvB"}
@@ -0,0 +1,234 @@
1
+ import { loadNamModel, namLoudness, } from "../nam/engine.js";
2
+ const MAX_FRAMES = 1024;
3
+ const GAIN_DB_LIMIT = 24;
4
+ /** A model stating a rate this far from the chain rate is refused, not run silently. */
5
+ const SAMPLE_RATE_TOLERANCE_HZ = 0.5;
6
+ /**
7
+ * A NAM (Neural Amp Modeler) capture as a chain node.
8
+ *
9
+ * **The node applies no loudness gain of its own, deliberately.** `nam_process` already implements
10
+ * NAM's `Normalized` output mode internally -- `10^((-18 - modelLoudness)/20)`, smoothed against
11
+ * clicks -- which is the policy the workbench validated by listening. Applying it again here would
12
+ * double it. `getInfo().loudness` reports what the engine did so a host can show it.
13
+ *
14
+ * The engine instance is created at `prepare`, not in the constructor, because instantiation is
15
+ * asynchronous and belongs to the caller. Until then the node passes audio through.
16
+ */
17
+ export class NamNode {
18
+ id;
19
+ name;
20
+ kind = "nam";
21
+ /** The engine adds no algorithmic delay; the buffer is in-place and sample-aligned. */
22
+ latencySamples = 0;
23
+ bypassed = false;
24
+ mix = 1.0;
25
+ engine;
26
+ modelJson;
27
+ slimSize;
28
+ inputGainDb;
29
+ outputGainDb;
30
+ sampleRate = 48000;
31
+ instanceId = 0;
32
+ bufferPointer = 0;
33
+ view = null;
34
+ loudness = { modelLoudnessDb: null, appliedGain: 1 };
35
+ expectedSampleRate = null;
36
+ slimmable = false;
37
+ slimmableBreakpoints = [];
38
+ constructor(id = "nam-amp", name = "NAM Amp", config) {
39
+ this.id = id;
40
+ this.name = name;
41
+ this.engine = config.engine;
42
+ this.modelJson = config.model;
43
+ this.slimSize = config.slimSize ?? -1;
44
+ this.inputGainDb = clampGainDb(config.inputGainDb ?? 0);
45
+ this.outputGainDb = clampGainDb(config.outputGainDb ?? 0);
46
+ }
47
+ prepare(sampleRate) {
48
+ this.sampleRate = sampleRate;
49
+ this.destroyInstance();
50
+ this.adoptInstance(this.createLoadedInstance(this.modelJson));
51
+ }
52
+ reset() {
53
+ // Recreating the instance is what "reload the state" means for this node: the engine's
54
+ // prewarm settles the network's initial conditions, which is the point of a reset.
55
+ this.prepare(this.sampleRate);
56
+ }
57
+ getParam(id) {
58
+ switch (id) {
59
+ case "inputGainDb":
60
+ return this.inputGainDb;
61
+ case "outputGainDb":
62
+ return this.outputGainDb;
63
+ case "slimSize":
64
+ // Not a param the engine will act on for this model, so it is not reported as
65
+ // one: a host that offered it would be offering a control that does nothing.
66
+ return this.slimmable ? this.slimSize : undefined;
67
+ default:
68
+ return undefined;
69
+ }
70
+ }
71
+ setParam(id, value) {
72
+ switch (id) {
73
+ case "inputGainDb":
74
+ this.inputGainDb = clampGainDb(value);
75
+ break;
76
+ case "outputGainDb":
77
+ this.outputGainDb = clampGainDb(value);
78
+ break;
79
+ case "slimSize":
80
+ // Ignored for non-slimmable models, and ignored rather than refused: the
81
+ // parameter is a host-level control that only some models answer to.
82
+ if (this.slimmable) {
83
+ this.slimSize = value;
84
+ this.engine._nam_setSlimmableSize(this.instanceId, value);
85
+ }
86
+ break;
87
+ }
88
+ }
89
+ getParams() {
90
+ const params = {
91
+ inputGainDb: this.inputGainDb,
92
+ outputGainDb: this.outputGainDb,
93
+ };
94
+ if (this.slimmable)
95
+ params.slimSize = this.slimSize;
96
+ return params;
97
+ }
98
+ getInfo() {
99
+ return {
100
+ loudness: { ...this.loudness },
101
+ expectedSampleRate: this.expectedSampleRate,
102
+ slimmable: this.slimmable,
103
+ slimmableBreakpoints: [...this.slimmableBreakpoints],
104
+ };
105
+ }
106
+ /**
107
+ * Swap the model. The replacement is loaded into a **new** instance; the current one keeps
108
+ * running until the new one is ready, and is released only then. A refused model therefore
109
+ * never interrupts playback -- the engine's own reason is thrown and the old model stays.
110
+ */
111
+ setModel(modelJson) {
112
+ const instanceId = this.createLoadedInstance(modelJson);
113
+ const previous = this.instanceId;
114
+ this.modelJson = modelJson;
115
+ this.adoptInstance(instanceId);
116
+ if (previous > 0)
117
+ this.engine._nam_destroyInstance(previous);
118
+ }
119
+ process(input) {
120
+ const length = input.length;
121
+ if (this.bypassed || this.instanceId <= 0) {
122
+ return new Float64Array(input);
123
+ }
124
+ const output = new Float64Array(length);
125
+ const inputGain = 10 ** (this.inputGainDb / 20);
126
+ const outputGain = 10 ** (this.outputGainDb / 20);
127
+ const wetMix = Math.max(0, Math.min(1, this.mix));
128
+ const dryMix = 1 - wetMix;
129
+ const engine = this.engine;
130
+ for (let offset = 0; offset < length; offset += MAX_FRAMES) {
131
+ const frames = Math.min(MAX_FRAMES, length - offset);
132
+ // Re-derived only when the heap identity changes. `ALLOW_MEMORY_GROWTH` means a growth
133
+ // detaches every existing view, and a detached `Float32Array` reads as zeros rather
134
+ // than throwing -- so the check is an identity comparison, not a try/catch.
135
+ const heap = this.bufferView();
136
+ for (let i = 0; i < frames; i++) {
137
+ heap[i] = (input[offset + i] ?? 0) * inputGain;
138
+ }
139
+ engine._nam_process(this.instanceId, frames);
140
+ // `nam_process` never allocates, so the view above is still attached here.
141
+ for (let i = 0; i < frames; i++) {
142
+ const wet = (heap[i] ?? 0) * outputGain;
143
+ const dry = input[offset + i] ?? 0;
144
+ output[offset + i] = dryMix * dry + wetMix * wet;
145
+ }
146
+ }
147
+ return output;
148
+ }
149
+ dispose() {
150
+ this.destroyInstance();
151
+ }
152
+ /**
153
+ * Create an instance with `modelJson` loaded, or throw. The instance is released on every
154
+ * failure path so a refused model does not strand one.
155
+ */
156
+ createLoadedInstance(modelJson) {
157
+ const instanceId = this.engine._nam_createInstance(this.sampleRate, MAX_FRAMES);
158
+ if (instanceId <= 0) {
159
+ throw new Error("nam_createInstance refused");
160
+ }
161
+ try {
162
+ loadNamModel(this.engine, instanceId, modelJson, this.slimSize);
163
+ const expected = this.engine._nam_getExpectedSampleRate(instanceId);
164
+ if (expected >= 0 &&
165
+ Math.abs(expected - this.sampleRate) > SAMPLE_RATE_TOLERANCE_HZ) {
166
+ throw new Error(`NAM model ${labelOf(modelJson)} states ${expected} Hz but the chain runs at ` +
167
+ `${this.sampleRate} Hz; refusing to run it at the wrong rate`);
168
+ }
169
+ return instanceId;
170
+ }
171
+ catch (error) {
172
+ this.engine._nam_destroyInstance(instanceId);
173
+ throw error;
174
+ }
175
+ }
176
+ adoptInstance(instanceId) {
177
+ this.instanceId = instanceId;
178
+ this.bufferPointer = this.engine._nam_getBuffer(instanceId);
179
+ this.view = null;
180
+ this.loudness = namLoudness(this.engine, instanceId);
181
+ const expected = this.engine._nam_getExpectedSampleRate(instanceId);
182
+ this.expectedSampleRate = expected < 0 ? null : expected;
183
+ this.slimmable = this.engine._nam_isSlimmable(instanceId) === 1;
184
+ this.slimmableBreakpoints = [];
185
+ if (this.slimmable) {
186
+ const count = this.engine._nam_getSlimmableBreakpointCount(instanceId);
187
+ for (let index = 0; index < count; index++) {
188
+ const breakpoint = this.engine._nam_getSlimmableBreakpoint(instanceId, index);
189
+ if (breakpoint >= 0)
190
+ this.slimmableBreakpoints.push(breakpoint);
191
+ }
192
+ }
193
+ }
194
+ bufferView() {
195
+ if (this.view === null || this.view.buffer !== this.engine.HEAPF32.buffer) {
196
+ const offset = this.bufferPointer >> 2;
197
+ this.view = this.engine.HEAPF32.subarray(offset, offset + MAX_FRAMES);
198
+ }
199
+ return this.view;
200
+ }
201
+ destroyInstance() {
202
+ if (this.instanceId > 0) {
203
+ this.engine._nam_destroyInstance(this.instanceId);
204
+ }
205
+ this.instanceId = 0;
206
+ this.bufferPointer = 0;
207
+ this.view = null;
208
+ this.loudness = { modelLoudnessDb: null, appliedGain: 1 };
209
+ this.expectedSampleRate = null;
210
+ this.slimmable = false;
211
+ this.slimmableBreakpoints = [];
212
+ }
213
+ }
214
+ function clampGainDb(value) {
215
+ return Math.max(-GAIN_DB_LIMIT, Math.min(GAIN_DB_LIMIT, value));
216
+ }
217
+ /** A short, stable label for a model document, for error messages. */
218
+ function labelOf(modelJson) {
219
+ try {
220
+ const parsed = JSON.parse(modelJson);
221
+ if (typeof parsed === "object" &&
222
+ parsed !== null &&
223
+ "name" in parsed &&
224
+ typeof parsed.name === "string" &&
225
+ parsed.name.length > 0) {
226
+ return parsed.name;
227
+ }
228
+ }
229
+ catch {
230
+ // Not parseable, or has no name: fall through to the truncated document.
231
+ }
232
+ return `${modelJson.slice(0, 80)}...`;
233
+ }
234
+ //# sourceMappingURL=nam-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nam-node.js","sourceRoot":"","sources":["../../src/nodes/nam-node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import type { Program, SupplyResolution } from "@vessel-dsp/compiler";
2
+ import type { SupplyProfile } from "../supply-profile.js";
3
+ import type { ChainNode } from "../types.js";
4
+ export type RuntimeNodeOptions = {
5
+ readonly source?: string;
6
+ };
7
+ export declare class RuntimeNode implements ChainNode {
8
+ readonly id: string;
9
+ readonly name: string;
10
+ readonly kind = "circuit-runtime";
11
+ bypassed: boolean;
12
+ mix: number;
13
+ private runtime;
14
+ private program;
15
+ private params;
16
+ private sampleRate;
17
+ private source;
18
+ private supplyResolution;
19
+ private supplyProfile;
20
+ private appliedVoltsMagnitude;
21
+ private appliedOhms;
22
+ constructor(id: string, name: string, program: Program, options?: RuntimeNodeOptions);
23
+ getProgram(): Program;
24
+ /**
25
+ * Apply a supply profile to the circuit's external supply stamps.
26
+ *
27
+ * Resolves once (lazily, cached) with `resolveSupplyStamps(source,
28
+ * program)`, then retargets every resolved stamp through the runtime's
29
+ * `setSupply`. A null `openCircuitVolts` keeps each stamp's compiled
30
+ * magnitude; an explicit value replaces the magnitude. The sign always
31
+ * follows the stamp's own volts sign read from `getSupplies()`, so a
32
+ * positive-ground germanium rail stays negative.
33
+ *
34
+ * Throws when no source text was given or when nothing resolves, naming
35
+ * the refusal reason codes and rail ids. A program with refused derived
36
+ * rails but one resolved external rail applies to the resolved one and
37
+ * keeps the refusals visible via `getSupplyResolution()`.
38
+ *
39
+ * Callable before and after `prepare()` and between `process()` calls,
40
+ * following the runtime's contract. There is no audio-domain processing
41
+ * in this path.
42
+ */
43
+ setSupplyProfile(profile: SupplyProfile): void;
44
+ /**
45
+ * The cached supply resolution, or null until `setSupplyProfile` has
46
+ * resolved once.
47
+ */
48
+ getSupplyResolution(): SupplyResolution | null;
49
+ /**
50
+ * The last applied supply profile, or null until one has been applied.
51
+ */
52
+ getSupplyProfile(): SupplyProfile | null;
53
+ prepare(sampleRate: number): void;
54
+ reset(): void;
55
+ getParam(id: string): number | undefined;
56
+ setParam(id: string, value: number): void;
57
+ getParams(): Record<string, number>;
58
+ process(input: Float64Array | Float32Array): Float64Array;
59
+ private resolveSupplies;
60
+ private describeRefusals;
61
+ private compiledVoltsFor;
62
+ private applyProfileToRuntime;
63
+ private fallbackVoltsMagnitude;
64
+ private fallbackOhms;
65
+ }
66
+ //# sourceMappingURL=runtime-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-node.d.ts","sourceRoot":"","sources":["../../src/nodes/runtime-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAItE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,MAAM,kBAAkB,GAAG;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAKF,qBAAa,WAAY,YAAW,SAAS;IAC5C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,UAAS;IACjB,GAAG,SAAO;IAEV,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,MAAM,CAA8B;IAE5C,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,WAAW,CAAuB;gBAGzC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,kBAAkB;IAiB7B,UAAU,IAAI,OAAO;IAIrB;;;;;;;;;;;;;;;;;;OAkBG;IACH,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IA0C9C;;;OAGG;IACH,mBAAmB,IAAI,gBAAgB,GAAG,IAAI;IAI9C;;OAEG;IACH,gBAAgB,IAAI,aAAa,GAAG,IAAI;IAIxC,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAWjC,KAAK,IAAI,IAAI;IAYb,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAUxC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAsBzC,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAanC,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,GAAG,YAAY;IA0BzD,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,qBAAqB;IAuC7B,OAAO,CAAC,sBAAsB;IAkB9B,OAAO,CAAC,YAAY;CASpB"}
@@ -0,0 +1,247 @@
1
+ import { resolveSupplyStamps } from "@vessel-dsp/compiler";
2
+ import { ReferenceRuntime } from "@vessel-dsp/runtime";
3
+ import { customSupplyProfile } from "../supply-profile.js";
4
+ const SUPPLY_VOLTS_PARAM = "supplyOpenCircuitVolts";
5
+ const SUPPLY_OHMS_PARAM = "supplyInternalResistanceOhms";
6
+ export class RuntimeNode {
7
+ id;
8
+ name;
9
+ kind = "circuit-runtime";
10
+ bypassed = false;
11
+ mix = 1.0;
12
+ runtime;
13
+ program;
14
+ params = {};
15
+ sampleRate = 48000;
16
+ source;
17
+ supplyResolution = null;
18
+ supplyProfile = null;
19
+ appliedVoltsMagnitude = null;
20
+ appliedOhms = null;
21
+ constructor(id, name, program, options) {
22
+ this.id = id;
23
+ this.name = name;
24
+ this.program = program;
25
+ this.source = options?.source;
26
+ this.runtime = new ReferenceRuntime(program);
27
+ // Initialize default parameters from program controls
28
+ if (program.controls) {
29
+ for (const ctrl of program.controls) {
30
+ this.params[ctrl.id] = ctrl.defaultPosition ?? 0.5;
31
+ this.runtime.setControl(ctrl.id, this.params[ctrl.id]);
32
+ }
33
+ }
34
+ }
35
+ getProgram() {
36
+ return this.program;
37
+ }
38
+ /**
39
+ * Apply a supply profile to the circuit's external supply stamps.
40
+ *
41
+ * Resolves once (lazily, cached) with `resolveSupplyStamps(source,
42
+ * program)`, then retargets every resolved stamp through the runtime's
43
+ * `setSupply`. A null `openCircuitVolts` keeps each stamp's compiled
44
+ * magnitude; an explicit value replaces the magnitude. The sign always
45
+ * follows the stamp's own volts sign read from `getSupplies()`, so a
46
+ * positive-ground germanium rail stays negative.
47
+ *
48
+ * Throws when no source text was given or when nothing resolves, naming
49
+ * the refusal reason codes and rail ids. A program with refused derived
50
+ * rails but one resolved external rail applies to the resolved one and
51
+ * keeps the refusals visible via `getSupplyResolution()`.
52
+ *
53
+ * Callable before and after `prepare()` and between `process()` calls,
54
+ * following the runtime's contract. There is no audio-domain processing
55
+ * in this path.
56
+ */
57
+ setSupplyProfile(profile) {
58
+ if (profile.openCircuitVolts !== null &&
59
+ (!Number.isFinite(profile.openCircuitVolts) ||
60
+ profile.openCircuitVolts <= 0)) {
61
+ throw new Error(`setSupplyProfile: openCircuitVolts must be null or a finite positive magnitude, got ${String(profile.openCircuitVolts)}`);
62
+ }
63
+ if (!Number.isFinite(profile.internalResistanceOhms) ||
64
+ profile.internalResistanceOhms < 0) {
65
+ throw new Error(`setSupplyProfile: internalResistanceOhms must be a finite non-negative resistance, got ${String(profile.internalResistanceOhms)}`);
66
+ }
67
+ const resolution = this.resolveSupplies();
68
+ if (resolution.supplies.length === 0) {
69
+ throw new Error(`setSupplyProfile: no external supply resolved (${this.describeRefusals(resolution)})`);
70
+ }
71
+ this.applyProfileToRuntime(profile, resolution);
72
+ this.supplyProfile = profile;
73
+ if (profile.openCircuitVolts !== null) {
74
+ this.appliedVoltsMagnitude = profile.openCircuitVolts;
75
+ }
76
+ else {
77
+ const first = resolution.supplies[0];
78
+ if (first === undefined) {
79
+ throw new Error(`setSupplyProfile: no external supply resolved (${this.describeRefusals(resolution)})`);
80
+ }
81
+ this.appliedVoltsMagnitude = Math.abs(this.compiledVoltsFor(first.address));
82
+ }
83
+ this.appliedOhms = profile.internalResistanceOhms;
84
+ }
85
+ /**
86
+ * The cached supply resolution, or null until `setSupplyProfile` has
87
+ * resolved once.
88
+ */
89
+ getSupplyResolution() {
90
+ return this.supplyResolution;
91
+ }
92
+ /**
93
+ * The last applied supply profile, or null until one has been applied.
94
+ */
95
+ getSupplyProfile() {
96
+ return this.supplyProfile;
97
+ }
98
+ prepare(sampleRate) {
99
+ this.sampleRate = sampleRate;
100
+ this.runtime.prepare(sampleRate);
101
+ if (this.supplyProfile !== null && this.supplyResolution !== null) {
102
+ this.applyProfileToRuntime(this.supplyProfile, this.supplyResolution);
103
+ }
104
+ }
105
+ reset() {
106
+ if (this.sampleRate > 0) {
107
+ this.runtime.prepare(this.sampleRate);
108
+ if (this.supplyProfile !== null && this.supplyResolution !== null) {
109
+ this.applyProfileToRuntime(this.supplyProfile, this.supplyResolution);
110
+ }
111
+ }
112
+ }
113
+ getParam(id) {
114
+ if (id === SUPPLY_VOLTS_PARAM) {
115
+ return this.appliedVoltsMagnitude ?? undefined;
116
+ }
117
+ if (id === SUPPLY_OHMS_PARAM) {
118
+ return this.appliedOhms ?? undefined;
119
+ }
120
+ return this.params[id];
121
+ }
122
+ setParam(id, value) {
123
+ if (id === SUPPLY_VOLTS_PARAM || id === SUPPLY_OHMS_PARAM) {
124
+ const currentVolts = this.appliedVoltsMagnitude ?? this.fallbackVoltsMagnitude();
125
+ const currentOhms = this.appliedOhms ?? this.fallbackOhms();
126
+ const nextVolts = id === SUPPLY_VOLTS_PARAM ? value : currentVolts;
127
+ const nextOhms = id === SUPPLY_OHMS_PARAM ? value : currentOhms;
128
+ const custom = customSupplyProfile({
129
+ openCircuitVolts: nextVolts,
130
+ internalResistanceOhms: nextOhms,
131
+ name: "Custom supply (preset)",
132
+ });
133
+ this.setSupplyProfile(custom);
134
+ return;
135
+ }
136
+ this.params[id] = value;
137
+ this.runtime.setControl(id, value);
138
+ }
139
+ getParams() {
140
+ const base = { ...this.params };
141
+ if (this.supplyProfile !== null &&
142
+ this.appliedVoltsMagnitude !== null &&
143
+ this.appliedOhms !== null) {
144
+ base[SUPPLY_VOLTS_PARAM] = this.appliedVoltsMagnitude;
145
+ base[SUPPLY_OHMS_PARAM] = this.appliedOhms;
146
+ }
147
+ return base;
148
+ }
149
+ process(input) {
150
+ const length = input.length;
151
+ const input64 = input instanceof Float64Array ? input : new Float64Array(input);
152
+ if (this.bypassed) {
153
+ return new Float64Array(input64);
154
+ }
155
+ const wet = this.runtime.process(input64);
156
+ if (this.mix >= 0.999) {
157
+ return wet;
158
+ }
159
+ const output = new Float64Array(length);
160
+ const wetMix = this.mix;
161
+ const dryMix = 1.0 - wetMix;
162
+ for (let i = 0; i < length; i++) {
163
+ output[i] = dryMix * (input64[i] ?? 0) + wetMix * (wet[i] ?? 0);
164
+ }
165
+ return output;
166
+ }
167
+ resolveSupplies() {
168
+ if (this.supplyResolution !== null) {
169
+ return this.supplyResolution;
170
+ }
171
+ if (this.source === undefined) {
172
+ throw new Error("setSupplyProfile: no source text was given to this RuntimeNode, so no external supply can be resolved: pass the .vdsp text as the fourth constructor argument");
173
+ }
174
+ const resolution = resolveSupplyStamps(this.source, this.program);
175
+ this.supplyResolution = resolution;
176
+ return resolution;
177
+ }
178
+ describeRefusals(resolution) {
179
+ if (resolution.refused.length === 0) {
180
+ return "no refusals recorded";
181
+ }
182
+ return resolution.refused
183
+ .map((entry) => `${entry.reason}(${entry.railComponentId ?? "no-rail"})`)
184
+ .join(", ");
185
+ }
186
+ compiledVoltsFor(address) {
187
+ const block = this.program.blocks[address.blockIndex];
188
+ if (block?.kind !== "mna") {
189
+ throw new Error(`setSupplyProfile: resolved block index ${String(address.blockIndex)} is not an MNA block`);
190
+ }
191
+ for (const stamp of block.stamps) {
192
+ if (stamp.kind === "dc-source" &&
193
+ stamp.sourceIndex === address.sourceIndex) {
194
+ return stamp.volts;
195
+ }
196
+ }
197
+ throw new Error(`setSupplyProfile: resolved supply at block ${String(address.blockIndex)} source ${String(address.sourceIndex)} has no compiled dc-source stamp`);
198
+ }
199
+ applyProfileToRuntime(profile, resolution) {
200
+ const liveByKey = new Map();
201
+ for (const info of this.runtime.getSupplies()) {
202
+ liveByKey.set(`${info.address.blockIndex}:${info.address.sourceIndex}`, info.volts);
203
+ }
204
+ const grouped = new Map();
205
+ for (const supply of resolution.supplies) {
206
+ const compiled = this.compiledVoltsFor(supply.address);
207
+ const live = liveByKey.get(`${supply.address.blockIndex}:${supply.address.sourceIndex}`);
208
+ const signSource = live ?? compiled;
209
+ const sign = signSource < 0 ? -1 : 1;
210
+ const magnitude = profile.openCircuitVolts ?? Math.abs(compiled);
211
+ const targetVolts = sign * magnitude;
212
+ const key = targetVolts;
213
+ let list = grouped.get(key);
214
+ if (list === undefined) {
215
+ list = [];
216
+ grouped.set(key, list);
217
+ }
218
+ list.push(supply.address);
219
+ }
220
+ for (const [targetVolts, addresses] of grouped) {
221
+ this.runtime.setSupply(addresses, targetVolts, profile.internalResistanceOhms);
222
+ }
223
+ }
224
+ fallbackVoltsMagnitude() {
225
+ const live = this.runtime.getSupplies()[0];
226
+ if (live !== undefined && Number.isFinite(live.volts)) {
227
+ const magnitude = Math.abs(live.volts);
228
+ if (magnitude > 0) {
229
+ return magnitude;
230
+ }
231
+ }
232
+ if (this.supplyResolution !== null) {
233
+ for (const supply of this.supplyResolution.supplies) {
234
+ return Math.abs(this.compiledVoltsFor(supply.address));
235
+ }
236
+ }
237
+ throw new Error("setSupplyProfile: supplyOpenCircuitVolts has no current value to pair with: apply a profile first");
238
+ }
239
+ fallbackOhms() {
240
+ const live = this.runtime.getSupplies()[0];
241
+ if (live !== undefined && Number.isFinite(live.sourceOhms)) {
242
+ return live.sourceOhms;
243
+ }
244
+ throw new Error("setSupplyProfile: supplyInternalResistanceOhms has no current value to pair with: apply a profile first");
245
+ }
246
+ }
247
+ //# sourceMappingURL=runtime-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-node.js","sourceRoot":"","sources":["../../src/nodes/runtime-node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Battery supply profiles for {@link RuntimeNode.setSupplyProfile}.
3
+ *
4
+ * A profile is an open-circuit EMF magnitude plus a series resistance. It is
5
+ * applied to the circuit's external supply stamps only (see
6
+ * `resolveSupplyStamps` in `@vessel-dsp/compiler`): derived rails keep their
7
+ * compiled values, and mains-fed rails are refused. There is no audio-domain
8
+ * processing here: no envelope follower, no waveshaper, no extra chain node.
9
+ * The circuit's own current draw through the series resistance is what
10
+ * produces sag inside the solver.
11
+ *
12
+ * Provenance rule: every numeric value below is either the literal
13
+ * "definition" (the ideal source) or a citation of the one opened document,
14
+ * Jack Orman, "9v Battery Impedance", AMZ-FX Lab Notebook, copyright 2015,
15
+ * http://www.muzique.com/lab/batteryz.htm, method: unloaded reading with a
16
+ * Fluke multimeter, then loaded with a 560 ohm resistor, internal resistance
17
+ * by Ohm's law. No adapter profile is listed because no source was found for
18
+ * one (design note section 5). No number from the old PowerSupplyNode is
19
+ * reused.
20
+ */
21
+ export type SupplyProfile = {
22
+ readonly id: string;
23
+ readonly name: string;
24
+ /** Open-circuit EMF magnitude in volts, or null to keep the pedal's own declared supply voltage. */
25
+ readonly openCircuitVolts: number | null;
26
+ /** Series resistance in ohms. */
27
+ readonly internalResistanceOhms: number;
28
+ /** A citation (document, year, table, exact values, how a derived number was computed) or the literal "definition". */
29
+ readonly source: string;
30
+ };
31
+ /**
32
+ * The five built-in profiles, and only these. Adapter profiles are
33
+ * deliberately absent: no source was found for a regulated 9 V, regulated
34
+ * 18 V, or unregulated AC/DC resistance or voltage.
35
+ */
36
+ export declare const SUPPLY_PROFILES: readonly SupplyProfile[];
37
+ /**
38
+ * Build a profile from the caller's own measurement, following Orman's
39
+ * method: read the open-circuit volts E, then the loaded volts across a known
40
+ * resistor Rload, and compute Rint = (Vopen - Vloaded) / (Vloaded / Rload).
41
+ */
42
+ export declare function profileFromMeasurement(input: {
43
+ readonly openCircuitVolts: number;
44
+ readonly loadedVolts: number;
45
+ readonly loadOhms: number;
46
+ }): SupplyProfile;
47
+ /**
48
+ * Build a profile from caller-supplied numbers (for example a preset
49
+ * round-trip). The source is the caller: no citation is claimed.
50
+ */
51
+ export declare function customSupplyProfile(input: {
52
+ readonly openCircuitVolts: number | null;
53
+ readonly internalResistanceOhms: number;
54
+ readonly name?: string;
55
+ }): SupplyProfile;
56
+ //# sourceMappingURL=supply-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supply-profile.d.ts","sourceRoot":"","sources":["../src/supply-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,MAAM,aAAa,GAAG;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oGAAoG;IACpG,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,iCAAiC;IACjC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,uHAAuH;IACvH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB,CAAC;AA0DF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,aAAa,EAMnD,CAAC;AAaF;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B,GAAG,aAAa,CA8BhB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IAC1C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,aAAa,CAyBhB"}