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
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
// Include standard library headers first to avoid conflicts with jni.h
|
|
2
|
-
#include <memory>
|
|
3
|
-
#include <optional>
|
|
4
|
-
#include <string>
|
|
5
|
-
|
|
6
|
-
// Then include JNI headers
|
|
7
|
-
#include <android/log.h>
|
|
8
|
-
#include <jni.h>
|
|
9
|
-
|
|
10
|
-
// STT wrapper
|
|
11
|
-
#include "sherpa-onnx-stt-wrapper.h"
|
|
12
|
-
|
|
13
|
-
#define LOG_TAG "SherpaOnnxJNI"
|
|
14
|
-
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
|
15
|
-
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
|
16
|
-
|
|
17
|
-
using namespace sherpaonnx;
|
|
18
|
-
|
|
19
|
-
// Global wrapper instance
|
|
20
|
-
static std::unique_ptr<SttWrapper> g_stt_wrapper = nullptr;
|
|
21
|
-
|
|
22
|
-
extern "C" {
|
|
23
|
-
|
|
24
|
-
JNIEXPORT jobject JNICALL
|
|
25
|
-
Java_com_sherpaonnx_SherpaOnnxModule_nativeSttInitialize(
|
|
26
|
-
JNIEnv *env,
|
|
27
|
-
jobject /* this */,
|
|
28
|
-
jstring modelDir,
|
|
29
|
-
jboolean preferInt8,
|
|
30
|
-
jboolean hasPreferInt8,
|
|
31
|
-
jstring modelType) {
|
|
32
|
-
try {
|
|
33
|
-
if (g_stt_wrapper == nullptr) {
|
|
34
|
-
g_stt_wrapper = std::make_unique<SttWrapper>();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const char *modelDirStr = env->GetStringUTFChars(modelDir, nullptr);
|
|
38
|
-
if (modelDirStr == nullptr) {
|
|
39
|
-
LOGE("Failed to get modelDir string from JNI");
|
|
40
|
-
return nullptr;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const char *modelTypeStr = env->GetStringUTFChars(modelType, nullptr);
|
|
44
|
-
if (modelTypeStr == nullptr) {
|
|
45
|
-
LOGE("Failed to get modelType string from JNI");
|
|
46
|
-
env->ReleaseStringUTFChars(modelDir, modelDirStr);
|
|
47
|
-
return nullptr;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
std::string modelDirPath(modelDirStr);
|
|
51
|
-
std::string modelTypePath(modelTypeStr);
|
|
52
|
-
|
|
53
|
-
// Convert Java boolean to C++ optional<bool>
|
|
54
|
-
std::optional<bool> preferInt8Opt;
|
|
55
|
-
if (hasPreferInt8 == JNI_TRUE) {
|
|
56
|
-
preferInt8Opt = (preferInt8 == JNI_TRUE);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Convert model type string to optional
|
|
60
|
-
std::optional<std::string> modelTypeOpt;
|
|
61
|
-
if (modelTypePath != "auto" && !modelTypePath.empty()) {
|
|
62
|
-
modelTypeOpt = modelTypePath;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
SttInitializeResult result = g_stt_wrapper->initialize(modelDirPath, preferInt8Opt, modelTypeOpt);
|
|
66
|
-
env->ReleaseStringUTFChars(modelDir, modelDirStr);
|
|
67
|
-
env->ReleaseStringUTFChars(modelType, modelTypeStr);
|
|
68
|
-
|
|
69
|
-
LOGI("STT JNI: Initialization result: success=%d, detected models=%zu", result.success, result.detectedModels.size());
|
|
70
|
-
if (!result.success) {
|
|
71
|
-
LOGE("STT JNI: Native initialization failed for: %s", modelDirPath.c_str());
|
|
72
|
-
} else {
|
|
73
|
-
LOGI("STT JNI: Successfully initialized model at: %s", modelDirPath.c_str());
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Create HashMap to return
|
|
77
|
-
LOGI("STT JNI: Creating HashMap for result");
|
|
78
|
-
jclass hashMapClass = env->FindClass("java/util/HashMap");
|
|
79
|
-
if (hashMapClass == nullptr || env->ExceptionCheck()) {
|
|
80
|
-
LOGE("STT JNI: Failed to find HashMap class");
|
|
81
|
-
if (env->ExceptionCheck()) {
|
|
82
|
-
env->ExceptionDescribe();
|
|
83
|
-
env->ExceptionClear();
|
|
84
|
-
}
|
|
85
|
-
return nullptr;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
jmethodID hashMapConstructor = env->GetMethodID(hashMapClass, "<init>", "()V");
|
|
89
|
-
if (hashMapConstructor == nullptr || env->ExceptionCheck()) {
|
|
90
|
-
LOGE("STT JNI: Failed to get HashMap constructor");
|
|
91
|
-
if (env->ExceptionCheck()) {
|
|
92
|
-
env->ExceptionDescribe();
|
|
93
|
-
env->ExceptionClear();
|
|
94
|
-
}
|
|
95
|
-
env->DeleteLocalRef(hashMapClass);
|
|
96
|
-
return nullptr;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
jmethodID putMethod = env->GetMethodID(hashMapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
|
100
|
-
if (putMethod == nullptr || env->ExceptionCheck()) {
|
|
101
|
-
LOGE("STT JNI: Failed to get HashMap put method");
|
|
102
|
-
if (env->ExceptionCheck()) {
|
|
103
|
-
env->ExceptionDescribe();
|
|
104
|
-
env->ExceptionClear();
|
|
105
|
-
}
|
|
106
|
-
env->DeleteLocalRef(hashMapClass);
|
|
107
|
-
return nullptr;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
jobject hashMap = env->NewObject(hashMapClass, hashMapConstructor);
|
|
111
|
-
if (hashMap == nullptr || env->ExceptionCheck()) {
|
|
112
|
-
LOGE("STT JNI: Failed to create HashMap object");
|
|
113
|
-
if (env->ExceptionCheck()) {
|
|
114
|
-
env->ExceptionDescribe();
|
|
115
|
-
env->ExceptionClear();
|
|
116
|
-
}
|
|
117
|
-
env->DeleteLocalRef(hashMapClass);
|
|
118
|
-
return nullptr;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Put success boolean
|
|
122
|
-
LOGI("STT JNI: Adding success field to HashMap");
|
|
123
|
-
jclass booleanClass = env->FindClass("java/lang/Boolean");
|
|
124
|
-
if (booleanClass == nullptr || env->ExceptionCheck()) {
|
|
125
|
-
LOGE("STT JNI: Failed to find Boolean class");
|
|
126
|
-
if (env->ExceptionCheck()) {
|
|
127
|
-
env->ExceptionDescribe();
|
|
128
|
-
env->ExceptionClear();
|
|
129
|
-
}
|
|
130
|
-
env->DeleteLocalRef(hashMap);
|
|
131
|
-
env->DeleteLocalRef(hashMapClass);
|
|
132
|
-
return nullptr;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
jmethodID booleanConstructor = env->GetMethodID(booleanClass, "<init>", "(Z)V");
|
|
136
|
-
if (booleanConstructor == nullptr || env->ExceptionCheck()) {
|
|
137
|
-
LOGE("STT JNI: Failed to get Boolean constructor");
|
|
138
|
-
if (env->ExceptionCheck()) {
|
|
139
|
-
env->ExceptionDescribe();
|
|
140
|
-
env->ExceptionClear();
|
|
141
|
-
}
|
|
142
|
-
env->DeleteLocalRef(booleanClass);
|
|
143
|
-
env->DeleteLocalRef(hashMap);
|
|
144
|
-
env->DeleteLocalRef(hashMapClass);
|
|
145
|
-
return nullptr;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
jobject successObj = env->NewObject(booleanClass, booleanConstructor, result.success ? JNI_TRUE : JNI_FALSE);
|
|
149
|
-
jstring successKey = env->NewStringUTF("success");
|
|
150
|
-
env->CallObjectMethod(hashMap, putMethod, successKey, successObj);
|
|
151
|
-
if (env->ExceptionCheck()) {
|
|
152
|
-
LOGE("STT JNI: Exception while putting success field");
|
|
153
|
-
env->ExceptionDescribe();
|
|
154
|
-
env->ExceptionClear();
|
|
155
|
-
env->DeleteLocalRef(successKey);
|
|
156
|
-
env->DeleteLocalRef(successObj);
|
|
157
|
-
env->DeleteLocalRef(booleanClass);
|
|
158
|
-
env->DeleteLocalRef(hashMap);
|
|
159
|
-
env->DeleteLocalRef(hashMapClass);
|
|
160
|
-
return nullptr;
|
|
161
|
-
}
|
|
162
|
-
env->DeleteLocalRef(successKey);
|
|
163
|
-
env->DeleteLocalRef(successObj);
|
|
164
|
-
env->DeleteLocalRef(booleanClass);
|
|
165
|
-
|
|
166
|
-
// Put detectedModels array
|
|
167
|
-
LOGI("STT JNI: Adding detectedModels array (%zu models)", result.detectedModels.size());
|
|
168
|
-
jclass arrayListClass = env->FindClass("java/util/ArrayList");
|
|
169
|
-
if (arrayListClass == nullptr || env->ExceptionCheck()) {
|
|
170
|
-
LOGE("STT JNI: Failed to find ArrayList class");
|
|
171
|
-
if (env->ExceptionCheck()) {
|
|
172
|
-
env->ExceptionDescribe();
|
|
173
|
-
env->ExceptionClear();
|
|
174
|
-
}
|
|
175
|
-
env->DeleteLocalRef(hashMap);
|
|
176
|
-
env->DeleteLocalRef(hashMapClass);
|
|
177
|
-
return nullptr;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
jmethodID arrayListConstructor = env->GetMethodID(arrayListClass, "<init>", "()V");
|
|
181
|
-
if (arrayListConstructor == nullptr || env->ExceptionCheck()) {
|
|
182
|
-
LOGE("STT JNI: Failed to get ArrayList constructor");
|
|
183
|
-
if (env->ExceptionCheck()) {
|
|
184
|
-
env->ExceptionDescribe();
|
|
185
|
-
env->ExceptionClear();
|
|
186
|
-
}
|
|
187
|
-
env->DeleteLocalRef(arrayListClass);
|
|
188
|
-
env->DeleteLocalRef(hashMap);
|
|
189
|
-
env->DeleteLocalRef(hashMapClass);
|
|
190
|
-
return nullptr;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
jmethodID addMethod = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
|
|
194
|
-
if (addMethod == nullptr || env->ExceptionCheck()) {
|
|
195
|
-
LOGE("STT JNI: Failed to get ArrayList add method");
|
|
196
|
-
if (env->ExceptionCheck()) {
|
|
197
|
-
env->ExceptionDescribe();
|
|
198
|
-
env->ExceptionClear();
|
|
199
|
-
}
|
|
200
|
-
env->DeleteLocalRef(arrayListClass);
|
|
201
|
-
env->DeleteLocalRef(hashMap);
|
|
202
|
-
env->DeleteLocalRef(hashMapClass);
|
|
203
|
-
return nullptr;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
jobject detectedModelsList = env->NewObject(arrayListClass, arrayListConstructor);
|
|
207
|
-
if (detectedModelsList == nullptr || env->ExceptionCheck()) {
|
|
208
|
-
LOGE("STT JNI: Failed to create ArrayList object");
|
|
209
|
-
if (env->ExceptionCheck()) {
|
|
210
|
-
env->ExceptionDescribe();
|
|
211
|
-
env->ExceptionClear();
|
|
212
|
-
}
|
|
213
|
-
env->DeleteLocalRef(arrayListClass);
|
|
214
|
-
env->DeleteLocalRef(hashMap);
|
|
215
|
-
env->DeleteLocalRef(hashMapClass);
|
|
216
|
-
return nullptr;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
for (const auto& model : result.detectedModels) {
|
|
220
|
-
// Create HashMap for each model with type and modelDir
|
|
221
|
-
jobject modelMap = env->NewObject(hashMapClass, hashMapConstructor);
|
|
222
|
-
if (modelMap == nullptr || env->ExceptionCheck()) {
|
|
223
|
-
LOGE("STT JNI: Failed to create model HashMap");
|
|
224
|
-
if (env->ExceptionCheck()) {
|
|
225
|
-
env->ExceptionDescribe();
|
|
226
|
-
env->ExceptionClear();
|
|
227
|
-
}
|
|
228
|
-
env->DeleteLocalRef(detectedModelsList);
|
|
229
|
-
env->DeleteLocalRef(arrayListClass);
|
|
230
|
-
env->DeleteLocalRef(hashMap);
|
|
231
|
-
env->DeleteLocalRef(hashMapClass);
|
|
232
|
-
return nullptr;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
jstring typeKey = env->NewStringUTF("type");
|
|
236
|
-
jstring typeValue = env->NewStringUTF(model.type.c_str());
|
|
237
|
-
env->CallObjectMethod(modelMap, putMethod, typeKey, typeValue);
|
|
238
|
-
env->DeleteLocalRef(typeKey);
|
|
239
|
-
env->DeleteLocalRef(typeValue);
|
|
240
|
-
|
|
241
|
-
jstring dirKey = env->NewStringUTF("modelDir");
|
|
242
|
-
jstring dirValue = env->NewStringUTF(model.modelDir.c_str());
|
|
243
|
-
env->CallObjectMethod(modelMap, putMethod, dirKey, dirValue);
|
|
244
|
-
env->DeleteLocalRef(dirKey);
|
|
245
|
-
env->DeleteLocalRef(dirValue);
|
|
246
|
-
|
|
247
|
-
env->CallBooleanMethod(detectedModelsList, addMethod, modelMap);
|
|
248
|
-
env->DeleteLocalRef(modelMap);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
jstring detectedModelsKey = env->NewStringUTF("detectedModels");
|
|
252
|
-
env->CallObjectMethod(hashMap, putMethod, detectedModelsKey, detectedModelsList);
|
|
253
|
-
if (env->ExceptionCheck()) {
|
|
254
|
-
LOGE("STT JNI: Exception while putting detectedModels field");
|
|
255
|
-
env->ExceptionDescribe();
|
|
256
|
-
env->ExceptionClear();
|
|
257
|
-
env->DeleteLocalRef(detectedModelsKey);
|
|
258
|
-
env->DeleteLocalRef(detectedModelsList);
|
|
259
|
-
env->DeleteLocalRef(arrayListClass);
|
|
260
|
-
env->DeleteLocalRef(hashMap);
|
|
261
|
-
env->DeleteLocalRef(hashMapClass);
|
|
262
|
-
return nullptr;
|
|
263
|
-
}
|
|
264
|
-
env->DeleteLocalRef(detectedModelsKey);
|
|
265
|
-
env->DeleteLocalRef(detectedModelsList);
|
|
266
|
-
env->DeleteLocalRef(arrayListClass);
|
|
267
|
-
env->DeleteLocalRef(hashMapClass);
|
|
268
|
-
|
|
269
|
-
LOGI("STT JNI: Successfully created result HashMap, returning to Java");
|
|
270
|
-
return hashMap;
|
|
271
|
-
} catch (const std::exception &e) {
|
|
272
|
-
LOGE("Exception in nativeInitialize: %s", e.what());
|
|
273
|
-
if (env->ExceptionCheck()) {
|
|
274
|
-
env->ExceptionDescribe();
|
|
275
|
-
env->ExceptionClear();
|
|
276
|
-
}
|
|
277
|
-
return nullptr;
|
|
278
|
-
} catch (...) {
|
|
279
|
-
LOGE("Unknown exception in nativeInitialize");
|
|
280
|
-
if (env->ExceptionCheck()) {
|
|
281
|
-
env->ExceptionDescribe();
|
|
282
|
-
env->ExceptionClear();
|
|
283
|
-
}
|
|
284
|
-
return nullptr;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
JNIEXPORT jstring JNICALL
|
|
289
|
-
Java_com_sherpaonnx_SherpaOnnxModule_nativeSttTranscribe(
|
|
290
|
-
JNIEnv *env,
|
|
291
|
-
jobject /* this */,
|
|
292
|
-
jstring filePath) {
|
|
293
|
-
try {
|
|
294
|
-
if (g_stt_wrapper == nullptr || !g_stt_wrapper->isInitialized()) {
|
|
295
|
-
LOGE("STT JNI: Not initialized. Call initialize() first.");
|
|
296
|
-
return env->NewStringUTF("");
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
const char *filePathStr = env->GetStringUTFChars(filePath, nullptr);
|
|
300
|
-
if (filePathStr == nullptr) {
|
|
301
|
-
LOGE("STT JNI: Failed to get filePath string");
|
|
302
|
-
return env->NewStringUTF("");
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
std::string result = g_stt_wrapper->transcribeFile(std::string(filePathStr));
|
|
306
|
-
env->ReleaseStringUTFChars(filePath, filePathStr);
|
|
307
|
-
|
|
308
|
-
return env->NewStringUTF(result.c_str());
|
|
309
|
-
} catch (const std::exception &e) {
|
|
310
|
-
LOGE("Exception in nativeTranscribeFile: %s", e.what());
|
|
311
|
-
return env->NewStringUTF("");
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
JNIEXPORT void JNICALL
|
|
316
|
-
Java_com_sherpaonnx_SherpaOnnxModule_nativeSttRelease(
|
|
317
|
-
JNIEnv * /* env */,
|
|
318
|
-
jobject /* this */) {
|
|
319
|
-
try {
|
|
320
|
-
if (g_stt_wrapper != nullptr) {
|
|
321
|
-
g_stt_wrapper->release();
|
|
322
|
-
g_stt_wrapper.reset();
|
|
323
|
-
}
|
|
324
|
-
} catch (const std::exception &e) {
|
|
325
|
-
LOGE("Exception in nativeRelease: %s", e.what());
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
JNIEXPORT jstring JNICALL
|
|
330
|
-
Java_com_sherpaonnx_SherpaOnnxModule_nativeTestSherpaInit(
|
|
331
|
-
JNIEnv *env,
|
|
332
|
-
jobject /* this */) {
|
|
333
|
-
return env->NewStringUTF("Sherpa ONNX loaded!");
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
} // extern "C"
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
#include "sherpa-onnx-stt-wrapper.h"
|
|
2
|
-
#include "sherpa-onnx-model-detect.h"
|
|
3
|
-
#include <android/log.h>
|
|
4
|
-
#include <algorithm>
|
|
5
|
-
#include <cctype>
|
|
6
|
-
#include <fstream>
|
|
7
|
-
#include <optional>
|
|
8
|
-
#include <sstream>
|
|
9
|
-
#include <sys/stat.h>
|
|
10
|
-
|
|
11
|
-
// Use filesystem if available (C++17), otherwise fallback
|
|
12
|
-
#if __cplusplus >= 201703L && __has_include(<filesystem>)
|
|
13
|
-
#include <filesystem>
|
|
14
|
-
namespace fs = std::filesystem;
|
|
15
|
-
#elif __has_include(<experimental/filesystem>)
|
|
16
|
-
#include <experimental/filesystem>
|
|
17
|
-
namespace fs = std::experimental::filesystem;
|
|
18
|
-
#else
|
|
19
|
-
// Fallback: use stat/opendir for older compilers
|
|
20
|
-
#include <dirent.h>
|
|
21
|
-
#include <sys/stat.h>
|
|
22
|
-
#endif
|
|
23
|
-
|
|
24
|
-
// sherpa-onnx headers - use cxx-api which is compatible with libsherpa-onnx-cxx-api.so
|
|
25
|
-
#include "sherpa-onnx/c-api/cxx-api.h"
|
|
26
|
-
|
|
27
|
-
#define LOG_TAG "SttWrapper"
|
|
28
|
-
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
|
29
|
-
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
|
30
|
-
|
|
31
|
-
namespace sherpaonnx {
|
|
32
|
-
|
|
33
|
-
// PIMPL pattern implementation
|
|
34
|
-
class SttWrapper::Impl {
|
|
35
|
-
public:
|
|
36
|
-
bool initialized = false;
|
|
37
|
-
std::string modelDir;
|
|
38
|
-
std::optional<sherpa_onnx::cxx::OfflineRecognizer> recognizer;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
SttWrapper::SttWrapper() : pImpl(std::make_unique<Impl>()) {
|
|
42
|
-
LOGI("SttWrapper created");
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
SttWrapper::~SttWrapper() {
|
|
46
|
-
release();
|
|
47
|
-
LOGI("SttWrapper destroyed");
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
SttInitializeResult SttWrapper::initialize(
|
|
51
|
-
const std::string& modelDir,
|
|
52
|
-
const std::optional<bool>& preferInt8,
|
|
53
|
-
const std::optional<std::string>& modelType
|
|
54
|
-
) {
|
|
55
|
-
SttInitializeResult result;
|
|
56
|
-
result.success = false;
|
|
57
|
-
|
|
58
|
-
if (pImpl->initialized) {
|
|
59
|
-
release();
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (modelDir.empty()) {
|
|
63
|
-
LOGE("Model directory is empty");
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
sherpa_onnx::cxx::OfflineRecognizerConfig config;
|
|
69
|
-
config.feat_config.sample_rate = 16000;
|
|
70
|
-
config.feat_config.feature_dim = 80;
|
|
71
|
-
|
|
72
|
-
auto detect = DetectSttModel(modelDir, preferInt8, modelType);
|
|
73
|
-
if (!detect.ok) {
|
|
74
|
-
LOGE("%s", detect.error.c_str());
|
|
75
|
-
return result;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
switch (detect.selectedKind) {
|
|
79
|
-
case SttModelKind::kTransducer:
|
|
80
|
-
config.model_config.transducer.encoder = detect.paths.encoder;
|
|
81
|
-
config.model_config.transducer.decoder = detect.paths.decoder;
|
|
82
|
-
config.model_config.transducer.joiner = detect.paths.joiner;
|
|
83
|
-
break;
|
|
84
|
-
case SttModelKind::kParaformer:
|
|
85
|
-
config.model_config.paraformer.model = detect.paths.paraformerModel;
|
|
86
|
-
break;
|
|
87
|
-
case SttModelKind::kNemoCtc:
|
|
88
|
-
config.model_config.nemo_ctc.model = detect.paths.ctcModel;
|
|
89
|
-
break;
|
|
90
|
-
case SttModelKind::kWenetCtc:
|
|
91
|
-
config.model_config.wenet_ctc.model = detect.paths.ctcModel;
|
|
92
|
-
break;
|
|
93
|
-
case SttModelKind::kSenseVoice:
|
|
94
|
-
config.model_config.sense_voice.model = detect.paths.ctcModel;
|
|
95
|
-
break;
|
|
96
|
-
case SttModelKind::kZipformerCtc:
|
|
97
|
-
config.model_config.zipformer_ctc.model = detect.paths.ctcModel;
|
|
98
|
-
break;
|
|
99
|
-
case SttModelKind::kWhisper:
|
|
100
|
-
config.model_config.whisper.encoder = detect.paths.whisperEncoder;
|
|
101
|
-
config.model_config.whisper.decoder = detect.paths.whisperDecoder;
|
|
102
|
-
break;
|
|
103
|
-
case SttModelKind::kFunAsrNano:
|
|
104
|
-
config.model_config.funasr_nano.encoder_adaptor = detect.paths.funasrEncoderAdaptor;
|
|
105
|
-
config.model_config.funasr_nano.llm = detect.paths.funasrLLM;
|
|
106
|
-
config.model_config.funasr_nano.embedding = detect.paths.funasrEmbedding;
|
|
107
|
-
config.model_config.funasr_nano.tokenizer = detect.paths.funasrTokenizer;
|
|
108
|
-
break;
|
|
109
|
-
case SttModelKind::kUnknown:
|
|
110
|
-
default:
|
|
111
|
-
LOGE("No compatible model type detected in %s", modelDir.c_str());
|
|
112
|
-
return result;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (!detect.paths.tokens.empty()) {
|
|
116
|
-
config.model_config.tokens = detect.paths.tokens;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
config.decoding_method = "greedy_search";
|
|
120
|
-
config.model_config.num_threads = 4;
|
|
121
|
-
config.model_config.provider = "cpu";
|
|
122
|
-
|
|
123
|
-
// Create recognizer
|
|
124
|
-
// Log configuration details
|
|
125
|
-
bool isWhisperModel = !config.model_config.whisper.encoder.empty() && !config.model_config.whisper.decoder.empty();
|
|
126
|
-
if (isWhisperModel) {
|
|
127
|
-
LOGI("Initializing Whisper model with encoder: %s, decoder: %s", config.model_config.whisper.encoder.c_str(), config.model_config.whisper.decoder.c_str());
|
|
128
|
-
} else {
|
|
129
|
-
LOGI("Initializing non-Whisper model");
|
|
130
|
-
}
|
|
131
|
-
try {
|
|
132
|
-
pImpl->recognizer = sherpa_onnx::cxx::OfflineRecognizer::Create(config);
|
|
133
|
-
} catch (const std::exception& e) {
|
|
134
|
-
LOGE("Failed to create recognizer: %s", e.what());
|
|
135
|
-
return result;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
pImpl->modelDir = modelDir;
|
|
139
|
-
pImpl->initialized = true;
|
|
140
|
-
|
|
141
|
-
// Success - return detected models
|
|
142
|
-
result.success = true;
|
|
143
|
-
result.detectedModels = detect.detectedModels;
|
|
144
|
-
return result;
|
|
145
|
-
} catch (const std::exception& e) {
|
|
146
|
-
LOGE("Exception during initialization: %s", e.what());
|
|
147
|
-
return result;
|
|
148
|
-
} catch (...) {
|
|
149
|
-
LOGE("Unknown exception during initialization");
|
|
150
|
-
return result;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
std::string SttWrapper::transcribeFile(const std::string& filePath) {
|
|
155
|
-
if (!pImpl->initialized || !pImpl->recognizer.has_value()) {
|
|
156
|
-
LOGE("Not initialized. Call initialize() first.");
|
|
157
|
-
return "";
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
try {
|
|
161
|
-
// Helper function to check if file exists
|
|
162
|
-
auto fileExists = [](const std::string& path) -> bool {
|
|
163
|
-
#if __cplusplus >= 201703L && __has_include(<filesystem>)
|
|
164
|
-
return std::filesystem::exists(path);
|
|
165
|
-
#elif __has_include(<experimental/filesystem>)
|
|
166
|
-
return std::experimental::filesystem::exists(path);
|
|
167
|
-
#else
|
|
168
|
-
struct stat buffer;
|
|
169
|
-
return (stat(path.c_str(), &buffer) == 0);
|
|
170
|
-
#endif
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
// Check if file exists
|
|
174
|
-
if (!fileExists(filePath)) {
|
|
175
|
-
LOGE("Audio file not found: %s", filePath.c_str());
|
|
176
|
-
return "";
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Read audio file using cxx-api
|
|
180
|
-
sherpa_onnx::cxx::Wave wave = sherpa_onnx::cxx::ReadWave(filePath);
|
|
181
|
-
|
|
182
|
-
if (wave.samples.empty()) {
|
|
183
|
-
LOGE("Audio file is empty or failed to read: %s", filePath.c_str());
|
|
184
|
-
return "";
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Create a stream
|
|
188
|
-
auto stream = pImpl->recognizer.value().CreateStream();
|
|
189
|
-
|
|
190
|
-
// Feed audio data to the stream (all samples at once for offline recognition)
|
|
191
|
-
stream.AcceptWaveform(wave.sample_rate, wave.samples.data(), wave.samples.size());
|
|
192
|
-
|
|
193
|
-
// Decode the stream
|
|
194
|
-
pImpl->recognizer.value().Decode(&stream);
|
|
195
|
-
|
|
196
|
-
// Get result
|
|
197
|
-
auto result = pImpl->recognizer.value().GetResult(&stream);
|
|
198
|
-
|
|
199
|
-
return result.text;
|
|
200
|
-
} catch (const std::exception& e) {
|
|
201
|
-
LOGE("Exception during transcription: %s", e.what());
|
|
202
|
-
return "";
|
|
203
|
-
} catch (...) {
|
|
204
|
-
LOGE("Unknown exception during transcription");
|
|
205
|
-
return "";
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
bool SttWrapper::isInitialized() const {
|
|
210
|
-
return pImpl->initialized;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
void SttWrapper::release() {
|
|
214
|
-
if (pImpl->initialized) {
|
|
215
|
-
// OfflineRecognizer uses RAII - destruction happens automatically when optional is reset
|
|
216
|
-
pImpl->recognizer.reset();
|
|
217
|
-
pImpl->initialized = false;
|
|
218
|
-
pImpl->modelDir.clear();
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
} // namespace sherpaonnx
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
#ifndef SHERPA_ONNX_STT_WRAPPER_H
|
|
2
|
-
#define SHERPA_ONNX_STT_WRAPPER_H
|
|
3
|
-
|
|
4
|
-
#include "sherpa-onnx-common.h"
|
|
5
|
-
#include <cstdint>
|
|
6
|
-
#include <memory>
|
|
7
|
-
#include <optional>
|
|
8
|
-
#include <string>
|
|
9
|
-
#include <vector>
|
|
10
|
-
|
|
11
|
-
namespace sherpaonnx {
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Result of STT initialization.
|
|
15
|
-
*/
|
|
16
|
-
struct SttInitializeResult {
|
|
17
|
-
bool success;
|
|
18
|
-
std::vector<DetectedModel> detectedModels; // List of detected models with type and path
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Wrapper class for sherpa-onnx OfflineRecognizer (STT).
|
|
23
|
-
* This provides a C++ interface that can be easily called from JNI.
|
|
24
|
-
*/
|
|
25
|
-
class SttWrapper {
|
|
26
|
-
public:
|
|
27
|
-
SttWrapper();
|
|
28
|
-
~SttWrapper();
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Initialize sherpa-onnx STT with model directory.
|
|
32
|
-
* @param modelDir Path to the model directory
|
|
33
|
-
* @param preferInt8 Optional: true = prefer int8 models, false = prefer regular models, nullopt = try int8 first (default)
|
|
34
|
-
* @param modelType Optional: explicit model type ("transducer", "paraformer", "nemo_ctc"), nullopt = auto-detect (default)
|
|
35
|
-
* @return SttInitializeResult with success status and list of detected usable models
|
|
36
|
-
*/
|
|
37
|
-
SttInitializeResult initialize(
|
|
38
|
-
const std::string& modelDir,
|
|
39
|
-
const std::optional<bool>& preferInt8 = std::nullopt,
|
|
40
|
-
const std::optional<std::string>& modelType = std::nullopt
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Transcribe an audio file.
|
|
45
|
-
* @param filePath Path to the audio file (WAV 16kHz mono 16-bit PCM)
|
|
46
|
-
* @return Transcribed text
|
|
47
|
-
*/
|
|
48
|
-
std::string transcribeFile(const std::string& filePath);
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Check if the recognizer is initialized.
|
|
52
|
-
* @return true if initialized, false otherwise
|
|
53
|
-
*/
|
|
54
|
-
bool isInitialized() const;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Release resources.
|
|
58
|
-
*/
|
|
59
|
-
void release();
|
|
60
|
-
|
|
61
|
-
private:
|
|
62
|
-
class Impl;
|
|
63
|
-
std::unique_ptr<Impl> pImpl;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
} // namespace sherpaonnx
|
|
67
|
-
|
|
68
|
-
#endif // SHERPA_ONNX_STT_WRAPPER_H
|