Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework Max wrapper to allow multiple inputs and different IO sizes fo… #397

Merged
merged 1 commit into from
Aug 23, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 62 additions & 75 deletions source/include/FluidMaxWrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -588,19 +588,29 @@ class FluidMaxWrapper
void operator()(FluidMaxWrapper* x, long ac, t_atom* av)
{
FluidContext c;


index whichIn = proxy_getinlet((t_object *)x);

atom_getdouble_array(std::min<index>(x->mListSize, ac), av,
std::min<index>(x->mListSize, ac),
x->mInputListData[0].data());
x->mClient.process(x->mInputListViews, x->mOutputListViews, c);
x->mInputListData[whichIn].data());

for (index i = asSigned(x->mDataOutlets.size()) - 1; i >= 0; --i)
if (!whichIn)
{
atom_setdouble_array(
std::min<index>(x->mListSize, ac), x->mOutputListAtoms.data(),
std::min<index>(x->mListSize, ac), x->mOutputListData[i].data());
outlet_list(x->mDataOutlets[i], nullptr, x->mListSize,
x->mOutputListAtoms.data());
x->mClient.process(x->mInputListViews, x->mOutputListViews, c);

index outSize = isControlOutFollowsIn<typename Client::Client> ? std::min<index>(x->mListSize, ac) : x->mClient.controlChannelsOut().size;

for (index i = asSigned(x->mDataOutlets.size()) - 1; i >= 0; --i)
{
assert(x->mOutputListData[i].size() == outSize);
atom_setdouble_array(outSize,
x->mOutputListAtoms.data(),
outSize,
x->mOutputListData[i].data());
outlet_list(x->mDataOutlets[i], nullptr, outSize,
x->mOutputListAtoms.data());
}
}
}
};
Expand Down Expand Up @@ -1252,7 +1262,7 @@ class FluidMaxWrapper
//TODO: this implicitly assumes no audio in?
if (index controlInputs = mClient.controlChannelsIn())
{
if(mListSize)
if (mListSize)
{
mInputListData.resize(controlInputs, mListSize);
for (index i = 1; i <= controlInputs; ++i)
Expand All @@ -1262,9 +1272,9 @@ class FluidMaxWrapper
//we already have a left inlet, but do we need more?
index newInlets = controlInputs - 1;
mProxies.reserve(newInlets);
for (index i = 1; i <= newInlets; ++i)
for (index i = newInlets; i >= 1; --i)
mProxies.push_back(
proxy_new(this, static_cast<long>(i + 1), &this->mProxyNumber));
proxy_new(this, static_cast<long>(i), &this->mProxyNumber));
}

//new proxy inlets for any additional input buffers beyond the first
Expand Down Expand Up @@ -1355,9 +1365,9 @@ class FluidMaxWrapper

