react-native-audio-api 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +58 -1
  2. package/RNAudioAPI.podspec +41 -0
  3. package/android/CMakeLists.txt +63 -0
  4. package/android/build.gradle +194 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +3 -0
  7. package/android/src/main/AndroidManifestNew.xml +2 -0
  8. package/android/src/main/cpp/AudioAPIInstaller/AudioAPIInstaller.cpp +22 -0
  9. package/android/src/main/cpp/AudioAPIInstaller/AudioAPIInstaller.h +48 -0
  10. package/android/src/main/cpp/AudioPlayer/AudioPlayer.cpp +45 -0
  11. package/android/src/main/cpp/AudioPlayer/AudioPlayer.h +30 -0
  12. package/android/src/main/cpp/OnLoad.cpp +9 -0
  13. package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +14 -0
  14. package/android/src/main/java/com/swmansion/audioapi/module/AudioAPIInstaller.kt +21 -0
  15. package/android/src/main/java/com/swmansion/audioapi/nativemodules/AudioAPIModule.kt +25 -0
  16. package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.cpp +52 -0
  17. package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h +45 -0
  18. package/common/cpp/AudioAPIInstaller/AudioAPIInstallerWrapper.h +38 -0
  19. package/common/cpp/AudioAPIInstaller/android/AudioAPIInstallerWrapper.cpp +16 -0
  20. package/common/cpp/AudioAPIInstaller/ios/AudioAPIInstallerWrapper.cpp +12 -0
  21. package/common/cpp/HostObjects/AudioBufferHostObject.cpp +143 -0
  22. package/common/cpp/HostObjects/AudioBufferHostObject.h +33 -0
  23. package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.cpp +67 -0
  24. package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.h +37 -0
  25. package/common/cpp/HostObjects/AudioContextHostObject.cpp +191 -0
  26. package/common/cpp/HostObjects/AudioContextHostObject.h +43 -0
  27. package/common/cpp/HostObjects/AudioDestinationNodeHostObject.cpp +33 -0
  28. package/common/cpp/HostObjects/AudioDestinationNodeHostObject.h +31 -0
  29. package/common/cpp/HostObjects/AudioNodeHostObject.cpp +108 -0
  30. package/common/cpp/HostObjects/AudioNodeHostObject.h +29 -0
  31. package/common/cpp/HostObjects/AudioParamHostObject.cpp +115 -0
  32. package/common/cpp/HostObjects/AudioParamHostObject.h +34 -0
  33. package/common/cpp/HostObjects/AudioScheduledSourceNodeHostObject.cpp +73 -0
  34. package/common/cpp/HostObjects/AudioScheduledSourceNodeHostObject.h +31 -0
  35. package/common/cpp/HostObjects/BiquadFilterNodeHostObject.cpp +81 -0
  36. package/common/cpp/HostObjects/BiquadFilterNodeHostObject.h +42 -0
  37. package/common/cpp/HostObjects/Constants.h +22 -0
  38. package/common/cpp/HostObjects/GainNodeHostObject.cpp +41 -0
  39. package/common/cpp/HostObjects/GainNodeHostObject.h +32 -0
  40. package/common/cpp/HostObjects/OscillatorNodeHostObject.cpp +67 -0
  41. package/common/cpp/HostObjects/OscillatorNodeHostObject.h +40 -0
  42. package/common/cpp/HostObjects/StereoPannerNodeHostObject.cpp +41 -0
  43. package/common/cpp/HostObjects/StereoPannerNodeHostObject.h +36 -0
  44. package/common/cpp/core/AudioBuffer.cpp +115 -0
  45. package/common/cpp/core/AudioBuffer.h +42 -0
  46. package/common/cpp/core/AudioBufferSourceNode.cpp +58 -0
  47. package/common/cpp/core/AudioBufferSourceNode.h +26 -0
  48. package/common/cpp/core/AudioContext.cpp +90 -0
  49. package/common/cpp/core/AudioContext.h +73 -0
  50. package/common/cpp/core/AudioDestinationNode.cpp +35 -0
  51. package/common/cpp/core/AudioDestinationNode.h +24 -0
  52. package/common/cpp/core/AudioNode.cpp +68 -0
  53. package/common/cpp/core/AudioNode.h +74 -0
  54. package/common/cpp/core/AudioParam.cpp +136 -0
  55. package/common/cpp/core/AudioParam.h +50 -0
  56. package/common/cpp/core/AudioScheduledSourceNode.cpp +39 -0
  57. package/common/cpp/core/AudioScheduledSourceNode.h +30 -0
  58. package/common/cpp/core/BiquadFilterNode.cpp +364 -0
  59. package/common/cpp/core/BiquadFilterNode.h +128 -0
  60. package/common/cpp/core/GainNode.cpp +30 -0
  61. package/common/cpp/core/GainNode.h +23 -0
  62. package/common/cpp/core/OscillatorNode.cpp +66 -0
  63. package/common/cpp/core/OscillatorNode.h +112 -0
  64. package/common/cpp/core/ParamChange.cpp +46 -0
  65. package/common/cpp/core/ParamChange.h +34 -0
  66. package/common/cpp/core/StereoPannerNode.cpp +58 -0
  67. package/common/cpp/core/StereoPannerNode.h +26 -0
  68. package/common/cpp/utils/VectorMath.cpp +609 -0
  69. package/common/cpp/utils/VectorMath.h +65 -0
  70. package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.cpp +35 -0
  71. package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.h +25 -0
  72. package/common/cpp/wrappers/AudioBufferWrapper.cpp +46 -0
  73. package/common/cpp/wrappers/AudioBufferWrapper.h +30 -0
  74. package/common/cpp/wrappers/AudioContextWrapper.cpp +70 -0
  75. package/common/cpp/wrappers/AudioContextWrapper.h +40 -0
  76. package/common/cpp/wrappers/AudioDestinationNodeWrapper.h +16 -0
  77. package/common/cpp/wrappers/AudioNodeWrapper.cpp +37 -0
  78. package/common/cpp/wrappers/AudioNodeWrapper.h +25 -0
  79. package/common/cpp/wrappers/AudioParamWrapper.cpp +42 -0
  80. package/common/cpp/wrappers/AudioParamWrapper.h +25 -0
  81. package/common/cpp/wrappers/AudioScheduledSourceNodeWrapper.cpp +23 -0
  82. package/common/cpp/wrappers/AudioScheduledSourceNodeWrapper.h +23 -0
  83. package/common/cpp/wrappers/BiquadFilterNodeWrapper.cpp +51 -0
  84. package/common/cpp/wrappers/BiquadFilterNodeWrapper.h +32 -0
  85. package/common/cpp/wrappers/GainNodeWrapper.cpp +14 -0
  86. package/common/cpp/wrappers/GainNodeWrapper.h +20 -0
  87. package/common/cpp/wrappers/OscillatorNodeWrapper.cpp +38 -0
  88. package/common/cpp/wrappers/OscillatorNodeWrapper.h +28 -0
  89. package/common/cpp/wrappers/StereoPannerNodeWrapper.cpp +16 -0
  90. package/common/cpp/wrappers/StereoPannerNodeWrapper.h +21 -0
  91. package/ios/AudioAPIModule.h +5 -0
  92. package/ios/AudioAPIModule.mm +44 -0
  93. package/ios/AudioPlayer/AudioPlayer.h +27 -0
  94. package/ios/AudioPlayer/AudioPlayer.m +121 -0
  95. package/ios/AudioPlayer/IOSAudioPlayer.h +29 -0
  96. package/ios/AudioPlayer/IOSAudioPlayer.mm +34 -0
  97. package/lib/module/index.js +39 -0
  98. package/lib/module/index.js.map +1 -0
  99. package/lib/module/modules/global.d.js +2 -0
  100. package/lib/module/modules/global.d.js.map +1 -0
  101. package/lib/module/types.js +2 -0
  102. package/lib/module/types.js.map +1 -0
  103. package/lib/module/utils/install.js +22 -0
  104. package/lib/module/utils/install.js.map +1 -0
  105. package/lib/typescript/index.d.ts +18 -0
  106. package/lib/typescript/index.d.ts.map +1 -0
  107. package/lib/typescript/types.d.ts +76 -0
  108. package/lib/typescript/types.d.ts.map +1 -0
  109. package/lib/typescript/utils/install.d.ts +7 -0
  110. package/lib/typescript/utils/install.d.ts.map +1 -0
  111. package/package.json +104 -5
  112. package/src/index.ts +79 -0
  113. package/src/modules/global.d.ts +10 -0
  114. package/src/types.ts +108 -0
  115. package/src/utils/install.ts +39 -0
  116. package/index.ts +0 -1
