react-native-audio-api 0.6.2-rc.6 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +25 -0
  2. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionCallback.kt +13 -0
  3. package/common/cpp/audioapi/HostObjects/AudioBufferBaseSourceNodeHostObject.h +60 -0
  4. package/common/cpp/audioapi/HostObjects/AudioBufferQueueSourceNodeHostObject.h +5 -67
  5. package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +26 -56
  6. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +9 -0
  7. package/common/cpp/audioapi/HostObjects/CustomProcessorNodeHostObject.h +54 -0
  8. package/common/cpp/audioapi/core/BaseAudioContext.cpp +9 -0
  9. package/common/cpp/audioapi/core/BaseAudioContext.h +2 -0
  10. package/common/cpp/audioapi/core/effects/CustomProcessorNode.cpp +173 -0
  11. package/common/cpp/audioapi/core/effects/CustomProcessorNode.h +186 -0
  12. package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +104 -0
  13. package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.h +54 -0
  14. package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.cpp +12 -129
  15. package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.h +8 -37
  16. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +4 -93
  17. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +4 -30
  18. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +1 -11
  19. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +2 -3
  20. package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +0 -5
  21. package/common/cpp/audioapi/core/sources/OscillatorNode.h +0 -1
  22. package/common/cpp/audioapi/core/utils/AudioNodeDestructor.cpp +3 -1
  23. package/common/cpp/audioapi/core/utils/AudioNodeManager.cpp +1 -1
  24. package/ios/audioapi/ios/system/AudioEngine.h +1 -0
  25. package/ios/audioapi/ios/system/AudioEngine.mm +14 -3
  26. package/ios/audioapi/ios/system/AudioSessionManager.h +1 -0
  27. package/ios/audioapi/ios/system/AudioSessionManager.mm +10 -0
  28. package/ios/audioapi/ios/system/NotificationManager.mm +2 -4
  29. package/lib/commonjs/api.js +7 -0
  30. package/lib/commonjs/api.js.map +1 -1
  31. package/lib/commonjs/core/AudioBufferBaseSourceNode.js +29 -0
  32. package/lib/commonjs/core/AudioBufferBaseSourceNode.js.map +1 -0
  33. package/lib/commonjs/core/AudioBufferQueueSourceNode.js +5 -22
  34. package/lib/commonjs/core/AudioBufferQueueSourceNode.js.map +1 -1
  35. package/lib/commonjs/core/AudioBufferSourceNode.js +4 -21
  36. package/lib/commonjs/core/AudioBufferSourceNode.js.map +1 -1
  37. package/lib/commonjs/core/AudioScheduledSourceNode.js.map +1 -1
  38. package/lib/commonjs/core/BaseAudioContext.js +4 -0
  39. package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
  40. package/lib/commonjs/core/CustomProcessorNode.js +23 -0
  41. package/lib/commonjs/core/CustomProcessorNode.js.map +1 -0
  42. package/lib/commonjs/web-core/AudioScheduledSourceNode.js +1 -4
  43. package/lib/commonjs/web-core/AudioScheduledSourceNode.js.map +1 -1
  44. package/lib/module/api.js +1 -0
  45. package/lib/module/api.js.map +1 -1
  46. package/lib/module/core/AudioBufferBaseSourceNode.js +23 -0
  47. package/lib/module/core/AudioBufferBaseSourceNode.js.map +1 -0
  48. package/lib/module/core/AudioBufferQueueSourceNode.js +5 -22
  49. package/lib/module/core/AudioBufferQueueSourceNode.js.map +1 -1
  50. package/lib/module/core/AudioBufferSourceNode.js +4 -21
  51. package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
  52. package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
  53. package/lib/module/core/BaseAudioContext.js +4 -0
  54. package/lib/module/core/BaseAudioContext.js.map +1 -1
  55. package/lib/module/core/CustomProcessorNode.js +17 -0
  56. package/lib/module/core/CustomProcessorNode.js.map +1 -0
  57. package/lib/module/web-core/AudioScheduledSourceNode.js +1 -4
  58. package/lib/module/web-core/AudioScheduledSourceNode.js.map +1 -1
  59. package/lib/typescript/api.d.ts +1 -0
  60. package/lib/typescript/api.d.ts.map +1 -1
  61. package/lib/typescript/core/AudioBufferBaseSourceNode.d.ts +13 -0
  62. package/lib/typescript/core/AudioBufferBaseSourceNode.d.ts.map +1 -0
  63. package/lib/typescript/core/AudioBufferQueueSourceNode.d.ts +3 -12
  64. package/lib/typescript/core/AudioBufferQueueSourceNode.d.ts.map +1 -1
  65. package/lib/typescript/core/AudioBufferSourceNode.d.ts +2 -11
  66. package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -1
  67. package/lib/typescript/core/AudioScheduledSourceNode.d.ts +2 -2
  68. package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -1
  69. package/lib/typescript/core/BaseAudioContext.d.ts +2 -0
  70. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
  71. package/lib/typescript/core/CustomProcessorNode.d.ts +12 -0
  72. package/lib/typescript/core/CustomProcessorNode.d.ts.map +1 -0
  73. package/lib/typescript/events/types.d.ts +2 -7
  74. package/lib/typescript/events/types.d.ts.map +1 -1
  75. package/lib/typescript/interfaces.d.ts +16 -13
  76. package/lib/typescript/interfaces.d.ts.map +1 -1
  77. package/lib/typescript/types.d.ts +1 -0
  78. package/lib/typescript/types.d.ts.map +1 -1
  79. package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts +2 -1
  80. package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts.map +1 -1
  81. package/package.json +1 -1
  82. package/src/api.ts +1 -0
  83. package/src/core/AudioBufferBaseSourceNode.ts +33 -0
  84. package/src/core/AudioBufferQueueSourceNode.ts +3 -35
  85. package/src/core/AudioBufferSourceNode.ts +10 -33
  86. package/src/core/AudioScheduledSourceNode.ts +2 -2
  87. package/src/core/BaseAudioContext.ts +8 -0
  88. package/src/core/CustomProcessorNode.ts +28 -0
  89. package/src/events/types.ts +2 -8
  90. package/src/interfaces.ts +25 -23
  91. package/src/types.ts +2 -0
  92. package/src/web-core/AudioScheduledSourceNode.tsx +3 -6
