react-native-audio-api 0.6.2-rc.6 → 0.6.3-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +25 -0
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionCallback.kt +13 -0
- package/common/cpp/audioapi/HostObjects/AudioBufferBaseSourceNodeHostObject.h +60 -0
- package/common/cpp/audioapi/HostObjects/AudioBufferQueueSourceNodeHostObject.h +5 -67
- package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +26 -56
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +9 -0
- package/common/cpp/audioapi/HostObjects/CustomProcessorNodeHostObject.h +54 -0
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +9 -0
- package/common/cpp/audioapi/core/BaseAudioContext.h +2 -0
- package/common/cpp/audioapi/core/effects/CustomProcessorNode.cpp +173 -0
- package/common/cpp/audioapi/core/effects/CustomProcessorNode.h +186 -0
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +106 -0
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.h +54 -0
- package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.cpp +11 -129
- package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.h +8 -37
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +5 -93
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +4 -30
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +8 -12
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +2 -3
- package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +0 -5
- package/common/cpp/audioapi/core/sources/OscillatorNode.h +0 -1
- package/common/cpp/audioapi/core/utils/AudioNodeDestructor.cpp +3 -1
- package/common/cpp/audioapi/core/utils/AudioNodeManager.cpp +1 -1
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +1 -1
- package/ios/audioapi/ios/system/AudioEngine.h +1 -0
- package/ios/audioapi/ios/system/AudioEngine.mm +14 -3
- package/ios/audioapi/ios/system/AudioSessionManager.h +1 -0
- package/ios/audioapi/ios/system/AudioSessionManager.mm +10 -0
- package/ios/audioapi/ios/system/NotificationManager.mm +2 -4
- package/lib/commonjs/api.js +7 -0
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/core/AudioBufferBaseSourceNode.js +35 -0
- package/lib/commonjs/core/AudioBufferBaseSourceNode.js.map +1 -0
- package/lib/commonjs/core/AudioBufferQueueSourceNode.js +5 -22
- package/lib/commonjs/core/AudioBufferQueueSourceNode.js.map +1 -1
- package/lib/commonjs/core/AudioBufferSourceNode.js +4 -21
- package/lib/commonjs/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/commonjs/core/AudioScheduledSourceNode.js +7 -2
- package/lib/commonjs/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/commonjs/core/BaseAudioContext.js +4 -0
- package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
- package/lib/commonjs/core/CustomProcessorNode.js +23 -0
- package/lib/commonjs/core/CustomProcessorNode.js.map +1 -0
- package/lib/commonjs/web-core/AudioScheduledSourceNode.js +1 -4
- package/lib/commonjs/web-core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/module/api.js +1 -0
- package/lib/module/api.js.map +1 -1
- package/lib/module/core/AudioBufferBaseSourceNode.js +29 -0
- package/lib/module/core/AudioBufferBaseSourceNode.js.map +1 -0
- package/lib/module/core/AudioBufferQueueSourceNode.js +5 -22
- package/lib/module/core/AudioBufferQueueSourceNode.js.map +1 -1
- package/lib/module/core/AudioBufferSourceNode.js +4 -21
- package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/module/core/AudioScheduledSourceNode.js +7 -2
- package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/module/core/BaseAudioContext.js +4 -0
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/module/core/CustomProcessorNode.js +17 -0
- package/lib/module/core/CustomProcessorNode.js.map +1 -0
- package/lib/module/web-core/AudioScheduledSourceNode.js +1 -4
- package/lib/module/web-core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/typescript/api.d.ts +1 -0
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/core/AudioBufferBaseSourceNode.d.ts +14 -0
- package/lib/typescript/core/AudioBufferBaseSourceNode.d.ts.map +1 -0
- package/lib/typescript/core/AudioBufferQueueSourceNode.d.ts +3 -12
- package/lib/typescript/core/AudioBufferQueueSourceNode.d.ts.map +1 -1
- package/lib/typescript/core/AudioBufferSourceNode.d.ts +2 -11
- package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts +3 -2
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -1
- package/lib/typescript/core/BaseAudioContext.d.ts +2 -0
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/core/CustomProcessorNode.d.ts +12 -0
- package/lib/typescript/core/CustomProcessorNode.d.ts.map +1 -0
- package/lib/typescript/events/types.d.ts +2 -7
- package/lib/typescript/events/types.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +16 -13
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +1 -0
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts +2 -1
- package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api.ts +1 -0
- package/src/core/AudioBufferBaseSourceNode.ts +41 -0
- package/src/core/AudioBufferQueueSourceNode.ts +3 -35
- package/src/core/AudioBufferSourceNode.ts +10 -33
- package/src/core/AudioScheduledSourceNode.ts +12 -5
- package/src/core/BaseAudioContext.ts +8 -0
- package/src/core/CustomProcessorNode.ts +28 -0
- package/src/events/types.ts +2 -8
- package/src/interfaces.ts +25 -23
- package/src/types.ts +2 -0
- 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/
|
|
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
|
|
14
|
+
: public AudioBufferBaseSourceNodeHostObject {
|
|
16
15
|
public:
|
|
17
16
|
explicit AudioBufferQueueSourceNodeHostObject(
|
|
18
17
|
const std::shared_ptr<AudioBufferQueueSourceNode> &node)
|
|
19
|
-
:
|
|
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
|
-
|
|
101
|
-
auto isLastBuffer = args[2].asBool();
|
|
39
|
+
auto isLastBuffer = args[1].asBool();
|
|
102
40
|
|
|
103
|
-
audioBufferQueueSourceNode->enqueueBuffer(audioBufferHostObject->audioBuffer_,
|
|
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/
|
|
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
|
|
14
|
+
: public AudioBufferBaseSourceNodeHostObject {
|
|
16
15
|
public:
|
|
17
16
|
explicit AudioBufferSourceNodeHostObject(
|
|
18
17
|
const std::shared_ptr<AudioBufferSourceNode> &node)
|
|
19
|
-
:
|
|
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
|