react-native-sherpa-onnx 0.3.8 → 0.4.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 (134) hide show
  1. package/README.md +20 -5
  2. package/SherpaOnnx.podspec +5 -1
  3. package/android/prebuilt-download.gradle +89 -49
  4. package/android/prebuilt-versions.gradle +1 -1
  5. package/android/src/main/assets/model_licenses/asr-models-license-status.csv +1 -0
  6. package/android/src/main/assets/model_licenses/speech-enhancement-models-license-status.csv +7 -0
  7. package/android/src/main/cpp/CMakeLists.txt +3 -0
  8. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-enhancement-wrapper.cpp +68 -0
  9. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-enhancement-wrapper.h +17 -0
  10. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-enhancement.cpp +119 -0
  11. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.cpp +23 -0
  12. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.h +9 -0
  13. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-stt.cpp +51 -8
  14. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect.h +41 -0
  15. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-stt-wrapper.cpp +5 -0
  16. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-validate-enhancement.cpp +68 -0
  17. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-validate-enhancement.h +30 -0
  18. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-validate-stt.cpp +11 -0
  19. package/android/src/main/cpp/jni/module/sherpa-onnx-module-jni.cpp +21 -0
  20. package/android/src/main/java/com/sherpaonnx/SherpaOnnxArchiveHelper.kt +110 -35
  21. package/android/src/main/java/com/sherpaonnx/SherpaOnnxAssetHelper.kt +6 -0
  22. package/android/src/main/java/com/sherpaonnx/SherpaOnnxEnhancementHelper.kt +377 -0
  23. package/android/src/main/java/com/sherpaonnx/SherpaOnnxExtractionNotificationHelper.kt +102 -0
  24. package/android/src/main/java/com/sherpaonnx/SherpaOnnxModule.kt +198 -18
  25. package/android/src/main/java/com/sherpaonnx/SherpaOnnxSttHelper.kt +22 -0
  26. package/ios/Resources/model_licenses/asr-models-license-status.csv +1 -0
  27. package/ios/Resources/model_licenses/speech-enhancement-models-license-status.csv +7 -0
  28. package/ios/SherpaOnnx+Assets.mm +5 -0
  29. package/ios/SherpaOnnx+Enhancement.mm +435 -0
  30. package/ios/SherpaOnnx+STT.mm +13 -1
  31. package/ios/SherpaOnnx.mm +87 -17
  32. package/ios/enhancement/sherpa-onnx-enhancement-wrapper.h +85 -0
  33. package/ios/enhancement/sherpa-onnx-enhancement-wrapper.mm +218 -0
  34. package/ios/model_detect/sherpa-onnx-model-detect-enhancement.mm +92 -0
  35. package/ios/model_detect/sherpa-onnx-model-detect-helper.h +5 -0
  36. package/ios/model_detect/sherpa-onnx-model-detect-helper.mm +23 -0
  37. package/ios/model_detect/sherpa-onnx-model-detect-stt.mm +51 -7
  38. package/ios/model_detect/sherpa-onnx-model-detect.h +33 -0
  39. package/ios/model_detect/sherpa-onnx-validate-enhancement.h +30 -0
  40. package/ios/model_detect/sherpa-onnx-validate-enhancement.mm +69 -0
  41. package/ios/model_detect/sherpa-onnx-validate-stt.mm +11 -0
  42. package/ios/stt/sherpa-onnx-stt-wrapper.h +11 -1
  43. package/ios/stt/sherpa-onnx-stt-wrapper.mm +30 -2
  44. package/ios/tts/sherpa-onnx-tts-wrapper.mm +16 -0
  45. package/lib/module/NativeSherpaOnnx.js.map +1 -1
  46. package/lib/module/download/localModels.js +2 -3
  47. package/lib/module/download/localModels.js.map +1 -1
  48. package/lib/module/download/paths.js +2 -1
  49. package/lib/module/download/paths.js.map +1 -1
  50. package/lib/module/download/postDownloadProcessing.js +17 -4
  51. package/lib/module/download/postDownloadProcessing.js.map +1 -1
  52. package/lib/module/enhancement/index.js +63 -48
  53. package/lib/module/enhancement/index.js.map +1 -1
  54. package/lib/module/enhancement/streaming.js +60 -0
  55. package/lib/module/enhancement/streaming.js.map +1 -0
  56. package/lib/module/enhancement/streamingTypes.js +4 -0
  57. package/lib/module/enhancement/streamingTypes.js.map +1 -0
  58. package/lib/module/enhancement/types.js +4 -0
  59. package/lib/module/enhancement/types.js.map +1 -0
  60. package/lib/module/extraction/extractTarBz2.js +2 -2
  61. package/lib/module/extraction/extractTarBz2.js.map +1 -1
  62. package/lib/module/extraction/extractTarZst.js +2 -2
  63. package/lib/module/extraction/extractTarZst.js.map +1 -1
  64. package/lib/module/extraction/index.js +10 -5
  65. package/lib/module/extraction/index.js.map +1 -1
  66. package/lib/module/licenses.js +9 -3
  67. package/lib/module/licenses.js.map +1 -1
  68. package/lib/module/stt/index.js +4 -2
  69. package/lib/module/stt/index.js.map +1 -1
  70. package/lib/module/stt/streaming.js +2 -1
  71. package/lib/module/stt/streaming.js.map +1 -1
  72. package/lib/module/stt/types.js +3 -1
  73. package/lib/module/stt/types.js.map +1 -1
  74. package/lib/module/tts/index.js +4 -2
  75. package/lib/module/tts/index.js.map +1 -1
  76. package/lib/module/tts/streaming.js +3 -1
  77. package/lib/module/tts/streaming.js.map +1 -1
  78. package/lib/typescript/src/NativeSherpaOnnx.d.ts +70 -9
  79. package/lib/typescript/src/NativeSherpaOnnx.d.ts.map +1 -1
  80. package/lib/typescript/src/download/localModels.d.ts.map +1 -1
  81. package/lib/typescript/src/download/paths.d.ts +2 -1
  82. package/lib/typescript/src/download/paths.d.ts.map +1 -1
  83. package/lib/typescript/src/download/postDownloadProcessing.d.ts +9 -0
  84. package/lib/typescript/src/download/postDownloadProcessing.d.ts.map +1 -1
  85. package/lib/typescript/src/enhancement/index.d.ts +9 -46
  86. package/lib/typescript/src/enhancement/index.d.ts.map +1 -1
  87. package/lib/typescript/src/enhancement/streaming.d.ts +6 -0
  88. package/lib/typescript/src/enhancement/streaming.d.ts.map +1 -0
  89. package/lib/typescript/src/enhancement/streamingTypes.d.ts +12 -0
  90. package/lib/typescript/src/enhancement/streamingTypes.d.ts.map +1 -0
  91. package/lib/typescript/src/enhancement/types.d.ts +31 -0
  92. package/lib/typescript/src/enhancement/types.d.ts.map +1 -0
  93. package/lib/typescript/src/extraction/extractTarBz2.d.ts +2 -1
  94. package/lib/typescript/src/extraction/extractTarBz2.d.ts.map +1 -1
  95. package/lib/typescript/src/extraction/extractTarZst.d.ts +2 -1
  96. package/lib/typescript/src/extraction/extractTarZst.d.ts.map +1 -1
  97. package/lib/typescript/src/extraction/index.d.ts +1 -1
  98. package/lib/typescript/src/extraction/index.d.ts.map +1 -1
  99. package/lib/typescript/src/extraction/types.d.ts +12 -0
  100. package/lib/typescript/src/extraction/types.d.ts.map +1 -1
  101. package/lib/typescript/src/licenses.d.ts.map +1 -1
  102. package/lib/typescript/src/stt/index.d.ts +1 -1
  103. package/lib/typescript/src/stt/index.d.ts.map +1 -1
  104. package/lib/typescript/src/stt/streaming.d.ts.map +1 -1
  105. package/lib/typescript/src/stt/types.d.ts +16 -1
  106. package/lib/typescript/src/stt/types.d.ts.map +1 -1
  107. package/lib/typescript/src/tts/index.d.ts.map +1 -1
  108. package/lib/typescript/src/tts/streaming.d.ts.map +1 -1
  109. package/package.json +1 -1
  110. package/scripts/ci/check-model-csvs.sh +27 -2
  111. package/scripts/ci/collect_all_sherpa_model_streams.sh +3 -1
  112. package/scripts/ci/collect_one_sherpa_release_stream.sh +3 -1
  113. package/scripts/ci/sherpa_speech_enhancement_model_release_streams.json +13 -0
  114. package/scripts/ci/update_model_license_csv.sh +17 -17
  115. package/src/NativeSherpaOnnx.ts +108 -10
  116. package/src/download/localModels.ts +1 -3
  117. package/src/download/paths.ts +2 -1
  118. package/src/download/postDownloadProcessing.ts +24 -1
  119. package/src/enhancement/index.ts +120 -58
  120. package/src/enhancement/streaming.ts +105 -0
  121. package/src/enhancement/streamingTypes.ts +14 -0
  122. package/src/enhancement/types.ts +36 -0
  123. package/src/extraction/extractTarBz2.ts +7 -2
  124. package/src/extraction/extractTarZst.ts +7 -2
  125. package/src/extraction/index.ts +29 -6
  126. package/src/extraction/types.ts +16 -0
  127. package/src/licenses.ts +13 -2
  128. package/src/stt/index.ts +8 -7
  129. package/src/stt/streaming.ts +7 -1
  130. package/src/stt/types.ts +18 -0
  131. package/src/tts/index.ts +7 -7
  132. package/src/tts/streaming.ts +6 -3
  133. package/third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG +1 -1
  134. package/third_party/sherpa-onnx-prebuilt/IOS_RELEASE_TAG +1 -1
