cwFlow,cwFlowNet,cwFlowTypes,cwFlowProc : Many changes.

Added ability to set types at proc instantiation time.
Added ability to have multi-type variables which get resolved at proc. instantiation time.
Added ability to proc 'log' attribute to print selected variables as they change.
Values are now coerced to the variable type in var_set().
Added new proc's : list,add,preset.
This commit is contained in:
kevin 2024-04-30 19:58:10 -04:00
parent 4619fc43a1
commit b57693f4e4
7 changed files with 1745 additions and 414 deletions

View File

@ -34,8 +34,8 @@ namespace cw
{ "midi_out", &midi_out::members }, { "midi_out", &midi_out::members },
{ "audio_in", &audio_in::members }, { "audio_in", &audio_in::members },
{ "audio_out", &audio_out::members }, { "audio_out", &audio_out::members },
{ "audioFileIn", &audioFileIn::members }, { "audio_file_in", &audio_file_in::members },
{ "audioFileOut", &audioFileOut::members }, { "audio_file_out", &audio_file_out::members },
{ "audio_gain", &audio_gain::members }, { "audio_gain", &audio_gain::members },
{ "audio_split", &audio_split::members }, { "audio_split", &audio_split::members },
{ "audio_duplicate", &audio_duplicate::members }, { "audio_duplicate", &audio_duplicate::members },
@ -58,6 +58,9 @@ namespace cw
{ "number", &number::members }, { "number", &number::members },
{ "timer", &timer::members }, { "timer", &timer::members },
{ "counter", &counter::members }, { "counter", &counter::members },
{ "list", &list::members },
{ "add", &add::members },
{ "preset", &preset::members },
{ nullptr, nullptr } { nullptr, nullptr }
}; };
@ -621,7 +624,7 @@ cw::rc_t cw::flow::test( const object_t* cfg, int argc, const char* argv[] )
// find the user requested test case // find the user requested test case
if((test_cfg = test_cases_cfg->find_child(argv[1])) == nullptr ) if((test_cfg = test_cases_cfg->find_child(argv[1])) == nullptr )
{ {
rc = cwLogError(kInvalidArgRC,"The test case named '%s' was not found.",argv[0]); rc = cwLogError(kInvalidArgRC,"The test case named '%s' was not found.",argv[1]);
goto errLabel; goto errLabel;
} }

View File

