react-native-audio-api 0.3.1 → 0.4.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 (155) hide show
  1. package/README.md +17 -11
  2. package/RNAudioAPI.podspec +40 -29
  3. package/android/CMakeLists.txt +17 -21
  4. package/android/build.gradle +26 -9
  5. package/android/src/main/cpp/OnLoad.cpp +1 -1
  6. package/android/src/main/cpp/core/AudioAPIInstaller.cpp +37 -0
  7. package/android/src/main/cpp/{AudioAPIInstaller → core}/AudioAPIInstaller.h +4 -13
  8. package/android/src/main/cpp/{AudioDecoder → core}/AudioDecoder.cpp +0 -8
  9. package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +2 -0
  10. package/android/src/main/java/com/swmansion/audioapi/nativemodules/AudioAPIModule.kt +6 -4
  11. package/common/cpp/HostObjects/AnalyserNodeHostObject.h +151 -0
  12. package/common/cpp/HostObjects/AudioParamHostObject.h +39 -2
  13. package/common/cpp/HostObjects/BaseAudioContextHostObject.h +8 -0
  14. package/common/cpp/core/AnalyserNode.cpp +237 -0
  15. package/common/cpp/core/AnalyserNode.h +54 -0
  16. package/common/cpp/core/AudioBufferSourceNode.cpp +4 -3
  17. package/{android/src/main/cpp/AudioDecoder → common/cpp/core}/AudioDecoder.h +1 -3
  18. package/common/cpp/core/AudioNode.cpp +6 -5
  19. package/common/cpp/core/AudioParam.cpp +218 -58
  20. package/common/cpp/core/AudioParam.h +19 -15
  21. package/common/cpp/core/AudioScheduledSourceNode.cpp +9 -2
  22. package/common/cpp/core/AudioScheduledSourceNode.h +4 -1
  23. package/common/cpp/core/BaseAudioContext.cpp +7 -12
  24. package/common/cpp/core/BaseAudioContext.h +4 -4
  25. package/common/cpp/core/BiquadFilterNode.cpp +5 -7
  26. package/common/cpp/{HostObjects → core}/Constants.h +11 -5
  27. package/common/cpp/core/GainNode.cpp +1 -1
  28. package/common/cpp/core/OscillatorNode.cpp +4 -3
  29. package/common/cpp/core/ParamChangeEvent.cpp +58 -0
  30. package/common/cpp/core/{ParamChange.h → ParamChangeEvent.h} +11 -5
  31. package/common/cpp/core/PeriodicWave.cpp +2 -2
  32. package/common/cpp/core/StereoPannerNode.cpp +1 -1
  33. package/common/cpp/jsi/JsiHostObject.cpp +35 -30
  34. package/common/cpp/jsi/JsiHostObject.h +12 -6
  35. package/common/cpp/jsi/RuntimeAwareCache.h +57 -0
  36. package/common/cpp/jsi/RuntimeLifecycleMonitor.cpp +61 -0
  37. package/common/cpp/jsi/RuntimeLifecycleMonitor.h +32 -0
  38. package/common/cpp/types/BiquadFilterType.h +0 -4
  39. package/common/cpp/types/ChannelCountMode.h +0 -3
  40. package/common/cpp/types/ChannelInterpretation.h +0 -3
  41. package/common/cpp/types/ContextState.h +0 -3
  42. package/common/cpp/types/OscillatorType.h +0 -4
  43. package/common/cpp/types/ParamChangeEventType.h +13 -0
  44. package/common/cpp/utils/AudioUtils.cpp +7 -0
  45. package/common/cpp/utils/AudioUtils.h +6 -6
  46. package/common/cpp/utils/FFTFrame.cpp +102 -0
  47. package/common/cpp/utils/FFTFrame.h +25 -10
  48. package/common/cpp/utils/VectorMath.cpp +10 -0
  49. package/common/cpp/utils/VectorMath.h +9 -33
  50. package/ios/AudioAPIModule.h +4 -12
  51. package/ios/AudioAPIModule.mm +25 -20
  52. package/ios/core/AudioDecoder.mm +45 -0
  53. package/lib/module/core/AnalyserNode.js +59 -0
  54. package/lib/module/core/AnalyserNode.js.map +1 -0
  55. package/lib/module/core/AudioBuffer.js +3 -1
  56. package/lib/module/core/AudioBuffer.js.map +1 -1
  57. package/lib/module/core/AudioBufferSourceNode.js +5 -3
  58. package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
  59. package/lib/module/core/AudioContext.js +3 -1
  60. package/lib/module/core/AudioContext.js.map +1 -1
  61. package/lib/module/core/AudioDestinationNode.js +4 -6
  62. package/lib/module/core/AudioDestinationNode.js.map +1 -1
  63. package/lib/module/core/AudioNode.js +3 -1
  64. package/lib/module/core/AudioNode.js.map +1 -1
  65. package/lib/module/core/AudioParam.js +27 -1
  66. package/lib/module/core/AudioParam.js.map +1 -1
  67. package/lib/module/core/AudioScheduledSourceNode.js +4 -5
  68. package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
  69. package/lib/module/core/BaseAudioContext.js +19 -9
  70. package/lib/module/core/BaseAudioContext.js.map +1 -1
  71. package/lib/module/core/BiquadFilterNode.js +5 -3
  72. package/lib/module/core/BiquadFilterNode.js.map +1 -1
  73. package/lib/module/core/GainNode.js +4 -2
  74. package/lib/module/core/GainNode.js.map +1 -1
  75. package/lib/module/core/OscillatorNode.js +5 -3
  76. package/lib/module/core/OscillatorNode.js.map +1 -1
  77. package/lib/module/core/PeriodicWave.js +2 -0
  78. package/lib/module/core/PeriodicWave.js.map +1 -1
  79. package/lib/module/core/StereoPannerNode.js +4 -2
  80. package/lib/module/core/StereoPannerNode.js.map +1 -1
  81. package/lib/module/core/types.js +1 -1
  82. package/lib/module/errors/IndexSizeError.js +2 -0
  83. package/lib/module/errors/IndexSizeError.js.map +1 -1
  84. package/lib/module/errors/InvalidAccessError.js +2 -0
  85. package/lib/module/errors/InvalidAccessError.js.map +1 -1
  86. package/lib/module/errors/InvalidStateError.js +2 -0
  87. package/lib/module/errors/InvalidStateError.js.map +1 -1
  88. package/lib/module/errors/RangeError.js +2 -0
  89. package/lib/module/errors/RangeError.js.map +1 -1
  90. package/lib/module/errors/index.js +6 -4
  91. package/lib/module/errors/index.js.map +1 -1
  92. package/lib/module/index.js +42 -10
  93. package/lib/module/index.js.map +1 -1
  94. package/lib/module/index.native.js +17 -14
  95. package/lib/module/index.native.js.map +1 -1
  96. package/lib/module/interfaces.js +2 -0
  97. package/lib/module/specs/global.d.js +4 -0
  98. package/lib/module/{modules → specs}/global.d.js.map +1 -1
  99. package/lib/module/{utils → specs}/install.js +5 -9
  100. package/lib/module/specs/install.js.map +1 -0
  101. package/lib/typescript/core/AnalyserNode.d.ts +18 -0
  102. package/lib/typescript/core/AnalyserNode.d.ts.map +1 -0
  103. package/lib/typescript/core/AudioBuffer.d.ts +2 -0
  104. package/lib/typescript/core/AudioBuffer.d.ts.map +1 -1
  105. package/lib/typescript/core/AudioDestinationNode.d.ts +0 -3
  106. package/lib/typescript/core/AudioDestinationNode.d.ts.map +1 -1
  107. package/lib/typescript/core/AudioParam.d.ts +4 -0
  108. package/lib/typescript/core/AudioParam.d.ts.map +1 -1
  109. package/lib/typescript/core/AudioScheduledSourceNode.d.ts +0 -3
  110. package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -1
  111. package/lib/typescript/core/BaseAudioContext.d.ts +2 -0
  112. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
  113. package/lib/typescript/core/PeriodicWave.d.ts +2 -0
  114. package/lib/typescript/core/PeriodicWave.d.ts.map +1 -1
  115. package/lib/typescript/index.d.ts +22 -3
  116. package/lib/typescript/index.d.ts.map +1 -1
  117. package/lib/typescript/index.native.d.ts +1 -0
  118. package/lib/typescript/index.native.d.ts.map +1 -1
  119. package/lib/typescript/interfaces.d.ts +16 -0
  120. package/lib/typescript/interfaces.d.ts.map +1 -1
  121. package/lib/typescript/{utils → specs}/install.d.ts.map +1 -1
  122. package/metro-config/index.d.ts +5 -0
  123. package/metro-config/index.js +41 -0
  124. package/metro-config/tsconfig.json +3 -0
  125. package/package.json +53 -17
  126. package/scripts/audioapi_utils.rb +56 -0
  127. package/src/core/AnalyserNode.ts +85 -0
  128. package/src/core/AudioDestinationNode.ts +1 -7
  129. package/src/core/AudioParam.ts +48 -0
  130. package/src/core/AudioScheduledSourceNode.ts +0 -5
  131. package/src/core/BaseAudioContext.ts +10 -0
  132. package/src/index.native.ts +2 -1
  133. package/src/index.ts +77 -14
  134. package/src/interfaces.ts +26 -0
  135. package/src/{modules → specs}/global.d.ts +2 -0
  136. package/src/{utils → specs}/install.ts +4 -11
  137. package/android/src/main/cpp/AudioAPIInstaller/AudioAPIInstaller.cpp +0 -20
  138. package/common/cpp/core/ParamChange.cpp +0 -46
  139. package/common/cpp/utils/android/FFTFrame.cpp +0 -23
  140. package/common/cpp/utils/ios/FFTFrame.cpp +0 -29
  141. package/ios/AudioDecoder/AudioDecoder.h +0 -17
  142. package/ios/AudioDecoder/AudioDecoder.m +0 -79
  143. package/ios/AudioDecoder/IOSAudioDecoder.h +0 -28
  144. package/ios/AudioDecoder/IOSAudioDecoder.mm +0 -46
  145. package/lib/module/modules/global.d.js +0 -2
  146. package/lib/module/utils/install.js.map +0 -1
  147. /package/android/src/main/cpp/{AudioPlayer → core}/AudioPlayer.cpp +0 -0
  148. /package/android/src/main/cpp/{AudioPlayer → core}/AudioPlayer.h +0 -0
  149. /package/common/cpp/{AudioAPIInstaller → HostObjects}/AudioAPIInstallerHostObject.h +0 -0
  150. /package/{android/libs/include → common/cpp/libs}/miniaudio.h +0 -0
  151. /package/ios/{AudioPlayer → core}/AudioPlayer.h +0 -0
  152. /package/ios/{AudioPlayer → core}/AudioPlayer.m +0 -0
  153. /package/ios/{AudioPlayer → core}/IOSAudioPlayer.h +0 -0
  154. /package/ios/{AudioPlayer → core}/IOSAudioPlayer.mm +0 -0
  155. /package/lib/typescript/{utils → specs}/install.d.ts +0 -0