package/README.md CHANGED
@@ -1,3 +1,60 @@
1
+ <img src="./docs/assets/react-native-audio-api-gh-cover.png?v0.0.1" alt="React Native Audio API" width="100%">
2
+
3
+ ### ⚠️ Pre-Alpha
4
+
5
+ This library is at a very early stage of development. There are known performance issues and the library is not yet suitable for real production applications. We will be publishing the first alpha version of the library in the upcoming days, stay tuned! 🎶
6
+
7
+ If you have questions about the library, our progress, plans or just want to say "hi!" you can reach us in our <a href="https://discord.swmansion.com" target="_blank" rel="noopener noreferrer">discord server</a>
8
+
1
9
  ### React Native Audio API
2
10
 
3
- react-native-audio-api context provides system for controlling audio in react-native environment compatible with Web Audio API specification.
11
+ `react-native-audio-api` provides system for controlling audio in React Native environment compatible with Web Audio API specification,
12
+ allowing developers to generate and modify audio in exact same way it is possible in browsers.
13
+
14
+ ## Installation
15
+
16
+ 1. Install `react-native-audio-api` library
17
+
18
+ ```bash
19
+ # using npm
20
+ npm install react-native-audio-api
21
+
22
+ # or using yarn
23
+ yarn add react-native-audio-api
24
+ ```
25
+
26
+ ## Documentation
27
+
28
+ `react-native-audio-api` tries to strictly follow the Web Audi API specification, which can be found at [https://www.w3.org/TR/webaudio/](https://www.w3.org/TR/webaudio/).
29
+ <br />
30
+ [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) is useful resource to get familiar with audio processing basics.
31
+
32
+ ## Coverage
33
+
34
+ Our current coverage of Web Audio API specification can be found here: [Web Audio API coverage](./docs/web-audio-coverage.md).
35
+
36
+ ## Examples
37
+
38
+ The source code for the example application is under the [`/apps/common-app`](./apps/common-app/) directory. If you want to play with the API but don't feel like trying it on a real app, you can run the example project. Check [Example README](./apps/common-example/README.md) for installation instructions.
39
+
40
+ ## Your feedback
41
+
42
+ We are open to new ideas and general feedback. If you want to share your opinion about `react-native-audio-api` or have some thoughts about how it could be further developed, don't hesitate to create an issue or contact the maintainers directly.
43
+
44
+ ## License
45
+
46
+ react-native-audio-api library is licensed under [The MIT License](./LICENSE). Some of the source code uses implementation directly copied from Webkit and copyrights are held by respective organizations, check [COPYING](./COPYING) file for further details
47
+
48
+ ## Credits
49
+
50
+ This project has been built and is maintained thanks to the support from [Software Mansion](https://swmansion.com)
51
+
52
+ [![swm](https://logo.swmansion.com/logo?color=white&variant=desktop&width=150&tag=react-native-reanimated-github 'Software Mansion')](https://swmansion.com)
53
+
54
+ ## Community Discord
55
+
56
+ <a href="https://discord.swmansion.com" target="_blank" rel="noopener noreferrer">Join the Software Mansion Community Discord</a> to chat about React Native Audio API or other Software Mansion libraries.
57
+
58
+ ## react-native-audio-api is created by Software Mansion
59
+
60
+ Since 2012 [Software Mansion](https://swmansion.com) is a software agency with experience in building web and mobile apps. We are Core React Native Contributors and experts in dealing with all kinds of React Native issues. We can help you build your next dream product – [Hire us](https://swmansion.com/contact/projects?utm_source=reanimated&utm_medium=readme).
@@ -0,0 +1,41 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+ folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
5
+
6
+ Pod::Spec.new do |s|
7
+ s.name = "RNAudioAPI"
8
+ s.version = package["version"]
9
+ s.summary = package["description"]
10
+ s.homepage = package["homepage"]
11
+ s.license = package["license"]
12
+ s.authors = package["author"]
13
+
14
+ s.platforms = { :ios => min_ios_version_supported }
15
+ s.source = { :git => "https://github.com/software-mansion-labs/react-native-audio-api.git", :tag => "#{s.version}" }
16
+
17
+ s.source_files = "ios/**/*.{h,m,mm}", "common/cpp/**/*.{hpp,cpp,c,h}"
18
+
19
+ # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
20
+ # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
21
+ if respond_to?(:install_modules_dependencies, true)
22
+ install_modules_dependencies(s)
23
+ else
24
+ s.dependency "React-Core"
25
+
26
+ # Don't install the dependencies when we run `pod install` in the old architecture.
27
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
28
+ s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
29
+ s.pod_target_xcconfig = {
30
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
31
+ "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
32
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
33
+ }
34
+ s.dependency "React-Codegen"
35
+ s.dependency "RCT-Folly"
36
+ s.dependency "RCTRequired"
37
+ s.dependency "RCTTypeSafety"
38
+ s.dependency "ReactCommon/turbomodule/core"
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,63 @@
1
+ cmake_minimum_required(VERSION 3.9.0)
2
+ project(react-native-audio-api)
3
+
4
+ set(CMAKE_VERBOSE_MAKEFILE ON)
5
+ set(CMAKE_CXX_STANDARD 17)
6
+
7
+ # Detect the operating system
8
+ if(APPLE)
9
+ set(HAVE_ACCELERATE TRUE)
10
+ endif()
11
+
12
+ # Detect the processor and SIMD support
13
+ if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
14
+ set(HAVE_ARM_NEON_INTRINSICS TRUE)
15
+ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64")
16
+ set(HAVE_X86_SSE2 TRUE)
17
+ endif()
18
+
19
+ include("${REACT_NATIVE_DIR}/ReactAndroid/cmake-utils/folly-flags.cmake")
20
+ add_compile_options(${folly_FLAGS})
21
+
22
+ file(GLOB_RECURSE SOURCE_FILES
23
+ "src/main/cpp/*.cpp"
24
+ "src/main/cpp/*.h"
25
+ "../common/cpp/*.cpp"
26
+ "../common/cpp/*.h"
27
+ "../common/cpp/core/*.cpp"
28
+ "../common/cpp/core/*.h"
29
+ "../common/cpp/wrappers/*.cpp"
30
+ "../common/cpp/wrappers/*.h"
31
+ "../common/cpp/HostObjects/*.cpp"
32
+ "../common/cpp/HostObjects/*.h"
33
+ "../common/cpp/utils/*.cpp"
34
+ "../common/cpp/utils/*.h"
35
+ )
36
+
37
+ add_library(react-native-audio-api SHARED ${SOURCE_FILES})
38
+
39
+ file(GLOB DIRS CONFIGURE_DEPENDS "src/main/cpp/**" "../common/cpp/**")
40
+
41
+ target_include_directories(
42
+ react-native-audio-api
43
+ PRIVATE
44
+ ${DIRS}
45
+ "${REACT_NATIVE_DIR}/ReactCommon/jsi"
46
+ "${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni/react/jni"
47
+ "${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni/third-party/folly"
48
+ )
49
+
50
+ find_package(ReactAndroid REQUIRED CONFIG)
51
+ find_package(fbjni REQUIRED CONFIG)
52
+ find_package (oboe REQUIRED CONFIG)
53
+
54
+ set(LINK_LIBRARIES
55
+ ReactAndroid::reactnative
56
+ ReactAndroid::jsi
57
+ fbjni::fbjni
58
+ android
59
+ log
60
+ oboe::oboe
61
+ )
62
+
63
+ target_link_libraries(react-native-audio-api ${LINK_LIBRARIES})
@@ -0,0 +1,194 @@
1
+ import com.android.Version
2
+ import org.apache.tools.ant.taskdefs.condition.Os
3
+
4
+ buildscript {
5
+ repositories {
6
+ google()
7
+ mavenCentral()
8
+ }
9
+
10
+ dependencies {
11
+ classpath "com.android.tools.build:gradle:7.2.2"
12
+ }
13
+ }
14
+
15
+ def reactNativeArchitectures() {
16
+ def value = rootProject.getProperties().get("reactNativeArchitectures")
17
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
18
+ }
19
+
20
+ def isNewArchitectureEnabled() {
21
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
22
+ }
23
+
24
+ apply plugin: "com.android.library"
25
+ apply plugin: 'org.jetbrains.kotlin.android'
26
+
27
+ if (isNewArchitectureEnabled()) {
28
+ apply plugin: "com.facebook.react"
29
+ }
30
+
31
+ def getExtOrDefault(name) {
32
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["AudioAPI_" + name]
33
+ }
34
+
35
+ def getExtOrIntegerDefault(name) {
36
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["AudioAPI_" + name]).toInteger()
37
+ }
38
+
39
+ def resolveBuildType() {
40
+ Gradle gradle = getGradle()
41
+ String tskReqStr = gradle.getStartParameter().getTaskRequests()['args'].toString()
42
+ return tskReqStr.contains('Release') ? 'release' : 'debug'
43
+ }
44
+
45
+ def safeAppExtGet(prop, fallback) {
46
+ def appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') }
47
+ appProject?.ext?.has(prop) ? appProject.ext.get(prop) : fallback
48
+ }
49
+
50
+ def resolveReactNativeDirectory() {
51
+ def reactNativeLocation = safeAppExtGet("REACT_NATIVE_NODE_MODULES_DIR", null)
52
+
53
+ if (reactNativeLocation !== null) {
54
+ return file(reactNativeLocation)
55
+ }
56
+
57
+ // Fallback to node resolver for custom directory structures like monorepos.
58
+ def reactNativePackage = file(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim())
59
+ if(reactNativePackage.exists()) {
60
+ return reactNativePackage.parentFile
61
+ }
62
+
63
+ throw new GradleException(
64
+ "[AudioAPI] Unable to resolve react-native location in node_modules. You should project extension property (in `app/build.gradle`) `REACT_NATIVE_NODE_MODULES_DIR` with path to react-native."
65
+ )
66
+ }
67
+
68
+ def toPlatformFileString(String path) {
69
+ if (Os.isFamily(Os.FAMILY_WINDOWS)) {
70
+ path = path.replace(File.separatorChar, '/' as char)
71
+ }
72
+ return path
73
+ }
74
+
75
+ def reactNativeRootDir = resolveReactNativeDirectory()
76
+
77
+ static def supportsNamespace() {
78
+ def parsed = Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
79
+ def major = parsed[0].toInteger()
80
+ def minor = parsed[1].toInteger()
81
+
82
+ // Namespace support was added in 7.3.0
83
+ return (major == 7 && minor >= 3) || major >= 8
84
+ }
85
+
86
+ android {
87
+ if (supportsNamespace()) {
88
+ namespace "com.swmansion.audioapi"
89
+
90
+ sourceSets {
91
+ main {
92
+ manifest.srcFile "src/main/AndroidManifestNew.xml"
93
+ }
94
+ }
95
+ }
96
+
97
+ ndkVersion getExtOrDefault("ndkVersion")
98
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
99
+
100
+ defaultConfig {
101
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
102
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
103
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
104
+
105
+ externalNativeBuild {
106
+ cmake {
107
+ cppFlags "-O2 -frtti -fexceptions -Wall -fstack-protector-all"
108
+ abiFilters (*reactNativeArchitectures())
109
+ arguments "-DANDROID_STL=c++_shared",
110
+ "-DREACT_NATIVE_DIR=${toPlatformFileString(reactNativeRootDir.path)}"
111
+ }
112
+ }
113
+ }
114
+
115
+ packagingOptions {
116
+ excludes = ["**/libc++_shared.so", "**/libfbjni.so", "**/libjsi.so", "**/libreactnativejni.so", "**/libfolly_json.so", "**/libreanimated.so", "**/libjscexecutor.so", "**/libhermes.so"]
117
+ }
118
+
119
+ externalNativeBuild {
120
+ cmake {
121
+ path "CMakeLists.txt"
122
+ }
123
+ }
124
+
125
+ buildFeatures {
126
+ buildConfig true
127
+ prefab true
128
+ }
129
+
130
+ buildTypes {
131
+ release {
132
+ minifyEnabled false
133
+ }
134
+ }
135
+
136
+ lintOptions {
137
+ disable "GradleCompatible"
138
+ }
139
+
140
+ compileOptions {
141
+ sourceCompatibility JavaVersion.VERSION_1_8
142
+ targetCompatibility JavaVersion.VERSION_1_8
143
+
144
+ packagingOptions {
145
+ doNotStrip resolveBuildType() == 'debug' ? "**/**/*.so" : ''
146
+
147
+ excludes = [
148
+ "**/libjsi.so",
149
+ "**/libfolly_runtime.so",
150
+ "**/libreactnativejni.so",
151
+ ]
152
+ }
153
+ }
154
+
155
+ sourceSets {
156
+ main {
157
+ if (isNewArchitectureEnabled()) {
158
+ java.srcDirs += [
159
+ // This is needed to build Kotlin project with NewArch enabled
160
+ "${project.buildDir}/generated/source/codegen/java"
161
+ ]
162
+ }
163
+ }
164
+ }
165
+ kotlinOptions {
166
+ jvmTarget = '17'
167
+ }
168
+ }
169
+
170
+ repositories {
171
+ mavenCentral()
172
+ google()
173
+ }
174
+
175
+
176
+ dependencies {
177
+ // For < 0.71, this will be from the local maven repo
178
+ // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
179
+ //noinspection GradleDynamicVersion
180
+ implementation "com.facebook.react:react-native:+"
181
+ implementation 'androidx.core:core-ktx:1.13.1'
182
+ implementation 'com.facebook.fbjni:fbjni:0.6.0'
183
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2"
184
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2"
185
+ implementation 'com.google.oboe:oboe:1.9.0'
186
+ }
187
+
188
+ if (isNewArchitectureEnabled()) {
189
+ react {
190
+ jsRootDir = file("../src/")
191
+ libraryName = "react-native-audio-api"
192
+ codegenJavaPackageName = "com.swmansion.audioapi"
193
+ }
194
+ }
@@ -0,0 +1,5 @@
1
+ AudioAPI_kotlinVersion=1.7.0
2
+ AudioAPI_minSdkVersion=21
3
+ AudioAPI_targetSdkVersion=31
4
+ AudioAPI_compileSdkVersion=31
5
+ AudioAPI_ndkversion=21.4.7075529
@@ -0,0 +1,3 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
+ package="com.swmansion.audioapi">
3
+ </manifest>
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,22 @@
1
+ #include "AudioAPIInstaller.h"
2
+
3
+ namespace audioapi {
4
+
5
+ using namespace facebook::jni;
6
+
7
+ AudioAPIInstaller::AudioAPIInstaller(
8
+ jni::alias_ref<AudioAPIInstaller::jhybridobject> &jThis)
9
+ : javaPart_(make_global(jThis)) {}
10
+
11
+ void AudioAPIInstaller::install(jlong jsContext) {
12
+ auto audioAPIInstallerWrapper =
13
+ std::make_shared<AudioAPIInstallerWrapper>(this);
14
+ AudioAPIInstallerHostObject::createAndInstallFromWrapper(
15
+ audioAPIInstallerWrapper, jsContext);
16
+ }
17
+
18
+ std::shared_ptr<AudioContext> AudioAPIInstaller::createAudioContext() {
19
+ return std::make_shared<AudioContext>();
20
+ }
21
+
22
+ } // namespace audioapi
@@ -0,0 +1,48 @@
1
+ #pragma once
2
+
3
+ #include <fbjni/fbjni.h>
4
+ #include <jsi/jsi.h>
5
+ #include <react/jni/CxxModuleWrapper.h>
6
+ #include <react/jni/JMessageQueueThread.h>
7
+ #include <memory>
8
+ #include <utility>
9
+
10
+ #include "AudioAPIInstallerHostObject.h"
11
+ #include "AudioAPIInstallerWrapper.h"
12
+ #include "AudioContext.h"
13
+
14
+ namespace audioapi {
15
+
16
+ using namespace facebook;
17
+ using namespace facebook::jni;
18
+
19
+ class AudioAPIInstaller : public jni::HybridClass<AudioAPIInstaller> {
20
+ public:
21
+ static auto constexpr kJavaDescriptor =
22
+ "Lcom/swmansion/audioapi/module/AudioAPIInstaller;";
23
+
24
+ static jni::local_ref<AudioAPIInstaller::jhybriddata> initHybrid(
25
+ jni::alias_ref<jhybridobject> jThis) {
26
+ return makeCxxInstance(jThis);
27
+ }
28
+
29
+ static void registerNatives() {
30
+ registerHybrid({
31
+ makeNativeMethod("initHybrid", AudioAPIInstaller::initHybrid),
32
+ makeNativeMethod("install", AudioAPIInstaller::install),
33
+ });
34
+ }
35
+
36
+ std::shared_ptr<AudioContext> createAudioContext();
37
+ void install(jlong jsContext);
38
+
39
+ private:
40
+ friend HybridBase;
41
+
42
+ global_ref<AudioAPIInstaller::javaobject> javaPart_;
43
+
44
+ explicit AudioAPIInstaller(
45
+ jni::alias_ref<AudioAPIInstaller::jhybridobject> &jThis);
46
+ };
47
+
48
+ } // namespace audioapi
@@ -0,0 +1,45 @@
1
+ #include "AudioPlayer.h"
2
+ #include "AudioContext.h"
3
+
4
+ namespace audioapi {
5
+ AudioPlayer::AudioPlayer(const std::function<void(float *, int)> &renderAudio)
6
+ : renderAudio_(renderAudio) {
7
+ AudioStreamBuilder builder;
8
+ builder.setSharingMode(SharingMode::Exclusive)
9
+ ->setFormat(AudioFormat::Float)
10
+ ->setFormatConversionAllowed(true)
11
+ ->setPerformanceMode(PerformanceMode::LowLatency)
12
+ ->setChannelCount(CHANNEL_COUNT)
13
+ ->setSampleRateConversionQuality(SampleRateConversionQuality::Medium)
14
+ ->setDataCallback(this)
15
+ ->openStream(mStream_);
16
+ }
17
+
18
+ int AudioPlayer::getSampleRate() const {
19
+ return mStream_->getSampleRate();
20
+ }
21
+
22
+ void AudioPlayer::start() {
23
+ if (mStream_) {
24
+ mStream_->requestStart();
25
+ }
26
+ }
27
+
28
+ void AudioPlayer::stop() {
29
+ if (mStream_) {
30
+ mStream_->requestStop();
31
+ mStream_->close();
32
+ mStream_.reset();
33
+ }
34
+ }
35
+
36
+ DataCallbackResult AudioPlayer::onAudioReady(
37
+ AudioStream *oboeStream,
38
+ void *audioData,
39
+ int32_t numFrames) {
40
+ auto buffer = static_cast<float *>(audioData);
41
+ renderAudio_(buffer, numFrames);
42
+
43
+ return DataCallbackResult::Continue;
44
+ }
45
+ } // namespace audioapi
@@ -0,0 +1,30 @@
1
+ #pragma once
2
+
3
+ #include <oboe/Oboe.h>
4
+ #include <memory>
5
+
6
+ namespace audioapi {
7
+
8
+ using namespace oboe;
9
+
10
+ class AudioContext;
11
+
12
+ class AudioPlayer : public AudioStreamDataCallback {
13
+ public:
14
+ explicit AudioPlayer(const std::function<void(float *, int)> &renderAudio);
15
+
16
+ int getSampleRate() const;
17
+ void start();
18
+ void stop();
19
+
20
+ DataCallbackResult onAudioReady(
21
+ AudioStream *oboeStream,
22
+ void *audioData,
23
+ int32_t numFrames) override;
24
+
25
+ private:
26
+ std::function<void(float *, int)> renderAudio_;
27
+ std::shared_ptr<AudioStream> mStream_;
28
+ };
29
+
30
+ } // namespace audioapi
@@ -0,0 +1,9 @@
1
+ #include <fbjni/fbjni.h>
2
+ #include "AudioAPIInstaller.h"
3
+
4
+ using namespace audioapi;
5
+
6
+ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
7
+ return facebook::jni::initialize(
8
+ vm, [] { AudioAPIInstaller::registerNatives(); });
9
+ }
@@ -0,0 +1,14 @@
1
+ package com.swmansion.audioapi
2
+
3
+ import com.facebook.react.ReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.uimanager.ViewManager
7
+ import com.swmansion.audioapi.nativemodules.AudioAPIModule
8
+
9
+ class AudioAPIPackage : ReactPackage {
10
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> =
11
+ listOf<NativeModule>(AudioAPIModule(reactContext))
12
+
13
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> = emptyList()
14
+ }
@@ -0,0 +1,21 @@
1
+ package com.swmansion.audioapi.module
2
+
3
+ import com.facebook.jni.HybridData
4
+
5
+ class AudioAPIInstaller {
6
+ private val mHybridData: HybridData?
7
+
8
+ companion object {
9
+ init {
10
+ System.loadLibrary("react-native-audio-api")
11
+ }
12
+ }
13
+
14
+ init {
15
+ mHybridData = initHybrid()
16
+ }
17
+
18
+ external fun initHybrid(): HybridData?
19
+
20
+ external fun install(jsContext: Long)
21
+ }
@@ -0,0 +1,25 @@
1
+ package com.swmansion.audioapi.nativemodules
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
5
+ import com.facebook.react.bridge.ReactMethod
6
+ import com.swmansion.audioapi.module.AudioAPIInstaller
7
+
8
+ class AudioAPIModule(
9
+ private val reactContext: ReactApplicationContext,
10
+ ) : ReactContextBaseJavaModule(reactContext) {
11
+ override fun getName(): String = NAME
12
+
13
+ @ReactMethod(isBlockingSynchronousMethod = true)
14
+ fun install(): Boolean {
15
+ val audioAPIInstaller = AudioAPIInstaller()
16
+ val jsContext = reactContext.javaScriptContextHolder!!.get()
17
+ audioAPIInstaller.install(jsContext)
18
+
19
+ return true
20
+ }
21
+
22
+ companion object {
23
+ const val NAME: String = "AudioAPIModule"
24
+ }
25
+ }
@@ -0,0 +1,52 @@
1
+ #include "AudioAPIInstallerHostObject.h"
2
+
3
+ namespace audioapi {
4
+ using namespace facebook;
5
+
6
+ AudioAPIInstallerHostObject::AudioAPIInstallerHostObject(
7
+ const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper)
8
+ : wrapper_(wrapper) {}
9
+
10
+ std::vector<jsi::PropNameID> AudioAPIInstallerHostObject::getPropertyNames(
11
+ jsi::Runtime &runtime) {
12
+ std::vector<jsi::PropNameID> propertyNames;
13
+ propertyNames.push_back(
14
+ jsi::PropNameID::forUtf8(runtime, "createAudioContext"));
15
+ return propertyNames;
16
+ }
17
+
18
+ jsi::Value AudioAPIInstallerHostObject::get(
19
+ jsi::Runtime &runtime,
20
+ const jsi::PropNameID &propNameId) {
21
+ auto propName = propNameId.utf8(runtime);
22
+
23
+ if (propName == "createAudioContext") {
24
+ return jsi::Function::createFromHostFunction(
25
+ runtime,
26
+ propNameId,
27
+ 0,
28
+ [this](
29
+ jsi::Runtime &runtime,
30
+ const jsi::Value &thisValue,
31
+ const jsi::Value *arguments,
32
+ size_t count) -> jsi::Value {
33
+ auto audioContext = wrapper_->createAudioContext();
34
+ auto audioContextHostObject =
35
+ AudioContextHostObject::createFromWrapper(audioContext);
36
+ return jsi::Object::createFromHostObject(
37
+ runtime, audioContextHostObject);
38
+ });
39
+ }
40
+
41
+ throw std::runtime_error("Not yet implemented!");
42
+ }
43
+
44
+ void AudioAPIInstallerHostObject::set(
45
+ jsi::Runtime &runtime,
46
+ const jsi::PropNameID &propNameId,
47
+ const jsi::Value &value) {
48
+ auto propName = propNameId.utf8(runtime);
49
+
50
+ throw std::runtime_error("Not yet implemented!");
51
+ }
52
+ } // namespace audioapi