diff --git a/src/signalProcessing/rapidPiPoTools/rapidPiPoHost.cpp b/src/signalProcessing/rapidPiPoTools/rapidPiPoHost.cpp new file mode 100644 index 0000000000000000000000000000000000000000..06211c9dea6748094789e15af10a41cb29b01bb8 --- /dev/null +++ b/src/signalProcessing/rapidPiPoTools/rapidPiPoHost.cpp @@ -0,0 +1,880 @@ +#include "rapidPiPoHost.h" + +//===================== P I P O = H O S T = U T I L S ========================// + +static const unsigned int maxWordLen = 256; + +static bool getPiPoInstanceAndAttrName(const char *attrName, + char *instanceName, + char *pipoAttrName) +{ + const char *dot = std::strrchr(attrName, '.'); + + if (dot != NULL) + { + unsigned int pipoAttrNameLen = dot - attrName; + std::strcpy(pipoAttrName, dot + 1); + + if (pipoAttrNameLen > maxWordLen) + { + pipoAttrNameLen = maxWordLen; + } + + std::strncpy(instanceName, attrName, pipoAttrNameLen); + instanceName[pipoAttrNameLen] = '\0'; + + return true; + } + + return false; +} + + +static void fromPiPoStreamAttributes(PiPoStreamAttributes &src, + pipoStreamAttributes &dst) +{ + unsigned int numCols = src.dims[0]; + unsigned int numLabels = src.numLabels; + + if (numLabels > PIPO_MAX_LABELS) { + numLabels = PIPO_MAX_LABELS; + } + + if (numLabels > numCols) { + numLabels = numCols; + } + + dst.hasTimeTags = src.hasTimeTags; + + if (src.rate <= MIN_PIPO_SAMPLERATE) { + dst.rate = MIN_PIPO_SAMPLERATE; + } else if (src.rate >= MAX_PIPO_SAMPLERATE) { + dst.rate = MAX_PIPO_SAMPLERATE; + } else { + dst.rate = src.rate; + } + + dst.rate = src.rate; + dst.offset = src.offset; + dst.dims = { src.dims[0], src.dims[1] }; + + dst.labels = std::vector<std::string>(); + + for (unsigned int i = 0; i < numLabels; ++i) + { + dst.labels.push_back(std::string(src.labels[i])); + } + + dst.hasVarSize = src.hasVarSize; + dst.domain = src.domain; + dst.maxFrames = src.maxFrames; +} + + +static void toPiPoStreamAttributes(pipoStreamAttributes &src, + PiPoStreamAttributes &dst) +{ + const char *labs[src.labels.size()]; + + for (unsigned int i = 0; i < src.labels.size(); ++i) + { + labs[i] = labels[i].c_str(); + } + + dst = PiPoStreamAttributes( + src.hasTimeTags, + src.rate, + src.offset, + { src.dims[0], src.dims[1] }, + &labs[0], + src.hasVarSize, + src.domain; + src.maxFrames + ); +} + +//========================= H O S T = M E T H O D S ==========================// + +PiPoHost::PiPoHost() : +inputStreamAttrs(PIPO_MAX_LABELS), +outputStreamAttrs(PIPO_MAX_LABELS) +{ + PiPoCollection::init(); + this->out = new PiPoOut(this); + this->graph = nullptr; +} + +PiPoHost::~PiPoHost() +{ + if (this->graph != nullptr) + { + delete this->graph; + } + + delete this->out; +} + +bool +PiPoHost::setPiPoGraph(std::string name) +{ + if (this->graph != nullptr) + { + delete this->graph; + } + + this->graph = PiPoCollection::create(name); + + if (this->graph != NULL) + { + this->graphName = name; + this->graph->connect((PiPo *)this->out); + return true; + } + + this->graph = nullptr; + this->graphName = "undefined"; + return false; +} + +void +PiPoHost::clearPiPoGraph() +{ + if (this->graph != nullptr) + { + delete this->graph; + this->graph = nullptr; + } +} + + +void +PiPoHost::onNewFrameOut(double time, std::vector<PiPoValue> &frame) +{ + std::cout << time << std::endl; + std::cout << "please override this method" << std::endl; +} + +std::vector<PiPoValue> +PiPoHost::getLastFrameOut() +{ + return this->out->getLastFrame(); +} + + + +void +PiPoHost::setInputStreamAttributes(pipoStreamAttributes &sa, bool propagate) +{ + toPiPoStreamAttributes(sa, inputStreamAttrs); + + if (propagate) + { + this->propagateInputStreamAttributes(); + } +} + +pipoStreamAttributes +PiPoHost::getOutputStreamAttributes() +{ + pipoStreamAttributes sa; + return fromPiPoStreamAttributes(this->outputStreamAttrs, sa); +} + +int +PiPoHost::frames(double time, double weight, PiPoValue *values, unsigned int size, + unsigned int num) +{ + return this->graph->frames(time, weight, values, size, num); +} + + + +// bool +// setAttr(const std::string &attrName, bool value) +// { + +// } + +// bool +// setAttr(const std::string &attrName, int value) +// { + +// } + +bool +setAttr(const std::string &attrName, double value) +{ + PiPo::Attr *attr = this->graph->getAttr(attrName.c_str()); + + if (attr != NULL) { + int iAttr = attr->getIndex(); + return this->pipo->setAttr(iAttr, value); + } + + return false; +} + +bool +setAttr(const std::string &attrName, const std::vector<double> &values) +{ + PiPo::Attr *attr = this->pipo->getAttr(attrName.c_str()); + + if (attr != NULL) { + int iAttr = attr->getIndex(); + double vals[values.size()]; + unsigned int i = 0; + for (auto &value : values) { + vals[i] = value; + i++; + } + return this->pipo->setAttr(iAttr, &vals[0], values.size()); + } + + return false; +} + +bool +setAttr(const std::string &attrName, const std::string &value) // for enums +{ + PiPo::Attr *attr = this->pipo->getAttr(attrName.c_str()); + + if (attr != NULL) { + int iAttr = attr->getIndex(); + PiPo::Type type = attr->getType(); + + if (type == PiPo::Type::Enum) { + std::vector<const char *> *list = attr->getEnumList(); + + for (int i = 0; i < list->size(); i++) { + if (strcmp(list->at(i), value.c_str()) == 0) { + attr->set(0, i); + return true; + } + } + } + } + + return false; +} + + +void +PiPoHost::propagateInputStreamAttributes() +{ + if (this->graph != nullptr) + { + this->graph->streamAttributes(this->inputStreamAttrs.hasTimeTags, + this->inputStreamAttrs.rate, + this->inputStreamAttrs.offset, + this->inputStreamAttrs.dims[0], + this->inputStreamAttrs.dims[1], + this->inputStreamAttrs.labels, + this->inputStreamAttrs.hasVarSize, + this->inputStreamAttrs.domain, + this->inputStreamAttrs.maxFrames); + } +} + + + + +// void +// PiPoHost::streamAttributesChanged(PiPo *pipo, PiPo::Attr *attr) { +// this->propagateInputAttributes(); +// } + +// void +// PiPoHost::signalError(PiPo *pipo, std::string errorMsg) { +// // todo +// } + +// void +// PiPoHost::signalWarning(PiPo *pipo, std::string warningMsg) { +// // todo +// } + +//--------------------- INPUT STREAM ATTRIBUTES SETTERS ----------------------// + +/* +void +PiPoHost::setInputHasTimeTags(bool hasTimeTags, bool propagate) { + this->inputStreamAttrs.hasTimeTags = hasTimeTags; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +#define MIN_PIPO_SAMPLERATE (1.0 / 31536000000.0) // once a year +#define MAX_PIPO_SAMPLERATE (96000000000.0) + +void +PiPoHost::setInputFrameRate(double rate, bool propagate) { + if (rate <= MIN_PIPO_SAMPLERATE) { + this->inputStreamAttrs.rate = MIN_PIPO_SAMPLERATE; + } else if (rate >= MAX_PIPO_SAMPLERATE) { + this->inputStreamAttrs.rate = MAX_PIPO_SAMPLERATE; + } else { + this->inputStreamAttrs.rate = rate; + } + + if (propagate) { + this->propagateInputAttributes(); + } +} + +void +PiPoHost::setInputFrameOffset(double offset, bool propagate) { + this->inputStreamAttrs.offset = offset; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +void +PiPoHost::setInputDims(int width, int height, bool propagate) { + this->inputStreamAttrs.dims[0] = width; + this->inputStreamAttrs.dims[1] = height; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +void +PiPoHost::setInputLabels(const std::vector<std::string> &labels, bool propagate) { + const char *labs[labels.size()]; + + for (unsigned int i = 0; i < labels.size(); ++i) { + labs[i] = labels[i].c_str(); + } + + this->inputStreamAttrs.labels = &labs[0]; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +void +PiPoHost::setInputHasVarSize(bool hasVarSize, bool propagate) { + this->inputStreamAttrs.hasVarSize = hasVarSize; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +void +PiPoHost::setInputDomain(double domain, bool propagate) { + this->inputStreamAttrs.domain = domain; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +void +PiPoHost::setInputMaxFrames(int maxFrames, bool propagate) { + this->inputStreamAttrs.maxFrames = maxFrames; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +//--------------------- INPUT STREAM ATTRIBUTES GETTERS ----------------------// + +bool +PiPoHost::getInputHasTimeTags() { + return this->inputStreamAttrs.hasTimeTags; +} + +double +PiPoHost::getInputFrameRate() { + return this->inputStreamAttrs.rate; +} + +double +PiPoHost::getInputFrameOffset() { + return this->inputStreamAttrs.offset; +} + +void +PiPoHost::getInputDims(int &width, int &height) { + width = this->inputStreamAttrs.dims[0]; + height = this->inputStreamAttrs.dims[1]; +} + +void +PiPoHost::getInputLabels(std::vector<std::string> &labels) { + //for (unsigned int i = 0; i < ) +} + +bool +PiPoHost::getInputHasVarSize() { + return this->inputStreamAttrs.hasVarSize; +} + +double +PiPoHost::getInputDomain() { + return this->inputStreamAttrs.domain; +} + +int +PiPoHost::getInputMaxFrames() { + return this->inputStreamAttrs.maxFrames; +} +//*/ + +//--------------------- OUTPUT STREAM ATTRIBUTES GETTERS ---------------------// + +void +PiPoHost::setOutputAttributes(bool hasTimeTags, double rate, double offset, + unsigned int width, unsigned int height, + const char **labels, bool hasVarSize, + double domain, unsigned int maxFrames) { + if (labels != NULL) { + int numLabels = width; + + if (numLabels > PIPO_MAX_LABELS) { + numLabels = PIPO_MAX_LABELS; + } + + for (unsigned int i = 0; i < numLabels; i++) { + try { + this->outputStreamAttrs.labels[i] = labels[i]; + } catch(std::exception e) { + this->outputStreamAttrs.labels[i] = "unnamed"; + } + } + + this->outputStreamAttrs.numLabels = numLabels; + } else { + this->outputStreamAttrs.numLabels = 0; + } + + this->outputStreamAttrs.hasTimeTags = hasTimeTags; + this->outputStreamAttrs.rate = rate; + this->outputStreamAttrs.offset = offset; + this->outputStreamAttrs.dims[0] = width; + this->outputStreamAttrs.dims[1] = height; + this->outputStreamAttrs.hasVarSize = hasVarSize; + this->outputStreamAttrs.domain = domain; + this->outputStreamAttrs.maxFrames = maxFrames; +} + +bool +PiPoHost::getOutputHasTimeTags() { + return this->outputStreamAttrs.hasTimeTags; +} + +double +PiPoHost::getOutputFrameRate() { + return this->outputStreamAttrs.rate; +} + +double +PiPoHost::getOutputFrameOffset() { + return this->outputStreamAttrs.offset; +} + +void +PiPoHost::getOutputDims(int &width, int &height) { + width = this->outputStreamAttrs.dims[0]; + height = this->outputStreamAttrs.dims[1]; +} + +void +PiPoHost::getOutputLabels(std::vector<std::string> &labels) { + labels.clear(); + + for (unsigned int i = 0; this->outputStreamAttrs.numLabels; ++i) { + + if (this->outputStreamAttrs.labels[i] != NULL) { + labels.push_back(std::string(this->outputStreamAttrs.labels[i])); + } else { + labels.push_back("unnamed"); + } + } +} + +bool +PiPoHost::getOutputHasVarSize() { + return this->outputStreamAttrs.hasVarSize; +} + +double +PiPoHost::getOutputDomain() { + return this->outputStreamAttrs.domain; +} + +int +PiPoHost::getOutputMaxFrames() { + return this->outputStreamAttrs.maxFrames; +} + + + + + + + + + + +//===================== PIPO HOST CLASS IMPLEMENTATION =======================// + +rapidPiPoHost::rapidPiPoHost(rapidPiPoOwner *rpo) : +owner(rpo), +inputStreamAttrs(PIPO_MAX_LABELS), +outputStreamAttrs(PIPO_MAX_LABELS) { + PiPoCollection::init(); + outputter = new rapidPiPoOutputter(this); + chain = nullptr; +} + +rapidPiPoHost::~rapidPiPoHost() { + if (chain != nullptr) { + delete chain; + } + delete outputter; +} + +rapidPiPoOwner * +rapidPiPoHost::getOwner() { + return owner; +} + +void +rapidPiPoHost::onNewFrame(double time, std::vector<PiPoValue> &frame) { + std::cout << time << std::endl; + owner->onNewFrame(frame); +} +// void +// rapidPiPoHost::onNewFrame(const std::function<void(std::vector<PiPoValue>, +// rapidPiPoOwner *rpo)> cb) { +// outputter->setFrameCallback(cb); +// } + +// void +// rapidPiPoHost::onNewFrame(std::function<void(std::vector<PiPoValue>)> cb) { +// outputter->setSimpleFrameCallback(cb); +// } + +std::vector<PiPoValue> +rapidPiPoHost::getLastFrame() { + return outputter->getLastFrame(); +} + +rapidPiPo * +rapidPiPoHost::setPiPoChain(std::string name) { + if (chain != nullptr) { + delete chain; + } + + chain = new rapidPiPo(name); + chain->connect((PiPo *)outputter); + return chain; +} + +void +rapidPiPoHost::clearPiPoChain() { + delete chain; + chain = nullptr; +} + +void +rapidPiPoHost::propagateInputAttributes() { + if (chain != nullptr) { + const char *colNameStr[PIPO_MAX_LABELS]; + + unsigned int numCols = this->inputStreamAttrs.dims[0]; + unsigned int numLabels = this->inputStreamAttrs.numLabels; + + if (numLabels > PIPO_MAX_LABELS) { + numLabels = PIPO_MAX_LABELS; + } + + if (numLabels > numCols) { + numLabels = numCols; + } + + std::vector<std::string> labels(numLabels); + + if (numLabels > 0) { + for (unsigned int i = 0; i < numLabels; i++) { + colNameStr[i] = this->inputStreamAttrs.labels[i]; + } + + for (unsigned int i = numLabels; i < numCols; i++) { + colNameStr[i] = "unnamed"; + } + + for (unsigned int i = 0; i < numCols; ++i) { + labels[i] = std::string(colNameStr[i]); + } + } + + chain->streamAttributes(this->inputStreamAttrs.hasTimeTags, + this->inputStreamAttrs.rate, + this->inputStreamAttrs.offset, + this->inputStreamAttrs.dims[0], + this->inputStreamAttrs.dims[1], + labels, + this->inputStreamAttrs.hasVarSize, + this->inputStreamAttrs.domain, + this->inputStreamAttrs.maxFrames); + } +} + +// void +// rapidPiPoHost::streamAttributesChanged(PiPo *pipo, PiPo::Attr *attr) { +// this->propagateInputAttributes(); +// } + +// void +// rapidPiPoHost::signalError(PiPo *pipo, std::string errorMsg) { +// // todo +// } + +// void +// rapidPiPoHost::signalWarning(PiPo *pipo, std::string warningMsg) { +// // todo +// } + +//--------------------- INPUT STREAM ATTRIBUTES SETTERS ----------------------// + +void +rapidPiPoHost::setInputHasTimeTags(bool hasTimeTags, bool propagate) { + this->inputStreamAttrs.hasTimeTags = hasTimeTags; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +#define MIN_PIPO_SAMPLERATE (1.0 / 31536000000.0) /* once a year */ +#define MAX_PIPO_SAMPLERATE (96000000000.0) + +void +rapidPiPoHost::setInputFrameRate(double rate, bool propagate) { + if (rate <= MIN_PIPO_SAMPLERATE) { + this->inputStreamAttrs.rate = MIN_PIPO_SAMPLERATE; + } else if (rate >= MAX_PIPO_SAMPLERATE) { + this->inputStreamAttrs.rate = MAX_PIPO_SAMPLERATE; + } else { + this->inputStreamAttrs.rate = rate; + } + + if (propagate) { + this->propagateInputAttributes(); + } +} + +void +rapidPiPoHost::setInputFrameOffset(double offset, bool propagate) { + this->inputStreamAttrs.offset = offset; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +void +rapidPiPoHost::setInputDims(int width, int height, bool propagate) { + this->inputStreamAttrs.dims[0] = width; + this->inputStreamAttrs.dims[1] = height; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +void +rapidPiPoHost::setInputLabels(const std::vector<std::string> &labels, bool propagate) { + const char *labs[labels.size()]; + + for (unsigned int i = 0; i < labels.size(); ++i) { + labs[i] = labels[i].c_str(); + } + + this->inputStreamAttrs.labels = &labs[0]; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +void +rapidPiPoHost::setInputHasVarSize(bool hasVarSize, bool propagate) { + this->inputStreamAttrs.hasVarSize = hasVarSize; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +void +rapidPiPoHost::setInputDomain(double domain, bool propagate) { + this->inputStreamAttrs.domain = domain; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +void +rapidPiPoHost::setInputMaxFrames(int maxFrames, bool propagate) { + this->inputStreamAttrs.maxFrames = maxFrames; + + if (propagate) { + this->propagateInputAttributes(); + } +} + +//--------------------- INPUT STREAM ATTRIBUTES GETTERS ----------------------// + +bool +rapidPiPoHost::getInputHasTimeTags() { + return this->inputStreamAttrs.hasTimeTags; +} + +double +rapidPiPoHost::getInputFrameRate() { + return this->inputStreamAttrs.rate; +} + +double +rapidPiPoHost::getInputFrameOffset() { + return this->inputStreamAttrs.offset; +} + +void +rapidPiPoHost::getInputDims(int &width, int &height) { + width = this->inputStreamAttrs.dims[0]; + height = this->inputStreamAttrs.dims[1]; +} + +void +rapidPiPoHost::getInputLabels(std::vector<std::string> &labels) { + //for (unsigned int i = 0; i < ) +} + +bool +rapidPiPoHost::getInputHasVarSize() { + return this->inputStreamAttrs.hasVarSize; +} + +double +rapidPiPoHost::getInputDomain() { + return this->inputStreamAttrs.domain; +} + +int +rapidPiPoHost::getInputMaxFrames() { + return this->inputStreamAttrs.maxFrames; +} + +//--------------------- OUTPUT STREAM ATTRIBUTES GETTERS ---------------------// + +void +rapidPiPoHost::setOutputAttributes(bool hasTimeTags, double rate, double offset, + unsigned int width, unsigned int height, + const char **labels, bool hasVarSize, + double domain, unsigned int maxFrames) { + if (labels != NULL) { + int numLabels = width; + + if (numLabels > PIPO_MAX_LABELS) { + numLabels = PIPO_MAX_LABELS; + } + + for (unsigned int i = 0; i < numLabels; i++) { + try { + this->outputStreamAttrs.labels[i] = labels[i]; + } catch(std::exception e) { + this->outputStreamAttrs.labels[i] = "unnamed"; + } + } + + this->outputStreamAttrs.numLabels = numLabels; + } else { + this->outputStreamAttrs.numLabels = 0; + } + + this->outputStreamAttrs.hasTimeTags = hasTimeTags; + this->outputStreamAttrs.rate = rate; + this->outputStreamAttrs.offset = offset; + this->outputStreamAttrs.dims[0] = width; + this->outputStreamAttrs.dims[1] = height; + this->outputStreamAttrs.hasVarSize = hasVarSize; + this->outputStreamAttrs.domain = domain; + this->outputStreamAttrs.maxFrames = maxFrames; +} + +bool +rapidPiPoHost::getOutputHasTimeTags() { + return this->outputStreamAttrs.hasTimeTags; +} + +double +rapidPiPoHost::getOutputFrameRate() { + return this->outputStreamAttrs.rate; +} + +double +rapidPiPoHost::getOutputFrameOffset() { + return this->outputStreamAttrs.offset; +} + +void +rapidPiPoHost::getOutputDims(int &width, int &height) { + width = this->outputStreamAttrs.dims[0]; + height = this->outputStreamAttrs.dims[1]; +} + +void +rapidPiPoHost::getOutputLabels(std::vector<std::string> &labels) { + labels.clear(); + + for (unsigned int i = 0; this->outputStreamAttrs.numLabels; ++i) { + + if (this->outputStreamAttrs.labels[i] != NULL) { + labels.push_back(std::string(this->outputStreamAttrs.labels[i])); + } else { + labels.push_back("unnamed"); + } + } +} + +bool +rapidPiPoHost::getOutputHasVarSize() { + return this->outputStreamAttrs.hasVarSize; +} + +double +rapidPiPoHost::getOutputDomain() { + return this->outputStreamAttrs.domain; +} + +int +rapidPiPoHost::getOutputMaxFrames() { + return this->outputStreamAttrs.maxFrames; +} + +// void +// rapidPiPoHost::setRapidPiPoParam(rapidPiPoParam *param) { +// char instanceName[maxWordLen]; +// char pipoAttrName[maxWordLen]; + +// if (getPiPoInstanceAndAttrName(param->getName(), instanceName, pipoAttrName)) { +// // todo (or not todo) +// } +// } + +// void +// rapidPiPoHost::getPiPoParams(std::vector<rapidPiPoParam> ¶ms) { + +// } diff --git a/src/signalProcessing/rapidPiPoTools/rapidPiPoHost.h b/src/signalProcessing/rapidPiPoTools/rapidPiPoHost.h new file mode 100644 index 0000000000000000000000000000000000000000..b665a3f024d869a2755958352d0f6dcaf3fe59be --- /dev/null +++ b/src/signalProcessing/rapidPiPoTools/rapidPiPoHost.h @@ -0,0 +1,312 @@ +#ifndef _RAPID_PIPO_HOST_H_ +#define _RAPID_PIPO_HOST_H_ + +#include "PiPo.h" +#include "PiPoHost.h" +#include "PiPoCollection.h" + +#define MIN_PIPO_SAMPLERATE (1.0 / 31536000000.0) /* once a year */ +#define MAX_PIPO_SAMPLERATE (96000000000.0) + +#define PIPO_OUT_RING_SIZE 2 + +struct pipoStreamAttributes { + pipoStreamAttributes() : + hasTimeTags(false), + rate(MIN_PIPO_SAMPLERATE), + offset(0), + labels({ "" }), + hasVarSize(false), + domain(0), + maxFrames(256) + { + dims[0] = 1; + dims[1] = 1; + } + + bool hasTimeTags; + double rate; + double offset; + unsigned int dims[2]; // width, height (by pipo convention) + std::vector<std::string> labels; + bool hasVarSize; + double domain; + unsigned int maxFrames; +}; + + +//class PiPoObserver; +class PiPoOut; + +//================================ H O S T ===================================// + +class PiPoHost : public PiPo::Parent { + friend class PiPoOut; + +private: + PiPo *graph; + std::string graphName; + PiPoOut *out; + // PiPoObserver *obs; + PiPoStreamAttributes inputStreamAttrs; + PiPoStreamAttributes outputStreamAttrs; + +public: + // PiPoHost(PiPoObserver *obs); + PiPoHost(); + ~PiPoHost(); + + // PiPoObserver *getObserver(); + + virtual bool setPiPoGraph(std::string name); + virtual void clearPiPoGraph(); + + // override this method when inheriting !!! + virtual void onNewFrameOut(double time, std::vector<PiPoValue> &frame); + virtual std::vector<PiPoValue> getLastFrameOut(); + + virtual int setInputStreamAttributes(pipoStreamAttributes sa, bool propagate = true); + virtual pipoStreamAttributes &getOutputStreamAttributes(); + + virtual int frames(double time, double weight, PiPoValue *values, unsigned int size, + unsigned int num); + + // virtual bool setAttr(const std::string &attrName, bool value); + // virtual bool setAttr(const std::string &attrName, int value); + virtual bool setAttr(const std::string &attrName, double value); + virtual bool setAttr(const std::string &attrName, const std::vector<double> &values); + virtual bool setAttr(const std::string &attrName, const std::string &value); // for enums + + // virtual const std::vector<std::string>& getAttrNames(); + // virtual bool isBoolAttr(const std::string &attrName); + // virtual bool isEnumAttr(const std::string &attrName); + // virtual bool isIntAttr(const std::string &attrName); + // virtual bool isIntArrayAttr(const std::string &attrName); + // virtual bool isFloatAttr(const std::string &attrName); + // virtual bool isFloatArrayAttr(const std::string &attrName); + // virtual bool isStringAttr(const std::string &attrName); + + // virtual bool getBoolAttr(const std::string &attrName); + // virtual int getIntAttr(const std::string &attrName); + // virtual float getFloatAttr(const std::string &attrName); + + + + // int streamAttributes(bool hasTimeTags, double rate, double offset, + // unsigned int width, unsigned int height, + // const std::vector<std::string> &labels, + // bool hasVarSize, double domain, unsigned int maxFrames, + // bool propagate = true); + + // void propagateInputAttributes(); + + + // void streamAttributesChanged(PiPo *pipo, PiPo::Attr *attr); + // void signalError(PiPo *pipo, std::string errorMsg); + // void signalWarning(PiPo *pipo, std::string warningMsg); + + /* + void setInputHasTimeTags(bool hasTimeTags, bool propagate = true); + void setInputFrameRate(double rate, bool propagate = true); + void setInputFrameOffset(double offset, bool propagate = true); + void setInputDims(int width, int height, bool propagate = true); + void setInputLabels(const std::vector<std::string> &labels, bool propagate = true); + void setInputHasVarSize(bool hasVarSize, bool propagate = true); + void setInputDomain(double domain, bool propagate = true); + void setInputMaxFrames(int maxFrames, bool propagate = true); + + bool getInputHasTimeTags(); + double getInputFrameRate(); + double getInputFrameOffset(); + void getInputDims(int &width, int &height); + void getInputLabels(std::vector<std::string> &labels); + bool getInputHasVarSize(); + double getInputDomain(); + int getInputMaxFrames(); + + bool getOutputHasTimeTags(); + double getOutputFrameRate(); + double getOutputFrameOffset(); + void getOutputDims(int &width, int &height); + void getOutputLabels(std::vector<std::string> &labels); + bool getOutputHasVarSize(); + double getOutputDomain(); + int getOutputMaxFrames(); + + // void setPiPoParam(PiPoParam *param); + //*/ +private: + void propagateInputStreamAttributes(); + void setOutputAttributes(bool hasTimeTags, double rate, double offset, + unsigned int width, unsigned int height, + const char **labels, bool hasVarSize, + double domain, unsigned int maxFrames); + +}; + +//================================= PiPoOut ==================================// + + class PiPoOut : public PiPo { +private: + PiPoHost *host; + std::atomic<int> writeIndex, readIndex; + std::vector<std::vector<PiPoValue>> ringBuffer; + //std::function<void(std::vector<PiPoValue>, PiPoObserver *rpo)> frameCallback; + std::function<void(std::vector<PiPoValue>)> simpleFrameCallback; + +public: + PiPoOut(PiPoHost *host) : + PiPo((PiPo::Parent *)host) { + this->host = host; + writeIndex = 0; + readIndex = 0; + ringBuffer.resize(PIPO_OUT_RING_SIZE); + } + + ~PiPoOut() {} + + int streamAttributes(bool hasTimeTags, + double rate, double offset, + unsigned int width, unsigned int height, + const char **labels, bool hasVarSize, + double domain, unsigned int maxFrames) { + + this->host->setOutputAttributes(hasTimeTags, rate, offset, width, height, + labels, hasVarSize, domain, maxFrames); + + for (int i = 0; i < PIPO_OUT_RING_SIZE; ++i) { + ringBuffer[i].resize(width * height); + } + + return 0; + } + + int frames(double time, double weight, float *values, + unsigned int size, unsigned int num) { + + if (num > 0) { + for (int i = 0; i < num; ++i) { + + for (int j = 0; j < size; ++j) { + ringBuffer[writeIndex][j] = values[i * size + j]; + } + + // atomic swap ? + writeIndex = 1 - writeIndex; + readIndex = 1 - writeIndex; + + this->host->onNewFrameOut(time, ringBuffer[readIndex]); + + if (writeIndex + 1 == PIPO_OUT_RING_SIZE) { + writeIndex = 0; + } else { + writeIndex++; + } + } + } + + return 0; + } + + //void setFrameCallback(std::function<void(std::vector<PiPoValue>, + // PiPoObserver *obs)> f) { + // frameCallback = f; + //} + + void setSimpleFrameCallback(std::function<void(std::vector<PiPoValue>)> f) { + simpleFrameCallback = f; + } + + std::vector<PiPoValue> getLastFrame() { + std::vector<PiPoValue> f; + + if (readIndex > -1) { + f = ringBuffer[readIndex]; + } + + return f; + } +}; + +//================================ PARAMETER =================================// + +// can we avoid using such a class ? +/* +class rapidPiPoParam { + std::string name; + std::string pipoName; + std::string paramName; + std::vector<std::string> values; + +public: + rapidPiPoParam() : + name(""), pipoName(""), paramName("") {} + + rapidPiPoParam(std::string name, std::string pipoName, std::string paramName, + std::vector<std::string> const &values) { + this->name = name; + this->pipoName = pipoName; + this->paramName = paramName; + this->values = std::vector<std::string>(values.size()); + for (int i = 0; i < values.size(); ++i) { + this->values[i] = values[i]; + } + } + + const char *getName() { + return name.c_str(); + } + + const char *getParamName() { + return paramName.c_str(); + } + + const char *getPiPoName() { + return pipoName.c_str(); + } + + int getNumValues() { + return values.size(); + } + + bool isValueInt(int i) { + // todo + return false; + } + + bool isValueFloat(int i) { + // todo + return false; + } + + bool isValueNum(int i) { + // todo; + return false; + } + + float getValueFloat(int i) { + // todo + return 0.; + } + + int getValueInt(int i) { + // todo + return 0; + } + + const char *getValueString() { + return values[0].c_str(); + //return values[i].c_str(); + } + + std::string getValuesAsString() { + std::string res = values[0]; + for (int i = 1; i < values.size(); ++i) { + res += " " + values[i]; + } + return res; + } +}; +//*/ + +#endif /* _RAPID_PIPO_HOST_H_ */ diff --git a/src/signalProcessing/rapidPiPoTools/rapidPiPoTools.h b/src/signalProcessing/rapidPiPoTools/rapidPiPoTools.h new file mode 100644 index 0000000000000000000000000000000000000000..45c381bba89694fe5529cc103ec640bde0a2f7db --- /dev/null +++ b/src/signalProcessing/rapidPiPoTools/rapidPiPoTools.h @@ -0,0 +1,6 @@ +#ifndef _RAPID_PIPO_TOOLS_H_ +#define _RAPID_PIPO_TOOLS_H_ + +#include "rapidPiPoHost.h" + +# endif /* _RAPID_PIPO_TOOLS_H_ */ \ No newline at end of file