#pragma once #include "ArgsFromClient.hpp" #include "Meta.hpp" #include "RealTimeBase.hpp" #include "SCWorldAllocator.hpp" #include #include // Real Time Processor namespace fluid { namespace client { namespace impl { template class RealTime : public SCUnit { using Delegate = impl::RealTimeBase; using Params = typename Client::ParamSetType; public: // static index ControlOffset(Unit* unit) { return Delegate::ControlOffset(unit); } // static index ControlSize(Unit* unit) { return Delegate::ControlSize(unit); } 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); } static void setup(InterfaceTable* ft, const char* name) { registerUnit(ft,name); ft->fDefineUnitCmd(name, "latency", doLatency); } static void doLatency(Unit* unit, sc_msg_iter*) { float l[]{ static_cast(static_cast(unit)->mClient.latency()) }; auto ft = Wrapper::getInterfaceTable(); std::stringstream ss; ss << '/' << Wrapper::getName() << "_latency"; // std::cout << ss.str() << ": " << l[0] << std::endl; ft->fSendNodeReply(&unit->mParent->mNode, -1, ss.str().c_str(), 1, l); } RealTime() : mSCAlloc{mWorld, Wrapper::getInterfaceTable()}, mAlloc{foonathan::memory::make_allocator_reference(mSCAlloc)}, mContext{fullBufferSize(), mAlloc}, mControls{mInBuf + ControlOffset(this),ControlSize(this)}, mParams{Client::getParameterDescriptors(), mAlloc}, mClient{Wrapper::setParams(this, mParams, mControls, mAlloc,true), mContext} { init(); } void init() { mDelegate.init(*this,mClient,mControls,mAlloc); mCalcFunc = make_calc_function(); Wrapper::getInterfaceTable()->fClearUnitOutputs(this, 1); } void next(int) { mControls.reset(mInBuf + ControlOffset(this)); mDelegate.next(*this,mClient,mParams,mControls, mAlloc); } private: SCRawAllocator mSCAlloc; Allocator mAlloc; FluidContext mContext; Delegate mDelegate; FloatControlsIter mControls; Params mParams; Client mClient; Wrapper* mWrapper{static_cast(this)}; }; } } }