762 lines
32 KiB
C++
762 lines
32 KiB
C++
//| Copyright: (C) 2020-2024 Kevin Larke <contact AT larke DOT org>
|
|
//| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
|
|
namespace cw
|
|
{
|
|
namespace flow
|
|
{
|
|
|
|
typedef dsp::coeff_t coeff_t;
|
|
typedef dsp::sample_t sample_t;
|
|
typedef dsp::fd_sample_t fd_sample_t;
|
|
typedef dsp::srate_t srate_t;
|
|
typedef dsp::ftime_t ftime_t;
|
|
typedef unsigned uint_t;
|
|
typedef int int_t;
|
|
|
|
|
|
typedef unsigned vid_t;
|
|
|
|
enum {
|
|
kBaseSfxId = 0,
|
|
kFbufVectN = 3, // count of signal vectors in fbuf (mag,phs,hz)
|
|
kAnyChIdx = kInvalidIdx,
|
|
kLocalValueN = 2,
|
|
kDefaultFramesPerCycle=64,
|
|
kDefaultSampleRate=48000
|
|
};
|
|
|
|
typedef struct abuf_str
|
|
{
|
|
srate_t srate; // Signal sample rate
|
|
unsigned chN; // Count of channels
|
|
unsigned frameN; // Count of sample frames per channel
|
|
unsigned bufAllocSmpN; // Size of allocated buf[] in samples.
|
|
sample_t* buf; // buf[ chN ][ frameN ]
|
|
} abuf_t;
|
|
|
|
|
|
typedef struct fbuf_str
|
|
{
|
|
unsigned memByteN; // Count of bytes in mem[].
|
|
void* mem; // mem[ memByteN ] All dynamically allocated memory used by this fbuf.
|
|
|
|
srate_t srate; // signal sample rate
|
|
unsigned flags; // See kXXXFbufFl
|
|
unsigned chN; // count of channels
|
|
unsigned* maxBinN_V; // maxBinN_V[chN] max value that binN_V[i] is allowed to take
|
|
unsigned* binN_V; // binN_V[ chN ] count of sample frames per channel
|
|
unsigned* hopSmpN_V; // hopSmpN_V[ chN ] hop sample count
|
|
fd_sample_t** magV; // magV[ chN ][ binN ]
|
|
fd_sample_t** phsV; // phsV[ chN ][ binN ]
|
|
fd_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)
|
|
} fbuf_t;
|
|
|
|
typedef struct mbuf_str
|
|
{
|
|
const midi::ch_msg_t* msgA;
|
|
unsigned msgN;
|
|
} mbuf_t;
|
|
|
|
enum
|
|
{
|
|
kInvalidTFl = 0x00000000,
|
|
kBoolTFl = 0x00000001,
|
|
kUIntTFl = 0x00000002,
|
|
kIntTFl = 0x00000004,
|
|
kFloatTFl = 0x00000008,
|
|
kDoubleTFl = 0x00000010,
|
|
|
|
kBoolMtxTFl = 0x00000020,
|
|
kUIntMtxTFl = 0x00000040,
|
|
kIntMtxTFl = 0x00000080,
|
|
kFloatMtxTFl = 0x00000100,
|
|
kDoubleMtxTFl= 0x00000200,
|
|
|
|
kABufTFl = 0x00000400,
|
|
kFBufTFl = 0x00000800,
|
|
kMBufTFl = 0x00001000,
|
|
kStringTFl = 0x00002000,
|
|
kTimeTFl = 0x00004000,
|
|
kCfgTFl = 0x00008000,
|
|
|
|
kTypeMask = 0x0000ffff,
|
|
|
|
kRuntimeTFl = 0x80000000,
|
|
|
|
kNumericTFl = kBoolTFl | kUIntTFl | kIntTFl | kFloatTFl | kDoubleTFl,
|
|
kMtxTFl = kBoolMtxTFl | kUIntMtxTFl | kIntMtxTFl | kFloatMtxTFl | kDoubleMtxTFl,
|
|
kAllTFl = kTypeMask
|
|
};
|
|
|
|
typedef struct mtx_str
|
|
{
|
|
union {
|
|
struct mtx::mtx_str< unsigned >* u;
|
|
struct mtx::mtx_str< int >* i;
|
|
struct mtx::mtx_str< float >* f;
|
|
struct mtx::mtx_str< double >* d;
|
|
} u;
|
|
} mtx_t;
|
|
|
|
typedef struct value_str
|
|
{
|
|
unsigned tflag;
|
|
|
|
union {
|
|
bool b;
|
|
uint_t u;
|
|
int_t i;
|
|
float f;
|
|
double d;
|
|
|
|
mtx_t* mtx;
|
|
abuf_t* abuf;
|
|
fbuf_t* fbuf;
|
|
mbuf_t* mbuf;
|
|
|
|
char* s;
|
|
|
|
const object_t* cfg;
|
|
void* p;
|
|
|
|
} u;
|
|
|
|
struct value_str* link;
|
|
|
|
} value_t;
|
|
|
|
|
|
struct proc_str;
|
|
struct variable_str;
|
|
|
|
typedef rc_t (*member_func_t)( struct proc_str* ctx );
|
|
typedef rc_t (*member_value_func_t)( struct proc_str* ctx, struct variable_str* var );
|
|
|
|
// var_desc_t attribute flags
|
|
enum
|
|
{
|
|
kInvalidVarDescFl = 0x00,
|
|
kSrcVarDescFl = 0x01,
|
|
kSrcOptVarDescFl = 0x02,
|
|
kNoSrcVarDescFl = 0x04,
|
|
kInitVarDescFl = 0x08,
|
|
kMultVarDescFl = 0x10,
|
|
kUdpOutVarDescFl = 0x20
|
|
};
|
|
|
|
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.
|
|
|
|
char* proxyProcLabel;
|
|
char* proxyVarLabel;
|
|
|
|
struct var_desc_str* link; // class_desc->varDescL list link
|
|
} var_desc_t;
|
|
|
|
typedef struct class_preset_str
|
|
{
|
|
const char* label;
|
|
const object_t* cfg;
|
|
struct class_preset_str* link;
|
|
} class_preset_t;
|
|
|
|
typedef struct class_desc_str
|
|
{
|
|
const object_t* cfg; // class cfg
|
|
const char* label; // class label;
|
|
var_desc_t* varDescL; // varDescL variable description linked on var_desc_t.link
|
|
class_preset_t* presetL; // preset linked list
|
|
class_members_t* members; // member functions for this class
|
|
unsigned polyLimitN; // max. poly copies of this class per network_t or 0 if no limit
|
|
ui_proc_desc_t* ui;
|
|
} class_desc_t;
|
|
|
|
enum {
|
|
kInvalidVarFl = 0x00,
|
|
kLogVarFl = 0x01,
|
|
kProxiedVarFl = 0x02,
|
|
kProxiedOutVarFl = 0x04
|
|
};
|
|
|
|
// Note: The concatenation of 'vid' and 'chIdx' should form a unique identifier among all variables
|
|
// on a given 'instance'.
|
|
typedef struct variable_str
|
|
{
|
|
struct proc_str* proc; // pointer to this variables instance
|
|
|
|
char* label; // this variables label
|
|
unsigned label_sfx_id; // the label suffix id of this variable or kBaseSfxId if this has no suffix
|
|
|
|
unsigned vid; // this variables numeric id ( cat(vid,chIdx) forms a unique variable identifier on this 'proc'
|
|
unsigned chIdx; // channel index
|
|
unsigned flags; // See kLogVarFl, kProxiedVarFl, etc
|
|
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)
|
|
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())
|
|
struct variable_str* src_var; // pointer to this input variables source link (or null if it uses the local_value)
|
|
value_t* value; // pointer to the value associated with this variable
|
|
|
|
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* 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.
|
|
|
|
ui_var_t* ui_var; // this variables UI description
|
|
std::atomic<struct variable_str*> ui_var_link; // UI update var link based on flow_t ui_var_head;
|
|
} variable_t;
|
|
|
|
|
|
struct network_str;
|
|
|
|
typedef struct proc_str
|
|
{
|
|
struct flow_str* ctx; // global system context
|
|
struct network_str* net; // network which owns this proc
|
|
|
|
class_desc_t* class_desc; //
|
|
|
|
char* label; // instance label
|
|
unsigned label_sfx_id; // label suffix id (set to kBaseSfxId (0) unless poly is non-null)
|
|
|
|
const object_t* proc_cfg; // instance configuration
|
|
|
|
void* userPtr; // instance state
|
|
|
|
variable_t* varL; // linked list of all variables on this instance
|
|
|
|
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
|
|
|
|
struct network_str* internal_net;
|
|
|
|
} proc_t;
|
|
|
|
|
|
// preset_value_t holds a preset value and the proc/var to which it will be applied.
|
|
typedef struct preset_value_str
|
|
{
|
|
proc_t* proc; // proc target for this preset value
|
|
variable_t* var; // var target for this preset value
|
|
value_t value; // Preset value.
|
|
unsigned pairTblIdx; // Index into the preset pair table for this preset value
|
|
struct preset_value_str* link;
|
|
} preset_value_t;
|
|
|
|
typedef struct preset_value_list_str
|
|
{
|
|
preset_value_t* value_head; // List of preset_value_t for this preset.
|
|
preset_value_t* value_tail; // Last preset value in the list.
|
|
} preset_value_list_t;
|
|
|
|
struct network_preset_str;
|
|
|
|
typedef struct dual_preset_str
|
|
{
|
|
const struct network_preset_str* pri;
|
|
const struct network_preset_str* sec;
|
|
double coeff;
|
|
} dual_preset_t;
|
|
|
|
typedef enum {
|
|
kPresetVListTId,
|
|
kPresetDualTId
|
|
} preset_type_id_t;
|
|
|
|
typedef struct network_preset_str
|
|
{
|
|
const char* label; // Preset label
|
|
preset_type_id_t tid;
|
|
|
|
union {
|
|
preset_value_list_t vlist;
|
|
dual_preset_t dual;
|
|
} u;
|
|
} network_preset_t;
|
|
|
|
// Preset-pair record used to apply dual presets.
|
|
typedef struct network_preset_pair_str
|
|
{
|
|
const proc_t* proc; //
|
|
const variable_t* var; //
|
|
unsigned chIdx; //
|
|
unsigned chN; //
|
|
const value_t* value; //
|
|
} network_preset_pair_t;
|
|
|
|
typedef struct net_global_var_str
|
|
{
|
|
const char* class_label;
|
|
char* var_label;
|
|
void* blob;
|
|
unsigned blobByteN;
|
|
|
|
struct net_global_var_str* link;
|
|
|
|
} net_global_var_t;
|
|
|
|
typedef struct network_str
|
|
{
|
|
const object_t* procsCfg; // network proc list
|
|
const object_t* presetsCfg; // presets designed for this network
|
|
|
|
struct proc_str** procA;
|
|
unsigned procN;
|
|
|
|
network_preset_t* presetA;
|
|
unsigned presetN;
|
|
|
|
// Preset pair table used by network_apply_dual_preset()
|
|
network_preset_pair_t* preset_pairA;
|
|
unsigned preset_pairN;
|
|
|
|
net_global_var_t* globalVarL;
|
|
|
|
struct network_str* poly_link;
|
|
unsigned poly_idx;
|
|
|
|
ui_net_t* ui_net;
|
|
|
|
} network_t;
|
|
|
|
|
|
typedef struct flow_str
|
|
{
|
|
const object_t* pgmCfg; // complete program cfg
|
|
const object_t* networkCfg; // 'network' cfg from pgmCfg
|
|
|
|
bool printNetworkFl;
|
|
bool non_real_time_fl; // set if this is a non-real-time program
|
|
unsigned framesPerCycle; // sample frames per cycle (64)
|
|
srate_t sample_rate; // default sample rate (48000.0)
|
|
unsigned maxCycleCount; // count of cycles to run on flow::exec() or 0 if there is no limit.
|
|
const char* init_net_preset_label;// network initialization preset label or nullptr if there is no net. init. preset
|
|
|
|
bool isInRuntimeFl; // Set when compile-time is complete
|
|
|
|
unsigned cycleIndex; // Incremented with each processing cycle
|
|
|
|
bool printLogHdrFl;
|
|
|
|
bool multiPriPresetProbFl; // If set then probability is used to choose presets on multi-preset application
|
|
bool multiSecPresetProbFl; //
|
|
bool multiPresetInterpFl; // If set then interpolation is applied between two selectedd presets on multi-preset application
|
|
|
|
class_desc_t* classDescA; //
|
|
unsigned classDescN; //
|
|
|
|
class_desc_t* udpDescA; //
|
|
unsigned udpDescN; //
|
|
|
|
external_device_t* deviceA; // deviceA[ deviceN ] external device description array
|
|
unsigned deviceN; //
|
|
|
|
const char* proj_dir; // default input/output directory
|
|
|
|
// Top-level preset list.
|
|
network_preset_t* presetA; // presetA[presetN] partial (label and tid only) parsing of the network presets
|
|
unsigned presetN; //
|
|
|
|
network_t* net; // The root of the network instance
|
|
|
|
ui_callback_t ui_callback;
|
|
void* ui_callback_arg;
|
|
|
|
std::atomic<variable_t*> ui_var_head; // Linked lists of var's to send to the UI
|
|
variable_t ui_var_stub;
|
|
variable_t* ui_var_tail;
|
|
|
|
} flow_t;
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Value Only
|
|
//
|
|
|
|
inline void set_null( value_t& v, unsigned tflag ) { v.tflag=tflag; v.u.p=nullptr; }
|
|
inline bool is_numeric( const value_t* v ) { return cwIsFlag(v->tflag,kNumericTFl); }
|
|
inline bool is_matrix( const value_t* v ) { return cwIsFlag(v->tflag,kMtxTFl); }
|
|
|
|
// if all of the src flags are set in the dst flags then the two types are convertable.
|
|
inline bool can_convert( unsigned src_tflag, unsigned dst_tflag ) { return (src_tflag&dst_tflag)==src_tflag; }
|
|
|
|
|
|
abuf_t* abuf_create( srate_t srate, unsigned chN, unsigned frameN );
|
|
void abuf_destroy( abuf_t*& buf );
|
|
|
|
// If 'dst' is null then a new abuf is allocated, filled with the contents of 'src'.
|
|
// If 'dst' is non-null and there is enough space for the contents of 'src' then only a copy is executed.
|
|
// If there is not enough space then dst is reallocated.
|
|
abuf_t* abuf_duplicate( abuf_t* dst, 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, const unsigned* maxBinN_V, const unsigned* binN_V, const unsigned* hopSmpN_V, const fd_sample_t** magV=nullptr, const fd_sample_t** phsV=nullptr, const fd_sample_t** hzV=nullptr );
|
|
fbuf_t* fbuf_create( srate_t srate, unsigned chN, unsigned maxBinN, unsigned binN, unsigned hopSmpN, const fd_sample_t** magV=nullptr, const fd_sample_t** phsV=nullptr, const fd_sample_t** hzV=nullptr );
|
|
void fbuf_destroy( fbuf_t*& buf );
|
|
|
|
// Memory allocation will only occur if dst is null, or the size of dst's internal buffer are too small.
|
|
fbuf_t* fbuf_duplicate( fbuf_t* dst, const fbuf_t* src );
|
|
|
|
mbuf_t* mbuf_create( const midi::ch_msg_t* msgA=nullptr, unsigned msgN=0 );
|
|
void mbuf_destroy( mbuf_t*& buf );
|
|
mbuf_t* mbuf_duplicate( const mbuf_t* src );
|
|
|
|
inline bool value_is_abuf( const value_t* v ) { return v->tflag & kABufTFl; }
|
|
inline bool value_is_fbuf( const value_t* v ) { return v->tflag & kFBufTFl; }
|
|
|
|
unsigned value_type_label_to_flag( const char* type_desc );
|
|
const char* value_type_flag_to_label( unsigned flag );
|
|
|
|
void value_duplicate( value_t& dst, const value_t& src );
|
|
|
|
void value_print( const value_t* value, bool info_fl=false);
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Class and Variable Description
|
|
//
|
|
|
|
var_desc_t* var_desc_create( const char* label, const object_t* value_cfg );
|
|
void var_desc_destroy( var_desc_t* var_desc );
|
|
|
|
unsigned var_desc_attr_label_to_flag( const char* attr_label );
|
|
const char* var_desc_flag_to_attribute( unsigned flag );
|
|
const idLabelPair_t* var_desc_flag_array( unsigned& array_cnt_ref );
|
|
|
|
void class_desc_destroy( class_desc_t* class_desc);
|
|
class_desc_t* class_desc_find( flow_t* p, const char* class_desc_label );
|
|
|
|
var_desc_t* var_desc_find( class_desc_t* cd, const char* var_label );
|
|
const var_desc_t* var_desc_find( const class_desc_t* cd, const char* var_label );
|
|
rc_t var_desc_find( class_desc_t* cd, const char* var_label, var_desc_t*& vdRef );
|
|
|
|
const class_preset_t* class_preset_find( const class_desc_t* cd, const char* preset_label );
|
|
|
|
void class_dict_print( flow_t* p );
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Network
|
|
//
|
|
|
|
// Access a blob stored via network_global_var()
|
|
void* network_global_var( proc_t* proc, const char* var_label );
|
|
|
|
// Copy a named blob into the network global variable space.
|
|
rc_t network_global_var_alloc( proc_t* proc, const char* var_label, const void* blob, unsigned blobByteN );
|
|
|
|
|
|
void network_print(const network_t& net );
|
|
|
|
const network_preset_t* network_preset_from_label( const network_t& net, const char* preset_label );
|
|
|
|
unsigned proc_mult_count( const network_t& net, const char* proc_label );
|
|
|
|
rc_t proc_mult_sfx_id_array( const network_t& net, const char* proc_label, unsigned* idA, unsigned idAllocN, unsigned& idN_ref );
|
|
|
|
unsigned network_poly_count( const network_t& net );
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Proc
|
|
//
|
|
|
|
void proc_destroy( proc_t* proc );
|
|
rc_t proc_validate( proc_t* proc );
|
|
|
|
proc_t* proc_find( network_t& net, const char* proc_label, unsigned sfx_id );
|
|
rc_t proc_find( network_t& net, const char* proc_label, unsigned sfx_id, proc_t*& procPtrRef );
|
|
|
|
external_device_t* external_device_find( flow_t* p, const char* device_label, unsigned typeId, unsigned inOrOutFl, const char* midiPortLabel=nullptr );
|
|
|
|
void proc_print( proc_t* proc );
|
|
|
|
// Count of all var instances on this proc. This is a count of the length of proc->varL.
|
|
unsigned proc_var_count( proc_t* proc );
|
|
|
|
// If fname has a '$' prefix then the system project directory is prepended to it.
|
|
// If fname has a '~' then the users home directory is prepended to it.
|
|
// The returned string must be release with a call to mem::free().
|
|
char* proc_expand_filename( const proc_t* proc, const char* fname );
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Variable
|
|
//
|
|
|
|
// Create a variable but do not assign it a value. Return a pointer to the new variable.
|
|
// Notes:
|
|
// 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( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, const object_t* value_cfg, unsigned altTypeFlag, variable_t*& varRef );
|
|
void var_destroy( variable_t* var );
|
|
|
|
// Channelizing creates a new var record with an explicit channel index to replace the
|
|
// automatically generated variable whose channel index is set to 'kAnyChIdx'.
|
|
rc_t var_channelize( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned chIdx, const object_t* value_cfg, unsigned vid, variable_t*& varRef );
|
|
|
|
// Get the count of channels attached to var_label:sfx_id:kAnyChIdx.
|
|
// Returns 0 if only kAnyChIdx exists,
|
|
// Returns kInvalidCnt if var_label:sfx_id does not exist.
|
|
// Otherwise returns count of channels no including kAnyChIdx. (e.g. mono=1, stereo=2, quad=4 ...)
|
|
unsigned var_channel_count( proc_t* proc, const char* var_label, unsigned sfx_id );
|
|
|
|
// Wrapper around call to var->proc->members->value()
|
|
rc_t var_call_custom_value_func( variable_t* var );
|
|
|
|
// Sets and get the var->flags field
|
|
unsigned var_flags( proc_t* proc, unsigned chIdx, const char* var_label, unsigned sfx_id, unsigned& flags_ref );
|
|
rc_t var_set_flags( proc_t* proc, unsigned chIdx, const char* var_label, unsigned sfx_id, unsigned flags );
|
|
rc_t var_clr_flags( proc_t* proc, unsigned chIdx, const char* var_label, unsigned sfx_id, unsigned flags );
|
|
|
|
// `value_cfg` is optional. Set it to NULL to ignore
|
|
rc_t var_register( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef );
|
|
|
|
// Returns true if this var is connected to a source proc variable
|
|
bool is_connected_to_source( const variable_t* var );
|
|
|
|
// Return true if this var is acting as a source for another var.
|
|
bool is_a_source_var( const variable_t* var );
|
|
|
|
// Connect in_var to src_var.
|
|
void var_connect( variable_t* src_var, variable_t* in_var );
|
|
|
|
// Disconnect an in_var from it's source
|
|
void var_disconnect( variable_t* in_var );
|
|
|
|
|
|
// Get the count of 'mult' vars associated with this var label.
|
|
unsigned var_mult_count( proc_t* proc, const char* var_label );
|
|
|
|
// Get all the label-sfx-id's associated with a give var label
|
|
rc_t var_mult_sfx_id_array( proc_t* proc, const char* var_label, unsigned* idA, unsigned idAllocN, unsigned& idN_ref );
|
|
|
|
// Send a variable value to the UI
|
|
rc_t var_send_to_ui( variable_t* var );
|
|
rc_t var_send_to_ui( proc_t* proc, unsigned vid, unsigned chIdx );
|
|
|
|
//-----------------
|
|
//
|
|
// var_register
|
|
//
|
|
|
|
inline rc_t _var_reg(cw::flow::proc_t*, unsigned int ) { return kOkRC; }
|
|
|
|
template< typename T0, typename T1, typename... ARGS >
|
|
rc_t _var_reg( proc_t* proc, unsigned chIdx, T0 vid, T1 var_label, unsigned sfx_id, ARGS&&... args )
|
|
{
|
|
rc_t rc;
|
|
variable_t* dummy = nullptr;
|
|
if((rc = var_register( proc, var_label, sfx_id, vid, chIdx, nullptr, dummy )) == kOkRC )
|
|
if((rc = _var_reg( proc, 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( proc_t* proc, unsigned chIdx, unsigned vid, const char* var_label, unsigned sfx_id, ARGS&&... args )
|
|
{ return _var_reg( proc, chIdx, vid, var_label, sfx_id, std::forward<ARGS>(args)...); }
|
|
|
|
|
|
|
|
//---------------------
|
|
//
|
|
// var_register_and_get
|
|
//
|
|
|
|
inline rc_t _var_register_and_get(cw::flow::proc_t*, unsigned int ) { return kOkRC; }
|
|
|
|
template< typename T>
|
|
rc_t var_register_and_get( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, T& valRef )
|
|
{
|
|
rc_t rc;
|
|
variable_t* var;
|
|
if((rc = var_register(proc,var_label,sfx_id,vid,chIdx,nullptr,var)) == kOkRC )
|
|
rc = var_get(var,valRef);
|
|
return rc;
|
|
}
|
|
|
|
|
|
inline rc_t _var_reg_and_get(cw::flow::proc_t*, unsigned int ) { return kOkRC; }
|
|
|
|
template< typename T0, typename T1, typename T2, typename... ARGS >
|
|
rc_t _var_reg_and_get( proc_t* proc, unsigned chIdx, T0 vid, T1 var_label, unsigned sfx_id, T2& valRef, ARGS&&... args )
|
|
{
|
|
rc_t rc;
|
|
|
|
if((rc = var_register_and_get( proc, var_label, sfx_id, vid, chIdx, valRef )) == kOkRC )
|
|
if((rc = _var_reg_and_get( proc, 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( proc_t* proc, unsigned chIdx, unsigned vid, const char* var_label, unsigned sfx_id, ARGS&&... args )
|
|
{ return _var_reg_and_get( proc, chIdx, vid, var_label, sfx_id, 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( proc_t* proc, const char* label, unsigned sfx_id, unsigned vid, unsigned chIdx, variable_t*& varRef );
|
|
|
|
rc_t var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned frameN );
|
|
rc_t var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, midi::ch_msg_t* midiA, unsigned midiN );
|
|
rc_t var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, const unsigned* maxBinN_V, const unsigned* binN_V, const unsigned* hopSmpN_V, const fd_sample_t** magV=nullptr, const fd_sample_t** phsV=nullptr, const fd_sample_t** hzV=nullptr );
|
|
rc_t var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned maxBinN, unsigned binN, unsigned hopSmpN, const fd_sample_t** magV=nullptr, const fd_sample_t** phsV=nullptr, const fd_sample_t** hzV=nullptr );
|
|
|
|
inline rc_t _var_register_and_set(cw::flow::proc_t*, unsigned int ) { return kOkRC; }
|
|
|
|
template< typename T0, typename T1, typename T2, typename... ARGS >
|
|
rc_t _var_register_and_set( proc_t* proc, unsigned chIdx, T0 vid, T1 var_label, unsigned sfx_id, T2 val, ARGS&&... args )
|
|
{
|
|
rc_t rc;
|
|
|
|
variable_t* var = nullptr;
|
|
if((rc = var_register_and_set( proc, var_label, sfx_id, vid, chIdx, var)) == kOkRC )
|
|
{
|
|
if((rc = var_set( proc, vid, chIdx, val )) != kOkRC )
|
|
return rc;
|
|
|
|
if((rc = _var_register_and_set( proc, 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( proc_t* proc, unsigned chIdx, unsigned vid, const char* var_label, unsigned sfx_id, ARGS&&... args )
|
|
{ return _var_register_and_set( proc, chIdx, vid, var_label, sfx_id, std::forward<ARGS>(args)...); }
|
|
|
|
|
|
|
|
void _var_destroy( variable_t* var );
|
|
|
|
bool var_exists( proc_t* proc, const char* label, unsigned sfx_id, unsigned chIdx );
|
|
bool var_has_value( proc_t* proc, const char* label, unsigned sfx_id, unsigned chIdx );
|
|
bool var_is_a_source( proc_t* proc, const char* label, unsigned sfx_id, unsigned chIdx );
|
|
bool var_is_a_source( proc_t* proc, unsigned vid, unsigned chIdx );
|
|
|
|
rc_t var_find( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned chIdx, const variable_t*& varRef );
|
|
rc_t var_find( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned chIdx, variable_t*& varRef );
|
|
rc_t var_find( proc_t* proc, unsigned vid, unsigned chIdx, variable_t*& varRef );
|
|
|
|
|
|
// Count of numbered channels - does not count the kAnyChIdx variable instance.
|
|
rc_t var_channel_count( proc_t* proc, const char* label, unsigned sfx_idx, unsigned& chCntRef );
|
|
rc_t var_channel_count( const variable_t* var, unsigned& chCntRef );
|
|
|
|
rc_t cfg_to_value( const object_t* cfg, value_t& value_ref );
|
|
|
|
|
|
//
|
|
// var_get() coerces the value of the variable to the type of the returned value.
|
|
//
|
|
|
|
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 );
|
|
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( const variable_t* var, const object_t*& valRef );
|
|
|
|
template< typename T>
|
|
rc_t var_get( proc_t* proc, unsigned vid, unsigned chIdx, T& valRef)
|
|
{
|
|
rc_t rc = kOkRC;
|
|
variable_t* var = nullptr;
|
|
|
|
if((rc = var_find(proc, vid, chIdx, var )) == kOkRC )
|
|
rc = var_get(var,valRef);
|
|
|
|
return rc;
|
|
}
|
|
|
|
template< typename T >
|
|
T val_get( proc_t* proc, unsigned vid, unsigned chIdx )
|
|
{
|
|
T value;
|
|
var_get(proc,vid,chIdx,value);
|
|
return value;
|
|
}
|
|
|
|
//
|
|
// var_set() coerces the incoming value to the type of the variable (var->type)
|
|
//
|
|
|
|
rc_t var_set_from_cfg( variable_t* var, const object_t* cfg_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( proc_t* proc, unsigned vid, unsigned chIdx, const value_t* val );
|
|
rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, bool val );
|
|
rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, uint_t val );
|
|
rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, int_t val );
|
|
rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, float val );
|
|
rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, double val );
|
|
rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, const char* val );
|
|
rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, abuf_t* val );
|
|
rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, fbuf_t* val );
|
|
rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, mbuf_t* val );
|
|
rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, const object_t* val );
|
|
|
|
|
|
}
|
|
}
|