@@ -13,6 +13,7 @@ import com.facebook.react.bridge.ReactApplicationContext
13
13
  import com.facebook.react.bridge.ReadableMap
14
14
  import com.facebook.react.bridge.ReadableType
15
15
  import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper.Companion.instance
16
+ import com.swmansion.audioapi.R
16
17
  import java.io.IOException
17
18
  import java.lang.ref.WeakReference
18
19
  import java.net.URL
@@ -182,6 +183,7 @@ class LockScreenManager(
182
183
  name: String,
183
184
  enabled: Boolean,
184
185
  ) {
186
+ pb = PlaybackStateCompat.Builder()
185
187
  var controlValue = 0L
186
188
  when (name) {
187
189
  "remotePlay" -> controlValue = PlaybackStateCompat.ACTION_PLAY
@@ -203,8 +205,31 @@ class LockScreenManager(
203
205
  }
204
206
 
205
207
  mediaNotificationManager.get()?.updateActions(controls)
208
+
209
+ if (hasControl(PlaybackStateCompat.ACTION_REWIND)) {
210
+ pb.addCustomAction(
211
+ PlaybackStateCompat.CustomAction
212
+ .Builder(
213
+ "SkipBackward",
214
+ "Skip Backward",
215
+ R.drawable.skip_backward_10,
216
+ ).build(),
217
+ )
218
+ }
219
+
206
220
  pb.setActions(controls)
207
221
 
222
+ if (hasControl(PlaybackStateCompat.ACTION_FAST_FORWARD)) {
223
+ pb.addCustomAction(
224
+ PlaybackStateCompat.CustomAction
225
+ .Builder(
226
+ "SkipForward",
227
+ "Skip Forward",
228
+ R.drawable.skip_forward_10,
229
+ ).build(),
230
+ )
231
+ }
232
+
208
233
  state = pb.build()
209
234
  mediaSession.get()?.setPlaybackState(state)
210
235
 
@@ -2,7 +2,9 @@ package com.swmansion.audioapi.system
2
2
 
3
3
  import android.content.Intent
4
4
  import android.os.Build
5
+ import android.os.Bundle
5
6
  import android.support.v4.media.session.MediaSessionCompat
7
+ import android.util.Log
6
8
  import androidx.core.app.NotificationManagerCompat
7
9
  import com.swmansion.audioapi.AudioAPIModule
8
10
  import java.lang.ref.WeakReference
@@ -53,4 +55,15 @@ class MediaSessionCallback(
53
55
  val body = HashMap<String, Any>().apply { put("value", (pos.toDouble() / 1000)) }
54
56
  audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remoteChangePlaybackPosition", body)
55
57
  }
58
+
59
+ override fun onCustomAction(
60
+ action: String?,
61
+ extras: Bundle?,
62
+ ) {
63
+ when (action) {
64
+ "SkipForward" -> onFastForward()
65
+ "SkipBackward" -> onRewind()
66
+ else -> Log.w("MediaSessionCallback", "Unknown custom action: $action")
67
+ }
68
+ }
56
69
  }
@@ -0,0 +1,60 @@
1
+ #pragma once
2
+
3
+ #include <audioapi/core/sources/AudioBufferBaseSourceNode.h>
4
+ #include <audioapi/HostObjects/AudioParamHostObject.h>
5
+ #include <audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h>
6
+
7
+ #include <memory>
8
+ #include <vector>
9
+
10
+ namespace audioapi {
11
+ using namespace facebook;
12
+
13
+ class AudioBufferBaseSourceNodeHostObject
14
+ : public AudioScheduledSourceNodeHostObject {
15
+ public:
16
+ explicit AudioBufferBaseSourceNodeHostObject(
17
+ const std::shared_ptr<AudioBufferBaseSourceNode> &node)
18
+ : AudioScheduledSourceNodeHostObject(node) {
19
+ addGetters(
20
+ JSI_EXPORT_PROPERTY_GETTER(AudioBufferBaseSourceNodeHostObject, detune),
21
+ JSI_EXPORT_PROPERTY_GETTER(AudioBufferBaseSourceNodeHostObject, playbackRate));
22
+
23
+ addSetters(
24
+ JSI_EXPORT_PROPERTY_SETTER(AudioBufferBaseSourceNodeHostObject, onPositionChanged),
25
+ JSI_EXPORT_PROPERTY_SETTER(AudioBufferBaseSourceNodeHostObject, onPositionChangedInterval));
26
+ }
27
+
28
+ JSI_PROPERTY_GETTER(detune) {
29
+ auto sourceNode =
30
+ std::static_pointer_cast<AudioBufferBaseSourceNode>(node_);
31
+ auto detune = sourceNode->getDetuneParam();
32
+ auto detuneHostObject = std::make_shared<AudioParamHostObject>(detune);
33
+ return jsi::Object::createFromHostObject(runtime, detuneHostObject);
34
+ }
35
+
36
+ JSI_PROPERTY_GETTER(playbackRate) {
37
+ auto sourceNode =
38
+ std::static_pointer_cast<AudioBufferBaseSourceNode>(node_);
39
+ auto playbackRate = sourceNode->getPlaybackRateParam();
40
+ auto playbackRateHostObject =
41
+ std::make_shared<AudioParamHostObject>(playbackRate);
42
+ return jsi::Object::createFromHostObject(runtime, playbackRateHostObject);
43
+ }
44
+
45
+ JSI_PROPERTY_SETTER(onPositionChanged) {
46
+ auto sourceNode =
47
+ std::static_pointer_cast<AudioBufferBaseSourceNode>(node_);
48
+
49
+ sourceNode->setOnPositionChangedCallbackId(std::stoull(value.getString(runtime).utf8(runtime)));
50
+ }
51
+
52
+ JSI_PROPERTY_SETTER(onPositionChangedInterval) {
53
+ auto sourceNode =
54
+ std::static_pointer_cast<AudioBufferBaseSourceNode>(node_);
55
+
56
+ sourceNode->setOnPositionChangedInterval(static_cast<int>(value.getNumber()));
57
+ }
58
+ };
59
+
60
+ } // namespace audioapi
@@ -2,8 +2,7 @@
2
2
 
3
3
  #include <audioapi/HostObjects/AudioBufferHostObject.h>
4
4
  #include <audioapi/core/sources/AudioBufferQueueSourceNode.h>
5
- #include <audioapi/HostObjects/AudioParamHostObject.h>
6
- #include <audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h>
5
+ #include <audioapi/HostObjects/AudioBufferBaseSourceNodeHostObject.h>
7
6
 
8
7
  #include <memory>
9
8
  #include <vector>
@@ -12,76 +11,16 @@ namespace audioapi {
12
11
  using namespace facebook;
13
12
 
14
13
  class AudioBufferQueueSourceNodeHostObject
15
- : public AudioScheduledSourceNodeHostObject {
14
+ : public AudioBufferBaseSourceNodeHostObject {
16
15
  public:
17
16
  explicit AudioBufferQueueSourceNodeHostObject(
18
17
  const std::shared_ptr<AudioBufferQueueSourceNode> &node)
19
- : AudioScheduledSourceNodeHostObject(node) {
20
- addGetters(
21
- JSI_EXPORT_PROPERTY_GETTER(AudioBufferQueueSourceNodeHostObject, detune),
22
- JSI_EXPORT_PROPERTY_GETTER(AudioBufferQueueSourceNodeHostObject, playbackRate));
23
-
24
- addSetters(
25
- JSI_EXPORT_PROPERTY_SETTER(AudioBufferQueueSourceNodeHostObject, onPositionChanged),
26
- JSI_EXPORT_PROPERTY_SETTER(AudioBufferQueueSourceNodeHostObject, onPositionChangedInterval));
27
-
28
- // start method is overridden in this class
29
- functions_->erase("start");
30
-
18
+ : AudioBufferBaseSourceNodeHostObject(node) {
31
19
  addFunctions(
32
- JSI_EXPORT_FUNCTION(AudioBufferQueueSourceNodeHostObject, start),
33
20
  JSI_EXPORT_FUNCTION(AudioBufferQueueSourceNodeHostObject, enqueueBuffer),
34
21
  JSI_EXPORT_FUNCTION(AudioBufferQueueSourceNodeHostObject, pause));
35
22
  }
36
23
 
37
- JSI_PROPERTY_GETTER(detune) {
38
- auto audioBufferSourceNode =
39
- std::static_pointer_cast<AudioBufferQueueSourceNode>(node_);
40
- auto detune = audioBufferSourceNode->getDetuneParam();
41
- auto detuneHostObject = std::make_shared<AudioParamHostObject>(detune);
42
- return jsi::Object::createFromHostObject(runtime, detuneHostObject);
43
- }
44
-
45
- JSI_PROPERTY_GETTER(playbackRate) {
46
- auto audioBufferSourceNode =
47
- std::static_pointer_cast<AudioBufferQueueSourceNode>(node_);
48
- auto playbackRate = audioBufferSourceNode->getPlaybackRateParam();
49
- auto playbackRateHostObject =
50
- std::make_shared<AudioParamHostObject>(playbackRate);
51
- return jsi::Object::createFromHostObject(runtime, playbackRateHostObject);
52
- }
53
-
54
- JSI_PROPERTY_SETTER(onPositionChanged) {
55
- auto audioBufferQueueSourceNode =
56
- std::static_pointer_cast<AudioBufferQueueSourceNode>(node_);
57
-
58
- audioBufferQueueSourceNode->setOnPositionChangedCallbackId(std::stoull(value.getString(runtime).utf8(runtime)));
59
- }
60
-
61
- JSI_PROPERTY_SETTER(onPositionChangedInterval) {
62
- auto audioBufferQueueSourceNode =
63
- std::static_pointer_cast<AudioBufferQueueSourceNode>(node_);
64
-
65
- audioBufferQueueSourceNode->setOnPositionChangedInterval(value.getNumber());
66
- }
67
-
68
- JSI_HOST_FUNCTION(start) {
69
- auto when = args[0].getNumber();
70
-
71
- auto audioBufferQueueSourceNode =
72
- std::static_pointer_cast<AudioBufferQueueSourceNode>(node_);
73
-
74
- double offset = -1.0;
75
-
76
- if (args[1].isNumber()) {
77
- offset = args[1].asNumber();
78
- }
79
-
80
- audioBufferQueueSourceNode->start(when, offset);
81
-
82
- return jsi::Value::undefined();
83
- }
84
-
85
24
  JSI_HOST_FUNCTION(pause) {
86
25
  auto audioBufferQueueSourceNode =
87
26
  std::static_pointer_cast<AudioBufferQueueSourceNode>(node_);
@@ -97,10 +36,9 @@ class AudioBufferQueueSourceNodeHostObject
97
36
 
98
37
  auto audioBufferHostObject =
99
38
  args[0].getObject(runtime).asHostObject<AudioBufferHostObject>(runtime);
100
- int bufferId = args[1].asNumber();
101
- auto isLastBuffer = args[2].asBool();
39
+ auto isLastBuffer = args[1].asBool();
102
40
 
103
- audioBufferQueueSourceNode->enqueueBuffer(audioBufferHostObject->audioBuffer_, bufferId, isLastBuffer);
41
+ audioBufferQueueSourceNode->enqueueBuffer(audioBufferHostObject->audioBuffer_, isLastBuffer);
104
42
 
105
43
  return jsi::Value::undefined();
106
44
  }
@@ -2,8 +2,7 @@
2
2
 
3
3
  #include <audioapi/HostObjects/AudioBufferHostObject.h>
4
4
  #include <audioapi/core/sources/AudioBufferSourceNode.h>
5
- #include <audioapi/HostObjects/AudioParamHostObject.h>
6
- #include <audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h>
5
+ #include <audioapi/HostObjects/AudioBufferBaseSourceNodeHostObject.h>
7
6
 
8
7
  #include <memory>
9
8
  #include <vector>
@@ -12,34 +11,30 @@ namespace audioapi {
12
11
  using namespace facebook;
13
12
 
14
13
  class AudioBufferSourceNodeHostObject
15
- : public AudioScheduledSourceNodeHostObject {
14
+ : public AudioBufferBaseSourceNodeHostObject {
16
15
  public:
17
16
  explicit AudioBufferSourceNodeHostObject(
18
17
  const std::shared_ptr<AudioBufferSourceNode> &node)
19
- : AudioScheduledSourceNodeHostObject(node) {
18
+ : AudioBufferBaseSourceNodeHostObject(node) {
20
19
  addGetters(
21
20
  JSI_EXPORT_PROPERTY_GETTER(AudioBufferSourceNodeHostObject, loop),
22
21
  JSI_EXPORT_PROPERTY_GETTER(AudioBufferSourceNodeHostObject, loopSkip),
23
22
  JSI_EXPORT_PROPERTY_GETTER(AudioBufferSourceNodeHostObject, buffer),
24
23
  JSI_EXPORT_PROPERTY_GETTER(AudioBufferSourceNodeHostObject, loopStart),
25
- JSI_EXPORT_PROPERTY_GETTER(AudioBufferSourceNodeHostObject, loopEnd),
26
- JSI_EXPORT_PROPERTY_GETTER(AudioBufferSourceNodeHostObject, detune),
27
- JSI_EXPORT_PROPERTY_GETTER(AudioBufferSourceNodeHostObject, playbackRate));
24
+ JSI_EXPORT_PROPERTY_GETTER(AudioBufferSourceNodeHostObject, loopEnd));
28
25
 
29
26
  addSetters(
30
27
  JSI_EXPORT_PROPERTY_SETTER(AudioBufferSourceNodeHostObject, loop),
31
28
  JSI_EXPORT_PROPERTY_SETTER(AudioBufferSourceNodeHostObject, loopSkip),
32
- JSI_EXPORT_PROPERTY_SETTER(AudioBufferSourceNodeHostObject, buffer),
33
29
  JSI_EXPORT_PROPERTY_SETTER(AudioBufferSourceNodeHostObject, loopStart),
34
- JSI_EXPORT_PROPERTY_SETTER(AudioBufferSourceNodeHostObject, loopEnd),
35
- JSI_EXPORT_PROPERTY_SETTER(AudioBufferSourceNodeHostObject, onPositionChanged),
36
- JSI_EXPORT_PROPERTY_SETTER(AudioBufferSourceNodeHostObject, onPositionChangedInterval));
30
+ JSI_EXPORT_PROPERTY_SETTER(AudioBufferSourceNodeHostObject, loopEnd));
37
31
 
38
32
  // start method is overridden in this class
39
33
  functions_->erase("start");
40
34
 
41
35
  addFunctions(
42
- JSI_EXPORT_FUNCTION(AudioBufferSourceNodeHostObject, start));
36
+ JSI_EXPORT_FUNCTION(AudioBufferSourceNodeHostObject, start),
37
+ JSI_EXPORT_FUNCTION(AudioBufferSourceNodeHostObject, setBuffer));
43
38
  }
44
39
 
45
40
  JSI_PROPERTY_GETTER(loop) {
@@ -83,23 +78,6 @@ class AudioBufferSourceNodeHostObject
83
78
  return {loopEnd};
84
79
  }
85
80
 
86
- JSI_PROPERTY_GETTER(detune) {
87
- auto audioBufferSourceNode =
88
- std::static_pointer_cast<AudioBufferSourceNode>(node_);
89
- auto detune = audioBufferSourceNode->getDetuneParam();
90
- auto detuneHostObject = std::make_shared<AudioParamHostObject>(detune);
91
- return jsi::Object::createFromHostObject(runtime, detuneHostObject);
92
- }
93
-
94
- JSI_PROPERTY_GETTER(playbackRate) {
95
- auto audioBufferSourceNode =
96
- std::static_pointer_cast<AudioBufferSourceNode>(node_);
97
- auto playbackRate = audioBufferSourceNode->getPlaybackRateParam();
98
- auto playbackRateHostObject =
99
- std::make_shared<AudioParamHostObject>(playbackRate);
100
- return jsi::Object::createFromHostObject(runtime, playbackRateHostObject);
101
- }
102
-
103
81
  JSI_PROPERTY_SETTER(loop) {
104
82
  auto audioBufferSourceNode =
105
83
  std::static_pointer_cast<AudioBufferSourceNode>(node_);
@@ -112,19 +90,6 @@ class AudioBufferSourceNodeHostObject
112
90
  audioBufferSourceNode->setLoopSkip(value.getBool());
113
91
  }
114
92
 
115
- JSI_PROPERTY_SETTER(buffer) {
116
- auto audioBufferSourceNode =
117
- std::static_pointer_cast<AudioBufferSourceNode>(node_);
118
- if (value.isNull()) {
119
- audioBufferSourceNode->setBuffer(std::shared_ptr<AudioBuffer>(nullptr));
120
- return;
121
- }
122
-
123
- auto bufferHostObject =
124
- value.getObject(runtime).asHostObject<AudioBufferHostObject>(runtime);
125
- audioBufferSourceNode->setBuffer(bufferHostObject->audioBuffer_);
126
- }
127
-
128
93
  JSI_PROPERTY_SETTER(loopStart) {
129
94
  auto audioBufferSourceNode =
130
95
  std::static_pointer_cast<AudioBufferSourceNode>(node_);
@@ -137,20 +102,6 @@ class AudioBufferSourceNodeHostObject
137
102
  audioBufferSourceNode->setLoopEnd(value.getNumber());
138
103
  }
139
104
 
140
- JSI_PROPERTY_SETTER(onPositionChanged) {
141
- auto audioBufferSourceNode =
142
- std::static_pointer_cast<AudioBufferSourceNode>(node_);
143
-
144
- audioBufferSourceNode->setOnPositionChangedCallbackId(std::stoull(value.getString(runtime).utf8(runtime)));
145
- }
146
-
147
- JSI_PROPERTY_SETTER(onPositionChangedInterval) {
148
- auto audioBufferSourceNode =
149
- std::static_pointer_cast<AudioBufferSourceNode>(node_);
150
-
151
- audioBufferSourceNode->setOnPositionChangedInterval(value.getNumber());
152
- }
153
-
154
105
  JSI_HOST_FUNCTION(start) {
155
106
  auto when = args[0].getNumber();
156
107
  auto offset = args[1].getNumber();
@@ -169,6 +120,25 @@ class AudioBufferSourceNodeHostObject
169
120
 
170
121
  return jsi::Value::undefined();
171
122
  }
123
+
124
+ JSI_HOST_FUNCTION(setBuffer) {
125
+ auto audioBufferSourceNode =
126
+ std::static_pointer_cast<AudioBufferSourceNode>(node_);
127
+
128
+ auto audioBufferSourceNodeJsiObject = args[0].getObject(runtime);
129
+
130
+ if (args[1].isNull()) {
131
+ audioBufferSourceNode->setBuffer(std::shared_ptr<AudioBuffer>(nullptr));
132
+ return jsi::Value::undefined();
133
+ }
134
+
135
+ auto bufferHostObject =
136
+ args[1].getObject(runtime).asHostObject<AudioBufferHostObject>(runtime);
137
+ audioBufferSourceNodeJsiObject.setExternalMemoryPressure(runtime,
138
+ bufferHostObject->getSizeInBytes() + 16);
139
+ audioBufferSourceNode->setBuffer(bufferHostObject->audioBuffer_);
140
+ return jsi::Value::undefined();
141
+ }
172
142
  };
173
143
 
174
144
  } // namespace audioapi
@@ -8,6 +8,7 @@
8
8
  #include <audioapi/HostObjects/AudioDestinationNodeHostObject.h>
9
9
  #include <audioapi/core/BaseAudioContext.h>
10
10
  #include <audioapi/HostObjects/BiquadFilterNodeHostObject.h>
11
+ #include <audioapi/HostObjects/CustomProcessorNodeHostObject.h>
11
12
  #include <audioapi/HostObjects/GainNodeHostObject.h>
12
13
  #include <audioapi/HostObjects/OscillatorNodeHostObject.h>
13
14
  #include <audioapi/HostObjects/PeriodicWaveHostObject.h>
@@ -40,6 +41,7 @@ class BaseAudioContextHostObject : public JsiHostObject {
40
41
 
41
42
  addFunctions(
42
43
  JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createOscillator),
44
+ JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createCustomProcessor),
43
45
  JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createGain),
44
46
  JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createStereoPanner),
45
47
  JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createBiquadFilter),
@@ -78,6 +80,13 @@ class BaseAudioContextHostObject : public JsiHostObject {
78
80
  return jsi::Object::createFromHostObject(runtime, oscillatorHostObject);
79
81
  }
80
82
 
83
+ JSI_HOST_FUNCTION(createCustomProcessor) {
84
+ auto identifier = args[0].getString(runtime).utf8(runtime);
85
+ auto customProcessor = context_->createCustomProcessor(identifier);
86
+ auto customProcessorHostObject = std::make_shared<CustomProcessorNodeHostObject>(customProcessor);
87
+ return jsi::Object::createFromHostObject(runtime, customProcessorHostObject);
88
+ }
89
+
81
90
  JSI_HOST_FUNCTION(createGain) {
82
91
  auto gain = context_->createGain();
83
92
  auto gainHostObject = std::make_shared<GainNodeHostObject>(gain);
@@ -0,0 +1,54 @@
1
+ #pragma once
2
+
3
+ #include <audioapi/HostObjects/AudioNodeHostObject.h>
4
+ #include <audioapi/HostObjects/AudioParamHostObject.h>
5
+ #include <audioapi/core/effects/CustomProcessorNode.h>
6
+
7
+ #include <memory>
8
+ #include <string>
9
+ #include <vector>
10
+
11
+ namespace audioapi {
12
+ using namespace facebook;
13
+
14
+ class CustomProcessorNodeHostObject : public AudioNodeHostObject {
15
+ public:
16
+ explicit CustomProcessorNodeHostObject(const std::shared_ptr<CustomProcessorNode> &node)
17
+ : AudioNodeHostObject(node) {
18
+ addGetters(
19
+ JSI_EXPORT_PROPERTY_GETTER(CustomProcessorNodeHostObject, customProcessor),
20
+ JSI_EXPORT_PROPERTY_GETTER(CustomProcessorNodeHostObject, processorMode));
21
+
22
+ addSetters(
23
+ JSI_EXPORT_PROPERTY_SETTER(CustomProcessorNodeHostObject, processorMode));
24
+ }
25
+
26
+ JSI_PROPERTY_GETTER(customProcessor) {
27
+ auto customProcessorNode = std::static_pointer_cast<CustomProcessorNode>(node_);
28
+ auto customProcessorParam =
29
+ std::make_shared<AudioParamHostObject>(customProcessorNode->getCustomProcessorParam());
30
+ return jsi::Object::createFromHostObject(runtime, customProcessorParam);
31
+ }
32
+
33
+ JSI_PROPERTY_GETTER(processorMode) {
34
+ auto customProcessorNode = std::static_pointer_cast<CustomProcessorNode>(node_);
35
+ auto mode = customProcessorNode->getProcessorMode();
36
+ std::string modeStr = (mode == CustomProcessorNode::ProcessorMode::ProcessThrough)
37
+ ? "processThrough"
38
+ : "processInPlace";
39
+ return jsi::String::createFromUtf8(runtime, modeStr);
40
+ }
41
+
42
+ JSI_PROPERTY_SETTER(processorMode) {
43
+ auto customProcessorNode = std::static_pointer_cast<CustomProcessorNode>(node_);
44
+ std::string modeStr = value.getString(runtime).utf8(runtime);
45
+
46
+ if (modeStr == "processThrough") {
47
+ customProcessorNode->setProcessorMode(CustomProcessorNode::ProcessorMode::ProcessThrough);
48
+ } else {
49
+ customProcessorNode->setProcessorMode(CustomProcessorNode::ProcessorMode::ProcessInPlace);
50
+ }
51
+ }
52
+ };
53
+
54
+ } // namespace audioapi
@@ -2,6 +2,7 @@
2
2
  #include <audioapi/core/analysis/AnalyserNode.h>
3
3
  #include <audioapi/core/destinations/AudioDestinationNode.h>
4
4
  #include <audioapi/core/effects/BiquadFilterNode.h>
5
+ #include <audioapi/core/effects/CustomProcessorNode.h>
5
6
  #include <audioapi/core/effects/GainNode.h>
6
7
  #include <audioapi/core/effects/StereoPannerNode.h>
7
8
  #include <audioapi/core/sources/AudioBuffer.h>
@@ -54,6 +55,14 @@ std::shared_ptr<OscillatorNode> BaseAudioContext::createOscillator() {
54
55
  return oscillator;
55
56
  }
56
57
 
58
+ std::shared_ptr<CustomProcessorNode> BaseAudioContext::createCustomProcessor(
59
+ const std::string &identifier) {
60
+ auto customProcessor =
61
+ std::make_shared<CustomProcessorNode>(this, identifier);
62
+ nodeManager_->addProcessingNode(customProcessor);
63
+ return customProcessor;
64
+ }
65
+
57
66
  std::shared_ptr<GainNode> BaseAudioContext::createGain() {
58
67
  auto gain = std::make_shared<GainNode>(this);
59
68
  nodeManager_->addProcessingNode(gain);
@@ -15,6 +15,7 @@
15
15
  namespace audioapi {
16
16
 
17
17
  class AudioBus;
18
+ class CustomProcessorNode;
18
19
  class GainNode;
19
20
  class AudioBuffer;
20
21
  class PeriodicWave;
@@ -41,6 +42,7 @@ class BaseAudioContext {
41
42
  std::shared_ptr<AudioDestinationNode> getDestination();
42
43
 
43
44
  std::shared_ptr<OscillatorNode> createOscillator();
45
+ std::shared_ptr<CustomProcessorNode> createCustomProcessor(const std::string& identifier);
44
46
  std::shared_ptr<GainNode> createGain();
45
47
  std::shared_ptr<StereoPannerNode> createStereoPanner();
46
48
  std::shared_ptr<BiquadFilterNode> createBiquadFilter();
@@ -0,0 +1,173 @@
1
+ #include <audioapi/core/BaseAudioContext.h>
2
+ #include <audioapi/core/effects/CustomProcessorNode.h>
3
+ #include <audioapi/utils/AudioArray.h>
4
+ #include <audioapi/utils/AudioBus.h>
5
+
6
+ #include <algorithm>
7
+ #include <cstring>
8
+ #include <iostream>
9
+
10
+ namespace audioapi {
11
+
12
+ // Static registries and active node tracking
13
+ std::map<std::string, std::function<std::shared_ptr<CustomAudioProcessor>()>>
14
+ CustomProcessorNode::s_processorFactoriesByIdentifier;
15
+ std::unordered_map<std::string, CustomProcessorNode::GenericControlHandler>
16
+ CustomProcessorNode::s_controlHandlersByIdentifier;
17
+ std::unordered_map<std::string, std::vector<CustomProcessorNode *>>
18
+ CustomProcessorNode::s_activeNodes;
19
+
20
+ // Constructor: initializes processor, tracking, and preallocated buffers
21
+ CustomProcessorNode::CustomProcessorNode(
22
+ BaseAudioContext *context,
23
+ const std::string &identifier)
24
+ : AudioNode(context), processorMode_(ProcessorMode::ProcessInPlace) {
25
+ customProcessorParam_ = std::make_shared<AudioParam>(
26
+ 1.0f, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT, context);
27
+ isInitialized_ = true;
28
+
29
+ auto it = s_processorFactoriesByIdentifier.find(identifier);
30
+ processor_ =
31
+ (it != s_processorFactoriesByIdentifier.end()) ? it->second() : nullptr;
32
+
33
+ s_activeNodes[identifier].push_back(this);
34
+ }
35
+
36
+ // Destructor: cleans up tracking for this instance
37
+ CustomProcessorNode::~CustomProcessorNode() {
38
+ for (auto &pair : s_activeNodes) {
39
+ auto &vec = pair.second;
40
+ vec.erase(std::remove(vec.begin(), vec.end(), this), vec.end());
41
+ }
42
+ }
43
+
44
+ // Gets the modifiable parameter
45
+ std::shared_ptr<AudioParam> CustomProcessorNode::getCustomProcessorParam()
46
+ const {
47
+ return customProcessorParam_;
48
+ }
49
+
50
+ // Returns the current processing mode
51
+ CustomProcessorNode::ProcessorMode CustomProcessorNode::getProcessorMode()
52
+ const {
53
+ return processorMode_;
54
+ }
55
+
56
+ // Updates the processing mode
57
+ void CustomProcessorNode::setProcessorMode(ProcessorMode mode) {
58
+ processorMode_ = mode;
59
+ }
60
+
61
+ // Registers a factory for dynamic processor instantiation
62
+ void CustomProcessorNode::registerProcessorFactory(
63
+ const std::string &identifier,
64
+ std::function<std::shared_ptr<CustomAudioProcessor>()> factory) {
65
+ s_processorFactoriesByIdentifier[identifier] = std::move(factory);
66
+ notifyProcessorChanged(identifier);
67
+ }
68
+
69
+ // Removes a processor factory from registry
70
+ void CustomProcessorNode::unregisterProcessorFactory(
71
+ const std::string &identifier) {
72
+ s_processorFactoriesByIdentifier.erase(identifier);
73
+ notifyProcessorChanged(identifier);
74
+ }
75
+
76
+ // Updates processor instances for all nodes using given identifier
77
+ void CustomProcessorNode::notifyProcessorChanged(
78
+ const std::string &identifier) {
79
+ auto it = s_activeNodes.find(identifier);
80
+ if (it != s_activeNodes.end()) {
81
+ for (CustomProcessorNode *node : it->second) {
82
+ auto f = s_processorFactoriesByIdentifier.find(identifier);
83
+ node->processor_ =
84
+ (f != s_processorFactoriesByIdentifier.end()) ? f->second() : nullptr;
85
+ }
86
+ }
87
+ }
88
+
89
+ // Registers control handler for runtime automation
90
+ void CustomProcessorNode::registerControlHandler(
91
+ const std::string &identifier,
92
+ GenericControlHandler handler) {
93
+ s_controlHandlersByIdentifier[identifier] = std::move(handler);
94
+ }
95
+
96
+ // Removes a control handler
97
+ void CustomProcessorNode::unregisterControlHandler(
98
+ const std::string &identifier) {
99
+ s_controlHandlersByIdentifier.erase(identifier);
100
+ }
101
+
102
+ // Core processing method routed by selected mode
103
+ void CustomProcessorNode::processNode(
104
+ const std::shared_ptr<AudioBus> &processingBus,
105
+ int framesToProcess) {
106
+ if (!processor_)
107
+ return;
108
+
109
+ int numChannels = processingBus->getNumberOfChannels();
110
+ if (preallocatedOutputBuffers_.size() != static_cast<size_t>(numChannels)) {
111
+ preallocatedOutputBuffers_.resize(numChannels);
112
+ }
113
+
114
+ for (int ch = 0; ch < numChannels; ++ch) {
115
+ if (preallocatedOutputBuffers_[ch].size() !=
116
+ static_cast<size_t>(framesToProcess)) {
117
+ preallocatedOutputBuffers_[ch].resize(framesToProcess);
118
+ }
119
+ }
120
+
121
+ switch (processorMode_) {
122
+ case ProcessorMode::ProcessThrough:
123
+ processThrough(processingBus, framesToProcess);
124
+ break;
125
+ case ProcessorMode::ProcessInPlace:
126
+ default:
127
+ processInPlace(processingBus, framesToProcess);
128
+ break;
129
+ }
130
+ }
131
+
132
+ // Executes in-place processing on the shared audio buffer
133
+ void CustomProcessorNode::processInPlace(
134
+ const std::shared_ptr<AudioBus> &bus,
135
+ int frames) {
136
+ if (!processor_)
137
+ return;
138
+
139
+ int numChannels = bus->getNumberOfChannels();
140
+ std::vector<float *> channelData(numChannels);
141
+ for (int ch = 0; ch < numChannels; ++ch) {
142
+ channelData[ch] = bus->getChannel(ch)->getData();
143
+ }
144
+
145
+ processor_->processInPlace(channelData.data(), numChannels, frames);
146
+ }
147
+
148
+ // Executes processing using separate input and output buffers with
149
+ // preallocation
150
+ void CustomProcessorNode::processThrough(
151
+ const std::shared_ptr<AudioBus> &bus,
152
+ int frames) {
153
+ if (!processor_)
154
+ return;
155
+
156
+ int numChannels = bus->getNumberOfChannels();
157
+ std::vector<float *> input(numChannels);
158
+ std::vector<float *> output(numChannels);
159
+
160
+ for (int ch = 0; ch < numChannels; ++ch) {
161
+ input[ch] = bus->getChannel(ch)->getData();
162
+ output[ch] = preallocatedOutputBuffers_[ch].data();
163
+ }
164
+
165
+ processor_->processThrough(input.data(), output.data(), numChannels, frames);
166
+
167
+ for (int ch = 0; ch < numChannels; ++ch) {
168
+ std::memcpy(
169
+ bus->getChannel(ch)->getData(), output[ch], sizeof(float) * frames);
170
+ }
171
+ }
172
+
173
+ } // namespace audioapi