package/README.md CHANGED
@@ -17,11 +17,25 @@ allowing developers to generate and modify audio in exact same way it is possibl
17
17
  yarn add react-native-audio-api
18
18
  ```
19
19
 
20
+ ## Usage with expo
21
+
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:
23
+
24
+ ```bash
25
+ # Build native iOS project
26
+ npx expo run:ios
27
+ # Build native Android project
28
+ npx expo run:android
29
+ ```
30
+
31
+ To learn more about expo development builds, please check out [Development Builds Documentation](https://docs.expo.dev/develop/development-builds/introduction/).
32
+
20
33
  ## Documentation
21
34
 
22
- `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/).
23
- <br />
24
- [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.
35
+ Check out our dedicated documentation page for info about this library, API reference and more:
36
+ [https://software-mansion-labs.github.io/react-native-audio-api/](https://software-mansion-labs.github.io/react-native-audio-api/)
37
+
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.
25
39
 
26
40
  ## Coverage
27
41
 
@@ -29,14 +43,6 @@ Our current coverage of Web Audio API specification can be found here: [Web Audi
29
43
 
30
44
  ## Examples
31
45
 
32
- <div align="center">
33
-
34
- <a href="https://www.youtube.com/watch?v=npALr9IIDkI" target="_blank" rel="noopener noreferrer">
35
- <img src="./docs/assets/rnaa-example-01-thumbnail.png" width="640" />
36
- </a>
37
-
38
- </div>
39
-
40
46
  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/fabric-example/README.md) for installation instructions.
41
47
 
42
48
  ## Your feedback
@@ -1,46 +1,57 @@
1
1
  require "json"
2
+ require_relative './scripts/audioapi_utils'
2
3
 
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'
4
+ package_json = JSON.parse(File.read(File.join(__dir__, "package.json")))
5
+
6
+ $config = find_config()
7
+ assert_minimal_react_native_version($config)
8
+ $new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
9
+
10
+ folly_flags = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32 -DREACT_NATIVE_MINOR_VERSION=#{$config[:react_native_minor_version]}"
11
+ fabric_flags = $new_arch_enabled ? '-DRCT_NEW_ARCH_ENABLED' : ''
12
+ version_flag = "-DAUDIOAPI_VERSION=#{package_json['version']}"
5
13
 
6
14
  Pod::Spec.new do |s|
7
15
  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"]
16
+ s.version = package_json["version"]
17
+ s.summary = package_json["description"]
18
+ s.homepage = package_json["homepage"]
19
+ s.license = package_json["license"]
20
+ s.authors = package_json["author"]
13
21
 
14
22
  s.platforms = { :ios => min_ios_version_supported }
15
23
  s.source = { :git => "https://github.com/software-mansion-labs/react-native-audio-api.git", :tag => "#{s.version}" }
16
24
 
17
25
  s.source_files = "ios/**/*.{h,m,mm}", "common/cpp/**/*.{hpp,cpp,c,h}"
18
26
 
19
- s.ios.frameworks = 'Accelerate'
27
+ s.ios.frameworks = 'CoreFoundation', 'CoreAudio', 'AudioToolbox', 'Accelerate'
28
+
29
+ s.pod_target_xcconfig = {
30
+ "USE_HEADERMAP" => "YES",
31
+ "DEFINES_MODULE" => "YES",
32
+ "HEADER_SEARCH_PATHS" => '"$(PODS_TARGET_SRCROOT)/ReactCommon" "$(PODS_TARGET_SRCROOT)" "$(PODS_ROOT)/RCT-Folly" "$(PODS_ROOT)/boost" "$(PODS_ROOT)/boost-for-react-native" "$(PODS_ROOT)/DoubleConversion" "$(PODS_ROOT)/Headers/Private/React-Core" "$(PODS_ROOT)/Headers/Private/Yoga"',
33
+ "FRAMEWORK_SEARCH_PATHS" => '"${PODS_CONFIGURATION_BUILD_DIR}/React-hermes"',
34
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
35
+ "GCC_PREPROCESSOR_DEFINITIONS" => '$(inherited) HAVE_ACCELERATE=1',
36
+ }
37
+ s.compiler_flags = "#{folly_flags}"
38
+
20
39
  s.xcconfig = {
21
- 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) HAVE_ACCELERATE=1'
40
+ "HEADER_SEARCH_PATHS" => [
41
+ '"$(PODS_ROOT)/boost"',
42
+ '"$(PODS_ROOT)/boost-for-react-native"',
43
+ '"$(PODS_ROOT)/glog"',
44
+ '"$(PODS_ROOT)/RCT-Folly"',
45
+ '"$(PODS_ROOT)/Headers/Public/React-hermes"',
46
+ '"$(PODS_ROOT)/Headers/Public/hermes-engine"',
47
+ "\"$(PODS_ROOT)/#{$config[:react_native_common_dir]}\"",
48
+ "\"$(PODS_ROOT)/#{$config[:react_native_audioapi_dir_from_pods_root]}/ios\"",
49
+ "\"$(PODS_ROOT)/#{$config[:react_native_audioapi_dir_from_pods_root]}/common/cpp\"",
50
+ ].join(' '),
51
+ 'OTHER_CFLAGS' => "$(inherited) #{folly_flags} #{fabric_flags} #{version_flag}"
22
52
  }
23
53
 
24
54
  # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
25
55
  # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
26
- if respond_to?(:install_modules_dependencies, true)
27
- install_modules_dependencies(s)
28
- else
29
- s.dependency "React-Core"
30
-
31
- # Don't install the dependencies when we run `pod install` in the old architecture.
32
- if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
33
- s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
34
- s.pod_target_xcconfig = {
35
- "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
36
- "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
37
- "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
38
- }
39
- s.dependency "React-Codegen"
40
- s.dependency "RCT-Folly"
41
- s.dependency "RCTRequired"
42
- s.dependency "RCTTypeSafety"
43
- s.dependency "ReactCommon/turbomodule/core"
44
- end
45
- end
56
+ install_modules_dependencies(s, new_arch_enabled: true)
46
57
  end
@@ -14,33 +14,28 @@ endif()
14
14
  include("${REACT_NATIVE_DIR}/ReactAndroid/cmake-utils/folly-flags.cmake")
15
15
  add_compile_options(${folly_FLAGS})
16
16
 
17
- file(GLOB_RECURSE SOURCE_FILES
18
- "src/main/cpp/*.cpp"
19
- "src/main/cpp/*.h"
20
- "../common/cpp/*.cpp"
21
- "../common/cpp/*.h"
22
- "../common/cpp/core/*.cpp"
23
- "../common/cpp/core/*.h"
24
- "../common/cpp/HostObjects/*.cpp"
25
- "../common/cpp/HostObjects/*.h"
26
- "../common/cpp/utils/*.cpp"
27
- "../common/cpp/utils/*.h"
28
- "../common/cpp/jsi/*.h"
29
- "../common/cpp/jsi/*.cpp"
30
- "../common/cpp/types/*.h"
31
- )
17
+ file(GLOB_RECURSE ANDROID_CPP_SOURCES CONFIGURE_DEPENDS "src/main/cpp/*.cpp")
18
+ file(GLOB_RECURSE COMMON_CPP_SOURCES CONFIGURE_DEPENDS "../common/cpp/*.cpp")
19
+
20
+ add_library(react-native-audio-api SHARED ${ANDROID_CPP_SOURCES} ${COMMON_CPP_SOURCES})
32
21
 
33
- add_library(react-native-audio-api SHARED ${SOURCE_FILES})
22
+ file(GLOB ANDROID_CPP_DIR CONFIGURE_DEPENDS "src/main/cpp/**")
23
+ file(GLOB COMMON_CPP_DIR CONFIGURE_DEPENDS "../common/cpp/**")
34
24
 
35
- file(GLOB DIRS CONFIGURE_DEPENDS "src/main/cpp/**" "../common/cpp/**")
25
+ target_include_directories(
26
+ react-native-audio-api
27
+ PUBLIC
28
+ ${ANDROID_CPP_DIR}
29
+ ${COMMON_CPP_DIR}
30
+ )
36
31
 
37
32
  target_include_directories(
38
33
  react-native-audio-api
39
34
  PRIVATE
40
- ${DIRS}
41
- "${REACT_NATIVE_DIR}/ReactCommon/jsi"
42
- "${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni/react/jni"
43
- "${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni/third-party/folly"
35
+ "${REACT_NATIVE_DIR}/ReactCommon"
36
+ "${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni/react/turbomodule"
37
+ "${REACT_NATIVE_DIR}/ReactCommon/react/nativemodule/core/ReactCommon"
38
+ "${REACT_NATIVE_DIR}/ReactCommon/callinvoker"
44
39
  "${CMAKE_CURRENT_SOURCE_DIR}/libs/include"
45
40
  )
46
41
 
@@ -66,6 +61,7 @@ if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
66
61
  else()
67
62
  set(RN_VERSION_LINK_LIBRARIES
68
63
  ReactAndroid::folly_runtime
64
+ ReactAndroid::react_nativemodule_core
69
65
  ReactAndroid::glog
70
66
  ReactAndroid::reactnativejni
71
67
  )
@@ -1,5 +1,6 @@
1
1
  import com.android.Version
2
2
  import org.apache.tools.ant.taskdefs.condition.Os
3
+ import com.android.build.gradle.tasks.ExternalNativeBuildJsonTask
3
4
 
4
5
  buildscript {
5
6
  repositories {
@@ -72,8 +73,6 @@ def toPlatformFileString(String path) {
72
73
  return path
73
74
  }
74
75
 
75
- def reactNativeRootDir = resolveReactNativeDirectory()
76
-
77
76
  static def supportsNamespace() {
78
77
  def parsed = Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
79
78
  def major = parsed[0].toInteger()
@@ -83,6 +82,15 @@ static def supportsNamespace() {
83
82
  return (major == 7 && minor >= 3) || major >= 8
84
83
  }
85
84
 
85
+ def reactNativeRootDir = resolveReactNativeDirectory()
86
+
87
+ def reactProperties = new Properties()
88
+ file("$reactNativeRootDir/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
89
+
90
+ def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME")
91
+ def REACT_NATIVE_MINOR_VERSION = REACT_NATIVE_VERSION.startsWith("0.0.0-") ? 1000 : REACT_NATIVE_VERSION.split("\\.")[1].toInteger()
92
+ def IS_NEW_ARCHITECTURE_ENABLED = isNewArchitectureEnabled()
93
+
86
94
  android {
87
95
  if (supportsNamespace()) {
88
96
  namespace "com.swmansion.audioapi"
@@ -107,7 +115,10 @@ android {
107
115
  cppFlags "-O2 -frtti -fexceptions -Wall -fstack-protector-all"
108
116
  abiFilters (*reactNativeArchitectures())
109
117
  arguments "-DANDROID_STL=c++_shared",
110
- "-DREACT_NATIVE_DIR=${toPlatformFileString(reactNativeRootDir.path)}"
118
+ "-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}",
119
+ "-DANDROID_TOOLCHAIN=clang",
120
+ "-DREACT_NATIVE_DIR=${toPlatformFileString(reactNativeRootDir.path)}",
121
+ "-DIS_NEW_ARCHITECTURE_ENABLED=${IS_NEW_ARCHITECTURE_ENABLED}"
111
122
  }
112
123
  }
113
124
  }
@@ -148,6 +159,7 @@ android {
148
159
  "**/libjsi.so",
149
160
  "**/libfolly_runtime.so",
150
161
  "**/libreactnativejni.so",
162
+ "**/libreactnative.so",
151
163
  ]
152
164
  }
153
165
  }
@@ -183,10 +195,15 @@ dependencies {
183
195
  implementation 'com.google.oboe:oboe:1.9.0'
184
196
  }
185
197
 
186
- if (isNewArchitectureEnabled()) {
187
- react {
188
- jsRootDir = file("../src/")
189
- libraryName = "react-native-audio-api"
190
- codegenJavaPackageName = "com.swmansion.audioapi"
191
- }
198
+ def assertMinimalReactNativeVersion = task assertMinimalReactNativeVersionTask {
199
+ // If you change the minimal React Native version remember to update Compatibility Table in docs
200
+ def minimalReactNativeVersion = 75
201
+ onlyIf { REACT_NATIVE_MINOR_VERSION < minimalReactNativeVersion }
202
+ doFirst {
203
+ throw new GradleException("[AudioAPI] Unsupported React Native version. Please use $minimalReactNativeVersion. or newer.")
204
+ }
205
+ }
206
+
207
+ tasks.preBuild {
208
+ dependsOn assertMinimalReactNativeVersion
192
209
  }
@@ -3,7 +3,7 @@
3
3
 
4
4
  using namespace audioapi;
5
5
 
6
- JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
6
+ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
7
7
  return facebook::jni::initialize(
8
8
  vm, [] { AudioAPIInstaller::registerNatives(); });
9
9
  }
@@ -0,0 +1,37 @@
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
+ jsi::Runtime *jsiRuntime,
10
+ const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker)
11
+ : javaPart_(make_global(jThis)),
12
+ jsiRuntime_(jsiRuntime),
13
+ jsCallInvoker_(jsCallInvoker) {}
14
+
15
+ jni::local_ref<AudioAPIInstaller::jhybriddata> AudioAPIInstaller::initHybrid(
16
+ jni::alias_ref<jhybridobject> jThis,
17
+ jlong jsContext,
18
+ jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>
19
+ jsCallInvokerHolder) {
20
+ auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker();
21
+ auto rnRuntime = reinterpret_cast<jsi::Runtime *>(jsContext);
22
+ return makeCxxInstance(jThis, rnRuntime, jsCallInvoker);
23
+ }
24
+
25
+ void AudioAPIInstaller::registerNatives() {
26
+ registerHybrid({
27
+ makeNativeMethod("initHybrid", AudioAPIInstaller::initHybrid),
28
+ makeNativeMethod("install", AudioAPIInstaller::install),
29
+ });
30
+ }
31
+
32
+ void AudioAPIInstaller::install() {
33
+ auto hostObject = std::make_shared<AudioAPIInstallerHostObject>(
34
+ jsiRuntime_, jsCallInvoker_);
35
+ hostObject->install();
36
+ }
37
+ } // namespace audioapi
@@ -24,18 +24,9 @@ class AudioAPIInstaller : public jni::HybridClass<AudioAPIInstaller> {
24
24
  jni::alias_ref<jhybridobject> jThis,
25
25
  jlong jsContext,
26
26
  jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>
27
- jsCallInvokerHolder) {
28
- auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker();
29
- auto rnRuntime = reinterpret_cast<jsi::Runtime *>(jsContext);
30
- return makeCxxInstance(jThis, rnRuntime, jsCallInvoker);
31
- }
32
-
33
- static void registerNatives() {
34
- registerHybrid({
35
- makeNativeMethod("initHybrid", AudioAPIInstaller::initHybrid),
36
- makeNativeMethod("install", AudioAPIInstaller::install),
37
- });
38
- }
27
+ jsCallInvokerHolder);
28
+
29
+ static void registerNatives();
39
30
 
