2021-08-15 20:07:12 +00:00
namespace cw
{
namespace flow
{
2021-08-23 02:41:33 +00:00
# define kRealTFl kFloatTFl
typedef dsp : : real_t real_t ;
typedef dsp : : sample_t sample_t ;
2023-01-05 12:22:37 +00:00
typedef dsp : : fd_real_t fd_real_t ;
2021-08-23 02:41:33 +00:00
typedef dsp : : srate_t srate_t ;
typedef unsigned uint_t ;
typedef int int_t ;
2021-08-15 20:07:12 +00:00
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 {
2022-12-05 22:19:58 +00:00
kFbufVectN = 3 , // count of signal vectors in fbuf (mag,phs,hz)
2022-01-22 14:49:45 +00:00
kAnyChIdx = kInvalidIdx ,
kLocalValueN = 2
2021-08-15 20:07:12 +00:00
} ;
typedef struct fbuf_str
{
struct value_str * base ;
2022-11-11 18:51:06 +00:00
srate_t srate ; // signal sample rate
unsigned flags ; // See kXXXFbufFl
unsigned chN ; // count of channels
2022-12-27 23:09:31 +00:00
unsigned * maxBinN_V ; // max value that binN_V[i] is allowed to take
2022-11-11 18:51:06 +00:00
unsigned * binN_V ; // binN_V[ chN ] count of sample frames per channel
unsigned * hopSmpN_V ; // hopSmpN_V[ chN ] hop sample count
2023-01-05 12:22:37 +00:00
fd_real_t * * magV ; // magV[ chN ][ binN ]
fd_real_t * * phsV ; // phsV[ chN ][ binN ]
fd_real_t * * hzV ; // hzV[ chN ][ binN ]
2022-11-11 18:51:06 +00:00
bool * readyFlV ; // readyFlV[chN] true if this channel is ready to be processed (used to sync. fbuf rate to abuf rate)
2023-01-05 12:22:37 +00:00
fd_real_t * buf ; // memory used by this buffer (or NULL if magV,phsV,hzV point are proxied to another buffer)
2021-08-15 20:07:12 +00:00
} fbuf_t ;
enum
{
2021-12-12 21:41:57 +00:00
kInvalidTFl = 0x00000000 ,
kBoolTFl = 0x00000001 ,
kUIntTFl = 0x00000002 ,
kIntTFl = 0x00000004 ,
kFloatTFl = 0x00000008 ,
kDoubleTFl = 0x00000010 ,
2021-08-15 20:07:12 +00:00
2021-12-12 21:41:57 +00:00
kBoolMtxTFl = 0x00000020 ,
kUIntMtxTFl = 0x00000040 ,
kIntMtxTFl = 0x00000080 ,
kRealMtxTFl = 0x00000100 ,
2021-08-23 02:41:33 +00:00
kFloatMtxTFl = 0x00000200 ,
kDoubleMtxTFl = 0x00000400 ,
2021-08-15 20:07:12 +00:00
2021-12-12 21:41:57 +00:00
kABufTFl = 0x00000800 ,
kFBufTFl = 0x00001000 ,
kStringTFl = 0x00002000 ,
kTimeTFl = 0x00004000 ,
2021-08-15 20:07:12 +00:00
2021-12-12 21:41:57 +00:00
kTypeMask = 0x00007fff ,
2021-08-15 20:07:12 +00:00
} ;
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 ;
2021-08-23 02:41:33 +00:00
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 ) ; }
2021-08-15 20:07:12 +00:00
struct instance_str ;
struct variable_str ;
2021-08-23 02:41:33 +00:00
2021-08-15 20:07:12 +00:00
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
{
2022-11-11 18:09:07 +00:00
kSrcVarFl = 0x01 ,
kSrcOptVarFl = 0x02
2021-08-15 20:07:12 +00:00
} ;
typedef struct class_members_str
{
member_func_t create ;
member_func_t destroy ;
member_value_func_t value ;
member_func_t exec ;
2021-08-23 02:41:33 +00:00
member_func_t report ;
2021-08-15 20:07:12 +00:00
} class_members_t ;
typedef struct var_desc_str
{
2021-08-23 02:41:33 +00:00
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
2021-08-15 20:07:12 +00:00
} 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 ;
2021-08-23 02:41:33 +00:00
// Note: The concatenation of 'vid' and 'chIdx' should form a unique identifier among all variables
// on a given 'instance'.
2021-08-15 20:07:12 +00:00
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
2022-01-22 14:49:45 +00:00
value_t local_value [ kLocalValueN ] ; // the local value instance (actual value if this is not a 'src' variable)
2023-01-07 14:27:36 +00:00
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())
2021-08-15 20:07:12 +00:00
value_t * value ; // pointer to the value associated with this variable
unsigned chIdx ; // channel index
2021-12-30 02:52:46 +00:00
struct variable_str * src_var ; // pointer to this input variables source link (or null if it uses the local_value)
2022-01-22 14:49:45 +00:00
struct variable_str * var_link ; // instance.varL link list
2021-08-15 20:07:12 +00:00
struct variable_str * connect_link ; // list of outgoing connections
2021-08-23 02:41:33 +00:00
struct variable_str * ch_link ; // list of channels that share this variable (rooted on 'any' channel - in order by channel number)
2021-08-15 20:07:12 +00:00
} 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
2023-01-05 12:22:37 +00:00
variable_t * varL ; // linked list of all variables on this instance
2021-08-15 20:07:12 +00:00
2023-01-05 12:22:37 +00:00
unsigned varMapChN ; // max count of channels (max 'chIdx' + 2) among all variables on this instance, (2=kAnyChIdx+index to count)
unsigned varMapIdN ; // max 'vid' among all variables on this instance
unsigned varMapN ; // varMapN = varMapIdN * varMapChN
variable_t * * varMapA ; // varMapA[ varMapN ] = allows fast lookup from ('vid','chIdx) to variable
2021-08-15 20:07:12 +00:00
struct instance_str * link ;
2021-12-11 20:17:11 +00:00
} instance_t ;
2021-08-15 20:07:12 +00:00
typedef struct flow_str
{
2021-12-19 17:10:35 +00:00
const object_t * networkCfg ; // complete cfg used to create this network
const object_t * presetCfg ; // presets designed for this network
2021-08-15 20:07:12 +00:00
2024-02-08 16:17:26 +00:00
unsigned framesPerCycle ; // sample frames per cycle (64)
2024-02-18 13:41:19 +00:00
bool multiPriPresetProbFl ; // If set then probability is used to choose presets on multi-preset application
bool multiSecPresetProbFl ; //
2024-02-08 16:17:26 +00:00
bool multiPresetInterpFl ; // If set then interpolation is applied between two selectedd presets on multi-preset application
2021-08-15 20:07:12 +00:00
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 ; //
2021-12-11 20:17:11 +00:00
external_device_t * deviceA ; // deviceA[ deviceN ] external device description array
unsigned deviceN ; //
2021-08-15 20:07:12 +00:00
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 ) ;
2022-01-22 14:49:45 +00:00
void abuf_destroy ( abuf_t * & buf ) ;
2021-08-23 02:41:33 +00:00
abuf_t * abuf_duplicate ( const abuf_t * src ) ;
2021-08-15 20:07:12 +00:00
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 ) ;
2023-01-05 12:22:37 +00:00
fbuf_t * fbuf_create ( srate_t srate , unsigned chN , const unsigned * maxBinN_V , const unsigned * binN_V , const unsigned * hopSmpN_V , const fd_real_t * * magV = nullptr , const fd_real_t * * phsV = nullptr , const fd_real_t * * hzV = nullptr ) ;
fbuf_t * fbuf_create ( srate_t srate , unsigned chN , unsigned maxBinN , unsigned binN , unsigned hopSmpN , const fd_real_t * * magV = nullptr , const fd_real_t * * phsV = nullptr , const fd_real_t * * hzV = nullptr ) ;
2022-01-22 14:49:45 +00:00
void fbuf_destroy ( fbuf_t * & buf ) ;
2021-08-23 02:41:33 +00:00
fbuf_t * fbuf_duplicate ( const fbuf_t * src ) ;
2021-08-15 20:07:12 +00:00
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 ) ;
2021-08-23 02:41:33 +00:00
class_desc_t * class_desc_find ( flow_t * p , const char * class_desc_label ) ;
void class_dict_print ( flow_t * p ) ;
//------------------------------------------------------------------------------------------------------------------------
//
// Network
//
2021-08-15 20:07:12 +00:00
void network_print ( flow_t * p ) ;
//------------------------------------------------------------------------------------------------------------------------
//
// Instance
//
2021-12-11 20:17:11 +00:00
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 ) ;
2021-08-15 20:07:12 +00:00
2021-12-19 17:10:35 +00:00
2021-08-15 20:07:12 +00:00
//------------------------------------------------------------------------------------------------------------------------
//
// Variable
//
// Create a variable but do not assign it a value. Return a pointer to the new variable.
2021-08-23 02:41:33 +00:00
// 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'.
2021-12-30 02:52:46 +00:00
rc_t var_channelize ( instance_t * inst , const char * var_label , unsigned chIdx , const object_t * value_cfg , unsigned vid , variable_t * & varRef ) ;
2021-08-23 02:41:33 +00:00
// `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 ) ;
2021-12-30 02:52:46 +00:00
// Returns true if this var is connected to an external proc variable
bool is_connected_to_external_proc ( const variable_t * var ) ;
2021-08-23 02:41:33 +00:00
//-----------------
//
// 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
//
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
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.
2021-08-15 20:07:12 +00:00
// 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.)
2021-08-23 02:41:33 +00:00
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 ) ;
2023-01-05 12:22:37 +00:00
rc_t var_register_and_set ( instance_t * inst , const char * var_label , unsigned vid , unsigned chIdx , srate_t srate , unsigned chN , const unsigned * maxBinN_V , const unsigned * binN_V , const unsigned * hopSmpN_V , const fd_real_t * * magV = nullptr , const fd_real_t * * phsV = nullptr , const fd_real_t * * hzV = nullptr ) ;
rc_t var_register_and_set ( instance_t * inst , const char * var_label , unsigned vid , unsigned chIdx , srate_t srate , unsigned chN , unsigned maxBinN , unsigned binN , unsigned hopSmpN , const fd_real_t * * magV = nullptr , const fd_real_t * * phsV = nullptr , const fd_real_t * * hzV = nullptr ) ;
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
inline rc_t _var_register_and_set ( cw : : flow : : instance_t * , unsigned int ) { return kOkRC ; }
2021-08-15 20:07:12 +00:00
template < typename T0 , typename T1 , typename T2 , typename . . . ARGS >
2021-08-23 02:41:33 +00:00
rc_t _var_register_and_set ( instance_t * inst , unsigned chIdx , T0 vid , T1 var_label , T2 val , ARGS & & . . . args )
2021-08-15 20:07:12 +00:00
{
rc_t rc ;
2021-08-23 02:41:33 +00:00
variable_t * var = nullptr ;
if ( ( rc = var_register_and_set ( inst , var_label , vid , chIdx , var ) ) = = kOkRC )
{
2021-12-28 01:23:38 +00:00
var_set ( inst , vid , chIdx , val ) ;
2021-08-23 02:41:33 +00:00
if ( ( rc = _var_register_and_set ( inst , chIdx , std : : forward < ARGS > ( args ) . . . ) ) ! = kOkRC )
return rc ;
}
2021-08-15 20:07:12 +00:00
return rc ;
}
2021-08-23 02:41:33 +00:00
// Call var_register_and_set() on a list of variables.
2021-08-15 20:07:12 +00:00
template < typename . . . ARGS >
2021-08-23 02:41:33 +00:00
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 ) . . . ) ; }
2021-08-15 20:07:12 +00:00
void _var_destroy ( variable_t * var ) ;
bool var_exists ( instance_t * inst , const char * label , unsigned chIdx ) ;
2022-11-11 18:09:07 +00:00
bool var_has_value ( instance_t * inst , const char * label , unsigned chIdx ) ;
2022-01-22 14:49:45 +00:00
2021-08-23 02:41:33 +00:00
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 ) ;
2022-01-22 14:49:45 +00:00
// Count of numbered channels - does not count the kAnyChIdx variable instance.
rc_t var_channel_count ( instance_t * inst , const char * label , unsigned & chCntRef ) ;
rc_t var_channel_count ( const variable_t * var , unsigned & chCntRef ) ;
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
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 ) ;
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
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 ;
2021-12-26 03:31:26 +00:00
}
2021-08-23 02:41:33 +00:00
2021-12-26 03:31:26 +00:00
template < typename T >
T val_get ( instance_t * inst , unsigned vid , unsigned chIdx )
{
T value ;
var_get ( inst , vid , chIdx , value ) ;
return value ;
2021-08-23 02:41:33 +00:00
}
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
rc_t var_set ( instance_t * inst , unsigned vid , unsigned chIdx , bool val ) ;
2021-08-15 20:07:12 +00:00
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 ) ;
2021-08-23 02:41:33 +00:00
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 ) ;
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
const preset_t * class_preset_find ( class_desc_t * cd , const char * preset_label ) ;
2021-08-15 20:07:12 +00:00
}
}