cwFlow,cwFlowNet,cwFlowTypes,cwFlowProc : 'poly' processor can now handle heterogeneous arrays of networks.
This commit is contained in:
parent
f98dd37e49
commit
49b4a1430f
40
cwFlow.cpp
40
cwFlow.cpp
@ -780,17 +780,17 @@ cw::rc_t cw::flow::initialize( handle_t h,
|
||||
}
|
||||
|
||||
// instantiate the network
|
||||
if((rc = network_create(p,p->networkCfg,p->net,proxyVarL)) != kOkRC )
|
||||
if((rc = network_create(p,&p->networkCfg,1,proxyVarL,1,p->net)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Network creation failed.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if( p->printNetworkFl )
|
||||
network_print(p->net);
|
||||
if( p->printNetworkFl && p->net != nullptr )
|
||||
network_print(*p->net);
|
||||
|
||||
if( p->init_net_preset_label != nullptr )
|
||||
network_apply_preset( p->net, p->init_net_preset_label );
|
||||
if( p->init_net_preset_label != nullptr && p->net != nullptr )
|
||||
network_apply_preset( *p->net, p->init_net_preset_label );
|
||||
|
||||
p->isInRuntimeFl = true;
|
||||
cwLogInfo("Entering runtime.");
|
||||
@ -866,7 +866,7 @@ cw::rc_t cw::flow::exec_cycle( handle_t h )
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = exec_cycle(p->net);
|
||||
rc = exec_cycle(*p->net);
|
||||
p->cycleIndex += 1;
|
||||
}
|
||||
|
||||
@ -888,52 +888,52 @@ cw::rc_t cw::flow::exec( handle_t h )
|
||||
cw::rc_t cw::flow::apply_preset( handle_t h, const char* presetLabel )
|
||||
{
|
||||
flow_t* p = _handleToPtr(h);
|
||||
return network_apply_preset(p->net,presetLabel);
|
||||
return network_apply_preset(*p->net,presetLabel);
|
||||
}
|
||||
|
||||
cw::rc_t cw::flow::apply_dual_preset( handle_t h, const char* presetLabel_0, const char* presetLabel_1, double coeff )
|
||||
{
|
||||
flow_t* p = _handleToPtr(h);
|
||||
return network_apply_dual_preset(p->net,presetLabel_0, presetLabel_1, coeff );
|
||||
return network_apply_dual_preset(*p->net,presetLabel_0, presetLabel_1, coeff );
|
||||
}
|
||||
|
||||
cw::rc_t cw::flow::apply_preset( handle_t h, const multi_preset_selector_t& mps )
|
||||
{
|
||||
flow_t* p = _handleToPtr(h);
|
||||
return network_apply_preset(p->net,mps);
|
||||
return network_apply_preset(*p->net,mps);
|
||||
}
|
||||
|
||||
|
||||
|
||||
cw::rc_t cw::flow::set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, bool value )
|
||||
{ return set_variable_value( _handleToPtr(h)->net, inst_label, var_label, chIdx, value ); }
|
||||
{ return set_variable_value( *_handleToPtr(h)->net, inst_label, var_label, chIdx, value ); }
|
||||
|
||||
cw::rc_t cw::flow::set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, int value )
|
||||
{ return set_variable_value( _handleToPtr(h)->net, inst_label, var_label, chIdx, value ); }
|
||||
{ return set_variable_value( *_handleToPtr(h)->net, inst_label, var_label, chIdx, value ); }
|
||||
|
||||
cw::rc_t cw::flow::set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, unsigned value )
|
||||
{ return set_variable_value( _handleToPtr(h)->net, inst_label, var_label, chIdx, value ); }
|
||||
{ return set_variable_value( *_handleToPtr(h)->net, inst_label, var_label, chIdx, value ); }
|
||||
|
||||
cw::rc_t cw::flow::set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, float value )
|
||||
{ return set_variable_value( _handleToPtr(h)->net, inst_label, var_label, chIdx, value ); }
|
||||
{ return set_variable_value( *_handleToPtr(h)->net, inst_label, var_label, chIdx, value ); }
|
||||
|
||||
cw::rc_t cw::flow::set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, double value )
|
||||
{ return set_variable_value( _handleToPtr(h)->net, inst_label, var_label, chIdx, value ); }
|
||||
{ return set_variable_value( *_handleToPtr(h)->net, inst_label, var_label, chIdx, value ); }
|
||||
|
||||
cw::rc_t cw::flow::get_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, bool& valueRef )
|
||||
{ return get_variable_value( _handleToPtr(h)->net, inst_label, var_label, chIdx, valueRef ); }
|
||||
{ return get_variable_value( *_handleToPtr(h)->net, inst_label, var_label, chIdx, valueRef ); }
|
||||
|
||||
cw::rc_t cw::flow::get_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, int& valueRef )
|
||||
{ return get_variable_value( _handleToPtr(h)->net, inst_label, var_label, chIdx, valueRef ); }
|
||||
{ return get_variable_value( *_handleToPtr(h)->net, inst_label, var_label, chIdx, valueRef ); }
|
||||
|
||||
cw::rc_t cw::flow::get_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, unsigned& valueRef )
|
||||
{ return get_variable_value( _handleToPtr(h)->net, inst_label, var_label, chIdx, valueRef ); }
|
||||
{ return get_variable_value( *_handleToPtr(h)->net, inst_label, var_label, chIdx, valueRef ); }
|
||||
|
||||
cw::rc_t cw::flow::get_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, float& valueRef )
|
||||
{ return get_variable_value( _handleToPtr(h)->net, inst_label, var_label, chIdx, valueRef ); }
|
||||
{ return get_variable_value( *_handleToPtr(h)->net, inst_label, var_label, chIdx, valueRef ); }
|
||||
|
||||
cw::rc_t cw::flow::get_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, double& valueRef )
|
||||
{ return get_variable_value( _handleToPtr(h)->net, inst_label, var_label, chIdx, valueRef ); }
|
||||
{ return get_variable_value( *_handleToPtr(h)->net, inst_label, var_label, chIdx, valueRef ); }
|
||||
|
||||
|
||||
|
||||
@ -950,7 +950,7 @@ void cw::flow::print_network( handle_t h )
|
||||
for(unsigned i=0; i<p->deviceN; ++i)
|
||||
print_external_device( p->deviceA + i );
|
||||
|
||||
network_print(p->net);
|
||||
network_print(*p->net);
|
||||
}
|
||||
|
||||
|
||||
|
234
cwFlowNet.cpp
234
cwFlowNet.cpp
@ -123,25 +123,23 @@ namespace cw
|
||||
_network_preset_destroy( net.presetA[i] );
|
||||
mem::release(net.presetA);
|
||||
}
|
||||
|
||||
rc_t _network_destroy( network_t& net )
|
||||
|
||||
rc_t _network_destroy_one( network_t*& net )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
for(unsigned i=0; i<net->proc_arrayN; ++i)
|
||||
proc_destroy(net->proc_array[i]);
|
||||
|
||||
for(unsigned i=0; i<net.proc_arrayN; ++i)
|
||||
proc_destroy(net.proc_array[i]);
|
||||
mem::release(net->proc_array);
|
||||
net->proc_arrayN = 0;
|
||||
|
||||
mem::release(net.poly_voiceA);
|
||||
mem::release(net.proc_array);
|
||||
net.proc_arrayAllocN = 0;
|
||||
net.proc_arrayN = 0;
|
||||
_network_preset_array_destroy(*net);
|
||||
|
||||
_network_preset_array_destroy(net);
|
||||
mem::release(net->preset_pairA);
|
||||
net->preset_pairN = 0;
|
||||
|
||||
mem::release(net.preset_pairA);
|
||||
net.preset_pairN = 0;
|
||||
|
||||
net_global_var_t* gv=net.globalVarL;
|
||||
net_global_var_t* gv=net->globalVarL;
|
||||
while( gv != nullptr )
|
||||
{
|
||||
net_global_var_t* gv0 = gv->link;
|
||||
@ -150,6 +148,24 @@ namespace cw
|
||||
mem::release(gv);
|
||||
gv = gv0;
|
||||
}
|
||||
|
||||
mem::release(net);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _network_destroy( network_t*& net )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
while( net != nullptr )
|
||||
{
|
||||
network_t* n0 = net->poly_link;
|
||||
rc_t rc0;
|
||||
if((rc0 = _network_destroy_one(net)) != kOkRC )
|
||||
rc = cwLogError(rc0,"A network destroy failed.");
|
||||
net = n0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -380,6 +396,11 @@ namespace cw
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( labeled_net == nullptr && net.poly_link != nullptr )
|
||||
labeled_net = _io_stmt_find_labeled_network(*net.poly_link,net_proc_label );
|
||||
|
||||
|
||||
return labeled_net;
|
||||
}
|
||||
|
||||
@ -707,10 +728,10 @@ namespace cw
|
||||
else
|
||||
{
|
||||
if( textIsEqual(io_stmt.remote_net_label,"_") )
|
||||
remote_net = &proc->ctx->net;
|
||||
remote_net = proc->ctx->net;
|
||||
else
|
||||
{
|
||||
if((remote_net = _io_stmt_find_labeled_network(proc->ctx->net,io_stmt.remote_net_label)) == nullptr )
|
||||
if((remote_net = _io_stmt_find_labeled_network(*proc->ctx->net,io_stmt.remote_net_label)) == nullptr )
|
||||
{
|
||||
rc = cwLogError(kSyntaxErrorRC,"The source net '%s' was not found.",cwStringNullGuard(io_stmt.remote_net_label));
|
||||
goto errLabel;
|
||||
@ -2860,81 +2881,143 @@ namespace cw
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//==================================================================================================================
|
||||
//
|
||||
// Network - Create
|
||||
//
|
||||
|
||||
rc_t _network_create( flow_t* p,
|
||||
const object_t* networkCfg,
|
||||
unsigned sfx_id,
|
||||
variable_t* proxyVarL,
|
||||
network_t*& net_ref )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
unsigned procN = 0;
|
||||
network_t* net = mem::allocZ<network_t>();
|
||||
|
||||
// if the top level network has not been set then set it here.
|
||||
// (this is necessary so that proc's later in the exec order
|
||||
// can locate proc's earlier in the exec order)
|
||||
if(p->net == nullptr )
|
||||
p->net = net;
|
||||
|
||||
if((rc = networkCfg->getv("procs",net->procsCfg)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Failed on parsing required network cfg. elements.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if((rc = networkCfg->getv_opt("presets",net->presetsCfg)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Failed on parsing optional network cfg. elements.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
procN = net->procsCfg->child_count();
|
||||
net->proc_array = mem::allocZ<proc_t*>(procN);
|
||||
|
||||
// for each proc in the network
|
||||
for(unsigned j=0; j<procN; ++j)
|
||||
{
|
||||
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->proc_array[j] ) ) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"The processor instantiation at proc index %i failed.",j);
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
net->proc_arrayN += 1;
|
||||
}
|
||||
|
||||
|
||||
if((rc = _network_preset_pair_create_table(*net)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
_network_preset_parse_top_level_dict(p, *net, net->presetsCfg );
|
||||
|
||||
net_ref = net;
|
||||
errLabel:
|
||||
|
||||
if( rc != kOkRC )
|
||||
{
|
||||
if( p->net == net )
|
||||
p->net = nullptr;
|
||||
|
||||
net_ref = nullptr;
|
||||
|
||||
_network_destroy(net);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
cw::rc_t cw::flow::network_create( flow_t* p,
|
||||
const object_t* networkCfg,
|
||||
network_t& net,
|
||||
variable_t* proxyVarL,
|
||||
unsigned polyCnt )
|
||||
|
||||
|
||||
cw::rc_t cw::flow::network_create( flow_t* p,
|
||||
const object_t* const * netCfgA,
|
||||
unsigned netCfgN,
|
||||
variable_t* proxyVarL,
|
||||
unsigned polyCnt,
|
||||
network_t*& net_ref )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
if((rc = networkCfg->getv("procs",net.procsCfg)) != kOkRC )
|
||||
rc_t rc = kOkRC;
|
||||
network_t* n0 = nullptr;
|
||||
|
||||
net_ref = nullptr;
|
||||
|
||||
if( !(netCfgN==1 || netCfgN==polyCnt ))
|
||||
{
|
||||
rc = cwLogError(rc,"Failed on parsing required network cfg. elements.");
|
||||
cwLogError(kInvalidArgRC,"The count of network cfg's must be one, or must match the 'poly count'.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if((rc = networkCfg->getv_opt("presets",net.presetsCfg)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Failed on parsing optional network cfg. elements.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
net.proc_arrayAllocN = polyCnt * net.procsCfg->child_count();
|
||||
net.proc_array = mem::allocZ<proc_t*>(net.proc_arrayAllocN);
|
||||
net.proc_arrayN = 0;
|
||||
net.poly_voiceA = mem::allocZ<poly_voice_t>(polyCnt);
|
||||
|
||||
// for each subnet
|
||||
|
||||
for(unsigned i=0; i<polyCnt; ++i)
|
||||
{
|
||||
assert( i<polyCnt && net.proc_arrayN < net.proc_arrayAllocN );
|
||||
network_t* net = nullptr;
|
||||
|
||||
// track the first proc in each subnet
|
||||
net.poly_voiceA[i].proc_idx = net.proc_arrayN;
|
||||
net.poly_voiceA[i].net = &net;
|
||||
// All procs in a poly should share the same sfx_id
|
||||
// otherwise the sfx_id can be automatically generated.
|
||||
unsigned sfx_id = polyCnt>1 ? i : kInvalidId;
|
||||
|
||||
const object_t* cfg = i < netCfgN ? netCfgA[i] : netCfgA[0];
|
||||
|
||||
// for each proc in the network
|
||||
for(unsigned j=0; j<net.procsCfg->child_count(); ++j)
|
||||
if((rc = _network_create(p, cfg, sfx_id, proxyVarL, net)) != kOkRC )
|
||||
{
|
||||
const object_t* proc_cfg = net.procsCfg->child_ele(j);
|
||||
unsigned sfx_id = polyCnt>1 ? i : kInvalidId;
|
||||
|
||||
assert(net.proc_arrayN < net.proc_arrayAllocN );
|
||||
|
||||
// create the proc inst instance
|
||||
if( (rc= _proc_create( p, proc_cfg, sfx_id, net, proxyVarL, net.proc_array[net.proc_arrayN] ) ) != kOkRC )
|
||||
{
|
||||
//rc = cwLogError(rc,"The instantiation at proc index %i is invalid.",net.proc_arrayN);
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
net.proc_arrayN += 1;
|
||||
net.poly_voiceA[i].proc_cnt += 1;
|
||||
rc = cwLogError(rc,"Network create failed on poly index %i.",i);
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// The returned net is always the first in a poly chain
|
||||
if( net_ref == nullptr )
|
||||
net_ref = net;
|
||||
|
||||
net->poly_idx = i;
|
||||
|
||||
if( n0 != nullptr )
|
||||
n0->poly_link = net;
|
||||
|
||||
n0 = net;
|
||||
|
||||
}
|
||||
|
||||
|
||||
net.poly_cnt = polyCnt;
|
||||
|
||||
|
||||
if((rc = _network_preset_pair_create_table(net)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
_network_preset_parse_top_level_dict(p, net, net.presetsCfg );
|
||||
|
||||
errLabel:
|
||||
if( rc != kOkRC )
|
||||
_network_destroy(net);
|
||||
if( rc != kOkRC && net_ref != nullptr )
|
||||
_network_destroy(net_ref);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
cw::rc_t cw::flow::network_destroy( network_t& net )
|
||||
cw::rc_t cw::flow::network_destroy( network_t*& net )
|
||||
{
|
||||
return _network_destroy(net);
|
||||
}
|
||||
@ -2954,23 +3037,13 @@ const cw::object_t* cw::flow::find_network_preset( const network_t& net, const c
|
||||
return preset_value;
|
||||
}
|
||||
|
||||
cw::rc_t cw::flow::exec_cycle( network_t& net, unsigned proc_idx, unsigned proc_cnt )
|
||||
cw::rc_t cw::flow::exec_cycle( network_t& net )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
bool halt_fl = false;
|
||||
|
||||
if( proc_cnt == kInvalidCnt )
|
||||
proc_cnt = net.proc_arrayN;
|
||||
|
||||
|
||||
for(unsigned i=proc_idx; i<proc_idx+proc_cnt; ++i)
|
||||
for(unsigned i=0; i<net.proc_arrayN; ++i)
|
||||
{
|
||||
if( i >= net.proc_arrayN )
|
||||
{
|
||||
rc = cwLogError(kEleNotFoundRC,"Network exec cycle failed on an invalid proc index. %i >= %i.",i,net.proc_arrayN );
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if((rc = net.proc_array[i]->class_desc->members->exec(net.proc_array[i])) != kOkRC )
|
||||
{
|
||||
if( rc == kEofRC )
|
||||
@ -2983,7 +3056,6 @@ cw::rc_t cw::flow::exec_cycle( network_t& net, unsigned proc_idx, unsigned proc_
|
||||
}
|
||||
}
|
||||
|
||||
errLabel:
|
||||
return halt_fl ? kEofRC : rc;
|
||||
}
|
||||
|
||||
|
15
cwFlowNet.h
15
cwFlowNet.h
@ -5,18 +5,19 @@ namespace cw
|
||||
{
|
||||
namespace flow
|
||||
{
|
||||
rc_t network_create( flow_t* p,
|
||||
const object_t* subnetCfgA, // subnetCfgA[subNetCfgN] per subnet cfg record
|
||||
network_t& net, // Network object to be filled with new proc instances
|
||||
variable_t* proxyVarL, //
|
||||
unsigned polyCnt = 1 // Count of networks to create
|
||||
rc_t network_create( flow_t* p,
|
||||
const object_t* const * netCfgA, // subnetCfgA[subNetCfgN] per subnet cfg record
|
||||
unsigned netCfgN,
|
||||
variable_t* proxyVarL, //
|
||||
unsigned polyCnt, // Count of poly networks to create or 1 if the network is not poly
|
||||
network_t*& net_ref
|
||||
);
|
||||
|
||||
rc_t network_destroy( network_t& net );
|
||||
rc_t network_destroy( network_t*& net );
|
||||
|
||||
const object_t* find_network_preset( const network_t& net, const char* presetLabel );
|
||||
|
||||
rc_t exec_cycle( network_t& net, unsigned proc_idx=0, unsigned proc_cnt=kInvalidCnt );
|
||||
rc_t exec_cycle( network_t& net );
|
||||
|
||||
|
||||
rc_t get_variable( network_t& net, const char* inst_label, const char* var_label, unsigned chIdx, proc_t*& instPtrRef, variable_t*& varPtrRef );
|
||||
|
160
cwFlowProc.cpp
160
cwFlowProc.cpp
@ -141,7 +141,7 @@ namespace cw
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
network_t net;
|
||||
network_t* net;
|
||||
} inst_t;
|
||||
|
||||
|
||||
@ -156,7 +156,7 @@ namespace cw
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if((rc = network_create(proc->ctx,networkCfg,p->net,proc->varL)) != kOkRC )
|
||||
if((rc = network_create(proc->ctx,&networkCfg,1,proc->varL,1,p->net)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Creation failed on the subnet internal network.");
|
||||
goto errLabel;
|
||||
@ -164,7 +164,7 @@ namespace cw
|
||||
|
||||
// Set the internal net pointer in the base proc instance
|
||||
// so that network based utilities can scan it
|
||||
proc->internal_net = &p->net;
|
||||
proc->internal_net = p->net;
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
@ -189,8 +189,9 @@ namespace cw
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
if((rc = exec_cycle(p->net)) != kOkRC )
|
||||
rc = cwLogError(rc,"poly internal network exec failed.");
|
||||
if(p->net != nullptr )
|
||||
if((rc = exec_cycle(*p->net)) != kOkRC )
|
||||
rc = cwLogError(rc,"poly internal network exec failed.");
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -228,8 +229,8 @@ namespace cw
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned count; // count of duplicate subnets in 'net'
|
||||
network_t net; // internal network containing 'count' duplicate sub-nets
|
||||
unsigned count; // count of subnets in 'net'
|
||||
//network_t* net; // internal network containing 'count' duplicate sub-nets
|
||||
bool parallel_fl; // true if the subnets should be executed in parallel
|
||||
thread_tasks::handle_t threadTasksH; //
|
||||
thread_tasks::task_t* taskA; // taskA[ count ]
|
||||
@ -242,9 +243,7 @@ namespace cw
|
||||
rc_t rc = kOkRC;
|
||||
voice_t* v = (voice_t*)arg;
|
||||
|
||||
poly_voice_t* pv = v->net->poly_voiceA + v->voice_idx;
|
||||
|
||||
if((rc = exec_cycle(*v->net, pv->proc_idx, pv->proc_cnt)) != kOkRC )
|
||||
if((rc = exec_cycle(*v->net)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Parallel subnet exec failed on voice %i.",v->voice_idx);
|
||||
goto errLabel;
|
||||
@ -257,35 +256,77 @@ 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;
|
||||
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;
|
||||
network_t* internal_net = nullptr;
|
||||
|
||||
proc->userPtr = inst;
|
||||
|
||||
if((rc = var_register_and_get( proc, kAnyChIdx,
|
||||
kParallelFlPId, "parallel_fl", kBaseSfxId, inst->parallel_fl,
|
||||
kCountPId, "count", kBaseSfxId, inst->count )) != kOkRC )
|
||||
{
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if( inst->count == 0 )
|
||||
{
|
||||
cwLogWarning("The 'poly' %s:%i was given a count of 0.",proc->label,proc->label_sfx_id);
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// get the network cfg
|
||||
if((rc = proc->proc_cfg->getv("network",networkCfg)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"The 'network' cfg. was not found.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// get the 'parallel flag'
|
||||
if((rc = var_register_and_get( proc, kAnyChIdx,kParallelFlPId, "parallel_fl", kBaseSfxId, inst->parallel_fl )) != kOkRC )
|
||||
{
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// if the network is a list of cfgs
|
||||
if( networkCfg->is_list() )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// the network cannot be empty
|
||||
if( inst->count == 0 )
|
||||
{
|
||||
cwLogWarning("The 'poly' %s:%i was given a count of 0.",proc->label,proc->label_sfx_id);
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// allocate the network cfg array
|
||||
networkCfgA = mem::allocZ<const object_t*>(inst->count);
|
||||
|
||||
// by default there is only one cfg.
|
||||
networkCfgA[0] = networkCfg;
|
||||
|
||||
// ... but if there are more than one cfg ...
|
||||
if( networkCfg->is_list() )
|
||||
{
|
||||
// ... fill the network cfg array
|
||||
for(unsigned i=0; i<inst->count; ++i)
|
||||
{
|
||||
networkCfgA[i] = networkCfg->child_ele(i);
|
||||
|
||||
if( !networkCfgA[i]->is_dict() )
|
||||
{
|
||||
cwLogError(kSyntaxErrorRC,"The network cfg. for the network index %i is not a dictionary.",i);
|
||||
goto errLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// create the network object - which will hold 'count' subnets - each a duplicate of the
|
||||
// network described by 'networkCfg'.
|
||||
if((rc = network_create(proc->ctx,networkCfg,inst->net,proxyVarL,inst->count)) != kOkRC )
|
||||
if((rc = network_create(proc->ctx,networkCfgA,networkCfgN,proxyVarL,inst->count,internal_net)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Creation failed on the internal network.");
|
||||
goto errLabel;
|
||||
@ -293,6 +334,8 @@ namespace cw
|
||||
|
||||
if( inst->parallel_fl )
|
||||
{
|
||||
network_t* net = internal_net;
|
||||
|
||||
// create a thread_tasks object
|
||||
if((rc = thread_tasks::create( inst->threadTasksH, inst->count )) != kOkRC )
|
||||
{
|
||||
@ -304,29 +347,37 @@ namespace cw
|
||||
inst->taskA = mem::allocZ<thread_tasks::task_t>(inst->count);
|
||||
inst->voiceA = mem::allocZ<voice_t>(inst->count);
|
||||
|
||||
for(unsigned i=0; i<inst->count; ++i)
|
||||
for(unsigned i=0; net !=nullptr; ++i)
|
||||
{
|
||||
assert(i<inst->count);
|
||||
|
||||
inst->voiceA[i].voice_idx = i;
|
||||
inst->voiceA[i].net = &inst->net;
|
||||
inst->voiceA[i].net = net;
|
||||
|
||||
inst->taskA[i].func = _voice_thread_func;
|
||||
inst->taskA[i].arg = inst->voiceA + i;
|
||||
|
||||
net = net->poly_link;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set the internal net pointer in the base proc instance
|
||||
// so that network based utilities can scan it
|
||||
proc->internal_net = &inst->net;
|
||||
proc->internal_net = internal_net;
|
||||
|
||||
errLabel:
|
||||
mem::release(networkCfgA);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t destroy( proc_t* proc )
|
||||
{
|
||||
inst_t* p = (inst_t*)proc->userPtr;
|
||||
network_destroy(p->net);
|
||||
|
||||
if( proc->internal_net != nullptr )
|
||||
network_destroy(proc->internal_net);
|
||||
|
||||
thread_tasks::destroy(p->threadTasksH);
|
||||
mem::release( p->taskA);
|
||||
@ -355,7 +406,7 @@ namespace cw
|
||||
}
|
||||
else
|
||||
{
|
||||
if((rc = exec_cycle(p->net)) != kOkRC )
|
||||
if((rc = exec_cycle(*proc->internal_net)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"poly internal network exec failed.");
|
||||
}
|
||||
@ -3842,6 +3893,8 @@ namespace cw
|
||||
const char* presetLabel = nullptr;
|
||||
unsigned netLabelSfxId = kBaseSfxId;
|
||||
abuf_t* srateSrc = nullptr;
|
||||
unsigned poly_cnt = 0;
|
||||
network_t* net = nullptr;
|
||||
coeff_t dum_dbl;
|
||||
|
||||
inst_t* p = mem::allocZ<inst_t>();
|
||||
@ -3869,13 +3922,17 @@ namespace cw
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if( p->net_proc->internal_net->poly_cnt < 3 )
|
||||
poly_cnt = p->net_proc->internal_net==nullptr ? 0 : network_poly_count(*p->net_proc->internal_net);
|
||||
|
||||
if( poly_cnt < 3 )
|
||||
{
|
||||
cwLogError(rc,"The xfade_ctl source network must have at least 3 poly channels. %i < 3",p->net_proc->internal_net->poly_cnt);
|
||||
cwLogError(rc,"The xfade_ctl source network must have at least 3 poly channels. %i < 3",poly_cnt);
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
p->poly_ch_cnt = p->net_proc->internal_net->poly_cnt;
|
||||
p->poly_ch_cnt = poly_cnt;
|
||||
|
||||
net = p->net_proc->internal_net;
|
||||
|
||||
// create the gain output variables - one output for each poly-channel
|
||||
for(unsigned i=1; i<p->poly_ch_cnt; ++i)
|
||||
@ -3889,29 +3946,30 @@ namespace cw
|
||||
}
|
||||
|
||||
// count of proc's in one poly-ch of the poly network
|
||||
p->net_proc_cnt = p->net_proc->internal_net->proc_arrayN / p->net_proc->internal_net->poly_cnt;
|
||||
//p->net_proc_cnt = p->net_proc->internal_net->proc_arrayN / p->net_proc->internal_net->poly_cnt;
|
||||
|
||||
p->netA = mem::allocZ<poly_ch_t>(p->poly_ch_cnt);
|
||||
|
||||
// create the proxy network networks
|
||||
for(unsigned i=0; i<p->poly_ch_cnt; ++i)
|
||||
for(unsigned i=0; i<p->poly_ch_cnt; ++i,net=net->poly_link)
|
||||
{
|
||||
p->netA[i].net.proc_arrayAllocN = p->net_proc_cnt;
|
||||
p->netA[i].net.proc_arrayN = p->netA[i].net.proc_arrayAllocN;
|
||||
p->netA[i].net.proc_array = mem::allocZ<proc_t*>(p->netA[i].net.proc_arrayAllocN);
|
||||
p->netA[i].net.presetsCfg = p->net_proc->internal_net->presetsCfg;
|
||||
|
||||
p->netA[i].net.presetA = p->net_proc->internal_net->presetA;
|
||||
p->netA[i].net.presetN = p->net_proc->internal_net->presetN;
|
||||
assert(net != nullptr );
|
||||
|
||||
p->netA[i].net.preset_pairA = p->net_proc->internal_net->preset_pairA;
|
||||
p->netA[i].net.preset_pairN = p->net_proc->internal_net->preset_pairN;
|
||||
p->netA[i].net.proc_arrayN = net->proc_arrayN;
|
||||
p->netA[i].net.proc_array = mem::allocZ<proc_t*>(p->netA[i].net.proc_arrayN);
|
||||
p->netA[i].net.presetsCfg = net->presetsCfg;
|
||||
|
||||
for(unsigned j=0,k=0; j<p->net_proc->internal_net->proc_arrayN; ++j)
|
||||
if( p->net_proc->internal_net->proc_array[j]->label_sfx_id == i )
|
||||
p->netA[i].net.presetA = net->presetA;
|
||||
p->netA[i].net.presetN = net->presetN;
|
||||
|
||||
p->netA[i].net.preset_pairA = net->preset_pairA;
|
||||
p->netA[i].net.preset_pairN = net->preset_pairN;
|
||||
|
||||
for(unsigned j=0,k=0; j<net->proc_arrayN; ++j)
|
||||
if( net->proc_array[j]->label_sfx_id == i )
|
||||
{
|
||||
assert( k < p->net_proc_cnt );
|
||||
p->netA[i].net.proc_array[k++] = p->net_proc->internal_net->proc_array[j];
|
||||
p->netA[i].net.proc_array[k++] = net->proc_array[j];
|
||||
}
|
||||
}
|
||||
|
||||
@ -4005,7 +4063,7 @@ namespace cw
|
||||
}
|
||||
|
||||
// update the cross-fade gain outputs
|
||||
for(unsigned i=0; i<p->net_proc->internal_net->poly_cnt; ++i)
|
||||
for(unsigned i=0; i<p->poly_ch_cnt; ++i)
|
||||
{
|
||||
p->netA[i].cur_gain += _signum(p->netA[i].target_gain - p->netA[i].cur_gain) * delta_gain_per_cycle;
|
||||
|
||||
|
@ -1721,6 +1721,15 @@ errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
unsigned cw::flow::network_poly_count( const network_t& net )
|
||||
{
|
||||
unsigned n =1;
|
||||
for(const network_t* n0 = net.poly_link; n0!=nullptr; n0=n0->poly_link)
|
||||
++n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void cw::flow::proc_destroy( proc_t* proc )
|
||||
{
|
||||
if( proc == nullptr )
|
||||
@ -1793,9 +1802,17 @@ cw::rc_t cw::flow::proc_validate( proc_t* proc )
|
||||
|
||||
cw::flow::proc_t* cw::flow::proc_find( network_t& net, const char* proc_label, unsigned sfx_id )
|
||||
{
|
||||
|
||||
for(unsigned i=0; i<net.proc_arrayN; ++i)
|
||||
{
|
||||
assert( net.proc_array[i] != nullptr );
|
||||
|
||||
if( net.proc_array[i]->label_sfx_id==sfx_id && textIsEqual(proc_label,net.proc_array[i]->label) )
|
||||
return net.proc_array[i];
|
||||
}
|
||||
|
||||
if( net.poly_link != nullptr )
|
||||
return proc_find(*net.poly_link, proc_label, sfx_id );
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -317,25 +317,13 @@ namespace cw
|
||||
|
||||
} net_global_var_t;
|
||||
|
||||
typedef struct poly_voice_str
|
||||
{
|
||||
struct network_str* net; // Network containing the proc's referened by proc_idx, proc_cnt
|
||||
unsigned proc_idx; // Index into network_t.proc_array[] of first proc in voice
|
||||
unsigned proc_cnt; // Count of proc's in the voice
|
||||
rc_t rc; // Result code from last call to exec_cycle()
|
||||
} poly_voice_t;
|
||||
|
||||
typedef struct network_str
|
||||
{
|
||||
const object_t* procsCfg; // network proc list
|
||||
const object_t* presetsCfg; // presets designed for this network
|
||||
|
||||
poly_voice_t* poly_voiceA; // poly_voiceA[ poly_cnt ].
|
||||
unsigned poly_cnt; // count of duplicated networks in the list
|
||||
|
||||
struct proc_str** proc_array;
|
||||
|
||||
unsigned proc_arrayAllocN;
|
||||
unsigned proc_arrayN;
|
||||
|
||||
network_preset_t* presetA;
|
||||
@ -346,6 +334,10 @@ namespace cw
|
||||
unsigned preset_pairN;
|
||||
|
||||
net_global_var_t* globalVarL;
|
||||
|
||||
struct network_str* poly_link;
|
||||
unsigned poly_idx;
|
||||
|
||||
} network_t;
|
||||
|
||||
|
||||
@ -382,7 +374,7 @@ namespace cw
|
||||
|
||||
const char* proj_dir; // default input/output directory
|
||||
|
||||
network_t net;
|
||||
network_t* net;
|
||||
|
||||
} flow_t;
|
||||
|
||||
@ -473,6 +465,8 @@ namespace cw
|
||||
unsigned proc_mult_count( const network_t& net, const char* proc_label );
|
||||
|
||||
rc_t proc_mult_sfx_id_array( const network_t& net, const char* proc_label, unsigned* idA, unsigned idAllocN, unsigned& idN_ref );
|
||||
|
||||
unsigned network_poly_count( const network_t& net );
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -321,7 +321,7 @@ cw::rc_t cw::thread_tasks::create( handle_t& hRef, unsigned threadN )
|
||||
p->threadA[i].owner = p;
|
||||
p->threadA[i].threadId = i;
|
||||
|
||||
// Threads are create in 'paused' mode
|
||||
// Threads are created in 'paused' mode
|
||||
if((rc = thread::create( p->threadA[i].threadH, _threadFunc, p->threadA + i, label )) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Task thread create %i failed.",i);
|
||||
|
Loading…
Reference in New Issue
Block a user