33e1945ab4
Added _set_var_template(), _var_setter()
447 lines
17 KiB
C++
447 lines
17 KiB
C++
namespace cw
|
|
{
|
|
namespace flow
|
|
{
|
|
|
|
#define kRealTFl kFloatTFl
|
|
typedef dsp::real_t real_t;
|
|
typedef dsp::sample_t sample_t;
|
|
typedef dsp::srate_t srate_t;
|
|
typedef unsigned uint_t;
|
|
typedef int int_t;
|
|
|
|
|
|
typedef unsigned vid_t;
|
|
|
|
typedef struct abuf_str
|
|
{
|
|
struct value_str* base;
|
|
srate_t srate; // signal sample rate
|
|
unsigned chN; // count of channels
|
|
unsigned frameN; // count of sample frames per channel
|
|
sample_t* buf; // buf[ chN ][ frameN ]
|
|
} abuf_t;
|
|
|
|
|
|
enum {
|
|
kFbufVectN = 3,
|
|
kAnyChIdx = kInvalidIdx
|
|
};
|
|
|
|
typedef struct fbuf_str
|
|
{
|
|
struct value_str* base;
|
|
srate_t srate; // signal sample rate
|
|
unsigned flags; // See kXXXFbufFl
|
|
unsigned chN; // count of channels
|
|
unsigned binN; // count of sample frames per channel
|
|
unsigned hopSmpN; // hop sample count
|
|
sample_t** magV; // magV[ chN ][ binN ]
|
|
sample_t** phsV; // phsV[ chN ][ binN ]
|
|
sample_t** hzV; // hzV[ chN ][ binN ]
|
|
bool* readyFlV; // readyFlV[chN] true if this channel is ready to be processed (used to sync. fbuf rate to abuf rate)
|
|
sample_t* buf; // memory used by this buffer (or NULL if magV,phsV,hzV point are proxied to another buffer)
|
|
} fbuf_t;
|
|
|
|
enum
|
|
{
|
|
kInvalidTFl = 0x00000000,
|
|
kBoolTFl = 0x00000001,
|
|
kUIntTFl = 0x00000002,
|
|
kIntTFl = 0x00000004,
|
|
kFloatTFl = 0x00000008,
|
|
kDoubleTFl = 0x00000010,
|
|
|
|
kBoolMtxTFl = 0x00000020,
|
|
kUIntMtxTFl = 0x00000040,
|
|
kIntMtxTFl = 0x00000080,
|
|
kRealMtxTFl = 0x00000100,
|
|
kFloatMtxTFl = 0x00000200,
|
|
kDoubleMtxTFl= 0x00000400,
|
|
|
|
kABufTFl = 0x00000800,
|
|
kFBufTFl = 0x00001000,
|
|
kStringTFl = 0x00002000,
|
|
kTimeTFl = 0x00004000,
|
|
|
|
kTypeMask = 0x00007fff,
|
|
|
|
};
|
|
|
|
typedef struct mtx_str
|
|
{
|
|
union {
|
|
struct mtx::mtx_str< unsigned >* u;
|
|
struct mtx::mtx_str< int >* i;
|
|
struct mtx::mtx_str< real_t >* r;
|
|
struct mtx::mtx_str< float >* f;
|
|
struct mtx::mtx_str< double >* d;
|
|
} u;
|
|
} mtx_t;
|
|
|
|
typedef struct value_str
|
|
{
|
|
unsigned flags;
|
|
union {
|
|
bool b;
|
|
uint_t u;
|
|
int_t i;
|
|
float f;
|
|
double d;
|
|
|
|
mtx_t* mtx;
|
|
|
|
abuf_t* abuf;
|
|
fbuf_t* fbuf;
|
|
|
|
char* s;
|
|
char* fname;
|
|
|
|
} u;
|
|
|
|
struct value_str* link;
|
|
|
|
} value_t;
|
|
|
|
|
|
inline bool is_numeric( const value_t* v ) { return cwIsFlag(v->flags,kBoolTFl|kUIntTFl|kIntTFl|kFloatTFl|kDoubleTFl); }
|
|
inline bool is_matrix( const value_t* v ) { return cwIsFlag(v->flags,kBoolMtxTFl|kUIntMtxTFl|kIntMtxTFl|kFloatMtxTFl|kDoubleMtxTFl); }
|
|
|
|
struct instance_str;
|
|
struct variable_str;
|
|
|
|
typedef rc_t (*member_func_t)( struct instance_str* ctx );
|
|
typedef rc_t (*member_value_func_t)( struct instance_str* ctx, struct variable_str* var );
|
|
enum
|
|
{
|
|
kSrcVarFl = 0x01
|
|
};
|
|
|
|
typedef struct class_members_str
|
|
{
|
|
member_func_t create;
|
|
member_func_t destroy;
|
|
member_value_func_t value;
|
|
member_func_t exec;
|
|
member_func_t report;
|
|
} class_members_t;
|
|
|
|
typedef struct var_desc_str
|
|
{
|
|
const object_t* cfg; // The cfg object that describes this variable from 'flow_class'.
|
|
const object_t* val_cfg; // An object containing the default value for this variable.
|
|
const char* label; // Name of this var.
|
|
unsigned type; // Value type id (e.g. kBoolTFl, kIntTFl, ...)
|
|
unsigned flags; // Attributes for this var. (e.g. kSrcVarFl )
|
|
const char* docText; // User help string for this var.
|
|
struct var_desc_str* link; // class_desc->varDescL list link
|
|
} var_desc_t;
|
|
|
|
typedef struct preset_str
|
|
{
|
|
const char* label;
|
|
const object_t* cfg;
|
|
struct preset_str* link;
|
|
} preset_t;
|
|
|
|
typedef struct class_desc_str
|
|
{
|
|
const object_t* cfg; //
|
|
const char* label; // class label;
|
|
var_desc_t* varDescL; // varDescA[varDescN] value description list
|
|
preset_t* presetL; // presetA[ presetN ]
|
|
class_members_t* members; // member functions for this class
|
|
} class_desc_t;
|
|
|
|
|
|
// Note: The concatenation of 'vid' and 'chIdx' should form a unique identifier among all variables
|
|
// on a given 'instance'.
|
|
typedef struct variable_str
|
|
{
|
|
struct instance_str* inst; // pointer to this variables instance
|
|
char* label; // this variables label
|
|
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
|
|
value_t local_value; // the local value instance (actual value if this is not a 'src' variable)
|
|
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* var_link; // link to other var's on 'inst'
|
|
struct variable_str* connect_link; // list of outgoing connections
|
|
struct variable_str* ch_link; // list of channels that share this variable (rooted on 'any' channel - in order by channel number)
|
|
} variable_t;
|
|
|
|
|
|
typedef struct instance_str
|
|
{
|
|
struct flow_str* ctx; // global system context
|
|
|
|
class_desc_t* class_desc; //
|
|
|
|
const char* label; // instance label
|
|
const object_t* inst_cfg; // instance configuration
|
|
|
|
const char* arg_label; // optional args label
|
|
const object_t* arg_cfg; // optional args configuration
|
|
|
|
void* userPtr; // instance state
|
|
|
|
variable_t* varL; // list of instance value
|
|
|
|
unsigned varMapChN; // max count of channels among all variables
|
|
unsigned varMapIdN;
|
|
unsigned varMapN; // varMapN
|
|
variable_t** varMapA; // varMapA[ varMapN ]
|
|
|
|
struct instance_str* link;
|
|
} instance_t;
|
|
|
|
|
|
|
|
typedef struct flow_str
|
|
{
|
|
const object_t* networkCfg; // complete cfg used to create this network
|
|
|
|
const object_t* presetCfg; // presets designed for this network
|
|
|
|
unsigned framesPerCycle; // sample frames per cycle (64)
|
|
unsigned cycleIndex; // Incremented with each processing cycle
|
|
unsigned maxCycleCount; // count of cycles to run on flow::exec() or 0 if there is no limit.
|
|
|
|
class_desc_t* classDescA; //
|
|
unsigned classDescN; //
|
|
|
|
external_device_t* deviceA; // deviceA[ deviceN ] external device description array
|
|
unsigned deviceN; //
|
|
|
|
struct instance_str* network_head; // first instance
|
|
struct instance_str* network_tail; // last insance
|
|
} flow_t;
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Value Only
|
|
//
|
|
|
|
abuf_t* abuf_create( srate_t srate, unsigned chN, unsigned frameN );
|
|
void abuf_destroy( abuf_t* buf );
|
|
abuf_t* abuf_duplicate( const abuf_t* src );
|
|
rc_t abuf_set_channel( abuf_t* buf, unsigned chIdx, const sample_t* v, unsigned vN );
|
|
const sample_t* abuf_get_channel( abuf_t* buf, unsigned chIdx );
|
|
|
|
fbuf_t* fbuf_create( srate_t srate, unsigned chN, unsigned binN, unsigned hopSmpN, const sample_t** magV=nullptr, const sample_t** phsV=nullptr, const sample_t** hzV=nullptr );
|
|
void fbuf_destroy( fbuf_t* buf );
|
|
fbuf_t* fbuf_duplicate( const fbuf_t* src );
|
|
|
|
inline bool value_is_abuf( const value_t* v ) { return v->flags & kABufTFl; }
|
|
inline bool value_is_fbuf( const value_t* v ) { return v->flags & kFBufTFl; }
|
|
|
|
unsigned value_type_label_to_flag( const char* type_desc );
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Class and Variable Description
|
|
//
|
|
|
|
var_desc_t* var_desc_find( class_desc_t* cd, const char* var_label );
|
|
rc_t var_desc_find( class_desc_t* cd, const char* label, var_desc_t*& vdRef );
|
|
|
|
class_desc_t* class_desc_find( flow_t* p, const char* class_desc_label );
|
|
|
|
void class_dict_print( flow_t* p );
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Network
|
|
//
|
|
void network_print( flow_t* p );
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Instance
|
|
//
|
|
|
|
instance_t* instance_find( flow_t* p, const char* inst_label );
|
|
rc_t instance_find( flow_t* p, const char* inst_label, instance_t*& instPtrRef );
|
|
external_device_t* external_device_find( flow_t* p, const char* device_label, unsigned typeId, unsigned inOrOutFl );
|
|
|
|
void instance_print( instance_t* inst );
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//
|
|
// 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
|
|
rc_t var_create( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef );
|
|
|
|
// Channelizing creates a new var record with an explicit channel index to replace the
|
|
// automatically generated variable whose channel index is set to 'all'.
|
|
rc_t var_channelize( instance_t* inst, const char* var_label, unsigned chIdx, const object_t* value_cfg, unsigned vid, variable_t*& varRef );
|
|
|
|
// `value_cfg` is optional. Set it to NULL to ignore
|
|
rc_t var_register( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef );
|
|
|
|
// Returns true if this var is connected to an external proc variable
|
|
bool is_connected_to_external_proc( const variable_t* var );
|
|
|
|
//-----------------
|
|
//
|
|
// var_register
|
|
//
|
|
|
|
inline rc_t _var_reg(cw::flow::instance_t*, unsigned int ) { return kOkRC; }
|
|
|
|
template< typename T0, typename T1, typename... ARGS >
|
|
rc_t _var_reg( instance_t* inst, unsigned chIdx, T0 vid, T1 var_label, ARGS&&... args )
|
|
{
|
|
rc_t rc;
|
|
variable_t* dummy = nullptr;
|
|
if((rc = var_register( inst, var_label, vid, chIdx, nullptr, dummy )) == kOkRC )
|
|
if((rc = _var_reg( inst, chIdx, std::forward<ARGS>(args)...)) != kOkRC )
|
|
return rc;
|
|
return rc;
|
|
}
|
|
|
|
// Call var_register() on a list of variables.
|
|
template< typename... ARGS >
|
|
rc_t var_register( instance_t* inst, unsigned chIdx, unsigned vid, const char* var_label, ARGS&&... args )
|
|
{ return _var_reg( inst, chIdx, vid, var_label, std::forward<ARGS>(args)...); }
|
|
|
|
|
|
|
|
//---------------------
|
|
//
|
|
// var_register_and_get
|
|
//
|
|
|
|
inline rc_t _var_register_and_get(cw::flow::instance_t*, unsigned int ) { return kOkRC; }
|
|
|
|
template< typename T>
|
|
rc_t var_register_and_get( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, T& valRef )
|
|
{
|
|
rc_t rc;
|
|
variable_t* var;
|
|
if((rc = var_register(inst,var_label,vid,chIdx,nullptr,var)) == kOkRC )
|
|
rc = var_get(var,valRef);
|
|
return rc;
|
|
}
|
|
|
|
|
|
inline rc_t _var_reg_and_get(cw::flow::instance_t*, unsigned int ) { return kOkRC; }
|
|
|
|
template< typename T0, typename T1, typename T2, typename... ARGS >
|
|
rc_t _var_reg_and_get( instance_t* inst, unsigned chIdx, T0 vid, T1 var_label, T2& valRef, ARGS&&... args )
|
|
{
|
|
rc_t rc;
|
|
|
|
if((rc = var_register_and_get( inst, var_label, vid, chIdx, valRef )) == kOkRC )
|
|
if((rc = _var_reg_and_get( inst, chIdx, std::forward<ARGS>(args)...)) != kOkRC )
|
|
return rc;
|
|
|
|
return rc;
|
|
}
|
|
|
|
// Call var_register_and_get() on a list of variables.
|
|
template< typename... ARGS >
|
|
rc_t var_register_and_get( instance_t* inst, unsigned chIdx, unsigned vid, const char* var_label, ARGS&&... args )
|
|
{ return _var_reg_and_get( inst, chIdx, vid, var_label, std::forward<ARGS>(args)...); }
|
|
|
|
|
|
|
|
//---------------------
|
|
//
|
|
// var_register_and_set
|
|
//
|
|
|
|
// var_register_and_set(). If the variable has not yet been created then it is created and assigned a value.
|
|
// If the variable has already been created then 'vid' and the value are updated.
|
|
// (Note that abuf and fbuf values are not changed by this function only the 'vid' is updated.)
|
|
rc_t var_register_and_set( instance_t* inst, const char* label, unsigned vid, unsigned chIdx, variable_t*& varRef );
|
|
|
|
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned frameN );
|
|
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned binN, unsigned hopSmpN, const sample_t** magV=nullptr, const sample_t** phsV=nullptr, const sample_t** hzV=nullptr );
|
|
|
|
inline rc_t _var_register_and_set(cw::flow::instance_t*, unsigned int ) { return kOkRC; }
|
|
|
|
template< typename T0, typename T1, typename T2, typename... ARGS >
|
|
rc_t _var_register_and_set( instance_t* inst, unsigned chIdx, T0 vid, T1 var_label, T2 val, ARGS&&... args )
|
|
{
|
|
rc_t rc;
|
|
|
|
variable_t* var = nullptr;
|
|
if((rc = var_register_and_set( inst, var_label, vid, chIdx, var)) == kOkRC )
|
|
{
|
|
var_set( inst, vid, chIdx, val );
|
|
|
|
if((rc = _var_register_and_set( inst, chIdx, std::forward<ARGS>(args)...)) != kOkRC )
|
|
return rc;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
// Call var_register_and_set() on a list of variables.
|
|
template< typename... ARGS >
|
|
rc_t var_register_and_set( instance_t* inst, unsigned chIdx, unsigned vid, const char* var_label, ARGS&&... args )
|
|
{ return _var_register_and_set( inst, chIdx, vid, var_label, std::forward<ARGS>(args)...); }
|
|
|
|
|
|
|
|
void _var_destroy( variable_t* var );
|
|
|
|
bool var_exists( instance_t* inst, const char* label, unsigned chIdx );
|
|
|
|
rc_t var_find( instance_t* inst, const char* var_label, unsigned chIdx, const variable_t*& varRef );
|
|
rc_t var_find( instance_t* inst, const char* var_label, unsigned chIdx, variable_t*& varRef );
|
|
rc_t var_find( instance_t* inst, unsigned vid, unsigned chIdx, variable_t*& varRef );
|
|
|
|
rc_t var_get( const variable_t* var, bool& valRef );
|
|
rc_t var_get( const variable_t* var, uint_t& valRef );
|
|
rc_t var_get( const variable_t* var, int_t& valRef );
|
|
rc_t var_get( const variable_t* var, float& valRef );
|
|
rc_t var_get( const variable_t* var, double& valRef );
|
|
rc_t var_get( const variable_t* var, const char*& valRef );
|
|
rc_t var_get( const variable_t* var, const abuf_t*& valRef );
|
|
rc_t var_get( variable_t* var, abuf_t*& valRef );
|
|
rc_t var_get( const variable_t* var, const fbuf_t*& valRef );
|
|
rc_t var_get( variable_t* var, fbuf_t*& valRef );
|
|
|
|
template< typename T>
|
|
rc_t var_get( instance_t* inst, unsigned vid, unsigned chIdx, T& valRef)
|
|
{
|
|
rc_t rc = kOkRC;
|
|
variable_t* var = nullptr;
|
|
|
|
if((rc = var_find(inst, vid, chIdx, var )) == kOkRC )
|
|
rc = var_get(var,valRef);
|
|
|
|
return rc;
|
|
}
|
|
|
|
template< typename T >
|
|
T val_get( instance_t* inst, unsigned vid, unsigned chIdx )
|
|
{
|
|
T value;
|
|
var_get(inst,vid,chIdx,value);
|
|
return value;
|
|
}
|
|
|
|
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, int_t val );
|
|
rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, float val );
|
|
rc_t var_set( instance_t* inst, unsigned vid, unsigned chIdx, double 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, fbuf_t* val );
|
|
|
|
const preset_t* class_preset_find( class_desc_t* cd, const char* preset_label );
|
|
|
|
}
|
|
}
|