nix
weefuzzy 3 years ago
commit 2461167499

@ -11,7 +11,7 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
################################################################################
# Paths
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/install" CACHE PATH "")
@ -89,7 +89,7 @@ include(flucoma-buildtools)
include(flucoma-buildtype)
# endif()
option(DOCS "Generate scdocs" OFF)
option(DOCS "Generate scdocs" ON)
set(FLUID_DOCS_PATH "" CACHE PATH "Optional path to flucoma-docs (needed for docs); will download if absent")
if(DOCS)

@ -76,8 +76,9 @@ public:
}
static auto& setParams(Unit* x, ParamSetType& p,
FloatControlsIter& inputs, bool constrain = false, bool initialized = true)
static auto& setParams(Unit* x, ParamSetType& p, FloatControlsIter& inputs,
Allocator& alloc, bool constrain = false,
bool initialized = true)
{
bool verbose = x->mWorld->mVerbosity > 0;
@ -85,7 +86,7 @@ public:
Reportage* reportage = initialized ? &(static_cast<FluidSCWrapper*>(x)->mReportage) : new Reportage();
p.template setParameterValuesRT<ControlSetter>(verbose ? reportage: nullptr , x, inputs);
p.template setParameterValuesRT<ControlSetter>(verbose ? reportage: nullptr , x, inputs, alloc);
if (constrain) p.constrainParameterValuesRT(verbose ? reportage : nullptr);
if(verbose)
{

@ -46,12 +46,12 @@ public:
static constexpr auto &getParameterDescriptors() { return DataSetWrParams; }
DataSetWriterClient(ParamSetViewType &p) : mParams(p) {}
DataSetWriterClient(ParamSetViewType &p, FluidContext&) : mParams(p) {}
template <typename T> Result process(FluidContext &) {
auto dataset = get<kDataSet>().get();
if (auto datasetPtr = dataset.lock()) {
std::string &idPrefix = get<kIDPrefix>();
std::string idPrefix = std::string(get<kIDPrefix>());
auto &idNumberArr = get<kIDNumber>();
if (idNumberArr.size() != 2)
return {Result::Status::kError, "ID number malformed"};

@ -1,6 +1,8 @@
#pragma once
#include "Meta.hpp"
#include <data/FluidMemory.hpp>
#include <fmt/format.h>
namespace fluid {
namespace client {
@ -40,7 +42,11 @@ struct ParamReader<impl::FloatControlsIter>
using Controls = impl::FloatControlsIter;
static auto fromArgs(Unit* /*x*/, Controls& args, std::string, int)
/// todo: fix std::string to use a specialisation with RT alloc
template <typename Alloc>
static auto
fromArgs(Unit* /*x*/, Controls& args,
std::basic_string<char, std::char_traits<char>, Alloc> const&, int)
{
// first is string size, then chars
index size = static_cast<index>(args.next());
@ -57,7 +63,8 @@ struct ParamReader<impl::FloatControlsIter>
using Container = typename LongArrayT::type;
using Value = typename Container::type;
index size = static_cast<index>(args.next());
Container res(size);
/// todo: fix allocator
Container res(size, FluidDefaultAllocator());
for (index i = 0; i < size; ++i)
res[i] = static_cast<Value>(args.next());
return res;
@ -225,7 +232,8 @@ struct ParamReader<sc_msg_iter>
return argTypeOK(T{},tag);
}
static auto fromArgs(World*, sc_msg_iter& args, std::string, int)
template<typename Alloc>
static auto fromArgs(World*, sc_msg_iter& args, std::basic_string<char,std::char_traits<char>,Alloc> const&, int)
{
const char* recv = args.gets("");
@ -285,7 +293,7 @@ struct ParamReader<sc_msg_iter>
using Container = typename LongArrayT::type;
using Value = typename Container::type;
index size = static_cast<index>(args.geti());
Container res(size);
Container res(size, FluidDefaultAllocator());
for (index i = 0; i < size; ++i)
res[i] = static_cast<Value>(args.geti());
return res;
@ -325,14 +333,14 @@ struct ClientParams{
template<typename Context, typename Client = typename Wrapper::Client, size_t Number = N>
std::enable_if_t<!impl::IsNamedShared_v<Client> || Number!=0, typename T::type>
operator()(Context* x, ArgType& args)
operator()(Context* x, ArgType& args, Allocator& alloc)
{
// Just return default if there's nothing left to grab
if (args.remain() == 0)
{
std::cout << "WARNING: " << Wrapper::getName()
<< " received fewer parameters than expected\n";
return Wrapper::Client::getParameterDescriptors().template makeValue<N>();
return Wrapper::Client::getParameterDescriptors().template makeValue<N>(alloc);
}
ParamLiteralConvertor<T, argSize> a;
@ -348,18 +356,25 @@ struct ClientParams{
template<typename Context, typename Client = typename Wrapper::Client, size_t Number = N>
std::enable_if_t<impl::IsNamedShared_v<Client> && Number==0, typename T::type>
operator()(Context* x, ArgType& args)
operator()(Context* x, ArgType& args, Allocator& alloc)
{
// Just return default if there's nothing left to grab
if (args.remain() == 0)
{
std::cout << "WARNING: " << Wrapper::getName()
<< " received fewer parameters than expected\n";
return Wrapper::Client::getParameterDescriptors().template makeValue<N>();
return Wrapper::Client::getParameterDescriptors().template makeValue<N>(alloc);
}
index id = ParamReader<ArgType>::fromArgs(x,args,index{},0);
return std::to_string(id);
using StdAlloc = foonathan::memory::std_allocator<char, Allocator>;
using fmt_memory_buffer =
fmt::basic_memory_buffer<char, fmt::inline_buffer_size, StdAlloc>;
auto buf = fmt_memory_buffer(alloc);
std::string_view fmt_string("{}");
fmt::vformat_to(std::back_inserter(buf), fmt_string,
fmt::make_format_args(id));
return rt::string(buf.data(), buf.size(), alloc);
}
};

@ -1,5 +1,7 @@
#pragma once
#include <data/FluidMemory.hpp>
namespace fluid {
namespace client {
@ -15,12 +17,12 @@ namespace client {
return 1;
}
static index allocSize(std::string s)
static index allocSize(std::string const& s)
{
return asSigned(s.size()) + 1;
} // put null char at end when we send
static index allocSize(FluidTensor<std::string, 1> s)
static index allocSize(FluidTensor<std::string, 1> const& s)
{
index count = 0;
for (auto& str : s) count += (str.size() + 1);
@ -28,7 +30,7 @@ namespace client {
}
template <typename T>
static index allocSize(FluidTensor<T, 1> s)
static index allocSize(FluidTensor<T, 1> const& s)
{
return s.size();
}
@ -68,12 +70,12 @@ namespace client {
f[0] = static_cast<float>(x);
}
static void convert(float* f, std::string s)
static void convert(float* f, std::string const& s)
{
std::copy(s.begin(), s.end(), f);
f[s.size()] = 0; // terminate
}
static void convert(float* f, FluidTensor<std::string, 1> s)
static void convert(float* f, FluidTensor<std::string, 1> const& s)
{
for (auto& str : s)
{
@ -83,7 +85,7 @@ namespace client {
}
}
template <typename T>
static void convert(float* f, FluidTensor<T, 1> s)
static void convert(float* f, FluidTensor<T, 1> const& s)
{
static_assert(std::is_convertible<T, float>::value,
"Can't convert this to float output");
@ -114,19 +116,24 @@ namespace client {
return 1;
}
static index numTags(std::string)
static index numTags(rt::string const&)
{
return 1;;
}
static index numTags(std::string const&)
{
return 1;;
}
template <typename T>
static index numTags(FluidTensor<T, 1> s)
static index numTags(FluidTensor<T, 1> const& s)
{
return s.size();
}
template <typename... Ts>
static index numTags(std::tuple<Ts...>&& t)
static index numTags(std::tuple<Ts...> const& t)
{
index count = 0;
ForEach(t,[&count](auto& x){ count += numTags(x);});
@ -143,10 +150,11 @@ namespace client {
static std::enable_if_t<std::is_floating_point<std::decay_t<T>>::value>
getTag(Packet& p, T&&) { p.addtag('f'); }
static void getTag (Packet& p, std::string) { p.addtag('s'); }
static void getTag (Packet& p, std::string const&) { p.addtag('s'); }
static void getTag (Packet& p, rt::string const&) { p.addtag('s'); }
template <typename T>
static void getTag(Packet& p, FluidTensor<T, 1> x)
static void getTag(Packet& p, FluidTensor<T, 1> const& x)
{
T dummy{};
for (int i = 0; i < x.rows(); i++)
@ -154,7 +162,7 @@ namespace client {
}
template <typename... Ts>
static void getTag(Packet& p, std::tuple<Ts...>&& t)
static void getTag(Packet& p, std::tuple<Ts...> const& t)
{
ForEach(t,[&p](auto& x){getTag(p,x);});
}
@ -179,19 +187,24 @@ namespace client {
p.addf(static_cast<float>(x));
}
static void convert(Packet& p, std::string s)
static void convert(Packet& p, std::string const& s)
{
p.adds(s.c_str());
}
static void convert(Packet& p, rt::string const& s)
{
p.adds(s.c_str());
}
template <typename T>
static void convert(Packet& p, FluidTensor<T, 1> s)
static void convert(Packet& p, FluidTensor<T, 1> const& s)
{
for(auto& x: s) convert(p,x);
}
template <typename... Ts>
static void convert(Packet& p, std::tuple<Ts...>&& t)
static void convert(Packet& p, std::tuple<Ts...> const& t)
{
ForEach(t,[&p](auto& x){ convert(p,x);});
}

@ -154,7 +154,7 @@ public:
static void refreshParams(Params& p, MessageResult<ParamValues>& r)
{
p.fromTuple(ParamValues(r));
p.fromTuple(r.value());
}
template<typename T>
@ -253,7 +253,7 @@ public:
template <typename T> // call from RT
static void messageOutput(const std::string& s, index id, MessageResult<T>& result, void* replyAddr)
{
index numTags = ToOSCTypes<small_scpacket>::numTags(static_cast<T>(result));
index numTags = ToOSCTypes<small_scpacket>::numTags(result.value());
if(numTags > 2048)
{
std::cout << "ERROR: Message response too big to send (" << asUnsigned(numTags) * sizeof(float) << " bytes)." << std::endl;
@ -290,9 +290,7 @@ public:
template <typename... Ts>
static void messageOutput(const std::string& s, index id, MessageResult<std::tuple<Ts...>>& result, void* replyAddr)
{
using T = std::tuple<Ts...>;
index numTags = ToOSCTypes<small_scpacket>::numTags(static_cast<T>(result));
index numTags = ToOSCTypes<small_scpacket>::numTags(result.value());
if(numTags > 2048)
{
std::cout << "ERROR: Message response too big to send (" << asUnsigned(numTags) * sizeof(float) << " bytes)." << std::endl;
@ -304,10 +302,10 @@ public:
packet.maketags(static_cast<int>(numTags + 2));
packet.addtag(',');
packet.addtag('i');
ToOSCTypes<small_scpacket>::getTag(packet,static_cast<T>(result));
ToOSCTypes<small_scpacket>::getTag(packet,result.value());
packet.addi(static_cast<int>(id));
ToOSCTypes<small_scpacket>::convert(packet, static_cast<T>(result));
ToOSCTypes<small_scpacket>::convert(packet, result.value());
if(replyAddr)
SendReply(replyAddr,packet.data(),static_cast<int>(packet.size()));

@ -42,7 +42,8 @@ private:
/// Instance cache
struct CacheEntry
{
CacheEntry(const Params& p) : mParams{p}, mClient{mParams} {}
CacheEntry(const Params& p, FluidContext c)
: mParams{p}, mClient{mParams, c} {}
Params mParams;
Client mClient;
@ -151,11 +152,11 @@ public:
return lookup == mCache.end() ? WeakCacheEntryPointer() : lookup->second;
}
static WeakCacheEntryPointer add(World* world, index id, const Params& params)
static WeakCacheEntryPointer add(World* world, index id, const Params& params, FluidContext context)
{
if (isNull(get(id)))
{
auto result = mCache.emplace(id, std::make_shared<CacheEntry>(params));
auto result = mCache.emplace(id, std::make_shared<CacheEntry>(params, context));
addToRTCache{}(world, *(result.first));
@ -199,8 +200,10 @@ private:
struct NRTCommand
{
NRTCommand(World*, sc_msg_iter* args, void* replyAddr,
NRTCommand(World* world, sc_msg_iter* args, void* replyAddr,
bool consumeID = true)
: mSCAlloc{world, Wrapper::getInterfaceTable()},
mAlloc{foonathan::memory::make_allocator_reference(mSCAlloc)}
{
auto count = args->count;
auto pos = args->rdpos;
@ -221,9 +224,11 @@ private:
if (mReplyAddress) deleteReplyAddress(mReplyAddress);
}
NRTCommand() {}
// NRTCommand() {}
explicit NRTCommand(index id) : mID{id} {}
explicit NRTCommand(World* world, index id)
: mSCAlloc{world, Wrapper::getInterfaceTable()},
mAlloc{foonathan::memory::make_allocator_reference(mSCAlloc)}, mID{id} {}
bool stage2(World*) { return true; } // nrt
bool stage3(World*) { return true; } // rt
@ -248,7 +253,15 @@ private:
static_cast<int>(packet.size()));
}
}
Allocator& allocator()
{
return mAlloc;
}
// protected:
SCRawAllocator mSCAlloc;
Allocator mAlloc;
index mID;
void* mReplyAddress{nullptr};
};
@ -257,16 +270,18 @@ private:
{
CommandNew(World* world, sc_msg_iter* args, void* replyAddr)
: NRTCommand{world, args, replyAddr, !IsNamedShared_v<Client>},
mParams{Client::getParameterDescriptors()}
mParams{Client::getParameterDescriptors(), NRTCommand::allocator()}
{
mParams.template setParameterValuesRT<ParamsFromOSC>(nullptr, world,
*args);
*args, NRTCommand::allocator());
}
CommandNew(index id, World*, FloatControlsIter& args, Unit* x)
: NRTCommand{id}, mParams{Client::getParameterDescriptors()}
CommandNew(index id, World* world, FloatControlsIter& args, Unit* x)
: NRTCommand{world, id}, mParams{Client::getParameterDescriptors(),
NRTCommand::allocator()}
{
mParams.template setParameterValuesRT<ParamsFromSynth>(nullptr, x, args);
mParams.template setParameterValuesRT<ParamsFromSynth>(
nullptr, x, args, NRTCommand::allocator());
}
static const char* name()
@ -281,7 +296,7 @@ private:
if (!constraintsRes.ok()) Wrapper::printResult(w, constraintsRes);
mResult = (!isNull(add(w, NRTCommand::mID, mParams)));
mResult = (!isNull(add(w, NRTCommand::mID, mParams, FluidContext())));
// Sigh. The cache entry above has both the client instance and main
// params instance.
@ -343,21 +358,23 @@ private:
{
CommandProcess(World* world, sc_msg_iter* args, void* replyAddr)
: NRTCommand{world, args, replyAddr},
mParams{Client::getParameterDescriptors()}
mParams{Client::getParameterDescriptors(),NRTCommand::allocator()}
{
auto& ar = *args;
if (auto ptr = get(NRTCommand::mID).lock())
{
ptr->mDone.store(false, std::memory_order_release);
mParams.template setParameterValuesRT<ParamsFromOSC>(nullptr, world,
ar);
ar, NRTCommand::allocator());
mSynchronous = static_cast<bool>(ar.geti());
} // if this fails, we'll hear about it in stage2 anyway
}
explicit CommandProcess(index id, bool synchronous, Params* params)
: NRTCommand{id},
mSynchronous(synchronous), mParams{Client::getParameterDescriptors()}
explicit CommandProcess(World* world, index id, bool synchronous,
Params* params)
: NRTCommand{world, id},
mSynchronous(synchronous), mParams{Client::getParameterDescriptors(),
NRTCommand::allocator()}
{
if (params)
{
@ -473,7 +490,8 @@ private:
/// Not registered as a PlugInCmd. Triggered by worker thread callback
struct CommandAsyncComplete : public NRTCommand
{
CommandAsyncComplete(World*, index id, void* replyAddress)
CommandAsyncComplete(World* world, index id, void* replyAddress)
: NRTCommand(world, id)
{
NRTCommand::mID = id;
NRTCommand::mReplyAddress = replyAddress;
@ -612,7 +630,9 @@ private:
struct CommandProcessNew : public NRTCommand
{
CommandProcessNew(World* world, sc_msg_iter* args, void* replyAddr)
: mNew{world, args, replyAddr}, mProcess{mNew.mID, false, nullptr}
: NRTCommand{world, args, replyAddr, false},
mNew{world, args, replyAddr},
mProcess{world, mNew.mID, false, nullptr}
{
mProcess.mSynchronous = args->geti();
mProcess.mReplyAddress = mNew.mReplyAddress;
@ -695,8 +715,8 @@ private:
auto& ar = *args;
if (auto ptr = get(NRTCommand::mID).lock())
{
ptr->mParams.template setParameterValuesRT<ParamsFromOSC>(nullptr,
world, ar);
ptr->mParams.template setParameterValuesRT<ParamsFromOSC>(
nullptr, world, ar, NRTCommand::allocator());
Result result = validateParameters(ptr->mParams);
ptr->mClient.setParams(ptr->mParams);
}
@ -726,7 +746,8 @@ private:
if (auto ptr = get(NRTCommand::mID).lock())
{
ptr->mParams.template setParameterValues<ParamsFromOSC>(true, world, mArgs);
ptr->mParams.template setParameterValues<ParamsFromOSC>(
true, world, mArgs, FluidDefaultAllocator());
Result result = validateParameters(ptr->mParams);
ptr->mClient.setParams(ptr->mParams);
}
@ -810,7 +831,6 @@ private:
template <typename Command>
static void defineNRTCommand()
{
auto ft = getInterfaceTable();
auto commandRunner = [](World* world, void*, struct sc_msg_iter* args,
void* replyAddr) {
auto ft = getInterfaceTable();
@ -918,7 +938,9 @@ private:
NRTTriggerUnit()
: mControlsIterator{mInBuf + ControlOffset(), ControlSize()},
mParams{Client::getParameterDescriptors()}
mSCAlloc(mWorld, Wrapper::getInterfaceTable()),
mAlloc{foonathan::memory::make_allocator_reference(mSCAlloc)},
mParams{Client::getParameterDescriptors(), mAlloc}
{
mID = static_cast<index>(mInBuf[0][0]);
if (mID == -1) mID = count();
@ -936,7 +958,7 @@ private:
~NRTTriggerUnit()
{
set_calc_function<NRTTriggerUnit, &NRTTriggerUnit::clear>();
auto cmd = NonRealTime::rtalloc<CommandFree>(mWorld, mID);
auto cmd = NonRealTime::rtalloc<CommandFree>(mWorld, mWorld, mID);
if (runAsyncCommand(mWorld, cmd, nullptr, 0, nullptr) != 0)
{
std::cout << "ERROR: Async command failed in ~NRTTriggerUnit()"
@ -963,12 +985,12 @@ private:
if (trigger)
{
mControlsIterator.reset(1 + mInBuf); // add one for ID
Wrapper::setParams(this, mParams, mControlsIterator, true, false);
Wrapper::setParams(this, mParams, mControlsIterator, mAlloc, true, false);
bool blocking = mInBuf[mNumInputs - 1][0] > 0;
CommandProcess* cmd =
rtalloc<CommandProcess>(mWorld, mID, blocking, &mParams);
rtalloc<CommandProcess>(mWorld, mWorld, mID, blocking, &mParams);
if (runAsyncCommand(mWorld, cmd, nullptr, 0, nullptr) != 0)
{
std::cout << "ERROR: Async command failed in NRTTriggerUnit::next()"
@ -1000,6 +1022,8 @@ private:
index mID;
index mRunCount{0};
WeakCacheEntryPointer mInst;
SCRawAllocator mSCAlloc;
Allocator mAlloc;
Params mParams;
bool mInit{false};
};

@ -1,6 +1,8 @@
#pragma once
#include <data/FluidMemory.hpp>
#include <SC_PlugIn.hpp>
#include <Eigen/Core>
namespace fluid {
namespace client {
@ -81,7 +83,8 @@ struct RealTimeBase
return countScan;
}
void init(SCUnit& unit, Client& client, FloatControlsIter& controls)
void init(SCUnit& unit, Client& client, FloatControlsIter& controls, Allocator& alloc)
{
assert(!(client.audioChannelsOut() > 0 &&
client.controlChannelsOut().count > 0) &&
@ -89,7 +92,7 @@ struct RealTimeBase
client.sampleRate(unit.fullSampleRate());
mInputConnections.reserve(asUnsigned(client.audioChannelsIn()));
mOutputConnections.reserve(asUnsigned(client.audioChannelsOut()));
mContext = FluidContext(unit.fullBufferSize(), alloc);
Result r;
if (!(r = expectedSize(controls)).ok())
{
@ -195,16 +198,19 @@ struct RealTimeBase
}
void next(SCUnit& unit, Client& client, Params& params,
FloatControlsIter& controls, bool updateParams = true)
FloatControlsIter& controls, Allocator& alloc,
bool updateParams = true)
{
bool trig =
IsModel_t<Client>::value ? !mPrevTrig && unit.in0(0) > 0 : false;
mPrevTrig = trig;
#ifdef EIGEN_RUNTIME_NO_MALLOC
Eigen::internal::set_is_malloc_allowed(false);
#endif
if (updateParams)
{
Wrapper::setParams(&unit, params, controls);
Wrapper::setParams(&unit, params, controls, alloc);
params.constrainParameterValuesRT(nullptr);
}
@ -212,6 +218,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
}
private:
@ -221,11 +230,11 @@ private:
std::vector<HostVector> mOutputs;
FluidTensor<float, 1> mControlInputBuffer;
FluidTensor<float, 1> mControlOutputBuffer;
FluidContext mContext;
bool mPrevTrig;
IOMapFn mInputMapper;
IOMapFn mOutMapperPre;
IOMapFn mOutMapperPost;
FluidContext mContext;
};
} // namespace impl
} // namespace client

@ -3,6 +3,7 @@
#include "ArgsFromClient.hpp"
#include "Meta.hpp"
#include "RealTimeBase.hpp"
#include "SCWorldAllocator.hpp"
#include <clients/common/FluidBaseClient.hpp>
#include <SC_PlugIn.hpp>
@ -53,73 +54,38 @@ public:
}
RealTime()
: mControls{mInBuf + ControlOffset(this),ControlSize(this)},
mClient{Wrapper::setParams(this, mParams, mControls,true)}
:
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()
{
// auto& client = mClient;
mDelegate.init(*this,mClient,mControls);
mDelegate.init(*this,mClient,mControls,mAlloc);
mCalcFunc = make_calc_function<RealTime, &RealTime::next>();
Wrapper::getInterfaceTable()->fClearUnitOutputs(this, 1);
// assert(
// !(client.audioChannelsOut() > 0 && client.controlChannelsOut() > 0) &&
// "Client can't have both audio and control outputs");
//
// Result r;
// if(!(r = expectedSize(mWrapper->mControlsIterator)).ok())
// {
// mCalcFunc = Wrapper::getInterfaceTable()->fClearUnitOutputs;
// std::cout
// << "ERROR: " << Wrapper::getName()
// << " wrong number of arguments."
// << r.message()
// << std::endl;
// return;
// }
//
// mWrapper->mControlsIterator.reset(mInBuf + mSpecialIndex + 1);
//
// client.sampleRate(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())));
//
// for (index i = 0; i < client.audioChannelsIn(); ++i)
// {
// mInputConnections.emplace_back(isAudioRateIn(static_cast<int>(i)));
// mAudioInputs.emplace_back(nullptr, 0, 0);
// }
//
// 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); }
//
// mCalcFunc = make_calc_function<RealTime, &RealTime::next>();
// Wrapper::getInterfaceTable()->fClearUnitOutputs(this, 1);
}
void next(int)
{
mControls.reset(mInBuf + ControlOffset(this));
mDelegate.next(*this,mClient,mParams,mControls);
mDelegate.next(*this,mClient,mParams,mControls, mAlloc);
}
private:
SCRawAllocator mSCAlloc;
Allocator mAlloc;
FluidContext mContext;
Delegate mDelegate;
FloatControlsIter mControls;
Params mParams{Client::getParameterDescriptors()};
Params mParams;
Client mClient;
Wrapper* mWrapper{static_cast<Wrapper*>(this)};
};

@ -14,6 +14,7 @@
#include <limits>
#include <new>
namespace fluid {
template <typename T, typename Wrapper>
@ -57,4 +58,34 @@ public:
if (mWorld && mInterface) mInterface->fRTFree(mWorld, p);
}
};
//foonathan::memory RawAllocator with SC rtalloc
struct SCRawAllocator
{
using is_stateful = std::true_type;
SCRawAllocator(World* w, InterfaceTable* interface)
: mWorld{w}, mInterface{interface}
{}
void* allocate_node(std::size_t size, std::size_t)
{
if(auto res = mInterface->fRTAlloc(mWorld,size))
{
// std::cout << "Allocated " << res << " with " << size << '\n';
return res;
}
throw std::bad_alloc();
}
void deallocate_node(void* node, std::size_t /*size*/, std::size_t) noexcept
{
mInterface->fRTFree(mWorld, node);
// std::cout << "Freed " << node << " with " << size << '\n';
}
private:
World* mWorld;
InterfaceTable* mInterface;
};
} // namespace fluid

@ -29,8 +29,8 @@ FluidBufLoudness : FluidBufProcessor{
source = source.asUGenInput;
features = features.asUGenInput;
source.isNil.if {"FluidBufPitch: Invalid source buffer".throw};
features.isNil.if {"FluidBufPitch: Invalid features buffer".throw};
source.isNil.if {"%: Invalid source buffer".format(this.class.name).throw};
features.isNil.if {"%: Invalid features buffer".format(this.class.name).throw};
^FluidProxyUgen.kr(\FluidBufLoudnessTrigger, -1, source, startFrame, numFrames, startChan, numChans, features, padding, selectbits, kWeighting, truePeak, windowSize, hopSize, maxwindowSize, trig, blocking);
}
@ -44,8 +44,8 @@ FluidBufLoudness : FluidBufProcessor{
source = source.asUGenInput;
features = features.asUGenInput;
source.isNil.if {"FluidBufPitch: Invalid source buffer".throw};
features.isNil.if {"FluidBufPitch: Invalid features buffer".throw};
source.isNil.if {"%: Invalid source buffer".format(this.class.name).throw};
features.isNil.if {"%: Invalid features buffer".format(this.class.name).throw};
^this.new(
server, nil, [features]
@ -63,8 +63,8 @@ FluidBufLoudness : FluidBufProcessor{
source = source.asUGenInput;
features = features.asUGenInput;
source.isNil.if {"FluidBufPitch: Invalid source buffer".throw};
features.isNil.if {"FluidBufPitch: Invalid features buffer".throw};
source.isNil.if {"%: Invalid source buffer".format(this.class.name).throw};
features.isNil.if {"%: Invalid features buffer".format(this.class.name).throw};
^this.new(
server, nil, [features]

@ -2,9 +2,6 @@ FluidBufSTFT : FluidBufProcessor {
*kr { |source, startFrame = 0, numFrames = -1, startChan = 0, magnitude, phase, resynth, inverse = 0,windowSize = 1024, hopSize = -1, fftSize = -1, padding = 1, trig = 1, blocking = 1|
// source = source.asUGenInput;
// source.isNil.if {"FluidBufScale: Invalid source buffer".throw};
source = source ? -1;
magnitude = magnitude ? -1;
phase = phase ? -1;
@ -15,9 +12,6 @@ FluidBufSTFT : FluidBufProcessor {
*process { |server, source, startFrame = 0, numFrames = -1, startChan = 0, magnitude, phase, resynth, inverse = 0, windowSize = 1024, hopSize = -1, fftSize = -1, padding = 1, freeWhenDone = true, action|
// source = source.asUGenInput;
// source.isNil.if {"FluidBufSTFT: Invalid source buffer".throw};
source = source ? -1;
magnitude = magnitude ? -1;
phase = phase ? -1;
@ -32,7 +26,6 @@ FluidBufSTFT : FluidBufProcessor {
*processBlocking { |server, source, startFrame = 0, numFrames = -1, startChan = 0, magnitude, phase, resynth, inverse = 0, windowSize = 1024, hopSize = -1, fftSize = -1, padding = 1,freeWhenDone = true, action|
// source = source.asUGenInput;
source = source ? -1;
magnitude = magnitude ? -1;
phase = phase ? -1;

@ -5,8 +5,8 @@ FluidBufTransientSlice : FluidBufProcessor {
source = source.asUGenInput;
indices = indices.asUGenInput;
source.isNil.if {"FluidBufNoveltySlice: Invalid source buffer".throw};
indices.isNil.if {"FluidBufNoveltySlice: Invalid features buffer".throw};
source.isNil.if {"%: Invalid source buffer".format(this.class.name).throw};
indices.isNil.if {"%: Invalid features buffer".format(this.class.name).throw};
^FluidProxyUgen.kr(this.objectClassName++\Trigger, -1, source, startFrame, numFrames, startChan, numChans, indices, order, blockSize, padSize, skew, threshFwd, threshBack, windowSize, clumpLength, minSliceLength, trig, blocking);
}
@ -16,8 +16,8 @@ FluidBufTransientSlice : FluidBufProcessor {
source = source.asUGenInput;
indices = indices.asUGenInput;
source.isNil.if {"FluidBufNoveltySlice: Invalid source buffer".throw};
indices.isNil.if {"FluidBufNoveltySlice: Invalid features buffer".throw};
source.isNil.if {"%: Invalid source buffer".format(this.class.name).throw};
indices.isNil.if {"%: Invalid features buffer".format(this.class.name).throw};
^this.new(
server, nil,[indices]
@ -30,8 +30,8 @@ FluidBufTransientSlice : FluidBufProcessor {
source = source.asUGenInput;
indices = indices.asUGenInput;
source.isNil.if {"FluidBufNoveltySlice: Invalid source buffer".throw};
indices.isNil.if {"FluidBufNoveltySlice: Invalid features buffer".throw};
source.isNil.if {"%: Invalid source buffer".format(this.class.name).throw};
indices.isNil.if {"%: Invalid features buffer".format(this.class.name).throw};
^this.new(
server, nil,[indices]

@ -1,4 +1,3 @@
FluidDataSetQuery : FluidDataObject {
*new{|server| ^super.new(server) }

@ -61,10 +61,9 @@ StaticText(w,Rect(732,150,50,20)).string_("maxIter:");
TextField(w,Rect(730,170,50,20)).string_(1000.asString).action_{|in| mlp.maxIter = in.value.asInteger.postln;};
StaticText(w,Rect(732,190,50,20)).string_("validation:");
TextField(w,Rect(730,210,50,20)).string_(0.0.asString).action_{|in|mlp.validation = in.value.asFloat.postln;};
)
//2- the synth
(
b = {
arg val = #[0,0,0,0,0,0,0,0,0,0];
var osc1, osc2, feed1, feed2, base1=69, base2=69, base3 = 130;

Loading…
Cancel
Save