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 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, bundlePath = "models/vad.omnivad") {
77
- const handle = M.ccall(
78
- "omni_vad_nonstream_create_from_bundle",
79
- "number",
80
- ["string"],
81
- [bundlePath]
82
- );
83
- if (!handle) throw new Error("Failed to create VAD model");
84
- return handle;
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" ? "omni_vad_nonstream_process_int16" : "omni_vad_nonstream_process";
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("omni_vad_nonstream_destroy", null, ["number"], [handle]);
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, bundlePath = "models/aed.omnivad") {
126
- const handle = M.ccall(
127
- "omni_aed_nonstream_create_from_bundle",
128
- "number",
129
- ["string"],
130
- [bundlePath]
131
- );
132
- if (!handle) throw new Error("Failed to create AED model");
133
- return handle;
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" ? "omni_aed_nonstream_process_int16" : "omni_aed_nonstream_process";
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("omni_aed_nonstream_destroy", null, ["number"], [handle]);
229
+ M.ccall("omni_aed_destroy", null, ["number"], [handle]);
179
230
  }
180
- function streamVadCreate(M, threshold = 0.5, bundlePath = "models/stream-vad.omnivad") {
181
- const handle = M.ccall(
182
- "omni_vad_stream_create_from_bundle",
183
- "number",
184
- ["string", "number"],
185
- [bundlePath, threshold]
186
- );
187
- if (!handle) throw new Error("Failed to create StreamVAD model");
188
- return handle;
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
- "omni_vad_stream_process",
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 === -6) return null;
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("omni_vad_stream_reset", null, ["number"], [handle]);
268
+ M.ccall("omni_stream_vad_reset", null, ["number"], [handle]);
212
269
  }
213
270
  function streamVadDestroy(M, handle) {
214
- M.ccall("omni_vad_stream_destroy", null, ["number"], [handle]);
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
- * Initializes WASM and loads the bundled ncnn model.
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 handle = vadCreate(M);
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
- * Initializes WASM and loads the bundled ncnn model.
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
- "omni_vad_stream_detect_full",
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
- * Initializes WASM and loads the bundled ncnn model.
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 handle = aedCreate(M);
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
@@ -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
- * Initializes WASM and loads the bundled ncnn model.
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
- * Initializes WASM and loads the bundled ncnn model.
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
- * Initializes WASM and loads the bundled ncnn model.
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 };