@openmixer/omx-dsp 0.0.0-stage → 0.25.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.
@@ -0,0 +1,4 @@
1
+ /** 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. (Hz) @see data/kernels/rta.json */
2
+ export declare const RTA_TARGET_BIN_HZ = 5.9;
3
+ /** The largest RTA FFT the native ring holds — generated into `omx_contract_limits.h` as `OMX_RTA_FFT_SIZE_MAX`. @see data/kernels/rta.json */
4
+ export declare const RTA_FFT_SIZE_MAX = 32768;
@@ -0,0 +1,7 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ // Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
3
+ // GENERATED by ts/tools/definitions.mjs from omx-dsp data/kernels/ - do not edit.
4
+ /** 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. (Hz) @see data/kernels/rta.json */
5
+ export const RTA_TARGET_BIN_HZ = 5.9;
6
+ /** The largest RTA FFT the native ring holds — generated into `omx_contract_limits.h` as `OMX_RTA_FFT_SIZE_MAX`. @see data/kernels/rta.json */
7
+ export const RTA_FFT_SIZE_MAX = 32768;
package/dist/eq.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ /** The twin of omx_eq_design.h omx_eq_octaves_q, moved verbatim from the console (its catalog package). */
2
+ /** Bandwidth in octaves → Q (the cookbook relation). */
3
+ export declare function octavesToQ(octaves: number): number;
package/dist/eq.js ADDED
@@ -0,0 +1,9 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ // Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
3
+ /** The twin of omx_eq_design.h omx_eq_octaves_q, moved verbatim from the console (its catalog package). */
4
+ /** Bandwidth in octaves → Q (the cookbook relation). */
5
+ export function octavesToQ(octaves) {
6
+ const bw = Math.max(octaves, 0.05);
7
+ const t = Math.pow(2, bw);
8
+ return Math.sqrt(t) / (t - 1);
9
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @openmixer/omx-dsp: the TypeScript twins of omx-dsp kernels, the ones that stay in TypeScript because doing
3
+ * the work in C would be silly (a display, a unit conversion a browser runs). Each is pinned to its kernel by an
4
+ * agreement test in test/ that feeds both the same grid.
5
+ */
6
+ export { ANALYSIS_FLOOR_DB, dbToLinearGain, linearGainToDb, linearToDbFloored } from './units.js';
7
+ export { octavesToQ } from './eq.js';
8
+ export { fftSizeForRate } from './rta.js';
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ // Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
3
+ /**
4
+ * @openmixer/omx-dsp: the TypeScript twins of omx-dsp kernels, the ones that stay in TypeScript because doing
5
+ * the work in C would be silly (a display, a unit conversion a browser runs). Each is pinned to its kernel by an
6
+ * agreement test in test/ that feeds both the same grid.
7
+ */
8
+ export { ANALYSIS_FLOOR_DB, dbToLinearGain, linearGainToDb, linearToDbFloored } from './units.js';
9
+ export { octavesToQ } from './eq.js';
10
+ export { fftSizeForRate } from './rta.js';
package/dist/rta.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ /** The twin of omx_rta.h omx_rta_fft_size_for, moved verbatim from the console (its spectrum bands); the two limits are omx-dsp's own (data/kernels/rta.json). */
2
+ /**
3
+ * The RTA FFT length for `rate` — the TypeScript mirror of `mix_dsp.h`'s `omx_rta_fft_size_for`:
4
+ * the smallest power of two whose bins are at or under {@link RTA_TARGET_BIN_HZ} (44.1/48 kHz →
5
+ * 8192, 88.2/96 kHz → 16384, 176.4/192 kHz → 32768). Window TIME stays ~171 ms at every rate —
6
+ * pinning the length instead of deriving it was how moving the rig to 96 kHz silently halved the
7
+ * resolution (2026-09-17 declare-derive audit, F2). Every consumer of an offline/synth or a
8
+ * server RTA frame derives its window from the graph rate through this function rather than
9
+ * declaring one of its own.
10
+ */
11
+ export declare function fftSizeForRate(rate: number): number;
package/dist/rta.js ADDED
@@ -0,0 +1,19 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ // Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
3
+ /** The twin of omx_rta.h omx_rta_fft_size_for, moved verbatim from the console (its spectrum bands); the two limits are omx-dsp's own (data/kernels/rta.json). */
4
+ import { RTA_TARGET_BIN_HZ, RTA_FFT_SIZE_MAX } from './definitions.js';
5
+ /**
6
+ * The RTA FFT length for `rate` — the TypeScript mirror of `mix_dsp.h`'s `omx_rta_fft_size_for`:
7
+ * the smallest power of two whose bins are at or under {@link RTA_TARGET_BIN_HZ} (44.1/48 kHz →
8
+ * 8192, 88.2/96 kHz → 16384, 176.4/192 kHz → 32768). Window TIME stays ~171 ms at every rate —
9
+ * pinning the length instead of deriving it was how moving the rig to 96 kHz silently halved the
10
+ * resolution (2026-09-17 declare-derive audit, F2). Every consumer of an offline/synth or a
11
+ * server RTA frame derives its window from the graph rate through this function rather than
12
+ * declaring one of its own.
13
+ */
14
+ export function fftSizeForRate(rate) {
15
+ let n = 2048;
16
+ while (n < RTA_FFT_SIZE_MAX && rate / n > RTA_TARGET_BIN_HZ)
17
+ n *= 2;
18
+ return n;
19
+ }
@@ -0,0 +1,33 @@
1
+ /** The dB and linear-amplitude twins of omx_units.h (omx_db_to_lin, omx_lin_to_db, omx_lin_to_db_d), moved verbatim from the console (its output routes). */
2
+ /**
3
+ * dB → linear amplitude (0 dB → 1, −6 dB → ~0.501). The trim/fold gain the engine applies.
4
+ *
5
+ * `-Infinity` dB → 0 falls out of the exponential itself (`10 ** -Infinity === 0`), so
6
+ * callers need no silence guard of their own.
7
+ */
8
+ export declare function dbToLinearGain(db: number): number;
9
+ /**
10
+ * Linear amplitude → dB — the exact inverse of {@link dbToLinearGain}, and the reason this
11
+ * one exists: without it the inverse direction was hand-rolled at every call site, which is
12
+ * how three different silence conventions (`1e-12`, `1e-7`, `-60`) grew up elsewhere in the
13
+ * tree for what is nominally the same conversion.
14
+ *
15
+ * Silence and any non-positive amplitude read `-Infinity`, not NaN: `Math.log10` of a
16
+ * negative is NaN, and an amplitude below zero is a phase-inverted sample's magnitude
17
+ * mistake, not a level. Note this is the LEVEL conversion — an analyser floors its own
18
+ * spectrum at a chosen epsilon instead, deliberately, and should keep doing so.
19
+ */
20
+ export declare function linearGainToDb(linear: number): number;
21
+ /**
22
+ * The analysers' magnitude floor: an FFT bin or an envelope at exact zero reads −240 dB, below
23
+ * any real signal and finite for the growth and ratio arithmetic built on it (was the epsilon
24
+ * `1e-12` inside three analysers' logarithms).
25
+ */
26
+ export declare const ANALYSIS_FLOOR_DB = -240;
27
+ /**
28
+ * Linear amplitude → dB, never below `floorDb` — the conversion for a site whose floor is
29
+ * deliberate (an analyser's magnitude, a plot's axis, a meter that must stay finite). The floor
30
+ * is a named dB value, never an epsilon hidden inside the logarithm (`Math.max(x, 1e-12)` is
31
+ * `linearToDbFloored(x, -240)`); silence reads `floorDb`, not `-Infinity`.
32
+ */
33
+ export declare function linearToDbFloored(linear: number, floorDb: number): number;
package/dist/units.js ADDED
@@ -0,0 +1,41 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ // Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
3
+ /** The dB and linear-amplitude twins of omx_units.h (omx_db_to_lin, omx_lin_to_db, omx_lin_to_db_d), moved verbatim from the console (its output routes). */
4
+ /**
5
+ * dB → linear amplitude (0 dB → 1, −6 dB → ~0.501). The trim/fold gain the engine applies.
6
+ *
7
+ * `-Infinity` dB → 0 falls out of the exponential itself (`10 ** -Infinity === 0`), so
8
+ * callers need no silence guard of their own.
9
+ */
10
+ export function dbToLinearGain(db) {
11
+ return 10 ** (db / 20);
12
+ }
13
+ /**
14
+ * Linear amplitude → dB — the exact inverse of {@link dbToLinearGain}, and the reason this
15
+ * one exists: without it the inverse direction was hand-rolled at every call site, which is
16
+ * how three different silence conventions (`1e-12`, `1e-7`, `-60`) grew up elsewhere in the
17
+ * tree for what is nominally the same conversion.
18
+ *
19
+ * Silence and any non-positive amplitude read `-Infinity`, not NaN: `Math.log10` of a
20
+ * negative is NaN, and an amplitude below zero is a phase-inverted sample's magnitude
21
+ * mistake, not a level. Note this is the LEVEL conversion — an analyser floors its own
22
+ * spectrum at a chosen epsilon instead, deliberately, and should keep doing so.
23
+ */
24
+ export function linearGainToDb(linear) {
25
+ return linear <= 0 ? -Infinity : 20 * Math.log10(linear);
26
+ }
27
+ /**
28
+ * The analysers' magnitude floor: an FFT bin or an envelope at exact zero reads −240 dB, below
29
+ * any real signal and finite for the growth and ratio arithmetic built on it (was the epsilon
30
+ * `1e-12` inside three analysers' logarithms).
31
+ */
32
+ export const ANALYSIS_FLOOR_DB = -240;
33
+ /**
34
+ * Linear amplitude → dB, never below `floorDb` — the conversion for a site whose floor is
35
+ * deliberate (an analyser's magnitude, a plot's axis, a meter that must stay finite). The floor
36
+ * is a named dB value, never an epsilon hidden inside the logarithm (`Math.max(x, 1e-12)` is
37
+ * `linearToDbFloored(x, -240)`); silence reads `floorDb`, not `-Infinity`.
38
+ */
39
+ export function linearToDbFloored(linear, floorDb) {
40
+ return Math.max(floorDb, linearGainToDb(linear));
41
+ }
package/package.json CHANGED
@@ -1,6 +1,40 @@
1
1
  {
2
2
  "name": "@openmixer/omx-dsp",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.25.0",
4
+ "description": "The TypeScript twins of omx-dsp kernels, each pinned to its C kernel by an agreement test",
5
+ "type": "module",
6
+ "license": "GPL-3.0-or-later",
7
+ "author": "Pau Aliagas <linuxnow@gmail.com>",
8
+ "homepage": "https://github.com/FreeMixer/omx-dsp",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/FreeMixer/omx-dsp.git",
12
+ "directory": "ts"
13
+ },
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js"
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "files": [
22
+ "dist/",
23
+ "src/"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsc -p tsconfig.json",
27
+ "test": "node tools/definitions.mjs --check && tsc -p tsconfig.json && node --test test/*.test.mjs",
28
+ "prepack": "tsc -p tsconfig.json"
29
+ },
30
+ "devDependencies": {
31
+ "typescript": "^5.6.0"
32
+ },
33
+ "engines": {
34
+ "node": ">=22.18"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public",
38
+ "registry": "https://registry.npmjs.org/"
39
+ }
40
+ }
@@ -0,0 +1,9 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ // Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
3
+ // GENERATED by ts/tools/definitions.mjs from omx-dsp data/kernels/ - do not edit.
4
+
5
+ /** 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. (Hz) @see data/kernels/rta.json */
6
+ export const RTA_TARGET_BIN_HZ = 5.9;
7
+
8
+ /** The largest RTA FFT the native ring holds — generated into `omx_contract_limits.h` as `OMX_RTA_FFT_SIZE_MAX`. @see data/kernels/rta.json */
9
+ export const RTA_FFT_SIZE_MAX = 32768;
package/src/eq.ts ADDED
@@ -0,0 +1,10 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ // Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
3
+ /** The twin of omx_eq_design.h omx_eq_octaves_q, moved verbatim from the console (its catalog package). */
4
+
5
+ /** Bandwidth in octaves → Q (the cookbook relation). */
6
+ export function octavesToQ(octaves: number): number {
7
+ const bw = Math.max(octaves, 0.05);
8
+ const t = Math.pow(2, bw);
9
+ return Math.sqrt(t) / (t - 1);
10
+ }
package/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ // Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
3
+ /**
4
+ * @openmixer/omx-dsp: the TypeScript twins of omx-dsp kernels, the ones that stay in TypeScript because doing
5
+ * the work in C would be silly (a display, a unit conversion a browser runs). Each is pinned to its kernel by an
6
+ * agreement test in test/ that feeds both the same grid.
7
+ */
8
+ export { ANALYSIS_FLOOR_DB, dbToLinearGain, linearGainToDb, linearToDbFloored } from './units.js';
9
+ export { octavesToQ } from './eq.js';
10
+ export { fftSizeForRate } from './rta.js';
package/src/rta.ts ADDED
@@ -0,0 +1,20 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ // Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
3
+ /** The twin of omx_rta.h omx_rta_fft_size_for, moved verbatim from the console (its spectrum bands); the two limits are omx-dsp's own (data/kernels/rta.json). */
4
+
5
+ import { RTA_TARGET_BIN_HZ, RTA_FFT_SIZE_MAX } from './definitions.js';
6
+
7
+ /**
8
+ * The RTA FFT length for `rate` — the TypeScript mirror of `mix_dsp.h`'s `omx_rta_fft_size_for`:
9
+ * the smallest power of two whose bins are at or under {@link RTA_TARGET_BIN_HZ} (44.1/48 kHz →
10
+ * 8192, 88.2/96 kHz → 16384, 176.4/192 kHz → 32768). Window TIME stays ~171 ms at every rate —
11
+ * pinning the length instead of deriving it was how moving the rig to 96 kHz silently halved the
12
+ * resolution (2026-09-17 declare-derive audit, F2). Every consumer of an offline/synth or a
13
+ * server RTA frame derives its window from the graph rate through this function rather than
14
+ * declaring one of its own.
15
+ */
16
+ export function fftSizeForRate(rate: number): number {
17
+ let n = 2048;
18
+ while (n < RTA_FFT_SIZE_MAX && rate / n > RTA_TARGET_BIN_HZ) n *= 2;
19
+ return n;
20
+ }
package/src/units.ts ADDED
@@ -0,0 +1,45 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ // Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
3
+ /** The dB and linear-amplitude twins of omx_units.h (omx_db_to_lin, omx_lin_to_db, omx_lin_to_db_d), moved verbatim from the console (its output routes). */
4
+
5
+ /**
6
+ * dB → linear amplitude (0 dB → 1, −6 dB → ~0.501). The trim/fold gain the engine applies.
7
+ *
8
+ * `-Infinity` dB → 0 falls out of the exponential itself (`10 ** -Infinity === 0`), so
9
+ * callers need no silence guard of their own.
10
+ */
11
+ export function dbToLinearGain(db: number): number {
12
+ return 10 ** (db / 20);
13
+ }
14
+
15
+ /**
16
+ * Linear amplitude → dB — the exact inverse of {@link dbToLinearGain}, and the reason this
17
+ * one exists: without it the inverse direction was hand-rolled at every call site, which is
18
+ * how three different silence conventions (`1e-12`, `1e-7`, `-60`) grew up elsewhere in the
19
+ * tree for what is nominally the same conversion.
20
+ *
21
+ * Silence and any non-positive amplitude read `-Infinity`, not NaN: `Math.log10` of a
22
+ * negative is NaN, and an amplitude below zero is a phase-inverted sample's magnitude
23
+ * mistake, not a level. Note this is the LEVEL conversion — an analyser floors its own
24
+ * spectrum at a chosen epsilon instead, deliberately, and should keep doing so.
25
+ */
26
+ export function linearGainToDb(linear: number): number {
27
+ return linear <= 0 ? -Infinity : 20 * Math.log10(linear);
28
+ }
29
+
30
+ /**
31
+ * The analysers' magnitude floor: an FFT bin or an envelope at exact zero reads −240 dB, below
32
+ * any real signal and finite for the growth and ratio arithmetic built on it (was the epsilon
33
+ * `1e-12` inside three analysers' logarithms).
34
+ */
35
+ export const ANALYSIS_FLOOR_DB = -240;
36
+
37
+ /**
38
+ * Linear amplitude → dB, never below `floorDb` — the conversion for a site whose floor is
39
+ * deliberate (an analyser's magnitude, a plot's axis, a meter that must stay finite). The floor
40
+ * is a named dB value, never an epsilon hidden inside the logarithm (`Math.max(x, 1e-12)` is
41
+ * `linearToDbFloored(x, -240)`); silence reads `floorDb`, not `-Infinity`.
42
+ */
43
+ export function linearToDbFloored(linear: number, floorDb: number): number {
44
+ return Math.max(floorDb, linearGainToDb(linear));
45
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.