react-native-sherpa-onnx 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/README.md +232 -236
  2. package/SherpaOnnx.podspec +68 -64
  3. package/android/build.gradle +182 -192
  4. package/android/codegen.gradle +57 -0
  5. package/android/prebuilt-download.gradle +428 -0
  6. package/android/prebuilt-versions.gradle +43 -0
  7. package/android/proguard-rules.pro +10 -0
  8. package/android/src/main/assets/testModels/add_mul_add.onnx +28 -0
  9. package/android/src/main/assets/testModels/nnapi_internal_uint8_support.onnx +0 -0
  10. package/android/src/main/assets/testModels/qnn_multi_ctx_embed.onnx +0 -0
  11. package/android/src/main/cpp/CMakeLists.txt +166 -129
  12. package/android/src/main/cpp/CMakePresets.json +54 -0
  13. package/android/src/main/cpp/crypto/sha256.cpp +174 -0
  14. package/android/src/main/cpp/crypto/sha256.h +16 -0
  15. package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-helper.cpp +404 -0
  16. package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-helper.h +56 -0
  17. package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-jni.cpp +181 -0
  18. package/android/src/main/cpp/jni/audio/sherpa-onnx-audio-convert-jni.cpp +888 -0
  19. package/{ios → android/src/main/cpp/jni/model_detect}/sherpa-onnx-common.h +18 -18
  20. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-detect-jni-common.cpp +86 -0
  21. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-detect-jni-common.h +20 -0
  22. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.cpp +423 -0
  23. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.h +55 -0
  24. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-stt.cpp +399 -0
  25. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-tts.cpp +238 -0
  26. package/{ios → android/src/main/cpp/jni/model_detect}/sherpa-onnx-model-detect.h +122 -89
  27. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-stt-wrapper.cpp +99 -0
  28. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-stt-wrapper.h +16 -0
  29. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-tts-wrapper.cpp +78 -0
  30. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-tts-wrapper.h +16 -0
  31. package/android/src/main/cpp/jni/module/sherpa-onnx-module-jni.cpp +190 -0
  32. package/android/src/main/cpp/jni/tts/sherpa-onnx-tts-zipvoice-jni.cpp +301 -0
  33. package/android/src/main/java/com/sherpaonnx/SherpaOnnxArchiveHelper.kt +94 -0
  34. package/android/src/main/java/com/sherpaonnx/{SherpaOnnxCoreHelper.kt → SherpaOnnxAssetHelper.kt} +350 -236
  35. package/android/src/main/java/com/sherpaonnx/SherpaOnnxModule.kt +791 -483
  36. package/android/src/main/java/com/sherpaonnx/SherpaOnnxSttHelper.kt +699 -109
  37. package/android/src/main/java/com/sherpaonnx/SherpaOnnxTtsHelper.kt +1123 -668
  38. package/android/src/main/java/com/sherpaonnx/ZipvoiceTtsWrapper.kt +187 -0
  39. package/ios/SherpaOnnx+Assets.h +11 -0
  40. package/ios/SherpaOnnx+Assets.mm +325 -0
  41. package/ios/SherpaOnnx+STT.mm +455 -118
  42. package/ios/SherpaOnnx+TTS.mm +1101 -712
  43. package/ios/SherpaOnnx.h +17 -6
  44. package/ios/SherpaOnnx.mm +206 -311
  45. package/ios/SherpaOnnx.xcconfig +19 -19
  46. package/ios/SherpaOnnxCoreMLHelper.swift +24 -0
  47. package/ios/archive/sherpa-onnx-archive-helper.h +21 -0
  48. package/ios/archive/sherpa-onnx-archive-helper.mm +296 -0
  49. package/ios/libarchive_darwin_config.h +153 -0
  50. package/{android/src/main/cpp/jni → ios/model_detect}/sherpa-onnx-common.h +18 -18
  51. package/ios/model_detect/sherpa-onnx-model-detect-helper.h +49 -0
  52. package/ios/model_detect/sherpa-onnx-model-detect-helper.mm +210 -0
  53. package/ios/model_detect/sherpa-onnx-model-detect-stt.mm +344 -0
  54. package/ios/model_detect/sherpa-onnx-model-detect-tts.mm +201 -0
  55. package/{android/src/main/cpp/jni → ios/model_detect}/sherpa-onnx-model-detect.h +117 -89
  56. package/ios/scripts/patch-libarchive-includes.sh +61 -0
  57. package/ios/scripts/setup-ios-libarchive.sh +98 -0
  58. package/ios/stt/sherpa-onnx-stt-wrapper.h +129 -0
  59. package/ios/stt/sherpa-onnx-stt-wrapper.mm +523 -0
  60. package/ios/{sherpa-onnx-tts-wrapper.h → tts/sherpa-onnx-tts-wrapper.h} +90 -85
  61. package/ios/{sherpa-onnx-tts-wrapper.mm → tts/sherpa-onnx-tts-wrapper.mm} +376 -345
  62. package/lib/module/NativeSherpaOnnx.js +3 -0
  63. package/lib/module/NativeSherpaOnnx.js.map +1 -1
  64. package/lib/module/audio/index.js +22 -0
  65. package/lib/module/audio/index.js.map +1 -0
  66. package/lib/module/diarization/index.js +1 -1
  67. package/lib/module/diarization/index.js.map +1 -1
  68. package/lib/module/download/ModelDownloadManager.js +918 -0
  69. package/lib/module/download/ModelDownloadManager.js.map +1 -0
  70. package/lib/module/download/extractTarBz2.js +53 -0
  71. package/lib/module/download/extractTarBz2.js.map +1 -0
  72. package/lib/module/download/index.js +6 -0
  73. package/lib/module/download/index.js.map +1 -0
  74. package/lib/module/download/validation.js +178 -0
  75. package/lib/module/download/validation.js.map +1 -0
  76. package/lib/module/enhancement/index.js +1 -1
  77. package/lib/module/enhancement/index.js.map +1 -1
  78. package/lib/module/index.js +41 -3
  79. package/lib/module/index.js.map +1 -1
  80. package/lib/module/separation/index.js +1 -1
  81. package/lib/module/separation/index.js.map +1 -1
  82. package/lib/module/stt/index.js +127 -60
  83. package/lib/module/stt/index.js.map +1 -1
  84. package/lib/module/stt/sttModelLanguages.js +512 -0
  85. package/lib/module/stt/sttModelLanguages.js.map +1 -0
  86. package/lib/module/stt/types.js +53 -1
  87. package/lib/module/stt/types.js.map +1 -1
  88. package/lib/module/tts/index.js +216 -289
  89. package/lib/module/tts/index.js.map +1 -1
  90. package/lib/module/tts/types.js +86 -1
  91. package/lib/module/tts/types.js.map +1 -1
  92. package/lib/module/types.js.map +1 -1
  93. package/lib/module/utils.js +86 -73
  94. package/lib/module/utils.js.map +1 -1
  95. package/lib/module/vad/index.js +1 -1
  96. package/lib/module/vad/index.js.map +1 -1
  97. package/lib/typescript/src/NativeSherpaOnnx.d.ts +192 -38
  98. package/lib/typescript/src/NativeSherpaOnnx.d.ts.map +1 -1
  99. package/lib/typescript/src/audio/index.d.ts +13 -0
  100. package/lib/typescript/src/audio/index.d.ts.map +1 -0
  101. package/lib/typescript/src/diarization/index.d.ts +3 -2
  102. package/lib/typescript/src/diarization/index.d.ts.map +1 -1
  103. package/lib/typescript/src/download/ModelDownloadManager.d.ts +108 -0
  104. package/lib/typescript/src/download/ModelDownloadManager.d.ts.map +1 -0
  105. package/lib/typescript/src/download/extractTarBz2.d.ts +14 -0
  106. package/lib/typescript/src/download/extractTarBz2.d.ts.map +1 -0
  107. package/lib/typescript/src/download/index.d.ts +7 -0
  108. package/lib/typescript/src/download/index.d.ts.map +1 -0
  109. package/lib/typescript/src/download/validation.d.ts +57 -0
  110. package/lib/typescript/src/download/validation.d.ts.map +1 -0
  111. package/lib/typescript/src/enhancement/index.d.ts +3 -2
  112. package/lib/typescript/src/enhancement/index.d.ts.map +1 -1
  113. package/lib/typescript/src/index.d.ts +26 -2
  114. package/lib/typescript/src/index.d.ts.map +1 -1
  115. package/lib/typescript/src/separation/index.d.ts +3 -2
  116. package/lib/typescript/src/separation/index.d.ts.map +1 -1
  117. package/lib/typescript/src/stt/index.d.ts +31 -43
  118. package/lib/typescript/src/stt/index.d.ts.map +1 -1
  119. package/lib/typescript/src/stt/sttModelLanguages.d.ts +52 -0
  120. package/lib/typescript/src/stt/sttModelLanguages.d.ts.map +1 -0
  121. package/lib/typescript/src/stt/types.d.ts +196 -9
  122. package/lib/typescript/src/stt/types.d.ts.map +1 -1
  123. package/lib/typescript/src/tts/index.d.ts +25 -211
  124. package/lib/typescript/src/tts/index.d.ts.map +1 -1
  125. package/lib/typescript/src/tts/types.d.ts +148 -25
  126. package/lib/typescript/src/tts/types.d.ts.map +1 -1
  127. package/lib/typescript/src/types.d.ts +0 -32
  128. package/lib/typescript/src/types.d.ts.map +1 -1
  129. package/lib/typescript/src/utils.d.ts +28 -13
  130. package/lib/typescript/src/utils.d.ts.map +1 -1
  131. package/lib/typescript/src/vad/index.d.ts +3 -2
  132. package/lib/typescript/src/vad/index.d.ts.map +1 -1
  133. package/package.json +250 -222
  134. package/scripts/check-qnn-support.sh +78 -0
  135. package/scripts/setup-ios-framework.sh +379 -282
  136. package/src/NativeSherpaOnnx.ts +474 -251
  137. package/src/audio/index.ts +32 -0
  138. package/src/diarization/index.ts +4 -2
  139. package/src/download/ModelDownloadManager.ts +1325 -0
  140. package/src/download/extractTarBz2.ts +78 -0
  141. package/src/download/index.ts +43 -0
  142. package/src/download/validation.ts +279 -0
  143. package/src/enhancement/index.ts +4 -2
  144. package/src/index.tsx +78 -27
  145. package/src/separation/index.ts +4 -2
  146. package/src/stt/index.ts +249 -89
  147. package/src/stt/sttModelLanguages.ts +237 -0
  148. package/src/stt/types.ts +263 -9
  149. package/src/tts/index.ts +470 -458
  150. package/src/tts/types.ts +373 -218
  151. package/src/types.ts +0 -44
  152. package/src/utils.ts +145 -131
  153. package/src/vad/index.ts +4 -2
  154. package/third_party/ffmpeg_prebuilt/ANDROID_RELEASE_TAG +1 -0
  155. package/third_party/libarchive_prebuilt/ANDROID_RELEASE_TAG +1 -0
  156. package/third_party/libarchive_prebuilt/IOS_RELEASE_TAG +1 -0
  157. package/third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG +1 -0
  158. package/third_party/sherpa-onnx-prebuilt/IOS_RELEASE_TAG +1 -0
  159. package/android/src/main/cpp/include/sherpa-onnx/c-api/c-api.h +0 -1918
  160. package/android/src/main/cpp/include/sherpa-onnx/c-api/cxx-api.h +0 -841
  161. package/android/src/main/cpp/jni/sherpa-onnx-model-detect.cpp +0 -541
  162. package/android/src/main/cpp/jni/sherpa-onnx-stt-jni.cpp +0 -336
  163. package/android/src/main/cpp/jni/sherpa-onnx-stt-wrapper.cpp +0 -222
  164. package/android/src/main/cpp/jni/sherpa-onnx-stt-wrapper.h +0 -68
  165. package/android/src/main/cpp/jni/sherpa-onnx-tts-jni.cpp +0 -823
  166. package/android/src/main/cpp/jni/sherpa-onnx-tts-wrapper.cpp +0 -387
  167. package/android/src/main/cpp/jni/sherpa-onnx-tts-wrapper.h +0 -147
  168. package/ios/Frameworks/sherpa_onnx.xcframework.zip +0 -0
  169. package/ios/include/sherpa-onnx/c-api/c-api.h +0 -1918
  170. package/ios/include/sherpa-onnx/c-api/cxx-api.h +0 -841
  171. package/ios/sherpa-onnx-model-detect.mm +0 -441
  172. package/ios/sherpa-onnx-stt-wrapper.h +0 -48
  173. package/ios/sherpa-onnx-stt-wrapper.mm +0 -201
  174. package/scripts/copy-headers.js +0 -184
  175. package/scripts/setup-assets.js +0 -323