@ -66,8 +66,10 @@ namespace cw
void _connect_vars( variable_t* src_var, variable_t* in_var ) void _connect_vars( variable_t* src_var, variable_t* in_var )
{ {
// connect in_var into src_var's outgoing var chain // connect in_var into src_var's outgoing var chain
in_var->connect_link = src_var->connect_link; in_var->dst_link = src_var->dst_tail;
src_var->connect_link = in_var; src_var->dst_tail = in_var;
if( src_var->dst_head == nullptr )
src_var->dst_head = in_var;
assert( src_var->value != nullptr ); assert( src_var->value != nullptr );
@ -172,6 +174,41 @@ namespace cw
} }
} }
rc_t _set_log_flags(instance_t* proc, const object_t* log_labels)
{
rc_t rc = kOkRC;
if( log_labels == nullptr )
return rc;
if( !log_labels->is_dict() )
{
rc = cwLogError(kSyntaxErrorRC,"The log spec on '%s:%i' is not a dictionary.",cwStringNullGuard(proc->label),proc->label_sfx_id);
goto errLabel;
}
for(unsigned i=0; i<log_labels->child_count(); ++i)
{
const object_t* pair;
unsigned sfx_id;
if((pair = log_labels->child_ele(i)) == nullptr || pair->pair_label()==nullptr || pair->pair_value()==nullptr || (rc=pair->pair_value()->value(sfx_id))!=kOkRC )
{
rc = cwLogError(kSyntaxErrorRC,"Syntax error on log var identifier.");
goto errLabel;
}
if((rc = var_set_flags( proc, kAnyChIdx, pair->pair_label(), sfx_id, kLogVarFl )) != kOkRC )
{
rc = cwLogError(rc,"Unable to set var flags on '%s:%i' var:'%s:%i'.",cwStringNullGuard(proc->label),proc->label_sfx_id,pair->pair_label(),sfx_id);
goto errLabel;
}
}
errLabel:
return rc;
}
rc_t _call_value_func_on_all_variables( instance_t* inst ) rc_t _call_value_func_on_all_variables( instance_t* inst )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
@ -182,38 +219,47 @@ namespace cw
{ {
variable_t* var = inst->varMapA[i]; variable_t* var = inst->varMapA[i];
if((rc = var->inst->class_desc->members->value( var->inst, var )) != kOkRC ) if((rc = var_call_custom_value_func( var )) != kOkRC )
rc1 = cwLogError(rc,"The proc instance '%s:%i' reported an invalid valid on variable:%s chIdx:%i.", var->inst->label, var->inst->label_sfx_id, var->label, var->chIdx ); rc1 = cwLogError(rc,"The proc instance '%s:%i' reported an invalid valid on variable:%s chIdx:%i.", var->inst->label, var->inst->label_sfx_id, var->label, var->chIdx );
} }
return rc1; return rc1;
} }
rc_t _var_channelize( instance_t* inst, const char* preset_label, const char* type_src_label, const char* value_label, const object_t* value ) rc_t _var_channelize( instance_t* inst, const char* preset_label, const char* type_src_label, const char* var_label, const object_t* value )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
variable_t* dummy = nullptr; variable_t* dummy = nullptr;
var_desc_t* vd = nullptr;
// verify that a valid value exists // verify that a valid value exists
if( value == nullptr ) if( value == nullptr )
{ {
rc = cwLogError(kSyntaxErrorRC,"Unexpected missig value on %s preset '%s' instance '%s' variable '%s'.", type_src_label, preset_label, inst->label, cwStringNullGuard(value_label) ); rc = cwLogError(kSyntaxErrorRC,"Unexpected missig value on %s preset '%s' instance '%s' variable '%s'.", type_src_label, preset_label, inst->label, cwStringNullGuard(var_label) );
goto errLabel; goto errLabel;
} }
else
// if a list of values was given
if( value->is_list() )
{ {
bool is_var_cfg_type_fl = (vd = var_desc_find( inst->class_desc, var_label ))!=nullptr && cwIsFlag(vd->type,kCfgTFl);
bool is_list_fl = value->is_list();
bool is_list_of_list_fl = is_list_fl && value->child_count() > 0 && value->child_ele(0)->is_list();
bool parse_list_fl = (is_list_fl && !is_var_cfg_type_fl) || (is_list_of_list_fl && is_var_cfg_type_fl);
// if a list of values was given and the var type is not a 'cfg' type or if a list of lists was given
if( parse_list_fl )
{
// then each value in the list is assigned to the associated channel
for(unsigned chIdx=0; chIdx<value->child_count(); ++chIdx) for(unsigned chIdx=0; chIdx<value->child_count(); ++chIdx)
if((rc = var_channelize( inst, value_label, kBaseSfxId, chIdx, value->child_ele(chIdx), kInvalidId, dummy )) != kOkRC ) if((rc = var_channelize( inst, var_label, kBaseSfxId, chIdx, value->child_ele(chIdx), kInvalidId, dummy )) != kOkRC )
goto errLabel; goto errLabel;
} }
else // otherwise a single value was given else // otherwise a single value was given
{ {
if((rc = var_channelize( inst, value_label, kBaseSfxId, kAnyChIdx, value, kInvalidId, dummy )) != kOkRC ) if((rc = var_channelize( inst, var_label, kBaseSfxId, kAnyChIdx, value, kInvalidId, dummy )) != kOkRC )
goto errLabel; goto errLabel;
} }
}
errLabel: errLabel:
return rc; return rc;
@ -237,11 +283,11 @@ namespace cw
for(unsigned i=0; i<preset_cfg->child_count(); ++i) for(unsigned i=0; i<preset_cfg->child_count(); ++i)
{ {
const object_t* value = preset_cfg->child_ele(i)->pair_value(); const object_t* value = preset_cfg->child_ele(i)->pair_value();
const char* value_label = preset_cfg->child_ele(i)->pair_label(); const char* var_label = preset_cfg->child_ele(i)->pair_label();
//cwLogInfo("variable:%s",value_label); //cwLogInfo("variable:%s",value_label);
if((rc = _var_channelize( inst, preset_label, type_src_label, value_label, value )) != kOkRC ) if((rc = _var_channelize( inst, preset_label, type_src_label, var_label, value )) != kOkRC )
goto errLabel; goto errLabel;
@ -707,6 +753,7 @@ namespace cw
const char* arg_label; // const char* arg_label; //
const object_t* preset_labels; // const object_t* preset_labels; //
const object_t* arg_cfg; // const object_t* arg_cfg; //
const object_t* log_labels; //
const object_t* in_dict; // cfg. node to the in-list const object_t* in_dict; // cfg. node to the in-list
in_stmt_t* in_array; // in_array[ in_arrayN ] in-stmt array in_stmt_t* in_array; // in_array[ in_arrayN ] in-stmt array
unsigned in_arrayN; // count of in-stmt's in the in-list. unsigned in_arrayN; // count of in-stmt's in the in-list.
@ -1253,9 +1300,16 @@ namespace cw
{ {
in_stmt_t& in_stmt = pstate.in_array[i]; in_stmt_t& in_stmt = pstate.in_array[i];
const object_t* in_pair = pstate.in_dict->child_ele(i); // in:src pair const object_t* in_pair = pstate.in_dict->child_ele(i); // in:src pair
const char* in_var_str = in_pair->pair_label(); // 'in' var string const char* in_var_str = nullptr;
const char* src_proc_var_str = nullptr; const char* src_proc_var_str = nullptr;
// validate the basic syntax
if( in_pair == nullptr || (in_var_str = in_pair->pair_label()) == nullptr || in_pair->pair_value()==nullptr )
{
cwLogError(rc,"Malformed dictionary encountered in 'in' statement.");
goto errLabel;
}
// get the src net/proc/var string // get the src net/proc/var string
if((rc = in_pair->pair_value()->value(src_proc_var_str)) != kOkRC ) if((rc = in_pair->pair_value()->value(src_proc_var_str)) != kOkRC )
{ {
@ -1282,6 +1336,7 @@ namespace cw
kInvalidId, kInvalidId,
kAnyChIdx, kAnyChIdx,
in_stmt.in_var_desc->val_cfg, in_stmt.in_var_desc->val_cfg,
kInvalidTFl,
dum )) != kOkRC ) dum )) != kOkRC )
{ {
rc = cwLogError(rc,"in-stmt var create failed on '%s:%s'.",cwStringNullGuard(in_var_str),cwStringNullGuard(src_proc_var_str)); rc = cwLogError(rc,"in-stmt var create failed on '%s:%s'.",cwStringNullGuard(in_var_str),cwStringNullGuard(src_proc_var_str));
@ -1434,7 +1489,8 @@ namespace cw
if((rc = proc_inst_cfg->pair_value()->getv_opt("args", arg_dict, if((rc = proc_inst_cfg->pair_value()->getv_opt("args", arg_dict,
"in", pstate.in_dict, "in", pstate.in_dict,
"argLabel", pstate.arg_label, "argLabel", pstate.arg_label,
"preset", pstate.preset_labels)) != kOkRC ) "preset", pstate.preset_labels,
"log", pstate.log_labels )) != kOkRC )
{ {
rc = cwLogError(kSyntaxErrorRC,"The instance cfg. '%s' missing: 'type'.",pstate.inst_label); rc = cwLogError(kSyntaxErrorRC,"The instance cfg. '%s' missing: 'type'.",pstate.inst_label);
goto errLabel; goto errLabel;
@ -1550,10 +1606,10 @@ namespace cw
// Instantiate all the variables in the class description - that were not already created in _parse_in_list() // Instantiate all the variables in the class description - that were not already created in _parse_in_list()
for(var_desc_t* vd=class_desc->varDescL; vd!=nullptr; vd=vd->link) for(var_desc_t* vd=class_desc->varDescL; vd!=nullptr; vd=vd->link)
if( !_is_var_inst_already_created( vd->label, pstate ) ) if( !_is_var_inst_already_created( vd->label, pstate ) && cwIsNotFlag(vd->type,kRuntimeTFl) )
{ {
variable_t* var = nullptr; variable_t* var = nullptr;
if((rc = var_create( inst, vd->label, kBaseSfxId, kInvalidId, kAnyChIdx, vd->val_cfg, var )) != kOkRC ) if((rc = var_create( inst, vd->label, kBaseSfxId, kInvalidId, kAnyChIdx, vd->val_cfg, kInvalidTFl, var )) != kOkRC )
goto errLabel; goto errLabel;
} }
@ -1584,7 +1640,7 @@ namespace cw
// Connect the in-list variables to their sources. // Connect the in-list variables to their sources.
if((rc = _connect_in_vars(net, inst, pstate)) != kOkRC ) if((rc = _connect_in_vars(net, inst, pstate)) != kOkRC )
{ {
rc = cwLogError(rc,"Creation of the proc instance '%s:%i' failed during input connection processing.",cwStringNullGuard(inst->label),inst->label_sfx_id); rc = cwLogError(rc,"Input connection processing failed.");
goto errLabel; goto errLabel;
} }
@ -1593,27 +1649,43 @@ namespace cw
// Call the custom instance create() function. // Call the custom instance create() function.
if((rc = class_desc->members->create( inst )) != kOkRC ) if((rc = class_desc->members->create( inst )) != kOkRC )
{ {
rc = cwLogError(kInvalidArgRC,"Instantiation failed on instance '%s:%i'.", inst->label,inst->label_sfx_id ); rc = cwLogError(kInvalidArgRC,"Custom instantiation failed." );
goto errLabel; goto errLabel;
} }
// Create the instance->varMap[] lookup array // Create the instance->varMap[] lookup array
if((rc =_create_instance_var_map( inst )) != kOkRC ) if((rc =_create_instance_var_map( inst )) != kOkRC )
{
rc = cwLogError(rc,"Variable map creation failed.");
goto errLabel; goto errLabel;
}
// the custom creation function may have added channels to in-list vars fix up those connections here. // the custom creation function may have added channels to in-list vars fix up those connections here.
_complete_input_connections(inst); _complete_input_connections(inst);
// set the log flags again so that vars created by the instance can be included in the log output
if((rc = _set_log_flags(inst,pstate.log_labels)) != kOkRC )
goto errLabel;
// call the 'value()' function to inform the instance of the current value of all of it's variables. // call the 'value()' function to inform the instance of the current value of all of it's variables.
if((rc = _call_value_func_on_all_variables( inst )) != kOkRC ) if((rc = _call_value_func_on_all_variables( inst )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = instance_validate(inst)) != kOkRC )
{
rc = cwLogError(rc,"Proc instance validation failed.");
goto errLabel;
}
inst_ref = inst; inst_ref = inst;
errLabel: errLabel:
if( rc != kOkRC ) if( rc != kOkRC )
{
rc = cwLogError(rc,"Proc instantiation failed on '%s:%i'.",cwStringNullGuard(pstate.inst_label),sfx_id);
_destroy_inst(inst); _destroy_inst(inst);
}
_destroy_pstate(pstate); _destroy_pstate(pstate);
return rc; return rc;

View File

@ -724,10 +724,10 @@ namespace cw
//------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------
// //
// AudioFileIn // audio_file_in
// //
namespace audioFileIn namespace audio_file_in
{ {
enum enum
{ {
@ -881,10 +881,10 @@ namespace cw
//------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------
// //
// AudioFileOut // audio_file_out
// //
namespace audioFileOut namespace audio_file_out
{ {
enum enum
{ {
@ -1753,6 +1753,7 @@ namespace cw
inst_t* inst = (inst_t*)ctx->userPtr; inst_t* inst = (inst_t*)ctx->userPtr;
mem::release(inst->phaseA);
mem::release(inst); mem::release(inst);
return rc; return rc;
@ -3346,7 +3347,7 @@ namespace cw
bool trigFl = false; bool trigFl = false;
variable_t* gainVar = nullptr; variable_t* gainVar = nullptr;
abuf_t* srateSrc = nullptr; abuf_t* srateSrc = nullptr;
double dum; double dum_dbl;
inst_t* p = mem::allocZ<inst_t>(); inst_t* p = mem::allocZ<inst_t>();
@ -3360,7 +3361,7 @@ namespace cw
kSrateRefPId, "srateSrc", kBaseSfxId, srateSrc, kSrateRefPId, "srateSrc", kBaseSfxId, srateSrc,
kDurMsPId, "durMs", kBaseSfxId, p->xfadeDurMs, kDurMsPId, "durMs", kBaseSfxId, p->xfadeDurMs,
kTriggerPId, "trigger", kBaseSfxId, trigFl, kTriggerPId, "trigger", kBaseSfxId, trigFl,
kGainPId, "gain", kBaseSfxId, dum)) != kOkRC ) kGainPId, "gain", kBaseSfxId, dum_dbl)) != kOkRC )
{ {
goto errLabel; goto errLabel;
} }
@ -3383,7 +3384,7 @@ namespace cw
for(unsigned i=1; i<p->net_proc->internal_net->poly_cnt; ++i) for(unsigned i=1; i<p->net_proc->internal_net->poly_cnt; ++i)
{ {
variable_t* dum; variable_t* dum;
if((rc = var_create(ctx, "gain", i, kGainPId+i, kAnyChIdx, nullptr, dum )) != kOkRC ) if((rc = var_create(ctx, "gain", i, kGainPId+i, kAnyChIdx, nullptr, kInvalidTFl, dum )) != kOkRC )
{ {
cwLogError(rc,"'gain:%i' create failed.",i); cwLogError(rc,"'gain:%i' create failed.",i);
goto errLabel; goto errLabel;
@ -3790,45 +3791,22 @@ namespace cw
namespace number namespace number
{ {
enum { enum {
kInPId, kValuePId,
kBoolPId,
kUIntPId,
kIntPId,
kFloatPId,
kOutPId
}; };
typedef struct
{
bool delta_fl;
double value;
} inst_t;
rc_t create( instance_t* proc ) rc_t create( instance_t* proc )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
inst_t* p = mem::allocZ<inst_t>(); double value = 0;
proc->userPtr = p;
if((rc = var_register_and_get(proc,kAnyChIdx, if((rc = var_register_and_get(proc,kAnyChIdx,
kInPId,"in",kBaseSfxId,p->value)) != kOkRC ) kValuePId,"value",kBaseSfxId,value)) != kOkRC )
{ {
goto errLabel; goto errLabel;
} }
if((rc = var_register_and_set(proc,kAnyChIdx,
kBoolPId,"bool",kBaseSfxId,p->value != 0,
kUIntPId,"uint",kBaseSfxId,(unsigned)p->value,
kIntPId,"int",kBaseSfxId,(int)p->value,
kFloatPId,"float",kBaseSfxId,(float)p->value,
kOutPId,"out",kBaseSfxId,p->value )) != kOkRC )
{
goto errLabel;
}
p->delta_fl = true;
errLabel: errLabel:
return rc; return rc;
} }
@ -3836,45 +3814,18 @@ namespace cw
rc_t destroy( instance_t* proc ) rc_t destroy( instance_t* proc )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
inst_t* p = (inst_t*)proc->userPtr;
mem::release(p);
return rc; return rc;
} }
rc_t value( instance_t* proc, variable_t* var ) rc_t value( instance_t* proc, variable_t* var )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
if( var->vid == kInPId )
{
double v;
if((rc = var_get(var,v)) == kOkRC )
{
inst_t* p = (inst_t*)proc->userPtr;
if( !p->delta_fl )
p->delta_fl = v != p->value;
p->value = v;
}
}
return rc; return rc;
} }
rc_t exec( instance_t* proc ) rc_t exec( instance_t* proc )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
inst_t* p = (inst_t*)proc->userPtr;
if( p->delta_fl )
{
p->delta_fl = false;
var_set(proc,kBoolPId,kAnyChIdx,p->value!=0);
var_set(proc,kUIntPId,kAnyChIdx,(unsigned)fabs(p->value));
var_set(proc,kIntPId,kAnyChIdx,(int)p->value);
var_set(proc,kFloatPId,kAnyChIdx,(float)p->value);
var_set(proc,kOutPId,kAnyChIdx,p->value);
}
return rc; return rc;
} }
@ -3978,6 +3929,7 @@ namespace cw
p->periodPhase += proc->ctx->framesPerCycle; p->periodPhase += proc->ctx->framesPerCycle;
//printf("%i %i\n",p->periodPhase,p->periodFrmN);
if( p->periodPhase >= p->periodFrmN ) if( p->periodPhase >= p->periodFrmN )
{ {
@ -4020,6 +3972,7 @@ namespace cw
kIncPId, kIncPId,
kRepeatPId, kRepeatPId,
kModePId, kModePId,
kOutTypePId,
kOutPId kOutPId
}; };
@ -4075,12 +4028,16 @@ namespace cw
proc->userPtr = p; proc->userPtr = p;
double init_val; double init_val;
const char* mode_label; const char* mode_label;
variable_t* dum = nullptr;
const char* out_type_label;
unsigned out_type_fl;
if((rc = var_register_and_get(proc, kAnyChIdx, if((rc = var_register_and_get(proc, kAnyChIdx,
kTriggerPId, "trigger", kBaseSfxId, p->trig_val, kTriggerPId, "trigger", kBaseSfxId, p->trig_val,
kResetPId, "reset", kBaseSfxId, p->reset_val, kResetPId, "reset", kBaseSfxId, p->reset_val,
kInitPId, "init", kBaseSfxId, init_val, kInitPId, "init", kBaseSfxId, init_val,
kModePId, "mode", kBaseSfxId, mode_label)) != kOkRC ) kModePId, "mode", kBaseSfxId, mode_label,
kOutTypePId, "out_type",kBaseSfxId, out_type_label)) != kOkRC )
{ {
goto errLabel; goto errLabel;
} }
@ -4095,9 +4052,22 @@ namespace cw
goto errLabel; goto errLabel;
} }
if((rc = var_register_and_set(proc,kAnyChIdx, // get the type of the output
kOutPId,"out",kBaseSfxId,init_val)) != kOkRC ) if(out_type_label==nullptr || (out_type_fl = value_type_label_to_flag( out_type_label )) == kInvalidTFl )
{ {
rc = cwLogError(kInvalidArgRC,"The output type '%s' is not a valid type.",cwStringNullGuard(out_type_label));
goto errLabel;
}
if((rc = var_create( proc, "out", kBaseSfxId, kOutPId, kAnyChIdx, nullptr, out_type_fl, dum )) != kOkRC )
{
goto errLabel;
}
if((rc = var_set( proc, kOutPId, kAnyChIdx, 0u )) != kOkRC )
{
rc = cwLogError(rc,"Unable to set the initial counter value to %f.",init_val);
goto errLabel; goto errLabel;
} }
@ -4131,7 +4101,6 @@ namespace cw
case kTriggerPId: case kTriggerPId:
{ {
bool v; bool v;
if((rc = var_get(var,v)) == kOkRC ) if((rc = var_get(var,v)) == kOkRC )
{ {
if( !p->delta_fl ) if( !p->delta_fl )
@ -4159,30 +4128,27 @@ namespace cw
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
inst_t* p = (inst_t*)proc->userPtr; inst_t* p = (inst_t*)proc->userPtr;
double cnt,inc,minv,maxv;
bool v; bool v;
if( !p->delta_fl )
return rc;
p->delta_fl = false;
if((rc = var_get(proc,kTriggerPId,kAnyChIdx,v)) != kOkRC ) if((rc = var_get(proc,kTriggerPId,kAnyChIdx,v)) != kOkRC )
{ {
cwLogError(rc,"Fail!"); cwLogError(rc,"Fail!");
goto errLabel; goto errLabel;
} }
p->delta_fl = v != p->trig_val;
p->trig_val = v; p->trig_val = v;
if( p->delta_fl )
{
p->delta_fl = false;
double cnt,inc,minv,maxv;
var_get(proc,kOutPId,kAnyChIdx,cnt); var_get(proc,kOutPId,kAnyChIdx,cnt);
var_get(proc,kIncPId,kAnyChIdx,inc); var_get(proc,kIncPId,kAnyChIdx,inc);
var_get(proc,kMinPId,kAnyChIdx,minv); var_get(proc,kMinPId,kAnyChIdx,minv);
var_get(proc,kMaxPId,kAnyChIdx,maxv); var_get(proc,kMaxPId,kAnyChIdx,maxv);
double incr = p->dir * inc; cnt += p->dir * inc;
cnt += incr;
if( minv > cnt || cnt > maxv ) if( minv > cnt || cnt > maxv )
{ {
@ -4244,12 +4210,10 @@ namespace cw
} }
} }
// if the counter has not reached it's terminal state
if( !p->done_fl ) if( !p->done_fl )
{
printf("cnt:%f\n",cnt);
var_set(proc,kOutPId,kAnyChIdx,cnt); var_set(proc,kOutPId,kAnyChIdx,cnt);
}
}
errLabel: errLabel:
return rc; return rc;
@ -4265,6 +4229,631 @@ namespace cw
} }
//------------------------------------------------------------------------------------------------------------------
//
// List
//
namespace list
{
enum
{
kInPId,
kListPId,
kOutPId
};
typedef struct
{
unsigned listN; // the length of the list
const object_t* list; // the list
unsigned typeFl; // the output type
unsigned index; // the last index referenced
bool deltaFl;
} inst_t;
rc_t _determine_type( const object_t* list, unsigned& typeFl_ref )
{
rc_t rc = kOkRC;
typeFl_ref = kInvalidTFl;
enum { bool_idx, uint_idx, int_idx, float_idx, double_idx, string_idx, cfg_idx, typeN };
typedef struct type_map_str
{
unsigned idx;
unsigned typeFl;
unsigned cnt;
} type_map_t;
type_map_t typeA[] = {
{ bool_idx, kBoolTFl, 0 },
{ uint_idx, kUIntTFl, 0 },
{ int_idx, kIntTFl, 0 },
{ float_idx, kFloatTFl, 0 },
{ double_idx, kDoubleTFl, 0 },
{ string_idx, kStringTFl, 0 },
{ cfg_idx, kCfgTFl, 0 },
};
// count the number of each type of element in the list.
for(unsigned i=0; i<list->child_count(); ++i)
{
const object_t* c = list->child_ele(i);
switch( c->type->id )
{
case kCharTId: typeA[uint_idx].cnt+=1; break;
case kInt8TId: typeA[int_idx].cnt +=1; break;
case kUInt8TId: typeA[uint_idx].cnt+=1; break;
case kInt16TId: typeA[int_idx].cnt +=1; break;
case kUInt16TId: typeA[uint_idx].cnt+=1; break;
case kInt32TId: typeA[int_idx].cnt +=1; break;
case kUInt32TId: typeA[uint_idx].cnt+=1; break;
case kFloatTId: typeA[float_idx].cnt+=1; break;
case kDoubleTId: typeA[double_idx].cnt+=1; break;
case kBoolTId: typeA[bool_idx].cnt+=1; break;
case kStringTId: typeA[string_idx].cnt+=1; break;
case kCStringTId:typeA[string_idx].cnt+=1; break;
break;
default:
switch( c->type->id )
{
case kVectTId:
case kPairTId:
case kListTId:
case kDictTId:
typeA[cfg_idx].cnt +=1;
break;
default:
rc = cwLogError(kSyntaxErrorRC,"The object type '0x%x' is not a valid list entry type. %i",c->type->flags,list->child_count());
goto errLabel;
}
}
unsigned type_flag = kInvalidTFl; // type flag of one of the reference types
unsigned type_cnt = 0; // count of types
for(unsigned i=0; i<typeN; ++i)
if( typeA[i].cnt > 0 )
{
type_cnt += 1;
type_flag = typeA[i].typeFl;
}
// it is an error if more than one type of element was included in the list -
// and one of those types was string or cfg - having multiple numeric types
// is ok because they can be converted between each other - but string, and cfg's
// cannot be converted to numbers, nor can the be converted between each other.
if( type_cnt > 1 && (typeA[string_idx].cnt>0 || typeA[cfg_idx].cnt>0) )
{
rc = cwLogError(kInvalidArgRC,"The list types. The list must be all numerics, all strings, or all cfg. types.");
for(unsigned i=0; i<typeN; ++i)
if( typeA[i].cnt > 0 )
cwLogInfo("%i %s",typeA[i].cnt, value_type_flag_to_label(typeA[i].typeFl));
goto errLabel;
}
typeFl_ref = type_flag;
}
errLabel:
return rc;
}
template< typename T >
rc_t _set_out_tmpl( instance_t* proc, inst_t* p, unsigned idx, T& v )
{
rc_t rc;
const object_t* ele;
// get the list element to output
if((ele = p->list->child_ele(idx)) == nullptr )
{
rc = cwLogError(kEleNotFoundRC,"The list element at index %i could not be accessed.",idx);
goto errLabel;
}
// get the value of the list element
if((rc = ele->value(v)) != kOkRC )
{
rc = cwLogError(rc,"List value access failed on index %i",idx);
goto errLabel;
}
// set the output
if((rc = var_set(proc,kOutPId,kAnyChIdx,v)) != kOkRC )
{
rc = cwLogError(rc,"List output failed on index %i",idx);
goto errLabel;
}
errLabel:
return rc;
}
rc_t _set_output( instance_t* proc, inst_t* p )
{
rc_t rc;
unsigned idx;
if((rc = var_get(proc,kInPId,kAnyChIdx,idx)) != kOkRC )
{
rc = cwLogError(rc,"Unable to get the list index.");
goto errLabel;
}
// if the index has not changed then there is nothing to do
if( idx == p->index )
goto errLabel;
switch( p->typeFl )
{
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;
p->index = idx;
errLabel:
return rc;
}
rc_t create( instance_t* proc )
{
rc_t rc = kOkRC;
inst_t* p = mem::allocZ<inst_t>();
unsigned index;
proc->userPtr = p;
variable_t* dum = nullptr;
p->index = kInvalidIdx;
p->typeFl = kInvalidTFl;
p->deltaFl = false;
if((rc = var_register_and_get(proc, kAnyChIdx,
kInPId, "in", kBaseSfxId, index,
kListPId,"list", kBaseSfxId, p->list)) != kOkRC )
{
goto errLabel;
}
if( !p->list->is_list() )
{
cwLogError(kSyntaxErrorRC,"The list cfg. value is not a list.");
goto errLabel;
}
p->listN = p->list->child_count();
// determine what type of element is in the list
// (all elements in the this list must be of the same type: numeric,string,cfg)
if((rc = _determine_type( p->list, p->typeFl )) != kOkRC )
goto errLabel;
// create the output variable
if((rc = var_create( proc, "out", kBaseSfxId, kOutPId, kAnyChIdx, nullptr, p->typeFl, dum )) != kOkRC )
{
rc = cwLogError(rc,"'out' var create failed.");
goto errLabel;
}
// set the initial value of the output
if((rc = _set_output(proc,p)) != kOkRC )
goto errLabel;
errLabel:
return rc;
}
rc_t destroy( instance_t* proc )
{
rc_t rc = kOkRC;
inst_t* p = (inst_t*)proc->userPtr;
mem::release(p);
return rc;
}
rc_t value( instance_t* proc, variable_t* var )
{
rc_t rc = kOkRC;
if( var->vid == kInPId )
{
inst_t* p = (inst_t*)proc->userPtr;
unsigned idx;
if( var_get(var,idx) == kOkRC && idx != p->index)
p->deltaFl = true;
}
return rc;
}
rc_t exec( instance_t* proc )
{
rc_t rc = kOkRC;
inst_t* p = (inst_t*)proc->userPtr;
if( p->deltaFl )
{
rc = _set_output(proc, p );
p->deltaFl = false;
}
return rc;
}
class_members_t members = {
.create = create,
.destroy = destroy,
.value = value,
.exec = exec,
.report = nullptr
};
}
//------------------------------------------------------------------------------------------------------------------
//
// add
//
namespace add
{
enum {
kOutPId,
kOTypePId,
kInPId
};
typedef struct
{
bool delta_fl;
unsigned inN;
} inst_t;
template< typename T >
rc_t _sum( instance_t* proc, variable_t* var )
{
rc_t rc = kOkRC;
inst_t* p = (inst_t*)proc->userPtr;
T sum = 0;
// read and sum the inputs
for(unsigned i=0; i<p->inN; ++i)
{
T val;
if((rc = var_get(proc,kInPId+i,kAnyChIdx,val)) == kOkRC )
sum += val;
else
{
rc = cwLogError(rc,"Operand index %i read failed.",i);
goto errLabel;
}
}
// set the output
if((rc = var_set(var,sum)) != kOkRC )
{
rc = cwLogError(rc,"Result set failed.");
goto errLabel;
}
errLabel:
return rc;
}
rc_t _exec( instance_t* proc, variable_t* out_var=nullptr )
{
rc_t rc = kOkRC;
inst_t* p = (inst_t*)(proc->userPtr);
if( !p->delta_fl )
return rc;
p->delta_fl = false;
if( out_var == nullptr )
if((rc = var_find(proc,kOutPId,kAnyChIdx,out_var)) != kOkRC )
{
rc = cwLogError(rc,"The output variable could not be found.");
goto errLabel;
}
switch( out_var->varDesc->type )
{
case kBoolTFl: rc = _sum<bool>(proc,out_var); break;
case kUIntTFl: rc = _sum<unsigned>(proc,out_var); break;
case kIntTFl: rc = _sum<int>(proc,out_var); break;
case kFloatTFl: rc = _sum<float>(proc,out_var); break;
case kDoubleTFl: rc = _sum<double>(proc,out_var); break;
default:
rc = cwLogError(kInvalidArgRC,"The output type %s (0x%x) is not valid.",value_type_flag_to_label(out_var->value->tflag),out_var->value->tflag);
goto errLabel;
}
if(rc != kOkRC )
rc = cwLogError(kOpFailRC,"Sum failed.");
errLabel:
return rc;
}
rc_t create( instance_t* proc )
{
rc_t rc = kOkRC;
inst_t* p = mem::allocZ<inst_t>();
proc->userPtr = p;
variable_t* out_var = nullptr;
const char* out_type_label = nullptr;
unsigned out_type_flag = kInvalidTFl;
unsigned sfxIdAllocN = instance_var_count(proc);
unsigned sfxIdA[ sfxIdAllocN ];
p->inN = 0;
// get a count of the number of input variables
if((rc = var_mult_sfx_id_array(proc, "in", sfxIdA, sfxIdAllocN, p->inN )) != kOkRC )
{
rc = cwLogError(rc,"Unable to obtain the array of mult label-sfx-id's for the variable 'in'.");
goto errLabel;
}
// if the adder has no inputs
if( p->inN == 0 )
{
rc = cwLogError(rc,"The 'add' unit '%s' appears to not have any inputs.",cwStringNullGuard(proc->label));
goto errLabel;
}
// sort the input id's in ascending order
std::sort(sfxIdA, sfxIdA + p->inN, [](unsigned& a,unsigned& b){ return a<b; } );
// register each of the input vars
for(unsigned i=0; i<p->inN; ++i)
{
variable_t* dum;
if((rc = var_register(proc, "in", sfxIdA[i], kInPId+i, kAnyChIdx, nullptr, dum )) != kOkRC )
{
rc = cwLogError(rc,"Variable registration failed for the variable 'in:%i'.",sfxIdA[i]);;
goto errLabel;
}
}
// Get the output type label as a string
if((rc = var_register_and_get(proc,kAnyChIdx,kOTypePId,"otype",kBaseSfxId,out_type_label)) != kOkRC )
{
rc = cwLogError(rc,"Variable registration failed for the variable 'otype:0'.");;
goto errLabel;
}
// Convert the output type label into a flag
if((out_type_flag = value_type_label_to_flag(out_type_label)) == kInvalidTFl )
{
rc = cwLogError(rc,"The type label '%s' does not identify a valid type.",cwStringNullGuard(out_type_label));;
goto errLabel;
}
// Create the output var
if((rc = var_create( proc, "out", kBaseSfxId, kOutPId, kAnyChIdx, nullptr, out_type_flag, out_var )) != kOkRC )
{
rc = cwLogError(rc,"The output variable create failed.");
goto errLabel;
}
/*
if((rc = var_set(proc,kOutPId,kAnyChIdx,0.0)) != kOkRC )
{
rc = cwLogError(rc,"Initial output variable set failed.");
goto errLabel;
}
*/
p->delta_fl=true;
_exec(proc,out_var);
errLabel:
return rc;
}
rc_t destroy( instance_t* proc )
{
rc_t rc = kOkRC;
inst_t* p = (inst_t*)proc->userPtr;
mem::release(p);
return rc;
}
rc_t value( instance_t* proc, variable_t* var )
{
rc_t rc = kOkRC;
inst_t* p = (inst_t*)(proc->userPtr);
if( kInPId <= var->vid && var->vid < kInPId+p->inN )
p->delta_fl = true;
return rc;
}
rc_t exec( instance_t* proc )
{
return _exec(proc);
}
class_members_t members = {
.create = create,
.destroy = destroy,
.value = value,
.exec = exec,
.report = nullptr
};
}
//------------------------------------------------------------------------------------------------------------------
//
// preset
//
namespace preset
{
enum { kInPId };
enum { kPresetLabelCharN=255 };
typedef struct
{
char preset_label[ kPresetLabelCharN+1];
} inst_t;
rc_t _set_preset( instance_t* proc, inst_t* p, const char* preset_label )
{
rc_t rc = kOkRC;
if( preset_label == nullptr )
{
if((rc = var_get(proc, kInPId, kAnyChIdx, preset_label)) != kOkRC )
{
rc = cwLogError(rc,"The variable 'in read failed.");
goto errLabel;
}
}
if( preset_label == nullptr )
{
rc = cwLogError(kInvalidArgRC,"Preset application failed due to blank preset label.");
goto errLabel;
}
if((rc = network_apply_preset(*proc->net, preset_label)) != kOkRC )
{
rc = cwLogError(rc,"Appy preset '%s' failed.",cwStringNullGuard(preset_label));
goto errLabel;
}
if( textLength(preset_label) >= kPresetLabelCharN )
strncpy(p->preset_label,preset_label,kPresetLabelCharN);
else
{
rc = cwLogError(kBufTooSmallRC,"The preset label '%s' is to long.",cwStringNullGuard(preset_label));
goto errLabel;
}
errLabel:
return rc;
}
rc_t create( instance_t* proc )
{
rc_t rc = kOkRC;
inst_t* p = mem::allocZ<inst_t>();
proc->userPtr = p;
const char* label = nullptr;
p->preset_label[0] = 0;
if((rc = var_register_and_get(proc,kAnyChIdx,kInPId,"in",kBaseSfxId,label)) != kOkRC )
goto errLabel;
errLabel:
return rc;
}
rc_t destroy( instance_t* proc )
{
rc_t rc = kOkRC;
inst_t* p = (inst_t*)proc->userPtr;
// Custom clean-up code goes here
mem::release(p);
return rc;
}
rc_t value( instance_t* proc, variable_t* var )
{
rc_t rc = kOkRC;
return rc;
}
rc_t exec( instance_t* proc )
{
rc_t rc = kOkRC;
//inst_t* p = (inst_t*)proc->userPtr;
return rc;
}
class_members_t members = {
.create = create,
.destroy = destroy,
.value = value,
.exec = exec,
.report = nullptr
};
}
} // flow } // flow
} // cw } // cw

View File

@ -7,8 +7,8 @@ namespace cw
namespace midi_out { extern class_members_t members; } namespace midi_out { extern class_members_t members; }
namespace audio_in { extern class_members_t members; } namespace audio_in { extern class_members_t members; }
namespace audio_out { extern class_members_t members; } namespace audio_out { extern class_members_t members; }
namespace audioFileIn { extern class_members_t members; } namespace audio_file_in { extern class_members_t members; }
namespace audioFileOut { extern class_members_t members; } namespace audio_file_out { extern class_members_t members; }
namespace audio_gain { extern class_members_t members; } namespace audio_gain { extern class_members_t members; }
namespace audio_split { extern class_members_t members; } namespace audio_split { extern class_members_t members; }
namespace audio_merge { extern class_members_t members; } namespace audio_merge { extern class_members_t members; }
@ -31,6 +31,9 @@ namespace cw
namespace number { extern class_members_t members; } namespace number { extern class_members_t members; }
namespace timer { extern class_members_t members; } namespace timer { extern class_members_t members; }
namespace counter { extern class_members_t members; } namespace counter { extern class_members_t members; }
namespace list { extern class_members_t members; }
namespace add { extern class_members_t members; }
namespace preset { extern class_members_t members; }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -78,6 +78,8 @@ namespace cw
kTypeMask = 0x0000ffff, kTypeMask = 0x0000ffff,
kRuntimeTFl = 0x80000000
}; };
typedef struct mtx_str typedef struct mtx_str
@ -92,7 +94,8 @@ namespace cw
typedef struct value_str typedef struct value_str
{ {
unsigned flags; unsigned tflag;
union { union {
bool b; bool b;
uint_t u; uint_t u;
@ -108,6 +111,7 @@ namespace cw
char* s; char* s;
const object_t* cfg; const object_t* cfg;
void* p;
} u; } u;
@ -116,8 +120,9 @@ namespace cw
} value_t; } value_t;
inline bool is_numeric( const value_t* v ) { return cwIsFlag(v->flags,kBoolTFl|kUIntTFl|kIntTFl|kFloatTFl|kDoubleTFl); } inline void set_null( value_t& v, unsigned tflag ) { v.tflag=tflag; v.u.p=nullptr; }
inline bool is_matrix( const value_t* v ) { return cwIsFlag(v->flags,kBoolMtxTFl|kUIntMtxTFl|kIntMtxTFl|kFloatMtxTFl|kDoubleMtxTFl); } inline bool is_numeric( const value_t* v ) { return cwIsFlag(v->tflag,kBoolTFl|kUIntTFl|kIntTFl|kFloatTFl|kDoubleTFl); }
inline bool is_matrix( const value_t* v ) { return cwIsFlag(v->tflag,kBoolMtxTFl|kUIntMtxTFl|kIntMtxTFl|kFloatMtxTFl|kDoubleMtxTFl); }
struct instance_str; struct instance_str;
struct variable_str; struct variable_str;
@ -170,24 +175,40 @@ namespace cw
unsigned polyLimitN; // max. poly copies of this class per network_t or 0 if no limit unsigned polyLimitN; // max. poly copies of this class per network_t or 0 if no limit
} class_desc_t; } class_desc_t;
enum {
kInvalidVarFl = 0x00,
kLogVarFl = 0x01
};
// Note: The concatenation of 'vid' and 'chIdx' should form a unique identifier among all variables // Note: The concatenation of 'vid' and 'chIdx' should form a unique identifier among all variables
// on a given 'instance'. // on a given 'instance'.
typedef struct variable_str typedef struct variable_str
{ {
struct instance_str* inst; // pointer to this variables instance struct instance_str* inst; // pointer to this variables instance
char* label; // this variables label char* label; // this variables label
unsigned label_sfx_id; // the label suffix id of this variable or kInvalidIdx if this has no suffix unsigned label_sfx_id; // the label suffix id of this variable or kInvalidIdx if this has no suffix
unsigned vid; // this variables numeric id ( cat(vid,chIdx) forms a unique variable identifier on this 'inst' unsigned vid; // this variables numeric id ( cat(vid,chIdx) forms a unique variable identifier on this 'inst'
var_desc_t* varDesc; // the variable description for this variable unsigned chIdx; // channel index
unsigned flags; // kLogVarFl
unsigned type; // This is the value type as established when the var is initialized - it never changes for the life of the var.
var_desc_t* classVarDesc; // pointer to this variables class var desc
var_desc_t* localVarDesc; // pointer to this variables local var desc - if it doesn't match classVarDesc.
var_desc_t* varDesc; // the effective variable description for this variable (set to classVarDesc or localVarDesc)
value_t local_value[ kLocalValueN ]; // the local value instance (actual value if this is not a 'src' variable) value_t local_value[ kLocalValueN ]; // the local value instance (actual value if this is not a 'src' variable)
unsigned local_value_idx; // local_value[] is double buffered to allow the cur value of the buf[] to be held while the next value is validated (see _var_set_template()) unsigned local_value_idx; // local_value[] is double buffered to allow the cur value of the buf[] to be held while the next value is validated (see _var_set_template())
value_t* value; // pointer to the value associated with this variable
unsigned chIdx; // channel index
struct variable_str* src_var; // pointer to this input variables source link (or null if it uses the local_value) struct variable_str* src_var; // pointer to this input variables source link (or null if it uses the local_value)
struct variable_str* var_link; // instance.varL link list value_t* value; // pointer to the value associated with this variable
struct variable_str* connect_link; // list of outgoing connections
struct variable_str* var_link; // instance.varL list link
struct variable_str* ch_link; // list of channels that share this variable (rooted on 'any' channel - in order by channel number) struct variable_str* ch_link; // list of channels that share this variable (rooted on 'any' channel - in order by channel number)
struct variable_str* dst_head; // Pointer to list of out-going connections (null on var's that do not have out-going connections)
struct variable_str* dst_tail; //
struct variable_str* dst_link; // Link used by dst_head list.
} variable_t; } variable_t;
@ -277,10 +298,12 @@ namespace cw
void mbuf_destroy( mbuf_t*& buf ); void mbuf_destroy( mbuf_t*& buf );
mbuf_t* mbuf_duplicate( const mbuf_t* src ); mbuf_t* mbuf_duplicate( const mbuf_t* src );
inline bool value_is_abuf( const value_t* v ) { return v->flags & kABufTFl; } inline bool value_is_abuf( const value_t* v ) { return v->tflag & kABufTFl; }
inline bool value_is_fbuf( const value_t* v ) { return v->flags & kFBufTFl; } inline bool value_is_fbuf( const value_t* v ) { return v->tflag & kFBufTFl; }
unsigned value_type_label_to_flag( const char* type_desc ); unsigned value_type_label_to_flag( const char* type_desc );
const char* value_type_flag_to_label( unsigned flag );
//------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------
// //
@ -306,6 +329,8 @@ namespace cw
// Instance // Instance
// //
rc_t instance_validate( instance_t* inst );
instance_t* instance_find( network_t& net, const char* inst_label, unsigned sfx_id ); instance_t* instance_find( network_t& net, const char* inst_label, unsigned sfx_id );
rc_t instance_find( network_t& net, const char* inst_label, unsigned sfx_id, instance_t*& instPtrRef ); rc_t instance_find( network_t& net, const char* inst_label, unsigned sfx_id, instance_t*& instPtrRef );
@ -313,6 +338,9 @@ namespace cw
void instance_print( instance_t* inst ); void instance_print( instance_t* inst );
// Count of all var instances on this proc. This is a count of the length of inst->varL.
unsigned instance_var_count( instance_t* inst );
//------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------
@ -321,13 +349,26 @@ namespace cw
// //
// Create a variable but do not assign it a value. Return a pointer to the new variable. // Create a variable but do not assign it a value. Return a pointer to the new variable.
// Note: `value_cfg` is optional. Set it to NULL to ignore // Notes:
rc_t var_create( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef ); // 1) `value_cfg` is optional. Set it to NULL to ignore
// 2) If `altTypeFl` is not set to kInvalidTFl then the var is assigned this type.
rc_t var_create( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, const object_t* value_cfg, unsigned altTypeFlag, variable_t*& varRef );
// Channelizing creates a new var record with an explicit channel index to replace the // Channelizing creates a new var record with an explicit channel index to replace the
// automatically generated variable whose channel index is set to 'all'. // automatically generated variable whose channel index is set to 'all'.
rc_t var_channelize( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned chIdx, const object_t* value_cfg, unsigned vid, variable_t*& varRef ); rc_t var_channelize( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned chIdx, const object_t* value_cfg, unsigned vid, variable_t*& varRef );
// Set the var. type at runtime.
//rc_t var_set_type( instance_t* inst, unsigned chIdx, const char* var_label, unsigned sfx_id, unsigned type_flags );
// Wrapper around call to var->inst->members->value()
rc_t var_call_custom_value_func( variable_t* var );
// Sets and get the var->flags field
unsigned var_flags( instance_t* inst, unsigned chIdx, const char* var_label, unsigned sfx_id, unsigned& flags_ref );
rc_t var_set_flags( instance_t* inst, unsigned chIdx, const char* var_label, unsigned sfx_id, unsigned flags );
rc_t var_clr_flags( instance_t* inst, unsigned chIdx, const char* var_label, unsigned sfx_id, unsigned flags );
// `value_cfg` is optional. Set it to NULL to ignore // `value_cfg` is optional. Set it to NULL to ignore
rc_t var_register( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef ); rc_t var_register( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef );
@ -337,6 +378,7 @@ namespace cw
// Return true if this var is acting as a source for another var. // Return true if this var is acting as a source for another var.
bool is_a_source_var( const variable_t* var ); bool is_a_source_var( const variable_t* var );
rc_t var_mult_sfx_id_array( instance_t* inst, const char* var_label, unsigned* idA, unsigned idAllocN, unsigned& idN_ref );
//----------------- //-----------------
// //
@ -473,6 +515,7 @@ namespace cw
rc_t var_get( variable_t* var, fbuf_t*& valRef ); rc_t var_get( variable_t* var, fbuf_t*& valRef );
rc_t var_get( const variable_t* var, const mbuf_t*& valRef ); rc_t var_get( const variable_t* var, const mbuf_t*& valRef );
rc_t var_get( variable_t* var, mbuf_t*& valRef ); rc_t var_get( variable_t* var, mbuf_t*& valRef );
rc_t var_get( const variable_t* var, const object_t*& valRef );
template< typename T> template< typename T>
rc_t var_get( instance_t* inst, unsigned vid, unsigned chIdx, T& valRef) rc_t var_get( instance_t* inst, unsigned vid, unsigned chIdx, T& valRef)
@ -494,6 +537,19 @@ namespace cw
return value; return value;
} }
rc_t var_set( variable_t* var, const value_t* val );
rc_t var_set( variable_t* var, bool val );
rc_t var_set( variable_t* var, uint_t val );
rc_t var_set( variable_t* var, int_t val );
rc_t var_set( variable_t* var, float val );
rc_t var_set( variable_t* var, double val );
rc_t var_set( variable_t* var, const char* val );
rc_t var_set( variable_t* var, abuf_t* val );
rc_t var_set( variable_t* var, fbuf_t* val );
rc_t var_set( variable_t* var, mbuf_t* val );
rc_t var_set( variable_t* var, const object_t* val );
rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, const value_t* val );
rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, bool val ); rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, bool val );
rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, uint_t val ); rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, uint_t val );
rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, int_t val ); rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, int_t val );
@ -502,6 +558,7 @@ namespace cw
rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, const char* val ); rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, const char* val );
rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, abuf_t* val ); rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, abuf_t* val );
rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, fbuf_t* val ); rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, fbuf_t* val );
rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, const object_t* val );
const preset_t* class_preset_find( class_desc_t* cd, const char* preset_label ); const preset_t* class_preset_find( class_desc_t* cd, const char* preset_label );

