react-native-audio-api 0.6.0-rc.0 → 0.6.0-rc.2

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 (207) hide show
  1. package/README.md +35 -22
  2. package/android/CMakeLists.txt +6 -3
  3. package/android/build.gradle +1 -0
  4. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +73 -0
  5. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +37 -0
  6. package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +6 -10
  7. package/android/src/main/cpp/audioapi/android/core/AudioPlayer.h +2 -3
  8. package/android/src/main/java/com/swmansion/audioapi/AudioManagerModule.kt +19 -14
  9. package/android/src/main/java/com/swmansion/audioapi/system/AudioFocusListener.kt +60 -0
  10. package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +294 -0
  11. package/android/src/main/java/com/swmansion/audioapi/system/MediaNotificationManager.kt +279 -0
  12. package/android/src/main/java/com/swmansion/audioapi/system/MediaReceiver.kt +46 -0
  13. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionCallback.kt +39 -0
  14. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionEventEmitter.kt +88 -0
  15. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +162 -0
  16. package/android/src/main/java/com/swmansion/audioapi/system/VolumeChangeListener.kt +27 -0
  17. package/android/src/main/res/drawable/next.xml +9 -0
  18. package/android/src/main/res/drawable/pause.xml +9 -0
  19. package/android/src/main/res/drawable/play.xml +9 -0
  20. package/android/src/main/res/drawable/previous.xml +9 -0
  21. package/android/src/main/res/drawable/skip_backward_5.xml +9 -0
  22. package/android/src/main/res/drawable/skip_forward_5.xml +9 -0
  23. package/android/src/main/res/drawable/stop.xml +9 -0
  24. package/app.plugin.js +1 -0
  25. package/common/cpp/audioapi/AudioAPIModuleInstaller.h +29 -5
  26. package/common/cpp/audioapi/HostObjects/AnalyserNodeHostObject.h +1 -0
  27. package/common/cpp/audioapi/HostObjects/AudioRecorderHostObject.h +149 -0
  28. package/common/cpp/audioapi/core/AudioContext.cpp +4 -3
  29. package/common/cpp/audioapi/core/BaseAudioContext.cpp +6 -6
  30. package/common/cpp/audioapi/core/inputs/AudioRecorder.h +38 -0
  31. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +1 -6
  32. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +8 -4
  33. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +6 -0
  34. package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +1 -1
  35. package/common/cpp/audioapi/core/utils/AudioNodeDestructor.cpp +3 -3
  36. package/common/cpp/audioapi/core/utils/AudioNodeManager.cpp +45 -11
  37. package/common/cpp/audioapi/core/utils/AudioNodeManager.h +6 -2
  38. package/ios/audioapi/ios/AudioManagerModule.mm +16 -15
  39. package/ios/audioapi/ios/core/IOSAudioPlayer.h +11 -12
  40. package/ios/audioapi/ios/core/IOSAudioPlayer.mm +22 -16
  41. package/ios/audioapi/ios/core/IOSAudioRecorder.h +36 -0
  42. package/ios/audioapi/ios/core/IOSAudioRecorder.mm +62 -0
  43. package/ios/audioapi/ios/core/{AudioPlayer.h → NativeAudioPlayer.h} +1 -8
  44. package/ios/audioapi/ios/core/{AudioPlayer.m → NativeAudioPlayer.m} +4 -33
  45. package/ios/audioapi/ios/core/NativeAudioRecorder.h +25 -0
  46. package/ios/audioapi/ios/core/NativeAudioRecorder.m +47 -0
  47. package/ios/audioapi/ios/system/AudioEngine.h +7 -1
  48. package/ios/audioapi/ios/system/AudioEngine.mm +64 -20
  49. package/ios/audioapi/ios/system/AudioSessionManager.h +3 -1
  50. package/ios/audioapi/ios/system/AudioSessionManager.mm +37 -25
  51. package/ios/audioapi/ios/system/LockScreenManager.mm +4 -8
  52. package/ios/audioapi/ios/system/NotificationManager.h +13 -1
  53. package/ios/audioapi/ios/system/NotificationManager.mm +96 -44
  54. package/lib/commonjs/api.js +211 -0
  55. package/lib/commonjs/api.js.map +1 -0
  56. package/lib/commonjs/api.web.js +219 -0
  57. package/lib/commonjs/api.web.js.map +1 -0
  58. package/lib/commonjs/core/AnalyserNode.js +71 -0
  59. package/lib/commonjs/core/AnalyserNode.js.map +1 -0
  60. package/lib/commonjs/core/AudioBuffer.js +44 -0
  61. package/lib/commonjs/core/AudioBuffer.js.map +1 -0
  62. package/lib/commonjs/core/AudioBufferSourceNode.js +68 -0
  63. package/lib/commonjs/core/AudioBufferSourceNode.js.map +1 -0
  64. package/lib/commonjs/core/AudioContext.js +29 -0
  65. package/lib/commonjs/core/AudioContext.js.map +1 -0
  66. package/lib/commonjs/core/AudioDestinationNode.js +11 -0
  67. package/lib/commonjs/core/AudioDestinationNode.js.map +1 -0
  68. package/lib/commonjs/core/AudioNode.js +30 -0
  69. package/lib/commonjs/core/AudioNode.js.map +1 -0
  70. package/lib/commonjs/core/AudioParam.js +82 -0
  71. package/lib/commonjs/core/AudioParam.js.map +1 -0
  72. package/lib/commonjs/core/AudioRecorder.js +51 -0
  73. package/lib/commonjs/core/AudioRecorder.js.map +1 -0
  74. package/lib/commonjs/core/AudioScheduledSourceNode.js +38 -0
  75. package/lib/commonjs/core/AudioScheduledSourceNode.js.map +1 -0
  76. package/lib/commonjs/core/BaseAudioContext.js +80 -0
  77. package/lib/commonjs/core/BaseAudioContext.js.map +1 -0
  78. package/lib/commonjs/core/BiquadFilterNode.js +33 -0
  79. package/lib/commonjs/core/BiquadFilterNode.js.map +1 -0
  80. package/lib/commonjs/core/GainNode.js +17 -0
  81. package/lib/commonjs/core/GainNode.js.map +1 -0
  82. package/lib/commonjs/core/OfflineAudioContext.js +63 -0
  83. package/lib/commonjs/core/OfflineAudioContext.js.map +1 -0
  84. package/lib/commonjs/core/OscillatorNode.js +32 -0
  85. package/lib/commonjs/core/OscillatorNode.js.map +1 -0
  86. package/lib/commonjs/core/PeriodicWave.js +15 -0
  87. package/lib/commonjs/core/PeriodicWave.js.map +1 -0
  88. package/lib/commonjs/core/StereoPannerNode.js +17 -0
  89. package/lib/commonjs/core/StereoPannerNode.js.map +1 -0
  90. package/lib/commonjs/errors/IndexSizeError.js +14 -0
  91. package/lib/commonjs/errors/IndexSizeError.js.map +1 -0
  92. package/lib/commonjs/errors/InvalidAccessError.js +14 -0
  93. package/lib/commonjs/errors/InvalidAccessError.js.map +1 -0
  94. package/lib/commonjs/errors/InvalidStateError.js +14 -0
  95. package/lib/commonjs/errors/InvalidStateError.js.map +1 -0
  96. package/lib/commonjs/errors/NotSupportedError.js +14 -0
  97. package/lib/commonjs/errors/NotSupportedError.js.map +1 -0
  98. package/lib/commonjs/errors/RangeError.js +14 -0
  99. package/lib/commonjs/errors/RangeError.js.map +1 -0
  100. package/lib/commonjs/errors/index.js +42 -0
  101. package/lib/commonjs/errors/index.js.map +1 -0
  102. package/lib/commonjs/hooks/useSytemVolume.js +24 -0
  103. package/lib/commonjs/hooks/useSytemVolume.js.map +1 -0
  104. package/lib/commonjs/index.js +17 -0
  105. package/lib/commonjs/index.js.map +1 -0
  106. package/lib/commonjs/interfaces.js +6 -0
  107. package/lib/commonjs/interfaces.js.map +1 -0
  108. package/lib/commonjs/package.json +1 -0
  109. package/lib/commonjs/plugin/withAudioAPI.js +62 -0
  110. package/lib/commonjs/plugin/withAudioAPI.js.map +1 -0
  111. package/lib/commonjs/specs/NativeAudioAPIModule.js +9 -0
  112. package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -0
  113. package/lib/commonjs/specs/NativeAudioManagerModule.js +36 -0
  114. package/lib/commonjs/specs/NativeAudioManagerModule.js.map +1 -0
  115. package/lib/commonjs/specs/index.js +27 -0
  116. package/lib/commonjs/specs/index.js.map +1 -0
  117. package/lib/commonjs/system/AudioManager.js +52 -0
  118. package/lib/commonjs/system/AudioManager.js.map +1 -0
  119. package/lib/commonjs/system/index.js +14 -0
  120. package/lib/commonjs/system/index.js.map +1 -0
  121. package/lib/commonjs/system/types.js +2 -0
  122. package/lib/commonjs/system/types.js.map +1 -0
  123. package/lib/commonjs/types.js +2 -0
  124. package/lib/commonjs/types.js.map +1 -0
  125. package/lib/commonjs/utils/index.js +10 -0
  126. package/lib/commonjs/utils/index.js.map +1 -0
  127. package/lib/commonjs/web-core/AnalyserNode.js +38 -0
  128. package/lib/commonjs/web-core/AnalyserNode.js.map +1 -0
  129. package/lib/commonjs/web-core/AudioBuffer.js +44 -0
  130. package/lib/commonjs/web-core/AudioBuffer.js.map +1 -0
  131. package/lib/commonjs/web-core/AudioBufferSourceNode.js +214 -0
  132. package/lib/commonjs/web-core/AudioBufferSourceNode.js.map +1 -0
  133. package/lib/commonjs/web-core/AudioContext.js +93 -0
  134. package/lib/commonjs/web-core/AudioContext.js.map +1 -0
  135. package/lib/commonjs/web-core/AudioDestinationNode.js +11 -0
  136. package/lib/commonjs/web-core/AudioDestinationNode.js.map +1 -0
  137. package/lib/commonjs/web-core/AudioNode.js +33 -0
  138. package/lib/commonjs/web-core/AudioNode.js.map +1 -0
  139. package/lib/commonjs/web-core/AudioParam.js +81 -0
  140. package/lib/commonjs/web-core/AudioParam.js.map +1 -0
  141. package/lib/commonjs/web-core/AudioScheduledSourceNode.js +41 -0
  142. package/lib/commonjs/web-core/AudioScheduledSourceNode.js.map +1 -0
  143. package/lib/commonjs/web-core/BaseAudioContext.js +2 -0
  144. package/lib/commonjs/web-core/BaseAudioContext.js.map +1 -0
  145. package/lib/commonjs/web-core/BiquadFilterNode.js +33 -0
  146. package/lib/commonjs/web-core/BiquadFilterNode.js.map +1 -0
  147. package/lib/commonjs/web-core/GainNode.js +17 -0
  148. package/lib/commonjs/web-core/GainNode.js.map +1 -0
  149. package/lib/commonjs/web-core/OfflineAudioContext.js +96 -0
  150. package/lib/commonjs/web-core/OfflineAudioContext.js.map +1 -0
  151. package/lib/commonjs/web-core/OscillatorNode.js +31 -0
  152. package/lib/commonjs/web-core/OscillatorNode.js.map +1 -0
  153. package/lib/commonjs/web-core/PeriodicWave.js +15 -0
  154. package/lib/commonjs/web-core/PeriodicWave.js.map +1 -0
  155. package/lib/commonjs/web-core/StereoPannerNode.js +17 -0
  156. package/lib/commonjs/web-core/StereoPannerNode.js.map +1 -0
  157. package/lib/commonjs/web-core/custom/LoadCustomWasm.js +37 -0
  158. package/lib/commonjs/web-core/custom/LoadCustomWasm.js.map +1 -0
  159. package/lib/commonjs/web-core/custom/index.js +14 -0
  160. package/lib/commonjs/web-core/custom/index.js.map +1 -0
  161. package/lib/commonjs/web-core/custom/signalsmithStretch/LICENSE.txt +21 -0
  162. package/lib/commonjs/web-core/custom/signalsmithStretch/README.md +46 -0
  163. package/lib/commonjs/web-core/custom/signalsmithStretch/SignalsmithStretch.mjs +826 -0
  164. package/lib/commonjs/web-core/custom/signalsmithStretch/SignalsmithStretch.mjs.map +1 -0
  165. package/lib/module/api.js +3 -1
  166. package/lib/module/api.js.map +1 -1
  167. package/lib/module/core/AudioRecorder.js +45 -0
  168. package/lib/module/core/AudioRecorder.js.map +1 -0
  169. package/lib/module/errors/NotSupportedError.js.map +1 -1
  170. package/lib/module/hooks/useSytemVolume.js +19 -0
  171. package/lib/module/hooks/useSytemVolume.js.map +1 -0
  172. package/lib/module/plugin/withAudioAPI.js +58 -0
  173. package/lib/module/plugin/withAudioAPI.js.map +1 -0
  174. package/lib/module/specs/NativeAudioManagerModule.js +10 -8
  175. package/lib/module/specs/NativeAudioManagerModule.js.map +1 -1
  176. package/lib/module/system/AudioManager.js +26 -44
  177. package/lib/module/system/AudioManager.js.map +1 -1
  178. package/lib/typescript/api.d.ts +5 -1
  179. package/lib/typescript/api.d.ts.map +1 -1
  180. package/lib/typescript/core/AudioRecorder.d.ts +22 -0
  181. package/lib/typescript/core/AudioRecorder.d.ts.map +1 -0
  182. package/lib/typescript/errors/NotSupportedError.d.ts.map +1 -1
  183. package/lib/typescript/hooks/useSytemVolume.d.ts +2 -0
  184. package/lib/typescript/hooks/useSytemVolume.d.ts.map +1 -0
  185. package/lib/typescript/interfaces.d.ts +11 -5
  186. package/lib/typescript/interfaces.d.ts.map +1 -1
  187. package/lib/typescript/plugin/withAudioAPI.d.ts +9 -0
  188. package/lib/typescript/plugin/withAudioAPI.d.ts.map +1 -0
  189. package/lib/typescript/specs/NativeAudioManagerModule.d.ts +4 -2
  190. package/lib/typescript/specs/NativeAudioManagerModule.d.ts.map +1 -1
  191. package/lib/typescript/system/AudioManager.d.ts +5 -2
  192. package/lib/typescript/system/AudioManager.d.ts.map +1 -1
  193. package/lib/typescript/system/types.d.ts +36 -5
  194. package/lib/typescript/system/types.d.ts.map +1 -1
  195. package/lib/typescript/types.d.ts +5 -0
  196. package/lib/typescript/types.d.ts.map +1 -1
  197. package/package.json +7 -3
  198. package/src/api.ts +13 -2
  199. package/src/core/AudioRecorder.ts +81 -0
  200. package/src/hooks/useSytemVolume.ts +19 -0
  201. package/src/interfaces.ts +25 -11
  202. package/src/plugin/withAudioAPI.ts +91 -0
  203. package/src/specs/NativeAudioManagerModule.ts +13 -19
  204. package/src/system/AudioManager.ts +37 -87
  205. package/src/system/types.ts +43 -17
  206. package/src/types.ts +13 -0
  207. /package/src/errors/{NotSupportedError.tsx → NotSupportedError.ts} +0 -0
