@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
@@ -13,6 +13,95 @@ export declare const PAN_RANGE: {
13
13
  readonly unit: "";
14
14
  };
15
15
 
16
+ /**
17
+ * The side of the threshold the band acts on. Above acts when the band is loud, taming a resonance that only rings when pushed; below acts when it is quiet, lifting a band that drops out. The order is the integer the kernel reads: above is 0, below is 1.
18
+ * @see data/kernels/band_dyn.json
19
+ */
20
+ export declare const BAND_DYN_MODES: readonly ["above", "below"];
21
+
22
+ /**
23
+ * Where the band starts to act, in dB of the band's own level and not the strip's. It is the same fact the de-esser's threshold is, so it carries the same travel.
24
+ * @see data/kernels/band_dyn.json
25
+ */
26
+ export declare const BAND_DYN_THRESHOLD_RANGE: {
27
+ readonly min: -60;
28
+ readonly max: 0;
29
+ readonly step: 0.5;
30
+ readonly unit: "dB";
31
+ readonly default: -30;
32
+ readonly defaultFrom: "desk";
33
+ };
34
+
35
+ /**
36
+ * How hard the band is held once it is past its threshold. 2:1 rather than the de-esser's 4:1, because a dynamic band is corrective, not a limiter for a sibilant.
37
+ * @see data/kernels/band_dyn.json
38
+ */
39
+ export declare const BAND_DYN_RATIO_RANGE: {
40
+ readonly min: 1;
41
+ readonly max: 20;
42
+ readonly step: 0.1;
43
+ readonly unit: "";
44
+ readonly default: 2;
45
+ readonly defaultFrom: "desk";
46
+ };
47
+
48
+ /**
49
+ * The most the band may add to its static gain, signed: below zero the deepest cut, above zero the largest boost. The ceiling of +12 keeps static plus dynamic inside the EQ's own travel. Zero makes the band inert without switching it off.
50
+ * @see data/kernels/band_dyn.json
51
+ */
52
+ export declare const BAND_DYN_RANGE_RANGE: {
53
+ readonly min: -24;
54
+ readonly max: 12;
55
+ readonly step: 0.5;
56
+ readonly unit: "dB";
57
+ readonly default: -6;
58
+ readonly defaultFrom: "desk";
59
+ };
60
+
61
+ /**
62
+ * The detector's attack, in ms. The travel stops at the oversampling floor, below which the band would need the compressor's delayed control path.
63
+ * @see data/kernels/band_dyn.json
64
+ */
65
+ export declare const BAND_DYN_ATTACK_RANGE: {
66
+ readonly min: 0.5;
67
+ readonly max: 100;
68
+ readonly step: 0.1;
69
+ readonly unit: "ms";
70
+ readonly default: 5;
71
+ readonly defaultFrom: "desk";
72
+ };
73
+
74
+ /**
75
+ * The detector's release, in ms. 100 ms is long enough not to modulate a 40 Hz band inside four cycles.
76
+ * @see data/kernels/band_dyn.json
77
+ */
78
+ export declare const BAND_DYN_RELEASE_RANGE: {
79
+ readonly min: 5;
80
+ readonly max: 3000;
81
+ readonly step: 1;
82
+ readonly unit: "ms";
83
+ readonly default: 100;
84
+ readonly defaultFrom: "desk";
85
+ };
86
+
87
+ /**
88
+ * The soft knee of the band's gain computer, in dB. One knee for the one band-dynamics word, shared by every stage that runs it, the de-esser included: a second spelling of 6 would be a second place where the reduction starts.
89
+ * @see data/kernels/band_dyn.json
90
+ */
91
+ export declare const BAND_DYN_KNEE_DB: 6;
92
+
93
+ /**
94
+ * How many dynamic bands a channel may hold. A dynamic band is an operator band, so the capacity is the operator's reserve, read and not typed again.
95
+ * @see data/kernels/band_dyn.json
96
+ */
97
+ export declare const BAND_DYN_MAX_BANDS: 9;
98
+
99
+ /**
100
+ * The shortest attack, in ms, at which the compressor's detector does not alias. Below it the compressor engages its 4x control path, which adds 72 samples of latency; a zero-latency band has no such path, so its attack travel stops at this floor.
101
+ * @see data/kernels/band_dyn.json
102
+ */
103
+ export declare const DETECTOR_OVERSAMPLE_AUTO_MS: 0.5;
104
+
16
105
  /**
17
106
  * The chorus's right-leg phase offset, in TURNS of its one oscillator (§2, §3a; the native-FX catalogue's M32 Dimension row). The right leg's voice k reads the LFO at k/N + spread: 0 is both legs one phase (the stage without the field, bit for bit), 0.25 quadrature, 0.5 the Dimension's opposed sweep. A fraction of a cycle carries no engineering symbol, so the unit is ''.
18
107
  * @see data/kernels/chorus.json
@@ -78,6 +167,18 @@ export declare const CHORUS_MIX_RANGE: {
78
167
  readonly defaultFrom: "desk";
79
168
  };
80
169
 
170
+ /**
171
+ * The chorus's base delay, ms: the voices swing around it by up to the depth.
172
+ * @see data/kernels/chorus.json
173
+ */
174
+ export declare const CHORUS_BASE_MS: 10;
175
+
176
+ /**
177
+ * The longest delay a chorus voice reaches, rounded up to whole ms: the base delay plus the depth maximum. The delay line is sized from it.
178
+ * @see data/kernels/chorus.json
179
+ */
180
+ export declare const CHORUS_MAX_MS: 22;
181
+
81
182
  /**
82
183
  * The legal range of each compressor field (engineering units). The widget clamps drags to these, `normalizeComp` enforces them, the row's codec refuses by them and the travel sheet publishes them. `default`/`defaultFrom` are the come-up values `defaultCompState` seeds a fresh strip with, read BACK from here rather than restated there.
83
184
  * @see data/kernels/comp.json
@@ -249,6 +350,12 @@ export declare const DEESS_RELEASE_RANGE: {
249
350
  readonly defaultFrom: "desk";
250
351
  };
251
352
 
353
+ /**
354
+ * The de-esser's modes, in the order of the integer the kernel reads: split attenuates the detected band only, wideband the whole signal while the sibilance lasts.
355
+ * @see data/kernels/deesser.json
356
+ */
357
+ export declare const DEESS_MODES: readonly ["split", "wideband"];
358
+
252
359
  /**
253
360
  * The knee, in dB — a CONSTANT of the stage and not a row field (`2026-09-22-native-deesser-stage.md` §4b): 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.
254
361
  * @see data/kernels/deesser.json
@@ -316,12 +423,6 @@ export declare const DELAY_MIX_RANGE: {
316
423
  */
