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.
Files changed (175) hide show
  1. package/README.md +232 -236
  2. package/SherpaOnnx.podspec +68 -64
  3. package/android/build.gradle +182 -192
  4. package/android/codegen.gradle +57 -0
  5. package/android/prebuilt-download.gradle +428 -0
  6. package/android/prebuilt-versions.gradle +43 -0
  7. package/android/proguard-rules.pro +10 -0
  8. package/android/src/main/assets/testModels/add_mul_add.onnx +28 -0
  9. package/android/src/main/assets/testModels/nnapi_internal_uint8_support.onnx +0 -0
  10. package/android/src/main/assets/testModels/qnn_multi_ctx_embed.onnx +0 -0
  11. package/android/src/main/cpp/CMakeLists.txt +166 -129
  12. package/android/src/main/cpp/CMakePresets.json +54 -0
  13. package/android/src/main/cpp/crypto/sha256.cpp +174 -0
  14. package/android/src/main/cpp/crypto/sha256.h +16 -0
  15. package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-helper.cpp +404 -0
  16. package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-helper.h +56 -0
  17. package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-jni.cpp +181 -0
  18. package/android/src/main/cpp/jni/audio/sherpa-onnx-audio-convert-jni.cpp +888 -0
  19. package/{ios → android/src/main/cpp/jni/model_detect}/sherpa-onnx-common.h +18 -18
  20. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-detect-jni-common.cpp +86 -0
  21. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-detect-jni-common.h +20 -0
  22. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.cpp +423 -0
  23. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.h +55 -0
  24. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-stt.cpp +399 -0
  25. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-tts.cpp +238 -0
  26. package/{ios → android/src/main/cpp/jni/model_detect}/sherpa-onnx-model-detect.h +122 -89
  27. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-stt-wrapper.cpp +99 -0
  28. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-stt-wrapper.h +16 -0
  29. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-tts-wrapper.cpp +78 -0
  30. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-tts-wrapper.h +16 -0
  31. package/android/src/main/cpp/jni/module/sherpa-onnx-module-jni.cpp +190 -0
  32. package/android/src/main/cpp/jni/tts/sherpa-onnx-tts-zipvoice-jni.cpp +301 -0
  33. package/android/src/main/java/com/sherpaonnx/SherpaOnnxArchiveHelper.kt +94 -0
  34. package/android/src/main/java/com/sherpaonnx/{SherpaOnnxCoreHelper.kt → SherpaOnnxAssetHelper.kt} +350 -236
  35. package/android/src/main/java/com/sherpaonnx/SherpaOnnxModule.kt +791 -483
  36. package/android/src/main/java/com/sherpaonnx/SherpaOnnxSttHelper.kt +699 -109
  37. package/android/src/main/java/com/sherpaonnx/SherpaOnnxTtsHelper.kt +1123 -668
  38. package/android/src/main/java/com/sherpaonnx/ZipvoiceTtsWrapper.kt +187 -0
  39. package/ios/SherpaOnnx+Assets.h +11 -0
  40. package/ios/SherpaOnnx+Assets.mm +325 -0
  41. package/ios/SherpaOnnx+STT.mm +455 -118
  42. package/ios/SherpaOnnx+TTS.mm +1101 -712
  43. package/ios/SherpaOnnx.h +17 -6
  44. package/ios/SherpaOnnx.mm +206 -311
  45. package/ios/SherpaOnnx.xcconfig +19 -19
  46. package/ios/SherpaOnnxCoreMLHelper.swift +24 -0
  47. package/ios/archive/sherpa-onnx-archive-helper.h +21 -0
  48. package/ios/archive/sherpa-onnx-archive-helper.mm +296 -0
  49. package/ios/libarchive_darwin_config.h +153 -0
  50. package/{android/src/main/cpp/jni → ios/model_detect}/sherpa-onnx-common.h +18 -18
  51. package/ios/model_detect/sherpa-onnx-model-detect-helper.h +49 -0
  52. package/ios/model_detect/sherpa-onnx-model-detect-helper.mm +210 -0
  53. package/ios/model_detect/sherpa-onnx-model-detect-stt.mm +344 -0
  54. package/ios/model_detect/sherpa-onnx-model-detect-tts.mm +201 -0
  55. package/{android/src/main/cpp/jni → ios/model_detect}/sherpa-onnx-model-detect.h +117 -89
  56. package/ios/scripts/patch-libarchive-includes.sh +61 -0
  57. package/ios/scripts/setup-ios-libarchive.sh +98 -0
  58. package/ios/stt/sherpa-onnx-stt-wrapper.h +129 -0
  59. package/ios/stt/sherpa-onnx-stt-wrapper.mm +523 -0
  60. package/ios/{sherpa-onnx-tts-wrapper.h → tts/sherpa-onnx-tts-wrapper.h} +90 -85
  61. package/ios/{sherpa-onnx-tts-wrapper.mm → tts/sherpa-onnx-tts-wrapper.mm} +376 -345
  62. package/lib/module/NativeSherpaOnnx.js +3 -0
  63. package/lib/module/NativeSherpaOnnx.js.map +1 -1
  64. package/lib/module/audio/index.js +22 -0
  65. package/lib/module/audio/index.js.map +1 -0
  66. package/lib/module/diarization/index.js +1 -1
  67. package/lib/module/diarization/index.js.map +1 -1
  68. package/lib/module/download/ModelDownloadManager.js +918 -0
  69. package/lib/module/download/ModelDownloadManager.js.map +1 -0
  70. package/lib/module/download/extractTarBz2.js +53 -0
  71. package/lib/module/download/extractTarBz2.js.map +1 -0
  72. package/lib/module/download/index.js +6 -0
  73. package/lib/module/download/index.js.map +1 -0
  74. package/lib/module/download/validation.js +178 -0
  75. package/lib/module/download/validation.js.map +1 -0
  76. package/lib/module/enhancement/index.js +1 -1
  77. package/lib/module/enhancement/index.js.map +1 -1
  78. package/lib/module/index.js +41 -3
  79. package/lib/module/index.js.map +1 -1
  80. package/lib/module/separation/index.js +1 -1
  81. package/lib/module/separation/index.js.map +1 -1
  82. package/lib/module/stt/index.js +127 -60
  83. package/lib/module/stt/index.js.map +1 -1
  84. package/lib/module/stt/sttModelLanguages.js +512 -0
  85. package/lib/module/stt/sttModelLanguages.js.map +1 -0
  86. package/lib/module/stt/types.js +53 -1
  87. package/lib/module/stt/types.js.map +1 -1
  88. package/lib/module/tts/index.js +216 -289
  89. package/lib/module/tts/index.js.map +1 -1
  90. package/lib/module/tts/types.js +86 -1
  91. package/lib/module/tts/types.js.map +1 -1
  92. package/lib/module/types.js.map +1 -1
  93. package/lib/module/utils.js +86 -73
  94. package/lib/module/utils.js.map +1 -1
  95. package/lib/module/vad/index.js +1 -1
  96. package/lib/module/vad/index.js.map +1 -1
  97. package/lib/typescript/src/NativeSherpaOnnx.d.ts +192 -38
  98. package/lib/typescript/src/NativeSherpaOnnx.d.ts.map +1 -1
  99. package/lib/typescript/src/audio/index.d.ts +13 -0
  100. package/lib/typescript/src/audio/index.d.ts.map +1 -0
  101. package/lib/typescript/src/diarization/index.d.ts +3 -2
  102. package/lib/typescript/src/diarization/index.d.ts.map +1 -1
  103. package/lib/typescript/src/download/ModelDownloadManager.d.ts +108 -0
  104. package/lib/typescript/src/download/ModelDownloadManager.d.ts.map +1 -0
  105. package/lib/typescript/src/download/extractTarBz2.d.ts +14 -0
  106. package/lib/typescript/src/download/extractTarBz2.d.ts.map +1 -0
  107. package/lib/typescript/src/download/index.d.ts +7 -0
  108. package/lib/typescript/src/download/index.d.ts.map +1 -0
  109. package/lib/typescript/src/download/validation.d.ts +57 -0
  110. package/lib/typescript/src/download/validation.d.ts.map +1 -0
  111. package/lib/typescript/src/enhancement/index.d.ts +3 -2
  112. package/lib/typescript/src/enhancement/index.d.ts.map +1 -1
  113. package/lib/typescript/src/index.d.ts +26 -2
  114. package/lib/typescript/src/index.d.ts.map +1 -1
  115. package/lib/typescript/src/separation/index.d.ts +3 -2
  116. package/lib/typescript/src/separation/index.d.ts.map +1 -1
  117. package/lib/typescript/src/stt/index.d.ts +31 -43
  118. package/lib/typescript/src/stt/index.d.ts.map +1 -1
  119. package/lib/typescript/src/stt/sttModelLanguages.d.ts +52 -0
  120. package/lib/typescript/src/stt/sttModelLanguages.d.ts.map +1 -0
  121. package/lib/typescript/src/stt/types.d.ts +196 -9
  122. package/lib/typescript/src/stt/types.d.ts.map +1 -1
  123. package/lib/typescript/src/tts/index.d.ts +25 -211
  124. package/lib/typescript/src/tts/index.d.ts.map +1 -1
  125. package/lib/typescript/src/tts/types.d.ts +148 -25
  126. package/lib/typescript/src/tts/types.d.ts.map +1 -1
  127. package/lib/typescript/src/types.d.ts +0 -32
  128. package/lib/typescript/src/types.d.ts.map +1 -1
  129. package/lib/typescript/src/utils.d.ts +28 -13
  130. package/lib/typescript/src/utils.d.ts.map +1 -1
  131. package/lib/typescript/src/vad/index.d.ts +3 -2
  132. package/lib/typescript/src/vad/index.d.ts.map +1 -1
  133. package/package.json +250 -222
  134. package/scripts/check-qnn-support.sh +78 -0
  135. package/scripts/setup-ios-framework.sh +379 -282
  136. package/src/NativeSherpaOnnx.ts +474 -251
  137. package/src/audio/index.ts +32 -0
  138. package/src/diarization/index.ts +4 -2
  139. package/src/download/ModelDownloadManager.ts +1325 -0
  140. package/src/download/extractTarBz2.ts +78 -0
  141. package/src/download/index.ts +43 -0
  142. package/src/download/validation.ts +279 -0
  143. package/src/enhancement/index.ts +4 -2
  144. package/src/index.tsx +78 -27
  145. package/src/separation/index.ts +4 -2
  146. package/src/stt/index.ts +249 -89
  147. package/src/stt/sttModelLanguages.ts +237 -0
  148. package/src/stt/types.ts +263 -9
  149. package/src/tts/index.ts +470 -458
  150. package/src/tts/types.ts +373 -218
  151. package/src/types.ts +0 -44
  152. package/src/utils.ts +145 -131
  153. package/src/vad/index.ts +4 -2
  154. package/third_party/ffmpeg_prebuilt/ANDROID_RELEASE_TAG +1 -0
  155. package/third_party/libarchive_prebuilt/ANDROID_RELEASE_TAG +1 -0
  156. package/third_party/libarchive_prebuilt/IOS_RELEASE_TAG +1 -0
  157. package/third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG +1 -0
  158. package/third_party/sherpa-onnx-prebuilt/IOS_RELEASE_TAG +1 -0
  159. package/android/src/main/cpp/include/sherpa-onnx/c-api/c-api.h +0 -1918
  160. package/android/src/main/cpp/include/sherpa-onnx/c-api/cxx-api.h +0 -841
  161. package/android/src/main/cpp/jni/sherpa-onnx-model-detect.cpp +0 -541
  162. package/android/src/main/cpp/jni/sherpa-onnx-stt-jni.cpp +0 -336
  163. package/android/src/main/cpp/jni/sherpa-onnx-stt-wrapper.cpp +0 -222
  164. package/android/src/main/cpp/jni/sherpa-onnx-stt-wrapper.h +0 -68
  165. package/android/src/main/cpp/jni/sherpa-onnx-tts-jni.cpp +0 -823
  166. package/android/src/main/cpp/jni/sherpa-onnx-tts-wrapper.cpp +0 -387
  167. package/android/src/main/cpp/jni/sherpa-onnx-tts-wrapper.h +0 -147
  168. package/ios/Frameworks/sherpa_onnx.xcframework.zip +0 -0
  169. package/ios/include/sherpa-onnx/c-api/c-api.h +0 -1918
  170. package/ios/include/sherpa-onnx/c-api/cxx-api.h +0 -841
  171. package/ios/sherpa-onnx-model-detect.mm +0 -441
  172. package/ios/sherpa-onnx-stt-wrapper.h +0 -48
  173. package/ios/sherpa-onnx-stt-wrapper.mm +0 -201
  174. package/scripts/copy-headers.js +0 -184
  175. 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
