@openmixer/omx-contract 2.0.0 → 2.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.
- package/README.md +37 -3
- package/data/kernels/limiter.json +1 -0
- package/lib/data.mjs +31 -2
- package/lib/fmt.mjs +1 -1
- package/lib/validate.mjs +5 -1
- package/package.json +1 -1
- package/render/json.mjs +6 -2
- package/share/omx-contract/omx-contract.json +636 -1
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ RTA constants, the EQ band budget, the choice enums (as the `set` kind), the EQ
|
|
|
13
13
|
one rule that gives a fresh EQ its bands, the measurement rate sets and the bus input cap. What is
|
|
14
14
|
declared here is declared nowhere else: the EQ band budget that 1.2.0 left in openmixer is here too.
|
|
15
15
|
2.0.0 changes how a kernel file is written, not what it declares: every render is the same.
|
|
16
|
+
2.1.0 adds each kernel's ordered controls to the JSON render, and a control's `rearms` flag.
|
|
16
17
|
|
|
17
18
|
```
|
|
18
19
|
data/ the declaration, one file per group, edited by hand
|
|
@@ -54,7 +55,10 @@ A kernel file, `data/kernels/<kernel>.json`, holds four sections and nothing els
|
|
|
54
55
|
- `controls`, in order: a `travel` (one travel) or a `choice` (ordered `ids`, an optional `default` and `labels`).
|
|
55
56
|
Its item name is `<KERNEL>_<NAME>_RANGE` for a travel and `<KERNEL>_<NAME>S` for a choice (`depth` in
|
|
56
57
|
tremolo.json is `TREMOLO_DEPTH_RANGE`, `mode` is `TREMOLO_MODES`); `global` names it when it is anything else.
|
|
57
|
-
A control with a `table` is one field of that table.
|
|
58
|
+
A control with a `table` is one field of that table. `"rearms": true` marks a control whose change re-arms the
|
|
59
|
+
kernel's state, so it is not a smooth parameter (the limiter's `lookaheadMs`: omx-dsp's limiter face re-arms
|
|
60
|
+
the state and restarts the gain at unity when the look-ahead moves by a frame). It is a boolean, only on a
|
|
61
|
+
control; it is no item, so the C and TypeScript renders do not carry it.
|
|
58
62
|
- `tables`: a travels table whose fields are the controls that name it, in control order (`GATE_LIMITS`).
|
|
59
63
|
- `aggregates`: a travels table whose fields are references to controls declared once above, listed by name.
|
|
60
64
|
- `constants`: scalars, lists and sheets, as items.
|
|
@@ -62,6 +66,36 @@ A kernel file, `data/kernels/<kernel>.json`, holds four sections and nothing els
|
|
|
62
66
|
`omx-contract validate` refuses any other key, a constant that is a travel or a set, and a kernel file written
|
|
63
67
|
as a flat item map (the 1.x shape). `rates.json` and `primitives.json` stay item maps.
|
|
64
68
|
|
|
69
|
+
## The JSON render's kernels
|
|
70
|
+
|
|
71
|
+
Beside `items`, `share/omx-contract/omx-contract.json` carries `kernels`: for every kernel file, its controls in
|
|
72
|
+
the order the file declares them. A consumer reads control order and kinds here, never from a kernel file.
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
"kernels": {
|
|
76
|
+
"limiter": {
|
|
77
|
+
"controls": [
|
|
78
|
+
{ "name": "ceilingDb", "kind": "travel", "global": "LIMITER_LIMITS", "table": "LIMITER_LIMITS" },
|
|
79
|
+
{ "name": "lookaheadMs", "kind": "travel", "global": "LIMITER_LIMITS", "table": "LIMITER_LIMITS", "rearms": true },
|
|
80
|
+
{ "name": "releaseMs", "kind": "travel", "global": "LIMITER_LIMITS", "table": "LIMITER_LIMITS" }
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
"tremolo": {
|
|
84
|
+
"controls": [
|
|
85
|
+
{ "name": "rateHz", "kind": "travel", "global": "TREMOLO_RATE_RANGE" },
|
|
86
|
+
{ "name": "mode", "kind": "choice", "global": "TREMOLO_MODES" }
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- `kind`: `travel` or `choice`.
|
|
93
|
+
- `global`: the item the control's value lives in: `items[global].value` for a travel or a choice, and
|
|
94
|
+
`items[global].value[name]` for a field of a table, when `table` (the same item) is present.
|
|
95
|
+
- `rearms`: present, and `true`, only on a control that declares it.
|
|
96
|
+
|
|
97
|
+
A kernel with no controls (fbs, mixmatrix, rta) is listed with an empty `controls`.
|
|
98
|
+
|
|
65
99
|
## The CLI
|
|
66
100
|
|
|
67
101
|
```
|
|
@@ -78,9 +112,9 @@ share/omx-contract` and `render --target ts --out test/golden/ts`; CI holds all
|
|
|
78
112
|
|
|
79
113
|
## Consuming it
|
|
80
114
|
|
|
81
|
-
Pin one version (`omx-contract 2.
|
|
115
|
+
Pin one version (`omx-contract 2.1.0` in `.github/pins.txt`) and build against its renders, committing
|
|
82
116
|
none: the installed `omx-contract-devel` / `libomx-contract-dev` at exactly that version
|
|
83
|
-
(`pkg-config --exact-version=2.
|
|
117
|
+
(`pkg-config --exact-version=2.1.0 omx-contract`), else the release's npm tarball, unpacked, and
|
|
84
118
|
`omx-contract render --target c --out build/omx-contract/include`. Include
|
|
85
119
|
`<omxcontract/omx_contract_limits.h>`. A plugin's parameter header is rendered by omx-plugins from its
|
|
86
120
|
declaration, by reference to the kernel travels here (since 1.1.0).
|
package/lib/data.mjs
CHANGED
|
@@ -70,7 +70,7 @@ export function entriesOf(rel, doc) {
|
|
|
70
70
|
const controls = Array.isArray(doc.controls) ? doc.controls : [];
|
|
71
71
|
const tables = new Map(Object.entries(doc.tables ?? {}).map(([n, meta]) => [n, { kind: 'travels', ...meta, fields: {} }]));
|
|
72
72
|
for (const c of controls) {
|
|
73
|
-
const { name, kind, global, table, ...rest } = c;
|
|
73
|
+
const { name, kind, global, table, rearms, ...rest } = c;
|
|
74
74
|
if (table) {
|
|
75
75
|
if (!tables.has(table)) throw new Error(`${rel}: control ${name} names table ${table}, which is not declared`);
|
|
76
76
|
tables.get(table).fields[name] = rest.travel;
|
|
@@ -91,6 +91,33 @@ export function entriesOf(rel, doc) {
|
|
|
91
91
|
return out;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
/** A kernel's name, read off its file name: `kernels/band_dyn.json` is band_dyn. */
|
|
95
|
+
export const kernelName = (rel) => rel.replace(/^.*\//, '').replace(/\.json$/, '');
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Every kernel's controls, in its file's order: `{ <kernel>: { controls: [{ name, kind, global, table?, rearms? }] } }`,
|
|
99
|
+
* kernels in file order. `global` is the item the control's value lives in: its own travel or set, or, for a field of
|
|
100
|
+
* a table, the table (`table` names it too, and the field is the control's name). `rearms` is carried only when true:
|
|
101
|
+
* changing the control re-arms the kernel's state, it is not a smooth parameter.
|
|
102
|
+
*/
|
|
103
|
+
export function kernelControls(data) {
|
|
104
|
+
const out = {};
|
|
105
|
+
for (const f of data.files) {
|
|
106
|
+
if (!isKernelFile(f.rel)) continue;
|
|
107
|
+
const controls = Array.isArray(f.doc.controls) ? f.doc.controls : [];
|
|
108
|
+
out[kernelName(f.rel)] = {
|
|
109
|
+
controls: controls.map((c) => ({
|
|
110
|
+
name: c.name,
|
|
111
|
+
kind: c.kind,
|
|
112
|
+
global: c.table ?? controlGlobal(f.rel, c),
|
|
113
|
+
...(c.table ? { table: c.table } : {}),
|
|
114
|
+
...(c.rearms === true ? { rearms: true } : {}),
|
|
115
|
+
})),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
120
|
+
|
|
94
121
|
const isWholeRef = (v) => typeof v === 'object' && v !== null && Object.keys(v).length === 1 && typeof v.ref === 'string' && !v.ref.includes('.');
|
|
95
122
|
|
|
96
123
|
/**
|
|
@@ -213,7 +240,8 @@ const isObj = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
|
213
240
|
|
|
214
241
|
/**
|
|
215
242
|
* Resolve every item: `{ name, rel, kind, doc, why?, unit?, c?, shape?, default?, labels?, value }` (default and labels: a set's), where `value` has
|
|
216
|
-
* every `{ref}` and `{derive}` evaluated.
|
|
243
|
+
* every `{ref}` and `{derive}` evaluated. The returned map also carries `kernels`, every kernel's ordered controls
|
|
244
|
+
* (kernelControls), which the json render publishes beside the items.
|
|
217
245
|
* @throws naming the item: a reference that does not resolve, a cycle, an unknown derivation.
|
|
218
246
|
*/
|
|
219
247
|
export function resolveData(data) {
|
|
@@ -262,6 +290,7 @@ export function resolveData(data) {
|
|
|
262
290
|
}
|
|
263
291
|
const out = new Map();
|
|
264
292
|
for (const name of data.items.keys()) out.set(name, resolveItem(name));
|
|
293
|
+
out.kernels = kernelControls(data);
|
|
265
294
|
return out;
|
|
266
295
|
}
|
|
267
296
|
|
package/lib/fmt.mjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
const ORDER = {
|
|
11
|
-
control: ['name', 'kind', 'global', 'table', 'since', 'doc', 'why', 'unit', 'ids', 'default', 'labels', 'travel', 'c'],
|
|
11
|
+
control: ['name', 'kind', 'global', 'table', 'rearms', 'since', 'doc', 'why', 'unit', 'ids', 'default', 'labels', 'travel', 'c'],
|
|
12
12
|
sections: ['controls', 'tables', 'aggregates', 'constants'],
|
|
13
13
|
item: ['kind', 'since', 'doc', 'why', 'unit', 'value', 'values', 'ids', 'default', 'labels', 'fields', 'travel', 'c'],
|
|
14
14
|
travel: ['min', 'max', 'step', 'unit', 'default', 'defaultFrom', 'scale', 'byKind', 'doc', 'why'],
|
package/lib/validate.mjs
CHANGED
|
@@ -18,7 +18,7 @@ let compiled;
|
|
|
18
18
|
/**
|
|
19
19
|
* The kernel-file shape (2.0.0), which the item schema cannot see: only the four sections at the top; every control
|
|
20
20
|
* named, of kind travel or choice, unique by name, a travel carrying a `travel` and a choice its `ids`; a control's
|
|
21
|
-
* `table` declared under `tables`; an aggregate's fields naming controls; a constant a scalar, a list or a sheet.
|
|
21
|
+
* `table` declared under `tables`; `rearms` a boolean, and only on a control; an aggregate's fields naming controls; a constant a scalar, a list or a sheet.
|
|
22
22
|
* A kernel file written as a flat item map (the 1.x shape) is refused as a whole. Any other data file returns [].
|
|
23
23
|
*/
|
|
24
24
|
export function shapeProblems(rel, doc) {
|
|
@@ -41,6 +41,10 @@ export function shapeProblems(rel, doc) {
|
|
|
41
41
|
else if (c.kind === 'choice' && !Array.isArray(c.ids)) out.push(`controls[${i}] ${c.name}: a choice without "ids"`);
|
|
42
42
|
else if (c.kind !== 'travel' && c.kind !== 'choice') out.push(`controls[${i}] ${c.name}: kind ${JSON.stringify(c.kind)} is neither travel nor choice`);
|
|
43
43
|
if (c.table && !(doc.tables && c.table in doc.tables)) out.push(`controls[${i}] ${c.name}: table ${c.table} is not declared`);
|
|
44
|
+
if ('rearms' in c && typeof c.rearms !== 'boolean') out.push(`controls[${i}] ${c.name}: rearms ${JSON.stringify(c.rearms)} is not a boolean`);
|
|
45
|
+
}
|
|
46
|
+
for (const s of ['tables', 'aggregates', 'constants']) {
|
|
47
|
+
for (const [n, it] of Object.entries(doc[s] ?? {})) if (it && typeof it === 'object' && 'rearms' in it) out.push(`${s} ${n}: rearms is a control's flag, never a ${s.slice(0, -1)}'s`);
|
|
44
48
|
}
|
|
45
49
|
for (const [n, a] of Object.entries(doc.aggregates ?? {})) for (const f of a.fields ?? []) if (!seen.has(f)) out.push(`aggregate ${n}: field ${f} names no control`);
|
|
46
50
|
for (const [n, it] of Object.entries(doc.constants ?? {})) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmixer/omx-contract",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "The FreeMixer declarations as data: a JSON Schema, the data, and one CLI that renders them into C, TypeScript and JSON",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "GPL-3.0-or-later",
|
package/render/json.mjs
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
// Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
|
|
3
3
|
/**
|
|
4
4
|
* The `json` target: the resolved data (every reference and derivation evaluated) for readers in
|
|
5
|
-
* other languages, which need no resolver of their own.
|
|
5
|
+
* other languages, which need no resolver of their own. Beside the items, `kernels` lists each
|
|
6
|
+
* kernel's controls in their declared order (name, kind, the global each resolves to, the table of a
|
|
7
|
+
* table field, `rearms` when changing it re-arms the kernel's state), so a reader needs no kernel file.
|
|
6
8
|
*/
|
|
7
9
|
|
|
8
10
|
/** Every file of the `json` target: `[{ path, text }]`. */
|
|
@@ -12,5 +14,7 @@ export function renderJson(resolved, version) {
|
|
|
12
14
|
const { name, ...rest } = r;
|
|
13
15
|
items[name] = rest;
|
|
14
16
|
}
|
|
15
|
-
|
|
17
|
+
const doc = { name: '@openmixer/omx-contract', version, items };
|
|
18
|
+
if (resolved.kernels) doc.kernels = resolved.kernels;
|
|
19
|
+
return [{ path: 'omx-contract.json', text: `${JSON.stringify(doc, null, 2)}\n` }];
|
|
16
20
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmixer/omx-contract",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"items": {
|
|
5
5
|
"PAN_RANGE": {
|
|
6
6
|
"rel": "data/kernels/balance.json",
|
|
@@ -2369,5 +2369,640 @@
|
|
|
2369
2369
|
192000
|
|
2370
2370
|
]
|
|
2371
2371
|
}
|
|
2372
|
+
},
|
|
2373
|
+
"kernels": {
|
|
2374
|
+
"balance": {
|
|
2375
|
+
"controls": [
|
|
2376
|
+
{
|
|
2377
|
+
"name": "pan",
|
|
2378
|
+
"kind": "travel",
|
|
2379
|
+
"global": "PAN_RANGE"
|
|
2380
|
+
}
|
|
2381
|
+
]
|
|
2382
|
+
},
|
|
2383
|
+
"band_dyn": {
|
|
2384
|
+
"controls": [
|
|
2385
|
+
{
|
|
2386
|
+
"name": "mode",
|
|
2387
|
+
"kind": "choice",
|
|
2388
|
+
"global": "BAND_DYN_MODES"
|
|
2389
|
+
},
|
|
2390
|
+
{
|
|
2391
|
+
"name": "threshold",
|
|
2392
|
+
"kind": "travel",
|
|
2393
|
+
"global": "BAND_DYN_THRESHOLD_RANGE"
|
|
2394
|
+
},
|
|
2395
|
+
{
|
|
2396
|
+
"name": "ratio",
|
|
2397
|
+
"kind": "travel",
|
|
2398
|
+
"global": "BAND_DYN_RATIO_RANGE"
|
|
2399
|
+
},
|
|
2400
|
+
{
|
|
2401
|
+
"name": "range",
|
|
2402
|
+
"kind": "travel",
|
|
2403
|
+
"global": "BAND_DYN_RANGE_RANGE"
|
|
2404
|
+
},
|
|
2405
|
+
{
|
|
2406
|
+
"name": "attack",
|
|
2407
|
+
"kind": "travel",
|
|
2408
|
+
"global": "BAND_DYN_ATTACK_RANGE"
|
|
2409
|
+
},
|
|
2410
|
+
{
|
|
2411
|
+
"name": "release",
|
|
2412
|
+
"kind": "travel",
|
|
2413
|
+
"global": "BAND_DYN_RELEASE_RANGE"
|
|
2414
|
+
}
|
|
2415
|
+
]
|
|
2416
|
+
},
|
|
2417
|
+
"chorus": {
|
|
2418
|
+
"controls": [
|
|
2419
|
+
{
|
|
2420
|
+
"name": "spread",
|
|
2421
|
+
"kind": "travel",
|
|
2422
|
+
"global": "CHORUS_SPREAD_RANGE"
|
|
2423
|
+
},
|
|
2424
|
+
{
|
|
2425
|
+
"name": "rate",
|
|
2426
|
+
"kind": "travel",
|
|
2427
|
+
"global": "CHORUS_RATE_RANGE"
|
|
2428
|
+
},
|
|
2429
|
+
{
|
|
2430
|
+
"name": "depth",
|
|
2431
|
+
"kind": "travel",
|
|
2432
|
+
"global": "CHORUS_DEPTH_RANGE"
|
|
2433
|
+
},
|
|
2434
|
+
{
|
|
2435
|
+
"name": "voices",
|
|
2436
|
+
"kind": "travel",
|
|
2437
|
+
"global": "CHORUS_VOICES_RANGE"
|
|
2438
|
+
},
|
|
2439
|
+
{
|
|
2440
|
+
"name": "mix",
|
|
2441
|
+
"kind": "travel",
|
|
2442
|
+
"global": "CHORUS_MIX_RANGE"
|
|
2443
|
+
}
|
|
2444
|
+
]
|
|
2445
|
+
},
|
|
2446
|
+
"comp": {
|
|
2447
|
+
"controls": [
|
|
2448
|
+
{
|
|
2449
|
+
"name": "thresholdDb",
|
|
2450
|
+
"kind": "travel",
|
|
2451
|
+
"global": "COMP_LIMITS",
|
|
2452
|
+
"table": "COMP_LIMITS"
|
|
2453
|
+
},
|
|
2454
|
+
{
|
|
2455
|
+
"name": "ratio",
|
|
2456
|
+
"kind": "travel",
|
|
2457
|
+
"global": "COMP_LIMITS",
|
|
2458
|
+
"table": "COMP_LIMITS"
|
|
2459
|
+
},
|
|
2460
|
+
{
|
|
2461
|
+
"name": "kneeDb",
|
|
2462
|
+
"kind": "travel",
|
|
2463
|
+
"global": "COMP_LIMITS",
|
|
2464
|
+
"table": "COMP_LIMITS"
|
|
2465
|
+
},
|
|
2466
|
+
{
|
|
2467
|
+
"name": "attackMs",
|
|
2468
|
+
"kind": "travel",
|
|
2469
|
+
"global": "COMP_LIMITS",
|
|
2470
|
+
"table": "COMP_LIMITS"
|
|
2471
|
+
},
|
|
2472
|
+
{
|
|
2473
|
+
"name": "releaseMs",
|
|
2474
|
+
"kind": "travel",
|
|
2475
|
+
"global": "COMP_LIMITS",
|
|
2476
|
+
"table": "COMP_LIMITS"
|
|
2477
|
+
},
|
|
2478
|
+
{
|
|
2479
|
+
"name": "makeupDb",
|
|
2480
|
+
"kind": "travel",
|
|
2481
|
+
"global": "COMP_LIMITS",
|
|
2482
|
+
"table": "COMP_LIMITS"
|
|
2483
|
+
},
|
|
2484
|
+
{
|
|
2485
|
+
"name": "mixPct",
|
|
2486
|
+
"kind": "travel",
|
|
2487
|
+
"global": "COMP_LIMITS",
|
|
2488
|
+
"table": "COMP_LIMITS"
|
|
2489
|
+
}
|
|
2490
|
+
]
|
|
2491
|
+
},
|
|
2492
|
+
"deesser": {
|
|
2493
|
+
"controls": [
|
|
2494
|
+
{
|
|
2495
|
+
"name": "deessFreq",
|
|
2496
|
+
"kind": "travel",
|
|
2497
|
+
"global": "DEESS_FREQ_RANGE"
|
|
2498
|
+
},
|
|
2499
|
+
{
|
|
2500
|
+
"name": "deessWidth",
|
|
2501
|
+
"kind": "travel",
|
|
2502
|
+
"global": "DEESS_WIDTH_RANGE"
|
|
2503
|
+
},
|
|
2504
|
+
{
|
|
2505
|
+
"name": "deessThreshold",
|
|
2506
|
+
"kind": "travel",
|
|
2507
|
+
"global": "DEESS_THRESHOLD_RANGE"
|
|
2508
|
+
},
|
|
2509
|
+
{
|
|
2510
|
+
"name": "deessRatio",
|
|
2511
|
+
"kind": "travel",
|
|
2512
|
+
"global": "DEESS_RATIO_RANGE"
|
|
2513
|
+
},
|
|
2514
|
+
{
|
|
2515
|
+
"name": "deessRange",
|
|
2516
|
+
"kind": "travel",
|
|
2517
|
+
"global": "DEESS_RANGE_RANGE"
|
|
2518
|
+
},
|
|
2519
|
+
{
|
|
2520
|
+
"name": "deessAttack",
|
|
2521
|
+
"kind": "travel",
|
|
2522
|
+
"global": "DEESS_ATTACK_RANGE"
|
|
2523
|
+
},
|
|
2524
|
+
{
|
|
2525
|
+
"name": "deessRelease",
|
|
2526
|
+
"kind": "travel",
|
|
2527
|
+
"global": "DEESS_RELEASE_RANGE"
|
|
2528
|
+
},
|
|
2529
|
+
{
|
|
2530
|
+
"name": "deessMode",
|
|
2531
|
+
"kind": "choice",
|
|
2532
|
+
"global": "DEESS_MODES"
|
|
2533
|
+
}
|
|
2534
|
+
]
|
|
2535
|
+
},
|
|
2536
|
+
"delay": {
|
|
2537
|
+
"controls": [
|
|
2538
|
+
{
|
|
2539
|
+
"name": "fxDelayTime",
|
|
2540
|
+
"kind": "travel",
|
|
2541
|
+
"global": "FX_DELAY_TIME_RANGE"
|
|
2542
|
+
},
|
|
2543
|
+
{
|
|
2544
|
+
"name": "fxDelayFeedback",
|
|
2545
|
+
"kind": "travel",
|
|
2546
|
+
"global": "FX_DELAY_FEEDBACK_RANGE"
|
|
2547
|
+
},
|
|
2548
|
+
{
|
|
2549
|
+
"name": "tone",
|
|
2550
|
+
"kind": "travel",
|
|
2551
|
+
"global": "DELAY_TONE_RANGE"
|
|
2552
|
+
},
|
|
2553
|
+
{
|
|
2554
|
+
"name": "mix",
|
|
2555
|
+
"kind": "travel",
|
|
2556
|
+
"global": "DELAY_MIX_RANGE"
|
|
2557
|
+
}
|
|
2558
|
+
]
|
|
2559
|
+
},
|
|
2560
|
+
"drive": {
|
|
2561
|
+
"controls": [
|
|
2562
|
+
{
|
|
2563
|
+
"name": "amount",
|
|
2564
|
+
"kind": "travel",
|
|
2565
|
+
"global": "DRIVE_AMOUNT_RANGE"
|
|
2566
|
+
},
|
|
2567
|
+
{
|
|
2568
|
+
"name": "character",
|
|
2569
|
+
"kind": "travel",
|
|
2570
|
+
"global": "DRIVE_CHARACTER_RANGE"
|
|
2571
|
+
},
|
|
2572
|
+
{
|
|
2573
|
+
"name": "bandFreq",
|
|
2574
|
+
"kind": "travel",
|
|
2575
|
+
"global": "DRIVE_BAND_FREQ_RANGE"
|
|
2576
|
+
},
|
|
2577
|
+
{
|
|
2578
|
+
"name": "mix",
|
|
2579
|
+
"kind": "travel",
|
|
2580
|
+
"global": "DRIVE_MIX_RANGE"
|
|
2581
|
+
},
|
|
2582
|
+
{
|
|
2583
|
+
"name": "trim",
|
|
2584
|
+
"kind": "travel",
|
|
2585
|
+
"global": "DRIVE_TRIM_RANGE"
|
|
2586
|
+
},
|
|
2587
|
+
{
|
|
2588
|
+
"name": "curve",
|
|
2589
|
+
"kind": "choice",
|
|
2590
|
+
"global": "DRIVE_CURVES"
|
|
2591
|
+
},
|
|
2592
|
+
{
|
|
2593
|
+
"name": "band",
|
|
2594
|
+
"kind": "choice",
|
|
2595
|
+
"global": "DRIVE_BANDS"
|
|
2596
|
+
}
|
|
2597
|
+
]
|
|
2598
|
+
},
|
|
2599
|
+
"eq": {
|
|
2600
|
+
"controls": [
|
|
2601
|
+
{
|
|
2602
|
+
"name": "freq",
|
|
2603
|
+
"kind": "travel",
|
|
2604
|
+
"global": "EQ_FREQ_RANGE"
|
|
2605
|
+
},
|
|
2606
|
+
{
|
|
2607
|
+
"name": "gain",
|
|
2608
|
+
"kind": "travel",
|
|
2609
|
+
"global": "EQ_GAIN_RANGE"
|
|
2610
|
+
},
|
|
2611
|
+
{
|
|
2612
|
+
"name": "q",
|
|
2613
|
+
"kind": "travel",
|
|
2614
|
+
"global": "EQ_Q_RANGE"
|
|
2615
|
+
},
|
|
2616
|
+
{
|
|
2617
|
+
"name": "notchQ",
|
|
2618
|
+
"kind": "travel",
|
|
2619
|
+
"global": "EQ_NOTCH_Q_RANGE"
|
|
2620
|
+
},
|
|
2621
|
+
{
|
|
2622
|
+
"name": "hpfFreq",
|
|
2623
|
+
"kind": "travel",
|
|
2624
|
+
"global": "HPF_FREQ_RANGE"
|
|
2625
|
+
},
|
|
2626
|
+
{
|
|
2627
|
+
"name": "lpfFreq",
|
|
2628
|
+
"kind": "travel",
|
|
2629
|
+
"global": "LPF_FREQ_RANGE"
|
|
2630
|
+
},
|
|
2631
|
+
{
|
|
2632
|
+
"name": "bandType",
|
|
2633
|
+
"kind": "choice",
|
|
2634
|
+
"global": "EQ_BAND_TYPES"
|
|
2635
|
+
},
|
|
2636
|
+
{
|
|
2637
|
+
"name": "filterSlope",
|
|
2638
|
+
"kind": "choice",
|
|
2639
|
+
"global": "FILTER_SLOPES"
|
|
2640
|
+
}
|
|
2641
|
+
]
|
|
2642
|
+
},
|
|
2643
|
+
"fbs": {
|
|
2644
|
+
"controls": []
|
|
2645
|
+
},
|
|
2646
|
+
"flanger": {
|
|
2647
|
+
"controls": [
|
|
2648
|
+
{
|
|
2649
|
+
"name": "rate",
|
|
2650
|
+
"kind": "travel",
|
|
2651
|
+
"global": "FLANGER_RATE_RANGE"
|
|
2652
|
+
},
|
|
2653
|
+
{
|
|
2654
|
+
"name": "depth",
|
|
2655
|
+
"kind": "travel",
|
|
2656
|
+
"global": "FLANGER_DEPTH_RANGE"
|
|
2657
|
+
},
|
|
2658
|
+
{
|
|
2659
|
+
"name": "feedback",
|
|
2660
|
+
"kind": "travel",
|
|
2661
|
+
"global": "FLANGER_FEEDBACK_RANGE"
|
|
2662
|
+
},
|
|
2663
|
+
{
|
|
2664
|
+
"name": "mix",
|
|
2665
|
+
"kind": "travel",
|
|
2666
|
+
"global": "FLANGER_MIX_RANGE"
|
|
2667
|
+
}
|
|
2668
|
+
]
|
|
2669
|
+
},
|
|
2670
|
+
"gate": {
|
|
2671
|
+
"controls": [
|
|
2672
|
+
{
|
|
2673
|
+
"name": "keySource",
|
|
2674
|
+
"kind": "choice",
|
|
2675
|
+
"global": "GATE_KEY_SOURCES"
|
|
2676
|
+
},
|
|
2677
|
+
{
|
|
2678
|
+
"name": "thresholdDb",
|
|
2679
|
+
"kind": "travel",
|
|
2680
|
+
"global": "GATE_LIMITS",
|
|
2681
|
+
"table": "GATE_LIMITS"
|
|
2682
|
+
},
|
|
2683
|
+
{
|
|
2684
|
+
"name": "rangeDb",
|
|
2685
|
+
"kind": "travel",
|
|
2686
|
+
"global": "GATE_LIMITS",
|
|
2687
|
+
"table": "GATE_LIMITS"
|
|
2688
|
+
},
|
|
2689
|
+
{
|
|
2690
|
+
"name": "kneeStartDb",
|
|
2691
|
+
"kind": "travel",
|
|
2692
|
+
"global": "GATE_LIMITS",
|
|
2693
|
+
"table": "GATE_LIMITS"
|
|
2694
|
+
},
|
|
2695
|
+
{
|
|
2696
|
+
"name": "kneeEndDb",
|
|
2697
|
+
"kind": "travel",
|
|
2698
|
+
"global": "GATE_LIMITS",
|
|
2699
|
+
"table": "GATE_LIMITS"
|
|
2700
|
+
},
|
|
2701
|
+
{
|
|
2702
|
+
"name": "attackMs",
|
|
2703
|
+
"kind": "travel",
|
|
2704
|
+
"global": "GATE_LIMITS",
|
|
2705
|
+
"table": "GATE_LIMITS"
|
|
2706
|
+
},
|
|
2707
|
+
{
|
|
2708
|
+
"name": "holdMs",
|
|
2709
|
+
"kind": "travel",
|
|
2710
|
+
"global": "GATE_LIMITS",
|
|
2711
|
+
"table": "GATE_LIMITS"
|
|
2712
|
+
},
|
|
2713
|
+
{
|
|
2714
|
+
"name": "releaseMs",
|
|
2715
|
+
"kind": "travel",
|
|
2716
|
+
"global": "GATE_LIMITS",
|
|
2717
|
+
"table": "GATE_LIMITS"
|
|
2718
|
+
},
|
|
2719
|
+
{
|
|
2720
|
+
"name": "hysteresisDb",
|
|
2721
|
+
"kind": "travel",
|
|
2722
|
+
"global": "GATE_LIMITS",
|
|
2723
|
+
"table": "GATE_LIMITS"
|
|
2724
|
+
},
|
|
2725
|
+
{
|
|
2726
|
+
"name": "ratio",
|
|
2727
|
+
"kind": "travel",
|
|
2728
|
+
"global": "GATE_LIMITS",
|
|
2729
|
+
"table": "GATE_LIMITS"
|
|
2730
|
+
}
|
|
2731
|
+
]
|
|
2732
|
+
},
|
|
2733
|
+
"geq": {
|
|
2734
|
+
"controls": [
|
|
2735
|
+
{
|
|
2736
|
+
"name": "band",
|
|
2737
|
+
"kind": "travel",
|
|
2738
|
+
"global": "GEQ_BAND_RANGE"
|
|
2739
|
+
}
|
|
2740
|
+
]
|
|
2741
|
+
},
|
|
2742
|
+
"hrp": {
|
|
2743
|
+
"controls": [
|
|
2744
|
+
{
|
|
2745
|
+
"name": "amount",
|
|
2746
|
+
"kind": "travel",
|
|
2747
|
+
"global": "HRP_AMOUNT_RANGE"
|
|
2748
|
+
}
|
|
2749
|
+
]
|
|
2750
|
+
},
|
|
2751
|
+
"limiter": {
|
|
2752
|
+
"controls": [
|
|
2753
|
+
{
|
|
2754
|
+
"name": "ceilingDb",
|
|
2755
|
+
"kind": "travel",
|
|
2756
|
+
"global": "LIMITER_LIMITS",
|
|
2757
|
+
"table": "LIMITER_LIMITS"
|
|
2758
|
+
},
|
|
2759
|
+
{
|
|
2760
|
+
"name": "lookaheadMs",
|
|
2761
|
+
"kind": "travel",
|
|
2762
|
+
"global": "LIMITER_LIMITS",
|
|
2763
|
+
"table": "LIMITER_LIMITS",
|
|
2764
|
+
"rearms": true
|
|
2765
|
+
},
|
|
2766
|
+
{
|
|
2767
|
+
"name": "releaseMs",
|
|
2768
|
+
"kind": "travel",
|
|
2769
|
+
"global": "LIMITER_LIMITS",
|
|
2770
|
+
"table": "LIMITER_LIMITS"
|
|
2771
|
+
}
|
|
2772
|
+
]
|
|
2773
|
+
},
|
|
2774
|
+
"mixmatrix": {
|
|
2775
|
+
"controls": []
|
|
2776
|
+
},
|
|
2777
|
+
"phaser": {
|
|
2778
|
+
"controls": [
|
|
2779
|
+
{
|
|
2780
|
+
"name": "rateHz",
|
|
2781
|
+
"kind": "travel",
|
|
2782
|
+
"global": "PHASER_RATE_RANGE"
|
|
2783
|
+
},
|
|
2784
|
+
{
|
|
2785
|
+
"name": "baseHz",
|
|
2786
|
+
"kind": "travel",
|
|
2787
|
+
"global": "PHASER_BASE_RANGE"
|
|
2788
|
+
},
|
|
2789
|
+
{
|
|
2790
|
+
"name": "depthOct",
|
|
2791
|
+
"kind": "travel",
|
|
2792
|
+
"global": "PHASER_DEPTH_RANGE"
|
|
2793
|
+
},
|
|
2794
|
+
{
|
|
2795
|
+
"name": "stages",
|
|
2796
|
+
"kind": "travel",
|
|
2797
|
+
"global": "PHASER_STAGES_RANGE"
|
|
2798
|
+
},
|
|
2799
|
+
{
|
|
2800
|
+
"name": "feedback",
|
|
2801
|
+
"kind": "travel",
|
|
2802
|
+
"global": "PHASER_FEEDBACK_RANGE"
|
|
2803
|
+
},
|
|
2804
|
+
{
|
|
2805
|
+
"name": "mix",
|
|
2806
|
+
"kind": "travel",
|
|
2807
|
+
"global": "PHASER_MIX_RANGE"
|
|
2808
|
+
}
|
|
2809
|
+
]
|
|
2810
|
+
},
|
|
2811
|
+
"pitch": {
|
|
2812
|
+
"controls": [
|
|
2813
|
+
{
|
|
2814
|
+
"name": "semitones",
|
|
2815
|
+
"kind": "travel",
|
|
2816
|
+
"global": "PITCH_LIMITS",
|
|
2817
|
+
"table": "PITCH_LIMITS"
|
|
2818
|
+
},
|
|
2819
|
+
{
|
|
2820
|
+
"name": "cents",
|
|
2821
|
+
"kind": "travel",
|
|
2822
|
+
"global": "PITCH_LIMITS",
|
|
2823
|
+
"table": "PITCH_LIMITS"
|
|
2824
|
+
},
|
|
2825
|
+
{
|
|
2826
|
+
"name": "mix",
|
|
2827
|
+
"kind": "travel",
|
|
2828
|
+
"global": "PITCH_LIMITS",
|
|
2829
|
+
"table": "PITCH_LIMITS"
|
|
2830
|
+
}
|
|
2831
|
+
]
|
|
2832
|
+
},
|
|
2833
|
+
"reverb": {
|
|
2834
|
+
"controls": [
|
|
2835
|
+
{
|
|
2836
|
+
"name": "plateModDepth",
|
|
2837
|
+
"kind": "travel",
|
|
2838
|
+
"global": "REVERB_PLATE_MOD_DEPTH_RANGE"
|
|
2839
|
+
},
|
|
2840
|
+
{
|
|
2841
|
+
"name": "mix",
|
|
2842
|
+
"kind": "travel",
|
|
2843
|
+
"global": "REVERB_MIX_RANGE"
|
|
2844
|
+
},
|
|
2845
|
+
{
|
|
2846
|
+
"name": "size",
|
|
2847
|
+
"kind": "travel",
|
|
2848
|
+
"global": "REVERB_SIZE_RANGE"
|
|
2849
|
+
},
|
|
2850
|
+
{
|
|
2851
|
+
"name": "damping",
|
|
2852
|
+
"kind": "travel",
|
|
2853
|
+
"global": "REVERB_DAMPING_RANGE"
|
|
2854
|
+
},
|
|
2855
|
+
{
|
|
2856
|
+
"name": "width",
|
|
2857
|
+
"kind": "travel",
|
|
2858
|
+
"global": "REVERB_WIDTH_RANGE"
|
|
2859
|
+
},
|
|
2860
|
+
{
|
|
2861
|
+
"name": "predelay",
|
|
2862
|
+
"kind": "travel",
|
|
2863
|
+
"global": "REVERB_PREDELAY_RANGE"
|
|
2864
|
+
},
|
|
2865
|
+
{
|
|
2866
|
+
"name": "lowcut",
|
|
2867
|
+
"kind": "travel",
|
|
2868
|
+
"global": "REVERB_LOWCUT_RANGE"
|
|
2869
|
+
},
|
|
2870
|
+
{
|
|
2871
|
+
"name": "highcut",
|
|
2872
|
+
"kind": "travel",
|
|
2873
|
+
"global": "REVERB_HIGHCUT_RANGE"
|
|
2874
|
+
},
|
|
2875
|
+
{
|
|
2876
|
+
"name": "reverse",
|
|
2877
|
+
"kind": "travel",
|
|
2878
|
+
"global": "REVERB_REVERSE_RANGE"
|
|
2879
|
+
},
|
|
2880
|
+
{
|
|
2881
|
+
"name": "hold",
|
|
2882
|
+
"kind": "travel",
|
|
2883
|
+
"global": "REVERB_HOLD_RANGE"
|
|
2884
|
+
},
|
|
2885
|
+
{
|
|
2886
|
+
"name": "release",
|
|
2887
|
+
"kind": "travel",
|
|
2888
|
+
"global": "REVERB_RELEASE_RANGE"
|
|
2889
|
+
},
|
|
2890
|
+
{
|
|
2891
|
+
"name": "gateThreshold",
|
|
2892
|
+
"kind": "travel",
|
|
2893
|
+
"global": "REVERB_GATE_THRESHOLD_RANGE"
|
|
2894
|
+
},
|
|
2895
|
+
{
|
|
2896
|
+
"name": "algorithm",
|
|
2897
|
+
"kind": "choice",
|
|
2898
|
+
"global": "REVERB_ALGORITHMS"
|
|
2899
|
+
}
|
|
2900
|
+
]
|
|
2901
|
+
},
|
|
2902
|
+
"rotary": {
|
|
2903
|
+
"controls": [
|
|
2904
|
+
{
|
|
2905
|
+
"name": "hornSlowHz",
|
|
2906
|
+
"kind": "travel",
|
|
2907
|
+
"global": "ROTARY_HORN_SLOW_RANGE"
|
|
2908
|
+
},
|
|
2909
|
+
{
|
|
2910
|
+
"name": "hornFastHz",
|
|
2911
|
+
"kind": "travel",
|
|
2912
|
+
"global": "ROTARY_HORN_FAST_RANGE"
|
|
2913
|
+
},
|
|
2914
|
+
{
|
|
2915
|
+
"name": "drumSlowHz",
|
|
2916
|
+
"kind": "travel",
|
|
2917
|
+
"global": "ROTARY_DRUM_SLOW_RANGE"
|
|
2918
|
+
},
|
|
2919
|
+
{
|
|
2920
|
+
"name": "drumFastHz",
|
|
2921
|
+
"kind": "travel",
|
|
2922
|
+
"global": "ROTARY_DRUM_FAST_RANGE"
|
|
2923
|
+
},
|
|
2924
|
+
{
|
|
2925
|
+
"name": "accel",
|
|
2926
|
+
"kind": "travel",
|
|
2927
|
+
"global": "ROTARY_ACCEL_RANGE"
|
|
2928
|
+
},
|
|
2929
|
+
{
|
|
2930
|
+
"name": "balance",
|
|
2931
|
+
"kind": "travel",
|
|
2932
|
+
"global": "ROTARY_BALANCE_RANGE"
|
|
2933
|
+
},
|
|
2934
|
+
{
|
|
2935
|
+
"name": "mix",
|
|
2936
|
+
"kind": "travel",
|
|
2937
|
+
"global": "ROTARY_MIX_RANGE"
|
|
2938
|
+
},
|
|
2939
|
+
{
|
|
2940
|
+
"name": "speed",
|
|
2941
|
+
"kind": "choice",
|
|
2942
|
+
"global": "ROTARY_SPEEDS"
|
|
2943
|
+
}
|
|
2944
|
+
]
|
|
2945
|
+
},
|
|
2946
|
+
"rta": {
|
|
2947
|
+
"controls": []
|
|
2948
|
+
},
|
|
2949
|
+
"transient": {
|
|
2950
|
+
"controls": [
|
|
2951
|
+
{
|
|
2952
|
+
"name": "attackDb",
|
|
2953
|
+
"kind": "travel",
|
|
2954
|
+
"global": "TRANSIENT_LIMITS",
|
|
2955
|
+
"table": "TRANSIENT_LIMITS"
|
|
2956
|
+
},
|
|
2957
|
+
{
|
|
2958
|
+
"name": "sustainDb",
|
|
2959
|
+
"kind": "travel",
|
|
2960
|
+
"global": "TRANSIENT_LIMITS",
|
|
2961
|
+
"table": "TRANSIENT_LIMITS"
|
|
2962
|
+
},
|
|
2963
|
+
{
|
|
2964
|
+
"name": "attackTimeMs",
|
|
2965
|
+
"kind": "travel",
|
|
2966
|
+
"global": "TRANSIENT_LIMITS",
|
|
2967
|
+
"table": "TRANSIENT_LIMITS"
|
|
2968
|
+
},
|
|
2969
|
+
{
|
|
2970
|
+
"name": "sustainTimeMs",
|
|
2971
|
+
"kind": "travel",
|
|
2972
|
+
"global": "TRANSIENT_LIMITS",
|
|
2973
|
+
"table": "TRANSIENT_LIMITS"
|
|
2974
|
+
},
|
|
2975
|
+
{
|
|
2976
|
+
"name": "outputDb",
|
|
2977
|
+
"kind": "travel",
|
|
2978
|
+
"global": "TRANSIENT_LIMITS",
|
|
2979
|
+
"table": "TRANSIENT_LIMITS"
|
|
2980
|
+
}
|
|
2981
|
+
]
|
|
2982
|
+
},
|
|
2983
|
+
"tremolo": {
|
|
2984
|
+
"controls": [
|
|
2985
|
+
{
|
|
2986
|
+
"name": "rateHz",
|
|
2987
|
+
"kind": "travel",
|
|
2988
|
+
"global": "TREMOLO_RATE_RANGE"
|
|
2989
|
+
},
|
|
2990
|
+
{
|
|
2991
|
+
"name": "depth",
|
|
2992
|
+
"kind": "travel",
|
|
2993
|
+
"global": "TREMOLO_DEPTH_RANGE"
|
|
2994
|
+
},
|
|
2995
|
+
{
|
|
2996
|
+
"name": "mix",
|
|
2997
|
+
"kind": "travel",
|
|
2998
|
+
"global": "TREMOLO_MIX_RANGE"
|
|
2999
|
+
},
|
|
3000
|
+
{
|
|
3001
|
+
"name": "mode",
|
|
3002
|
+
"kind": "choice",
|
|
3003
|
+
"global": "TREMOLO_MODES"
|
|
3004
|
+
}
|
|
3005
|
+
]
|
|
3006
|
+
}
|
|
2372
3007
|
}
|
|
2373
3008
|
}
|