cwFlowProc.cpp : Refactored xfade_ctl to implement preset updates.
This commit is contained in:
parent
f2dea88734
commit
072d0eecd6
289
cwFlowProc.cpp
289
cwFlowProc.cpp
@ -3340,27 +3340,31 @@ namespace cw
|
|||||||
kGainPId,
|
kGainPId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct poly_ch_str
|
||||||
|
{
|
||||||
|
network_t net;
|
||||||
|
coeff_t target_gain;
|
||||||
|
coeff_t cur_gain;
|
||||||
|
} poly_ch_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned xfadeDurMs; // crossfade duration in milliseconds
|
unsigned xfadeDurMs; // crossfade duration in milliseconds
|
||||||
instance_t* net_proc; // source 'poly' network
|
instance_t* net_proc; // source 'poly' network
|
||||||
network_t net; // internal proxy network
|
poly_ch_t* netA; // netA[ poly_ch_cnt ] internal proxy network
|
||||||
unsigned poly_ch_cnt; // set to 2 (one for 'cur' poly-ch., one for 'next' poly-ch.)
|
unsigned poly_ch_cnt; // count of poly channels in net_proc
|
||||||
unsigned net_proc_cnt; // count of proc's in a single poly-channel (net_proc->proc_arrayN/poly_cnt)
|
unsigned net_proc_cnt; // count of proc's in a single poly-channel (net_proc->proc_arrayN/poly_cnt)
|
||||||
unsigned cur_poly_ch_idx; //
|
unsigned cur_poly_ch_idx; // This is the active channel.
|
||||||
unsigned next_poly_ch_idx; //
|
unsigned next_poly_ch_idx; // This is the next channel that will be active.
|
||||||
float* target_gainA; // target_gainA[net_proc->poly_cnt]
|
srate_t srate; // Sample rate used for time base
|
||||||
float* cur_gainA; // cur_gainA[net_proc->poly_cnt]
|
bool preset_delta_fl; // Preset change trigger flag.
|
||||||
double srate;
|
bool trigFl; // Cross-fade trigger flag.
|
||||||
bool preset_delta_fl;
|
|
||||||
bool trigFl;
|
|
||||||
bool trigVal;
|
|
||||||
} inst_t;
|
} inst_t;
|
||||||
|
|
||||||
void _trigger_xfade( inst_t* p )
|
void _trigger_xfade( inst_t* p )
|
||||||
{
|
{
|
||||||
// begin fading out the cur channel
|
// begin fading out the cur channel
|
||||||
p->target_gainA[ p->cur_poly_ch_idx ] = 0;
|
p->netA[p->cur_poly_ch_idx].target_gain = 0;
|
||||||
|
|
||||||
// the next poly-ch become the cur poly-ch
|
// the next poly-ch become the cur poly-ch
|
||||||
p->cur_poly_ch_idx = p->next_poly_ch_idx;
|
p->cur_poly_ch_idx = p->next_poly_ch_idx;
|
||||||
@ -3368,25 +3372,11 @@ namespace cw
|
|||||||
// the next poly-ch advances
|
// the next poly-ch advances
|
||||||
p->next_poly_ch_idx = p->next_poly_ch_idx+1 >= p->poly_ch_cnt ? 0 : p->next_poly_ch_idx+1;
|
p->next_poly_ch_idx = p->next_poly_ch_idx+1 >= p->poly_ch_cnt ? 0 : p->next_poly_ch_idx+1;
|
||||||
|
|
||||||
// j selects a block of 'net_proc_cnt' slots in the proxy network which will become the 'next' channel
|
|
||||||
unsigned j = p->next_poly_ch_idx * p->net_proc_cnt;
|
|
||||||
|
|
||||||
// set the [j:j+poly_proc_cnt] pointers in the proxy net to the actual proc instances in the source net
|
|
||||||
for(unsigned i=0; i<p->net_proc->internal_net->proc_arrayN; ++i)
|
|
||||||
if( p->net_proc->internal_net->proc_array[i]->label_sfx_id == p->next_poly_ch_idx )
|
|
||||||
{
|
|
||||||
assert( p->next_poly_ch_idx * p->net_proc_cnt <= j
|
|
||||||
&& j < p->next_poly_ch_idx * p->net_proc_cnt + p->net_proc_cnt
|
|
||||||
&& j < p->net.proc_arrayN );
|
|
||||||
|
|
||||||
p->net.proc_array[j++] = p->net_proc->internal_net->proc_array[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// begin fading in the new cur channel
|
// begin fading in the new cur channel
|
||||||
p->target_gainA[ p->cur_poly_ch_idx ] = 1;
|
p->netA[p->cur_poly_ch_idx].target_gain = 1;
|
||||||
|
|
||||||
// if the next channel is not already at 0 send it in that direction
|
// if the next channel is not already at 0 send it in that direction
|
||||||
p->target_gainA[ p->next_poly_ch_idx ] = 0;
|
p->netA[p->next_poly_ch_idx].target_gain = 0;
|
||||||
|
|
||||||
//printf("xfad:%i %i : %i\n",p->cur_poly_ch_idx, p->next_poly_ch_idx,p->poly_ch_cnt);
|
//printf("xfad:%i %i : %i\n",p->cur_poly_ch_idx, p->next_poly_ch_idx,p->poly_ch_cnt);
|
||||||
|
|
||||||
@ -3398,22 +3388,21 @@ namespace cw
|
|||||||
const char* netLabel = nullptr;
|
const char* netLabel = nullptr;
|
||||||
const char* presetLabel = nullptr;
|
const char* presetLabel = nullptr;
|
||||||
unsigned netLabelSfxId = kBaseSfxId;
|
unsigned netLabelSfxId = kBaseSfxId;
|
||||||
bool trigFl = false;
|
|
||||||
variable_t* gainVar = nullptr;
|
|
||||||
abuf_t* srateSrc = nullptr;
|
abuf_t* srateSrc = nullptr;
|
||||||
double dum_dbl;
|
coeff_t dum_dbl;
|
||||||
|
|
||||||
inst_t* p = mem::allocZ<inst_t>();
|
inst_t* p = mem::allocZ<inst_t>();
|
||||||
|
|
||||||
ctx->userPtr = p;
|
ctx->userPtr = p;
|
||||||
|
|
||||||
|
if((rc = var_register(ctx,kAnyChIdx,kTriggerPId,"trigger", kBaseSfxId )) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
if((rc = var_register_and_get(ctx,kAnyChIdx,
|
if((rc = var_register_and_get(ctx,kAnyChIdx,
|
||||||
kNetLabelPId, "net", kBaseSfxId, netLabel,
|
kNetLabelPId, "net", kBaseSfxId, netLabel,
|
||||||
kNetLabelSfxPId, "netSfxId", kBaseSfxId, netLabelSfxId,
|
kNetLabelSfxPId, "netSfxId", kBaseSfxId, netLabelSfxId,
|
||||||
kSrateRefPId, "srateSrc", kBaseSfxId, srateSrc,
|
kSrateRefPId, "srateSrc", kBaseSfxId, srateSrc,
|
||||||
kDurMsPId, "durMs", kBaseSfxId, p->xfadeDurMs,
|
kDurMsPId, "durMs", kBaseSfxId, p->xfadeDurMs,
|
||||||
kTriggerPId, "trigger", kBaseSfxId, p->trigVal,
|
|
||||||
kPresetPId, "preset", kBaseSfxId, presetLabel,
|
kPresetPId, "preset", kBaseSfxId, presetLabel,
|
||||||
kGainPId, "gain", kBaseSfxId, dum_dbl)) != kOkRC )
|
kGainPId, "gain", kBaseSfxId, dum_dbl)) != kOkRC )
|
||||||
{
|
{
|
||||||
@ -3435,9 +3424,8 @@ namespace cw
|
|||||||
|
|
||||||
p->poly_ch_cnt = p->net_proc->internal_net->poly_cnt;
|
p->poly_ch_cnt = p->net_proc->internal_net->poly_cnt;
|
||||||
|
|
||||||
|
|
||||||
// create the gain output variables - one output for each poly-channel
|
// create the gain output variables - one output for each poly-channel
|
||||||
for(unsigned i=1; i<p->net_proc->internal_net->poly_cnt; ++i)
|
for(unsigned i=1; i<p->poly_ch_cnt; ++i)
|
||||||
{
|
{
|
||||||
variable_t* dum;
|
variable_t* dum;
|
||||||
if((rc = var_create(ctx, "gain", i, kGainPId+i, kAnyChIdx, nullptr, kInvalidTFl, dum )) != kOkRC )
|
if((rc = var_create(ctx, "gain", i, kGainPId+i, kAnyChIdx, nullptr, kInvalidTFl, dum )) != kOkRC )
|
||||||
@ -3450,17 +3438,29 @@ namespace cw
|
|||||||
// count of proc's in one poly-ch of the poly network
|
// 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;
|
||||||
|
|
||||||
// create the proxy network
|
p->netA = mem::allocZ<poly_ch_t>(p->poly_ch_cnt);
|
||||||
p->net.proc_arrayAllocN = p->net_proc_cnt * p->poly_ch_cnt;
|
|
||||||
p->net.proc_arrayN = p->net.proc_arrayAllocN;
|
// create the proxy network networks
|
||||||
p->net.proc_array = mem::allocZ<instance_t*>(p->net.proc_arrayAllocN);
|
for(unsigned i=0; i<p->poly_ch_cnt; ++i)
|
||||||
p->target_gainA = mem::allocZ<float>(p->net_proc->internal_net->poly_cnt);
|
{
|
||||||
p->cur_gainA = mem::allocZ<float>(p->net_proc->internal_net->poly_cnt);
|
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<instance_t*>(p->netA[i].net.proc_arrayAllocN);
|
||||||
|
p->netA[i].net.presetsCfg = p->net_proc->internal_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 )
|
||||||
|
{
|
||||||
|
assert( k < p->net_proc_cnt );
|
||||||
|
p->netA[i].net.proc_array[k++] = p->net_proc->internal_net->proc_array[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( srateSrc == nullptr )
|
||||||
|
p->srate = ctx->ctx->sample_rate;
|
||||||
|
else
|
||||||
p->srate = srateSrc->srate;
|
p->srate = srateSrc->srate;
|
||||||
|
|
||||||
// make the proxy network public - xfad_ctl now looks like the source network
|
|
||||||
// because it has the same proc instances
|
|
||||||
ctx->internal_net = &p->net;
|
|
||||||
|
|
||||||
// setup the channels such that the first active channel after _trigger_xfade()
|
// setup the channels such that the first active channel after _trigger_xfade()
|
||||||
// will be channel 0
|
// will be channel 0
|
||||||
@ -3469,8 +3469,6 @@ namespace cw
|
|||||||
_trigger_xfade(p); // cur=2 nxt=0 initialize inst ptrs in range: p->net[0:net_proc_cnt]
|
_trigger_xfade(p); // cur=2 nxt=0 initialize inst ptrs in range: p->net[0:net_proc_cnt]
|
||||||
_trigger_xfade(p); // cur=0 nxt=1 initialize inst ptrs in range: p->net[net_proc_cnt:2*net_proc_cnt]
|
_trigger_xfade(p); // cur=0 nxt=1 initialize inst ptrs in range: p->net[net_proc_cnt:2*net_proc_cnt]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -3478,9 +3476,10 @@ namespace cw
|
|||||||
rc_t destroy( instance_t* ctx )
|
rc_t destroy( instance_t* ctx )
|
||||||
{
|
{
|
||||||
inst_t* p = (inst_t*)ctx->userPtr;
|
inst_t* p = (inst_t*)ctx->userPtr;
|
||||||
mem::release(p->net.proc_array);
|
for(unsigned i=0; i<p->poly_ch_cnt; ++i)
|
||||||
mem::release(p->target_gainA);
|
mem::release(p->netA[i].net.proc_array);
|
||||||
mem::release(p->cur_gainA);
|
|
||||||
|
mem::release(p->netA);
|
||||||
mem::release(ctx->userPtr);
|
mem::release(ctx->userPtr);
|
||||||
|
|
||||||
return kOkRC;
|
return kOkRC;
|
||||||
@ -3491,19 +3490,15 @@ namespace cw
|
|||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
inst_t* p = (inst_t*)ctx->userPtr;
|
inst_t* p = (inst_t*)ctx->userPtr;
|
||||||
|
|
||||||
if(var->vid == kTriggerPId )
|
switch( var->vid )
|
||||||
{
|
{
|
||||||
bool v;
|
case kTriggerPId:
|
||||||
if((rc = var_get(var,v)) == kOkRC )
|
p->trigFl = true;
|
||||||
{
|
break;
|
||||||
if( !p->trigFl )
|
|
||||||
p->trigFl = p->trigVal != v;
|
|
||||||
|
|
||||||
p->trigVal = v;
|
|
||||||
}
|
|
||||||
//printf("tr:%i %i %i\n",v,p->trigVal,p->trigFl);
|
|
||||||
|
|
||||||
|
|
||||||
|
case kPresetPId:
|
||||||
|
p->preset_delta_fl = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return kOkRC;
|
return kOkRC;
|
||||||
@ -3517,6 +3512,32 @@ namespace cw
|
|||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
inst_t* p = (inst_t*)ctx->userPtr;
|
inst_t* p = (inst_t*)ctx->userPtr;
|
||||||
|
|
||||||
|
// time in sample frames to complete a xfade
|
||||||
|
double xfade_dur_smp = p->xfadeDurMs * p->srate / 1000.0;
|
||||||
|
|
||||||
|
// fraction of a xfade which will be completed in on exec() cycle
|
||||||
|
float delta_gain_per_cycle = (float)(ctx->ctx->framesPerCycle / xfade_dur_smp);
|
||||||
|
|
||||||
|
|
||||||
|
if( p->preset_delta_fl )
|
||||||
|
{
|
||||||
|
const char* preset_label = nullptr;
|
||||||
|
|
||||||
|
p->preset_delta_fl = false;
|
||||||
|
|
||||||
|
if((rc = var_get(ctx,kPresetPId,kAnyChIdx,preset_label)) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = cwLogError(rc,"Preset label access failed.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((rc = network_apply_preset(p->netA[p->next_poly_ch_idx].net, preset_label,p->next_poly_ch_idx)) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = cwLogError(rc,"Appy preset '%s' failed.",cwStringNullGuard(preset_label));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check if a cross-fade has been triggered
|
// check if a cross-fade has been triggered
|
||||||
if(p->trigFl )
|
if(p->trigFl )
|
||||||
{
|
{
|
||||||
@ -3524,22 +3545,19 @@ namespace cw
|
|||||||
_trigger_xfade(p);
|
_trigger_xfade(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// time in sample frames to complete a xfade
|
|
||||||
double xfade_dur_smp = p->xfadeDurMs * p->srate / 1000.0;
|
|
||||||
|
|
||||||
// fraction of a xfade which will be completed in on exec() cycle
|
|
||||||
float delta_gain_per_cycle = (float)(ctx->ctx->framesPerCycle / xfade_dur_smp);
|
|
||||||
|
|
||||||
// update the cross-fade gain outputs
|
// 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->net_proc->internal_net->poly_cnt; ++i)
|
||||||
{
|
{
|
||||||
p->cur_gainA[i] += _signum(p->target_gainA[i] - p->cur_gainA[i]) * delta_gain_per_cycle;
|
p->netA[i].cur_gain += _signum(p->netA[i].target_gain - p->netA[i].cur_gain) * delta_gain_per_cycle;
|
||||||
|
|
||||||
p->cur_gainA[i] = std::min(1.0f, std::max(0.0f, p->cur_gainA[i]));
|
p->netA[i].cur_gain = std::min(1.0f, std::max(0.0f, p->netA[i].cur_gain));
|
||||||
|
|
||||||
var_set(ctx,kGainPId+i,kAnyChIdx,p->cur_gainA[i]);
|
var_set(ctx,kGainPId+i,kAnyChIdx,p->netA[i].cur_gain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -4402,7 +4420,8 @@ namespace cw
|
|||||||
{
|
{
|
||||||
kInPId,
|
kInPId,
|
||||||
kListPId,
|
kListPId,
|
||||||
kOutPId
|
kOutPId,
|
||||||
|
kValueBasePId
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -4509,7 +4528,7 @@ namespace cw
|
|||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
rc_t _set_out_tmpl( instance_t* proc, inst_t* p, unsigned idx, T& v )
|
rc_t _set_out_tmpl( instance_t* proc, inst_t* p, unsigned idx, unsigned vid, T& v )
|
||||||
{
|
{
|
||||||
rc_t rc;
|
rc_t rc;
|
||||||
const object_t* ele;
|
const object_t* ele;
|
||||||
@ -4529,7 +4548,7 @@ namespace cw
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set the output
|
// set the output
|
||||||
if((rc = var_set(proc,kOutPId,kAnyChIdx,v)) != kOkRC )
|
if((rc = var_set(proc,vid,kAnyChIdx,v)) != kOkRC )
|
||||||
{
|
{
|
||||||
rc = cwLogError(rc,"List output failed on index %i",idx);
|
rc = cwLogError(rc,"List output failed on index %i",idx);
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
@ -4539,6 +4558,64 @@ namespace cw
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc_t _set_output( instance_t* proc, inst_t* p, unsigned idx, unsigned vid )
|
||||||
|
{
|
||||||
|
rc_t rc;
|
||||||
|
|
||||||
|
switch( p->typeFl )
|
||||||
|
{
|
||||||
|
case kUIntTFl:
|
||||||
|
{
|
||||||
|
unsigned v;
|
||||||
|
rc = _set_out_tmpl(proc,p,idx,vid,v);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kIntTFl:
|
||||||
|
{
|
||||||
|
int v;
|
||||||
|
rc = _set_out_tmpl(proc,p,idx,vid,v);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kFloatTFl:
|
||||||
|
{
|
||||||
|
float v;
|
||||||
|
rc = _set_out_tmpl(proc,p,idx,vid,v);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kDoubleTFl:
|
||||||
|
{
|
||||||
|
double v;
|
||||||
|
rc = _set_out_tmpl(proc,p,idx,vid,v);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kStringTFl:
|
||||||
|
{
|
||||||
|
const char* v;
|
||||||
|
rc = _set_out_tmpl(proc,p,idx,vid,v);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kCfgTFl:
|
||||||
|
{
|
||||||
|
const object_t* v;
|
||||||
|
rc = _set_out_tmpl(proc,p,idx,vid,v);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
rc = cwLogError(kInvalidArgRC,"The list type flag %s (0x%x) is not valid.",value_type_flag_to_label(p->typeFl),p->typeFl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
rc_t _set_output( instance_t* proc, inst_t* p )
|
rc_t _set_output( instance_t* proc, inst_t* p )
|
||||||
{
|
{
|
||||||
rc_t rc;
|
rc_t rc;
|
||||||
@ -4554,57 +4631,7 @@ namespace cw
|
|||||||
if( idx == p->index )
|
if( idx == p->index )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
switch( p->typeFl )
|
if((rc = _set_output(proc,p,idx, kOutPId )) != kOkRC )
|
||||||
{
|
|
||||||
case kUIntTFl:
|
|
||||||
{
|
|
||||||
unsigned v;
|
|
||||||
rc = _set_out_tmpl(proc,p,idx,v);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kIntTFl:
|
|
||||||
{
|
|
||||||
int v;
|
|
||||||
rc = _set_out_tmpl(proc,p,idx,v);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kFloatTFl:
|
|
||||||
{
|
|
||||||
float v;
|
|
||||||
rc = _set_out_tmpl(proc,p,idx,v);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kDoubleTFl:
|
|
||||||
{
|
|
||||||
double v;
|
|
||||||
rc = _set_out_tmpl(proc,p,idx,v);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kStringTFl:
|
|
||||||
{
|
|
||||||
const char* v;
|
|
||||||
rc = _set_out_tmpl(proc,p,idx,v);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kCfgTFl:
|
|
||||||
{
|
|
||||||
const object_t* v;
|
|
||||||
rc = _set_out_tmpl(proc,p,idx,v);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
rc = cwLogError(kInvalidArgRC,"The list type flag %s (0x%x) is not valid.",value_type_flag_to_label(p->typeFl),p->typeFl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rc != kOkRC )
|
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
p->index = idx;
|
p->index = idx;
|
||||||
@ -4613,6 +4640,8 @@ namespace cw
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rc_t create( instance_t* proc )
|
rc_t create( instance_t* proc )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
@ -4657,6 +4686,24 @@ namespace cw
|
|||||||
if((rc = _set_output(proc,p)) != kOkRC )
|
if((rc = _set_output(proc,p)) != kOkRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
|
// create the output variable
|
||||||
|
for(unsigned i=0; i<p->listN; ++i)
|
||||||
|
{
|
||||||
|
if((rc = var_create( proc, "value", i, kValueBasePId+i, kAnyChIdx, nullptr, p->typeFl, dum )) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = cwLogError(rc,"'value%i' var create failed.",i);
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((rc = _set_output(proc, p, i, kValueBasePId+i )) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = cwLogError(rc,"'value%i' output failed.",i);
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user