317
424
  export declare const FX_DELAY_PINGPONG_DEFAULT: false;
318
425
 
319
- /**
320
- * 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.
321
- * @see data/kernels/drive.json
322
- */
323
- export declare const DRIVE_BIAS_MAX: 0.7071067811865476;
324
-
325
426
  /**
326
427
  * The PRE-CURVE gain, in dB. 0 dB is unity into the curve, so a stage switched on at its defaults changes almost nothing — which is what an `on` switch should mean. The ceiling is where every curve is saturating hard on any signal a console carries.
327
428
  * @see data/kernels/drive.json
@@ -388,22 +489,22 @@ export declare const DRIVE_TRIM_RANGE: {
388
489
  };
389
490
 
390
491
  /**
391
- * 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 (`output-delay-ceiling.test.ts` 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.
392
- * @see data/kernels/eq.json
492
+ * The drive's shaper curves, in the order of the integer the kernel reads. Exciter runs the soft shape in a parallel-sum topology.
493
+ * @see data/kernels/drive.json
393
494
  */
394
- export declare const EQ_MAX_BANDS: 24;
495
+ export declare const DRIVE_CURVES: readonly ["soft", "tape", "tube", "exciter"];
395
496
 
396
497
  /**
397
- * The standard ISO 266 one-third-octave centre frequencies, 20 Hz–20 kHz (31 bands) — the classic 31-band graphic-EQ layout's centres.
398
- * @see data/kernels/eq.json
498
+ * Which part of the spectrum the drive's curve is fed, in the order of the integer the kernel reads. The split is complementary, so mix 0 stays bit-identical to the dry signal.
499
+ * @see data/kernels/drive.json
399
500
  */
400
- export declare const ISO_THIRD_OCTAVE_CENTRES_HZ: readonly [20, 25, 31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000, 6300, 8000, 10000, 12500, 16000, 20000];
501
+ export declare const DRIVE_BANDS: readonly ["full", "low", "high", "tilt"];
401
502
 
402
503
  /**
403
- * The graphic EQ's section count: DERIVED from ISO_THIRD_OCTAVE_CENTRES_HZ, never a second literal. Generated into `omx_contract_limits.h` as `OMX_GEQ_BANDS`, which sizes `mix_geq.h`'s section array — its OWN budget, never a claimant on EQ_MAX_BANDS (graphic-eq-31 spec §3, roster ruling 3).
404
- * @see data/kernels/eq.json
504
+ * 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.
505
+ * @see data/kernels/drive.json
405
506
  */
406
- export declare const GEQ_BANDS: 31;
507
+ export declare const DRIVE_BIAS_MAX: 0.7071067811865476;
407
508
 