package/README.md CHANGED
@@ -1,43 +1,56 @@
1
1
  <img src="./assets/react-native-audio-api-gh-cover.png?v0.0.1" alt="React Native Audio API" width="100%">
2
2
 
3
- ### React Native Audio API
3
+ ### High-performance audio engine for React Native based on web audio api specification
4
+
5
+ [![NPM latest](https://img.shields.io/npm/v/react-native-audio-api/latest)](https://www.npmjs.com/package/react-native-audio-api)
6
+ [![NPM next](https://img.shields.io/npm/v/react-native-audio-api/next)](https://www.npmjs.com/package/react-native-audio-api?activeTab=versions)
7
+ [![github ci](https://img.shields.io/github/actions/workflow/status/software-mansion/react-native-audio-api/ci.yml)](https://github.com/software-mansion/react-native-audio-api/actions)
4
8
 
5
9
  `react-native-audio-api` provides system for controlling audio in React Native environment compatible with Web Audio API specification,
6
10
  allowing developers to generate and modify audio in exact same way it is possible in browsers.
7
11
 
8
12
  ## Installation
9
13
 
10
- 1. Install `react-native-audio-api` library
14
+ check out the [Getting Started](https://docs.swmansion.com/react-native-audio-api/fundamentals/getting-started) section of our documentation for detailed instructions!
11
15
 
12
- ```bash
13
- # using npm
14
- npm install react-native-audio-api
16
+ ## Roadmap
15
17
 
16
- # or using yarn
17
- yarn add react-native-audio-api
18
- ```
18
+ - <sub>[![Released in 0.1.0](https://img.shields.io/badge/Released_in-0.1.0-green)](https://github.com/software-mansion/react-native-audio-api/releases/tag/0.1.0)</sub> **Sound synthesis and system audio** 🐣 <br />
19
+ Access to devices audio engines and threads, basic nodes for sound synthesis, simple effects and audio graph implementation
20
+ <br />
19
21
 
20
- ## Usage with expo
22
+ - <sub>[![Released in 0.2.0](https://img.shields.io/badge/Released_in-0.2.0-green)](https://github.com/software-mansion/react-native-audio-api/releases/tag/0.2.0)</sub> **Graph Processing** 🛎️ <br />
23
+ Support for multi-channel audio processing, audio-graph route optimizations, improved react-native layer for managing audio nodes
24
+ <br />
25
+ - <sub>[![Released in 0.3.2](https://img.shields.io/badge/Released_in-0.3.2-green)](https://github.com/software-mansion/react-native-audio-api/releases/tag/0.3.2)</sub> **Audio Files** 🎸 <br />
26
+ Support for local and remote audio file resources: MP3, WAV, FLAC.
27
+ <br />
21
28
 
22
- `react-native-audio-api` contains native custom code and isn't part of the Expo Go application. In order to be available in expo managed builds, you have to use Expo development build. Simplest way on starting local expo dev builds, is to use:
29
+ - <sub>[![Released in 0.4.0](https://img.shields.io/badge/Released_in-0.4.0-green)](https://github.com/software-mansion/react-native-audio-api/releases/tag/0.4.0)</sub> **Analyser Node** 🌊 <br />
30
+ Ability to draw, animate or simply debug audio data in time or frequency domain.
31
+ <br />
23
32
 
24
- ```bash
25
- # Build native iOS project
26
- npx expo run:ios
27
- # Build native Android project
28
- npx expo run:android
29
- ```
33
+ - <sub>[![Released in 0.5.0](https://img.shields.io/badge/Released_in-0.5.0-green)](https://github.com/software-mansion/react-native-audio-api/releases/tag/0.5.0)</sub> **Pitch correction, extending the web** 💥 <br />
34
+ Ability to modify playback speed without affecting pitch of the sound
35
+ <br />
30
36
 
31
- To learn more about expo development builds, please check out [Development Builds Documentation](https://docs.expo.dev/develop/development-builds/introduction/).
37
+ - <sub>![Coming in 0.6.0](https://img.shields.io/badge/Coming_in-0.6.0-blue)</sub> **System configuration** 🛠️ <br />
38
+ Full control of system audio settings, remote controls, lock screen integration and most importantly configurable background modes
39
+ <br />
32
40
 
33
- ## Documentation
41
+ - **Microphone support** 🎙️ <br />
42
+ Grab audio data from device microphone or connected device, connect it to the audio graph or stream through the internet
43
+ <br />
34
44
 
35
- Check out our dedicated documentation page for info about this library, API reference and more:
36
- [https://software-mansion.github.io/react-native-audio-api/](https://software-mansion.github.io/react-native-audio-api/)
45
+ - **Connect audio param** 🤞 <br />
46
+ Ability to connect Audio nodes to audio params, which will allow for powerful and efficient modulation of audio parameters, creating effects like tremolo, vibrato or complex envelope followers.
47
+ <br />
37
48
 
38
- You can also check out [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) for fully detailed description of the audio api.
49
+ - **JS Audio Worklets** 🐎 <br />
50
+ Ability to run JS functions connected to the audio graph running on audio thread allowing for full customization of what happens to the audio signal.
51
+ <br />
39
52
 
40
- ## Coverage
53
+ ## Web Audio API Specification Coverage
41
54
 
42
55
  Our current coverage of Web Audio API specification can be found here: [Web Audio API coverage](https://software-mansion.github.io/react-native-audio-api/other/web-audio-api-coverage).
43
56
 
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.12.0)
2
2
  project(react-native-audio-api)
3
3
 
4
4
  set(CMAKE_VERBOSE_MAKEFILE ON)
5
+ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
5
6
  set(CMAKE_CXX_STANDARD 20)
6
7
 
7
8
  # Detect the processor and SIMD support
@@ -14,9 +15,11 @@ endif()
14
15
  include("${REACT_NATIVE_DIR}/ReactAndroid/cmake-utils/folly-flags.cmake")
15
16
  add_compile_options(${folly_FLAGS})
16
17
 
17
- # string(APPEND CMAKE_CXX_FLAGS
18
- # " -fexceptions -fno-omit-frame-pointer -frtti -fstack-protector-all\
19
- # -std=c++${CMAKE_CXX_STANDARD} -Wall -Werror")
18
+ # frtti - enable Run-Time Type Information (dynamic_cast, typeid)
19
+ # -std=c++20 - use C++20 standard
20
+ # -Wall - enable all compiler's warning messages
21
+ string(APPEND CMAKE_CXX_FLAGS
22
+ " -frtti -std=c++${CMAKE_CXX_STANDARD} -Wall")
20
23
 
21
24
  if(${IS_NEW_ARCHITECTURE_ENABLED})
22
25
  string(APPEND CMAKE_CXX_FLAGS " -DRCT_NEW_ARCH_ENABLED")
@@ -218,6 +218,7 @@ dependencies {
218
218
  implementation 'androidx.core:core-ktx:1.13.1'
219
219
  implementation 'com.facebook.fbjni:fbjni:0.6.0'
220
220
  implementation 'com.google.oboe:oboe:1.9.0'
221
+ implementation 'androidx.media:media:1.7.0'
221
222
  }
222
223
 
223
224
  def assertMinimalReactNativeVersion = task assertMinimalReactNativeVersionTask {
@@ -0,0 +1,73 @@
1
+ #include <audioapi/android/core/AndroidAudioRecorder.h>
2
+ #include <audioapi/core/Constants.h>
3
+ #include <audioapi/utils/AudioArray.h>
4
+ #include <audioapi/utils/AudioBus.h>
5
+
6
+ namespace audioapi {
7
+
8
+ AndroidAudioRecorder::AndroidAudioRecorder(
9
+ float sampleRate,
10
+ int bufferLength,
11
+ const std::function<void(void)> &onError,
12
+ const std::function<void(void)> &onStatusChange,
13
+ const std::function<void(std::shared_ptr<AudioBus>, int, double)>
14
+ &onAudioReady)
15
+ : AudioRecorder(
16
+ sampleRate,
17
+ bufferLength,
18
+ onError,
19
+ onStatusChange,
20
+ onAudioReady) {
21
+ AudioStreamBuilder builder;
22
+ builder.setSharingMode(SharingMode::Exclusive)
23
+ ->setDirection(Direction::Input)
24
+ ->setFormat(AudioFormat::Float)
25
+ ->setFormatConversionAllowed(true)
26
+ ->setPerformanceMode(PerformanceMode::None)
27
+ ->setChannelCount(1)
28
+ ->setSampleRateConversionQuality(SampleRateConversionQuality::Medium)
29
+ ->setDataCallback(this)
30
+ ->setSampleRate(static_cast<int>(sampleRate))
31
+ ->setFramesPerDataCallback(bufferLength)
32
+ ->openStream(mStream_);
33
+ }
34
+
35
+ AndroidAudioRecorder::~AndroidAudioRecorder() {
36
+ AudioRecorder::~AudioRecorder();
37
+
38
+ if (mStream_) {
39
+ mStream_->requestStop();
40
+ mStream_->close();
41
+ mStream_.reset();
42
+ }
43
+ }
44
+
45
+ void AndroidAudioRecorder::start() {
46
+ if (mStream_) {
47
+ mStream_->requestStart();
48
+ }
49
+ }
50
+
51
+ void AndroidAudioRecorder::stop() {
52
+ if (mStream_) {
53
+ mStream_->requestStop();
54
+ }
55
+ }
56
+
57
+ DataCallbackResult AndroidAudioRecorder::onAudioReady(
58
+ oboe::AudioStream *oboeStream,
59
+ void *audioData,
60
+ int32_t numFrames) {
61
+ auto buffer = static_cast<float *>(audioData);
62
+
63
+ auto bus = std::make_shared<AudioBus>(bufferLength_, 1, sampleRate_);
64
+ memcpy(bus->getChannel(0)->getData(), buffer, numFrames * sizeof(float));
65
+ auto when = static_cast<double>(
66
+ oboeStream->getTimestamp(CLOCK_MONOTONIC).value().timestamp);
67
+
68
+ onAudioReady_(bus, numFrames, when);
69
+
70
+ return DataCallbackResult::Continue;
71
+ }
72
+
73
+ } // namespace audioapi
@@ -0,0 +1,37 @@
1
+ #pragma once
2
+
3
+ #include <audioapi/core/inputs/AudioRecorder.h>
4
+
5
+ #include <oboe/Oboe.h>
6
+ #include <functional>
7
+ #include <memory>
8
+
9
+ namespace audioapi {
10
+
11
+ using namespace oboe;
12
+
13
+ class AudioBus;
14
+
15
+ class AndroidAudioRecorder : public AudioStreamDataCallback, public AudioRecorder {
16
+ public:
17
+ AndroidAudioRecorder(float sampleRate,
18
+ int bufferLength,
19
+ const std::function<void(void)> &onError,
20
+ const std::function<void(void)> &onStatusChange,
21
+ const std::function<void(std::shared_ptr<AudioBus>, int, double)> &onAudioReady);
22
+
23
+ ~AndroidAudioRecorder() override;
24
+
25
+ void start() override;
26
+ void stop() override;
27
+
28
+ DataCallbackResult onAudioReady(
29
+ AudioStream *oboeStream,
30
+ void *audioData,
31
+ int32_t numFrames) override;
32
+
33
+ private:
34
+ std::shared_ptr<AudioStream> mStream_;
35
+ };
36
+
37
+ } // namespace audioapi
@@ -27,11 +27,13 @@ AudioPlayer::AudioPlayer(
27
27
  isInitialized_ = true;
28
28
  }
29
29
 
30
- float AudioPlayer::getSampleRate() const {
31
- return sampleRate_;
30
+ void AudioPlayer::start() {
31
+ if (mStream_) {
32
+ mStream_->requestStart();
33
+ }
32
34
  }
33
35
 
34
- void AudioPlayer::start() {
36
+ void AudioPlayer::resume() {
35
37
  if (mStream_) {
36
38
  mStream_->requestStart();
37
39
  }
@@ -47,13 +49,7 @@ void AudioPlayer::stop() {
47
49
  }
48
50
  }
49
51
 
50
- void AudioPlayer::resume() {
51
- if (mStream_) {
52
- mStream_->requestStart();
53
- }
54
- }
55
-
56
- void AudioPlayer::suspend() {
52
+ void AudioPlayer::pause() {
57
53
  if (mStream_) {
58
54
  mStream_->requestPause();
59
55
  }
@@ -18,11 +18,10 @@ class AudioPlayer : public AudioStreamDataCallback {
18
18
  const std::function<void(std::shared_ptr<AudioBus>, int)> &renderAudio,
19
19
  float sampleRate);
20
20
 
21
- [[nodiscard]] float getSampleRate() const;
22
21
  void start();
23
- void stop();
24
22
  void resume();
25
- void suspend();
23
+ void stop();
24
+ void pause();
26
25
 
27
26
  DataCallbackResult onAudioReady(
28
27
  AudioStream *oboeStream,
@@ -1,12 +1,11 @@
1
1
  package com.swmansion.audioapi
2
2
 
3
- import android.content.Context
4
- import android.media.AudioManager
5
3
  import com.facebook.react.bridge.ReactApplicationContext
6
4
  import com.facebook.react.bridge.ReactContextBaseJavaModule
7
5
  import com.facebook.react.bridge.ReactMethod
8
6
  import com.facebook.react.bridge.ReadableArray
9
7
  import com.facebook.react.bridge.ReadableMap
8
+ import com.swmansion.audioapi.system.MediaSessionManager
10
9
 
11
10
  class AudioManagerModule(
12
11
  reactContext: ReactApplicationContext,
@@ -15,45 +14,51 @@ class AudioManagerModule(
15
14
  const val NAME = "AudioManagerModule"
16
15
  }
17
16
 
18
- private val audioManager: AudioManager = reactContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
19
-
20
17
  init {
21
18
  try {
22
19
  System.loadLibrary("react-native-audio-api")
23
20
  } catch (exception: UnsatisfiedLinkError) {
24
21
  throw RuntimeException("Could not load native module AudioAPIModule", exception)
25
22
  }
23
+
24
+ MediaSessionManager.initialize(reactContext)
26
25
  }
27
26
 
28
- @ReactMethod
27
+ @ReactMethod(isBlockingSynchronousMethod = true)
29
28
  fun setLockScreenInfo(info: ReadableMap?) {
29
+ MediaSessionManager.setLockScreenInfo(info)
30
30
  }
31
31
 
32
- @ReactMethod
32
+ @ReactMethod(isBlockingSynchronousMethod = true)
33
33
  fun resetLockScreenInfo() {
34
+ MediaSessionManager.resetLockScreenInfo()
34
35
  }
35
36
 
36
- @ReactMethod
37
+ @ReactMethod(isBlockingSynchronousMethod = true)
37
38
  fun enableRemoteCommand(
38
- name: String?,
39
+ name: String,
39
40
  enabled: Boolean,
40
41
  ) {
42
+ MediaSessionManager.enableRemoteCommand(name, enabled)
41
43
  }
42
44
 
43
- @ReactMethod
45
+ @ReactMethod(isBlockingSynchronousMethod = true)
44
46
  fun setAudioSessionOptions(
45
47
  category: String?,
46
48
  mode: String?,
47
49
  options: ReadableArray?,
48
- active: Boolean,
49
50
  ) {
51
+ // Nothing to do here
50
52
  }
51
53
 
52
54
  @ReactMethod(isBlockingSynchronousMethod = true)
53
- fun getDevicePreferredSampleRate(): Double {
54
- val sampleRate = this.audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)
55
- return sampleRate.toDouble()
56
- }
55
+ fun getDevicePreferredSampleRate(): Double = MediaSessionManager.getDevicePreferredSampleRate()
56
+
57
+ @ReactMethod(isBlockingSynchronousMethod = true)
58
+ fun observeAudioInterruptions(enable: Boolean) = MediaSessionManager.observeAudioInterruptions(enable)
59
+
60
+ @ReactMethod(isBlockingSynchronousMethod = true)
61
+ fun observeVolumeChanges(enable: Boolean) = MediaSessionManager.observeVolumeChanges(enable)
57
62
 
58
63
  override fun getName(): String = NAME
59
64
  }
@@ -0,0 +1,60 @@
1
+ package com.swmansion.audioapi.system
2
+
3
+ import android.media.AudioFocusRequest
4
+ import android.media.AudioManager
5
+ import android.os.Build
6
+ import android.util.Log
7
+
8
+ class AudioFocusListener(
9
+ private val audioManager: AudioManager,
10
+ val eventEmitter: MediaSessionEventEmitter,
11
+ private val lockScreenManager: LockScreenManager,
12
+ ) : AudioManager.OnAudioFocusChangeListener {
13
+ private var playOnAudioFocus = false
14
+ private var focusRequest: AudioFocusRequest? = null
15
+
16
+ override fun onAudioFocusChange(focusChange: Int) {
17
+ Log.d("AudioFocusListener", "onAudioFocusChange: $focusChange")
18
+ when (focusChange) {
19
+ AudioManager.AUDIOFOCUS_LOSS -> {
20
+ playOnAudioFocus = false
21
+ eventEmitter.onInterruption(mapOf("type" to "began", "shouldResume" to false))
22
+ }
23
+ AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
24
+ playOnAudioFocus = lockScreenManager.isPlaying
25
+ eventEmitter.onInterruption(mapOf("type" to "began", "shouldResume" to playOnAudioFocus))
26
+ }
27
+ AudioManager.AUDIOFOCUS_GAIN -> {
28
+ if (playOnAudioFocus) {
29
+ eventEmitter.onInterruption(mapOf("type" to "ended", "shouldResume" to true))
30
+ } else {
31
+ eventEmitter.onInterruption(mapOf("type" to "ended", "shouldResume" to false))
32
+ }
33
+
34
+ playOnAudioFocus = false
35
+ }
36
+ }
37
+ }
38
+
39
+ fun requestAudioFocus() {
40
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
41
+ this.focusRequest =
42
+ AudioFocusRequest
43
+ .Builder(AudioManager.AUDIOFOCUS_GAIN)
44
+ .setOnAudioFocusChangeListener(this)
45
+ .build()
46
+
47
+ audioManager.requestAudioFocus(focusRequest!!)
48
+ } else {
49
+ audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN)
50
+ }
51
+ }
52
+
53
+ fun abandonAudioFocus() {
54
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && this.focusRequest != null) {
55
+ audioManager.abandonAudioFocusRequest(focusRequest!!)
56
+ } else {
57
+ audioManager.abandonAudioFocus(this)
58
+ }
59
+ }
60
+ }