react-native-sherpa-onnx 0.3.2 → 0.3.4
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 +84 -77
- package/SherpaOnnx.podspec +79 -45
- package/android/build.gradle +8 -2
- package/android/prebuilt-download.gradle +70 -16
- package/android/prebuilt-versions.gradle +14 -6
- package/android/src/main/cpp/CMakeLists.txt +2 -0
- package/android/src/main/cpp/jni/audio/sherpa-onnx-audio-convert-jni.cpp +202 -328
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-detect-jni-common.cpp +22 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-detect-jni-common.h +2 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.cpp +96 -142
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.h +40 -4
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-stt.cpp +774 -316
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-tts.cpp +208 -122
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect.h +92 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-stt-wrapper.cpp +3 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-tts-wrapper.cpp +14 -2
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-validate-stt.cpp +229 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-validate-stt.h +38 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-validate-tts.cpp +144 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-validate-tts.h +38 -0
- package/android/src/main/cpp/jni/module/sherpa-onnx-module-jni.cpp +1 -1
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxModule.kt +157 -11
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxPcmCapture.kt +150 -0
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxSttHelper.kt +75 -24
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxTtsHelper.kt +52 -1
- package/ios/SherpaOnnx+PcmLiveStream.mm +288 -0
- package/ios/SherpaOnnx+STT.mm +2 -0
- package/ios/SherpaOnnx+TTS.mm +17 -0
- package/ios/SherpaOnnx.mm +27 -3
- package/ios/SherpaOnnxAudioConvert.h +28 -0
- package/ios/SherpaOnnxAudioConvert.mm +698 -0
- package/ios/archive/sherpa-onnx-archive-helper.mm +12 -0
- package/ios/model_detect/sherpa-onnx-model-detect-helper.h +37 -3
- package/ios/model_detect/sherpa-onnx-model-detect-helper.mm +80 -45
- package/ios/model_detect/sherpa-onnx-model-detect-stt.mm +629 -267
- package/ios/model_detect/sherpa-onnx-model-detect-tts.mm +148 -56
- package/ios/model_detect/sherpa-onnx-model-detect.h +72 -0
- package/ios/model_detect/sherpa-onnx-validate-stt.h +38 -0
- package/ios/model_detect/sherpa-onnx-validate-stt.mm +229 -0
- package/ios/model_detect/sherpa-onnx-validate-tts.h +38 -0
- package/ios/model_detect/sherpa-onnx-validate-tts.mm +144 -0
- package/ios/stt/sherpa-onnx-stt-wrapper.mm +4 -0
- package/lib/module/NativeSherpaOnnx.js.map +1 -1
- package/lib/module/audio/index.js +55 -1
- package/lib/module/audio/index.js.map +1 -1
- package/lib/module/download/ModelDownloadManager.js +14 -0
- package/lib/module/download/ModelDownloadManager.js.map +1 -1
- package/lib/module/index.js +10 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/stt/streaming.js +6 -3
- package/lib/module/stt/streaming.js.map +1 -1
- package/lib/module/tts/index.js +13 -1
- package/lib/module/tts/index.js.map +1 -1
- package/lib/typescript/src/NativeSherpaOnnx.d.ts +32 -3
- package/lib/typescript/src/NativeSherpaOnnx.d.ts.map +1 -1
- package/lib/typescript/src/audio/index.d.ts +20 -1
- package/lib/typescript/src/audio/index.d.ts.map +1 -1
- package/lib/typescript/src/download/ModelDownloadManager.d.ts +2 -1
- package/lib/typescript/src/download/ModelDownloadManager.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +10 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/stt/streaming.d.ts.map +1 -1
- package/lib/typescript/src/stt/streamingTypes.d.ts +1 -1
- package/lib/typescript/src/stt/streamingTypes.d.ts.map +1 -1
- package/lib/typescript/src/tts/index.d.ts +12 -1
- package/lib/typescript/src/tts/index.d.ts.map +1 -1
- package/package.json +6 -1
- package/scripts/check-model-csvs.sh +72 -0
- package/scripts/setup-ios-framework.sh +272 -191
- package/src/NativeSherpaOnnx.ts +37 -3
- package/src/audio/index.ts +84 -1
- package/src/download/ModelDownloadManager.ts +19 -0
- package/src/index.tsx +15 -0
- package/src/stt/streaming.ts +10 -5
- package/src/stt/streamingTypes.ts +1 -1
- package/src/tts/index.ts +25 -1
- package/third_party/ffmpeg_prebuilt/ANDROID_RELEASE_TAG +1 -1
- package/third_party/libarchive_prebuilt/ANDROID_RELEASE_TAG +1 -1
- package/third_party/libarchive_prebuilt/IOS_RELEASE_TAG +1 -1
- package/third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG +1 -1
- package/third_party/sherpa-onnx-prebuilt/IOS_RELEASE_TAG +1 -1
- package/ios/scripts/patch-libarchive-includes.sh +0 -61
- package/ios/scripts/setup-ios-libarchive.sh +0 -98
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sherpa-onnx-validate-stt.cpp
|
|
3
|
+
*
|
|
4
|
+
* Validates that all required file paths are set for a given SttModelKind.
|
|
5
|
+
* Requirements are declared in static tables at the top of this file —
|
|
6
|
+
* edit them when adding a new model type or changing what is required.
|
|
7
|
+
*/
|
|
8
|
+
#include "sherpa-onnx-validate-stt.h"
|
|
9
|
+
#include <cstddef>
|
|
10
|
+
#include <cstring>
|
|
11
|
+
|
|
12
|
+
namespace sherpaonnx {
|
|
13
|
+
namespace {
|
|
14
|
+
|
|
15
|
+
// ============================================================
|
|
16
|
+
// REQUIREMENT TABLES — one entry per SttModelKind (or group).
|
|
17
|
+
// Edit here when adding a new model type or changing requirements.
|
|
18
|
+
// ============================================================
|
|
19
|
+
|
|
20
|
+
static const SttFieldRequirement kTransducerReqs[] = {
|
|
21
|
+
{"encoder", &SttModelPaths::encoder, true},
|
|
22
|
+
{"decoder", &SttModelPaths::decoder, true},
|
|
23
|
+
{"joiner", &SttModelPaths::joiner, true},
|
|
24
|
+
{"tokens", &SttModelPaths::tokens, true},
|
|
25
|
+
{"bpeVocab", &SttModelPaths::bpeVocab, false},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Offline paraformer uses paraformerModel; streaming paraformer uses encoder+decoder.
|
|
29
|
+
// Both are valid — validated via custom logic in ValidateSttPaths, not via this table.
|
|
30
|
+
static const SttFieldRequirement kParaformerReqs[] = {
|
|
31
|
+
{"paraformerModel", &SttModelPaths::paraformerModel, false},
|
|
32
|
+
{"encoder", &SttModelPaths::encoder, false},
|
|
33
|
+
{"decoder", &SttModelPaths::decoder, false},
|
|
34
|
+
{"tokens", &SttModelPaths::tokens, true},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
static const SttFieldRequirement kCtcReqs[] = {
|
|
38
|
+
{"ctcModel", &SttModelPaths::ctcModel, true},
|
|
39
|
+
{"tokens", &SttModelPaths::tokens, true},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
static const SttFieldRequirement kWhisperReqs[] = {
|
|
43
|
+
{"whisperEncoder", &SttModelPaths::whisperEncoder, true},
|
|
44
|
+
{"whisperDecoder", &SttModelPaths::whisperDecoder, true},
|
|
45
|
+
{"tokens", &SttModelPaths::tokens, true},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
static const SttFieldRequirement kFunAsrNanoReqs[] = {
|
|
49
|
+
{"funasrEncoderAdaptor", &SttModelPaths::funasrEncoderAdaptor, true},
|
|
50
|
+
{"funasrLLM", &SttModelPaths::funasrLLM, true},
|
|
51
|
+
{"funasrEmbedding", &SttModelPaths::funasrEmbedding, true},
|
|
52
|
+
{"funasrTokenizer", &SttModelPaths::funasrTokenizer, true},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
static const SttFieldRequirement kMoonshineReqs[] = {
|
|
56
|
+
{"moonshinePreprocessor", &SttModelPaths::moonshinePreprocessor, true},
|
|
57
|
+
{"moonshineEncoder", &SttModelPaths::moonshineEncoder, true},
|
|
58
|
+
{"moonshineUncachedDecoder", &SttModelPaths::moonshineUncachedDecoder, true},
|
|
59
|
+
{"moonshineCachedDecoder", &SttModelPaths::moonshineCachedDecoder, true},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
static const SttFieldRequirement kMoonshineV2Reqs[] = {
|
|
63
|
+
{"moonshineEncoder", &SttModelPaths::moonshineEncoder, true},
|
|
64
|
+
{"moonshineMergedDecoder", &SttModelPaths::moonshineMergedDecoder, true},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
static const SttFieldRequirement kFireRedReqs[] = {
|
|
68
|
+
{"fireRedEncoder", &SttModelPaths::fireRedEncoder, true},
|
|
69
|
+
{"fireRedDecoder", &SttModelPaths::fireRedDecoder, true},
|
|
70
|
+
{"tokens", &SttModelPaths::tokens, true},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
static const SttFieldRequirement kCanaryReqs[] = {
|
|
74
|
+
{"canaryEncoder", &SttModelPaths::canaryEncoder, true},
|
|
75
|
+
{"canaryDecoder", &SttModelPaths::canaryDecoder, true},
|
|
76
|
+
{"tokens", &SttModelPaths::tokens, true},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
static const SttFieldRequirement kDolphinReqs[] = {
|
|
80
|
+
{"dolphinModel", &SttModelPaths::dolphinModel, true},
|
|
81
|
+
{"tokens", &SttModelPaths::tokens, true},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
static const SttFieldRequirement kOmnilingualReqs[] = {
|
|
85
|
+
{"omnilingualModel", &SttModelPaths::omnilingualModel, true},
|
|
86
|
+
{"tokens", &SttModelPaths::tokens, true},
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
static const SttFieldRequirement kMedAsrReqs[] = {
|
|
90
|
+
{"medasrModel", &SttModelPaths::medasrModel, true},
|
|
91
|
+
{"tokens", &SttModelPaths::tokens, true},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
static const SttFieldRequirement kTeleSpeechReqs[] = {
|
|
95
|
+
{"telespeechCtcModel", &SttModelPaths::telespeechCtcModel, true},
|
|
96
|
+
{"tokens", &SttModelPaths::tokens, true},
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// ============================================================
|
|
100
|
+
|
|
101
|
+
static const SttFieldRequirement* GetRequirements(SttModelKind kind, size_t& count) {
|
|
102
|
+
switch (kind) {
|
|
103
|
+
case SttModelKind::kTransducer:
|
|
104
|
+
case SttModelKind::kNemoTransducer:
|
|
105
|
+
count = std::size(kTransducerReqs);
|
|
106
|
+
return kTransducerReqs;
|
|
107
|
+
case SttModelKind::kParaformer:
|
|
108
|
+
count = std::size(kParaformerReqs);
|
|
109
|
+
return kParaformerReqs;
|
|
110
|
+
case SttModelKind::kNemoCtc:
|
|
111
|
+
case SttModelKind::kWenetCtc:
|
|
112
|
+
case SttModelKind::kSenseVoice:
|
|
113
|
+
case SttModelKind::kZipformerCtc:
|
|
114
|
+
case SttModelKind::kToneCtc:
|
|
115
|
+
count = std::size(kCtcReqs);
|
|
116
|
+
return kCtcReqs;
|
|
117
|
+
case SttModelKind::kWhisper:
|
|
118
|
+
count = std::size(kWhisperReqs);
|
|
119
|
+
return kWhisperReqs;
|
|
120
|
+
case SttModelKind::kFunAsrNano:
|
|
121
|
+
count = std::size(kFunAsrNanoReqs);
|
|
122
|
+
return kFunAsrNanoReqs;
|
|
123
|
+
case SttModelKind::kMoonshine:
|
|
124
|
+
count = std::size(kMoonshineReqs);
|
|
125
|
+
return kMoonshineReqs;
|
|
126
|
+
case SttModelKind::kMoonshineV2:
|
|
127
|
+
count = std::size(kMoonshineV2Reqs);
|
|
128
|
+
return kMoonshineV2Reqs;
|
|
129
|
+
case SttModelKind::kFireRedAsr:
|
|
130
|
+
count = std::size(kFireRedReqs);
|
|
131
|
+
return kFireRedReqs;
|
|
132
|
+
case SttModelKind::kCanary:
|
|
133
|
+
count = std::size(kCanaryReqs);
|
|
134
|
+
return kCanaryReqs;
|
|
135
|
+
case SttModelKind::kDolphin:
|
|
136
|
+
count = std::size(kDolphinReqs);
|
|
137
|
+
return kDolphinReqs;
|
|
138
|
+
case SttModelKind::kOmnilingual:
|
|
139
|
+
count = std::size(kOmnilingualReqs);
|
|
140
|
+
return kOmnilingualReqs;
|
|
141
|
+
case SttModelKind::kMedAsr:
|
|
142
|
+
count = std::size(kMedAsrReqs);
|
|
143
|
+
return kMedAsrReqs;
|
|
144
|
+
case SttModelKind::kTeleSpeechCtc:
|
|
145
|
+
count = std::size(kTeleSpeechReqs);
|
|
146
|
+
return kTeleSpeechReqs;
|
|
147
|
+
default:
|
|
148
|
+
count = 0;
|
|
149
|
+
return nullptr;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
static const char* SttKindToName(SttModelKind k) {
|
|
154
|
+
switch (k) {
|
|
155
|
+
case SttModelKind::kTransducer: return "Transducer";
|
|
156
|
+
case SttModelKind::kNemoTransducer: return "NeMo Transducer";
|
|
157
|
+
case SttModelKind::kParaformer: return "Paraformer";
|
|
158
|
+
case SttModelKind::kNemoCtc: return "NeMo CTC";
|
|
159
|
+
case SttModelKind::kWenetCtc: return "WeNet CTC";
|
|
160
|
+
case SttModelKind::kSenseVoice: return "SenseVoice";
|
|
161
|
+
case SttModelKind::kZipformerCtc: return "Zipformer CTC";
|
|
162
|
+
case SttModelKind::kWhisper: return "Whisper";
|
|
163
|
+
case SttModelKind::kFunAsrNano: return "FunASR Nano";
|
|
164
|
+
case SttModelKind::kFireRedAsr: return "Fire Red ASR";
|
|
165
|
+
case SttModelKind::kMoonshine: return "Moonshine";
|
|
166
|
+
case SttModelKind::kMoonshineV2: return "Moonshine v2";
|
|
167
|
+
case SttModelKind::kDolphin: return "Dolphin";
|
|
168
|
+
case SttModelKind::kCanary: return "Canary";
|
|
169
|
+
case SttModelKind::kOmnilingual: return "Omnilingual";
|
|
170
|
+
case SttModelKind::kMedAsr: return "MedASR";
|
|
171
|
+
case SttModelKind::kTeleSpeechCtc: return "TeleSpeech CTC";
|
|
172
|
+
case SttModelKind::kToneCtc: return "Tone CTC";
|
|
173
|
+
default: return "Unknown";
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
static const char* GetFieldHint(const char* fieldName) {
|
|
178
|
+
if (std::strcmp(fieldName, "tokens") == 0)
|
|
179
|
+
return "Ensure tokens.txt is present in the model directory.";
|
|
180
|
+
return nullptr;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
} // namespace
|
|
184
|
+
|
|
185
|
+
SttValidationResult ValidateSttPaths(
|
|
186
|
+
SttModelKind kind,
|
|
187
|
+
const SttModelPaths& paths,
|
|
188
|
+
const std::string& modelDir
|
|
189
|
+
) {
|
|
190
|
+
SttValidationResult result;
|
|
191
|
+
size_t count = 0;
|
|
192
|
+
const auto* reqs = GetRequirements(kind, count);
|
|
193
|
+
if (!reqs) return result;
|
|
194
|
+
|
|
195
|
+
for (size_t i = 0; i < count; ++i) {
|
|
196
|
+
if (reqs[i].required && (paths.*(reqs[i].field)).empty()) {
|
|
197
|
+
result.missingRequired.push_back(reqs[i].fieldName);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Paraformer: offline uses paraformerModel, streaming uses encoder+decoder.
|
|
202
|
+
// At least one variant must be present.
|
|
203
|
+
if (kind == SttModelKind::kParaformer) {
|
|
204
|
+
bool hasOffline = !paths.paraformerModel.empty();
|
|
205
|
+
bool hasStreaming = !paths.encoder.empty() && !paths.decoder.empty();
|
|
206
|
+
if (!hasOffline && !hasStreaming) {
|
|
207
|
+
result.missingRequired.push_back("paraformerModel (or encoder+decoder for streaming)");
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (!result.missingRequired.empty()) {
|
|
212
|
+
result.ok = false;
|
|
213
|
+
result.error = std::string("STT ") + SttKindToName(kind)
|
|
214
|
+
+ ": missing required files in " + modelDir + ": ";
|
|
215
|
+
for (size_t i = 0; i < result.missingRequired.size(); ++i) {
|
|
216
|
+
if (i > 0) result.error += ", ";
|
|
217
|
+
result.error += result.missingRequired[i];
|
|
218
|
+
const char* hint = GetFieldHint(result.missingRequired[i].c_str());
|
|
219
|
+
if (hint) {
|
|
220
|
+
result.error += " (";
|
|
221
|
+
result.error += hint;
|
|
222
|
+
result.error += ")";
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
} // namespace sherpaonnx
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sherpa-onnx-validate-stt.h
|
|
3
|
+
*
|
|
4
|
+
* Declares ValidateSttPaths(): after model detection resolves a kind and populates
|
|
5
|
+
* SttModelPaths, this function checks that every *required* path field for that kind
|
|
6
|
+
* is non-empty. Returns a validation result with ok/error and the list of missing
|
|
7
|
+
* fields so the caller can surface a specific error instead of crashing at init time.
|
|
8
|
+
*/
|
|
9
|
+
#ifndef SHERPA_ONNX_VALIDATE_STT_H
|
|
10
|
+
#define SHERPA_ONNX_VALIDATE_STT_H
|
|
11
|
+
|
|
12
|
+
#include "sherpa-onnx-model-detect.h"
|
|
13
|
+
#include <string>
|
|
14
|
+
#include <vector>
|
|
15
|
+
|
|
16
|
+
namespace sherpaonnx {
|
|
17
|
+
|
|
18
|
+
struct SttFieldRequirement {
|
|
19
|
+
const char* fieldName;
|
|
20
|
+
std::string SttModelPaths::* field;
|
|
21
|
+
bool required;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
struct SttValidationResult {
|
|
25
|
+
bool ok = true;
|
|
26
|
+
std::vector<std::string> missingRequired;
|
|
27
|
+
std::string error;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
SttValidationResult ValidateSttPaths(
|
|
31
|
+
SttModelKind kind,
|
|
32
|
+
const SttModelPaths& paths,
|
|
33
|
+
const std::string& modelDir
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
} // namespace sherpaonnx
|
|
37
|
+
|
|
38
|
+
#endif // SHERPA_ONNX_VALIDATE_STT_H
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sherpa-onnx-validate-tts.cpp
|
|
3
|
+
*
|
|
4
|
+
* Validates that all required file paths are set for a given TtsModelKind.
|
|
5
|
+
* Requirements are declared in static tables at the top of this file —
|
|
6
|
+
* edit them when adding a new model type or changing what is required.
|
|
7
|
+
*/
|
|
8
|
+
#include "sherpa-onnx-validate-tts.h"
|
|
9
|
+
#include <cstddef>
|
|
10
|
+
#include <cstring>
|
|
11
|
+
|
|
12
|
+
namespace sherpaonnx {
|
|
13
|
+
namespace {
|
|
14
|
+
|
|
15
|
+
// ============================================================
|
|
16
|
+
// REQUIREMENT TABLES — one entry per TtsModelKind.
|
|
17
|
+
// Edit here when adding a new model type or changing requirements.
|
|
18
|
+
// ============================================================
|
|
19
|
+
|
|
20
|
+
static const TtsFieldRequirement kVitsReqs[] = {
|
|
21
|
+
{"ttsModel", &TtsModelPaths::ttsModel, true},
|
|
22
|
+
{"tokens", &TtsModelPaths::tokens, true},
|
|
23
|
+
{"dataDir", &TtsModelPaths::dataDir, false},
|
|
24
|
+
{"lexicon", &TtsModelPaths::lexicon, false},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
static const TtsFieldRequirement kMatchaReqs[] = {
|
|
28
|
+
{"acousticModel", &TtsModelPaths::acousticModel, true},
|
|
29
|
+
{"vocoder", &TtsModelPaths::vocoder, true},
|
|
30
|
+
{"tokens", &TtsModelPaths::tokens, true},
|
|
31
|
+
{"dataDir", &TtsModelPaths::dataDir, false},
|
|
32
|
+
{"lexicon", &TtsModelPaths::lexicon, false},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
static const TtsFieldRequirement kKokoroReqs[] = {
|
|
36
|
+
{"ttsModel", &TtsModelPaths::ttsModel, true},
|
|
37
|
+
{"tokens", &TtsModelPaths::tokens, true},
|
|
38
|
+
{"voices", &TtsModelPaths::voices, true},
|
|
39
|
+
{"dataDir", &TtsModelPaths::dataDir, true},
|
|
40
|
+
{"lexicon", &TtsModelPaths::lexicon, false},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
static const TtsFieldRequirement kPocketReqs[] = {
|
|
44
|
+
{"lmFlow", &TtsModelPaths::lmFlow, true},
|
|
45
|
+
{"lmMain", &TtsModelPaths::lmMain, true},
|
|
46
|
+
{"encoder", &TtsModelPaths::encoder, true},
|
|
47
|
+
{"decoder", &TtsModelPaths::decoder, true},
|
|
48
|
+
{"textConditioner", &TtsModelPaths::textConditioner, true},
|
|
49
|
+
{"vocabJson", &TtsModelPaths::vocabJson, true},
|
|
50
|
+
{"tokenScoresJson", &TtsModelPaths::tokenScoresJson, true},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
static const TtsFieldRequirement kZipvoiceReqs[] = {
|
|
54
|
+
{"encoder", &TtsModelPaths::encoder, true},
|
|
55
|
+
{"decoder", &TtsModelPaths::decoder, true},
|
|
56
|
+
{"vocoder", &TtsModelPaths::vocoder, true},
|
|
57
|
+
{"tokens", &TtsModelPaths::tokens, true},
|
|
58
|
+
{"dataDir", &TtsModelPaths::dataDir, false},
|
|
59
|
+
{"lexicon", &TtsModelPaths::lexicon, false},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// ============================================================
|
|
63
|
+
|
|
64
|
+
static const TtsFieldRequirement* GetRequirements(TtsModelKind kind, size_t& count) {
|
|
65
|
+
switch (kind) {
|
|
66
|
+
case TtsModelKind::kVits:
|
|
67
|
+
count = std::size(kVitsReqs);
|
|
68
|
+
return kVitsReqs;
|
|
69
|
+
case TtsModelKind::kMatcha:
|
|
70
|
+
count = std::size(kMatchaReqs);
|
|
71
|
+
return kMatchaReqs;
|
|
72
|
+
case TtsModelKind::kKokoro:
|
|
73
|
+
case TtsModelKind::kKitten:
|
|
74
|
+
count = std::size(kKokoroReqs);
|
|
75
|
+
return kKokoroReqs;
|
|
76
|
+
case TtsModelKind::kPocket:
|
|
77
|
+
count = std::size(kPocketReqs);
|
|
78
|
+
return kPocketReqs;
|
|
79
|
+
case TtsModelKind::kZipvoice:
|
|
80
|
+
count = std::size(kZipvoiceReqs);
|
|
81
|
+
return kZipvoiceReqs;
|
|
82
|
+
default:
|
|
83
|
+
count = 0;
|
|
84
|
+
return nullptr;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static const char* TtsKindToName(TtsModelKind k) {
|
|
89
|
+
switch (k) {
|
|
90
|
+
case TtsModelKind::kVits: return "VITS";
|
|
91
|
+
case TtsModelKind::kMatcha: return "Matcha";
|
|
92
|
+
case TtsModelKind::kKokoro: return "Kokoro";
|
|
93
|
+
case TtsModelKind::kKitten: return "Kitten";
|
|
94
|
+
case TtsModelKind::kPocket: return "Pocket";
|
|
95
|
+
case TtsModelKind::kZipvoice: return "Zipvoice";
|
|
96
|
+
default: return "Unknown";
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static const char* GetFieldHint(const char* fieldName) {
|
|
101
|
+
if (std::strcmp(fieldName, "dataDir") == 0)
|
|
102
|
+
return "Copy espeak-ng-data into the model directory.";
|
|
103
|
+
if (std::strcmp(fieldName, "tokens") == 0)
|
|
104
|
+
return "Ensure tokens.txt is present in the model directory.";
|
|
105
|
+
return nullptr;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
} // namespace
|
|
109
|
+
|
|
110
|
+
TtsValidationResult ValidateTtsPaths(
|
|
111
|
+
TtsModelKind kind,
|
|
112
|
+
const TtsModelPaths& paths,
|
|
113
|
+
const std::string& modelDir
|
|
114
|
+
) {
|
|
115
|
+
TtsValidationResult result;
|
|
116
|
+
size_t count = 0;
|
|
117
|
+
const auto* reqs = GetRequirements(kind, count);
|
|
118
|
+
if (!reqs) return result;
|
|
119
|
+
|
|
120
|
+
for (size_t i = 0; i < count; ++i) {
|
|
121
|
+
if (reqs[i].required && (paths.*(reqs[i].field)).empty()) {
|
|
122
|
+
result.missingRequired.push_back(reqs[i].fieldName);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (!result.missingRequired.empty()) {
|
|
127
|
+
result.ok = false;
|
|
128
|
+
result.error = std::string("TTS ") + TtsKindToName(kind)
|
|
129
|
+
+ ": missing required files in " + modelDir + ": ";
|
|
130
|
+
for (size_t i = 0; i < result.missingRequired.size(); ++i) {
|
|
131
|
+
if (i > 0) result.error += ", ";
|
|
132
|
+
result.error += result.missingRequired[i];
|
|
133
|
+
const char* hint = GetFieldHint(result.missingRequired[i].c_str());
|
|
134
|
+
if (hint) {
|
|
135
|
+
result.error += " (";
|
|
136
|
+
result.error += hint;
|
|
137
|
+
result.error += ")";
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
} // namespace sherpaonnx
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sherpa-onnx-validate-tts.h
|
|
3
|
+
*
|
|
4
|
+
* Declares ValidateTtsPaths(): after model detection resolves a kind and populates
|
|
5
|
+
* TtsModelPaths, this function checks that every *required* path field for that kind
|
|
6
|
+
* is non-empty. Returns a validation result with ok/error and the list of missing
|
|
7
|
+
* fields so the caller can surface a specific error instead of crashing at init time.
|
|
8
|
+
*/
|
|
9
|
+
#ifndef SHERPA_ONNX_VALIDATE_TTS_H
|
|
10
|
+
#define SHERPA_ONNX_VALIDATE_TTS_H
|
|
11
|
+
|
|
12
|
+
#include "sherpa-onnx-model-detect.h"
|
|
13
|
+
#include <string>
|
|
14
|
+
#include <vector>
|
|
15
|
+
|
|
16
|
+
namespace sherpaonnx {
|
|
17
|
+
|
|
18
|
+
struct TtsFieldRequirement {
|
|
19
|
+
const char* fieldName;
|
|
20
|
+
std::string TtsModelPaths::* field;
|
|
21
|
+
bool required;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
struct TtsValidationResult {
|
|
25
|
+
bool ok = true;
|
|
26
|
+
std::vector<std::string> missingRequired;
|
|
27
|
+
std::string error;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
TtsValidationResult ValidateTtsPaths(
|
|
31
|
+
TtsModelKind kind,
|
|
32
|
+
const TtsModelPaths& paths,
|
|
33
|
+
const std::string& modelDir
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
} // namespace sherpaonnx
|
|
37
|
+
|
|
38
|
+
#endif // SHERPA_ONNX_VALIDATE_TTS_H
|
|
@@ -72,7 +72,7 @@ constexpr int ANEURALNETWORKS_NO_ERROR = 0;
|
|
|
72
72
|
// UNKNOWN= 0, OTHER = 1, CPU = 2, GPU = 3, ACCELERATOR = 4.
|
|
73
73
|
constexpr int32_t ANEURALNETWORKS_DEVICE_GPU = 3;
|
|
74
74
|
constexpr int32_t ANEURALNETWORKS_DEVICE_ACCELERATOR = 4;
|
|
75
|
-
struct ANeuralNetworksDeviceOpaque
|
|
75
|
+
struct ANeuralNetworksDeviceOpaque;
|
|
76
76
|
using ANeuralNetworksDevice = ANeuralNetworksDeviceOpaque*;
|
|
77
77
|
} // namespace
|
|
78
78
|
#endif
|