diff --git a/include/wrapper/RealTimeBase.hpp b/include/wrapper/RealTimeBase.hpp index 0249e61..554d8ab 100644 --- a/include/wrapper/RealTimeBase.hpp +++ b/include/wrapper/RealTimeBase.hpp @@ -1,169 +1,229 @@ -#pragma once +#pragma once #include -namespace fluid{ -namespace client{ -namespace impl{ - template - struct RealTimeBase - { - using HostVector = FluidTensorView; - using Params = typename Client::ParamSetType; - template - struct doExpectedCount; - - template - struct doExpectedCount - { - static void count(const T& d,FloatControlsIter& c,Result& status) - { - if(!status.ok()) return; - - if(c.remain()) - { - index statedSize = d.fixedSize; - - if(c.remain() < statedSize) - status = {Result::Status::kError,"Ran out of arguments at ", d.name}; - - //fastforward - for(index i=0; i < statedSize; ++i) c.next(); - - } - } - }; - - template - struct doExpectedCount - { - static void count(const T& d,FloatControlsIter& c,Result& status) - { - if(!status.ok()) return; - - if(c.remain()) - { - index statedSize = 1; - - if(c.remain() < statedSize) - status = {Result::Status::kError,"Ran out of arguments at ", d.name}; - - //fastforward - for(index i=0; i < statedSize; ++i) c.next(); - - } - } - }; - template - struct ExpectedCount{ - void operator ()(const T& descriptor,FloatControlsIter& c, Result& status) +namespace fluid { +namespace client { +namespace impl { + + +template +struct RealTimeBase +{ + using IOMapFn = void (RealTimeBase::*)(SCUnit&, Client&); + using HostVector = FluidTensorView; + using Params = typename Client::ParamSetType; + template + struct doExpectedCount; + + template + struct doExpectedCount + { + static void count(const T& d, FloatControlsIter& c, Result& status) + { + if (!status.ok()) return; + + if (c.remain()) { - doExpectedCount::value>::count(descriptor,c,status); + index statedSize = d.fixedSize; + + if (c.remain() < statedSize) + status = {Result::Status::kError, "Ran out of arguments at ", d.name}; + + // fastforward + for (index i = 0; i < statedSize; ++i) c.next(); } - }; + } + }; - Result expectedSize(FloatControlsIter& controls) + template + struct doExpectedCount + { + static void count(const T& d, FloatControlsIter& c, Result& status) { - if(controls.size() < Client::getParameterDescriptors().count()) + if (!status.ok()) return; + + if (c.remain()) { - return {Result::Status::kError,"Fewer parameters than exepected. Got ", controls.size(), "expect at least", Client::getParameterDescriptors().count()}; + index statedSize = 1; + + if (c.remain() < statedSize) + status = {Result::Status::kError, "Ran out of arguments at ", d.name}; + + // fastforward + for (index i = 0; i < statedSize; ++i) c.next(); } - - Result countScan; - Client::getParameterDescriptors().template iterate( - std::forward(controls), - std::forward(countScan)); - return countScan; } + }; + template + struct ExpectedCount + { + void operator()(const T& descriptor, FloatControlsIter& c, Result& status) + { + doExpectedCount::value>::count( + descriptor, c, status); + } + }; - // static index ControlOffset(Unit* unit) { return unit->mSpecialIndex + 1; } - // static index ControlSize(Unit* unit) { return static_cast(unit->mNumInputs) - unit->mSpecialIndex - 1 -(IsModel_t::value ? 1 : 0); } - - void init(SCUnit& unit, Client& client, FloatControlsIter& controls) + Result expectedSize(FloatControlsIter& controls) + { + if (controls.size() < Client::getParameterDescriptors().count()) { - assert(!(client.audioChannelsOut() > 0 && client.controlChannelsOut() > 0) &&"Client can't have both audio and control outputs"); - // consoltr.reset(unit.mInBuf + unit.mSpecialIndex + 1); - client.sampleRate(unit.fullSampleRate()); - mInputConnections.reserve(asUnsigned(client.audioChannelsIn())); - mOutputConnections.reserve(asUnsigned(client.audioChannelsOut())); - mAudioInputs.reserve(asUnsigned(client.audioChannelsIn())); - mOutputs.reserve(asUnsigned( - std::max(client.audioChannelsOut(), client.controlChannelsOut()))); + return {Result::Status::kError, "Fewer parameters than exepected. Got ", + controls.size(), "expect at least", + Client::getParameterDescriptors().count()}; + } + Result countScan; + Client::getParameterDescriptors().template iterate( + std::forward(controls), + std::forward(countScan)); + return countScan; + } - Result r; - if(!(r = expectedSize(controls)).ok()) - { -// mCalcFunc = Wrapper::getInterfaceTable()->fClearUnitOutputs; - std::cout - << "ERROR: " << Wrapper::getName() - << " wrong number of arguments." - << r.message() - << std::endl; - return; - } + void init(SCUnit& unit, Client& client, FloatControlsIter& controls) + { + assert(!(client.audioChannelsOut() > 0 && + client.controlChannelsOut().count > 0) && + "Client can't have both audio and control outputs"); + client.sampleRate(unit.fullSampleRate()); + mInputConnections.reserve(asUnsigned(client.audioChannelsIn())); + mOutputConnections.reserve(asUnsigned(client.audioChannelsOut())); + Result r; + if (!(r = expectedSize(controls)).ok()) + { + std::cout << "ERROR: " << Wrapper::getName() + << " wrong number of arguments." << r.message() << std::endl; + return; + } + if (client.audioChannelsIn()) + { + mAudioInputs.reserve(asUnsigned(client.audioChannelsIn())); for (index i = 0; i < client.audioChannelsIn(); ++i) { mInputConnections.emplace_back(unit.isAudioRateIn(static_cast(i))); mAudioInputs.emplace_back(nullptr, 0, 0); } + mInputMapper = &RealTimeBase::mapAudioInputs; + } + else if (client.controlChannelsIn()) + { + mControlInputBuffer.resize(unit.mSpecialIndex + 1); + mAudioInputs.emplace_back(mControlInputBuffer); + mInputMapper = &RealTimeBase::mapControlInputs; + } + + index outputSize = client.controlChannelsOut().size > 0 + ? std::max(client.audioChannelsOut(), + client.controlChannelsOut().size) + : unit.mSpecialIndex + 1; + mOutputs.reserve(asUnsigned(outputSize)); + if (client.audioChannelsOut()) + { for (index i = 0; i < client.audioChannelsOut(); ++i) { mOutputConnections.emplace_back(true); mOutputs.emplace_back(nullptr, 0, 0); } - - for (index i = 0; i < client.controlChannelsOut(); ++i) - { - mOutputs.emplace_back(nullptr, 0, 0); + + mOutMapperPre = &RealTimeBase::mapAudioOutputs; + mOutMapperPost = &RealTimeBase::mapNoOp; + } + else + { + index totalControlOutputs = + client.controlChannelsOut().count * outputSize; + mControlOutputBuffer.resize(totalControlOutputs); + for (index i = 0; i < client.controlChannelsOut().count; ++i) + { + mOutputs.emplace_back( + mControlOutputBuffer(fluid::Slice(i * outputSize, outputSize))); } - } - - void next(SCUnit& unit, Client& client,Params& params,FloatControlsIter& controls,bool updateParams = true) - { - bool trig = IsModel_t::value ? !mPrevTrig && unit.in0(0) > 0 : false; - - mPrevTrig = trig; - - if(updateParams) - { + + mOutMapperPre = &RealTimeBase::mapNoOp; + mOutMapperPost = &RealTimeBase::mapControlOutputs; + } + } + + void mapNoOp(SCUnit&, Client&) {} + + void mapAudioInputs(SCUnit& unit, Client& client) + { + for (index i = 0; i < client.audioChannelsIn(); ++i) + { + assert(i <= std::numeric_limits::max()); + if (mInputConnections[asUnsigned(i)]) + mAudioInputs[asUnsigned(i)].reset( + const_cast(unit.in(static_cast(i))), 0, + unit.fullBufferSize()); + } + } + + void mapAudioOutputs(SCUnit& unit, Client& client) + { + for (index i = 0; i < client.audioChannelsOut(); ++i) + { + assert(i <= std::numeric_limits::max()); + if (mOutputConnections[asUnsigned(i)]) + mOutputs[asUnsigned(i)].reset(unit.out(static_cast(i)), 0, + unit.fullBufferSize()); + } + } + + void mapControlInputs(SCUnit& unit, Client& client) + { + for (index i = 0; i < unit.mSpecialIndex + 1; ++i) + { + assert(i <= std::numeric_limits::max()); + mControlInputBuffer[asUnsigned(i)] = unit.in0(static_cast(i)); + } + } + + void mapControlOutputs(SCUnit& unit, Client& client) + { + for (index i = 0; i < mControlOutputBuffer.size(); ++i) + { + assert(i <= std::numeric_limits::max()); + unit.out0(static_cast(i)) = mControlOutputBuffer(i); + } + } + + void next(SCUnit& unit, Client& client, Params& params, + FloatControlsIter& controls, bool updateParams = true) + { + bool trig = + IsModel_t::value ? !mPrevTrig && unit.in0(0) > 0 : false; + + mPrevTrig = trig; + + if (updateParams) + { Wrapper::setParams(&unit, params, controls); params.constrainParameterValuesRT(nullptr); - } - - for (index i = 0; i < client.audioChannelsIn(); ++i) - { - assert(i <= std::numeric_limits::max()); - if (mInputConnections[asUnsigned(i)]) - mAudioInputs[asUnsigned(i)].reset(const_cast(unit.in(static_cast(i))), 0,unit.fullBufferSize()); - } - - for (index i = 0; i < client.audioChannelsOut(); ++i) - { - assert(i <= std::numeric_limits::max()); - if (mOutputConnections[asUnsigned(i)]) - mOutputs[asUnsigned(i)].reset(unit.out(static_cast(i)), 0, - unit.fullBufferSize()); - } - - for (index i = 0; i < client.controlChannelsOut(); ++i) - { - assert(i <= std::numeric_limits::max()); - mOutputs[asUnsigned(i)].reset(unit.out(static_cast(i)), 0, 1); - } - client.process(mAudioInputs, mOutputs, mContext); - } - private: - std::vector mInputConnections; - std::vector mOutputConnections; - std::vector mAudioInputs; - std::vector mOutputs; - FluidContext mContext; - bool mPrevTrig; - }; -} -} -} + } + + (this->*mInputMapper)(unit, client); + (this->*mOutMapperPre)(unit, client); + client.process(mAudioInputs, mOutputs, mContext); + (this->*mOutMapperPost)(unit, client); + } + +private: + std::vector mInputConnections; + std::vector mOutputConnections; + std::vector mAudioInputs; + std::vector mOutputs; + FluidTensor mControlInputBuffer; + FluidTensor mControlOutputBuffer; + FluidContext mContext; + bool mPrevTrig; + IOMapFn mInputMapper; + IOMapFn mOutMapperPre; + IOMapFn mOutMapperPost; +}; +} // namespace impl +} // namespace client +} // namespace fluid diff --git a/release-packaging/Classes/FluidKDTree.sc b/release-packaging/Classes/FluidKDTree.sc index 57ef743..8ce1aac 100644 --- a/release-packaging/Classes/FluidKDTree.sc +++ b/release-packaging/Classes/FluidKDTree.sc @@ -1,13 +1,12 @@ -FluidKDTree : FluidRealTimeModel +FluidKDTree : FluidModelObject { - var neighbours,radius,lookup; + var neighbours,radius; - *new{ |server, numNeighbours = 1, radius = 0, lookupDataSet| - ^super.new(server,[numNeighbours,radius,lookupDataSet ? -1]) + *new{ |server, numNeighbours = 1, radius = 0| + ^super.new(server,[numNeighbours,radius ? -1]) .numNeighbours_(numNeighbours) - .radius_(radius) - .lookupDataSet_(lookupDataSet); + .radius_(radius); } numNeighbours_{|k|neighbours = k.asInteger; } @@ -16,10 +15,7 @@ FluidKDTree : FluidRealTimeModel radius_{|r| radius = r.asUGenInput;} radius{ ^radius; } - lookupDataSet_{|ds| lookup = ds ? -1; } - lookupDataSet{|ds| ^ (lookup ? -1) } - - prGetParams{^[this.numNeighbours,this.radius,this.lookupDataSet,-1,-1];} + prGetParams{^[this.id, this.numNeighbours,this.radius];} fitMsg{ |dataSet| ^this.prMakeMsg(\fit,this.id,dataSet.id);} @@ -47,16 +43,26 @@ FluidKDTree : FluidRealTimeModel } kr{|trig, inputBuffer,outputBuffer, numNeighbours = 1, lookupDataSet| - this.numNeighbours_(numNeighbours); +/* this.numNeighbours_(numNeighbours); lookupDataSet = lookupDataSet ? -1; - this.lookupDataSet_(lookupDataSet); + this.lookupDataSet_(lookupDataSet);*/ - ^FluidKDTreeQuery.kr(K2A.ar(trig), - this, this.numNeighbours, this.radius, this.lookupDataSet.asUGenInput, - this.prEncodeBuffer(inputBuffer), - this.prEncodeBuffer(outputBuffer)); + ^FluidKDTreeQuery.kr(trig, + this, numNeighbours, this.radius,lookupDataSet.asUGenInput, + inputBuffer,outputBuffer); } } -FluidKDTreeQuery : FluidRTQuery {} +FluidKDTreeQuery : FluidRTMultiOutUGen +{ + *kr{ |trig, tree, numNeighbours, radius,lookupDataSet, inputBuffer, outputBuffer | + ^this.multiNew('control',trig, tree.asUGenInput, numNeighbours, radius,lookupDataSet!?(_.asUGenInput)??{-1}, inputBuffer.asUGenInput, outputBuffer.asUGenInput) + } + + init { arg ... theInputs; + inputs = theInputs; + ^this.initOutputs(1, rate); + } + +} diff --git a/release-packaging/Classes/FluidKMeans.sc b/release-packaging/Classes/FluidKMeans.sc index 31fda02..ca0a828 100644 --- a/release-packaging/Classes/FluidKMeans.sc +++ b/release-packaging/Classes/FluidKMeans.sc @@ -1,4 +1,4 @@ -FluidKMeans : FluidRealTimeModel { +FluidKMeans : FluidModelObject { var clusters, maxiter; @@ -14,7 +14,7 @@ FluidKMeans : FluidRealTimeModel { maxIter_{|i| maxiter = i.asInteger} maxIter{ ^maxiter } - prGetParams{^[this.numClusters,this.maxIter,-1,-1];} + prGetParams{^[this.id,this.numClusters,this.maxIter];} fitMsg{ |dataSet| ^this.prMakeMsg(\fit,id,dataSet.id);} @@ -111,11 +111,21 @@ FluidKMeans : FluidRealTimeModel { } kr{|trig, inputBuffer,outputBuffer| - ^FluidKMeansQuery.kr(K2A.ar(trig), - this, clusters, maxiter, - this.prEncodeBuffer(inputBuffer), - this.prEncodeBuffer(outputBuffer)); + ^FluidKMeansQuery.kr(trig, + this, + this.prEncodeBuffer(inputBuffer), + this.prEncodeBuffer(outputBuffer)); } } -FluidKMeansQuery : FluidRTQuery {} +FluidKMeansQuery : FluidRTMultiOutUGen { + + *kr{ |trig, model,inputBuffer, outputBuffer | + ^this.multiNew('control',trig, model.asUGenInput,inputBuffer.asUGenInput, outputBuffer.asUGenInput) + } + + init { arg ... theInputs; + inputs = theInputs; + ^this.initOutputs(1, rate); + } +} diff --git a/release-packaging/Classes/FluidKNNClassifier.sc b/release-packaging/Classes/FluidKNNClassifier.sc index 0161bb1..19f8767 100644 --- a/release-packaging/Classes/FluidKNNClassifier.sc +++ b/release-packaging/Classes/FluidKNNClassifier.sc @@ -1,4 +1,4 @@ -FluidKNNClassifier : FluidRealTimeModel { +FluidKNNClassifier : FluidModelObject { var <>numNeighbours, <>weight; @@ -8,7 +8,7 @@ FluidKNNClassifier : FluidRealTimeModel { .weight_(weight); } - prGetParams{^[this.numNeighbours,this.weight,-1,-1];} + prGetParams{^[this.id,this.numNeighbours,this.weight];} fitMsg{|dataSet, labelSet| ^this.prMakeMsg(\fit, id, dataSet.id, labelSet.id) @@ -38,7 +38,7 @@ FluidKNNClassifier : FluidRealTimeModel { } kr{|trig, inputBuffer,outputBuffer| - ^FluidKNNClassifierQuery.kr(K2A.ar(trig), + ^FluidKNNClassifierQuery.kr(trig, this, this.numNeighbours, this.weight, this.prEncodeBuffer(inputBuffer), this.prEncodeBuffer(outputBuffer)); @@ -46,4 +46,17 @@ FluidKNNClassifier : FluidRealTimeModel { } -FluidKNNClassifierQuery : FluidRTQuery {} +FluidKNNClassifierQuery : FluidRTMultiOutUGen { + + *kr{ |trig, model,numNeighbours = 3, weight = 1,inputBuffer, outputBuffer | + ^this.multiNew('control',trig, model.asUGenInput, + numNeighbours,weight, + inputBuffer.asUGenInput, outputBuffer.asUGenInput) + } + + init { arg ... theInputs; + inputs = theInputs; + ^this.initOutputs(1, rate); + } +} + diff --git a/release-packaging/Classes/FluidKNNRegressor.sc b/release-packaging/Classes/FluidKNNRegressor.sc index 8c622a5..b386e2e 100644 --- a/release-packaging/Classes/FluidKNNRegressor.sc +++ b/release-packaging/Classes/FluidKNNRegressor.sc @@ -1,4 +1,4 @@ -FluidKNNRegressor : FluidRealTimeModel { +FluidKNNRegressor : FluidModelObject { var <>numNeighbours, <>weight; @@ -8,7 +8,7 @@ FluidKNNRegressor : FluidRealTimeModel { .weight_(weight); } - prGetParams{^[this.numNeighbours,this.weight,-1,-1];} + prGetParams{^[this.id,this.numNeighbours,this.weight,-1,-1];} fitMsg{|sourceDataSet, targetDataSet| ^this.prMakeMsg(\fit,this.id,sourceDataSet.id,targetDataSet.id) @@ -45,4 +45,16 @@ FluidKNNRegressor : FluidRealTimeModel { } } -FluidKNNRegressorQuery : FluidRTQuery {} +FluidKNNRegressorQuery : FluidRTMultiOutUGen { + + *kr{ |trig, model,numNeighbours = 3, weight = 1,inputBuffer, outputBuffer | + ^this.multiNew('control',trig, model.asUGenInput, + numNeighbours,weight, + inputBuffer.asUGenInput, outputBuffer.asUGenInput) + } + + init { arg ... theInputs; + inputs = theInputs; + ^this.initOutputs(1, rate); + } +} \ No newline at end of file diff --git a/release-packaging/Classes/FluidMLP.sc b/release-packaging/Classes/FluidMLP.sc index 23e5624..1de31a5 100644 --- a/release-packaging/Classes/FluidMLP.sc +++ b/release-packaging/Classes/FluidMLP.sc @@ -1,4 +1,4 @@ -FluidMLPRegressor : FluidRealTimeModel { +FluidMLPRegressor : FluidModelObject { const min, <>max, <>invert; @@ -8,7 +8,7 @@ FluidNormalize : FluidRealTimeModel { } prGetParams{ - ^[this.min,this.max,this.invert,-1,-1]; + ^[this.id, this.min,this.max,this.invert,-1,-1]; } @@ -52,7 +52,7 @@ FluidNormalize : FluidRealTimeModel { this.prSendMsg(this.transformPointMsg(sourceBuffer, destBuffer)); } - kr{|trig, inputBuffer,outputBuffer,min,max,invert| + kr{|trig, inputBuffer,outputBuffer,min = 0 ,max = 1,invert = 0| min = min ? this.min; max = max ? this.max; @@ -60,11 +60,24 @@ FluidNormalize : FluidRealTimeModel { this.min_(min).max_(max).invert_(invert); - ^FluidNormalizeQuery.kr( K2A.ar(trig), - this, this.min, this.max, this.invert, this.prEncodeBuffer(inputBuffer), this.prEncodeBuffer(outputBuffer)); + ^FluidNormalizeQuery.kr(trig, + this, this.prEncodeBuffer(inputBuffer), this.prEncodeBuffer(outputBuffer), this.min, this.max, this.invert); } } -FluidNormalizeQuery : FluidRTQuery {} +FluidNormalizeQuery : FluidRTMultiOutUGen { + + *kr{ |trig, model,inputBuffer,outputBuffer,min = 0 ,max = 1,invert = 0| + inputBuffer.asUGenInput.postln; + ^this.multiNew('control',trig, model.asUGenInput, + min,max,invert, + inputBuffer.asUGenInput, outputBuffer.asUGenInput) + } + + init { arg ... theInputs; + inputs = theInputs; + ^this.initOutputs(1, rate); + } +} \ No newline at end of file diff --git a/release-packaging/Classes/FluidPCA.sc b/release-packaging/Classes/FluidPCA.sc index 20190c5..466b33e 100644 --- a/release-packaging/Classes/FluidPCA.sc +++ b/release-packaging/Classes/FluidPCA.sc @@ -1,4 +1,4 @@ -FluidPCA : FluidRealTimeModel{ +FluidPCA : FluidModelObject{ var <>numDimensions; @@ -7,7 +7,7 @@ FluidPCA : FluidRealTimeModel{ } prGetParams{ - ^[numDimensions,-1,-1]; + ^[this.id, numDimensions]; } fitMsg{|dataSet| @@ -55,9 +55,20 @@ FluidPCA : FluidRealTimeModel{ numDimensions = numDimensions ? this.numDimensions; this.numDimensions_(numDimensions); - ^FluidPCAQuery.kr(K2A.ar(trig),this, this.numDimensions, this.prEncodeBuffer(inputBuffer), this.prEncodeBuffer(outputBuffer)); + ^FluidPCAQuery.kr(trig ,this, this.prEncodeBuffer(inputBuffer), this.prEncodeBuffer(outputBuffer), this.numDimensions); } } -FluidPCAQuery : FluidRTQuery {} +FluidPCAQuery : FluidRTMultiOutUGen { + *kr{ |trig, model, inputBuffer,outputBuffer,numDimensions| + ^this.multiNew('control',trig, model.asUGenInput, + numDimensions, + inputBuffer.asUGenInput, outputBuffer.asUGenInput) + } + + init { arg ... theInputs; + inputs = theInputs; + ^this.initOutputs(1, rate); + } +} \ No newline at end of file diff --git a/release-packaging/Classes/FluidRobustScale.sc b/release-packaging/Classes/FluidRobustScale.sc index 963745b..3e7d34f 100644 --- a/release-packaging/Classes/FluidRobustScale.sc +++ b/release-packaging/Classes/FluidRobustScale.sc @@ -1,4 +1,4 @@ -FluidRobustScale : FluidRealTimeModel { +FluidRobustScale : FluidModelObject { var <>low, <>high, <>invert; @@ -8,7 +8,7 @@ FluidRobustScale : FluidRealTimeModel { } prGetParams{ - ^[this.low,this.high,this.invert,-1,-1]; + ^[this.id,this.low,this.high,this.invert]; } @@ -52,18 +52,27 @@ FluidRobustScale : FluidRealTimeModel { this.prSendMsg(this.transformPointMsg(sourceBuffer, destBuffer)); } - kr{|trig, inputBuffer,outputBuffer,low,high,invert| + kr{|trig, inputBuffer,outputBuffer,invert| - low = low ? this.low; - high = high ? this.high; invert = invert ? this.invert; - this.low_(low).high_(high).invert_(invert); + // this.invert_(invert); - ^FluidRobustScaleQuery.kr(K2A.ar(trig),this, this.low, this.high, this.invert, this.prEncodeBuffer(inputBuffer), this.prEncodeBuffer(outputBuffer)); + ^FluidRobustScaleQuery.kr(trig,this, this.prEncodeBuffer(inputBuffer), this.prEncodeBuffer(outputBuffer), invert,); } } -FluidRobustScaleQuery : FluidRTQuery {} +FluidRobustScaleQuery : FluidRTMultiOutUGen { + *kr{ |trig, model, inputBuffer,outputBuffer,invert| + ^this.multiNew('control',trig, model.asUGenInput, + invert, + inputBuffer.asUGenInput, outputBuffer.asUGenInput) + } + + init { arg ... theInputs; + inputs = theInputs; + ^this.initOutputs(1, rate); + } +} diff --git a/release-packaging/Classes/FluidStandardize.sc b/release-packaging/Classes/FluidStandardize.sc index dca033c..b4127b8 100644 --- a/release-packaging/Classes/FluidStandardize.sc +++ b/release-packaging/Classes/FluidStandardize.sc @@ -1,4 +1,4 @@ -FluidStandardize : FluidRealTimeModel { +FluidStandardize : FluidModelObject { var <>invert; @@ -7,7 +7,7 @@ FluidStandardize : FluidRealTimeModel { } prGetParams{ - ^[this.invert, -1, 1]; + ^[this.id, this.invert]; } fitMsg{|dataSet| @@ -52,8 +52,19 @@ FluidStandardize : FluidRealTimeModel { invert = invert ? this.invert; this.invert_(invert); - ^FluidStandardizeQuery.kr(K2A.ar(trig),this, this.invert, this.prEncodeBuffer(inputBuffer), this.prEncodeBuffer(outputBuffer)); + ^FluidStandardizeQuery.kr(trig,this, this.prEncodeBuffer(inputBuffer), this.prEncodeBuffer(outputBuffer), this.invert); } } -FluidStandardizeQuery : FluidRTQuery {} +FluidStandardizeQuery : FluidRTMultiOutUGen { + *kr{ |trig, model,inputBuffer,outputBuffer,invert = 0| + ^this.multiNew('control',trig, model.asUGenInput, + invert, + inputBuffer.asUGenInput, outputBuffer.asUGenInput) + } + + init { arg ... theInputs; + inputs = theInputs; + ^this.initOutputs(1, rate); + } +} diff --git a/release-packaging/Classes/FluidStats.sc b/release-packaging/Classes/FluidStats.sc new file mode 100644 index 0000000..5447e36 --- /dev/null +++ b/release-packaging/Classes/FluidStats.sc @@ -0,0 +1,51 @@ +FluidStats : MultiOutUGen { + + var numDimensions, <>numNeighbours, <>minDist, <>iterations, <>learnRate; @@ -13,12 +13,12 @@ FluidUMAP : FluidRealTimeModel { prGetParams{ ^[ + this.id, this.numDimensions, this.numNeighbours, this.minDist, this.iterations, this.learnRate, - -1,-1 ] } @@ -68,13 +68,8 @@ FluidUMAP : FluidRealTimeModel { numDimensions = numDimensions ? this.numDimensions; this.numDimensions_(numDimensions); - ^FluidUMAPQuery.kr(K2A.ar(trig), + ^FluidUMAPQuery.kr(trig, this, - this.numDimensions, - this.numNeighbours, - this.minDist, - this.iterations, - this.learnRate, this.prEncodeBuffer(inputBuffer), this.prEncodeBuffer(outputBuffer)); } @@ -84,4 +79,14 @@ FluidUMAP : FluidRealTimeModel { size { |action|} } -FluidUMAPQuery : FluidRTQuery {} +FluidUMAPQuery : FluidRTMultiOutUGen { + *kr{ |trig, model, inputBuffer,outputBuffer| + ^this.multiNew('control',trig, model.asUGenInput, + inputBuffer.asUGenInput, outputBuffer.asUGenInput) + } + + init { arg ... theInputs; + inputs = theInputs; + ^this.initOutputs(1, rate); + } +} diff --git a/src/FluidManipulation/FluidManipulation.cpp b/src/FluidManipulation/FluidManipulation.cpp index 783c5cf..241a2aa 100644 --- a/src/FluidManipulation/FluidManipulation.cpp +++ b/src/FluidManipulation/FluidManipulation.cpp @@ -29,18 +29,43 @@ PluginLoad(FluidSTFTUGen) makeSCWrapper("FluidDataSet",ft); makeSCWrapper("FluidDataSetQuery",ft); makeSCWrapper("FluidLabelSet",ft); - makeSCWrapper("FluidKDTree",ft); - makeSCWrapper("FluidKMeans",ft); - makeSCWrapper("FluidKNNClassifier",ft); - makeSCWrapper("FluidKNNRegressor",ft); - makeSCWrapper("FluidNormalize",ft); - makeSCWrapper("FluidRobustScale",ft); - makeSCWrapper("FluidStandardize",ft); - makeSCWrapper("FluidPCA",ft); + + makeSCWrapper("FluidKDTree",ft); + makeSCWrapper("FluidKDTreeQuery",ft); + + makeSCWrapper("FluidKMeans",ft); + makeSCWrapper("FluidKMeansQuery",ft); + + makeSCWrapper("FluidKNNClassifier",ft); + makeSCWrapper("FluidKNNClassifierQuery",ft); + + makeSCWrapper("FluidKNNRegressor",ft); + makeSCWrapper("FluidKNNRegressorQuery",ft); + + makeSCWrapper("FluidNormalize",ft); + makeSCWrapper("FluidNormalizeQuery",ft); + + makeSCWrapper("FluidRobustScale",ft); + makeSCWrapper("FluidRobustScaleQuery",ft); + + makeSCWrapper("FluidStandardize",ft); + makeSCWrapper("FluidStandardizeQuery",ft); + + makeSCWrapper("FluidPCA",ft); + makeSCWrapper("FluidPCAQuery",ft); + makeSCWrapper("FluidMDS",ft); - makeSCWrapper("FluidUMAP",ft); + + makeSCWrapper("FluidUMAP",ft); + makeSCWrapper("FluidUMAPQuery",ft); + makeSCWrapper("FluidDataSetWr", ft); - makeSCWrapper("FluidMLPRegressor",ft); - makeSCWrapper("FluidMLPClassifier",ft); + + makeSCWrapper("FluidMLPRegressor",ft); + makeSCWrapper("FluidMLPRegressorQuery",ft); + + makeSCWrapper("FluidMLPClassifier",ft); + makeSCWrapper("FluidMLPClassifierQuery",ft); + makeSCWrapper("FluidGrid",ft); } diff --git a/src/FluidStats/CMakeLists.txt b/src/FluidStats/CMakeLists.txt new file mode 100644 index 0000000..711f3d3 --- /dev/null +++ b/src/FluidStats/CMakeLists.txt @@ -0,0 +1,22 @@ +# Part of the Fluid Corpus Manipulation Project (http://www.flucoma.org/) +# Copyright 2017-2019 University of Huddersfield. +# Licensed under the BSD-3 License. +# See license.md file in the project root for full license information. +# This project has received funding from the European Research Council (ERC) +# under the European Union’s Horizon 2020 research and innovation programme +# (grant agreement No 725899). + +cmake_minimum_required(VERSION 3.11) + +get_filename_component(PLUGIN ${CMAKE_CURRENT_LIST_DIR} NAME_WE) +message("Configuring ${PLUGIN}") +set(FILENAME ${PLUGIN}.cpp) + +add_library( + ${PLUGIN} + MODULE + ${FILENAME} +) + + +include(${CMAKE_CURRENT_LIST_DIR}/../../scripts/target_post.cmake) diff --git a/src/FluidStats/FluidStats.cpp b/src/FluidStats/FluidStats.cpp new file mode 100644 index 0000000..6442231 --- /dev/null +++ b/src/FluidStats/FluidStats.cpp @@ -0,0 +1,22 @@ +/* +Part of the Fluid Corpus Manipulation Project (http://www.flucoma.org/) +Copyright 2017-2019 University of Huddersfield. +Licensed under the BSD-3 License. +See license.md file in the project root for full license information. +This project has received funding from the European Research Council (ERC) +under the European Union’s Horizon 2020 research and innovation programme +(grant agreement No 725899). +*/ + +#include + +#include + +static InterfaceTable *ft; + +PluginLoad(FluidStatsUGen) +{ + ft = inTable; + using namespace fluid::client; + makeSCWrapper("FluidStats", ft); +}