@mentra/bluetooth-sdk 0.1.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 (278) hide show
  1. package/README.md +278 -0
  2. package/android/build.gradle +167 -0
  3. package/android/lc3Lib/CMakeLists.txt +6 -0
  4. package/android/lc3Lib/build.gradle +109 -0
  5. package/android/lc3Lib/proguard-rules.pro +33 -0
  6. package/android/lc3Lib/src/main/AndroidManifest.xml +2 -0
  7. package/android/lc3Lib/src/main/cpp/CMakeLists.txt +8 -0
  8. package/android/lc3Lib/src/main/cpp/google_opus_stuff/CMakeLists.txt +30 -0
  9. package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/CMakeLists.txt +7 -0
  10. package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.cc +96 -0
  11. package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.h +53 -0
  12. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/Makefile.am +6 -0
  13. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h +26 -0
  14. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h.in +26 -0
  15. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/ogg.h +209 -0
  16. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/os_types.h +158 -0
  17. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus.h +981 -0
  18. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_custom.h +342 -0
  19. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_defines.h +799 -0
  20. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_multistream.h +660 -0
  21. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_projection.h +568 -0
  22. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_types.h +166 -0
  23. package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.cc +268 -0
  24. package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.h +115 -0
  25. package/android/lc3Lib/src/main/cpp/google_opus_stuff/opus_tools/opus_header.h +59 -0
  26. package/android/lc3Lib/src/main/cpp/liblc3/CMakeLists.txt +38 -0
  27. package/android/lc3Lib/src/main/cpp/liblc3/include/lc3.h +309 -0
  28. package/android/lc3Lib/src/main/cpp/liblc3/include/lc3_private.h +162 -0
  29. package/android/lc3Lib/src/main/cpp/liblc3/include/rnnoise.h +114 -0
  30. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/CMakeLists.txt +19 -0
  31. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.c +92 -0
  32. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.h +44 -0
  33. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.c +375 -0
  34. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.h +315 -0
  35. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.c +129 -0
  36. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.h +69 -0
  37. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/common.h +148 -0
  38. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.c +70 -0
  39. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.h +43 -0
  40. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/fastmath.h +158 -0
  41. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/lc3.c +702 -0
  42. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.c +893 -0
  43. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.h +111 -0
  44. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_arm.h +506 -0
  45. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_neon.h +281 -0
  46. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/makefile.mk +35 -0
  47. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.c +452 -0
  48. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.h +57 -0
  49. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct_neon.h +296 -0
  50. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/meson.build +46 -0
  51. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.c +61 -0
  52. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.h +57 -0
  53. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.c +880 -0
  54. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.h +103 -0
  55. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.c +904 -0
  56. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.h +119 -0
  57. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.c +3457 -0
  58. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.h +94 -0
  59. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.c +457 -0
  60. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.h +99 -0
  61. package/android/lc3Lib/src/main/cpp/liblc3/liblc3.cpp +159 -0
  62. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/_kiss_fft_guts.h +182 -0
  63. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/arch.h +261 -0
  64. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.c +279 -0
  65. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.h +59 -0
  66. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/common.h +48 -0
  67. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/compile.sh +3 -0
  68. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/denoise.c +646 -0
  69. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.c +601 -0
  70. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.h +203 -0
  71. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/opus_types.h +159 -0
  72. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.c +526 -0
  73. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.h +149 -0
  74. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.c +178 -0
  75. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.h +69 -0
  76. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.c +11051 -0
  77. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.h +34 -0
  78. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_reader.c +168 -0
  79. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_train.py +66 -0
  80. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/tansig_table.h +45 -0
  81. package/android/lc3Lib/src/main/java/com/mentra/lc3Lib/Lc3Cpp.java +38 -0
  82. package/android/lc3Lib/third_party/CMakeLists.txt +23 -0
  83. package/android/lc3Lib/third_party/CMakeLists_libogg.txt +18 -0
  84. package/android/lc3Lib/third_party/CMakeLists_libopus.txt +18 -0
  85. package/android/lc3Lib/third_party/CMakeLists_opus-tools.txt +23 -0
  86. package/android/lc3Lib/third_party/opus_tools/src/AUTHORS +5 -0
  87. package/android/lc3Lib/third_party/opus_tools/src/CMakeLists.txt +4 -0
  88. package/android/lc3Lib/third_party/opus_tools/src/COPYING +371 -0
  89. package/android/lc3Lib/third_party/opus_tools/src/ChangeLog +3 -0
  90. package/android/lc3Lib/third_party/opus_tools/src/Makefile.am +42 -0
  91. package/android/lc3Lib/third_party/opus_tools/src/Makefile.unix +23 -0
  92. package/android/lc3Lib/third_party/opus_tools/src/NEWS +0 -0
  93. package/android/lc3Lib/third_party/opus_tools/src/README +0 -0
  94. package/android/lc3Lib/third_party/opus_tools/src/autogen.sh +115 -0
  95. package/android/lc3Lib/third_party/opus_tools/src/configure.ac +293 -0
  96. package/android/lc3Lib/third_party/opus_tools/src/src/arch.h +239 -0
  97. package/android/lc3Lib/third_party/opus_tools/src/src/audio-in.c +1046 -0
  98. package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.c +245 -0
  99. package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.h +28 -0
  100. package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.c +320 -0
  101. package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.h +51 -0
  102. package/android/lc3Lib/third_party/opus_tools/src/src/lpc.c +157 -0
  103. package/android/lc3Lib/third_party/opus_tools/src/src/lpc.h +27 -0
  104. package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.c +286 -0
  105. package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.h +59 -0
  106. package/android/lc3Lib/third_party/opus_tools/src/src/opusdec.c +884 -0
  107. package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.c +1021 -0
  108. package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.h +101 -0
  109. package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.c +639 -0
  110. package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.h +51 -0
  111. package/android/lc3Lib/third_party/opus_tools/src/src/os_support.h +167 -0
  112. package/android/lc3Lib/third_party/opus_tools/src/src/resample.c +1137 -0
  113. package/android/lc3Lib/third_party/opus_tools/src/src/speex_resampler.h +344 -0
  114. package/android/lc3Lib/third_party/opus_tools/src/src/stack_alloc.h +115 -0
  115. package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.c +125 -0
  116. package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.h +62 -0
  117. package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.c +223 -0
  118. package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.h +60 -0
  119. package/android/settings.gradle +1 -0
  120. package/android/src/main/AndroidManifest.xml +40 -0
  121. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +528 -0
  122. package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +610 -0
  123. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +1616 -0
  124. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +314 -0
  125. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothModels.kt +1710 -0
  126. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +554 -0
  127. package/android/src/main/java/com/mentra/bluetoothsdk/ObservableStore.kt +68 -0
  128. package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +158 -0
  129. package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +934 -0
  130. package/android/src/main/java/com/mentra/bluetoothsdk/services/Foreground.kt +175 -0
  131. package/android/src/main/java/com/mentra/bluetoothsdk/services/PhoneMic.kt +1109 -0
  132. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +3974 -0
  133. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +3551 -0
  134. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +1327 -0
  135. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +6959 -0
  136. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +1655 -0
  137. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraosBle.java +53675 -0
  138. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +202 -0
  139. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +224 -0
  140. package/android/src/main/java/com/mentra/bluetoothsdk/stt/STTTools.kt +340 -0
  141. package/android/src/main/java/com/mentra/bluetoothsdk/stt/SherpaOnnxTranscriber.kt +465 -0
  142. package/android/src/main/java/com/mentra/bluetoothsdk/stt/VadGateSpeechPolicy.kt +221 -0
  143. package/android/src/main/java/com/mentra/bluetoothsdk/utils/AES.java +106 -0
  144. package/android/src/main/java/com/mentra/bluetoothsdk/utils/AudioSessionMonitor.kt +189 -0
  145. package/android/src/main/java/com/mentra/bluetoothsdk/utils/BitmapJavaUtils.java +169 -0
  146. package/android/src/main/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadService.java +179 -0
  147. package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +44 -0
  148. package/android/src/main/java/com/mentra/bluetoothsdk/utils/G1Text.kt +436 -0
  149. package/android/src/main/java/com/mentra/bluetoothsdk/utils/IncidentLogBleRelayNaming.java +29 -0
  150. package/android/src/main/java/com/mentra/bluetoothsdk/utils/IncidentLogBleUploadService.java +76 -0
  151. package/android/src/main/java/com/mentra/bluetoothsdk/utils/K900ProtocolUtils.java +791 -0
  152. package/android/src/main/java/com/mentra/bluetoothsdk/utils/MessageChunker.java +186 -0
  153. package/android/src/main/java/com/mentra/bluetoothsdk/utils/NexSGCUtils.kt +589 -0
  154. package/android/src/main/java/com/mentra/bluetoothsdk/utils/PhoneAudioMonitor.kt +303 -0
  155. package/android/src/main/java/com/mentra/bluetoothsdk/utils/SmartGlassesConnectionState.java +9 -0
  156. package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/ByteUtilAudioPlayer.java +655 -0
  157. package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/Lc3Player.java +441 -0
  158. package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/PCMAudioPlayer.java +431 -0
  159. package/android/src/main/res/values/strings.xml +4 -0
  160. package/app.plugin.js +1 -0
  161. package/build/BluetoothSdk.types.d.ts +498 -0
  162. package/build/BluetoothSdk.types.d.ts.map +1 -0
  163. package/build/BluetoothSdk.types.js +23 -0
  164. package/build/BluetoothSdk.types.js.map +1 -0
  165. package/build/BluetoothSdkModule.d.ts +71 -0
  166. package/build/BluetoothSdkModule.d.ts.map +1 -0
  167. package/build/BluetoothSdkModule.js +106 -0
  168. package/build/BluetoothSdkModule.js.map +1 -0
  169. package/build/index.d.ts +3 -0
  170. package/build/index.d.ts.map +1 -0
  171. package/build/index.js +5 -0
  172. package/build/index.js.map +1 -0
  173. package/expo-module.config.json +9 -0
  174. package/ios/BluetoothSdkModule.swift +665 -0
  175. package/ios/MentraBluetoothSDK.podspec +77 -0
  176. package/ios/Packages/CoreObjC/CoreObjC.xcodeproj/project.pbxproj +213 -0
  177. package/ios/Packages/CoreObjC/PcmConverter.h +22 -0
  178. package/ios/Packages/CoreObjC/PcmConverter.m +266 -0
  179. package/ios/Packages/CoreObjC/attdet.c +92 -0
  180. package/ios/Packages/CoreObjC/attdet.h +44 -0
  181. package/ios/Packages/CoreObjC/bits.c +375 -0
  182. package/ios/Packages/CoreObjC/bits.h +315 -0
  183. package/ios/Packages/CoreObjC/bwdet.c +129 -0
  184. package/ios/Packages/CoreObjC/bwdet.h +69 -0
  185. package/ios/Packages/CoreObjC/common.h +151 -0
  186. package/ios/Packages/CoreObjC/energy.c +70 -0
  187. package/ios/Packages/CoreObjC/energy.h +43 -0
  188. package/ios/Packages/CoreObjC/fastmath.h +158 -0
  189. package/ios/Packages/CoreObjC/lc3.c +704 -0
  190. package/ios/Packages/CoreObjC/lc3.h +313 -0
  191. package/ios/Packages/CoreObjC/lc3_cpp.h +283 -0
  192. package/ios/Packages/CoreObjC/lc3_private.h +163 -0
  193. package/ios/Packages/CoreObjC/ltpf.c +905 -0
  194. package/ios/Packages/CoreObjC/ltpf.h +111 -0
  195. package/ios/Packages/CoreObjC/ltpf_arm.h +506 -0
  196. package/ios/Packages/CoreObjC/ltpf_neon.h +281 -0
  197. package/ios/Packages/CoreObjC/makefile.mk +35 -0
  198. package/ios/Packages/CoreObjC/mdct.c +469 -0
  199. package/ios/Packages/CoreObjC/mdct.h +57 -0
  200. package/ios/Packages/CoreObjC/mdct_neon.h +296 -0
  201. package/ios/Packages/CoreObjC/meson.build +61 -0
  202. package/ios/Packages/CoreObjC/plc.c +61 -0
  203. package/ios/Packages/CoreObjC/plc.h +57 -0
  204. package/ios/Packages/CoreObjC/rnnoise.h +114 -0
  205. package/ios/Packages/CoreObjC/sns.c +880 -0
  206. package/ios/Packages/CoreObjC/sns.h +103 -0
  207. package/ios/Packages/CoreObjC/spec.c +907 -0
  208. package/ios/Packages/CoreObjC/spec.h +119 -0
  209. package/ios/Packages/CoreObjC/tables.c +3457 -0
  210. package/ios/Packages/CoreObjC/tables.h +94 -0
  211. package/ios/Packages/CoreObjC/tns.c +457 -0
  212. package/ios/Packages/CoreObjC/tns.h +99 -0
  213. package/ios/Packages/SherpaOnnx/Model/joiner.onnx +0 -0
  214. package/ios/Packages/SherpaOnnx/Model/tokens.txt +502 -0
  215. package/ios/Packages/SherpaOnnx/SherpaOnnx.swift +1659 -0
  216. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/cargs.h +162 -0
  217. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/c-api.h +1852 -0
  218. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/cxx-api.h +674 -0
  219. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Info.plist +44 -0
  220. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/libsherpa-onnx.a +0 -0
  221. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/sherpa-onnx.a +0 -0
  222. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/libsherpa-onnx.a +0 -0
  223. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/sherpa-onnx.a +0 -0
  224. package/ios/Packages/VAD/Common/VAD/VADQuality.swift +41 -0
  225. package/ios/Packages/VAD/Common/VAD/VADState.swift +26 -0
  226. package/ios/Packages/VAD/Common/VAD/VADStrategy.swift +29 -0
  227. package/ios/Packages/VAD/Common/VAD/VADType.swift +14 -0
  228. package/ios/Packages/VAD/Data/Configuration.swift +68 -0
  229. package/ios/Packages/VAD/Data/FrameSize.swift +39 -0
  230. package/ios/Packages/VAD/Data/Record.swift +13 -0
  231. package/ios/Packages/VAD/Data/Result.swift +22 -0
  232. package/ios/Packages/VAD/Data/SampleRate.swift +48 -0
  233. package/ios/Packages/VAD/Silero/Model/silero_vad.onnx +0 -0
  234. package/ios/Packages/VAD/Silero/SileroVAD.swift +284 -0
  235. package/ios/Packages/VAD/Silero/SileroVADStrategy.swift +64 -0
  236. package/ios/Packages/libbz2/module.modulemap +5 -0
  237. package/ios/Packages/libbz2/shim.h +1 -0
  238. package/ios/Source/Bridge.swift +353 -0
  239. package/ios/Source/Bridging-Header.h +16 -0
  240. package/ios/Source/DeviceManager.swift +1478 -0
  241. package/ios/Source/DeviceStore.swift +295 -0
  242. package/ios/Source/MentraBluetoothSDK.swift +2439 -0
  243. package/ios/Source/ObservableStore.swift +88 -0
  244. package/ios/Source/PrivacyInfo.xcprivacy +23 -0
  245. package/ios/Source/controllers/ControllerManager.swift +187 -0
  246. package/ios/Source/controllers/R1.swift +827 -0
  247. package/ios/Source/services/PhoneMic.swift +662 -0
  248. package/ios/Source/sgcs/Frame.swift +651 -0
  249. package/ios/Source/sgcs/G1.swift +2505 -0
  250. package/ios/Source/sgcs/G2.swift +3730 -0
  251. package/ios/Source/sgcs/Mach1.swift +543 -0
  252. package/ios/Source/sgcs/MentraLive.swift +4708 -0
  253. package/ios/Source/sgcs/MentraNex.swift +2479 -0
  254. package/ios/Source/sgcs/SGCManager.swift +243 -0
  255. package/ios/Source/sgcs/Simulated.swift +270 -0
  256. package/ios/Source/sgcs/mentraos_ble.pb.swift +3811 -0
  257. package/ios/Source/stt/STTTools.swift +154 -0
  258. package/ios/Source/stt/SherpaOnnxTranscriber.swift +401 -0
  259. package/ios/Source/utils/AudioSessionMonitor.swift +283 -0
  260. package/ios/Source/utils/Constants.swift +74 -0
  261. package/ios/Source/utils/Enums.swift +95 -0
  262. package/ios/Source/utils/G1Text.swift +2067 -0
  263. package/ios/Source/utils/JSCExperiment.swift +241 -0
  264. package/ios/Source/utils/MemoryMonitor.swift +44 -0
  265. package/ios/Source/utils/MessageChunker.swift +164 -0
  266. package/ios/Source/utils/Models.swift +135 -0
  267. package/ios/Source/utils/PhoneAudioMonitor.swift +226 -0
  268. package/ios/Source/utils/TarBz2Extractor.swift +206 -0
  269. package/package.json +78 -0
  270. package/plugin/build/index.d.ts +6 -0
  271. package/plugin/build/index.js +12 -0
  272. package/plugin/build/withAndroid.d.ts +4 -0
  273. package/plugin/build/withAndroid.js +80 -0
  274. package/plugin/build/withIos.d.ts +4 -0
  275. package/plugin/build/withIos.js +64 -0
  276. package/src/BluetoothSdk.types.ts +581 -0
  277. package/src/BluetoothSdkModule.ts +259 -0
  278. package/src/index.ts +4 -0
