@openmixer/omx-contract 1.2.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +41 -4
  2. package/bin/omx-contract.mjs +14 -3
  3. package/data/kernels/balance.json +18 -14
  4. package/data/kernels/band_dyn.json +132 -0
  5. package/data/kernels/chorus.json +87 -56
  6. package/data/kernels/comp.json +67 -29
  7. package/data/kernels/deesser.json +114 -86
  8. package/data/kernels/delay.json +67 -57
  9. package/data/kernels/drive.json +118 -87
  10. package/data/kernels/eq.json +284 -113
  11. package/data/kernels/fbs.json +150 -0
  12. package/data/kernels/flanger.json +74 -44
  13. package/data/kernels/gate.json +76 -21
  14. package/data/kernels/geq.json +32 -27
  15. package/data/kernels/hrp.json +68 -0
  16. package/data/kernels/limiter.json +25 -9
  17. package/data/kernels/mixmatrix.json +11 -0
  18. package/data/kernels/phaser.json +110 -100
  19. package/data/kernels/pitch.json +35 -17
  20. package/data/kernels/reverb.json +176 -142
  21. package/data/kernels/rotary.json +189 -177
  22. package/data/kernels/rta.json +17 -0
  23. package/data/kernels/transient.json +64 -36
  24. package/data/kernels/tremolo.json +59 -48
  25. package/data/primitives.json +51 -0
  26. package/data/rates.json +29 -0
  27. package/dist/ts/omx-contract.d.ts +527 -21
  28. package/dist/ts/omx-contract.js +832 -57
  29. package/include/omxcontract/omx_contract_limits.h +233 -0
  30. package/lib/data.mjs +115 -3
  31. package/lib/eq-defaults.mjs +87 -0
  32. package/lib/fmt.mjs +24 -4
  33. package/lib/semver.mjs +12 -2
  34. package/lib/validate.mjs +99 -3
  35. package/package.json +1 -1
  36. package/render/c.mjs +76 -10
  37. package/render/doors.mjs +6 -3
  38. package/render/ts.mjs +40 -2
  39. package/schema/omx-contract.schema.json +39 -3
  40. package/share/omx-contract/omx-contract.json +759 -71
  41. package/render/c/omx_plugin_param.h +0 -25
  42. package/render/c/params-generate.mjs +0 -83
