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,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sherpa-onnx-model-detect-tts.mm
|
|
3
|
+
*
|
|
4
|
+
* Purpose: Detects TTS (text-to-speech) model type and fills TtsModelPaths from a model directory.
|
|
5
|
+
* Supports Vits, Piper, Kokoro, Zipvoice, Pocket, etc. Used by the TTS wrapper on iOS.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include "sherpa-onnx-model-detect.h"
|
|
9
|
+
#include "sherpa-onnx-model-detect-helper.h"
|
|
10
|
+
|
|
11
|
+
#include <string>
|
|
12
|
+
|
|
13
|
+
namespace sherpaonnx {
|
|
14
|
+
namespace {
|
|
15
|
+
|
|
16
|
+
using namespace model_detect;
|
|
17
|
+
|
|
18
|
+
TtsModelKind ParseTtsModelType(const std::string& modelType) {
|
|
19
|
+
if (modelType == "vits") return TtsModelKind::kVits;
|
|
20
|
+
if (modelType == "matcha") return TtsModelKind::kMatcha;
|
|
21
|
+
if (modelType == "kokoro") return TtsModelKind::kKokoro;
|
|
22
|
+
if (modelType == "kitten") return TtsModelKind::kKitten;
|
|
23
|
+
if (modelType == "pocket") return TtsModelKind::kPocket;
|
|
24
|
+
if (modelType == "zipvoice") return TtsModelKind::kZipvoice;
|
|
25
|
+
return TtsModelKind::kUnknown;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
} // namespace
|
|
29
|
+
|
|
30
|
+
TtsDetectResult DetectTtsModel(const std::string& modelDir, const std::string& modelType) {
|
|
31
|
+
using namespace model_detect;
|
|
32
|
+
|
|
33
|
+
TtsDetectResult result;
|
|
34
|
+
|
|
35
|
+
if (modelDir.empty()) {
|
|
36
|
+
result.error = "TTS: Model directory is empty";
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!FileExists(modelDir) || !IsDirectory(modelDir)) {
|
|
41
|
+
result.error = "TTS: Model directory does not exist or is not a directory: " + modelDir;
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const int kMaxSearchDepth = 4;
|
|
46
|
+
const std::vector<FileEntry> files = ListFilesRecursive(modelDir, kMaxSearchDepth);
|
|
47
|
+
|
|
48
|
+
std::string tokensFile = FindFileByName(modelDir, "tokens.txt", kMaxSearchDepth);
|
|
49
|
+
std::string lexiconFile = FindFileByName(modelDir, "lexicon.txt", kMaxSearchDepth);
|
|
50
|
+
std::string dataDirPath = FindDirectoryByName(modelDir, "espeak-ng-data", kMaxSearchDepth);
|
|
51
|
+
std::string voicesFile = FindFileByName(modelDir, "voices.bin", kMaxSearchDepth);
|
|
52
|
+
|
|
53
|
+
std::string acousticModel = FindOnnxByAnyToken(files, {"acoustic_model", "acoustic-model"}, std::nullopt);
|
|
54
|
+
std::string vocoder = FindOnnxByAnyToken(files, {"vocoder", "vocos"}, std::nullopt);
|
|
55
|
+
std::string encoder = FindOnnxByAnyToken(files, {"encoder"}, std::nullopt);
|
|
56
|
+
std::string decoder = FindOnnxByAnyToken(files, {"decoder"}, std::nullopt);
|
|
57
|
+
std::string lmFlow = FindOnnxByAnyToken(files, {"lm_flow", "lm-flow"}, std::nullopt);
|
|
58
|
+
std::string lmMain = FindOnnxByAnyToken(files, {"lm_main", "lm-main"}, std::nullopt);
|
|
59
|
+
std::string textConditioner = FindOnnxByAnyToken(files, {"text_conditioner", "text-conditioner"}, std::nullopt);
|
|
60
|
+
std::string vocabJsonFile = FindFileByName(modelDir, "vocab.json", kMaxSearchDepth);
|
|
61
|
+
std::string tokenScoresJsonFile = FindFileByName(modelDir, "token_scores.json", kMaxSearchDepth);
|
|
62
|
+
|
|
63
|
+
std::vector<std::string> modelExcludes = {"acoustic", "vocoder", "encoder", "decoder", "joiner"};
|
|
64
|
+
std::string ttsModel = FindOnnxByAnyToken(files, {"model"}, std::nullopt);
|
|
65
|
+
if (ttsModel.empty()) {
|
|
66
|
+
ttsModel = FindLargestOnnxExcludingTokens(files, modelExcludes);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
bool hasVits = !ttsModel.empty();
|
|
70
|
+
bool hasMatcha = !acousticModel.empty() && !vocoder.empty();
|
|
71
|
+
bool hasVoicesFile = !voicesFile.empty() && FileExists(voicesFile);
|
|
72
|
+
bool hasZipvoice = !encoder.empty() && !decoder.empty() && !vocoder.empty();
|
|
73
|
+
bool hasPocket = !lmFlow.empty() && !lmMain.empty() && !encoder.empty() && !decoder.empty() &&
|
|
74
|
+
!textConditioner.empty() && !vocabJsonFile.empty() && FileExists(vocabJsonFile) &&
|
|
75
|
+
!tokenScoresJsonFile.empty() && FileExists(tokenScoresJsonFile);
|
|
76
|
+
bool hasDataDir = !dataDirPath.empty() && IsDirectory(dataDirPath);
|
|
77
|
+
|
|
78
|
+
std::string modelDirLower = ToLower(modelDir);
|
|
79
|
+
bool isLikelyKitten = modelDirLower.find("kitten") != std::string::npos;
|
|
80
|
+
bool isLikelyKokoro = modelDirLower.find("kokoro") != std::string::npos;
|
|
81
|
+
|
|
82
|
+
if (hasMatcha) {
|
|
83
|
+
result.detectedModels.push_back({"matcha", modelDir});
|
|
84
|
+
}
|
|
85
|
+
if (hasPocket) {
|
|
86
|
+
result.detectedModels.push_back({"pocket", modelDir});
|
|
87
|
+
}
|
|
88
|
+
if (hasZipvoice && !hasMatcha) {
|
|
89
|
+
result.detectedModels.push_back({"zipvoice", modelDir});
|
|
90
|
+
}
|
|
91
|
+
if (hasVoicesFile) {
|
|
92
|
+
if (isLikelyKitten && !isLikelyKokoro) {
|
|
93
|
+
result.detectedModels.push_back({"kitten", modelDir});
|
|
94
|
+
} else if (isLikelyKokoro && !isLikelyKitten) {
|
|
95
|
+
result.detectedModels.push_back({"kokoro", modelDir});
|
|
96
|
+
} else {
|
|
97
|
+
result.detectedModels.push_back({"kokoro", modelDir});
|
|
98
|
+
result.detectedModels.push_back({"kitten", modelDir});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (hasVits) {
|
|
102
|
+
bool isLikelyVits = modelDirLower.find("vits") != std::string::npos;
|
|
103
|
+
bool voicesAmbiguous = !isLikelyKitten && !isLikelyKokoro;
|
|
104
|
+
bool addVits = false;
|
|
105
|
+
if (!hasVoicesFile) {
|
|
106
|
+
addVits = true;
|
|
107
|
+
} else {
|
|
108
|
+
if (isLikelyVits || voicesAmbiguous) addVits = true;
|
|
109
|
+
}
|
|
110
|
+
if (addVits) {
|
|
111
|
+
result.detectedModels.push_back({"vits", modelDir});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
TtsModelKind selected = TtsModelKind::kUnknown;
|
|
116
|
+
if (modelType != "auto") {
|
|
117
|
+
selected = ParseTtsModelType(modelType);
|
|
118
|
+
if (selected == TtsModelKind::kUnknown) {
|
|
119
|
+
result.error = "TTS: Unknown model type: " + modelType;
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
if (hasMatcha) {
|
|
124
|
+
selected = TtsModelKind::kMatcha;
|
|
125
|
+
} else if (hasPocket) {
|
|
126
|
+
selected = TtsModelKind::kPocket;
|
|
127
|
+
} else if (hasZipvoice) {
|
|
128
|
+
selected = TtsModelKind::kZipvoice;
|
|
129
|
+
} else if (hasVoicesFile) {
|
|
130
|
+
if (isLikelyKitten && !isLikelyKokoro) {
|
|
131
|
+
selected = TtsModelKind::kKitten;
|
|
132
|
+
} else if (isLikelyKokoro && !isLikelyKitten) {
|
|
133
|
+
selected = TtsModelKind::kKokoro;
|
|
134
|
+
} else {
|
|
135
|
+
selected = TtsModelKind::kKokoro;
|
|
136
|
+
}
|
|
137
|
+
} else if (hasVits) {
|
|
138
|
+
selected = TtsModelKind::kVits;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (selected == TtsModelKind::kUnknown) {
|
|
143
|
+
result.error = "TTS: No compatible model type detected in " + modelDir;
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (selected == TtsModelKind::kVits && !hasVits) {
|
|
148
|
+
result.error = "TTS: VITS model requested but model file not found in " + modelDir;
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
if (selected == TtsModelKind::kMatcha && !hasMatcha) {
|
|
152
|
+
result.error = "TTS: Matcha model requested but required files not found in " + modelDir;
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
if ((selected == TtsModelKind::kKokoro || selected == TtsModelKind::kKitten) && (!hasVits || !hasVoicesFile)) {
|
|
156
|
+
result.error = "TTS: Kokoro/Kitten model requested but required files not found in " + modelDir;
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
if (selected == TtsModelKind::kPocket && !hasPocket) {
|
|
160
|
+
result.error = "TTS: Pocket model requested but required files not found in " + modelDir;
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
if (selected == TtsModelKind::kZipvoice && !hasZipvoice) {
|
|
164
|
+
result.error = "TTS: Zipvoice model requested but required files not found in " + modelDir;
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
if ((selected == TtsModelKind::kVits || selected == TtsModelKind::kMatcha ||
|
|
168
|
+
selected == TtsModelKind::kKokoro || selected == TtsModelKind::kKitten ||
|
|
169
|
+
selected == TtsModelKind::kZipvoice) &&
|
|
170
|
+
!hasDataDir) {
|
|
171
|
+
result.error = "TTS: espeak-ng-data not found in " + modelDir +
|
|
172
|
+
". Copy espeak-ng-data into the model directory.";
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
result.selectedKind = selected;
|
|
177
|
+
result.paths.ttsModel = ttsModel;
|
|
178
|
+
result.paths.tokens = tokensFile;
|
|
179
|
+
result.paths.lexicon = (!lexiconFile.empty() && FileExists(lexiconFile)) ? lexiconFile : "";
|
|
180
|
+
result.paths.dataDir = dataDirPath;
|
|
181
|
+
result.paths.voices = voicesFile;
|
|
182
|
+
result.paths.acousticModel = acousticModel;
|
|
183
|
+
result.paths.vocoder = vocoder;
|
|
184
|
+
result.paths.encoder = encoder;
|
|
185
|
+
result.paths.decoder = decoder;
|
|
186
|
+
result.paths.lmFlow = lmFlow;
|
|
187
|
+
result.paths.lmMain = lmMain;
|
|
188
|
+
result.paths.textConditioner = textConditioner;
|
|
189
|
+
result.paths.vocabJson = vocabJsonFile;
|
|
190
|
+
result.paths.tokenScoresJson = tokenScoresJsonFile;
|
|
191
|
+
|
|
192
|
+
if (selected != TtsModelKind::kPocket && (tokensFile.empty() || !FileExists(tokensFile))) {
|
|
193
|
+
result.error = "TTS: tokens.txt not found in " + modelDir;
|
|
194
|
+
return result;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
result.ok = true;
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
} // namespace sherpaonnx
|
|
@@ -1,89 +1,117 @@
|
|
|
1
|
-
#ifndef SHERPA_ONNX_MODEL_DETECT_H
|
|
2
|
-
#define SHERPA_ONNX_MODEL_DETECT_H
|
|
3
|
-
|
|
4
|
-
#include "sherpa-onnx-common.h"
|
|
5
|
-
#include <optional>
|
|
6
|
-
#include <string>
|
|
7
|
-
#include <vector>
|
|
8
|
-
|
|
9
|
-
namespace sherpaonnx {
|
|
10
|
-
|
|
11
|
-
enum class SttModelKind {
|
|
12
|
-
kUnknown,
|
|
13
|
-
kTransducer,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
std::string
|
|
43
|
-
std::string
|
|
44
|
-
std::string
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
std::string
|
|
49
|
-
std::string tokens;
|
|
50
|
-
std::string
|
|
51
|
-
std::string
|
|
52
|
-
std::string
|
|
53
|
-
std::string
|
|
54
|
-
std::string
|
|
55
|
-
std::string
|
|
56
|
-
std::string
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
std::string
|
|
62
|
-
std::
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
struct
|
|
69
|
-
|
|
70
|
-
std::string
|
|
71
|
-
std::
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
1
|
+
#ifndef SHERPA_ONNX_MODEL_DETECT_H
|
|
2
|
+
#define SHERPA_ONNX_MODEL_DETECT_H
|
|
3
|
+
|
|
4
|
+
#include "sherpa-onnx-common.h"
|
|
5
|
+
#include <optional>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <vector>
|
|
8
|
+
|
|
9
|
+
namespace sherpaonnx {
|
|
10
|
+
|
|
11
|
+
enum class SttModelKind {
|
|
12
|
+
kUnknown,
|
|
13
|
+
kTransducer,
|
|
14
|
+
kNemoTransducer,
|
|
15
|
+
kParaformer,
|
|
16
|
+
kNemoCtc,
|
|
17
|
+
kWenetCtc,
|
|
18
|
+
kSenseVoice,
|
|
19
|
+
kZipformerCtc,
|
|
20
|
+
kWhisper,
|
|
21
|
+
kFunAsrNano,
|
|
22
|
+
kFireRedAsr,
|
|
23
|
+
kMoonshine,
|
|
24
|
+
kDolphin,
|
|
25
|
+
kCanary,
|
|
26
|
+
kOmnilingual,
|
|
27
|
+
kMedAsr,
|
|
28
|
+
kTeleSpeechCtc
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
enum class TtsModelKind {
|
|
32
|
+
kUnknown,
|
|
33
|
+
kVits,
|
|
34
|
+
kMatcha,
|
|
35
|
+
kKokoro,
|
|
36
|
+
kKitten,
|
|
37
|
+
kPocket,
|
|
38
|
+
kZipvoice
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
struct SttModelPaths {
|
|
42
|
+
std::string encoder;
|
|
43
|
+
std::string decoder;
|
|
44
|
+
std::string joiner;
|
|
45
|
+
std::string paraformerModel;
|
|
46
|
+
std::string ctcModel;
|
|
47
|
+
std::string whisperEncoder;
|
|
48
|
+
std::string whisperDecoder;
|
|
49
|
+
std::string tokens;
|
|
50
|
+
std::string funasrEncoderAdaptor;
|
|
51
|
+
std::string funasrLLM;
|
|
52
|
+
std::string funasrEmbedding;
|
|
53
|
+
std::string funasrTokenizer;
|
|
54
|
+
std::string moonshinePreprocessor;
|
|
55
|
+
std::string moonshineEncoder;
|
|
56
|
+
std::string moonshineUncachedDecoder;
|
|
57
|
+
std::string moonshineCachedDecoder;
|
|
58
|
+
std::string dolphinModel;
|
|
59
|
+
std::string omnilingualModel;
|
|
60
|
+
std::string medasrModel;
|
|
61
|
+
std::string telespeechCtcModel;
|
|
62
|
+
std::string fireRedEncoder;
|
|
63
|
+
std::string fireRedDecoder;
|
|
64
|
+
std::string canaryEncoder;
|
|
65
|
+
std::string canaryDecoder;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
struct TtsModelPaths {
|
|
69
|
+
std::string ttsModel;
|
|
70
|
+
std::string tokens;
|
|
71
|
+
std::string lexicon;
|
|
72
|
+
std::string dataDir;
|
|
73
|
+
std::string voices;
|
|
74
|
+
std::string acousticModel;
|
|
75
|
+
std::string vocoder;
|
|
76
|
+
std::string encoder;
|
|
77
|
+
std::string decoder;
|
|
78
|
+
// Pocket TTS
|
|
79
|
+
std::string lmFlow;
|
|
80
|
+
std::string lmMain;
|
|
81
|
+
std::string textConditioner;
|
|
82
|
+
std::string vocabJson;
|
|
83
|
+
std::string tokenScoresJson;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
struct SttDetectResult {
|
|
87
|
+
bool ok = false;
|
|
88
|
+
std::string error;
|
|
89
|
+
std::vector<DetectedModel> detectedModels;
|
|
90
|
+
SttModelKind selectedKind = SttModelKind::kUnknown;
|
|
91
|
+
bool tokensRequired = true;
|
|
92
|
+
SttModelPaths paths;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
struct TtsDetectResult {
|
|
96
|
+
bool ok = false;
|
|
97
|
+
std::string error;
|
|
98
|
+
std::vector<DetectedModel> detectedModels;
|
|
99
|
+
TtsModelKind selectedKind = TtsModelKind::kUnknown;
|
|
100
|
+
TtsModelPaths paths;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
SttDetectResult DetectSttModel(
|
|
104
|
+
const std::string& modelDir,
|
|
105
|
+
const std::optional<bool>& preferInt8,
|
|
106
|
+
const std::optional<std::string>& modelType,
|
|
107
|
+
bool debug = false
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
TtsDetectResult DetectTtsModel(
|
|
111
|
+
const std::string& modelDir,
|
|
112
|
+
const std::string& modelType
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
} // namespace sherpaonnx
|
|
116
|
+
|
|
117
|
+
#endif // SHERPA_ONNX_MODEL_DETECT_H
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Copy libarchive .c files to ios/patched_libarchive and insert <stdio.h> and <unistd.h>
|
|
3
|
+
# after #include "archive_platform.h" so they compile without modifying the submodule.
|
|
4
|
+
# Called from SherpaOnnx.podspec during evaluation.
|
|
5
|
+
# Requires: libarchive source dir (same as used for HEADER_SEARCH_PATHS: third_party or ios/Downloads/libarchive).
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
+
SDK_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
11
|
+
LIBARCHIVE_SRC="${1:-}"
|
|
12
|
+
PATCHED_DIR="$SDK_ROOT/ios/patched_libarchive"
|
|
13
|
+
|
|
14
|
+
if [ -z "$LIBARCHIVE_SRC" ]; then
|
|
15
|
+
echo "Error: libarchive source dir not set. Usage: $0 <libarchive_source_dir>" >&2
|
|
16
|
+
echo "Use the same path as libarchive_dir in the pod (e.g. third_party/libarchive_prebuilt/libarchive-ios-layout or ios/Downloads/libarchive)." >&2
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
if [ ! -d "$LIBARCHIVE_SRC" ]; then
|
|
21
|
+
echo "Error: libarchive source dir not found: $LIBARCHIVE_SRC" >&2
|
|
22
|
+
echo "Run third_party/libarchive_prebuilt/build_libarchive_ios.sh (repo) or ios/scripts/setup-ios-libarchive.sh (npm)." >&2
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
if [ ! -f "$LIBARCHIVE_SRC/archive_platform.h" ]; then
|
|
27
|
+
echo "Error: $LIBARCHIVE_SRC does not look like libarchive (archive_platform.h missing)." >&2
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
mkdir -p "$PATCHED_DIR"
|
|
32
|
+
count=0
|
|
33
|
+
|
|
34
|
+
# Same exclude as podspec: no test, windows, linux, sunos, freebsd
|
|
35
|
+
for f in "$LIBARCHIVE_SRC"/*.c; do
|
|
36
|
+
[ -f "$f" ] || continue
|
|
37
|
+
base=$(basename "$f" .c)
|
|
38
|
+
[[ "$(basename "$f")" =~ ^test\. ]] && continue
|
|
39
|
+
[[ "$base" == *windows* ]] && continue
|
|
40
|
+
[[ "$base" == *linux* ]] && continue
|
|
41
|
+
[[ "$base" == *sunos* ]] && continue
|
|
42
|
+
[[ "$base" == *freebsd* ]] && continue
|
|
43
|
+
|
|
44
|
+
dest="$PATCHED_DIR/$(basename "$f")"
|
|
45
|
+
# Insert #include <stdio.h> and #include <unistd.h> after first #include "archive_platform.h"
|
|
46
|
+
inserted=0
|
|
47
|
+
while IFS= read -r line; do
|
|
48
|
+
echo "$line"
|
|
49
|
+
if [ "$inserted" -eq 0 ] && echo "$line" | grep -q '^#include "archive_platform.h"'; then
|
|
50
|
+
echo '#include <stdio.h>'
|
|
51
|
+
echo '#include <unistd.h>'
|
|
52
|
+
inserted=1
|
|
53
|
+
fi
|
|
54
|
+
done < "$f" > "$dest"
|
|
55
|
+
count=$((count + 1))
|
|
56
|
+
done
|
|
57
|
+
|
|
58
|
+
if [ "$count" -eq 0 ]; then
|
|
59
|
+
echo "Error: No libarchive .c files were copied to $PATCHED_DIR. Check excludes and source dir." >&2
|
|
60
|
+
exit 1
|
|
61
|
+
fi
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Download libarchive iOS sources from GitHub Releases and extract to ios/Downloads/libarchive.
|
|
3
|
+
# Always downloads (no skip when prebuilts exist). Call from Podfile pre_install so that
|
|
4
|
+
# ios/Downloads/libarchive exists before the podspec is evaluated (required when using the SDK from npm).
|
|
5
|
+
#
|
|
6
|
+
# Usage: run from repo root or from Podfile pre_install, e.g.:
|
|
7
|
+
# system("bash", "#{sdk_path}/ios/scripts/setup-ios-libarchive.sh")
|
|
8
|
+
# Or: ./ios/scripts/setup-ios-libarchive.sh
|
|
9
|
+
|
|
10
|
+
set -e
|
|
11
|
+
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
# SDK root = parent of ios/
|
|
14
|
+
SDK_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
15
|
+
DOWNLOADS_DIR="$SDK_ROOT/ios/Downloads"
|
|
16
|
+
LIBARCHIVE_DIR="$DOWNLOADS_DIR/libarchive"
|
|
17
|
+
TAG_FILE="$SDK_ROOT/third_party/libarchive_prebuilt/IOS_RELEASE_TAG"
|
|
18
|
+
|
|
19
|
+
# Resolve release tag: env LIBARCHIVE_IOS_RELEASE_TAG, or IOS_RELEASE_TAG file (single source of truth; committed and included in npm package).
|
|
20
|
+
RELEASE_TAG="${LIBARCHIVE_IOS_RELEASE_TAG:-}"
|
|
21
|
+
if [ -z "$RELEASE_TAG" ] && [ -f "$TAG_FILE" ]; then
|
|
22
|
+
RELEASE_TAG=$(grep -v '^#' "$TAG_FILE" | grep -v '^[[:space:]]*$' | head -1 | tr -d '\r\n')
|
|
23
|
+
fi
|
|
24
|
+
if [ -z "$RELEASE_TAG" ]; then
|
|
25
|
+
echo "Error: IOS_RELEASE_TAG not found at $TAG_FILE. Reinstall the package or run from repo." >&2
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# Skip download if already present (podspec can be evaluated multiple times during pod install).
|
|
30
|
+
if [ -d "$LIBARCHIVE_DIR" ] && [ -f "$LIBARCHIVE_DIR/archive.h" ] && [ -n "$(find "$LIBARCHIVE_DIR" -maxdepth 1 -name '*.c' -print -quit 2>/dev/null)" ]; then
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
AUTH_ARGS=()
|
|
35
|
+
if [ -n "$GITHUB_TOKEN" ]; then
|
|
36
|
+
AUTH_ARGS+=(-H "Authorization: Bearer $GITHUB_TOKEN")
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
echo "Downloading libarchive iOS sources from release $RELEASE_TAG..."
|
|
40
|
+
|
|
41
|
+
release_json=$(curl -s "${AUTH_ARGS[@]}" -H "Accept: application/vnd.github+json" \
|
|
42
|
+
"https://api.github.com/repos/XDcobra/react-native-sherpa-onnx/releases/tags/$RELEASE_TAG" 2>/dev/null || true)
|
|
43
|
+
if [ -z "$release_json" ] || ! echo "$release_json" | grep -q '"assets"'; then
|
|
44
|
+
echo "Error: Could not fetch release $RELEASE_TAG or no assets (rate limit?)." >&2
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
download_url=""
|
|
49
|
+
if command -v jq &>/dev/null; then
|
|
50
|
+
download_url=$(echo "$release_json" | jq -r '.assets[] | select(.name == "libarchive-ios-sources.zip") | .browser_download_url' | head -1)
|
|
51
|
+
else
|
|
52
|
+
download_url=$(echo "$release_json" | grep -o '"browser_download_url": "[^"]*libarchive-ios-sources.zip[^"]*"' | head -1 | sed 's/.*: "//;s/"$//')
|
|
53
|
+
fi
|
|
54
|
+
if [ -z "$download_url" ]; then
|
|
55
|
+
echo "Error: Asset libarchive-ios-sources.zip not found in release $RELEASE_TAG" >&2
|
|
56
|
+
exit 1
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
mkdir -p "$DOWNLOADS_DIR"
|
|
60
|
+
zip_path="$DOWNLOADS_DIR/libarchive-ios-sources.zip"
|
|
61
|
+
if ! curl -L -f "${AUTH_ARGS[@]}" -o "$zip_path" "$download_url"; then
|
|
62
|
+
rm -f "$zip_path"
|
|
63
|
+
exit 1
|
|
64
|
+
fi
|
|
65
|
+
if ! file "$zip_path" 2>/dev/null | grep -q "Zip archive"; then
|
|
66
|
+
echo "Error: Downloaded file is not a valid zip" >&2
|
|
67
|
+
rm -f "$zip_path"
|
|
68
|
+
exit 1
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
rm -rf "$LIBARCHIVE_DIR"
|
|
72
|
+
mkdir -p "$LIBARCHIVE_DIR"
|
|
73
|
+
unzip -q -o "$zip_path" -d "$LIBARCHIVE_DIR"
|
|
74
|
+
rm -f "$zip_path"
|
|
75
|
+
|
|
76
|
+
# If the zip had a single top-level dir (e.g. libarchive-ios-sources), flatten so
|
|
77
|
+
# archive.h and archive_xxhash.h are directly in LIBARCHIVE_DIR (podspec HEADER_SEARCH_PATHS expects that).
|
|
78
|
+
subdirs=("$LIBARCHIVE_DIR"/*/)
|
|
79
|
+
if [ -d "${subdirs[0]}" ] && [ "${#subdirs[@]}" -eq 1 ] && [ ! -f "$LIBARCHIVE_DIR/archive.h" ]; then
|
|
80
|
+
subdir="${subdirs[0]}"
|
|
81
|
+
echo "Flattening single top-level directory: $(basename "$subdir")"
|
|
82
|
+
shopt -s dotglob
|
|
83
|
+
mv "$subdir"* "$LIBARCHIVE_DIR/"
|
|
84
|
+
shopt -u dotglob
|
|
85
|
+
rmdir "$subdir" 2>/dev/null || true
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Ensure required headers exist (e.g. archive_xxhash.h for LZ4 support)
|
|
89
|
+
if [ ! -f "$LIBARCHIVE_DIR/archive.h" ]; then
|
|
90
|
+
echo "Error: $LIBARCHIVE_DIR/archive.h missing after extract. Zip layout may be unexpected." >&2
|
|
91
|
+
exit 1
|
|
92
|
+
fi
|
|
93
|
+
if [ ! -f "$LIBARCHIVE_DIR/archive_xxhash.h" ]; then
|
|
94
|
+
echo "Error: $LIBARCHIVE_DIR/archive_xxhash.h missing. Re-publish libarchive iOS release (build_libarchive_ios.sh copies all *.h)." >&2
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
echo "Libarchive iOS sources extracted to $LIBARCHIVE_DIR"
|