@@ -0,0 +1,1659 @@
1
+ // swift-api-examples/SherpaOnnx.swift
2
+ // Copyright (c) 2023 Xiaomi Corporation
3
+
4
+ import Foundation // For NSString
5
+
6
+ // Convert a String from swift to a `const char*` so that we can pass it to
7
+ // the C language.
8
+ //
9
+ // - Parameters:
10
+ // - s: The String to convert.
11
+ // - Returns: A pointer that can be passed to C as `const char*`
12
+
13
+ func toCPointer(_ s: String) -> UnsafePointer<Int8>! {
14
+ let cs = (s as NSString).utf8String
15
+ return UnsafePointer<Int8>(cs)
16
+ }
17
+
18
+ /// Return an instance of SherpaOnnxOnlineTransducerModelConfig.
19
+ ///
20
+ /// Please refer to
21
+ /// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-transducer/index.html
22
+ /// to download the required `.onnx` files.
23
+ ///
24
+ /// - Parameters:
25
+ /// - encoder: Path to encoder.onnx
26
+ /// - decoder: Path to decoder.onnx
27
+ /// - joiner: Path to joiner.onnx
28
+ ///
29
+ /// - Returns: Return an instance of SherpaOnnxOnlineTransducerModelConfig
30
+ func sherpaOnnxOnlineTransducerModelConfig(
31
+ encoder: String = "",
32
+ decoder: String = "",
33
+ joiner: String = ""
34
+ ) -> SherpaOnnxOnlineTransducerModelConfig {
35
+ return SherpaOnnxOnlineTransducerModelConfig(
36
+ encoder: toCPointer(encoder),
37
+ decoder: toCPointer(decoder),
38
+ joiner: toCPointer(joiner)
39
+ )
40
+ }
41
+
42
+ /// Return an instance of SherpaOnnxOnlineParaformerModelConfig.
43
+ ///
44
+ /// Please refer to
45
+ /// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-paraformer/index.html
46
+ /// to download the required `.onnx` files.
47
+ ///
48
+ /// - Parameters:
49
+ /// - encoder: Path to encoder.onnx
50
+ /// - decoder: Path to decoder.onnx
51
+ ///
52
+ /// - Returns: Return an instance of SherpaOnnxOnlineParaformerModelConfig
53
+ func sherpaOnnxOnlineParaformerModelConfig(
54
+ encoder: String = "",
55
+ decoder: String = ""
56
+ ) -> SherpaOnnxOnlineParaformerModelConfig {
57
+ return SherpaOnnxOnlineParaformerModelConfig(
58
+ encoder: toCPointer(encoder),
59
+ decoder: toCPointer(decoder)
60
+ )
61
+ }
62
+
63
+ func sherpaOnnxOnlineZipformer2CtcModelConfig(
64
+ model: String = ""
65
+ ) -> SherpaOnnxOnlineZipformer2CtcModelConfig {
66
+ return SherpaOnnxOnlineZipformer2CtcModelConfig(
67
+ model: toCPointer(model)
68
+ )
69
+ }
70
+
71
+ func sherpaOnnxOnlineNemoCtcModelConfig(
72
+ model: String = ""
73
+ ) -> SherpaOnnxOnlineNemoCtcModelConfig {
74
+ return SherpaOnnxOnlineNemoCtcModelConfig(
75
+ model: toCPointer(model)
76
+ )
77
+ }
78
+
79
+ /// Return an instance of SherpaOnnxOnlineModelConfig.
80
+ ///
81
+ /// Please refer to
82
+ /// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
83
+ /// to download the required `.onnx` files.
84
+ ///
85
+ /// - Parameters:
86
+ /// - tokens: Path to tokens.txt
87
+ /// - numThreads: Number of threads to use for neural network computation.
88
+ ///
89
+ /// - Returns: Return an instance of SherpaOnnxOnlineTransducerModelConfig
90
+ func sherpaOnnxOnlineModelConfig(
91
+ tokens: String,
92
+ transducer: SherpaOnnxOnlineTransducerModelConfig = sherpaOnnxOnlineTransducerModelConfig(),
93
+ paraformer: SherpaOnnxOnlineParaformerModelConfig = sherpaOnnxOnlineParaformerModelConfig(),
94
+ zipformer2Ctc: SherpaOnnxOnlineZipformer2CtcModelConfig =
95
+ sherpaOnnxOnlineZipformer2CtcModelConfig(),
96
+ numThreads: Int = 1,
97
+ provider: String = "cpu",
98
+ debug: Int = 0,
99
+ modelType: String = "",
100
+ modelingUnit: String = "cjkchar",
101
+ bpeVocab: String = "",
102
+ tokensBuf: String = "",
103
+ tokensBufSize: Int = 0,
104
+ nemoCtc: SherpaOnnxOnlineNemoCtcModelConfig = sherpaOnnxOnlineNemoCtcModelConfig()
105
+ ) -> SherpaOnnxOnlineModelConfig {
106
+ return SherpaOnnxOnlineModelConfig(
107
+ transducer: transducer,
108
+ paraformer: paraformer,
109
+ zipformer2_ctc: zipformer2Ctc,
110
+ tokens: toCPointer(tokens),
111
+ num_threads: Int32(numThreads),
112
+ provider: toCPointer(provider),
113
+ debug: Int32(debug),
114
+ model_type: toCPointer(modelType),
115
+ modeling_unit: toCPointer(modelingUnit),
116
+ bpe_vocab: toCPointer(bpeVocab),
117
+ tokens_buf: toCPointer(tokensBuf),
118
+ tokens_buf_size: Int32(tokensBufSize),
119
+ nemo_ctc: nemoCtc
120
+ )
121
+ }
122
+
123
+ func sherpaOnnxFeatureConfig(
124
+ sampleRate: Int = 16000,
125
+ featureDim: Int = 80
126
+ ) -> SherpaOnnxFeatureConfig {
127
+ return SherpaOnnxFeatureConfig(
128
+ sample_rate: Int32(sampleRate),
129
+ feature_dim: Int32(featureDim)
130
+ )
131
+ }
132
+
133
+ func sherpaOnnxOnlineCtcFstDecoderConfig(
134
+ graph: String = "",
135
+ maxActive: Int = 3000
136
+ ) -> SherpaOnnxOnlineCtcFstDecoderConfig {
137
+ return SherpaOnnxOnlineCtcFstDecoderConfig(
138
+ graph: toCPointer(graph),
139
+ max_active: Int32(maxActive)
140
+ )
141
+ }
142
+
143
+ func sherpaOnnxHomophoneReplacerConfig(
144
+ dictDir: String = "",
145
+ lexicon: String = "",
146
+ ruleFsts: String = ""
147
+ ) -> SherpaOnnxHomophoneReplacerConfig {
148
+ return SherpaOnnxHomophoneReplacerConfig(
149
+ dict_dir: toCPointer(dictDir),
150
+ lexicon: toCPointer(lexicon),
151
+ rule_fsts: toCPointer(ruleFsts)
152
+ )
153
+ }
154
+
155
+ func sherpaOnnxOnlineRecognizerConfig(
156
+ featConfig: SherpaOnnxFeatureConfig,
157
+ modelConfig: SherpaOnnxOnlineModelConfig,
158
+ enableEndpoint: Bool = false,
159
+ rule1MinTrailingSilence: Float = 2.4,
160
+ rule2MinTrailingSilence: Float = 1.2,
161
+ rule3MinUtteranceLength: Float = 30,
162
+ decodingMethod: String = "greedy_search",
163
+ maxActivePaths: Int = 4,
164
+ hotwordsFile: String = "",
165
+ hotwordsScore: Float = 1.5,
166
+ ctcFstDecoderConfig: SherpaOnnxOnlineCtcFstDecoderConfig = sherpaOnnxOnlineCtcFstDecoderConfig(),
167
+ ruleFsts: String = "",
168
+ ruleFars: String = "",
169
+ blankPenalty: Float = 0.0,
170
+ hotwordsBuf: String = "",
171
+ hotwordsBufSize: Int = 0,
172
+ hr: SherpaOnnxHomophoneReplacerConfig = sherpaOnnxHomophoneReplacerConfig()
173
+ ) -> SherpaOnnxOnlineRecognizerConfig {
174
+ return SherpaOnnxOnlineRecognizerConfig(
175
+ feat_config: featConfig,
176
+ model_config: modelConfig,
177
+ decoding_method: toCPointer(decodingMethod),
178
+ max_active_paths: Int32(maxActivePaths),
179
+ enable_endpoint: enableEndpoint ? 1 : 0,
180
+ rule1_min_trailing_silence: rule1MinTrailingSilence,
181
+ rule2_min_trailing_silence: rule2MinTrailingSilence,
182
+ rule3_min_utterance_length: rule3MinUtteranceLength,
183
+ hotwords_file: toCPointer(hotwordsFile),
184
+ hotwords_score: hotwordsScore,
185
+ ctc_fst_decoder_config: ctcFstDecoderConfig,
186
+ rule_fsts: toCPointer(ruleFsts),
187
+ rule_fars: toCPointer(ruleFars),
188
+ blank_penalty: blankPenalty,
189
+ hotwords_buf: toCPointer(hotwordsBuf),
190
+ hotwords_buf_size: Int32(hotwordsBufSize),
191
+ hr: hr
192
+ )
193
+ }
194
+
195
+ /// Wrapper for recognition result.
196
+ ///
197
+ /// Usage:
198
+ ///
199
+ /// let result = recognizer.getResult()
200
+ /// print("text: \(result.text)")
201
+ ///
202
+ class SherpaOnnxOnlineRecongitionResult {
203
+ /// A pointer to the underlying counterpart in C
204
+ private let result: UnsafePointer<SherpaOnnxOnlineRecognizerResult>
205
+
206
+ private lazy var _text: String = {
207
+ guard let cstr = result.pointee.text else { return "" }
208
+ return String(cString: cstr)
209
+ }()
210
+
211
+ private lazy var _tokens: [String] = {
212
+ guard let tokensPointer = result.pointee.tokens_arr else { return [] }
213
+ return (0 ..< count).compactMap { index in
214
+ guard let ptr = tokensPointer[index] else { return nil }
215
+ return String(cString: ptr)
216
+ }
217
+ }()
218
+
219
+ private lazy var _timestamps: [Float] = {
220
+ guard let timestampsPointer = result.pointee.timestamps else { return [] }
221
+ return (0 ..< count).map { index in timestampsPointer[index] }
222
+ }()
223
+
224
+ init(result: UnsafePointer<SherpaOnnxOnlineRecognizerResult>) {
225
+ self.result = result
226
+ }
227
+
228
+ deinit {
229
+ SherpaOnnxDestroyOnlineRecognizerResult(result)
230
+ }
231
+
232
+ /// Return the actual recognition result.
233
+ /// For English models, it contains words separated by spaces.
234
+ /// For Chinese models, it contains Chinese words.
235
+ var text: String {
236
+ _text
237
+ }
238
+
239
+ var count: Int {
240
+ Int(result.pointee.count)
241
+ }
242
+
243
+ var tokens: [String] {
244
+ _tokens
245
+ }
246
+
247
+ var timestamps: [Float] {
248
+ _timestamps
249
+ }
250
+ }
251
+
252
+ class SherpaOnnxRecognizer {
253
+ /// A pointer to the underlying counterpart in C
254
+ private let recognizer: OpaquePointer
255
+ private var stream: OpaquePointer
256
+ private let lock = NSLock() // for thread-safe stream replacement
257
+
258
+ /// Constructor taking a model config
259
+ init(
260
+ config: UnsafePointer<SherpaOnnxOnlineRecognizerConfig>
261
+ ) {
262
+ recognizer = SherpaOnnxCreateOnlineRecognizer(config)
263
+ stream = SherpaOnnxCreateOnlineStream(recognizer)
264
+ }
265
+
266
+ deinit {
267
+ SherpaOnnxDestroyOnlineStream(stream)
268
+ SherpaOnnxDestroyOnlineRecognizer(recognizer)
269
+ }
270
+
271
+ /// Decode wave samples.
272
+ ///
273
+ /// - Parameters:
274
+ /// - samples: Audio samples normalized to the range [-1, 1]
275
+ /// - sampleRate: Sample rate of the input audio samples. Must match
276
+ /// the one expected by the model.
277
+ func acceptWaveform(samples: [Float], sampleRate: Int = 16000) {
278
+ SherpaOnnxOnlineStreamAcceptWaveform(stream, Int32(sampleRate), samples, Int32(samples.count))
279
+ }
280
+
281
+ func isReady() -> Bool {
282
+ return SherpaOnnxIsOnlineStreamReady(recognizer, stream) != 0
283
+ }
284
+
285
+ /// If there are enough number of feature frames, it invokes the neural
286
+ /// network computation and decoding. Otherwise, it is a no-op.
287
+ func decode() {
288
+ SherpaOnnxDecodeOnlineStream(recognizer, stream)
289
+ }
290
+
291
+ /// Get the decoding results so far
292
+ func getResult() -> SherpaOnnxOnlineRecongitionResult {
293
+ guard let result = SherpaOnnxGetOnlineStreamResult(recognizer, stream) else {
294
+ fatalError("SherpaOnnxGetOnlineStreamResult returned nil")
295
+ }
296
+ return SherpaOnnxOnlineRecongitionResult(result: result)
297
+ }
298
+
299
+ /// Reset the recognizer, which clears the neural network model state
300
+ /// and the state for decoding.
301
+ /// If hotwords is an empty string, it just recreates the decoding stream
302
+ /// If hotwords is not empty, it will create a new decoding stream with
303
+ /// the given hotWords appended to the default hotwords.
304
+ func reset(hotwords: String? = nil) {
305
+ guard let words = hotwords, !words.isEmpty else {
306
+ SherpaOnnxOnlineStreamReset(recognizer, stream)
307
+ return
308
+ }
309
+
310
+ words.withCString { cString in
311
+ guard let newStream = SherpaOnnxCreateOnlineStreamWithHotwords(recognizer, cString) else {
312
+ fatalError("SherpaOnnxCreateOnlineStreamWithHotwords returned nil")
313
+ }
314
+ lock.lock()
315
+ // lock while release and replace stream
316
+ SherpaOnnxDestroyOnlineStream(stream)
317
+ stream = newStream
318
+ lock.unlock()
319
+ }
320
+ }
321
+
322
+ /// Signal that no more audio samples would be available.
323
+ /// After this call, you cannot call acceptWaveform() any more.
324
+ func inputFinished() {
325
+ SherpaOnnxOnlineStreamInputFinished(stream)
326
+ }
327
+
328
+ /// Return true is an endpoint has been detected.
329
+ func isEndpoint() -> Bool {
330
+ return SherpaOnnxOnlineStreamIsEndpoint(recognizer, stream) != 0
331
+ }
332
+ }
333
+
334
+ // For offline APIs
335
+
336
+ func sherpaOnnxOfflineTransducerModelConfig(
337
+ encoder: String = "",
338
+ decoder: String = "",
339
+ joiner: String = ""
340
+ ) -> SherpaOnnxOfflineTransducerModelConfig {
341
+ return SherpaOnnxOfflineTransducerModelConfig(
342
+ encoder: toCPointer(encoder),
343
+ decoder: toCPointer(decoder),
344
+ joiner: toCPointer(joiner)
345
+ )
346
+ }
347
+
348
+ func sherpaOnnxOfflineParaformerModelConfig(
349
+ model: String = ""
350
+ ) -> SherpaOnnxOfflineParaformerModelConfig {
351
+ return SherpaOnnxOfflineParaformerModelConfig(
352
+ model: toCPointer(model)
353
+ )
354
+ }
355
+
356
+ func sherpaOnnxOfflineZipformerCtcModelConfig(
357
+ model: String = ""
358
+ ) -> SherpaOnnxOfflineZipformerCtcModelConfig {
359
+ return SherpaOnnxOfflineZipformerCtcModelConfig(
360
+ model: toCPointer(model)
361
+ )
362
+ }
363
+
364
+ func sherpaOnnxOfflineNemoEncDecCtcModelConfig(
365
+ model: String = ""
366
+ ) -> SherpaOnnxOfflineNemoEncDecCtcModelConfig {
367
+ return SherpaOnnxOfflineNemoEncDecCtcModelConfig(
368
+ model: toCPointer(model)
369
+ )
370
+ }
371
+
372
+ func sherpaOnnxOfflineDolphinModelConfig(
373
+ model: String = ""
374
+ ) -> SherpaOnnxOfflineDolphinModelConfig {
375
+ return SherpaOnnxOfflineDolphinModelConfig(
376
+ model: toCPointer(model)
377
+ )
378
+ }
379
+
380
+ func sherpaOnnxOfflineWhisperModelConfig(
381
+ encoder: String = "",
382
+ decoder: String = "",
383
+ language: String = "",
384
+ task: String = "transcribe",
385
+ tailPaddings: Int = -1
386
+ ) -> SherpaOnnxOfflineWhisperModelConfig {
387
+ return SherpaOnnxOfflineWhisperModelConfig(
388
+ encoder: toCPointer(encoder),
389
+ decoder: toCPointer(decoder),
390
+ language: toCPointer(language),
391
+ task: toCPointer(task),
392
+ tail_paddings: Int32(tailPaddings)
393
+ )
394
+ }
395
+
396
+ func sherpaOnnxOfflineCanaryModelConfig(
397
+ encoder: String = "",
398
+ decoder: String = "",
399
+ srcLang: String = "en",
400
+ tgtLang: String = "en",
401
+ usePnc: Bool = true
402
+ ) -> SherpaOnnxOfflineCanaryModelConfig {
403
+ return SherpaOnnxOfflineCanaryModelConfig(
404
+ encoder: toCPointer(encoder),
405
+ decoder: toCPointer(decoder),
406
+ src_lang: toCPointer(srcLang),
407
+ tgt_lang: toCPointer(tgtLang),
408
+ use_pnc: usePnc ? 1 : 0
409
+ )
410
+ }
411
+
412
+ func sherpaOnnxOfflineFireRedAsrModelConfig(
413
+ encoder: String = "",
414
+ decoder: String = ""
415
+ ) -> SherpaOnnxOfflineFireRedAsrModelConfig {
416
+ return SherpaOnnxOfflineFireRedAsrModelConfig(
417
+ encoder: toCPointer(encoder),
418
+ decoder: toCPointer(decoder)
419
+ )
420
+ }
421
+
422
+ func sherpaOnnxOfflineMoonshineModelConfig(
423
+ preprocessor: String = "",
424
+ encoder: String = "",
425
+ uncachedDecoder: String = "",
426
+ cachedDecoder: String = ""
427
+ ) -> SherpaOnnxOfflineMoonshineModelConfig {
428
+ return SherpaOnnxOfflineMoonshineModelConfig(
429
+ preprocessor: toCPointer(preprocessor),
430
+ encoder: toCPointer(encoder),
431
+ uncached_decoder: toCPointer(uncachedDecoder),
432
+ cached_decoder: toCPointer(cachedDecoder)
433
+ )
434
+ }
435
+
436
+ func sherpaOnnxOfflineTdnnModelConfig(
437
+ model: String = ""
438
+ ) -> SherpaOnnxOfflineTdnnModelConfig {
439
+ return SherpaOnnxOfflineTdnnModelConfig(
440
+ model: toCPointer(model)
441
+ )
442
+ }
443
+
444
+ func sherpaOnnxOfflineSenseVoiceModelConfig(
445
+ model: String = "",
446
+ language: String = "",
447
+ useInverseTextNormalization: Bool = false
448
+ ) -> SherpaOnnxOfflineSenseVoiceModelConfig {
449
+ return SherpaOnnxOfflineSenseVoiceModelConfig(
450
+ model: toCPointer(model),
451
+ language: toCPointer(language),
452
+ use_itn: useInverseTextNormalization ? 1 : 0
453
+ )
454
+ }
455
+
456
+ func sherpaOnnxOfflineLMConfig(
457
+ model: String = "",
458
+ scale: Float = 1.0
459
+ ) -> SherpaOnnxOfflineLMConfig {
460
+ return SherpaOnnxOfflineLMConfig(
461
+ model: toCPointer(model),
462
+ scale: scale
463
+ )
464
+ }
465
+
466
+ func sherpaOnnxOfflineModelConfig(
467
+ tokens: String,
468
+ transducer: SherpaOnnxOfflineTransducerModelConfig = sherpaOnnxOfflineTransducerModelConfig(),
469
+ paraformer: SherpaOnnxOfflineParaformerModelConfig = sherpaOnnxOfflineParaformerModelConfig(),
470
+ nemoCtc: SherpaOnnxOfflineNemoEncDecCtcModelConfig = sherpaOnnxOfflineNemoEncDecCtcModelConfig(),
471
+ whisper: SherpaOnnxOfflineWhisperModelConfig = sherpaOnnxOfflineWhisperModelConfig(),
472
+ tdnn: SherpaOnnxOfflineTdnnModelConfig = sherpaOnnxOfflineTdnnModelConfig(),
473
+ numThreads: Int = 1,
474
+ provider: String = "cpu",
475
+ debug: Int = 0,
476
+ modelType: String = "",
477
+ modelingUnit: String = "cjkchar",
478
+ bpeVocab: String = "",
479
+ teleSpeechCtc: String = "",
480
+ senseVoice: SherpaOnnxOfflineSenseVoiceModelConfig = sherpaOnnxOfflineSenseVoiceModelConfig(),
481
+ moonshine: SherpaOnnxOfflineMoonshineModelConfig = sherpaOnnxOfflineMoonshineModelConfig(),
482
+ fireRedAsr: SherpaOnnxOfflineFireRedAsrModelConfig = sherpaOnnxOfflineFireRedAsrModelConfig(),
483
+ dolphin: SherpaOnnxOfflineDolphinModelConfig = sherpaOnnxOfflineDolphinModelConfig(),
484
+ zipformerCtc: SherpaOnnxOfflineZipformerCtcModelConfig =
485
+ sherpaOnnxOfflineZipformerCtcModelConfig(),
486
+ canary: SherpaOnnxOfflineCanaryModelConfig = sherpaOnnxOfflineCanaryModelConfig()
487
+ ) -> SherpaOnnxOfflineModelConfig {
488
+ return SherpaOnnxOfflineModelConfig(
489
+ transducer: transducer,
490
+ paraformer: paraformer,
491
+ nemo_ctc: nemoCtc,
492
+ whisper: whisper,
493
+ tdnn: tdnn,
494
+ tokens: toCPointer(tokens),
495
+ num_threads: Int32(numThreads),
496
+ debug: Int32(debug),
497
+ provider: toCPointer(provider),
498
+ model_type: toCPointer(modelType),
499
+ modeling_unit: toCPointer(modelingUnit),
500
+ bpe_vocab: toCPointer(bpeVocab),
501
+ telespeech_ctc: toCPointer(teleSpeechCtc),
502
+ sense_voice: senseVoice,
503
+ moonshine: moonshine,
504
+ fire_red_asr: fireRedAsr,
505
+ dolphin: dolphin,
506
+ zipformer_ctc: zipformerCtc,
507
+ canary: canary
508
+ )
509
+ }
510
+
511
+ func sherpaOnnxOfflineRecognizerConfig(
512
+ featConfig: SherpaOnnxFeatureConfig,
513
+ modelConfig: SherpaOnnxOfflineModelConfig,
514
+ lmConfig: SherpaOnnxOfflineLMConfig = sherpaOnnxOfflineLMConfig(),
515
+ decodingMethod: String = "greedy_search",
516
+ maxActivePaths: Int = 4,
517
+ hotwordsFile: String = "",
518
+ hotwordsScore: Float = 1.5,
519
+ ruleFsts: String = "",
520
+ ruleFars: String = "",
521
+ blankPenalty: Float = 0.0,
522
+ hr: SherpaOnnxHomophoneReplacerConfig = sherpaOnnxHomophoneReplacerConfig()
523
+ ) -> SherpaOnnxOfflineRecognizerConfig {
524
+ return SherpaOnnxOfflineRecognizerConfig(
525
+ feat_config: featConfig,
526
+ model_config: modelConfig,
527
+ lm_config: lmConfig,
528
+ decoding_method: toCPointer(decodingMethod),
529
+ max_active_paths: Int32(maxActivePaths),
530
+ hotwords_file: toCPointer(hotwordsFile),
531
+ hotwords_score: hotwordsScore,
532
+ rule_fsts: toCPointer(ruleFsts),
533
+ rule_fars: toCPointer(ruleFars),
534
+ blank_penalty: blankPenalty,
535
+ hr: hr
536
+ )
537
+ }
538
+
539
+ class SherpaOnnxOfflineRecongitionResult {
540
+ /// A pointer to the underlying counterpart in C
541
+ let result: UnsafePointer<SherpaOnnxOfflineRecognizerResult>
542
+
543
+ private lazy var _text: String = {
544
+ guard let cstr = result.pointee.text else { return "" }
545
+ return String(cString: cstr)
546
+ }()
547
+
548
+ private lazy var _timestamps: [Float] = {
549
+ guard let p = result.pointee.timestamps else { return [] }
550
+ return (0 ..< result.pointee.count).map { p[Int($0)] }
551
+ }()
552
+
553
+ private lazy var _lang: String = {
554
+ guard let cstr = result.pointee.lang else { return "" }
555
+ return String(cString: cstr)
556
+ }()
557
+
558
+ private lazy var _emotion: String = {
559
+ guard let cstr = result.pointee.emotion else { return "" }
560
+ return String(cString: cstr)
561
+ }()
562
+
563
+ private lazy var _event: String = {
564
+ guard let cstr = result.pointee.event else { return "" }
565
+ return String(cString: cstr)
566
+ }()
567
+
568
+ /// Return the actual recognition result.
569
+ /// For English models, it contains words separated by spaces.
570
+ /// For Chinese models, it contains Chinese words.
571
+ var text: String {
572
+ _text
573
+ }
574
+
575
+ var count: Int {
576
+ Int(result.pointee.count)
577
+ }
578
+
579
+ var timestamps: [Float] {
580
+ _timestamps
581
+ }
582
+
583
+ /// For SenseVoice models, it can be zh, en, ja, yue, ko
584
+ /// where zh is for Chinese
585
+ /// en is for English
586
+ /// ja is for Japanese
587
+ /// yue is for Cantonese
588
+ /// ko is for Korean
589
+ var lang: String {
590
+ _lang
591
+ }
592
+
593
+ /// for SenseVoice models
594
+ var emotion: String {
595
+ _emotion
596
+ }
597
+
598
+ /// for SenseVoice models
599
+ var event: String {
600
+ _event
601
+ }
602
+
603
+ init(result: UnsafePointer<SherpaOnnxOfflineRecognizerResult>) {
604
+ self.result = result
605
+ }
606
+
607
+ deinit {
608
+ SherpaOnnxDestroyOfflineRecognizerResult(result)
609
+ }
610
+ }
611
+
612
+ class SherpaOnnxOfflineRecognizer {
613
+ /// A pointer to the underlying counterpart in C
614
+ private let recognizer: OpaquePointer
615
+
616
+ init(
617
+ config: UnsafePointer<SherpaOnnxOfflineRecognizerConfig>
618
+ ) {
619
+ guard let ptr = SherpaOnnxCreateOfflineRecognizer(config) else {
620
+ fatalError("Failed to create SherpaOnnxOfflineRecognizer")
621
+ }
622
+ recognizer = ptr
623
+ }
624
+
625
+ deinit {
626
+ SherpaOnnxDestroyOfflineRecognizer(recognizer)
627
+ }
628
+
629
+ /// Decode wave samples.
630
+ ///
631
+ /// - Parameters:
632
+ /// - samples: Audio samples normalized to the range [-1, 1]
633
+ /// - sampleRate: Sample rate of the input audio samples. Must match
634
+ /// the one expected by the model.
635
+ func decode(samples: [Float], sampleRate: Int = 16000) -> SherpaOnnxOfflineRecongitionResult {
636
+ guard let stream = SherpaOnnxCreateOfflineStream(recognizer) else {
637
+ fatalError("Failed to create offline stream")
638
+ }
639
+
640
+ defer { SherpaOnnxDestroyOfflineStream(stream) }
641
+
642
+ SherpaOnnxAcceptWaveformOffline(stream, Int32(sampleRate), samples, Int32(samples.count))
643
+
644
+ SherpaOnnxDecodeOfflineStream(recognizer, stream)
645
+
646
+ guard let resultPtr = SherpaOnnxGetOfflineStreamResult(stream) else {
647
+ fatalError("Failed to get offline recognition result")
648
+ }
649
+
650
+ return SherpaOnnxOfflineRecongitionResult(result: resultPtr)
651
+ }
652
+
653
+ func setConfig(config: UnsafePointer<SherpaOnnxOfflineRecognizerConfig>) {
654
+ SherpaOnnxOfflineRecognizerSetConfig(recognizer, config)
655
+ }
656
+ }
657
+
658
+ func sherpaOnnxSileroVadModelConfig(
659
+ model: String = "",
660
+ threshold: Float = 0.5,
661
+ minSilenceDuration: Float = 0.25,
662
+ minSpeechDuration: Float = 0.5,
663
+ windowSize: Int = 512,
664
+ maxSpeechDuration: Float = 5.0
665
+ ) -> SherpaOnnxSileroVadModelConfig {
666
+ return SherpaOnnxSileroVadModelConfig(
667
+ model: toCPointer(model),
668
+ threshold: threshold,
669
+ min_silence_duration: minSilenceDuration,
670
+ min_speech_duration: minSpeechDuration,
671
+ window_size: Int32(windowSize),
672
+ max_speech_duration: maxSpeechDuration
673
+ )
674
+ }
675
+
676
+ func sherpaOnnxTenVadModelConfig(
677
+ model: String = "",
678
+ threshold: Float = 0.5,
679
+ minSilenceDuration: Float = 0.25,
680
+ minSpeechDuration: Float = 0.5,
681
+ windowSize: Int = 256,
682
+ maxSpeechDuration: Float = 5.0
683
+ ) -> SherpaOnnxTenVadModelConfig {
684
+ return SherpaOnnxTenVadModelConfig(
685
+ model: toCPointer(model),
686
+ threshold: threshold,
687
+ min_silence_duration: minSilenceDuration,
688
+ min_speech_duration: minSpeechDuration,
689
+ window_size: Int32(windowSize),
690
+ max_speech_duration: maxSpeechDuration
691
+ )
692
+ }
693
+
694
+ func sherpaOnnxVadModelConfig(
695
+ sileroVad: SherpaOnnxSileroVadModelConfig = sherpaOnnxSileroVadModelConfig(),
696
+ sampleRate: Int32 = 16000,
697
+ numThreads: Int = 1,
698
+ provider: String = "cpu",
699
+ debug: Int = 0,
700
+ tenVad: SherpaOnnxTenVadModelConfig = sherpaOnnxTenVadModelConfig()
701
+ ) -> SherpaOnnxVadModelConfig {
702
+ return SherpaOnnxVadModelConfig(
703
+ silero_vad: sileroVad,
704
+ sample_rate: sampleRate,
705
+ num_threads: Int32(numThreads),
706
+ provider: toCPointer(provider),
707
+ debug: Int32(debug),
708
+ ten_vad: tenVad
709
+ )
710
+ }
711
+
712
+ class SherpaOnnxCircularBufferWrapper {
713
+ private let buffer: OpaquePointer
714
+
715
+ init(capacity: Int) {
716
+ guard let ptr = SherpaOnnxCreateCircularBuffer(Int32(capacity)) else {
717
+ fatalError("Failed to create SherpaOnnxCircularBuffer")
718
+ }
719
+ buffer = ptr
720
+ }
721
+
722
+ deinit {
723
+ SherpaOnnxDestroyCircularBuffer(buffer)
724
+ }
725
+
726
+ func push(samples: [Float]) {
727
+ guard !samples.isEmpty else { return }
728
+ SherpaOnnxCircularBufferPush(buffer, samples, Int32(samples.count))
729
+ }
730
+
731
+ func get(startIndex: Int, n: Int) -> [Float] {
732
+ guard startIndex >= 0 else { return [] }
733
+ guard n > 0 else { return [] }
734
+
735
+ guard let ptr = SherpaOnnxCircularBufferGet(buffer, Int32(startIndex), Int32(n)) else {
736
+ return []
737
+ }
738
+ defer { SherpaOnnxCircularBufferFree(ptr) }
739
+
740
+ return Array(UnsafeBufferPointer(start: ptr, count: n))
741
+ }
742
+
743
+ func pop(n: Int) {
744
+ guard n > 0 else { return }
745
+ SherpaOnnxCircularBufferPop(buffer, Int32(n))
746
+ }
747
+
748
+ func size() -> Int {
749
+ return Int(SherpaOnnxCircularBufferSize(buffer))
750
+ }
751
+
752
+ func reset() {
753
+ SherpaOnnxCircularBufferReset(buffer)
754
+ }
755
+ }
756
+
757
+ class SherpaOnnxSpeechSegmentWrapper {
758
+ private let p: UnsafePointer<SherpaOnnxSpeechSegment>
759
+
760
+ init(p: UnsafePointer<SherpaOnnxSpeechSegment>) {
761
+ self.p = p
762
+ }
763
+
764
+ deinit {
765
+ SherpaOnnxDestroySpeechSegment(p)
766
+ }
767
+
768
+ var start: Int {
769
+ Int(p.pointee.start)
770
+ }
771
+
772
+ var n: Int {
773
+ Int(p.pointee.n)
774
+ }
775
+
776
+ lazy var samples: [Float] = Array(UnsafeBufferPointer(start: p.pointee.samples, count: n))
777
+ }
778
+
779
+ class SherpaOnnxVoiceActivityDetectorWrapper {
780
+ /// A pointer to the underlying counterpart in C
781
+ private let vad: OpaquePointer
782
+
783
+ init(config: UnsafePointer<SherpaOnnxVadModelConfig>, buffer_size_in_seconds: Float) {
784
+ guard let vad = SherpaOnnxCreateVoiceActivityDetector(config, buffer_size_in_seconds) else {
785
+ fatalError("SherpaOnnxCreateVoiceActivityDetector returned nil")
786
+ }
787
+ self.vad = vad
788
+ }
789
+
790
+ deinit {
791
+ SherpaOnnxDestroyVoiceActivityDetector(vad)
792
+ }
793
+
794
+ func acceptWaveform(samples: [Float]) {
795
+ SherpaOnnxVoiceActivityDetectorAcceptWaveform(vad, samples, Int32(samples.count))
796
+ }
797
+
798
+ func isEmpty() -> Bool {
799
+ return SherpaOnnxVoiceActivityDetectorEmpty(vad) == 1
800
+ }
801
+
802
+ func isSpeechDetected() -> Bool {
803
+ return SherpaOnnxVoiceActivityDetectorDetected(vad) == 1
804
+ }
805
+
806
+ func pop() {
807
+ SherpaOnnxVoiceActivityDetectorPop(vad)
808
+ }
809
+
810
+ func clear() {
811
+ SherpaOnnxVoiceActivityDetectorClear(vad)
812
+ }
813
+
814
+ func front() -> SherpaOnnxSpeechSegmentWrapper {
815
+ guard let p = SherpaOnnxVoiceActivityDetectorFront(vad) else {
816
+ fatalError("SherpaOnnxVoiceActivityDetectorFront returned nil")
817
+ }
818
+ return SherpaOnnxSpeechSegmentWrapper(p: p)
819
+ }
820
+
821
+ func reset() {
822
+ SherpaOnnxVoiceActivityDetectorReset(vad)
823
+ }
824
+
825
+ func flush() {
826
+ SherpaOnnxVoiceActivityDetectorFlush(vad)
827
+ }
828
+ }
829
+
830
+ /// offline tts
831
+ func sherpaOnnxOfflineTtsVitsModelConfig(
832
+ model: String = "",
833
+ lexicon: String = "",
834
+ tokens: String = "",
835
+ dataDir: String = "",
836
+ noiseScale: Float = 0.667,
837
+ noiseScaleW: Float = 0.8,
838
+ lengthScale: Float = 1.0,
839
+ dictDir: String = ""
840
+ ) -> SherpaOnnxOfflineTtsVitsModelConfig {
841
+ return SherpaOnnxOfflineTtsVitsModelConfig(
842
+ model: toCPointer(model),
843
+ lexicon: toCPointer(lexicon),
844
+ tokens: toCPointer(tokens),
845
+ data_dir: toCPointer(dataDir),
846
+ noise_scale: noiseScale,
847
+ noise_scale_w: noiseScaleW,
848
+ length_scale: lengthScale,
849
+ dict_dir: toCPointer(dictDir)
850
+ )
851
+ }
852
+
853
+ func sherpaOnnxOfflineTtsMatchaModelConfig(
854
+ acousticModel: String = "",
855
+ vocoder: String = "",
856
+ lexicon: String = "",
857
+ tokens: String = "",
858
+ dataDir: String = "",
859
+ noiseScale: Float = 0.667,
860
+ lengthScale: Float = 1.0,
861
+ dictDir: String = ""
862
+ ) -> SherpaOnnxOfflineTtsMatchaModelConfig {
863
+ return SherpaOnnxOfflineTtsMatchaModelConfig(
864
+ acoustic_model: toCPointer(acousticModel),
865
+ vocoder: toCPointer(vocoder),
866
+ lexicon: toCPointer(lexicon),
867
+ tokens: toCPointer(tokens),
868
+ data_dir: toCPointer(dataDir),
869
+ noise_scale: noiseScale,
870
+ length_scale: lengthScale,
871
+ dict_dir: toCPointer(dictDir)
872
+ )
873
+ }
874
+
875
+ func sherpaOnnxOfflineTtsKokoroModelConfig(
876
+ model: String = "",
877
+ voices: String = "",
878
+ tokens: String = "",
879
+ dataDir: String = "",
880
+ lengthScale: Float = 1.0,
881
+ dictDir: String = "",
882
+ lexicon: String = "",
883
+ lang: String = ""
884
+ ) -> SherpaOnnxOfflineTtsKokoroModelConfig {
885
+ return SherpaOnnxOfflineTtsKokoroModelConfig(
886
+ model: toCPointer(model),
887
+ voices: toCPointer(voices),
888
+ tokens: toCPointer(tokens),
889
+ data_dir: toCPointer(dataDir),
890
+ length_scale: lengthScale,
891
+ dict_dir: toCPointer(dictDir),
892
+ lexicon: toCPointer(lexicon),
893
+ lang: toCPointer(lang)
894
+ )
895
+ }
896
+
897
+ func sherpaOnnxOfflineTtsKittenModelConfig(
898
+ model: String = "",
899
+ voices: String = "",
900
+ tokens: String = "",
901
+ dataDir: String = "",
902
+ lengthScale: Float = 1.0
903
+ ) -> SherpaOnnxOfflineTtsKittenModelConfig {
904
+ return SherpaOnnxOfflineTtsKittenModelConfig(
905
+ model: toCPointer(model),
906
+ voices: toCPointer(voices),
907
+ tokens: toCPointer(tokens),
908
+ data_dir: toCPointer(dataDir),
909
+ length_scale: lengthScale
910
+ )
911
+ }
912
+
913
+ func sherpaOnnxOfflineTtsModelConfig(
914
+ vits: SherpaOnnxOfflineTtsVitsModelConfig = sherpaOnnxOfflineTtsVitsModelConfig(),
915
+ matcha: SherpaOnnxOfflineTtsMatchaModelConfig = sherpaOnnxOfflineTtsMatchaModelConfig(),
916
+ kokoro: SherpaOnnxOfflineTtsKokoroModelConfig = sherpaOnnxOfflineTtsKokoroModelConfig(),
917
+ numThreads: Int = 1,
918
+ debug: Int = 0,
919
+ provider: String = "cpu",
920
+ kitten: SherpaOnnxOfflineTtsKittenModelConfig = sherpaOnnxOfflineTtsKittenModelConfig()
921
+ ) -> SherpaOnnxOfflineTtsModelConfig {
922
+ return SherpaOnnxOfflineTtsModelConfig(
923
+ vits: vits,
924
+ num_threads: Int32(numThreads),
925
+ debug: Int32(debug),
926
+ provider: toCPointer(provider),
927
+ matcha: matcha,
928
+ kokoro: kokoro,
929
+ kitten: kitten
930
+ )
931
+ }
932
+
933
+ func sherpaOnnxOfflineTtsConfig(
934
+ model: SherpaOnnxOfflineTtsModelConfig,
935
+ ruleFsts: String = "",
936
+ ruleFars: String = "",
937
+ maxNumSentences: Int = 1,
938
+ silenceScale: Float = 0.2
939
+ ) -> SherpaOnnxOfflineTtsConfig {
940
+ return SherpaOnnxOfflineTtsConfig(
941
+ model: model,
942
+ rule_fsts: toCPointer(ruleFsts),
943
+ max_num_sentences: Int32(maxNumSentences),
944
+ rule_fars: toCPointer(ruleFars),
945
+ silence_scale: silenceScale
946
+ )
947
+ }
948
+
949
+ class SherpaOnnxWaveWrapper {
950
+ let wave: UnsafePointer<SherpaOnnxWave>!
951
+
952
+ class func readWave(filename: String) -> SherpaOnnxWaveWrapper {
953
+ let wave = SherpaOnnxReadWave(toCPointer(filename))
954
+ return SherpaOnnxWaveWrapper(wave: wave)
955
+ }
956
+
957
+ init(wave: UnsafePointer<SherpaOnnxWave>!) {
958
+ self.wave = wave
959
+ }
960
+
961
+ deinit {
962
+ if let wave {
963
+ SherpaOnnxFreeWave(wave)
964
+ }
965
+ }
966
+
967
+ var numSamples: Int {
968
+ return Int(wave.pointee.num_samples)
969
+ }
970
+
971
+ var sampleRate: Int {
972
+ return Int(wave.pointee.sample_rate)
973
+ }
974
+
975
+ var samples: [Float] {
976
+ if numSamples == 0 {
977
+ return []
978
+ } else {
979
+ return [Float](UnsafeBufferPointer(start: wave.pointee.samples, count: numSamples))
980
+ }
981
+ }
982
+ }
983
+
984
+ class SherpaOnnxGeneratedAudioWrapper {
985
+ /// A pointer to the underlying counterpart in C
986
+ let audio: UnsafePointer<SherpaOnnxGeneratedAudio>!
987
+
988
+ init(audio: UnsafePointer<SherpaOnnxGeneratedAudio>!) {
989
+ self.audio = audio
990
+ }
991
+
992
+ deinit {
993
+ if let audio {
994
+ SherpaOnnxDestroyOfflineTtsGeneratedAudio(audio)
995
+ }
996
+ }
997
+
998
+ var n: Int32 {
999
+ return audio.pointee.n
1000
+ }
1001
+
1002
+ var sampleRate: Int32 {
1003
+ return audio.pointee.sample_rate
1004
+ }
1005
+
1006
+ var samples: [Float] {
1007
+ if let p = audio.pointee.samples {
1008
+ return [Float](UnsafeBufferPointer(start: p, count: Int(n)))
1009
+ } else {
1010
+ return []
1011
+ }
1012
+ }
1013
+
1014
+ func save(filename: String) -> Int32 {
1015
+ return SherpaOnnxWriteWave(audio.pointee.samples, n, sampleRate, toCPointer(filename))
1016
+ }
1017
+ }
1018
+
1019
+ typealias TtsCallbackWithArg = (
1020
+ @convention(c) (
1021
+ UnsafePointer<Float>?, // const float* samples
1022
+ Int32, // int32_t n
1023
+ UnsafeMutableRawPointer? // void *arg
1024
+ ) -> Int32
1025
+ )?
1026
+
1027
+ class SherpaOnnxOfflineTtsWrapper {
1028
+ /// A pointer to the underlying counterpart in C
1029
+ let tts: OpaquePointer!
1030
+
1031
+ /// Constructor taking a model config
1032
+ init(
1033
+ config: UnsafePointer<SherpaOnnxOfflineTtsConfig>!
1034
+ ) {
1035
+ tts = SherpaOnnxCreateOfflineTts(config)
1036
+ }
1037
+
1038
+ deinit {
1039
+ if let tts {
1040
+ SherpaOnnxDestroyOfflineTts(tts)
1041
+ }
1042
+ }
1043
+
1044
+ func generate(text: String, sid: Int = 0, speed: Float = 1.0) -> SherpaOnnxGeneratedAudioWrapper {
1045
+ let audio: UnsafePointer<SherpaOnnxGeneratedAudio>? = SherpaOnnxOfflineTtsGenerate(
1046
+ tts, toCPointer(text), Int32(sid), speed
1047
+ )
1048
+
1049
+ return SherpaOnnxGeneratedAudioWrapper(audio: audio)
1050
+ }
1051
+
1052
+ func generateWithCallbackWithArg(
1053
+ text: String, callback: TtsCallbackWithArg, arg: UnsafeMutableRawPointer, sid: Int = 0,
1054
+ speed: Float = 1.0
1055
+ ) -> SherpaOnnxGeneratedAudioWrapper {
1056
+ let audio: UnsafePointer<SherpaOnnxGeneratedAudio>? =
1057
+ SherpaOnnxOfflineTtsGenerateWithCallbackWithArg(
1058
+ tts, toCPointer(text), Int32(sid), speed, callback, arg
1059
+ )
1060
+
1061
+ return SherpaOnnxGeneratedAudioWrapper(audio: audio)
1062
+ }
1063
+ }
1064
+
1065
+ // spoken language identification
1066
+
1067
+ func sherpaOnnxSpokenLanguageIdentificationWhisperConfig(
1068
+ encoder: String,
1069
+ decoder: String,
1070
+ tailPaddings: Int = -1
1071
+ ) -> SherpaOnnxSpokenLanguageIdentificationWhisperConfig {
1072
+ return SherpaOnnxSpokenLanguageIdentificationWhisperConfig(
1073
+ encoder: toCPointer(encoder),
1074
+ decoder: toCPointer(decoder),
1075
+ tail_paddings: Int32(tailPaddings)
1076
+ )
1077
+ }
1078
+
1079
+ func sherpaOnnxSpokenLanguageIdentificationConfig(
1080
+ whisper: SherpaOnnxSpokenLanguageIdentificationWhisperConfig,
1081
+ numThreads: Int = 1,
1082
+ debug: Int = 0,
1083
+ provider: String = "cpu"
1084
+ ) -> SherpaOnnxSpokenLanguageIdentificationConfig {
1085
+ return SherpaOnnxSpokenLanguageIdentificationConfig(
1086
+ whisper: whisper,
1087
+ num_threads: Int32(numThreads),
1088
+ debug: Int32(debug),
1089
+ provider: toCPointer(provider)
1090
+ )
1091
+ }
1092
+
1093
+ class SherpaOnnxSpokenLanguageIdentificationResultWrapper {
1094
+ /// A pointer to the underlying counterpart in C
1095
+ let result: UnsafePointer<SherpaOnnxSpokenLanguageIdentificationResult>!
1096
+
1097
+ /// Return the detected language.
1098
+ /// en for English
1099
+ /// zh for Chinese
1100
+ /// es for Spanish
1101
+ /// de for German
1102
+ /// etc.
1103
+ var lang: String {
1104
+ return String(cString: result.pointee.lang)
1105
+ }
1106
+
1107
+ init(result: UnsafePointer<SherpaOnnxSpokenLanguageIdentificationResult>!) {
1108
+ self.result = result
1109
+ }
1110
+
1111
+ deinit {
1112
+ if let result {
1113
+ SherpaOnnxDestroySpokenLanguageIdentificationResult(result)
1114
+ }
1115
+ }
1116
+ }
1117
+
1118
+ class SherpaOnnxSpokenLanguageIdentificationWrapper {
1119
+ /// A pointer to the underlying counterpart in C
1120
+ let slid: OpaquePointer!
1121
+
1122
+ init(
1123
+ config: UnsafePointer<SherpaOnnxSpokenLanguageIdentificationConfig>!
1124
+ ) {
1125
+ slid = SherpaOnnxCreateSpokenLanguageIdentification(config)
1126
+ }
1127
+
1128
+ deinit {
1129
+ if let slid {
1130
+ SherpaOnnxDestroySpokenLanguageIdentification(slid)
1131
+ }
1132
+ }
1133
+
1134
+ func decode(samples: [Float], sampleRate: Int = 16000)
1135
+ -> SherpaOnnxSpokenLanguageIdentificationResultWrapper
1136
+ {
1137
+ let stream: OpaquePointer! = SherpaOnnxSpokenLanguageIdentificationCreateOfflineStream(slid)
1138
+ SherpaOnnxAcceptWaveformOffline(stream, Int32(sampleRate), samples, Int32(samples.count))
1139
+
1140
+ let result: UnsafePointer<SherpaOnnxSpokenLanguageIdentificationResult>? =
1141
+ SherpaOnnxSpokenLanguageIdentificationCompute(
1142
+ slid,
1143
+ stream
1144
+ )
1145
+
1146
+ SherpaOnnxDestroyOfflineStream(stream)
1147
+ return SherpaOnnxSpokenLanguageIdentificationResultWrapper(result: result)
1148
+ }
1149
+ }
1150
+
1151
+ // keyword spotting
1152
+
1153
+ class SherpaOnnxKeywordResultWrapper {
1154
+ /// A pointer to the underlying counterpart in C
1155
+ let result: UnsafePointer<SherpaOnnxKeywordResult>!
1156
+
1157
+ var keyword: String {
1158
+ return String(cString: result.pointee.keyword)
1159
+ }
1160
+
1161
+ var count: Int32 {
1162
+ return result.pointee.count
1163
+ }
1164
+
1165
+ var tokens: [String] {
1166
+ if let tokensPointer = result.pointee.tokens_arr {
1167
+ var tokens: [String] = []
1168
+ for index in 0 ..< count {
1169
+ if let tokenPointer = tokensPointer[Int(index)] {
1170
+ let token = String(cString: tokenPointer)
1171
+ tokens.append(token)
1172
+ }
1173
+ }
1174
+ return tokens
1175
+ } else {
1176
+ return []
1177
+ }
1178
+ }
1179
+
1180
+ init(result: UnsafePointer<SherpaOnnxKeywordResult>!) {
1181
+ self.result = result
1182
+ }
1183
+
1184
+ deinit {
1185
+ if let result {
1186
+ SherpaOnnxDestroyKeywordResult(result)
1187
+ }
1188
+ }
1189
+ }
1190
+
1191
+ func sherpaOnnxKeywordSpotterConfig(
1192
+ featConfig: SherpaOnnxFeatureConfig,
1193
+ modelConfig: SherpaOnnxOnlineModelConfig,
1194
+ keywordsFile: String,
1195
+ maxActivePaths: Int = 4,
1196
+ numTrailingBlanks: Int = 1,
1197
+ keywordsScore: Float = 1.0,
1198
+ keywordsThreshold: Float = 0.25,
1199
+ keywordsBuf: String = "",
1200
+ keywordsBufSize: Int = 0
1201
+ ) -> SherpaOnnxKeywordSpotterConfig {
1202
+ return SherpaOnnxKeywordSpotterConfig(
1203
+ feat_config: featConfig,
1204
+ model_config: modelConfig,
1205
+ max_active_paths: Int32(maxActivePaths),
1206
+ num_trailing_blanks: Int32(numTrailingBlanks),
1207
+ keywords_score: keywordsScore,
1208
+ keywords_threshold: keywordsThreshold,
1209
+ keywords_file: toCPointer(keywordsFile),
1210
+ keywords_buf: toCPointer(keywordsBuf),
1211
+ keywords_buf_size: Int32(keywordsBufSize)
1212
+ )
1213
+ }
1214
+
1215
+ class SherpaOnnxKeywordSpotterWrapper {
1216
+ /// A pointer to the underlying counterpart in C
1217
+ let spotter: OpaquePointer!
1218
+ var stream: OpaquePointer!
1219
+
1220
+ init(
1221
+ config: UnsafePointer<SherpaOnnxKeywordSpotterConfig>!
1222
+ ) {
1223
+ spotter = SherpaOnnxCreateKeywordSpotter(config)
1224
+ stream = SherpaOnnxCreateKeywordStream(spotter)
1225
+ }
1226
+
1227
+ deinit {
1228
+ if let stream {
1229
+ SherpaOnnxDestroyOnlineStream(stream)
1230
+ }
1231
+
1232
+ if let spotter {
1233
+ SherpaOnnxDestroyKeywordSpotter(spotter)
1234
+ }
1235
+ }
1236
+
1237
+ func acceptWaveform(samples: [Float], sampleRate: Int = 16000) {
1238
+ SherpaOnnxOnlineStreamAcceptWaveform(stream, Int32(sampleRate), samples, Int32(samples.count))
1239
+ }
1240
+
1241
+ func isReady() -> Bool {
1242
+ return SherpaOnnxIsKeywordStreamReady(spotter, stream) == 1 ? true : false
1243
+ }
1244
+
1245
+ func decode() {
1246
+ SherpaOnnxDecodeKeywordStream(spotter, stream)
1247
+ }
1248
+
1249
+ func reset() {
1250
+ SherpaOnnxResetKeywordStream(spotter, stream)
1251
+ }
1252
+
1253
+ func getResult() -> SherpaOnnxKeywordResultWrapper {
1254
+ let result: UnsafePointer<SherpaOnnxKeywordResult>? = SherpaOnnxGetKeywordResult(
1255
+ spotter, stream
1256
+ )
1257
+ return SherpaOnnxKeywordResultWrapper(result: result)
1258
+ }
1259
+
1260
+ /// Signal that no more audio samples would be available.
1261
+ /// After this call, you cannot call acceptWaveform() any more.
1262
+ func inputFinished() {
1263
+ SherpaOnnxOnlineStreamInputFinished(stream)
1264
+ }
1265
+ }
1266
+
1267
+ // Punctuation
1268
+
1269
+ func sherpaOnnxOfflinePunctuationModelConfig(
1270
+ ctTransformer: String,
1271
+ numThreads: Int = 1,
1272
+ debug: Int = 0,
1273
+ provider: String = "cpu"
1274
+ ) -> SherpaOnnxOfflinePunctuationModelConfig {
1275
+ return SherpaOnnxOfflinePunctuationModelConfig(
1276
+ ct_transformer: toCPointer(ctTransformer),
1277
+ num_threads: Int32(numThreads),
1278
+ debug: Int32(debug),
1279
+ provider: toCPointer(provider)
1280
+ )
1281
+ }
1282
+
1283
+ func sherpaOnnxOfflinePunctuationConfig(
1284
+ model: SherpaOnnxOfflinePunctuationModelConfig
1285
+ ) -> SherpaOnnxOfflinePunctuationConfig {
1286
+ return SherpaOnnxOfflinePunctuationConfig(
1287
+ model: model
1288
+ )
1289
+ }
1290
+
1291
+ class SherpaOnnxOfflinePunctuationWrapper {
1292
+ /// A pointer to the underlying counterpart in C
1293
+ let ptr: OpaquePointer!
1294
+
1295
+ /// Constructor taking a model config
1296
+ init(
1297
+ config: UnsafePointer<SherpaOnnxOfflinePunctuationConfig>!
1298
+ ) {
1299
+ ptr = SherpaOnnxCreateOfflinePunctuation(config)
1300
+ }
1301
+
1302
+ deinit {
1303
+ if let ptr {
1304
+ SherpaOnnxDestroyOfflinePunctuation(ptr)
1305
+ }
1306
+ }
1307
+
1308
+ func addPunct(text: String) -> String {
1309
+ let cText = SherpaOfflinePunctuationAddPunct(ptr, toCPointer(text))
1310
+ let ans = String(cString: cText!)
1311
+ SherpaOfflinePunctuationFreeText(cText)
1312
+ return ans
1313
+ }
1314
+ }
1315
+
1316
+ func sherpaOnnxOnlinePunctuationModelConfig(
1317
+ cnnBiLstm: String,
1318
+ bpeVocab: String,
1319
+ numThreads: Int = 1,
1320
+ debug: Int = 0,
1321
+ provider: String = "cpu"
1322
+ ) -> SherpaOnnxOnlinePunctuationModelConfig {
1323
+ return SherpaOnnxOnlinePunctuationModelConfig(
1324
+ cnn_bilstm: toCPointer(cnnBiLstm),
1325
+ bpe_vocab: toCPointer(bpeVocab),
1326
+ num_threads: Int32(numThreads),
1327
+ debug: Int32(debug),
1328
+ provider: toCPointer(provider)
1329
+ )
1330
+ }
1331
+
1332
+ func sherpaOnnxOnlinePunctuationConfig(
1333
+ model: SherpaOnnxOnlinePunctuationModelConfig
1334
+ ) -> SherpaOnnxOnlinePunctuationConfig {
1335
+ return SherpaOnnxOnlinePunctuationConfig(model: model)
1336
+ }
1337
+
1338
+ class SherpaOnnxOnlinePunctuationWrapper {
1339
+ /// A pointer to the underlying counterpart in C
1340
+ let ptr: OpaquePointer!
1341
+
1342
+ /// Constructor taking a model config
1343
+ init(
1344
+ config: UnsafePointer<SherpaOnnxOnlinePunctuationConfig>!
1345
+ ) {
1346
+ ptr = SherpaOnnxCreateOnlinePunctuation(config)
1347
+ }
1348
+
1349
+ deinit {
1350
+ if let ptr {
1351
+ SherpaOnnxDestroyOnlinePunctuation(ptr)
1352
+ }
1353
+ }
1354
+
1355
+ func addPunct(text: String) -> String {
1356
+ let cText = SherpaOnnxOnlinePunctuationAddPunct(ptr, toCPointer(text))
1357
+ let ans = String(cString: cText!)
1358
+ SherpaOnnxOnlinePunctuationFreeText(cText)
1359
+ return ans
1360
+ }
1361
+ }
1362
+
1363
+ func sherpaOnnxOfflineSpeakerSegmentationPyannoteModelConfig(model: String)
1364
+ -> SherpaOnnxOfflineSpeakerSegmentationPyannoteModelConfig
1365
+ {
1366
+ return SherpaOnnxOfflineSpeakerSegmentationPyannoteModelConfig(model: toCPointer(model))
1367
+ }
1368
+
1369
+ func sherpaOnnxOfflineSpeakerSegmentationModelConfig(
1370
+ pyannote: SherpaOnnxOfflineSpeakerSegmentationPyannoteModelConfig,
1371
+ numThreads: Int = 1,
1372
+ debug: Int = 0,
1373
+ provider: String = "cpu"
1374
+ ) -> SherpaOnnxOfflineSpeakerSegmentationModelConfig {
1375
+ return SherpaOnnxOfflineSpeakerSegmentationModelConfig(
1376
+ pyannote: pyannote,
1377
+ num_threads: Int32(numThreads),
1378
+ debug: Int32(debug),
1379
+ provider: toCPointer(provider)
1380
+ )
1381
+ }
1382
+
1383
+ func sherpaOnnxFastClusteringConfig(numClusters: Int = -1, threshold: Float = 0.5)
1384
+ -> SherpaOnnxFastClusteringConfig
1385
+ {
1386
+ return SherpaOnnxFastClusteringConfig(num_clusters: Int32(numClusters), threshold: threshold)
1387
+ }
1388
+
1389
+ func sherpaOnnxSpeakerEmbeddingExtractorConfig(
1390
+ model: String,
1391
+ numThreads: Int = 1,
1392
+ debug: Int = 0,
1393
+ provider: String = "cpu"
1394
+ ) -> SherpaOnnxSpeakerEmbeddingExtractorConfig {
1395
+ return SherpaOnnxSpeakerEmbeddingExtractorConfig(
1396
+ model: toCPointer(model),
1397
+ num_threads: Int32(numThreads),
1398
+ debug: Int32(debug),
1399
+ provider: toCPointer(provider)
1400
+ )
1401
+ }
1402
+
1403
+ func sherpaOnnxOfflineSpeakerDiarizationConfig(
1404
+ segmentation: SherpaOnnxOfflineSpeakerSegmentationModelConfig,
1405
+ embedding: SherpaOnnxSpeakerEmbeddingExtractorConfig,
1406
+ clustering: SherpaOnnxFastClusteringConfig,
1407
+ minDurationOn: Float = 0.3,
1408
+ minDurationOff: Float = 0.5
1409
+ ) -> SherpaOnnxOfflineSpeakerDiarizationConfig {
1410
+ return SherpaOnnxOfflineSpeakerDiarizationConfig(
1411
+ segmentation: segmentation,
1412
+ embedding: embedding,
1413
+ clustering: clustering,
1414
+ min_duration_on: minDurationOn,
1415
+ min_duration_off: minDurationOff
1416
+ )
1417
+ }
1418
+
1419
+ struct SherpaOnnxOfflineSpeakerDiarizationSegmentWrapper {
1420
+ var start: Float = 0
1421
+ var end: Float = 0
1422
+ var speaker: Int = 0
1423
+ }
1424
+
1425
+ class SherpaOnnxOfflineSpeakerDiarizationWrapper {
1426
+ /// A pointer to the underlying counterpart in C
1427
+ let impl: OpaquePointer!
1428
+
1429
+ init(
1430
+ config: UnsafePointer<SherpaOnnxOfflineSpeakerDiarizationConfig>!
1431
+ ) {
1432
+ impl = SherpaOnnxCreateOfflineSpeakerDiarization(config)
1433
+ }
1434
+
1435
+ deinit {
1436
+ if let impl {
1437
+ SherpaOnnxDestroyOfflineSpeakerDiarization(impl)
1438
+ }
1439
+ }
1440
+
1441
+ var sampleRate: Int {
1442
+ return Int(SherpaOnnxOfflineSpeakerDiarizationGetSampleRate(impl))
1443
+ }
1444
+
1445
+ /// only config.clustering is used. All other fields are ignored
1446
+ func setConfig(config: UnsafePointer<SherpaOnnxOfflineSpeakerDiarizationConfig>!) {
1447
+ SherpaOnnxOfflineSpeakerDiarizationSetConfig(impl, config)
1448
+ }
1449
+
1450
+ func process(samples: [Float]) -> [SherpaOnnxOfflineSpeakerDiarizationSegmentWrapper] {
1451
+ let result = SherpaOnnxOfflineSpeakerDiarizationProcess(
1452
+ impl, samples, Int32(samples.count)
1453
+ )
1454
+
1455
+ if result == nil {
1456
+ return []
1457
+ }
1458
+
1459
+ let numSegments = Int(SherpaOnnxOfflineSpeakerDiarizationResultGetNumSegments(result))
1460
+
1461
+ let p: UnsafePointer<SherpaOnnxOfflineSpeakerDiarizationSegment>? =
1462
+ SherpaOnnxOfflineSpeakerDiarizationResultSortByStartTime(result)
1463
+
1464
+ if p == nil {
1465
+ return []
1466
+ }
1467
+
1468
+ var ans: [SherpaOnnxOfflineSpeakerDiarizationSegmentWrapper] = []
1469
+ for i in 0 ..< numSegments {
1470
+ ans.append(
1471
+ SherpaOnnxOfflineSpeakerDiarizationSegmentWrapper(
1472
+ start: p![i].start, end: p![i].end, speaker: Int(p![i].speaker)
1473
+ )
1474
+ )
1475
+ }
1476
+
1477
+ SherpaOnnxOfflineSpeakerDiarizationDestroySegment(p)
1478
+ SherpaOnnxOfflineSpeakerDiarizationDestroyResult(result)
1479
+
1480
+ return ans
1481
+ }
1482
+ }
1483
+
1484
+ class SherpaOnnxOnlineStreamWrapper {
1485
+ /// A pointer to the underlying counterpart in C
1486
+ let impl: OpaquePointer!
1487
+ init(impl: OpaquePointer!) {
1488
+ self.impl = impl
1489
+ }
1490
+
1491
+ deinit {
1492
+ if let impl {
1493
+ SherpaOnnxDestroyOnlineStream(impl)
1494
+ }
1495
+ }
1496
+
1497
+ func acceptWaveform(samples: [Float], sampleRate: Int = 16000) {
1498
+ SherpaOnnxOnlineStreamAcceptWaveform(impl, Int32(sampleRate), samples, Int32(samples.count))
1499
+ }
1500
+
1501
+ func inputFinished() {
1502
+ SherpaOnnxOnlineStreamInputFinished(impl)
1503
+ }
1504
+ }
1505
+
1506
+ class SherpaOnnxSpeakerEmbeddingExtractorWrapper {
1507
+ /// A pointer to the underlying counterpart in C
1508
+ let impl: OpaquePointer!
1509
+
1510
+ init(
1511
+ config: UnsafePointer<SherpaOnnxSpeakerEmbeddingExtractorConfig>!
1512
+ ) {
1513
+ impl = SherpaOnnxCreateSpeakerEmbeddingExtractor(config)
1514
+ }
1515
+
1516
+ deinit {
1517
+ if let impl {
1518
+ SherpaOnnxDestroySpeakerEmbeddingExtractor(impl)
1519
+ }
1520
+ }
1521
+
1522
+ var dim: Int {
1523
+ return Int(SherpaOnnxSpeakerEmbeddingExtractorDim(impl))
1524
+ }
1525
+
1526
+ func createStream() -> SherpaOnnxOnlineStreamWrapper {
1527
+ let newStream = SherpaOnnxSpeakerEmbeddingExtractorCreateStream(impl)
1528
+ return SherpaOnnxOnlineStreamWrapper(impl: newStream)
1529
+ }
1530
+
1531
+ func isReady(stream: SherpaOnnxOnlineStreamWrapper) -> Bool {
1532
+ return SherpaOnnxSpeakerEmbeddingExtractorIsReady(impl, stream.impl) == 1 ? true : false
1533
+ }
1534
+
1535
+ func compute(stream: SherpaOnnxOnlineStreamWrapper) -> [Float] {
1536
+ if !isReady(stream: stream) {
1537
+ return []
1538
+ }
1539
+
1540
+ let p = SherpaOnnxSpeakerEmbeddingExtractorComputeEmbedding(impl, stream.impl)
1541
+
1542
+ defer {
1543
+ SherpaOnnxSpeakerEmbeddingExtractorDestroyEmbedding(p)
1544
+ }
1545
+
1546
+ return [Float](UnsafeBufferPointer(start: p, count: dim))
1547
+ }
1548
+ }
1549
+
1550
+ func sherpaOnnxOfflineSpeechDenoiserGtcrnModelConfig(model: String = "")
1551
+ -> SherpaOnnxOfflineSpeechDenoiserGtcrnModelConfig
1552
+ {
1553
+ return SherpaOnnxOfflineSpeechDenoiserGtcrnModelConfig(model: toCPointer(model))
1554
+ }
1555
+
1556
+ func sherpaOnnxOfflineSpeechDenoiserModelConfig(
1557
+ gtcrn: SherpaOnnxOfflineSpeechDenoiserGtcrnModelConfig =
1558
+ sherpaOnnxOfflineSpeechDenoiserGtcrnModelConfig(),
1559
+ numThreads: Int = 1,
1560
+ provider: String = "cpu",
1561
+ debug: Int = 0
1562
+ ) -> SherpaOnnxOfflineSpeechDenoiserModelConfig {
1563
+ return SherpaOnnxOfflineSpeechDenoiserModelConfig(
1564
+ gtcrn: gtcrn,
1565
+ num_threads: Int32(numThreads),
1566
+ debug: Int32(debug),
1567
+ provider: toCPointer(provider)
1568
+ )
1569
+ }
1570
+
1571
+ func sherpaOnnxOfflineSpeechDenoiserConfig(
1572
+ model: SherpaOnnxOfflineSpeechDenoiserModelConfig =
1573
+ sherpaOnnxOfflineSpeechDenoiserModelConfig()
1574
+ ) -> SherpaOnnxOfflineSpeechDenoiserConfig {
1575
+ return SherpaOnnxOfflineSpeechDenoiserConfig(
1576
+ model: model
1577
+ )
1578
+ }
1579
+
1580
+ class SherpaOnnxDenoisedAudioWrapper {
1581
+ /// A pointer to the underlying counterpart in C
1582
+ let audio: UnsafePointer<SherpaOnnxDenoisedAudio>!
1583
+
1584
+ init(audio: UnsafePointer<SherpaOnnxDenoisedAudio>!) {
1585
+ self.audio = audio
1586
+ }
1587
+
1588
+ deinit {
1589
+ if let audio {
1590
+ SherpaOnnxDestroyDenoisedAudio(audio)
1591
+ }
1592
+ }
1593
+
1594
+ var n: Int32 {
1595
+ return audio.pointee.n
1596
+ }
1597
+
1598
+ var sampleRate: Int32 {
1599
+ return audio.pointee.sample_rate
1600
+ }
1601
+
1602
+ var samples: [Float] {
1603
+ if let p = audio.pointee.samples {
1604
+ var samples: [Float] = []
1605
+ for index in 0 ..< n {
1606
+ samples.append(p[Int(index)])
1607
+ }
1608
+ return samples
1609
+ } else {
1610
+ return []
1611
+ }
1612
+ }
1613
+
1614
+ func save(filename: String) -> Int32 {
1615
+ return SherpaOnnxWriteWave(audio.pointee.samples, n, sampleRate, toCPointer(filename))
1616
+ }
1617
+ }
1618
+
1619
+ class SherpaOnnxOfflineSpeechDenoiserWrapper {
1620
+ /// A pointer to the underlying counterpart in C
1621
+ let impl: OpaquePointer!
1622
+
1623
+ /// Constructor taking a model config
1624
+ init(
1625
+ config: UnsafePointer<SherpaOnnxOfflineSpeechDenoiserConfig>!
1626
+ ) {
1627
+ impl = SherpaOnnxCreateOfflineSpeechDenoiser(config)
1628
+ }
1629
+
1630
+ deinit {
1631
+ if let impl {
1632
+ SherpaOnnxDestroyOfflineSpeechDenoiser(impl)
1633
+ }
1634
+ }
1635
+
1636
+ func run(samples: [Float], sampleRate: Int) -> SherpaOnnxDenoisedAudioWrapper {
1637
+ let audio: UnsafePointer<SherpaOnnxDenoisedAudio>? = SherpaOnnxOfflineSpeechDenoiserRun(
1638
+ impl, samples, Int32(samples.count), Int32(sampleRate)
1639
+ )
1640
+
1641
+ return SherpaOnnxDenoisedAudioWrapper(audio: audio)
1642
+ }
1643
+
1644
+ var sampleRate: Int {
1645
+ return Int(SherpaOnnxOfflineSpeechDenoiserGetSampleRate(impl))
1646
+ }
1647
+ }
1648
+
1649
+ func getSherpaOnnxVersion() -> String {
1650
+ return String(cString: SherpaOnnxGetVersionStr())
1651
+ }
1652
+
1653
+ func getSherpaOnnxGitSha1() -> String {
1654
+ return String(cString: SherpaOnnxGetGitSha1())
1655
+ }
1656
+
1657
+ func getSherpaOnnxGitDate() -> String {
1658
+ return String(cString: SherpaOnnxGetGitDate())
1659
+ }