From 7fbaf8fdabdaa80f8f3f4e1ebde73894660162ad Mon Sep 17 00:00:00 2001 From: tremblap Date: Mon, 4 Sep 2023 21:53:19 +0100 Subject: [PATCH] Feature/add multiple out support to kr (#164) * Tag release to correct commit * release: delete pre-existing * almost working class def and no difference to the wrapper * removed the print outs and added size check of the inputs - still not sure how I get that shape of output when it should be 3 of in.asArray.size * input shape now working * correct input count division (was the wrong way round) * computes the real size of the input to decline the output size * and finally a working class. We're all set! * troubleshooting prints all over * new proper class for proper algo * remove the debugging pritns * clang-format-ed * pre-clang-format * clang-format-ed with the right style sheet --------- Co-authored-by: Owen Green --- include/FluidSCWrapper.hpp | 92 +++++++++++++++----------------- include/wrapper/RealTimeBase.hpp | 58 ++++++++++++-------- 2 files changed, 81 insertions(+), 69 deletions(-) diff --git a/include/FluidSCWrapper.hpp b/include/FluidSCWrapper.hpp index b7285127..331cbc23 100644 --- a/include/FluidSCWrapper.hpp +++ b/include/FluidSCWrapper.hpp @@ -24,10 +24,10 @@ template class FluidSCWrapper : public impl::FluidSCWrapperBase { using FloatControlsIter = impl::FloatControlsIter; - - //I would like to template these to something more scaleable, but baby steps - friend class impl::RealTime; - friend class impl::NonRealTime; + + // I would like to template these to something more scaleable, but baby steps + friend class impl::RealTime; + friend class impl::NonRealTime; static void doVersion(Unit*, sc_msg_iter*) { @@ -38,12 +38,14 @@ class FluidSCWrapper : public impl::FluidSCWrapperBase bool mInit{false}; public: - template - using ArgumentSetter = typename ClientParams::template Setter; + using ArgumentSetter = + typename ClientParams::template Setter; template - using ControlSetter = typename ClientParams::template Setter; + using ControlSetter = + typename ClientParams::template Setter; using Client = C; using ParamSetType = typename C::ParamSetType; @@ -66,14 +68,14 @@ class FluidSCWrapper : public impl::FluidSCWrapperBase getInterfaceTable(ft); impl::FluidSCWrapperBase::setup(ft, name); ft->fDefineUnitCmd(name, "version", doVersion); - + std::string commandName("/"); commandName += getName(); commandName += "/version"; - ft->fDefinePlugInCmd(commandName.c_str(), - [](World*, void*, sc_msg_iter*, void*){ doVersion(nullptr,nullptr); }, - nullptr); - + ft->fDefinePlugInCmd( + commandName.c_str(), + [](World*, void*, sc_msg_iter*, void*) { doVersion(nullptr, nullptr); }, + nullptr); } static auto& setParams(Unit* x, ParamSetType& p, FloatControlsIter& inputs, @@ -81,58 +83,52 @@ class FluidSCWrapper : public impl::FluidSCWrapperBase bool initialized = true) { bool verbose = x->mWorld->mVerbosity > 0; - + using Reportage = decltype(static_cast(x)->mReportage); - - Reportage* reportage = initialized ? &(static_cast(x)->mReportage) : new Reportage(); + + Reportage* reportage = initialized + ? &(static_cast(x)->mReportage) + : new Reportage(); p.template setParameterValuesRT( verbose ? reportage : nullptr, x, inputs, p, alloc); if (constrain) p.constrainParameterValuesRT(verbose ? reportage : nullptr); - if(verbose) + if (verbose) { - for(auto& r:*reportage) + for (auto& r : *reportage) { - if(!r.ok()) printResult(x->mParent->mNode.mWorld, r); + if (!r.ok()) printResult(x->mParent->mNode.mWorld, r); } } - if(!initialized) delete reportage; + if (!initialized) delete reportage; return p; } -// static void printResult(SharedState& x, Result& r) -// { -// if (!x.get() || !x->mNodeAlive) return; -// FluidSCWrapper::printResult(x->mNode->mWorld, r); -// } - - static void printResult(World* w,Result& r) + static void printResult(World* w, Result& r) { - + switch (r.status()) { - case Result::Status::kWarning: - { - if (!w || w->mVerbosity > 0) - std::cout << "WARNING: " << getName() << " - " << r.message().c_str() << '\n'; - break; - } - case Result::Status::kError: - { - std::cout << "ERROR: " << getName() << " - " << r.message().c_str() << '\n'; - break; - } - case Result::Status::kCancelled: - { - std::cout << getName() << ": Task cancelled\n" << '\n'; - break; - } - default: - { - } - } + case Result::Status::kWarning: { + if (!w || w->mVerbosity > 0) + std::cout << "WARNING: " << getName() << " - " << r.message().c_str() + << '\n'; + break; + } + case Result::Status::kError: { + std::cout << "ERROR: " << getName() << " - " << r.message().c_str() + << '\n'; + break; + } + case Result::Status::kCancelled: { + std::cout << getName() << ": Task cancelled\n" << '\n'; + break; + } + default: { + } + } } - + private: std::array mReportage; }; diff --git a/include/wrapper/RealTimeBase.hpp b/include/wrapper/RealTimeBase.hpp index ffeb5c78..59e6654d 100644 --- a/include/wrapper/RealTimeBase.hpp +++ b/include/wrapper/RealTimeBase.hpp @@ -1,8 +1,8 @@ #pragma once +#include #include #include -#include namespace fluid { namespace client { @@ -82,9 +82,10 @@ struct RealTimeBase std::forward(countScan)); return countScan; } - - void init(SCUnit& unit, Client& client, FloatControlsIter& controls, Allocator& alloc) + + void init(SCUnit& unit, Client& client, FloatControlsIter& controls, + Allocator& alloc) { assert(!(client.audioChannelsOut() > 0 && client.controlChannelsOut().count > 0) && @@ -92,7 +93,7 @@ struct RealTimeBase client.sampleRate(unit.fullSampleRate()); mInputConnections.reserve(asUnsigned(client.audioChannelsIn())); mOutputConnections.reserve(asUnsigned(client.audioChannelsOut())); - mContext = FluidContext(unit.fullBufferSize(), alloc); + mContext = FluidContext(unit.fullBufferSize(), alloc); Result r; if (!(r = expectedSize(controls)).ok()) { @@ -113,16 +114,22 @@ struct RealTimeBase } else if (client.controlChannelsIn()) { - mControlInputBuffer.resize(unit.mSpecialIndex + 1); - mAudioInputs.emplace_back(mControlInputBuffer); + mControlInputBuffer.resize(client.controlChannelsIn(), + (unit.mSpecialIndex + 1) / + client.controlChannelsIn()); + for (index i = 0; i < client.controlChannelsIn(); ++i) + { + mAudioInputs.emplace_back(mControlInputBuffer.row(i)); + } mInputMapper = &RealTimeBase::mapControlInputs; } - else mInputMapper = &RealTimeBase::mapNoOp; + else { mInputMapper = &RealTimeBase::mapNoOp; } index outputSize = client.controlChannelsOut().size > 0 ? std::max(client.audioChannelsOut(), client.maxControlChannelsOut()) - : unit.mSpecialIndex + 1; + : (unit.mSpecialIndex + 1); + mOutputs.reserve(asUnsigned(outputSize)); if (client.audioChannelsOut()) @@ -132,7 +139,7 @@ struct RealTimeBase mOutputConnections.emplace_back(true); mOutputs.emplace_back(nullptr, 0, 0); } - + mOutMapperPre = &RealTimeBase::mapAudioOutputs; mOutMapperPost = &RealTimeBase::mapNoOp; } @@ -177,19 +184,28 @@ struct RealTimeBase } } - void mapControlInputs(SCUnit& unit, Client&) + void mapControlInputs(SCUnit& unit, Client& client) { - for (index i = 0; i < unit.mSpecialIndex + 1; ++i) + assert((unit.mSpecialIndex + 1) % client.controlChannelsIn() == 0 && + "Control channels can't be mapped"); + index itemsPerChannel = + (unit.mSpecialIndex + 1) / client.controlChannelsIn(); + for (index i = 0, offset = 0; i < client.controlChannelsIn(); + ++i, offset += itemsPerChannel) { - assert(i <= std::numeric_limits::max()); - mControlInputBuffer[i] = unit.in0(static_cast(i)); + for (index j = 0; j < itemsPerChannel; ++j) + { + assert(j <= std::numeric_limits::max()); + mControlInputBuffer(i, j) = unit.in0(static_cast(offset + j)); + } } } void mapControlOutputs(SCUnit& unit, Client&) { - index numOuts = std::min(mControlOutputBuffer.size(),unit.mNumOutputs); - + index numOuts = + std::min(mControlOutputBuffer.size(), unit.mNumOutputs); + for (index i = 0; i < numOuts; ++i) { assert(i <= std::numeric_limits::max()); @@ -205,9 +221,9 @@ struct RealTimeBase IsModel_t::value ? !mPrevTrig && unit.in0(0) > 0 : false; mPrevTrig = trig; - #ifdef EIGEN_RUNTIME_NO_MALLOC +#ifdef EIGEN_RUNTIME_NO_MALLOC Eigen::internal::set_is_malloc_allowed(false); - #endif +#endif if (updateParams) { Wrapper::setParams(&unit, params, controls, alloc); @@ -218,9 +234,9 @@ struct RealTimeBase (this->*mOutMapperPre)(unit, client); client.process(mAudioInputs, mOutputs, mContext); (this->*mOutMapperPost)(unit, client); - #ifdef EIGEN_RUNTIME_NO_MALLOC - Eigen::internal::set_is_malloc_allowed(true); //not really - #endif +#ifdef EIGEN_RUNTIME_NO_MALLOC + Eigen::internal::set_is_malloc_allowed(true); // not really +#endif } private: @@ -228,7 +244,7 @@ struct RealTimeBase std::vector mOutputConnections; std::vector mAudioInputs; std::vector mOutputs; - FluidTensor mControlInputBuffer; + FluidTensor mControlInputBuffer; FluidTensor mControlOutputBuffer; bool mPrevTrig; IOMapFn mInputMapper;