40
31
  void install();
41
32
 
@@ -43,7 +34,7 @@ class AudioAPIInstaller : public jni::HybridClass<AudioAPIInstaller> {
43
34
  friend HybridBase;
44
35
 
45
36
  jni::global_ref<AudioAPIInstaller::javaobject> javaPart_;
46
- jsi::Runtime *rnRuntime_;
37
+ jsi::Runtime *jsiRuntime_;
47
38
  std::shared_ptr<facebook::react::CallInvoker> jsCallInvoker_;
48
39
 
49
40
  explicit AudioAPIInstaller(
@@ -9,8 +9,6 @@
9
9
 
10
10
  namespace audioapi {
11
11
 
12
- AudioDecoder::AudioDecoder(int sampleRate) : sampleRate_(sampleRate) {}
13
-
14
12
  AudioBus *AudioDecoder::decodeWithFilePath(const std::string &path) const {
15
13
  ma_decoder decoder;
16
14
  ma_decoder_config config =
@@ -55,10 +53,4 @@ AudioBus *AudioDecoder::decodeWithFilePath(const std::string &path) const {
55
53
 
56
54
  return audioBus;
57
55
  }
58
-
59
- AudioBus *AudioDecoder::decodeWithArrayBuffer() const {
60
- // TODO: implement this
61
- return new AudioBus(1, 1, 1);
62
- }
63
-
64
56
  } // namespace audioapi
@@ -3,9 +3,11 @@ package com.swmansion.audioapi
3
3
  import com.facebook.react.ReactPackage
4
4
  import com.facebook.react.bridge.NativeModule
5
5
  import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.annotations.ReactModuleList
6
7
  import com.facebook.react.uimanager.ViewManager
7
8
  import com.swmansion.audioapi.nativemodules.AudioAPIModule
8
9
 
10
+ @ReactModuleList(nativeModules = [AudioAPIModule::class])
9
11
  class AudioAPIPackage : ReactPackage {
10
12
  override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> =
11
13
  listOf<NativeModule>(AudioAPIModule(reactContext))
@@ -3,11 +3,17 @@ package com.swmansion.audioapi.nativemodules
3
3
  import com.facebook.react.bridge.ReactApplicationContext
4
4
  import com.facebook.react.bridge.ReactContextBaseJavaModule
5
5
  import com.facebook.react.bridge.ReactMethod
6
+ import com.facebook.react.module.annotations.ReactModule
6
7
  import com.swmansion.audioapi.module.AudioAPIInstaller
7
8
 
9
+ @ReactModule(name = AudioAPIModule.NAME)
8
10
  class AudioAPIModule(
9
11
  private val reactContext: ReactApplicationContext,
10
12
  ) : ReactContextBaseJavaModule(reactContext) {
13
+ companion object {
14
+ const val NAME: String = "AudioAPIModule"
15
+ }
16
+
11
17
  override fun getName(): String = NAME
12
18
 
13
19
  @ReactMethod(isBlockingSynchronousMethod = true)
@@ -17,8 +23,4 @@ class AudioAPIModule(
17
23
 
18
24
  return true
19
25
  }
20
-
21
- companion object {
22
- const val NAME: String = "AudioAPIModule"
23
- }
24
26
  }
@@ -0,0 +1,151 @@
1
+ #pragma once
2
+
3
+ #include <memory>
4
+ #include <string>
5
+ #include <vector>
6
+
7
+ #include "AnalyserNode.h"
8
+ #include "AudioNodeHostObject.h"
9
+
10
+ namespace audioapi {
11
+ using namespace facebook;
12
+
13
+ class AnalyserNodeHostObject : public AudioNodeHostObject {
14
+ public:
15
+ explicit AnalyserNodeHostObject(const std::shared_ptr<AnalyserNode> &node)
16
+ : AudioNodeHostObject(node) {
17
+ addGetters(
18
+ JSI_EXPORT_PROPERTY_GETTER(AnalyserNodeHostObject, fftSize),
19
+ JSI_EXPORT_PROPERTY_GETTER(AnalyserNodeHostObject, frequencyBinCount),
20
+ JSI_EXPORT_PROPERTY_GETTER(AnalyserNodeHostObject, minDecibels),
21
+ JSI_EXPORT_PROPERTY_GETTER(AnalyserNodeHostObject, maxDecibels),
22
+ JSI_EXPORT_PROPERTY_GETTER(AnalyserNodeHostObject, smoothingTimeConstant));
23
+
24
+ addFunctions(
25
+ JSI_EXPORT_FUNCTION(
26
+ AnalyserNodeHostObject, getFloatFrequencyData),
27
+ JSI_EXPORT_FUNCTION(
28
+ AnalyserNodeHostObject, getByteFrequencyData),
29
+ JSI_EXPORT_FUNCTION(
30
+ AnalyserNodeHostObject, getFloatTimeDomainData),
31
+ JSI_EXPORT_FUNCTION(
32
+ AnalyserNodeHostObject, getByteTimeDomainData));
33
+
34
+ addSetters(
35
+ JSI_EXPORT_PROPERTY_SETTER(AnalyserNodeHostObject, fftSize),
36
+ JSI_EXPORT_PROPERTY_SETTER(AnalyserNodeHostObject, minDecibels),
37
+ JSI_EXPORT_PROPERTY_SETTER(AnalyserNodeHostObject, maxDecibels),
38
+ JSI_EXPORT_PROPERTY_SETTER(
39
+ AnalyserNodeHostObject, smoothingTimeConstant));
40
+ }
41
+
42
+ JSI_PROPERTY_GETTER(fftSize) {
43
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
44
+ return {static_cast<int>(analyserNode->getFftSize())};
45
+ }
46
+
47
+ JSI_PROPERTY_GETTER(frequencyBinCount) {
48
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
49
+ return {static_cast<int>(analyserNode->getFrequencyBinCount())};
50
+ }
51
+
52
+ JSI_PROPERTY_GETTER(minDecibels) {
53
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
54
+ return {analyserNode->getMinDecibels()};
55
+ }
56
+
57
+ JSI_PROPERTY_GETTER(maxDecibels) {
58
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
59
+ return {analyserNode->getMaxDecibels()};
60
+ }
61
+
62
+ JSI_PROPERTY_GETTER(smoothingTimeConstant) {
63
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
64
+ return {analyserNode->getSmoothingTimeConstant()};
65
+ }
66
+
67
+ JSI_HOST_FUNCTION(getFloatFrequencyData) {
68
+ auto destination = args[0].getObject(runtime).asArray(runtime);
69
+ auto length = static_cast<int>(destination.getProperty(runtime, "length").asNumber());
70
+ auto data = new float[length];
71
+
72
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
73
+ analyserNode->getFloatFrequencyData(data, length);
74
+
75
+ for (int i = 0; i < length; i++) {
76
+ destination.setValueAtIndex(runtime, i, jsi::Value(data[i]));
77
+ }
78
+
79
+ return jsi::Value::undefined();
80
+ }
81
+
82
+ JSI_HOST_FUNCTION(getByteFrequencyData) {
83
+ auto destination = args[0].getObject(runtime).asArray(runtime);
84
+ auto length = static_cast<int>(destination.getProperty(runtime, "length").asNumber());
85
+ auto data = new uint8_t[length];
86
+
87
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
88
+ analyserNode->getByteFrequencyData(data, length);
89
+
90
+ for (int i = 0; i < length; i++) {
91
+ destination.setValueAtIndex(runtime, i, jsi::Value(data[i]));
92
+ }
93
+
94
+ return jsi::Value::undefined();
95
+ }
96
+
97
+ JSI_HOST_FUNCTION(getFloatTimeDomainData) {
98
+ auto destination = args[0].getObject(runtime).asArray(runtime);
99
+ auto length = static_cast<int>(destination.getProperty(runtime, "length").asNumber());
100
+ auto data = new float[length];
101
+
102
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
103
+ analyserNode->getFloatTimeDomainData(data, length);
104
+
105
+ for (int i = 0; i < length; i++) {
106
+ destination.setValueAtIndex(runtime, i, jsi::Value(data[i]));
107
+ }
108
+
109
+ return jsi::Value::undefined();
110
+ }
111
+
112
+ JSI_HOST_FUNCTION(getByteTimeDomainData) {
113
+ auto destination = args[0].getObject(runtime).asArray(runtime);
114
+ auto length = static_cast<int>(destination.getProperty(runtime, "length").asNumber());
115
+ auto data = new uint8_t[length];
116
+
117
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
118
+ analyserNode->getByteTimeDomainData(data, length);
119
+
120
+ for (int i = 0; i < length; i++) {
121
+ destination.setValueAtIndex(runtime, i, jsi::Value(data[i]));
122
+ }
123
+
124
+ return jsi::Value::undefined();
125
+ }
126
+
127
+ JSI_PROPERTY_SETTER(fftSize) {
128
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
129
+ auto fftSize = static_cast<size_t>(value.getNumber());
130
+ analyserNode->setFftSize(fftSize);
131
+ }
132
+
133
+ JSI_PROPERTY_SETTER(minDecibels) {
134
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
135
+ auto minDecibels = static_cast<int>(value.getNumber());
136
+ analyserNode->setMinDecibels(minDecibels);
137
+ }
138
+
139
+ JSI_PROPERTY_SETTER(maxDecibels) {
140
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
141
+ auto maxDecibels = static_cast<int>(value.getNumber());
142
+ analyserNode->setMaxDecibels(maxDecibels);
143
+ }
144
+
145
+ JSI_PROPERTY_SETTER(smoothingTimeConstant) {
146
+ auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
147
+ auto smoothingTimeConstant = static_cast<int>(value.getNumber());
148
+ analyserNode->setSmoothingTimeConstant(smoothingTimeConstant);
149
+ }
150
+ };
151
+ } // namespace audioapi
@@ -23,8 +23,11 @@ class AudioParamHostObject : public JsiHostObject {
23
23
  addFunctions(
24
24
  JSI_EXPORT_FUNCTION(AudioParamHostObject, setValueAtTime),
25
25
  JSI_EXPORT_FUNCTION(AudioParamHostObject, linearRampToValueAtTime),
26
- JSI_EXPORT_FUNCTION(
27
- AudioParamHostObject, exponentialRampToValueAtTime));
26
+ JSI_EXPORT_FUNCTION(AudioParamHostObject, exponentialRampToValueAtTime),
27
+ JSI_EXPORT_FUNCTION(AudioParamHostObject, setTargetAtTime),
28
+ JSI_EXPORT_FUNCTION(AudioParamHostObject, setValueCurveAtTime),
29
+ JSI_EXPORT_FUNCTION(AudioParamHostObject, cancelScheduledValues),
30
+ JSI_EXPORT_FUNCTION(AudioParamHostObject, cancelAndHoldAtTime));
28
31
 
29
32
  addSetters(JSI_EXPORT_PROPERTY_SETTER(AudioParamHostObject, value));
30
33
  }
@@ -66,6 +69,40 @@ class AudioParamHostObject : public JsiHostObject {
66
69
  return jsi::Value::undefined();
67
70
  }
68
71
 
72
+ JSI_HOST_FUNCTION(setTargetAtTime) {
73
+ auto target = static_cast<float>(args[0].getNumber());
74
+ double startTime = args[1].getNumber();
75
+ double timeConstant = args[2].getNumber();
76
+ param_->setTargetAtTime(target, startTime, timeConstant);
77
+ return jsi::Value::undefined();
78
+ }
79
+
80
+ JSI_HOST_FUNCTION(setValueCurveAtTime) {
81
+ auto values = args[0].getObject(runtime).asArray(runtime);
82
+ auto length = static_cast<int>(values.length(runtime));
83
+ auto valuesData = new float[length];
84
+ for (size_t i = 0; i < values.length(runtime); i++) {
85
+ valuesData[i] =
86
+ static_cast<float>(values.getValueAtIndex(runtime, i).getNumber());
87
+ }
88
+ double startTime = args[1].getNumber();
89
+ double duration = args[2].getNumber();
90
+ param_->setValueCurveAtTime(valuesData, length, startTime, duration);
91
+ return jsi::Value::undefined();
92
+ }
93
+
94
+ JSI_HOST_FUNCTION(cancelScheduledValues) {
95
+ double cancelTime = args[0].getNumber();
96
+ param_->cancelScheduledValues(cancelTime);
97
+ return jsi::Value::undefined();
98
+ }
99
+
100
+ JSI_HOST_FUNCTION(cancelAndHoldAtTime) {
101
+ double cancelTime = args[0].getNumber();
102
+ param_->cancelAndHoldAtTime(cancelTime);
103
+ return jsi::Value::undefined();
104
+ }
105
+
69
106
  JSI_PROPERTY_SETTER(value) {
70
107
  param_->setValue(static_cast<float>(value.getNumber()));
71
108
  }
@@ -17,6 +17,7 @@
17
17
  #include "OscillatorNodeHostObject.h"
18
18
  #include "PeriodicWaveHostObject.h"
19
19
  #include "StereoPannerNodeHostObject.h"
20
+ #include "AnalyserNodeHostObject.h"
20
21
 
21
22
  namespace audioapi {
22
23
  using namespace facebook;
@@ -41,6 +42,7 @@ class BaseAudioContextHostObject : public JsiHostObject {
41
42
  JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createBufferSource),
42
43
  JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createBuffer),
43
44
  JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createPeriodicWave),
45
+ JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createAnalyser),
44
46
  JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, decodeAudioDataSource));
45
47
  }
46
48
 
@@ -131,6 +133,12 @@ class BaseAudioContextHostObject : public JsiHostObject {
131
133
  return jsi::Object::createFromHostObject(runtime, periodicWaveHostObject);
132
134
  }
133
135
 
136
+ JSI_HOST_FUNCTION(createAnalyser) {
137
+ auto analyser = context_->createAnalyser();
138
+ auto analyserHostObject = std::make_shared<AnalyserNodeHostObject>(analyser);
139
+ return jsi::Object::createFromHostObject(runtime, analyserHostObject);
140
+ }
141
+
134
142
  JSI_HOST_FUNCTION(decodeAudioDataSource) {
135
143
  auto sourcePath = args[0].getString(runtime).utf8(runtime);
136
144