@vessel-dsp/runtime 0.2.2 → 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 +22 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/wasm/v2_dsp.wasm +0 -0
- package/dist/worklet/v2-audio-worklet.js +6770 -0
- package/dist/worklet/v2-worklet-protocol.d.ts +209 -0
- package/dist/worklet/v2-worklet-protocol.d.ts.map +1 -0
- package/dist/worklet/v2-worklet-protocol.js +35 -0
- package/dist/worklet/v2-worklet-protocol.js.map +1 -0
- package/package.json +6 -2
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import type { ControlId, Program } from "@vessel-dsp/compiler";
|
|
2
|
+
import type { ChainAdvisory } from "../chain-advisories";
|
|
3
|
+
import type { StageCoverage } from "../chain-slot";
|
|
4
|
+
import type { SupplyGroundConflict } from "../supply-ground";
|
|
5
|
+
export declare const v2WorkletProcessorName = "v2-pedal-processor";
|
|
6
|
+
/**
|
|
7
|
+
* The minimum port surface the worklet helper needs. `MessagePort` rather than a
|
|
8
|
+
* narrower type is what the workbench copy takes; this structural form accepts the
|
|
9
|
+
* same object while keeping this headless package free of a DOM lib import, so a
|
|
10
|
+
* host (or a bun test) can pass any `{ postMessage }` holder, including a real port.
|
|
11
|
+
*/
|
|
12
|
+
export type V2WorkletPort = {
|
|
13
|
+
postMessage(message: V2WorkletInboundMessage): void;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Send an inbound message to the worklet, type-checked.
|
|
17
|
+
*
|
|
18
|
+
* **This exists because `MessagePort.postMessage` takes `any`.** When the `load` message changed
|
|
19
|
+
* from `programs` to `slots`, `tsc` stayed silent on the one call site that still sent the old
|
|
20
|
+
* shape -- the worklet would have read `message.slots` as `undefined` and gone quiet, with no
|
|
21
|
+
* compile error anywhere. A one-line wrapper is the difference between that and a build failure.
|
|
22
|
+
*/
|
|
23
|
+
export declare function postV2WorkletMessage(port: V2WorkletPort, message: V2WorkletInboundMessage): void;
|
|
24
|
+
/**
|
|
25
|
+
* One slot in the chain the worklet is asked to build.
|
|
26
|
+
*
|
|
27
|
+
* **A discriminated union rather than a `Program[]`, because a chain slot is no longer always a
|
|
28
|
+
* compiled circuit.** The runtime has accepted injected processors since heterogeneous chain slots
|
|
29
|
+
* landed; this is the message shape that lets a caller send one. `programs` is gone rather than
|
|
30
|
+
* kept alongside -- an obsolete path, not a compatibility surface.
|
|
31
|
+
*
|
|
32
|
+
* `ir` covers **both** an impulse response and the cab simulation, and that is the design rather
|
|
33
|
+
* than a shortcut: nothing in `ChainSlot` distinguishes them, since both are buffer-in/buffer-out
|
|
34
|
+
* filters producing a miked signal, so a second kind would be two names for one behaviour.
|
|
35
|
+
*
|
|
36
|
+
* `nam` is its own kind for the opposite reason -- not because the chain treats it differently, but
|
|
37
|
+
* because building one needs different *inputs*: wasm bytes and a model document rather than taps.
|
|
38
|
+
* The `ExternalProcessor` it becomes is indistinguishable to the chain.
|
|
39
|
+
*/
|
|
40
|
+
export type BypassMode = "wire" | "buffer" | "effect";
|
|
41
|
+
export type V2WorkletSlot = {
|
|
42
|
+
readonly kind: "program";
|
|
43
|
+
readonly program: Program;
|
|
44
|
+
readonly bufferProgram?: Program;
|
|
45
|
+
readonly bypassMode?: BypassMode;
|
|
46
|
+
} | {
|
|
47
|
+
readonly kind: "ir";
|
|
48
|
+
/** Named in advisories and telemetry. A label, never a discriminator. */
|
|
49
|
+
readonly id: string;
|
|
50
|
+
/**
|
|
51
|
+
* Impulse response taps at the destination `AudioContext` rate. A `Float32Array`
|
|
52
|
+
* rather than a number list: structured clone carries typed arrays, and an IR is
|
|
53
|
+
* thousands of taps where JSON would be both large and lossy about precision.
|
|
54
|
+
* Resampling is the caller's, via `cab-mic-external-ir-resample.ts`.
|
|
55
|
+
*/
|
|
56
|
+
readonly taps: Float32Array;
|
|
57
|
+
readonly produces?: StageCoverage;
|
|
58
|
+
readonly expects?: StageCoverage;
|
|
59
|
+
/**
|
|
60
|
+
* Optional scalar on the taps. Omitted means 1 and no normalisation -- the worklet
|
|
61
|
+
* invents no level. See `IrProcessorOptions.gain`.
|
|
62
|
+
*/
|
|
63
|
+
readonly gain?: number;
|
|
64
|
+
readonly bypassMode?: BypassMode;
|
|
65
|
+
} | {
|
|
66
|
+
readonly kind: "nam";
|
|
67
|
+
/** Named in advisories and telemetry. A label, never a discriminator. */
|
|
68
|
+
readonly id: string;
|
|
69
|
+
/**
|
|
70
|
+
* The bytes of `web/nam-engine.wasm`.
|
|
71
|
+
*
|
|
72
|
+
* **Passed in rather than fetched, which is a requirement and not a preference:** an
|
|
73
|
+
* `AudioWorkletGlobalScope` has no `fetch`, so the module cannot load itself there. The
|
|
74
|
+
* worklet memoises instantiation, so sending these on a second load costs a structured
|
|
75
|
+
* clone and nothing more -- it will not recompile the module, which is the thing that
|
|
76
|
+
* crashed iOS tabs in the architecture this replaced.
|
|
77
|
+
*/
|
|
78
|
+
readonly wasmBytes: ArrayBuffer;
|
|
79
|
+
/** The `.nam` document's text. The engine parses it; nothing here does. */
|
|
80
|
+
readonly modelJson: string;
|
|
81
|
+
/**
|
|
82
|
+
* Defaults to `speaker-electrical` -- a load-box capture is taken *at* the speaker
|
|
83
|
+
* terminal. Pass `miked` only for a profile that states it is a full-rig capture; nothing
|
|
84
|
+
* infers that from a file name or a title.
|
|
85
|
+
*/
|
|
86
|
+
readonly produces?: StageCoverage;
|
|
87
|
+
readonly expects?: StageCoverage;
|
|
88
|
+
/** A2/slimmable size in [0,1]; negative or omitted selects full size. */
|
|
89
|
+
readonly slimSize?: number;
|
|
90
|
+
};
|
|
91
|
+
/** Main thread -> worklet. */
|
|
92
|
+
export type V2WorkletInboundMessage = {
|
|
93
|
+
readonly type: "load";
|
|
94
|
+
/** An ordered chain of slots. A compiled Program round-trips through emit() already
|
|
95
|
+
* (src/compiler/emit.ts) and an IR's taps are a typed array, so structured clone
|
|
96
|
+
* carries the whole list intact. Slot 0 runs first; its output feeds slot 1, and so
|
|
97
|
+
* on. */
|
|
98
|
+
readonly slots: readonly V2WorkletSlot[];
|
|
99
|
+
/**
|
|
100
|
+
* When present, every `program` slot runs on the C++/WASM console instead of the
|
|
101
|
+
* TS `ReferenceRuntime` — same Program ROM, different console. The host supplies
|
|
102
|
+
* the wasm binary because an AudioWorkletGlobalScope cannot fetch; the glue is
|
|
103
|
+
* bundled statically like the NAM engine's. Absent means the TS console, which is
|
|
104
|
+
* also the fallback for nothing: a wasm load failure is a reported error, never a
|
|
105
|
+
* silent downgrade — two consoles that can disagree must never be swapped quietly.
|
|
106
|
+
*/
|
|
107
|
+
readonly wasmConsole?: {
|
|
108
|
+
readonly wasmBytes: ArrayBuffer;
|
|
109
|
+
};
|
|
110
|
+
} | {
|
|
111
|
+
readonly type: "setControl";
|
|
112
|
+
/** Which slot's program owns this control. */
|
|
113
|
+
readonly slot: number;
|
|
114
|
+
readonly id: ControlId;
|
|
115
|
+
/** 0..1. That slot's own runtime applies its program's own taper; nothing here does. */
|
|
116
|
+
readonly position: number;
|
|
117
|
+
} | {
|
|
118
|
+
readonly type: "setBypassMode";
|
|
119
|
+
/** Which slot to change bypass mode for. */
|
|
120
|
+
readonly slot: number;
|
|
121
|
+
readonly mode: BypassMode;
|
|
122
|
+
};
|
|
123
|
+
/** Worklet -> main thread. */
|
|
124
|
+
export type V2WorkletOutboundMessage = {
|
|
125
|
+
readonly type: "loaded";
|
|
126
|
+
/** Every slot's controls, labelled by slot so a listener can address `setControl`
|
|
127
|
+
* correctly even when two slots declare the same control id. */
|
|
128
|
+
readonly controls: readonly {
|
|
129
|
+
readonly slot: number;
|
|
130
|
+
readonly id: ControlId;
|
|
131
|
+
}[];
|
|
132
|
+
/**
|
|
133
|
+
* Chain-level supply-ground conflicts (`src/runtime/supply-ground.ts`), empty when
|
|
134
|
+
* the chain agrees.
|
|
135
|
+
*
|
|
136
|
+
* Carried on `loaded` rather than as its own message, and that is the point: it is
|
|
137
|
+
* a property of the chain that just loaded, so it cannot arrive stale, be missed by
|
|
138
|
+
* a listener that subscribed late, or outlive the chain it describes. It rides
|
|
139
|
+
* *with* a successful load because the chain plays correctly either way -- each
|
|
140
|
+
* program is solved against its own rails -- and what it warns about is the board a
|
|
141
|
+
* listener would have to build to hear this on hardware.
|
|
142
|
+
*
|
|
143
|
+
* The type comes from the runtime module that computes it rather than being
|
|
144
|
+
* restated here, so the two cannot drift.
|
|
145
|
+
*/
|
|
146
|
+
readonly supplyGroundConflicts: readonly SupplyGroundConflict[];
|
|
147
|
+
/**
|
|
148
|
+
* What the chain can say about itself that no single program can
|
|
149
|
+
* (`src/runtime/chain-advisories.ts`): a seam it could not scale, or a slot whose
|
|
150
|
+
* speaker-terminal output feeds another slot's input. Empty when the chain is sound.
|
|
151
|
+
*
|
|
152
|
+
* Carried on `loaded` for the same reason as the conflicts above: it describes the
|
|
153
|
+
* chain that just loaded. A level mismatch is not corrected at such a seam, which is
|
|
154
|
+
* the old behaviour — the difference is that it is now stated rather than silent.
|
|
155
|
+
*/
|
|
156
|
+
readonly chainAdvisories: readonly ChainAdvisory[];
|
|
157
|
+
} | {
|
|
158
|
+
readonly type: "telemetry";
|
|
159
|
+
/** Every slot's own telemetry, labelled by slot and never blended into one total --
|
|
160
|
+
* a non-converging pedal in slot 2 must stay visible even when slot 0 is clean.
|
|
161
|
+
* `heldSamples` is nonConvergedSamples + nonFiniteSamples from RuntimeTelemetry: a
|
|
162
|
+
* silent overrun must be visible, per this repository's Evidence Hygiene rule. */
|
|
163
|
+
readonly slots: readonly {
|
|
164
|
+
readonly slot: number;
|
|
165
|
+
readonly samples: number;
|
|
166
|
+
readonly heldSamples: number;
|
|
167
|
+
readonly operatingPointFailures: number;
|
|
168
|
+
readonly peakIterations: number;
|
|
169
|
+
}[];
|
|
170
|
+
/**
|
|
171
|
+
* The WASM console's per-slot iteration peak. Separate from `slots` rather than folded
|
|
172
|
+
* into it because a WASM slot is an `ExternalProcessor` to `ChainRuntime`, which reports
|
|
173
|
+
* no telemetry for it at all -- so `slots` arrives EMPTY on the WASM path and the UI read
|
|
174
|
+
* `Peak: 0 iters` while the engine was at 232% CPU. Reporting a synthetic slot row with
|
|
175
|
+
* `heldSamples: 0` would have been worse: this module already refuses to let a processor
|
|
176
|
+
* slot claim a zero held-sample count, because "never ran a solve" and "converged fine"
|
|
177
|
+
* must not print the same. So only the field the C ABI actually exposes is carried.
|
|
178
|
+
*/
|
|
179
|
+
readonly wasmSlots?: readonly {
|
|
180
|
+
readonly slot: number;
|
|
181
|
+
/** `Engine::maxIterationsObserved()` -- a SESSION peak, never reset, not a window. */
|
|
182
|
+
readonly peakIterations: number;
|
|
183
|
+
}[];
|
|
184
|
+
/** True when the active program slots are executed on the WASM console. */
|
|
185
|
+
readonly isWasmConsole?: boolean;
|
|
186
|
+
/**
|
|
187
|
+
* MEAN CPU budget usage over the telemetry window (100% = the whole 2.67 ms quantum).
|
|
188
|
+
* A mean is the wrong statistic for a deadline and is kept only as context: an amp can
|
|
189
|
+
* average 101% while missing 616 deadlines, because what overruns is individual quanta,
|
|
190
|
+
* not the average. Judge with `cpuPeakPercent`/`cpuP95Percent`, and with `overrunCount`.
|
|
191
|
+
*/
|
|
192
|
+
readonly cpuLoadPercent?: number;
|
|
193
|
+
/** Worst single quantum in the telemetry window, as a percentage of budget. */
|
|
194
|
+
readonly cpuPeakPercent?: number;
|
|
195
|
+
/** 95th-percentile quantum in the window, as a percentage of budget. */
|
|
196
|
+
readonly cpuP95Percent?: number;
|
|
197
|
+
/** Worst single quantum since the chain loaded -- a rare spike must not scroll away. */
|
|
198
|
+
readonly cpuSessionPeakPercent?: number;
|
|
199
|
+
/** Average compute time per 128-sample quantum in milliseconds. */
|
|
200
|
+
readonly quantumTimeMs?: number;
|
|
201
|
+
/** Total number of audio quantum deadlines missed (quantum compute time > budget). */
|
|
202
|
+
readonly overrunCount?: number;
|
|
203
|
+
} | {
|
|
204
|
+
/** A refusal or a per-sample throw. The worklet goes silent rather than
|
|
205
|
+
* killing the audio graph; this message is how a listener finds out why. */
|
|
206
|
+
readonly type: "error";
|
|
207
|
+
readonly message: string;
|
|
208
|
+
};
|
|
209
|
+
//# sourceMappingURL=v2-worklet-protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2-worklet-protocol.d.ts","sourceRoot":"","sources":["../../src/worklet/v2-worklet-protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Message protocol between the main thread and the v2 AudioWorkletProcessor
|
|
2
|
+
// (v2-audio-worklet.ts). Ported from the workbench reference copy at
|
|
3
|
+
// `workbench/src/web/v2-worklet-protocol.ts`, which the workbench keeps; this
|
|
4
|
+
// package copy is the npm-published one. Behaviour is identical; only the
|
|
5
|
+
// imports below are retargeted into this package, and the `postV2WorkletMessage`
|
|
6
|
+
// port parameter is structural so hosts without a DOM lib can call it.
|
|
7
|
+
// Deliberately separate from pedal-worklet-protocol-types.d.ts:
|
|
8
|
+
// that protocol is v1's and carries 19 block.type variants plus a 622-line control
|
|
9
|
+
// dispatch (see thoughts/shared/plans/2026-08-12-runtime-modules.md, "where the boundary
|
|
10
|
+
// actually breaks"). The v2 runtime is a generic console that executes whatever a
|
|
11
|
+
// compiled Program declares, so its protocol is two messages, not a per-pedal dispatch.
|
|
12
|
+
//
|
|
13
|
+
// Both the worklet (bundled separately, see scripts/build-worklet.ts) and the main-thread
|
|
14
|
+
// panel import this file. It carries no runtime code beyond a couple of trivial
|
|
15
|
+
// constructors, so being imported into two separate bundles duplicates nothing that
|
|
16
|
+
// matters.
|
|
17
|
+
//
|
|
18
|
+
// "load" carries an ordered chain (`src/runtime/chain.ts`), not a single Program: a single
|
|
19
|
+
// pedal is that chain's one-element case, not a separate message shape -- the same "no
|
|
20
|
+
// single-program entry point" decision `admission.ts` already made. "setControl" addresses
|
|
21
|
+
// a control by (slot, id) rather than id alone, because two identical pedals in a chain
|
|
22
|
+
// declare the same control ids and slot index is the only thing that disambiguates them.
|
|
23
|
+
export const v2WorkletProcessorName = "v2-pedal-processor";
|
|
24
|
+
/**
|
|
25
|
+
* Send an inbound message to the worklet, type-checked.
|
|
26
|
+
*
|
|
27
|
+
* **This exists because `MessagePort.postMessage` takes `any`.** When the `load` message changed
|
|
28
|
+
* from `programs` to `slots`, `tsc` stayed silent on the one call site that still sent the old
|
|
29
|
+
* shape -- the worklet would have read `message.slots` as `undefined` and gone quiet, with no
|
|
30
|
+
* compile error anywhere. A one-line wrapper is the difference between that and a build failure.
|
|
31
|
+
*/
|
|
32
|
+
export function postV2WorkletMessage(port, message) {
|
|
33
|
+
port.postMessage(message);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=v2-worklet-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2-worklet-protocol.js","sourceRoot":"","sources":["../../src/worklet/v2-worklet-protocol.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,qEAAqE;AACrE,8EAA8E;AAC9E,0EAA0E;AAC1E,iFAAiF;AACjF,uEAAuE;AACvE,gEAAgE;AAChE,mFAAmF;AACnF,yFAAyF;AACzF,kFAAkF;AAClF,wFAAwF;AACxF,EAAE;AACF,0FAA0F;AAC1F,gFAAgF;AAChF,oFAAoF;AACpF,WAAW;AACX,EAAE;AACF,2FAA2F;AAC3F,uFAAuF;AACvF,2FAA2F;AAC3F,wFAAwF;AACxF,yFAAyF;AAOzF,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAY3D;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CACnC,IAAmB,EACnB,OAAgC;IAEhC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vessel-dsp/runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Real-time MNA simulation runtime and solver console for VesselDSP Program ROMs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"guitar-pedal",
|
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
},
|
|
34
34
|
"./wasm/*": {
|
|
35
35
|
"default": "./dist/wasm/*"
|
|
36
|
+
},
|
|
37
|
+
"./worklet.js": {
|
|
38
|
+
"default": "./dist/worklet/v2-audio-worklet.js"
|
|
36
39
|
}
|
|
37
40
|
},
|
|
38
41
|
"main": "./dist/index.js",
|
|
@@ -44,12 +47,13 @@
|
|
|
44
47
|
"LICENSE.md"
|
|
45
48
|
],
|
|
46
49
|
"scripts": {
|
|
47
|
-
"build": "tsc -p tsconfig.build.json && bun run ../../scripts/fix-dist-imports.ts dist && rm -rf dist/wasm && cp -r src/wasm dist/wasm",
|
|
50
|
+
"build": "tsc -p tsconfig.build.json && bun run ../../scripts/fix-dist-imports.ts dist && rm -rf dist/wasm && cp -r src/wasm dist/wasm && bun scripts/build-worklet.ts",
|
|
48
51
|
"clean": "rm -rf dist",
|
|
49
52
|
"prepack": "bun run --cwd ../core build && bun run --cwd ../compiler build && bun run build:wasm && bun run build",
|
|
50
53
|
"pack:dry-run": "npm pack --dry-run",
|
|
51
54
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
52
55
|
"build:wasm": "bash scripts/build-wasm.sh",
|
|
56
|
+
"build:worklet": "bun scripts/build-worklet.ts",
|
|
53
57
|
"test": "bun test tests",
|
|
54
58
|
"generate-kernels": "bun scripts/generate-kernels.ts"
|
|
55
59
|
},
|