Skip to content

Commit 22c5b5f

Browse files
committed
feat: bridge audio param to graph
1 parent b6adf6c commit 22c5b5f

22 files changed

Lines changed: 403 additions & 437 deletions

packages/react-native-audio-api/common/cpp/audioapi/HostObjects/AudioNodeHostObject.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ JSI_HOST_FUNCTION_IMPL(AudioNodeHostObject, connect) {
6666
connect(*node);
6767
} else if (obj.isHostObject<AudioParamHostObject>(runtime)) {
6868
auto param = obj.getHostObject<AudioParamHostObject>(runtime);
69-
auto owner = args[1].getObject(runtime).getHostObject<AudioNodeHostObject>(runtime);
70-
connectParam(*owner, param->param_.get());
69+
// Connect source → bridge (the bridge → owner edge is created at param construction)
70+
graph_->addEdge(node_, param->bridgeNode());
7171
}
7272
return jsi::Value::undefined();
7373
}
@@ -84,8 +84,8 @@ JSI_HOST_FUNCTION_IMPL(AudioNodeHostObject, disconnect) {
8484
disconnect(*node);
8585
} else if (obj.isHostObject<AudioParamHostObject>(runtime)) {
8686
auto param = obj.getHostObject<AudioParamHostObject>(runtime);
87-
auto owner = args[1].getObject(runtime).getHostObject<AudioNodeHostObject>(runtime);
88-
disconnectParam(*owner, param->param_.get());
87+
// Disconnect source → bridge
88+
graph_->removeEdge(node_, param->bridgeNode());
8989
}
9090

9191
return jsi::Value::undefined();

packages/react-native-audio-api/common/cpp/audioapi/HostObjects/AudioParamHostObject.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,30 @@
11
#include <audioapi/HostObjects/AudioParamHostObject.h>
22

33
#include <audioapi/core/AudioParam.h>
4+
#include <audioapi/core/utils/graph/BridgeNode.hpp>
45
#include <audioapi/utils/AudioArray.hpp>
56

67
#include <memory>
78
#include <utility>
89

