From 5496a72a188304029abc305a04e772225a47b176 Mon Sep 17 00:00:00 2001 From: Owen Green Date: Mon, 4 Feb 2019 10:58:37 +0000 Subject: [PATCH] Updates to wrapper for HPSS freq-amp pairs parameter, improved kontrol input handling. Updated object stubs include/FluidSCWrapper.hpp src/FluidBufHPSS/FluidBufHPSS.cpp src/FluidBufNoveltySlice/FluidBufNoveltySlice.cpp src/FluidHPSS/FluidHPSS.cpp --- include/FluidSCWrapper.hpp | 64 ++++++++- src/FluidBufHPSS/FluidBufHPSS.cpp | 97 +------------ .../FluidBufNoveltySlice.cpp | 71 +--------- src/FluidHPSS/FluidHPSS.cpp | 134 +----------------- 4 files changed, 73 insertions(+), 293 deletions(-) diff --git a/include/FluidSCWrapper.hpp b/include/FluidSCWrapper.hpp index 7065455..b7ef1f5 100644 --- a/include/FluidSCWrapper.hpp +++ b/include/FluidSCWrapper.hpp @@ -19,6 +19,7 @@ namespace client { template class FluidSCWrapper; namespace impl { + template struct Setter; template struct ArgumentGetter; template struct ControlGetter; @@ -33,11 +34,33 @@ template Method> struct GetArgument } }; -template struct GetControl + +struct FloatControlsIter { - T operator()(World*, float **controls) { return *controls[N]; } + FloatControlsIter(float** vals, size_t N):mValues(vals), mSize(N) {} + + float next() + { + assert(mCount + 1 < mSize); + return *mValues[mCount++]; + } + + void reset(float** vals) + { + mValues = vals; + mCount = 0; + } + + private: + float** mValues; + size_t mSize; + size_t mCount{0}; }; +template struct GetControl +{ + T operator()(World*, FloatControlsIter& controls) { return controls.next(); } +}; template struct ArgumentGetter : public GetArgument {}; @@ -59,9 +82,38 @@ template struct ArgumentGetter } }; +template struct ArgumentGetter +{ + typename FloatPairsArrayT::type operator()(World* w, sc_msg_iter *args) + { + return {{args->getf(),args->getf()},{args->getf(),args->getf()}}; + } +}; + + + template struct ControlGetter : public GetControl {}; + +template struct ControlGetter +{ + auto operator()(World* w, FloatControlsIter& iter) + { + long bufnum = iter.next(); + return std::unique_ptr(new SCBufferAdaptor(bufnum,w)); + } +}; + +template +struct ControlGetter +{ + typename FloatPairsArrayT::type operator()(World*, FloatControlsIter& iter) + { + return {{iter.next(),iter.next()},{iter.next(),iter.next()}}; + } +}; + //template class RealTime : public SCUnit @@ -72,7 +124,7 @@ template class RealTime : public SCUnit public: static void setup(InterfaceTable *ft, const char *name) { registerUnit(ft, name); } - RealTime() {} + RealTime():mControlsIterator{nullptr,0} {} void init() { @@ -105,7 +157,8 @@ public: { Wrapper *w = static_cast(this); auto &client = w->client(); - w->setParams( mWorld->mVerbosity > 0, mWorld,mInBuf + client.audioChannelsIn()); // forward on inputs N + audio inputs as params + mControlsIterator.reset(mInBuf + client.audioChannelsIn()); + w->setParams( mWorld->mVerbosity > 0, mWorld,mControlsIterator); // forward on inputs N + audio inputs as params const Unit *unit = this; for (int i = 0; i < client.audioChannelsIn(); ++i) { @@ -123,6 +176,7 @@ private: std::vector mOutputConnections; std::vector mAudioInputs; std::vector mAudioOutputs; + FloatControlsIter mControlsIterator; }; template class NonRealTime @@ -292,7 +346,7 @@ public: impl::FluidSCWrapperBase::setup(ft, name); } - auto setParams(bool verbose, World* world, float **inputs) + auto setParams(bool verbose, World* world, impl::FloatControlsIter& inputs) { return mClient.template setParameterValues(verbose, world, inputs); } diff --git a/src/FluidBufHPSS/FluidBufHPSS.cpp b/src/FluidBufHPSS/FluidBufHPSS.cpp index 7e5c774..bc979c0 100644 --- a/src/FluidBufHPSS/FluidBufHPSS.cpp +++ b/src/FluidBufHPSS/FluidBufHPSS.cpp @@ -1,101 +1,14 @@ // FD_BufHPSS, an NRT buffer HPSS Processor // A tool from the FluCoMa project, funded by the European Research Council (ERC) under the European Union’s Horizon 2020 research and innovation programme (grant agreement No 725899) -#include "fdNRTBase.hpp" -#include "algorithms/STFT.hpp" -#include "data/FluidTensor.hpp" -#include "clients/nrt/HPSS.hpp" -#include "clients/common/FluidParams.hpp" -#include "SC_PlugIn.h" -#include -#include +#include +#include +#include static InterfaceTable *ft; -//Using statements for fluidtensor -using fluid::FluidTensor; -using fluid::FluidTensorView; - -namespace fluid { - namespace wrapper{ - - class BufHPSS: public NRTCommandBase - { - /* - - srcbuf num - – src start frame - - src numframes - – src start chan - – src num chans - – harms dst - – perc dst - – window size - – hop size - – fft size - */ - public: - using client_type = client::HPSSClient; - using NRTCommandBase::NRTCommandBase; - - ~BufHPSS() {} - - void runCommand(World* world, void* replyAddr, char* completionMsgData, size_t completionMsgSize) - { - cmd(world, "/BufHPSS", replyAddr, completionMsgData, completionMsgSize); - } - - bool process(World* world) - { - //sanity check the parameters - bool parametersOk; - client::HPSSClient::ProcessModel processModel; - std::string whatHappened;//this will give us a message to pass back if param check fails - std::tie(parametersOk,whatHappened,processModel) = processor.sanityCheck(); - if(!parametersOk) - { - Print("fdHPSS: %s \n", whatHappened.c_str()); - return false; - } - //Now, we can proceed - processor.process(processModel); - mModel = processModel; - return true; - } - - bool postProcess(World* world) - { - static_cast(mModel.harm)->assignToRT(world); - static_cast(mModel.perc)->assignToRT(world); - - if(mModel.res) - static_cast(mModel.res)->assignToRT(world); - - return true; - } - - bool postComplete(World*) { - static_cast(mModel.harm)->cleanUp(); - static_cast(mModel.perc)->cleanUp(); - if(mModel.res) - static_cast(mModel.res)->cleanUp(); - return true; - } - - - std::vector& parameters() - { - return processor.getParams(); - } - private: - client::HPSSClient processor; - client::HPSSClient::ProcessModel mModel; - };//class - } //namespace wrapper -}//namespace fluid - - PluginLoad(OfflineFluidDecompositionUGens) { ft = inTable; - registerCommand(ft, "BufHPSS"); - fluid::wrapper::printCmd(ft,"BufHPSS","FDHPSS"); + using namespace fluid::client; + makeSCWrapper>>(ft, "BufHPSS"); } diff --git a/src/FluidBufNoveltySlice/FluidBufNoveltySlice.cpp b/src/FluidBufNoveltySlice/FluidBufNoveltySlice.cpp index 7950753..206b5e2 100644 --- a/src/FluidBufNoveltySlice/FluidBufNoveltySlice.cpp +++ b/src/FluidBufNoveltySlice/FluidBufNoveltySlice.cpp @@ -2,74 +2,13 @@ // A tool from the FluCoMa project, funded by the European Research Council (ERC) under the European Union’s Horizon 2020 research and innovation programme (grant agreement No 725899) -#include "clients/nrt/NoveltyClient.hpp" -#include "fdNRTBase.hpp" -#include "data/FluidTensor.hpp" -#include "clients/common/FluidParams.hpp" -//#include "SC_PlugIn.h" -//#include -//#include - -static InterfaceTable *ft; - -namespace fluid { - namespace wrapper{ - - class BufNoveltySlice: public NRTCommandBase - { - public: - using client_type = client::NoveltyClient; - using NRTCommandBase::NRTCommandBase; - - ~BufNoveltySlice() {} - - void runCommand(World* world, void* replyAddr, char* completionMsgData, size_t completionMsgSize) - { - cmd(world, "/BufNoveltySlice", replyAddr, completionMsgData, completionMsgSize); - } - - bool process(World* world) - { - //sanity check the parameters - bool parametersOk; - client_type::ProcessModel processModel; - std::string whatHappened;//this will give us a message to pass back if param check fails - std::tie(parametersOk,whatHappened,processModel) = trans.sanityCheck(); - if(!parametersOk) - { - Print("FluidBufNovletySlice: %s \n", whatHappened.c_str()); - return false; - } - trans.process(processModel); - mModel = processModel; - return true; - } - - bool postProcess(World* world) - { - static_cast(mModel.indices)->assignToRT(world); - return true; - } - - bool postComplete(World*) { - static_cast(mModel.indices)->cleanUp(); - return true; - } - - std::vector& parameters() - { - return trans.getParams(); - } - private: - client_type trans; - client_type::ProcessModel mModel; - };//class - } //namespace wrapper -}//namespace fluid +#include +#include +static InterfaceTable* ft; PluginLoad(OfflineFluidDecompositionUGens) { ft = inTable; - registerCommand(ft, "BufNoveltySlice"); - fluid::wrapper::printCmd(ft,"BufNoveltySlice","FluidBufNoveltySlice"); + using namespace fluid::client; + makeSCWrapper(ft, "BufNoveltySlice"); } diff --git a/src/FluidHPSS/FluidHPSS.cpp b/src/FluidHPSS/FluidHPSS.cpp index 015e5ba..1b779e5 100644 --- a/src/FluidHPSS/FluidHPSS.cpp +++ b/src/FluidHPSS/FluidHPSS.cpp @@ -1,140 +1,14 @@ // A tool from the FluCoMa project, funded by the European Research Council (ERC) under the European Union’s Horizon 2020 research and innovation programme (grant agreement No 725899) - -#include "SC_PlugIn.hpp" -#include "data/FluidTensor.hpp" -#include "clients/rt/HPSSClient.hpp" +#include +#include static InterfaceTable *ft; -namespace fluid { -namespace wrapper{ - class FDRTHPSS: public SCUnit - { - using AudioSignalWrapper = client::HPSSClient::AudioSignal; - using SignalWrapper = client::HPSSClient::Signal; - using SignalPointer = std::unique_ptr; - using ClientPointer = std::unique_ptr>; - template - using SignalArray = std::array; - public: - FDRTHPSS() - { - //Order of args - //psize hszie pthresh hthresh Window size, Hop size, FFT Size - - //Oh NO! Heap allocation! Make client object - mClient = ClientPointer(new client::HPSSClient(65536)); - - setParams(true); - - bool isOK; - std::string feedback; - - std::tie(isOK, feedback) = mClient->sanityCheck(); - if(!isOK) - { - Print("fdRTHPSS Error: %s",feedback.c_str()); - return; - } - - - mClient->setHostBufferSize(bufferSize()); - mClient->reset(); - - //Work out what signals we need. For now keep it simple: - inputSignals[0] = SignalPointer(new AudioSignalWrapper()); - outputSignals[0] = SignalPointer(new AudioSignalWrapper()); - outputSignals[1] = SignalPointer(new AudioSignalWrapper()); - outputSignals[2] = SignalPointer(new AudioSignalWrapper()); - - mCalcFunc = make_calc_function(); - Unit* unit = this; - ClearUnitOutputs(unit,1); - } - - ~FDRTHPSS() {} - - private: - - void setParams(bool instantiation) - { - assert(mClient); - for(size_t i = 0; i < mClient->getParams().size(); ++i) - { - client::Instance& p = mClient->getParams()[i]; - if(!instantiation && p.getDescriptor().instantiation()) - continue; - switch(p.getDescriptor().getType()) - { - case client::Type::kLong: - p.setLong(in0(i + 1)); - p.checkRange(); - break; - case client::Type::kFloat: { - - // We need to constrain threshold (normalised) frequency pairs at - // runtime. - std::string attrname = p.getDescriptor().getName(); - auto constraint = paramConstraints.find(attrname); - - if (constraint != paramConstraints.end()) { - double limit = client::lookupParam(constraint->second.param, - mClient->getParams()) - .getFloat(); - - if (!constraint->second.condition(in0(i + 1), limit)) { - return; - } - } - - p.setFloat(in0(i + 1)); - p.checkRange(); - } - break; - case client::Type::kBuffer: - // p.setBuffer( in0(i+1)); - break; - default: - break; - } - } - } - - void next(int numsamples) - { - setParams(false); - const float* input = in(0); - const float inscalar = in0(0); - inputSignals[0]->set(const_cast(input), inscalar); - outputSignals[0]->set(out(0), out0(0)); - outputSignals[1]->set(out(1), out0(1)); - outputSignals[2]->set(out(2), out0(2)); - mClient->doProcess(std::begin(inputSignals),std::end(inputSignals),std::begin(outputSignals), std::end(outputSignals),numsamples,1,3); - } - - struct Constraint{ - std::string param; - std::function condition; - }; - - std::map paramConstraints{ - {"ptf1",{"ptf2", std::less()}}, - {"htf1",{"htf2", std::less()}}, - {"ptf2",{"ptf1", std::greater()}}, - {"htf2",{"htf1", std::greater()}} - }; - - - ClientPointer mClient; - SignalArray<1> inputSignals; - SignalArray<3> outputSignals; - }; -} -} PluginLoad(FluidSTFTUGen) { ft = inTable; - registerUnit(ft, "FluidHPSS"); + using namespace fluid::client; + makeSCWrapper>(ft, "FluidHPSS"); }