@openmixer/omx-contract 2.4.0 → 2.6.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 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.4.0 omx-contract`), else the npm tarball, unpacked, and
52
+ that version (`pkg-config --exact-version=2.6.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).
@@ -122,6 +122,17 @@
122
122
  "Off",
123
123
  "4x"
124
124
  ]
125
+ },
126
+ {
127
+ "name": "detectorTopology",
128
+ "kind": "choice",
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`, openmixer's ssl-bus-compressor spec §3a) and comes up `feedforward`, so a zeroed atom is the compressor every slot runs.",
131
+ "ids": [
132
+ "feedforward",
133
+ "feedback"
134
+ ],
135
+ "default": "feedforward"
125
136
  }
126
137
  ],
127
138
  "readouts": [
@@ -160,6 +171,12 @@
160
171
  }
161
172
  }
162
173
  }
174
+ },
175
+ "DYN_FB_LOOP_DELAY_SAMPLES": {
176
+ "kind": "scalar",
177
+ "doc": "The feedback detector's loop delay, in samples: the output y[n] depends on the gain at n, so the detector can only have heard y[n - 1]. Not a latency: the audio is never delayed by it. omx-dsp's feedback state holds exactly this many output samples per leg.",
178
+ "unit": "",
179
+ "value": 1
163
180
  }
164
181
  }
165
182
  }
@@ -0,0 +1,27 @@
1
+ {
2
+ "$schema": "../../schema/omx-contract.schema.json",
3
+ "controls": [
4
+ {
5
+ "name": "kind",
6
+ "kind": "choice",
7
+ "doc": "The generator kinds, in surface order: its position is the integer omx-dsp's omx_gen_fill takes as its kind (OMX_GEN_OSC, OMX_GEN_WHITE, OMX_GEN_PINK).",
8
+ "ids": [
9
+ "oscillator",
10
+ "white",
11
+ "pink"
12
+ ]
13
+ },
14
+ {
15
+ "name": "waveform",
16
+ "kind": "choice",
17
+ "global": "WAVEFORMS",
18
+ "doc": "The selectable oscillator waveforms, in surface order: its position is the integer omx-dsp's omx_gen_osc takes (OMX_WAVE_SINE, OMX_WAVE_SQUARE, OMX_WAVE_SAW, OMX_WAVE_TRIANGLE).",
19
+ "ids": [
20
+ "sine",
21
+ "square",
22
+ "saw",
23
+ "triangle"
24
+ ]
25
+ }
26
+ ]
27
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "$schema": "../../schema/omx-contract.schema.json",
3
+ "constants": {
4
+ "SRC_TAPS": {
5
+ "kind": "scalar",
6
+ "doc": "Taps per phase. 64 puts the design's transition band comfortably inside what a Kaiser of this beta can hold at every standard rate pair, and costs 64 multiply-adds per output sample — about 12 M flops per track-minute at 48 kHz, which is nothing offline.",
7
+ "unit": "",
8
+ "value": 64
9
+ },
10
+ "SRC_STOPBAND_DB": {
11
+ "kind": "scalar",
12
+ "doc": "Stopband attenuation the window is designed for, in dB. 96 dB is below the noise floor of any take this console can capture (float capture of a 24-bit converter), so the conversion is not what limits the file.",
13
+ "unit": "dB",
14
+ "value": 96
15
+ },
16
+ "SRC_ROLLOFF": {
17
+ "kind": "scalar",
18
+ "doc": "How much of the shared Nyquist the passband keeps. The remaining 8 % is the transition band the window needs to reach its stopband: at 48 kHz that puts the corner at 22.08 kHz and the stopband in place by 24 kHz.",
19
+ "unit": "",
20
+ "value": 0.92
21
+ },
22
+ "SRC_MAX_L": {
23
+ "kind": "scalar",
24
+ "doc": "The largest interpolation factor a plan may carry. 44.1 kHz -> 192 kHz is 640/147, the widest pair the console's standard rates produce; the cap refuses an exotic pair before it allocates a table nobody budgeted for, rather than discovering it as a bad_alloc.",
25
+ "unit": "",
26
+ "value": 1024
27
+ }
28
+ }
29
+ }
@@ -254,6 +254,12 @@ export declare const COMP_KINDS: readonly ["comp", "limiter"];
254
254
  */
255
255
  export declare const DETECTOR_OVERSAMPLINGS: readonly ["auto", "off", "x4"];
256
256
 
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`, openmixer's ssl-bus-compressor spec §3a) and comes up `feedforward`, so a zeroed atom is the compressor every slot runs.
259
+ * @see data/kernels/comp.json
260
+ */
261
+ export declare const DETECTOR_TOPOLOGY: readonly ["feedforward", "feedback"];
262
+
257
263
  /**
258
264
  * The program-dependent release's model constants — the LA-2A's opto cell as DATA (`docs/design/specs/2026-09-26-compressor-models.md` §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.
259
265
  * @see data/kernels/comp.json
@@ -271,6 +277,12 @@ export declare const PROGRAM_RELEASE: {
271
277
  };
272
278
  };
273
279
 
280
+ /**
281
+ * The feedback detector's loop delay, in samples: the output y[n] depends on the gain at n, so the detector can only have heard y[n - 1]. Not a latency: the audio is never delayed by it. omx-dsp's feedback state holds exactly this many output samples per leg.
282
+ * @see data/kernels/comp.json
283
+ */
284
+ export declare const DYN_FB_LOOP_DELAY_SAMPLES: 1;
285
+
274
286
  /**
275
287
  * The detector band's CENTRE, in Hz. Sibilance lives at 5–10 kHz on most voices; 7 kHz with the default width covers 4 950–9 900 Hz, which is where an "s" and a "t" sit on a close vocal mic. The travel is wider than the come-up on both sides on purpose: a bright female vocal wants the band up near 9 kHz and a chesty male one down at 5, and a surface narrower than the row removes reach the console genuinely has (the same reasoning core's `REVERB_CUT_RANGE` records).
276
288
  * @see data/kernels/deesser.json
@@ -1000,6 +1012,18 @@ export declare const GATE_LIMITS: {
1000
1012
  };
1001
1013
  };
1002
1014
 
1015
+ /**
1016
+ * The generator kinds, in surface order: its position is the integer omx-dsp's omx_gen_fill takes as its kind (OMX_GEN_OSC, OMX_GEN_WHITE, OMX_GEN_PINK).
1017
+ * @see data/kernels/generator.json
1018
+ */
1019
+ export declare const GENERATOR_KINDS: readonly ["oscillator", "white", "pink"];
1020
+
1021
+ /**
1022
+ * The selectable oscillator waveforms, in surface order: its position is the integer omx-dsp's omx_gen_osc takes (OMX_WAVE_SINE, OMX_WAVE_SQUARE, OMX_WAVE_SAW, OMX_WAVE_TRIANGLE).
1023
+ * @see data/kernels/generator.json
1024
+ */
1025
+ export declare const WAVEFORMS: readonly ["sine", "square", "saw", "triangle"];
1026
+
1003
1027
  /**
1004
1028
  * One graphic-EQ fader's travel: EQ_GAIN_RANGE by reference (a graphic fader is an EQ gain), with the come-up value it needs as a row field — flat, 0 dB (graphic-eq-31 spec §3).
1005
1029
  * @see data/kernels/geq.json
@@ -1713,6 +1737,30 @@ export declare const RTA_TARGET_BIN_HZ: 5.9;
1713
1737
  */
1714
1738
  export declare const RTA_FFT_SIZE_MAX: 32768;
1715
1739
 
1740
+ /**
1741
+ * Taps per phase. 64 puts the design's transition band comfortably inside what a Kaiser of this beta can hold at every standard rate pair, and costs 64 multiply-adds per output sample — about 12 M flops per track-minute at 48 kHz, which is nothing offline.
1742
+ * @see data/kernels/src.json
1743
+ */
1744
+ export declare const SRC_TAPS: 64;
1745
+
1746
+ /**
1747
+ * Stopband attenuation the window is designed for, in dB. 96 dB is below the noise floor of any take this console can capture (float capture of a 24-bit converter), so the conversion is not what limits the file.
1748
+ * @see data/kernels/src.json
1749
+ */
1750
+ export declare const SRC_STOPBAND_DB: 96;
1751
+
1752
+ /**
1753
+ * How much of the shared Nyquist the passband keeps. The remaining 8 % is the transition band the window needs to reach its stopband: at 48 kHz that puts the corner at 22.08 kHz and the stopband in place by 24 kHz.
1754
+ * @see data/kernels/src.json
1755
+ */
1756
+ export declare const SRC_ROLLOFF: 0.92;
1757
+
1758
+ /**
1759
+ * The largest interpolation factor a plan may carry. 44.1 kHz -> 192 kHz is 640/147, the widest pair the console's standard rates produce; the cap refuses an exotic pair before it allocates a table nobody budgeted for, rather than discovering it as a bad_alloc.
1760
+ * @see data/kernels/src.json
1761
+ */
1762
+ export declare const SRC_MAX_L: 1024;
1763
+
1716
1764
  /**
1717
1765
  * 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).
1718
1766
  * @see data/kernels/transient.json
@@ -264,6 +264,15 @@ export const DETECTOR_OVERSAMPLINGS = [
264
264
  "x4"
265
265
  ];
266
266
 
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`, openmixer's ssl-bus-compressor spec §3a) and comes up `feedforward`, so a zeroed atom is the compressor every slot runs.
269
+ * @see data/kernels/comp.json
270
+ */
271
+ export const DETECTOR_TOPOLOGY = [
272
+ "feedforward",
273
+ "feedback"
274
+ ];
275
+
267
276
  /**
268
277
  * The program-dependent release's model constants — the LA-2A's opto cell as DATA (`docs/design/specs/2026-09-26-compressor-models.md` §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.
269
278
  * @see data/kernels/comp.json
@@ -281,6 +290,12 @@ export const PROGRAM_RELEASE = {
281
290
  }
282
291
  };
283
292
 
293
+ /**
294
+ * The feedback detector's loop delay, in samples: the output y[n] depends on the gain at n, so the detector can only have heard y[n - 1]. Not a latency: the audio is never delayed by it. omx-dsp's feedback state holds exactly this many output samples per leg.
295
+ * @see data/kernels/comp.json
296
+ */
297
+ export const DYN_FB_LOOP_DELAY_SAMPLES = 1;
298
+
284
299
  /**
285
300
  * The detector band's CENTRE, in Hz. Sibilance lives at 5–10 kHz on most voices; 7 kHz with the default width covers 4 950–9 900 Hz, which is where an "s" and a "t" sit on a close vocal mic. The travel is wider than the come-up on both sides on purpose: a bright female vocal wants the band up near 9 kHz and a chesty male one down at 5, and a surface narrower than the row removes reach the console genuinely has (the same reasoning core's `REVERB_CUT_RANGE` records).
286
301
  * @see data/kernels/deesser.json
@@ -1157,6 +1172,27 @@ export const GATE_LIMITS = {
1157
1172
  }
1158
1173
  };
1159
1174
 
1175
+ /**
1176
+ * The generator kinds, in surface order: its position is the integer omx-dsp's omx_gen_fill takes as its kind (OMX_GEN_OSC, OMX_GEN_WHITE, OMX_GEN_PINK).
1177
+ * @see data/kernels/generator.json
1178
+ */
1179
+ export const GENERATOR_KINDS = [
1180
+ "oscillator",
1181
+ "white",
1182
+ "pink"
1183
+ ];
1184
+
1185
+ /**
1186
+ * The selectable oscillator waveforms, in surface order: its position is the integer omx-dsp's omx_gen_osc takes (OMX_WAVE_SINE, OMX_WAVE_SQUARE, OMX_WAVE_SAW, OMX_WAVE_TRIANGLE).
1187
+ * @see data/kernels/generator.json
1188
+ */
1189
+ export const WAVEFORMS = [
1190
+ "sine",
1191
+ "square",
1192
+ "saw",
1193
+ "triangle"
1194
+ ];
1195
+
1160
1196
  /**
1161
1197
  * One graphic-EQ fader's travel: EQ_GAIN_RANGE by reference (a graphic fader is an EQ gain), with the come-up value it needs as a row field — flat, 0 dB (graphic-eq-31 spec §3).
1162
1198
  * @see data/kernels/geq.json
@@ -1887,6 +1923,30 @@ export const RTA_TARGET_BIN_HZ = 5.9;
1887
1923
  */
1888
1924
  export const RTA_FFT_SIZE_MAX = 32768;
1889
1925
 
1926
+ /**
1927
+ * Taps per phase. 64 puts the design's transition band comfortably inside what a Kaiser of this beta can hold at every standard rate pair, and costs 64 multiply-adds per output sample — about 12 M flops per track-minute at 48 kHz, which is nothing offline.
1928
+ * @see data/kernels/src.json
1929
+ */
1930
+ export const SRC_TAPS = 64;
1931
+
1932
+ /**
1933
+ * Stopband attenuation the window is designed for, in dB. 96 dB is below the noise floor of any take this console can capture (float capture of a 24-bit converter), so the conversion is not what limits the file.
1934
+ * @see data/kernels/src.json
1935
+ */
1936
+ export const SRC_STOPBAND_DB = 96;
1937
+
1938
+ /**
1939
+ * How much of the shared Nyquist the passband keeps. The remaining 8 % is the transition band the window needs to reach its stopband: at 48 kHz that puts the corner at 22.08 kHz and the stopband in place by 24 kHz.
1940
+ * @see data/kernels/src.json
1941
+ */
1942
+ export const SRC_ROLLOFF = 0.92;
1943
+
1944
+ /**
1945
+ * The largest interpolation factor a plan may carry. 44.1 kHz -> 192 kHz is 640/147, the widest pair the console's standard rates produce; the cap refuses an exotic pair before it allocates a table nobody budgeted for, rather than discovering it as a bad_alloc.
1946
+ * @see data/kernels/src.json
1947
+ */
1948
+ export const SRC_MAX_L = 1024;
1949
+
1890
1950
  /**
1891
1951
  * 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).
1892
1952
  * @see data/kernels/transient.json
@@ -279,6 +279,7 @@
279
279
  #define OMX_DRIVE_TRIM_RANGE_STEP 0.1f
280
280
  #define OMX_DRIVE_TRIM_RANGE_STEP_DOUBLE 0.1
281
281
  #define OMX_DSP_KNOB_REFERENCE_RATE 96000
282
+ #define OMX_DYN_FB_LOOP_DELAY_SAMPLES 1
282
283
  #define OMX_EQ_BAND_COUNTS_CHANNEL_DEFAULT 4
283
284
  #define OMX_EQ_BAND_COUNTS_CHANNEL_MAX 24
284
285
  #define OMX_EQ_BAND_COUNTS_EQ16_DEFAULT 16
@@ -569,6 +570,11 @@
569
570
  #define OMX_RTA_TARGET_BIN_HZ_DOUBLE 5.9
570
571
  #define OMX_RT_HARD_TARGET_QUANTUM 128
571
572
  #define OMX_RT_HARD_TARGET_RATE 192000
573
+ #define OMX_SRC_MAX_L 1024
574
+ #define OMX_SRC_ROLLOFF 0.92f
575
+ #define OMX_SRC_ROLLOFF_DOUBLE 0.92
576
+ #define OMX_SRC_STOPBAND_DB 96
577
+ #define OMX_SRC_TAPS 64
572
578
  #define OMX_SUBHARMONIC_RADIUS_BINS 2
573
579
  #define OMX_TRANSIENT_FAST_ATTACK_MS 0.5f
574
580
  #define OMX_TRANSIENT_FAST_ATTACK_MS_DOUBLE 0.5
@@ -652,6 +658,12 @@ enum omx_detector_oversamplings {
652
658
  };
653
659
  #define OMX_DETECTOR_OVERSAMPLINGS_COUNT 3u
654
660
  #define OMX_DETECTOR_OVERSAMPLINGS_DEFAULT OMX_DETECTOR_OVERSAMPLINGS_AUTO
661
+ enum omx_detector_topology {
662
+ OMX_DETECTOR_TOPOLOGY_FEEDFORWARD = 0,
663
+ OMX_DETECTOR_TOPOLOGY_FEEDBACK = 1,
664
+ };
665
+ #define OMX_DETECTOR_TOPOLOGY_COUNT 2u
666
+ #define OMX_DETECTOR_TOPOLOGY_DEFAULT OMX_DETECTOR_TOPOLOGY_FEEDFORWARD
655
667
  enum omx_drive_auto_gains {
656
668
  OMX_DRIVE_AUTO_GAINS_OFF = 0,
657
669
  OMX_DRIVE_AUTO_GAINS_ON = 1,
@@ -723,6 +735,12 @@ enum omx_gate_key_sources {
723
735
  OMX_GATE_KEY_SOURCES_SIDECHAIN = 1,
724
736
  };
725
737
  #define OMX_GATE_KEY_SOURCES_COUNT 2u
738
+ enum omx_generator_kinds {
739
+ OMX_GENERATOR_KINDS_OSCILLATOR = 0,
740
+ OMX_GENERATOR_KINDS_WHITE = 1,
741
+ OMX_GENERATOR_KINDS_PINK = 2,
742
+ };
743
+ #define OMX_GENERATOR_KINDS_COUNT 3u
726
744
  enum omx_param_scales {
727
745
  OMX_PARAM_SCALES_LINEAR = 0,
728
746
  OMX_PARAM_SCALES_LOG = 1,
@@ -750,6 +768,13 @@ enum omx_tremolo_modes {
750
768
  };
751
769
  #define OMX_TREMOLO_MODES_COUNT 2u
752
770
  #define OMX_TREMOLO_MODES_DEFAULT OMX_TREMOLO_MODES_TREMOLO
771
+ enum omx_waveforms {
772
+ OMX_WAVEFORMS_SINE = 0,
773
+ OMX_WAVEFORMS_SQUARE = 1,
774
+ OMX_WAVEFORMS_SAW = 2,
775
+ OMX_WAVEFORMS_TRIANGLE = 3,
776
+ };
777
+ #define OMX_WAVEFORMS_COUNT 4u
753
778
 
754
779
  /* Every kernel's readouts, the meters a host draws (docs/readouts.md): an enum of the readouts at their position,
755
780
  * `OMX_<KERNEL>_READOUT_COUNT`, and per readout its display range (_MIN, _MAX), _RATE_HZ, _SCALE (an OMX_PARAM_SCALES_*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmixer/omx-contract",
3
- "version": "2.4.0",
3
+ "version": "2.6.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,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmixer/omx-contract",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "items": {
5
5
  "PAN_RANGE": {
6
6
  "rel": "data/kernels/balance.json",
@@ -299,6 +299,16 @@
299
299
  "x4"
300
300
  ]
301
301
  },
302
+ "DETECTOR_TOPOLOGY": {
303
+ "rel": "data/kernels/comp.json",
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`, openmixer's ssl-bus-compressor spec §3a) and comes up `feedforward`, so a zeroed atom is the compressor every slot runs.",
306
+ "default": "feedforward",
307
+ "value": [
308
+ "feedforward",
309
+ "feedback"
310
+ ]
311
+ },
302
312
  "PROGRAM_RELEASE": {
303
313
  "rel": "data/kernels/comp.json",
304
314
  "kind": "sheet",
@@ -316,6 +326,13 @@
316
326
  }
317
327
  }
318
328
  },
329
+ "DYN_FB_LOOP_DELAY_SAMPLES": {
330
+ "rel": "data/kernels/comp.json",
331
+ "kind": "scalar",
332
+ "doc": "The feedback detector's loop delay, in samples: the output y[n] depends on the gain at n, so the detector can only have heard y[n - 1]. Not a latency: the audio is never delayed by it. omx-dsp's feedback state holds exactly this many output samples per leg.",
333
+ "unit": "",
334
+ "value": 1
335
+ },
319
336
  "DEESS_FREQ_RANGE": {
320
337
  "rel": "data/kernels/deesser.json",
321
338
  "kind": "travels",
@@ -1330,6 +1347,27 @@
1330
1347
  }
1331
1348
  }
1332
1349
  },
1350
+ "GENERATOR_KINDS": {
1351
+ "rel": "data/kernels/generator.json",
1352
+ "kind": "set",
1353
+ "doc": "The generator kinds, in surface order: its position is the integer omx-dsp's omx_gen_fill takes as its kind (OMX_GEN_OSC, OMX_GEN_WHITE, OMX_GEN_PINK).",
1354
+ "value": [
1355
+ "oscillator",
1356
+ "white",
1357
+ "pink"
1358
+ ]
1359
+ },
1360
+ "WAVEFORMS": {
1361
+ "rel": "data/kernels/generator.json",
1362
+ "kind": "set",
1363
+ "doc": "The selectable oscillator waveforms, in surface order: its position is the integer omx-dsp's omx_gen_osc takes (OMX_WAVE_SINE, OMX_WAVE_SQUARE, OMX_WAVE_SAW, OMX_WAVE_TRIANGLE).",
1364
+ "value": [
1365
+ "sine",
1366
+ "square",
1367
+ "saw",
1368
+ "triangle"
1369
+ ]
1370
+ },
1333
1371
  "GEQ_BAND_RANGE": {
1334
1372
  "rel": "data/kernels/geq.json",
1335
1373
  "kind": "travels",
@@ -2120,6 +2158,34 @@
2120
2158
  "unit": "",
2121
2159
  "value": 32768
2122
2160
  },
2161
+ "SRC_TAPS": {
2162
+ "rel": "data/kernels/src.json",
2163
+ "kind": "scalar",
2164
+ "doc": "Taps per phase. 64 puts the design's transition band comfortably inside what a Kaiser of this beta can hold at every standard rate pair, and costs 64 multiply-adds per output sample — about 12 M flops per track-minute at 48 kHz, which is nothing offline.",
2165
+ "unit": "",
2166
+ "value": 64
2167
+ },
2168
+ "SRC_STOPBAND_DB": {
2169
+ "rel": "data/kernels/src.json",
2170
+ "kind": "scalar",
2171
+ "doc": "Stopband attenuation the window is designed for, in dB. 96 dB is below the noise floor of any take this console can capture (float capture of a 24-bit converter), so the conversion is not what limits the file.",
2172
+ "unit": "dB",
2173
+ "value": 96
2174
+ },
2175
+ "SRC_ROLLOFF": {
2176
+ "rel": "data/kernels/src.json",
2177
+ "kind": "scalar",
2178
+ "doc": "How much of the shared Nyquist the passband keeps. The remaining 8 % is the transition band the window needs to reach its stopband: at 48 kHz that puts the corner at 22.08 kHz and the stopband in place by 24 kHz.",
2179
+ "unit": "",
2180
+ "value": 0.92
2181
+ },
2182
+ "SRC_MAX_L": {
2183
+ "rel": "data/kernels/src.json",
2184
+ "kind": "scalar",
2185
+ "doc": "The largest interpolation factor a plan may carry. 44.1 kHz -> 192 kHz is 640/147, the widest pair the console's standard rates produce; the cap refuses an exotic pair before it allocates a table nobody budgeted for, rather than discovering it as a bad_alloc.",
2186
+ "unit": "",
2187
+ "value": 1024
2188
+ },
2123
2189
  "TRANSIENT_LIMITS": {
2124
2190
  "rel": "data/kernels/transient.json",
2125
2191
  "kind": "travels",
@@ -2646,6 +2712,11 @@
2646
2712
  "name": "detectorOversampling",
2647
2713
  "kind": "choice",
2648
2714
  "global": "DETECTOR_OVERSAMPLINGS"
2715
+ },
2716
+ {
2717
+ "name": "detectorTopology",
2718
+ "kind": "choice",
2719
+ "global": "DETECTOR_TOPOLOGY"
2649
2720
  }
2650
2721
  ],
2651
2722
  "readouts": [
@@ -2970,6 +3041,20 @@
2970
3041
  }
2971
3042
  ]
2972
3043
  },
3044
+ "generator": {
3045
+ "controls": [
3046
+ {
3047
+ "name": "kind",
3048
+ "kind": "choice",
3049
+ "global": "GENERATOR_KINDS"
3050
+ },
3051
+ {
3052
+ "name": "waveform",
3053
+ "kind": "choice",
3054
+ "global": "WAVEFORMS"
3055
+ }
3056
+ ]
3057
+ },
2973
3058
  "geq": {
2974
3059
  "controls": [
2975
3060
  {
@@ -3198,6 +3283,9 @@
3198
3283
  "rta": {
3199
3284
  "controls": []
3200
3285
  },
3286
+ "src": {
3287
+ "controls": []
3288
+ },
3201
3289
  "transient": {
3202
3290
  "controls": [
3203
3291
  {