@picovoice/eagle-web 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +1 -1
- package/dist/esm/index.js +1823 -1450
- package/dist/esm/index.min.js +1 -1
- package/dist/iife/index.js +1823 -1449
- package/dist/iife/index.min.js +1 -1
- package/dist/types/eagle.d.ts +18 -4
- package/dist/types/eagle.d.ts.map +1 -1
- package/dist/types/eagle_errors.d.ts +48 -0
- package/dist/types/eagle_errors.d.ts.map +1 -0
- package/dist/types/eagle_profiler_worker.d.ts +2 -0
- package/dist/types/eagle_profiler_worker.d.ts.map +1 -1
- package/dist/types/eagle_worker.d.ts +3 -1
- package/dist/types/eagle_worker.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types.d.ts +22 -2
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/eagle.ts +280 -94
- package/src/eagle_errors.ts +252 -0
- package/src/eagle_profiler_worker.ts +17 -10
- package/src/eagle_profiler_worker_handler.ts +67 -20
- package/src/eagle_worker.ts +16 -9
- package/src/eagle_worker_handler.ts +51 -15
- package/src/index.ts +2 -0
- package/src/types.ts +23 -2
package/src/eagle.ts
CHANGED
|
@@ -25,7 +25,15 @@ import {
|
|
|
25
25
|
|
|
26
26
|
import { simd } from 'wasm-feature-detect';
|
|
27
27
|
|
|
28
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
EagleModel,
|
|
30
|
+
EagleProfile,
|
|
31
|
+
EagleProfilerEnrollResult,
|
|
32
|
+
PvStatus
|
|
33
|
+
} from './types';
|
|
34
|
+
|
|
35
|
+
import * as EagleErrors from './eagle_errors';
|
|
36
|
+
import { pvStatusToException } from './eagle_errors';
|
|
29
37
|
|
|
30
38
|
/**
|
|
31
39
|
* WebAssembly function types
|
|
@@ -74,6 +82,12 @@ type pv_eagle_frame_length_type = () => Promise<number>;
|
|
|
74
82
|
type pv_eagle_version_type = () => Promise<number>;
|
|
75
83
|
type pv_sample_rate_type = () => Promise<number>;
|
|
76
84
|
type pv_status_to_string_type = (status: number) => Promise<number>;
|
|
85
|
+
type pv_set_sdk_type = (sdk: number) => Promise<void>;
|
|
86
|
+
type pv_get_error_stack_type = (
|
|
87
|
+
messageStack: number,
|
|
88
|
+
messageStackDepth: number
|
|
89
|
+
) => Promise<number>;
|
|
90
|
+
type pv_free_error_stack_type = (messageStack: number) => Promise<void>;
|
|
77
91
|
|
|
78
92
|
type EagleBaseWasmOutput = {
|
|
79
93
|
memory: WebAssembly.Memory;
|
|
@@ -84,7 +98,13 @@ type EagleBaseWasmOutput = {
|
|
|
84
98
|
sampleRate: number;
|
|
85
99
|
version: string;
|
|
86
100
|
|
|
101
|
+
messageStackAddressAddressAddress: number;
|
|
102
|
+
messageStackDepthAddress: number;
|
|
103
|
+
|
|
87
104
|
pvStatusToString: pv_status_to_string_type;
|
|
105
|
+
pvGetErrorStack: pv_get_error_stack_type;
|
|
106
|
+
pvFreeErrorStack: pv_free_error_stack_type;
|
|
107
|
+
|
|
88
108
|
exports: any;
|
|
89
109
|
};
|
|
90
110
|
|
|
@@ -120,16 +140,20 @@ class EagleBase {
|
|
|
120
140
|
protected _wasmMemory: WebAssembly.Memory | undefined;
|
|
121
141
|
protected readonly _alignedAlloc: CallableFunction;
|
|
122
142
|
protected readonly _pvFree: pv_free_type;
|
|
123
|
-
protected readonly _memoryBuffer: Int16Array;
|
|
124
|
-
protected readonly _memoryBufferUint8: Uint8Array;
|
|
125
|
-
protected readonly _memoryBufferView: DataView;
|
|
126
143
|
protected readonly _functionMutex: Mutex;
|
|
127
144
|
|
|
145
|
+
protected readonly _pvGetErrorStack: pv_get_error_stack_type;
|
|
146
|
+
protected readonly _pvFreeErrorStack: pv_free_error_stack_type;
|
|
147
|
+
|
|
148
|
+
protected readonly _messageStackAddressAddressAddress: number;
|
|
149
|
+
protected readonly _messageStackDepthAddress: number;
|
|
150
|
+
|
|
128
151
|
protected static _sampleRate: number;
|
|
129
152
|
protected static _version: string;
|
|
130
153
|
|
|
131
154
|
protected static _wasm: string;
|
|
132
155
|
protected static _wasmSimd: string;
|
|
156
|
+
protected static _sdk: string = 'web';
|
|
133
157
|
|
|
134
158
|
protected static _eagleMutex = new Mutex();
|
|
135
159
|
|
|
@@ -146,9 +170,11 @@ class EagleBase {
|
|
|
146
170
|
this._pvFree = handleWasm.pvFree;
|
|
147
171
|
this._pvError = handleWasm.pvError;
|
|
148
172
|
|
|
149
|
-
this.
|
|
150
|
-
this.
|
|
151
|
-
|
|
173
|
+
this._pvGetErrorStack = handleWasm.pvGetErrorStack;
|
|
174
|
+
this._pvFreeErrorStack = handleWasm.pvFreeErrorStack;
|
|
175
|
+
|
|
176
|
+
this._messageStackAddressAddressAddress = handleWasm.messageStackAddressAddressAddress;
|
|
177
|
+
this._messageStackDepthAddress = handleWasm.messageStackDepthAddress;
|
|
152
178
|
|
|
153
179
|
this._functionMutex = new Mutex();
|
|
154
180
|
}
|
|
@@ -187,6 +213,10 @@ class EagleBase {
|
|
|
187
213
|
}
|
|
188
214
|
}
|
|
189
215
|
|
|
216
|
+
public static setSdk(sdk: string): void {
|
|
217
|
+
EagleBase._sdk = sdk;
|
|
218
|
+
}
|
|
219
|
+
|
|
190
220
|
protected static async _initBaseWasm(
|
|
191
221
|
wasmBase64: string,
|
|
192
222
|
wasmMemorySize: number
|
|
@@ -203,6 +233,11 @@ class EagleBase {
|
|
|
203
233
|
const pv_sample_rate = exports.pv_sample_rate as pv_sample_rate_type;
|
|
204
234
|
const pv_status_to_string =
|
|
205
235
|
exports.pv_status_to_string as pv_status_to_string_type;
|
|
236
|
+
const pv_set_sdk = exports.pv_set_sdk as pv_set_sdk_type;
|
|
237
|
+
const pv_get_error_stack =
|
|
238
|
+
exports.pv_get_error_stack as pv_get_error_stack_type;
|
|
239
|
+
const pv_free_error_stack =
|
|
240
|
+
exports.pv_free_error_stack as pv_free_error_stack_type;
|
|
206
241
|
|
|
207
242
|
const sampleRate = await pv_sample_rate();
|
|
208
243
|
const versionAddress = await pv_eagle_version();
|
|
@@ -211,6 +246,40 @@ class EagleBase {
|
|
|
211
246
|
versionAddress
|
|
212
247
|
);
|
|
213
248
|
|
|
249
|
+
const sdkEncoded = new TextEncoder().encode(this._sdk);
|
|
250
|
+
const sdkAddress = await aligned_alloc(
|
|
251
|
+
Uint8Array.BYTES_PER_ELEMENT,
|
|
252
|
+
(sdkEncoded.length + 1) * Uint8Array.BYTES_PER_ELEMENT
|
|
253
|
+
);
|
|
254
|
+
if (!sdkAddress) {
|
|
255
|
+
throw new EagleErrors.EagleOutOfMemoryError(
|
|
256
|
+
'malloc failed: Cannot allocate memory'
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
memoryBufferUint8.set(sdkEncoded, sdkAddress);
|
|
260
|
+
memoryBufferUint8[sdkAddress + sdkEncoded.length] = 0;
|
|
261
|
+
await pv_set_sdk(sdkAddress);
|
|
262
|
+
|
|
263
|
+
const messageStackDepthAddress = await aligned_alloc(
|
|
264
|
+
Int32Array.BYTES_PER_ELEMENT,
|
|
265
|
+
Int32Array.BYTES_PER_ELEMENT
|
|
266
|
+
);
|
|
267
|
+
if (!messageStackDepthAddress) {
|
|
268
|
+
throw new EagleErrors.EagleOutOfMemoryError(
|
|
269
|
+
'malloc failed: Cannot allocate memory'
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const messageStackAddressAddressAddress = await aligned_alloc(
|
|
274
|
+
Int32Array.BYTES_PER_ELEMENT,
|
|
275
|
+
Int32Array.BYTES_PER_ELEMENT
|
|
276
|
+
);
|
|
277
|
+
if (!messageStackAddressAddressAddress) {
|
|
278
|
+
throw new EagleErrors.EagleOutOfMemoryError(
|
|
279
|
+
'malloc failed: Cannot allocate memory'
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
214
283
|
return {
|
|
215
284
|
memory: memory,
|
|
216
285
|
alignedAlloc: aligned_alloc,
|
|
@@ -220,10 +289,67 @@ class EagleBase {
|
|
|
220
289
|
sampleRate: sampleRate,
|
|
221
290
|
version: version,
|
|
222
291
|
|
|
292
|
+
messageStackAddressAddressAddress: messageStackAddressAddressAddress,
|
|
293
|
+
messageStackDepthAddress: messageStackDepthAddress,
|
|
294
|
+
|
|
223
295
|
pvStatusToString: pv_status_to_string,
|
|
296
|
+
pvGetErrorStack: pv_get_error_stack,
|
|
297
|
+
pvFreeErrorStack: pv_free_error_stack,
|
|
298
|
+
|
|
224
299
|
exports: exports,
|
|
225
300
|
};
|
|
226
301
|
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Releases resources acquired by Eagle
|
|
305
|
+
*/
|
|
306
|
+
public async release(): Promise<void> {
|
|
307
|
+
await this._pvFree(this._messageStackAddressAddressAddress);
|
|
308
|
+
await this._pvFree(this._messageStackDepthAddress);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
protected static async getMessageStack(
|
|
312
|
+
pv_get_error_stack: pv_get_error_stack_type,
|
|
313
|
+
pv_free_error_stack: pv_free_error_stack_type,
|
|
314
|
+
messageStackAddressAddressAddress: number,
|
|
315
|
+
messageStackDepthAddress: number,
|
|
316
|
+
memoryBufferView: DataView,
|
|
317
|
+
memoryBufferUint8: Uint8Array
|
|
318
|
+
): Promise<string[]> {
|
|
319
|
+
const status = await pv_get_error_stack(
|
|
320
|
+
messageStackAddressAddressAddress,
|
|
321
|
+
messageStackDepthAddress
|
|
322
|
+
);
|
|
323
|
+
if (status !== PvStatus.SUCCESS) {
|
|
324
|
+
throw pvStatusToException(status, 'Unable to get Eagle error state');
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const messageStackAddressAddress = memoryBufferView.getInt32(
|
|
328
|
+
messageStackAddressAddressAddress,
|
|
329
|
+
true
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
const messageStackDepth = memoryBufferView.getInt32(
|
|
333
|
+
messageStackDepthAddress,
|
|
334
|
+
true
|
|
335
|
+
);
|
|
336
|
+
const messageStack: string[] = [];
|
|
337
|
+
for (let i = 0; i < messageStackDepth; i++) {
|
|
338
|
+
const messageStackAddress = memoryBufferView.getInt32(
|
|
339
|
+
messageStackAddressAddress + i * Int32Array.BYTES_PER_ELEMENT,
|
|
340
|
+
true
|
|
341
|
+
);
|
|
342
|
+
const message = arrayBufferToStringAtIndex(
|
|
343
|
+
memoryBufferUint8,
|
|
344
|
+
messageStackAddress
|
|
345
|
+
);
|
|
346
|
+
messageStack.push(message);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
await pv_free_error_stack(messageStackAddressAddress);
|
|
350
|
+
|
|
351
|
+
return messageStack;
|
|
352
|
+
}
|
|
227
353
|
}
|
|
228
354
|
|
|
229
355
|
/**
|
|
@@ -296,7 +422,7 @@ export class EagleProfiler extends EagleBase {
|
|
|
296
422
|
modelPath: string
|
|
297
423
|
): Promise<EagleProfiler> {
|
|
298
424
|
if (!isAccessKeyValid(accessKey)) {
|
|
299
|
-
throw new
|
|
425
|
+
throw new EagleErrors.EagleInvalidArgumentError('Invalid AccessKey');
|
|
300
426
|
}
|
|
301
427
|
|
|
302
428
|
return new Promise<EagleProfiler>((resolve, reject) => {
|
|
@@ -346,11 +472,11 @@ export class EagleProfiler extends EagleBase {
|
|
|
346
472
|
*/
|
|
347
473
|
public async enroll(pcm: Int16Array): Promise<EagleProfilerEnrollResult> {
|
|
348
474
|
if (!(pcm instanceof Int16Array)) {
|
|
349
|
-
throw new
|
|
475
|
+
throw new EagleErrors.EagleInvalidArgumentError("The argument 'pcm' must be provided as an Int16Array");
|
|
350
476
|
}
|
|
351
477
|
|
|
352
478
|
if (pcm.length > EagleProfiler._maxEnrollSamples) {
|
|
353
|
-
throw new
|
|
479
|
+
throw new EagleErrors.EagleInvalidArgumentError(
|
|
354
480
|
`'pcm' size must be smaller than ${EagleProfiler._maxEnrollSamples}`
|
|
355
481
|
);
|
|
356
482
|
}
|
|
@@ -359,7 +485,7 @@ export class EagleProfiler extends EagleBase {
|
|
|
359
485
|
this._functionMutex
|
|
360
486
|
.runExclusive(async () => {
|
|
361
487
|
if (this._wasmMemory === undefined) {
|
|
362
|
-
throw new
|
|
488
|
+
throw new EagleErrors.EagleInvalidStateError('Attempted to call `.enroll()` after release');
|
|
363
489
|
}
|
|
364
490
|
|
|
365
491
|
const pcmAddress = await this._alignedAlloc(
|
|
@@ -367,24 +493,24 @@ export class EagleProfiler extends EagleBase {
|
|
|
367
493
|
pcm.length * Int16Array.BYTES_PER_ELEMENT
|
|
368
494
|
);
|
|
369
495
|
|
|
370
|
-
const memoryBufferInt16 = new Int16Array(this._wasmMemory.buffer);
|
|
371
|
-
memoryBufferInt16.set(pcm, pcmAddress / Int16Array.BYTES_PER_ELEMENT);
|
|
372
|
-
|
|
373
496
|
const feedbackAddress = await this._alignedAlloc(
|
|
374
497
|
Int32Array.BYTES_PER_ELEMENT,
|
|
375
498
|
Int32Array.BYTES_PER_ELEMENT
|
|
376
499
|
);
|
|
377
500
|
if (feedbackAddress === 0) {
|
|
378
|
-
throw new
|
|
501
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
379
502
|
}
|
|
380
503
|
const percentageAddress = await this._alignedAlloc(
|
|
381
504
|
Int32Array.BYTES_PER_ELEMENT,
|
|
382
505
|
Int32Array.BYTES_PER_ELEMENT
|
|
383
506
|
);
|
|
384
507
|
if (percentageAddress === 0) {
|
|
385
|
-
throw new
|
|
508
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
386
509
|
}
|
|
387
510
|
|
|
511
|
+
const memoryBufferInt16 = new Int16Array(this._wasmMemory.buffer);
|
|
512
|
+
memoryBufferInt16.set(pcm, pcmAddress / Int16Array.BYTES_PER_ELEMENT);
|
|
513
|
+
|
|
388
514
|
const status = await this._pvEagleProfilerEnroll(
|
|
389
515
|
this._objectAddress,
|
|
390
516
|
pcmAddress,
|
|
@@ -397,24 +523,34 @@ export class EagleProfiler extends EagleBase {
|
|
|
397
523
|
await this._pvFree(feedbackAddress);
|
|
398
524
|
await this._pvFree(percentageAddress);
|
|
399
525
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
526
|
+
const memoryBufferView = new DataView(this._wasmMemory.buffer);
|
|
527
|
+
const memoryBufferUint8 = new Uint8Array(this._wasmMemory.buffer);
|
|
528
|
+
|
|
529
|
+
const messageStack = await EagleProfiler.getMessageStack(
|
|
530
|
+
this._pvGetErrorStack,
|
|
531
|
+
this._pvFreeErrorStack,
|
|
532
|
+
this._messageStackAddressAddressAddress,
|
|
533
|
+
this._messageStackDepthAddress,
|
|
534
|
+
memoryBufferView,
|
|
535
|
+
memoryBufferUint8
|
|
405
536
|
);
|
|
537
|
+
|
|
538
|
+
throw pvStatusToException(status, "EagleProfiler enroll failed", messageStack);
|
|
406
539
|
}
|
|
407
540
|
|
|
408
|
-
const
|
|
541
|
+
const memoryBufferView = new DataView(this._wasmMemory.buffer);
|
|
542
|
+
|
|
543
|
+
const feedback = memoryBufferView.getInt32(
|
|
409
544
|
feedbackAddress,
|
|
410
545
|
true
|
|
411
546
|
);
|
|
412
|
-
await this._pvFree(feedbackAddress);
|
|
413
547
|
|
|
414
|
-
const percentage =
|
|
548
|
+
const percentage = memoryBufferView.getFloat32(
|
|
415
549
|
percentageAddress,
|
|
416
550
|
true
|
|
417
551
|
);
|
|
552
|
+
|
|
553
|
+
await this._pvFree(feedbackAddress);
|
|
418
554
|
await this._pvFree(percentageAddress);
|
|
419
555
|
|
|
420
556
|
return { feedback, percentage };
|
|
@@ -439,7 +575,7 @@ export class EagleProfiler extends EagleBase {
|
|
|
439
575
|
this._functionMutex
|
|
440
576
|
.runExclusive(async () => {
|
|
441
577
|
if (this._wasmMemory === undefined) {
|
|
442
|
-
throw new
|
|
578
|
+
throw new EagleErrors.EagleInvalidStateError('Attempted to call `.export()` after release');
|
|
443
579
|
}
|
|
444
580
|
|
|
445
581
|
const profileAddress = await this._alignedAlloc(
|
|
@@ -453,15 +589,25 @@ export class EagleProfiler extends EagleBase {
|
|
|
453
589
|
);
|
|
454
590
|
if (status !== PV_STATUS_SUCCESS) {
|
|
455
591
|
await this._pvFree(profileAddress);
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
592
|
+
|
|
593
|
+
const memoryBufferView = new DataView(this._wasmMemory.buffer);
|
|
594
|
+
const memoryBufferUint8 = new Uint8Array(this._wasmMemory.buffer);
|
|
595
|
+
|
|
596
|
+
const messageStack = await EagleProfiler.getMessageStack(
|
|
597
|
+
this._pvGetErrorStack,
|
|
598
|
+
this._pvFreeErrorStack,
|
|
599
|
+
this._messageStackAddressAddressAddress,
|
|
600
|
+
this._messageStackDepthAddress,
|
|
601
|
+
memoryBufferView,
|
|
602
|
+
memoryBufferUint8
|
|
461
603
|
);
|
|
604
|
+
|
|
605
|
+
throw pvStatusToException(status, "EagleProfiler export failed", messageStack);
|
|
462
606
|
}
|
|
463
607
|
|
|
464
|
-
const
|
|
608
|
+
const memoryBufferUint8 = new Uint8Array(this._wasmMemory.buffer);
|
|
609
|
+
|
|
610
|
+
const profile = memoryBufferUint8.slice(
|
|
465
611
|
profileAddress / Uint8Array.BYTES_PER_ELEMENT,
|
|
466
612
|
profileAddress / Uint8Array.BYTES_PER_ELEMENT +
|
|
467
613
|
EagleProfiler._profileSize
|
|
@@ -488,17 +634,24 @@ export class EagleProfiler extends EagleBase {
|
|
|
488
634
|
this._functionMutex
|
|
489
635
|
.runExclusive(async () => {
|
|
490
636
|
if (this._wasmMemory === undefined) {
|
|
491
|
-
throw new
|
|
637
|
+
throw new EagleErrors.EagleInvalidStateError('Attempted to call `.reset()` after release');
|
|
492
638
|
}
|
|
493
639
|
|
|
494
640
|
const status = await this._pvEagleProfilerReset(this._objectAddress);
|
|
495
641
|
if (status !== PV_STATUS_SUCCESS) {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
642
|
+
const memoryBufferView = new DataView(this._wasmMemory.buffer);
|
|
643
|
+
const memoryBufferUint8 = new Uint8Array(this._wasmMemory.buffer);
|
|
644
|
+
|
|
645
|
+
const messageStack = await EagleProfiler.getMessageStack(
|
|
646
|
+
this._pvGetErrorStack,
|
|
647
|
+
this._pvFreeErrorStack,
|
|
648
|
+
this._messageStackAddressAddressAddress,
|
|
649
|
+
this._messageStackDepthAddress,
|
|
650
|
+
memoryBufferView,
|
|
651
|
+
memoryBufferUint8
|
|
501
652
|
);
|
|
653
|
+
|
|
654
|
+
throw pvStatusToException(status, "EagleProfiler reset failed", messageStack);
|
|
502
655
|
}
|
|
503
656
|
})
|
|
504
657
|
.then(() => {
|
|
@@ -514,6 +667,7 @@ export class EagleProfiler extends EagleBase {
|
|
|
514
667
|
* Releases resources acquired by Eagle Profiler
|
|
515
668
|
*/
|
|
516
669
|
public async release(): Promise<void> {
|
|
670
|
+
await super.release();
|
|
517
671
|
await this._pvEagleProfilerDelete(this._objectAddress);
|
|
518
672
|
delete this._wasmMemory;
|
|
519
673
|
this._wasmMemory = undefined;
|
|
@@ -548,7 +702,7 @@ export class EagleProfiler extends EagleBase {
|
|
|
548
702
|
Int32Array.BYTES_PER_ELEMENT
|
|
549
703
|
);
|
|
550
704
|
if (objectAddressAddress === 0) {
|
|
551
|
-
throw new
|
|
705
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
552
706
|
}
|
|
553
707
|
|
|
554
708
|
const accessKeyAddress = await baseWasmOutput.alignedAlloc(
|
|
@@ -556,7 +710,7 @@ export class EagleProfiler extends EagleBase {
|
|
|
556
710
|
(accessKey.length + 1) * Uint8Array.BYTES_PER_ELEMENT
|
|
557
711
|
);
|
|
558
712
|
if (accessKeyAddress === 0) {
|
|
559
|
-
throw new
|
|
713
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
560
714
|
}
|
|
561
715
|
for (let i = 0; i < accessKey.length; i++) {
|
|
562
716
|
memoryBufferUint8[accessKeyAddress + i] = accessKey.charCodeAt(i);
|
|
@@ -569,7 +723,7 @@ export class EagleProfiler extends EagleBase {
|
|
|
569
723
|
(modelPathEncoded.length + 1) * Uint8Array.BYTES_PER_ELEMENT
|
|
570
724
|
);
|
|
571
725
|
if (modelPathAddress === 0) {
|
|
572
|
-
throw new
|
|
726
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
573
727
|
}
|
|
574
728
|
memoryBufferUint8.set(modelPathEncoded, modelPathAddress);
|
|
575
729
|
memoryBufferUint8[modelPathAddress + modelPathEncoded.length] = 0;
|
|
@@ -581,18 +735,22 @@ export class EagleProfiler extends EagleBase {
|
|
|
581
735
|
);
|
|
582
736
|
await baseWasmOutput.pvFree(accessKeyAddress);
|
|
583
737
|
await baseWasmOutput.pvFree(modelPathAddress);
|
|
584
|
-
if (status !== PV_STATUS_SUCCESS) {
|
|
585
|
-
const msg = `'pv_eagle_profiler_init' failed with status ${arrayBufferToStringAtIndex(
|
|
586
|
-
memoryBufferUint8,
|
|
587
|
-
await baseWasmOutput.pvStatusToString(status)
|
|
588
|
-
)}`;
|
|
589
738
|
|
|
590
|
-
|
|
591
|
-
|
|
739
|
+
const memoryBufferView = new DataView(baseWasmOutput.memory.buffer);
|
|
740
|
+
|
|
741
|
+
if (status !== PV_STATUS_SUCCESS) {
|
|
742
|
+
const messageStack = await EagleProfiler.getMessageStack(
|
|
743
|
+
baseWasmOutput.pvGetErrorStack,
|
|
744
|
+
baseWasmOutput.pvFreeErrorStack,
|
|
745
|
+
baseWasmOutput.messageStackAddressAddressAddress,
|
|
746
|
+
baseWasmOutput.messageStackDepthAddress,
|
|
747
|
+
memoryBufferView,
|
|
748
|
+
memoryBufferUint8
|
|
592
749
|
);
|
|
750
|
+
|
|
751
|
+
throw pvStatusToException(status, "EagleProfiler init failed", messageStack, baseWasmOutput.pvError);
|
|
593
752
|
}
|
|
594
753
|
|
|
595
|
-
const memoryBufferView = new DataView(baseWasmOutput.memory.buffer);
|
|
596
754
|
const objectAddress = memoryBufferView.getInt32(objectAddressAddress, true);
|
|
597
755
|
await baseWasmOutput.pvFree(objectAddressAddress);
|
|
598
756
|
|
|
@@ -601,7 +759,7 @@ export class EagleProfiler extends EagleBase {
|
|
|
601
759
|
Int32Array.BYTES_PER_ELEMENT
|
|
602
760
|
);
|
|
603
761
|
if (minEnrollSamplesAddress === 0) {
|
|
604
|
-
throw new
|
|
762
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
605
763
|
}
|
|
606
764
|
|
|
607
765
|
status = await pv_eagle_profiler_enroll_min_audio_length_samples(
|
|
@@ -609,14 +767,18 @@ export class EagleProfiler extends EagleBase {
|
|
|
609
767
|
minEnrollSamplesAddress
|
|
610
768
|
);
|
|
611
769
|
if (status !== PV_STATUS_SUCCESS) {
|
|
612
|
-
const
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
770
|
+
const messageStack = await EagleProfiler.getMessageStack(
|
|
771
|
+
baseWasmOutput.pvGetErrorStack,
|
|
772
|
+
baseWasmOutput.pvFreeErrorStack,
|
|
773
|
+
baseWasmOutput.messageStackAddressAddressAddress,
|
|
774
|
+
baseWasmOutput.messageStackDepthAddress,
|
|
775
|
+
memoryBufferView,
|
|
776
|
+
memoryBufferUint8
|
|
618
777
|
);
|
|
778
|
+
|
|
779
|
+
throw pvStatusToException(status, "EagleProfiler failed to get min enroll audio length", messageStack, baseWasmOutput.pvError);
|
|
619
780
|
}
|
|
781
|
+
|
|
620
782
|
const minEnrollSamples = memoryBufferView.getInt32(
|
|
621
783
|
minEnrollSamplesAddress,
|
|
622
784
|
true
|
|
@@ -628,7 +790,7 @@ export class EagleProfiler extends EagleBase {
|
|
|
628
790
|
Int32Array.BYTES_PER_ELEMENT
|
|
629
791
|
);
|
|
630
792
|
if (profileSizeAddress === 0) {
|
|
631
|
-
throw new
|
|
793
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
632
794
|
}
|
|
633
795
|
|
|
634
796
|
status = await pv_eagle_profiler_export_size(
|
|
@@ -636,13 +798,16 @@ export class EagleProfiler extends EagleBase {
|
|
|
636
798
|
profileSizeAddress
|
|
637
799
|
);
|
|
638
800
|
if (status !== PV_STATUS_SUCCESS) {
|
|
639
|
-
const
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
801
|
+
const messageStack = await EagleProfiler.getMessageStack(
|
|
802
|
+
baseWasmOutput.pvGetErrorStack,
|
|
803
|
+
baseWasmOutput.pvFreeErrorStack,
|
|
804
|
+
baseWasmOutput.messageStackAddressAddressAddress,
|
|
805
|
+
baseWasmOutput.messageStackDepthAddress,
|
|
806
|
+
memoryBufferView,
|
|
807
|
+
memoryBufferUint8
|
|
645
808
|
);
|
|
809
|
+
|
|
810
|
+
throw pvStatusToException(status, "EagleProfiler failed to get export size", messageStack, baseWasmOutput.pvError);
|
|
646
811
|
}
|
|
647
812
|
|
|
648
813
|
const profileSize = memoryBufferView.getInt32(profileSizeAddress, true);
|
|
@@ -702,7 +867,7 @@ export class Eagle extends EagleBase {
|
|
|
702
867
|
/**
|
|
703
868
|
* Creates an instance of the Picovoice Eagle Speaker Recognition Engine.
|
|
704
869
|
*
|
|
705
|
-
* @param accessKey
|
|
870
|
+
* @param accessKey AccessKey obtained from Picovoice Console (https://console.picovoice.ai/)
|
|
706
871
|
* @param model Eagle model options.
|
|
707
872
|
* @param model.base64 The model in base64 string to initialize Eagle.
|
|
708
873
|
* @param model.publicPath The model path relative to the public directory.
|
|
@@ -737,11 +902,11 @@ export class Eagle extends EagleBase {
|
|
|
737
902
|
speakerProfiles: EagleProfile[]
|
|
738
903
|
): Promise<Eagle> {
|
|
739
904
|
if (!isAccessKeyValid(accessKey)) {
|
|
740
|
-
throw new
|
|
905
|
+
throw new EagleErrors.EagleInvalidArgumentError('Invalid AccessKey');
|
|
741
906
|
}
|
|
742
907
|
|
|
743
908
|
if (!speakerProfiles || speakerProfiles.length === 0) {
|
|
744
|
-
throw new
|
|
909
|
+
throw new EagleErrors.EagleInvalidArgumentError('No speaker profiles provided');
|
|
745
910
|
}
|
|
746
911
|
|
|
747
912
|
return new Promise<Eagle>((resolve, reject) => {
|
|
@@ -777,11 +942,11 @@ export class Eagle extends EagleBase {
|
|
|
777
942
|
*/
|
|
778
943
|
public async process(pcm: Int16Array): Promise<number[]> {
|
|
779
944
|
if (!(pcm instanceof Int16Array)) {
|
|
780
|
-
throw new
|
|
945
|
+
throw new EagleErrors.EagleInvalidArgumentError("The argument 'pcm' must be provided as an Int16Array");
|
|
781
946
|
}
|
|
782
947
|
|
|
783
948
|
if (pcm.length !== Eagle._frameLength) {
|
|
784
|
-
throw new
|
|
949
|
+
throw new EagleErrors.EagleInvalidArgumentError(
|
|
785
950
|
`Length of input frame (${pcm.length}) does not match required frame length (${Eagle._frameLength})`
|
|
786
951
|
);
|
|
787
952
|
}
|
|
@@ -790,7 +955,7 @@ export class Eagle extends EagleBase {
|
|
|
790
955
|
this._functionMutex
|
|
791
956
|
.runExclusive(async () => {
|
|
792
957
|
if (this._wasmMemory === undefined) {
|
|
793
|
-
throw new
|
|
958
|
+
throw new EagleErrors.EagleInvalidStateError('Attempted to call `.process` after release');
|
|
794
959
|
}
|
|
795
960
|
|
|
796
961
|
const pcmAddress = await this._alignedAlloc(
|
|
@@ -808,18 +973,27 @@ export class Eagle extends EagleBase {
|
|
|
808
973
|
);
|
|
809
974
|
await this._pvFree(pcmAddress);
|
|
810
975
|
if (status !== PV_STATUS_SUCCESS) {
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
976
|
+
const memoryBufferView = new DataView(this._wasmMemory.buffer);
|
|
977
|
+
const memoryBufferUint8 = new Uint8Array(this._wasmMemory.buffer);
|
|
978
|
+
|
|
979
|
+
const messageStack = await EagleProfiler.getMessageStack(
|
|
980
|
+
this._pvGetErrorStack,
|
|
981
|
+
this._pvFreeErrorStack,
|
|
982
|
+
this._messageStackAddressAddressAddress,
|
|
983
|
+
this._messageStackDepthAddress,
|
|
984
|
+
memoryBufferView,
|
|
985
|
+
memoryBufferUint8
|
|
816
986
|
);
|
|
987
|
+
|
|
988
|
+
throw pvStatusToException(status, "Eagle process failed", messageStack);
|
|
817
989
|
}
|
|
818
990
|
|
|
991
|
+
const memoryBufferView = new DataView(this._wasmMemory.buffer);
|
|
992
|
+
|
|
819
993
|
const scores: number[] = [];
|
|
820
994
|
for (let i = 0; i < this._numSpeakers; i++) {
|
|
821
995
|
scores.push(
|
|
822
|
-
|
|
996
|
+
memoryBufferView.getFloat32(
|
|
823
997
|
this._scoresAddress + i * Float32Array.BYTES_PER_ELEMENT,
|
|
824
998
|
true
|
|
825
999
|
)
|
|
@@ -847,17 +1021,24 @@ export class Eagle extends EagleBase {
|
|
|
847
1021
|
this._functionMutex
|
|
848
1022
|
.runExclusive(async () => {
|
|
849
1023
|
if (this._wasmMemory === undefined) {
|
|
850
|
-
throw new
|
|
1024
|
+
throw new EagleErrors.EagleInvalidStateError('Attempted to call `.reset` after release');
|
|
851
1025
|
}
|
|
852
1026
|
|
|
853
1027
|
const status = await this._pvEagleReset(this._objectAddress);
|
|
854
1028
|
if (status !== PV_STATUS_SUCCESS) {
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
1029
|
+
const memoryBufferView = new DataView(this._wasmMemory.buffer);
|
|
1030
|
+
const memoryBufferUint8 = new Uint8Array(this._wasmMemory.buffer);
|
|
1031
|
+
|
|
1032
|
+
const messageStack = await EagleProfiler.getMessageStack(
|
|
1033
|
+
this._pvGetErrorStack,
|
|
1034
|
+
this._pvFreeErrorStack,
|
|
1035
|
+
this._messageStackAddressAddressAddress,
|
|
1036
|
+
this._messageStackDepthAddress,
|
|
1037
|
+
memoryBufferView,
|
|
1038
|
+
memoryBufferUint8
|
|
860
1039
|
);
|
|
1040
|
+
|
|
1041
|
+
throw pvStatusToException(status, "Eagle reset failed", messageStack);
|
|
861
1042
|
}
|
|
862
1043
|
})
|
|
863
1044
|
.then(() => {
|
|
@@ -873,6 +1054,7 @@ export class Eagle extends EagleBase {
|
|
|
873
1054
|
* Releases resources acquired by Eagle
|
|
874
1055
|
*/
|
|
875
1056
|
public async release(): Promise<void> {
|
|
1057
|
+
await super.release();
|
|
876
1058
|
await this._pvFree(this._scoresAddress);
|
|
877
1059
|
await this._pvEagleDelete(this._objectAddress);
|
|
878
1060
|
delete this._wasmMemory;
|
|
@@ -905,7 +1087,7 @@ export class Eagle extends EagleBase {
|
|
|
905
1087
|
Int32Array.BYTES_PER_ELEMENT
|
|
906
1088
|
);
|
|
907
1089
|
if (objectAddressAddress === 0) {
|
|
908
|
-
throw new
|
|
1090
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
909
1091
|
}
|
|
910
1092
|
|
|
911
1093
|
const accessKeyAddress = await baseWasmOutput.alignedAlloc(
|
|
@@ -913,7 +1095,7 @@ export class Eagle extends EagleBase {
|
|
|
913
1095
|
(accessKey.length + 1) * Uint8Array.BYTES_PER_ELEMENT
|
|
914
1096
|
);
|
|
915
1097
|
if (accessKeyAddress === 0) {
|
|
916
|
-
throw new
|
|
1098
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
917
1099
|
}
|
|
918
1100
|
for (let i = 0; i < accessKey.length; i++) {
|
|
919
1101
|
memoryBufferUint8[accessKeyAddress + i] = accessKey.charCodeAt(i);
|
|
@@ -926,7 +1108,7 @@ export class Eagle extends EagleBase {
|
|
|
926
1108
|
(modelPathEncoded.length + 1) * Uint8Array.BYTES_PER_ELEMENT
|
|
927
1109
|
);
|
|
928
1110
|
if (modelPathAddress === 0) {
|
|
929
|
-
throw new
|
|
1111
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
930
1112
|
}
|
|
931
1113
|
memoryBufferUint8.set(modelPathEncoded, modelPathAddress);
|
|
932
1114
|
memoryBufferUint8[modelPathAddress + modelPathEncoded.length] = 0;
|
|
@@ -937,7 +1119,7 @@ export class Eagle extends EagleBase {
|
|
|
937
1119
|
numSpeakers * Int32Array.BYTES_PER_ELEMENT
|
|
938
1120
|
);
|
|
939
1121
|
if (profilesAddressAddress === 0) {
|
|
940
|
-
throw new
|
|
1122
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
941
1123
|
}
|
|
942
1124
|
const profilesAddressList: number[] = [];
|
|
943
1125
|
for (const profile of speakerProfiles) {
|
|
@@ -946,7 +1128,7 @@ export class Eagle extends EagleBase {
|
|
|
946
1128
|
profile.bytes.length * Uint8Array.BYTES_PER_ELEMENT
|
|
947
1129
|
);
|
|
948
1130
|
if (profileAddress === 0) {
|
|
949
|
-
throw new
|
|
1131
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
950
1132
|
}
|
|
951
1133
|
memoryBufferUint8.set(profile.bytes, profileAddress);
|
|
952
1134
|
profilesAddressList.push(profileAddress);
|
|
@@ -965,18 +1147,22 @@ export class Eagle extends EagleBase {
|
|
|
965
1147
|
await baseWasmOutput.pvFree(accessKeyAddress);
|
|
966
1148
|
await baseWasmOutput.pvFree(modelPathAddress);
|
|
967
1149
|
await baseWasmOutput.pvFree(profilesAddressAddress);
|
|
968
|
-
if (status !== PV_STATUS_SUCCESS) {
|
|
969
|
-
const msg = `'pv_eagle_init' failed with status ${arrayBufferToStringAtIndex(
|
|
970
|
-
memoryBufferUint8,
|
|
971
|
-
await baseWasmOutput.pvStatusToString(status)
|
|
972
|
-
)}`;
|
|
973
1150
|
|
|
974
|
-
|
|
975
|
-
|
|
1151
|
+
const memoryBufferView = new DataView(baseWasmOutput.memory.buffer);
|
|
1152
|
+
|
|
1153
|
+
if (status !== PV_STATUS_SUCCESS) {
|
|
1154
|
+
const messageStack = await EagleProfiler.getMessageStack(
|
|
1155
|
+
baseWasmOutput.pvGetErrorStack,
|
|
1156
|
+
baseWasmOutput.pvFreeErrorStack,
|
|
1157
|
+
baseWasmOutput.messageStackAddressAddressAddress,
|
|
1158
|
+
baseWasmOutput.messageStackDepthAddress,
|
|
1159
|
+
memoryBufferView,
|
|
1160
|
+
memoryBufferUint8
|
|
976
1161
|
);
|
|
1162
|
+
|
|
1163
|
+
throw pvStatusToException(status, "Eagle init failed", messageStack, baseWasmOutput.pvError);
|
|
977
1164
|
}
|
|
978
1165
|
|
|
979
|
-
const memoryBufferView = new DataView(baseWasmOutput.memory.buffer);
|
|
980
1166
|
const objectAddress = memoryBufferView.getInt32(objectAddressAddress, true);
|
|
981
1167
|
await baseWasmOutput.pvFree(objectAddressAddress);
|
|
982
1168
|
|
|
@@ -985,7 +1171,7 @@ export class Eagle extends EagleBase {
|
|
|
985
1171
|
numSpeakers * Float32Array.BYTES_PER_ELEMENT
|
|
986
1172
|
);
|
|
987
1173
|
if (scoresAddress === 0) {
|
|
988
|
-
throw new
|
|
1174
|
+
throw new EagleErrors.EagleOutOfMemoryError('malloc failed: Cannot allocate memory');
|
|
989
1175
|
}
|
|
990
1176
|
|
|
991
1177
|
const frameLength = await pv_eagle_frame_length();
|