408
509
  /**
409
510
  * The frequency band a parametric band can be dragged across.
@@ -471,6 +572,231 @@ export declare const LPF_FREQ_RANGE: {
471
572
  readonly unit: "Hz";
472
573
  };
473
574
 
575
+ /**
576
+ * The generic EQ band shapes, in the order a picker offers them and in the order of the integer a plugin host sees on a band type port. The id is the name; the position is the value. A bell is the shape a band added by the operator starts as.
577
+ * @see data/kernels/eq.json
578
+ */
579
+ export declare const EQ_BAND_TYPES: readonly ["bell", "lowShelf", "highShelf", "notch", "allpass1", "allpass2"];
580
+
581
+ /**
582
+ * The pass-filter slopes the EQ offers, in dB per octave. The id is the slope: 12 is one maximally flat section, 24 the two-section Butterworth.
583
+ * @see data/kernels/eq.json
584
+ */
585
+ export declare const FILTER_SLOPES: readonly [12, 24];
586
+
587
+ /**
588
+ * 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 (`output-delay-ceiling.test.ts` 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.
589
+ * @see data/kernels/eq.json
590
+ */
591
+ export declare const EQ_MAX_BANDS: 24;
592
+
593
+ /**
594
+ * The standard ISO 266 one-third-octave centre frequencies, 20 Hz–20 kHz (31 bands) — the classic 31-band graphic-EQ layout's centres.
595
+ * @see data/kernels/eq.json
596
+ */
597
+ export declare const ISO_THIRD_OCTAVE_CENTRES_HZ: readonly [20, 25, 31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000, 6300, 8000, 10000, 12500, 16000, 20000];
598
+
599
+ /**
600
+ * The graphic EQ's section count: DERIVED from ISO_THIRD_OCTAVE_CENTRES_HZ, never a second literal. Generated into `omx_contract_limits.h` as `OMX_GEQ_BANDS`, which sizes `mix_geq.h`'s section array — its OWN budget, never a claimant on EQ_MAX_BANDS (graphic-eq-31 spec §3, roster ruling 3).
601
+ * @see data/kernels/eq.json
602
+ */
603
+ export declare const GEQ_BANDS: 31;
604
+
605
+ /**
606
+ * The band slots kept for the operator's own hand: the reserve the feedback suppressor and the ring correction may never eat into. Nine is the working set a live EQ actually holds. The budget OPERATOR_EQ_BANDS_RESERVE + FBS_DEFAULT_MAX_AUTO_BANDS + HRP_DEFAULT_MAX_AUTO_BANDS (9 + 6 + 8 = 23) must fit EQ_MAX_BANDS, and `omx-contract validate` refuses data where it does not.
607
+ * @see data/kernels/eq.json
608
+ */
609
+ export declare const OPERATOR_EQ_BANDS_RESERVE: 9;
610
+
611
+ /**
612
+ * How many bands each strip type's EQ starts with (`default`) and may hold (`max`). `channel` is the console's channel strip: it starts with four and the operator adds bands up to EQ_MAX_BANDS (a band added takes the frequency it is added at, so no default is declared for it). `strip` is the omx-strip plugin's EQ and `eq8`, `eq16` and `eq32` the omx-eq plugins, whose bands are fixed. A default may never exceed its maximum, and the default centres of any count come from the one default rule, whatever the strip.
613
+ * @see data/kernels/eq.json
614
+ */
615
+ export declare const EQ_BAND_COUNTS: {
616
+ readonly channel: {
617
+ readonly default: 4;
618
+ readonly max: 24;
619
+ };
620
+ readonly strip: {
621
+ readonly default: 4;
622
+ readonly max: 4;
623
+ };
624
+ readonly eq8: {
625
+ readonly default: 8;
626
+ readonly max: 8;
627
+ };
628
+ readonly eq16: {
629
+ readonly default: 16;
630
+ readonly max: 16;
631
+ };
632
+ readonly eq32: {
633
+ readonly default: 32;
634
+ readonly max: 32;
635
+ };
636
+ };
637
+
638
+ /**
639
+ * What every band of a fresh EQ comes up at, whatever its type and its strip: flat (0 dB) and Q 1. The band frequencies and types come from the default rule.
640
+ * @see data/kernels/eq.json
641
+ */
642
+ export declare const EQ_BAND_DEFAULTS: {
643
+ readonly gainDb: 0;
644
+ readonly q: 1;
645
+ };
646
+
647
+ /**
648
+ * The corners the high-pass and low-pass filters of a fresh EQ are parked at, whatever the strip. Both come up off.
649
+ * @see data/kernels/eq.json
650
+ */
651
+ export declare const EQ_PASS_FILTER_DEFAULTS: {
652
+ readonly hpfFreqHz: 80;
653
+ readonly lpfFreqHz: 18000;
654
+ };
655
+
656
+ /**
657
+ * The default band centres of a four-band EQ, Hz: ISO 266 preferred values, two to two and a half octaves apart. The default rule gives every other band count its centres from the preferred series; four bands start here.
658
+ * @see data/kernels/eq.json
659
+ */
660
+ export declare const EQ_DEFAULT_CENTRES_FOUR_BAND_HZ: readonly [100, 400, 2000, 8000];
661
+
662
+ /**
663
+ * The ISO 266 R20 preferred frequencies from 20 Hz to 20 kHz (61 values, sixth-octave spacing): the finer series the default band rule falls back to where R10 (ISO_THIRD_OCTAVE_CENTRES_HZ, 31 values) has too few to give every band its own centre. R10 is a subset of it.
664
+ * @see data/kernels/eq.json
665
+ */
666
+ export declare const EQ_CENTRE_SERIES_R20_HZ: readonly [20, 22.4, 25, 28, 31.5, 35.5, 40, 45, 50, 56, 63, 71, 80, 90, 100, 112, 125, 140, 160, 180, 200, 224, 250, 280, 315, 355, 400, 450, 500, 560, 630, 710, 800, 900, 1000, 1120, 1250, 1400, 1600, 1800, 2000, 2240, 2500, 2800, 3150, 3550, 4000, 4500, 5000, 5600, 6300, 7100, 8000, 9000, 10000, 11200, 12500, 14000, 16000, 18000, 20000];
667
+
668
+ /**
669
+ * How far (bins) around bin/2 and bin/3 PSHR (`omx_fbs_pshr`) scans for a sub-harmonic line. A true half/third partial lands mid-bin in the worst case (bin/2 and bin/3 are rarely integers) and spectral leakage smears it one bin further; ±2 covers both. Measured on the #116 live-music corpus: every false positive's sub-line sat inside this window. Deliberately NOT wider — at low bins the window is already a large fraction of an octave, and widening it would start reading unrelated program lines as "sub-harmonics" of real feedback.
670
+ * @see data/kernels/fbs.json
671
+ */
672
+ export declare const SUBHARMONIC_RADIUS_BINS: 2;
673
+
674
+ /**
675
+ * PAPR's guard band: bins either side of the peak left out of the floor average (its own skirt).
676
+ * @see data/kernels/fbs.json
677
+ */
678
+ export declare const FBS_PAPR_GUARD_BINS: 2;
679
+
680
+ /**
681
+ * PNPR's neighbourhood radius in bins, and the guard inside it that belongs to the peak's own skirt: a pure tone is compared with bins 2 and 3 away on each side.
682
+ * @see data/kernels/fbs.json
683
+ */
684
+ export declare const FBS_PNPR_RADIUS_BINS: 3;
685
+
686
+ /**
687
+ * The guard inside PNPR's neighbourhood radius that belongs to the peak's own skirt, in bins.
688
+ * @see data/kernels/fbs.json
689
+ */
690
+ export declare const FBS_PNPR_GUARD_BINS: 1;
691
+
692
+ /**
693
+ * How many harmonics PHPR reads above the candidate: 2f, 3f and 4f.
694
+ * @see data/kernels/fbs.json
695
+ */
696
+ export declare const FBS_PHPR_HARMONICS: 3;
697
+
698
+ /**
699
+ * PSHR skips sub-window bins within this many of the candidate, so a low bin never measures its own skirt as a sub-harmonic.
700
+ * @see data/kernels/fbs.json
701
+ */
702
+ export declare const FBS_PSHR_SELF_SKIP_BINS: 3;
703
+
704
+ /**
705
+ * The magnitude floor of every detector dB reading (−240 dB): a zero bin stays finite.
706
+ * @see data/kernels/fbs.json
707
+ */
708
+ export declare const FBS_FLOOR_LIN: 1e-12;
709
+
710
+ /**
711
+ * Tracked candidate bins per armed channel. A candidate that finds no free slot is COUNTED and reported, never dropped silently; the identity corpus peaks at 34.
712
+ * @see data/kernels/fbs.json
713
+ */
714
+ export declare const FBS_TRACK_SLOTS: 512;
715
+
716
+ /**
717
+ * Minimum PSHR (`omx_fbs_pshr`) (dB) for a candidate frame to count as sub-harmonic-CLEAN. Evidence-set on the #116 corpus, margin on both sides: the four live false positives (musical overtones at 1 869.1 / 832.0 / 263.7 / 228.5 Hz) read PSHR between −10.2 and +8.8 dB across their windows — never a 5-frame sub-clean stretch, and the single closest approach (+8.8) is isolated between frames at ≈ −1 and −10 — while the committed #106 injected ramp reads ≥ +12.2 dB from its second frame on (its frame 0 sits at +9.4, costing exactly one frame of confirm latency, pinned in the corpus test). A static program line at f/2 of REAL feedback also clears this fast: the runaway gains several dB per hop on anything static, so the deferral is transient.
718
+ * @see data/kernels/fbs.json
719
+ */
720
+ export declare const PSHR_MIN_DB: 10;
721
+
722
+ /**
723
+ * How many of a candidate bin's most recent dB readings feed the growth-slope estimate (the engine's least-squares slope) — set equal to DEFAULT_THRESHOLDS's `persistFrames` so growth is judged over the SAME window persistence already demands (the full run since the bin became a candidate, not a shorter or longer slice of it). Long enough that a couple of noisy/vibrato frames can't fake a trend by themselves.
724
+ * @see data/kernels/fbs.json
725
+ */
726
+ export declare const GROWTH_WINDOW_FRAMES: 5;
727
+
728
+ /**
729
+ * The DEEP plateau tier's dwell: ~2 s at the watcher's 10 Hz — the TIME that buys the deeper floor its music safety (see DetectThresholds.deepPlateauFloorDb).
730
+ * @see data/kernels/fbs.json
731
+ */
732
+ export declare const DEEP_PLATEAU_FRAMES: 20;
733
+
734
+ /**
735
+ * Minimum least-squares slope, in dB PER FRAME, over GROWTH_WINDOW_FRAMES for a bin to count as "running away" rather than merely holding level. Set with real margin on BOTH sides — comfortably above measurement jitter on a held tone or a quiet/broadband mix (well under 0.2 dB/frame in practice) and comfortably below a genuine feedback ramp, which climbs several dB across a handful of ~20 ms hops as it heads toward clipping. Issue #91's acceptance bar is "arming must never burst-alarm on non-growing content", so this errs conservative (under-fire a marginal ramp) rather than tight (risk a false alarm) — the ramp gate (`omx_fbs_is_growing`) also requires the window's end to sit above its start, a cheap belt-and-braces check against a fit dragged positive by one mid-window wobble.
736
+ * @see data/kernels/fbs.json
737
+ */
738
+ export declare const GROWTH_MIN_DB_PER_FRAME: 0.8;
739
+
740
+ /**
741
+ * Largest single-frame DIP (dB) a run-away window may contain. Real feedback climbs every hop; a small allowance covers measurement jitter and the −0.3 dB-ish wobble frames seen on live captures, while any real drop (a note ending, tremolo) breaks the run.
742
+ * @see data/kernels/fbs.json
743
+ */
744
+ export declare const GROWTH_MAX_DIP_DB: 0.5;
745
+
746
+ /**
747
+ * Minimum END-TO-END rise (dB) across the window. The live-music corpus (issue #106) showed sustained melody notes drifting up ~4–5 dB over a window without ever being feedback; a loop past unity gains several dB per hop and clears 6 dB in a window trivially. Below this the tone is holding level, not running away.
748
+ * @see data/kernels/fbs.json
749
+ */
750
+ export declare const GROWTH_MIN_TOTAL_RISE_DB: 6;
751
+
752
+ /**
753
+ * Cap on the share of the window's total rise a SINGLE frame may carry. Feedback is exponential in amplitude ⇒ linear in dB ⇒ its rise is distributed roughly evenly across the window; a musical attack / re-articulation puts almost the whole rise in one hop (the exact shape behind every one of issue #106's 72 live false positives). One half is generous to real ramps (an even N-frame ramp puts 1/(N−1) per hop) and fatal to steps. A side effect worth knowing: a 2-sample window can never pass (one hop IS the whole rise), so confirmation always rests on at least three frames of actual ramp evidence.
754
+ * @see data/kernels/fbs.json
755
+ */
756
+ export declare const GROWTH_MAX_SINGLE_FRAME_SHARE: 0.5;
757
+
758
+ /**
759
+ * How many CONSECUTIVE frames the ramp gate (`omx_fbs_is_growing`) must hold before a bin confirms — the time-domain tiebreak for the one shape a single window cannot judge (issue #106): a smooth musical crescendo. Within one window a +6 dB swell (live corpus: a C6 at 1 049 Hz, `[-53.7, -51.4, -50.4, -48, -47.3]`) is indistinguishable from slow feedback — the difference is only visible on the NEXT hop, where a crescendo peaks and plateaus (the window's rise collapses) while feedback keeps climbing. Requiring the gate to hold twice in a row costs a clean ramp nothing — its gate is already true while persistence is still arming — and blocks the swell that peaks the very frame it would have confirmed.
760
+ * @see data/kernels/fbs.json
761
+ */
762
+ export declare const GROWTH_CONFIRM_FRAMES: 2;
763
+
764
+ /**
765
+ * The corpus-tuned SAFE DEFAULT — today's exact gates, assembled byte-for-byte from the exported consts above (which stay the authoritative literal source, so the corpus test's import type { MagnitudeSeries } from './spectrum-bands.js'; imports remain the single truth). This is the ANCHOR the whole sensitivity mapping pins to: thresholdsFor`(0, 'live')` and `(0, 'fixed')` both deep-equal this object, so an untouched channel runs the identical detector it does now. `plateauFloorDb` is omitted ⇒ the #140 plateau route is OFF at the default.
766
+ * @see data/kernels/fbs.json
767
+ */
768
+ export declare const DEFAULT_THRESHOLDS: {
769
+ readonly paprDb: 18;
770
+ readonly pnprDb: 12;
771
+ readonly phprDb: 9;
772
+ readonly persistFrames: 5;
773
+ readonly growthConfirmFrames: 2;
774
+ readonly subCleanFrames: 5;
775
+ readonly growthMinTotalRiseDb: 6;
776
+ readonly growthMaxSingleFrameShare: 0.5;
777
+ readonly growthMinDbPerFrame: 0.8;
778
+ readonly growthMaxDipDb: 0.5;
779
+ readonly pshrMinDb: 10;
780
+ };
781
+
782
+ /**
783
+ * 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 (2026-09-08-room-analysis.md §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.
784
+ * @see data/kernels/fbs.json
785
+ */
786
+ export declare const FBS_MAX_NOTCH_DEPTH_DB: 18;
787
+
788
+ /**
789
+ * Default planted-notch width (Q) — the dbx-AFS-style ultra-narrow notch the corrector plants. `addBand`'s per-shape clamp holds it at 116 for a fixed notch and narrows it to 8 for a live bell, so this is the declared starting point rather than the width every notch ends up with.
790
+ * @see data/kernels/fbs.json
791
+ */
792
+ export declare const FBS_DEFAULT_NOTCH_Q: 116;
793
+
794
+ /**
795
+ * Default per-channel cap on auto-planted bands — a full pool plants nothing and raises a pool-full alert instead (predictability over silent eviction).
796
+ * @see data/kernels/fbs.json
797
+ */
798
+ export declare const FBS_DEFAULT_MAX_AUTO_BANDS: 6;
799
+
474
800
  /**
475
801
  * The flanger's jet sweep (§3b).
476
802
  * @see data/kernels/flanger.json
@@ -523,6 +849,24 @@ export declare const FLANGER_MIX_RANGE: {
523
849
  readonly defaultFrom: "desk";
524
850
  };
525
851
 
852
+ /**
853
+ * The flanger's base delay, ms: the sweep rides on it up to the depth.
854
+ * @see data/kernels/flanger.json
855
+ */
856
+ export declare const FLANGER_BASE_MS: 0.5;
857
+
858
+ /**
859
+ * The longest delay a flanger sweep reaches, rounded up to whole ms: the base delay plus the depth maximum. The delay line is sized from it.
860
+ * @see data/kernels/flanger.json
861
+ */
862
+ export declare const FLANGER_MAX_MS: 6;
863
+
864
+ /**
865
+ * Where the gate listens: its own input (self), or the key it is handed (sidechain), in the order of the integer the key port carries.
866
+ * @see data/kernels/gate.json
867
+ */
868
+ export declare const GATE_KEY_SOURCES: readonly ["self", "sidechain"];
869
+
526
870
  /**
527
871
  * The legal range of each gate field (engineering units). The widget clamps drags to these, `normalizeGate` enforces them, the row's codec refuses by them and the travel sheet publishes them — one source of truth. `rangeDb` reaches GATE_RANGE_FLOOR_DB, shown as "−∞" in readouts (a gate fully closed is silence).
528
872
  * @see data/kernels/gate.json
@@ -633,6 +977,67 @@ export declare const GEQ_PROTO_DB: 12;
633
977
  */
