@vessel-dsp/core 0.6.3 → 0.6.5
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 +11 -3
- package/dist/editor/commands.d.ts +13 -13
- package/dist/editor/commands.d.ts.map +1 -1
- package/dist/editor/commands.js +44 -29
- package/dist/editor/commands.js.map +1 -1
- package/dist/editor/factory.d.ts +1 -1
- package/dist/editor/factory.d.ts.map +1 -1
- package/dist/editor/factory.js +51 -51
- package/dist/editor/factory.js.map +1 -1
- package/dist/editor/history.d.ts +7 -7
- package/dist/editor/history.d.ts.map +1 -1
- package/dist/editor/history.js +20 -12
- package/dist/editor/history.js.map +1 -1
- package/dist/editor/index.d.ts +8 -8
- package/dist/editor/index.d.ts.map +1 -1
- package/dist/editor/index.js +4 -4
- package/dist/editor/index.js.map +1 -1
- package/dist/editor/layout.d.ts +1 -1
- package/dist/editor/layout.d.ts.map +1 -1
- package/dist/editor/layout.js +11 -6
- package/dist/editor/layout.js.map +1 -1
- package/dist/formats/circuit-json/serializer.d.ts +15 -15
- package/dist/formats/circuit-json/serializer.d.ts.map +1 -1
- package/dist/formats/circuit-json/serializer.js +486 -394
- package/dist/formats/circuit-json/serializer.js.map +1 -1
- package/dist/formats/document.d.ts +6 -6
- package/dist/formats/document.d.ts.map +1 -1
- package/dist/formats/document.js +112 -92
- package/dist/formats/document.js.map +1 -1
- package/dist/formats/interchange/parser.d.ts +1 -1
- package/dist/formats/interchange/parser.d.ts.map +1 -1
- package/dist/formats/interchange/parser.js +483 -286
- package/dist/formats/interchange/parser.js.map +1 -1
- package/dist/formats/interchange/serializer.d.ts +1 -1
- package/dist/formats/interchange/serializer.d.ts.map +1 -1
- package/dist/formats/interchange/serializer.js +59 -28
- package/dist/formats/interchange/serializer.js.map +1 -1
- package/dist/formats/ltspice/catalog.d.ts +1 -1
- package/dist/formats/ltspice/catalog.d.ts.map +1 -1
- package/dist/formats/ltspice/catalog.js +150 -48
- package/dist/formats/ltspice/catalog.js.map +1 -1
- package/dist/formats/ltspice/encoding.js +12 -40
- package/dist/formats/ltspice/encoding.js.map +1 -1
- package/dist/formats/ltspice/parser.d.ts +1 -1
- package/dist/formats/ltspice/parser.d.ts.map +1 -1
- package/dist/formats/ltspice/parser.js +122 -75
- package/dist/formats/ltspice/parser.js.map +1 -1
- package/dist/formats/ltspice/serializer.d.ts +1 -1
- package/dist/formats/ltspice/serializer.d.ts.map +1 -1
- package/dist/formats/ltspice/serializer.js +69 -47
- package/dist/formats/ltspice/serializer.js.map +1 -1
- package/dist/formats/schx/catalog.d.ts +1 -1
- package/dist/formats/schx/catalog.d.ts.map +1 -1
- package/dist/formats/schx/catalog.js +499 -254
- package/dist/formats/schx/catalog.js.map +1 -1
- package/dist/formats/schx/parser.d.ts +1 -1
- package/dist/formats/schx/parser.d.ts.map +1 -1
- package/dist/formats/schx/parser.js +40 -38
- package/dist/formats/schx/parser.js.map +1 -1
- package/dist/formats/schx/runtime-descriptors.d.ts +1 -1
- package/dist/formats/schx/runtime-descriptors.d.ts.map +1 -1
- package/dist/formats/schx/runtime-descriptors.js +239 -201
- package/dist/formats/schx/runtime-descriptors.js.map +1 -1
- package/dist/formats/schx/serializer.d.ts +2 -2
- package/dist/formats/schx/serializer.d.ts.map +1 -1
- package/dist/formats/schx/serializer.js +106 -106
- package/dist/formats/schx/serializer.js.map +1 -1
- package/dist/formats/schx/transforms.d.ts +1 -1
- package/dist/formats/schx/transforms.d.ts.map +1 -1
- package/dist/formats/schx/transforms.js +16 -8
- package/dist/formats/schx/transforms.js.map +1 -1
- package/dist/formats/spice/parser.d.ts +1 -1
- package/dist/formats/spice/parser.d.ts.map +1 -1
- package/dist/formats/spice/parser.js +105 -56
- package/dist/formats/spice/parser.js.map +1 -1
- package/dist/formats/spice/serializer.d.ts +1 -1
- package/dist/formats/spice/serializer.js +14 -12
- package/dist/formats/spice/serializer.js.map +1 -1
- package/dist/index.d.ts +47 -46
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -31
- package/dist/index.js.map +1 -1
- package/dist/model/connectivity.d.ts +1 -1
- package/dist/model/connectivity.d.ts.map +1 -1
- package/dist/model/connectivity.js +22 -7
- package/dist/model/connectivity.js.map +1 -1
- package/dist/model/netlist.d.ts +3 -3
- package/dist/model/netlist.d.ts.map +1 -1
- package/dist/model/netlist.js +117 -100
- package/dist/model/netlist.js.map +1 -1
- package/dist/model/properties.d.ts +1 -1
- package/dist/model/properties.d.ts.map +1 -1
- package/dist/model/properties.js +16 -16
- package/dist/model/properties.js.map +1 -1
- package/dist/model/quantity.d.ts +1 -1
- package/dist/model/quantity.d.ts.map +1 -1
- package/dist/model/quantity.js +35 -35
- package/dist/model/quantity.js.map +1 -1
- package/dist/model/types.d.ts +72 -37
- package/dist/model/types.d.ts.map +1 -1
- package/dist/model/types.js +1 -1
- package/dist/model/types.js.map +1 -1
- package/dist/model/validation.d.ts +5 -5
- package/dist/model/validation.d.ts.map +1 -1
- package/dist/model/validation.js +763 -315
- package/dist/model/validation.js.map +1 -1
- package/dist/model/wires.d.ts +1 -1
- package/dist/model/wires.d.ts.map +1 -1
- package/dist/model/wires.js +4 -1
- package/dist/model/wires.js.map +1 -1
- package/dist/panel/extract.d.ts +2 -2
- package/dist/panel/extract.d.ts.map +1 -1
- package/dist/panel/extract.js +376 -216
- package/dist/panel/extract.js.map +1 -1
- package/dist/panel/index.d.ts +7 -5
- package/dist/panel/index.d.ts.map +1 -1
- package/dist/panel/index.js +5 -4
- package/dist/panel/index.js.map +1 -1
- package/dist/panel/knobs.d.ts +4 -4
- package/dist/panel/knobs.d.ts.map +1 -1
- package/dist/panel/knobs.js +1 -1
- package/dist/panel/knobs.js.map +1 -1
- package/dist/panel/placement.d.ts +27 -0
- package/dist/panel/placement.d.ts.map +1 -0
- package/dist/panel/placement.js +91 -0
- package/dist/panel/placement.js.map +1 -0
- package/dist/panel/protocol.d.ts +1 -1
- package/dist/panel/protocol.d.ts.map +1 -1
- package/dist/panel/protocol.js +32 -23
- package/dist/panel/protocol.js.map +1 -1
- package/dist/panel/types.d.ts +26 -18
- package/dist/panel/types.d.ts.map +1 -1
- package/dist/panel/types.js.map +1 -1
- package/dist/preview/bounds.d.ts +1 -1
- package/dist/preview/bounds.d.ts.map +1 -1
- package/dist/preview/bounds.js +3 -3
- package/dist/preview/bounds.js.map +1 -1
- package/dist/preview/box-layout.d.ts +2 -2
- package/dist/preview/box-layout.js.map +1 -1
- package/dist/preview/colors.d.ts +1 -1
- package/dist/preview/colors.js +35 -35
- package/dist/preview/colors.js.map +1 -1
- package/dist/preview/hanging.d.ts +1 -1
- package/dist/preview/hanging.d.ts.map +1 -1
- package/dist/preview/hanging.js +4 -1
- package/dist/preview/hanging.js.map +1 -1
- package/dist/preview/junctions.d.ts +1 -1
- package/dist/preview/junctions.d.ts.map +1 -1
- package/dist/preview/junctions.js.map +1 -1
- package/dist/preview/label-layout.d.ts.map +1 -1
- package/dist/preview/label-layout.js +4 -4
- package/dist/preview/label-layout.js.map +1 -1
- package/dist/preview/ports.d.ts +1 -1
- package/dist/preview/ports.d.ts.map +1 -1
- package/dist/preview/ports.js +2 -1
- package/dist/preview/ports.js.map +1 -1
- package/dist/preview/renderable-wires.d.ts +1 -1
- package/dist/preview/renderable-wires.d.ts.map +1 -1
- package/dist/preview/renderable-wires.js +3 -1
- package/dist/preview/renderable-wires.js.map +1 -1
- package/dist/preview/routing.d.ts +1 -1
- package/dist/preview/routing.js +1 -1
- package/dist/preview/routing.js.map +1 -1
- package/dist/preview/snap.d.ts +1 -1
- package/dist/preview/snap.d.ts.map +1 -1
- package/dist/preview/snap.js +11 -3
- package/dist/preview/snap.js.map +1 -1
- package/dist/preview/symbols/svg-content.d.ts.map +1 -1
- package/dist/preview/symbols/svg-content.js +200 -50
- package/dist/preview/symbols/svg-content.js.map +1 -1
- package/dist/preview/symbols.d.ts +2 -2
- package/dist/preview/symbols.d.ts.map +1 -1
- package/dist/preview/symbols.js +100 -97
- package/dist/preview/symbols.js.map +1 -1
- package/dist/preview/wire-chains.d.ts +1 -1
- package/dist/preview/wire-chains.d.ts.map +1 -1
- package/dist/preview/wire-chains.js.map +1 -1
- package/dist/profiles.d.ts +600 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +118 -0
- package/dist/profiles.js.map +1 -0
- package/package.json +54 -54
package/dist/panel/extract.js
CHANGED
|
@@ -1,13 +1,48 @@
|
|
|
1
|
-
import { isParsedQuantity, propertyNumericValue, propertyStringValue } from
|
|
2
|
-
import { buildKnobSteps, snapKnobPosition } from
|
|
1
|
+
import { isParsedQuantity, propertyNumericValue, propertyStringValue, } from "../model/properties.js";
|
|
2
|
+
import { buildKnobSteps, snapKnobPosition } from "./knobs.js";
|
|
3
3
|
const RUNTIME_CONTINUOUS_CONTROL_SPECS = [
|
|
4
|
-
{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
{
|
|
4
|
+
{
|
|
5
|
+
key: "time",
|
|
6
|
+
controlProperty: "TimeControl",
|
|
7
|
+
wipeProperty: "TimeControlWipe",
|
|
8
|
+
sweepProperty: "TimeControlSweep",
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
key: "feedback",
|
|
12
|
+
controlProperty: "FeedbackControl",
|
|
13
|
+
wipeProperty: "FeedbackControlWipe",
|
|
14
|
+
sweepProperty: "FeedbackControlSweep",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
key: "mix",
|
|
18
|
+
controlProperty: "MixControl",
|
|
19
|
+
wipeProperty: "MixControlWipe",
|
|
20
|
+
sweepProperty: "MixControlSweep",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
key: "level",
|
|
24
|
+
controlProperty: "LevelControl",
|
|
25
|
+
wipeProperty: "LevelControlWipe",
|
|
26
|
+
sweepProperty: "LevelControlSweep",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
key: "tone",
|
|
30
|
+
controlProperty: "ToneControl",
|
|
31
|
+
wipeProperty: "ToneControlWipe",
|
|
32
|
+
sweepProperty: "ToneControlSweep",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
key: "mod-rate",
|
|
36
|
+
controlProperty: "ModRateControl",
|
|
37
|
+
wipeProperty: "ModRateControlWipe",
|
|
38
|
+
sweepProperty: "ModRateControlSweep",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
key: "mod-depth",
|
|
42
|
+
controlProperty: "ModDepthControl",
|
|
43
|
+
wipeProperty: "ModDepthControlWipe",
|
|
44
|
+
sweepProperty: "ModDepthControlSweep",
|
|
45
|
+
},
|
|
11
46
|
];
|
|
12
47
|
// extractPanel inspects a CircuitDocument and emits the typed Panel descriptor
|
|
13
48
|
// that drives the runtime control surface. It's a pure read over the existing
|
|
@@ -20,7 +55,19 @@ export function extractPanel(doc) {
|
|
|
20
55
|
const jacks = [];
|
|
21
56
|
for (const component of doc.components) {
|
|
22
57
|
switch (component.kind) {
|
|
23
|
-
case
|
|
58
|
+
case "variable-resistor": {
|
|
59
|
+
if (!isVariableResistorControl(component)) {
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
if (isSliderControl(component)) {
|
|
63
|
+
sliders.push(toSlider(component));
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
knobs.push(toKnob(component));
|
|
67
|
+
}
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
case "potentiometer": {
|
|
24
71
|
if (isSliderControl(component)) {
|
|
25
72
|
sliders.push(toSlider(component));
|
|
26
73
|
}
|
|
@@ -29,15 +76,15 @@ export function extractPanel(doc) {
|
|
|
29
76
|
}
|
|
30
77
|
break;
|
|
31
78
|
}
|
|
32
|
-
case
|
|
79
|
+
case "switch": {
|
|
33
80
|
switches.push(toSwitch(component));
|
|
34
81
|
break;
|
|
35
82
|
}
|
|
36
|
-
case
|
|
83
|
+
case "led": {
|
|
37
84
|
leds.push(toLed(component));
|
|
38
85
|
break;
|
|
39
86
|
}
|
|
40
|
-
case
|
|
87
|
+
case "jack": {
|
|
41
88
|
jacks.push(toJack(component));
|
|
42
89
|
break;
|
|
43
90
|
}
|
|
@@ -74,7 +121,7 @@ export function extractDeviceInterface(doc) {
|
|
|
74
121
|
for (const control of doc.deviceInterface?.controls ?? []) {
|
|
75
122
|
controls.set(control.id, {
|
|
76
123
|
...control,
|
|
77
|
-
provenance:
|
|
124
|
+
provenance: "vdsp-declared",
|
|
78
125
|
});
|
|
79
126
|
}
|
|
80
127
|
for (const inferred of inferredControls) {
|
|
@@ -90,24 +137,73 @@ export function extractDeviceInterface(doc) {
|
|
|
90
137
|
});
|
|
91
138
|
continue;
|
|
92
139
|
}
|
|
93
|
-
if (declared.binding !== undefined
|
|
94
|
-
|
|
95
|
-
|
|
140
|
+
if (declared.binding !== undefined &&
|
|
141
|
+
inferred.binding !== undefined &&
|
|
142
|
+
bindingSignature(declared.binding) !== bindingSignature(inferred.binding)) {
|
|
96
143
|
diagnostics.push({
|
|
97
|
-
code:
|
|
144
|
+
code: "device-interface-inferred-binding-conflict",
|
|
98
145
|
message: `Declared device interface control "${declared.id}" conflicts with inferred binding`,
|
|
99
146
|
componentId: declared.id,
|
|
100
147
|
});
|
|
101
148
|
}
|
|
102
149
|
}
|
|
150
|
+
const resolvedControls = Array.from(controls.values());
|
|
103
151
|
return {
|
|
104
152
|
groups: doc.controlGroups ?? [],
|
|
105
153
|
contexts: doc.controlContexts ?? [],
|
|
106
|
-
controls:
|
|
154
|
+
controls: resolvedControls,
|
|
155
|
+
groupMemberships: resolveControlGroupMemberships(doc.controlGroups ?? [], controls),
|
|
107
156
|
...(panel.placement === undefined ? {} : { placement: panel.placement }),
|
|
108
157
|
diagnostics,
|
|
109
158
|
};
|
|
110
159
|
}
|
|
160
|
+
function resolveControlGroupMemberships(groups, controls) {
|
|
161
|
+
const memberships = [];
|
|
162
|
+
const groupsById = new Map(groups.map((group) => [group.id, group]));
|
|
163
|
+
const explicitMemberships = new Set();
|
|
164
|
+
for (const group of groups) {
|
|
165
|
+
for (const member of group.members ?? []) {
|
|
166
|
+
const control = controls.get(member.controlId);
|
|
167
|
+
if (control === undefined) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
explicitMemberships.add(`${group.id}:${control.id}`);
|
|
171
|
+
memberships.push({
|
|
172
|
+
group,
|
|
173
|
+
control,
|
|
174
|
+
...(member.order === undefined ? {} : { order: member.order }),
|
|
175
|
+
...(member.appliesWhen === undefined
|
|
176
|
+
? {}
|
|
177
|
+
: { appliesWhen: member.appliesWhen }),
|
|
178
|
+
...(member.description === undefined
|
|
179
|
+
? {}
|
|
180
|
+
: { description: member.description }),
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
for (const control of controls.values()) {
|
|
185
|
+
if (control.groupId === undefined) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const group = groupsById.get(control.groupId);
|
|
189
|
+
if (group === undefined ||
|
|
190
|
+
explicitMemberships.has(`${group.id}:${control.id}`)) {
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
memberships.push({
|
|
194
|
+
group,
|
|
195
|
+
control,
|
|
196
|
+
...(control.order === undefined ? {} : { order: control.order }),
|
|
197
|
+
...(control.appliesWhen === undefined
|
|
198
|
+
? {}
|
|
199
|
+
: { appliesWhen: control.appliesWhen }),
|
|
200
|
+
...(control.description === undefined
|
|
201
|
+
? {}
|
|
202
|
+
: { description: control.description }),
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return memberships;
|
|
206
|
+
}
|
|
111
207
|
function inferDeviceInterfaceControls(doc, panel) {
|
|
112
208
|
const controls = [];
|
|
113
209
|
const controlInterfaceIds = new Set();
|
|
@@ -123,7 +219,7 @@ function inferDeviceInterfaceControls(doc, panel) {
|
|
|
123
219
|
controls.push({
|
|
124
220
|
id: knob.id,
|
|
125
221
|
label: knob.name,
|
|
126
|
-
kind:
|
|
222
|
+
kind: "knob",
|
|
127
223
|
role: roleFromControlId(knob.id),
|
|
128
224
|
binding: {
|
|
129
225
|
componentId,
|
|
@@ -138,21 +234,21 @@ function inferDeviceInterfaceControls(doc, panel) {
|
|
|
138
234
|
controls.push({
|
|
139
235
|
id: slider.id,
|
|
140
236
|
label: slider.name,
|
|
141
|
-
kind:
|
|
237
|
+
kind: "slider",
|
|
142
238
|
role: roleFromControlId(slider.id),
|
|
143
239
|
binding: {
|
|
144
240
|
componentId: componentIdFromControlId(slider.id),
|
|
145
241
|
controlId: slider.id,
|
|
146
242
|
controlName: slider.name,
|
|
147
243
|
},
|
|
148
|
-
provenance:
|
|
244
|
+
provenance: "source-inferred",
|
|
149
245
|
});
|
|
150
246
|
}
|
|
151
247
|
for (const switchControl of panel.switches) {
|
|
152
248
|
controls.push({
|
|
153
249
|
id: switchControl.id,
|
|
154
250
|
label: switchControl.name,
|
|
155
|
-
kind:
|
|
251
|
+
kind: "switch",
|
|
156
252
|
role: roleFromControlId(switchControl.id),
|
|
157
253
|
binding: {
|
|
158
254
|
componentId: componentIdFromControlId(switchControl.id),
|
|
@@ -166,14 +262,14 @@ function inferDeviceInterfaceControls(doc, panel) {
|
|
|
166
262
|
controls.push({
|
|
167
263
|
id: led.id,
|
|
168
264
|
label: led.name,
|
|
169
|
-
kind:
|
|
170
|
-
role:
|
|
265
|
+
kind: "led",
|
|
266
|
+
role: "indicator",
|
|
171
267
|
binding: {
|
|
172
268
|
componentId: componentIdFromControlId(led.id),
|
|
173
269
|
controlId: led.id,
|
|
174
270
|
controlName: led.name,
|
|
175
271
|
},
|
|
176
|
-
provenance:
|
|
272
|
+
provenance: "source-inferred",
|
|
177
273
|
});
|
|
178
274
|
}
|
|
179
275
|
for (const jack of panel.jacks) {
|
|
@@ -182,11 +278,11 @@ function inferDeviceInterfaceControls(doc, panel) {
|
|
|
182
278
|
controls.push({
|
|
183
279
|
id: jack.id,
|
|
184
280
|
label: jack.name,
|
|
185
|
-
kind:
|
|
281
|
+
kind: "jack",
|
|
186
282
|
role: jack.controlRole ?? jack.role,
|
|
187
283
|
...(binding === undefined ? {} : { binding }),
|
|
188
284
|
provenance: controlInterfaceIds.has(jack.id)
|
|
189
|
-
?
|
|
285
|
+
? "control-interface-declared"
|
|
190
286
|
: provenanceForComponentControl(doc, componentId),
|
|
191
287
|
});
|
|
192
288
|
}
|
|
@@ -196,12 +292,12 @@ function deviceBindingForJack(jack, componentId) {
|
|
|
196
292
|
if (jack.binding !== undefined) {
|
|
197
293
|
return deviceBindingFromControlInterfaceBinding(jack.binding, componentId);
|
|
198
294
|
}
|
|
199
|
-
if (jack.id.endsWith(
|
|
295
|
+
if (jack.id.endsWith(":tempo-tap")) {
|
|
200
296
|
return {
|
|
201
297
|
componentId,
|
|
202
298
|
controlId: jack.id,
|
|
203
299
|
controlName: jack.name,
|
|
204
|
-
property:
|
|
300
|
+
property: "TempoTapControl",
|
|
205
301
|
};
|
|
206
302
|
}
|
|
207
303
|
if (jack.sourceComponentId !== undefined || jack.id === componentId) {
|
|
@@ -220,23 +316,27 @@ function deviceBindingFromControlInterfaceBinding(binding, fallbackComponentId)
|
|
|
220
316
|
const componentId = binding.sourceComponentId ?? fallbackComponentId;
|
|
221
317
|
return {
|
|
222
318
|
componentId,
|
|
223
|
-
...(binding.controlId === undefined
|
|
224
|
-
|
|
319
|
+
...(binding.controlId === undefined
|
|
320
|
+
? {}
|
|
321
|
+
: { controlId: binding.controlId }),
|
|
322
|
+
...(binding.controlName === undefined
|
|
323
|
+
? {}
|
|
324
|
+
: { controlName: binding.controlName }),
|
|
225
325
|
...(binding.property === undefined ? {} : { property: binding.property }),
|
|
226
326
|
};
|
|
227
327
|
}
|
|
228
328
|
function provenanceForComponentControl(doc, componentId) {
|
|
229
329
|
const component = doc.components.find((candidate) => candidate.id === componentId);
|
|
230
330
|
return component !== undefined && isRuntimeDescriptor(component)
|
|
231
|
-
?
|
|
232
|
-
:
|
|
331
|
+
? "runtime-descriptor-inferred"
|
|
332
|
+
: "source-inferred";
|
|
233
333
|
}
|
|
234
334
|
function componentIdFromControlId(id) {
|
|
235
|
-
const separator = id.indexOf(
|
|
335
|
+
const separator = id.indexOf(":");
|
|
236
336
|
return separator <= 0 ? id : id.slice(0, separator);
|
|
237
337
|
}
|
|
238
338
|
function roleFromControlId(id) {
|
|
239
|
-
const separator = id.indexOf(
|
|
339
|
+
const separator = id.indexOf(":");
|
|
240
340
|
const raw = separator >= 0 ? id.slice(separator + 1) : id;
|
|
241
341
|
return normalizeToken(raw);
|
|
242
342
|
}
|
|
@@ -247,25 +347,25 @@ function runtimeControlProperty(id) {
|
|
|
247
347
|
return spec.controlProperty;
|
|
248
348
|
}
|
|
249
349
|
}
|
|
250
|
-
if (key ===
|
|
251
|
-
return
|
|
350
|
+
if (key === "mode") {
|
|
351
|
+
return "ModeControl";
|
|
252
352
|
}
|
|
253
|
-
if (key ===
|
|
254
|
-
return
|
|
353
|
+
if (key === "tempo-tap") {
|
|
354
|
+
return "TempoTapControl";
|
|
255
355
|
}
|
|
256
|
-
if (key ===
|
|
257
|
-
return
|
|
356
|
+
if (key === "direct-out") {
|
|
357
|
+
return "DirectOutputJack";
|
|
258
358
|
}
|
|
259
359
|
return undefined;
|
|
260
360
|
}
|
|
261
361
|
function bindingSignature(binding) {
|
|
262
362
|
return [
|
|
263
363
|
binding.componentId,
|
|
264
|
-
binding.controlId ??
|
|
265
|
-
binding.controlName ??
|
|
266
|
-
binding.property ??
|
|
267
|
-
binding.externalInterfaceId ??
|
|
268
|
-
].join(
|
|
364
|
+
binding.controlId ?? "",
|
|
365
|
+
binding.controlName ?? "",
|
|
366
|
+
binding.property ?? "",
|
|
367
|
+
binding.externalInterfaceId ?? "",
|
|
368
|
+
].join(":");
|
|
269
369
|
}
|
|
270
370
|
function applyControlInterfaces(controlInterfaces, jacks) {
|
|
271
371
|
for (const controlInterface of controlInterfaces ?? []) {
|
|
@@ -295,70 +395,90 @@ function toControlInterfaceJack(controlInterface) {
|
|
|
295
395
|
...(sourceComponentId === undefined ? {} : { sourceComponentId }),
|
|
296
396
|
...(controlRole === undefined ? {} : { controlRole }),
|
|
297
397
|
...(interfaceName === undefined ? {} : { interface: interfaceName }),
|
|
298
|
-
...(controlInterface.connector === undefined
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
...(controlInterface.
|
|
302
|
-
|
|
398
|
+
...(controlInterface.connector === undefined
|
|
399
|
+
? {}
|
|
400
|
+
: { connector: controlInterface.connector }),
|
|
401
|
+
...(controlInterface.assignmentHint === undefined
|
|
402
|
+
? {}
|
|
403
|
+
: { assignmentHint: controlInterface.assignmentHint }),
|
|
404
|
+
...(controlInterface.polarity === undefined
|
|
405
|
+
? {}
|
|
406
|
+
: { polarity: controlInterface.polarity }),
|
|
407
|
+
...(controlInterface.binding === undefined
|
|
408
|
+
? {}
|
|
409
|
+
: { binding: controlInterface.binding }),
|
|
410
|
+
...(controlInterface.description === undefined
|
|
411
|
+
? {}
|
|
412
|
+
: { description: controlInterface.description }),
|
|
303
413
|
};
|
|
304
414
|
}
|
|
305
415
|
function jackRoleForControlInterface(controlInterface) {
|
|
306
416
|
switch (controlInterface.role) {
|
|
307
|
-
case
|
|
308
|
-
return
|
|
309
|
-
case
|
|
310
|
-
return
|
|
311
|
-
case
|
|
312
|
-
case
|
|
313
|
-
case
|
|
314
|
-
case
|
|
315
|
-
return
|
|
316
|
-
case
|
|
317
|
-
return
|
|
417
|
+
case "tempo-tap":
|
|
418
|
+
return "tempo-tap";
|
|
419
|
+
case "expression":
|
|
420
|
+
return "expression";
|
|
421
|
+
case "external-control":
|
|
422
|
+
case "trigger":
|
|
423
|
+
case "reset":
|
|
424
|
+
case "sampler-trigger":
|
|
425
|
+
return "external-control";
|
|
426
|
+
case "unknown":
|
|
427
|
+
return "unknown";
|
|
318
428
|
}
|
|
319
429
|
}
|
|
320
430
|
function defaultControlRole(controlInterface) {
|
|
321
|
-
return controlInterface.role ===
|
|
431
|
+
return controlInterface.role === "unknown" ||
|
|
432
|
+
controlInterface.role === "external-control"
|
|
322
433
|
? undefined
|
|
323
434
|
: controlInterface.role;
|
|
324
435
|
}
|
|
325
436
|
function defaultInterfaceName(controlInterface) {
|
|
326
|
-
if (controlInterface.role ===
|
|
327
|
-
return
|
|
437
|
+
if (controlInterface.role === "tempo-tap") {
|
|
438
|
+
return "tap-tempo";
|
|
328
439
|
}
|
|
329
|
-
if (controlInterface.role ===
|
|
440
|
+
if (controlInterface.role === "unknown") {
|
|
330
441
|
return undefined;
|
|
331
442
|
}
|
|
332
|
-
return
|
|
443
|
+
return "external-control-input";
|
|
333
444
|
}
|
|
334
445
|
function toKnob(component) {
|
|
335
|
-
const taper = resolveTaper(propertyString(component,
|
|
336
|
-
const stepLabels = parseStepLabels(propertyStringAny(component, [
|
|
337
|
-
const explicitStepCount = parseStepCount(propertyStringAny(component, [
|
|
338
|
-
|
|
446
|
+
const taper = resolveTaper(propertyString(component, "Sweep") ?? propertyString(component, "Taper"));
|
|
447
|
+
const stepLabels = parseStepLabels(propertyStringAny(component, ["StepLabels", "Steps"]));
|
|
448
|
+
const explicitStepCount = parseStepCount(propertyStringAny(component, [
|
|
449
|
+
"StepCount",
|
|
450
|
+
"Detents",
|
|
451
|
+
"Positions",
|
|
452
|
+
"Steps",
|
|
453
|
+
]));
|
|
454
|
+
const steps = buildKnobSteps(stepLabels.length >= 2 ? stepLabels.length : (explicitStepCount ?? 0), stepLabels);
|
|
339
455
|
const rawDefaultPosition = clamp01(parseNumeric(component.properties.Wipe) ?? 0.5);
|
|
340
|
-
const defaultPosition = steps === undefined
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
const
|
|
456
|
+
const defaultPosition = steps === undefined
|
|
457
|
+
? rawDefaultPosition
|
|
458
|
+
: snapKnobPosition({ steps }, rawDefaultPosition);
|
|
459
|
+
const resistance = quantityProperty(component, "Resistance");
|
|
460
|
+
const gangGroup = propertyString(component, "Group") ?? undefined;
|
|
461
|
+
const description = propertyString(component, "Description") ?? undefined;
|
|
344
462
|
return {
|
|
345
463
|
id: component.id,
|
|
346
464
|
name: component.name,
|
|
347
465
|
taper,
|
|
348
|
-
controlMode: steps === undefined ?
|
|
466
|
+
controlMode: steps === undefined ? "continuous" : "stepped",
|
|
349
467
|
defaultPosition,
|
|
350
468
|
...(steps !== undefined ? { steps } : {}),
|
|
351
469
|
...(resistance !== undefined ? { resistance } : {}),
|
|
352
470
|
...(gangGroup !== undefined && gangGroup.length > 0 ? { gangGroup } : {}),
|
|
353
|
-
...(description !== undefined && description.length > 0
|
|
471
|
+
...(description !== undefined && description.length > 0
|
|
472
|
+
? { description }
|
|
473
|
+
: {}),
|
|
354
474
|
};
|
|
355
475
|
}
|
|
356
476
|
function toSlider(component) {
|
|
357
477
|
const defaultPosition = clamp01(parseNumeric(component.properties.Wipe) ?? 0.5);
|
|
358
|
-
const orientation = resolveSliderOrientation(propertyStringAny(component, [
|
|
478
|
+
const orientation = resolveSliderOrientation(propertyStringAny(component, ["Orientation", "SliderOrientation"]));
|
|
359
479
|
const range = sliderRange(component);
|
|
360
|
-
const gangGroup = propertyString(component,
|
|
361
|
-
const description = propertyString(component,
|
|
480
|
+
const gangGroup = propertyString(component, "Group") ?? undefined;
|
|
481
|
+
const description = propertyString(component, "Description") ?? undefined;
|
|
362
482
|
return {
|
|
363
483
|
id: component.id,
|
|
364
484
|
name: component.name,
|
|
@@ -366,16 +486,18 @@ function toSlider(component) {
|
|
|
366
486
|
orientation,
|
|
367
487
|
...(range !== undefined ? { range } : {}),
|
|
368
488
|
...(gangGroup !== undefined && gangGroup.length > 0 ? { gangGroup } : {}),
|
|
369
|
-
...(description !== undefined && description.length > 0
|
|
489
|
+
...(description !== undefined && description.length > 0
|
|
490
|
+
? { description }
|
|
491
|
+
: {}),
|
|
370
492
|
};
|
|
371
493
|
}
|
|
372
494
|
function toSwitch(component) {
|
|
373
495
|
const switchKind = resolveSwitchKind(component);
|
|
374
496
|
const { poles, positions } = switchGeometry(switchKind);
|
|
375
497
|
const defaultPosition = clampInt(parseNumeric(component.properties.Position) ?? 0, 0, positions - 1);
|
|
376
|
-
const gangGroup = propertyString(component,
|
|
377
|
-
const partNumber = propertyString(component,
|
|
378
|
-
const description = propertyString(component,
|
|
498
|
+
const gangGroup = propertyString(component, "Group") ?? undefined;
|
|
499
|
+
const partNumber = propertyString(component, "PartNumber") ?? undefined;
|
|
500
|
+
const description = propertyString(component, "Description") ?? undefined;
|
|
379
501
|
return {
|
|
380
502
|
id: component.id,
|
|
381
503
|
name: component.name,
|
|
@@ -384,30 +506,39 @@ function toSwitch(component) {
|
|
|
384
506
|
positions,
|
|
385
507
|
defaultPosition,
|
|
386
508
|
...(gangGroup !== undefined && gangGroup.length > 0 ? { gangGroup } : {}),
|
|
387
|
-
...(partNumber !== undefined && partNumber.length > 0
|
|
388
|
-
|
|
509
|
+
...(partNumber !== undefined && partNumber.length > 0
|
|
510
|
+
? { partNumber }
|
|
511
|
+
: {}),
|
|
512
|
+
...(description !== undefined && description.length > 0
|
|
513
|
+
? { description }
|
|
514
|
+
: {}),
|
|
389
515
|
};
|
|
390
516
|
}
|
|
391
517
|
function toLed(component) {
|
|
392
|
-
const color = propertyString(component,
|
|
393
|
-
const partNumber = propertyString(component,
|
|
394
|
-
const description = propertyString(component,
|
|
518
|
+
const color = propertyString(component, "Color") ?? inferLedColor(component);
|
|
519
|
+
const partNumber = propertyString(component, "PartNumber") ?? undefined;
|
|
520
|
+
const description = propertyString(component, "Description") ?? undefined;
|
|
395
521
|
return {
|
|
396
522
|
id: component.id,
|
|
397
523
|
name: component.name,
|
|
398
524
|
...(color !== undefined ? { color } : {}),
|
|
399
|
-
...(partNumber !== undefined && partNumber.length > 0
|
|
400
|
-
|
|
525
|
+
...(partNumber !== undefined && partNumber.length > 0
|
|
526
|
+
? { partNumber }
|
|
527
|
+
: {}),
|
|
528
|
+
...(description !== undefined && description.length > 0
|
|
529
|
+
? { description }
|
|
530
|
+
: {}),
|
|
401
531
|
};
|
|
402
532
|
}
|
|
403
533
|
function toJack(component) {
|
|
404
534
|
const role = resolveJackRole(component);
|
|
405
|
-
const name = nonEmptyString(propertyStringAny(component, [
|
|
406
|
-
|
|
407
|
-
const
|
|
408
|
-
const
|
|
409
|
-
const
|
|
410
|
-
const
|
|
535
|
+
const name = nonEmptyString(propertyStringAny(component, ["JackLabel", "Label"])) ??
|
|
536
|
+
component.name;
|
|
537
|
+
const audioRole = nonEmptyString(propertyString(component, "AudioRole"));
|
|
538
|
+
const impedance = quantityProperty(component, "Impedance");
|
|
539
|
+
const controlRole = nonEmptyString(propertyString(component, "ControlRole"));
|
|
540
|
+
const interfaceName = nonEmptyString(propertyString(component, "Interface"));
|
|
541
|
+
const description = propertyString(component, "Description") ?? undefined;
|
|
411
542
|
const sourceTypeName = component.sourceTypeName ?? undefined;
|
|
412
543
|
return {
|
|
413
544
|
id: component.id,
|
|
@@ -418,7 +549,9 @@ function toJack(component) {
|
|
|
418
549
|
...(sourceTypeName !== undefined ? { sourceTypeName } : {}),
|
|
419
550
|
...(controlRole !== undefined ? { controlRole } : {}),
|
|
420
551
|
...(interfaceName !== undefined ? { interface: interfaceName } : {}),
|
|
421
|
-
...(description !== undefined && description.length > 0
|
|
552
|
+
...(description !== undefined && description.length > 0
|
|
553
|
+
? { description }
|
|
554
|
+
: {}),
|
|
422
555
|
};
|
|
423
556
|
}
|
|
424
557
|
function runtimeDescriptorKnobs(component) {
|
|
@@ -432,7 +565,7 @@ function runtimeDescriptorKnobs(component) {
|
|
|
432
565
|
id: `${component.id}:${spec.key}`,
|
|
433
566
|
name,
|
|
434
567
|
taper: resolveTaper(propertyString(component, spec.sweepProperty)),
|
|
435
|
-
controlMode:
|
|
568
|
+
controlMode: "continuous",
|
|
436
569
|
defaultPosition: clamp01(parseNumeric(component.properties[spec.wipeProperty]) ?? 0.5),
|
|
437
570
|
});
|
|
438
571
|
}
|
|
@@ -443,96 +576,120 @@ function runtimeDescriptorKnobs(component) {
|
|
|
443
576
|
return knobs;
|
|
444
577
|
}
|
|
445
578
|
function runtimeDescriptorMode(component) {
|
|
446
|
-
const name = nonEmptyString(propertyString(component,
|
|
447
|
-
const labels = parseStepLabels(propertyStringAny(component, [
|
|
448
|
-
const explicitStepCount = parseStepCount(propertyStringAny(component, [
|
|
449
|
-
const steps = buildKnobSteps(labels.length >= 2 ? labels.length : explicitStepCount ?? 0, labels);
|
|
579
|
+
const name = nonEmptyString(propertyString(component, "ModeControl"));
|
|
580
|
+
const labels = parseStepLabels(propertyStringAny(component, ["ModeLabels", "ModeOptions"]));
|
|
581
|
+
const explicitStepCount = parseStepCount(propertyStringAny(component, ["ModeStepCount", "ModeSteps", "ModeCount"]));
|
|
582
|
+
const steps = buildKnobSteps(labels.length >= 2 ? labels.length : (explicitStepCount ?? 0), labels);
|
|
450
583
|
if (name === undefined || steps === undefined) {
|
|
451
584
|
return undefined;
|
|
452
585
|
}
|
|
453
586
|
return {
|
|
454
587
|
id: `${component.id}:mode`,
|
|
455
588
|
name,
|
|
456
|
-
taper:
|
|
457
|
-
controlMode:
|
|
458
|
-
defaultPosition: runtimeModeDefaultPosition(steps, parseNumericAny(component, [
|
|
589
|
+
taper: "unknown",
|
|
590
|
+
controlMode: "stepped",
|
|
591
|
+
defaultPosition: runtimeModeDefaultPosition(steps, parseNumericAny(component, [
|
|
592
|
+
"ModeControlWipe",
|
|
593
|
+
"ModeDefaultIndex",
|
|
594
|
+
"ModeIndex",
|
|
595
|
+
])),
|
|
459
596
|
steps,
|
|
460
597
|
};
|
|
461
598
|
}
|
|
462
599
|
function runtimeDescriptorTempoTap(component) {
|
|
463
|
-
const name = nonEmptyString(propertyStringAny(component, [
|
|
600
|
+
const name = nonEmptyString(propertyStringAny(component, [
|
|
601
|
+
"TempoTapControl",
|
|
602
|
+
"TapTempoControl",
|
|
603
|
+
"TempoControl",
|
|
604
|
+
]));
|
|
464
605
|
if (name === undefined) {
|
|
465
606
|
return undefined;
|
|
466
607
|
}
|
|
467
608
|
const sourceTypeName = component.sourceTypeName ?? undefined;
|
|
468
|
-
const assignmentHint =
|
|
609
|
+
const assignmentHint = "momentary";
|
|
469
610
|
return {
|
|
470
611
|
id: `${component.id}:tempo-tap`,
|
|
471
612
|
name,
|
|
472
|
-
role:
|
|
613
|
+
role: "tempo-tap",
|
|
473
614
|
sourceComponentId: component.id,
|
|
474
|
-
controlRole:
|
|
475
|
-
interface:
|
|
615
|
+
controlRole: "tempo-tap",
|
|
616
|
+
interface: "tap-tempo",
|
|
476
617
|
assignmentHint,
|
|
477
618
|
...(sourceTypeName !== undefined ? { sourceTypeName } : {}),
|
|
478
619
|
};
|
|
479
620
|
}
|
|
480
621
|
function runtimeDescriptorDirectOut(component) {
|
|
481
622
|
const name = nonEmptyString(propertyStringAny(component, [
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
623
|
+
"DirectOutputJack",
|
|
624
|
+
"DirectOutJack",
|
|
625
|
+
"DirectOutputControl",
|
|
626
|
+
"DirectOutControl",
|
|
486
627
|
]));
|
|
487
628
|
if (name === undefined) {
|
|
488
629
|
return undefined;
|
|
489
630
|
}
|
|
490
631
|
const sourceTypeName = component.sourceTypeName ?? undefined;
|
|
491
632
|
const description = nonEmptyString(propertyStringAny(component, [
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
633
|
+
"DirectOutputRuntimeBoundary",
|
|
634
|
+
"DirectOutputDescription",
|
|
635
|
+
"DirectOutDescription",
|
|
495
636
|
]));
|
|
496
637
|
const controlId = `${component.id}:direct-out`;
|
|
497
638
|
return {
|
|
498
639
|
id: controlId,
|
|
499
640
|
name,
|
|
500
|
-
role:
|
|
641
|
+
role: "direct-output",
|
|
501
642
|
sourceComponentId: component.id,
|
|
502
|
-
controlRole:
|
|
503
|
-
interface:
|
|
643
|
+
controlRole: "direct-output",
|
|
644
|
+
interface: "audio-output",
|
|
504
645
|
binding: {
|
|
505
646
|
sourceComponentId: component.id,
|
|
506
647
|
controlId,
|
|
507
648
|
controlName: name,
|
|
508
|
-
property:
|
|
649
|
+
property: "DirectOutputJack",
|
|
509
650
|
},
|
|
510
651
|
...(sourceTypeName !== undefined ? { sourceTypeName } : {}),
|
|
511
652
|
...(description === undefined ? {} : { description }),
|
|
512
653
|
};
|
|
513
654
|
}
|
|
514
655
|
function isSliderControl(component) {
|
|
515
|
-
const style = propertyStringAny(component, [
|
|
656
|
+
const style = propertyStringAny(component, [
|
|
657
|
+
"ControlStyle",
|
|
658
|
+
"ControlType",
|
|
659
|
+
"PanelControl",
|
|
660
|
+
"UiControl",
|
|
661
|
+
"Style",
|
|
662
|
+
]);
|
|
516
663
|
if (style === null) {
|
|
517
664
|
return false;
|
|
518
665
|
}
|
|
519
666
|
const lower = style.toLowerCase();
|
|
520
|
-
return lower.includes(
|
|
667
|
+
return lower.includes("slider") || lower.includes("fader");
|
|
668
|
+
}
|
|
669
|
+
function isVariableResistorControl(component) {
|
|
670
|
+
return (component.properties.Wipe !== undefined ||
|
|
671
|
+
component.properties.Sweep !== undefined ||
|
|
672
|
+
component.properties.Taper !== undefined ||
|
|
673
|
+
isSliderControl(component));
|
|
521
674
|
}
|
|
522
675
|
function resolveSliderOrientation(value) {
|
|
523
|
-
if (value?.toLowerCase().includes(
|
|
524
|
-
return
|
|
676
|
+
if (value?.toLowerCase().includes("horizontal")) {
|
|
677
|
+
return "horizontal";
|
|
525
678
|
}
|
|
526
|
-
return
|
|
679
|
+
return "vertical";
|
|
527
680
|
}
|
|
528
681
|
function sliderRange(component) {
|
|
529
|
-
const min = parseNumericAny(component, [
|
|
530
|
-
const max = parseNumericAny(component, [
|
|
682
|
+
const min = parseNumericAny(component, ["RangeMin", "Min", "Minimum"]);
|
|
683
|
+
const max = parseNumericAny(component, ["RangeMax", "Max", "Maximum"]);
|
|
531
684
|
if (min === undefined || max === undefined || min >= max) {
|
|
532
685
|
return undefined;
|
|
533
686
|
}
|
|
534
|
-
const unit = propertyStringAny(component, [
|
|
535
|
-
const center = parseNumericAny(component, [
|
|
687
|
+
const unit = propertyStringAny(component, ["Unit", "RangeUnit"]) ?? undefined;
|
|
688
|
+
const center = parseNumericAny(component, [
|
|
689
|
+
"Center",
|
|
690
|
+
"CenterValue",
|
|
691
|
+
"RangeCenter",
|
|
692
|
+
]);
|
|
536
693
|
return {
|
|
537
694
|
min,
|
|
538
695
|
max,
|
|
@@ -542,19 +699,19 @@ function sliderRange(component) {
|
|
|
542
699
|
}
|
|
543
700
|
function resolveTaper(value) {
|
|
544
701
|
if (value === null || value === undefined) {
|
|
545
|
-
return
|
|
702
|
+
return "unknown";
|
|
546
703
|
}
|
|
547
704
|
const lower = value.toLowerCase();
|
|
548
|
-
if (lower.includes(
|
|
549
|
-
return
|
|
705
|
+
if (lower.includes("log") && lower.includes("rev")) {
|
|
706
|
+
return "reverse-log";
|
|
550
707
|
}
|
|
551
|
-
if (lower.includes(
|
|
552
|
-
return
|
|
708
|
+
if (lower.includes("log") || lower.includes("audio")) {
|
|
709
|
+
return "log";
|
|
553
710
|
}
|
|
554
|
-
if (lower.includes(
|
|
555
|
-
return
|
|
711
|
+
if (lower.includes("lin")) {
|
|
712
|
+
return "linear";
|
|
556
713
|
}
|
|
557
|
-
return
|
|
714
|
+
return "unknown";
|
|
558
715
|
}
|
|
559
716
|
function resolveSwitchKind(component) {
|
|
560
717
|
const short = shortType(component.sourceTypeName);
|
|
@@ -562,47 +719,47 @@ function resolveSwitchKind(component) {
|
|
|
562
719
|
return inferFromTerminals(component.terminals.length);
|
|
563
720
|
}
|
|
564
721
|
const upper = short.toUpperCase();
|
|
565
|
-
if (upper ===
|
|
566
|
-
return
|
|
567
|
-
if (upper ===
|
|
568
|
-
return
|
|
569
|
-
if (upper ===
|
|
570
|
-
return
|
|
571
|
-
if (upper ===
|
|
572
|
-
return
|
|
573
|
-
if (upper ===
|
|
574
|
-
return
|
|
575
|
-
if (upper ===
|
|
576
|
-
return
|
|
577
|
-
if (upper ===
|
|
578
|
-
return
|
|
722
|
+
if (upper === "SPDT")
|
|
723
|
+
return "spdt";
|
|
724
|
+
if (upper === "SP3T")
|
|
725
|
+
return "sp3t";
|
|
726
|
+
if (upper === "SP4T")
|
|
727
|
+
return "sp4t";
|
|
728
|
+
if (upper === "3PDT")
|
|
729
|
+
return "3pdt";
|
|
730
|
+
if (upper === "TOGGLE")
|
|
731
|
+
return "toggle";
|
|
732
|
+
if (upper === "ROTARY")
|
|
733
|
+
return "rotary";
|
|
734
|
+
if (upper === "SWITCH")
|
|
735
|
+
return "spst";
|
|
579
736
|
return inferFromTerminals(component.terminals.length);
|
|
580
737
|
}
|
|
581
738
|
function inferFromTerminals(count) {
|
|
582
739
|
if (count <= 2)
|
|
583
|
-
return
|
|
740
|
+
return "spst";
|
|
584
741
|
if (count === 3)
|
|
585
|
-
return
|
|
742
|
+
return "spdt";
|
|
586
743
|
if (count === 9)
|
|
587
|
-
return
|
|
588
|
-
return
|
|
744
|
+
return "3pdt";
|
|
745
|
+
return "unknown";
|
|
589
746
|
}
|
|
590
747
|
function switchGeometry(kind) {
|
|
591
748
|
switch (kind) {
|
|
592
|
-
case
|
|
593
|
-
case
|
|
749
|
+
case "spst":
|
|
750
|
+
case "toggle":
|
|
594
751
|
return { poles: 1, positions: 2 };
|
|
595
|
-
case
|
|
752
|
+
case "spdt":
|
|
596
753
|
return { poles: 1, positions: 2 };
|
|
597
|
-
case
|
|
754
|
+
case "sp3t":
|
|
598
755
|
return { poles: 1, positions: 3 };
|
|
599
|
-
case
|
|
756
|
+
case "sp4t":
|
|
600
757
|
return { poles: 1, positions: 4 };
|
|
601
|
-
case
|
|
758
|
+
case "3pdt":
|
|
602
759
|
return { poles: 3, positions: 2 };
|
|
603
|
-
case
|
|
760
|
+
case "rotary":
|
|
604
761
|
return { poles: 1, positions: 6 };
|
|
605
|
-
case
|
|
762
|
+
case "unknown":
|
|
606
763
|
return { poles: 1, positions: 2 };
|
|
607
764
|
}
|
|
608
765
|
}
|
|
@@ -613,23 +770,23 @@ function resolveJackRole(component) {
|
|
|
613
770
|
}
|
|
614
771
|
const short = shortType(component.sourceTypeName);
|
|
615
772
|
if (short === null) {
|
|
616
|
-
return
|
|
773
|
+
return "unknown";
|
|
617
774
|
}
|
|
618
775
|
const upper = short.toUpperCase();
|
|
619
|
-
if (upper ===
|
|
620
|
-
return
|
|
621
|
-
if (upper ===
|
|
622
|
-
return
|
|
623
|
-
if (upper ===
|
|
624
|
-
return
|
|
625
|
-
if (upper ===
|
|
626
|
-
return
|
|
627
|
-
if (upper ===
|
|
628
|
-
return
|
|
629
|
-
return
|
|
776
|
+
if (upper === "INPUT" || upper === "INPUTJACK")
|
|
777
|
+
return "input";
|
|
778
|
+
if (upper === "SPEAKER" || upper === "OUTPUTJACK")
|
|
779
|
+
return "output";
|
|
780
|
+
if (upper === "SEND")
|
|
781
|
+
return "send";
|
|
782
|
+
if (upper === "RETURN")
|
|
783
|
+
return "return";
|
|
784
|
+
if (upper === "EXPRESSION" || upper === "EXP")
|
|
785
|
+
return "expression";
|
|
786
|
+
return "unknown";
|
|
630
787
|
}
|
|
631
788
|
function resolveSemanticJackRole(component) {
|
|
632
|
-
const semanticProperties = [
|
|
789
|
+
const semanticProperties = ["Role", "ControlRole", "Interface"];
|
|
633
790
|
for (const name of semanticProperties) {
|
|
634
791
|
const value = propertyString(component, name);
|
|
635
792
|
if (value === null) {
|
|
@@ -644,48 +801,48 @@ function resolveSemanticJackRole(component) {
|
|
|
644
801
|
}
|
|
645
802
|
function normalizeJackRole(value) {
|
|
646
803
|
const normalized = normalizeToken(value);
|
|
647
|
-
if ([
|
|
648
|
-
return
|
|
649
|
-
if ([
|
|
650
|
-
return
|
|
651
|
-
if ([
|
|
652
|
-
return
|
|
653
|
-
if (normalized ===
|
|
654
|
-
return
|
|
655
|
-
if (normalized ===
|
|
656
|
-
return
|
|
657
|
-
if ([
|
|
658
|
-
return
|
|
659
|
-
if ([
|
|
660
|
-
return
|
|
804
|
+
if (["input", "audio-input", "in"].includes(normalized))
|
|
805
|
+
return "input";
|
|
806
|
+
if (["direct-output", "direct-out", "dry-output", "dry-out"].includes(normalized))
|
|
807
|
+
return "direct-output";
|
|
808
|
+
if (["output", "audio-output", "out"].includes(normalized))
|
|
809
|
+
return "output";
|
|
810
|
+
if (normalized === "send")
|
|
811
|
+
return "send";
|
|
812
|
+
if (normalized === "return")
|
|
813
|
+
return "return";
|
|
814
|
+
if (["expression", "exp", "expression-pedal"].includes(normalized))
|
|
815
|
+
return "expression";
|
|
816
|
+
if (["tempo-tap", "tap-tempo", "tempo-in", "tap", "tempo"].includes(normalized))
|
|
817
|
+
return "tempo-tap";
|
|
661
818
|
if ([
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
819
|
+
"external-control",
|
|
820
|
+
"external-control-input",
|
|
821
|
+
"control-input",
|
|
822
|
+
"remote",
|
|
823
|
+
"footswitch",
|
|
824
|
+
"trigger",
|
|
825
|
+
"reset",
|
|
669
826
|
].includes(normalized)) {
|
|
670
|
-
return
|
|
827
|
+
return "external-control";
|
|
671
828
|
}
|
|
672
829
|
return null;
|
|
673
830
|
}
|
|
674
831
|
function inferLedColor(component) {
|
|
675
832
|
// Common pedal LED colors are usually red / amber / green. Try the part number.
|
|
676
|
-
const part = propertyString(component,
|
|
677
|
-
if (part.includes(
|
|
678
|
-
return
|
|
679
|
-
if (part.includes(
|
|
680
|
-
return
|
|
681
|
-
if (part.includes(
|
|
682
|
-
return
|
|
683
|
-
if (part.includes(
|
|
684
|
-
return
|
|
685
|
-
if (part.includes(
|
|
686
|
-
return
|
|
687
|
-
if (part.includes(
|
|
688
|
-
return
|
|
833
|
+
const part = propertyString(component, "PartNumber")?.toLowerCase() ?? "";
|
|
834
|
+
if (part.includes("red"))
|
|
835
|
+
return "red";
|
|
836
|
+
if (part.includes("green"))
|
|
837
|
+
return "green";
|
|
838
|
+
if (part.includes("amber"))
|
|
839
|
+
return "amber";
|
|
840
|
+
if (part.includes("blue"))
|
|
841
|
+
return "blue";
|
|
842
|
+
if (part.includes("yellow"))
|
|
843
|
+
return "yellow";
|
|
844
|
+
if (part.includes("white"))
|
|
845
|
+
return "white";
|
|
689
846
|
return undefined;
|
|
690
847
|
}
|
|
691
848
|
function shortType(sourceTypeName) {
|
|
@@ -766,10 +923,13 @@ function runtimeModeDefaultPosition(steps, rawValue) {
|
|
|
766
923
|
return snapKnobPosition({ steps }, clamp01(rawValue));
|
|
767
924
|
}
|
|
768
925
|
function isRuntimeDescriptor(component) {
|
|
769
|
-
return component.kind ===
|
|
926
|
+
return (component.kind === "ic" && component.properties.RuntimeDescriptor === "true");
|
|
770
927
|
}
|
|
771
928
|
function normalizeToken(value) {
|
|
772
|
-
return value
|
|
929
|
+
return value
|
|
930
|
+
.trim()
|
|
931
|
+
.toLowerCase()
|
|
932
|
+
.replace(/[\s_]+/g, "-");
|
|
773
933
|
}
|
|
774
934
|
function clamp01(v) {
|
|
775
935
|
if (v < 0)
|