cwFlowProc.cpp, cwFlow.cpp,cwFlowNet.h/cpp : Implemented presets for het. poly nets.

This commit is contained in:
kevin 2024-12-27 15:24:44 -05:00
parent ccdac53013
commit fc94d3859d
4 changed files with 311 additions and 163 deletions

View File

@ -1037,6 +1037,7 @@ cw::rc_t cw::flow::initialize( handle_t h,
rc_t rc = kOkRC;
variable_t* proxyVarL = nullptr;
flow_t* p = _handleToPtr(h);
const char* root_label = "root";
p->deviceA = deviceA;
p->deviceN = deviceN;
@ -1069,7 +1070,7 @@ cw::rc_t cw::flow::initialize( handle_t h,
}
// instantiate the network
if((rc = network_create(p,&p->networkCfg,1,proxyVarL,nullptr,1,p->net)) != kOkRC )
if((rc = network_create(p,&root_label,&p->networkCfg,1,proxyVarL,1,p->net)) != kOkRC )
{
rc = cwLogError(rc,"Network creation failed.");
goto errLabel;

View File

@ -48,6 +48,7 @@ namespace cw
unsigned sfx_id; // 'sfx_id' is only used by _io_stmt_connect_vars()
unsigned sfx_id_count; // Literal sfx_id_count or kInvalidCnt if not given
unsigned is_iter_fl; // This id included an '_' (underscore)
unsigned has_sfx_fl; // true if a suffix was specified (differentiates label0 from label)
} io_ele_t;
typedef struct io_stmt_str
@ -332,6 +333,7 @@ namespace cw
else
{
r.is_iter_fl = true;
r.has_sfx_fl = true;
// if there is a number following the underscore then this is the secInt
if( textLength(underscore + 1) )
@ -382,6 +384,8 @@ namespace cw
*digit = 0; // zero terminate the label
r.has_sfx_fl = true;
}
// verify that some content remains in the id string
@ -1508,7 +1512,7 @@ namespace cw
}
// Set pstate.proc_label and pstate.label_sfx_id
rc_t _proc_parse_inst_label( const char* proc_label_str, unsigned system_sfx_id, proc_inst_parse_state_t& pstate )
rc_t _proc_parse_inst_label( const network_t& net, const char* proc_label_str, proc_inst_parse_state_t& pstate )
{
rc_t rc = kOkRC;
unsigned digitCharN = 0;
@ -1544,16 +1548,18 @@ namespace cw
}
}
// if the parsed sfx-id did not exist
// if the parsed sfx-id was not explicitly set then set it to the network index
if( sfx_id == kInvalidId )
{
sfx_id = system_sfx_id==kInvalidId ? kBaseSfxId : system_sfx_id;
sfx_id = net.poly_idx;
}
// be sure the parsed sfx-id does not conflict with the system provided sfx-id
if( system_sfx_id != kInvalidId && sfx_id != system_sfx_id )
// if this net is part of a network array then the proc suffix id is used distinguish this
// proc instance from the same proc instance in sibling networks and so it can't
// be changed to some other value by providing an explicit suffix id
if( net.polyN > 1 && sfx_id != net.poly_idx )
{
rc = cwLogError(kInvalidStateRC,"The proc instance '%s' numeric suffix id (%i) conflicts with the system provided sfx id (%i).",cwStringNullGuard(proc_label_str),pstate.proc_label_sfx_id,system_sfx_id);
rc = cwLogError(kInvalidStateRC,"The proc instance '%s' numeric suffix id (%i) conflicts with the network poly index (%i).",cwStringNullGuard(proc_label_str),pstate.proc_label_sfx_id,net.poly_idx);
goto errLabel;
}
@ -1565,7 +1571,7 @@ namespace cw
}
rc_t _proc_parse_cfg( network_t& net, const object_t* proc_inst_cfg, unsigned system_sfx_id, proc_inst_parse_state_t& pstate )
rc_t _proc_parse_cfg( network_t& net, const object_t* proc_inst_cfg, proc_inst_parse_state_t& pstate )
{
rc_t rc = kOkRC;
const object_t* arg_dict = nullptr;
@ -1580,7 +1586,7 @@ namespace cw
pstate.proc_label_sfx_id = kInvalidId;
// extract the proc instance label and (sfx-id suffix)
if((rc = _proc_parse_inst_label( proc_inst_cfg->pair_label(), system_sfx_id, pstate )) != kOkRC )
if((rc = _proc_parse_inst_label( net, proc_inst_cfg->pair_label(), pstate )) != kOkRC )
{
rc = cwLogError(kSyntaxErrorRC,"Parsing failed on the label and sfx-id for '%s'.",cwStringNullGuard(proc_inst_cfg->pair_label()));
goto errLabel;
@ -1914,22 +1920,19 @@ namespace cw
rc_t _proc_create( flow_t* p,
const object_t* proc_inst_cfg,
unsigned sfx_id,
network_t& net,
variable_t* proxyVarL,
//const object_t* net_preset_cfgD,
proc_t*& proc_ref )
{
rc_t rc = kOkRC;
proc_inst_parse_state_t pstate = {};
proc_t* proc = nullptr;
class_desc_t* class_desc = nullptr;
//const object_t* proc_preset_cfg = nullptr;
proc_ref = nullptr;
// parse the proc instance configuration
if((rc = _proc_parse_cfg( net, proc_inst_cfg, sfx_id, pstate )) != kOkRC )
if((rc = _proc_parse_cfg( net, proc_inst_cfg, pstate )) != kOkRC )
goto errLabel;
// locate the proc class desc
@ -2220,7 +2223,7 @@ namespace cw
// Preset processing
//
rc_t _parse_network_proc_label( const network_t& net, const network_preset_t& network_preset, const char* proc_label, unsigned proc_label_sfx_id, io_ele_t& proc_id )
rc_t _parse_network_proc_label( const network_t& net, const network_preset_t& network_preset, const char* proc_label, io_ele_t& proc_id )
{
rc_t rc = kOkRC;
@ -2231,9 +2234,9 @@ namespace cw
goto errLabel;
}
// set the proc_id base sfx id
// if the proc label sfx id was not explicitely set then set it to the network poly index
if( proc_id.base_sfx_id == kInvalidId )
proc_id.base_sfx_id = proc_label_sfx_id==kInvalidId ? kBaseSfxId : proc_label_sfx_id;
proc_id.base_sfx_id = net.poly_idx;
// if not iterating
if( !proc_id.is_iter_fl )
@ -2570,15 +2573,11 @@ namespace cw
return rc;
}
rc_t _network_preset_handle_poly_preset_reference(network_preset_t& network_preset, proc_t* poly_proc, const char* preset_label )
rc_t _network_preset_handle_poly_preset_ref(network_preset_t& network_preset, network_t* poly_net, const char* preset_label )
{
rc_t rc = kOkRC;
preset_value_t* preset_value = nullptr;
network_t* poly_net = poly_proc->internal_net;
for(; poly_net!=nullptr; poly_net=poly_net->poly_link)
{
network_preset_t* poly_net_preset = nullptr;
for(unsigned i=0; i<poly_net->presetN; ++i)
@ -2590,7 +2589,7 @@ namespace cw
if( poly_net_preset == nullptr )
{
rc = cwLogError(kEleNotFoundRC,"The preset '%s' could not be found on the poly proc '%s:%i'.",cwStringNullGuard(poly_proc->label),poly_proc->label_sfx_id);
rc = cwLogError(kEleNotFoundRC,"The preset '%s' could not be found on the net '%s:%i'.",preset_label,cwStringNullGuard(poly_net->label),poly_net->poly_idx);
goto errLabel;
}
@ -2599,24 +2598,87 @@ namespace cw
preset_value->tid = kNetRefPresetValueTId;
preset_value->u.npv.net_preset = poly_net_preset;
preset_value->u.npv.net_preset_net = poly_net;
//preset_value->u.npv.net_preset_proc = poly_proc;
_network_preset_link_in_value( network_preset, preset_value );
}
errLabel:
return rc;
}
rc_t _network_preset_handle_poly_preset_reference(network_preset_t& network_preset, proc_t* poly_proc, const io_ele_t& proc_id, const char* preset_label )
{
rc_t rc = kOkRC;
const class_preset_t* class_pre;
unsigned min_sfx_id = proc_id.base_sfx_id;
unsigned sfx_cnt = proc_id.is_iter_fl ? proc_id.sfx_id_count : (proc_id.has_sfx_fl ? 1 : poly_proc->internal_net->polyN);
network_t* poly_net = poly_proc->internal_net;
// for each specified poly net
for(; poly_net!=nullptr; poly_net=poly_net->poly_link)
if( min_sfx_id <= poly_net->poly_idx && poly_net->poly_idx < min_sfx_id + sfx_cnt )
{
// if this network is not a het. net then the preset can be directly found in the network preset list
if( poly_proc->internal_net_cnt == 1 )
rc = _network_preset_handle_poly_preset_ref(network_preset, poly_net, preset_label);
else
{
// the network is het. net and so the preset must be looked up first in the poly proc instance preset list
// and then mapped to each of the named networks.
if((class_pre = proc_preset_find(poly_proc,preset_label)) != nullptr )
{
// ... the referenced preset ia a poly preset instance preset ....
unsigned childN = class_pre->cfg->child_count();
// ... iterate through each of the elements of the preset dictionary
for(unsigned i=0; i<childN; ++i)
{
const object_t* pair = class_pre->cfg->child_ele(i);
const char* net_preset_label = nullptr;
const char* net_label = pair->pair_label();
// pair = (net-label:net-preset-label)
// the het. net referenced in the in preset must match the current net (poly_net) label
if( textIsEqual(net_label,poly_net->label) )
{
// get the net specific preset label
if( pair->pair_value()->value(net_preset_label) != kOkRC )
{
rc = cwLogError(kSyntaxErrorRC,"The value associated with '%s' is not a string.",pair->pair_label());
goto errLabel;
}
if((rc = _network_preset_handle_poly_preset_ref(network_preset, poly_net, net_preset_label )) != kOkRC )
{
goto errLabel;
}
}
}
}
}
}
errLabel:
if( rc != kOkRC )
rc = cwLogError(rc,"The poly processor preset '%s' on '%s:%i' is not valid.",cwStringNullGuard(preset_label),cwStringNullGuard(poly_proc->label),poly_proc->label_sfx_id);
return rc;
}
rc_t _network_preset_parse_value_list( flow_t* p,
network_t& net,
unsigned net_sfx_id,
const object_t* network_preset_dict_cfg,
network_preset_t& network_preset )
{
rc_t rc = kOkRC;
unsigned procN = 0;
unsigned pairN = 0;
if( network_preset_dict_cfg==nullptr || !network_preset_dict_cfg->is_dict() )
{
@ -2626,10 +2688,10 @@ namespace cw
network_preset.tid = kPresetVListTId;
procN = network_preset_dict_cfg->child_count();
pairN = network_preset_dict_cfg->child_count();
// for each proc in the network preset
for(unsigned i=0; i<procN; ++i)
// for each pair in the preset value dictionary
for(unsigned i=0; i<pairN; ++i)
{
const object_t* var_dict = nullptr;
const object_t* proc_preset_pair = network_preset_dict_cfg->child_ele(i);
@ -2637,6 +2699,7 @@ namespace cw
io_ele_t proc_id = {};
unsigned varN = 0;
// validate the process preset syntax
if( proc_preset_pair==nullptr || !proc_preset_pair->is_pair() || (proc_label=proc_preset_pair->pair_label())==nullptr || proc_preset_pair->pair_value()==nullptr )
{
@ -2644,16 +2707,35 @@ namespace cw
goto errLabel;
}
// parse the proc label
if((rc= _parse_network_proc_label(net, network_preset, proc_label, net_sfx_id, proc_id )) != kOkRC )
// each pair has the syntax:
// <proc-label>:<preset_value>
// where:
// <proc-label> identifies a proc inside this network where the <preset-value> will be applied.
// <preset-value> idenfifies a label or a dictionary of <var>:<value> pairs.
//
// parse the label
if((rc= _parse_network_proc_label(net, network_preset, proc_label, proc_id )) != kOkRC )
goto errLabel;
// if the preset has a label
// if the preset-value is a label ...
if( proc_preset_pair->pair_value()->is_string() )
{
const char* proc_preset_label = nullptr;
proc_t* proc = nullptr;
// ... then the label refers to a proc where the proc may be
// one of two types:
//
// 1) 'poly' proc - in which case we need to a poly_preset_value_t
// record for each poly channel -
//
// 2) a proc instance in this network
// in which case the label refers to a class or instance preset
// and we store proc_var_value_t for each variable referenced in the preset cfg.
// get the proc preset label
if((proc_preset_pair->pair_value()->value(proc_preset_label)) != kOkRC )
{
@ -2662,17 +2744,8 @@ namespace cw
}
// the label may refer to a
// 1) 'poly' proc - in which case we need to a poly_preset_value_t
// record for each poly channel -
//
// 2) a proc instance in this network
// in which case the label refers to a class or instance preset
// and we store proc_var_value_t for each variable referenced in the preset cfg.
// locate the proc this preset will be applied to
if((proc = proc_find(net, proc_id.label, net_sfx_id /*proc_id.sfx_id*/ )) == nullptr )
if((proc = proc_find(net, proc_id.label, net.poly_idx )) == nullptr )
{
rc = cwLogError(rc,"The proc '%s:%i' could not be found for the preset:'%s'",cwStringNullGuard(proc_id.label),proc_id.sfx_id,cwStringNullGuard(network_preset.label));
goto errLabel;
@ -2681,7 +2754,8 @@ namespace cw
// if this is a 'poly' proc
if( proc->internal_net != nullptr )
{
if((rc = _network_preset_handle_poly_preset_reference(network_preset,proc,proc_preset_label)) != kOkRC )
if((rc = _network_preset_handle_poly_preset_reference(network_preset,proc,proc_id,proc_preset_label)) != kOkRC )
goto errLabel;
// the referenced preset was added to the network_preset.u.vlist - no further processing is required
@ -2690,10 +2764,11 @@ namespace cw
}
else
{
// get the referenced preset cfg from the class desc
// get the referenced preset preset cfg
if((rc = _network_preset_get_preset_cfg_dict( net, network_preset.label, proc_id.label, proc_id.base_sfx_id, proc_preset_label, var_dict )) != kOkRC )
goto errLabel;
}
}
else // the preset is a dictionary of var/value pairs
{
@ -2721,7 +2796,7 @@ namespace cw
// for each proc/sf_id (the proc label may refer to multiple proc instances)
// This loop is designed to handle the case where the preset proc. label uses underscore notation
// to address specific or all instances of a given named proc's.
// to address specific vs all instances of a given named proc's.
// If no underscore notation is used then it addresses all instances with the
// specified name.
@ -2735,8 +2810,8 @@ namespace cw
const object_t* var_pair = var_dict->child_ele(k);
unsigned proc_label_sfx_id = proc_id.base_sfx_id + j;
// if the net is part of a poly net
if( net_sfx_id!=kInvalidId && proc_label_sfx_id != net_sfx_id )
// if this net is part of a poly net - but the proc sfx id does not match the poly index
if( net.polyN>1 && proc_label_sfx_id != net.poly_idx )
continue;
// parse the preset var label - the var may use underscore notation to address multiple vars
@ -2762,7 +2837,7 @@ namespace cw
}
rc_t _network_preset_parse_dict( flow_t* p, network_t& net, unsigned proc_sfx_id, const object_t* preset_cfg )
rc_t _network_preset_parse_dict( flow_t* p, network_t& net, const object_t* preset_cfg )
{
rc_t rc = kOkRC;
unsigned presetAllocN = 0;
@ -2796,7 +2871,7 @@ namespace cw
switch( preset_pair_cfg->pair_value()->type_id() )
{
case kDictTId: // 'value-list' preset
if((rc = _network_preset_parse_value_list(p, net, proc_sfx_id, preset_pair_cfg->pair_value(), network_preset)) != kOkRC )
if((rc = _network_preset_parse_value_list(p, net, preset_pair_cfg->pair_value(), network_preset)) != kOkRC )
{
rc = cwLogError(kSyntaxErrorRC,"Network value-list preset parse failed on preset:'%s'.",cwStringNullGuard(network_preset.label));
goto errLabel;
@ -3253,7 +3328,6 @@ namespace cw
rc_t _network_init( flow_t* p,
const object_t* networkCfg,
unsigned sfx_id,
variable_t* proxyVarL,
network_t* net )
{
@ -3295,7 +3369,7 @@ namespace cw
const object_t* proc_cfg = net->procsCfg->child_ele(j);
// create the proc inst instance
if( (rc= _proc_create( p, proc_cfg, sfx_id, *net, proxyVarL, net->procA[j] ) ) != kOkRC )
if( (rc= _proc_create( p, proc_cfg, *net, proxyVarL, net->procA[j] ) ) != kOkRC )
{
rc = cwLogError(rc,"The processor instantiation at proc index %i failed.",j);
goto errLabel;
@ -3309,7 +3383,7 @@ namespace cw
goto errLabel;
// parse the network presets but do not apply them
if((rc = _network_preset_parse_dict(p, *net, sfx_id, net->presetsCfg )) != kOkRC )
if((rc = _network_preset_parse_dict(p, *net, net->presetsCfg )) != kOkRC )
goto errLabel;
errLabel:
@ -3414,10 +3488,11 @@ namespace cw
cw::rc_t cw::flow::network_create( flow_t* p,
const object_t* const * netCfgA,
const char* const * netLabelA, // netLabel[ netCfgN ]
const object_t* const * netCfgA, // netCfgA[ netCfgA ]
unsigned netCfgN,
variable_t* proxyVarL,
const proc_t* owner_proc,
//const proc_t* owner_proc,
unsigned polyCnt,
network_t*& net_ref )
{
@ -3426,26 +3501,38 @@ cw::rc_t cw::flow::network_create( flow_t* p,
net_ref = nullptr;
/*
if( !(netCfgN==1 || netCfgN==polyCnt ))
{
cwLogError(kInvalidArgRC,"The count of network cfg's must be one, or must match the 'poly count'.");
goto errLabel;
}
*/
for(unsigned i=0; i<polyCnt; ++i)
// for each network configuration
for(unsigned cfg_idx=0; cfg_idx<netCfgN; ++cfg_idx)
{
// All procs in a poly should share the same sfx_id
// otherwise the sfx_id can be automatically generated.
unsigned sfx_id = i; //polyCnt>1 ? i : kInvalidId;
unsigned poly_cnt = polyCnt;
const object_t* netCfg = i < netCfgN ? netCfgA[i] : netCfgA[0];
const object_t* netCfg = netCfgA[cfg_idx];
const char* netLabel = netLabelA[cfg_idx];
// overrride poly_cnt with the optional 'count' field passed from the caller
if((rc = netCfg->getv_opt("count",poly_cnt)) != kOkRC )
{
rc = cwLogError(rc,"Poly network 'count' parse failed on the network '%s'.",cwStringNullGuard(netLabel));
goto errLabel;
}
// for each poly network
for(unsigned i=0; i<poly_cnt; ++i)
{
// allocate the network
network_t* net = mem::allocZ<network_t>();
net->owner_proc = owner_proc;
net->polyN = polyCnt;
//net->owner_proc = owner_proc;
net->label = netLabel;
net->polyN = poly_cnt;
net->poly_idx = i;
if( net_ref == nullptr )
@ -3457,14 +3544,14 @@ cw::rc_t cw::flow::network_create( flow_t* p,
n0 = net;
// create the network
if((rc = _network_init(p, netCfg, sfx_id, proxyVarL, net)) != kOkRC )
if((rc = _network_init(p, netCfg, proxyVarL, net)) != kOkRC )
{
rc = cwLogError(rc,"Network create failed on poly index %i.",i);
goto errLabel;
}
}
}
errLabel:
if( rc != kOkRC && net_ref != nullptr )

View File

@ -12,10 +12,10 @@ namespace cw
// The only time netCfgN will be greater than 1 is when a heterogenous poly network is being
// instantiated.
rc_t network_create( flow_t* p,
const char* const * netLabelA, // netLabel[netCfgN]
const object_t* const * netCfgA, // netCfgA[netCfgN]
unsigned netCfgN, // count of cfg. records in netCfgN
variable_t* proxyVarL, //
const proc_t* owner_proc, // Pointer to the proc that owns this network (or null if creating the top level network)
unsigned polyCnt, // Count of poly subnets to create or 1 if the network is not poly
network_t*& net_ref // Returned network handle.
);

View File

@ -129,7 +129,7 @@ namespace cw
goto errLabel;
}
if((rc = network_create(proc->ctx,&networkCfg,1,proc->varL,proc,1,p->net)) != kOkRC )
if((rc = network_create(proc->ctx,&proc->label,&networkCfg,1,proc->varL,1,p->net)) != kOkRC )
{
rc = cwLogError(rc,"Creation failed on the subnet internal network.");
goto errLabel;
@ -204,11 +204,11 @@ namespace cw
typedef struct
{
unsigned count; // count of subnets in 'net'
bool parallel_fl; // true if the subnets should be executed in parallel
thread_tasks::handle_t threadTasksH; //
thread_tasks::task_t* taskA; // taskA[ count ]
voice_t* voiceA; // voiceA[ count ]
unsigned voiceN;
unsigned preset_sfx_id;
} inst_t;
@ -253,17 +253,21 @@ namespace cw
}
rc_t create( proc_t* proc )
{
rc_t rc = kOkRC;
inst_t* inst = mem::allocZ<inst_t>();
const object_t* networkCfg = nullptr;
variable_t* proxyVarL = nullptr;
const object_t** networkCfgA = nullptr;
unsigned networkCfgN = 1;
const char** netLabelA = nullptr;
const object_t** netCfgA = nullptr;
unsigned netCfgN = 1;
network_t* internal_net = nullptr;
unsigned preset_sfx_id = kInvalidId;
const char* preset_label = nullptr;
bool het_poly_fl = false;
unsigned poly_cnt = 1;
proc->userPtr = inst;
@ -283,54 +287,60 @@ namespace cw
goto errLabel;
}
het_poly_fl = networkCfg->find("procs") == nullptr;
// if the network is a list of cfgs
if( networkCfg->is_list() )
if( het_poly_fl )
{
inst->count = networkCfg->child_count();
networkCfgN = inst->count;
netCfgN = networkCfg->child_count();
}
else
{
// otherwise multiple networks use the same cfg
if((rc = var_register_and_get( proc, kAnyChIdx,kCountPId,"count", kBaseSfxId, inst->count )) != kOkRC )
// get the default poly count
if((rc = var_register_and_get( proc, kAnyChIdx,kCountPId,"count", kBaseSfxId, poly_cnt )) != kOkRC )
{
goto errLabel;
}
}
// the network cannot be empty
if( inst->count == 0 )
if( netCfgN == 0 )
{
cwLogWarning("The 'poly' %s:%i was given a count of 0.",proc->label,proc->label_sfx_id);
cwLogWarning("The 'poly' %s:%i does not define any networks.",proc->label,proc->label_sfx_id);
goto errLabel;
}
// allocate the network cfg array
networkCfgA = mem::allocZ<const object_t*>(inst->count);
netCfgA = mem::allocZ<const object_t*>(netCfgN);
netLabelA = mem::allocZ<const char*>(netCfgN);
// by default there is only one cfg.
networkCfgA[0] = networkCfg;
netCfgA[0] = networkCfg;
// ... but if there are more than one cfg ...
if( networkCfg->is_list() )
if( het_poly_fl )
{
// ... fill the network cfg array
for(unsigned i=0; i<inst->count; ++i)
for(unsigned i=0; i<netCfgN; ++i)
{
networkCfgA[i] = networkCfg->child_ele(i);
const object_t* pair = networkCfg->child_ele(i);
if( !networkCfgA[i]->is_dict() )
if( (pair->pair_label() == nullptr) || (pair->pair_value() == nullptr) || (!pair->pair_value()->is_dict()) )
{
cwLogError(kSyntaxErrorRC,"The network cfg. for the network index %i is not a dictionary.",i);
cwLogError(kSyntaxErrorRC,"The network cfg. for the network index %i is not a label/dictionary pair.",i);
goto errLabel;
}
else
{
netCfgA[i] = pair->pair_value();
netLabelA[i] = pair->pair_label();
}
}
}
proc->internal_net_cnt = netCfgN;
// create the network object - which will hold 'count' subnets - each a duplicate of the
// network described by 'networkCfg'.
if((rc = network_create(proc->ctx,networkCfgA,networkCfgN,proxyVarL,proc,inst->count,internal_net)) != kOkRC )
// create the network object
if((rc = network_create(proc->ctx,netLabelA,netCfgA,netCfgN,proxyVarL,poly_cnt,internal_net)) != kOkRC )
{
rc = cwLogError(rc,"Creation failed on the internal network.");
goto errLabel;
@ -342,25 +352,29 @@ namespace cw
goto errLabel;
}
inst->voiceN = 0;
for(network_t* net=internal_net; net!=nullptr; net=net->poly_link)
inst->voiceN += 1;
if( inst->parallel_fl )
{
network_t* net = internal_net;
// create a thread_tasks object
if((rc = thread_tasks::create( inst->threadTasksH, inst->count )) != kOkRC )
if((rc = thread_tasks::create( inst->threadTasksH, inst->voiceN )) != kOkRC )
{
rc = cwLogError(rc,"Thread machine create failed.");
goto errLabel;
}
// the taskA[] array is needed to hold voice specific info. for the call to thread_tasks::run()
inst->taskA = mem::allocZ<thread_tasks::task_t>(inst->count);
inst->voiceA = mem::allocZ<voice_t>(inst->count);
inst->taskA = mem::allocZ<thread_tasks::task_t>(inst->voiceN);
inst->voiceA = mem::allocZ<voice_t>(inst->voiceN);
for(unsigned i=0; net !=nullptr; ++i)
{
assert(i<inst->count);
inst->voiceA[i].voice_idx = i;
inst->voiceA[i].net = net;
@ -377,7 +391,8 @@ namespace cw
proc->internal_net = internal_net;
errLabel:
mem::release(networkCfgA);
mem::release(netCfgA);
mem::release(netLabelA);
return rc;
}
@ -431,7 +446,7 @@ namespace cw
if( p->parallel_fl )
{
if((rc = thread_tasks::run(p->threadTasksH,p->taskA,p->count)) != kOkRC )
if((rc = thread_tasks::run(p->threadTasksH,p->taskA,p->voiceN)) != kOkRC )
{
rc = cwLogError(rc,"poly internal network parallel exec failed.");
}
@ -4029,7 +4044,7 @@ namespace cw
goto errLabel;
}
poly_cnt = p->net_proc->internal_net==nullptr ? 0 : network_poly_count(*p->net_proc->internal_net);
poly_cnt = 0; //p->net_proc->internal_net==nullptr ? 0 : network_poly_count(*p->net_proc->internal_net);
if( poly_cnt < 3 )
{
@ -7966,6 +7981,7 @@ namespace cw
namespace poly_xform_ctl
{
enum {
kTriggerPId,
kOutChCntPId,
kOutChIdxPId,
kInBasePId,
@ -7976,17 +7992,26 @@ namespace cw
unsigned out_idx;
} in_var_t;
typedef struct out_var_str
{
int cnt;
} out_var_t;
typedef struct
{
unsigned inVarN;
in_var_t* inVarA;
unsigned outVarN;
out_var_t* outVarA;
unsigned midiBasePId;
unsigned doneFlBasePId;
unsigned outBasePId;
bool trigger_fl;
unsigned out_idx;
} inst_t;
@ -8055,15 +8080,20 @@ namespace cw
if((rc = var_register_and_get( proc, kAnyChIdx, kOutChCntPId, "out_ch_cnt", kBaseSfxId, p->outVarN )) != kOkRC )
goto errLabel;
// register the output selector var
if((rc = var_register( proc, kAnyChIdx, kOutChIdxPId,"out_ch_idx", kBaseSfxId )) != kOkRC )
if((rc = var_register( proc, kAnyChIdx,
kOutChIdxPId,"out_ch_idx", kBaseSfxId,
kTriggerPId, "trig", kBaseSfxId)) != kOkRC )
{
goto errLabel;
}
// create the output audio var's
for(unsigned i=0; i<p->outVarN; ++i)
if((rc = var_register_and_set( proc, "out", kBaseSfxId + i, p->outBasePId+i, kAnyChIdx, srate, chCntPerInputSignal, audioFrameN )) != kOkRC )
goto errLabel;
p->outVarA = mem::allocZ<out_var_t>(p->outVarN);
errLabel:
return rc;
@ -8081,6 +8111,9 @@ namespace cw
rc_t _value( proc_t* proc, inst_t* p, variable_t* var )
{
rc_t rc = kOkRC;
if( proc->ctx->isInRuntimeFl && var->vid == kTriggerPId )
p->trigger_fl = true;
return rc;
}
@ -8110,14 +8143,40 @@ namespace cw
}
unsigned _get_next_out_index(inst_t* p)
{
int min_cnt = p->outVarA[0].cnt;
unsigned min_idx = 0;
for(unsigned i=1; i<p->outVarN; ++i)
if( p->outVarA[i].cnt < min_cnt )
{
min_cnt = p->outVarA[i].cnt;
min_idx = i;
}
cwLogPrint("%i %i\n",min_idx,min_cnt);
return min_idx;
}
rc_t _exec( proc_t* proc, inst_t* p )
{
rc_t rc = kOkRC;
abuf_t* outAudioBufA[ p->outVarN ];
unsigned out_var_idx;
if((var_get(proc,kOutChIdxPId,kAnyChIdx,out_var_idx)) != kOkRC )
goto errLabel;
if( p->trigger_fl )
{
p->trigger_fl = false;
p->out_idx = _get_next_out_index(p);
var_set(proc,kOutChIdxPId,kAnyChIdx,p->out_idx);
}
//if((var_get(proc,kOutChIdxPId,kAnyChIdx,out_var_idx)) != kOkRC )
// goto errLabel;
// get the audio output buffers
for(unsigned i=0; i<p->outVarN; ++i)
@ -8141,7 +8200,8 @@ namespace cw
for(unsigned j=0; j<mbuf->msgN; ++j)
if( midi::isNoteOn(mbuf->msgA[j].status,mbuf->msgA[j].d1) )
{
p->inVarA[i].out_idx = out_var_idx;
p->inVarA[i].out_idx = p->out_idx;
p->outVarA[ p->out_idx ].cnt += 1;
//printf("VA: %i->%i\n",i,out_var_idx);
}
@ -8153,8 +8213,8 @@ namespace cw
// if this input channel is no longer active
if( p->inVarA[i].out_idx != kInvalidIdx && done_fl )
{
p->outVarA[ p->inVarA[i].out_idx ].cnt -= 1;
p->inVarA[i].out_idx = kInvalidIdx;
//printf("D:%i\n",i);
}
// if this channel has a valid out var index