634
978
  export declare const GEQ_DESIGN_GAIN_MAX_DB: 30;
635
979
 
980
+ /**
981
+ * How much of the computed correction HRP applies: 0 = analyse only, 1 = the full cut. It comes up at 0.5, half the computed cut.
982
+ * @see data/kernels/hrp.json
983
+ */
984
+ export declare const HRP_AMOUNT_RANGE: {
985
+ readonly min: 0;
986
+ readonly max: 1;
987
+ readonly step: 0;
988
+ readonly unit: "";
989
+ readonly default: 0.5;
990
+ readonly defaultFrom: "desk";
991
+ };
992
+
993
+ /**
994
+ * The largest automatic cut HRP may place on one harmonic, as a POSITIVE dB magnitude. Well inside the ±15 dB an operator band may hold (core's `EQ_GAIN_LIMIT_DB`): an automatic correction the operator did not ask for gets far less authority than one they dialled themselves.
995
+ * @see data/kernels/hrp.json
996
+ */
997
+ export declare const HRP_MAX_CUT_DB: 6;
998
+
999
+ /**
1000
+ * 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. `core/src/output-delay-ceiling.test.ts` 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.
1001
+ * @see data/kernels/hrp.json
1002
+ */
1003
+ export declare const HRP_MAX_VOICES: 8;
1004
+
1005
+ /**
1006
+ * The Q of an HRP correction band — one declared number, operator-adjustable later. A musical cut, not a ring killer: FBS's default notch Q is ~116 because a howl is a single frequency, whereas a partial that is too loud is a note an instrument is playing and a surgical null on it would be heard as a hole. 5 sits mid-band in the 4…6 range a musical subtractive cut occupies, and inside EQ_Q_RANGE — the gain-carrying shapes' extent — so it survives the store's clamp unchanged. Deliberately NOT derived from the harmonic index. A derivation invented with no measurement behind it is a second declaration wearing a formula; this is revisited when the analyse-only surface shows what real corrections look like.
1007
+ * @see data/kernels/hrp.json
1008
+ */
1009
+ export declare const HRP_BAND_Q: 5;
1010
+
1011
+ /**
1012
+ * How far a partial must stand above its LEARNED BASELINE before HRP calls it a resonance (increment 8, §23–§24: `deviation = measured − baseline[note][harmonic]`). A partial level tells you nothing on its own; what marks a resonance is a partial louder than THIS instrument normally measures at THIS note. Three decibels is the same order as the feedback detector's peak-to-neighbour gate and for the same reason: below it, an ordinary performance's variation — a bow dug in, a verse sung harder — would be flattened, and flattening expression is not correcting a room. (Before the learned model existed this same threshold gated the placeholder neighbour rule; the number and its reasoning carried over.)
1013
+ * @see data/kernels/hrp.json
1014
+ */
1015
+ export declare const HRP_EXCESS_THRESHOLD_DB: 3;
1016
+
1017
+ /**
1018
+ * How far ONE reconcile pass may move an HRP band's gain, in dB — §48's gain smoothing, done at the control level because the native cascade applies pushed coefficients verbatim and §48 forbids interpolating there. An unbounded gain step is a waveform discontinuity — the click heard when a correction entered or left at full depth (found live, 2026-08-20, the evening increment 9 raised the enter/leave rate). Bounded, a correction ENTERS by deepening from silence and LEAVES by walking to exactly 0 dB — the provable parked identity (`eqBandIsIdentity`) — from which removal is bit-identical. Two decibels per pass at the corrector's 10 Hz cadence walks the full HRP_MAX_CUT_DB travel in ~300 ms: the same order as the tracker's stability hold and FBS's lift steps, while each individual move stays below audibility on a Q-5 bell.
1019
+ * @see data/kernels/hrp.json
1020
+ */
1021
+ export declare const HRP_GAIN_STEP_DB: 2;
1022
+
1023
+ /**
1024
+ * How close two correction candidates must sit, in cents, to count as the SAME spectral region (§30): within it, the stronger candidate is selected and the weaker discarded rather than two near-identical filters being planted. One semitone, and the number follows from HRP_BAND_Q: a Q-5 bell's −3 dB half-width is ~170 cents, so two cuts a semitone apart overlap over most of their travel — the second one deepens the first far more than it shapes anything of its own. The spec orders the threshold configurable and tested (§30's last line): declared once here, a parameter everywhere below.
1025
+ * @see data/kernels/hrp.json
1026
+ */
1027
+ export declare const HRP_COLLISION_CENTS: 100;
1028
+
1029
+ /**
1030
+ * The ATTRIBUTION window (§11): two partials closer than this are one spectral event as far as the desk can tell — the same ±1 bin `omx_hrp_bin_peak` reads over, expressed musically so it holds across the range. A different law from HRP_COLLISION_CENTS (§30's SELECTION window, which stays above it): this one is the analyser's resolution, that one the corrector's. Generated into `omx_contract_limits.h` as `OMX_HRP_ATTRIBUTION_CENTS`; `hrp_attribute.h` reads it.
1031
+ * @see data/kernels/hrp.json
1032
+ */
1033
+ export declare const HRP_ATTRIBUTION_CENTS: 60;
1034
+
1035
+ /**
1036
+ * 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. `eq-budget-fits.test.ts` 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.
1037
+ * @see data/kernels/hrp.json
1038
+ */
1039
+ export declare const HRP_DEFAULT_MAX_AUTO_BANDS: 8;
1040
+
636
1041
  /**
637
1042
  * The precision limiter's travels (`2026-09-27-precision-limiter.md` §2), rendered into `omx_contract_limits.h` as `OMX_LIMITER_*` by `harness/contract-limits-gen.mjs`, 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.
638
1043
  * @see data/kernels/limiter.json
@@ -664,6 +1069,12 @@ export declare const LIMITER_LIMITS: {
664
1069
  };
665
1070
  };
666
1071
 
1072
+ /**
1073
+ * 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. `native-input-ceiling.test.ts` holds this to the C header; spec `docs/design/specs/2026-09-14-console-allocation.md` §9 carries the ruling and the measured cost of width.
1074
+ * @see data/kernels/mixmatrix.json
1075
+ */
1076
+ export declare const BUS_INPUT_CAP: 128;
1077
+
667
1078
  /**
668
1079
  * The phaser's sweep speed (§3). `omx_lfo_inc` freezes at Nyquist; this travel stays far below.
669
1080
  * @see data/kernels/phaser.json
@@ -716,12 +1127,6 @@ export declare const PHASER_STAGES_RANGE: {
716
1127
  readonly defaultFrom: "desk";
717
1128
  };
718
1129
 
719
- /**
720
- * The member set the `stages` field accepts: PHASER_STAGES_RANGE walked by its step.
721
- * @see data/kernels/phaser.json
722
- */
723
- export declare const PHASER_STAGE_COUNTS: readonly [2, 4, 6, 8, 10, 12];
724
-
725
1130
  /**
726
1131
  * The phaser's SIGNED resonance (§3). ±0.9, tighter than the flanger's ±0.95: the loop runs through a time-varying chain. Declared here (the refusal half); the kernel's clamp is the enforcement half.
727
1132
  * @see data/kernels/phaser.json
@@ -795,6 +1200,18 @@ export declare const PHASER_TRAVELS: {
795
1200
  };
796
1201
  };
797
1202
 
1203
+ /**
1204
+ * The member set the `stages` field accepts: PHASER_STAGES_RANGE walked by its step.
1205
+ * @see data/kernels/phaser.json
1206
+ */
1207
+ export declare const PHASER_STAGE_COUNTS: readonly [2, 4, 6, 8, 10, 12];
1208
+
1209
+ /**
1210
+ * The highest frequency the phaser's all-pass sweep reaches, Hz.
1211
+ * @see data/kernels/phaser.json
1212
+ */
1213
+ export declare const PHASER_F_TOP_HZ: 16000;
1214
+
798
1215
  /**
799
1216
  * PITCH_LIMITS, moved from openmixer.
800
1217
  * @see data/kernels/pitch.json
@@ -986,6 +1403,18 @@ export declare const REVERB_GATE_THRESHOLD_RANGE: {
986
1403
  readonly defaultFrom: "desk";
987
1404
  };
988
1405
 
1406
+ /**
1407
+ * The reverb's algorithms, in the order of the integer the kernel reads. Reverse and gated are the room network handed a window and a gate.
1408
+ * @see data/kernels/reverb.json
1409
+ */
1410
+ export declare const REVERB_ALGORITHMS: readonly ["room", "plate", "hall", "reverse", "gated"];
1411
+
1412
+ /**
1413
+ * The gated reverb's gate attack, ms: the time the gate takes to open on a hit.
1414
+ * @see data/kernels/reverb.json
1415
+ */
1416
+ export declare const REVERB_GATE_ATTACK_MS: 1.5;
1417
+
989
1418
  /**
990
1419
  * The horn's chorale (slow) rate, Hz.
991
1420
  * @see data/kernels/rotary.json
@@ -1077,6 +1506,12 @@ export declare const ROTARY_MIX_RANGE: {
1077
1506
  readonly defaultFrom: "desk";
1078
1507
  };
1079
1508
 
1509
+ /**
1510
+ * 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.
1511
+ * @see data/kernels/rotary.json
1512
+ */
1513
+ export declare const ROTARY_SPEEDS: readonly ["stop", "slow", "fast"];
1514
+
1080
1515
  /**
1081
1516
  * 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).
1082
1517
  * @see data/kernels/rotary.json
@@ -1212,6 +1647,18 @@ export declare const ROTARY_STOP_EPS: 0.0001;
1212
1647
  */
