Skip to content

Commit

Permalink
Structure node graph files. Add generalized signal generators base.
Browse files Browse the repository at this point in the history
  • Loading branch information
linuscu committed Sep 11, 2024
1 parent 6ccedb9 commit 4305a25
Show file tree
Hide file tree
Showing 30 changed files with 962 additions and 560 deletions.
2 changes: 1 addition & 1 deletion packages/math/include/math/MathFunc.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ namespace l::math::functions {
T mod(T val, T mod) {
if constexpr (std::is_floating_point_v<T>) {
if constexpr (sizeof(T) == 4) {
return modff(val, mod);
return fmodf(val, mod);
}
else if constexpr (sizeof(T) == 8) {
return fmod(val, mod);
Expand Down
30 changes: 17 additions & 13 deletions packages/nodegraph/include/nodegraph/NodeGraphSchema.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

#include "logging/LoggingAll.h"

#include "nodegraph/NodeGraph.h"
#include "nodegraph/NodeGraphOpEffect.h"
#include "nodegraph/NodeGraphOpFilter.h"
#include "nodegraph/NodeGraphOpInput.h"
#include "nodegraph/NodeGraphOpLogic.h"
#include "nodegraph/NodeGraphOpNumeric.h"
#include "nodegraph/NodeGraphOpOutput.h"
#include "nodegraph/NodeGraphOpSource.h"
#include "nodegraph/core/NodeGraphGroup.h"
#include "nodegraph/operations/NodeGraphOpEffect.h"
#include "nodegraph/operations/NodeGraphOpFilter.h"
#include "nodegraph/operations/NodeGraphOpInput.h"
#include "nodegraph/operations/NodeGraphOpLogic.h"
#include "nodegraph/operations/NodeGraphOpNumeric.h"
#include "nodegraph/operations/NodeGraphOpOutput.h"
#include "nodegraph/operations/NodeGraphOpSource.h"
#include "nodegraph/operations/NodeGraphOpSignal.h"

#include "hid/Midi.h"

Expand Down Expand Up @@ -45,11 +46,6 @@ namespace l::nodegraph {
RegisterNodeType("Source", 2, "Value [0,100]");
RegisterNodeType("Source", 3, "Value [-inf,inf]");
RegisterNodeType("Source", 4, "Time");
RegisterNodeType("Source", 5, "Sine");
RegisterNodeType("Source", 6, "Sine FM 1");
RegisterNodeType("Source", 7, "Sine FM 2");
RegisterNodeType("Source", 8, "Sine FM 3");
RegisterNodeType("Source", 9, "Saw");
RegisterNodeType("Numeric", 50, "Add");
RegisterNodeType("Numeric", 51, "Subtract");
RegisterNodeType("Numeric", 52, "Negate");
Expand All @@ -62,6 +58,7 @@ namespace l::nodegraph {
RegisterNodeType("Logic", 101, "Or");
RegisterNodeType("Logic", 102, "Xor");
RegisterNodeType("Filter", 150, "Lowpass");
RegisterNodeType("Filter", 151, "Highpass");
RegisterNodeType("Output", 200, "Debug");
RegisterNodeType("Output", 201, "Speaker");
RegisterNodeType("Output", 202, "Plot");
Expand All @@ -81,6 +78,13 @@ namespace l::nodegraph {
RegisterNodeType("Input", 305, "Midi Button Group 3");
RegisterNodeType("Input", 306, "Midi Button Group 4");
RegisterNodeType("Input", 307, "Midi Button Group 5");
RegisterNodeType("Signal", 350, "Sine");
RegisterNodeType("Signal", 351, "Sine FM 1");
RegisterNodeType("Signal", 352, "Sine FM 2");
RegisterNodeType("Signal", 353, "Sine FM 3");
RegisterNodeType("Signal", 354, "Saw");
RegisterNodeType("Signal", 355, "Sine 2");

}

~NodeGraphSchema() = default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,117 +11,22 @@

#include "math/MathConstants.h"

#include "nodegraph/core/NodeGraphInput.h"
#include "nodegraph/core/NodeGraphOutput.h"

namespace l::nodegraph {

int32_t CreateUniqueId();
bool IsValidInOutNum(int8_t inoutNum, size_t inoutSize);

enum class DataType {
FLOAT32,
INT32,
BITFIELD32
};

enum class InputType {
INPUT_EMPTY,
INPUT_NODE,
INPUT_CONSTANT,
INPUT_VALUE,
INPUT_ARRAY
};

enum class InputBound {
INPUT_DONTCHANGE,
INPUT_UNBOUNDED,
INPUT_0_TO_1,
INPUT_0_TO_2,
INPUT_NEG_1_POS_1,
INPUT_0_100,
INPUT_CUSTOM,
};

enum class OutputType {
Default, // node will be processed if it is connected to the groups output by some route
ExternalOutput, // node does not have meaningful output for other nodes but should still be processed (ex speaker output only has input)
ExternalVisualOutput,
};

bool IsValidInOutNum(int8_t inoutNum, size_t inoutSize);

class NodeGraphOutput {
public:
NodeGraphOutput() = default;

float mOutput = 0.0f;
std::unique_ptr<std::vector<float>> mOutputBuf = nullptr;
std::unique_ptr<std::string> mName = nullptr;
bool mOutputPolled = false;

float& GetOutput(int32_t size = 1) {
if (!mOutputBuf) {
if (size <= 1) {
mOutputPolled = true;
return mOutput;
}
else {
mOutputBuf = std::make_unique<std::vector<float>>();
}
}
if (static_cast<int32_t>(mOutputBuf->size()) < size) {
mOutputBuf->resize(size);
}
mOutputPolled = true;
return *mOutputBuf->data();
}

int32_t GetOutputSize() {
if (!mOutputBuf) {
return 1;
}
else {
return static_cast<int32_t>(mOutputBuf->size());
}
}

bool IsOutputPolled() {
return mOutputPolled;
}

void ResetOutputPollState() {
mOutputPolled = false;
}
};

class NodeGraphBase;
class NodeGraphGroup;

union Input {
NodeGraphBase* mInputNode = nullptr;
float* mInputFloat;
float mInputFloatConstant;
int32_t* mInputInt;
int32_t mInputIntConstant;
};

struct NodeGraphInput {
Input mInput;
InputType mInputType = InputType::INPUT_EMPTY;

float mBoundMin = -l::math::constants::FLTMAX;
float mBoundMax = l::math::constants::FLTMAX;
InputBound mInputBound = InputBound::INPUT_UNBOUNDED;

int8_t mInputFromOutputChannel = 0;
std::unique_ptr<std::string> mName;

// hack to get input buffers working
std::unique_ptr<std::vector<float>> mInputBuf = nullptr;

void Reset();
bool HasInputNode();
float Get();
float& Get(int32_t numSamples);
};

class NodeGraphBase {
public:
NodeGraphBase(OutputType outputType) : mId(CreateUniqueId()), mOutputType(outputType) {
Expand Down Expand Up @@ -232,16 +137,6 @@ namespace l::nodegraph {
int8_t mNumConstants = 0;
};

class GraphDataCopy : public NodeGraphOp {
public:
GraphDataCopy(NodeGraphBase* node) :
NodeGraphOp(node, 0)
{}
virtual ~GraphDataCopy() = default;

void Process(int32_t numSamples, std::vector<NodeGraphInput>& inputs, std::vector<NodeGraphOutput>& outputs) override;
};

template<class T, class... Params>
class NodeGraph : public NodeGraphBase {
public:
Expand Down Expand Up @@ -332,67 +227,5 @@ namespace l::nodegraph {
T mOperation;
};

class NodeGraphGroup {
public:
NodeGraphGroup() :
mInputNode(OutputType::Default),
mOutputNode(OutputType::Default)
{
SetNumInputs(1);
SetNumOutputs(1);
mOutputNodes.push_back(&mOutputNode);
}
~NodeGraphGroup() {
LOG(LogInfo) << "Node group destroyed";
}

void SetNumInputs(int8_t numInputs);
void SetNumOutputs(int8_t outputCount);
void SetInput(int8_t inputChannel, NodeGraphBase& source, int8_t sourceOutputChannel);
void SetInput(int8_t inputChannel, NodeGraphGroup& source, int8_t sourceOutputChannel);
void SetInput(int8_t inputChannel, float constant);
void SetInput(int8_t inputChannel, float* floatPtr);

void SetOutput(int8_t outputChannel, NodeGraphBase& source, int8_t sourceOutputChannel);
void SetOutput(int8_t outputChannel, NodeGraphGroup& source, int8_t sourceOutputChannel);

float GetOutput(int8_t outputChannel);
NodeGraphBase& GetInputNode();
NodeGraphBase& GetOutputNode();

bool ContainsNode(int32_t id);
NodeGraphBase* GetNode(int32_t id);

template<class T, class U = void, class = std::enable_if_t<std::is_base_of_v<NodeGraphOp, T>>>
NodeGraph<T, U>* GetTypedNode(int32_t id) {
auto p = GetNode(id);
return reinterpret_cast<NodeGraph<T, U>*>(p);
}

bool RemoveNode(int32_t id);

template<class T, class = std::enable_if_t<std::is_base_of_v<NodeGraphOp, T>>, class... Params>
l::nodegraph::NodeGraphBase* NewNode(OutputType nodeType, Params&&... params) {
mNodes.push_back(std::make_unique<l::nodegraph::NodeGraph<T, Params...>>(nodeType, std::forward<Params>(params)...));
auto nodePtr = mNodes.back().get();
if (nodeType == OutputType::ExternalOutput || nodeType == OutputType::ExternalVisualOutput) {
mOutputNodes.push_back(nodePtr);
}
return nodePtr;
}

void ClearProcessFlags();
void ProcessSubGraph(int32_t numSamples, bool recomputeSubGraphCache = true);
void Tick(int32_t tickCount, float elapsed);
protected:
NodeGraph<GraphDataCopy> mInputNode;
NodeGraph<GraphDataCopy> mOutputNode;

std::vector<std::unique_ptr<NodeGraphBase>> mNodes;
std::vector<NodeGraphBase*> mOutputNodes;

int32_t mLastTickCount = 0;
};

}

91 changes: 91 additions & 0 deletions packages/nodegraph/include/nodegraph/core/NodeGraphGroup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#pragma once

#include "logging/LoggingAll.h"

#include <string>
#include <vector>
#include <map>
#include <typeinfo>
#include <type_traits>
#include <memory>

#include "math/MathConstants.h"

#include "nodegraph/core/NodeGraphBase.h"

namespace l::nodegraph {

class GraphDataCopy : public NodeGraphOp {
public:
GraphDataCopy(NodeGraphBase* node) :
NodeGraphOp(node, 0)
{}
virtual ~GraphDataCopy() = default;

void Process(int32_t numSamples, std::vector<NodeGraphInput>& inputs, std::vector<NodeGraphOutput>& outputs) override;
};

class NodeGraphGroup {
public:
NodeGraphGroup() :
mInputNode(OutputType::Default),
mOutputNode(OutputType::Default)
{
SetNumInputs(1);
SetNumOutputs(1);
mOutputNodes.push_back(&mOutputNode);
}
~NodeGraphGroup() {
LOG(LogInfo) << "Node group destroyed";
}

void SetNumInputs(int8_t numInputs);
void SetNumOutputs(int8_t outputCount);
void SetInput(int8_t inputChannel, NodeGraphBase& source, int8_t sourceOutputChannel);
void SetInput(int8_t inputChannel, NodeGraphGroup& source, int8_t sourceOutputChannel);
void SetInput(int8_t inputChannel, float constant);
void SetInput(int8_t inputChannel, float* floatPtr);

void SetOutput(int8_t outputChannel, NodeGraphBase& source, int8_t sourceOutputChannel);
void SetOutput(int8_t outputChannel, NodeGraphGroup& source, int8_t sourceOutputChannel);

float GetOutput(int8_t outputChannel);
NodeGraphBase& GetInputNode();
NodeGraphBase& GetOutputNode();

bool ContainsNode(int32_t id);
NodeGraphBase* GetNode(int32_t id);

template<class T, class U = void, class = std::enable_if_t<std::is_base_of_v<NodeGraphOp, T>>>
NodeGraph<T, U>* GetTypedNode(int32_t id) {
auto p = GetNode(id);
return reinterpret_cast<NodeGraph<T, U>*>(p);
}

bool RemoveNode(int32_t id);

template<class T, class = std::enable_if_t<std::is_base_of_v<NodeGraphOp, T>>, class... Params>
l::nodegraph::NodeGraphBase* NewNode(OutputType nodeType, Params&&... params) {
mNodes.push_back(std::make_unique<l::nodegraph::NodeGraph<T, Params...>>(nodeType, std::forward<Params>(params)...));
auto nodePtr = mNodes.back().get();
if (nodeType == OutputType::ExternalOutput || nodeType == OutputType::ExternalVisualOutput) {
mOutputNodes.push_back(nodePtr);
}
return nodePtr;
}

void ClearProcessFlags();
void ProcessSubGraph(int32_t numSamples, bool recomputeSubGraphCache = true);
void Tick(int32_t tickCount, float elapsed);
protected:
NodeGraph<GraphDataCopy> mInputNode;
NodeGraph<GraphDataCopy> mOutputNode;

std::vector<std::unique_ptr<NodeGraphBase>> mNodes;
std::vector<NodeGraphBase*> mOutputNodes;

int32_t mLastTickCount = 0;
};

}

Loading

0 comments on commit 4305a25

Please sign in to comment.