@@ -1,186 +1,198 @@
1
1
  {
2
2
  "$schema": "../../schema/omx-contract.schema.json",
3
- "ROTARY_HORN_SLOW_RANGE": {
4
- "kind": "travels",
5
- "doc": "The horn's chorale (slow) rate, Hz.",
6
- "travel": {
7
- "min": 0.1,
8
- "max": 2,
9
- "step": 0.01,
10
- "unit": "Hz",
11
- "default": 0.8,
12
- "defaultFrom": "desk"
13
- }
14
- },
15
- "ROTARY_HORN_FAST_RANGE": {
16
- "kind": "travels",
17
- "doc": "The horn's tremolo (fast) rate, Hz.",
18
- "travel": {
19
- "min": 3,
20
- "max": 10,
21
- "step": 0.01,
22
- "unit": "Hz",
23
- "default": 6.8,
24
- "defaultFrom": "desk"
3
+ "controls": [
4
+ {
5
+ "name": "hornSlowHz",
6
+ "kind": "travel",
7
+ "global": "ROTARY_HORN_SLOW_RANGE",
8
+ "doc": "The horn's chorale (slow) rate, Hz.",
9
+ "travel": {
10
+ "min": 0.1,
11
+ "max": 2,
12
+ "step": 0.01,
13
+ "unit": "Hz",
14
+ "default": 0.8,
15
+ "defaultFrom": "desk"
16
+ }
17
+ },
18
+ {
19
+ "name": "hornFastHz",
20
+ "kind": "travel",
21
+ "global": "ROTARY_HORN_FAST_RANGE",
22
+ "doc": "The horn's tremolo (fast) rate, Hz.",
23
+ "travel": {
24
+ "min": 3,
25
+ "max": 10,
26
+ "step": 0.01,
27
+ "unit": "Hz",
28
+ "default": 6.8,
29
+ "defaultFrom": "desk"
30
+ }
31
+ },
32
+ {
33
+ "name": "drumSlowHz",
34
+ "kind": "travel",
35
+ "global": "ROTARY_DRUM_SLOW_RANGE",
36
+ "doc": "The drum's chorale (slow) rate, Hz.",
37
+ "travel": {
38
+ "min": 0.1,
39
+ "max": 2,
40
+ "step": 0.01,
41
+ "unit": "Hz",
42
+ "default": 0.7,
43
+ "defaultFrom": "desk"
44
+ }
45
+ },
46
+ {
47
+ "name": "drumFastHz",
48
+ "kind": "travel",
49
+ "global": "ROTARY_DRUM_FAST_RANGE",
50
+ "doc": "The drum's tremolo (fast) rate, Hz.",
51
+ "travel": {
52
+ "min": 3,
53
+ "max": 10,
54
+ "step": 0.01,
55
+ "unit": "Hz",
56
+ "default": 5.9,
57
+ "defaultFrom": "desk"
58
+ }
59
+ },
60
+ {
61
+ "name": "accel",
62
+ "kind": "travel",
63
+ "doc": "The scale on every speed-change time constant (`ROTARY_*_ACCEL_MS`/`_DECEL_MS`): 2 is twice as slow.",
64
+ "travel": {
65
+ "min": 0.25,
66
+ "max": 4,
67
+ "step": 0.01,
68
+ "unit": "x",
69
+ "default": 1,
70
+ "defaultFrom": "desk"
71
+ }
72
+ },
73
+ {
74
+ "name": "balance",
75
+ "kind": "travel",
76
+ "doc": "The drum/horn balance, percent: −100 drum only, +100 horn only; the law attenuates, never boosts.",
77
+ "travel": {
78
+ "min": -100,
79
+ "max": 100,
80
+ "step": 1,
81
+ "unit": "%",
82
+ "default": 0,
83
+ "defaultFrom": "desk"
84
+ }
85
+ },
86
+ {
87
+ "name": "mix",
88
+ "kind": "travel",
89
+ "doc": "The rotary's wet/dry, as an instance of DRIVE_MIX_RANGE: 100 %, because a rotary on an insert IS the sound (it replaces the cabinet) and an `fxReturn` wants it wet too (§3).",
90
+ "travel": {
91
+ "min": 0,
92
+ "max": 100,
93
+ "step": 0.1,
94
+ "unit": "%",
95
+ "default": 100,
96
+ "defaultFrom": "desk"
97
+ }
98
+ },
99
+ {
100
+ "name": "speed",
101
+ "kind": "choice",
102
+ "doc": "The rotary speaker's speed settings, in the order of the integer the kernel reads: the rotors stopped, at their chorale (slow) rate, or at their tremolo (fast) rate.",
103
+ "ids": [
104
+ "stop",
105
+ "slow",
106
+ "fast"
107
+ ]
25
108
  }
26
- },
27
- "ROTARY_DRUM_SLOW_RANGE": {
28
- "kind": "travels",
29
- "doc": "The drum's chorale (slow) rate, Hz.",
30
- "travel": {
31
- "min": 0.1,
32
- "max": 2,
33
- "step": 0.01,
34
- "unit": "Hz",
35
- "default": 0.7,
36
- "defaultFrom": "desk"
109
+ ],
110
+ "aggregates": {
111
+ "ROTARY_TRAVELS": {
112
+ "doc": "The rotary's numeric travels, field → declaration: the ONE map the row's state, its bounds, its OPTIONS and its controller read (`speed` is a member set, ROTARY_SPEEDS, beside it).",
113
+ "fields": [
114
+ "hornSlowHz",
115
+ "hornFastHz",
116
+ "drumSlowHz",
117
+ "drumFastHz",
118
+ "accel",
119
+ "balance",
120
+ "mix"
121
+ ]
37
122
  }
38
123
  },
39
- "ROTARY_DRUM_FAST_RANGE": {
40
- "kind": "travels",
41
- "doc": "The drum's tremolo (fast) rate, Hz.",
42
- "travel": {
43
- "min": 3,
44
- "max": 10,
45
- "step": 0.01,
124
+ "constants": {
125
+ "ROTARY_CROSSOVER_HZ": {
126
+ "kind": "scalar",
127
+ "doc": "The complementary split's low-pass corner, Hz: the Leslie 122's passive crossover.",
46
128
  "unit": "Hz",
47
- "default": 5.9,
48
- "defaultFrom": "desk"
49
- }
50
- },
51
- "ROTARY_ACCEL_RANGE": {
52
- "kind": "travels",
53
- "doc": "The scale on every speed-change time constant (`ROTARY_*_ACCEL_MS`/`_DECEL_MS`): 2 is twice as slow.",
54
- "travel": {
55
- "min": 0.25,
56
- "max": 4,
57
- "step": 0.01,
58
- "unit": "x",
59
- "default": 1,
60
- "defaultFrom": "desk"
61
- }
62
- },
63
- "ROTARY_BALANCE_RANGE": {
64
- "kind": "travels",
65
- "doc": "The drum/horn balance, percent: −100 drum only, +100 horn only; the law attenuates, never boosts.",
66
- "travel": {
67
- "min": -100,
68
- "max": 100,
69
- "step": 1,
70
- "unit": "%",
71
- "default": 0,
72
- "defaultFrom": "desk"
129
+ "value": 800
130
+ },
131
+ "ROTARY_BASE_MS": {
132
+ "kind": "scalar",
133
+ "doc": "The shortest Doppler read, ms — above the order-3 read's one-sample reach at every rate.",
134
+ "unit": "ms",
135
+ "value": 0.1
136
+ },
137
+ "ROTARY_HORN_DOPPLER_MS": {
138
+ "kind": "scalar",
139
+ "doc": "The horn's Doppler excursion `D_horn`, ms: a 0.15 m radius over 343 m/s.",
140
+ "unit": "ms",
141
+ "value": 0.44
142
+ },
143
+ "ROTARY_DRUM_DOPPLER_MS": {
144
+ "kind": "scalar",
145
+ "doc": "The drum's Doppler excursion `D_drum`, ms: its baffle turns over a fixed woofer.",
146
+ "unit": "ms",
147
+ "value": 0.29
148
+ },
149
+ "ROTARY_HORN_AM": {
150
+ "kind": "scalar",
151
+ "doc": "The horn's amplitude swing `m_horn` (a −6 dB directivity dip), a ratio.",
152
+ "unit": "",
153
+ "value": 0.5
154
+ },
155
+ "ROTARY_DRUM_AM": {
156
+ "kind": "scalar",
157
+ "doc": "The drum baffle's amplitude swing `m_drum`, a ratio.",
158
+ "unit": "",
159
+ "value": 0.3
160
+ },
161
+ "ROTARY_HORN_ACCEL_MS": {
162
+ "kind": "scalar",
163
+ "doc": "The horn rotor's speed-up time constant, ms (at `accel` 1).",
164
+ "unit": "ms",
165
+ "value": 330
166
+ },
167
+ "ROTARY_HORN_DECEL_MS": {
168
+ "kind": "scalar",
169
+ "doc": "The horn rotor's slow-down time constant, ms (at `accel` 1).",
170
+ "unit": "ms",
171
+ "value": 500
172
+ },
173
+ "ROTARY_DRUM_ACCEL_MS": {
174
+ "kind": "scalar",
175
+ "doc": "The drum rotor's speed-up time constant, ms (at `accel` 1).",
176
+ "unit": "ms",
177
+ "value": 1700
178
+ },
179
+ "ROTARY_DRUM_DECEL_MS": {
180
+ "kind": "scalar",
181
+ "doc": "The drum rotor's slow-down time constant, ms (at `accel` 1).",
182
+ "unit": "ms",
183
+ "value": 1800
184
+ },
185
+ "ROTARY_STOP_EPS": {
186
+ "kind": "scalar",
187
+ "doc": "Below this rate, Hz, a rotor coasting toward `stop` is snapped to exactly 0.",
188
+ "unit": "",
189
+ "value": 0.0001
190
+ },
191
+ "ROTARY_RING_FLOATS": {
192
+ "kind": "scalar",
193
+ "doc": "One inline ring per rotor per leg, floats — at least the 192 kHz need of the horn's sweep.",
194
+ "unit": "",
195
+ "value": 256
73
196
  }
74
- },
75
- "ROTARY_MIX_RANGE": {
76
- "kind": "travels",
77
- "doc": "The rotary's wet/dry, as an instance of DRIVE_MIX_RANGE: 100 %, because a rotary on an insert IS the sound (it replaces the cabinet) and an `fxReturn` wants it wet too (§3).",
78
- "travel": {
79
- "min": 0,
80
- "max": 100,
81
- "step": 0.1,
82
- "unit": "%",
83
- "default": 100,
84
- "defaultFrom": "desk"
85
- }
86
- },
87
- "ROTARY_TRAVELS": {
88
- "kind": "travels",
89
- "doc": "The rotary's numeric travels, field → declaration: the ONE map the row's state, its bounds, its OPTIONS and its controller read (`speed` is a member set, ROTARY_SPEEDS, beside it).",
90
- "fields": {
91
- "hornSlowHz": {
92
- "ref": "ROTARY_HORN_SLOW_RANGE"
93
- },
94
- "hornFastHz": {
95
- "ref": "ROTARY_HORN_FAST_RANGE"
96
- },
97
- "drumSlowHz": {
98
- "ref": "ROTARY_DRUM_SLOW_RANGE"
99
- },
100
- "drumFastHz": {
101
- "ref": "ROTARY_DRUM_FAST_RANGE"
102
- },
103
- "accel": {
104
- "ref": "ROTARY_ACCEL_RANGE"
105
- },
106
- "balance": {
107
- "ref": "ROTARY_BALANCE_RANGE"
108
- },
109
- "mix": {
110
- "ref": "ROTARY_MIX_RANGE"
111
- }
112
- }
113
- },
114
- "ROTARY_CROSSOVER_HZ": {
115
- "kind": "scalar",
116
- "doc": "The complementary split's low-pass corner, Hz: the Leslie 122's passive crossover.",
117
- "unit": "Hz",
118
- "value": 800
119
- },
120
- "ROTARY_BASE_MS": {
121
- "kind": "scalar",
122
- "doc": "The shortest Doppler read, ms — above the order-3 read's one-sample reach at every rate.",
123
- "unit": "ms",
124
- "value": 0.1
125
- },
126
- "ROTARY_HORN_DOPPLER_MS": {
127
- "kind": "scalar",
128
- "doc": "The horn's Doppler excursion `D_horn`, ms: a 0.15 m radius over 343 m/s.",
129
- "unit": "ms",
130
- "value": 0.44
131
- },
132
- "ROTARY_DRUM_DOPPLER_MS": {
133
- "kind": "scalar",
134
- "doc": "The drum's Doppler excursion `D_drum`, ms: its baffle turns over a fixed woofer.",
135
- "unit": "ms",
136
- "value": 0.29
137
- },
138
- "ROTARY_HORN_AM": {
139
- "kind": "scalar",
140
- "doc": "The horn's amplitude swing `m_horn` (a −6 dB directivity dip), a ratio.",
141
- "unit": "",
142
- "value": 0.5
143
- },
144
- "ROTARY_DRUM_AM": {
145
- "kind": "scalar",
146
- "doc": "The drum baffle's amplitude swing `m_drum`, a ratio.",
147
- "unit": "",
148
- "value": 0.3
149
- },
150
- "ROTARY_HORN_ACCEL_MS": {
151
- "kind": "scalar",
152
- "doc": "The horn rotor's speed-up time constant, ms (at `accel` 1).",
153
- "unit": "ms",
154
- "value": 330
155
- },
156
- "ROTARY_HORN_DECEL_MS": {
157
- "kind": "scalar",
158
- "doc": "The horn rotor's slow-down time constant, ms (at `accel` 1).",
159
- "unit": "ms",
160
- "value": 500
161
- },
162
- "ROTARY_DRUM_ACCEL_MS": {
163
- "kind": "scalar",
164
- "doc": "The drum rotor's speed-up time constant, ms (at `accel` 1).",
165
- "unit": "ms",
166
- "value": 1700
167
- },
168
- "ROTARY_DRUM_DECEL_MS": {
169
- "kind": "scalar",
170
- "doc": "The drum rotor's slow-down time constant, ms (at `accel` 1).",
171
- "unit": "ms",
172
- "value": 1800
173
- },
174
- "ROTARY_STOP_EPS": {
175
- "kind": "scalar",
176
- "doc": "Below this rate, Hz, a rotor coasting toward `stop` is snapped to exactly 0.",
177
- "unit": "",
178
- "value": 0.0001
179
- },
180
- "ROTARY_RING_FLOATS": {
181
- "kind": "scalar",
182
- "doc": "One inline ring per rotor per leg, floats — at least the 192 kHz need of the horn's sweep.",
183
- "unit": "",
184
- "value": 256
185
197
  }
186
198
  }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "../../schema/omx-contract.schema.json",
3
+ "constants": {
4
+ "RTA_TARGET_BIN_HZ": {
5
+ "kind": "scalar",
6
+ "doc": "The RTA's target bin resolution — generated into `omx_contract_limits.h` as `OMX_RTA_TARGET_BIN_HZ`, which `mix_dsp.h` reads; `rta-window-derivation.test.ts` reads it back from the header.",
7
+ "unit": "Hz",
8
+ "value": 5.9
9
+ },
10
+ "RTA_FFT_SIZE_MAX": {
11
+ "kind": "scalar",
12
+ "doc": "The largest RTA FFT the native ring holds — generated into `omx_contract_limits.h` as `OMX_RTA_FFT_SIZE_MAX`.",
13
+ "unit": "",
14
+ "value": 32768
15
+ }
16
+ }
17
+ }
@@ -1,42 +1,63 @@
1
1
  {
2
2
  "$schema": "../../schema/omx-contract.schema.json",
3
- "TRANSIENT_LIMITS": {
4
- "kind": "travels",
5
- "doc": "The legal range of each transient-designer field (engineering units), transient spec §3. Every kind comes up flat: no per-kind default differs. `harness/contract-limits-gen.mjs` emits each as `OMX_TRANSIENT_<FIELD>_{MIN,MAX,DEFAULT}` for `mix_transient.h`'s resolve; the row publishes them on OPTIONS when it lands (issue #921).",
6
- "fields": {
7
- "attackDb": {
3
+ "controls": [
4
+ {
5
+ "name": "attackDb",
6
+ "kind": "travel",
7
+ "table": "TRANSIENT_LIMITS",
8
+ "travel": {
8
9
  "min": -24,
9
10
  "max": 24,
10
11
  "step": 0.1,
11
12
  "unit": "dB",
12
13
  "default": 0,
13
14
  "defaultFrom": "desk"
14
- },
15
- "sustainDb": {
15
+ }
16
+ },
17
+ {
18
+ "name": "sustainDb",
19
+ "kind": "travel",
20
+ "table": "TRANSIENT_LIMITS",
21
+ "travel": {
16
22
  "min": -24,
17
23
  "max": 24,
18
24
  "step": 0.1,
19
25
  "unit": "dB",
20
26
  "default": 0,
21
27
  "defaultFrom": "desk"
22
- },
23
- "attackTimeMs": {
28
+ }
29
+ },
30
+ {
31
+ "name": "attackTimeMs",
32
+ "kind": "travel",
33
+ "table": "TRANSIENT_LIMITS",
34
+ "travel": {
24
35
  "min": 2,
25
36
  "max": 50,
26
37
  "step": 0.1,
27
38
  "unit": "ms",
28
39
  "default": 10,
29
40
  "defaultFrom": "desk"
30
- },
31
- "sustainTimeMs": {
41
+ }
42
+ },
43
+ {
44
+ "name": "sustainTimeMs",
45
+ "kind": "travel",
46
+ "table": "TRANSIENT_LIMITS",
47
+ "travel": {
32
48
  "min": 50,
33
49
  "max": 2000,
34
50
  "step": 1,
35
51
  "unit": "ms",
36
52
  "default": 250,
37
53
  "defaultFrom": "desk"
38
- },
39
- "outputDb": {
54
+ }
55
+ },
56
+ {
57
+ "name": "outputDb",
58
+ "kind": "travel",
59
+ "table": "TRANSIENT_LIMITS",
60
+ "travel": {
40
61
  "min": -24,
41
62
  "max": 12,
42
63
  "step": 0.1,
@@ -45,29 +66,36 @@
45
66
  "defaultFrom": "desk"
46
67
  }
47
68
  }
69
+ ],
70
+ "tables": {
71
+ "TRANSIENT_LIMITS": {
72
+ "doc": "The legal range of each transient-designer field (engineering units), transient spec §3. Every kind comes up flat: no per-kind default differs. `harness/contract-limits-gen.mjs` emits each as `OMX_TRANSIENT_<FIELD>_{MIN,MAX,DEFAULT}` for `mix_transient.h`'s resolve; the row publishes them on OPTIONS when it lands (issue #921)."
73
+ }
48
74
  },
49
- "TRANSIENT_FAST_ATTACK_MS": {
50
- "kind": "scalar",
51
- "doc": "The fast follower's attack, ms: exactly the dynamics detector's no-oversampling line (transient spec §3, L7).",
52
- "unit": "ms",
53
- "value": 0.5
54
- },
55
- "TRANSIENT_FAST_RELEASE_MS": {
56
- "kind": "scalar",
57
- "doc": "The fast follower's release, ms: one 50 Hz cycle held, a 180 bpm sixteenth forgotten (transient spec §3).",
58
- "unit": "ms",
59
- "value": 20
60
- },
61
- "TRANSIENT_REF_DB": {
62
- "kind": "scalar",
63
- "doc": "The contrast, dB, at which a knob reaches its full value (transient spec §2, §3).",
64
- "unit": "dB",
65
- "value": 6
66
- },
67
- "TRANSIENT_FLOOR_LIN": {
68
- "kind": "scalar",
69
- "doc": "The detector floor, linear (−100 dBFS): below it both envelopes read the floor and the stage is unity (transient spec §3).",
70
- "unit": "",
71
- "value": 0.00001
75
+ "constants": {
76
+ "TRANSIENT_FAST_ATTACK_MS": {
77
+ "kind": "scalar",
78
+ "doc": "The fast follower's attack, ms: exactly the dynamics detector's no-oversampling line (transient spec §3, L7).",
79
+ "unit": "ms",
80
+ "value": 0.5
81
+ },
82
+ "TRANSIENT_FAST_RELEASE_MS": {
83
+ "kind": "scalar",
84
+ "doc": "The fast follower's release, ms: one 50 Hz cycle held, a 180 bpm sixteenth forgotten (transient spec §3).",
85
+ "unit": "ms",
86
+ "value": 20
87
+ },
88
+ "TRANSIENT_REF_DB": {
89
+ "kind": "scalar",
90
+ "doc": "The contrast, dB, at which a knob reaches its full value (transient spec §2, §3).",
91
+ "unit": "dB",
92
+ "value": 6
93
+ },
94
+ "TRANSIENT_FLOOR_LIN": {
95
+ "kind": "scalar",
96
+ "doc": "The detector floor, linear (−100 dBFS): below it both envelopes read the floor and the stage is unity (transient spec §3).",
97
+ "unit": "",
98
+ "value": 0.00001
99
+ }
72
100
  }
73
101
  }
@@ -1,54 +1,65 @@
1
1
  {
2
2
  "$schema": "../../schema/omx-contract.schema.json",
3
- "TREMOLO_RATE_RANGE": {
4
- "kind": "travels",
5
- "doc": "The tremolo's LFO rate (the catalogue row's 0.1..20 Hz); 4 Hz is the classic amp tremolo.",
6
- "travel": {
7
- "min": 0.1,
8
- "max": 20,
9
- "step": 0.01,
10
- "unit": "Hz",
11
- "default": 4,
12
- "defaultFrom": "desk"
13
- }
14
- },
15
- "TREMOLO_DEPTH_RANGE": {
16
- "kind": "travels",
17
- "doc": "The tremolo's modulation depth: the gain's trough is `1 − mix·depth`.",
18
- "travel": {
19
- "min": 0,
20
- "max": 100,
21
- "step": 0.1,
22
- "unit": "%",
23
- "default": 50,
24
- "defaultFrom": "desk"
25
- }
26
- },
27
- "TREMOLO_MIX_RANGE": {
28
- "kind": "travels",
29
- "doc": "The tremolo's wet/dry, as an instance of DRIVE_MIX_RANGE: 100 %. The kernel folds the wet/dry into its one gain, so a strip tremolo IS the sound (as the rotary's mix 100 % is).",
30
- "travel": {
31
- "min": 0,
32
- "max": 100,
33
- "step": 0.1,
34
- "unit": "%",
35
- "default": 100,
36
- "defaultFrom": "desk"
37
- }
38
- },
39
- "TREMOLO_TRAVELS": {
40
- "kind": "travels",
41
- "doc": "The tremolo's numeric travels, field → declaration: the ONE map the row's state, its bounds, its OPTIONS and its controller read (`mode` is a member set, TREMOLO_MODES, beside it).",
42
- "fields": {
43
- "rateHz": {
44
- "ref": "TREMOLO_RATE_RANGE"
45
- },
46
- "depth": {
47
- "ref": "TREMOLO_DEPTH_RANGE"
48
- },
49
- "mix": {
50
- "ref": "TREMOLO_MIX_RANGE"
3
+ "controls": [
4
+ {
5
+ "name": "rateHz",
6
+ "kind": "travel",
7
+ "global": "TREMOLO_RATE_RANGE",
8
+ "doc": "The tremolo's LFO rate (the catalogue row's 0.1..20 Hz); 4 Hz is the classic amp tremolo.",
9
+ "travel": {
10
+ "min": 0.1,
11
+ "max": 20,
12
+ "step": 0.01,
13
+ "unit": "Hz",
14
+ "default": 4,
15
+ "defaultFrom": "desk"
51
16
  }
17
+ },
18
+ {
19
+ "name": "depth",
20
+ "kind": "travel",
21
+ "doc": "The tremolo's modulation depth: the gain's trough is `1 − mix·depth`.",
22
+ "travel": {
23
+ "min": 0,
24
+ "max": 100,
25
+ "step": 0.1,
26
+ "unit": "%",
27
+ "default": 50,
28
+ "defaultFrom": "desk"
29
+ }
30
+ },
31
+ {
32
+ "name": "mix",
33
+ "kind": "travel",
34
+ "doc": "The tremolo's wet/dry, as an instance of DRIVE_MIX_RANGE: 100 %. The kernel folds the wet/dry into its one gain, so a strip tremolo IS the sound (as the rotary's mix 100 % is).",
35
+ "travel": {
36
+ "min": 0,
37
+ "max": 100,
38
+ "step": 0.1,
39
+ "unit": "%",
40
+ "default": 100,
41
+ "defaultFrom": "desk"
42
+ }
43
+ },
44
+ {
45
+ "name": "mode",
46
+ "kind": "choice",
47
+ "doc": "What the tremolo's one oscillator modulates, in the order of the integer the kernel reads: the level of both legs in phase (tremolo), or the balance law's position with the legs in opposition (pan).",
48
+ "ids": [
49
+ "tremolo",
50
+ "pan"
51
+ ],
52
+ "default": "tremolo"
53
+ }
54
+ ],
55
+ "aggregates": {
56
+ "TREMOLO_TRAVELS": {
57
+ "doc": "The tremolo's numeric travels, field → declaration: the ONE map the row's state, its bounds, its OPTIONS and its controller read (`mode` is a member set, TREMOLO_MODES, beside it).",
58
+ "fields": [
59
+ "rateHz",
60
+ "depth",
61
+ "mix"
62
+ ]
52
63
  }
53
64
  }
54
65
  }