1213
1648
  export declare const ROTARY_RING_FLOATS: 256;
1214
1649
 
1650
+ /**
1651
+ * 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.
1652
+ * @see data/kernels/rta.json
1653
+ */
1654
+ export declare const RTA_TARGET_BIN_HZ: 5.9;
1655
+
1656
+ /**
1657
+ * The largest RTA FFT the native ring holds — generated into `omx_contract_limits.h` as `OMX_RTA_FFT_SIZE_MAX`.
1658
+ * @see data/kernels/rta.json
1659
+ */
1660
+ export declare const RTA_FFT_SIZE_MAX: 32768;
1661
+
1215
1662
  /**
1216
1663
  * 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).
1217
1664
  * @see data/kernels/transient.json
@@ -1322,6 +1769,12 @@ export declare const TREMOLO_MIX_RANGE: {
1322
1769
  readonly defaultFrom: "desk";
1323
1770
  };
1324
1771
 
1772
+ /**
1773
+ * 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).
1774
+ * @see data/kernels/tremolo.json
1775
+ */
1776
+ export declare const TREMOLO_MODES: readonly ["tremolo", "pan"];
1777
+
1325
1778
  /**
1326
1779
  * 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).
1327
1780
  * @see data/kernels/tremolo.json
@@ -1466,6 +1919,40 @@ export declare const TRIM_TRAVELS: {
1466
1919
  };
1467
1920
  };
1468
1921
 
1922
+ /**
1923
+ * How a host draws a parameter: linear, logarithmic (a frequency, a time) or in discrete steps. The words omx-plugins' declarations and plugin-hostd's protocol use; a travel names its own with `scale`.
1924
+ * @see data/primitives.json
1925
+ */
1926
+ export declare const PARAM_SCALES: readonly ["linear", "log", "stepped"];
1927
+
1928
+ /**
1929
+ * The EQ's three frequency travels as a host draws them: the band frequency, the high-pass corner and the low-pass corner, EQ_FREQ_RANGE's, HPF_FREQ_RANGE's and LPF_FREQ_RANGE's bounds with no step and a logarithmic scale. The console's EQ quantises frequency to 10 Hz; a frequency drags continuously on a log axis, which is how every host draws it, so this is the form the omx-plugins read. Every number but the step is the source's, held equal by test/continuous-travels.test.mjs. Not rendered to C: no C reader needs a second spelling of the EQ's bounds.
1930
+ * @see data/primitives.json
1931
+ */
1932
+ export declare const EQ_CONTINUOUS_TRAVELS: {
1933
+ readonly freqHz: {
1934
+ readonly min: 20;
1935
+ readonly max: 20000;
1936
+ readonly step: 0;
1937
+ readonly unit: "Hz";
1938
+ readonly scale: "log";
1939
+ };
1940
+ readonly hpfFreqHz: {
1941
+ readonly min: 20;
1942
+ readonly max: 1000;
1943
+ readonly step: 0;
1944
+ readonly unit: "Hz";
1945
+ readonly scale: "log";
1946
+ };
1947
+ readonly lpfFreqHz: {
1948
+ readonly min: 1000;
1949
+ readonly max: 20000;
1950
+ readonly step: 0;
1951
+ readonly unit: "Hz";
1952
+ readonly scale: "log";
1953
+ };
1954
+ };
1955
+
1469
1956
  /**
1470
1957
  * 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` (`2026-07-15-clock-rate-honest-force-rate.md`) — this is the ceiling a write is refused by, never a menu.
1471
1958
  * @see data/rates.json
@@ -1486,3 +1973,22 @@ export declare const RT_HARD_TARGET: {
1486
1973
  * @see data/rates.json
1487
1974
  */
