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.
- package/README.md +35 -22
- package/android/CMakeLists.txt +6 -3
- package/android/build.gradle +1 -0
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +73 -0
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +37 -0
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +6 -10
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.h +2 -3
- package/android/src/main/java/com/swmansion/audioapi/AudioManagerModule.kt +19 -14
- package/android/src/main/java/com/swmansion/audioapi/system/AudioFocusListener.kt +60 -0
- package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +294 -0
- package/android/src/main/java/com/swmansion/audioapi/system/MediaNotificationManager.kt +279 -0
- package/android/src/main/java/com/swmansion/audioapi/system/MediaReceiver.kt +46 -0
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionCallback.kt +39 -0
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionEventEmitter.kt +88 -0
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +162 -0
- package/android/src/main/java/com/swmansion/audioapi/system/VolumeChangeListener.kt +27 -0
- package/android/src/main/res/drawable/next.xml +9 -0
- package/android/src/main/res/drawable/pause.xml +9 -0
- package/android/src/main/res/drawable/play.xml +9 -0
- package/android/src/main/res/drawable/previous.xml +9 -0
- package/android/src/main/res/drawable/skip_backward_5.xml +9 -0
- package/android/src/main/res/drawable/skip_forward_5.xml +9 -0
- package/android/src/main/res/drawable/stop.xml +9 -0
- package/app.plugin.js +1 -0
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +29 -5
- package/common/cpp/audioapi/HostObjects/AnalyserNodeHostObject.h +1 -0
- package/common/cpp/audioapi/HostObjects/AudioRecorderHostObject.h +149 -0
- package/common/cpp/audioapi/core/AudioContext.cpp +4 -3
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +6 -6
- package/common/cpp/audioapi/core/inputs/AudioRecorder.h +38 -0
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +1 -6
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +8 -4
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +6 -0
- package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +1 -1
- package/common/cpp/audioapi/core/utils/AudioNodeDestructor.cpp +3 -3
- package/common/cpp/audioapi/core/utils/AudioNodeManager.cpp +45 -11
- package/common/cpp/audioapi/core/utils/AudioNodeManager.h +6 -2
- package/ios/audioapi/ios/AudioManagerModule.mm +16 -15
- package/ios/audioapi/ios/core/IOSAudioPlayer.h +11 -12
- package/ios/audioapi/ios/core/IOSAudioPlayer.mm +22 -16
- package/ios/audioapi/ios/core/IOSAudioRecorder.h +36 -0
- package/ios/audioapi/ios/core/IOSAudioRecorder.mm +62 -0
- package/ios/audioapi/ios/core/{AudioPlayer.h → NativeAudioPlayer.h} +1 -8
- package/ios/audioapi/ios/core/{AudioPlayer.m → NativeAudioPlayer.m} +4 -33
- package/ios/audioapi/ios/core/NativeAudioRecorder.h +25 -0
- package/ios/audioapi/ios/core/NativeAudioRecorder.m +47 -0
- package/ios/audioapi/ios/system/AudioEngine.h +7 -1
- package/ios/audioapi/ios/system/AudioEngine.mm +64 -20
- package/ios/audioapi/ios/system/AudioSessionManager.h +3 -1
- package/ios/audioapi/ios/system/AudioSessionManager.mm +37 -25
- package/ios/audioapi/ios/system/LockScreenManager.mm +4 -8
- package/ios/audioapi/ios/system/NotificationManager.h +13 -1
- package/ios/audioapi/ios/system/NotificationManager.mm +96 -44
- package/lib/commonjs/api.js +211 -0
- package/lib/commonjs/api.js.map +1 -0
- package/lib/commonjs/api.web.js +219 -0
- package/lib/commonjs/api.web.js.map +1 -0
- package/lib/commonjs/core/AnalyserNode.js +71 -0
- package/lib/commonjs/core/AnalyserNode.js.map +1 -0
- package/lib/commonjs/core/AudioBuffer.js +44 -0
- package/lib/commonjs/core/AudioBuffer.js.map +1 -0
- package/lib/commonjs/core/AudioBufferSourceNode.js +68 -0
- package/lib/commonjs/core/AudioBufferSourceNode.js.map +1 -0
- package/lib/commonjs/core/AudioContext.js +29 -0
- package/lib/commonjs/core/AudioContext.js.map +1 -0
- package/lib/commonjs/core/AudioDestinationNode.js +11 -0
- package/lib/commonjs/core/AudioDestinationNode.js.map +1 -0
- package/lib/commonjs/core/AudioNode.js +30 -0
- package/lib/commonjs/core/AudioNode.js.map +1 -0
- package/lib/commonjs/core/AudioParam.js +82 -0
- package/lib/commonjs/core/AudioParam.js.map +1 -0
- package/lib/commonjs/core/AudioRecorder.js +51 -0
- package/lib/commonjs/core/AudioRecorder.js.map +1 -0
- package/lib/commonjs/core/AudioScheduledSourceNode.js +38 -0
- package/lib/commonjs/core/AudioScheduledSourceNode.js.map +1 -0
- package/lib/commonjs/core/BaseAudioContext.js +80 -0
- package/lib/commonjs/core/BaseAudioContext.js.map +1 -0
- package/lib/commonjs/core/BiquadFilterNode.js +33 -0
- package/lib/commonjs/core/BiquadFilterNode.js.map +1 -0
- package/lib/commonjs/core/GainNode.js +17 -0
- package/lib/commonjs/core/GainNode.js.map +1 -0
- package/lib/commonjs/core/OfflineAudioContext.js +63 -0
- package/lib/commonjs/core/OfflineAudioContext.js.map +1 -0
- package/lib/commonjs/core/OscillatorNode.js +32 -0
- package/lib/commonjs/core/OscillatorNode.js.map +1 -0
- package/lib/commonjs/core/PeriodicWave.js +15 -0
- package/lib/commonjs/core/PeriodicWave.js.map +1 -0
- package/lib/commonjs/core/StereoPannerNode.js +17 -0
- package/lib/commonjs/core/StereoPannerNode.js.map +1 -0
- package/lib/commonjs/errors/IndexSizeError.js +14 -0
- package/lib/commonjs/errors/IndexSizeError.js.map +1 -0
- package/lib/commonjs/errors/InvalidAccessError.js +14 -0
- package/lib/commonjs/errors/InvalidAccessError.js.map +1 -0
- package/lib/commonjs/errors/InvalidStateError.js +14 -0
- package/lib/commonjs/errors/InvalidStateError.js.map +1 -0
- package/lib/commonjs/errors/NotSupportedError.js +14 -0
- package/lib/commonjs/errors/NotSupportedError.js.map +1 -0
- package/lib/commonjs/errors/RangeError.js +14 -0
- package/lib/commonjs/errors/RangeError.js.map +1 -0
- package/lib/commonjs/errors/index.js +42 -0
- package/lib/commonjs/errors/index.js.map +1 -0
- package/lib/commonjs/hooks/useSytemVolume.js +24 -0
- package/lib/commonjs/hooks/useSytemVolume.js.map +1 -0
- package/lib/commonjs/index.js +17 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/interfaces.js +6 -0
- package/lib/commonjs/interfaces.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/plugin/withAudioAPI.js +62 -0
- package/lib/commonjs/plugin/withAudioAPI.js.map +1 -0
- package/lib/commonjs/specs/NativeAudioAPIModule.js +9 -0
- package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -0
- package/lib/commonjs/specs/NativeAudioManagerModule.js +36 -0
- package/lib/commonjs/specs/NativeAudioManagerModule.js.map +1 -0
- package/lib/commonjs/specs/index.js +27 -0
- package/lib/commonjs/specs/index.js.map +1 -0
- package/lib/commonjs/system/AudioManager.js +52 -0
- package/lib/commonjs/system/AudioManager.js.map +1 -0
- package/lib/commonjs/system/index.js +14 -0
- package/lib/commonjs/system/index.js.map +1 -0
- package/lib/commonjs/system/types.js +2 -0
- package/lib/commonjs/system/types.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/utils/index.js +10 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/commonjs/web-core/AnalyserNode.js +38 -0
- package/lib/commonjs/web-core/AnalyserNode.js.map +1 -0
- package/lib/commonjs/web-core/AudioBuffer.js +44 -0
- package/lib/commonjs/web-core/AudioBuffer.js.map +1 -0
- package/lib/commonjs/web-core/AudioBufferSourceNode.js +214 -0
- package/lib/commonjs/web-core/AudioBufferSourceNode.js.map +1 -0
- package/lib/commonjs/web-core/AudioContext.js +93 -0
- package/lib/commonjs/web-core/AudioContext.js.map +1 -0
- package/lib/commonjs/web-core/AudioDestinationNode.js +11 -0
- package/lib/commonjs/web-core/AudioDestinationNode.js.map +1 -0
- package/lib/commonjs/web-core/AudioNode.js +33 -0
- package/lib/commonjs/web-core/AudioNode.js.map +1 -0
- package/lib/commonjs/web-core/AudioParam.js +81 -0
- package/lib/commonjs/web-core/AudioParam.js.map +1 -0
- package/lib/commonjs/web-core/AudioScheduledSourceNode.js +41 -0
- package/lib/commonjs/web-core/AudioScheduledSourceNode.js.map +1 -0
- package/lib/commonjs/web-core/BaseAudioContext.js +2 -0
- package/lib/commonjs/web-core/BaseAudioContext.js.map +1 -0
- package/lib/commonjs/web-core/BiquadFilterNode.js +33 -0
- package/lib/commonjs/web-core/BiquadFilterNode.js.map +1 -0
- package/lib/commonjs/web-core/GainNode.js +17 -0
- package/lib/commonjs/web-core/GainNode.js.map +1 -0
- package/lib/commonjs/web-core/OfflineAudioContext.js +96 -0
- package/lib/commonjs/web-core/OfflineAudioContext.js.map +1 -0
- package/lib/commonjs/web-core/OscillatorNode.js +31 -0
- package/lib/commonjs/web-core/OscillatorNode.js.map +1 -0
- package/lib/commonjs/web-core/PeriodicWave.js +15 -0
- package/lib/commonjs/web-core/PeriodicWave.js.map +1 -0
- package/lib/commonjs/web-core/StereoPannerNode.js +17 -0
- package/lib/commonjs/web-core/StereoPannerNode.js.map +1 -0
- package/lib/commonjs/web-core/custom/LoadCustomWasm.js +37 -0
- package/lib/commonjs/web-core/custom/LoadCustomWasm.js.map +1 -0
- package/lib/commonjs/web-core/custom/index.js +14 -0
- package/lib/commonjs/web-core/custom/index.js.map +1 -0
- package/lib/commonjs/web-core/custom/signalsmithStretch/LICENSE.txt +21 -0
- package/lib/commonjs/web-core/custom/signalsmithStretch/README.md +46 -0
- package/lib/commonjs/web-core/custom/signalsmithStretch/SignalsmithStretch.mjs +826 -0
- package/lib/commonjs/web-core/custom/signalsmithStretch/SignalsmithStretch.mjs.map +1 -0
- package/lib/module/api.js +3 -1
- package/lib/module/api.js.map +1 -1
- package/lib/module/core/AudioRecorder.js +45 -0
- package/lib/module/core/AudioRecorder.js.map +1 -0
- package/lib/module/errors/NotSupportedError.js.map +1 -1
- package/lib/module/hooks/useSytemVolume.js +19 -0
- package/lib/module/hooks/useSytemVolume.js.map +1 -0
- package/lib/module/plugin/withAudioAPI.js +58 -0
- package/lib/module/plugin/withAudioAPI.js.map +1 -0
- package/lib/module/specs/NativeAudioManagerModule.js +10 -8
- package/lib/module/specs/NativeAudioManagerModule.js.map +1 -1
- package/lib/module/system/AudioManager.js +26 -44
- package/lib/module/system/AudioManager.js.map +1 -1
- package/lib/typescript/api.d.ts +5 -1
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/core/AudioRecorder.d.ts +22 -0
- package/lib/typescript/core/AudioRecorder.d.ts.map +1 -0
- package/lib/typescript/errors/NotSupportedError.d.ts.map +1 -1
- package/lib/typescript/hooks/useSytemVolume.d.ts +2 -0
- package/lib/typescript/hooks/useSytemVolume.d.ts.map +1 -0
- package/lib/typescript/interfaces.d.ts +11 -5
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/plugin/withAudioAPI.d.ts +9 -0
- package/lib/typescript/plugin/withAudioAPI.d.ts.map +1 -0
- package/lib/typescript/specs/NativeAudioManagerModule.d.ts +4 -2
- package/lib/typescript/specs/NativeAudioManagerModule.d.ts.map +1 -1
- package/lib/typescript/system/AudioManager.d.ts +5 -2
- package/lib/typescript/system/AudioManager.d.ts.map +1 -1
- package/lib/typescript/system/types.d.ts +36 -5
- package/lib/typescript/system/types.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +5 -0
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +7 -3
- package/src/api.ts +13 -2
- package/src/core/AudioRecorder.ts +81 -0
- package/src/hooks/useSytemVolume.ts +19 -0
- package/src/interfaces.ts +25 -11
- package/src/plugin/withAudioAPI.ts +91 -0
- package/src/specs/NativeAudioManagerModule.ts +13 -19
- package/src/system/AudioManager.ts +37 -87
- package/src/system/types.ts +43 -17
- package/src/types.ts +13 -0
- /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
|
|
3
|
+
### High-performance audio engine for React Native based on web audio api specification
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/react-native-audio-api)
|
|
6
|
+
[](https://www.npmjs.com/package/react-native-audio-api?activeTab=versions)
|
|
7
|
+
[](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
|
-
|
|
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
|
-
|
|
13
|
-
# using npm
|
|
14
|
-
npm install react-native-audio-api
|
|
16
|
+
## Roadmap
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
- <sub>[](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
|
-
|
|
22
|
+
- <sub>[](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>[](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
|
-
|
|
29
|
+
- <sub>[](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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
# Build native Android project
|
|
28
|
-
npx expo run:android
|
|
29
|
-
```
|
|
33
|
+
- <sub>[](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
|
-
|
|
37
|
+
- <sub></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
|
-
|
|
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
|
-
|
|
36
|
-
|
|
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
|
-
|
|
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
|
|
package/android/CMakeLists.txt
CHANGED
|
@@ -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
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
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")
|
package/android/build.gradle
CHANGED
|
@@ -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
|
-
|
|
31
|
-
|
|
30
|
+
void AudioPlayer::start() {
|
|
31
|
+
if (mStream_) {
|
|
32
|
+
mStream_->requestStart();
|
|
33
|
+
}
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
void AudioPlayer::
|
|
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::
|
|
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
|
|
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
|
-
|
|
55
|
-
|
|
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
|
+
}
|