package/README.md CHANGED
@@ -92,6 +92,7 @@ Full step-by-step: [Download manager – Setup (iOS & Android)](docs/download-ma
92
92
  - [Supported Model Types](#supported-model-types)
93
93
  - [Speech-to-Text (STT) Models](#speech-to-text-stt-models)
94
94
  - [Text-to-Speech (TTS) Models](#text-to-speech-tts-models)
95
+ - [Speech Enhancement Models](#speech-enhancement-models)
95
96
  - [Documentation](#documentation)
96
97
  - [Requirements](#requirements)
97
98
  - [Breaking changes (upgrading to 0.3.0)](#breaking-changes-upgrading-to-030)
@@ -108,8 +109,8 @@ Full step-by-step: [Download manager – Setup (iOS & Android)](docs/download-ma
108
109
 
109
110
  | Platform | Version |
110
111
  |----------|---------|
111
- | Android | 1.12.31 |
112
- | iOS | 1.12.31 |
112
+ | Android | 1.12.34 |
113
+ | iOS | 1.12.34 |
113
114
 
114
115
  ## Feature Support
115
116
 
@@ -126,8 +127,8 @@ Full step-by-step: [Download manager – Setup (iOS & Android)](docs/download-ma
126
127
  | Model quantization | ✅ **Supported** | [Model setup](./docs/model-setup.md) | Automatic detection and preference for quantized (int8) models. |
127
128
  | Flexible model loading | ✅ **Supported** | [Model setup](./docs/model-setup.md) | Asset models, file system models, or auto-detection. |
128
129
  | TypeScript | ✅ **Supported** | — | Full type definitions included. |
129
- | Speaker Diarization | Not yet supported | [Diarization](./docs/diarization.md) | Scheduled for release 0.4.0 |
130
- | Speech Enhancement | ❌ Not yet supported | [Enhancement](./docs/enhancement.md) | Scheduled for release 0.5.0 |
130
+ | Speech Enhancement | **Supported** | [Speech Enhancement](./docs/speech-enhancement.md) | API and initialization covered in docs. |
131
+ | Speaker Diarization | ❌ Not yet supported | [Diarization](./docs/diarization.md) | Scheduled for release 0.5.0 |
131
132
  | Source Separation | ❌ Not yet supported | [Separation](./docs/separation.md) | Scheduled for release 0.6.0 |
132
133
  | VAD (Voice Activity Detection) | ❌ Not yet supported | [VAD](./docs/vad.md) | Scheduled for release 0.7.0 |
133
134
 
@@ -148,6 +149,7 @@ Full step-by-step: [Download manager – Setup (iOS & Android)](docs/download-ma
148
149
 
149
150
  | Model Type | `modelType` Value | Description | Download Links |
150
151
  | ------------------------ | ----------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
152
+ | **Auto Detect** | `'auto'` | Automatically detects model layout/type from files in the model folder and picks the best supported STT type. | n/a |
151
153
  | **Zipformer/Transducer** | `'transducer'` | Encoder–decoder–joiner (e.g. icefall). Good balance of speed and accuracy. Folder name should contain **zipformer** or **transducer** for auto-detection. | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/offline-transducer/index.html) |
152
154
  | **LSTM Transducer** | `'transducer'` | Same layout as Zipformer (encoder–decoder–joiner). LSTM-based streaming ASR; detected as transducer. Folder name may contain **lstm**. | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-transducer/lstm-transducer-models.html) |
153
155
  | **Paraformer** | `'paraformer'` | Single-model non-autoregressive ASR; fast and accurate. Detected by `model.onnx`; no folder token required. | [Download](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/offline-paraformer/index.html) |
@@ -172,6 +174,7 @@ For **real-time (streaming) recognition** from a microphone or audio stream, use
172
174
 
173
175
  | Model Type | `modelType` Value | Description | Download Links |
174
176
  | ---------------- | ----------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
177
+ | **Auto Detect** | `'auto'` | Automatically detects the TTS model layout from files in the model folder and selects the matching supported type. | n/a |
175
178
  | **VITS** | `'vits'` | Fast, high-quality TTS (Piper, Coqui, MeloTTS, MMS). Folder name should contain **vits** if used with other voice models. | [Download](https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models) |
176
179
  | **Matcha** | `'matcha'` | High-quality acoustic model + vocoder. Detected by acoustic_model + vocoder; no folder token required. | [Download](https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/matcha.html) |
177
180
  | **Kokoro** | `'kokoro'` | Multi-speaker, multi-language. Folder name should contain **kokoro** (not kitten) for auto-detection. | [Download](https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models) |
@@ -182,6 +185,18 @@ For **real-time (streaming) recognition** from a microphone or audio stream, use
182
185
 
183
186
  For **streaming TTS** (incremental generation, low latency), use `createStreamingTTS()` with supported model types. See [Streaming Text-to-Speech](./docs/tts-streaming.md).
184
187
 
188
+ ### Speech Enhancement Models
189
+
190
+ Speech enhancement improves noisy or degraded speech using ONNX models from the sherpa-onnx **speech-enhancement-models** release. Detection looks for **`.onnx`** filenames containing **`gtcrn`** or **`dpdfnet`** (case-insensitive). With **`'auto'`**, **GTCRN** is preferred when both are present in the same folder.
191
+
192
+ | Model Type | `modelType` Value | Description | Download Links |
193
+ | ------------ | ----------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
194
+ | **Auto Detect** | `'auto'` | Picks **GTCRN** if a matching `.onnx` exists, otherwise **DPDFNet** if found. | n/a |
195
+ | **GTCRN** | `'gtcrn'` | Lightweight speech enhancement (e.g. `gtcrn_simple.onnx`). | [Download](https://github.com/k2-fsa/sherpa-onnx/releases/tag/speech-enhancement-models) |
196
+ | **DPDFNet** | `'dpdfnet'` | Deep speech enhancement variants (e.g. `dpdfnet2.onnx`, `dpdfnet4.onnx`, `dpdfnet8.onnx`, `dpdfnet_baseline.onnx`, `dpdfnet2_48khz_hr.onnx`). | [Download](https://github.com/k2-fsa/sherpa-onnx/releases/tag/speech-enhancement-models) |
197
+
198
+ APIs, batch vs online processing, and initialization are covered in [Speech Enhancement](./docs/speech-enhancement.md).
199
+
185
200
  ## Documentation
186
201
 
187
202
  - [Known issues](./docs/KNOWN_ISSUES.md) – SDK-facing notes (e.g. Pocket TTS cloning / cross-platform behavior)
@@ -193,7 +208,7 @@ For **streaming TTS** (incremental generation, low latency), use `createStreamin
193
208
  - [Execution provider support (QNN, NNAPI, XNNPACK, Core ML)](./docs/execution-providers.md) – Checking and using acceleration backends
194
209
  - [Voice Activity Detection (VAD)](./docs/vad.md)
195
210
  - [Speaker Diarization](./docs/diarization.md)
196
- - [Speech Enhancement](./docs/enhancement.md)
211
+ - [Speech Enhancement](./docs/speech-enhancement.md)
197
212
  - [Source Separation](./docs/separation.md)
198
213
  - [Model Setup](./docs/model-setup.md) – Bundled assets, Play Asset Delivery (PAD), model discovery APIs, and troubleshooting
199
214
  - [Model Download Manager](./docs/download-manager.md)
@@ -94,6 +94,7 @@ Pod::Spec.new do |s|
94
94
  "\"#{pod_root}/ios/model_detect\"",
95
95
  "\"#{pod_root}/ios/stt\"",
96
96
  "\"#{pod_root}/ios/tts\"",
97
+ "\"#{pod_root}/ios/enhancement\"",
97
98
  "\"#{pod_root}/ios/online_stt\"",
98
99
  "\"#{device_headers}\"",
99
100
  "\"#{simulator_headers}\""
@@ -140,7 +141,10 @@ Pod::Spec.new do |s|
140
141
  s.libraries = "c++", "z", "iconv", "bz2"
141
142
 
142
143
  # Per-release-model license metadata (synced from CI; same CSV as android/src/main/assets/model_licenses/).
143
- s.resources = ["ios/Resources/model_licenses/*.csv"]
144
+ # Use resource_bundles so assets are packaged reliably across CocoaPods integration modes.
145
+ s.resource_bundles = {
146
+ "SherpaOnnxResources" => ["ios/Resources/model_licenses/*.csv"]
147
+ }
144
148
 
145
149
  install_modules_dependencies(s)
146
150
  end
@@ -19,10 +19,12 @@ def requiredFfmpegSoFiles = [
19
19
  'libavcodec.so', 'libavformat.so', 'libavutil.so', 'libswresample.so', 'libavfilter.so', 'libshine.so'
20
20
  ]
21
21
  def requiredSherpaOnnxSoFiles = [
22
- 'libsherpa-onnx-jni.so', 'libsherpa-onnx-c-api.so', 'libsherpa-onnx-cxx-api.so', 'libonnxruntime.so'
22
+ 'libsherpa-onnx-jni.so', 'libsherpa-onnx-c-api.so', 'libsherpa-onnx-cxx-api.so'
23
23
  ]
24
24
  def requiredLibarchiveSoFiles = ['libarchive.so', 'libzstd.so']
25
25
  def requiredOnnxruntimeJniSoFiles = ['libonnxruntime4j_jni.so']
26
+ /** Both from the same onnxruntime release (AAR or third_party); required for Java ORT + symbol consistency. */
27
+ def requiredOnnxruntimeBundleSoFiles = ['libonnxruntime4j_jni.so', 'libonnxruntime.so']
26
28
 
27
29
  def jniLibsDir = file("${project.projectDir}/src/main/jniLibs")
28
30
  def sherpaOnnxClassesDir = file("${project.buildDir}/sherpa-onnx-classes")
@@ -79,11 +81,12 @@ def hasLibarchiveHeaders = {
79
81
  return new File(project.projectDir, "src/main/cpp/include/libarchive/archive.h").exists()
80
82
  }
81
83
 
82
- def hasAllOnnxruntimeJniLibs = {
84
+ /** Both ORT .so present per ABI (sherpa-onnx AAR no longer ships libonnxruntime.so). */
85
+ def hasAllOnnxruntimeBundleLibs = {
83
86
  for (abi in requiredAbis) {
84
87
  def dir = new File(jniLibsDir, abi)
85
88
  if (!dir.exists()) return false
86
- for (soName in requiredOnnxruntimeJniSoFiles) {
89
+ for (soName in requiredOnnxruntimeBundleSoFiles) {
87
90
  if (!new File(dir, soName).exists()) return false
88
91
  }
89
92
  }
@@ -163,14 +166,11 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
163
166
  def libarchiveHdrsOk = hasLibarchiveHeaders()
164
167
  def libarchiveNeedsUpdate = !libarchiveLibsOk || !libarchiveHdrsOk || storedLibarchiveVersion == null || storedLibarchiveVersion != currentLibarchiveVersion
165
168
 
166
- def ortJniOk = hasAllOnnxruntimeJniLibs()
167
-
168
169
  println "[prebuilt] Resolution order: (1) THIRD_PARTY (2) LOCAL_SDK (3) MAVEN_AAR (4) GITHUB_RELEASE — see docs/PREBUILT_RESOLUTION.md"
169
170
 
170
171
  def sherpaResolved = false
171
172
  def ffmpegResolved = false
172
173
  def libarchiveResolved = false
173
- def ortJniResolved = ortJniOk
174
174
 
175
175
  // =====================================================================
176
176
  // sherpa-onnx: JNI (.so) + C headers
@@ -222,14 +222,14 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
222
222
  sherpaVersionFile.text = currentSherpaVersion
223
223
  sherpaResolved = true
224
224
  println "[sherpa-onnx] jniLibs (*.so per ABI) .............. MAVEN_AAR ${aar.name}"
225
- println "[sherpa-onnx] install: jni/<abi>/*.so ${jniLibsHuman}/<abi>/"
226
- println "[sherpa-onnx] C headers (sherpa-onnx) ............. ${copiedHeaders ? 'MAVEN_AAR c-api/** ' + includeSherpaDir : 'unchanged (no c-api/ in AAR; existing tree kept)'}"
225
+ println "[sherpa-onnx] install: jni/<abi>/*.so --> ${jniLibsHuman}/<abi>/"
226
+ println "[sherpa-onnx] C headers (sherpa-onnx) ............. ${copiedHeaders ? 'MAVEN_AAR c-api/** --> ' + includeSherpaDir : 'unchanged (no c-api/ in AAR; existing tree kept)'}"
227
227
  println "[sherpa-onnx] version stamp ...................... written ${sherpaVersionFile.name}=${currentSherpaVersion}"
228
228
  } else {
229
- println "[sherpa-onnx] MAVEN_AAR: sherpaOnnxAar empty trying GITHUB_RELEASE"
229
+ println "[sherpa-onnx] MAVEN_AAR: sherpaOnnxAar empty --> trying GITHUB_RELEASE"
230
230
  }
231
231
  } catch (Exception e) {
232
- println "[sherpa-onnx] MAVEN_AAR failed: ${e.message} trying GITHUB_RELEASE"
232
+ println "[sherpa-onnx] MAVEN_AAR failed: ${e.message} --> trying GITHUB_RELEASE"
233
233
  }
234
234
  }
235
235
  } else {
@@ -290,14 +290,14 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
290
290
  ffmpegVersionFile.text = currentFfmpegVersion
291
291
  ffmpegResolved = true
292
292
  println "[FFmpeg] jniLibs .................................. MAVEN_AAR ${aar.name}"
293
- println "[FFmpeg] install: jni/<abi>/*.so ${jniLibsHuman}/<abi>/"
294
- println "[FFmpeg] C headers ................................ ${copiedHdr ? 'MAVEN_AAR include/** ' + ffmpegIncludeDir : 'unchanged (no include/ in AAR)'}"
293
+ println "[FFmpeg] install: jni/<abi>/*.so --> ${jniLibsHuman}/<abi>/"
294
+ println "[FFmpeg] C headers ................................ ${copiedHdr ? 'MAVEN_AAR include/** --> ' + ffmpegIncludeDir : 'unchanged (no include/ in AAR)'}"
295
295
  println "[FFmpeg] version stamp ............................ written ${ffmpegVersionFile.name}=${currentFfmpegVersion}"
296
296
  } else {
297
- println "[FFmpeg] MAVEN_AAR: ffmpegAar empty trying GITHUB_RELEASE"
297
+ println "[FFmpeg] MAVEN_AAR: ffmpegAar empty --> trying GITHUB_RELEASE"
298
298
  }
299
299
  } catch (Exception e) {
300
- println "[FFmpeg] MAVEN_AAR failed: ${e.message} trying GITHUB_RELEASE"
300
+ println "[FFmpeg] MAVEN_AAR failed: ${e.message} --> trying GITHUB_RELEASE"
301
301
  }
302
302
  }
303
303
  } else {
@@ -358,14 +358,14 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
358
358
  libarchiveVersionFile.text = currentLibarchiveVersion
359
359
  libarchiveResolved = true
360
360
  println "[libarchive] jniLibs .............................. MAVEN_AAR ${aar.name}"
361
- println "[libarchive] install: jni/<abi>/*.so ${jniLibsHuman}/<abi>/"
362
- println "[libarchive] C headers ............................ ${copiedHdr ? 'MAVEN_AAR include/** ' + libarchiveIncludeDir : 'unchanged (no include/ in AAR)'}"
361
+ println "[libarchive] install: jni/<abi>/*.so --> ${jniLibsHuman}/<abi>/"
362
+ println "[libarchive] C headers ............................ ${copiedHdr ? 'MAVEN_AAR include/** --> ' + libarchiveIncludeDir : 'unchanged (no include/ in AAR)'}"
363
363
  println "[libarchive] version stamp ........................ written ${libarchiveVersionFile.name}=${currentLibarchiveVersion}"
364
364
  } else {
365
- println "[libarchive] MAVEN_AAR: libarchiveAar empty trying GITHUB_RELEASE"
365
+ println "[libarchive] MAVEN_AAR: libarchiveAar empty --> trying GITHUB_RELEASE"
366
366
  }
367
367
  } catch (Exception e) {
368
- println "[libarchive] MAVEN_AAR failed: ${e.message} trying GITHUB_RELEASE"
368
+ println "[libarchive] MAVEN_AAR failed: ${e.message} --> trying GITHUB_RELEASE"
369
369
  }
370
370
  }
371
371
  } else {
@@ -374,13 +374,55 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
374
374
  }
375
375
 
376
376
  // =====================================================================
377
- // onnxruntime: JNI bridge only (libonnxruntime4j_jni.so)
378
- // libonnxruntime.so comes from sherpa-onnx prebuilts; not extracted here.
377
+ // onnxruntime: libonnxruntime.so + libonnxruntime4j_jni.so (same ORT build)
378
+ //
379
+ // Java OrtEnvironment loads libonnxruntime4j_jni.so, which dlopen's libonnxruntime.so.
380
+ // Sherpa-onnx AAR does not ship libonnxruntime.so; both come from the onnxruntime AAR
381
+ // or a full third_party/onnxruntime_prebuilt/android bundle.
379
382
  // =====================================================================
380
- if (!ortJniOk) {
381
- // Stage 1: THIRD_PARTY
382
- def tpJni = hasAllLibsUnder(thirdPartyOrtDir, requiredOnnxruntimeJniSoFiles)
383
- if (tpJni) {
383
+ def ortMatchedPairCopied = false
384
+ if (hasAllLibsUnder(thirdPartyOrtDir, requiredOnnxruntimeBundleSoFiles)) {
385
+ requiredAbis.each { abi ->
386
+ copy {
387
+ from new File(thirdPartyOrtDir, "jni/${abi}")
388
+ include 'libonnxruntime4j_jni.so', 'libonnxruntime.so'
389
+ into new File(jniLibsDir, abi)
390
+ }
391
+ }
392
+ ortMatchedPairCopied = true
393
+ println "[onnxruntime] libonnxruntime.so + libonnxruntime4j_jni.so (matched pair) .... THIRD_PARTY ${thirdPartyOrtDir}"
394
+ }
395
+ if (!ortMatchedPairCopied) {
396
+ try {
397
+ def aarFiles = project.configurations.onnxruntimeAar.files
398
+ if (!aarFiles.isEmpty()) {
399
+ downloadDir.mkdirs()
400
+ def aar = aarFiles.iterator().next()
401
+ def aarExtractDir = new File(downloadDir, "onnxruntime-aar-extract")
402
+ if (aarExtractDir.exists()) aarExtractDir.deleteDir()
403
+ aarExtractDir.mkdirs()
404
+ copy { from zipTree(aar); into aarExtractDir }
405
+ requiredAbis.each { abi ->
406
+ def aarJniDir = new File(aarExtractDir, "jni/${abi}")
407
+ if (aarJniDir.exists()) {
408
+ copy {
409
+ from aarJniDir
410
+ include 'libonnxruntime4j_jni.so', 'libonnxruntime.so'
411
+ into new File(jniLibsDir, abi)
412
+ }
413
+ }
414
+ }
415
+ ortMatchedPairCopied = true
416
+ println "[onnxruntime] libonnxruntime.so + libonnxruntime4j_jni.so (matched pair) .... MAVEN_AAR ${aar.name}"
417
+ }
418
+ } catch (Exception e) {
419
+ println "[onnxruntime] MAVEN_AAR matched-pair copy failed: ${e.message}"
420
+ }
421
+ }
422
+ if (!ortMatchedPairCopied && !hasAllOnnxruntimeBundleLibs()) {
423
+ // Legacy: third_party with JNI only (incomplete bundle)
424
+ def tpJniOnly = hasAllLibsUnder(thirdPartyOrtDir, requiredOnnxruntimeJniSoFiles)
425
+ if (tpJniOnly) {
384
426
  requiredAbis.each { abi ->
385
427
  copy {
386
428
  from new File(thirdPartyOrtDir, "jni/${abi}")
@@ -388,18 +430,16 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
388
430
  into new File(jniLibsDir, abi)
389
431
  }
390
432
  }
391
- ortJniResolved = true
392
- println "[onnxruntime] libonnxruntime4j_jni.so .......... THIRD_PARTY ${thirdPartyOrtDir}"
433
+ println "[onnxruntime] libonnxruntime4j_jni.so only .... THIRD_PARTY ${thirdPartyOrtDir}"
434
+ println "[onnxruntime] WARN: no libonnxruntime.so in ort third_party — add full bundle or resolve onnxruntime AAR."
393
435
  }
394
-
395
- // Stage 3: MAVEN_AAR
396
- if (!ortJniResolved) {
436
+ if (!hasAllOnnxruntimeBundleLibs()) {
397
437
  try {
398
438
  def aarFiles = project.configurations.onnxruntimeAar.files
399
439
  if (!aarFiles.isEmpty()) {
400
440
  downloadDir.mkdirs()
401
441
  def aar = aarFiles.iterator().next()
402
- def aarExtractDir = new File(downloadDir, "onnxruntime-aar-extract")
442
+ def aarExtractDir = new File(downloadDir, "onnxruntime-aar-extract-jni-only")
403
443
  if (aarExtractDir.exists()) aarExtractDir.deleteDir()
404
444
  aarExtractDir.mkdirs()
405
445
  copy { from zipTree(aar); into aarExtractDir }
@@ -413,18 +453,18 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
413
453
  }
414
454
  }
415
455
  }
416
- ortJniResolved = true
417
- println "[onnxruntime] libonnxruntime4j_jni.so .......... MAVEN_AAR ${aar.name}"
418
- println "[onnxruntime] install: per ABI → ${jniLibsHuman}/<abi>/ (only JNI bridge; libonnxruntime.so from sherpa prebuilts)"
456
+ println "[onnxruntime] libonnxruntime4j_jni.so only .... MAVEN_AAR ${aar.name}"
457
+ println "[onnxruntime] WARN: AAR jni/<abi> missing libonnxruntime.so use a complete onnxruntime AAR."
419
458
  } else {
420
- println "[onnxruntime] MAVEN_AAR: onnxruntimeAar empty — libonnxruntime4j_jni.so still missing"
459
+ println "[onnxruntime] MAVEN_AAR: onnxruntimeAar empty — ORT native libs still missing"
421
460
  }
422
461
  } catch (Exception e) {
423
- println "[onnxruntime] MAVEN_AAR failed: ${e.message}"
462
+ println "[onnxruntime] MAVEN_AAR jni-only failed: ${e.message}"
424
463
  }
425
464
  }
426
- } else {
427
- println "[onnxruntime] libonnxruntime4j_jni.so (per ABI) .... LOCAL_SDK"
465
+ }
466
+ if (!hasAllOnnxruntimeBundleLibs()) {
467
+ println "[onnxruntime] WARN: libonnxruntime.so and/or libonnxruntime4j_jni.so missing after resolution. checkJniLibs will fail; use com.xdcobra.sherpa:onnxruntime or full third_party bundle."
428
468
  }
429
469
 
430
470
  // =====================================================================
@@ -436,7 +476,7 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
436
476
  def needLibarchive = !sherpaOnnxDisableLibarchive && !libarchiveResolved
437
477
  def needSherpa = !sherpaResolved
438
478
  if (needFfmpeg || needLibarchive || needSherpa) {
439
- println "[prebuilt] GITHUB_RELEASE: skipped (no repo). Set -PprebuiltGitHubRepo=owner/repo or git remote origin github.com"
479
+ println "[prebuilt] GITHUB_RELEASE: skipped (no repo). Set -PprebuiltGitHubRepo=owner/repo or git remote origin --> github.com"
440
480
  println "[prebuilt] still need: sherpa=${needSherpa}, ffmpeg=${needFfmpeg}, libarchive=${needLibarchive}"
441
481
  def diag = [
442
482
  "prebuiltGitHubRepo=${project.findProperty('prebuiltGitHubRepo') ?: '(not set)'}",
@@ -492,7 +532,7 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
492
532
  ffmpegVersionFile.text = currentFfmpegVersion
493
533
  println "[FFmpeg] jniLibs + C headers ...................... GITHUB_RELEASE tag=${tag}"
494
534
  println "[FFmpeg] url: ${url}"
495
- println "[FFmpeg] install: <abi>/*.so ${jniLibsHuman}/"
535
+ println "[FFmpeg] install: <abi>/*.so --> ${jniLibsHuman}/"
496
536
  println "[FFmpeg] version stamp .......................... written ${ffmpegVersionFile.name}=${currentFfmpegVersion}"
497
537
  }
498
538
 
@@ -522,7 +562,7 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
522
562
  libarchiveVersionFile.text = currentLibarchiveVersion
523
563
  println "[libarchive] jniLibs + C headers .................. GITHUB_RELEASE tag=${tag}"
524
564
  println "[libarchive] url: ${url}"
525
- println "[libarchive] install: <abi>/*.so ${jniLibsHuman}/"
565
+ println "[libarchive] install: <abi>/*.so --> ${jniLibsHuman}/"
526
566
  println "[libarchive] version stamp ........................ written ${libarchiveVersionFile.name}=${currentLibarchiveVersion}"
527
567
  }
528
568
 
@@ -560,8 +600,8 @@ project.tasks.register("downloadNativeLibsIfNeeded") {
560
600
  sherpaVersionFile.text = currentSherpaVersion
561
601
  println "[sherpa-onnx] jniLibs + C headers ................. GITHUB_RELEASE tag=${tag}"
562
602
  println "[sherpa-onnx] url: ${url}"
563
- println "[sherpa-onnx] install: <abi>/*.so ${jniLibsHuman}/"
564
- println "[sherpa-onnx] classes.jar ......................... ${sherpaJavaJar.exists() ? 'GITHUB_RELEASE ' + sherpaOnnxClassesDir : 'not in zip (use extractSherpaOnnxClasses)'}"
603
+ println "[sherpa-onnx] install: <abi>/*.so --> ${jniLibsHuman}/"
604
+ println "[sherpa-onnx] classes.jar ......................... ${sherpaJavaJar.exists() ? 'GITHUB_RELEASE --> ' + sherpaOnnxClassesDir : 'not in zip (use extractSherpaOnnxClasses)'}"
565
605
  println "[sherpa-onnx] version stamp ...................... written ${sherpaVersionFile.name}=${currentSherpaVersion}"
566
606
  }
567
607
  println ""
@@ -598,10 +638,10 @@ project.tasks.register("checkJniLibs") {
598
638
  }
599
639
  }
600
640
  }
601
- requiredOnnxruntimeJniSoFiles.each { soName ->
641
+ requiredOnnxruntimeBundleSoFiles.each { soName ->
602
642
  def soFile = new File(dir, soName)
603
643
  if (!soFile.exists()) {
604
- throw new RuntimeException("Missing onnxruntime JNI bridge '${soName}' for ABI ${abi}. Ensure Maven com.xdcobra.sherpa:onnxruntime is available.")
644
+ throw new RuntimeException("Missing onnxruntime native library '${soName}' for ABI ${abi}. Ensure Maven com.xdcobra.sherpa:onnxruntime (libonnxruntime.so + libonnxruntime4j_jni.so) resolves.")
605
645
  }
606
646
  }
607
647
  }
@@ -612,7 +652,7 @@ project.afterEvaluate {
612
652
  project.tasks.findByName('preBuild')?.dependsOn(project.tasks.findByName('checkJniLibs'))
613
653
  }
614
654
 
615
- // sherpa-onnx classes.jar: resolution order THIRD_PARTY MAVEN_AAR GITHUB_EXTRACT
655
+ // sherpa-onnx classes.jar: resolution order THIRD_PARTY --> MAVEN_AAR --> GITHUB_EXTRACT
616
656
  def sherpaLocalJar = file("${project.projectDir.parent}/third_party/sherpa-onnx-prebuilt/android/java/classes.jar")
617
657
  def sherpaExtractedJar = file("${project.buildDir}/prebuilt-downloads/sherpa-onnx-extract/java/classes.jar")
618
658
 
@@ -627,7 +667,7 @@ project.tasks.register("extractSherpaOnnxClasses") {
627
667
  copy { from sherpaLocalJar; into sherpaOnnxClassesDir }
628
668
  println "[prebuilt] extractSherpaOnnxClasses"
629
669
  println "[sherpa-onnx] classes.jar (Kotlin API) .......... THIRD_PARTY"
630
- println "[sherpa-onnx] ${sherpaLocalJar.absolutePath} ${sherpaOnnxClassesDir}"
670
+ println "[sherpa-onnx] ${sherpaLocalJar.absolutePath} --> ${sherpaOnnxClassesDir}"
631
671
  return
632
672
  }
633
673
  def aarFiles = project.configurations.sherpaOnnxAar.files
@@ -640,14 +680,14 @@ project.tasks.register("extractSherpaOnnxClasses") {
640
680
  }
641
681
  println "[prebuilt] extractSherpaOnnxClasses"
642
682
  println "[sherpa-onnx] classes.jar (Kotlin API) .......... MAVEN_AAR ${aar.name}"
643
- println "[sherpa-onnx] classes.jar ${sherpaOnnxClassesDir}"
683
+ println "[sherpa-onnx] classes.jar --> ${sherpaOnnxClassesDir}"
644
684
  return
645
685
  }
646
686
  if (sherpaExtractedJar.exists()) {
647
687
  copy { from sherpaExtractedJar; into sherpaOnnxClassesDir }
648
688
  println "[prebuilt] extractSherpaOnnxClasses"
649
689
  println "[sherpa-onnx] classes.jar (Kotlin API) .......... GITHUB_EXTRACT"
650
- println "[sherpa-onnx] ${sherpaExtractedJar.absolutePath} ${sherpaOnnxClassesDir}"
690
+ println "[sherpa-onnx] ${sherpaExtractedJar.absolutePath} --> ${sherpaOnnxClassesDir}"
651
691
  return
652
692
  }
653
693
  throw new RuntimeException(
@@ -678,7 +718,7 @@ project.tasks.register("extractOnnxruntimeClasses") {
678
718
  }
679
719
  println "[prebuilt] extractOnnxruntimeClasses"
680
720
  println "[onnxruntime] classes.jar (Java API) ........... MAVEN_AAR ${aar.name}"
681
- println "[onnxruntime] renamed to onnxruntime-classes.jar ${onnxruntimeClassesDir}"
721
+ println "[onnxruntime] renamed to onnxruntime-classes.jar --> ${onnxruntimeClassesDir}"
682
722
  return
683
723
  }
684
724
  throw new RuntimeException(
@@ -45,7 +45,7 @@ println "[react-native-sherpa-onnx] libarchive version (extracted/used): ${libar
45
45
  def ortVersion = System.getenv('ORT_VERSION')
46
46
  if (!ortVersion) {
47
47
  def v = readVersionFromTagFile(new File(moduleRoot, 'third_party/onnxruntime_prebuilt/ANDROID_RELEASE_TAG'), 'ort-android-qnn-v')
48
- ortVersion = v ?: (project.hasProperty('ortVersion') ? project.ortVersion : '1.24.2-qnn2.43.1.260218')
48
+ ortVersion = v ?: (project.hasProperty('ortVersion') ? project.ortVersion : '1.24.4-qnn2.43.1.260218-1')
49
49
  }
50
50
  project.ext.ortVersion = ortVersion
51
51
  println "[react-native-sherpa-onnx] onnxruntime version (extracted/used): ${ortVersion}"
@@ -397,6 +397,7 @@ sherpa-onnx-rk3576-streaming-zipformer-en-2023-06-26.tar.bz2,apache-2.0,yes,high
397
397
  sherpa-onnx-rk3568-streaming-zipformer-en-2023-06-26.tar.bz2,apache-2.0,yes,high,manual,https://huggingface.co/csukuangfj/sherpa-onnx-streaming-zipformer-en-2023-06-26
398
398
  sherpa-onnx-rk3566-streaming-zipformer-en-2023-06-26.tar.bz2,apache-2.0,yes,high,manual,https://huggingface.co/csukuangfj/sherpa-onnx-streaming-zipformer-en-2023-06-26
399
399
  sherpa-onnx-rk3562-streaming-zipformer-en-2023-06-26.tar.bz2,apache-2.0,yes,high,manual,https://huggingface.co/csukuangfj/sherpa-onnx-streaming-zipformer-en-2023-06-26
400
+ sherpa-onnx-qwen3-asr-0.6B-int8-2026-03-25.tar.bz2,apache-2.0,yes,high,manual,https://huggingface.co/Qwen/Qwen3-ASR-0.6B
400
401
  sherpa-onnx-rk3588-streaming-zipformer-small-bilingual-zh-en-2023-02-16.tar.bz2,apache-2.0,yes,high,manual,https://huggingface.co/csukuangfj/k2fsa-zipformer-bilingual-zh-en-t
401
402
  sherpa-onnx-rk3588-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2,apache-2.0,yes,high,manual,https://huggingface.co/csukuangfj/k2fsa-zipformer-bilingual-zh-en-t
402
403
  sherpa-onnx-rk3576-streaming-zipformer-small-bilingual-zh-en-2023-02-16.tar.bz2,apache-2.0,yes,high,manual,https://huggingface.co/csukuangfj/k2fsa-zipformer-bilingual-zh-en-t
@@ -0,0 +1,7 @@
1
+ asset_name,license_type,commercial_use,confidence,detection_source,license_file
2
+ dpdfnet2.onnx,apache-2.0,yes,high,manual,https://huggingface.co/Ceva-IP/DPDFNet/tree/main/onnx
3
+ dpdfnet2_48khz_hr.onnx,apache-2.0,yes,high,manual,https://huggingface.co/Ceva-IP/DPDFNet/tree/main/onnx
4
+ dpdfnet4.onnx,apache-2.0,yes,high,manual,https://huggingface.co/Ceva-IP/DPDFNet/tree/main/onnx
5
+ dpdfnet8.onnx,apache-2.0,yes,high,manual,https://huggingface.co/Ceva-IP/DPDFNet/tree/main/onnx
6
+ dpdfnet_baseline.onnx,apache-2.0,yes,high,manual,https://huggingface.co/Ceva-IP/DPDFNet/tree/main/onnx
7
+ gtcrn_simple.onnx,mit,yes,high,manual,https://github.com/Xiaobin-Rong/gtcrn/tree/main
@@ -83,11 +83,14 @@ set(SOURCES
83
83
  jni/model_detect/sherpa-onnx-model-detect-helper.cpp
84
84
  jni/model_detect/sherpa-onnx-model-detect-stt.cpp
85
85
  jni/model_detect/sherpa-onnx-model-detect-tts.cpp
86
+ jni/model_detect/sherpa-onnx-model-detect-enhancement.cpp
86
87
  jni/model_detect/sherpa-onnx-validate-stt.cpp
87
88
  jni/model_detect/sherpa-onnx-validate-tts.cpp
89
+ jni/model_detect/sherpa-onnx-validate-enhancement.cpp
88
90
  jni/model_detect/sherpa-onnx-detect-jni-common.cpp
89
91
  jni/model_detect/sherpa-onnx-stt-wrapper.cpp
90
92
  jni/model_detect/sherpa-onnx-tts-wrapper.cpp
93
+ jni/model_detect/sherpa-onnx-enhancement-wrapper.cpp
91
94
  jni/audio/sherpa-onnx-audio-convert-jni.cpp
92
95
  crypto/sha256.cpp
93
96
  )
@@ -0,0 +1,68 @@
1
+ #include "sherpa-onnx-enhancement-wrapper.h"
2
+
3
+ #include "sherpa-onnx-detect-jni-common.h"
4
+
5
+ namespace sherpaonnx {
6
+ namespace {
7
+
8
+ const char* EnhancementModelKindToString(EnhancementModelKind k) {
9
+ switch (k) {
10
+ case EnhancementModelKind::kGtcrn:
11
+ return "gtcrn";
12
+ case EnhancementModelKind::kDpdfNet:
13
+ return "dpdfnet";
14
+ default:
15
+ return "unknown";
16
+ }
17
+ }
18
+
19
+ } // namespace
20
+
21
+ jobject EnhancementDetectResultToJava(
22
+ JNIEnv* env,
23
+ const EnhancementDetectResult& result
24
+ ) {
25
+ jclass mapClass = env->FindClass("java/util/HashMap");
26
+ if (!mapClass) return nullptr;
27
+ jmethodID mapInit = env->GetMethodID(mapClass, "<init>", "()V");
28
+ jmethodID mapPut =
29
+ env->GetMethodID(mapClass, "put",
30
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
31
+ if (!mapInit || !mapPut) {
32
+ env->DeleteLocalRef(mapClass);
33
+ return nullptr;
34
+ }
35
+ jobject map = env->NewObject(mapClass, mapInit);
36
+ env->DeleteLocalRef(mapClass);
37
+ if (!map) return nullptr;
38
+
39
+ PutBoolean(env, map, mapPut, "success", result.ok);
40
+ PutString(env, map, mapPut, "error", result.error);
41
+ PutString(env, map, mapPut, "modelType",
42
+ EnhancementModelKindToString(result.selectedKind));
43
+
44
+ jobject detectedList = BuildDetectedModelsList(env, result.detectedModels);
45
+ if (detectedList) {
46
+ jstring keyDetected = env->NewStringUTF("detectedModels");
47
+ env->CallObjectMethod(map, mapPut, keyDetected, detectedList);
48
+ env->DeleteLocalRef(keyDetected);
49
+ env->DeleteLocalRef(detectedList);
50
+ }
51
+
52
+ jclass hashMapClass = env->FindClass("java/util/HashMap");
53
+ if (hashMapClass) {
54
+ jobject pathsMap = env->NewObject(hashMapClass, mapInit);
55
+ env->DeleteLocalRef(hashMapClass);
56
+ if (pathsMap) {
57
+ PutString(env, pathsMap, mapPut, "model", result.paths.model);
58
+ jstring keyPaths = env->NewStringUTF("paths");
59
+ env->CallObjectMethod(map, mapPut, keyPaths, pathsMap);
60
+ env->DeleteLocalRef(keyPaths);
61
+ env->DeleteLocalRef(pathsMap);
62
+ }
63
+ }
64
+
65
+ return map;
66
+ }
67
+
68
+ } // namespace sherpaonnx
@@ -0,0 +1,17 @@
1
+ #ifndef SHERPA_ONNX_ENHANCEMENT_WRAPPER_H
2
+ #define SHERPA_ONNX_ENHANCEMENT_WRAPPER_H
3
+
4
+ #include <jni.h>
5
+
6
+ #include "sherpa-onnx-model-detect.h"
7
+
8
+ namespace sherpaonnx {
9
+
10
+ jobject EnhancementDetectResultToJava(
11
+ JNIEnv* env,
12
+ const EnhancementDetectResult& result
13
+ );
14
+
15
+ } // namespace sherpaonnx
16
+
17
+ #endif // SHERPA_ONNX_ENHANCEMENT_WRAPPER_H
@@ -0,0 +1,119 @@
1
+ #include "sherpa-onnx-model-detect.h"
2
+ #include "sherpa-onnx-model-detect-helper.h"
3
+ #include "sherpa-onnx-validate-enhancement.h"
4
+
5
+ #include <optional>
6
+ #include <string>
7
+ #include <vector>
8
+
9
+ namespace {
10
+
11
+ using namespace sherpaonnx::model_detect;
12
+
13
+ sherpaonnx::EnhancementModelKind ParseEnhancementModelType(const std::string& modelType) {
14
+ if (modelType == "gtcrn") return sherpaonnx::EnhancementModelKind::kGtcrn;
15
+ if (modelType == "dpdfnet") return sherpaonnx::EnhancementModelKind::kDpdfNet;
16
+ return sherpaonnx::EnhancementModelKind::kUnknown;
17
+ }
18
+
19
+ sherpaonnx::EnhancementDetectResult DetectEnhancementModelFromFiles(
20
+ const std::vector<FileEntry>& files,
21
+ const std::string& modelDir,
22
+ const std::string& modelType
23
+ ) {
24
+ sherpaonnx::EnhancementDetectResult result;
25
+
26
+ const std::string gtcrnModel =
27
+ FindOnnxByAnyToken(files, {"gtcrn"}, std::nullopt);
28
+ const std::string dpdfnetModel =
29
+ FindOnnxByAnyToken(files, {"dpdfnet"}, std::nullopt);
30
+
31
+ if (!gtcrnModel.empty()) {
32
+ result.detectedModels.push_back({"gtcrn", modelDir});
33
+ }
34
+ if (!dpdfnetModel.empty()) {
35
+ result.detectedModels.push_back({"dpdfnet", modelDir});
36
+ }
37
+
38
+ sherpaonnx::EnhancementModelKind selected = sherpaonnx::EnhancementModelKind::kUnknown;
39
+ if (modelType == "auto" || modelType.empty()) {
40
+ if (!gtcrnModel.empty()) {
41
+ selected = sherpaonnx::EnhancementModelKind::kGtcrn;
42
+ } else if (!dpdfnetModel.empty()) {
43
+ selected = sherpaonnx::EnhancementModelKind::kDpdfNet;
44
+ }
45
+ } else {
46
+ selected = ParseEnhancementModelType(modelType);
47
+ if (selected == sherpaonnx::EnhancementModelKind::kUnknown) {
48
+ result.error = "Enhancement: unknown model type: " + modelType;
49
+ return result;
50
+ }
51
+ }
52
+
53
+ switch (selected) {
54
+ case sherpaonnx::EnhancementModelKind::kGtcrn:
55
+ result.paths.model = gtcrnModel;
56
+ break;
57
+ case sherpaonnx::EnhancementModelKind::kDpdfNet:
58
+ result.paths.model = dpdfnetModel;
59
+ break;
60
+ default:
61
+ result.error = "Enhancement: no compatible model type detected in " +
62
+ modelDir;
63
+ return result;
64
+ }
65
+
66
+ auto validation =
67
+ sherpaonnx::ValidateEnhancementPaths(selected, result.paths, modelDir);
68
+ if (!validation.ok) {
69
+ result.error = validation.error;
70
+ return result;
71
+ }
72
+
73
+ result.selectedKind = selected;
74
+ result.ok = true;
75
+ return result;
76
+ }
77
+
78
+ } // namespace
79
+
80
+ namespace sherpaonnx {
81
+
82
+ using namespace model_detect;
83
+
84
+ EnhancementDetectResult DetectEnhancementModel(
85
+ const std::string& modelDir,
86
+ const std::string& modelType
87
+ ) {
88
+ EnhancementDetectResult result;
89
+
90
+ if (modelDir.empty()) {
91
+ result.error = "Enhancement: model directory is empty";
92
+ return result;
93
+ }
94
+ if (!FileExists(modelDir) || !IsDirectory(modelDir)) {
95
+ result.error =
96
+ "Enhancement: model directory does not exist or is not a directory: " +
97
+ modelDir;
98
+ return result;
99
+ }
100
+
101
+ const std::vector<model_detect::FileEntry> files = ListFilesRecursive(modelDir, 4);
102
+ return DetectEnhancementModelFromFiles(files, modelDir, modelType);
103
+ }
104
+
105
+ // Test-only: used by host-side model_detect_test; not used in production.
106
+ EnhancementDetectResult DetectEnhancementModelFromFileList(
107
+ const std::vector<model_detect::FileEntry>& files,
108
+ const std::string& modelDir,
109
+ const std::string& modelType
110
+ ) {
111
+ EnhancementDetectResult result;
112
+ if (modelDir.empty()) {
113
+ result.error = "Enhancement: model directory is empty";
114
+ return result;
115
+ }
116
+ return DetectEnhancementModelFromFiles(files, modelDir, modelType);
117
+ }
118
+
119
+ } // namespace sherpaonnx