@openmixer/omx-contract 2.7.0 → 2.8.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 +1 -1
- package/data/kernels/comp.json +2 -2
- package/data/kernels/deesser.json +1 -1
- package/data/kernels/delay.json +3 -3
- package/data/kernels/drive.json +16 -0
- package/data/kernels/eq.json +2 -2
- package/data/kernels/fbs.json +1 -1
- package/data/kernels/hrp.json +2 -2
- package/data/kernels/limiter.json +1 -1
- package/data/kernels/mixmatrix.json +1 -1
- package/data/kernels/reverb.json +2 -2
- package/data/kernels/rta.json +1 -1
- package/data/kernels/transient.json +1 -1
- package/data/kernels/trim.json +1 -1
- package/data/rates.json +1 -1
- package/dist/ts/omx-contract.d.ts +25 -19
- package/dist/ts/omx-contract.js +29 -19
- package/include/omxcontract/omx_contract_limits.h +7 -0
- package/lib/semver.mjs +1 -1
- package/package.json +1 -1
- package/render/c/contract-limits-render.mjs +4 -5
- package/render/doors.mjs +2 -2
- package/share/omx-contract/omx-contract.json +41 -20
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ pkg-config --cflags omx-contract
|
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
Pin one version and build against its renders instead of keeping a copy: the installed package at exactly
|
|
52
|
-
that version (`pkg-config --exact-version=2.
|
|
52
|
+
that version (`pkg-config --exact-version=2.8.0 omx-contract`), else the npm tarball, unpacked, and
|
|
53
53
|
`omx-contract render --target c --out build/omx-contract/include`. A kernel's controls and readouts, in their
|
|
54
54
|
order, are in `share/omx-contract/omx-contract.json`; how a declaration is written is in
|
|
55
55
|
[docs/kernel-files.md](docs/kernel-files.md), and what a readout is in [docs/readouts.md](docs/readouts.md).
|
package/data/kernels/comp.json
CHANGED
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"name": "detectorTopology",
|
|
128
128
|
"kind": "choice",
|
|
129
129
|
"global": "DETECTOR_TOPOLOGY",
|
|
130
|
-
"doc": "Where the compressor's detector listens: `feedforward` hears the slot's input (or its key), `feedback` hears the slot's own pre-make-up output DYN_FB_LOOP_DELAY_SAMPLES late, through one envelope stage, and a keyed slot stays feed-forward (omx-dsp's OMX_DYN_TOPOLOGY_FEEDFORWARD 0 and _FEEDBACK 1, in that order; the set is named for its control, so C spells them OMX_DETECTOR_TOPOLOGY_*). The console's comp row carries it (`detectorTopology`,
|
|
130
|
+
"doc": "Where the compressor's detector listens: `feedforward` hears the slot's input (or its key), `feedback` hears the slot's own pre-make-up output DYN_FB_LOOP_DELAY_SAMPLES late, through one envelope stage, and a keyed slot stays feed-forward (omx-dsp's OMX_DYN_TOPOLOGY_FEEDFORWARD 0 and _FEEDBACK 1, in that order; the set is named for its control, so C spells them OMX_DETECTOR_TOPOLOGY_*). The console's comp row carries it (`detectorTopology`, the SSL bus compressor design §3a) and comes up `feedforward`, so a zeroed atom is the compressor every slot runs.",
|
|
131
131
|
"ids": [
|
|
132
132
|
"feedforward",
|
|
133
133
|
"feedback"
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
"constants": {
|
|
159
159
|
"PROGRAM_RELEASE": {
|
|
160
160
|
"kind": "sheet",
|
|
161
|
-
"doc": "The program-dependent release's model constants — the LA-2A's opto cell as DATA (
|
|
161
|
+
"doc": "The program-dependent release's model constants — the LA-2A's opto cell as DATA (compressor models design §3b). `chargeMs`/`dischargeMs` are the word's memory constants, shared by every profile; each profile's `fastMs`, `slowMinMs`, `slowMaxMs` and `share` fit the unit's published two-stage recovery. Not operator controls: generated into `omx_contract_limits.h` as `OMX_PROGRAM_RELEASE_*`, which libomxdsp's `omx_env_program_release` reads.",
|
|
162
162
|
"value": {
|
|
163
163
|
"chargeMs": 1000,
|
|
164
164
|
"dischargeMs": 5000,
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"constants": {
|
|
129
129
|
"DEESS_KNEE_DB": {
|
|
130
130
|
"kind": "scalar",
|
|
131
|
-
"doc": "The knee, in dB — a CONSTANT of the stage and not a row field
|
|
131
|
+
"doc": "The knee, in dB — a CONSTANT of the stage and not a row field: a de-esser without a soft knee latches audibly on the first sibilant of a phrase, and no other value of this number is a de-esser anyone would dial. The controller pushes it to the node and this is the same number; a second spelling would be a picture that disagrees with the audio about where the reduction starts.",
|
|
132
132
|
"unit": "dB",
|
|
133
133
|
"value": 6
|
|
134
134
|
}
|
package/data/kernels/delay.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "fxDelayTime",
|
|
6
6
|
"kind": "travel",
|
|
7
7
|
"global": "FX_DELAY_TIME_RANGE",
|
|
8
|
-
"doc": "The FX delay's time travel. `max` is the NATIVE ring's ceiling — the same number as `OMX_FXDELAY_MAX_MS` in `omx_delay.h`, pinned to it by
|
|
8
|
+
"doc": "The FX delay's time travel. `max` is the NATIVE ring's ceiling — the same number as `OMX_FXDELAY_MAX_MS` in `omx_delay.h`, pinned to it by the engine's conformance test. Distinct from the per-route ALIGNMENT delay (`OUTPUT_DELAY_RANGE`, 1 s, `OMX_DELAY_MAX_MS`): one is a musical echo with feedback and mix, the other is a pure latency. Two facts, two rings, two ceilings — sharing the word \"delay\" is why they keep being confused for each other.",
|
|
9
9
|
"travel": {
|
|
10
10
|
"min": 0,
|
|
11
11
|
"max": 2000,
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
{
|
|
39
39
|
"name": "tone",
|
|
40
40
|
"kind": "travel",
|
|
41
|
-
"doc": "The FX delay's TONE — a NORMALIZED_RANGE instance with its own come-up value, matching
|
|
41
|
+
"doc": "The FX delay's TONE — a NORMALIZED_RANGE instance with its own come-up value, matching the console's delay default tone. See REVERB_SIZE_RANGE for why this is a named constant rather than a default on the shared shape.",
|
|
42
42
|
"travel": {
|
|
43
43
|
"min": 0,
|
|
44
44
|
"max": 1,
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"constants": {
|
|
85
85
|
"FX_DELAY_PINGPONG_DEFAULT": {
|
|
86
86
|
"kind": "scalar",
|
|
87
|
-
"doc": "The FX delay's PING-PONG come-up value — a toggle, so it has no travel, only this. Declared here rather than as a literal in the
|
|
87
|
+
"doc": "The FX delay's PING-PONG come-up value — a toggle, so it has no travel, only this. Declared here rather than as a literal in the console's delay default state (which now reads it) so the DPF plugin generator (omx-plugins, DPF plugin design §3a) reads the same fact the desk seeds a fresh strip with.",
|
|
88
88
|
"unit": "",
|
|
89
89
|
"value": false
|
|
90
90
|
}
|
package/data/kernels/drive.json
CHANGED
|
@@ -161,6 +161,22 @@
|
|
|
161
161
|
"12 kHz",
|
|
162
162
|
"16 kHz"
|
|
163
163
|
]
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"name": "oversample",
|
|
167
|
+
"kind": "choice",
|
|
168
|
+
"doc": "The drive's OVERSAMPLING factor: the shaper runs inside the console's one oversampler at 1x, 2x or 4x, and the id is the factor (`omx_drive.h`'s `omx_drive_factor_of` member set, `struct omx_drive.os_factor`). A field of the console's drive row (`DriveState.oversample`, the console's DRIVE_OVERSAMPLE_FACTORS; the set is named for its control), 4 at come-up there and in omx-dsp's drive face (OMX_DRIVE_INSTANCE_FACTOR, the oversampler's largest).",
|
|
169
|
+
"ids": [
|
|
170
|
+
1,
|
|
171
|
+
2,
|
|
172
|
+
4
|
|
173
|
+
],
|
|
174
|
+
"default": 4,
|
|
175
|
+
"labels": [
|
|
176
|
+
"1x",
|
|
177
|
+
"2x",
|
|
178
|
+
"4x"
|
|
179
|
+
]
|
|
164
180
|
}
|
|
165
181
|
],
|
|
166
182
|
"constants": {
|
package/data/kernels/eq.json
CHANGED
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
{
|
|
108
108
|
"name": "gain",
|
|
109
109
|
"kind": "travel",
|
|
110
|
-
"doc": "The parametric-band gain travel, in dB. The ± scalar `clampEqGain` enforces is READ off this (
|
|
110
|
+
"doc": "The parametric-band gain travel, in dB. The ± scalar `clampEqGain` enforces is READ off this (the engine derives its gain limit from `max`), so the bound is stated once and a surface cannot draw a wider knob than the clamp will honour.",
|
|
111
111
|
"travel": {
|
|
112
112
|
"min": -15,
|
|
113
113
|
"max": 15,
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
"constants": {
|
|
163
163
|
"EQ_MAX_BANDS": {
|
|
164
164
|
"kind": "scalar",
|
|
165
|
-
"doc": "The maximum number of parametric bands a channel EQ may hold — the operator can add up to this many. Generated into `omx_contract_limits.h` as `OMX_EQ_MAX_BANDS`, which `omx_biquad.h` reads (
|
|
165
|
+
"doc": "The maximum number of parametric bands a channel EQ may hold — the operator can add up to this many. Generated into `omx_contract_limits.h` as `OMX_EQ_MAX_BANDS`, which `omx_biquad.h` reads (the engine's conformance test reads the header): the native lane allocates exactly this many biquad slots per channel and silently clamps above it, so the model, the wire, and the DSP agree by test, not by memory.",
|
|
166
166
|
"unit": "",
|
|
167
167
|
"value": 24
|
|
168
168
|
},
|
package/data/kernels/fbs.json
CHANGED
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
},
|
|
131
131
|
"FBS_MAX_NOTCH_DEPTH_DB": {
|
|
132
132
|
"kind": "scalar",
|
|
133
|
-
"doc": "THE NOTCH DEPTH LAW: the deepest cut any machine planter may propose from one reading, in dB. A number, not a literal at the call site, because two planters now lean on it. FBS derives a candidate's depth from the peak-to-average ratio around its bin and stops here; Room Analysis derives a mode's depth from its height above the median curve and is held to the SAME ceiling (
|
|
133
|
+
"doc": "THE NOTCH DEPTH LAW: the deepest cut any machine planter may propose from one reading, in dB. A number, not a literal at the call site, because two planters now lean on it. FBS derives a candidate's depth from the peak-to-average ratio around its bin and stops here; Room Analysis derives a mode's depth from its height above the median curve and is held to the SAME ceiling (the room-analysis design §4 — \"never more than the FBS notch depth law\"). Written twice as `18` those two bounds would be equal by coincidence and could drift apart in silence. It is a CEILING ON THE PROPOSAL, not the final gain: a band that lands as a rampable BELL is bounded again by `EQ_GAIN_RANGE`, which is tighter. A planter must honour both and REPORT when either bit, never quietly deliver a shallower cut than it was asked for.",
|
|
134
134
|
"unit": "dB",
|
|
135
135
|
"value": 18
|
|
136
136
|
},
|
package/data/kernels/hrp.json
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"HRP_MAX_VOICES": {
|
|
26
26
|
"kind": "scalar",
|
|
27
|
-
"doc": "How many simultaneous musical voices the detector may report on one channel. PINNED to `OMX_HRP_MAX_VOICES` in `pipewire-native/src/hrp_pitch.h` — the C voice set is a FIXED-SIZE array, so a TS number above the macro promises voices the analyser structurally cannot return, and one below it silently drops notes the C already found.
|
|
27
|
+
"doc": "How many simultaneous musical voices the detector may report on one channel. PINNED to `OMX_HRP_MAX_VOICES` in `pipewire-native/src/hrp_pitch.h` — the C voice set is a FIXED-SIZE array, so a TS number above the macro promises voices the analyser structurally cannot return, and one below it silently drops notes the C already found. the engine's conformance test reads the header and holds the pair equal. EIGHT (operator sizing, 2026-09-01): a guitar sounds six strings, a piano or string-section voicing sits at eight. It is a SEARCH ceiling, not a cost — the detector abandons a round as soon as no credible candidate remains, so monophonic material costs what it always did.",
|
|
28
28
|
"unit": "",
|
|
29
29
|
"value": 8
|
|
30
30
|
},
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"HRP_DEFAULT_MAX_AUTO_BANDS": {
|
|
62
62
|
"kind": "scalar",
|
|
63
|
-
"doc": "How many bands HRP may plant on ONE channel — its half of the machine budget, and the number that makes the budget FORECASTABLE rather than emergent. Without it the count is whatever the material happens to provoke: the placement law is sparse, so a clean note plants two bands and a resonant room plants nine, and nobody can answer \"will this fit?\" until it does not. With FBS senior (§9.3(b)) that discovery would happen at showtime, to the junior planter, silently. Declared instead, the whole sum is arithmetic an operator can read before a note is played: operator bands + FBS maxAutoBands + HRP maxAutoBands <= EQ_MAX_BANDS EIGHT — ONE CORRECTION PER VOICE at full polyphony (operator sizing, 2026-09-01). The detector's ceiling is HRP_MAX_VOICES voices, a guitar's six strings and a piano/string voicing's eight, and a budget below the voice count would decide by arithmetic which of the notes actually sounding may be corrected — a limit nobody could read off the desk. Scarcity is handled where it belongs instead: the candidates from every voice meet in ONE globally ranked list (spec §29) and the head of it is what gets planted. It is NOT a claim to seniority, and it is larger than FBS's six. Seniority is the ALLOCATION ORDER — `HrpPlanter` takes only `EQ_MAX_BANDS − others.length`, the remainder after the operator and every other machine — so a bigger junior default cannot reach a senior slot; it only means HRP asks for more of what is left.
|
|
63
|
+
"doc": "How many bands HRP may plant on ONE channel — its half of the machine budget, and the number that makes the budget FORECASTABLE rather than emergent. Without it the count is whatever the material happens to provoke: the placement law is sparse, so a clean note plants two bands and a resonant room plants nine, and nobody can answer \"will this fit?\" until it does not. With FBS senior (§9.3(b)) that discovery would happen at showtime, to the junior planter, silently. Declared instead, the whole sum is arithmetic an operator can read before a note is played: operator bands + FBS maxAutoBands + HRP maxAutoBands <= EQ_MAX_BANDS EIGHT — ONE CORRECTION PER VOICE at full polyphony (operator sizing, 2026-09-01). The detector's ceiling is HRP_MAX_VOICES voices, a guitar's six strings and a piano/string voicing's eight, and a budget below the voice count would decide by arithmetic which of the notes actually sounding may be corrected — a limit nobody could read off the desk. Scarcity is handled where it belongs instead: the candidates from every voice meet in ONE globally ranked list (spec §29) and the head of it is what gets planted. It is NOT a claim to seniority, and it is larger than FBS's six. Seniority is the ALLOCATION ORDER — `HrpPlanter` takes only `EQ_MAX_BANDS − others.length`, the remainder after the operator and every other machine — so a bigger junior default cannot reach a senior slot; it only means HRP asks for more of what is left. the engine's conformance test asserts both halves. The per-channel DEFAULT; the row's travel is HRP_AUTO_BANDS_RANGE, so a channel that needs more can have more, as an explicit decision with a visible cost.",
|
|
64
64
|
"unit": "",
|
|
65
65
|
"value": 8
|
|
66
66
|
}
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
],
|
|
60
60
|
"tables": {
|
|
61
61
|
"LIMITER_LIMITS": {
|
|
62
|
-
"doc": "The precision limiter's travels
|
|
62
|
+
"doc": "The precision limiter's travels, rendered into `omx_contract_limits.h` as `OMX_LIMITER_*` by the engine's limits generator, so `mix_limiter.h` reads them and never restates one (R-094). The ceiling is a TRUE peak in dBFS (the ×4 detector); the look-ahead sets the declared latency; the release is the envelope's time constant on the gain depth."
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"constants": {
|
|
4
4
|
"BUS_INPUT_CAP": {
|
|
5
5
|
"kind": "scalar",
|
|
6
|
-
"doc": "The input cap a summing bus can be sized to — **the engine's declared input ceiling**, read from `@freemixer/declarations` rather than re-typed here. A gig with more than this many inputs needs more than one engine node; below it a bus is sized to `min(N, BUS_INPUT_CAP)`. It was a literal 64 until 2026-09-15, said to mirror the engine's `MAX_BUS_INPUTS` — and it did, but that 64 was the PipeWire builtin mixer's single-tier fan-in (8 × 8), never the engine's bound: the native node has allocated `OMX_MAX_STRIPS` (128) strips all along. Two literals agreeing by hand is how the console came to refuse a 96-channel desk it could carry.
|
|
6
|
+
"doc": "The input cap a summing bus can be sized to — **the engine's declared input ceiling**, read from `@freemixer/declarations` rather than re-typed here. A gig with more than this many inputs needs more than one engine node; below it a bus is sized to `min(N, BUS_INPUT_CAP)`. It was a literal 64 until 2026-09-15, said to mirror the engine's `MAX_BUS_INPUTS` — and it did, but that 64 was the PipeWire builtin mixer's single-tier fan-in (8 × 8), never the engine's bound: the native node has allocated `OMX_MAX_STRIPS` (128) strips all along. Two literals agreeing by hand is how the console came to refuse a 96-channel desk it could carry. the engine's conformance test holds this to the C header; the console allocation design §9 carries the ruling and the measured cost of width.",
|
|
7
7
|
"unit": "",
|
|
8
8
|
"value": 128
|
|
9
9
|
}
|
package/data/kernels/reverb.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
{
|
|
5
5
|
"name": "plateModDepth",
|
|
6
6
|
"kind": "travel",
|
|
7
|
-
"doc": "PLATE's tank MODULATION DEPTH, in percent of Dattorro's own excursion (±8 samples at his 29 761 Hz tuning rate, scaled to the live rate the way the tank lengths are). 100 is the depth the plate has always run at, so the come-up is bit-identical to the plate before the field; 0 brings back the unmodulated tank's ring; 400 is the wide, chorused EMT-style swing. The rate stays 1 Hz. Only PLATE reads it
|
|
7
|
+
"doc": "PLATE's tank MODULATION DEPTH, in percent of Dattorro's own excursion (±8 samples at his 29 761 Hz tuning rate, scaled to the live rate the way the tank lengths are). 100 is the depth the plate has always run at, so the come-up is bit-identical to the plate before the field; 0 brings back the unmodulated tank's ring; 400 is the wide, chorused EMT-style swing. The rate stays 1 Hz. Only PLATE reads it.",
|
|
8
8
|
"travel": {
|
|
9
9
|
"min": 0,
|
|
10
10
|
"max": 400,
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
{
|
|
112
112
|
"name": "reverse",
|
|
113
113
|
"kind": "travel",
|
|
114
|
-
"doc": "REVERSE's MIRROR WINDOW — how long a slice of the wet is played backward, in milliseconds
|
|
114
|
+
"doc": "REVERSE's MIRROR WINDOW — how long a slice of the wet is played backward, in milliseconds. A DECLARED travel and never derived from `size`'s RT60: an RT60 of seconds cannot be buffered at 192 kHz, and a window silently clamped to fit is the silent-clamp defect. The ceiling is what `mix_reverb.h`'s pool budgets a ring for (`OMX_REVERB_REVERSE_MAX_MS`), so the console offers exactly the travel the kernel accepts — nothing wider, nothing narrower.",
|
|
115
115
|
"travel": {
|
|
116
116
|
"min": 50,
|
|
117
117
|
"max": 500,
|
package/data/kernels/rta.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"constants": {
|
|
4
4
|
"RTA_TARGET_BIN_HZ": {
|
|
5
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;
|
|
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; the engine's conformance test reads it back from the header.",
|
|
7
7
|
"unit": "Hz",
|
|
8
8
|
"value": 5.9
|
|
9
9
|
},
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
],
|
|
70
70
|
"tables": {
|
|
71
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.
|
|
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. the engine's limits generator 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
73
|
}
|
|
74
74
|
},
|
|
75
75
|
"constants": {
|
package/data/kernels/trim.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "trimDb",
|
|
6
6
|
"kind": "travel",
|
|
7
7
|
"global": "TRIM_RANGE",
|
|
8
|
-
"doc": "The digital input trim, in dB: the console's fine head gain, applied first in a channel's lane as a click-free ramp from the last block's gain to this one (
|
|
8
|
+
"doc": "The digital input trim, in dB: the console's fine head gain, applied first in a channel's lane as a click-free ramp from the last block's gain to this one (the console's trim range, -24..+24 dB in 0.1 dB steps, spelled minDb/maxDb/stepDb there). It comes up at 0 dB, the trim a channel has when none is set. omx-dsp's trim face takes it as `trim_db`.",
|
|
9
9
|
"travel": {
|
|
10
10
|
"min": -24,
|
|
11
11
|
"max": 24,
|
package/data/rates.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "../schema/omx-contract.schema.json",
|
|
3
3
|
"STANDARD_SAMPLE_RATES": {
|
|
4
4
|
"kind": "list",
|
|
5
|
-
"doc": "The standard sample rates (Hz) the desk recognises — the pro-audio superset. One source of truth for the clock controller's `clock.allowed-rates` seed, the force row's validation ceiling and the device-rate probe fallback. What the operator is OFFERED is always the DEVICE's own `supportedRates`
|
|
5
|
+
"doc": "The standard sample rates (Hz) the desk recognises — the pro-audio superset. One source of truth for the clock controller's `clock.allowed-rates` seed, the force row's validation ceiling and the device-rate probe fallback. What the operator is OFFERED is always the DEVICE's own `supportedRates` — this is the ceiling a write is refused by, never a menu.",
|
|
6
6
|
"unit": "Hz",
|
|
7
7
|
"values": [
|
|
8
8
|
44100,
|
|
@@ -255,13 +255,13 @@ export declare const COMP_KINDS: readonly ["comp", "limiter"];
|
|
|
255
255
|
export declare const DETECTOR_OVERSAMPLINGS: readonly ["auto", "off", "x4"];
|
|
256
256
|
|
|
257
257
|
/**
|
|
258
|
-
* Where the compressor's detector listens: `feedforward` hears the slot's input (or its key), `feedback` hears the slot's own pre-make-up output DYN_FB_LOOP_DELAY_SAMPLES late, through one envelope stage, and a keyed slot stays feed-forward (omx-dsp's OMX_DYN_TOPOLOGY_FEEDFORWARD 0 and _FEEDBACK 1, in that order; the set is named for its control, so C spells them OMX_DETECTOR_TOPOLOGY_*). The console's comp row carries it (`detectorTopology`,
|
|
258
|
+
* Where the compressor's detector listens: `feedforward` hears the slot's input (or its key), `feedback` hears the slot's own pre-make-up output DYN_FB_LOOP_DELAY_SAMPLES late, through one envelope stage, and a keyed slot stays feed-forward (omx-dsp's OMX_DYN_TOPOLOGY_FEEDFORWARD 0 and _FEEDBACK 1, in that order; the set is named for its control, so C spells them OMX_DETECTOR_TOPOLOGY_*). The console's comp row carries it (`detectorTopology`, the SSL bus compressor design §3a) and comes up `feedforward`, so a zeroed atom is the compressor every slot runs.
|
|
259
259
|
* @see data/kernels/comp.json
|
|
260
260
|
*/
|
|
261
261
|
export declare const DETECTOR_TOPOLOGY: readonly ["feedforward", "feedback"];
|
|
262
262
|
|
|
263
263
|
/**
|
|
264
|
-
* The program-dependent release's model constants — the LA-2A's opto cell as DATA (
|
|
264
|
+
* The program-dependent release's model constants — the LA-2A's opto cell as DATA (compressor models design §3b). `chargeMs`/`dischargeMs` are the word's memory constants, shared by every profile; each profile's `fastMs`, `slowMinMs`, `slowMaxMs` and `share` fit the unit's published two-stage recovery. Not operator controls: generated into `omx_contract_limits.h` as `OMX_PROGRAM_RELEASE_*`, which libomxdsp's `omx_env_program_release` reads.
|
|
265
265
|
* @see data/kernels/comp.json
|
|
266
266
|
*/
|
|
267
267
|
export declare const PROGRAM_RELEASE: {
|
|
@@ -381,13 +381,13 @@ export declare const DEESS_RELEASE_RANGE: {
|
|
|
381
381
|
export declare const DEESS_MODES: readonly ["split", "wideband"];
|
|
382
382
|
|
|
383
383
|
/**
|
|
384
|
-
* The knee, in dB — a CONSTANT of the stage and not a row field
|
|
384
|
+
* The knee, in dB — a CONSTANT of the stage and not a row field: a de-esser without a soft knee latches audibly on the first sibilant of a phrase, and no other value of this number is a de-esser anyone would dial. The controller pushes it to the node and this is the same number; a second spelling would be a picture that disagrees with the audio about where the reduction starts.
|
|
385
385
|
* @see data/kernels/deesser.json
|
|
386
386
|
*/
|
|
387
387
|
export declare const DEESS_KNEE_DB: 6;
|
|
388
388
|
|
|
389
389
|
/**
|
|
390
|
-
* The FX delay's time travel. `max` is the NATIVE ring's ceiling — the same number as `OMX_FXDELAY_MAX_MS` in `omx_delay.h`, pinned to it by
|
|
390
|
+
* The FX delay's time travel. `max` is the NATIVE ring's ceiling — the same number as `OMX_FXDELAY_MAX_MS` in `omx_delay.h`, pinned to it by the engine's conformance test. Distinct from the per-route ALIGNMENT delay (`OUTPUT_DELAY_RANGE`, 1 s, `OMX_DELAY_MAX_MS`): one is a musical echo with feedback and mix, the other is a pure latency. Two facts, two rings, two ceilings — sharing the word "delay" is why they keep being confused for each other.
|
|
391
391
|
* @see data/kernels/delay.json
|
|
392
392
|
*/
|
|
393
393
|
export declare const FX_DELAY_TIME_RANGE: {
|
|
@@ -413,7 +413,7 @@ export declare const FX_DELAY_FEEDBACK_RANGE: {
|
|
|
413
413
|
};
|
|
414
414
|
|
|
415
415
|
/**
|
|
416
|
-
* The FX delay's TONE — a NORMALIZED_RANGE instance with its own come-up value, matching
|
|
416
|
+
* The FX delay's TONE — a NORMALIZED_RANGE instance with its own come-up value, matching the console's delay default tone. See REVERB_SIZE_RANGE for why this is a named constant rather than a default on the shared shape.
|
|
417
417
|
* @see data/kernels/delay.json
|
|
418
418
|
*/
|
|
419
419
|
export declare const DELAY_TONE_RANGE: {
|
|
@@ -448,7 +448,7 @@ export declare const DELAY_MIX_RANGE: {
|
|
|
448
448
|
export declare const DELAY_PINGPONGS: readonly ["off", "on"];
|
|
449
449
|
|
|
450
450
|
/**
|
|
451
|
-
* The FX delay's PING-PONG come-up value — a toggle, so it has no travel, only this. Declared here rather than as a literal in the
|
|
451
|
+
* The FX delay's PING-PONG come-up value — a toggle, so it has no travel, only this. Declared here rather than as a literal in the console's delay default state (which now reads it) so the DPF plugin generator (omx-plugins, DPF plugin design §3a) reads the same fact the desk seeds a fresh strip with.
|
|
452
452
|
* @see data/kernels/delay.json
|
|
453
453
|
*/
|
|
454
454
|
export declare const FX_DELAY_PINGPONG_DEFAULT: false;
|
|
@@ -548,6 +548,12 @@ export declare const DRIVE_STEREO_LINKS: readonly ["off", "on"];
|
|
|
548
548
|
*/
|
|
549
549
|
export declare const DRIVE_HF_ROLLOFFS: readonly [0, 12000, 16000];
|
|
550
550
|
|
|
551
|
+
/**
|
|
552
|
+
* The drive's OVERSAMPLING factor: the shaper runs inside the console's one oversampler at 1x, 2x or 4x, and the id is the factor (`omx_drive.h`'s `omx_drive_factor_of` member set, `struct omx_drive.os_factor`). A field of the console's drive row (`DriveState.oversample`, the console's DRIVE_OVERSAMPLE_FACTORS; the set is named for its control), 4 at come-up there and in omx-dsp's drive face (OMX_DRIVE_INSTANCE_FACTOR, the oversampler's largest).
|
|
553
|
+
* @see data/kernels/drive.json
|
|
554
|
+
*/
|
|
555
|
+
export declare const DRIVE_OVERSAMPLES: readonly [1, 2, 4];
|
|
556
|
+
|
|
551
557
|
/**
|
|
552
558
|
* The bias at `character = +1`, in the SHAPER's own input units — `OMX_DRIVE_BIAS_MAX`. DERIVED, not chosen (§4b). In the saturating limit every knee tends to `sgn`, the output is a rectangular wave of duty `d = ½ + asin(b)/π`, and its `n`th harmonic goes as `sin(nπd)/n` — so `|H2|` is maximal at `d = ¾`, which is `b = sin(π/4) = 1/√2` exactly. Measured too: the H2-maximising bias for a full-scale sine at unity drive is 0.712 (soft), 0.658 (tape), 0.645 (tube), and this one value costs 0.000 / 0.035 / 0.088 dB of H2 against each curve's own optimum. ONE normalised bias for all three knees, not three.
|
|
553
559
|
* @see data/kernels/drive.json
|
|
@@ -612,7 +618,7 @@ export declare const EQ_FREQ_RANGE: {
|
|
|
612
618
|
};
|
|
613
619
|
|
|
614
620
|
/**
|
|
615
|
-
* The parametric-band gain travel, in dB. The ± scalar `clampEqGain` enforces is READ off this (
|
|
621
|
+
* The parametric-band gain travel, in dB. The ± scalar `clampEqGain` enforces is READ off this (the engine derives its gain limit from `max`), so the bound is stated once and a surface cannot draw a wider knob than the clamp will honour.
|
|
616
622
|
* @see data/kernels/eq.json
|
|
617
623
|
*/
|
|
618
624
|
export declare const EQ_GAIN_RANGE: {
|
|
@@ -651,7 +657,7 @@ export declare const EQ_NOTCH_Q_RANGE: {
|
|
|
651
657
|
export declare const EQ_BAND_ONS: readonly ["off", "on"];
|
|
652
658
|
|
|
653
659
|
/**
|
|
654
|
-
* The maximum number of parametric bands a channel EQ may hold — the operator can add up to this many. Generated into `omx_contract_limits.h` as `OMX_EQ_MAX_BANDS`, which `omx_biquad.h` reads (
|
|
660
|
+
* The maximum number of parametric bands a channel EQ may hold — the operator can add up to this many. Generated into `omx_contract_limits.h` as `OMX_EQ_MAX_BANDS`, which `omx_biquad.h` reads (the engine's conformance test reads the header): the native lane allocates exactly this many biquad slots per channel and silently clamps above it, so the model, the wire, and the DSP agree by test, not by memory.
|
|
655
661
|
* @see data/kernels/eq.json
|
|
656
662
|
*/
|
|
657
663
|
export declare const EQ_MAX_BANDS: 24;
|
|
@@ -846,7 +852,7 @@ export declare const DEFAULT_THRESHOLDS: {
|
|
|
846
852
|
};
|
|
847
853
|
|
|
848
854
|
/**
|
|
849
|
-
* THE NOTCH DEPTH LAW: the deepest cut any machine planter may propose from one reading, in dB. A number, not a literal at the call site, because two planters now lean on it. FBS derives a candidate's depth from the peak-to-average ratio around its bin and stops here; Room Analysis derives a mode's depth from its height above the median curve and is held to the SAME ceiling (
|
|
855
|
+
* THE NOTCH DEPTH LAW: the deepest cut any machine planter may propose from one reading, in dB. A number, not a literal at the call site, because two planters now lean on it. FBS derives a candidate's depth from the peak-to-average ratio around its bin and stops here; Room Analysis derives a mode's depth from its height above the median curve and is held to the SAME ceiling (the room-analysis design §4 — "never more than the FBS notch depth law"). Written twice as `18` those two bounds would be equal by coincidence and could drift apart in silence. It is a CEILING ON THE PROPOSAL, not the final gain: a band that lands as a rampable BELL is bounded again by `EQ_GAIN_RANGE`, which is tighter. A planter must honour both and REPORT when either bit, never quietly deliver a shallower cut than it was asked for.
|
|
850
856
|
* @see data/kernels/fbs.json
|
|
851
857
|
*/
|
|
852
858
|
export declare const FBS_MAX_NOTCH_DEPTH_DB: 18;
|
|
@@ -1094,7 +1100,7 @@ export declare const HRP_AMOUNT_RANGE: {
|
|
|
1094
1100
|
export declare const HRP_MAX_CUT_DB: 6;
|
|
1095
1101
|
|
|
1096
1102
|
/**
|
|
1097
|
-
* How many simultaneous musical voices the detector may report on one channel. PINNED to `OMX_HRP_MAX_VOICES` in `pipewire-native/src/hrp_pitch.h` — the C voice set is a FIXED-SIZE array, so a TS number above the macro promises voices the analyser structurally cannot return, and one below it silently drops notes the C already found.
|
|
1103
|
+
* How many simultaneous musical voices the detector may report on one channel. PINNED to `OMX_HRP_MAX_VOICES` in `pipewire-native/src/hrp_pitch.h` — the C voice set is a FIXED-SIZE array, so a TS number above the macro promises voices the analyser structurally cannot return, and one below it silently drops notes the C already found. the engine's conformance test reads the header and holds the pair equal. EIGHT (operator sizing, 2026-09-01): a guitar sounds six strings, a piano or string-section voicing sits at eight. It is a SEARCH ceiling, not a cost — the detector abandons a round as soon as no credible candidate remains, so monophonic material costs what it always did.
|
|
1098
1104
|
* @see data/kernels/hrp.json
|
|
1099
1105
|
*/
|
|
1100
1106
|
export declare const HRP_MAX_VOICES: 8;
|
|
@@ -1130,13 +1136,13 @@ export declare const HRP_COLLISION_CENTS: 100;
|
|
|
1130
1136
|
export declare const HRP_ATTRIBUTION_CENTS: 60;
|
|
1131
1137
|
|
|
1132
1138
|
/**
|
|
1133
|
-
* How many bands HRP may plant on ONE channel — its half of the machine budget, and the number that makes the budget FORECASTABLE rather than emergent. Without it the count is whatever the material happens to provoke: the placement law is sparse, so a clean note plants two bands and a resonant room plants nine, and nobody can answer "will this fit?" until it does not. With FBS senior (§9.3(b)) that discovery would happen at showtime, to the junior planter, silently. Declared instead, the whole sum is arithmetic an operator can read before a note is played: operator bands + FBS maxAutoBands + HRP maxAutoBands <= EQ_MAX_BANDS EIGHT — ONE CORRECTION PER VOICE at full polyphony (operator sizing, 2026-09-01). The detector's ceiling is HRP_MAX_VOICES voices, a guitar's six strings and a piano/string voicing's eight, and a budget below the voice count would decide by arithmetic which of the notes actually sounding may be corrected — a limit nobody could read off the desk. Scarcity is handled where it belongs instead: the candidates from every voice meet in ONE globally ranked list (spec §29) and the head of it is what gets planted. It is NOT a claim to seniority, and it is larger than FBS's six. Seniority is the ALLOCATION ORDER — `HrpPlanter` takes only `EQ_MAX_BANDS − others.length`, the remainder after the operator and every other machine — so a bigger junior default cannot reach a senior slot; it only means HRP asks for more of what is left.
|
|
1139
|
+
* How many bands HRP may plant on ONE channel — its half of the machine budget, and the number that makes the budget FORECASTABLE rather than emergent. Without it the count is whatever the material happens to provoke: the placement law is sparse, so a clean note plants two bands and a resonant room plants nine, and nobody can answer "will this fit?" until it does not. With FBS senior (§9.3(b)) that discovery would happen at showtime, to the junior planter, silently. Declared instead, the whole sum is arithmetic an operator can read before a note is played: operator bands + FBS maxAutoBands + HRP maxAutoBands <= EQ_MAX_BANDS EIGHT — ONE CORRECTION PER VOICE at full polyphony (operator sizing, 2026-09-01). The detector's ceiling is HRP_MAX_VOICES voices, a guitar's six strings and a piano/string voicing's eight, and a budget below the voice count would decide by arithmetic which of the notes actually sounding may be corrected — a limit nobody could read off the desk. Scarcity is handled where it belongs instead: the candidates from every voice meet in ONE globally ranked list (spec §29) and the head of it is what gets planted. It is NOT a claim to seniority, and it is larger than FBS's six. Seniority is the ALLOCATION ORDER — `HrpPlanter` takes only `EQ_MAX_BANDS − others.length`, the remainder after the operator and every other machine — so a bigger junior default cannot reach a senior slot; it only means HRP asks for more of what is left. the engine's conformance test asserts both halves. The per-channel DEFAULT; the row's travel is HRP_AUTO_BANDS_RANGE, so a channel that needs more can have more, as an explicit decision with a visible cost.
|
|
1134
1140
|
* @see data/kernels/hrp.json
|
|
1135
1141
|
*/
|
|
1136
1142
|
export declare const HRP_DEFAULT_MAX_AUTO_BANDS: 8;
|
|
1137
1143
|
|
|
1138
1144
|
/**
|
|
1139
|
-
* The precision limiter's travels
|
|
1145
|
+
* The precision limiter's travels, rendered into `omx_contract_limits.h` as `OMX_LIMITER_*` by the engine's limits generator, so `mix_limiter.h` reads them and never restates one (R-094). The ceiling is a TRUE peak in dBFS (the ×4 detector); the look-ahead sets the declared latency; the release is the envelope's time constant on the gain depth.
|
|
1140
1146
|
* @see data/kernels/limiter.json
|
|
1141
1147
|
*/
|
|
1142
1148
|
export declare const LIMITER_LIMITS: {
|
|
@@ -1167,7 +1173,7 @@ export declare const LIMITER_LIMITS: {
|
|
|
1167
1173
|
};
|
|
1168
1174
|
|
|
1169
1175
|
/**
|
|
1170
|
-
* The input cap a summing bus can be sized to — **the engine's declared input ceiling**, read from `@freemixer/declarations` rather than re-typed here. A gig with more than this many inputs needs more than one engine node; below it a bus is sized to `min(N, BUS_INPUT_CAP)`. It was a literal 64 until 2026-09-15, said to mirror the engine's `MAX_BUS_INPUTS` — and it did, but that 64 was the PipeWire builtin mixer's single-tier fan-in (8 × 8), never the engine's bound: the native node has allocated `OMX_MAX_STRIPS` (128) strips all along. Two literals agreeing by hand is how the console came to refuse a 96-channel desk it could carry.
|
|
1176
|
+
* The input cap a summing bus can be sized to — **the engine's declared input ceiling**, read from `@freemixer/declarations` rather than re-typed here. A gig with more than this many inputs needs more than one engine node; below it a bus is sized to `min(N, BUS_INPUT_CAP)`. It was a literal 64 until 2026-09-15, said to mirror the engine's `MAX_BUS_INPUTS` — and it did, but that 64 was the PipeWire builtin mixer's single-tier fan-in (8 × 8), never the engine's bound: the native node has allocated `OMX_MAX_STRIPS` (128) strips all along. Two literals agreeing by hand is how the console came to refuse a 96-channel desk it could carry. the engine's conformance test holds this to the C header; the console allocation design §9 carries the ruling and the measured cost of width.
|
|
1171
1177
|
* @see data/kernels/mixmatrix.json
|
|
1172
1178
|
*/
|
|
1173
1179
|
export declare const BUS_INPUT_CAP: 128;
|
|
@@ -1342,7 +1348,7 @@ export declare const PITCH_KERNEL: {
|
|
|
1342
1348
|
};
|
|
1343
1349
|
|
|
1344
1350
|
/**
|
|
1345
|
-
* PLATE's tank MODULATION DEPTH, in percent of Dattorro's own excursion (±8 samples at his 29 761 Hz tuning rate, scaled to the live rate the way the tank lengths are). 100 is the depth the plate has always run at, so the come-up is bit-identical to the plate before the field; 0 brings back the unmodulated tank's ring; 400 is the wide, chorused EMT-style swing. The rate stays 1 Hz. Only PLATE reads it
|
|
1351
|
+
* PLATE's tank MODULATION DEPTH, in percent of Dattorro's own excursion (±8 samples at his 29 761 Hz tuning rate, scaled to the live rate the way the tank lengths are). 100 is the depth the plate has always run at, so the come-up is bit-identical to the plate before the field; 0 brings back the unmodulated tank's ring; 400 is the wide, chorused EMT-style swing. The rate stays 1 Hz. Only PLATE reads it.
|
|
1346
1352
|
* @see data/kernels/reverb.json
|
|
1347
1353
|
*/
|
|
1348
1354
|
export declare const REVERB_PLATE_MOD_DEPTH_RANGE: {
|
|
@@ -1449,7 +1455,7 @@ export declare const REVERB_HIGHCUT_RANGE: {
|
|
|
1449
1455
|
};
|
|
1450
1456
|
|
|
1451
1457
|
/**
|
|
1452
|
-
* REVERSE's MIRROR WINDOW — how long a slice of the wet is played backward, in milliseconds
|
|
1458
|
+
* REVERSE's MIRROR WINDOW — how long a slice of the wet is played backward, in milliseconds. A DECLARED travel and never derived from `size`'s RT60: an RT60 of seconds cannot be buffered at 192 kHz, and a window silently clamped to fit is the silent-clamp defect. The ceiling is what `mix_reverb.h`'s pool budgets a ring for (`OMX_REVERB_REVERSE_MAX_MS`), so the console offers exactly the travel the kernel accepts — nothing wider, nothing narrower.
|
|
1453
1459
|
* @see data/kernels/reverb.json
|
|
1454
1460
|
*/
|
|
1455
1461
|
export declare const REVERB_REVERSE_RANGE: {
|
|
@@ -1745,7 +1751,7 @@ export declare const ROTARY_STOP_EPS: 0.0001;
|
|
|
1745
1751
|
export declare const ROTARY_RING_FLOATS: 256;
|
|
1746
1752
|
|
|
1747
1753
|
/**
|
|
1748
|
-
* The RTA's target bin resolution — generated into `omx_contract_limits.h` as `OMX_RTA_TARGET_BIN_HZ`, which `mix_dsp.h` reads;
|
|
1754
|
+
* The RTA's target bin resolution — generated into `omx_contract_limits.h` as `OMX_RTA_TARGET_BIN_HZ`, which `mix_dsp.h` reads; the engine's conformance test reads it back from the header.
|
|
1749
1755
|
* @see data/kernels/rta.json
|
|
1750
1756
|
*/
|
|
1751
1757
|
export declare const RTA_TARGET_BIN_HZ: 5.9;
|
|
@@ -1781,7 +1787,7 @@ export declare const SRC_ROLLOFF: 0.92;
|
|
|
1781
1787
|
export declare const SRC_MAX_L: 1024;
|
|
1782
1788
|
|
|
1783
1789
|
/**
|
|
1784
|
-
* The legal range of each transient-designer field (engineering units), transient spec §3. Every kind comes up flat: no per-kind default differs.
|
|
1790
|
+
* The legal range of each transient-designer field (engineering units), transient spec §3. Every kind comes up flat: no per-kind default differs. the engine's limits generator 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).
|
|
1785
1791
|
* @see data/kernels/transient.json
|
|
1786
1792
|
*/
|
|
1787
1793
|
export declare const TRANSIENT_LIMITS: {
|
|
@@ -1928,7 +1934,7 @@ export declare const TREMOLO_TRAVELS: {
|
|
|
1928
1934
|
};
|
|
1929
1935
|
|
|
1930
1936
|
/**
|
|
1931
|
-
* The digital input trim, in dB: the console's fine head gain, applied first in a channel's lane as a click-free ramp from the last block's gain to this one (
|
|
1937
|
+
* The digital input trim, in dB: the console's fine head gain, applied first in a channel's lane as a click-free ramp from the last block's gain to this one (the console's trim range, -24..+24 dB in 0.1 dB steps, spelled minDb/maxDb/stepDb there). It comes up at 0 dB, the trim a channel has when none is set. omx-dsp's trim face takes it as `trim_db`.
|
|
1932
1938
|
* @see data/kernels/trim.json
|
|
1933
1939
|
*/
|
|
1934
1940
|
export declare const TRIM_RANGE: {
|
|
@@ -2094,7 +2100,7 @@ export declare const EQ_CONTINUOUS_TRAVELS: {
|
|
|
2094
2100
|
export declare const READOUT_RATE_HZ: 50;
|
|
2095
2101
|
|
|
2096
2102
|
/**
|
|
2097
|
-
* The standard sample rates (Hz) the desk recognises — the pro-audio superset. One source of truth for the clock controller's `clock.allowed-rates` seed, the force row's validation ceiling and the device-rate probe fallback. What the operator is OFFERED is always the DEVICE's own `supportedRates`
|
|
2103
|
+
* The standard sample rates (Hz) the desk recognises — the pro-audio superset. One source of truth for the clock controller's `clock.allowed-rates` seed, the force row's validation ceiling and the device-rate probe fallback. What the operator is OFFERED is always the DEVICE's own `supportedRates` — this is the ceiling a write is refused by, never a menu.
|
|
2098
2104
|
* @see data/rates.json
|
|
2099
2105
|
*/
|
|
2100
2106
|
export declare const STANDARD_SAMPLE_RATES: readonly [44100, 48000, 88200, 96000, 176400, 192000];
|
package/dist/ts/omx-contract.js
CHANGED
|
@@ -265,7 +265,7 @@ export const DETECTOR_OVERSAMPLINGS = [
|
|
|
265
265
|
];
|
|
266
266
|
|
|
267
267
|
/**
|
|
268
|
-
* Where the compressor's detector listens: `feedforward` hears the slot's input (or its key), `feedback` hears the slot's own pre-make-up output DYN_FB_LOOP_DELAY_SAMPLES late, through one envelope stage, and a keyed slot stays feed-forward (omx-dsp's OMX_DYN_TOPOLOGY_FEEDFORWARD 0 and _FEEDBACK 1, in that order; the set is named for its control, so C spells them OMX_DETECTOR_TOPOLOGY_*). The console's comp row carries it (`detectorTopology`,
|
|
268
|
+
* Where the compressor's detector listens: `feedforward` hears the slot's input (or its key), `feedback` hears the slot's own pre-make-up output DYN_FB_LOOP_DELAY_SAMPLES late, through one envelope stage, and a keyed slot stays feed-forward (omx-dsp's OMX_DYN_TOPOLOGY_FEEDFORWARD 0 and _FEEDBACK 1, in that order; the set is named for its control, so C spells them OMX_DETECTOR_TOPOLOGY_*). The console's comp row carries it (`detectorTopology`, the SSL bus compressor design §3a) and comes up `feedforward`, so a zeroed atom is the compressor every slot runs.
|
|
269
269
|
* @see data/kernels/comp.json
|
|
270
270
|
*/
|
|
271
271
|
export const DETECTOR_TOPOLOGY = [
|
|
@@ -274,7 +274,7 @@ export const DETECTOR_TOPOLOGY = [
|
|
|
274
274
|
];
|
|
275
275
|
|
|
276
276
|
/**
|
|
277
|
-
* The program-dependent release's model constants — the LA-2A's opto cell as DATA (
|
|
277
|
+
* The program-dependent release's model constants — the LA-2A's opto cell as DATA (compressor models design §3b). `chargeMs`/`dischargeMs` are the word's memory constants, shared by every profile; each profile's `fastMs`, `slowMinMs`, `slowMaxMs` and `share` fit the unit's published two-stage recovery. Not operator controls: generated into `omx_contract_limits.h` as `OMX_PROGRAM_RELEASE_*`, which libomxdsp's `omx_env_program_release` reads.
|
|
278
278
|
* @see data/kernels/comp.json
|
|
279
279
|
*/
|
|
280
280
|
export const PROGRAM_RELEASE = {
|
|
@@ -397,13 +397,13 @@ export const DEESS_MODES = [
|
|
|
397
397
|
];
|
|
398
398
|
|
|
399
399
|
/**
|
|
400
|
-
* The knee, in dB — a CONSTANT of the stage and not a row field
|
|
400
|
+
* The knee, in dB — a CONSTANT of the stage and not a row field: a de-esser without a soft knee latches audibly on the first sibilant of a phrase, and no other value of this number is a de-esser anyone would dial. The controller pushes it to the node and this is the same number; a second spelling would be a picture that disagrees with the audio about where the reduction starts.
|
|
401
401
|
* @see data/kernels/deesser.json
|
|
402
402
|
*/
|
|
403
403
|
export const DEESS_KNEE_DB = 6;
|
|
404
404
|
|
|
405
405
|
/**
|
|
406
|
-
* The FX delay's time travel. `max` is the NATIVE ring's ceiling — the same number as `OMX_FXDELAY_MAX_MS` in `omx_delay.h`, pinned to it by
|
|
406
|
+
* The FX delay's time travel. `max` is the NATIVE ring's ceiling — the same number as `OMX_FXDELAY_MAX_MS` in `omx_delay.h`, pinned to it by the engine's conformance test. Distinct from the per-route ALIGNMENT delay (`OUTPUT_DELAY_RANGE`, 1 s, `OMX_DELAY_MAX_MS`): one is a musical echo with feedback and mix, the other is a pure latency. Two facts, two rings, two ceilings — sharing the word "delay" is why they keep being confused for each other.
|
|
407
407
|
* @see data/kernels/delay.json
|
|
408
408
|
*/
|
|
409
409
|
export const FX_DELAY_TIME_RANGE = {
|
|
@@ -429,7 +429,7 @@ export const FX_DELAY_FEEDBACK_RANGE = {
|
|
|
429
429
|
};
|
|
430
430
|
|
|
431
431
|
/**
|
|
432
|
-
* The FX delay's TONE — a NORMALIZED_RANGE instance with its own come-up value, matching
|
|
432
|
+
* The FX delay's TONE — a NORMALIZED_RANGE instance with its own come-up value, matching the console's delay default tone. See REVERB_SIZE_RANGE for why this is a named constant rather than a default on the shared shape.
|
|
433
433
|
* @see data/kernels/delay.json
|
|
434
434
|
*/
|
|
435
435
|
export const DELAY_TONE_RANGE = {
|
|
@@ -467,7 +467,7 @@ export const DELAY_PINGPONGS = [
|
|
|
467
467
|
];
|
|
468
468
|
|
|
469
469
|
/**
|
|
470
|
-
* The FX delay's PING-PONG come-up value — a toggle, so it has no travel, only this. Declared here rather than as a literal in the
|
|
470
|
+
* The FX delay's PING-PONG come-up value — a toggle, so it has no travel, only this. Declared here rather than as a literal in the console's delay default state (which now reads it) so the DPF plugin generator (omx-plugins, DPF plugin design §3a) reads the same fact the desk seeds a fresh strip with.
|
|
471
471
|
* @see data/kernels/delay.json
|
|
472
472
|
*/
|
|
473
473
|
export const FX_DELAY_PINGPONG_DEFAULT = false;
|
|
@@ -587,6 +587,16 @@ export const DRIVE_HF_ROLLOFFS = [
|
|
|
587
587
|
16000
|
|
588
588
|
];
|
|
589
589
|
|
|
590
|
+
/**
|
|
591
|
+
* The drive's OVERSAMPLING factor: the shaper runs inside the console's one oversampler at 1x, 2x or 4x, and the id is the factor (`omx_drive.h`'s `omx_drive_factor_of` member set, `struct omx_drive.os_factor`). A field of the console's drive row (`DriveState.oversample`, the console's DRIVE_OVERSAMPLE_FACTORS; the set is named for its control), 4 at come-up there and in omx-dsp's drive face (OMX_DRIVE_INSTANCE_FACTOR, the oversampler's largest).
|
|
592
|
+
* @see data/kernels/drive.json
|
|
593
|
+
*/
|
|
594
|
+
export const DRIVE_OVERSAMPLES = [
|
|
595
|
+
1,
|
|
596
|
+
2,
|
|
597
|
+
4
|
|
598
|
+
];
|
|
599
|
+
|
|
590
600
|
/**
|
|
591
601
|
* The bias at `character = +1`, in the SHAPER's own input units — `OMX_DRIVE_BIAS_MAX`. DERIVED, not chosen (§4b). In the saturating limit every knee tends to `sgn`, the output is a rectangular wave of duty `d = ½ + asin(b)/π`, and its `n`th harmonic goes as `sin(nπd)/n` — so `|H2|` is maximal at `d = ¾`, which is `b = sin(π/4) = 1/√2` exactly. Measured too: the H2-maximising bias for a full-scale sine at unity drive is 0.712 (soft), 0.658 (tape), 0.645 (tube), and this one value costs 0.000 / 0.035 / 0.088 dB of H2 against each curve's own optimum. ONE normalised bias for all three knees, not three.
|
|
592
602
|
* @see data/kernels/drive.json
|
|
@@ -667,7 +677,7 @@ export const EQ_FREQ_RANGE = {
|
|
|
667
677
|
};
|
|
668
678
|
|
|
669
679
|
/**
|
|
670
|
-
* The parametric-band gain travel, in dB. The ± scalar `clampEqGain` enforces is READ off this (
|
|
680
|
+
* The parametric-band gain travel, in dB. The ± scalar `clampEqGain` enforces is READ off this (the engine derives its gain limit from `max`), so the bound is stated once and a surface cannot draw a wider knob than the clamp will honour.
|
|
671
681
|
* @see data/kernels/eq.json
|
|
672
682
|
*/
|
|
673
683
|
export const EQ_GAIN_RANGE = {
|
|
@@ -709,7 +719,7 @@ export const EQ_BAND_ONS = [
|
|
|
709
719
|
];
|
|
710
720
|
|
|
711
721
|
/**
|
|
712
|
-
* The maximum number of parametric bands a channel EQ may hold — the operator can add up to this many. Generated into `omx_contract_limits.h` as `OMX_EQ_MAX_BANDS`, which `omx_biquad.h` reads (
|
|
722
|
+
* The maximum number of parametric bands a channel EQ may hold — the operator can add up to this many. Generated into `omx_contract_limits.h` as `OMX_EQ_MAX_BANDS`, which `omx_biquad.h` reads (the engine's conformance test reads the header): the native lane allocates exactly this many biquad slots per channel and silently clamps above it, so the model, the wire, and the DSP agree by test, not by memory.
|
|
713
723
|
* @see data/kernels/eq.json
|
|
714
724
|
*/
|
|
715
725
|
export const EQ_MAX_BANDS = 24;
|
|
@@ -1003,7 +1013,7 @@ export const DEFAULT_THRESHOLDS = {
|
|
|
1003
1013
|
};
|
|
1004
1014
|
|
|
1005
1015
|
/**
|
|
1006
|
-
* THE NOTCH DEPTH LAW: the deepest cut any machine planter may propose from one reading, in dB. A number, not a literal at the call site, because two planters now lean on it. FBS derives a candidate's depth from the peak-to-average ratio around its bin and stops here; Room Analysis derives a mode's depth from its height above the median curve and is held to the SAME ceiling (
|
|
1016
|
+
* THE NOTCH DEPTH LAW: the deepest cut any machine planter may propose from one reading, in dB. A number, not a literal at the call site, because two planters now lean on it. FBS derives a candidate's depth from the peak-to-average ratio around its bin and stops here; Room Analysis derives a mode's depth from its height above the median curve and is held to the SAME ceiling (the room-analysis design §4 — "never more than the FBS notch depth law"). Written twice as `18` those two bounds would be equal by coincidence and could drift apart in silence. It is a CEILING ON THE PROPOSAL, not the final gain: a band that lands as a rampable BELL is bounded again by `EQ_GAIN_RANGE`, which is tighter. A planter must honour both and REPORT when either bit, never quietly deliver a shallower cut than it was asked for.
|
|
1007
1017
|
* @see data/kernels/fbs.json
|
|
1008
1018
|
*/
|
|
1009
1019
|
export const FBS_MAX_NOTCH_DEPTH_DB = 18;
|
|
@@ -1263,7 +1273,7 @@ export const HRP_AMOUNT_RANGE = {
|
|
|
1263
1273
|
export const HRP_MAX_CUT_DB = 6;
|
|
1264
1274
|
|
|
1265
1275
|
/**
|
|
1266
|
-
* How many simultaneous musical voices the detector may report on one channel. PINNED to `OMX_HRP_MAX_VOICES` in `pipewire-native/src/hrp_pitch.h` — the C voice set is a FIXED-SIZE array, so a TS number above the macro promises voices the analyser structurally cannot return, and one below it silently drops notes the C already found.
|
|
1276
|
+
* How many simultaneous musical voices the detector may report on one channel. PINNED to `OMX_HRP_MAX_VOICES` in `pipewire-native/src/hrp_pitch.h` — the C voice set is a FIXED-SIZE array, so a TS number above the macro promises voices the analyser structurally cannot return, and one below it silently drops notes the C already found. the engine's conformance test reads the header and holds the pair equal. EIGHT (operator sizing, 2026-09-01): a guitar sounds six strings, a piano or string-section voicing sits at eight. It is a SEARCH ceiling, not a cost — the detector abandons a round as soon as no credible candidate remains, so monophonic material costs what it always did.
|
|
1267
1277
|
* @see data/kernels/hrp.json
|
|
1268
1278
|
*/
|
|
1269
1279
|
export const HRP_MAX_VOICES = 8;
|
|
@@ -1299,13 +1309,13 @@ export const HRP_COLLISION_CENTS = 100;
|
|
|
1299
1309
|
export const HRP_ATTRIBUTION_CENTS = 60;
|
|
1300
1310
|
|
|
1301
1311
|
/**
|
|
1302
|
-
* How many bands HRP may plant on ONE channel — its half of the machine budget, and the number that makes the budget FORECASTABLE rather than emergent. Without it the count is whatever the material happens to provoke: the placement law is sparse, so a clean note plants two bands and a resonant room plants nine, and nobody can answer "will this fit?" until it does not. With FBS senior (§9.3(b)) that discovery would happen at showtime, to the junior planter, silently. Declared instead, the whole sum is arithmetic an operator can read before a note is played: operator bands + FBS maxAutoBands + HRP maxAutoBands <= EQ_MAX_BANDS EIGHT — ONE CORRECTION PER VOICE at full polyphony (operator sizing, 2026-09-01). The detector's ceiling is HRP_MAX_VOICES voices, a guitar's six strings and a piano/string voicing's eight, and a budget below the voice count would decide by arithmetic which of the notes actually sounding may be corrected — a limit nobody could read off the desk. Scarcity is handled where it belongs instead: the candidates from every voice meet in ONE globally ranked list (spec §29) and the head of it is what gets planted. It is NOT a claim to seniority, and it is larger than FBS's six. Seniority is the ALLOCATION ORDER — `HrpPlanter` takes only `EQ_MAX_BANDS − others.length`, the remainder after the operator and every other machine — so a bigger junior default cannot reach a senior slot; it only means HRP asks for more of what is left.
|
|
1312
|
+
* How many bands HRP may plant on ONE channel — its half of the machine budget, and the number that makes the budget FORECASTABLE rather than emergent. Without it the count is whatever the material happens to provoke: the placement law is sparse, so a clean note plants two bands and a resonant room plants nine, and nobody can answer "will this fit?" until it does not. With FBS senior (§9.3(b)) that discovery would happen at showtime, to the junior planter, silently. Declared instead, the whole sum is arithmetic an operator can read before a note is played: operator bands + FBS maxAutoBands + HRP maxAutoBands <= EQ_MAX_BANDS EIGHT — ONE CORRECTION PER VOICE at full polyphony (operator sizing, 2026-09-01). The detector's ceiling is HRP_MAX_VOICES voices, a guitar's six strings and a piano/string voicing's eight, and a budget below the voice count would decide by arithmetic which of the notes actually sounding may be corrected — a limit nobody could read off the desk. Scarcity is handled where it belongs instead: the candidates from every voice meet in ONE globally ranked list (spec §29) and the head of it is what gets planted. It is NOT a claim to seniority, and it is larger than FBS's six. Seniority is the ALLOCATION ORDER — `HrpPlanter` takes only `EQ_MAX_BANDS − others.length`, the remainder after the operator and every other machine — so a bigger junior default cannot reach a senior slot; it only means HRP asks for more of what is left. the engine's conformance test asserts both halves. The per-channel DEFAULT; the row's travel is HRP_AUTO_BANDS_RANGE, so a channel that needs more can have more, as an explicit decision with a visible cost.
|
|
1303
1313
|
* @see data/kernels/hrp.json
|
|
1304
1314
|
*/
|
|
1305
1315
|
export const HRP_DEFAULT_MAX_AUTO_BANDS = 8;
|
|
1306
1316
|
|
|
1307
1317
|
/**
|
|
1308
|
-
* The precision limiter's travels
|
|
1318
|
+
* The precision limiter's travels, rendered into `omx_contract_limits.h` as `OMX_LIMITER_*` by the engine's limits generator, so `mix_limiter.h` reads them and never restates one (R-094). The ceiling is a TRUE peak in dBFS (the ×4 detector); the look-ahead sets the declared latency; the release is the envelope's time constant on the gain depth.
|
|
1309
1319
|
* @see data/kernels/limiter.json
|
|
1310
1320
|
*/
|
|
1311
1321
|
export const LIMITER_LIMITS = {
|
|
@@ -1336,7 +1346,7 @@ export const LIMITER_LIMITS = {
|
|
|
1336
1346
|
};
|
|
1337
1347
|
|
|
1338
1348
|
/**
|
|
1339
|
-
* The input cap a summing bus can be sized to — **the engine's declared input ceiling**, read from `@freemixer/declarations` rather than re-typed here. A gig with more than this many inputs needs more than one engine node; below it a bus is sized to `min(N, BUS_INPUT_CAP)`. It was a literal 64 until 2026-09-15, said to mirror the engine's `MAX_BUS_INPUTS` — and it did, but that 64 was the PipeWire builtin mixer's single-tier fan-in (8 × 8), never the engine's bound: the native node has allocated `OMX_MAX_STRIPS` (128) strips all along. Two literals agreeing by hand is how the console came to refuse a 96-channel desk it could carry.
|
|
1349
|
+
* The input cap a summing bus can be sized to — **the engine's declared input ceiling**, read from `@freemixer/declarations` rather than re-typed here. A gig with more than this many inputs needs more than one engine node; below it a bus is sized to `min(N, BUS_INPUT_CAP)`. It was a literal 64 until 2026-09-15, said to mirror the engine's `MAX_BUS_INPUTS` — and it did, but that 64 was the PipeWire builtin mixer's single-tier fan-in (8 × 8), never the engine's bound: the native node has allocated `OMX_MAX_STRIPS` (128) strips all along. Two literals agreeing by hand is how the console came to refuse a 96-channel desk it could carry. the engine's conformance test holds this to the C header; the console allocation design §9 carries the ruling and the measured cost of width.
|
|
1340
1350
|
* @see data/kernels/mixmatrix.json
|
|
1341
1351
|
*/
|
|
1342
1352
|
export const BUS_INPUT_CAP = 128;
|
|
@@ -1518,7 +1528,7 @@ export const PITCH_KERNEL = {
|
|
|
1518
1528
|
};
|
|
1519
1529
|
|
|
1520
1530
|
/**
|
|
1521
|
-
* PLATE's tank MODULATION DEPTH, in percent of Dattorro's own excursion (±8 samples at his 29 761 Hz tuning rate, scaled to the live rate the way the tank lengths are). 100 is the depth the plate has always run at, so the come-up is bit-identical to the plate before the field; 0 brings back the unmodulated tank's ring; 400 is the wide, chorused EMT-style swing. The rate stays 1 Hz. Only PLATE reads it
|
|
1531
|
+
* PLATE's tank MODULATION DEPTH, in percent of Dattorro's own excursion (±8 samples at his 29 761 Hz tuning rate, scaled to the live rate the way the tank lengths are). 100 is the depth the plate has always run at, so the come-up is bit-identical to the plate before the field; 0 brings back the unmodulated tank's ring; 400 is the wide, chorused EMT-style swing. The rate stays 1 Hz. Only PLATE reads it.
|
|
1522
1532
|
* @see data/kernels/reverb.json
|
|
1523
1533
|
*/
|
|
1524
1534
|
export const REVERB_PLATE_MOD_DEPTH_RANGE = {
|
|
@@ -1625,7 +1635,7 @@ export const REVERB_HIGHCUT_RANGE = {
|
|
|
1625
1635
|
};
|
|
1626
1636
|
|
|
1627
1637
|
/**
|
|
1628
|
-
* REVERSE's MIRROR WINDOW — how long a slice of the wet is played backward, in milliseconds
|
|
1638
|
+
* REVERSE's MIRROR WINDOW — how long a slice of the wet is played backward, in milliseconds. A DECLARED travel and never derived from `size`'s RT60: an RT60 of seconds cannot be buffered at 192 kHz, and a window silently clamped to fit is the silent-clamp defect. The ceiling is what `mix_reverb.h`'s pool budgets a ring for (`OMX_REVERB_REVERSE_MAX_MS`), so the console offers exactly the travel the kernel accepts — nothing wider, nothing narrower.
|
|
1629
1639
|
* @see data/kernels/reverb.json
|
|
1630
1640
|
*/
|
|
1631
1641
|
export const REVERB_REVERSE_RANGE = {
|
|
@@ -1931,7 +1941,7 @@ export const ROTARY_STOP_EPS = 0.0001;
|
|
|
1931
1941
|
export const ROTARY_RING_FLOATS = 256;
|
|
1932
1942
|
|
|
1933
1943
|
/**
|
|
1934
|
-
* The RTA's target bin resolution — generated into `omx_contract_limits.h` as `OMX_RTA_TARGET_BIN_HZ`, which `mix_dsp.h` reads;
|
|
1944
|
+
* The RTA's target bin resolution — generated into `omx_contract_limits.h` as `OMX_RTA_TARGET_BIN_HZ`, which `mix_dsp.h` reads; the engine's conformance test reads it back from the header.
|
|
1935
1945
|
* @see data/kernels/rta.json
|
|
1936
1946
|
*/
|
|
1937
1947
|
export const RTA_TARGET_BIN_HZ = 5.9;
|
|
@@ -1967,7 +1977,7 @@ export const SRC_ROLLOFF = 0.92;
|
|
|
1967
1977
|
export const SRC_MAX_L = 1024;
|
|
1968
1978
|
|
|
1969
1979
|
/**
|
|
1970
|
-
* The legal range of each transient-designer field (engineering units), transient spec §3. Every kind comes up flat: no per-kind default differs.
|
|
1980
|
+
* The legal range of each transient-designer field (engineering units), transient spec §3. Every kind comes up flat: no per-kind default differs. the engine's limits generator 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).
|
|
1971
1981
|
* @see data/kernels/transient.json
|
|
1972
1982
|
*/
|
|
1973
1983
|
export const TRANSIENT_LIMITS = {
|
|
@@ -2117,7 +2127,7 @@ export const TREMOLO_TRAVELS = {
|
|
|
2117
2127
|
};
|
|
2118
2128
|
|
|
2119
2129
|
/**
|
|
2120
|
-
* The digital input trim, in dB: the console's fine head gain, applied first in a channel's lane as a click-free ramp from the last block's gain to this one (
|
|
2130
|
+
* The digital input trim, in dB: the console's fine head gain, applied first in a channel's lane as a click-free ramp from the last block's gain to this one (the console's trim range, -24..+24 dB in 0.1 dB steps, spelled minDb/maxDb/stepDb there). It comes up at 0 dB, the trim a channel has when none is set. omx-dsp's trim face takes it as `trim_db`.
|
|
2121
2131
|
* @see data/kernels/trim.json
|
|
2122
2132
|
*/
|
|
2123
2133
|
export const TRIM_RANGE = {
|
|
@@ -2287,7 +2297,7 @@ export const EQ_CONTINUOUS_TRAVELS = {
|
|
|
2287
2297
|
export const READOUT_RATE_HZ = 50;
|
|
2288
2298
|
|
|
2289
2299
|
/**
|
|
2290
|
-
* The standard sample rates (Hz) the desk recognises — the pro-audio superset. One source of truth for the clock controller's `clock.allowed-rates` seed, the force row's validation ceiling and the device-rate probe fallback. What the operator is OFFERED is always the DEVICE's own `supportedRates`
|
|
2300
|
+
* The standard sample rates (Hz) the desk recognises — the pro-audio superset. One source of truth for the clock controller's `clock.allowed-rates` seed, the force row's validation ceiling and the device-rate probe fallback. What the operator is OFFERED is always the DEVICE's own `supportedRates` — this is the ceiling a write is refused by, never a menu.
|
|
2291
2301
|
* @see data/rates.json
|
|
2292
2302
|
*/
|
|
2293
2303
|
export const STANDARD_SAMPLE_RATES = [
|
|
@@ -696,6 +696,13 @@ enum omx_drive_hf_rolloffs {
|
|
|
696
696
|
};
|
|
697
697
|
#define OMX_DRIVE_HF_ROLLOFFS_COUNT 3u
|
|
698
698
|
#define OMX_DRIVE_HF_ROLLOFFS_DEFAULT OMX_DRIVE_HF_ROLLOFFS_0
|
|
699
|
+
enum omx_drive_oversamples {
|
|
700
|
+
OMX_DRIVE_OVERSAMPLES_1 = 1,
|
|
701
|
+
OMX_DRIVE_OVERSAMPLES_2 = 2,
|
|
702
|
+
OMX_DRIVE_OVERSAMPLES_4 = 4,
|
|
703
|
+
};
|
|
704
|
+
#define OMX_DRIVE_OVERSAMPLES_COUNT 3u
|
|
705
|
+
#define OMX_DRIVE_OVERSAMPLES_DEFAULT OMX_DRIVE_OVERSAMPLES_4
|
|
699
706
|
enum omx_drive_stereo_links {
|
|
700
707
|
OMX_DRIVE_STEREO_LINKS_OFF = 0,
|
|
701
708
|
OMX_DRIVE_STEREO_LINKS_ON = 1,
|
package/lib/semver.mjs
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
const RANK = { none: 0, patch: 1, minor: 2, major: 3 };
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* The development-phase rule (
|
|
23
|
+
* The development-phase rule (omx-contract spec §3.6): while every consumer of
|
|
24
24
|
* omx-contract is a FreeMixer repository named here, removing an item is MINOR. The rule ends, and
|
|
25
25
|
* this becomes null so a removal is MAJOR again, in the release that names the first consumer
|
|
26
26
|
* outside the list.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmixer/omx-contract",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.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",
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
// Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
|
|
3
|
-
// Moved unchanged from
|
|
4
|
-
// §3.4): a frozen export of
|
|
3
|
+
// Moved unchanged from the console engine's contract-limits renderer at 6c6e709f4429 (omx-contract spec
|
|
4
|
+
// §3.4): a frozen export of the engine's whole sheet renders through it byte for byte (test/round-trip.test.mjs).
|
|
5
5
|
/**
|
|
6
6
|
* The RENDER half of `contract-limits-gen.mjs`: the header text as a pure function of the
|
|
7
|
-
* declaration sheet it is handed. Split out so the declaration-perturbation
|
|
8
|
-
* `packages/server/src/declaration-perturbation-conformance.test.ts`) can render the header over
|
|
7
|
+
* declaration sheet it is handed. Split out so the engine's declaration-perturbation test can render the header over
|
|
9
8
|
* a PERTURBED sheet and see whether every define follows it — the generator itself imports the
|
|
10
9
|
* built modules and calls this, so there is one renderer and no second copy.
|
|
11
10
|
*/
|
|
@@ -220,7 +219,7 @@ function genDeclaredListsBlock(DECLARED_LISTS, definedElsewhere) {
|
|
|
220
219
|
* over `<PREFIX>_LIMITS`, `declaredScalars`, `declaredSets`, `declaredLists`), then `extra` — the
|
|
221
220
|
* names that are not in the core barrel (`OMX_CLAP_HOST_EXTENSIONS`) or a test's override of one
|
|
222
221
|
* door. The generator and every render test build the sheet here, so a new door is added once,
|
|
223
|
-
* never appended to a hand list per caller
|
|
222
|
+
* never appended to a hand list per caller.
|
|
224
223
|
*/
|
|
225
224
|
export function contractLimitsSheet(coreNs, declarations, extra = {}) {
|
|
226
225
|
return {
|
package/render/doors.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
// Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
|
|
3
3
|
/**
|
|
4
|
-
* The resolved data cut into the C renderer's doors, as
|
|
5
|
-
* (
|
|
4
|
+
* The resolved data cut into the C renderer's doors, as the engine's discovery cut its barrels
|
|
5
|
+
* (its native limit tables, declared scalars and declared lists): a `travels`
|
|
6
6
|
* table named <PREFIX>_LIMITS is a native table; every scalar, sheet and single travel is scalars
|
|
7
7
|
* (its finite-number leaves, a travel's `unit`/`defaultFrom` labels skipped); a list is a declared
|
|
8
8
|
* list unless its item says `"c": { "render": false }`; a set is an enum; a `c.alias` is the core-limit spelling.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmixer/omx-contract",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"items": {
|
|
5
5
|
"PAN_RANGE": {
|
|
6
6
|
"rel": "data/kernels/balance.json",
|
|
@@ -302,7 +302,7 @@
|
|
|
302
302
|
"DETECTOR_TOPOLOGY": {
|
|
303
303
|
"rel": "data/kernels/comp.json",
|
|
304
304
|
"kind": "set",
|
|
305
|
-
"doc": "Where the compressor's detector listens: `feedforward` hears the slot's input (or its key), `feedback` hears the slot's own pre-make-up output DYN_FB_LOOP_DELAY_SAMPLES late, through one envelope stage, and a keyed slot stays feed-forward (omx-dsp's OMX_DYN_TOPOLOGY_FEEDFORWARD 0 and _FEEDBACK 1, in that order; the set is named for its control, so C spells them OMX_DETECTOR_TOPOLOGY_*). The console's comp row carries it (`detectorTopology`,
|
|
305
|
+
"doc": "Where the compressor's detector listens: `feedforward` hears the slot's input (or its key), `feedback` hears the slot's own pre-make-up output DYN_FB_LOOP_DELAY_SAMPLES late, through one envelope stage, and a keyed slot stays feed-forward (omx-dsp's OMX_DYN_TOPOLOGY_FEEDFORWARD 0 and _FEEDBACK 1, in that order; the set is named for its control, so C spells them OMX_DETECTOR_TOPOLOGY_*). The console's comp row carries it (`detectorTopology`, the SSL bus compressor design §3a) and comes up `feedforward`, so a zeroed atom is the compressor every slot runs.",
|
|
306
306
|
"default": "feedforward",
|
|
307
307
|
"value": [
|
|
308
308
|
"feedforward",
|
|
@@ -312,7 +312,7 @@
|
|
|
312
312
|
"PROGRAM_RELEASE": {
|
|
313
313
|
"rel": "data/kernels/comp.json",
|
|
314
314
|
"kind": "sheet",
|
|
315
|
-
"doc": "The program-dependent release's model constants — the LA-2A's opto cell as DATA (
|
|
315
|
+
"doc": "The program-dependent release's model constants — the LA-2A's opto cell as DATA (compressor models design §3b). `chargeMs`/`dischargeMs` are the word's memory constants, shared by every profile; each profile's `fastMs`, `slowMinMs`, `slowMaxMs` and `share` fit the unit's published two-stage recovery. Not operator controls: generated into `omx_contract_limits.h` as `OMX_PROGRAM_RELEASE_*`, which libomxdsp's `omx_env_program_release` reads.",
|
|
316
316
|
"value": {
|
|
317
317
|
"chargeMs": 1000,
|
|
318
318
|
"dischargeMs": 5000,
|
|
@@ -443,14 +443,14 @@
|
|
|
443
443
|
"DEESS_KNEE_DB": {
|
|
444
444
|
"rel": "data/kernels/deesser.json",
|
|
445
445
|
"kind": "scalar",
|
|
446
|
-
"doc": "The knee, in dB — a CONSTANT of the stage and not a row field
|
|
446
|
+
"doc": "The knee, in dB — a CONSTANT of the stage and not a row field: a de-esser without a soft knee latches audibly on the first sibilant of a phrase, and no other value of this number is a de-esser anyone would dial. The controller pushes it to the node and this is the same number; a second spelling would be a picture that disagrees with the audio about where the reduction starts.",
|
|
447
447
|
"unit": "dB",
|
|
448
448
|
"value": 6
|
|
449
449
|
},
|
|
450
450
|
"FX_DELAY_TIME_RANGE": {
|
|
451
451
|
"rel": "data/kernels/delay.json",
|
|
452
452
|
"kind": "travels",
|
|
453
|
-
"doc": "The FX delay's time travel. `max` is the NATIVE ring's ceiling — the same number as `OMX_FXDELAY_MAX_MS` in `omx_delay.h`, pinned to it by
|
|
453
|
+
"doc": "The FX delay's time travel. `max` is the NATIVE ring's ceiling — the same number as `OMX_FXDELAY_MAX_MS` in `omx_delay.h`, pinned to it by the engine's conformance test. Distinct from the per-route ALIGNMENT delay (`OUTPUT_DELAY_RANGE`, 1 s, `OMX_DELAY_MAX_MS`): one is a musical echo with feedback and mix, the other is a pure latency. Two facts, two rings, two ceilings — sharing the word \"delay\" is why they keep being confused for each other.",
|
|
454
454
|
"c": {
|
|
455
455
|
"alias": {
|
|
456
456
|
"fact": "delay",
|
|
@@ -484,7 +484,7 @@
|
|
|
484
484
|
"DELAY_TONE_RANGE": {
|
|
485
485
|
"rel": "data/kernels/delay.json",
|
|
486
486
|
"kind": "travels",
|
|
487
|
-
"doc": "The FX delay's TONE — a NORMALIZED_RANGE instance with its own come-up value, matching
|
|
487
|
+
"doc": "The FX delay's TONE — a NORMALIZED_RANGE instance with its own come-up value, matching the console's delay default tone. See REVERB_SIZE_RANGE for why this is a named constant rather than a default on the shared shape.",
|
|
488
488
|
"shape": "travel",
|
|
489
489
|
"value": {
|
|
490
490
|
"min": 0,
|
|
@@ -529,7 +529,7 @@
|
|
|
529
529
|
"FX_DELAY_PINGPONG_DEFAULT": {
|
|
530
530
|
"rel": "data/kernels/delay.json",
|
|
531
531
|
"kind": "scalar",
|
|
532
|
-
"doc": "The FX delay's PING-PONG come-up value — a toggle, so it has no travel, only this. Declared here rather than as a literal in the
|
|
532
|
+
"doc": "The FX delay's PING-PONG come-up value — a toggle, so it has no travel, only this. Declared here rather than as a literal in the console's delay default state (which now reads it) so the DPF plugin generator (omx-plugins, DPF plugin design §3a) reads the same fact the desk seeds a fresh strip with.",
|
|
533
533
|
"unit": "",
|
|
534
534
|
"value": false
|
|
535
535
|
},
|
|
@@ -699,6 +699,22 @@
|
|
|
699
699
|
16000
|
|
700
700
|
]
|
|
701
701
|
},
|
|
702
|
+
"DRIVE_OVERSAMPLES": {
|
|
703
|
+
"rel": "data/kernels/drive.json",
|
|
704
|
+
"kind": "set",
|
|
705
|
+
"doc": "The drive's OVERSAMPLING factor: the shaper runs inside the console's one oversampler at 1x, 2x or 4x, and the id is the factor (`omx_drive.h`'s `omx_drive_factor_of` member set, `struct omx_drive.os_factor`). A field of the console's drive row (`DriveState.oversample`, the console's DRIVE_OVERSAMPLE_FACTORS; the set is named for its control), 4 at come-up there and in omx-dsp's drive face (OMX_DRIVE_INSTANCE_FACTOR, the oversampler's largest).",
|
|
706
|
+
"default": 4,
|
|
707
|
+
"labels": [
|
|
708
|
+
"1x",
|
|
709
|
+
"2x",
|
|
710
|
+
"4x"
|
|
711
|
+
],
|
|
712
|
+
"value": [
|
|
713
|
+
1,
|
|
714
|
+
2,
|
|
715
|
+
4
|
|
716
|
+
]
|
|
717
|
+
},
|
|
702
718
|
"DRIVE_BIAS_MAX": {
|
|
703
719
|
"rel": "data/kernels/drive.json",
|
|
704
720
|
"kind": "scalar",
|
|
@@ -805,7 +821,7 @@
|
|
|
805
821
|
"EQ_GAIN_RANGE": {
|
|
806
822
|
"rel": "data/kernels/eq.json",
|
|
807
823
|
"kind": "travels",
|
|
808
|
-
"doc": "The parametric-band gain travel, in dB. The ± scalar `clampEqGain` enforces is READ off this (
|
|
824
|
+
"doc": "The parametric-band gain travel, in dB. The ± scalar `clampEqGain` enforces is READ off this (the engine derives its gain limit from `max`), so the bound is stated once and a surface cannot draw a wider knob than the clamp will honour.",
|
|
809
825
|
"shape": "travel",
|
|
810
826
|
"value": {
|
|
811
827
|
"min": -15,
|
|
@@ -854,7 +870,7 @@
|
|
|
854
870
|
"EQ_MAX_BANDS": {
|
|
855
871
|
"rel": "data/kernels/eq.json",
|
|
856
872
|
"kind": "scalar",
|
|
857
|
-
"doc": "The maximum number of parametric bands a channel EQ may hold — the operator can add up to this many. Generated into `omx_contract_limits.h` as `OMX_EQ_MAX_BANDS`, which `omx_biquad.h` reads (
|
|
873
|
+
"doc": "The maximum number of parametric bands a channel EQ may hold — the operator can add up to this many. Generated into `omx_contract_limits.h` as `OMX_EQ_MAX_BANDS`, which `omx_biquad.h` reads (the engine's conformance test reads the header): the native lane allocates exactly this many biquad slots per channel and silently clamps above it, so the model, the wire, and the DSP agree by test, not by memory.",
|
|
858
874
|
"unit": "",
|
|
859
875
|
"value": 24
|
|
860
876
|
},
|
|
@@ -1170,7 +1186,7 @@
|
|
|
1170
1186
|
"FBS_MAX_NOTCH_DEPTH_DB": {
|
|
1171
1187
|
"rel": "data/kernels/fbs.json",
|
|
1172
1188
|
"kind": "scalar",
|
|
1173
|
-
"doc": "THE NOTCH DEPTH LAW: the deepest cut any machine planter may propose from one reading, in dB. A number, not a literal at the call site, because two planters now lean on it. FBS derives a candidate's depth from the peak-to-average ratio around its bin and stops here; Room Analysis derives a mode's depth from its height above the median curve and is held to the SAME ceiling (
|
|
1189
|
+
"doc": "THE NOTCH DEPTH LAW: the deepest cut any machine planter may propose from one reading, in dB. A number, not a literal at the call site, because two planters now lean on it. FBS derives a candidate's depth from the peak-to-average ratio around its bin and stops here; Room Analysis derives a mode's depth from its height above the median curve and is held to the SAME ceiling (the room-analysis design §4 — \"never more than the FBS notch depth law\"). Written twice as `18` those two bounds would be equal by coincidence and could drift apart in silence. It is a CEILING ON THE PROPOSAL, not the final gain: a band that lands as a rampable BELL is bounded again by `EQ_GAIN_RANGE`, which is tighter. A planter must honour both and REPORT when either bit, never quietly deliver a shallower cut than it was asked for.",
|
|
1174
1190
|
"unit": "dB",
|
|
1175
1191
|
"value": 18
|
|
1176
1192
|
},
|
|
@@ -1447,7 +1463,7 @@
|
|
|
1447
1463
|
"HRP_MAX_VOICES": {
|
|
1448
1464
|
"rel": "data/kernels/hrp.json",
|
|
1449
1465
|
"kind": "scalar",
|
|
1450
|
-
"doc": "How many simultaneous musical voices the detector may report on one channel. PINNED to `OMX_HRP_MAX_VOICES` in `pipewire-native/src/hrp_pitch.h` — the C voice set is a FIXED-SIZE array, so a TS number above the macro promises voices the analyser structurally cannot return, and one below it silently drops notes the C already found.
|
|
1466
|
+
"doc": "How many simultaneous musical voices the detector may report on one channel. PINNED to `OMX_HRP_MAX_VOICES` in `pipewire-native/src/hrp_pitch.h` — the C voice set is a FIXED-SIZE array, so a TS number above the macro promises voices the analyser structurally cannot return, and one below it silently drops notes the C already found. the engine's conformance test reads the header and holds the pair equal. EIGHT (operator sizing, 2026-09-01): a guitar sounds six strings, a piano or string-section voicing sits at eight. It is a SEARCH ceiling, not a cost — the detector abandons a round as soon as no credible candidate remains, so monophonic material costs what it always did.",
|
|
1451
1467
|
"unit": "",
|
|
1452
1468
|
"value": 8
|
|
1453
1469
|
},
|
|
@@ -1489,14 +1505,14 @@
|
|
|
1489
1505
|
"HRP_DEFAULT_MAX_AUTO_BANDS": {
|
|
1490
1506
|
"rel": "data/kernels/hrp.json",
|
|
1491
1507
|
"kind": "scalar",
|
|
1492
|
-
"doc": "How many bands HRP may plant on ONE channel — its half of the machine budget, and the number that makes the budget FORECASTABLE rather than emergent. Without it the count is whatever the material happens to provoke: the placement law is sparse, so a clean note plants two bands and a resonant room plants nine, and nobody can answer \"will this fit?\" until it does not. With FBS senior (§9.3(b)) that discovery would happen at showtime, to the junior planter, silently. Declared instead, the whole sum is arithmetic an operator can read before a note is played: operator bands + FBS maxAutoBands + HRP maxAutoBands <= EQ_MAX_BANDS EIGHT — ONE CORRECTION PER VOICE at full polyphony (operator sizing, 2026-09-01). The detector's ceiling is HRP_MAX_VOICES voices, a guitar's six strings and a piano/string voicing's eight, and a budget below the voice count would decide by arithmetic which of the notes actually sounding may be corrected — a limit nobody could read off the desk. Scarcity is handled where it belongs instead: the candidates from every voice meet in ONE globally ranked list (spec §29) and the head of it is what gets planted. It is NOT a claim to seniority, and it is larger than FBS's six. Seniority is the ALLOCATION ORDER — `HrpPlanter` takes only `EQ_MAX_BANDS − others.length`, the remainder after the operator and every other machine — so a bigger junior default cannot reach a senior slot; it only means HRP asks for more of what is left.
|
|
1508
|
+
"doc": "How many bands HRP may plant on ONE channel — its half of the machine budget, and the number that makes the budget FORECASTABLE rather than emergent. Without it the count is whatever the material happens to provoke: the placement law is sparse, so a clean note plants two bands and a resonant room plants nine, and nobody can answer \"will this fit?\" until it does not. With FBS senior (§9.3(b)) that discovery would happen at showtime, to the junior planter, silently. Declared instead, the whole sum is arithmetic an operator can read before a note is played: operator bands + FBS maxAutoBands + HRP maxAutoBands <= EQ_MAX_BANDS EIGHT — ONE CORRECTION PER VOICE at full polyphony (operator sizing, 2026-09-01). The detector's ceiling is HRP_MAX_VOICES voices, a guitar's six strings and a piano/string voicing's eight, and a budget below the voice count would decide by arithmetic which of the notes actually sounding may be corrected — a limit nobody could read off the desk. Scarcity is handled where it belongs instead: the candidates from every voice meet in ONE globally ranked list (spec §29) and the head of it is what gets planted. It is NOT a claim to seniority, and it is larger than FBS's six. Seniority is the ALLOCATION ORDER — `HrpPlanter` takes only `EQ_MAX_BANDS − others.length`, the remainder after the operator and every other machine — so a bigger junior default cannot reach a senior slot; it only means HRP asks for more of what is left. the engine's conformance test asserts both halves. The per-channel DEFAULT; the row's travel is HRP_AUTO_BANDS_RANGE, so a channel that needs more can have more, as an explicit decision with a visible cost.",
|
|
1493
1509
|
"unit": "",
|
|
1494
1510
|
"value": 8
|
|
1495
1511
|
},
|
|
1496
1512
|
"LIMITER_LIMITS": {
|
|
1497
1513
|
"rel": "data/kernels/limiter.json",
|
|
1498
1514
|
"kind": "travels",
|
|
1499
|
-
"doc": "The precision limiter's travels
|
|
1515
|
+
"doc": "The precision limiter's travels, rendered into `omx_contract_limits.h` as `OMX_LIMITER_*` by the engine's limits generator, so `mix_limiter.h` reads them and never restates one (R-094). The ceiling is a TRUE peak in dBFS (the ×4 detector); the look-ahead sets the declared latency; the release is the envelope's time constant on the gain depth.",
|
|
1500
1516
|
"shape": "table",
|
|
1501
1517
|
"value": {
|
|
1502
1518
|
"ceilingDb": {
|
|
@@ -1528,7 +1544,7 @@
|
|
|
1528
1544
|
"BUS_INPUT_CAP": {
|
|
1529
1545
|
"rel": "data/kernels/mixmatrix.json",
|
|
1530
1546
|
"kind": "scalar",
|
|
1531
|
-
"doc": "The input cap a summing bus can be sized to — **the engine's declared input ceiling**, read from `@freemixer/declarations` rather than re-typed here. A gig with more than this many inputs needs more than one engine node; below it a bus is sized to `min(N, BUS_INPUT_CAP)`. It was a literal 64 until 2026-09-15, said to mirror the engine's `MAX_BUS_INPUTS` — and it did, but that 64 was the PipeWire builtin mixer's single-tier fan-in (8 × 8), never the engine's bound: the native node has allocated `OMX_MAX_STRIPS` (128) strips all along. Two literals agreeing by hand is how the console came to refuse a 96-channel desk it could carry.
|
|
1547
|
+
"doc": "The input cap a summing bus can be sized to — **the engine's declared input ceiling**, read from `@freemixer/declarations` rather than re-typed here. A gig with more than this many inputs needs more than one engine node; below it a bus is sized to `min(N, BUS_INPUT_CAP)`. It was a literal 64 until 2026-09-15, said to mirror the engine's `MAX_BUS_INPUTS` — and it did, but that 64 was the PipeWire builtin mixer's single-tier fan-in (8 × 8), never the engine's bound: the native node has allocated `OMX_MAX_STRIPS` (128) strips all along. Two literals agreeing by hand is how the console came to refuse a 96-channel desk it could carry. the engine's conformance test holds this to the C header; the console allocation design §9 carries the ruling and the measured cost of width.",
|
|
1532
1548
|
"unit": "",
|
|
1533
1549
|
"value": 128
|
|
1534
1550
|
},
|
|
@@ -1721,7 +1737,7 @@
|
|
|
1721
1737
|
"REVERB_PLATE_MOD_DEPTH_RANGE": {
|
|
1722
1738
|
"rel": "data/kernels/reverb.json",
|
|
1723
1739
|
"kind": "travels",
|
|
1724
|
-
"doc": "PLATE's tank MODULATION DEPTH, in percent of Dattorro's own excursion (±8 samples at his 29 761 Hz tuning rate, scaled to the live rate the way the tank lengths are). 100 is the depth the plate has always run at, so the come-up is bit-identical to the plate before the field; 0 brings back the unmodulated tank's ring; 400 is the wide, chorused EMT-style swing. The rate stays 1 Hz. Only PLATE reads it
|
|
1740
|
+
"doc": "PLATE's tank MODULATION DEPTH, in percent of Dattorro's own excursion (±8 samples at his 29 761 Hz tuning rate, scaled to the live rate the way the tank lengths are). 100 is the depth the plate has always run at, so the come-up is bit-identical to the plate before the field; 0 brings back the unmodulated tank's ring; 400 is the wide, chorused EMT-style swing. The rate stays 1 Hz. Only PLATE reads it.",
|
|
1725
1741
|
"shape": "travel",
|
|
1726
1742
|
"value": {
|
|
1727
1743
|
"min": 0,
|
|
@@ -1836,7 +1852,7 @@
|
|
|
1836
1852
|
"REVERB_REVERSE_RANGE": {
|
|
1837
1853
|
"rel": "data/kernels/reverb.json",
|
|
1838
1854
|
"kind": "travels",
|
|
1839
|
-
"doc": "REVERSE's MIRROR WINDOW — how long a slice of the wet is played backward, in milliseconds
|
|
1855
|
+
"doc": "REVERSE's MIRROR WINDOW — how long a slice of the wet is played backward, in milliseconds. A DECLARED travel and never derived from `size`'s RT60: an RT60 of seconds cannot be buffered at 192 kHz, and a window silently clamped to fit is the silent-clamp defect. The ceiling is what `mix_reverb.h`'s pool budgets a ring for (`OMX_REVERB_REVERSE_MAX_MS`), so the console offers exactly the travel the kernel accepts — nothing wider, nothing narrower.",
|
|
1840
1856
|
"shape": "travel",
|
|
1841
1857
|
"value": {
|
|
1842
1858
|
"min": 50,
|
|
@@ -2167,7 +2183,7 @@
|
|
|
2167
2183
|
"RTA_TARGET_BIN_HZ": {
|
|
2168
2184
|
"rel": "data/kernels/rta.json",
|
|
2169
2185
|
"kind": "scalar",
|
|
2170
|
-
"doc": "The RTA's target bin resolution — generated into `omx_contract_limits.h` as `OMX_RTA_TARGET_BIN_HZ`, which `mix_dsp.h` reads;
|
|
2186
|
+
"doc": "The RTA's target bin resolution — generated into `omx_contract_limits.h` as `OMX_RTA_TARGET_BIN_HZ`, which `mix_dsp.h` reads; the engine's conformance test reads it back from the header.",
|
|
2171
2187
|
"unit": "Hz",
|
|
2172
2188
|
"value": 5.9
|
|
2173
2189
|
},
|
|
@@ -2209,7 +2225,7 @@
|
|
|
2209
2225
|
"TRANSIENT_LIMITS": {
|
|
2210
2226
|
"rel": "data/kernels/transient.json",
|
|
2211
2227
|
"kind": "travels",
|
|
2212
|
-
"doc": "The legal range of each transient-designer field (engineering units), transient spec §3. Every kind comes up flat: no per-kind default differs.
|
|
2228
|
+
"doc": "The legal range of each transient-designer field (engineering units), transient spec §3. Every kind comes up flat: no per-kind default differs. the engine's limits generator 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).",
|
|
2213
2229
|
"shape": "table",
|
|
2214
2230
|
"value": {
|
|
2215
2231
|
"attackDb": {
|
|
@@ -2369,7 +2385,7 @@
|
|
|
2369
2385
|
"TRIM_RANGE": {
|
|
2370
2386
|
"rel": "data/kernels/trim.json",
|
|
2371
2387
|
"kind": "travels",
|
|
2372
|
-
"doc": "The digital input trim, in dB: the console's fine head gain, applied first in a channel's lane as a click-free ramp from the last block's gain to this one (
|
|
2388
|
+
"doc": "The digital input trim, in dB: the console's fine head gain, applied first in a channel's lane as a click-free ramp from the last block's gain to this one (the console's trim range, -24..+24 dB in 0.1 dB steps, spelled minDb/maxDb/stepDb there). It comes up at 0 dB, the trim a channel has when none is set. omx-dsp's trim face takes it as `trim_db`.",
|
|
2373
2389
|
"shape": "travel",
|
|
2374
2390
|
"value": {
|
|
2375
2391
|
"min": -24,
|
|
@@ -2549,7 +2565,7 @@
|
|
|
2549
2565
|
"STANDARD_SAMPLE_RATES": {
|
|
2550
2566
|
"rel": "data/rates.json",
|
|
2551
2567
|
"kind": "list",
|
|
2552
|
-
"doc": "The standard sample rates (Hz) the desk recognises — the pro-audio superset. One source of truth for the clock controller's `clock.allowed-rates` seed, the force row's validation ceiling and the device-rate probe fallback. What the operator is OFFERED is always the DEVICE's own `supportedRates`
|
|
2568
|
+
"doc": "The standard sample rates (Hz) the desk recognises — the pro-audio superset. One source of truth for the clock controller's `clock.allowed-rates` seed, the force row's validation ceiling and the device-rate probe fallback. What the operator is OFFERED is always the DEVICE's own `supportedRates` — this is the ceiling a write is refused by, never a menu.",
|
|
2553
2569
|
"unit": "Hz",
|
|
2554
2570
|
"value": [
|
|
2555
2571
|
44100,
|
|
@@ -2886,6 +2902,11 @@
|
|
|
2886
2902
|
"name": "hfRolloff",
|
|
2887
2903
|
"kind": "choice",
|
|
2888
2904
|
"global": "DRIVE_HF_ROLLOFFS"
|
|
2905
|
+
},
|
|
2906
|
+
{
|
|
2907
|
+
"name": "oversample",
|
|
2908
|
+
"kind": "choice",
|
|
2909
|
+
"global": "DRIVE_OVERSAMPLES"
|
|
2889
2910
|
}
|
|
2890
2911
|
]
|
|
2891
2912
|
},
|