1488
1975
  export declare const DSP_KNOB_REFERENCE_RATE: 96000;
1976
+
1977
+ /**
1978
+ * The four rates every kernel oracle runs at, whatever STANDARD_SAMPLE_RATES says: a declared list missing one of them stops a suite instead of testing less (omx-dsp, omx-plugins and omx-clap-host run their oracles at these).
1979
+ * @see data/rates.json
1980
+ */
1981
+ export declare const ORACLE_FLOOR_RATES: readonly [44100, 48000, 96000, 192000];
1982
+
1983
+ /**
1984
+ * The nine rates an RME interface clocks at, 32 to 192 kHz. STANDARD_SAMPLE_RATES is a subset of them; an oracle that runs here also covers 32, 64 and 128 kHz, where a kernel still has to meet its closed form even though the console never asks for them.
1985
+ * @see data/rates.json
1986
+ */
1987
+ export declare const RME_RATES: readonly [32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000];
1988
+
1989
+ /** The default band centres (Hz) of an EQ with `count` bands: THE one rule, for every strip, host and count. */
1990
+ export declare function eqDefaultCentres(count: number): number[];
1991
+ /** The default band types, by EQ_BAND_TYPES id: a low shelf, bells, a high shelf (a single band is a bell). */
1992
+ export declare function eqDefaultTypes(count: number): string[];
1993
+ /** Every default band of an EQ with `count` bands: type, centre, gain and Q. */
1994
+ export declare function eqDefaultBands(count: number): { type: string; freqHz: number; gainDb: number; q: number }[];