View File

@ -23,7 +23,32 @@ and audio processing networks and the application of network state data.
### Polyphonic Network. ### Polyphonic Network.
3. Network with sub-nets. ### Network with sub-nets.
## Proc Instance Syntax:
```
<label> : { 'class':<class>, "in":{<in_stmt>*}, "preset":<class_preset_label>, "log":<log_dict> "argLabel":<arg_preset_label>, "args":<args_dict> }
```
__args__ : This is a dictionary of named variable value records.
__preset__ : This string references a class preset to use for initializing this proc instance.
__argLabel__ : This string references an `args` dictionary parameter set to be applied after the __preset__ class preset.
If this argument is not given then it is automatically assigned the value "default". (What if there is not __arg__ record named default?
What if the are no __arg__ records at all?)
__log__ : This is a dictionary of `<var_label>:<sfx_id>` pairs whose value should be printed to the console when they change at runtime.
Notes:
1. All fields except 'class' are optional.
2. The class preset named by __preset__ is always applied before the __arg__ values referenced by __argLabel__.
- When a preset is given as a list of values each entry in the list is taken as the value for
the associated channel. When a list value is given to a var that is of type 'cfg' the list is passed
as a single value.
## Processing Unit Class ## Processing Unit Class
@ -40,6 +65,7 @@ srate | (float) Sample rate type
sample | (float) Audio sample type sample | (float) Audio sample type
coeff | (float) Value that will be directly applied to a sample value (e.g added or multiplied) coeff | (float) Value that will be directly applied to a sample value (e.g added or multiplied)
ftime | (double) Fractional seconds ftime | (double) Fractional seconds
runtime| The type is left up to the processors custom 'create' function. These vars are not automatically created.
See list in cwFlowTypes.cpp : typeLabelFlagsA[] See list in cwFlowTypes.cpp : typeLabelFlagsA[]
@ -166,6 +192,11 @@ uint | `uint32_t`
real | `double` real | `double`
audio | multi-channel audio audio | multi-channel audio
spectrum | multi-channel spectrum spectrum | multi-channel spectrum
cfg |
srate | platform defined sample rate type
sample | platform defined audio sample type
coeff | platform defined signal processing coefficient type
### Variable Flags: ### Variable Flags:
@ -180,7 +211,10 @@ Flag | Description
Notes: Notes:
1. Unless the `no_src` attribute is set any variable may be connected to a source variable 1. Unless the `no_src` attribute is set any variable may be connected to a source variable
in the proc instantation 'in' statement. in the proc instantation 'in' statement. `no_src` variables are output variables whose
value is calculated by the proc and therefore don't make sense to be fed from
some other entity.
2. By default all variables are created prior to the proc `create()` function being called. 2. By default all variables are created prior to the proc `create()` function being called.
Variable with the `no_dflt_create` attribute will not be created. This is useful in cases Variable with the `no_dflt_create` attribute will not be created. This is useful in cases