7c645d6af9
1. cw::flow::value_t moved from cwFlowTypes.h/cpp to cwFlowValue.h/cpp. 2. Added new flow value type cw::flow::recd_t and related functions and types.
334 lines
12 KiB
C++
334 lines
12 KiB
C++
#ifndef cwFlowValue_h
|
|
#define cwFLowValue_h
|
|
|
|
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,
|
|
kRBufTFl = 0x00002000,
|
|
kStringTFl = 0x00004000,
|
|
kTimeTFl = 0x00008000,
|
|
kCfgTFl = 0x00010000,
|
|
kMidiTFl = 0x00020000,
|
|
|
|
kTypeMask = 0x0003ffff,
|
|
|
|
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 recd_field_str
|
|
{
|
|
bool group_fl; // set if this field record is a group
|
|
char* label; // field or group label
|
|
union
|
|
{
|
|
unsigned index; // index into recd_t.valA of the value associated with this field
|
|
struct recd_field_str* group_fieldL;
|
|
} u;
|
|
|
|
struct recd_field_str* link;
|
|
} recd_field_t;
|
|
|
|
typedef struct recd_type_str
|
|
{
|
|
recd_field_t* fieldL; // linked list of field spec's
|
|
unsigned fieldN; // length of fieldL list (fieldN + base->fieldN) is total field count
|
|
const struct recd_type_str* base;
|
|
} recd_type_t;
|
|
|
|
struct value_str;
|
|
typedef struct recd_str
|
|
{
|
|
struct value_str* valA; // varA[ fieldN ] array of field values
|
|
const struct recd_str* base; // base record fields
|
|
} recd_t;
|
|
|
|
typedef struct rbuf_str
|
|
{
|
|
const recd_type_t* type; // all msgs are formed from this type
|
|
const recd_t* recdA; // recdA[ recdN ]
|
|
unsigned recdN; //
|
|
} rbuf_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;
|
|
rbuf_t* rbuf;
|
|
|
|
char* s;
|
|
|
|
const object_t* cfg;
|
|
midi::ch_msg_t* midi;
|
|
void* p;
|
|
|
|
|
|
} u;
|
|
|
|
struct value_str* link;
|
|
|
|
} value_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 );
|
|
|
|
rbuf_t* rbuf_create( const recd_type_t* type=nullptr, const recd_t* recdA=nullptr, unsigned recdN=0 );
|
|
void rbuf_destroy( rbuf_t*& buf );
|
|
rbuf_t* rbuf_duplicate( const rbuf_t* src );
|
|
void rbuf_setup( rbuf_t* rbuf, recd_type_t* type, recd_t* recdA, unsigned recdN );
|
|
|
|
|
|
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_release( value_t* v );
|
|
void value_duplicate( value_t& dst, const value_t& src );
|
|
|
|
void value_print( const value_t* value, bool info_fl=false);
|
|
|
|
rc_t value_get( const value_t* val, bool& valRef );
|
|
rc_t value_set( value_t* val, bool v );
|
|
|
|
rc_t value_get( const value_t* val, uint_t& valRef );
|
|
rc_t value_set( value_t* val, uint_t v );
|
|
|
|
rc_t value_get( const value_t* val, int_t& valRef );
|
|
rc_t value_set( value_t* val, int_t v );
|
|
|
|
rc_t value_get( const value_t* val, float& valRef );
|
|
rc_t value_set( value_t* val, float v );
|
|
|
|
rc_t value_get( const value_t* val, double& valRef );
|
|
rc_t value_set( value_t* val, double v );
|
|
|
|
rc_t value_get( const value_t* val, const char*& valRef );
|
|
rc_t value_set( value_t* val, const char* v );
|
|
|
|
rc_t value_get( value_t* val, abuf_t*& valRef );
|
|
rc_t value_get( value_t* val, const abuf_t*& valRef );
|
|
rc_t value_set( value_t* val, abuf_t* v );
|
|
|
|
rc_t value_get( value_t* val, fbuf_t*& valRef );
|
|
rc_t value_get( value_t* val, const fbuf_t*& valRef );
|
|
rc_t value_set( value_t* val, fbuf_t* v );
|
|
|
|
rc_t value_get( value_t* val, mbuf_t*& valRef );
|
|
rc_t value_get( value_t* val, const mbuf_t*& valRef );
|
|
rc_t value_set( value_t* val, mbuf_t* v );
|
|
|
|
rc_t value_get( value_t* val, rbuf_t*& valRef );
|
|
rc_t value_get( value_t* val, const rbuf_t*& valRef );
|
|
rc_t value_set( value_t* val, rbuf_t* v );
|
|
|
|
rc_t value_get( value_t* val, const object_t*& valRef );
|
|
rc_t value_set( value_t* val, const object_t* v );
|
|
|
|
rc_t value_get( const value_t* val, midi::ch_msg_t*& valRef );
|
|
rc_t value_set( value_t* val, midi::ch_msg_t* v );
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Record
|
|
//
|
|
|
|
|
|
typedef struct recd_array_str
|
|
{
|
|
recd_type_t* type;
|
|
value_t* valA; // valA[ allocRecdN * type->fieldN ]
|
|
recd_t* recdA;
|
|
unsigned allocRecdN;
|
|
} recd_array_t;
|
|
|
|
rc_t recd_type_create( recd_type_t*& recd_type_ref, const recd_type_t* base_type, const char* fields_string=nullptr );
|
|
void recd_type_destroy( recd_type_t*& recd_type );
|
|
|
|
rc_t recd_type_add_value_fields( recd_type_t* recd_type, const char* field_labels );
|
|
rc_t recd_type_add_group( recd_type_t* recd_type, const char* group_label, const char* field_labels );
|
|
|
|
// Count of fields combined local and base record types.
|
|
rc_t recd_type_max_field_count( const recd_type_t* recd_type );
|
|
|
|
// use '.' notation to separate groups from fields.
|
|
// Note if this is a 'local' field then the high bit in the returned index will be set.
|
|
unsigned recd_type_field_index( const recd_type_t* recd_type, const char* field_label);
|
|
|
|
void recd_type_print( const recd_type_t* recd_type );
|
|
|
|
template< typename T >
|
|
rc_t recd_get( const recd_type_t* type, const recd_t* recd, unsigned field_idx, T& val_ref )
|
|
{
|
|
if( field_idx < type->fieldN )
|
|
return value_get( recd->valA + field_idx, val_ref );
|
|
|
|
return recd_get( type->base, recd->base, field_idx - type->fieldN, val_ref );
|
|
}
|
|
|
|
inline rc_t recd_set_base( const recd_type_t* type, recd_t* recd, const recd_t* base )
|
|
{
|
|
// if we are setting base then the type must have a base type
|
|
assert( (type->base == nullptr && base==nullptr) || (type->base!=nullptr && base!=nullptr) );
|
|
|
|
recd->base = base;
|
|
return kOkRC;
|
|
}
|
|
|
|
template< typename T >
|
|
rc_t recd_set( const recd_type_t* type, const recd_t* base, recd_t* recd, unsigned field_idx, const T& val )
|
|
{
|
|
if( field_idx >= type->fieldN )
|
|
return cwLogError(kInvalidArgRC,"Only 'local' record value may be set.");
|
|
|
|
// set the base of this record
|
|
recd_set_base(type,recd,base);
|
|
|
|
return value_set( recd->valA + field_idx, val );
|
|
}
|
|
|
|
rc_t recd_print( const recd_type_t* recd_type, const recd_t* r );
|
|
|
|
rc_t recd_array_create( recd_array_t*& recd_array_ref, recd_type_t* recd_type, unsigned allocRecdN );
|
|
rc_t recd_array_destroy( recd_array_t*& recd_array_ref );
|
|
|
|
rc_t value_test( const test::test_args_t& args );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|