react-native-audio-api 0.8.3 → 0.9.0-nightly-7ecb495-20251008

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 (323) hide show
  1. package/README.md +40 -39
  2. package/RNAudioAPI.podspec +17 -12
  3. package/android/build.gradle +44 -4
  4. package/android/src/main/cpp/audioapi/CMakeLists.txt +65 -0
  5. package/android/src/main/cpp/audioapi/android/AudioAPIModule.cpp +29 -1
  6. package/android/src/main/cpp/audioapi/android/AudioAPIModule.h +14 -0
  7. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +7 -1
  8. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +6 -1
  9. package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +1 -1
  10. package/android/src/main/cpp/audioapi/android/core/NativeAudioRecorder.hpp +36 -0
  11. package/android/src/main/cpp/audioapi/android/core/{AudioDecoder.cpp → utils/AudioDecoder.cpp} +79 -75
  12. package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +11 -1
  13. package/android/src/main/java/com/swmansion/audioapi/core/NativeAudioRecorder.kt +24 -0
  14. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +15 -2
  15. package/common/cpp/audioapi/AudioAPIModuleInstaller.h +154 -38
  16. package/common/cpp/audioapi/HostObjects/AudioContextHostObject.cpp +57 -0
  17. package/common/cpp/audioapi/HostObjects/AudioContextHostObject.h +6 -46
  18. package/common/cpp/audioapi/HostObjects/AudioNodeHostObject.cpp +70 -6
  19. package/common/cpp/audioapi/HostObjects/AudioNodeHostObject.h +10 -66
  20. package/common/cpp/audioapi/HostObjects/AudioParamHostObject.cpp +105 -0
  21. package/common/cpp/audioapi/HostObjects/AudioParamHostObject.h +17 -91
  22. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp +262 -6
  23. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +26 -241
  24. package/common/cpp/audioapi/HostObjects/OfflineAudioContextHostObject.cpp +70 -0
  25. package/common/cpp/audioapi/HostObjects/OfflineAudioContextHostObject.h +6 -50
  26. package/common/cpp/audioapi/HostObjects/WorkletNodeHostObject.h +18 -0
  27. package/common/cpp/audioapi/HostObjects/WorkletProcessingNodeHostObject.h +18 -0
  28. package/common/cpp/audioapi/HostObjects/analysis/AnalyserNodeHostObject.cpp +148 -0
  29. package/common/cpp/audioapi/HostObjects/analysis/AnalyserNodeHostObject.h +37 -0
  30. package/common/cpp/audioapi/HostObjects/effects/BiquadFilterNodeHostObject.cpp +92 -0
  31. package/common/cpp/audioapi/HostObjects/effects/BiquadFilterNodeHostObject.h +29 -0
  32. package/common/cpp/audioapi/HostObjects/effects/GainNodeHostObject.cpp +20 -0
  33. package/common/cpp/audioapi/HostObjects/effects/GainNodeHostObject.h +19 -0
  34. package/common/cpp/audioapi/HostObjects/effects/StereoPannerNodeHostObject.cpp +21 -0
  35. package/common/cpp/audioapi/HostObjects/effects/StereoPannerNodeHostObject.h +21 -0
  36. package/common/cpp/audioapi/HostObjects/events/AudioEventHandlerRegistryHostObject.cpp +41 -0
  37. package/common/cpp/audioapi/HostObjects/events/AudioEventHandlerRegistryHostObject.h +28 -0
  38. package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.cpp +69 -0
  39. package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.h +33 -0
  40. package/common/cpp/audioapi/HostObjects/sources/AudioBufferBaseSourceNodeHostObject.cpp +73 -0
  41. package/common/cpp/audioapi/HostObjects/sources/AudioBufferBaseSourceNodeHostObject.h +29 -0
  42. package/common/cpp/audioapi/HostObjects/sources/AudioBufferHostObject.cpp +94 -0
  43. package/common/cpp/audioapi/HostObjects/sources/AudioBufferHostObject.h +46 -0
  44. package/common/cpp/audioapi/HostObjects/sources/AudioBufferQueueSourceNodeHostObject.cpp +60 -0
  45. package/common/cpp/audioapi/HostObjects/sources/AudioBufferQueueSourceNodeHostObject.h +25 -0
  46. package/common/cpp/audioapi/HostObjects/sources/AudioBufferSourceNodeHostObject.cpp +152 -0
  47. package/common/cpp/audioapi/HostObjects/sources/AudioBufferSourceNodeHostObject.h +37 -0
  48. package/common/cpp/audioapi/HostObjects/sources/AudioScheduledSourceNodeHostObject.cpp +52 -0
  49. package/common/cpp/audioapi/HostObjects/sources/AudioScheduledSourceNodeHostObject.h +25 -0
  50. package/common/cpp/audioapi/HostObjects/sources/ConstantSourceNodeHostObject.cpp +19 -0
  51. package/common/cpp/audioapi/HostObjects/sources/ConstantSourceNodeHostObject.h +21 -0
  52. package/common/cpp/audioapi/HostObjects/sources/OscillatorNodeHostObject.cpp +55 -0
  53. package/common/cpp/audioapi/HostObjects/sources/OscillatorNodeHostObject.h +27 -0
  54. package/common/cpp/audioapi/HostObjects/{RecorderAdapterNodeHostObject.h → sources/RecorderAdapterNodeHostObject.h} +1 -2
  55. package/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.cpp +22 -0
  56. package/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.h +28 -0
  57. package/common/cpp/audioapi/HostObjects/sources/WorkletSourceNodeHostObject.h +18 -0
  58. package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.cpp +133 -0
  59. package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.h +28 -0
  60. package/common/cpp/audioapi/HostObjects/utils/AudioStretcherHostObject.cpp +58 -0
  61. package/common/cpp/audioapi/HostObjects/utils/AudioStretcherHostObject.h +26 -0
  62. package/common/cpp/audioapi/core/AudioContext.cpp +3 -4
  63. package/common/cpp/audioapi/core/AudioContext.h +2 -1
  64. package/common/cpp/audioapi/core/AudioNode.cpp +3 -3
  65. package/common/cpp/audioapi/core/AudioNode.h +2 -2
  66. package/common/cpp/audioapi/core/AudioParam.cpp +2 -2
  67. package/common/cpp/audioapi/core/AudioParam.h +1 -1
  68. package/common/cpp/audioapi/core/BaseAudioContext.cpp +47 -38
  69. package/common/cpp/audioapi/core/BaseAudioContext.h +17 -16
  70. package/common/cpp/audioapi/core/OfflineAudioContext.cpp +4 -5
  71. package/common/cpp/audioapi/core/OfflineAudioContext.h +2 -1
  72. package/common/cpp/audioapi/core/analysis/AnalyserNode.cpp +3 -1
  73. package/common/cpp/audioapi/core/analysis/AnalyserNode.h +1 -1
  74. package/common/cpp/audioapi/core/destinations/AudioDestinationNode.h +1 -1
  75. package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +3 -1
  76. package/common/cpp/audioapi/core/effects/BiquadFilterNode.h +1 -1
  77. package/common/cpp/audioapi/core/effects/GainNode.cpp +3 -1
  78. package/common/cpp/audioapi/core/effects/GainNode.h +1 -1
  79. package/common/cpp/audioapi/core/effects/PeriodicWave.cpp +1 -1
  80. package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +18 -13
  81. package/common/cpp/audioapi/core/effects/StereoPannerNode.h +1 -1
  82. package/common/cpp/audioapi/core/effects/WorkletNode.cpp +89 -0
  83. package/common/cpp/audioapi/core/effects/WorkletNode.h +65 -0
  84. package/common/cpp/audioapi/core/effects/WorkletProcessingNode.cpp +91 -0
  85. package/common/cpp/audioapi/core/effects/WorkletProcessingNode.h +52 -0
  86. package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +1 -1
  87. package/common/cpp/audioapi/core/inputs/AudioRecorder.h +2 -2
  88. package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +47 -10
  89. package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.h +18 -3
  90. package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.cpp +98 -14
  91. package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.h +9 -3
  92. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +37 -44
  93. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +7 -9
  94. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +1 -6
  95. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +1 -1
  96. package/common/cpp/audioapi/core/sources/ConstantSourceNode.cpp +53 -0
  97. package/common/cpp/audioapi/core/sources/ConstantSourceNode.h +26 -0
  98. package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +7 -2
  99. package/common/cpp/audioapi/core/sources/OscillatorNode.h +1 -1
  100. package/common/cpp/audioapi/core/sources/RecorderAdapterNode.cpp +3 -1
  101. package/common/cpp/audioapi/core/sources/RecorderAdapterNode.h +1 -1
  102. package/common/cpp/audioapi/core/sources/StreamerNode.cpp +9 -1
  103. package/common/cpp/audioapi/core/sources/StreamerNode.h +1 -9
  104. package/common/cpp/audioapi/core/sources/WorkletSourceNode.cpp +84 -0
  105. package/common/cpp/audioapi/core/sources/WorkletSourceNode.h +47 -0
  106. package/common/cpp/audioapi/core/types/AudioFormat.h +16 -0
  107. package/common/cpp/audioapi/core/utils/AudioDecoder.h +36 -91
  108. package/common/cpp/audioapi/core/{AudioParamEventQueue.cpp → utils/AudioParamEventQueue.cpp} +13 -7
  109. package/common/cpp/audioapi/core/utils/AudioStretcher.cpp +75 -0
  110. package/common/cpp/audioapi/core/utils/AudioStretcher.h +30 -0
  111. package/common/cpp/audioapi/core/{Constants.h → utils/Constants.h} +9 -0
  112. package/common/cpp/audioapi/core/utils/worklets/SafeIncludes.h +52 -0
  113. package/common/cpp/audioapi/core/utils/worklets/WorkletsRunner.cpp +9 -0
  114. package/common/cpp/audioapi/core/utils/worklets/WorkletsRunner.h +73 -0
  115. package/common/cpp/audioapi/dsp/Windows.cpp +1 -1
  116. package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +1 -1
  117. package/common/cpp/audioapi/events/AudioEventHandlerRegistry.h +2 -1
  118. package/common/cpp/audioapi/jsi/AudioArrayBuffer.h +14 -1
  119. package/common/cpp/audioapi/jsi/JsiHostObject.h +6 -12
  120. package/common/cpp/audioapi/jsi/JsiPromise.cpp +49 -0
  121. package/common/cpp/audioapi/jsi/JsiPromise.h +29 -1
  122. package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.cpp +241 -282
  123. package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.h +57 -19
  124. package/common/cpp/audioapi/utils/AudioBus.cpp +1 -1
  125. package/common/cpp/audioapi/utils/ThreadPool.hpp +104 -0
  126. package/common/cpp/test/AudioParamTest.cpp +204 -0
  127. package/common/cpp/test/CMakeLists.txt +13 -4
  128. package/common/cpp/test/GainTest.cpp +11 -10
  129. package/common/cpp/test/OscillatorTest.cpp +2 -1
  130. package/common/cpp/test/StereoPannerTest.cpp +129 -0
  131. package/ios/audioapi/ios/AudioAPIModule.mm +32 -5
  132. package/ios/audioapi/ios/core/IOSAudioPlayer.mm +1 -1
  133. package/ios/audioapi/ios/core/IOSAudioRecorder.mm +1 -1
  134. package/ios/audioapi/ios/core/utils/AudioDecoder.mm +160 -0
  135. package/lib/commonjs/api.js +57 -3
  136. package/lib/commonjs/api.js.map +1 -1
  137. package/lib/commonjs/api.web.js +8 -0
  138. package/lib/commonjs/api.web.js.map +1 -1
  139. package/lib/commonjs/core/AudioBufferBaseSourceNode.js +7 -7
  140. package/lib/commonjs/core/AudioBufferBaseSourceNode.js.map +1 -1
  141. package/lib/commonjs/core/AudioBufferQueueSourceNode.js +1 -6
  142. package/lib/commonjs/core/AudioBufferQueueSourceNode.js.map +1 -1
  143. package/lib/commonjs/core/AudioBufferSourceNode.js +15 -0
  144. package/lib/commonjs/core/AudioBufferSourceNode.js.map +1 -1
  145. package/lib/commonjs/core/AudioContext.js +10 -1
  146. package/lib/commonjs/core/AudioContext.js.map +1 -1
  147. package/lib/commonjs/core/AudioDecoder.js +48 -0
  148. package/lib/commonjs/core/AudioDecoder.js.map +1 -0
  149. package/lib/commonjs/core/AudioScheduledSourceNode.js +4 -4
  150. package/lib/commonjs/core/AudioScheduledSourceNode.js.map +1 -1
  151. package/lib/commonjs/core/AudioStretcher.js +31 -0
  152. package/lib/commonjs/core/AudioStretcher.js.map +1 -0
  153. package/lib/commonjs/core/BaseAudioContext.js +76 -28
  154. package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
  155. package/lib/commonjs/core/ConstantSourceNode.js +17 -0
  156. package/lib/commonjs/core/ConstantSourceNode.js.map +1 -0
  157. package/lib/commonjs/core/OfflineAudioContext.js +11 -2
  158. package/lib/commonjs/core/OfflineAudioContext.js.map +1 -1
  159. package/lib/commonjs/core/OscillatorNode.js +6 -0
  160. package/lib/commonjs/core/OscillatorNode.js.map +1 -1
  161. package/lib/commonjs/core/WorkletNode.js +11 -0
  162. package/lib/commonjs/core/WorkletNode.js.map +1 -0
  163. package/lib/commonjs/core/WorkletProcessingNode.js +11 -0
  164. package/lib/commonjs/core/WorkletProcessingNode.js.map +1 -0
  165. package/lib/commonjs/core/WorkletSourceNode.js +11 -0
  166. package/lib/commonjs/core/WorkletSourceNode.js.map +1 -0
  167. package/lib/commonjs/hooks/{useSytemVolume.js → useSystemVolume.js} +1 -1
  168. package/lib/commonjs/hooks/useSystemVolume.js.map +1 -0
  169. package/lib/commonjs/utils/index.js +9 -0
  170. package/lib/commonjs/utils/index.js.map +1 -1
  171. package/lib/commonjs/web-core/AudioContext.js +4 -0
  172. package/lib/commonjs/web-core/AudioContext.js.map +1 -1
  173. package/lib/commonjs/web-core/AudioScheduledSourceNode.js +1 -1
  174. package/lib/commonjs/web-core/AudioScheduledSourceNode.js.map +1 -1
  175. package/lib/commonjs/web-core/ConstantSourceNode.js +17 -0
  176. package/lib/commonjs/web-core/ConstantSourceNode.js.map +1 -0
  177. package/lib/commonjs/web-core/OfflineAudioContext.js +4 -0
  178. package/lib/commonjs/web-core/OfflineAudioContext.js.map +1 -1
  179. package/lib/module/api.js +9 -3
  180. package/lib/module/api.js.map +1 -1
  181. package/lib/module/api.web.js +1 -0
  182. package/lib/module/api.web.js.map +1 -1
  183. package/lib/module/core/AudioBufferBaseSourceNode.js +7 -7
  184. package/lib/module/core/AudioBufferBaseSourceNode.js.map +1 -1
  185. package/lib/module/core/AudioBufferQueueSourceNode.js +1 -6
  186. package/lib/module/core/AudioBufferQueueSourceNode.js.map +1 -1
  187. package/lib/module/core/AudioBufferSourceNode.js +15 -0
  188. package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
  189. package/lib/module/core/AudioContext.js +10 -1
  190. package/lib/module/core/AudioContext.js.map +1 -1
  191. package/lib/module/core/AudioDecoder.js +42 -0
  192. package/lib/module/core/AudioDecoder.js.map +1 -0
  193. package/lib/module/core/AudioScheduledSourceNode.js +4 -4
  194. package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
  195. package/lib/module/core/AudioStretcher.js +26 -0
  196. package/lib/module/core/AudioStretcher.js.map +1 -0
  197. package/lib/module/core/BaseAudioContext.js +76 -28
  198. package/lib/module/core/BaseAudioContext.js.map +1 -1
  199. package/lib/module/core/ConstantSourceNode.js +11 -0
  200. package/lib/module/core/ConstantSourceNode.js.map +1 -0
  201. package/lib/module/core/OfflineAudioContext.js +11 -2
  202. package/lib/module/core/OfflineAudioContext.js.map +1 -1
  203. package/lib/module/core/OscillatorNode.js +6 -0
  204. package/lib/module/core/OscillatorNode.js.map +1 -1
  205. package/lib/module/core/WorkletNode.js +5 -0
  206. package/lib/module/core/WorkletNode.js.map +1 -0
  207. package/lib/module/core/WorkletProcessingNode.js +5 -0
  208. package/lib/module/core/WorkletProcessingNode.js.map +1 -0
  209. package/lib/module/core/WorkletSourceNode.js +5 -0
  210. package/lib/module/core/WorkletSourceNode.js.map +1 -0
  211. package/lib/module/hooks/{useSytemVolume.js → useSystemVolume.js} +1 -1
  212. package/lib/module/hooks/useSystemVolume.js.map +1 -0
  213. package/lib/module/utils/index.js +8 -0
  214. package/lib/module/utils/index.js.map +1 -1
  215. package/lib/module/web-core/AudioContext.js +4 -0
  216. package/lib/module/web-core/AudioContext.js.map +1 -1
  217. package/lib/module/web-core/AudioScheduledSourceNode.js +1 -1
  218. package/lib/module/web-core/AudioScheduledSourceNode.js.map +1 -1
  219. package/lib/module/web-core/ConstantSourceNode.js +11 -0
  220. package/lib/module/web-core/ConstantSourceNode.js.map +1 -0
  221. package/lib/module/web-core/OfflineAudioContext.js +4 -0
  222. package/lib/module/web-core/OfflineAudioContext.js.map +1 -1
  223. package/lib/typescript/api.d.ts +13 -5
  224. package/lib/typescript/api.d.ts.map +1 -1
  225. package/lib/typescript/api.web.d.ts +1 -0
  226. package/lib/typescript/api.web.d.ts.map +1 -1
  227. package/lib/typescript/core/AudioBufferBaseSourceNode.d.ts +2 -2
  228. package/lib/typescript/core/AudioBufferBaseSourceNode.d.ts.map +1 -1
  229. package/lib/typescript/core/AudioBufferQueueSourceNode.d.ts +1 -1
  230. package/lib/typescript/core/AudioBufferQueueSourceNode.d.ts.map +1 -1
  231. package/lib/typescript/core/AudioBufferSourceNode.d.ts +4 -0
  232. package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -1
  233. package/lib/typescript/core/AudioContext.d.ts +1 -0
  234. package/lib/typescript/core/AudioContext.d.ts.map +1 -1
  235. package/lib/typescript/core/AudioDecoder.d.ts +4 -0
  236. package/lib/typescript/core/AudioDecoder.d.ts.map +1 -0
  237. package/lib/typescript/core/AudioScheduledSourceNode.d.ts +1 -1
  238. package/lib/typescript/core/AudioStretcher.d.ts +3 -0
  239. package/lib/typescript/core/AudioStretcher.d.ts.map +1 -0
  240. package/lib/typescript/core/BaseAudioContext.d.ts +21 -16
  241. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
  242. package/lib/typescript/core/ConstantSourceNode.d.ts +9 -0
  243. package/lib/typescript/core/ConstantSourceNode.d.ts.map +1 -0
  244. package/lib/typescript/core/OfflineAudioContext.d.ts +1 -0
  245. package/lib/typescript/core/OfflineAudioContext.d.ts.map +1 -1
  246. package/lib/typescript/core/OscillatorNode.d.ts +3 -0
  247. package/lib/typescript/core/OscillatorNode.d.ts.map +1 -1
  248. package/lib/typescript/core/WorkletNode.d.ts +4 -0
  249. package/lib/typescript/core/WorkletNode.d.ts.map +1 -0
  250. package/lib/typescript/core/WorkletProcessingNode.d.ts +4 -0
  251. package/lib/typescript/core/WorkletProcessingNode.d.ts.map +1 -0
  252. package/lib/typescript/core/WorkletSourceNode.d.ts +4 -0
  253. package/lib/typescript/core/WorkletSourceNode.d.ts.map +1 -0
  254. package/lib/typescript/events/types.d.ts +2 -0
  255. package/lib/typescript/events/types.d.ts.map +1 -1
  256. package/lib/typescript/hooks/{useSytemVolume.d.ts → useSystemVolume.d.ts} +1 -1
  257. package/lib/typescript/hooks/useSystemVolume.d.ts.map +1 -0
  258. package/lib/typescript/interfaces.d.ts +31 -6
  259. package/lib/typescript/interfaces.d.ts.map +1 -1
  260. package/lib/typescript/types.d.ts +2 -1
  261. package/lib/typescript/types.d.ts.map +1 -1
  262. package/lib/typescript/utils/index.d.ts +8 -0
  263. package/lib/typescript/utils/index.d.ts.map +1 -1
  264. package/lib/typescript/web-core/AudioBufferSourceNode.d.ts +1 -1
  265. package/lib/typescript/web-core/AudioContext.d.ts +4 -2
  266. package/lib/typescript/web-core/AudioContext.d.ts.map +1 -1
  267. package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts +1 -1
  268. package/lib/typescript/web-core/BaseAudioContext.d.ts +2 -0
  269. package/lib/typescript/web-core/BaseAudioContext.d.ts.map +1 -1
  270. package/lib/typescript/web-core/ConstantSourceNode.d.ts +8 -0
  271. package/lib/typescript/web-core/ConstantSourceNode.d.ts.map +1 -0
  272. package/lib/typescript/web-core/OfflineAudioContext.d.ts +4 -2
  273. package/lib/typescript/web-core/OfflineAudioContext.d.ts.map +1 -1
  274. package/package.json +3 -2
  275. package/src/api.ts +22 -3
  276. package/src/api.web.ts +1 -0
  277. package/src/core/AudioBufferBaseSourceNode.ts +9 -9
  278. package/src/core/AudioBufferQueueSourceNode.ts +1 -9
  279. package/src/core/AudioBufferSourceNode.ts +28 -0
  280. package/src/core/AudioContext.ts +12 -1
  281. package/src/core/AudioDecoder.ts +78 -0
  282. package/src/core/AudioScheduledSourceNode.ts +5 -5
  283. package/src/core/AudioStretcher.ts +43 -0
  284. package/src/core/BaseAudioContext.ts +174 -41
  285. package/src/core/ConstantSourceNode.ts +13 -0
  286. package/src/core/OfflineAudioContext.ts +18 -2
  287. package/src/core/OscillatorNode.ts +11 -0
  288. package/src/core/WorkletNode.ts +3 -0
  289. package/src/core/WorkletProcessingNode.ts +3 -0
  290. package/src/core/WorkletSourceNode.ts +3 -0
  291. package/src/events/types.ts +2 -0
  292. package/src/interfaces.ts +85 -11
  293. package/src/types.ts +3 -1
  294. package/src/utils/index.ts +21 -0
  295. package/src/web-core/AudioBufferSourceNode.tsx +1 -1
  296. package/src/web-core/AudioContext.tsx +7 -2
  297. package/src/web-core/AudioScheduledSourceNode.tsx +1 -1
  298. package/src/web-core/BaseAudioContext.tsx +2 -0
  299. package/src/web-core/ConstantSourceNode.tsx +12 -0
  300. package/src/web-core/OfflineAudioContext.tsx +7 -2
  301. package/common/cpp/audioapi/HostObjects/AnalyserNodeHostObject.h +0 -149
  302. package/common/cpp/audioapi/HostObjects/AudioBufferBaseSourceNodeHostObject.h +0 -76
  303. package/common/cpp/audioapi/HostObjects/AudioBufferHostObject.h +0 -120
  304. package/common/cpp/audioapi/HostObjects/AudioBufferQueueSourceNodeHostObject.h +0 -67
  305. package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +0 -142
  306. package/common/cpp/audioapi/HostObjects/AudioRecorderHostObject.h +0 -86
  307. package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +0 -56
  308. package/common/cpp/audioapi/HostObjects/BiquadFilterNodeHostObject.h +0 -89
  309. package/common/cpp/audioapi/HostObjects/GainNodeHostObject.h +0 -27
  310. package/common/cpp/audioapi/HostObjects/OscillatorNodeHostObject.h +0 -65
  311. package/common/cpp/audioapi/HostObjects/StereoPannerNodeHostObject.h +0 -29
  312. package/common/cpp/audioapi/HostObjects/StreamerNodeHostObject.h +0 -30
  313. package/common/cpp/audioapi/events/AudioEventHandlerRegistryHostObject.h +0 -48
  314. package/ios/audioapi/ios/core/AudioDecoder.mm +0 -156
  315. package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.h +0 -7
  316. package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.mm +0 -12
  317. package/lib/commonjs/hooks/useSytemVolume.js.map +0 -1
  318. package/lib/module/hooks/useSytemVolume.js.map +0 -1
  319. package/lib/typescript/hooks/useSytemVolume.d.ts.map +0 -1
  320. /package/common/cpp/audioapi/HostObjects/{AudioDestinationNodeHostObject.h → destinations/AudioDestinationNodeHostObject.h} +0 -0
  321. /package/common/cpp/audioapi/HostObjects/{PeriodicWaveHostObject.h → effects/PeriodicWaveHostObject.h} +0 -0
  322. /package/common/cpp/audioapi/core/{AudioParamEventQueue.h → utils/AudioParamEventQueue.h} +0 -0
  323. /package/src/hooks/{useSytemVolume.ts → useSystemVolume.ts} +0 -0
