react-native-sherpa-onnx 0.3.6 → 0.3.8
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/LICENSE +1 -0
- package/README.md +92 -21
- package/SherpaOnnx.podspec +3 -0
- package/THIRD_PARTY_LICENSES/README.md +62 -0
- package/THIRD_PARTY_LICENSES/ffmpeg.txt +502 -0
- package/THIRD_PARTY_LICENSES/libarchive.txt +65 -0
- package/THIRD_PARTY_LICENSES/nvidia_omla.txt +181 -0
- package/THIRD_PARTY_LICENSES/onnxruntime.txt +21 -0
- package/THIRD_PARTY_LICENSES/opus.txt +44 -0
- package/THIRD_PARTY_LICENSES/sherpa-onnx.txt +201 -0
- package/THIRD_PARTY_LICENSES/shine.txt +482 -0
- package/THIRD_PARTY_LICENSES/zstd.txt +30 -0
- package/android/build.gradle +7 -3
- package/android/prebuilt-download.gradle +344 -152
- package/android/prebuilt-versions.gradle +1 -1
- package/android/src/main/assets/model_licenses/asr-models-license-status.csv +409 -0
- package/android/src/main/assets/model_licenses/qnn-asr-models-license-status.csv +695 -0
- package/android/src/main/assets/model_licenses/tts-models-license-status.csv +596 -0
- package/android/src/main/cpp/CMakeLists.txt +28 -10
- package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-helper.cpp +2 -2
- package/android/src/main/cpp/jni/audio/sherpa-onnx-audio-convert-jni.cpp +268 -2
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-tts.cpp +37 -6
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect.h +9 -1
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-tts-wrapper.cpp +7 -0
- package/android/src/main/cpp/jni/model_detect/sherpa-onnx-validate-tts.cpp +18 -2
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxArchiveHelper.kt +40 -10
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxModule.kt +99 -0
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxOnlineSttHelper.kt +4 -1
- package/android/src/main/java/com/sherpaonnx/SherpaOnnxTtsHelper.kt +127 -97
- package/ios/Resources/model_licenses/asr-models-license-status.csv +409 -0
- package/ios/Resources/model_licenses/qnn-asr-models-license-status.csv +695 -0
- package/ios/Resources/model_licenses/tts-models-license-status.csv +596 -0
- package/ios/SherpaOnnx+OnlineSTT.mm +2 -0
- package/ios/SherpaOnnx+PcmLiveStream.mm +2 -29
- package/ios/SherpaOnnx+TTS.mm +179 -20
- package/ios/SherpaOnnx.mm +54 -0
- package/ios/SherpaOnnxAudioConvert.h +10 -0
- package/ios/SherpaOnnxAudioConvert.mm +257 -1
- package/ios/archive/sherpa-onnx-archive-helper.h +3 -0
- package/ios/archive/sherpa-onnx-archive-helper.mm +39 -6
- package/ios/model_detect/sherpa-onnx-model-detect-tts.mm +49 -6
- package/ios/model_detect/sherpa-onnx-model-detect.h +9 -1
- package/ios/model_detect/sherpa-onnx-validate-tts.mm +18 -2
- package/ios/online_stt/sherpa-onnx-online-stt-wrapper.h +1 -0
- package/ios/online_stt/sherpa-onnx-online-stt-wrapper.mm +4 -0
- package/ios/tts/sherpa-onnx-tts-wrapper.h +37 -0
- package/ios/tts/sherpa-onnx-tts-wrapper.mm +158 -3
- package/lib/module/NativeSherpaOnnx.js.map +1 -1
- package/lib/module/audio/index.js +8 -0
- package/lib/module/audio/index.js.map +1 -1
- package/lib/module/download/ModelDownloadManager.js +10 -929
- package/lib/module/download/ModelDownloadManager.js.map +1 -1
- package/lib/module/download/activeModelOperations.js +26 -0
- package/lib/module/download/activeModelOperations.js.map +1 -0
- package/lib/module/download/background-downloader-types.js +2 -0
- package/lib/module/download/background-downloader-types.js.map +1 -0
- package/lib/module/download/bulkPurge.js +72 -0
- package/lib/module/download/bulkPurge.js.map +1 -0
- package/lib/module/download/checksumPrompt.js +19 -0
- package/lib/module/download/checksumPrompt.js.map +1 -0
- package/lib/module/download/constants.js +7 -0
- package/lib/module/download/constants.js.map +1 -0
- package/lib/module/download/downloadEvents.js +35 -0
- package/lib/module/download/downloadEvents.js.map +1 -0
- package/lib/module/download/downloadTask.js +438 -0
- package/lib/module/download/downloadTask.js.map +1 -0
- package/lib/module/download/ensureModel.js +89 -0
- package/lib/module/download/ensureModel.js.map +1 -0
- package/lib/module/download/index.js +4 -4
- package/lib/module/download/index.js.map +1 -1
- package/lib/module/download/localModels.js +151 -0
- package/lib/module/download/localModels.js.map +1 -0
- package/lib/module/download/modelExtraction.js +174 -0
- package/lib/module/download/modelExtraction.js.map +1 -0
- package/lib/module/download/paths.js +98 -0
- package/lib/module/download/paths.js.map +1 -0
- package/lib/module/download/postDownloadProcessing.js +206 -0
- package/lib/module/download/postDownloadProcessing.js.map +1 -0
- package/lib/module/download/protectedModelKeys.js +31 -0
- package/lib/module/download/protectedModelKeys.js.map +1 -0
- package/lib/module/download/registry.js +268 -0
- package/lib/module/download/registry.js.map +1 -0
- package/lib/module/download/retry.js +59 -0
- package/lib/module/download/retry.js.map +1 -0
- package/lib/module/download/types.js +17 -0
- package/lib/module/download/types.js.map +1 -0
- package/lib/module/download/validation.js +101 -5
- package/lib/module/download/validation.js.map +1 -1
- package/lib/module/{download → extraction}/extractTarBz2.js +3 -1
- package/lib/module/extraction/extractTarBz2.js.map +1 -0
- package/lib/module/{download → extraction}/extractTarZst.js +3 -1
- package/lib/module/extraction/extractTarZst.js.map +1 -0
- package/lib/module/extraction/index.js +3 -4
- package/lib/module/extraction/index.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/licenses.js +63 -0
- package/lib/module/licenses.js.map +1 -0
- package/lib/module/stt/index.js +16 -2
- package/lib/module/stt/index.js.map +1 -1
- package/lib/module/stt/streaming.js +2 -0
- package/lib/module/stt/streaming.js.map +1 -1
- package/lib/module/stt/streamingTypes.js.map +1 -1
- package/lib/module/stt/types.js.map +1 -1
- package/lib/module/tts/index.js +21 -3
- package/lib/module/tts/index.js.map +1 -1
- package/lib/module/tts/streaming.js +5 -1
- package/lib/module/tts/streaming.js.map +1 -1
- package/lib/module/tts/types.js +4 -1
- package/lib/module/tts/types.js.map +1 -1
- package/lib/module/utils.js +16 -1
- package/lib/module/utils.js.map +1 -1
- package/lib/typescript/src/NativeSherpaOnnx.d.ts +34 -6
- package/lib/typescript/src/NativeSherpaOnnx.d.ts.map +1 -1
- package/lib/typescript/src/audio/index.d.ts +10 -0
- package/lib/typescript/src/audio/index.d.ts.map +1 -1
- package/lib/typescript/src/download/ModelDownloadManager.d.ts +11 -108
- package/lib/typescript/src/download/ModelDownloadManager.d.ts.map +1 -1
- package/lib/typescript/src/download/activeModelOperations.d.ts +6 -0
- package/lib/typescript/src/download/activeModelOperations.d.ts.map +1 -0
- package/lib/typescript/src/download/background-downloader-types.d.ts +64 -0
- package/lib/typescript/src/download/background-downloader-types.d.ts.map +1 -0
- package/lib/typescript/src/download/bulkPurge.d.ts +14 -0
- package/lib/typescript/src/download/bulkPurge.d.ts.map +1 -0
- package/lib/typescript/src/download/checksumPrompt.d.ts +3 -0
- package/lib/typescript/src/download/checksumPrompt.d.ts.map +1 -0
- package/lib/typescript/src/download/constants.d.ts +5 -0
- package/lib/typescript/src/download/constants.d.ts.map +1 -0
- package/lib/typescript/src/download/downloadEvents.d.ts +6 -0
- package/lib/typescript/src/download/downloadEvents.d.ts.map +1 -0
- package/lib/typescript/src/download/downloadTask.d.ts +30 -0
- package/lib/typescript/src/download/downloadTask.d.ts.map +1 -0
- package/lib/typescript/src/download/ensureModel.d.ts +26 -0
- package/lib/typescript/src/download/ensureModel.d.ts.map +1 -0
- package/lib/typescript/src/download/index.d.ts +7 -7
- package/lib/typescript/src/download/index.d.ts.map +1 -1
- package/lib/typescript/src/download/localModels.d.ts +15 -0
- package/lib/typescript/src/download/localModels.d.ts.map +1 -0
- package/lib/typescript/src/download/modelExtraction.d.ts +36 -0
- package/lib/typescript/src/download/modelExtraction.d.ts.map +1 -0
- package/lib/typescript/src/download/paths.d.ts +28 -0
- package/lib/typescript/src/download/paths.d.ts.map +1 -0
- package/lib/typescript/src/download/postDownloadProcessing.d.ts +19 -0
- package/lib/typescript/src/download/postDownloadProcessing.d.ts.map +1 -0
- package/lib/typescript/src/download/protectedModelKeys.d.ts +6 -0
- package/lib/typescript/src/download/protectedModelKeys.d.ts.map +1 -0
- package/lib/typescript/src/download/registry.d.ts +14 -0
- package/lib/typescript/src/download/registry.d.ts.map +1 -0
- package/lib/typescript/src/download/retry.d.ts +15 -0
- package/lib/typescript/src/download/retry.d.ts.map +1 -0
- package/lib/typescript/src/download/types.d.ts +96 -0
- package/lib/typescript/src/download/types.d.ts.map +1 -0
- package/lib/typescript/src/download/validation.d.ts +19 -0
- package/lib/typescript/src/download/validation.d.ts.map +1 -1
- package/lib/typescript/src/extraction/extractTarBz2.d.ts.map +1 -0
- package/lib/typescript/src/extraction/extractTarZst.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/licenses.d.ts +10 -0
- package/lib/typescript/src/licenses.d.ts.map +1 -0
- package/lib/typescript/src/stt/index.d.ts +4 -1
- package/lib/typescript/src/stt/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 +5 -0
- package/lib/typescript/src/stt/streamingTypes.d.ts.map +1 -1
- package/lib/typescript/src/stt/types.d.ts +3 -1
- package/lib/typescript/src/stt/types.d.ts.map +1 -1
- package/lib/typescript/src/tts/index.d.ts +4 -2
- package/lib/typescript/src/tts/index.d.ts.map +1 -1
- package/lib/typescript/src/tts/streaming.d.ts.map +1 -1
- package/lib/typescript/src/tts/types.d.ts +12 -6
- package/lib/typescript/src/tts/types.d.ts.map +1 -1
- package/lib/typescript/src/utils.d.ts +5 -0
- package/lib/typescript/src/utils.d.ts.map +1 -1
- package/package.json +6 -1
- package/scripts/{check-model-csvs.sh → ci/check-model-csvs.sh} +9 -2
- package/scripts/ci/collect_all_sherpa_model_streams.sh +101 -0
- package/scripts/ci/collect_one_sherpa_release_stream.sh +189 -0
- package/scripts/ci/sherpa_asr_model_release_streams.json +21 -0
- package/scripts/ci/sherpa_tts_model_release_streams.json +13 -0
- package/scripts/ci/update_model_license_csv.sh +765 -0
- package/scripts/setup-ios-framework.sh +14 -11
- package/scripts/update_commercial_use.js +73 -0
- package/src/NativeSherpaOnnx.ts +37 -6
- package/src/audio/index.ts +20 -0
- package/src/download/ModelDownloadManager.ts +57 -1343
- package/src/download/activeModelOperations.ts +38 -0
- package/src/download/background-downloader-types.ts +73 -0
- package/src/download/bulkPurge.ts +102 -0
- package/src/download/checksumPrompt.ts +25 -0
- package/src/download/constants.ts +5 -0
- package/src/download/downloadEvents.ts +55 -0
- package/src/download/downloadTask.ts +565 -0
- package/src/download/ensureModel.ts +124 -0
- package/src/download/index.ts +21 -4
- package/src/download/localModels.ts +234 -0
- package/src/download/modelExtraction.ts +244 -0
- package/src/download/paths.ts +134 -0
- package/src/download/postDownloadProcessing.ts +292 -0
- package/src/download/protectedModelKeys.ts +30 -0
- package/src/download/registry.ts +405 -0
- package/src/download/retry.ts +76 -0
- package/src/download/types.ts +120 -0
- package/src/download/validation.ts +114 -8
- package/src/{download → extraction}/extractTarBz2.ts +3 -1
- package/src/{download → extraction}/extractTarZst.ts +3 -1
- package/src/extraction/index.ts +3 -7
- package/src/index.tsx +1 -0
- package/src/licenses.ts +100 -0
- package/src/stt/index.ts +20 -2
- package/src/stt/streaming.ts +3 -0
- package/src/stt/streamingTypes.ts +5 -0
- package/src/stt/types.ts +3 -1
- package/src/tts/index.ts +33 -2
- package/src/tts/streaming.ts +12 -0
- package/src/tts/types.ts +15 -5
- package/src/utils.ts +22 -1
- package/third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG +1 -1
- package/third_party/sherpa-onnx-prebuilt/IOS_RELEASE_TAG +1 -1
- package/android/src/main/cpp/jni/tts/sherpa-onnx-tts-zipvoice-jni.cpp +0 -301
- package/android/src/main/java/com/sherpaonnx/ZipvoiceTtsWrapper.kt +0 -187
- package/lib/module/download/extractTarBz2.js.map +0 -1
- package/lib/module/download/extractTarZst.js.map +0 -1
- package/lib/typescript/src/download/extractTarBz2.d.ts.map +0 -1
- package/lib/typescript/src/download/extractTarZst.d.ts.map +0 -1
- package/scripts/check-qnn-support.sh +0 -78
- /package/lib/typescript/src/{download → extraction}/extractTarBz2.d.ts +0 -0
- /package/lib/typescript/src/{download → extraction}/extractTarZst.d.ts +0 -0
|
@@ -4,6 +4,7 @@ import android.content.Context
|
|
|
4
4
|
import android.util.Log
|
|
5
5
|
import com.facebook.react.bridge.Arguments
|
|
6
6
|
import com.facebook.react.bridge.Promise
|
|
7
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
7
8
|
import java.util.concurrent.ExecutorService
|
|
8
9
|
import java.util.concurrent.Executors
|
|
9
10
|
import java.util.concurrent.atomic.AtomicBoolean
|
|
@@ -13,11 +14,12 @@ import java.util.concurrent.atomic.AtomicBoolean
|
|
|
13
14
|
* This class delegates to C++ native implementation via JNI.
|
|
14
15
|
*/
|
|
15
16
|
class SherpaOnnxArchiveHelper {
|
|
16
|
-
private val cancelRequested = AtomicBoolean(false)
|
|
17
|
-
|
|
18
17
|
companion object {
|
|
19
|
-
/**
|
|
20
|
-
private val extractExecutor: ExecutorService = Executors.
|
|
18
|
+
/** Thread pool for extractions – allows up to 2 concurrent extractions while keeping them off the React Native bridge thread. */
|
|
19
|
+
private val extractExecutor: ExecutorService = Executors.newFixedThreadPool(2)
|
|
20
|
+
|
|
21
|
+
/** Per-source-path cancellation flags. Key = absolute source archive path. */
|
|
22
|
+
private val cancelFlags = ConcurrentHashMap<String, AtomicBoolean>()
|
|
21
23
|
|
|
22
24
|
init {
|
|
23
25
|
try {
|
|
@@ -29,15 +31,24 @@ class SherpaOnnxArchiveHelper {
|
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
fun cancelExtractTarBz2() {
|
|
32
|
-
|
|
34
|
+
// Cancel ALL ongoing extractions (legacy global cancel)
|
|
35
|
+
for (flag in cancelFlags.values) flag.set(true)
|
|
33
36
|
nativeCancelExtract()
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
fun cancelExtractTarZst() {
|
|
37
|
-
|
|
40
|
+
// Cancel ALL ongoing extractions (legacy global cancel)
|
|
41
|
+
for (flag in cancelFlags.values) flag.set(true)
|
|
38
42
|
nativeCancelExtract()
|
|
39
43
|
}
|
|
40
44
|
|
|
45
|
+
/** Cancel a specific extraction identified by its source archive path. */
|
|
46
|
+
fun cancelExtractBySourcePath(sourcePath: String) {
|
|
47
|
+
// Only set the per-path flag; do not call nativeCancelExtract() since that is
|
|
48
|
+
// a global cancel that would also interrupt unrelated concurrent extractions.
|
|
49
|
+
cancelFlags[sourcePath]?.set(true)
|
|
50
|
+
}
|
|
51
|
+
|
|
41
52
|
fun extractTarBz2(
|
|
42
53
|
sourcePath: String,
|
|
43
54
|
targetPath: String,
|
|
@@ -55,7 +66,9 @@ class SherpaOnnxArchiveHelper {
|
|
|
55
66
|
}
|
|
56
67
|
|
|
57
68
|
try {
|
|
58
|
-
|
|
69
|
+
// Register per-path cancel flag
|
|
70
|
+
val cancelFlag = AtomicBoolean(false)
|
|
71
|
+
cancelFlags[sourcePath] = cancelFlag
|
|
59
72
|
|
|
60
73
|
// Create a progress callback object that JNI can call
|
|
61
74
|
val progressCallback = object : Any() {
|
|
@@ -65,15 +78,23 @@ class SherpaOnnxArchiveHelper {
|
|
|
65
78
|
}
|
|
66
79
|
|
|
67
80
|
// Run extraction on a background thread so the React Native bridge thread is not blocked.
|
|
68
|
-
//
|
|
81
|
+
// The thread pool allows multiple extractions in parallel.
|
|
69
82
|
extractExecutor.execute {
|
|
70
83
|
try {
|
|
84
|
+
// Check per-path cancel flag before starting the native extraction.
|
|
85
|
+
if (cancelFlag.get()) {
|
|
86
|
+
resolveOnce(false, "Cancelled")
|
|
87
|
+
return@execute
|
|
88
|
+
}
|
|
71
89
|
nativeExtractTarBz2(sourcePath, targetPath, force, progressCallback, promise)
|
|
72
90
|
} catch (e: Exception) {
|
|
73
91
|
resolveOnce(false, "Archive extraction error: ${e.message}")
|
|
92
|
+
} finally {
|
|
93
|
+
cancelFlags.remove(sourcePath)
|
|
74
94
|
}
|
|
75
95
|
}
|
|
76
96
|
} catch (e: Exception) {
|
|
97
|
+
cancelFlags.remove(sourcePath)
|
|
77
98
|
resolveOnce(false, "Archive extraction error: ${e.message}")
|
|
78
99
|
}
|
|
79
100
|
}
|
|
@@ -95,7 +116,9 @@ class SherpaOnnxArchiveHelper {
|
|
|
95
116
|
}
|
|
96
117
|
|
|
97
118
|
try {
|
|
98
|
-
|
|
119
|
+
val cancelFlag = AtomicBoolean(false)
|
|
120
|
+
cancelFlags[sourcePath] = cancelFlag
|
|
121
|
+
|
|
99
122
|
val progressCallback = object : Any() {
|
|
100
123
|
fun invoke(bytesExtracted: Long, totalBytes: Long, percent: Double) {
|
|
101
124
|
onProgress(bytesExtracted, totalBytes, percent)
|
|
@@ -103,12 +126,20 @@ class SherpaOnnxArchiveHelper {
|
|
|
103
126
|
}
|
|
104
127
|
extractExecutor.execute {
|
|
105
128
|
try {
|
|
129
|
+
// Check per-path cancel flag before starting the native extraction.
|
|
130
|
+
if (cancelFlag.get()) {
|
|
131
|
+
resolveOnce(false, "Cancelled")
|
|
132
|
+
return@execute
|
|
133
|
+
}
|
|
106
134
|
nativeExtractTarZst(sourcePath, targetPath, force, progressCallback, promise)
|
|
107
135
|
} catch (e: Exception) {
|
|
108
136
|
resolveOnce(false, "Archive extraction error: ${e.message}")
|
|
137
|
+
} finally {
|
|
138
|
+
cancelFlags.remove(sourcePath)
|
|
109
139
|
}
|
|
110
140
|
}
|
|
111
141
|
} catch (e: Exception) {
|
|
142
|
+
cancelFlags.remove(sourcePath)
|
|
112
143
|
resolveOnce(false, "Archive extraction error: ${e.message}")
|
|
113
144
|
}
|
|
114
145
|
}
|
|
@@ -124,7 +155,6 @@ class SherpaOnnxArchiveHelper {
|
|
|
124
155
|
if (BuildConfig.DEBUG) {
|
|
125
156
|
Log.i("SherpaOnnx", "extractTarZstFromAsset assetPath=$assetPath targetPath=$targetPath")
|
|
126
157
|
}
|
|
127
|
-
cancelRequested.set(false)
|
|
128
158
|
val progressCallback = object : Any() {
|
|
129
159
|
fun invoke(bytesExtracted: Long, totalBytes: Long, percent: Double) {
|
|
130
160
|
onProgress(bytesExtracted, totalBytes, percent)
|
|
@@ -8,6 +8,7 @@ import com.facebook.react.bridge.ReadableMap
|
|
|
8
8
|
import com.facebook.react.bridge.Arguments
|
|
9
9
|
import com.facebook.react.module.annotations.ReactModule
|
|
10
10
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
11
|
+
import com.k2fsa.sherpa.onnx.WaveReader
|
|
11
12
|
|
|
12
13
|
@ReactModule(name = SherpaOnnxModule.NAME)
|
|
13
14
|
class SherpaOnnxModule(reactContext: ReactApplicationContext) :
|
|
@@ -314,6 +315,11 @@ class SherpaOnnxModule(reactContext: ReactApplicationContext) :
|
|
|
314
315
|
promise.resolve(null)
|
|
315
316
|
}
|
|
316
317
|
|
|
318
|
+
override fun cancelExtractBySourcePath(sourcePath: String, promise: Promise) {
|
|
319
|
+
archiveHelper.cancelExtractBySourcePath(sourcePath)
|
|
320
|
+
promise.resolve(null)
|
|
321
|
+
}
|
|
322
|
+
|
|
317
323
|
override fun computeFileSha256(filePath: String, promise: Promise) {
|
|
318
324
|
archiveHelper.computeFileSha256(filePath, promise)
|
|
319
325
|
}
|
|
@@ -452,6 +458,7 @@ class SherpaOnnxModule(reactContext: ReactApplicationContext) :
|
|
|
452
458
|
val provider = if (options.hasKey("provider")) options.getString("provider") else null
|
|
453
459
|
val ruleFsts = if (options.hasKey("ruleFsts")) options.getString("ruleFsts") else null
|
|
454
460
|
val ruleFars = if (options.hasKey("ruleFars")) options.getString("ruleFars") else null
|
|
461
|
+
val dither = if (options.hasKey("dither")) options.getDouble("dither") else null
|
|
455
462
|
val blankPenalty = if (options.hasKey("blankPenalty")) options.getDouble("blankPenalty") else null
|
|
456
463
|
val debug = if (options.hasKey("debug")) options.getBoolean("debug") else null
|
|
457
464
|
val rule1MustContainNonSilence = if (options.hasKey("rule1MustContainNonSilence")) options.getBoolean("rule1MustContainNonSilence") else null
|
|
@@ -476,6 +483,7 @@ class SherpaOnnxModule(reactContext: ReactApplicationContext) :
|
|
|
476
483
|
provider,
|
|
477
484
|
ruleFsts,
|
|
478
485
|
ruleFars,
|
|
486
|
+
dither,
|
|
479
487
|
blankPenalty,
|
|
480
488
|
debug,
|
|
481
489
|
rule1MustContainNonSilence,
|
|
@@ -712,6 +720,72 @@ class SherpaOnnxModule(reactContext: ReactApplicationContext) :
|
|
|
712
720
|
}
|
|
713
721
|
}
|
|
714
722
|
|
|
723
|
+
/**
|
|
724
|
+
* Decode audio to mono float samples (approx. [-1, 1]) and effective sample rate.
|
|
725
|
+
* Same path/URI handling as [convertAudioToFormat]. WAV may use [WaveReader] when no resample is requested.
|
|
726
|
+
*/
|
|
727
|
+
override fun decodeAudioFileToFloatSamples(inputPath: String, targetSampleRateHz: Double?, promise: Promise) {
|
|
728
|
+
var tmpFile: java.io.File? = null
|
|
729
|
+
try {
|
|
730
|
+
val targetHz = (targetSampleRateHz ?: 0.0).toInt()
|
|
731
|
+
if (targetHz < 0) {
|
|
732
|
+
promise.reject("DECODE_ERROR", "targetSampleRateHz must be >= 0")
|
|
733
|
+
return
|
|
734
|
+
}
|
|
735
|
+
val (pathToUse, tmp) = resolveInputForConvert(inputPath)
|
|
736
|
+
tmpFile = tmp
|
|
737
|
+
|
|
738
|
+
if (pathToUse.endsWith(".wav", ignoreCase = true)) {
|
|
739
|
+
try {
|
|
740
|
+
val wave = WaveReader.readWave(pathToUse)
|
|
741
|
+
val s = wave.samples
|
|
742
|
+
if (s != null && s.isNotEmpty() && wave.sampleRate > 0 && (targetHz == 0 || targetHz == wave.sampleRate)) {
|
|
743
|
+
val map = Arguments.createMap()
|
|
744
|
+
val arr = Arguments.createArray()
|
|
745
|
+
for (i in s.indices) {
|
|
746
|
+
arr.pushDouble(s[i].toDouble())
|
|
747
|
+
}
|
|
748
|
+
map.putArray("samples", arr)
|
|
749
|
+
map.putInt("sampleRate", wave.sampleRate)
|
|
750
|
+
promise.resolve(map)
|
|
751
|
+
return
|
|
752
|
+
}
|
|
753
|
+
} catch (_: Throwable) {
|
|
754
|
+
// Fall through to FFmpeg/native path (e.g. odd WAV or resample requested).
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
val result = Companion.nativeDecodeAudioFileToFloatSamples(pathToUse, targetHz)
|
|
759
|
+
if (result.size == 1 && result[0] is String) {
|
|
760
|
+
promise.reject("DECODE_ERROR", result[0] as String)
|
|
761
|
+
return
|
|
762
|
+
}
|
|
763
|
+
if (result.size != 2 || result[0] !is FloatArray) {
|
|
764
|
+
promise.reject("DECODE_ERROR", "Unexpected native decode result")
|
|
765
|
+
return
|
|
766
|
+
}
|
|
767
|
+
val floats = result[0] as FloatArray
|
|
768
|
+
val rateObj = result.getOrNull(1) as? Number ?: run {
|
|
769
|
+
promise.reject("DECODE_ERROR", "Unexpected sample rate in native decode result")
|
|
770
|
+
return
|
|
771
|
+
}
|
|
772
|
+
val sr = rateObj.toInt()
|
|
773
|
+
val map = Arguments.createMap()
|
|
774
|
+
val arr = Arguments.createArray()
|
|
775
|
+
for (i in floats.indices) {
|
|
776
|
+
arr.pushDouble(floats[i].toDouble())
|
|
777
|
+
}
|
|
778
|
+
map.putArray("samples", arr)
|
|
779
|
+
map.putInt("sampleRate", sr)
|
|
780
|
+
promise.resolve(map)
|
|
781
|
+
} catch (e: Exception) {
|
|
782
|
+
android.util.Log.e(NAME, "DECODE_EXCEPTION: ${e.message}", e)
|
|
783
|
+
promise.reject("DECODE_EXCEPTION", e.message ?: "Failed to decode audio", e)
|
|
784
|
+
} finally {
|
|
785
|
+
tmpFile?.delete()
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
|
|
715
789
|
// ==================== TTS Methods ====================
|
|
716
790
|
|
|
717
791
|
/**
|
|
@@ -1057,6 +1131,25 @@ class SherpaOnnxModule(reactContext: ReactApplicationContext) :
|
|
|
1057
1131
|
}
|
|
1058
1132
|
}
|
|
1059
1133
|
|
|
1134
|
+
override fun readAssetFileAsUtf8(assetPath: String, promise: Promise) {
|
|
1135
|
+
// Validate assetPath to prevent path traversal: reject paths containing
|
|
1136
|
+
// "..", starting with "/" or "\", or containing backslashes.
|
|
1137
|
+
if (assetPath.contains("..") ||
|
|
1138
|
+
assetPath.startsWith("/") ||
|
|
1139
|
+
assetPath.startsWith("\\") ||
|
|
1140
|
+
assetPath.contains("\\")) {
|
|
1141
|
+
promise.reject("ASSET_READ_ERROR", "Invalid asset path: $assetPath")
|
|
1142
|
+
return
|
|
1143
|
+
}
|
|
1144
|
+
try {
|
|
1145
|
+
val content = reactApplicationContext.assets.open(assetPath).bufferedReader().use { it.readText() }
|
|
1146
|
+
promise.resolve(content)
|
|
1147
|
+
} catch (e: Exception) {
|
|
1148
|
+
android.util.Log.e(NAME, "Failed to read asset $assetPath: ${e.message}", e)
|
|
1149
|
+
promise.reject("ASSET_READ_ERROR", "Failed to read asset $assetPath: ${e.message}", e)
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1060
1153
|
companion object {
|
|
1061
1154
|
const val NAME = "SherpaOnnx"
|
|
1062
1155
|
|
|
@@ -1099,5 +1192,11 @@ class SherpaOnnxModule(reactContext: ReactApplicationContext) :
|
|
|
1099
1192
|
/** Convert any supported audio file to WAV 16 kHz mono 16-bit PCM. Returns empty string on success, error message otherwise. Requires FFmpeg prebuilts. */
|
|
1100
1193
|
@JvmStatic
|
|
1101
1194
|
private external fun nativeConvertAudioToWav16k(inputPath: String, outputPath: String): String
|
|
1195
|
+
|
|
1196
|
+
/**
|
|
1197
|
+
* On success: [FloatArray samples, Integer sampleRate]. On error: [String message].
|
|
1198
|
+
*/
|
|
1199
|
+
@JvmStatic
|
|
1200
|
+
private external fun nativeDecodeAudioFileToFloatSamples(inputPath: String, targetSampleRateHz: Int): Array<Any>
|
|
1102
1201
|
}
|
|
1103
1202
|
}
|
|
@@ -132,6 +132,7 @@ internal class SherpaOnnxOnlineSttHelper(
|
|
|
132
132
|
provider: String?,
|
|
133
133
|
ruleFsts: String?,
|
|
134
134
|
ruleFars: String?,
|
|
135
|
+
dither: Float?,
|
|
135
136
|
blankPenalty: Float?,
|
|
136
137
|
debug: Boolean?,
|
|
137
138
|
rule1MustContainNonSilence: Boolean?,
|
|
@@ -233,7 +234,7 @@ internal class SherpaOnnxOnlineSttHelper(
|
|
|
233
234
|
}
|
|
234
235
|
|
|
235
236
|
return OnlineRecognizerConfig(
|
|
236
|
-
featConfig = FeatureConfig(sampleRate = 16000, featureDim = 80, dither = 0f),
|
|
237
|
+
featConfig = FeatureConfig(sampleRate = 16000, featureDim = 80, dither = dither ?: 0f),
|
|
237
238
|
modelConfig = modelConfig,
|
|
238
239
|
endpointConfig = endpointConfig,
|
|
239
240
|
enableEndpoint = enableEndpoint,
|
|
@@ -260,6 +261,7 @@ internal class SherpaOnnxOnlineSttHelper(
|
|
|
260
261
|
provider: String?,
|
|
261
262
|
ruleFsts: String?,
|
|
262
263
|
ruleFars: String?,
|
|
264
|
+
dither: Double?,
|
|
263
265
|
blankPenalty: Double?,
|
|
264
266
|
debug: Boolean?,
|
|
265
267
|
rule1MustContainNonSilence: Boolean?,
|
|
@@ -286,6 +288,7 @@ internal class SherpaOnnxOnlineSttHelper(
|
|
|
286
288
|
provider = provider,
|
|
287
289
|
ruleFsts = ruleFsts,
|
|
288
290
|
ruleFars = ruleFars,
|
|
291
|
+
dither = dither?.toFloat(),
|
|
289
292
|
blankPenalty = blankPenalty?.toFloat(),
|
|
290
293
|
debug = debug,
|
|
291
294
|
rule1MustContainNonSilence = rule1MustContainNonSilence,
|