From fc94d3859da4beaa823ebd86696e1750a1b5b80b Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 27 Dec 2024 15:24:44 -0500 Subject: [PATCH] cwFlowProc.cpp, cwFlow.cpp,cwFlowNet.h/cpp : Implemented presets for het. poly nets. --- cwFlow.cpp | 3 +- cwFlowNet.cpp | 287 ++++++++++++++++++++++++++++++++----------------- cwFlowNet.h | 12 +-- cwFlowProc.cpp | 172 +++++++++++++++++++---------- 4 files changed, 311 insertions(+), 163 deletions(-) diff --git a/cwFlow.cpp b/cwFlow.cpp index 0b1e4cf..81f31a4 100644 --- a/cwFlow.cpp +++ b/cwFlow.cpp @@ -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; diff --git a/cwFlowNet.cpp b/cwFlowNet.cpp index e8de8fc..cb91c21 100644 --- a/cwFlowNet.cpp +++ b/cwFlowNet.cpp @@ -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,53 +2573,112 @@ 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; + 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; + network_preset_t* poly_net_preset = nullptr; - for(unsigned i=0; ipresetN; ++i) - if( textIsEqual(poly_net->presetA[i].label,preset_label) ) - { - poly_net_preset = poly_net->presetA + i; - break; - } - - if( poly_net_preset == nullptr ) + for(unsigned i=0; ipresetN; ++i) + if( textIsEqual(poly_net->presetA[i].label,preset_label) ) { - 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); - goto errLabel; + poly_net_preset = poly_net->presetA + i; + break; } - preset_value = mem::allocZ(); - - 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 ); + if( poly_net_preset == nullptr ) + { + 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; } - + preset_value = mem::allocZ(); + + preset_value->tid = kNetRefPresetValueTId; + preset_value->u.npv.net_preset = poly_net_preset; + preset_value->u.npv.net_preset_net = poly_net; + + _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; icfg->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; ichild_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,15 +2707,34 @@ 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: + // : + // where: + // identifies a proc inside this network where the will be applied. + // idenfifies a label or a dictionary of : 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 ) @@ -2660,19 +2742,10 @@ namespace cw rc = cwLogError(rc,"The proc preset label '%s' could not be parsed on the preset:'%s'",cwStringNullGuard(proc_preset_label),cwStringNullGuard(proc_label)); goto errLabel; } - - - // 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,45 +3501,57 @@ 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; i1 ? 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]; - network_t* net = mem::allocZ(); - - net->owner_proc = owner_proc; - net->polyN = polyCnt; - net->poly_idx = i; - - if( net_ref == nullptr ) - net_ref = net; - - if( n0 != nullptr ) - n0->poly_link = net; - - n0 = net; - - // create the network - if((rc = _network_init(p, netCfg, sfx_id, proxyVarL, net)) != kOkRC ) + // overrride poly_cnt with the optional 'count' field passed from the caller + if((rc = netCfg->getv_opt("count",poly_cnt)) != kOkRC ) { - rc = cwLogError(rc,"Network create failed on poly index %i.",i); + 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(); + + //net->owner_proc = owner_proc; + net->label = netLabel; + net->polyN = poly_cnt; + net->poly_idx = i; + + if( net_ref == nullptr ) + net_ref = net; + + if( n0 != nullptr ) + n0->poly_link = net; + + n0 = net; + + // create the network + 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 ) diff --git a/cwFlowNet.h b/cwFlowNet.h index 6cabab1..98ccf5c 100644 --- a/cwFlowNet.h +++ b/cwFlowNet.h @@ -12,12 +12,12 @@ 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 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. + const char* const * netLabelA, // netLabel[netCfgN] + const object_t* const * netCfgA, // netCfgA[netCfgN] + unsigned netCfgN, // count of cfg. records in netCfgN + variable_t* proxyVarL, // + unsigned polyCnt, // Count of poly subnets to create or 1 if the network is not poly + network_t*& net_ref // Returned network handle. ); rc_t network_destroy( network_t*& net ); diff --git a/cwFlowProc.cpp b/cwFlowProc.cpp index ae2bca9..7911416 100644 --- a/cwFlowProc.cpp +++ b/cwFlowProc.cpp @@ -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; @@ -203,13 +203,13 @@ namespace cw } voice_t; 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 preset_sfx_id; + unsigned voiceN; + unsigned preset_sfx_id; } inst_t; rc_t _poly_thread_func( void* arg ) @@ -253,17 +253,21 @@ namespace cw } + rc_t create( proc_t* proc ) { - rc_t rc = kOkRC; - inst_t* inst = mem::allocZ(); - const object_t* networkCfg = nullptr; - variable_t* proxyVarL = nullptr; - const object_t** networkCfgA = nullptr; - unsigned networkCfgN = 1; - network_t* internal_net = nullptr; + rc_t rc = kOkRC; + inst_t* inst = mem::allocZ(); + const object_t* networkCfg = nullptr; + variable_t* proxyVarL = nullptr; + 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; + 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; - } - else - { - // otherwise multiple networks use the same cfg - if((rc = var_register_and_get( proc, kAnyChIdx,kCountPId,"count", kBaseSfxId, inst->count )) != kOkRC ) - { - goto errLabel; - } + netCfgN = networkCfg->child_count(); } - // the network cannot be empty - if( inst->count == 0 ) + + // get the default poly count + if((rc = var_register_and_get( proc, kAnyChIdx,kCountPId,"count", kBaseSfxId, poly_cnt )) != kOkRC ) { - cwLogWarning("The 'poly' %s:%i was given a count of 0.",proc->label,proc->label_sfx_id); + goto errLabel; + } + + // the network cannot be empty + if( netCfgN == 0 ) + { + 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(inst->count); + netCfgA = mem::allocZ(netCfgN); + netLabelA = mem::allocZ(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; icount; ++i) + for(unsigned i=0; ichild_ele(i); - - if( !networkCfgA[i]->is_dict() ) + const object_t* pair = networkCfg->child_ele(i); + + 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); - goto errLabel; + 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(); } } } - - - // 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 ) + + proc->internal_net_cnt = netCfgN; + + // 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(inst->count); - inst->voiceA = mem::allocZ(inst->count); + inst->taskA = mem::allocZ(inst->voiceN); + inst->voiceA = mem::allocZ(inst->voiceN); for(unsigned i=0; net !=nullptr; ++i) - { - assert(icount); - + { 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, @@ -7975,6 +7991,11 @@ namespace cw { unsigned out_idx; } in_var_t; + + typedef struct out_var_str + { + int cnt; + } out_var_t; typedef struct { @@ -7982,10 +8003,14 @@ namespace cw 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,14 +8080,19 @@ 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; ioutVarN; ++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(p->outVarN); errLabel: @@ -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; ioutVarN; ++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; ioutVarN; ++i) @@ -8141,7 +8200,8 @@ namespace cw for(unsigned j=0; jmsgN; ++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