@@ -23,7 +23,7 @@ void RecorderAdapterNode::init(size_t bufferSize) {
23
23
  buff_ = std::make_shared<CircularOverflowableAudioArray>(bufferSize);
24
24
  }
25
25
 
26
- void RecorderAdapterNode::processNode(
26
+ std::shared_ptr<AudioBus> RecorderAdapterNode::processNode(
27
27
  const std::shared_ptr<AudioBus> &processingBus,
28
28
  int framesToProcess) {
29
29
  float *outputChannel = processingBus->getChannel(0)->getData();
@@ -33,6 +33,8 @@ void RecorderAdapterNode::processNode(
33
33
  processingBus->getChannel(i)->copy(
34
34
  processingBus->getChannel(0), 0, framesToProcess);
35
35
  }
36
+
37
+ return processingBus;
36
38
  }
37
39
 
38
40
  void RecorderAdapterNode::readFrames(float *output, const size_t framesToRead) {
@@ -27,7 +27,7 @@ class RecorderAdapterNode : public AudioNode {
27
27
  void init(size_t bufferSize);
28
28
 
29
29
  protected:
30
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
30
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
31
31
  std::shared_ptr<CircularOverflowableAudioArray> buff_;
32
32
 
33
33
  private:
@@ -147,12 +147,18 @@ void StreamerNode::streamAudio() {
147
147
  }
148
148
  }
149
149
 
150
- void StreamerNode::processNode(
150
+ std::shared_ptr<AudioBus> StreamerNode::processNode(
151
151
  const std::shared_ptr<AudioBus> &processingBus,
152
152
  int framesToProcess) {
153
153
  size_t startOffset = 0;
154
154
  size_t offsetLength = 0;
155
155
  updatePlaybackInfo(processingBus, framesToProcess, startOffset, offsetLength);
156
+
157
+ if (!isPlaying() && !isStopScheduled()) {
158
+ processingBus->zero();
159
+ return processingBus;
160
+ }
161
+
156
162
  // If we have enough buffered data, copy to output bus
157
163
  if (bufferedBusIndex_ >= framesToProcess) {
158
164
  Locker locker(mutex_);
@@ -169,6 +175,8 @@ void StreamerNode::processNode(
169
175
  }
170
176
  bufferedBusIndex_ -= offsetLength;
171
177
  }
178
+
179
+ return processingBus;
172
180
  }
173
181
 
174
182
  bool StreamerNode::processFrameWithResampler(AVFrame *frame) {
@@ -43,16 +43,8 @@ class StreamerNode : public AudioScheduledSourceNode {
43
43
  bool initialize(const std::string& inputUrl);
44
44
  void stop(double when) override;
45
45
 
46
- private:
47
- static constexpr int SIZE = 4'000'000; // 4MB
48
-
49
- public:
50
- static constexpr int getEstimatedSize() {
51
- return StreamerNode::SIZE;
52
- } // in bytes
53
-
54
46
  protected:
55
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
47
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
56
48
 
57
49
  private:
58
50
  #ifndef AUDIO_API_TEST_SUITE
@@ -0,0 +1,84 @@
1
+ #include <audioapi/core/sources/WorkletSourceNode.h>
2
+ #include <audioapi/core/utils/Constants.h>
3
+
4
+ namespace audioapi {
5
+
6
+ WorkletSourceNode::WorkletSourceNode(
7
+ BaseAudioContext *context,
8
+ std::shared_ptr<worklets::SerializableWorklet> &worklet,
9
+ std::weak_ptr<worklets::WorkletRuntime> runtime)
10
+ : AudioScheduledSourceNode(context),
11
+ workletRunner_(runtime),
12
+ shareableWorklet_(worklet) {
13
+ isInitialized_ = true;
14
+
15
+ // Prepare buffers for audio processing
16
+ size_t outputChannelCount = this->getChannelCount();
17
+ outputBuffsHandles_.resize(outputChannelCount);
18
+ for (size_t i = 0; i < outputChannelCount; ++i) {
19
+ auto buff = new uint8_t[RENDER_QUANTUM_SIZE * sizeof(float)];
20
+ outputBuffsHandles_[i] = std::make_shared<AudioArrayBuffer>(
21
+ buff, RENDER_QUANTUM_SIZE * sizeof(float));
22
+ }
23
+ }
24
+
25
+ std::shared_ptr<AudioBus> WorkletSourceNode::processNode(
26
+ const std::shared_ptr<AudioBus> &processingBus,
27
+ int framesToProcess) {
28
+ if (isUnscheduled() || isFinished() || !isEnabled()) {
29
+ processingBus->zero();
30
+ return processingBus;
31
+ }
32
+
33
+ size_t startOffset = 0;
34
+ size_t nonSilentFramesToProcess = framesToProcess;
35
+
36
+ updatePlaybackInfo(
37
+ processingBus, framesToProcess, startOffset, nonSilentFramesToProcess);
38
+
39
+ if (nonSilentFramesToProcess == 0) {
40
+ processingBus->zero();
41
+ return processingBus;
42
+ }
43
+
44
+ size_t outputChannelCount = processingBus->getNumberOfChannels();
45
+
46
+ auto result = workletRunner_.executeOnRuntimeGuardedSync(
47
+ [this, nonSilentFramesToProcess, startOffset](jsi::Runtime &rt) {
48
+ auto jsiArray = jsi::Array(rt, this->outputBuffsHandles_.size());
49
+ for (size_t i = 0; i < this->outputBuffsHandles_.size(); ++i) {
50
+ auto arrayBuffer = jsi::ArrayBuffer(rt, this->outputBuffsHandles_[i]);
51
+ jsiArray.setValueAtIndex(rt, i, arrayBuffer);
52
+ }
53
+ return workletRunner_
54
+ .executeWorklet(
55
+ shareableWorklet_,
56
+ jsiArray,
57
+ jsi::Value(rt, static_cast<int>(nonSilentFramesToProcess)),
58
+ jsi::Value(rt, this->context_->getCurrentTime()),
59
+ jsi::Value(rt, static_cast<int>(startOffset)))
60
+ .value_or(jsi::Value::undefined());
61
+ });
62
+
63
+ // If the worklet execution failed, zero the output
64
+ // It might happen if the runtime is not available
65
+ if (!result.has_value()) {
66
+ processingBus->zero();
67
+ return processingBus;
68
+ }
69
+
70
+ // Copy the processed data back to the AudioBus
71
+ for (size_t i = 0; i < outputChannelCount; ++i) {
72
+ float *channelData = processingBus->getChannel(i)->getData();
73
+ memcpy(
74
+ channelData + startOffset,
75
+ outputBuffsHandles_[i]->data(),
76
+ nonSilentFramesToProcess * sizeof(float));
77
+ }
78
+
79
+ handleStopScheduled();
80
+
81
+ return processingBus;
82
+ }
83
+
84
+ } // namespace audioapi
@@ -0,0 +1,47 @@
1
+ #pragma once
2
+ #include <jsi/jsi.h>
3
+ #include <audioapi/core/BaseAudioContext.h>
4
+ #include <audioapi/utils/AudioBus.h>
5
+ #include <audioapi/core/sources/AudioScheduledSourceNode.h>
6
+ #include <audioapi/core/utils/worklets/SafeIncludes.h>
7
+ #include <audioapi/core/utils/worklets/WorkletsRunner.h>
8
+ #include <audioapi/jsi/AudioArrayBuffer.h>
9
+ #include <audioapi/utils/AudioArray.h>
10
+
11
+ #include <vector>
12
+ #include <memory>
13
+
14
+ namespace audioapi {
15
+
16
+ #if RN_AUDIO_API_TEST
17
+ class WorkletSourceNode : public AudioScheduledSourceNode {
18
+ public:
19
+ explicit WorkletSourceNode(
20
+ BaseAudioContext *context,
21
+ std::shared_ptr<worklets::SerializableWorklet> &worklet,
22
+ std::weak_ptr<worklets::WorkletRuntime> runtime
23
+ ) : AudioScheduledSourceNode(context) {}
24
+
25
+ protected:
26
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override { return processingBus; }
27
+ };
28
+ #else
29
+
30
+ class WorkletSourceNode : public AudioScheduledSourceNode {
31
+ public:
32
+ explicit WorkletSourceNode(
33
+ BaseAudioContext *context,
34
+ std::shared_ptr<worklets::SerializableWorklet> &worklet,
35
+ std::weak_ptr<worklets::WorkletRuntime> runtime
36
+ );
37
+
38
+ protected:
39
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
40
+ private:
41
+ WorkletsRunner workletRunner_;
42
+ std::shared_ptr<worklets::SerializableWorklet> shareableWorklet_;
43
+ std::vector<std::shared_ptr<AudioArrayBuffer>> outputBuffsHandles_;
44
+ };
45
+ #endif // RN_AUDIO_API_TEST
46
+
47
+ } // namespace audioapi
@@ -0,0 +1,16 @@
1
+ #pragma once
2
+
3
+ namespace audioapi {
4
+
5
+ enum class AudioFormat {
6
+ UNKNOWN,
7
+ WAV,
8
+ OGG,
9
+ FLAC,
10
+ AAC,
11
+ MP3,
12
+ M4A,
13
+ MP4,
14
+ MOV
15
+ };
16
+ } // namespace audioapi
@@ -1,124 +1,67 @@
1
1
  #pragma once
2
2
 
3
- #include <audioapi/libs/audio-stretch/stretch.h>
3
+ #include <audioapi/core/types/AudioFormat.h>
4
4
  #include <audioapi/libs/miniaudio/miniaudio.h>
5
+ #include <algorithm>
6
+ #include <cstring>
5
7
  #include <memory>
6
8
  #include <string>
7
9
  #include <vector>
8
- #include <cstring>
9
- #include <algorithm>
10
10
 
11
11
  namespace audioapi {
12
12
 
13
- enum class AudioFormat {
14
- UNKNOWN,
15
- WAV,
16
- OGG,
17
- FLAC,
18
- AAC,
19
- MP3,
20
- M4A,
21
- MP4,
22
- MOV
23
- };
24
-
25
- class AudioBus;
13
+ class AudioBuffer;
26
14
 
27
15
  static constexpr int CHUNK_SIZE = 4096;
28
16
 
29
17
  class AudioDecoder {
30
18
  public:
31
- explicit AudioDecoder(float sampleRate) : sampleRate_(sampleRate) {}
19
+ AudioDecoder() = delete;
32
20
 
33
- [[nodiscard]] std::shared_ptr<AudioBus> decodeWithFilePath(
34
- const std::string &path) const;
35
- [[nodiscard]] std::shared_ptr<AudioBus> decodeWithMemoryBlock(
36
- const void *data,
37
- size_t size) const;
38
- [[nodiscard]] std::shared_ptr<AudioBus> decodeWithPCMInBase64(
39
- const std::string &data,
40
- float playbackSpeed) const;
21
+ [[nodiscard]] static std::shared_ptr<AudioBuffer> decodeWithFilePath(const std::string &path, float sampleRate);
22
+ [[nodiscard]] static std::shared_ptr<AudioBuffer>
23
+ decodeWithMemoryBlock(const void *data, size_t size, float sampleRate);
24
+ [[nodiscard]] static std::shared_ptr<AudioBuffer>
25
+ decodeWithPCMInBase64(const std::string &data, float inputSampleRate, int inputChannelCount, bool interleaved);
41
26
 
42
27
  private:
43
- float sampleRate_;
44
- int numChannels_ = 2;
45
-
46
- static std::vector<int16_t> readAllPcmFrames(
47
- ma_decoder &decoder,
48
- int numChannels,
49
- ma_uint64 &outFramesRead);
50
- static std::shared_ptr<AudioBus> makeAudioBusFromInt16Buffer(
51
- const std::vector<int16_t> &buffer,
52
- int numChannels,
53
- float sampleRate);
54
-
55
- void changePlaybackSpeedIfNeeded(
56
- std::vector<int16_t> &buffer,
57
- size_t framesDecoded,
58
- int numChannels,
59
- float playbackSpeed) const {
60
- if (playbackSpeed == 1.0f) {
61
- return;
62
- }
63
-
64
- auto stretcher = stretch_init(
65
- static_cast<int>(sampleRate_ / 333.0f),
66
- static_cast<int>(sampleRate_ / 55.0f),
67
- numChannels,
68
- 0x1);
28
+ static std::vector<float> readAllPcmFrames(ma_decoder &decoder, int outputChannels);
29
+ static std::shared_ptr<AudioBuffer>
30
+ makeAudioBufferFromFloatBuffer(const std::vector<float> &buffer, float outputSampleRate, int outputChannels);
69
31
 
70
- int maxOutputFrames = stretch_output_capacity(
71
- stretcher, static_cast<int>(framesDecoded), 1 / playbackSpeed);
72
- std::vector<int16_t> stretchedBuffer(maxOutputFrames);
73
-
74
- int outputFrames = stretch_samples(
75
- stretcher,
76
- buffer.data(),
77
- static_cast<int>(framesDecoded),
78
- stretchedBuffer.data(),
79
- 1 / playbackSpeed);
80
-
81
- outputFrames +=
82
- stretch_flush(stretcher, stretchedBuffer.data() + (outputFrames));
83
- stretchedBuffer.resize(outputFrames);
84
-
85
- buffer = stretchedBuffer;
86
-
87
- stretch_deinit(stretcher);
88
- }
89
-
90
- static AudioFormat detectAudioFormat(const void* data, size_t size) {
91
- if (size < 12) return AudioFormat::UNKNOWN;
92
- const auto* bytes = static_cast<const unsigned char*>(data);
32
+ static AudioFormat detectAudioFormat(const void *data, size_t size) {
33
+ if (size < 12)
34
+ return AudioFormat::UNKNOWN;
35
+ const auto *bytes = static_cast<const unsigned char *>(data);
93
36
 
94
37
  // WAV/RIFF
95
38
  if (std::memcmp(bytes, "RIFF", 4) == 0 && std::memcmp(bytes + 8, "WAVE", 4) == 0)
96
- return AudioFormat::WAV;
39
+ return AudioFormat::WAV;
97
40
 
98
41
  // OGG
99
42
  if (std::memcmp(bytes, "OggS", 4) == 0)
100
- return AudioFormat::OGG;
43
+ return AudioFormat::OGG;
101
44
 
102
45
  // FLAC
103
46
  if (std::memcmp(bytes, "fLaC", 4) == 0)
104
- return AudioFormat::FLAC;
47
+ return AudioFormat::FLAC;
105
48
 
106
49
  // AAC starts with 0xFF 0xF1 or 0xFF 0xF9
107
50
  if (bytes[0] == 0xFF && (bytes[1] & 0xF6) == 0xF0)
108
- return AudioFormat::AAC;
51
+ return AudioFormat::AAC;
109
52
 
110
53
  // MP3: "ID3" or 11-bit frame sync (0xFF 0xE0)
111
54
  if (std::memcmp(bytes, "ID3", 3) == 0)
112
- return AudioFormat::MP3;
55
+ return AudioFormat::MP3;
113
56
  if (bytes[0] == 0xFF && (bytes[1] & 0xE0) == 0xE0)
114
- return AudioFormat::MP3;
57
+ return AudioFormat::MP3;
115
58
 
116
59
  if (std::memcmp(bytes + 4, "ftyp", 4) == 0) {
117
- if (std::memcmp(bytes + 8, "M4A ", 4) == 0)
118
- return AudioFormat::M4A;
119
- else if (std::memcmp(bytes + 8, "qt ", 4) == 0)
120
- return AudioFormat::MOV;
121
- return AudioFormat::MP4;
60
+ if (std::memcmp(bytes + 8, "M4A ", 4) == 0)
61
+ return AudioFormat::M4A;
62
+ else if (std::memcmp(bytes + 8, "qt ", 4) == 0)
63
+ return AudioFormat::MOV;
64
+ return AudioFormat::MP4;
122
65
  }
123
66
  return AudioFormat::UNKNOWN;
124
67
  }
@@ -126,19 +69,21 @@ class AudioDecoder {
126
69
  static inline bool pathHasExtension(const std::string &path, const std::vector<std::string> &extensions) {
127
70
  std::string pathLower = path;
128
71
  std::transform(pathLower.begin(), pathLower.end(), pathLower.begin(), ::tolower);
129
- for (const auto& ext : extensions) {
130
- if (pathLower.ends_with(ext))
131
- return true;
72
+ for (const auto &ext : extensions) {
73
+ if (pathLower.ends_with(ext))
74
+ return true;
132
75
  }
133
76
  return false;
134
77
  }
135
78
 
136
-
137
79
  [[nodiscard]] static inline int16_t floatToInt16(float sample) {
138
- return static_cast<int16_t>(sample * 32768.0f);
80
+ return static_cast<int16_t>(sample * INT16_MAX);
139
81
  }
140
82
  [[nodiscard]] static inline float int16ToFloat(int16_t sample) {
141
- return static_cast<float>(sample) / 32768.0f;
83
+ return static_cast<float>(sample) / INT16_MAX;
84
+ }
85
+ [[nodiscard]] static inline float uint8ToFloat(uint8_t byte1, uint8_t byte2) {
86
+ return static_cast<float>(static_cast<int16_t>((byte2 << 8) | byte1)) / INT16_MAX;
142
87
  }
143
88
  };
144
89
 
@@ -1,4 +1,4 @@
1
- #include <audioapi/core/AudioParamEventQueue.h>
1
+ #include <audioapi/core/utils/AudioParamEventQueue.h>
2
2
 
3
3
  namespace audioapi {
4
4
 
@@ -31,12 +31,12 @@ bool AudioParamEventQueue::popFront(ParamChangeEvent &event) {
31
31
 
32
32
  void AudioParamEventQueue::cancelScheduledValues(double cancelTime) {
33
33
  while (!eventQueue_.isEmpty()) {
34
- auto &front = eventQueue_.peekBack();
35
- if (front.getEndTime() < cancelTime) {
34
+ auto &back = eventQueue_.peekBack();
35
+ if (back.getEndTime() < cancelTime) {
36
36
  break;
37
37
  }
38
- if (front.getStartTime() >= cancelTime ||
39
- front.getType() == ParamChangeEventType::SET_VALUE_CURVE) {
38
+ if (back.getStartTime() >= cancelTime ||
39
+ back.getType() == ParamChangeEventType::SET_VALUE_CURVE) {
40
40
  eventQueue_.popBack();
41
41
  }
42
42
  }
@@ -46,8 +46,8 @@ void AudioParamEventQueue::cancelAndHoldAtTime(
46
46
  double cancelTime,
47
47
  double &endTimeCache) {
48
48
  while (!eventQueue_.isEmpty()) {
49
- auto &front = eventQueue_.peekBack();
50
- if (front.getEndTime() < cancelTime || front.getStartTime() <= cancelTime) {
49
+ auto &back = eventQueue_.peekBack();
50
+ if (back.getEndTime() < cancelTime || back.getStartTime() <= cancelTime) {
51
51
  break;
52
52
  }
53
53
  eventQueue_.popBack();
@@ -59,6 +59,12 @@ void AudioParamEventQueue::cancelAndHoldAtTime(
59
59
  }
60
60
 
61
61
  auto &back = eventQueue_.peekBackMut();
62
+ back.setEndValue(back.getCalculateValue()(
63
+ back.getStartTime(),
64
+ back.getEndTime(),
65
+ back.getStartValue(),
66
+ back.getEndValue(),
67
+ cancelTime));
62
68
  back.setEndTime(std::min(cancelTime, back.getEndTime()));
63
69
  }
64
70
 
@@ -0,0 +1,75 @@
1
+ #include <audioapi/core/sources/AudioBuffer.h>
2
+ #include <audioapi/core/utils/AudioStretcher.h>
3
+ #include <audioapi/core/utils/Constants.h>
4
+ #include <audioapi/libs/audio-stretch/stretch.h>
5
+ #include <audioapi/utils/AudioArray.h>
6
+ #include <audioapi/utils/AudioBus.h>
7
+ #include <cstdint>
8
+
9
+ namespace audioapi {
10
+
11
+ std::vector<int16_t> AudioStretcher::castToInt16Buffer(AudioBuffer &buffer) {
12
+ const size_t numChannels = buffer.getNumberOfChannels();
13
+ const size_t numFrames = buffer.getLength();
14
+
15
+ std::vector<int16_t> int16Buffer(numFrames * numChannels);
16
+
17
+ for (size_t ch = 0; ch < numChannels; ++ch) {
18
+ const float *channelData = buffer.getChannelData(ch);
19
+ for (size_t i = 0; i < numFrames; ++i) {
20
+ int16Buffer[i * numChannels + ch] = floatToInt16(channelData[i]);
21
+ }
22
+ }
23
+
24
+ return int16Buffer;
25
+ }
26
+
27
+ std::shared_ptr<AudioBuffer> AudioStretcher::changePlaybackSpeed(
28
+ AudioBuffer buffer,
29
+ float playbackSpeed) {
30
+ const float sampleRate = buffer.getSampleRate();
31
+ const size_t outputChannels = buffer.getNumberOfChannels();
32
+ const size_t numFrames = buffer.getLength();
33
+
34
+ if (playbackSpeed == 1.0f) {
35
+ return std::make_shared<AudioBuffer>(buffer);
36
+ }
37
+
38
+ std::vector<int16_t> int16Buffer = castToInt16Buffer(buffer);
39
+
40
+ auto stretcher = stretch_init(
41
+ static_cast<int>(sampleRate / UPPER_FREQUENCY_LIMIT_DETECTION),
42
+ static_cast<int>(sampleRate / LOWER_FREQUENCY_LIMIT_DETECTION),
43
+ outputChannels,
44
+ 0x1);
45
+
46
+ int maxOutputFrames = stretch_output_capacity(
47
+ stretcher, static_cast<int>(numFrames), 1 / playbackSpeed);
48
+ std::vector<int16_t> stretchedBuffer(maxOutputFrames * outputChannels);
49
+
50
+ int outputFrames = stretch_samples(
51
+ stretcher,
52
+ int16Buffer.data(),
53
+ static_cast<int>(numFrames),
54
+ stretchedBuffer.data(),
55
+ 1 / playbackSpeed);
56
+
57
+ outputFrames +=
58
+ stretch_flush(stretcher, stretchedBuffer.data() + (outputFrames));
59
+ stretchedBuffer.resize(outputFrames * outputChannels);
60
+ stretch_deinit(stretcher);
61
+
62
+ auto audioBus =
63
+ std::make_shared<AudioBus>(outputFrames, outputChannels, sampleRate);
64
+
65
+ for (int ch = 0; ch < outputChannels; ++ch) {
66
+ auto channelData = audioBus->getChannel(ch)->getData();
67
+ for (int i = 0; i < outputFrames; ++i) {
68
+ channelData[i] = int16ToFloat(stretchedBuffer[i * outputChannels + ch]);
69
+ }
70
+ }
71
+
72
+ return std::make_shared<AudioBuffer>(audioBus);
73
+ }
74
+
75
+ } // namespace audioapi
@@ -0,0 +1,30 @@
1
+ #pragma once
2
+
3
+ #include <memory>
4
+ #include <vector>
5
+
6
+ namespace audioapi {
7
+
8
+ class AudioBus;
9
+ class AudioBuffer;
10
+
11
+ class AudioStretcher {
12
+ public:
13
+ AudioStretcher() = delete;
14
+
15
+ [[nodiscard]] static std::shared_ptr<AudioBuffer> changePlaybackSpeed(
16
+ AudioBuffer buffer,
17
+ float playbackSpeed);
18
+
19
+ private:
20
+ static std::vector<int16_t> castToInt16Buffer(AudioBuffer &buffer);
21
+
22
+ [[nodiscard]] static inline int16_t floatToInt16(float sample) {
23
+ return static_cast<int16_t>(sample * INT16_MAX);
24
+ }
25
+ [[nodiscard]] static inline float int16ToFloat(int16_t sample) {
26
+ return static_cast<float>(sample) / INT16_MAX;
27
+ }
28
+ };
29
+
30
+ } // namespace audioapi
@@ -10,10 +10,19 @@ namespace audioapi {
10
10
  static constexpr int RENDER_QUANTUM_SIZE = 128;
11
11
  static constexpr size_t MAX_FFT_SIZE = 32768;
12
12
 
13
+ // stretcher
14
+ static constexpr float UPPER_FREQUENCY_LIMIT_DETECTION = 333.0f;
15
+ static constexpr float LOWER_FREQUENCY_LIMIT_DETECTION = 55.0f;
16
+
13
17
  // general
14
18
  static constexpr float MOST_POSITIVE_SINGLE_FLOAT = static_cast<float>(std::numeric_limits<float>::max());
15
19
  static constexpr float MOST_NEGATIVE_SINGLE_FLOAT = static_cast<float>(std::numeric_limits<float>::lowest());
16
20
  static float LOG2_MOST_POSITIVE_SINGLE_FLOAT = std::log2(MOST_POSITIVE_SINGLE_FLOAT);
17
21
  static float LOG10_MOST_POSITIVE_SINGLE_FLOAT = std::log10(MOST_POSITIVE_SINGLE_FLOAT);
18
22
  static constexpr float PI = static_cast<float>(M_PI);
23
+
24
+ // buffer sizes
25
+ static constexpr size_t PROMISE_VENDOR_THREAD_POOL_WORKER_COUNT = 4;
26
+ static constexpr size_t PROMISE_VENDOR_THREAD_POOL_LOAD_BALANCER_QUEUE_SIZE = 32;
27
+ static constexpr size_t PROMISE_VENDOR_THREAD_POOL_WORKER_QUEUE_SIZE = 32;
19
28
  } // namespace audioapi
@@ -0,0 +1,52 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+
5
+ #include <string>
6
+ #include <memory>
7
+
8
+ #ifdef __APPLE__
9
+ /// We cannot make any conditional logic inside podspec but it should automatically compile those files
10
+ /// they should be accessible if someone has react-native-worklets in node_modules
11
+ #if __has_include(<worklets/WorkletRuntime/WorkletRuntime.h>)
12
+ #define RN_AUDIO_API_ENABLE_WORKLETS 1
13
+ #else
14
+ #define RN_AUDIO_API_ENABLE_WORKLETS 0
15
+ #endif
16
+ #endif
17
+
18
+ #ifndef RN_AUDIO_API_TEST
19
+ #define RN_AUDIO_API_TEST 0
20
+ #endif
21
+
22
+ #if RN_AUDIO_API_ENABLE_WORKLETS
23
+ #include <worklets/WorkletRuntime/WorkletRuntime.h>
24
+ #include <worklets/SharedItems/Serializable.h>
25
+ #include <worklets/NativeModules/WorkletsModuleProxy.h>
26
+ #if ANDROID
27
+ #include <worklets/android/WorkletsModule.h>
28
+ #endif
29
+ #else
30
+ /// @brief Dummy implementation of worklets for non-worklet builds they should do nothing and mock necessary methods
31
+ /// @note It helps to reduce compile time branching across codebase
32
+ /// @note If you need to base some c++ implementation on if the worklets are enabled use `#if RN_AUDIO_API_ENABLE_WORKLETS`
33
+ namespace worklets {
34
+
35
+ using namespace facebook;
36
+ class MessageQueueThread {};
37
+ class WorkletsModuleProxy {};
38
+ class WorkletRuntime {
39
+ explicit WorkletRuntime(uint64_t, const std::shared_ptr<MessageQueueThread> &, const std::string &, const bool);
40
+ };
41
+ class SerializableWorklet {
42
+ SerializableWorklet(jsi::Runtime*, const jsi::Object &);
43
+ };
44
+ } // namespace worklets
45
+ #endif
46
+
47
+ /// @brief Struct to hold references to different runtimes used in the AudioAPI
48
+ /// @note it is used to pass them around and avoid creating multiple instances of the same runtime
49
+ struct RuntimeRegistry {
50
+ std::weak_ptr<worklets::WorkletRuntime> uiRuntime;
51
+ std::weak_ptr<worklets::WorkletRuntime> audioRuntime;
52
+ };
@@ -0,0 +1,9 @@
1
+ #include <audioapi/core/utils/worklets/WorkletsRunner.h>
2
+
3
+ namespace audioapi {
4
+
5
+ WorkletsRunner::WorkletsRunner(
6
+ std::weak_ptr<worklets::WorkletRuntime> weakUiRuntime) noexcept
7
+ : weakUiRuntime_(std::move(weakUiRuntime)) {}
8
+
9
+ }; // namespace audioapi