react-native-sherpa-onnx 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +232 -236
- package/SherpaOnnx.podspec +68 -64
- package/android/build.gradle +182 -192
- package/android/codegen.gradle +57 -0
- package/android/prebuilt-download.gradle +428 -0
- package/android/prebuilt-versions.gradle +43 -0
- package/android/proguard-rules.pro +10 -0
- package/android/src/main/assets/testModels/add_mul_add.onnx +28 -0
- package/android/src/main/assets/testModels/nnapi_internal_uint8_support.onnx +0 -0
- package/android/src/main/assets/testModels/qnn_multi_ctx_embed.onnx +0 -0
- package/android/src/main/cpp/CMakeLists.txt +166 -129
- package/android/src/main/cpp/CMakePresets.json +54 -0
- package/android/src/main/cpp/crypto/sha256.cpp +174 -0
- package/android/src/main/cpp/crypto/sha256.h +16 -0
- package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-helper.cpp +404 -0
- package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-helper.h +56 -0
- package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-jni.cpp +181 -0
- package/android/src/main/cpp/jni/audio/sherpa-onnx-audio-convert-jni.cpp +888 -0
- package/{ios → android/src/main/cpp/jni/model_detect}/sherpa-onnx-common.h +18 -18
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-detect-jni-common.cpp +86 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-detect-jni-common.h +20 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.cpp +423 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.h +55 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-stt.cpp +399 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-tts.cpp +238 -0
- package/{ios → android/src/main/cpp/jni/model_detect}/sherpa-onnx-model-detect.h +122 -89
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-stt-wrapper.cpp +99 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-stt-wrapper.h +16 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-tts-wrapper.cpp +78 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-tts-wrapper.h +16 -0
- package/android/src/main/cpp/jni/module/sherpa-onnx-module-jni.cpp +190 -0
- package/android/src/main/cpp/jni/tts/sherpa-onnx-tts-zipvoice-jni.cpp +301 -0
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxArchiveHelper.kt +94 -0
- package/android/src/main/java/com/sherpaonnx/{SherpaOnnxCoreHelper.kt → SherpaOnnxAssetHelper.kt} +350 -236
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxModule.kt +791 -483
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxSttHelper.kt +699 -109
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxTtsHelper.kt +1123 -668
- package/android/src/main/java/com/sherpaonnx/ZipvoiceTtsWrapper.kt +187 -0
- package/ios/SherpaOnnx+Assets.h +11 -0
- package/ios/SherpaOnnx+Assets.mm +325 -0
- package/ios/SherpaOnnx+STT.mm +455 -118
- package/ios/SherpaOnnx+TTS.mm +1101 -712
- package/ios/SherpaOnnx.h +17 -6
- package/ios/SherpaOnnx.mm +206 -311
- package/ios/SherpaOnnx.xcconfig +19 -19
- package/ios/SherpaOnnxCoreMLHelper.swift +24 -0
- package/ios/archive/sherpa-onnx-archive-helper.h +21 -0
- package/ios/archive/sherpa-onnx-archive-helper.mm +296 -0
- package/ios/libarchive_darwin_config.h +153 -0
- package/{android/src/main/cpp/jni → ios/model_detect}/sherpa-onnx-common.h +18 -18
- package/ios/model_detect/sherpa-onnx-model-detect-helper.h +49 -0
- package/ios/model_detect/sherpa-onnx-model-detect-helper.mm +210 -0
- package/ios/model_detect/sherpa-onnx-model-detect-stt.mm +344 -0
- package/ios/model_detect/sherpa-onnx-model-detect-tts.mm +201 -0
- package/{android/src/main/cpp/jni → ios/model_detect}/sherpa-onnx-model-detect.h +117 -89
- package/ios/scripts/patch-libarchive-includes.sh +61 -0
- package/ios/scripts/setup-ios-libarchive.sh +98 -0
- package/ios/stt/sherpa-onnx-stt-wrapper.h +129 -0
- package/ios/stt/sherpa-onnx-stt-wrapper.mm +523 -0
- package/ios/{sherpa-onnx-tts-wrapper.h → tts/sherpa-onnx-tts-wrapper.h} +90 -85
- package/ios/{sherpa-onnx-tts-wrapper.mm → tts/sherpa-onnx-tts-wrapper.mm} +376 -345
- package/lib/module/NativeSherpaOnnx.js +3 -0
- package/lib/module/NativeSherpaOnnx.js.map +1 -1
- package/lib/module/audio/index.js +22 -0
- package/lib/module/audio/index.js.map +1 -0
- package/lib/module/diarization/index.js +1 -1
- package/lib/module/diarization/index.js.map +1 -1
- package/lib/module/download/ModelDownloadManager.js +918 -0
- package/lib/module/download/ModelDownloadManager.js.map +1 -0
- package/lib/module/download/extractTarBz2.js +53 -0
- package/lib/module/download/extractTarBz2.js.map +1 -0
- package/lib/module/download/index.js +6 -0
- package/lib/module/download/index.js.map +1 -0
- package/lib/module/download/validation.js +178 -0
- package/lib/module/download/validation.js.map +1 -0
- package/lib/module/enhancement/index.js +1 -1
- package/lib/module/enhancement/index.js.map +1 -1
- package/lib/module/index.js +41 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/separation/index.js +1 -1
- package/lib/module/separation/index.js.map +1 -1
- package/lib/module/stt/index.js +127 -60
- package/lib/module/stt/index.js.map +1 -1
- package/lib/module/stt/sttModelLanguages.js +512 -0
- package/lib/module/stt/sttModelLanguages.js.map +1 -0
- package/lib/module/stt/types.js +53 -1
- package/lib/module/stt/types.js.map +1 -1
- package/lib/module/tts/index.js +216 -289
- package/lib/module/tts/index.js.map +1 -1
- package/lib/module/tts/types.js +86 -1
- package/lib/module/tts/types.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils.js +86 -73
- package/lib/module/utils.js.map +1 -1
- package/lib/module/vad/index.js +1 -1
- package/lib/module/vad/index.js.map +1 -1
- package/lib/typescript/src/NativeSherpaOnnx.d.ts +192 -38
- package/lib/typescript/src/NativeSherpaOnnx.d.ts.map +1 -1
- package/lib/typescript/src/audio/index.d.ts +13 -0
- package/lib/typescript/src/audio/index.d.ts.map +1 -0
- package/lib/typescript/src/diarization/index.d.ts +3 -2
- package/lib/typescript/src/diarization/index.d.ts.map +1 -1
- package/lib/typescript/src/download/ModelDownloadManager.d.ts +108 -0
- package/lib/typescript/src/download/ModelDownloadManager.d.ts.map +1 -0
- package/lib/typescript/src/download/extractTarBz2.d.ts +14 -0
- package/lib/typescript/src/download/extractTarBz2.d.ts.map +1 -0
- package/lib/typescript/src/download/index.d.ts +7 -0
- package/lib/typescript/src/download/index.d.ts.map +1 -0
- package/lib/typescript/src/download/validation.d.ts +57 -0
- package/lib/typescript/src/download/validation.d.ts.map +1 -0
- package/lib/typescript/src/enhancement/index.d.ts +3 -2
- package/lib/typescript/src/enhancement/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +26 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/separation/index.d.ts +3 -2
- package/lib/typescript/src/separation/index.d.ts.map +1 -1
- package/lib/typescript/src/stt/index.d.ts +31 -43
- package/lib/typescript/src/stt/index.d.ts.map +1 -1
- package/lib/typescript/src/stt/sttModelLanguages.d.ts +52 -0
- package/lib/typescript/src/stt/sttModelLanguages.d.ts.map +1 -0
- package/lib/typescript/src/stt/types.d.ts +196 -9
- package/lib/typescript/src/stt/types.d.ts.map +1 -1
- package/lib/typescript/src/tts/index.d.ts +25 -211
- package/lib/typescript/src/tts/index.d.ts.map +1 -1
- package/lib/typescript/src/tts/types.d.ts +148 -25
- package/lib/typescript/src/tts/types.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +0 -32
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/utils.d.ts +28 -13
- package/lib/typescript/src/utils.d.ts.map +1 -1
- package/lib/typescript/src/vad/index.d.ts +3 -2
- package/lib/typescript/src/vad/index.d.ts.map +1 -1
- package/package.json +250 -222
- package/scripts/check-qnn-support.sh +78 -0
- package/scripts/setup-ios-framework.sh +379 -282
- package/src/NativeSherpaOnnx.ts +474 -251
- package/src/audio/index.ts +32 -0
- package/src/diarization/index.ts +4 -2
- package/src/download/ModelDownloadManager.ts +1325 -0
- package/src/download/extractTarBz2.ts +78 -0
- package/src/download/index.ts +43 -0
- package/src/download/validation.ts +279 -0
- package/src/enhancement/index.ts +4 -2
- package/src/index.tsx +78 -27
- package/src/separation/index.ts +4 -2
- package/src/stt/index.ts +249 -89
- package/src/stt/sttModelLanguages.ts +237 -0
- package/src/stt/types.ts +263 -9
- package/src/tts/index.ts +470 -458
- package/src/tts/types.ts +373 -218
- package/src/types.ts +0 -44
- package/src/utils.ts +145 -131
- package/src/vad/index.ts +4 -2
- package/third_party/ffmpeg_prebuilt/ANDROID_RELEASE_TAG +1 -0
- package/third_party/libarchive_prebuilt/ANDROID_RELEASE_TAG +1 -0
- package/third_party/libarchive_prebuilt/IOS_RELEASE_TAG +1 -0
- package/third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG +1 -0
- package/third_party/sherpa-onnx-prebuilt/IOS_RELEASE_TAG +1 -0
- package/android/src/main/cpp/include/sherpa-onnx/c-api/c-api.h +0 -1918
- package/android/src/main/cpp/include/sherpa-onnx/c-api/cxx-api.h +0 -841
- package/android/src/main/cpp/jni/sherpa-onnx-model-detect.cpp +0 -541
- package/android/src/main/cpp/jni/sherpa-onnx-stt-jni.cpp +0 -336
- package/android/src/main/cpp/jni/sherpa-onnx-stt-wrapper.cpp +0 -222
- package/android/src/main/cpp/jni/sherpa-onnx-stt-wrapper.h +0 -68
- package/android/src/main/cpp/jni/sherpa-onnx-tts-jni.cpp +0 -823
- package/android/src/main/cpp/jni/sherpa-onnx-tts-wrapper.cpp +0 -387
- package/android/src/main/cpp/jni/sherpa-onnx-tts-wrapper.h +0 -147
- package/ios/Frameworks/sherpa_onnx.xcframework.zip +0 -0
- package/ios/include/sherpa-onnx/c-api/c-api.h +0 -1918
- package/ios/include/sherpa-onnx/c-api/cxx-api.h +0 -841
- package/ios/sherpa-onnx-model-detect.mm +0 -441
- package/ios/sherpa-onnx-stt-wrapper.h +0 -48
- package/ios/sherpa-onnx-stt-wrapper.mm +0 -201
- package/scripts/copy-headers.js +0 -184
- package/scripts/setup-assets.js +0 -323
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { DeviceEventEmitter } from 'react-native';
|
|
2
|
+
import SherpaOnnx from '../NativeSherpaOnnx';
|
|
3
|
+
|
|
4
|
+
export type ExtractProgressEvent = {
|
|
5
|
+
bytes: number;
|
|
6
|
+
totalBytes: number;
|
|
7
|
+
percent: number;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type ExtractResult = {
|
|
11
|
+
success: boolean;
|
|
12
|
+
path?: string;
|
|
13
|
+
sha256?: string;
|
|
14
|
+
reason?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export async function extractTarBz2(
|
|
18
|
+
sourcePath: string,
|
|
19
|
+
targetPath: string,
|
|
20
|
+
force = true,
|
|
21
|
+
onProgress?: (event: ExtractProgressEvent) => void,
|
|
22
|
+
signal?: AbortSignal
|
|
23
|
+
): Promise<ExtractResult> {
|
|
24
|
+
let subscription: { remove: () => void } | null = null;
|
|
25
|
+
let removeAbortListener: (() => void) | null = null;
|
|
26
|
+
|
|
27
|
+
if (signal?.aborted) {
|
|
28
|
+
const abortError = new Error('Extraction aborted');
|
|
29
|
+
abortError.name = 'AbortError';
|
|
30
|
+
throw abortError;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (onProgress) {
|
|
34
|
+
subscription = DeviceEventEmitter.addListener(
|
|
35
|
+
'extractTarBz2Progress',
|
|
36
|
+
(event: ExtractProgressEvent & { sourcePath?: string }) => {
|
|
37
|
+
// Only handle events for this extraction (fixes parallel extractions showing same %)
|
|
38
|
+
if (event.sourcePath != null && event.sourcePath !== sourcePath) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const safePercent = Math.max(0, Math.min(100, event.percent));
|
|
42
|
+
onProgress({ ...event, percent: safePercent });
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (signal) {
|
|
48
|
+
const onAbort = () => {
|
|
49
|
+
try {
|
|
50
|
+
SherpaOnnx.cancelExtractTarBz2();
|
|
51
|
+
} catch {
|
|
52
|
+
// Ignore cancel errors to avoid crashing on abort.
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
signal.addEventListener('abort', onAbort);
|
|
56
|
+
removeAbortListener = () => signal.removeEventListener('abort', onAbort);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const result = await SherpaOnnx.extractTarBz2(
|
|
61
|
+
sourcePath,
|
|
62
|
+
targetPath,
|
|
63
|
+
force
|
|
64
|
+
);
|
|
65
|
+
if (!result.success) {
|
|
66
|
+
const message = result.reason || 'Extraction failed';
|
|
67
|
+
const error = new Error(message);
|
|
68
|
+
if (signal?.aborted || /cancel/i.test(message)) {
|
|
69
|
+
error.name = 'AbortError';
|
|
70
|
+
}
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
} finally {
|
|
75
|
+
subscription?.remove();
|
|
76
|
+
removeAbortListener?.();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export { extractTarBz2 } from './extractTarBz2';
|
|
2
|
+
export type { ExtractProgressEvent } from './extractTarBz2';
|
|
3
|
+
export {
|
|
4
|
+
listModelsByCategory,
|
|
5
|
+
refreshModelsByCategory,
|
|
6
|
+
getModelsCacheStatusByCategory,
|
|
7
|
+
getModelByIdByCategory,
|
|
8
|
+
listDownloadedModelsByCategory,
|
|
9
|
+
isModelDownloadedByCategory,
|
|
10
|
+
getLocalModelPathByCategory,
|
|
11
|
+
downloadModelByCategory,
|
|
12
|
+
deleteModelByCategory,
|
|
13
|
+
clearModelCacheByCategory,
|
|
14
|
+
getDownloadStorageBase,
|
|
15
|
+
subscribeDownloadProgress,
|
|
16
|
+
subscribeModelsListUpdated,
|
|
17
|
+
updateModelLastUsed,
|
|
18
|
+
listDownloadedModelsWithMetadata,
|
|
19
|
+
cleanupLeastRecentlyUsed,
|
|
20
|
+
ModelCategory,
|
|
21
|
+
} from './ModelDownloadManager';
|
|
22
|
+
export type {
|
|
23
|
+
ModelMetaBase,
|
|
24
|
+
TtsModelMeta,
|
|
25
|
+
TtsModelType,
|
|
26
|
+
Quantization,
|
|
27
|
+
SizeTier,
|
|
28
|
+
DownloadProgress,
|
|
29
|
+
DownloadProgressListener,
|
|
30
|
+
ModelsListUpdatedListener,
|
|
31
|
+
DownloadResult,
|
|
32
|
+
ModelWithMetadata,
|
|
33
|
+
} from './ModelDownloadManager';
|
|
34
|
+
export {
|
|
35
|
+
validateChecksum,
|
|
36
|
+
validateExtractedFiles,
|
|
37
|
+
checkDiskSpace,
|
|
38
|
+
setExpectedFilesForCategory,
|
|
39
|
+
getExpectedFilesForCategory,
|
|
40
|
+
parseChecksumFile,
|
|
41
|
+
calculateFileChecksum,
|
|
42
|
+
} from './validation';
|
|
43
|
+
export type { ValidationError } from './validation';
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DocumentDirectoryPath,
|
|
3
|
+
stat,
|
|
4
|
+
exists,
|
|
5
|
+
readDir,
|
|
6
|
+
type ReadDirResItemT,
|
|
7
|
+
} from '@dr.pogodin/react-native-fs';
|
|
8
|
+
import SherpaOnnx from '../NativeSherpaOnnx';
|
|
9
|
+
|
|
10
|
+
export type ValidationError =
|
|
11
|
+
| 'CHECKSUM_MISMATCH'
|
|
12
|
+
| 'CHECKSUM_FAILED'
|
|
13
|
+
| 'MISSING_FILES'
|
|
14
|
+
| 'INSUFFICIENT_DISK_SPACE';
|
|
15
|
+
|
|
16
|
+
export class ValidationResult {
|
|
17
|
+
success: boolean;
|
|
18
|
+
error?: ValidationError;
|
|
19
|
+
message?: string;
|
|
20
|
+
|
|
21
|
+
constructor(success: boolean, error?: ValidationError, message?: string) {
|
|
22
|
+
this.success = success;
|
|
23
|
+
this.error = error;
|
|
24
|
+
this.message = message;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Parse checksum.txt format into a Map of filename -> hash
|
|
30
|
+
* Expected format:
|
|
31
|
+
* filename\tsha256hash
|
|
32
|
+
* example:
|
|
33
|
+
* vits-vctk.tar.bz2 4f0a02db66914b3760b144cebc004e65dd4d1aeef43379f2b058849e74002490
|
|
34
|
+
*/
|
|
35
|
+
export function parseChecksumFile(content: string): Map<string, string> {
|
|
36
|
+
const checksums = new Map<string, string>();
|
|
37
|
+
const lines = content.split('\n').filter((line) => line.trim());
|
|
38
|
+
|
|
39
|
+
for (const line of lines) {
|
|
40
|
+
const [filename, hash] = line.split(/\s+/);
|
|
41
|
+
if (filename && hash) {
|
|
42
|
+
checksums.set(filename.trim(), hash.trim());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return checksums;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Calculate SHA256 hash of a file in chunks to avoid OOM
|
|
51
|
+
* Reads file in 1MB chunks and processes them efficiently
|
|
52
|
+
*/
|
|
53
|
+
export async function calculateFileChecksum(
|
|
54
|
+
filePath: string,
|
|
55
|
+
onProgress?: (
|
|
56
|
+
bytesProcessed: number,
|
|
57
|
+
totalBytes: number,
|
|
58
|
+
percent: number
|
|
59
|
+
) => void
|
|
60
|
+
): Promise<string> {
|
|
61
|
+
try {
|
|
62
|
+
const digest = await SherpaOnnx.computeFileSha256(filePath);
|
|
63
|
+
if (onProgress) {
|
|
64
|
+
const statResult = await stat(filePath);
|
|
65
|
+
const total = statResult.size;
|
|
66
|
+
onProgress(total, total, 100);
|
|
67
|
+
}
|
|
68
|
+
return digest.toLowerCase();
|
|
69
|
+
} catch (error) {
|
|
70
|
+
throw new Error(`Failed to calculate checksum: ${error}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Validate checksum of downloaded file
|
|
76
|
+
*/
|
|
77
|
+
export async function validateChecksum(
|
|
78
|
+
filePath: string,
|
|
79
|
+
expectedChecksum: string,
|
|
80
|
+
onProgress?: (
|
|
81
|
+
bytesProcessed: number,
|
|
82
|
+
totalBytes: number,
|
|
83
|
+
percent: number
|
|
84
|
+
) => void
|
|
85
|
+
): Promise<ValidationResult> {
|
|
86
|
+
try {
|
|
87
|
+
const actualChecksum = await calculateFileChecksum(filePath, onProgress);
|
|
88
|
+
// checksum comparison logged
|
|
89
|
+
if (actualChecksum.toLowerCase() !== expectedChecksum.toLowerCase()) {
|
|
90
|
+
return new ValidationResult(
|
|
91
|
+
false,
|
|
92
|
+
'CHECKSUM_MISMATCH',
|
|
93
|
+
`Checksum mismatch: expected ${expectedChecksum}, got ${actualChecksum}`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
return new ValidationResult(true);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
return new ValidationResult(
|
|
99
|
+
false,
|
|
100
|
+
'CHECKSUM_FAILED',
|
|
101
|
+
`Failed to validate checksum: ${error}`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Validate that extraction was successful by checking:
|
|
108
|
+
* - Directory exists and is not empty
|
|
109
|
+
* - Contains at least some files (not just directories)
|
|
110
|
+
*
|
|
111
|
+
* The actual model validation (correct files for specific model type)
|
|
112
|
+
* is delegated to the native DetectSttModel / DetectTtsModel functions,
|
|
113
|
+
* so we don't need to check for specific filenames here.
|
|
114
|
+
*/
|
|
115
|
+
export async function validateExtractedFiles(
|
|
116
|
+
modelDir: string,
|
|
117
|
+
_category: string
|
|
118
|
+
): Promise<ValidationResult> {
|
|
119
|
+
try {
|
|
120
|
+
const dirExists = await exists(modelDir);
|
|
121
|
+
if (!dirExists) {
|
|
122
|
+
return new ValidationResult(
|
|
123
|
+
false,
|
|
124
|
+
'MISSING_FILES',
|
|
125
|
+
`Model directory does not exist: ${modelDir}`
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const isModelLikeFile = (name: string) => {
|
|
130
|
+
const lower = name.toLowerCase();
|
|
131
|
+
return (
|
|
132
|
+
lower.endsWith('.onnx') ||
|
|
133
|
+
lower.endsWith('.txt') ||
|
|
134
|
+
lower.endsWith('.bin') ||
|
|
135
|
+
lower.endsWith('.json')
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const collectFilesRecursive = async (
|
|
140
|
+
dir: string,
|
|
141
|
+
depth = 0,
|
|
142
|
+
maxDepth = 4
|
|
143
|
+
): Promise<ReadDirResItemT[]> => {
|
|
144
|
+
if (depth > maxDepth) return [];
|
|
145
|
+
|
|
146
|
+
const entries = await readDir(dir);
|
|
147
|
+
const files: ReadDirResItemT[] = [];
|
|
148
|
+
|
|
149
|
+
for (const entry of entries) {
|
|
150
|
+
if (entry.isDirectory()) {
|
|
151
|
+
const nested = await collectFilesRecursive(
|
|
152
|
+
entry.path,
|
|
153
|
+
depth + 1,
|
|
154
|
+
maxDepth
|
|
155
|
+
);
|
|
156
|
+
files.push(...nested);
|
|
157
|
+
} else {
|
|
158
|
+
files.push(entry);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return files;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const entries = await readDir(modelDir);
|
|
166
|
+
const actualFiles = entries.filter((entry) => !entry.isDirectory());
|
|
167
|
+
const subdirs = entries.filter((entry) => entry.isDirectory());
|
|
168
|
+
|
|
169
|
+
if (actualFiles.length === 0 && subdirs.length === 0) {
|
|
170
|
+
return new ValidationResult(
|
|
171
|
+
false,
|
|
172
|
+
'MISSING_FILES',
|
|
173
|
+
`Extraction failed: directory is empty: ${modelDir}`
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
let hasModelLikeFiles = actualFiles.some((file) =>
|
|
178
|
+
isModelLikeFile(file.name)
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
if (!hasModelLikeFiles) {
|
|
182
|
+
const nestedFiles = await collectFilesRecursive(modelDir);
|
|
183
|
+
hasModelLikeFiles = nestedFiles.some((file) =>
|
|
184
|
+
isModelLikeFile(file.name)
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (!hasModelLikeFiles) {
|
|
189
|
+
return new ValidationResult(
|
|
190
|
+
false,
|
|
191
|
+
'MISSING_FILES',
|
|
192
|
+
`Extraction may have failed: no model files (.onnx/.txt/.bin/.json) found under ${modelDir}`
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return new ValidationResult(true);
|
|
197
|
+
} catch (error) {
|
|
198
|
+
return new ValidationResult(
|
|
199
|
+
false,
|
|
200
|
+
'MISSING_FILES',
|
|
201
|
+
`Failed to validate extracted files: ${error}`
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Get available disk space (in bytes)
|
|
208
|
+
* This is a simplified version. For accurate values on Android/iOS, use native modules.
|
|
209
|
+
*/
|
|
210
|
+
export async function getAvailableDiskSpace(): Promise<number> {
|
|
211
|
+
try {
|
|
212
|
+
// Try to get the document directory (simple check for availability)
|
|
213
|
+
const dirExists = await exists(DocumentDirectoryPath);
|
|
214
|
+
if (dirExists) {
|
|
215
|
+
// Default to 10GB for modern devices
|
|
216
|
+
// In production, integrate native disk space calculation
|
|
217
|
+
return 10 * 1024 * 1024 * 1024; // 10GB
|
|
218
|
+
}
|
|
219
|
+
} catch (error) {
|
|
220
|
+
console.warn('Failed to check disk space:', error);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Fallback: return 10GB estimate for modern devices
|
|
224
|
+
return 10 * 1024 * 1024 * 1024;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Check if there's enough disk space for download
|
|
229
|
+
* Adds 20% buffer to the required size
|
|
230
|
+
*/
|
|
231
|
+
export async function checkDiskSpace(
|
|
232
|
+
requiredBytes: number
|
|
233
|
+
): Promise<ValidationResult> {
|
|
234
|
+
try {
|
|
235
|
+
const available = await getAvailableDiskSpace();
|
|
236
|
+
const buffer = requiredBytes * 0.2; // 20% safety buffer
|
|
237
|
+
const totalRequired = requiredBytes + buffer;
|
|
238
|
+
|
|
239
|
+
if (available < totalRequired) {
|
|
240
|
+
const availableGB = (available / (1024 * 1024 * 1024)).toFixed(2);
|
|
241
|
+
const requiredGB = (totalRequired / (1024 * 1024 * 1024)).toFixed(2);
|
|
242
|
+
return new ValidationResult(
|
|
243
|
+
false,
|
|
244
|
+
'INSUFFICIENT_DISK_SPACE',
|
|
245
|
+
`Insufficient disk space. Available: ${availableGB}GB, Required: ${requiredGB}GB`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return new ValidationResult(true);
|
|
250
|
+
} catch (error) {
|
|
251
|
+
return new ValidationResult(
|
|
252
|
+
false,
|
|
253
|
+
'INSUFFICIENT_DISK_SPACE',
|
|
254
|
+
`Failed to check disk space: ${error}`
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Update expected files configuration for a category
|
|
261
|
+
* DEPRECATED: The native DetectSttModel/DetectTtsModel functions handle model validation.
|
|
262
|
+
* This function is kept for backward compatibility but does nothing.
|
|
263
|
+
*/
|
|
264
|
+
export function setExpectedFilesForCategory(
|
|
265
|
+
_category: string,
|
|
266
|
+
_files: string[]
|
|
267
|
+
): void {
|
|
268
|
+
// No-op: validation is now handled by native detect functions
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Get expected files for a category
|
|
273
|
+
* DEPRECATED: The native DetectSttModel/DetectTtsModel functions handle model validation.
|
|
274
|
+
* This function is kept for backward compatibility.
|
|
275
|
+
*/
|
|
276
|
+
export function getExpectedFilesForCategory(_category: string): string[] {
|
|
277
|
+
// Return empty array: validation is now handled by native detect functions
|
|
278
|
+
return [];
|
|
279
|
+
}
|
package/src/enhancement/index.ts
CHANGED
|
@@ -10,16 +10,18 @@
|
|
|
10
10
|
* // Future usage:
|
|
11
11
|
* import { initializeEnhancement, enhanceAudio } from 'react-native-sherpa-onnx/enhancement';
|
|
12
12
|
*
|
|
13
|
-
* await initializeEnhancement({ modelPath: 'models/enhancement-model' });
|
|
13
|
+
* await initializeEnhancement({ modelPath: { type: 'auto', path: 'models/enhancement-model' } });
|
|
14
14
|
* const enhancedPath = await enhanceAudio('path/to/noisy-audio.wav');
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
import type { ModelPathConfig } from '../types';
|
|
19
|
+
|
|
18
20
|
/**
|
|
19
21
|
* Enhancement initialization options (placeholder)
|
|
20
22
|
*/
|
|
21
23
|
export interface EnhancementInitializeOptions {
|
|
22
|
-
modelPath:
|
|
24
|
+
modelPath: ModelPathConfig;
|
|
23
25
|
// Additional enhancement-specific options will be added here
|
|
24
26
|
}
|
|
25
27
|
|
package/src/index.tsx
CHANGED
|
@@ -1,27 +1,78 @@
|
|
|
1
|
-
import SherpaOnnx from './NativeSherpaOnnx';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// -
|
|
20
|
-
// - import { ... } from 'react-native-sherpa-onnx/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
1
|
+
import SherpaOnnx from './NativeSherpaOnnx';
|
|
2
|
+
import type { AccelerationSupport } from './NativeSherpaOnnx';
|
|
3
|
+
|
|
4
|
+
// Export common types and utilities
|
|
5
|
+
export type { AccelerationSupport } from './NativeSherpaOnnx';
|
|
6
|
+
export type { ModelPathConfig } from './types';
|
|
7
|
+
export {
|
|
8
|
+
assetModelPath,
|
|
9
|
+
autoModelPath,
|
|
10
|
+
fileModelPath,
|
|
11
|
+
getAssetPackPath,
|
|
12
|
+
getDefaultModelPath,
|
|
13
|
+
getPlayAssetDeliveryModelsPath,
|
|
14
|
+
listAssetModels,
|
|
15
|
+
listModelsAtPath,
|
|
16
|
+
resolveModelPath,
|
|
17
|
+
} from './utils';
|
|
18
|
+
|
|
19
|
+
// Note: Feature-specific exports are available via subpath imports:
|
|
20
|
+
// - import { ... } from 'react-native-sherpa-onnx/stt'
|
|
21
|
+
// - import { ... } from 'react-native-sherpa-onnx/tts'
|
|
22
|
+
// - import { ... } from 'react-native-sherpa-onnx/download'
|
|
23
|
+
// - import { ... } from 'react-native-sherpa-onnx/vad' (planned)
|
|
24
|
+
// - import { ... } from 'react-native-sherpa-onnx/diarization' (planned)
|
|
25
|
+
// - import { ... } from 'react-native-sherpa-onnx/enhancement' (planned)
|
|
26
|
+
// - import { ... } from 'react-native-sherpa-onnx/separation' (planned)
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Test method to verify sherpa-onnx native library is loaded.
|
|
30
|
+
*/
|
|
31
|
+
export function testSherpaInit(): Promise<string> {
|
|
32
|
+
return SherpaOnnx.testSherpaInit();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* QNN support (Android). Optional modelBase64 for canInit (session test); if omitted, SDK uses embedded test model.
|
|
37
|
+
*/
|
|
38
|
+
export function getQnnSupport(
|
|
39
|
+
modelBase64?: string
|
|
40
|
+
): Promise<AccelerationSupport> {
|
|
41
|
+
return SherpaOnnx.getQnnSupport(modelBase64);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Return the list of available ONNX Runtime execution providers
|
|
46
|
+
* (e.g. "CPU", "NNAPI", "QNN", "XNNPACK").
|
|
47
|
+
* Requires the ORT Java bridge from the onnxruntime AAR.
|
|
48
|
+
*/
|
|
49
|
+
export function getAvailableProviders(): Promise<string[]> {
|
|
50
|
+
return SherpaOnnx.getAvailableProviders();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* NNAPI support (Android). Optional modelBase64 for canInit (session test). On iOS returns all false.
|
|
55
|
+
*/
|
|
56
|
+
export function getNnapiSupport(
|
|
57
|
+
modelBase64?: string
|
|
58
|
+
): Promise<AccelerationSupport> {
|
|
59
|
+
return SherpaOnnx.getNnapiSupport(modelBase64);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* XNNPACK support. hasAccelerator = true when providerCompiled (CPU-optimized). Optional modelBase64 for canInit. On iOS returns all false.
|
|
64
|
+
*/
|
|
65
|
+
export function getXnnpackSupport(
|
|
66
|
+
modelBase64?: string
|
|
67
|
+
): Promise<AccelerationSupport> {
|
|
68
|
+
return SherpaOnnx.getXnnpackSupport(modelBase64);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Core ML support (iOS). providerCompiled = true (Core ML on iOS 11+), hasAccelerator = Apple Neural Engine. Optional modelBase64 for canInit. On Android returns all false.
|
|
73
|
+
*/
|
|
74
|
+
export function getCoreMlSupport(
|
|
75
|
+
modelBase64?: string
|
|
76
|
+
): Promise<AccelerationSupport> {
|
|
77
|
+
return SherpaOnnx.getCoreMlSupport(modelBase64);
|
|
78
|
+
}
|
package/src/separation/index.ts
CHANGED
|
@@ -10,16 +10,18 @@
|
|
|
10
10
|
* // Future usage:
|
|
11
11
|
* import { initializeSeparation, separateSources } from 'react-native-sherpa-onnx/separation';
|
|
12
12
|
*
|
|
13
|
-
* await initializeSeparation({ modelPath: 'models/separation-model' });
|
|
13
|
+
* await initializeSeparation({ modelPath: { type: 'auto', path: 'models/separation-model' } });
|
|
14
14
|
* const sources = await separateSources('path/to/mixed-audio.wav');
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
import type { ModelPathConfig } from '../types';
|
|
19
|
+
|
|
18
20
|
/**
|
|
19
21
|
* Separation initialization options (placeholder)
|
|
20
22
|
*/
|
|
21
23
|
export interface SeparationInitializeOptions {
|
|
22
|
-
modelPath:
|
|
24
|
+
modelPath: ModelPathConfig;
|
|
23
25
|
// Additional separation-specific options will be added here
|
|
24
26
|
}
|
|
25
27
|
|