if (mClient.controlChannelsOut().count)
{
index outputSize = mClient.controlChannelsOut().max > -1
? mClient.controlChannelsOut().max
: mListSize;
index outputSize = isControlOutFollowsIn<typename Client::Client>
? mListSize
: mClient.controlChannelsOut().max;

if (outputSize)
{
Expand Down Expand Up @@ -1462,12 +1472,12 @@ class FluidMaxWrapper
{
void* x = object_alloc(getClass());
new (x) FluidMaxWrapper(sym, ac, av);
if (static_cast<index>(attr_args_offset(static_cast<short>(ac), av)) - isControlIn<typename Client::Client> >
if (static_cast<index>(attr_args_offset(static_cast<short>(ac), av)) - isControlOutFollowsIn<typename Client::Client>>
ParamDescType::NumFixedParams + ParamDescType::NumPrimaryParams)
{
object_warn((t_object*) x,
"Too many arguments. Got %d, expect at most %d", ac,
ParamDescType::NumFixedParams + ParamDescType::NumPrimaryParams + isControlIn<typename Client::Client>);
ParamDescType::NumFixedParams + ParamDescType::NumPrimaryParams + isControlOutFollowsIn<typename Client::Client>);
}

return x;
Expand All @@ -1477,7 +1487,6 @@ class FluidMaxWrapper

static void makeClass(const char* className)
{

static constexpr bool AudioInput = isAudioIn<typename Client::Client>;
const ParamDescType& p = Client::getParameterDescriptors();
const auto& m = Client::getMessageDescriptors();
Expand All @@ -1488,13 +1497,16 @@ class FluidMaxWrapper
if (isControlIn<typename Client::Client>)
{
class_addmethod(getClass(), (method) handleList, "list", A_GIMME, 0);
}

if (isControlOutFollowsIn<typename Client::Client>)
{
t_object* a = attr_offset_new("autosize", USESYM(atom_long), 0, nullptr, nullptr,
calcoffset(FluidMaxWrapper, mAutosize));
class_addattr(getClass(), a);
CLASS_ATTR_FILTER_CLIP(getClass(), "autosize", 0, 1);
CLASS_ATTR_STYLE_LABEL(getClass(), "autosize", 0, "onoff",
"Set auto size for list output");

"Set auto resizing of list input and output");
}

class_addmethod(getClass(), (method) doNotify, "notify", A_CANT, 0);
Expand All @@ -1520,9 +1532,8 @@ class FluidMaxWrapper
p.template iterateMutable<SetupAttribute>();
p.template iterateFixed<SetupReadOnlyAttribute>();


//for non-audio classes, give us cold inlets for non-left
if(!AudioInput)
if (!AudioInput)
class_addmethod(getClass(), (method)stdinletinfo, "inletinfo", A_CANT, 0);

class_dumpout_wrap(getClass());
Expand Down Expand Up @@ -1555,72 +1566,48 @@ class FluidMaxWrapper

void resizeListHandlers(index newSize)
{
if (mListSize != newSize)
{
mListSize = newSize;
index numIns = mClient.controlChannelsIn();
mListSize = newSize;
if(mListSize)
mInputListData.resize(numIns, mListSize);
mInputListViews.clear();
for (index i = 0; i < numIns; ++i)
{
mInputListData.resize(numIns,mListSize);
mInputListViews.clear();
for (index i = 0; i < numIns; ++i)
{
mInputListViews.emplace_back(mInputListData.row(i));
}

index outputSize = mClient.controlChannelsOut().size > -1
? mClient.controlChannelsOut().size
: mListSize;
mInputListViews.emplace_back(mInputListData.row(i));
}

mOutputListData.resize(mClient.controlChannelsOut().count, outputSize);
mOutputListAtoms.reserve(outputSize);
if (isControlOutFollowsIn<typename Client::Client>)
{
mOutputListData.resize(mClient.controlChannelsOut().count, mListSize);
mOutputListAtoms.reserve(mListSize);
mOutputListViews.clear();
for (index i = 0; i < mClient.controlChannelsOut().count; ++i)
{
mOutputListViews.emplace_back(mOutputListData.row(i));
}
}
}
}

static void doList(FluidMaxWrapper* x, t_symbol*, long ac, t_atom* av)
{

// if(!isr() && x->mAutosize && (ac != x->mListSize)) x->resizeListHandlers(ac);
x->mListHandler(x, ac, av);
}

static void doListResize(FluidMaxWrapper* x, t_symbol*, long ac, t_atom*)
static void handleList(FluidMaxWrapper* x, t_symbol* /*s*/, long ac, t_atom* av)
{
x->resizeListHandlers(ac);
}


static void handleList(FluidMaxWrapper* x, t_symbol* s, long ac, t_atom* av)
{
if(!x->mListSize && !x->mAutosize)
{
object_error((t_object*)x, "No list size argument nor autosize enabled: can't do anything");
return;
}

if(isr())
{
if(x->mAutosize && ac != x->mListSize)
{
object_warn((t_object*)x, "input list size (%d) != object argument (%d) and autosize is enabled: this operation will be deferred",ac,x->mListSize);
defer(x, method(doListResize), s, static_cast<short>(ac), av);
defer(x, (method) doList, s, static_cast<short>(ac), av);
return;
}
if (!x->mListSize && !x->mAutosize)
{
object_error((t_object*)x, "No list size argument nor autosize enabled: can't do anything");
return;
}

if(!x->mAutosize && ac != x->mListSize)
{
object_warn((t_object*)x, "bad input list size (%d), expect %d",ac,x->mListSize);
return;
}
}
else if(ac != x->mListSize) doListResize(x,s,ac,av);

doList(x,s,ac,av);
if (!x->mAutosize && ac != x->mListSize)
{
object_warn((t_object*)x, "bad input list size (%d), expect %d",ac,x->mListSize);
return;
}

if (x->mAutosize)
x->resizeListHandlers(ac);

x->mListHandler(x, ac, av);
}

static void doSharedClientRefer(FluidMaxWrapper* x, t_symbol* newName)
Expand Down Expand Up @@ -1753,7 +1740,7 @@ class FluidMaxWrapper
{
long argCount{0};

if(isControlIn<typename Client::Client>)
if (isControlOutFollowsIn<typename Client::Client>)
{
mListSize = atom_getlong(av);
numArgs -= 1;
Expand Down