- kParaformer,
15
- kNemoCtc,
16
- kWenetCtc,
17
- kSenseVoice,
18
- kZipformerCtc,
19
- kWhisper,
20
- kFunAsrNano
21
- };
22
-
23
- enum class TtsModelKind {
24
- kUnknown,
25
- kVits,
26
- kMatcha,
27
- kKokoro,
28
- kKitten,
29
- kZipvoice
30
- };
31
-
32
- struct SttModelPaths {
33
- std::string encoder;
34
- std::string decoder;
35
- std::string joiner;
36
- std::string paraformerModel;
37
- std::string ctcModel;
38
- std::string whisperEncoder;
39
- std::string whisperDecoder;
40
- std::string tokens;
41
- std::string funasrEncoderAdaptor;
42
- std::string funasrLLM;
43
- std::string funasrEmbedding;
44
- std::string funasrTokenizer;
45
- };
46
-
47
- struct TtsModelPaths {
48
- std::string ttsModel;
49
- std::string tokens;
50
- std::string lexicon;
51
- std::string dataDir;
52
- std::string voices;
53
- std::string acousticModel;
54
- std::string vocoder;
55
- std::string encoder;
56
- std::string decoder;
57
- };
58
-
59
- struct SttDetectResult {
60
- bool ok = false;
61
- std::string error;
62
- std::vector<DetectedModel> detectedModels;
63
- SttModelKind selectedKind = SttModelKind::kUnknown;
64
- bool tokensRequired = true;
65
- SttModelPaths paths;
66
- };
67
-
68
- struct TtsDetectResult {
69
- bool ok = false;
70
- std::string error;
71
- std::vector<DetectedModel> detectedModels;
72
- TtsModelKind selectedKind = TtsModelKind::kUnknown;
73
- TtsModelPaths paths;
74
- };
75
-
76
- SttDetectResult DetectSttModel(
77
- const std::string& modelDir,
78
- const std::optional<bool>& preferInt8,
79
- const std::optional<std::string>& modelType
80
- );
81
-
82
- TtsDetectResult DetectTtsModel(
83
- const std::string& modelDir,
84
- const std::string& modelType
85
- );
86
-
87
- } // namespace sherpaonnx
88
-
89
- #endif // SHERPA_ONNX_MODEL_DETECT_H
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"