Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Introduce the concept of a BufferPool. Refactor dsp tree construction…

… to take advantage of the buffer pool. Test the concept of per-DspObject data.

per-DspObject data concept needs to be tested more. Is it really faster
than the usual DspObject list?
  • Loading branch information...
commit 01b7ca6bef89fe6ca3f70a62ec7bc1ed26323986 1 parent b848dc2
@mhroth authored
View
10 Xcode/ZenGarden.xcodeproj/project.pbxproj
@@ -666,6 +666,9 @@
90D0312C1204866300FEE5BB /* MessageListSplit.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D031281204866300FEE5BB /* MessageListSplit.h */; };
90D0312D1204866300FEE5BB /* MessageListSplit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D031291204866300FEE5BB /* MessageListSplit.cpp */; };
90D0312E1204866300FEE5BB /* MessageListSplit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D031291204866300FEE5BB /* MessageListSplit.cpp */; };
+ 90D4564D1516A26A00ED6B05 /* BufferPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D4564C1516A26A00ED6B05 /* BufferPool.cpp */; };
+ 90D4564E1516A26A00ED6B05 /* BufferPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D4564C1516A26A00ED6B05 /* BufferPool.cpp */; };
+ 90D4564F1516A26A00ED6B05 /* BufferPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D4564C1516A26A00ED6B05 /* BufferPool.cpp */; };
90D76584120A208B0047C019 /* DeclareList.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D76583120A208B0047C019 /* DeclareList.h */; };
90D76585120A208B0047C019 /* DeclareList.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D76583120A208B0047C019 /* DeclareList.h */; };
90DA52A2120A1F2100D00917 /* DeclareList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90DA52A1120A1F2100D00917 /* DeclareList.cpp */; };
@@ -990,6 +993,8 @@
90CCEBE21299CD7D009D36DF /* DspReciprocalSqrt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DspReciprocalSqrt.cpp; path = ../src/DspReciprocalSqrt.cpp; sourceTree = SOURCE_ROOT; };
90D031281204866300FEE5BB /* MessageListSplit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MessageListSplit.h; path = ../src/MessageListSplit.h; sourceTree = SOURCE_ROOT; };
90D031291204866300FEE5BB /* MessageListSplit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MessageListSplit.cpp; path = ../src/MessageListSplit.cpp; sourceTree = SOURCE_ROOT; };
+ 90D4564C1516A26A00ED6B05 /* BufferPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BufferPool.cpp; path = ../src/BufferPool.cpp; sourceTree = "<group>"; };
+ 90D456501516A28A00ED6B05 /* BufferPool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BufferPool.h; path = ../src/BufferPool.h; sourceTree = "<group>"; };
90D76583120A208B0047C019 /* DeclareList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DeclareList.h; path = ../src/DeclareList.h; sourceTree = SOURCE_ROOT; };
90DA52A1120A1F2100D00917 /* DeclareList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DeclareList.cpp; path = ../src/DeclareList.cpp; sourceTree = SOURCE_ROOT; };
90DC264E13A003EF000954D7 /* MessageCputime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MessageCputime.cpp; path = ../src/MessageCputime.cpp; sourceTree = "<group>"; };
@@ -1057,6 +1062,8 @@
isa = PBXGroup;
children = (
90337B4A11D0D847009FCC01 /* ArrayArithmetic.h */,
+ 90D4564C1516A26A00ED6B05 /* BufferPool.cpp */,
+ 90D456501516A28A00ED6B05 /* BufferPool.h */,
90337B4B11D0D847009FCC01 /* ConnectionType.h */,
90DA52A1120A1F2100D00917 /* DeclareList.cpp */,
90D76583120A208B0047C019 /* DeclareList.h */,
@@ -1900,6 +1907,7 @@
90F3D68813F82F5F0058E68D /* ObjectFactoryMap.cpp in Sources */,
90A42CC0143E68BB00DBF988 /* DspFilter.cpp in Sources */,
90119EF61500DB0700A9AB46 /* DspImplicitAdd.cpp in Sources */,
+ 90D4564D1516A26A00ED6B05 /* BufferPool.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2043,6 +2051,7 @@
90F3D68913F82F5F0058E68D /* ObjectFactoryMap.cpp in Sources */,
90A42CC1143E68BB00DBF988 /* DspFilter.cpp in Sources */,
90119EF71500DB0700A9AB46 /* DspImplicitAdd.cpp in Sources */,
+ 90D4564E1516A26A00ED6B05 /* BufferPool.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2186,6 +2195,7 @@
90F3D68A13F82F5F0058E68D /* ObjectFactoryMap.cpp in Sources */,
90A42CC2143E68BB00DBF988 /* DspFilter.cpp in Sources */,
90119EF81500DB0700A9AB46 /* DspImplicitAdd.cpp in Sources */,
+ 90D4564F1516A26A00ED6B05 /* BufferPool.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
79 src/BufferPool.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2012 Reality Jockey, Ltd.
+ * info@rjdj.me
+ * http://rjdj.me/
+ *
+ * This file is part of ZenGarden.
+ *
+ * ZenGarden is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ZenGarden is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ZenGarden. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "BufferPool.h"
+
+BufferPool::BufferPool(unsigned short size) {
+ bufferSize = size;
+}
+
+BufferPool::~BufferPool() {
+ // free all buffers, reserved and available
+ for (list<std::pair<float *, unsigned int> >::iterator it = reserved.begin(); it != reserved.end(); ++it) {
+ free((*it).first);
+ }
+ while (!pool.empty()) {
+ free(pool.top());
+ pool.pop();
+ }
+}
+
+float *BufferPool::getBuffer(unsigned int numDependencies) {
+ float *buffer = NULL;
+ if (pool.size() > 0) {
+ buffer = pool.top();
+ pool.pop();
+ } else {
+ buffer = (float *) valloc(bufferSize * sizeof(float));
+ }
+ reserved.push_back(std::pair<float *, unsigned int>(buffer, numDependencies));
+ printf("%i/%i buffer used.\n", getNumReservedBuffers(), getNumTotalBuffers());
+ return buffer;
+}
+
+void BufferPool::releaseBuffer(float *buffer) {
+ for (list<std::pair<float *, unsigned int> >::iterator it = reserved.begin(); it != reserved.end(); ++it) {
+ if ((*it).first == buffer) {
+ --((*it).second);
+ if ((*it).second == 0) {
+ reserved.erase(it);
+ pool.push(buffer);
+ printf("%i/%i buffer used.\n", getNumReservedBuffers(), getNumTotalBuffers());
+ break;
+ }
+ }
+ }
+}
+
+void BufferPool::resizeBuffers(unsigned int newBufferSize) {
+ for (list<std::pair<float *, unsigned int> >::iterator it = reserved.begin(); it != reserved.end(); ++it) {
+ float *buffer = (*it).first;
+ float *newBuffer = (float *) realloc(buffer, newBufferSize * sizeof(float));
+ if (newBuffer != buffer) { // buffer should start at same address so that it is still 16-byte aligned
+ free(buffer);
+ free(newBuffer);
+ (*it).first = (float *) valloc(newBufferSize * sizeof(float));
+ }
+ }
+
+ // TODO(mhroth): resize all buffers in pool
+}
View
61 src/BufferPool.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2012 Reality Jockey, Ltd.
+ * info@rjdj.me
+ * http://rjdj.me/
+ *
+ * This file is part of ZenGarden.
+ *
+ * ZenGarden is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ZenGarden is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ZenGarden. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef _BUFFER_POOL_
+#define _BUFFER_POOL_
+
+#include <list>
+#include <stack>
+using namespace std;
+
+class BufferPool {
+ public:
+ BufferPool(unsigned short bufferSize);
+ ~BufferPool();
+
+ /**
+ * If a buffer is available, it is reserved with a number of dependencies. Otherwise a new
+ * buffer is created.
+ */
+ float *getBuffer(unsigned int numDependencies);
+
+ /** The buffer is released, possibly made available for other objects. */
+ void releaseBuffer(float *buffer);
+
+ /** Resizes all buffers in the pool (reserved and available). */
+ void resizeBuffers(unsigned int newBufferSize);
+
+ unsigned int getNumReservedBuffers() { return reserved.size(); }
+ unsigned int getNumAvailableBuffers() { return pool.size(); }
+ unsigned int getNumTotalBuffers() { return (pool.size() + reserved.size()); }
+
+ private:
+ /** A pool of reserved buffers, paired with the number of outstanding dependencies. */
+ list<std::pair<float *, unsigned int> > reserved;
+
+ /** A pool of available buffers. */
+ stack<float *> pool;
+
+ unsigned short bufferSize;
+};
+
+#endif // _BUFFER_POOL_
View
47 src/DspAdd.cpp
@@ -64,23 +64,42 @@ void DspAdd::processMessage(int inletIndex, PdMessage *message) {
}
}
-void DspAdd::processDsp() {
- switch (codepath) {
- case DSP_ADD_DSP_DSP: {
- ArrayArithmetic::add(dspBufferAtInlet[0], dspBufferAtInlet[1], dspBufferAtOutlet[0], 0, blockSizeInt);
- break;
- }
- case DSP_OBJECT_PROCESS_NO_MESSAGE: {
- ArrayArithmetic::add(dspBufferAtInlet[0], constant, dspBufferAtOutlet[0], 0, blockSizeInt);
- break;
- }
- default: {
- DspObject::processDsp();
- break;
- }
+DspData *DspAdd::getProcessData() {
+ DspAddData *data = new DspAddData();
+ if (codepath == DSP_ADD_DSP_DSP) {
+ data->processDsp = &DspAdd::processSignal;
+ data->dspInletBuffer0 = dspBufferAtInlet[0];
+ data->dspInletBuffer1 = dspBufferAtInlet[1];
+ data->dspOutletBuffer0 = dspBufferAtOutlet[0];
+ data->fromIndex = 0;
+ data->toIndex = blockSizeInt;
+ } else {
+ data->processDsp = &DspAdd::processScalar;
+ data->dspInletBuffer0 = dspBufferAtInlet[0];
+ data->dspInletBuffer1 = NULL;
+ data->dspOutletBuffer0 = dspBufferAtOutlet[0];
+ data->fromIndex = 0;
+ data->toIndex = blockSizeInt;
+ data->constant = constant;
}
+ return data;
}
+void DspAdd::processSignal(DspData *data) {
+ DspAddData *d = reinterpret_cast<DspAddData *>(data);
+ ArrayArithmetic::add(d->dspInletBuffer0, d->dspInletBuffer1, d->dspOutletBuffer0, d->fromIndex, d->toIndex);
+}
+
+void DspAdd::processScalar(DspData *data) {
+ DspAddData *d = reinterpret_cast<DspAddData *>(data);
+ ArrayArithmetic::add(d->dspInletBuffer0, d->constant, d->dspOutletBuffer0, d->fromIndex, d->toIndex);
+}
+
+//void DspAdd::processMessage(DspData *data) {
+// DspAddData *d = reinterpret_cast<DspAddData *>(data);
+// d->dspObject->processDsp();
+//}
+
void DspAdd::processDspWithIndex(int fromIndex, int toIndex) {
ArrayArithmetic::add(dspBufferAtInlet[0], constant, dspBufferAtOutlet[0], fromIndex, toIndex);
}
View
14 src/DspAdd.h
@@ -29,6 +29,16 @@ enum DspAddCodePath {
DSP_ADD_DSP_DSP = DSP_OBJECT_PROCESS_OTHER
};
+class DspAddData : public DspData {
+ public:
+ float *dspInletBuffer0;
+ float *dspInletBuffer1;
+ float *dspOutletBuffer0;
+ short fromIndex;
+ short toIndex;
+ float constant;
+};
+
/** [+~], [+~ float] */
class DspAdd : public DspObject {
@@ -42,7 +52,9 @@ class DspAdd : public DspObject {
void onInletConnectionUpdate(unsigned int inletIndex);
- void processDsp();
+ DspData *getProcessData();
+ static void processSignal(DspData *data);
+ static void processScalar(DspData *data);
private:
void processMessage(int inletIndex, PdMessage *message);
View
12 src/DspDac.cpp
@@ -36,6 +36,18 @@ DspDac::~DspDac() {
// nothing to do
}
+DspData *DspDac::getProcessData() {
+ DspDacData *data = new DspDacData();
+ data->processDsp = &DspDac::processDsp;
+ data->dspObject = this;
+ return data;
+}
+
+void DspDac::processDsp(DspData *data) {
+ DspDacData *d = reinterpret_cast<DspDacData *>(data);
+ d->dspObject->processDsp();
+}
+
void DspDac::processDsp() {
switch (incomingDspConnections.size()) {
default: {
View
10 src/DspDac.h
@@ -25,6 +25,12 @@
#include "DspObject.h"
+class DspDac;
+class DspDacData : public DspData {
+ public:
+ DspDac *dspObject;
+};
+
class DspDac : public DspObject {
public:
@@ -35,7 +41,11 @@ class DspDac : public DspObject {
static const char *getObjectLabel() { return "dac~"; }
string toString() { return string(DspDac::getObjectLabel()); }
+ DspData *getProcessData();
+ static void processDsp(DspData *data);
+
void processDsp();
+ static void processDsp(DspDacData *data);
};
#endif // _DSP_DAC_H_
View
15 src/DspImplicitAdd.cpp
@@ -35,12 +35,19 @@ DspImplicitAdd::~DspImplicitAdd() {
// nothing to do
}
-const char *DspImplicitAdd::getObjectLabel() {
- return "+~~";
+DspData *DspImplicitAdd::getProcessData() {
+ DspImplicitAddData *data = new DspImplicitAddData();
+ data->processDsp = &DspImplicitAdd::processSignal;
+ data->dspInletBuffer0 = dspBufferAtInlet[0];
+ data->dspInletBuffer1 = dspBufferAtInlet[1];
+ data->dspOutletBuffer0 = dspBufferAtOutlet[0];
+ data->blockSize = blockSizeInt;
+ return data;
}
-string DspImplicitAdd::toString() {
- return string(getObjectLabel());
+void DspImplicitAdd::processSignal(DspData *data) {
+ DspImplicitAddData *d = reinterpret_cast<DspImplicitAddData *>(data);
+ ArrayArithmetic::add(d->dspInletBuffer0, d->dspInletBuffer1, d->dspOutletBuffer0, 0, d->blockSize);
}
void DspImplicitAdd::setDspBufferAtInletWithReuse(float *buffer, unsigned int inletIndex, bool mayReuse) {
View
15 src/DspImplicitAdd.h
@@ -25,6 +25,14 @@
#include "DspObject.h"
+class DspImplicitAddData : public DspData {
+ public:
+ float *dspInletBuffer0;
+ float *dspInletBuffer1;
+ float *dspOutletBuffer0;
+ unsigned short blockSize;
+};
+
/**
* This object is a stripped down version of DspAdd used soley for the purposes of summing two
* DSP vectors together as a a part of the implicit add step.
@@ -36,8 +44,11 @@ class DspImplicitAdd : public DspObject {
DspImplicitAdd(PdMessage *initMessage, PdGraph *graph);
~DspImplicitAdd();
- static const char *getObjectLabel();
- string toString();
+ static const char *getObjectLabel() { return "+~~"; }
+ string toString() { return string(getObjectLabel()); }
+
+ DspData *getProcessData();
+ static void processSignal(DspData *data);
void setDspBufferAtInletWithReuse(float *buffer, unsigned int inletIndex, bool mayReuse);
View
37 src/DspInlet.cpp
@@ -36,36 +36,22 @@ DspInlet::~DspInlet() {
// nothing to do
}
-const char *DspInlet::getObjectLabel() {
- return "inlet~";
-}
-
ObjectType DspInlet::getObjectType() {
return DSP_INLET;
}
-string DspInlet::toString() {
- return string(getObjectLabel());
-}
-
-list<MessageObject *> *DspInlet::getProcessOrder() {
- list<MessageObject *> *processOrder = new list<MessageObject *>();
- if (!isOrdered) {
- isOrdered = true;
- processOrder->push_back(this);
- }
- return processOrder;
+list<DspObject *> DspInlet::getProcessOrder() {
+ // inlet~ does not process audio, so it always returns an empty list
+ return list<DspObject *>();
}
-list<MessageObject *> *DspInlet::getProcessOrderFromInlet() {
- list<MessageObject *> *processList = new list<MessageObject *>();
- list<ObjectLetPair>::iterator it = incomingDspConnections[0].begin();
- list<ObjectLetPair>::iterator end = incomingDspConnections[0].end();
- while (it != end) {
- ObjectLetPair objectLetPair = *it++;
- list<MessageObject *> *parentProcessList = objectLetPair.first->getProcessOrder();
- processList->splice(processList->end(), *parentProcessList);
- delete parentProcessList;
+list<DspObject *> DspInlet::getProcessOrderFromInlet() {
+ list<DspObject *> processList;
+ for (list<ObjectLetPair>::iterator it = incomingDspConnections[0].begin();
+ it != incomingDspConnections[0].end(); ++it) {
+ ObjectLetPair objectLetPair = *it;
+ list<DspObject *> parentProcessList = objectLetPair.first->getProcessOrder();
+ processList.splice(processList.end(), parentProcessList);
}
return processList;
}
@@ -76,7 +62,6 @@ void DspInlet::onDspBufferAtInletUpdate(float *buffer, unsigned int inletIndex)
for (list<ObjectLetPair>::iterator it = dspConnections.begin(); it != dspConnections.end(); ++it) {
ObjectLetPair letPair = *it;
DspObject *dspObject = reinterpret_cast<DspObject *>(letPair.first);
- dspObject->setDspBufferAtInletWithReuse(dspBufferAtInlet[inletIndex], letPair.second,
- it == dspConnections.begin());
+ dspObject->setDspBufferAtInlet(dspBufferAtInlet[inletIndex], letPair.second);
}
}
View
8 src/DspInlet.h
@@ -39,12 +39,12 @@ class DspInlet : public DspObject {
DspInlet(PdGraph *graph);
~DspInlet();
- static const char *getObjectLabel();
- string toString();
+ static const char *getObjectLabel() { return "inlet~"; }
+ string toString() { return string(getObjectLabel()); }
ObjectType getObjectType();
- list<MessageObject *> *getProcessOrder();
- list<MessageObject *> *getProcessOrderFromInlet();
+ list<DspObject *> getProcessOrder();
+ list<DspObject *> getProcessOrderFromInlet();
// [inlet~] does nothing with audio
bool doesProcessAudio() { return false; }
View
39 src/DspMultiply.cpp
@@ -65,18 +65,35 @@ void DspMultiply::processMessage(int inletIndex, PdMessage *message) {
}
}
-void DspMultiply::processDsp() {
- switch (codepath) {
- case DSP_MULTIPLY_DSP_DSP: {
- ArrayArithmetic::multiply(dspBufferAtInlet[0], dspBufferAtInlet[1], dspBufferAtOutlet[0], 0, blockSizeInt);
- break;
- }
- case DSP_OBJECT_PROCESS_NO_MESSAGE: {
- ArrayArithmetic::multiply(dspBufferAtInlet[0], constant, dspBufferAtOutlet[0], 0, blockSizeInt);
- break;
- }
- default: DspObject::processDsp(); break;
+DspData *DspMultiply::getProcessData() {
+ DspMultiplyData *data = new DspMultiplyData();
+ if (codepath == DSP_MULTIPLY_DSP_DSP) {
+ data->processDsp = &DspMultiply::processSignal;
+ data->dspInletBuffer0 = dspBufferAtInlet[0];
+ data->dspInletBuffer1 = dspBufferAtInlet[1];
+ data->dspOutletBuffer0 = dspBufferAtOutlet[0];
+ data->fromIndex = 0;
+ data->toIndex = blockSizeInt;
+ } else {
+ data->processDsp = &DspMultiply::processScalar;
+ data->dspInletBuffer0 = dspBufferAtInlet[0];
+ data->dspInletBuffer1 = NULL;
+ data->dspOutletBuffer0 = dspBufferAtOutlet[0];
+ data->fromIndex = 0;
+ data->toIndex = blockSizeInt;
+ data->constant = constant;
}
+ return data;
+}
+
+void DspMultiply::processSignal(DspData *data) {
+ DspMultiplyData *d = reinterpret_cast<DspMultiplyData *>(data);
+ ArrayArithmetic::multiply(d->dspInletBuffer0, d->dspInletBuffer1, d->dspOutletBuffer0, 0, d->toIndex);
+}
+
+void DspMultiply::processScalar(DspData *data) {
+ DspMultiplyData *d = reinterpret_cast<DspMultiplyData *>(data);
+ ArrayArithmetic::multiply(d->dspInletBuffer0, d->constant, d->dspOutletBuffer0, d->fromIndex, d->toIndex);
}
void DspMultiply::processDspWithIndex(int fromIndex, int toIndex) {
View
14 src/DspMultiply.h
@@ -29,6 +29,16 @@ enum DspMultiplyCodePath {
DSP_MULTIPLY_DSP_DSP = DSP_OBJECT_PROCESS_OTHER
};
+class DspMultiplyData : public DspData {
+ public:
+ float *dspInletBuffer0;
+ float *dspInletBuffer1;
+ float *dspOutletBuffer0;
+ short fromIndex;
+ short toIndex;
+ float constant;
+};
+
class DspMultiply : public DspObject {
public:
@@ -39,7 +49,9 @@ class DspMultiply : public DspObject {
static const char *getObjectLabel();
string toString();
- void processDsp();
+ DspData *getProcessData();
+ static void processSignal(DspData *data);
+ static void processScalar(DspData *data);
private:
void processMessage(int inletIndex, PdMessage *message);
View
155 src/DspObject.cpp
@@ -21,6 +21,7 @@
*/
#include "ArrayArithmetic.h"
+#include "DspImplicitAdd.h"
#include "DspObject.h"
#include "PdGraph.h"
@@ -63,11 +64,7 @@ void DspObject::init(int numDspInlets, int numDspOutlets, int blockSize) {
dspBufferAtInlet = (numDspInlets > 0) ? (float **) calloc(numDspInlets, sizeof(float *)) : NULL;
// initialise the local output audio buffers
- dspBufferAtOutlet = (numDspOutlets > 0) ? (float **) calloc(numDspOutlets, sizeof(float)) : NULL;
- for (int i = 0; i < numDspOutlets; ++i) {
- dspBufferAtOutlet[i] = (float *) valloc(blockSizeInt * sizeof(float));
- memset(dspBufferAtOutlet[i], 0, blockSize * sizeof(float));
- }
+ dspBufferAtOutlet = (numDspOutlets > 0) ? (float **) calloc(numDspOutlets, sizeof(float *)) : NULL;
}
DspObject::~DspObject() {
@@ -80,13 +77,7 @@ DspObject::~DspObject() {
// delete any messages still pending
clearMessageQueue();
- // delete outlet buffers
- for (int i = 0; i < outgoingDspConnections.size(); i++) {
- if (i > 0 || (i == 0 && (incomingDspConnections.size() == 0 ||
- (incomingDspConnections.size() > 0 && dspBufferAtInlet[0] != dspBufferAtOutlet[0])))) {
- free(dspBufferAtOutlet[i]);
- }
- }
+ // inlet and outlet buffers are managed by the BufferPool
// free the inlet buffer index
free(dspBufferAtInlet);
@@ -192,44 +183,19 @@ void DspObject::removeConnectionToObjectFromOutlet(MessageObject *messageObject,
}
}
-void DspObject::setDspBufferAtInletWithReuse(float *buffer, unsigned int inletIndex, bool mayReuse) {
- // check to see if all outgoing connections are to the same object
- // if not, then the input buffer cannot be reused as an output buffer
- bool allConnectionsAreToSameObject = outgoingDspConnections.size() == 1 && outgoingDspConnections[0].size() > 0;
- if (allConnectionsAreToSameObject) {
- list<ObjectLetPair> connections = outgoingDspConnections[0];
- MessageObject *object = connections.front().first;
- for (list<ObjectLetPair>::iterator it = ++(connections.begin()); it != connections.end(); ++it) {
- if ((*it).first != object) {
- allConnectionsAreToSameObject = false;
- break;
- }
- }
- }
-
- // if it is possible to reuse the input buffer, do so
- if (inletIndex == 0 &&
- mayReuse && canReuseInputBuffer() &&
- allConnectionsAreToSameObject &&
- buffer != DspObject::zeroBuffer) { // don't overwrite the zero buffer
- // if the input and output buffers are not already the same, then free the output buffer
- if (dspBufferAtInlet[0] != dspBufferAtOutlet[0]) free(dspBufferAtOutlet[0]);
-
- dspBufferAtInlet[0] = buffer; // set the incoming buffer
- dspBufferAtOutlet[0] = buffer;
- } else {
- if (inletIndex == 0 &&
- outgoingDspConnections.size() > 0 &&
- dspBufferAtInlet[0] == dspBufferAtOutlet[0]) {
- dspBufferAtOutlet[0] = (float *) valloc(blockSizeInt * sizeof(float));
- }
- dspBufferAtInlet[inletIndex] = buffer; // set the incoming buffer
- }
+void DspObject::setDspBufferAtInlet(float *buffer, unsigned int inletIndex) {
+ dspBufferAtInlet[inletIndex] = buffer;
// if the object must take any special steps when updating the input buffer, do so now
onDspBufferAtInletUpdate(buffer, inletIndex);
}
+void DspObject::setDspBufferAtOutlet(float *buffer, unsigned int outletIndex) {
+ dspBufferAtOutlet[outletIndex] = buffer;
+
+ onDspBufferAtOutletUpdate(buffer, outletIndex);
+}
+
#pragma mark -
@@ -293,46 +259,99 @@ void DspObject::processDspWithIndex(int fromIndex, int toIndex) {
}
bool DspObject::isLeafNode() {
- if (!MessageObject::isLeafNode()) {
- return false;
- } else {
+ if (!MessageObject::isLeafNode()) return false;
+ else {
for (int i = 0; i < outgoingDspConnections.size(); i++) {
- if (outgoingDspConnections[i].size() > 0) {
- return false;
- }
+ if (outgoingDspConnections[i].size() > 0) return false;
}
return true;
}
}
-list<MessageObject *> *DspObject::getProcessOrder() {
+list<DspObject *> DspObject::getProcessOrder() {
if (isOrdered) {
// if this object has already been ordered, then move on
- return new list<MessageObject *>();
+ return list<DspObject *>();
} else {
isOrdered = true;
- list<MessageObject *> *processList = new list<MessageObject *>();
+ list<DspObject *> processList;
for (int i = 0; i < incomingMessageConnections.size(); i++) {
- list<ObjectLetPair>::iterator it = incomingMessageConnections[i].begin();
- list<ObjectLetPair>::iterator end = incomingMessageConnections[i].end();
- while (it != end) {
+ for (list<ObjectLetPair>::iterator it = incomingMessageConnections[i].begin();
+ it != incomingMessageConnections[i].end(); it++) {
ObjectLetPair objectLetPair = *it++;
- list<MessageObject *> *parentProcessList = objectLetPair.first->getProcessOrder();
- processList->splice(processList->end(), *parentProcessList);
- delete parentProcessList;
+ list<DspObject *> parentProcessList = objectLetPair.first->getProcessOrder();
+ // DspObjects "connected" through message connections must be processed, but buffers
+ // not otherwise calculated
+ processList.splice(processList.end(), parentProcessList);
}
}
+
+ BufferPool *bufferPool = graph->getBufferPool();
+ PdMessage *dspAddInitMessage = PD_MESSAGE_ON_STACK(1);
+ dspAddInitMessage->initWithTimestampAndFloat(0, 0.0f);
for (int i = 0; i < incomingDspConnections.size(); i++) {
- list<ObjectLetPair>::iterator it = incomingDspConnections[i].begin();
- list<ObjectLetPair>::iterator end = incomingDspConnections[i].end();
- while (it != end) {
- ObjectLetPair objectLetPair = *it++;
- list<MessageObject *> *parentProcessList = objectLetPair.first->getProcessOrder();
- processList->splice(processList->end(), *parentProcessList);
- delete parentProcessList;
+ switch (incomingDspConnections[i].size()) {
+ case 0: {
+ setDspBufferAtInlet(zeroBuffer, i);
+ break;
+ }
+ case 1: {
+ ObjectLetPair objectLetPair = incomingDspConnections[i].front();
+ list<DspObject *> parentProcessList = objectLetPair.first->getProcessOrder();
+
+ // configure the input buffers
+ DspObject *dspObject = reinterpret_cast<DspObject *>(objectLetPair.first);
+ float *buffer = dspObject->getDspBufferAtOutlet(objectLetPair.second);
+ setDspBufferAtInlet(buffer, i);
+ bufferPool->releaseBuffer(buffer);
+
+ // conbine the process lists
+ processList.splice(processList.end(), parentProcessList);
+ break;
+ }
+ default: { // > 1
+ list<ObjectLetPair>::iterator it = incomingDspConnections[i].begin();
+ ObjectLetPair leftOlPair = *it++;
+ list<DspObject *> parentProcessList = leftOlPair.first->getProcessOrder();
+ processList.splice(processList.end(), parentProcessList);
+
+ while (it != incomingDspConnections[i].end()) {
+ ObjectLetPair objectLetPair = *it++;
+ list<DspObject *> parentProcessList = objectLetPair.first->getProcessOrder();
+ processList.splice(processList.end(), parentProcessList);
+
+ DspImplicitAdd *dspAdd = new DspImplicitAdd(dspAddInitMessage, getGraph());
+ float *buffer = reinterpret_cast<DspObject *>(leftOlPair.first)->getDspBufferAtOutlet(leftOlPair.second);
+ dspAdd->setDspBufferAtInlet(buffer, 0);
+ bufferPool->releaseBuffer(buffer);
+
+ buffer = reinterpret_cast<DspObject *>(objectLetPair.first)->getDspBufferAtOutlet(objectLetPair.second);
+ dspAdd->setDspBufferAtInlet(buffer, 1);
+ bufferPool->releaseBuffer(buffer);
+
+ // assign the output buffer of the +~~
+ dspAdd->setDspBufferAtOutlet(bufferPool->getBuffer(1), 0);
+
+ processList.push_back(dspAdd);
+ leftOlPair = objectLetPair;
+ }
+
+ float *buffer = reinterpret_cast<DspObject *>(leftOlPair.first)->getDspBufferAtOutlet(leftOlPair.second);
+ setDspBufferAtInlet(buffer, i);
+ bufferPool->releaseBuffer(buffer);
+ break;
+ }
}
}
- processList->push_back(this);
+
+ for (int i = 0; i < getNumDspOutlets(); i++) {
+ float *buffer = bufferPool->getBuffer(outgoingDspConnections[i].size());
+ setDspBufferAtOutlet(buffer, i);
+ }
+
+ // NOTE(mhroth): even if an object does not process audio, its buffer still need to be connected.
+ // They may be passed on to other objects, such as s~/r~ pairs
+ if (doesProcessAudio()) processList.push_back(this);
return processList;
}
}
View
22 src/DspObject.h
@@ -35,6 +35,15 @@ enum DspObjectProcessMessage {
DSP_OBJECT_PROCESS_OTHER // some other process operation will take place
};
+class DspData {
+ public:
+ void (*processDsp)(DspData *);
+
+ DspData() {
+ processDsp = NULL;
+ }
+};
+
/**
* A <code>DspObject</code> is the abstract superclass of any object which processes audio.
* <code>DspObject</code> is a subclass of <code>MessageObject</code>, such that all of the former
@@ -78,12 +87,8 @@ class DspObject : public MessageObject {
*/
virtual bool mayReuseBuffer(DspObject *dspObject, unsigned int outletIndex);
- /**
- * Set the incoming buffer at the given inlet index. A boolean indicates if the given buffer
- * may be reused as an output buffer by the object. This object may also set its output buffer
- * with the given buffer, if all necessary conditions are satisfied.
- */
- virtual void setDspBufferAtInletWithReuse(float *buffer, unsigned int inletIndex, bool mayReuse);
+ virtual void setDspBufferAtInlet(float *buffer, unsigned int inletIndex);
+ virtual void setDspBufferAtOutlet(float *buffer, unsigned int outletIndex);
virtual void addConnectionFromObjectToInlet(MessageObject *messageObject, int outletIndex, int inletIndex);
virtual void addConnectionToObjectFromOutlet(MessageObject *messageObject, int inletIndex, int outletIndex);
@@ -94,7 +99,7 @@ class DspObject : public MessageObject {
virtual bool isLeafNode();
- virtual list<MessageObject *> *getProcessOrder();
+ virtual list<DspObject *> getProcessOrder();
virtual unsigned int getNumInlets() {
return max(incomingMessageConnections.size(), incomingDspConnections.size());
@@ -124,6 +129,8 @@ class DspObject : public MessageObject {
virtual list<ObjectLetPair> getOutgoingDspConnections(unsigned int outletIndex);
static const char *getObjectLabel();
+
+ virtual DspData *getProcessData() { return new DspData(); }
protected:
/* IMPORTANT: one of these two functions MUST be overridden (or processDsp()) */
@@ -138,6 +145,7 @@ class DspObject : public MessageObject {
virtual void onInletConnectionUpdate(unsigned int inletIndex);
virtual void onDspBufferAtInletUpdate(float *buffer, unsigned int inletIndex) { }
+ virtual void onDspBufferAtOutletUpdate(float *buffer, unsigned int inletIndex) { }
/** Immediately deletes all messages in the message queue without executing them. */
void clearMessageQueue();
View
3  src/DspOutlet.cpp
@@ -56,7 +56,6 @@ void DspOutlet::onDspBufferAtInletUpdate(float *buffer, unsigned int inletIndex)
for (list<ObjectLetPair>::iterator it = dspConnections.begin(); it != dspConnections.end(); ++it) {
ObjectLetPair letPair = *it;
DspObject *dspObject = reinterpret_cast<DspObject *>(letPair.first);
- dspObject->setDspBufferAtInletWithReuse(dspBufferAtInlet[inletIndex], letPair.second,
- it == dspConnections.begin());
+ dspObject->setDspBufferAtInlet(dspBufferAtInlet[inletIndex], letPair.second);
}
}
View
14 src/DspSignal.cpp
@@ -46,12 +46,26 @@ string DspSignal::toString() {
return string(str);
}
+DspData *DspSignal::getProcessData() {
+ DspSignalData *data = new DspSignalData();
+ data->processDsp = DspSignal::processSignal;
+ data->dspOutletBuffer0 = dspBufferAtOutlet[0];
+ data->blockSize = blockSizeInt;
+ data->constant = constant;
+ return data;
+}
+
void DspSignal::processMessage(int inletIndex, PdMessage *message) {
if (message->isFloat(0)) {
constant = message->getFloat(0);
}
}
+void DspSignal::processSignal(DspData *data) {
+ DspSignalData *d = reinterpret_cast<DspSignalData *>(data);
+ ArrayArithmetic::fill(d->dspOutletBuffer0, d->constant, 0, d->blockSize);
+}
+
void DspSignal::processDspWithIndex(int fromIndex, int toIndex) {
ArrayArithmetic::fill(dspBufferAtOutlet[0], constant, fromIndex, toIndex);
}
View
10 src/DspSignal.h
@@ -25,6 +25,13 @@
#include "DspObject.h"
+class DspSignalData : public DspData {
+ public:
+ float *dspOutletBuffer0;
+ unsigned short blockSize;
+ float constant;
+};
+
/** [sig~] */
class DspSignal : public DspObject {
@@ -36,6 +43,9 @@ class DspSignal : public DspObject {
static const char *getObjectLabel();
string toString();
+ DspData *getProcessData();
+ static void processSignal(DspData *data);
+
private:
void processMessage(int inletIndex, PdMessage *message);
void processDspWithIndex(int fromIndex, int toIndex);
View
34 src/MessageInlet.cpp
@@ -30,17 +30,13 @@ MessageObject *MessageInlet::newObject(PdMessage *initMessage, PdGraph *graph) {
// MessageInlet is initialised with an inlet because it manages connections from outside of the
// containing graph.
MessageInlet::MessageInlet(PdGraph *graph) : MessageObject(1, 1, graph) {
- canvasX = 0.0f;
+ // nothing to do
}
MessageInlet::~MessageInlet() {
// nothing to do
}
-const char *MessageInlet::getObjectLabel() {
- return "inlet";
-}
-
ObjectType MessageInlet::getObjectType() {
return MESSAGE_INLET;
}
@@ -49,26 +45,18 @@ void MessageInlet::receiveMessage(int inletIndex, PdMessage *message) {
sendMessage(0, message);
}
-list<MessageObject *> *MessageInlet::getProcessOrder() {
- if (isOrdered) {
- return new list<MessageObject *>();
- } else {
- isOrdered = true;
- list<MessageObject *> *processList = new list<MessageObject *>();
- processList->push_back(this);
- return processList;
- }
+list<DspObject *> MessageInlet::getProcessOrder() {
+ // a MessageInlet always returns an empty list as it does not process any audio
+ return list<DspObject *>();
}
-list<MessageObject *> *MessageInlet::getProcessOrderFromInlet() {
- list<MessageObject *> *processList = new list<MessageObject *>();
- list<ObjectLetPair>::iterator it = incomingMessageConnections[0].begin();
- list<ObjectLetPair>::iterator end = incomingMessageConnections[0].end();
- while (it != end) {
- ObjectLetPair objectLetPair = *it++;
- list<MessageObject *> *parentProcessList = objectLetPair.first->getProcessOrder();
- processList->splice(processList->end(), *parentProcessList);
- delete parentProcessList;
+list<DspObject *> MessageInlet::getProcessOrderFromInlet() {
+ list<DspObject *> processList;
+ for (list<ObjectLetPair>::iterator it = incomingMessageConnections[0].begin();
+ it != incomingMessageConnections[0].end(); ++it) {
+ ObjectLetPair objectLetPair = *it;
+ list<DspObject *> parentProcessList = objectLetPair.first->getProcessOrder();
+ processList.splice(processList.end(), parentProcessList);
}
return processList;
}
View
6 src/MessageInlet.h
@@ -33,11 +33,11 @@ class MessageInlet : public MessageObject {
MessageInlet(PdGraph *graph);
~MessageInlet();
- static const char *getObjectLabel();
+ static const char *getObjectLabel() { return "inlet"; }
ObjectType getObjectType();
- list<MessageObject *> *getProcessOrder();
- list<MessageObject *> *getProcessOrderFromInlet();
+ list<DspObject *> getProcessOrder();
+ list<DspObject *> getProcessOrderFromInlet();
void receiveMessage(int inletIndex, PdMessage *message);
};
View
13 src/MessageObject.cpp
@@ -184,24 +184,23 @@ bool MessageObject::isLeafNode() {
return true;
}
-list<MessageObject *> *MessageObject::getProcessOrder() {
+list<DspObject *> MessageObject::getProcessOrder() {
if (isOrdered) {
// if this object has already been ordered, then move on
- return new list<MessageObject *>();
+ return list<DspObject *>();
} else {
isOrdered = true;
- list<MessageObject *> *processList = new list<MessageObject *>();
+ list<DspObject *> processList;
for (int i = 0; i < incomingMessageConnections.size(); i++) {
list<ObjectLetPair>::iterator it = incomingMessageConnections[i].begin();
list<ObjectLetPair>::iterator end = incomingMessageConnections[i].end();
while (it != end) {
ObjectLetPair objectLetPair = *it++;
- list<MessageObject *> *parentProcessList = objectLetPair.first->getProcessOrder();
- processList->splice(processList->end(), *parentProcessList); // append parentProcessList to processList
- delete parentProcessList;
+ list<DspObject *> parentProcessList = objectLetPair.first->getProcessOrder();
+ processList.splice(processList.end(), parentProcessList); // append parentProcessList to processList
}
}
- processList->push_back(this);
+ // this object is not added to the process list as MessageObjects do not process audio
return processList;
}
}
View
3  src/MessageObject.h
@@ -33,6 +33,7 @@
#include "StaticUtils.h"
using namespace std;
+class DspObject;
class PdGraph;
class MessageObject;
@@ -129,7 +130,7 @@ class MessageObject {
virtual bool isLeafNode();
/** Returns an ordered list of all parent objects of this object. */
- virtual list<MessageObject *> *getProcessOrder();
+ virtual list<DspObject *> getProcessOrder();
/**
* Reset the <code>isOrdered</code> flag to <code>false</code>. This is necessary in order to
View
127 src/PdGraph.cpp
@@ -52,6 +52,7 @@ PdGraph::PdGraph(PdMessage *initMessage, PdGraph *parentGraph, PdContext *contex
// all graphs start out unattached to any context, though they exist in a context
isAttachedToContext = false;
switched = true; // graphs are switched on by default
+ bufferPool = new BufferPool(blockSizeInt);
// initialise the graph arguments
this->graphId = graphId;
@@ -66,6 +67,7 @@ PdGraph::PdGraph(PdMessage *initMessage, PdGraph *parentGraph, PdContext *contex
PdGraph::~PdGraph() {
graphArguments->freeMessage();
delete declareList;
+ delete bufferPool;
// delete all implicit +~ nodes
for (list<DspImplicitAdd *>::iterator it = implicitDspAddList.begin(); it != implicitDspAddList.end(); ++it) {
@@ -532,8 +534,13 @@ void PdGraph::processDsp() {
// TODO(mhroth): iterate depending on local blocksize relative to parent
// execute all nodes which process audio
- for (list<DspObject *>::iterator it = dspNodeList.begin(); it != dspNodeList.end(); ++it) {
- (*it)->processDsp();
+// for (list<DspObject *>::iterator it = dspNodeList.begin(); it != dspNodeList.end(); ++it) {
+// (*it)->processDsp();
+// }
+
+ for (list<DspData *>::iterator it = dspDataList.begin(); it != dspDataList.end(); ++it) {
+ DspData *data = *it;
+ data->processDsp(data);
}
}
}
@@ -597,37 +604,31 @@ void PdGraph::removeConnectionToObjectFromOutlet(MessageObject *messageObject, i
outletObject->removeConnectionToObjectFromOutlet(messageObject, inletIndex, 0);
}
-list<MessageObject *> *PdGraph::getProcessOrder() {
+list<DspObject *> PdGraph::getProcessOrder() {
if (isOrdered) {
- return new list<MessageObject *>();
+ return list<DspObject *>();
} else {
isOrdered = true;
- list<MessageObject *> *processOrder = new list<MessageObject *>();
- vector<MessageObject *>::iterator it = inletList.begin();
- vector<MessageObject *>::iterator end = inletList.end();
- while (it != end) {
+ list<DspObject *> processOrder;
+ for (vector<MessageObject *>::iterator it = inletList.begin(); it != inletList.end(); ++it) {
MessageObject *messageObject = *it++;
switch (messageObject->getObjectType()) {
case MESSAGE_INLET: {
- MessageInlet *messgeInlet = (MessageInlet *) messageObject;
- list<MessageObject *> *inletProcessOrder = messgeInlet->getProcessOrderFromInlet();
- processOrder->splice(processOrder->end(), *inletProcessOrder);
- delete inletProcessOrder;
+ MessageInlet *messgeInlet = reinterpret_cast<MessageInlet *>(messageObject);
+ list<DspObject *> inletProcessOrder = messgeInlet->getProcessOrderFromInlet();
+ processOrder.splice(processOrder.end(), inletProcessOrder);
break;
}
case DSP_INLET: {
- DspInlet *dspInlet = (DspInlet *) messageObject;
- list<MessageObject *> *inletProcessOrder = dspInlet->getProcessOrderFromInlet();
- processOrder->splice(processOrder->end(), *inletProcessOrder);
- delete inletProcessOrder;
- break;
- }
- default: {
+ DspInlet *dspInlet = reinterpret_cast<DspInlet *>(messageObject);
+ list<DspObject *> inletProcessOrder = dspInlet->getProcessOrderFromInlet();
+ processOrder.splice(processOrder.end(), inletProcessOrder);
break;
}
+ default: break;
}
}
- processOrder->push_back(this);
+ if (doesProcessAudio()) processOrder.push_back(this);
return processOrder;
}
}
@@ -663,89 +664,21 @@ void PdGraph::computeLocalDspProcessOrder() {
leafNodeList.push_back(object);
}
}
+
+ // NOTE(mhroth): massive memory leak here as reference to all +~~ objects are lost
+ dspNodeList.clear();
// for all leaf nodes, order the tree
- list<MessageObject *> processList;
+ list<DspObject *> dspNodeList;
for (list<MessageObject *>::iterator it = leafNodeList.begin(); it != leafNodeList.end(); ++it) {
MessageObject *object = *it;
- list<MessageObject *> *processSubList = object->getProcessOrder();
- processList.splice(processList.end(), *processSubList);
- delete processSubList;
- }
-
- // add only those nodes which process audio to the final list
-
-
- // delete all objects in the implicit +~ list
- for (list<DspImplicitAdd *>::iterator it = implicitDspAddList.begin();
- it != implicitDspAddList.end(); ++it) {
- delete *it;
+ list<DspObject *> processSubList = object->getProcessOrder();
+ dspNodeList.splice(dspNodeList.end(), processSubList);
}
- implicitDspAddList.clear();
- dspNodeList.clear(); // reset the dsp node list
-
- for (list<MessageObject *>::iterator it = processList.begin(); it != processList.end(); ++it) {
- // dsp elements at the top of the graph (i.e. process list) are processed first
- MessageObject *object = *it;
- if (object->doesProcessAudio()) {
- DspObject *dspObject = reinterpret_cast<DspObject *>(object);
- printStd("%s", dspObject->toString().c_str());
-
- // Add +~ objects to perform implicit sum operation for signal connections to the same inlet
- for (int i = 0; i < dspObject->getNumDspInlets(); i++) {
- list<ObjectLetPair> incomingDspConnectionsList = dspObject->getIncomingDspConnections(i);
- switch (incomingDspConnectionsList.size()) {
- case 0: {
- // if no connections are made to an inlet, then it receives a zero buffer
- // the zero buffer may never be reused, but there is an additional check for it anyway
- dspObject->setDspBufferAtInletWithReuse(zeroBuffer, i, false);
- break;
- }
- case 1: {
- // if only one connection exists to this object, add the connection directly
- ObjectLetPair objectLetPair = incomingDspConnectionsList.front();
- DspObject *prevObject = (DspObject *) objectLetPair.first;
- unsigned int outletIndex = objectLetPair.second;
- dspObject->setDspBufferAtInletWithReuse(prevObject->getDspBufferAtOutlet(outletIndex), i,
- prevObject->mayReuseBuffer(dspObject, outletIndex));
- break;
- }
- default: {
- // if more than one connection exists to an inlet, create a series of dummy +~ objects
- // to perform implicit summing
- list<ObjectLetPair>::iterator jt = incomingDspConnectionsList.begin();
- DspObject *prevObject = reinterpret_cast<DspObject *>((*jt).first);
- unsigned int prevOutlet = (*jt++).second;
- PdMessage *dspAddInitMessage = PD_MESSAGE_ON_STACK(1); dspAddInitMessage->setFloat(0, 0.0f);
- bool mayReuseBufferFromLeftConnection = prevObject->mayReuseBuffer(dspObject, prevOutlet);
- while (jt != incomingDspConnectionsList.end()) {
- DspImplicitAdd *dspAdd = new DspImplicitAdd(dspAddInitMessage, this);
- dspAdd->setDspBufferAtInletWithReuse(prevObject->getDspBufferAtOutlet(prevOutlet), 0,
- mayReuseBufferFromLeftConnection);
-
- // after the first left connection, we only connect with +~~ objects and thus are
- // definitely allowed to reuse the buffer
- mayReuseBufferFromLeftConnection = true;
-
- // the second connection is always a non-+~~ object
- DspObject *prevObject1 = reinterpret_cast<DspObject *>((*jt).first);
- unsigned int prevOutlet1 = (*jt++).second;
- dspAdd->setDspBufferAtInletWithReuse(prevObject1->getDspBufferAtOutlet(prevOutlet1), 1,
- prevObject1->mayReuseBuffer(dspObject, prevOutlet1));
-
- prevObject = dspAdd; prevOutlet = 0;
- dspNodeList.push_back(dspAdd);
- implicitDspAddList.push_back(dspAdd);
- }
- // set dsp ref at inlet of dspObject to prevObject
- dspObject->setDspBufferAtInletWithReuse(prevObject->getDspBufferAtOutlet(0), i, true);
- break;
- }
- }
- }
- dspNodeList.push_back(dspObject); // add the dsp object to the dsp node list
- }
+ dspDataList.clear();
+ for (list<DspObject *>::iterator it = dspNodeList.begin(); it != dspNodeList.end(); it++) {
+ dspDataList.push_back((*it)->getProcessData());
}
/* print out process order of local dsp objects (for debugging) */
View
9 src/PdGraph.h
@@ -23,6 +23,7 @@
#ifndef _PD_GRAPH_H_
#define _PD_GRAPH_H_
+#include "BufferPool.h"
#include "DspObject.h"
#include "OrderedMessageQueue.h"
@@ -137,7 +138,7 @@ class PdGraph : public DspObject {
/** (Re-)Computes the local tree and node processing ordering for dsp nodes. */
void computeLocalDspProcessOrder();
- list<MessageObject *> *getProcessOrder();
+ list<DspObject *> getProcessOrder();
bool isLeafNode();
/**
@@ -212,6 +213,8 @@ class PdGraph : public DspObject {
/** Unlocks the context if this graph is attached. */
void unlockContextIfAttached();
+ BufferPool *getBufferPool() { return bufferPool; }
+
private:
/** Create a new object based on its initialisation string. */
MessageObject *newObject(char *objectType, char *objectLabel, PdMessage *initMessage, PdGraph *graph);
@@ -255,6 +258,8 @@ class PdGraph : public DspObject {
*/
list<DspObject *> dspNodeList;
+ list<DspData *> dspDataList;
+
list<DspImplicitAdd *> implicitDspAddList;
/** A list of all inlet (message or audio) nodes in this subgraph. */
@@ -265,6 +270,8 @@ class PdGraph : public DspObject {
/** A global list of all declared directories (-path and -stdpath) */
DeclareList *declareList;
+
+ BufferPool *bufferPool;
};
#endif // _PD_GRAPH_H_
Please sign in to comment.
Something went wrong with that request. Please try again.