910
namespace audioapi {
1011

11-
AudioParamHostObject::AudioParamHostObject(const std::shared_ptr<AudioParam> &param)
12-
: param_(param),
12+
AudioParamHostObject::AudioParamHostObject(
13+
std::shared_ptr<utils::graph::Graph> graph,
14+
HNode *ownerNode,
15+
const std::shared_ptr<AudioParam> &param)
16+
: graph_(std::move(graph)),
17+
param_(param),
1318
defaultValue_(param->getDefaultValue()),
1419
minValue_(param->getMinValue()),
1520
maxValue_(param->getMaxValue()) {
21+
// Create the bridge node in the graph
22+
auto bridgeGraphObject = std::make_unique<utils::graph::BridgeNode>(param.get());
23+
bridgeNode_ = graph_->addNode(std::move(bridgeGraphObject));
24+
25+
// Connect bridge → owner so topological sort orders correctly
26+
(void)graph_->addEdge(bridgeNode_, ownerNode);
27+
1628
addGetters(
1729
JSI_EXPORT_PROPERTY_GETTER(AudioParamHostObject, value),
1830
JSI_EXPORT_PROPERTY_GETTER(AudioParamHostObject, defaultValue),
@@ -31,6 +43,16 @@ AudioParamHostObject::AudioParamHostObject(const std::shared_ptr<AudioParam> &pa
3143
addSetters(JSI_EXPORT_PROPERTY_SETTER(AudioParamHostObject, value));
3244
}
3345

46+
AudioParamHostObject::~AudioParamHostObject() {
47+
if (graph_ && bridgeNode_) {
48+
// Remove outgoing edges (bridge → owner)
49+
(void)graph_->removeAllEdges(bridgeNode_);
50+
// Remove the bridge node itself
51+
(void)graph_->removeNode(bridgeNode_);
52+
bridgeNode_ = nullptr;
53+
}
54+
}
55+
3456
JSI_PROPERTY_GETTER_IMPL(AudioParamHostObject, value) {
3557
return {param_->getValue()};
3658
}

packages/react-native-audio-api/common/cpp/audioapi/HostObjects/AudioParamHostObject.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <audioapi/core/utils/graph/HostNode.hpp>
34
#include <audioapi/jsi/JsiHostObject.h>
45

56
#include <jsi/jsi.h>
@@ -11,9 +12,27 @@ using namespace facebook;
1112

1213
class AudioParam;
1314

15+
/// @brief Host object for AudioParam that owns its BridgeNode.
16+
///
17+
/// When created, a BridgeNode is added to the graph and connected to the
18+
/// owner node (bridge → owner). Sources connecting to this param connect
19+
/// to the bridge node (source → bridge).
20+
///
21+
/// When destroyed, the BridgeNode is removed from the graph.
1422
class AudioParamHostObject : public JsiHostObject {
1523
public:
16-
explicit AudioParamHostObject(const std::shared_ptr<AudioParam> &param);
24+
using HNode = utils::graph::HostGraph::Node;
25+
26+
/// @brief Creates an AudioParamHostObject with its BridgeNode.
27+
/// @param graph The audio graph
28+
/// @param ownerNode The HNode* of the AudioNode that owns this param
29+
/// @param param The AudioParam this host object represents
30+
explicit AudioParamHostObject(
31+
std::shared_ptr<utils::graph::Graph> graph,
32+
HNode *ownerNode,
33+
const std::shared_ptr<AudioParam> &param);
34+
35+
~AudioParamHostObject() override;
1736

1837
JSI_PROPERTY_GETTER_DECL(value);
1938
JSI_PROPERTY_GETTER_DECL(defaultValue);
@@ -30,9 +49,16 @@ class AudioParamHostObject : public JsiHostObject {
3049
JSI_HOST_FUNCTION_DECL(cancelScheduledValues);
3150
JSI_HOST_FUNCTION_DECL(cancelAndHoldAtTime);
3251

52+
/// @brief Returns the bridge node for this param (for source → bridge connections).
53+
[[nodiscard]] HNode *bridgeNode() const {
54+
return bridgeNode_;
55+
}
56+
3357
private:
3458
friend class AudioNodeHostObject;
3559

60+
std::shared_ptr<utils::graph::Graph> graph_;
61+
HNode *bridgeNode_ = nullptr;
3662
std::shared_ptr<AudioParam> param_;
3763
float defaultValue_;
3864
float minValue_;

packages/react-native-audio-api/common/cpp/audioapi/HostObjects/effects/BiquadFilterNodeHostObject.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ BiquadFilterNodeHostObject::BiquadFilterNodeHostObject(
2020
options),
2121
type_(options.type) {
2222
auto biquadFilterNode = static_cast<BiquadFilterNode *>(node_->handle->audioNode->asAudioNode());
23-
frequencyParam_ = std::make_shared<AudioParamHostObject>(biquadFilterNode->getFrequencyParam());
24-
detuneParam_ = std::make_shared<AudioParamHostObject>(biquadFilterNode->getDetuneParam());
25-
QParam_ = std::make_shared<AudioParamHostObject>(biquadFilterNode->getQParam());
26-
gainParam_ = std::make_shared<AudioParamHostObject>(biquadFilterNode->getGainParam());
23+
frequencyParam_ =
24+
std::make_shared<AudioParamHostObject>(graph_, node_, biquadFilterNode->getFrequencyParam());
25+
detuneParam_ =
26+
std::make_shared<AudioParamHostObject>(graph_, node_, biquadFilterNode->getDetuneParam());
27+
QParam_ = std::make_shared<AudioParamHostObject>(graph_, node_, biquadFilterNode->getQParam());
28+
gainParam_ =
29+
std::make_shared<AudioParamHostObject>(graph_, node_, biquadFilterNode->getGainParam());
2730

2831
addGetters(
2932
JSI_EXPORT_PROPERTY_GETTER(BiquadFilterNodeHostObject, frequency),

packages/react-native-audio-api/common/cpp/audioapi/HostObjects/effects/DelayNodeHostObject.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ DelayNodeHostObject::DelayNodeHostObject(
1616
std::make_unique<DelayNode>(context, options),
1717
options) {
1818
auto delayNode = static_cast<DelayNode *>(node_->handle->audioNode->asAudioNode());
19-
delayTimeParam_ = std::make_shared<AudioParamHostObject>(delayNode->getDelayTimeParam());
19+
delayTimeParam_ =
20+
std::make_shared<AudioParamHostObject>(graph_, node_, delayNode->getDelayTimeParam());
2021
addGetters(JSI_EXPORT_PROPERTY_GETTER(DelayNodeHostObject, delayTime));
2122
}
2223

packages/react-native-audio-api/common/cpp/audioapi/HostObjects/effects/GainNodeHostObject.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ GainNodeHostObject::GainNodeHostObject(
1616
std::make_unique<GainNode>(context, options),
1717
options) {
1818
auto gainNode = static_cast<GainNode *>(node_->handle->audioNode->asAudioNode());
19-
gainParam_ = std::make_shared<AudioParamHostObject>(gainNode->getGainParam());
19+
gainParam_ = std::make_shared<AudioParamHostObject>(graph_, node_, gainNode->getGainParam());
2020

2121
addGetters(JSI_EXPORT_PROPERTY_GETTER(GainNodeHostObject, gain));
2222
}

packages/react-native-audio-api/common/cpp/audioapi/HostObjects/effects/StereoPannerNodeHostObject.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ StereoPannerNodeHostObject::StereoPannerNodeHostObject(
1616
std::make_unique<StereoPannerNode>(context, options),
1717
options) {
1818
auto stereoPannerNode = static_cast<StereoPannerNode *>(node_->handle->audioNode->asAudioNode());
19-
panParam_ = std::make_shared<AudioParamHostObject>(stereoPannerNode->getPanParam());
19+
panParam_ =
20+
std::make_shared<AudioParamHostObject>(graph_, node_, stereoPannerNode->getPanParam());
2021

2122
addGetters(JSI_EXPORT_PROPERTY_GETTER(StereoPannerNodeHostObject, pan));
2223
}

packages/react-native-audio-api/common/cpp/audioapi/HostObjects/sources/AudioBufferBaseSourceNodeHostObject.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ AudioBufferBaseSourceNodeHostObject::AudioBufferBaseSourceNodeHostObject(
1919
pitchCorrection_(options.pitchCorrection) {
2020
auto sourceNode =
2121
static_cast<AudioBufferBaseSourceNode *>(node_->handle->audioNode->asAudioNode());
22-
detuneParam_ = std::make_shared<AudioParamHostObject>(sourceNode->getDetuneParam());
23-
playbackRateParam_ = std::make_shared<AudioParamHostObject>(sourceNode->getPlaybackRateParam());
22+
detuneParam_ =
23+
std::make_shared<AudioParamHostObject>(graph_, node_, sourceNode->getDetuneParam());
24+
playbackRateParam_ =
25+
std::make_shared<AudioParamHostObject>(graph_, node_, sourceNode->getPlaybackRateParam());
2426

2527
addGetters(
2628
JSI_EXPORT_PROPERTY_GETTER(AudioBufferBaseSourceNodeHostObject, detune),

packages/react-native-audio-api/common/cpp/audioapi/HostObjects/sources/ConstantSourceNodeHostObject.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ ConstantSourceNodeHostObject::ConstantSourceNodeHostObject(
1616
options) {
1717
auto constantSourceNode =
1818
static_cast<ConstantSourceNode *>(node_->handle->audioNode->asAudioNode());
19-
offsetParam_ = std::make_shared<AudioParamHostObject>(constantSourceNode->getOffsetParam());
19+
offsetParam_ =
20+
std::make_shared<AudioParamHostObject>(graph_, node_, constantSourceNode->getOffsetParam());
2021

2122
addGetters(JSI_EXPORT_PROPERTY_GETTER(ConstantSourceNodeHostObject, offset));
2223
}

packages/react-native-audio-api/common/cpp/audioapi/HostObjects/sources/OscillatorNodeHostObject.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ OscillatorNodeHostObject::OscillatorNodeHostObject(
2020
options),
2121
type_(options.type) {
2222
auto oscillatorNode = static_cast<OscillatorNode *>(node_->handle->audioNode->asAudioNode());
23-
frequencyParam_ = std::make_shared<AudioParamHostObject>(oscillatorNode->getFrequencyParam());
24-
detuneParam_ = std::make_shared<AudioParamHostObject>(oscillatorNode->getDetuneParam());
23+
frequencyParam_ =
24+
std::make_shared<AudioParamHostObject>(graph_, node_, oscillatorNode->getFrequencyParam());
25+
detuneParam_ =
26+
std::make_shared<AudioParamHostObject>(graph_, node_, oscillatorNode->getDetuneParam());
2527

2628
addGetters(
2729
JSI_EXPORT_PROPERTY_GETTER(OscillatorNodeHostObject, frequency),

0 commit comments

Comments
 (0)