Skip to content

Commit 46cfc61

Browse files
committed
Fix arpeggio by adding input buffers. This will also enable buffering if necessary for batch processing. Fix a few math issues.
1 parent 0d335ef commit 46cfc61

File tree

10 files changed

+174
-103
lines changed

10 files changed

+174
-103
lines changed

packages/audio/include/audio/AudioUtils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
#include <functional>
44

55
namespace l::audio {
6-
extern const float gNoNote;
6+
extern const float gNoNote_f;
7+
extern const int32_t gNoNote;
78
float GetFrequencyFromNote(float note);
89
double GetPhaseModifier(double note, double modifier);
910
float GetRCAFactor(float numSamples, float limit = 0.01f);

packages/audio/source/common/AudioUtils.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
#include <math.h>
99

1010
namespace l::audio {
11-
const float gNoNote = -500.0f;
11+
const float gNoNote_f = -500.0f;
12+
const int32_t gNoNote = -500;
1213

1314
float GetFrequencyFromNote(float note) {
1415
return 440.0f * l::math::functions::pow(2.0f, (note - 49.0f) / 12.0f);

packages/math/include/math/MathFunc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
namespace l::math::functions {
1313

1414
template<class T>
15-
bool equal(T a, T b, T accuracy) {
15+
bool equal(T a, T b, T accuracy = static_cast<T>(0.0001)) {
1616
return abs(a - b) < accuracy;
1717
}
1818

packages/math/include/math/MathSmooth.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,41 +12,41 @@ namespace l::math::smooth {
1212
// Quintic Polynomial - C2 continuity
1313
template <class V>
1414
V smoothPolyC2(V x) {
15-
return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
15+
return x * x * x * (x * (x * static_cast<V>(6.0) - static_cast<V>(15.0)) + static_cast<V>(10.0));
1616
}
1717

1818
template <class V>
1919
V smoothPolyC2Grad(V x) {
20-
return 30.0 * x * x * (x * (x - 2.0) + 1.0);
20+
return static_cast<V>(30.0) * x * x * (x * (x - static_cast<V>(2.0)) + static_cast<V>(1.0));
2121
}
2222

2323
template <class V>
2424
V smoothPoly4(V x) {
2525
V x2 = x * x;
26-
return 4.0 * x2 * x - 3.0 * x2 * x2;
26+
return static_cast<V>(4.0) * x2 * x - static_cast<V>(3.0) * x2 * x2;
2727
}
2828

2929
template <class V>
3030
V smoothPoly4grad(V x) {
3131
V x2 = x * x;
32-
return 12.0 * x2 - 12.0 * x2 * x;
32+
return static_cast<V>(12.0) * x2 - static_cast<V>(12.0) * x2 * x;
3333
}
3434

3535
template <class V>
3636
V smootPolyh3(V x) {
3737
V x2 = x * x;
38-
return 3.0 * x2 - 2.0 * x2 * x;
38+
return static_cast<V>(3.0) * x2 - static_cast<V>(2.0) * x2 * x;
3939
}
4040

4141
template <class V>
4242
V smoothPoly3grad(V x) {
43-
return 6.0 * x - 6.0 * x * x;
43+
return static_cast<V>(6.0) * x - static_cast<V>(6.0) * x * x;
4444
}
4545

4646
template <class V>
4747
V smoothRationalC2(V x)
4848
{
49-
return x * x * x / (3.0 * x * x - 3.0 * x + 1.0);
49+
return x * x * x / (static_cast<V>(3.0) * x * x - static_cast<V>(3.0) * x + static_cast<V>(1.0));
5050
}
5151

5252
}

packages/nodegraph/include/nodegraph/NodeGraph.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace l::nodegraph {
2626
INPUT_NODE,
2727
INPUT_CONSTANT,
2828
INPUT_VALUE,
29-
//INPUT_ARRAY // TODO: is it possible to process batches for example for audio processing?
29+
INPUT_ARRAY
3030
};
3131

3232
enum class InputBound {
@@ -55,18 +55,18 @@ namespace l::nodegraph {
5555
std::unique_ptr<std::string> mName = nullptr;
5656
bool mOutputPolled = false;
5757

58-
float& GetOutput(int32_t numSamples = 1) {
58+
float& GetOutput(int32_t size = 1) {
5959
if (!mOutputBuf) {
60-
if (numSamples <= 1) {
60+
if (size <= 1) {
6161
mOutputPolled = true;
6262
return mOutput;
6363
}
6464
else {
6565
mOutputBuf = std::make_unique<std::vector<float>>();
6666
}
6767
}
68-
if (static_cast<int32_t>(mOutputBuf->size()) < numSamples) {
69-
mOutputBuf->resize(numSamples);
68+
if (static_cast<int32_t>(mOutputBuf->size()) < size) {
69+
mOutputBuf->resize(size);
7070
}
7171
mOutputPolled = true;
7272
return *mOutputBuf->data();
@@ -111,9 +111,10 @@ namespace l::nodegraph {
111111

112112
int8_t mInputFromOutputChannel = 0;
113113
std::unique_ptr<std::string> mName;
114+
std::unique_ptr<std::vector<float>> mInputBuf = nullptr;
114115

115116
void Reset();
116-
bool HasInput();
117+
bool HasInputNode();
117118
float Get();
118119
float& Get(int32_t numSamples);
119120
};
@@ -144,8 +145,9 @@ namespace l::nodegraph {
144145
virtual int8_t GetNumOutputs();
145146
virtual int8_t GetNumConstants();
146147

147-
virtual float& GetOutput(int8_t outputChannel, int32_t numSamples = 1);
148+
virtual float& GetOutput(int8_t outputChannel, int32_t size = 1);
148149
virtual float GetInput(int8_t inputChannel);
150+
virtual float& GetInput(int8_t inputChannel, int32_t size);
149151

150152
virtual int32_t GetOutputSize(int8_t outputChannel);
151153

@@ -159,7 +161,7 @@ namespace l::nodegraph {
159161

160162
virtual bool SetInput(int8_t inputChannel, NodeGraphBase& source, int8_t sourceOutputChannel);
161163
virtual bool SetInput(int8_t inputChannel, NodeGraphGroup& source, int8_t sourceOutputChannel);
162-
virtual bool SetInput(int8_t inputChannel, float constant);
164+
virtual bool SetInput(int8_t inputChannel, float constant, int32_t size = -1);
163165
virtual bool SetInput(int8_t inputChannel, float* floatPtr);
164166

165167
virtual bool SetInputBound(int8_t inputChannel, InputBound bound = InputBound::INPUT_DONTCHANGE, float boundMin = 0.0f, float boundMax = 0.0f);

packages/nodegraph/include/nodegraph/NodeGraphOpEffect.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ namespace l::nodegraph {
244244
/*********************************************************************/
245245
class GraphEffectTranceGate : public NodeGraphOp {
246246
public:
247-
std::string defaultInStrings[6] = { "In 1", "In 2", "Bpm", "Fmod", "Attack", "Pattern" };
247+
std::string defaultInStrings[7] = { "In 1", "In 2", "Bpm", "Fmod", "Attack", "Pattern", "Drift Sync"};
248248
std::string defaultOutStrings[3] = { "Out 1", "Out 2" };
249249

250250
const std::vector< std::vector<float>> patterns = {
@@ -261,7 +261,7 @@ namespace l::nodegraph {
261261
};
262262

263263
GraphEffectTranceGate(NodeGraphBase* node) :
264-
NodeGraphOp(node, 6, 2, 0)
264+
NodeGraphOp(node, 7, 2, 0)
265265
{}
266266

267267
virtual ~GraphEffectTranceGate() = default;
@@ -295,11 +295,11 @@ namespace l::nodegraph {
295295
/*********************************************************************/
296296
class GraphEffectArpeggio: public NodeGraphOp {
297297
public:
298-
std::string defaultInStrings[6] = { "Note On Id", "Note Off Id", "Velocity", "Bpm", "Fmod", "Attack"};
298+
std::string defaultInStrings[7] = { "Note On Id", "Note Off Id", "Velocity", "Bpm", "Fmod", "Attack", "Drift Sync"};
299299
std::string defaultOutStrings[3] = { "Freq", "Volume" };
300300

301301
GraphEffectArpeggio(NodeGraphBase* node) :
302-
NodeGraphOp(node, 6, 2, 0)
302+
NodeGraphOp(node, 7, 2, 0)
303303
{}
304304

305305
virtual ~GraphEffectArpeggio() = default;
@@ -328,11 +328,8 @@ namespace l::nodegraph {
328328
float mGainSmoothing = 0.01f;
329329
float mGainSmoothingNeg = 0.01f;
330330

331-
float mNoteOnId = l::audio::gNoNote;
332-
float mNoteOffId = l::audio::gNoNote;
333-
334331
float mCurrentNoteFreq = 0.0f;
335-
std::vector<float> mNotes;
332+
std::vector<int32_t> mNotes;
336333
int32_t mNoteIndex = 0;
337334
};
338335
}

packages/nodegraph/source/common/NodeGraph.cpp

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ namespace l::nodegraph {
9191
mLastTickCount = tickCount;
9292
}
9393

94-
float& NodeGraphBase::GetOutput(int8_t outputChannel, int32_t numSamples) {
95-
return mOutputs.at(outputChannel).GetOutput(numSamples);
94+
float& NodeGraphBase::GetOutput(int8_t outputChannel, int32_t size) {
95+
return mOutputs.at(outputChannel).GetOutput(size);
9696
}
9797

9898
int32_t NodeGraphBase::GetOutputSize(int8_t outputChannel) {
@@ -103,13 +103,17 @@ namespace l::nodegraph {
103103
return mInputs.at(inputChannel).Get();
104104
}
105105

106+
float& NodeGraphBase::GetInput(int8_t inputChannel, int32_t size) {
107+
return mInputs.at(inputChannel).Get(size);
108+
}
109+
106110
bool NodeGraphBase::ClearInput(int8_t inputChannel) {
107111
ASSERT(inputChannel >= 0 && static_cast<size_t>(inputChannel) < mInputs.size());
108112
if (!IsValidInOutNum(inputChannel, mInputs.size())) {
109113
return false;
110114
}
111115
auto& input = mInputs.at(inputChannel);
112-
if (!input.HasInput()) {
116+
if (!input.HasInputNode()) {
113117
return false;
114118
}
115119
input.mInputType = InputType::INPUT_EMPTY;
@@ -126,7 +130,7 @@ namespace l::nodegraph {
126130
auto& input = mInputs.at(inputChannel);
127131
if (!IsValidInOutNum(sourceOutputChannel, source.mOutputs.size()) ||
128132
!IsValidInOutNum(inputChannel, mInputs.size()) ||
129-
input.HasInput()) {
133+
input.HasInputNode()) {
130134
return false;
131135
}
132136
input.mInput.mInputNode = &source;
@@ -144,7 +148,7 @@ namespace l::nodegraph {
144148
if (source.ContainsNode(GetId())) {
145149
if (!IsValidInOutNum(sourceChannel, source.GetInputNode().GetNumOutputs()) ||
146150
!IsValidInOutNum(inputChannel, mInputs.size()) ||
147-
input.HasInput()) {
151+
input.HasInputNode()) {
148152
return false;
149153
}
150154
input.mInput.mInputNode = &source.GetInputNode();
@@ -153,7 +157,7 @@ namespace l::nodegraph {
153157
else {
154158
if (!IsValidInOutNum(sourceChannel, source.GetOutputNode().GetNumOutputs()) ||
155159
!IsValidInOutNum(inputChannel, mInputs.size()) ||
156-
input.HasInput()) {
160+
input.HasInputNode()) {
157161
return false;
158162
}
159163
input.mInput.mInputNode = &source.GetOutputNode();
@@ -163,15 +167,25 @@ namespace l::nodegraph {
163167
return true;
164168
}
165169

166-
bool NodeGraphBase::SetInput(int8_t inputChannel, float constant) {
170+
bool NodeGraphBase::SetInput(int8_t inputChannel, float constant, int32_t size) {
167171
ASSERT(inputChannel >= 0 && static_cast<size_t>(inputChannel) < mInputs.size());
168172
if (!IsValidInOutNum(inputChannel, mInputs.size())) {
169173
return false;
170174
}
171175
auto& input = mInputs.at(inputChannel);
172-
input.mInput.mInputFloatConstant = constant;
173-
input.mInputType = InputType::INPUT_CONSTANT;
174-
input.mInputFromOutputChannel = 0;
176+
if (size <= 0) {
177+
input.mInput.mInputFloatConstant = constant;
178+
input.mInputType = InputType::INPUT_CONSTANT;
179+
input.mInputFromOutputChannel = 0;
180+
}
181+
else {
182+
input.mInputType = InputType::INPUT_ARRAY;
183+
input.mInputFromOutputChannel = 0;
184+
auto inputBuf = &input.Get(size);
185+
for (int32_t i = 0; i < size; i++) {
186+
*inputBuf++ = constant;
187+
}
188+
}
175189

176190
return true;
177191
}
@@ -346,19 +360,9 @@ namespace l::nodegraph {
346360
}
347361
}
348362

349-
bool NodeGraphInput::HasInput() {
350-
switch (mInputType) {
351-
case InputType::INPUT_NODE:
352-
if (mInput.mInputNode != nullptr) {
353-
return true;
354-
}
355-
break;
356-
case InputType::INPUT_CONSTANT:
357-
break;
358-
case InputType::INPUT_VALUE:
359-
return mInput.mInputFloat != nullptr;
360-
case InputType::INPUT_EMPTY:
361-
break;
363+
bool NodeGraphInput::HasInputNode() {
364+
if (mInputType == InputType::INPUT_NODE) {
365+
return true;
362366
}
363367
return false;
364368
}
@@ -374,6 +378,8 @@ namespace l::nodegraph {
374378
case InputType::INPUT_CONSTANT:
375379
value = mInput.mInputFloatConstant;
376380
break;
381+
case InputType::INPUT_ARRAY:
382+
return *mInputBuf->data();
377383
case InputType::INPUT_VALUE:
378384
value = *mInput.mInputFloat;
379385
break;
@@ -383,13 +389,21 @@ namespace l::nodegraph {
383389
return l::math::functions::clamp(value, mBoundMin, mBoundMax);
384390
}
385391

386-
float& NodeGraphInput::Get(int32_t numSamples) {
392+
float& NodeGraphInput::Get(int32_t size) {
387393
switch (mInputType) {
388394
case InputType::INPUT_NODE:
389395
if (mInput.mInputNode != nullptr) {
390-
return mInput.mInputNode->GetOutput(mInputFromOutputChannel, numSamples);
396+
return mInput.mInputNode->GetOutput(mInputFromOutputChannel, size);
391397
}
392398
break;
399+
case InputType::INPUT_ARRAY:
400+
if (!mInputBuf) {
401+
mInputBuf = std::make_unique<std::vector<float>>();
402+
}
403+
if (static_cast<int32_t>(mInputBuf->size()) < size) {
404+
mInputBuf->resize(size);
405+
}
406+
return *mInputBuf->data();
393407
case InputType::INPUT_CONSTANT:
394408
return mInput.mInputFloatConstant;
395409
case InputType::INPUT_VALUE:

0 commit comments

Comments
 (0)