@@ -0,0 +1,428 @@
1
+ // Prebuilt download and check logic. Applied after android {} and configurations.
2
+ // Depends on: sherpaOnnxVersion, ffmpegVersion, libarchiveVersion, ortVersion (from prebuilt-versions.gradle)
3
+ // and configurations.sherpaOnnxAar, ffmpegAar, libarchiveAar, onnxruntimeAar (from build.gradle).
4
+
5
+ def requiredAbis = ["arm64-v8a", "armeabi-v7a", "x86", "x86_64"]
6
+ def requiredFfmpegSoFiles = [
7
+ 'libavcodec.so', 'libavformat.so', 'libavutil.so', 'libswresample.so', 'libavfilter.so', 'libshine.so'
8
+ ]
9
+ def requiredSherpaOnnxSoFiles = [
10
+ 'libsherpa-onnx-jni.so', 'libsherpa-onnx-c-api.so', 'libsherpa-onnx-cxx-api.so', 'libonnxruntime.so'
11
+ ]
12
+ def requiredLibarchiveSoFiles = ['libarchive.so']
13
+ def requiredOnnxruntimeJniSoFiles = ['libonnxruntime4j_jni.so']
14
+
15
+ def jniLibsDir = file("${project.projectDir}/src/main/jniLibs")
16
+ def sherpaOnnxClassesDir = file("${project.buildDir}/sherpa-onnx-classes")
17
+ def onnxruntimeClassesDir = file("${project.buildDir}/onnxruntime-classes")
18
+
19
+ def hasAllFfmpegLibs = {
20
+ for (abi in requiredAbis) {
21
+ def dir = new File(jniLibsDir, abi)
22
+ if (!dir.exists()) return false
23
+ for (soName in requiredFfmpegSoFiles) {
24
+ if (!new File(dir, soName).exists()) return false
25
+ }
26
+ }
27
+ return true
28
+ }
29
+
30
+ def hasAllSherpaLibs = {
31
+ for (abi in requiredAbis) {
32
+ def dir = new File(jniLibsDir, abi)
33
+ if (!dir.exists()) return false
34
+ for (soName in requiredSherpaOnnxSoFiles) {
35
+ if (!new File(dir, soName).exists()) return false
36
+ }
37
+ }
38
+ return true
39
+ }
40
+
41
+ def hasSherpaHeaders = {
42
+ return new File(project.projectDir, "src/main/cpp/include/sherpa-onnx/c-api/c-api.h").exists()
43
+ }
44
+
45
+ def hasAllLibarchiveLibs = {
46
+ for (abi in requiredAbis) {
47
+ def dir = new File(jniLibsDir, abi)
48
+ if (!dir.exists()) return false
49
+ for (soName in requiredLibarchiveSoFiles) {
50
+ if (!new File(dir, soName).exists()) return false
51
+ }
52
+ }
53
+ return true
54
+ }
55
+
56
+ def hasFfmpegHeaders = {
57
+ return new File(project.projectDir, "src/main/cpp/include/ffmpeg/libavcodec/avcodec.h").exists()
58
+ }
59
+
60
+ def hasLibarchiveHeaders = {
61
+ return new File(project.projectDir, "src/main/cpp/include/libarchive/archive.h").exists()
62
+ }
63
+
64
+ def hasAllOnnxruntimeJniLibs = {
65
+ for (abi in requiredAbis) {
66
+ def dir = new File(jniLibsDir, abi)
67
+ if (!dir.exists()) return false
68
+ for (soName in requiredOnnxruntimeJniSoFiles) {
69
+ if (!new File(dir, soName).exists()) return false
70
+ }
71
+ }
72
+ return true
73
+ }
74
+
75
+ def getGitHubRepo = {
76
+ try {
77
+ def proc = ['git', 'remote', 'get-url', 'origin'].execute(null, project.rootDir)
78
+ proc.waitFor()
79
+ if (proc.exitValue() != 0) return null
80
+ def url = proc.text.trim()
81
+ def m = (url =~ /github\.com[:\/]([^\/]+\/[^\/\s]+?)(\.git)?$/)
82
+ return m ? m[0][1] : null
83
+ } catch (Exception e) { return null }
84
+ }
85
+
86
+ def readReleaseTag = { File tagFile ->
87
+ if (!tagFile.exists()) return null
88
+ return tagFile.text.split(/\r?\n/).findResult { line ->
89
+ def t = line.replaceAll(/\s*#.*$/, '').trim()
90
+ t ? t : null
91
+ }
92
+ }
93
+
94
+ project.tasks.register("downloadNativeLibsIfNeeded") {
95
+ doLast {
96
+ def downloadDir = file("${project.buildDir}/prebuilt-downloads")
97
+
98
+ if (hasAllSherpaLibs() && hasSherpaHeaders()) {
99
+ println "[sherpa-onnx] Native libs + headers: (1) local third_party (jniLibs + cpp/include already present)"
100
+ }
101
+
102
+ if (!hasAllSherpaLibs() || !hasSherpaHeaders()) {
103
+ try {
104
+ def aarFiles = project.configurations.sherpaOnnxAar.files
105
+ if (!aarFiles.isEmpty()) {
106
+ downloadDir.mkdirs()
107
+ def aar = aarFiles.iterator().next()
108
+ def aarExtractDir = new File(downloadDir, "sherpa-onnx-aar-extract")
109
+ if (aarExtractDir.exists()) aarExtractDir.deleteDir()
110
+ aarExtractDir.mkdirs()
111
+ copy { from zipTree(aar); into aarExtractDir }
112
+ requiredAbis.each { abi ->
113
+ def aarJniDir = new File(aarExtractDir, "jni/${abi}")
114
+ if (aarJniDir.exists()) {
115
+ copy { from aarJniDir; into new File(jniLibsDir, abi) }
116
+ }
117
+ }
118
+ def includeSherpaDir = file("${project.projectDir}/src/main/cpp/include/sherpa-onnx")
119
+ def aarCapiDir = new File(aarExtractDir, "c-api")
120
+ if (aarCapiDir.exists()) {
121
+ includeSherpaDir.mkdirs()
122
+ copy { from fileTree(aarExtractDir) { include 'c-api/**' }; into includeSherpaDir }
123
+ println "Extracted sherpa-onnx C-API headers from Maven AAR"
124
+ }
125
+ println "[sherpa-onnx] Native libs + headers: (2) Maven AAR (${aar.name})"
126
+ }
127
+ } catch (Exception e) {
128
+ println "Could not resolve sherpa-onnx Maven AAR: ${e.message}"
129
+ }
130
+ }
131
+
132
+ if (!hasAllFfmpegLibs() || !hasFfmpegHeaders()) {
133
+ try {
134
+ def aarFiles = project.configurations.ffmpegAar.files
135
+ if (!aarFiles.isEmpty()) {
136
+ downloadDir.mkdirs()
137
+ def aar = aarFiles.iterator().next()
138
+ def aarExtractDir = new File(downloadDir, "ffmpeg-aar-extract")
139
+ if (aarExtractDir.exists()) aarExtractDir.deleteDir()
140
+ aarExtractDir.mkdirs()
141
+ copy { from zipTree(aar); into aarExtractDir }
142
+ requiredAbis.each { abi ->
143
+ def aarJniDir = new File(aarExtractDir, "jni/${abi}")
144
+ if (aarJniDir.exists()) {
145
+ copy { from aarJniDir; into new File(jniLibsDir, abi) }
146
+ }
147
+ }
148
+ def ffmpegIncludeDir = file("${project.projectDir}/src/main/cpp/include/ffmpeg")
149
+ def aarIncludeDir = new File(aarExtractDir, "include")
150
+ if (aarIncludeDir.exists()) {
151
+ ffmpegIncludeDir.mkdirs()
152
+ copy { from aarIncludeDir; into ffmpegIncludeDir }
153
+ println "Extracted FFmpeg headers from Maven AAR"
154
+ }
155
+ println "[FFmpeg] Native libs + headers: (2) Maven AAR (${aar.name})"
156
+ }
157
+ } catch (Exception e) {
158
+ println "Could not resolve FFmpeg Maven AAR: ${e.message}"
159
+ }
160
+ }
161
+
162
+ if (!hasAllLibarchiveLibs() || !hasLibarchiveHeaders()) {
163
+ try {
164
+ def aarFiles = project.configurations.libarchiveAar.files
165
+ if (!aarFiles.isEmpty()) {
166
+ downloadDir.mkdirs()
167
+ def aar = aarFiles.iterator().next()
168
+ def aarExtractDir = new File(downloadDir, "libarchive-aar-extract")
169
+ if (aarExtractDir.exists()) aarExtractDir.deleteDir()
170
+ aarExtractDir.mkdirs()
171
+ copy { from zipTree(aar); into aarExtractDir }
172
+ requiredAbis.each { abi ->
173
+ def aarJniDir = new File(aarExtractDir, "jni/${abi}")
174
+ if (aarJniDir.exists()) {
175
+ copy { from aarJniDir; into new File(jniLibsDir, abi) }
176
+ }
177
+ }
178
+ def libarchiveIncludeDir = file("${project.projectDir}/src/main/cpp/include/libarchive")
179
+ def aarIncludeDir = new File(aarExtractDir, "include")
180
+ if (aarIncludeDir.exists()) {
181
+ libarchiveIncludeDir.mkdirs()
182
+ copy { from aarIncludeDir; into libarchiveIncludeDir }
183
+ println "Extracted libarchive headers from Maven AAR"
184
+ }
185
+ println "[libarchive] Native libs + headers: (2) Maven AAR (${aar.name})"
186
+ }
187
+ } catch (Exception e) {
188
+ println "Could not resolve libarchive Maven AAR: ${e.message}"
189
+ }
190
+ }
191
+
192
+ // onnxruntime AAR: extract only libonnxruntime4j_jni.so (the Java↔C bridge)
193
+ // into jniLibs. We do NOT extract libonnxruntime.so from this AAR because
194
+ // jniLibs already has it from the sherpa-onnx prebuilts — avoids duplicates.
195
+ if (!hasAllOnnxruntimeJniLibs()) {
196
+ try {
197
+ def aarFiles = project.configurations.onnxruntimeAar.files
198
+ if (!aarFiles.isEmpty()) {
199
+ downloadDir.mkdirs()
200
+ def aar = aarFiles.iterator().next()
201
+ def aarExtractDir = new File(downloadDir, "onnxruntime-aar-extract")
202
+ if (aarExtractDir.exists()) aarExtractDir.deleteDir()
203
+ aarExtractDir.mkdirs()
204
+ copy { from zipTree(aar); into aarExtractDir }
205
+ requiredAbis.each { abi ->
206
+ def aarJniDir = new File(aarExtractDir, "jni/${abi}")
207
+ if (aarJniDir.exists()) {
208
+ copy {
209
+ from aarJniDir
210
+ include 'libonnxruntime4j_jni.so'
211
+ into new File(jniLibsDir, abi)
212
+ }
213
+ }
214
+ }
215
+ println "[onnxruntime] JNI bridge: Maven AAR (${aar.name})"
216
+ }
217
+ } catch (Exception e) {
218
+ println "Could not resolve onnxruntime Maven AAR: ${e.message}"
219
+ }
220
+ }
221
+
222
+ def repo = project.findProperty('prebuiltGitHubRepo') ?: getGitHubRepo()
223
+ if (!repo) {
224
+ if (!hasAllFfmpegLibs() || !hasFfmpegHeaders() || !hasAllSherpaLibs() || !hasSherpaHeaders() || !hasAllLibarchiveLibs() || !hasLibarchiveHeaders()) {
225
+ throw new RuntimeException(
226
+ "Native libs/headers still missing and GitHub repo unknown. Set -PprebuiltGitHubRepo=owner/repo or ensure git remote origin is a GitHub URL. " +
227
+ "Alternatively run third_party/ffmpeg_prebuilt/copy_prebuilts_to_sdk.js, third_party/sherpa-onnx-prebuilt/copy_prebuilts_to_sdk.js, third_party/libarchive_prebuilt/copy_prebuilts_to_sdk.js, or use Maven (com.xdcobra.sherpa:ffmpeg / sherpa-onnx / libarchive), or ensure ANDROID_RELEASE_TAG releases exist."
228
+ )
229
+ }
230
+ return
231
+ }
232
+ def baseUrl = "https://github.com/${repo}/releases/download"
233
+ downloadDir.mkdirs()
234
+
235
+ if (!hasAllFfmpegLibs() || !hasFfmpegHeaders()) {
236
+ def tagFile = file("${project.projectDir.parent}/third_party/ffmpeg_prebuilt/ANDROID_RELEASE_TAG")
237
+ def tag = readReleaseTag(tagFile)
238
+ if (!tag) throw new RuntimeException("Missing or empty third_party/ffmpeg_prebuilt/ANDROID_RELEASE_TAG")
239
+ def zipFile = new File(downloadDir, "ffmpeg-android.zip")
240
+ def url = "${baseUrl}/${tag}/ffmpeg-android.zip"
241
+ exec { commandLine 'curl', '-sSL', '-o', zipFile, url; workingDir project.projectDir }
242
+ if (!zipFile.exists() || zipFile.length() == 0) throw new RuntimeException("Download failed or empty: ${url}")
243
+ def ffmpegExtractDir = new File(downloadDir, "ffmpeg-extract")
244
+ if (ffmpegExtractDir.exists()) ffmpegExtractDir.deleteDir()
245
+ ffmpegExtractDir.mkdirs()
246
+ copy { from zipTree(zipFile); into ffmpegExtractDir }
247
+ copy {
248
+ from fileTree(ffmpegExtractDir) { include 'arm64-v8a/**', 'armeabi-v7a/**', 'x86/**', 'x86_64/**' }
249
+ into jniLibsDir
250
+ }
251
+ def ffmpegIncludeDir = file("${project.projectDir}/src/main/cpp/include/ffmpeg")
252
+ def ffmpegIncludeInZip = new File(ffmpegExtractDir, "include")
253
+ if (ffmpegIncludeInZip.exists()) {
254
+ copy { from fileTree(ffmpegIncludeInZip); into ffmpegIncludeDir }
255
+ }
256
+ println "Downloaded and extracted FFmpeg prebuilts (libs + include) from ${tag}"
257
+ }
258
+
259
+ if (!hasAllLibarchiveLibs() || !hasLibarchiveHeaders()) {
260
+ def tagFile = file("${project.projectDir.parent}/third_party/libarchive_prebuilt/ANDROID_RELEASE_TAG")
261
+ def tag = readReleaseTag(tagFile)
262
+ if (!tag) throw new RuntimeException("Missing or empty third_party/libarchive_prebuilt/ANDROID_RELEASE_TAG")
263
+ def zipFile = new File(downloadDir, "libarchive-android.zip")
264
+ def url = "${baseUrl}/${tag}/libarchive-android.zip"
265
+ exec { commandLine 'curl', '-sSL', '-o', zipFile, url; workingDir project.projectDir }
266
+ if (!zipFile.exists() || zipFile.length() == 0) throw new RuntimeException("Download failed or empty: ${url}")
267
+ def libarchiveExtractDir = new File(downloadDir, "libarchive-extract")
268
+ if (libarchiveExtractDir.exists()) libarchiveExtractDir.deleteDir()
269
+ libarchiveExtractDir.mkdirs()
270
+ copy { from zipTree(zipFile); into libarchiveExtractDir }
271
+ copy {
272
+ from fileTree(libarchiveExtractDir) { include 'arm64-v8a/**', 'armeabi-v7a/**', 'x86/**', 'x86_64/**' }
273
+ into jniLibsDir
274
+ }
275
+ def libarchiveIncludeDir = file("${project.projectDir}/src/main/cpp/include/libarchive")
276
+ def libarchiveIncludeInZip = new File(libarchiveExtractDir, "include")
277
+ if (libarchiveIncludeInZip.exists()) {
278
+ libarchiveIncludeDir.mkdirs()
279
+ copy { from libarchiveIncludeInZip; into libarchiveIncludeDir }
280
+ }
281
+ println "Downloaded and extracted libarchive prebuilts (libs + include) from ${tag}"
282
+ }
283
+
284
+ if (!hasAllSherpaLibs() || !hasSherpaHeaders()) {
285
+ def tagFile = file("${project.projectDir.parent}/third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG")
286
+ def tag = readReleaseTag(tagFile)
287
+ if (!tag) throw new RuntimeException("Missing or empty third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG")
288
+ def zipFile = new File(downloadDir, "sherpa-onnx-android.zip")
289
+ def url = "${baseUrl}/${tag}/sherpa-onnx-android.zip"
290
+ exec { commandLine 'curl', '-sSL', '-o', zipFile, url; workingDir project.projectDir }
291
+ if (!zipFile.exists() || zipFile.length() == 0) throw new RuntimeException("Download failed or empty: ${url}")
292
+ def sherpaExtractDir = new File(downloadDir, "sherpa-onnx-extract")
293
+ if (sherpaExtractDir.exists()) sherpaExtractDir.deleteDir()
294
+ sherpaExtractDir.mkdirs()
295
+ copy {
296
+ from zipTree(zipFile)
297
+ into sherpaExtractDir
298
+ }
299
+ copy {
300
+ from fileTree(sherpaExtractDir) { include 'arm64-v8a/**', 'armeabi-v7a/**', 'x86/**', 'x86_64/**' }
301
+ into jniLibsDir
302
+ }
303
+ def includeSherpaDir = file("${project.projectDir}/src/main/cpp/include/sherpa-onnx")
304
+ copy {
305
+ from fileTree(sherpaExtractDir) { include 'c-api/**' }
306
+ into includeSherpaDir
307
+ }
308
+ def sherpaJavaJar = new File(sherpaExtractDir, "java/classes.jar")
309
+ if (sherpaJavaJar.exists()) {
310
+ sherpaOnnxClassesDir.mkdirs()
311
+ copy { from sherpaJavaJar; into sherpaOnnxClassesDir }
312
+ }
313
+ println "[sherpa-onnx] Native libs + headers: (3) GitHub release (${tag})"
314
+ } else {
315
+ def sherpaClassesJar = file("${project.projectDir.parent}/third_party/sherpa-onnx-prebuilt/android/java/classes.jar")
316
+ if (sherpaClassesJar.exists() && !sherpaOnnxClassesDir.listFiles()?.any { it.name.endsWith('.jar') }) {
317
+ sherpaOnnxClassesDir.mkdirs()
318
+ copy { from sherpaClassesJar; into sherpaOnnxClassesDir }
319
+ println "Copied sherpa-onnx classes.jar from local prebuilts into sherpa-onnx-classes"
320
+ }
321
+ }
322
+ }
323
+ }
324
+
325
+ project.tasks.register("checkJniLibs") {
326
+ dependsOn project.tasks.named("downloadNativeLibsIfNeeded")
327
+ doLast {
328
+ requiredAbis.each { abi ->
329
+ def dir = file("${project.projectDir}/src/main/jniLibs/${abi}")
330
+ if (!dir.exists()) {
331
+ throw new RuntimeException("Missing native libs for ABI ${abi} in ${dir}. Run third_party/ffmpeg_prebuilt/copy_prebuilts_to_sdk.js, third_party/sherpa-onnx-prebuilt/copy_prebuilts_to_sdk.js, third_party/libarchive_prebuilt/copy_prebuilts_to_sdk.js, or use Maven (com.xdcobra.sherpa:ffmpeg / sherpa-onnx / libarchive), or ensure ANDROID_RELEASE_TAG releases exist.")
332
+ }
333
+ requiredFfmpegSoFiles.each { soName ->
334
+ def soFile = new File(dir, soName)
335
+ if (!soFile.exists()) {
336
+ throw new RuntimeException("Missing required FFmpeg library '${soName}' for ABI ${abi}. Run third_party/ffmpeg_prebuilt/copy_prebuilts_to_sdk.js or ensure Maven com.xdcobra.sherpa:ffmpeg is available.")
337
+ }
338
+ }
339
+ requiredSherpaOnnxSoFiles.each { soName ->
340
+ def soFile = new File(dir, soName)
341
+ if (!soFile.exists()) {
342
+ throw new RuntimeException("Missing required sherpa-onnx library '${soName}' for ABI ${abi}. Run third_party/sherpa-onnx-prebuilt/copy_prebuilts_to_sdk.js")
343
+ }
344
+ }
345
+ requiredLibarchiveSoFiles.each { soName ->
346
+ def soFile = new File(dir, soName)
347
+ if (!soFile.exists()) {
348
+ throw new RuntimeException("Missing required libarchive library '${soName}' for ABI ${abi}. Run third_party/libarchive_prebuilt/copy_prebuilts_to_sdk.js or ensure Maven com.xdcobra.sherpa:libarchive is available.")
349
+ }
350
+ }
351
+ requiredOnnxruntimeJniSoFiles.each { soName ->
352
+ def soFile = new File(dir, soName)
353
+ if (!soFile.exists()) {
354
+ throw new RuntimeException("Missing onnxruntime JNI bridge '${soName}' for ABI ${abi}. Ensure Maven com.xdcobra.sherpa:onnxruntime is available.")
355
+ }
356
+ }
357
+ }
358
+ }
359
+ }
360
+
361
+ project.afterEvaluate {
362
+ project.tasks.findByName('preBuild')?.dependsOn(project.tasks.findByName('checkJniLibs'))
363
+ }
364
+
365
+ def sherpaLocalJar = file("${project.projectDir.parent}/third_party/sherpa-onnx-prebuilt/android/java/classes.jar")
366
+ def sherpaExtractedJar = file("${project.buildDir}/prebuilt-downloads/sherpa-onnx-extract/java/classes.jar")
367
+
368
+ project.tasks.register("extractSherpaOnnxClasses") {
369
+ outputs.dir sherpaOnnxClassesDir
370
+ inputs.files(project.configurations.sherpaOnnxAar)
371
+ if (sherpaLocalJar.exists()) inputs.file(sherpaLocalJar)
372
+ doLast {
373
+ sherpaOnnxClassesDir.mkdirs()
374
+ file(sherpaOnnxClassesDir).listFiles()?.findAll { it.name.endsWith('.jar') }?.each { it.delete() }
375
+ if (sherpaLocalJar.exists()) {
376
+ copy { from sherpaLocalJar; into sherpaOnnxClassesDir }
377
+ println "[sherpa-onnx] classes.jar: (1) local third_party"
378
+ return
379
+ }
380
+ def aarFiles = project.configurations.sherpaOnnxAar.files
381
+ if (!aarFiles.isEmpty()) {
382
+ def aar = aarFiles.iterator().next()
383
+ copy {
384
+ from zipTree(aar)
385
+ include 'classes.jar'
386
+ into sherpaOnnxClassesDir
387
+ }
388
+ println "[sherpa-onnx] classes.jar: (2) Maven AAR Kotlin (${aar.name})"
389
+ return
390
+ }
391
+ if (sherpaExtractedJar.exists()) {
392
+ copy { from sherpaExtractedJar; into sherpaOnnxClassesDir }
393
+ println "[sherpa-onnx] classes.jar: (3) GitHub release extract"
394
+ return
395
+ }
396
+ throw new RuntimeException(
397
+ "Missing sherpa-onnx classes.jar (Kotlin API). Use (1) local build_sherpa_onnx.sh, (2) Maven com.xdcobra.sherpa:sherpa-onnx, or (3) a GitHub release with java/classes.jar.")
398
+ }
399
+ }
400
+
401
+ // Extract classes.jar from the onnxruntime AAR so ai.onnxruntime.* Java classes
402
+ // are bundled directly in the SDK. No compileOnly needed; users get it for free.
403
+ project.tasks.register("extractOnnxruntimeClasses") {
404
+ outputs.dir onnxruntimeClassesDir
405
+ inputs.files(project.configurations.onnxruntimeAar)
406
+ doLast {
407
+ onnxruntimeClassesDir.mkdirs()
408
+ file(onnxruntimeClassesDir).listFiles()?.findAll { it.name.endsWith('.jar') }?.each { it.delete() }
409
+ def aarFiles = project.configurations.onnxruntimeAar.files
410
+ if (!aarFiles.isEmpty()) {
411
+ def aar = aarFiles.iterator().next()
412
+ copy {
413
+ from zipTree(aar)
414
+ include 'classes.jar'
415
+ into onnxruntimeClassesDir
416
+ }
417
+ def extractedJar = new File(onnxruntimeClassesDir, "classes.jar")
418
+ if (extractedJar.exists()) {
419
+ def renamed = new File(onnxruntimeClassesDir, "onnxruntime-classes.jar")
420
+ extractedJar.renameTo(renamed)
421
+ }
422
+ println "[onnxruntime] classes.jar: Maven AAR (${aar.name})"
423
+ return
424
+ }
425
+ throw new RuntimeException(
426
+ "Missing onnxruntime classes.jar. Ensure Maven com.xdcobra.sherpa:onnxruntime is available.")
427
+ }
428
+ }
@@ -0,0 +1,43 @@
1
+ // Resolve prebuilt versions from env, ANDROID_RELEASE_TAG files, or defaults.
2
+ // Used by dependencies (AAR coordinates) and by prebuilt-download.gradle.
3
+ // Returns version string from tag file (e.g. ffmpeg-android-v8.0.1 -> 8.0.1) or null if not found.
4
+ def readVersionFromTagFile(File tagFile, String prefix) {
5
+ if (!tagFile.exists()) return null
6
+ def tag = tagFile.text.split(/\r?\n/).findResult { line ->
7
+ def t = line.replaceAll(/\s*#.*$/, '').trim()
8
+ t ? t : null
9
+ }
10
+ if (tag?.startsWith(prefix)) return tag.replaceFirst(~/^\Q${prefix}\E/, '')
11
+ return null
12
+ }
13
+
14
+ // sherpa-onnx: 1. SHERPA_ONNX_VERSION env 2. ANDROID_RELEASE_TAG 3. property 4. default
15
+ def sherpaOnnxVersion = System.getenv('SHERPA_ONNX_VERSION')
16
+ if (!sherpaOnnxVersion) {
17
+ def v = readVersionFromTagFile(new File(rootDir, 'third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG'), 'sherpa-onnx-android-v')
18
+ sherpaOnnxVersion = v ?: (project.hasProperty('sherpaOnnxVersion') ? project.sherpaOnnxVersion : '1.12.24')
19
+ }
20
+ project.ext.sherpaOnnxVersion = sherpaOnnxVersion
21
+
22
+ // FFmpeg: 1. FFMPEG_VERSION env 2. ANDROID_RELEASE_TAG 3. property 4. default
23
+ def ffmpegVersion = System.getenv('FFMPEG_VERSION')
24
+ if (!ffmpegVersion) {
25
+ def v = readVersionFromTagFile(new File(rootDir, 'third_party/ffmpeg_prebuilt/ANDROID_RELEASE_TAG'), 'ffmpeg-android-v')
26
+ ffmpegVersion = v ?: (project.hasProperty('ffmpegVersion') ? project.ffmpegVersion : '8.0.1')
27
+ }
28
+ project.ext.ffmpegVersion = ffmpegVersion
29
+
30
+ // libarchive: 1. LIBARCHIVE_VERSION env 2. ANDROID_RELEASE_TAG 3. property 4. default
31
+ def libarchiveVersion = System.getenv('LIBARCHIVE_VERSION')
32
+ if (!libarchiveVersion) {
33
+ def v = readVersionFromTagFile(new File(rootDir, 'third_party/libarchive_prebuilt/ANDROID_RELEASE_TAG'), 'libarchive-android-v')
34
+ libarchiveVersion = v ?: (project.hasProperty('libarchiveVersion') ? project.libarchiveVersion : '3.8.5')
35
+ }
36
+ project.ext.libarchiveVersion = libarchiveVersion
37
+
38
+ // onnxruntime (ORT Java bridge): 1. ORT_VERSION env 2. property 3. default
39
+ def ortVersion = System.getenv('ORT_VERSION')
40
+ if (!ortVersion) {
41
+ ortVersion = project.hasProperty('ortVersion') ? project.ortVersion : '1.24.2-qnn2.43.1.260218'
42
+ }
43
+ project.ext.ortVersion = ortVersion
@@ -0,0 +1,10 @@
1
+ # Consumer ProGuard rules for react-native-sherpa-onnx.
2
+ # These are merged into the app's ProGuard config when the library is used in release builds.
3
+
4
+ # JNI: native code looks up progress callback by class and method "invoke(JJD)V".
5
+ # R8/ProGuard must not rename or remove the callback class or method.
6
+ -keep class com.sherpaonnx.SherpaOnnxArchiveHelper { *; }
7
+ -keep class com.sherpaonnx.SherpaOnnxArchiveHelper$* { *; }
8
+
9
+ # ORT Java bridge: loaded via JNI from libonnxruntime4j_jni.so.
10
+ -keep class ai.onnxruntime.** { *; }
@@ -0,0 +1,28 @@
1
+ 
2
+ :�
3
+ 
4
+ A
5
+ B
6
+ add_outputadd_0"Add
7
+ '
8
+
9
+ add_output
10
+ B
11
+ mul_outputmul_0"Mul
12
+ 
13
+
14
+ mul_output
15
+ ACadd_1"Add
16
+ Main_graphZ
17
+ A
18
+ 
19
+ 
20
+ Z
21
+ B
22
+ 
23
+ 
24
+ b
25
+ C
26
+ 
27
+ 
28
+ B