omnivad 0.2.0 → 0.2.2
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/dist/index.cjs +106 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -6
- package/dist/index.d.ts +34 -6
- package/dist/index.js +103 -43
- package/dist/index.js.map +1 -1
- package/dist/wasm/omnivad.cjs +1 -1
- package/dist/wasm/omnivad.js +1 -1
- package/dist/wasm/omnivad.wasm +0 -0
- package/models/aed.omnivad +0 -0
- package/models/stream-vad.omnivad +0 -0
- package/models/vad.omnivad +0 -0
- package/package.json +3 -2
- package/dist/wasm/omnivad.data +0 -0
package/dist/index.cjs
CHANGED
|
@@ -8,6 +8,14 @@ var SIZEOF_POST_CONFIG = 28;
|
|
|
8
8
|
var SIZEOF_AED_POST_CONFIG = 3 * SIZEOF_POST_CONFIG;
|
|
9
9
|
var SIZEOF_SEGMENT = 8;
|
|
10
10
|
var SIZEOF_AED_SEGMENT = 16;
|
|
11
|
+
var OMNI_ERR_NO_FRAMES = -7;
|
|
12
|
+
var VERSION = "0.2.1";
|
|
13
|
+
var DEFAULT_CDN_BASE = `https://cdn.jsdelivr.net/npm/omnivad@${VERSION}/models`;
|
|
14
|
+
var MODEL_FILES = {
|
|
15
|
+
vad: "vad.omnivad",
|
|
16
|
+
"stream-vad": "stream-vad.omnivad",
|
|
17
|
+
aed: "aed.omnivad"
|
|
18
|
+
};
|
|
11
19
|
async function initWasm(wasmLocator) {
|
|
12
20
|
if (_module) return _module;
|
|
13
21
|
if (_loading) return _loading;
|
|
@@ -45,10 +53,53 @@ async function initWasm(wasmLocator) {
|
|
|
45
53
|
})();
|
|
46
54
|
return _loading;
|
|
47
55
|
}
|
|
56
|
+
async function loadModel(modelType, modelUrl, modelData) {
|
|
57
|
+
if (modelData) return modelData;
|
|
58
|
+
if (modelUrl) {
|
|
59
|
+
const resp2 = await fetch(modelUrl.toString());
|
|
60
|
+
if (!resp2.ok) throw new Error(`Failed to fetch model from ${modelUrl}: ${resp2.status}`);
|
|
61
|
+
return resp2.arrayBuffer();
|
|
62
|
+
}
|
|
63
|
+
const filename = MODEL_FILES[modelType];
|
|
64
|
+
if (typeof globalThis.process?.versions?.node === "string") {
|
|
65
|
+
const { createRequire } = await import(
|
|
66
|
+
/* webpackIgnore: true */
|
|
67
|
+
'module'
|
|
68
|
+
);
|
|
69
|
+
const { dirname, join } = await import('path');
|
|
70
|
+
const { readFile } = await import('fs/promises');
|
|
71
|
+
const req = createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
72
|
+
const pkgDir = dirname(req.resolve("../package.json"));
|
|
73
|
+
const modelPath = join(pkgDir, "models", filename);
|
|
74
|
+
const buf = await readFile(modelPath);
|
|
75
|
+
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
76
|
+
}
|
|
77
|
+
const url = `${DEFAULT_CDN_BASE}/${filename}`;
|
|
78
|
+
const resp = await fetch(url);
|
|
79
|
+
if (!resp.ok) throw new Error(`Failed to fetch model from ${url}: ${resp.status}`);
|
|
80
|
+
return resp.arrayBuffer();
|
|
81
|
+
}
|
|
48
82
|
function getModule() {
|
|
49
83
|
if (!_module) throw new Error("WASM not initialized. Call initWasm() first.");
|
|
50
84
|
return _module;
|
|
51
85
|
}
|
|
86
|
+
function readNativeError(M, code) {
|
|
87
|
+
const msg = M.ccall("omni_error_string", "string", ["number"], [code]);
|
|
88
|
+
return msg ? `${msg} (${code})` : `error ${code}`;
|
|
89
|
+
}
|
|
90
|
+
function createModel(M, fnName, argTypes, args, label) {
|
|
91
|
+
const errPtr = M._malloc(4);
|
|
92
|
+
try {
|
|
93
|
+
const handle = M.ccall(fnName, "number", [...argTypes, "number"], [...args, errPtr]);
|
|
94
|
+
if (!handle) {
|
|
95
|
+
const err = M.getValue(errPtr, "i32");
|
|
96
|
+
throw new Error(`Failed to create ${label} model: ${readNativeError(M, err)}`);
|
|
97
|
+
}
|
|
98
|
+
return handle;
|
|
99
|
+
} finally {
|
|
100
|
+
M._free(errPtr);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
52
103
|
function copyAudioToHeap(M, audio) {
|
|
53
104
|
const ptr = M._malloc(audio.length * 4);
|
|
54
105
|
const heap = new Float32Array(M.HEAPU8.buffer, ptr, audio.length);
|
|
@@ -73,15 +124,15 @@ var DEFAULT_VAD_CONFIG = {
|
|
|
73
124
|
mergeSilenceFrames: 0,
|
|
74
125
|
extendSpeechFrames: 0
|
|
75
126
|
};
|
|
76
|
-
function vadCreate(M,
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
[
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
127
|
+
function vadCreate(M, modelBuffer) {
|
|
128
|
+
const bytes = new Uint8Array(modelBuffer);
|
|
129
|
+
const ptr = M._malloc(bytes.length);
|
|
130
|
+
M.HEAPU8.set(bytes, ptr);
|
|
131
|
+
try {
|
|
132
|
+
return createModel(M, "omni_vad_create_from_buffer", ["number", "number"], [ptr, bytes.length], "VAD");
|
|
133
|
+
} finally {
|
|
134
|
+
M._free(ptr);
|
|
135
|
+
}
|
|
85
136
|
}
|
|
86
137
|
function readSegments(M, segPtrPtr, countPtr) {
|
|
87
138
|
const count = M.getValue(countPtr, "i32");
|
|
@@ -101,7 +152,7 @@ function vadDetect(M, handle, audioPtr, numSamples, cfg, format = "f32") {
|
|
|
101
152
|
const cfgPtr = M._malloc(SIZEOF_POST_CONFIG);
|
|
102
153
|
const segPtrPtr = M._malloc(4);
|
|
103
154
|
const countPtr = M._malloc(4);
|
|
104
|
-
const fn = format === "int16" ? "
|
|
155
|
+
const fn = format === "int16" ? "omni_vad_detect_int16" : "omni_vad_detect";
|
|
105
156
|
try {
|
|
106
157
|
writePostConfig(M, cfgPtr, cfg);
|
|
107
158
|
const ret = M.ccall(
|
|
@@ -119,24 +170,24 @@ function vadDetect(M, handle, audioPtr, numSamples, cfg, format = "f32") {
|
|
|
119
170
|
}
|
|
120
171
|
}
|
|
121
172
|
function vadDestroy(M, handle) {
|
|
122
|
-
M.ccall("
|
|
173
|
+
M.ccall("omni_vad_destroy", null, ["number"], [handle]);
|
|
123
174
|
}
|
|
124
175
|
var AED_CLASSES = { 0: "speech", 1: "singing", 2: "music" };
|
|
125
|
-
function aedCreate(M,
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
[
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
176
|
+
function aedCreate(M, modelBuffer) {
|
|
177
|
+
const bytes = new Uint8Array(modelBuffer);
|
|
178
|
+
const ptr = M._malloc(bytes.length);
|
|
179
|
+
M.HEAPU8.set(bytes, ptr);
|
|
180
|
+
try {
|
|
181
|
+
return createModel(M, "omni_aed_create_from_buffer", ["number", "number"], [ptr, bytes.length], "AED");
|
|
182
|
+
} finally {
|
|
183
|
+
M._free(ptr);
|
|
184
|
+
}
|
|
134
185
|
}
|
|
135
186
|
function aedDetect(M, handle, audioPtr, numSamples, cfg, format = "f32") {
|
|
136
187
|
const cfgPtr = M._malloc(SIZEOF_AED_POST_CONFIG);
|
|
137
188
|
const segPtrPtr = M._malloc(4);
|
|
138
189
|
const countPtr = M._malloc(4);
|
|
139
|
-
const fn = format === "int16" ? "
|
|
190
|
+
const fn = format === "int16" ? "omni_aed_detect_int16" : "omni_aed_detect";
|
|
140
191
|
try {
|
|
141
192
|
writePostConfig(M, cfgPtr, cfg.speech);
|
|
142
193
|
writePostConfig(M, cfgPtr + SIZEOF_POST_CONFIG, cfg.singing);
|
|
@@ -175,28 +226,34 @@ function aedDetect(M, handle, audioPtr, numSamples, cfg, format = "f32") {
|
|
|
175
226
|
}
|
|
176
227
|
}
|
|
177
228
|
function aedDestroy(M, handle) {
|
|
178
|
-
M.ccall("
|
|
229
|
+
M.ccall("omni_aed_destroy", null, ["number"], [handle]);
|
|
179
230
|
}
|
|
180
|
-
function streamVadCreate(M, threshold = 0.5
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
231
|
+
function streamVadCreate(M, modelBuffer, threshold = 0.5) {
|
|
232
|
+
const bytes = new Uint8Array(modelBuffer);
|
|
233
|
+
const ptr = M._malloc(bytes.length);
|
|
234
|
+
M.HEAPU8.set(bytes, ptr);
|
|
235
|
+
try {
|
|
236
|
+
return createModel(
|
|
237
|
+
M,
|
|
238
|
+
"omni_stream_vad_create_from_buffer",
|
|
239
|
+
["number", "number", "number"],
|
|
240
|
+
[ptr, bytes.length, threshold],
|
|
241
|
+
"StreamVAD"
|
|
242
|
+
);
|
|
243
|
+
} finally {
|
|
244
|
+
M._free(ptr);
|
|
245
|
+
}
|
|
189
246
|
}
|
|
190
247
|
function streamVadProcess(M, handle, pcm16Ptr, numSamples) {
|
|
191
248
|
const resultPtr = M._malloc(12);
|
|
192
249
|
try {
|
|
193
250
|
const ret = M.ccall(
|
|
194
|
-
"
|
|
251
|
+
"omni_stream_vad_process",
|
|
195
252
|
"number",
|
|
196
253
|
["number", "number", "number", "number"],
|
|
197
254
|
[handle, pcm16Ptr, numSamples, resultPtr]
|
|
198
255
|
);
|
|
199
|
-
if (ret ===
|
|
256
|
+
if (ret === OMNI_ERR_NO_FRAMES) return null;
|
|
200
257
|
if (ret !== 0) throw new Error(`StreamVAD process failed: ${ret}`);
|
|
201
258
|
return {
|
|
202
259
|
confidence: M.getValue(resultPtr, "float"),
|
|
@@ -208,10 +265,10 @@ function streamVadProcess(M, handle, pcm16Ptr, numSamples) {
|
|
|
208
265
|
}
|
|
209
266
|
}
|
|
210
267
|
function streamVadReset(M, handle) {
|
|
211
|
-
M.ccall("
|
|
268
|
+
M.ccall("omni_stream_vad_reset", null, ["number"], [handle]);
|
|
212
269
|
}
|
|
213
270
|
function streamVadDestroy(M, handle) {
|
|
214
|
-
M.ccall("
|
|
271
|
+
M.ccall("omni_stream_vad_destroy", null, ["number"], [handle]);
|
|
215
272
|
}
|
|
216
273
|
|
|
217
274
|
// src/vad.ts
|
|
@@ -223,12 +280,13 @@ var OmniVAD = class _OmniVAD {
|
|
|
223
280
|
}
|
|
224
281
|
/**
|
|
225
282
|
* Create a new OmniVAD instance.
|
|
226
|
-
*
|
|
283
|
+
* Loads model from CDN (browser), local package (Node.js), or custom source.
|
|
227
284
|
*/
|
|
228
285
|
static async create(options = {}) {
|
|
229
286
|
await initWasm();
|
|
230
287
|
const M = getModule();
|
|
231
|
-
const
|
|
288
|
+
const modelBuffer = await loadModel("vad", options.modelUrl, options.modelData);
|
|
289
|
+
const handle = vadCreate(M, modelBuffer);
|
|
232
290
|
const config = {
|
|
233
291
|
threshold: options.speechThreshold ?? DEFAULT_VAD_CONFIG.threshold,
|
|
234
292
|
smoothWindowSize: options.smoothWindowSize ?? DEFAULT_VAD_CONFIG.smoothWindowSize,
|
|
@@ -287,13 +345,14 @@ var OmniStreamVAD = class _OmniStreamVAD {
|
|
|
287
345
|
}
|
|
288
346
|
/**
|
|
289
347
|
* Create a new OmniStreamVAD instance.
|
|
290
|
-
*
|
|
348
|
+
* Loads model from CDN (browser), local package (Node.js), or custom source.
|
|
291
349
|
*/
|
|
292
350
|
static async create(options = {}) {
|
|
293
351
|
await initWasm();
|
|
294
352
|
const M = getModule();
|
|
353
|
+
const modelBuffer = await loadModel("stream-vad", options.modelUrl, options.modelData);
|
|
295
354
|
const threshold = options.speechThreshold ?? 0.5;
|
|
296
|
-
const handle = streamVadCreate(M, threshold);
|
|
355
|
+
const handle = streamVadCreate(M, modelBuffer, threshold);
|
|
297
356
|
return new _OmniStreamVAD(handle);
|
|
298
357
|
}
|
|
299
358
|
/**
|
|
@@ -346,7 +405,7 @@ var OmniStreamVAD = class _OmniStreamVAD {
|
|
|
346
405
|
const framesPtr = M._malloc(4);
|
|
347
406
|
try {
|
|
348
407
|
const ret = M.ccall(
|
|
349
|
-
"
|
|
408
|
+
"omni_stream_vad_detect_full",
|
|
350
409
|
"number",
|
|
351
410
|
["number", "number", "number", "number", "number"],
|
|
352
411
|
[this.handle, audioPtr, f32.length, probsPtrPtr, framesPtr]
|
|
@@ -418,12 +477,13 @@ var OmniAED = class _OmniAED {
|
|
|
418
477
|
}
|
|
419
478
|
/**
|
|
420
479
|
* Create a new OmniAED instance.
|
|
421
|
-
*
|
|
480
|
+
* Loads model from CDN (browser), local package (Node.js), or custom source.
|
|
422
481
|
*/
|
|
423
482
|
static async create(options = {}) {
|
|
424
483
|
await initWasm();
|
|
425
484
|
const M = getModule();
|
|
426
|
-
const
|
|
485
|
+
const modelBuffer = await loadModel("aed", options.modelUrl, options.modelData);
|
|
486
|
+
const handle = aedCreate(M, modelBuffer);
|
|
427
487
|
const base = {
|
|
428
488
|
smoothWindowSize: options.smoothWindowSize ?? DEFAULT_VAD_CONFIG.smoothWindowSize,
|
|
429
489
|
minSpeechFrames: options.minSpeechFrames ?? DEFAULT_VAD_CONFIG.minSpeechFrames,
|
|
@@ -493,12 +553,16 @@ function computeCoverageRatios(events, duration) {
|
|
|
493
553
|
return ratios;
|
|
494
554
|
}
|
|
495
555
|
|
|
556
|
+
exports.DEFAULT_CDN_BASE = DEFAULT_CDN_BASE;
|
|
496
557
|
exports.FireRedAED = OmniAED;
|
|
497
558
|
exports.FireRedStreamVAD = OmniStreamVAD;
|
|
498
559
|
exports.FireRedVAD = OmniVAD;
|
|
560
|
+
exports.MODEL_FILES = MODEL_FILES;
|
|
499
561
|
exports.OmniAED = OmniAED;
|
|
500
562
|
exports.OmniStreamVAD = OmniStreamVAD;
|
|
501
563
|
exports.OmniVAD = OmniVAD;
|
|
564
|
+
exports.VERSION = VERSION;
|
|
502
565
|
exports.initWasm = initWasm;
|
|
566
|
+
exports.loadModel = loadModel;
|
|
503
567
|
//# sourceMappingURL=index.cjs.map
|
|
504
568
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/wasm-binding.ts","../src/vad.ts","../src/stream-vad.ts","../src/aed.ts"],"names":["SAMPLE_RATE","prepareAudio","int16ToNormalizedFloat32"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Low-level WASM binding for omnivad C API.\n * Loads the Emscripten module and provides typed wrappers.\n */\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EmscriptenModule = any;\n\nlet _module: EmscriptenModule | null = null;\nlet _loading: Promise<EmscriptenModule> | null = null;\n\n/** Post-processing config matching C struct OmniPostConfig (7 x i32/float, 28 bytes) */\nexport interface PostConfig {\n threshold: number;\n smoothWindowSize: number;\n minSpeechFrames: number;\n minSilenceFrames: number;\n maxSpeechFrames: number;\n mergeSilenceFrames: number;\n extendSpeechFrames: number;\n}\n\nconst SIZEOF_POST_CONFIG = 28; // 7 * 4 bytes\nconst SIZEOF_AED_POST_CONFIG = 3 * SIZEOF_POST_CONFIG; // 84 bytes\nconst SIZEOF_SEGMENT = 8; // start(f32) + end(f32)\nconst SIZEOF_AED_SEGMENT = 16; // start(f32) + end(f32) + cls(i32) + confidence(f32)\n\n/**\n * Initialize the WASM module. Call once before using any other functions.\n * Safe to call multiple times (returns cached module).\n */\nexport async function initWasm(\n wasmLocator?: (filename: string) => string,\n): Promise<EmscriptenModule> {\n if (_module) return _module;\n if (_loading) return _loading;\n\n _loading = (async () => {\n // Dynamic import of the Emscripten glue\n let createOmniVAD: (opts?: Record<string, unknown>) => Promise<EmscriptenModule>;\n let defaultLocateFile: ((filename: string) => string) | undefined;\n\n if (typeof globalThis.process?.versions?.node === \"string\") {\n // Node.js: use require for .cjs (avoids ESM detection issues)\n const { createRequire } = await import(/* webpackIgnore: true */ \"module\");\n const { dirname, join } = await import(\"path\");\n const req = createRequire(import.meta.url);\n const gluePath = req.resolve(\"../dist/wasm/omnivad.cjs\");\n const wasmDir = dirname(gluePath);\n createOmniVAD = req(gluePath);\n defaultLocateFile = (filename: string) => join(wasmDir, filename);\n } else {\n // Browser: dynamic import\n const glueUrl = new URL(\"../dist/wasm/omnivad.js\", import.meta.url);\n const mod = await import(/* webpackIgnore: true */ glueUrl.href);\n createOmniVAD = mod.default || mod;\n const wasmBaseUrl = new URL(\"./\", glueUrl);\n defaultLocateFile = (filename: string) => new URL(filename, wasmBaseUrl).toString();\n }\n\n const opts: Record<string, unknown> = {};\n const locateFile = wasmLocator ?? defaultLocateFile;\n if (locateFile) {\n opts.locateFile = (path: string) => locateFile(path);\n }\n\n _module = await createOmniVAD(opts);\n return _module!;\n })();\n\n return _loading;\n}\n\n/** Get the initialized WASM module (throws if not initialized) */\nexport function getModule(): EmscriptenModule {\n if (!_module) throw new Error(\"WASM not initialized. Call initWasm() first.\");\n return _module;\n}\n\n// -------------------------------------------------------------------------- //\n// Memory helpers //\n// -------------------------------------------------------------------------- //\n\n/** Copy Float32Array audio into WASM heap, returns pointer. Caller must free. */\nexport function copyAudioToHeap(M: EmscriptenModule, audio: Float32Array): number {\n const ptr = M._malloc(audio.length * 4);\n const heap = new Float32Array(M.HEAPU8.buffer, ptr, audio.length);\n heap.set(audio);\n return ptr;\n}\n\n/** Write PostConfig struct to WASM heap at ptr */\nexport function writePostConfig(M: EmscriptenModule, ptr: number, cfg: PostConfig): void {\n M.setValue(ptr + 0, cfg.threshold, \"float\");\n M.setValue(ptr + 4, cfg.smoothWindowSize, \"i32\");\n M.setValue(ptr + 8, cfg.minSpeechFrames, \"i32\");\n M.setValue(ptr + 12, cfg.minSilenceFrames, \"i32\");\n M.setValue(ptr + 16, cfg.maxSpeechFrames, \"i32\");\n M.setValue(ptr + 20, cfg.mergeSilenceFrames, \"i32\");\n M.setValue(ptr + 24, cfg.extendSpeechFrames, \"i32\");\n}\n\nexport const DEFAULT_VAD_CONFIG: PostConfig = {\n threshold: 0.4,\n smoothWindowSize: 5,\n minSpeechFrames: 20,\n minSilenceFrames: 20,\n maxSpeechFrames: 2000,\n mergeSilenceFrames: 0,\n extendSpeechFrames: 0,\n};\n\n// -------------------------------------------------------------------------- //\n// Non-stream VAD //\n// -------------------------------------------------------------------------- //\n\nexport function vadCreate(M: EmscriptenModule, bundlePath = \"models/vad.omnivad\"): number {\n const handle = M.ccall(\n \"omni_vad_nonstream_create_from_bundle\",\n \"number\",\n [\"string\"],\n [bundlePath],\n );\n if (!handle) throw new Error(\"Failed to create VAD model\");\n return handle;\n}\n\n/**\n * Audio format: two types only.\n * \"f32\" — float* in [-1.0, 1.0] (Web Audio API, soundfile, torch)\n * \"int16\" — int16_t* PCM (WAV files, microphones)\n */\nexport type AudioFormat = \"f32\" | \"int16\";\n\nfunction readSegments(M: EmscriptenModule, segPtrPtr: number, countPtr: number): Array<[number, number]> {\n const count = M.getValue(countPtr, \"i32\");\n const segPtr = M.getValue(segPtrPtr, \"i32\");\n const segments: Array<[number, number]> = [];\n for (let i = 0; i < count; i++) {\n const base = segPtr + i * SIZEOF_SEGMENT;\n segments.push([\n Math.round(M.getValue(base, \"float\") * 1000) / 1000,\n Math.round(M.getValue(base + 4, \"float\") * 1000) / 1000,\n ]);\n }\n if (segPtr) M._free(segPtr);\n return segments;\n}\n\nexport function vadDetect(\n M: EmscriptenModule,\n handle: number,\n audioPtr: number,\n numSamples: number,\n cfg: PostConfig,\n format: AudioFormat = \"f32\",\n): Array<[number, number]> {\n const cfgPtr = M._malloc(SIZEOF_POST_CONFIG);\n const segPtrPtr = M._malloc(4);\n const countPtr = M._malloc(4);\n const fn = format === \"int16\" ? \"omni_vad_nonstream_process_int16\" : \"omni_vad_nonstream_process\";\n\n try {\n writePostConfig(M, cfgPtr, cfg);\n const ret = M.ccall(\n fn,\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\", \"number\"],\n [handle, audioPtr, numSamples, cfgPtr, segPtrPtr, countPtr],\n );\n if (ret !== 0) throw new Error(`VAD detect failed: ${ret}`);\n return readSegments(M, segPtrPtr, countPtr);\n } finally {\n M._free(cfgPtr);\n M._free(segPtrPtr);\n M._free(countPtr);\n }\n}\n\nexport function vadDestroy(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_vad_nonstream_destroy\", null, [\"number\"], [handle]);\n}\n\n// -------------------------------------------------------------------------- //\n// Non-stream AED //\n// -------------------------------------------------------------------------- //\n\nconst AED_CLASSES: Record<number, string> = { 0: \"speech\", 1: \"singing\", 2: \"music\" };\n\nexport function aedCreate(M: EmscriptenModule, bundlePath = \"models/aed.omnivad\"): number {\n const handle = M.ccall(\n \"omni_aed_nonstream_create_from_bundle\",\n \"number\",\n [\"string\"],\n [bundlePath],\n );\n if (!handle) throw new Error(\"Failed to create AED model\");\n return handle;\n}\n\nexport interface AedPostConfig {\n speech: PostConfig;\n singing: PostConfig;\n music: PostConfig;\n}\n\nexport function aedDetect(\n M: EmscriptenModule,\n handle: number,\n audioPtr: number,\n numSamples: number,\n cfg: AedPostConfig,\n format: AudioFormat = \"f32\",\n): Record<string, Array<[number, number]>> {\n const cfgPtr = M._malloc(SIZEOF_AED_POST_CONFIG);\n const segPtrPtr = M._malloc(4);\n const countPtr = M._malloc(4);\n const fn = format === \"int16\" ? \"omni_aed_nonstream_process_int16\" : \"omni_aed_nonstream_process\";\n\n try {\n writePostConfig(M, cfgPtr, cfg.speech);\n writePostConfig(M, cfgPtr + SIZEOF_POST_CONFIG, cfg.singing);\n writePostConfig(M, cfgPtr + 2 * SIZEOF_POST_CONFIG, cfg.music);\n\n const ret = M.ccall(\n fn,\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\", \"number\"],\n [handle, audioPtr, numSamples, cfgPtr, segPtrPtr, countPtr],\n );\n if (ret !== 0) throw new Error(`AED detect failed: ${ret}`);\n\n const count = M.getValue(countPtr, \"i32\");\n const segPtr = M.getValue(segPtrPtr, \"i32\");\n const events: Record<string, Array<[number, number]>> = {\n speech: [],\n singing: [],\n music: [],\n };\n for (let i = 0; i < count; i++) {\n const base = segPtr + i * SIZEOF_AED_SEGMENT;\n const cls = M.getValue(base + 8, \"i32\");\n const name = AED_CLASSES[cls];\n if (name && events[name]) {\n events[name].push([\n Math.round(M.getValue(base, \"float\") * 1000) / 1000,\n Math.round(M.getValue(base + 4, \"float\") * 1000) / 1000,\n ]);\n }\n }\n if (segPtr) M._free(segPtr);\n return events;\n } finally {\n M._free(cfgPtr);\n M._free(segPtrPtr);\n M._free(countPtr);\n }\n}\n\nexport function aedDestroy(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_aed_nonstream_destroy\", null, [\"number\"], [handle]);\n}\n\n// -------------------------------------------------------------------------- //\n// Stream VAD //\n// -------------------------------------------------------------------------- //\n\nexport function streamVadCreate(\n M: EmscriptenModule,\n threshold = 0.5,\n bundlePath = \"models/stream-vad.omnivad\",\n): number {\n const handle = M.ccall(\n \"omni_vad_stream_create_from_bundle\",\n \"number\",\n [\"string\", \"number\"],\n [bundlePath, threshold],\n );\n if (!handle) throw new Error(\"Failed to create StreamVAD model\");\n return handle;\n}\n\nexport interface StreamVadResult {\n confidence: number;\n isSpeech: boolean;\n frameOffset: number;\n}\n\n/** Process one chunk of int16 PCM (160 samples = 10ms). Returns null if buffering. */\nexport function streamVadProcess(\n M: EmscriptenModule,\n handle: number,\n pcm16Ptr: number,\n numSamples: number,\n): StreamVadResult | null {\n // OmniVadStreamResult: { float confidence, bool is_speech, int frame_offset } = 12 bytes\n const resultPtr = M._malloc(12);\n try {\n const ret = M.ccall(\n \"omni_vad_stream_process\",\n \"number\",\n [\"number\", \"number\", \"number\", \"number\"],\n [handle, pcm16Ptr, numSamples, resultPtr],\n );\n if (ret === -6) return null; // OMNI_ERR_NO_FRAMES\n if (ret !== 0) throw new Error(`StreamVAD process failed: ${ret}`);\n return {\n confidence: M.getValue(resultPtr, \"float\"),\n isSpeech: M.getValue(resultPtr + 4, \"i8\") !== 0,\n frameOffset: M.getValue(resultPtr + 8, \"i32\"),\n };\n } finally {\n M._free(resultPtr);\n }\n}\n\nexport function streamVadReset(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_vad_stream_reset\", null, [\"number\"], [handle]);\n}\n\nexport function streamVadDestroy(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_vad_stream_destroy\", null, [\"number\"], [handle]);\n}\n","/**\n * Non-streaming Voice Activity Detection (WASM/ncnn backend).\n *\n * Audio format:\n * - Int16Array: raw 16-bit PCM, converted to normalized float internally\n * - Float32Array in [-1.0, 1.0]: normalized audio (Web Audio API format)\n */\n\nimport type { VADConfig, VADResult } from \"./types.js\";\nimport {\n initWasm,\n getModule,\n copyAudioToHeap,\n vadCreate,\n vadDetect,\n vadDestroy,\n DEFAULT_VAD_CONFIG,\n type AudioFormat,\n type PostConfig,\n} from \"./wasm-binding.js\";\n\nconst SAMPLE_RATE = 16000;\n\nexport class OmniVAD {\n private handle: number;\n private config: PostConfig;\n\n private constructor(handle: number, config: PostConfig) {\n this.handle = handle;\n this.config = config;\n }\n\n /**\n * Create a new OmniVAD instance.\n * Initializes WASM and loads the bundled ncnn model.\n */\n static async create(options: VADConfig = {}): Promise<OmniVAD> {\n await initWasm();\n const M = getModule();\n const handle = vadCreate(M);\n const config: PostConfig = {\n threshold: options.speechThreshold ?? DEFAULT_VAD_CONFIG.threshold,\n smoothWindowSize: options.smoothWindowSize ?? DEFAULT_VAD_CONFIG.smoothWindowSize,\n minSpeechFrames: options.minSpeechFrames ?? DEFAULT_VAD_CONFIG.minSpeechFrames,\n minSilenceFrames: options.minSilenceFrames ?? DEFAULT_VAD_CONFIG.minSilenceFrames,\n maxSpeechFrames: options.maxSpeechFrames ?? DEFAULT_VAD_CONFIG.maxSpeechFrames,\n mergeSilenceFrames: options.mergeSilenceFrames ?? DEFAULT_VAD_CONFIG.mergeSilenceFrames,\n extendSpeechFrames: options.extendSpeechFrames ?? DEFAULT_VAD_CONFIG.extendSpeechFrames,\n };\n return new OmniVAD(handle, config);\n }\n\n /**\n * Detect speech segments in audio.\n *\n * Accepts Int16Array (PCM) or normalized Float32Array in [-1, 1].\n */\n detect(audio: Float32Array | Int16Array): VADResult {\n const M = getModule();\n const { ptr, length, format } = prepareAudio(M, audio);\n\n try {\n const timestamps = vadDetect(M, this.handle, ptr, length, this.config, format);\n return {\n duration: Math.round((length / SAMPLE_RATE) * 1000) / 1000,\n timestamps,\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /** Release native resources. */\n dispose(): void {\n if (this.handle) {\n vadDestroy(getModule(), this.handle);\n this.handle = 0;\n }\n }\n}\n\n/** Copy audio to WASM heap as normalized float audio. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction prepareAudio(M: any, audio: Float32Array | Int16Array): { ptr: number; length: number; format: AudioFormat } {\n const f32 = audio instanceof Int16Array ? int16ToNormalizedFloat32(audio) : audio;\n const ptr = copyAudioToHeap(M, f32);\n return { ptr, length: f32.length, format: \"f32\" };\n}\n\nfunction int16ToNormalizedFloat32(i16: Int16Array): Float32Array {\n const f32 = new Float32Array(i16.length);\n for (let i = 0; i < i16.length; i++) f32[i] = i16[i] / 32768;\n return f32;\n}\n","/**\n * Streaming Voice Activity Detection (WASM/ncnn backend).\n * Processes audio frame-by-frame (10ms chunks of 160 samples @ 16kHz).\n */\n\nimport type { StreamVADConfig, StreamVADFrameResult, StreamVADFullResult } from \"./types.js\";\nimport {\n initWasm,\n getModule,\n copyAudioToHeap,\n streamVadCreate,\n streamVadProcess,\n streamVadReset,\n streamVadDestroy,\n} from \"./wasm-binding.js\";\n\nconst SAMPLE_RATE = 16000;\n\nexport class OmniStreamVAD {\n private handle: number;\n private inSpeech = false;\n private speechStartFrame = 0;\n\n private constructor(handle: number) {\n this.handle = handle;\n }\n\n /**\n * Create a new OmniStreamVAD instance.\n * Initializes WASM and loads the bundled ncnn model.\n */\n static async create(options: StreamVADConfig = {}): Promise<OmniStreamVAD> {\n await initWasm();\n const M = getModule();\n const threshold = options.speechThreshold ?? 0.5;\n const handle = streamVadCreate(M, threshold);\n return new OmniStreamVAD(handle);\n }\n\n /**\n * Process one frame of audio (160 int16 samples = 10ms @ 16kHz).\n * Returns null until enough audio is accumulated.\n */\n processFrame(pcm160: Int16Array): StreamVADFrameResult | null {\n const M = getModule();\n const ptr = M._malloc(pcm160.length * 2);\n const heap16 = new Int16Array(M.HEAPU8.buffer, ptr, pcm160.length);\n heap16.set(pcm160);\n\n try {\n const result = streamVadProcess(M, this.handle, ptr, pcm160.length);\n if (!result || result.frameOffset === 0) return null;\n\n const frameIndex = result.frameOffset;\n const isSpeechStart = result.isSpeech && !this.inSpeech;\n const isSpeechEnd = !result.isSpeech && this.inSpeech;\n\n if (isSpeechStart) {\n this.speechStartFrame = frameIndex;\n }\n\n const activeSpeechStartFrame = isSpeechEnd ? this.speechStartFrame : result.isSpeech ? this.speechStartFrame : 0;\n const speechEndFrame = isSpeechEnd ? Math.max(1, frameIndex - 1) : 0;\n\n this.inSpeech = result.isSpeech;\n if (isSpeechEnd) {\n this.speechStartFrame = 0;\n }\n\n return {\n confidence: result.confidence,\n smoothedConfidence: result.confidence,\n isSpeech: result.isSpeech,\n frameIndex,\n isSpeechStart,\n isSpeechEnd,\n speechStartFrame: activeSpeechStartFrame,\n speechEndFrame,\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /**\n * Process entire audio at once and return per-frame probabilities.\n * @param audio - Float32Array in [-1, 1] or Int16Array of 16kHz mono PCM\n */\n detectFull(audio: Float32Array | Int16Array): StreamVADFullResult {\n const M = getModule();\n const f32 = prepareDetectFullAudio(audio);\n const audioPtr = copyAudioToHeap(M, f32);\n const probsPtrPtr = M._malloc(4);\n const framesPtr = M._malloc(4);\n\n try {\n const ret = M.ccall(\n \"omni_vad_stream_detect_full\",\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\"],\n [this.handle, audioPtr, f32.length, probsPtrPtr, framesPtr],\n );\n if (ret !== 0) throw new Error(`StreamVAD detectFull failed: ${ret}`);\n\n const numFrames = M.getValue(framesPtr, \"i32\");\n const probsPtr = M.getValue(probsPtrPtr, \"i32\");\n const probabilities = probsPtr\n ? new Float32Array(new Float32Array(M.HEAPU8.buffer, probsPtr, numFrames))\n : new Float32Array(0);\n if (probsPtr) M._free(probsPtr);\n\n return {\n probabilities,\n numFrames,\n duration: Math.round((f32.length / SAMPLE_RATE) * 1000) / 1000,\n };\n } finally {\n M._free(audioPtr);\n M._free(probsPtrPtr);\n M._free(framesPtr);\n }\n }\n\n /** Reset all internal state. */\n reset(): void {\n streamVadReset(getModule(), this.handle);\n this.inSpeech = false;\n this.speechStartFrame = 0;\n }\n\n /** Release native resources. */\n dispose(): void {\n if (this.handle) {\n streamVadDestroy(getModule(), this.handle);\n this.handle = 0;\n }\n this.inSpeech = false;\n this.speechStartFrame = 0;\n }\n}\n\nfunction int16ToFloat32(i16: Int16Array): Float32Array {\n const f32 = new Float32Array(i16.length);\n for (let i = 0; i < i16.length; i++) f32[i] = i16[i];\n return f32;\n}\n\nfunction prepareDetectFullAudio(audio: Float32Array | Int16Array): Float32Array {\n if (audio instanceof Int16Array) {\n return int16ToFloat32(audio);\n }\n if (isNormalizedFloat(audio)) {\n const scaled = new Float32Array(audio.length);\n for (let i = 0; i < audio.length; i++) scaled[i] = audio[i] * 32768;\n return scaled;\n }\n return audio;\n}\n\nfunction isNormalizedFloat(audio: Float32Array): boolean {\n const step = Math.max(1, Math.floor(audio.length / 1000));\n let maxAbs = 0;\n for (let i = 0; i < audio.length; i += step) {\n const v = Math.abs(audio[i]);\n if (v > maxAbs) maxAbs = v;\n }\n return maxAbs <= 1.0;\n}\n","/**\n * Audio Event Detection: speech, singing, music (WASM/ncnn backend).\n *\n * Audio format: same as OmniVAD — Int16Array or normalized Float32Array [-1, 1].\n */\n\nimport type { AEDConfig, AEDResult } from \"./types.js\";\nimport {\n initWasm,\n getModule,\n aedCreate,\n aedDetect,\n aedDestroy,\n DEFAULT_VAD_CONFIG,\n type AudioFormat,\n type AedPostConfig,\n} from \"./wasm-binding.js\";\n\nconst SAMPLE_RATE = 16000;\n\nexport class OmniAED {\n private handle: number;\n private config: AedPostConfig;\n\n private constructor(handle: number, config: AedPostConfig) {\n this.handle = handle;\n this.config = config;\n }\n\n /**\n * Create a new OmniAED instance.\n * Initializes WASM and loads the bundled ncnn model.\n */\n static async create(options: AEDConfig = {}): Promise<OmniAED> {\n await initWasm();\n const M = getModule();\n const handle = aedCreate(M);\n\n const base = {\n smoothWindowSize: options.smoothWindowSize ?? DEFAULT_VAD_CONFIG.smoothWindowSize,\n minSpeechFrames: options.minSpeechFrames ?? DEFAULT_VAD_CONFIG.minSpeechFrames,\n minSilenceFrames: options.minSilenceFrames ?? DEFAULT_VAD_CONFIG.minSilenceFrames,\n maxSpeechFrames: options.maxSpeechFrames ?? DEFAULT_VAD_CONFIG.maxSpeechFrames,\n mergeSilenceFrames: options.mergeSilenceFrames ?? DEFAULT_VAD_CONFIG.mergeSilenceFrames,\n extendSpeechFrames: options.extendSpeechFrames ?? DEFAULT_VAD_CONFIG.extendSpeechFrames,\n };\n\n const config: AedPostConfig = {\n speech: { ...base, threshold: options.speechThreshold ?? 0.4 },\n singing: { ...base, threshold: options.singingThreshold ?? 0.5 },\n music: { ...base, threshold: options.musicThreshold ?? 0.5 },\n };\n return new OmniAED(handle, config);\n }\n\n /**\n * Detect audio events (speech, singing, music).\n *\n * Accepts Int16Array (PCM) or normalized Float32Array in [-1, 1].\n */\n detect(audio: Float32Array | Int16Array): AEDResult {\n const M = getModule();\n const { ptr, length, format } = prepareAudio(M, audio);\n const duration = Math.round((length / SAMPLE_RATE) * 1000) / 1000;\n\n try {\n const events = aedDetect(M, this.handle, ptr, length, this.config, format);\n return {\n duration,\n events,\n ratios: computeCoverageRatios(events, duration),\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /** Release native resources. */\n dispose(): void {\n if (this.handle) {\n aedDestroy(getModule(), this.handle);\n this.handle = 0;\n }\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction prepareAudio(M: any, audio: Float32Array | Int16Array): { ptr: number; length: number; format: AudioFormat } {\n const f32 = audio instanceof Int16Array ? int16ToNormalizedFloat32(audio) : audio;\n const ptr = M._malloc(f32.length * 4);\n const heap = new Float32Array(M.HEAPU8.buffer, ptr, f32.length);\n heap.set(f32);\n return { ptr, length: f32.length, format: \"f32\" };\n}\n\nfunction int16ToNormalizedFloat32(i16: Int16Array): Float32Array {\n const f32 = new Float32Array(i16.length);\n for (let i = 0; i < i16.length; i++) f32[i] = i16[i] / 32768;\n return f32;\n}\n\nfunction computeCoverageRatios(\n events: Record<string, Array<[number, number]>>,\n duration: number,\n): Record<string, number> {\n const ratios: Record<string, number> = {\n speech: 0,\n singing: 0,\n music: 0,\n };\n\n if (duration <= 0) return ratios;\n\n for (const cls of Object.keys(ratios)) {\n const covered = (events[cls] ?? []).reduce((sum, [start, end]) => sum + Math.max(0, end - start), 0);\n ratios[cls] = Math.round(Math.min(1, covered / duration) * 1e6) / 1e6;\n }\n\n return ratios;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/wasm-binding.ts","../src/vad.ts","../src/stream-vad.ts","../src/aed.ts"],"names":["resp","SAMPLE_RATE","prepareAudio","int16ToNormalizedFloat32"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Low-level WASM binding for omnivad C API.\n * Loads the Emscripten module and provides typed wrappers.\n */\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EmscriptenModule = any;\n\nlet _module: EmscriptenModule | null = null;\nlet _loading: Promise<EmscriptenModule> | null = null;\n\n/** Post-processing config matching C struct OmniPostConfig (7 x i32/float, 28 bytes) */\nexport interface PostConfig {\n threshold: number;\n smoothWindowSize: number;\n minSpeechFrames: number;\n minSilenceFrames: number;\n maxSpeechFrames: number;\n mergeSilenceFrames: number;\n extendSpeechFrames: number;\n}\n\nconst SIZEOF_POST_CONFIG = 28; // 7 * 4 bytes\nconst SIZEOF_AED_POST_CONFIG = 3 * SIZEOF_POST_CONFIG; // 84 bytes\nconst SIZEOF_SEGMENT = 8; // start(f32) + end(f32)\nconst SIZEOF_AED_SEGMENT = 16; // start(f32) + end(f32) + cls(i32) + confidence(f32)\nconst OMNI_ERR_NO_FRAMES = -7;\n\n/** Package version — used to construct default CDN URLs. */\nexport const VERSION = \"0.2.1\";\n\n/** Default CDN base for model files (jsDelivr serves npm package contents). */\nexport const DEFAULT_CDN_BASE = `https://cdn.jsdelivr.net/npm/omnivad@${VERSION}/models`;\n\n/** Model filenames keyed by type. */\nexport const MODEL_FILES = {\n vad: \"vad.omnivad\",\n \"stream-vad\": \"stream-vad.omnivad\",\n aed: \"aed.omnivad\",\n} as const;\n\nexport type ModelType = keyof typeof MODEL_FILES;\n\n/**\n * Initialize the WASM module. Call once before using any other functions.\n * Safe to call multiple times (returns cached module).\n */\nexport async function initWasm(\n wasmLocator?: (filename: string) => string,\n): Promise<EmscriptenModule> {\n if (_module) return _module;\n if (_loading) return _loading;\n\n _loading = (async () => {\n // Dynamic import of the Emscripten glue\n let createOmniVAD: (opts?: Record<string, unknown>) => Promise<EmscriptenModule>;\n let defaultLocateFile: ((filename: string) => string) | undefined;\n\n if (typeof globalThis.process?.versions?.node === \"string\") {\n // Node.js: use require for .cjs (avoids ESM detection issues)\n const { createRequire } = await import(/* webpackIgnore: true */ \"module\");\n const { dirname, join } = await import(\"path\");\n const req = createRequire(import.meta.url);\n const gluePath = req.resolve(\"../dist/wasm/omnivad.cjs\");\n const wasmDir = dirname(gluePath);\n createOmniVAD = req(gluePath);\n defaultLocateFile = (filename: string) => join(wasmDir, filename);\n } else {\n // Browser: dynamic import\n const glueUrl = new URL(\"../dist/wasm/omnivad.js\", import.meta.url);\n const mod = await import(/* webpackIgnore: true */ glueUrl.href);\n createOmniVAD = mod.default || mod;\n const wasmBaseUrl = new URL(\"./\", glueUrl);\n defaultLocateFile = (filename: string) => new URL(filename, wasmBaseUrl).toString();\n }\n\n const opts: Record<string, unknown> = {};\n const locateFile = wasmLocator ?? defaultLocateFile;\n if (locateFile) {\n opts.locateFile = (path: string) => locateFile(path);\n }\n\n _module = await createOmniVAD(opts);\n return _module!;\n })();\n\n return _loading;\n}\n\n/**\n * Load a model file as ArrayBuffer.\n *\n * Resolution order:\n * 1. modelData (ArrayBuffer) — use directly\n * 2. modelUrl (string/URL) — fetch from that URL\n * 3. Node.js — read from npm package's models/ directory\n * 4. Browser — fetch from jsDelivr CDN\n */\nexport async function loadModel(\n modelType: ModelType,\n modelUrl?: string | URL,\n modelData?: ArrayBuffer,\n): Promise<ArrayBuffer> {\n if (modelData) return modelData;\n\n if (modelUrl) {\n const resp = await fetch(modelUrl.toString());\n if (!resp.ok) throw new Error(`Failed to fetch model from ${modelUrl}: ${resp.status}`);\n return resp.arrayBuffer();\n }\n\n const filename = MODEL_FILES[modelType];\n\n if (typeof globalThis.process?.versions?.node === \"string\") {\n // Node.js: read from package's models/ directory\n const { createRequire } = await import(/* webpackIgnore: true */ \"module\");\n const { dirname, join } = await import(\"path\");\n const { readFile } = await import(\"fs/promises\");\n const req = createRequire(import.meta.url);\n const pkgDir = dirname(req.resolve(\"../package.json\"));\n const modelPath = join(pkgDir, \"models\", filename);\n const buf = await readFile(modelPath);\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n }\n\n // Browser: fetch from CDN\n const url = `${DEFAULT_CDN_BASE}/${filename}`;\n const resp = await fetch(url);\n if (!resp.ok) throw new Error(`Failed to fetch model from ${url}: ${resp.status}`);\n return resp.arrayBuffer();\n}\n\n/** Get the initialized WASM module (throws if not initialized) */\nexport function getModule(): EmscriptenModule {\n if (!_module) throw new Error(\"WASM not initialized. Call initWasm() first.\");\n return _module;\n}\n\nfunction readNativeError(M: EmscriptenModule, code: number): string {\n const msg = M.ccall(\"omni_error_string\", \"string\", [\"number\"], [code]);\n return msg ? `${msg} (${code})` : `error ${code}`;\n}\n\n/** Shared helper: call a C create function with out_error, throw on failure. */\nfunction createModel(\n M: EmscriptenModule,\n fnName: string,\n argTypes: string[],\n args: unknown[],\n label: string,\n): number {\n const errPtr = M._malloc(4);\n try {\n const handle = M.ccall(fnName, \"number\", [...argTypes, \"number\"], [...args, errPtr]);\n if (!handle) {\n const err = M.getValue(errPtr, \"i32\");\n throw new Error(`Failed to create ${label} model: ${readNativeError(M, err)}`);\n }\n return handle;\n } finally {\n M._free(errPtr);\n }\n}\n\n// -------------------------------------------------------------------------- //\n// Memory helpers //\n// -------------------------------------------------------------------------- //\n\n/** Copy Float32Array audio into WASM heap, returns pointer. Caller must free. */\nexport function copyAudioToHeap(M: EmscriptenModule, audio: Float32Array): number {\n const ptr = M._malloc(audio.length * 4);\n const heap = new Float32Array(M.HEAPU8.buffer, ptr, audio.length);\n heap.set(audio);\n return ptr;\n}\n\n/** Write PostConfig struct to WASM heap at ptr */\nexport function writePostConfig(M: EmscriptenModule, ptr: number, cfg: PostConfig): void {\n M.setValue(ptr + 0, cfg.threshold, \"float\");\n M.setValue(ptr + 4, cfg.smoothWindowSize, \"i32\");\n M.setValue(ptr + 8, cfg.minSpeechFrames, \"i32\");\n M.setValue(ptr + 12, cfg.minSilenceFrames, \"i32\");\n M.setValue(ptr + 16, cfg.maxSpeechFrames, \"i32\");\n M.setValue(ptr + 20, cfg.mergeSilenceFrames, \"i32\");\n M.setValue(ptr + 24, cfg.extendSpeechFrames, \"i32\");\n}\n\nexport const DEFAULT_VAD_CONFIG: PostConfig = {\n threshold: 0.4,\n smoothWindowSize: 5,\n minSpeechFrames: 20,\n minSilenceFrames: 20,\n maxSpeechFrames: 2000,\n mergeSilenceFrames: 0,\n extendSpeechFrames: 0,\n};\n\n// -------------------------------------------------------------------------- //\n// Non-stream VAD //\n// -------------------------------------------------------------------------- //\n\nexport function vadCreate(M: EmscriptenModule, modelBuffer: ArrayBuffer): number {\n const bytes = new Uint8Array(modelBuffer);\n const ptr = M._malloc(bytes.length);\n M.HEAPU8.set(bytes, ptr);\n try {\n return createModel(M, \"omni_vad_create_from_buffer\", [\"number\", \"number\"], [ptr, bytes.length], \"VAD\");\n } finally {\n M._free(ptr);\n }\n}\n\n/**\n * Audio format: two types only.\n * \"f32\" — float* in [-1.0, 1.0] (Web Audio API, soundfile, torch)\n * \"int16\" — int16_t* PCM (WAV files, microphones)\n */\nexport type AudioFormat = \"f32\" | \"int16\";\n\nfunction readSegments(M: EmscriptenModule, segPtrPtr: number, countPtr: number): Array<[number, number]> {\n const count = M.getValue(countPtr, \"i32\");\n const segPtr = M.getValue(segPtrPtr, \"i32\");\n const segments: Array<[number, number]> = [];\n for (let i = 0; i < count; i++) {\n const base = segPtr + i * SIZEOF_SEGMENT;\n segments.push([\n Math.round(M.getValue(base, \"float\") * 1000) / 1000,\n Math.round(M.getValue(base + 4, \"float\") * 1000) / 1000,\n ]);\n }\n if (segPtr) M._free(segPtr);\n return segments;\n}\n\nexport function vadDetect(\n M: EmscriptenModule,\n handle: number,\n audioPtr: number,\n numSamples: number,\n cfg: PostConfig,\n format: AudioFormat = \"f32\",\n): Array<[number, number]> {\n const cfgPtr = M._malloc(SIZEOF_POST_CONFIG);\n const segPtrPtr = M._malloc(4);\n const countPtr = M._malloc(4);\n const fn = format === \"int16\" ? \"omni_vad_detect_int16\" : \"omni_vad_detect\";\n\n try {\n writePostConfig(M, cfgPtr, cfg);\n const ret = M.ccall(\n fn,\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\", \"number\"],\n [handle, audioPtr, numSamples, cfgPtr, segPtrPtr, countPtr],\n );\n if (ret !== 0) throw new Error(`VAD detect failed: ${ret}`);\n return readSegments(M, segPtrPtr, countPtr);\n } finally {\n M._free(cfgPtr);\n M._free(segPtrPtr);\n M._free(countPtr);\n }\n}\n\nexport function vadDestroy(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_vad_destroy\", null, [\"number\"], [handle]);\n}\n\n// -------------------------------------------------------------------------- //\n// Non-stream AED //\n// -------------------------------------------------------------------------- //\n\nconst AED_CLASSES: Record<number, string> = { 0: \"speech\", 1: \"singing\", 2: \"music\" };\n\nexport function aedCreate(M: EmscriptenModule, modelBuffer: ArrayBuffer): number {\n const bytes = new Uint8Array(modelBuffer);\n const ptr = M._malloc(bytes.length);\n M.HEAPU8.set(bytes, ptr);\n try {\n return createModel(M, \"omni_aed_create_from_buffer\", [\"number\", \"number\"], [ptr, bytes.length], \"AED\");\n } finally {\n M._free(ptr);\n }\n}\n\nexport interface AedPostConfig {\n speech: PostConfig;\n singing: PostConfig;\n music: PostConfig;\n}\n\nexport function aedDetect(\n M: EmscriptenModule,\n handle: number,\n audioPtr: number,\n numSamples: number,\n cfg: AedPostConfig,\n format: AudioFormat = \"f32\",\n): Record<string, Array<[number, number]>> {\n const cfgPtr = M._malloc(SIZEOF_AED_POST_CONFIG);\n const segPtrPtr = M._malloc(4);\n const countPtr = M._malloc(4);\n const fn = format === \"int16\" ? \"omni_aed_detect_int16\" : \"omni_aed_detect\";\n\n try {\n writePostConfig(M, cfgPtr, cfg.speech);\n writePostConfig(M, cfgPtr + SIZEOF_POST_CONFIG, cfg.singing);\n writePostConfig(M, cfgPtr + 2 * SIZEOF_POST_CONFIG, cfg.music);\n\n const ret = M.ccall(\n fn,\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\", \"number\"],\n [handle, audioPtr, numSamples, cfgPtr, segPtrPtr, countPtr],\n );\n if (ret !== 0) throw new Error(`AED detect failed: ${ret}`);\n\n const count = M.getValue(countPtr, \"i32\");\n const segPtr = M.getValue(segPtrPtr, \"i32\");\n const events: Record<string, Array<[number, number]>> = {\n speech: [],\n singing: [],\n music: [],\n };\n for (let i = 0; i < count; i++) {\n const base = segPtr + i * SIZEOF_AED_SEGMENT;\n const cls = M.getValue(base + 8, \"i32\");\n const name = AED_CLASSES[cls];\n if (name && events[name]) {\n events[name].push([\n Math.round(M.getValue(base, \"float\") * 1000) / 1000,\n Math.round(M.getValue(base + 4, \"float\") * 1000) / 1000,\n ]);\n }\n }\n if (segPtr) M._free(segPtr);\n return events;\n } finally {\n M._free(cfgPtr);\n M._free(segPtrPtr);\n M._free(countPtr);\n }\n}\n\nexport function aedDestroy(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_aed_destroy\", null, [\"number\"], [handle]);\n}\n\n// -------------------------------------------------------------------------- //\n// Stream VAD //\n// -------------------------------------------------------------------------- //\n\nexport function streamVadCreate(\n M: EmscriptenModule,\n modelBuffer: ArrayBuffer,\n threshold = 0.5,\n): number {\n const bytes = new Uint8Array(modelBuffer);\n const ptr = M._malloc(bytes.length);\n M.HEAPU8.set(bytes, ptr);\n try {\n return createModel(\n M,\n \"omni_stream_vad_create_from_buffer\",\n [\"number\", \"number\", \"number\"],\n [ptr, bytes.length, threshold],\n \"StreamVAD\",\n );\n } finally {\n M._free(ptr);\n }\n}\n\nexport interface StreamVadResult {\n confidence: number;\n isSpeech: boolean;\n frameOffset: number;\n}\n\n/** Process one chunk of int16 PCM (160 samples = 10ms). Returns null if buffering. */\nexport function streamVadProcess(\n M: EmscriptenModule,\n handle: number,\n pcm16Ptr: number,\n numSamples: number,\n): StreamVadResult | null {\n // OmniStreamVadResult: { float confidence, bool is_speech, int frame_offset } = 12 bytes\n const resultPtr = M._malloc(12);\n try {\n const ret = M.ccall(\n \"omni_stream_vad_process\",\n \"number\",\n [\"number\", \"number\", \"number\", \"number\"],\n [handle, pcm16Ptr, numSamples, resultPtr],\n );\n if (ret === OMNI_ERR_NO_FRAMES) return null;\n if (ret !== 0) throw new Error(`StreamVAD process failed: ${ret}`);\n return {\n confidence: M.getValue(resultPtr, \"float\"),\n isSpeech: M.getValue(resultPtr + 4, \"i8\") !== 0,\n frameOffset: M.getValue(resultPtr + 8, \"i32\"),\n };\n } finally {\n M._free(resultPtr);\n }\n}\n\nexport function streamVadReset(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_stream_vad_reset\", null, [\"number\"], [handle]);\n}\n\nexport function streamVadDestroy(M: EmscriptenModule, handle: number): void {\n M.ccall(\"omni_stream_vad_destroy\", null, [\"number\"], [handle]);\n}\n","/**\n * Non-streaming Voice Activity Detection (WASM/ncnn backend).\n *\n * Audio format:\n * - Int16Array: raw 16-bit PCM, converted to normalized float internally\n * - Float32Array in [-1.0, 1.0]: normalized audio (Web Audio API format)\n */\n\nimport type { VADConfig, VADResult } from \"./types.js\";\nimport {\n initWasm,\n getModule,\n copyAudioToHeap,\n loadModel,\n vadCreate,\n vadDetect,\n vadDestroy,\n DEFAULT_VAD_CONFIG,\n type AudioFormat,\n type PostConfig,\n} from \"./wasm-binding.js\";\n\nconst SAMPLE_RATE = 16000;\n\nexport class OmniVAD {\n private handle: number;\n private config: PostConfig;\n\n private constructor(handle: number, config: PostConfig) {\n this.handle = handle;\n this.config = config;\n }\n\n /**\n * Create a new OmniVAD instance.\n * Loads model from CDN (browser), local package (Node.js), or custom source.\n */\n static async create(options: VADConfig = {}): Promise<OmniVAD> {\n await initWasm();\n const M = getModule();\n const modelBuffer = await loadModel(\"vad\", options.modelUrl, options.modelData);\n const handle = vadCreate(M, modelBuffer);\n const config: PostConfig = {\n threshold: options.speechThreshold ?? DEFAULT_VAD_CONFIG.threshold,\n smoothWindowSize: options.smoothWindowSize ?? DEFAULT_VAD_CONFIG.smoothWindowSize,\n minSpeechFrames: options.minSpeechFrames ?? DEFAULT_VAD_CONFIG.minSpeechFrames,\n minSilenceFrames: options.minSilenceFrames ?? DEFAULT_VAD_CONFIG.minSilenceFrames,\n maxSpeechFrames: options.maxSpeechFrames ?? DEFAULT_VAD_CONFIG.maxSpeechFrames,\n mergeSilenceFrames: options.mergeSilenceFrames ?? DEFAULT_VAD_CONFIG.mergeSilenceFrames,\n extendSpeechFrames: options.extendSpeechFrames ?? DEFAULT_VAD_CONFIG.extendSpeechFrames,\n };\n return new OmniVAD(handle, config);\n }\n\n /**\n * Detect speech segments in audio.\n *\n * Accepts Int16Array (PCM) or normalized Float32Array in [-1, 1].\n */\n detect(audio: Float32Array | Int16Array): VADResult {\n const M = getModule();\n const { ptr, length, format } = prepareAudio(M, audio);\n\n try {\n const timestamps = vadDetect(M, this.handle, ptr, length, this.config, format);\n return {\n duration: Math.round((length / SAMPLE_RATE) * 1000) / 1000,\n timestamps,\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /** Release native resources. */\n dispose(): void {\n if (this.handle) {\n vadDestroy(getModule(), this.handle);\n this.handle = 0;\n }\n }\n}\n\n/** Copy audio to WASM heap as normalized float audio. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction prepareAudio(M: any, audio: Float32Array | Int16Array): { ptr: number; length: number; format: AudioFormat } {\n const f32 = audio instanceof Int16Array ? int16ToNormalizedFloat32(audio) : audio;\n const ptr = copyAudioToHeap(M, f32);\n return { ptr, length: f32.length, format: \"f32\" };\n}\n\nfunction int16ToNormalizedFloat32(i16: Int16Array): Float32Array {\n const f32 = new Float32Array(i16.length);\n for (let i = 0; i < i16.length; i++) f32[i] = i16[i] / 32768;\n return f32;\n}\n","/**\n * Streaming Voice Activity Detection (WASM/ncnn backend).\n * Processes audio frame-by-frame (10ms chunks of 160 samples @ 16kHz).\n */\n\nimport type { StreamVADConfig, StreamVADFrameResult, StreamVADFullResult } from \"./types.js\";\nimport {\n initWasm,\n getModule,\n copyAudioToHeap,\n loadModel,\n streamVadCreate,\n streamVadProcess,\n streamVadReset,\n streamVadDestroy,\n} from \"./wasm-binding.js\";\n\nconst SAMPLE_RATE = 16000;\n\nexport class OmniStreamVAD {\n private handle: number;\n private inSpeech = false;\n private speechStartFrame = 0;\n\n private constructor(handle: number) {\n this.handle = handle;\n }\n\n /**\n * Create a new OmniStreamVAD instance.\n * Loads model from CDN (browser), local package (Node.js), or custom source.\n */\n static async create(options: StreamVADConfig = {}): Promise<OmniStreamVAD> {\n await initWasm();\n const M = getModule();\n const modelBuffer = await loadModel(\"stream-vad\", options.modelUrl, options.modelData);\n const threshold = options.speechThreshold ?? 0.5;\n const handle = streamVadCreate(M, modelBuffer, threshold);\n return new OmniStreamVAD(handle);\n }\n\n /**\n * Process one frame of audio (160 int16 samples = 10ms @ 16kHz).\n * Returns null until enough audio is accumulated.\n */\n processFrame(pcm160: Int16Array): StreamVADFrameResult | null {\n const M = getModule();\n const ptr = M._malloc(pcm160.length * 2);\n const heap16 = new Int16Array(M.HEAPU8.buffer, ptr, pcm160.length);\n heap16.set(pcm160);\n\n try {\n const result = streamVadProcess(M, this.handle, ptr, pcm160.length);\n if (!result || result.frameOffset === 0) return null;\n\n const frameIndex = result.frameOffset;\n const isSpeechStart = result.isSpeech && !this.inSpeech;\n const isSpeechEnd = !result.isSpeech && this.inSpeech;\n\n if (isSpeechStart) {\n this.speechStartFrame = frameIndex;\n }\n\n const activeSpeechStartFrame = isSpeechEnd ? this.speechStartFrame : result.isSpeech ? this.speechStartFrame : 0;\n const speechEndFrame = isSpeechEnd ? Math.max(1, frameIndex - 1) : 0;\n\n this.inSpeech = result.isSpeech;\n if (isSpeechEnd) {\n this.speechStartFrame = 0;\n }\n\n return {\n confidence: result.confidence,\n smoothedConfidence: result.confidence,\n isSpeech: result.isSpeech,\n frameIndex,\n isSpeechStart,\n isSpeechEnd,\n speechStartFrame: activeSpeechStartFrame,\n speechEndFrame,\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /**\n * Process entire audio at once and return per-frame probabilities.\n * @param audio - Float32Array in [-1, 1] or Int16Array of 16kHz mono PCM\n */\n detectFull(audio: Float32Array | Int16Array): StreamVADFullResult {\n const M = getModule();\n const f32 = prepareDetectFullAudio(audio);\n const audioPtr = copyAudioToHeap(M, f32);\n const probsPtrPtr = M._malloc(4);\n const framesPtr = M._malloc(4);\n\n try {\n const ret = M.ccall(\n \"omni_stream_vad_detect_full\",\n \"number\",\n [\"number\", \"number\", \"number\", \"number\", \"number\"],\n [this.handle, audioPtr, f32.length, probsPtrPtr, framesPtr],\n );\n if (ret !== 0) throw new Error(`StreamVAD detectFull failed: ${ret}`);\n\n const numFrames = M.getValue(framesPtr, \"i32\");\n const probsPtr = M.getValue(probsPtrPtr, \"i32\");\n const probabilities = probsPtr\n ? new Float32Array(new Float32Array(M.HEAPU8.buffer, probsPtr, numFrames))\n : new Float32Array(0);\n if (probsPtr) M._free(probsPtr);\n\n return {\n probabilities,\n numFrames,\n duration: Math.round((f32.length / SAMPLE_RATE) * 1000) / 1000,\n };\n } finally {\n M._free(audioPtr);\n M._free(probsPtrPtr);\n M._free(framesPtr);\n }\n }\n\n /** Reset all internal state. */\n reset(): void {\n streamVadReset(getModule(), this.handle);\n this.inSpeech = false;\n this.speechStartFrame = 0;\n }\n\n /** Release native resources. */\n dispose(): void {\n if (this.handle) {\n streamVadDestroy(getModule(), this.handle);\n this.handle = 0;\n }\n this.inSpeech = false;\n this.speechStartFrame = 0;\n }\n}\n\nfunction int16ToFloat32(i16: Int16Array): Float32Array {\n const f32 = new Float32Array(i16.length);\n for (let i = 0; i < i16.length; i++) f32[i] = i16[i];\n return f32;\n}\n\nfunction prepareDetectFullAudio(audio: Float32Array | Int16Array): Float32Array {\n if (audio instanceof Int16Array) {\n return int16ToFloat32(audio);\n }\n if (isNormalizedFloat(audio)) {\n const scaled = new Float32Array(audio.length);\n for (let i = 0; i < audio.length; i++) scaled[i] = audio[i] * 32768;\n return scaled;\n }\n return audio;\n}\n\nfunction isNormalizedFloat(audio: Float32Array): boolean {\n const step = Math.max(1, Math.floor(audio.length / 1000));\n let maxAbs = 0;\n for (let i = 0; i < audio.length; i += step) {\n const v = Math.abs(audio[i]);\n if (v > maxAbs) maxAbs = v;\n }\n return maxAbs <= 1.0;\n}\n","/**\n * Audio Event Detection: speech, singing, music (WASM/ncnn backend).\n *\n * Audio format: same as OmniVAD — Int16Array or normalized Float32Array [-1, 1].\n */\n\nimport type { AEDConfig, AEDResult } from \"./types.js\";\nimport {\n initWasm,\n getModule,\n loadModel,\n aedCreate,\n aedDetect,\n aedDestroy,\n DEFAULT_VAD_CONFIG,\n type AudioFormat,\n type AedPostConfig,\n} from \"./wasm-binding.js\";\n\nconst SAMPLE_RATE = 16000;\n\nexport class OmniAED {\n private handle: number;\n private config: AedPostConfig;\n\n private constructor(handle: number, config: AedPostConfig) {\n this.handle = handle;\n this.config = config;\n }\n\n /**\n * Create a new OmniAED instance.\n * Loads model from CDN (browser), local package (Node.js), or custom source.\n */\n static async create(options: AEDConfig = {}): Promise<OmniAED> {\n await initWasm();\n const M = getModule();\n const modelBuffer = await loadModel(\"aed\", options.modelUrl, options.modelData);\n const handle = aedCreate(M, modelBuffer);\n\n const base = {\n smoothWindowSize: options.smoothWindowSize ?? DEFAULT_VAD_CONFIG.smoothWindowSize,\n minSpeechFrames: options.minSpeechFrames ?? DEFAULT_VAD_CONFIG.minSpeechFrames,\n minSilenceFrames: options.minSilenceFrames ?? DEFAULT_VAD_CONFIG.minSilenceFrames,\n maxSpeechFrames: options.maxSpeechFrames ?? DEFAULT_VAD_CONFIG.maxSpeechFrames,\n mergeSilenceFrames: options.mergeSilenceFrames ?? DEFAULT_VAD_CONFIG.mergeSilenceFrames,\n extendSpeechFrames: options.extendSpeechFrames ?? DEFAULT_VAD_CONFIG.extendSpeechFrames,\n };\n\n const config: AedPostConfig = {\n speech: { ...base, threshold: options.speechThreshold ?? 0.4 },\n singing: { ...base, threshold: options.singingThreshold ?? 0.5 },\n music: { ...base, threshold: options.musicThreshold ?? 0.5 },\n };\n return new OmniAED(handle, config);\n }\n\n /**\n * Detect audio events (speech, singing, music).\n *\n * Accepts Int16Array (PCM) or normalized Float32Array in [-1, 1].\n */\n detect(audio: Float32Array | Int16Array): AEDResult {\n const M = getModule();\n const { ptr, length, format } = prepareAudio(M, audio);\n const duration = Math.round((length / SAMPLE_RATE) * 1000) / 1000;\n\n try {\n const events = aedDetect(M, this.handle, ptr, length, this.config, format);\n return {\n duration,\n events,\n ratios: computeCoverageRatios(events, duration),\n };\n } finally {\n M._free(ptr);\n }\n }\n\n /** Release native resources. */\n dispose(): void {\n if (this.handle) {\n aedDestroy(getModule(), this.handle);\n this.handle = 0;\n }\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction prepareAudio(M: any, audio: Float32Array | Int16Array): { ptr: number; length: number; format: AudioFormat } {\n const f32 = audio instanceof Int16Array ? int16ToNormalizedFloat32(audio) : audio;\n const ptr = M._malloc(f32.length * 4);\n const heap = new Float32Array(M.HEAPU8.buffer, ptr, f32.length);\n heap.set(f32);\n return { ptr, length: f32.length, format: \"f32\" };\n}\n\nfunction int16ToNormalizedFloat32(i16: Int16Array): Float32Array {\n const f32 = new Float32Array(i16.length);\n for (let i = 0; i < i16.length; i++) f32[i] = i16[i] / 32768;\n return f32;\n}\n\nfunction computeCoverageRatios(\n events: Record<string, Array<[number, number]>>,\n duration: number,\n): Record<string, number> {\n const ratios: Record<string, number> = {\n speech: 0,\n singing: 0,\n music: 0,\n };\n\n if (duration <= 0) return ratios;\n\n for (const cls of Object.keys(ratios)) {\n const covered = (events[cls] ?? []).reduce((sum, [start, end]) => sum + Math.max(0, end - start), 0);\n ratios[cls] = Math.round(Math.min(1, covered / duration) * 1e6) / 1e6;\n }\n\n return ratios;\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -42,8 +42,15 @@ interface StreamVADFullResult {
|
|
|
42
42
|
/** Audio duration in seconds */
|
|
43
43
|
duration: number;
|
|
44
44
|
}
|
|
45
|
+
/** Model source options shared by all model types. */
|
|
46
|
+
interface ModelSource {
|
|
47
|
+
/** URL to fetch the .omnivad model from (overrides default CDN). */
|
|
48
|
+
modelUrl?: string | URL;
|
|
49
|
+
/** Pre-loaded model data (skips fetch entirely). */
|
|
50
|
+
modelData?: ArrayBuffer;
|
|
51
|
+
}
|
|
45
52
|
/** Configuration for non-streaming VAD */
|
|
46
|
-
interface VADConfig {
|
|
53
|
+
interface VADConfig extends ModelSource {
|
|
47
54
|
/** Speech probability threshold (default: 0.4) */
|
|
48
55
|
speechThreshold?: number;
|
|
49
56
|
/** Smoothing window size in frames (default: 5) */
|
|
@@ -67,7 +74,7 @@ interface AEDConfig extends VADConfig {
|
|
|
67
74
|
musicThreshold?: number;
|
|
68
75
|
}
|
|
69
76
|
/** Configuration for streaming VAD */
|
|
70
|
-
interface StreamVADConfig {
|
|
77
|
+
interface StreamVADConfig extends ModelSource {
|
|
71
78
|
/** Speech probability threshold (default: 0.5) */
|
|
72
79
|
speechThreshold?: number;
|
|
73
80
|
}
|
|
@@ -86,7 +93,7 @@ declare class OmniVAD {
|
|
|
86
93
|
private constructor();
|
|
87
94
|
/**
|
|
88
95
|
* Create a new OmniVAD instance.
|
|
89
|
-
*
|
|
96
|
+
* Loads model from CDN (browser), local package (Node.js), or custom source.
|
|
90
97
|
*/
|
|
91
98
|
static create(options?: VADConfig): Promise<OmniVAD>;
|
|
92
99
|
/**
|
|
@@ -111,7 +118,7 @@ declare class OmniStreamVAD {
|
|
|
111
118
|
private constructor();
|
|
112
119
|
/**
|
|
113
120
|
* Create a new OmniStreamVAD instance.
|
|
114
|
-
*
|
|
121
|
+
* Loads model from CDN (browser), local package (Node.js), or custom source.
|
|
115
122
|
*/
|
|
116
123
|
static create(options?: StreamVADConfig): Promise<OmniStreamVAD>;
|
|
117
124
|
/**
|
|
@@ -142,7 +149,7 @@ declare class OmniAED {
|
|
|
142
149
|
private constructor();
|
|
143
150
|
/**
|
|
144
151
|
* Create a new OmniAED instance.
|
|
145
|
-
*
|
|
152
|
+
* Loads model from CDN (browser), local package (Node.js), or custom source.
|
|
146
153
|
*/
|
|
147
154
|
static create(options?: AEDConfig): Promise<OmniAED>;
|
|
148
155
|
/**
|
|
@@ -160,10 +167,31 @@ declare class OmniAED {
|
|
|
160
167
|
* Loads the Emscripten module and provides typed wrappers.
|
|
161
168
|
*/
|
|
162
169
|
type EmscriptenModule = any;
|
|
170
|
+
/** Package version — used to construct default CDN URLs. */
|
|
171
|
+
declare const VERSION = "0.2.1";
|
|
172
|
+
/** Default CDN base for model files (jsDelivr serves npm package contents). */
|
|
173
|
+
declare const DEFAULT_CDN_BASE = "https://cdn.jsdelivr.net/npm/omnivad@0.2.1/models";
|
|
174
|
+
/** Model filenames keyed by type. */
|
|
175
|
+
declare const MODEL_FILES: {
|
|
176
|
+
readonly vad: "vad.omnivad";
|
|
177
|
+
readonly "stream-vad": "stream-vad.omnivad";
|
|
178
|
+
readonly aed: "aed.omnivad";
|
|
179
|
+
};
|
|
180
|
+
type ModelType = keyof typeof MODEL_FILES;
|
|
163
181
|
/**
|
|
164
182
|
* Initialize the WASM module. Call once before using any other functions.
|
|
165
183
|
* Safe to call multiple times (returns cached module).
|
|
166
184
|
*/
|
|
167
185
|
declare function initWasm(wasmLocator?: (filename: string) => string): Promise<EmscriptenModule>;
|
|
186
|
+
/**
|
|
187
|
+
* Load a model file as ArrayBuffer.
|
|
188
|
+
*
|
|
189
|
+
* Resolution order:
|
|
190
|
+
* 1. modelData (ArrayBuffer) — use directly
|
|
191
|
+
* 2. modelUrl (string/URL) — fetch from that URL
|
|
192
|
+
* 3. Node.js — read from npm package's models/ directory
|
|
193
|
+
* 4. Browser — fetch from jsDelivr CDN
|
|
194
|
+
*/
|
|
195
|
+
declare function loadModel(modelType: ModelType, modelUrl?: string | URL, modelData?: ArrayBuffer): Promise<ArrayBuffer>;
|
|
168
196
|
|
|
169
|
-
export { type AEDConfig, type AEDResult, OmniAED as FireRedAED, OmniStreamVAD as FireRedStreamVAD, OmniVAD as FireRedVAD, OmniAED, OmniStreamVAD, OmniVAD, type StreamVADConfig, type StreamVADFrameResult, type StreamVADFullResult, type VADConfig, type VADResult, initWasm };
|
|
197
|
+
export { type AEDConfig, type AEDResult, DEFAULT_CDN_BASE, OmniAED as FireRedAED, OmniStreamVAD as FireRedStreamVAD, OmniVAD as FireRedVAD, MODEL_FILES, type ModelSource, OmniAED, OmniStreamVAD, OmniVAD, type StreamVADConfig, type StreamVADFrameResult, type StreamVADFullResult, type VADConfig, type VADResult, VERSION, initWasm, loadModel };
|