2024-12-01 19:35:24 +00:00
//| Copyright: (C) 2020-2024 Kevin Larke <contact AT larke DOT org>
//| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
2021-08-15 20:07:12 +00:00
# include "cwCommon.h"
# include "cwLog.h"
# include "cwCommonImpl.h"
2024-05-29 16:36:57 +00:00
# include "cwTest.h"
2021-08-15 20:07:12 +00:00
# include "cwMem.h"
2024-04-30 23:58:10 +00:00
# include "cwMath.h"
2021-08-15 20:07:12 +00:00
# include "cwText.h"
# include "cwObject.h"
2024-05-10 02:03:08 +00:00
# include "cwFileSys.h"
2021-08-15 20:07:12 +00:00
# include "cwVectOps.h"
# include "cwMtx.h"
2021-08-23 02:41:33 +00:00
# include "cwDspTypes.h" // real_t, sample_t
2024-04-06 20:07:46 +00:00
# include "cwTime.h"
# include "cwMidiDecls.h"
2024-01-13 15:18:21 +00:00
# include "cwFlowDecl.h"
2021-12-11 20:17:11 +00:00
# include "cwFlow.h"
2021-08-15 20:07:12 +00:00
# include "cwFlowTypes.h"
namespace cw
{
namespace flow
{
2024-05-06 19:44:53 +00:00
idLabelPair_t _varDescAttrFlagsA [ ] =
{
{ kSrcVarDescFl , " src " } ,
{ kSrcOptVarDescFl , " src_opt " } ,
{ kNoSrcVarDescFl , " no_src " } ,
{ kInitVarDescFl , " init " } ,
{ kMultVarDescFl , " mult " } ,
2024-09-16 17:43:52 +00:00
{ kUdpOutVarDescFl , " out " } ,
2024-05-06 19:44:53 +00:00
{ kInvalidVarDescFl , " <invalid> " }
} ;
idLabelPair_t _typeLabelFlagsA [ ] = {
2021-08-15 20:07:12 +00:00
2024-04-06 20:07:46 +00:00
{ kBoolTFl , " bool " } ,
{ kUIntTFl , " uint " } ,
{ kIntTFl , " int " , } ,
{ kFloatTFl , " float " } ,
{ kDoubleTFl , " double " } ,
2021-08-15 20:07:12 +00:00
2024-04-06 20:07:46 +00:00
{ kBoolMtxTFl , " bool_mtx " } ,
{ kUIntMtxTFl , " uint_mtx " } ,
{ kIntMtxTFl , " int_mtx " } ,
{ kFloatMtxTFl , " float_mtx " } ,
{ kDoubleMtxTFl , " double_mtx " } ,
2021-08-15 20:07:12 +00:00
{ kABufTFl , " audio " } ,
{ kFBufTFl , " spectrum " } ,
2024-04-06 20:07:46 +00:00
{ kMBufTFl , " midi " } ,
2021-08-15 20:07:12 +00:00
{ kStringTFl , " string " } ,
{ kTimeTFl , " time " } ,
2024-04-26 21:04:03 +00:00
{ kCfgTFl , " cfg " } ,
// alias types to map to cwDspTypes.h
{ kFloatTFl , " srate " } ,
{ kFloatTFl , " sample " } ,
{ kFloatTFl , " coeff " } ,
{ kDoubleTFl , " ftime " } ,
2024-05-03 13:16:37 +00:00
{ kNumericTFl , " numeric " } ,
{ kAllTFl , " all " } ,
2024-04-30 23:58:10 +00:00
{ kRuntimeTFl , " runtime " } ,
2024-05-06 19:44:53 +00:00
{ kInvalidTFl , " <invalid> " }
2021-08-15 20:07:12 +00:00
} ;
const char * _typeFlagToLabel ( unsigned flag )
{
2024-05-06 19:44:53 +00:00
return idToLabel ( _typeLabelFlagsA , flag , kInvalidTFl ) ;
2021-08-15 20:07:12 +00:00
}
void _value_release ( value_t * v )
{
if ( v = = nullptr )
return ;
2024-04-30 23:58:10 +00:00
switch ( v - > tflag & kTypeMask )
2021-08-15 20:07:12 +00:00
{
case kInvalidTFl :
break ;
case kBoolTFl :
case kUIntTFl :
case kIntTFl :
2021-08-23 02:41:33 +00:00
case kFloatTFl :
case kDoubleTFl :
2021-08-15 20:07:12 +00:00
break ;
case kABufTFl :
abuf_destroy ( v - > u . abuf ) ;
break ;
case kFBufTFl :
fbuf_destroy ( v - > u . fbuf ) ;
break ;
2024-04-06 20:07:46 +00:00
case kMBufTFl :
mbuf_destroy ( v - > u . mbuf ) ;
break ;
2021-08-15 20:07:12 +00:00
case kBoolMtxTFl :
case kUIntMtxTFl :
case kIntMtxTFl :
2021-08-23 02:41:33 +00:00
case kFloatMtxTFl :
case kDoubleMtxTFl :
2021-08-15 20:07:12 +00:00
assert ( 0 ) ; // not implemeneted
break ;
case kStringTFl :
mem : : release ( v - > u . s ) ;
break ;
2024-04-30 23:58:10 +00:00
2021-08-23 02:41:33 +00:00
case kTimeTFl :
assert ( 0 ) ;
break ;
2024-04-30 23:58:10 +00:00
case kCfgTFl :
break ;
2021-08-23 02:41:33 +00:00
default :
assert ( 0 ) ;
break ;
}
2024-04-30 23:58:10 +00:00
v - > tflag = kInvalidTFl ;
2021-08-23 02:41:33 +00:00
}
void _value_duplicate ( value_t & dst , const value_t & src )
2024-04-06 20:07:46 +00:00
{
2024-04-30 23:58:10 +00:00
switch ( src . tflag & kTypeMask )
2021-08-23 02:41:33 +00:00
{
case kInvalidTFl :
break ;
case kBoolTFl :
case kUIntTFl :
case kIntTFl :
case kFloatTFl :
case kDoubleTFl :
dst = src ;
break ;
case kABufTFl :
2021-08-15 20:07:12 +00:00
2024-06-04 12:45:05 +00:00
dst . u . abuf = src . u . abuf = = nullptr ? nullptr : abuf_duplicate ( dst . u . abuf , src . u . abuf ) ;
2024-04-30 23:58:10 +00:00
dst . tflag = src . tflag ;
2021-08-23 02:41:33 +00:00
break ;
case kFBufTFl :
2024-06-04 12:45:05 +00:00
dst . u . fbuf = src . u . fbuf = = nullptr ? nullptr : fbuf_duplicate ( dst . u . fbuf , src . u . fbuf ) ;
2024-04-30 23:58:10 +00:00
dst . tflag = src . tflag ;
2021-08-23 02:41:33 +00:00
break ;
2024-04-06 20:07:46 +00:00
case kMBufTFl :
dst . u . mbuf = src . u . mbuf = = nullptr ? nullptr : mbuf_duplicate ( src . u . mbuf ) ;
2024-04-30 23:58:10 +00:00
dst . tflag = src . tflag ;
2024-04-06 20:07:46 +00:00
break ;
2021-08-23 02:41:33 +00:00
case kBoolMtxTFl :
case kUIntMtxTFl :
case kIntMtxTFl :
case kFloatMtxTFl :
case kDoubleMtxTFl :
assert ( 0 ) ; // not implemeneted
2021-08-15 20:07:12 +00:00
break ;
2021-08-23 02:41:33 +00:00
case kStringTFl :
dst . u . s = mem : : duplStr ( dst . u . s ) ;
2024-04-30 23:58:10 +00:00
dst . tflag = src . tflag ;
2021-08-23 02:41:33 +00:00
break ;
2021-08-15 20:07:12 +00:00
case kTimeTFl :
assert ( 0 ) ;
break ;
2024-04-30 23:58:10 +00:00
case kCfgTFl :
dst = src ;
break ;
2021-08-15 20:07:12 +00:00
default :
assert ( 0 ) ;
break ;
}
}
2021-08-23 02:41:33 +00:00
2024-05-24 20:41:42 +00:00
void _value_print ( const value_t * v , bool info_fl = true )
2021-08-15 20:07:12 +00:00
{
if ( v = = nullptr )
return ;
2024-04-30 23:58:10 +00:00
switch ( v - > tflag & kTypeMask )
2021-08-15 20:07:12 +00:00
{
case kInvalidTFl :
2024-07-03 18:27:50 +00:00
cwLogPrint ( " <invalid> " ) ;
2021-08-15 20:07:12 +00:00
break ;
2024-05-24 20:41:42 +00:00
case kBoolTFl :
cwLogPrint ( " %s%s " , info_fl ? " b: " : " " , v - > u . b ? " true " : " false " ) ;
break ;
case kUIntTFl :
cwLogPrint ( " %s%i " , info_fl ? " u: " : " " , v - > u . u ) ;
break ;
case kIntTFl :
cwLogPrint ( " %s%i " , info_fl ? " i: " : " " , v - > u . i ) ;
break ;
case kFloatTFl :
cwLogPrint ( " %s%f " , info_fl ? " f: " : " " , v - > u . f ) ;
break ;
case kDoubleTFl :
cwLogPrint ( " %s%f " , info_fl ? " d: " : " " , v - > u . d ) ;
break ;
2021-08-23 02:41:33 +00:00
case kABufTFl :
2024-05-24 20:41:42 +00:00
if ( info_fl )
{
if ( v - > u . abuf = = nullptr )
cwLogPrint ( " abuf: <null> " ) ;
else
cwLogPrint ( " abuf: chN:%i frameN:%i srate:%8.1f " , v - > u . abuf - > chN , v - > u . abuf - > frameN , v - > u . abuf - > srate ) ;
}
2021-08-23 02:41:33 +00:00
else
2024-05-24 20:41:42 +00:00
{
bool null_fl = v - > u . abuf = = nullptr | | v - > u . abuf - > buf = = nullptr ;
cwLogPrint ( " ( " ) ;
for ( unsigned i = 0 ; i < v - > u . abuf - > chN ; + + i )
cwLogPrint ( " %f " , null_fl ? 0.0 : vop : : rms ( v - > u . abuf - > buf + i * v - > u . abuf - > frameN , v - > u . abuf - > frameN ) ) ;
cwLogPrint ( " ) " ) ;
}
2021-08-23 02:41:33 +00:00
break ;
case kFBufTFl :
2024-05-24 20:41:42 +00:00
if ( info_fl )
{
if ( v - > u . fbuf = = nullptr )
cwLogPrint ( " fbuf: <null> " ) ;
else
{
cwLogPrint ( " fbuf: chN:%i srate:%8.1f " , v - > u . fbuf - > chN , v - > u . fbuf - > srate ) ;
for ( unsigned i = 0 ; i < v - > u . fbuf - > chN ; + + i )
cwLogPrint ( " (binN:%i hopSmpN:%i) " , v - > u . fbuf - > binN_V [ i ] , v - > u . fbuf - > hopSmpN_V [ i ] ) ;
}
}
2021-08-23 02:41:33 +00:00
else
2022-11-11 18:51:06 +00:00
{
2024-05-24 20:41:42 +00:00
bool null_fl = v - > u . fbuf = = nullptr | | v - > u . fbuf - > magV = = nullptr ;
cwLogPrint ( " ( " ) ;
2022-12-22 20:25:54 +00:00
for ( unsigned i = 0 ; i < v - > u . fbuf - > chN ; + + i )
2024-05-24 20:41:42 +00:00
cwLogPrint ( " %f " , null_fl ? 0.0 : vop : : mean ( v - > u . fbuf - > magV [ i ] , v - > u . fbuf - > binN_V [ i ] ) ) ;
cwLogPrint ( " ) " ) ;
2022-11-11 18:51:06 +00:00
}
2021-08-23 02:41:33 +00:00
break ;
2024-04-06 20:07:46 +00:00
case kMBufTFl :
2024-05-24 20:41:42 +00:00
if ( info_fl )
{
if ( v - > u . mbuf = = nullptr )
cwLogPrint ( " mbuf: <null> " ) ;
else
{
cwLogPrint ( " mbuf: cnt: %i " , v - > u . mbuf - > msgN ) ;
}
}
2024-04-06 20:07:46 +00:00
else
{
2024-05-29 18:06:54 +00:00
//bool null_fl = v->u.mbuf==nullptr || v->u.mbuf->msgA == nullptr;
2024-05-24 20:41:42 +00:00
for ( unsigned i = 0 ; i < v - > u . mbuf - > msgN ; + + i )
cwLogPrint ( " (0x%x 0x%x 0x%x) " , v - > u . mbuf - > msgA [ i ] . status + v - > u . mbuf - > msgA [ i ] . ch , v - > u . mbuf - > msgA [ i ] . d0 , v - > u . mbuf - > msgA [ i ] . d1 ) ;
2022-11-11 18:51:06 +00:00
}
2021-08-23 02:41:33 +00:00
break ;
2021-08-15 20:07:12 +00:00
case kBoolMtxTFl :
case kUIntMtxTFl :
case kIntMtxTFl :
2021-08-23 02:41:33 +00:00
case kFloatMtxTFl :
case kDoubleMtxTFl :
2021-08-15 20:07:12 +00:00
assert ( 0 ) ; // not implemeneted
break ;
2021-08-23 02:41:33 +00:00
case kStringTFl :
2024-09-12 21:18:42 +00:00
cwLogPrint ( " s:%s " , v - > u . s ) ;
2021-08-23 02:41:33 +00:00
break ;
2021-08-15 20:07:12 +00:00
case kTimeTFl :
assert ( 0 ) ;
break ;
2024-04-30 23:58:10 +00:00
case kCfgTFl :
2024-09-12 21:18:42 +00:00
cwLogPrint ( " c: " ) ;
2024-04-30 23:58:10 +00:00
if ( v - > u . cfg ! = nullptr )
v - > u . cfg - > print ( ) ;
break ;
2021-08-15 20:07:12 +00:00
default :
assert ( 0 ) ;
break ;
}
}
2024-05-24 20:41:42 +00:00
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
rc_t _val_get ( const value_t * val , bool & valRef )
{
rc_t rc = kOkRC ;
2024-04-30 23:58:10 +00:00
switch ( val - > tflag & kTypeMask )
2021-08-23 02:41:33 +00:00
{
case kBoolTFl : valRef = val - > u . b ; break ;
case kUIntTFl : valRef = val - > u . u ! = 0 ; break ;
case kIntTFl : valRef = val - > u . i ! = 0 ; break ;
case kFloatTFl : valRef = val - > u . f ! = 0 ; break ;
2024-04-30 23:58:10 +00:00
case kDoubleTFl : valRef = val - > u . d ! = 0 ; break ;
default :
rc = cwLogError ( kTypeMismatchRC , " The type %s (0x%x) could not be converted to a bool. " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
}
return rc ;
}
rc_t _val_set ( value_t * val , bool v )
{
rc_t rc = kOkRC ;
switch ( val - > tflag & kTypeMask )
{
case kBoolTFl : val - > u . b = v ; break ;
case kUIntTFl : val - > u . u = v ; break ;
case kIntTFl : val - > u . i = v ; break ;
case kFloatTFl : val - > u . f = v ; break ;
case kDoubleTFl : val - > u . d = v ; break ;
case kInvalidTFl :
val - > u . b = v ;
val - > tflag = kBoolTFl ;
break ;
2021-08-23 02:41:33 +00:00
default :
2024-04-30 23:58:10 +00:00
rc = cwLogError ( kTypeMismatchRC , " A bool could not be converted to a %s (0x%x). " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
2021-08-23 02:41:33 +00:00
}
2024-04-30 23:58:10 +00:00
2021-08-23 02:41:33 +00:00
return rc ;
}
rc_t _val_get ( const value_t * val , uint_t & valRef )
{
rc_t rc = kOkRC ;
2024-04-30 23:58:10 +00:00
switch ( val - > tflag & kTypeMask )
2021-08-23 02:41:33 +00:00
{
case kBoolTFl : valRef = val - > u . b ? 1 : 0 ; break ;
case kUIntTFl : valRef = val - > u . u ; break ;
case kIntTFl : valRef = val - > u . i ; break ;
case kFloatTFl : valRef = ( uint_t ) val - > u . f ; break ;
case kDoubleTFl : valRef = ( uint_t ) val - > u . d ; break ;
default :
2024-04-30 23:58:10 +00:00
rc = cwLogError ( kTypeMismatchRC , " The type %s (0x%x) could not be converted to a uint. " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
2021-08-23 02:41:33 +00:00
}
return rc ;
}
2024-04-30 23:58:10 +00:00
rc_t _val_set ( value_t * val , uint_t v )
{
rc_t rc = kOkRC ;
2021-08-23 02:41:33 +00:00
2024-04-30 23:58:10 +00:00
switch ( val - > tflag & kTypeMask )
{
case kBoolTFl : val - > u . b = v ! = 0 ; break ;
case kUIntTFl : val - > u . u = v ; break ;
case kIntTFl : val - > u . i = v ; break ;
case kFloatTFl : val - > u . f = v ; break ;
case kDoubleTFl : val - > u . d = v ; break ;
case kInvalidTFl :
val - > u . u = v ;
val - > tflag = kUIntTFl ;
break ;
default :
rc = cwLogError ( kTypeMismatchRC , " A uint could not be converted to a %s (0x%x). " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
}
return rc ;
}
2021-08-23 02:41:33 +00:00
rc_t _val_get ( const value_t * val , int_t & valRef )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
rc_t rc = kOkRC ;
2024-04-30 23:58:10 +00:00
switch ( val - > tflag & kTypeMask )
2021-08-23 02:41:33 +00:00
{
case kBoolTFl : valRef = val - > u . b ? 1 : 0 ; break ;
case kUIntTFl : valRef = ( int_t ) val - > u . u ; break ;
case kIntTFl : valRef = val - > u . i ; break ;
case kFloatTFl : valRef = ( int_t ) val - > u . f ; break ;
case kDoubleTFl : valRef = ( int_t ) val - > u . d ; break ;
default :
2024-04-30 23:58:10 +00:00
rc = cwLogError ( kTypeMismatchRC , " The type %s (0x%x) could not be converted to an int. " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
2021-08-23 02:41:33 +00:00
}
return rc ;
}
2021-08-15 20:07:12 +00:00
2024-04-30 23:58:10 +00:00
rc_t _val_set ( value_t * val , int_t v )
{
rc_t rc = kOkRC ;
switch ( val - > tflag & kTypeMask )
{
case kBoolTFl : val - > u . b = v ! = 0 ; break ;
case kUIntTFl : val - > u . u = v ; break ;
case kIntTFl : val - > u . i = v ; break ;
case kFloatTFl : val - > u . f = v ; break ;
case kDoubleTFl : val - > u . d = v ; break ;
case kInvalidTFl :
val - > u . i = v ;
val - > tflag = kIntTFl ;
break ;
default :
rc = cwLogError ( kTypeMismatchRC , " An int could not be converted to a %s (0x%x). " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
2021-08-23 02:41:33 +00:00
}
2024-04-30 23:58:10 +00:00
2021-08-23 02:41:33 +00:00
return rc ;
}
2024-04-30 23:58:10 +00:00
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
rc_t _val_get ( const value_t * val , float & valRef )
{
rc_t rc = kOkRC ;
2024-04-30 23:58:10 +00:00
switch ( val - > tflag & kTypeMask )
2021-08-23 02:41:33 +00:00
{
case kBoolTFl : valRef = val - > u . b ? 1 : 0 ; break ;
case kUIntTFl : valRef = ( float ) val - > u . u ; break ;
case kIntTFl : valRef = ( float ) val - > u . i ; break ;
case kFloatTFl : valRef = ( float ) val - > u . f ; break ;
case kDoubleTFl : valRef = ( float ) val - > u . d ; break ;
default :
2024-04-30 23:58:10 +00:00
rc = cwLogError ( kTypeMismatchRC , " The type %s (0x%x) could not be converted to a float. " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
2021-08-23 02:41:33 +00:00
}
return rc ;
}
2021-08-15 20:07:12 +00:00
2024-04-30 23:58:10 +00:00
rc_t _val_set ( value_t * val , float v )
{
rc_t rc = kOkRC ;
switch ( val - > tflag & kTypeMask )
{
case kBoolTFl : val - > u . b = v ! = 0 ; break ;
case kUIntTFl : val - > u . u = ( unsigned ) v ; break ;
case kIntTFl : val - > u . i = ( int ) v ; break ;
case kFloatTFl : val - > u . f = v ; break ;
case kDoubleTFl : val - > u . d = v ; break ;
case kInvalidTFl :
val - > u . f = v ;
val - > tflag = kFloatTFl ;
break ;
default :
rc = cwLogError ( kTypeMismatchRC , " A float could not be converted to a %s (0x%x). " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
}
return rc ;
}
2021-08-23 02:41:33 +00:00
rc_t _val_get ( const value_t * val , double & valRef )
{
rc_t rc = kOkRC ;
2024-04-30 23:58:10 +00:00
switch ( val - > tflag & kTypeMask )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
case kBoolTFl : valRef = val - > u . b ? 1 : 0 ; break ;
case kUIntTFl : valRef = ( double ) val - > u . u ; break ;
case kIntTFl : valRef = ( double ) val - > u . i ; break ;
case kFloatTFl : valRef = ( double ) val - > u . f ; break ;
case kDoubleTFl : valRef = val - > u . d ; break ;
default :
2024-04-30 23:58:10 +00:00
rc = cwLogError ( kTypeMismatchRC , " The type %s (0x%x) could not be converted to a double. " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
2021-08-23 02:41:33 +00:00
}
return rc ;
}
2021-08-15 20:07:12 +00:00
2024-04-30 23:58:10 +00:00
rc_t _val_set ( value_t * val , double v )
{
rc_t rc = kOkRC ;
switch ( val - > tflag & kTypeMask )
{
case kBoolTFl : val - > u . b = v ! = 0 ; break ;
case kUIntTFl : val - > u . u = ( unsigned ) v ; break ;
case kIntTFl : val - > u . i = ( int ) v ; break ;
case kFloatTFl : val - > u . f = ( float ) v ; break ;
case kDoubleTFl : val - > u . d = v ; break ;
case kInvalidTFl :
val - > u . d = v ;
val - > tflag = kDoubleTFl ;
break ;
default :
rc = cwLogError ( kTypeMismatchRC , " A double could not be converted to a %s (0x%x). " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
}
return rc ;
}
2021-08-23 02:41:33 +00:00
rc_t _val_get ( const value_t * val , const char * & valRef )
{
rc_t rc = kOkRC ;
2024-04-30 23:58:10 +00:00
if ( cwIsFlag ( val - > tflag & kTypeMask , kStringTFl ) )
2021-08-23 02:41:33 +00:00
valRef = val - > u . s ;
else
{
2024-04-30 23:58:10 +00:00
rc = cwLogError ( kTypeMismatchRC , " The type %s (0x%x) could not be converted to a string. " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
2021-08-23 02:41:33 +00:00
valRef = nullptr ;
2021-08-15 20:07:12 +00:00
}
return rc ;
}
2024-04-30 23:58:10 +00:00
rc_t _val_set ( value_t * val , const char * v )
{
rc_t rc = kOkRC ;
switch ( val - > tflag & kTypeMask )
{
case kStringTFl :
val - > u . s = mem : : duplStr ( v ) ; break ;
case kInvalidTFl :
val - > u . s = mem : : duplStr ( v ) ;
val - > tflag = kStringTFl ;
break ;
default :
rc = cwLogError ( kTypeMismatchRC , " A string could not be converted to a %s (0x%x). " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
}
return rc ;
}
2021-08-23 02:41:33 +00:00
rc_t _val_get ( value_t * val , abuf_t * & valRef )
{
rc_t rc = kOkRC ;
2024-04-30 23:58:10 +00:00
if ( cwIsFlag ( val - > tflag & kTypeMask , kABufTFl ) )
2021-08-23 02:41:33 +00:00
valRef = val - > u . abuf ;
else
{
2024-04-30 23:58:10 +00:00
rc = cwLogError ( kTypeMismatchRC , " The type %s (0x%x) could not be converted to an abuf. " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
2021-08-23 02:41:33 +00:00
valRef = nullptr ;
}
return rc ;
}
rc_t _val_get ( value_t * val , const abuf_t * & valRef )
{
abuf_t * non_const_val ;
rc_t rc = kOkRC ;
if ( ( rc = _val_get ( val , non_const_val ) ) = = kOkRC )
valRef = non_const_val ;
return rc ;
}
2024-04-30 23:58:10 +00:00
rc_t _val_set ( value_t * val , abuf_t * v )
{
rc_t rc = kOkRC ;
switch ( val - > tflag & kTypeMask )
{
case kABufTFl :
val - > u . abuf = v ;
break ;
case kInvalidTFl :
val - > u . abuf = v ;
val - > tflag = kABufTFl ;
break ;
default :
rc = cwLogError ( kTypeMismatchRC , " A audio signal could not be converted to a %s (0x%x). " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
}
return rc ;
}
2021-08-23 02:41:33 +00:00
rc_t _val_get ( value_t * val , fbuf_t * & valRef )
{
rc_t rc = kOkRC ;
2024-04-30 23:58:10 +00:00
if ( cwIsFlag ( val - > tflag & kTypeMask , kFBufTFl ) )
2021-08-23 02:41:33 +00:00
valRef = val - > u . fbuf ;
else
{
valRef = nullptr ;
2024-04-30 23:58:10 +00:00
rc = cwLogError ( kTypeMismatchRC , " The type %s (0x%x) could not be converted to an fbuf. " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
2021-08-23 02:41:33 +00:00
}
return rc ;
}
rc_t _val_get ( value_t * val , const fbuf_t * & valRef )
{
fbuf_t * non_const_val ;
rc_t rc = kOkRC ;
if ( ( rc = _val_get ( val , non_const_val ) ) = = kOkRC )
valRef = non_const_val ;
return rc ;
}
2022-01-22 14:49:45 +00:00
2024-04-30 23:58:10 +00:00
rc_t _val_set ( value_t * val , fbuf_t * v )
2022-01-22 14:49:45 +00:00
{
2024-04-30 23:58:10 +00:00
rc_t rc = kOkRC ;
2022-01-22 14:49:45 +00:00
2024-04-30 23:58:10 +00:00
switch ( val - > tflag & kTypeMask )
{
case kFBufTFl :
val - > u . fbuf = v ;
break ;
case kInvalidTFl :
val - > u . fbuf = v ;
val - > tflag = kFBufTFl ;
break ;
2022-01-22 14:49:45 +00:00
2024-04-30 23:58:10 +00:00
default :
rc = cwLogError ( kTypeMismatchRC , " A spectrum signal could not be converted to a %s (0x%x). " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
}
return rc ;
2022-01-22 14:49:45 +00:00
}
2024-04-30 23:58:10 +00:00
2024-04-06 20:07:46 +00:00
rc_t _val_get ( value_t * val , mbuf_t * & valRef )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
rc_t rc = kOkRC ;
2024-04-30 23:58:10 +00:00
if ( cwIsFlag ( val - > tflag & kTypeMask , kMBufTFl ) )
2024-04-06 20:07:46 +00:00
valRef = val - > u . mbuf ;
else
{
valRef = nullptr ;
2024-04-30 23:58:10 +00:00
rc = cwLogError ( kTypeMismatchRC , " The type %s (0x%x) could not be converted to an mbuf. " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
}
return rc ;
}
2021-08-23 02:41:33 +00:00
2024-04-30 23:58:10 +00:00
rc_t _val_set ( value_t * val , mbuf_t * v )
{
rc_t rc = kOkRC ;
switch ( val - > tflag & kTypeMask )
2021-08-23 02:41:33 +00:00
{
2024-04-30 23:58:10 +00:00
case kMBufTFl :
val - > u . mbuf = v ;
break ;
case kInvalidTFl :
val - > u . mbuf = v ;
val - > tflag = kMBufTFl ;
break ;
default :
rc = cwLogError ( kTypeMismatchRC , " A MIDI signal could not be converted to a %s (0x%x). " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
2024-04-06 20:07:46 +00:00
}
2024-04-30 23:58:10 +00:00
2024-04-06 20:07:46 +00:00
return rc ;
}
2021-08-23 02:41:33 +00:00
2024-04-06 20:07:46 +00:00
rc_t _val_get ( value_t * val , const mbuf_t * & valRef )
{
mbuf_t * non_const_val ;
rc_t rc = kOkRC ;
if ( ( rc = _val_get ( val , non_const_val ) ) = = kOkRC )
valRef = non_const_val ;
return rc ;
}
2024-04-30 23:58:10 +00:00
rc_t _val_get ( value_t * val , const object_t * & valRef )
{
rc_t rc = kOkRC ;
if ( cwIsFlag ( val - > tflag & kTypeMask , kCfgTFl ) )
valRef = val - > u . cfg ;
else
{
valRef = nullptr ;
rc = cwLogError ( kTypeMismatchRC , " The type %s (0x%x) could not be converted to a cfg. " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
2021-08-23 02:41:33 +00:00
}
2024-04-30 23:58:10 +00:00
return rc ;
}
2024-04-06 20:07:46 +00:00
2024-04-30 23:58:10 +00:00
rc_t _val_set ( value_t * val , const object_t * v )
{
rc_t rc = kOkRC ;
switch ( val - > tflag & kTypeMask )
{
case kCfgTFl :
val - > u . cfg = v ;
break ;
case kInvalidTFl :
val - > u . cfg = v ;
val - > tflag = kCfgTFl ;
break ;
2021-08-23 02:41:33 +00:00
2024-04-30 23:58:10 +00:00
default :
rc = cwLogError ( kTypeMismatchRC , " A cfg. could not be converted to a %s (0x%x). " , _typeFlagToLabel ( val - > tflag ) , val - > tflag ) ;
}
2021-08-23 02:41:33 +00:00
return rc ;
}
2022-01-22 14:49:45 +00:00
template < typename T >
rc_t _val_get_driver ( const variable_t * var , T & valRef )
{
if ( var = = nullptr )
return cwLogError ( kInvalidArgRC , " Cannnot get the value of a non-existent variable. " ) ;
if ( var - > value = = nullptr )
2024-05-06 19:44:53 +00:00
return cwLogError ( kInvalidStateRC , " No value has been assigned to the variable: %s:%i.%s:%i ch:%i. " , cwStringNullGuard ( var - > proc - > label ) , var - > proc - > label_sfx_id , cwStringNullGuard ( var - > label ) , var - > label_sfx_id , var - > chIdx ) ;
2022-01-22 14:49:45 +00:00
return _val_get ( var - > value , valRef ) ;
2024-04-30 23:58:10 +00:00
2021-08-23 02:41:33 +00:00
}
2024-05-02 17:59:19 +00:00
2021-08-23 02:41:33 +00:00
// Variable lookup: Exact match on vid and chIdx
2024-05-06 19:44:53 +00:00
rc_t _var_find_on_vid_and_ch ( proc_t * proc , unsigned vid , unsigned chIdx , variable_t * & varRef )
2021-08-23 02:41:33 +00:00
{
varRef = nullptr ;
2024-05-06 19:44:53 +00:00
for ( variable_t * var = proc - > varL ; var ! = nullptr ; var = var - > var_link )
2021-08-23 02:41:33 +00:00
{
// the variable vid and chIdx should form a unique pair
if ( var - > vid = = vid & & var - > chIdx = = chIdx )
{
varRef = var ;
return kOkRC ;
}
}
2024-05-08 14:21:21 +00:00
return cwLogError ( kInvalidIdRC , " The variable matching id:%i ch:%i on proc '%s:%i' could not be found. " , vid , chIdx , proc - > label , proc - > label_sfx_id ) ;
2021-08-23 02:41:33 +00:00
}
// Variable lookup: Exact match on label and chIdx
2024-05-06 19:44:53 +00:00
variable_t * _var_find_on_label_and_ch ( proc_t * proc , const char * var_label , unsigned sfx_id , unsigned chIdx )
2021-08-23 02:41:33 +00:00
{
2024-05-06 19:44:53 +00:00
for ( variable_t * var = proc - > varL ; var ! = nullptr ; var = var - > var_link )
2021-08-23 02:41:33 +00:00
{
// the variable vid and chIdx should form a unique pair
2024-04-22 20:02:40 +00:00
if ( var - > label_sfx_id = = sfx_id & & textCompare ( var - > label , var_label ) = = 0 & & var - > chIdx = = chIdx )
2021-08-15 20:07:12 +00:00
return var ;
2021-08-23 02:41:33 +00:00
}
2021-08-15 20:07:12 +00:00
return nullptr ;
2021-08-23 02:41:33 +00:00
}
2024-05-06 19:44:53 +00:00
rc_t _var_find_on_label_and_ch ( proc_t * proc , const char * var_label , unsigned sfx_id , unsigned chIdx , variable_t * & var_ref )
2021-08-15 20:07:12 +00:00
{
rc_t rc = kOkRC ;
2024-05-06 19:44:53 +00:00
if ( ( var_ref = _var_find_on_label_and_ch ( proc , var_label , sfx_id , chIdx ) ) = = nullptr )
rc = cwLogError ( kEleNotFoundRC , " The variable '%s:%i' cannot be found on the proc:%s. " , cwStringNullGuard ( var_label ) , sfx_id , cwStringNullGuard ( proc - > label ) ) ;
2021-12-30 02:52:46 +00:00
return rc ;
}
2021-08-23 02:41:33 +00:00
2021-08-15 20:07:12 +00:00
rc_t _validate_var_assignment ( variable_t * var , unsigned typeFl )
2021-12-30 02:52:46 +00:00
{
2024-05-06 19:44:53 +00:00
if ( cwIsFlag ( var - > varDesc - > flags , kSrcVarDescFl ) )
2024-05-08 14:21:21 +00:00
return cwLogError ( kInvalidStateRC , " The variable '%s:%i' on proc '%s:%i' cannot be set because it is a 'src' variable. " , var - > label , var - > label_sfx_id , var - > proc - > label , var - > proc - > label_sfx_id ) ;
2024-04-30 23:58:10 +00:00
/*
2021-08-15 20:07:12 +00:00
if ( ! cwIsFlag ( var - > varDesc - > type , typeFl ) )
2024-05-08 14:21:21 +00:00
return cwLogError ( kTypeMismatchRC , " The variable '%s:%i' on proc '%s:%i' is not a '%s'. " , var - > label , var - > label_sfx_id , var - > proc - > label , var - > proc - > label_sfx_id , _typeFlagToLabel ( typeFl ) ) ;
2024-04-30 23:58:10 +00:00
*/
2021-08-15 20:07:12 +00:00
return kOkRC ;
2021-12-30 02:52:46 +00:00
}
2024-05-02 17:59:19 +00:00
void _var_print_addr ( const char * title , const variable_t * v )
2024-05-10 02:03:08 +00:00
{ cwLogPrint ( " %s:%s:%i.%s:%i " , title , v - > proc - > label , v - > proc - > label_sfx_id , v - > label , v - > label_sfx_id ) ; }
2021-12-30 02:52:46 +00:00
2024-04-30 23:58:10 +00:00
void _var_print ( const variable_t * var )
2021-12-30 02:52:46 +00:00
{
2024-05-10 19:52:37 +00:00
const char * conn_label = is_connected_to_source ( var ) ? " extern " : " " ;
2024-04-30 23:58:10 +00:00
2024-06-08 21:00:53 +00:00
cwLogPrint ( " %12s:%3i vid:%3i ch:%3i : %s : " , var - > label , var - > label_sfx_id , var - > vid , var - > chIdx , conn_label ) ;
2024-04-30 23:58:10 +00:00
if ( var - > value = = nullptr )
_value_print ( & var - > local_value [ 0 ] ) ;
else
_value_print ( var - > value ) ;
2021-12-30 02:52:46 +00:00
2024-04-30 23:58:10 +00:00
if ( var - > src_var ! = nullptr )
2024-05-10 02:03:08 +00:00
cwLogPrint ( " src:%s:%i.%s:%i " , var - > src_var - > proc - > label , var - > src_var - > proc - > label_sfx_id , var - > src_var - > label , var - > src_var - > label_sfx_id ) ;
2021-12-30 02:52:46 +00:00
2024-05-02 17:59:19 +00:00
if ( var - > dst_head ! = nullptr )
{
for ( variable_t * v = var - > dst_head ; v ! = nullptr ; v = v - > dst_link )
2024-05-10 02:03:08 +00:00
cwLogPrint ( " dst:%s:%i.%s:%i " , v - > proc - > label , v - > proc - > label_sfx_id , v - > label , v - > label_sfx_id ) ;
2024-05-02 17:59:19 +00:00
}
2021-12-30 02:52:46 +00:00
2024-05-10 02:03:08 +00:00
cwLogPrint ( " \n " ) ;
2021-12-30 02:52:46 +00:00
}
2024-04-30 23:58:10 +00:00
2021-08-15 20:07:12 +00:00
rc_t _var_broadcast_new_value ( variable_t * var )
2021-12-30 02:52:46 +00:00
{
2021-08-15 20:07:12 +00:00
rc_t rc = kOkRC ;
2024-04-26 21:04:03 +00:00
2021-08-15 20:07:12 +00:00
// notify each connected var that the value has changed
2024-04-30 23:58:10 +00:00
for ( variable_t * con_var = var - > dst_head ; con_var ! = nullptr ; con_var = con_var - > dst_link )
2024-04-26 21:04:03 +00:00
{
// the var->local_value[] slot used by the source variable may have changed - update the destination variable
// so that it points to the correct value.
con_var - > value = var - > value ;
2024-04-30 23:58:10 +00:00
2024-05-02 17:59:19 +00:00
cwLogMod ( " %s:%i %s:%i -> %s:%i %s:%i " ,
2024-05-06 19:44:53 +00:00
var - > proc - > label , var - > proc - > label_sfx_id ,
2024-04-30 23:58:10 +00:00
var - > label , var - > label_sfx_id ,
2024-05-06 19:44:53 +00:00
con_var - > proc - > label , con_var - > proc - > label_sfx_id ,
2024-04-30 23:58:10 +00:00
con_var - > label , con_var - > label_sfx_id ) ;
// Call the value() function on the connected variable
if ( ( rc = var_call_custom_value_func ( con_var ) ) ! = kOkRC )
break ;
2024-04-26 21:04:03 +00:00
}
2021-12-30 02:52:46 +00:00
return rc ;
}
2024-05-02 17:59:19 +00:00
// 'argTypeFlag' is the type (tflag) of 'val'.
2024-04-30 23:58:10 +00:00
template < typename T >
rc_t _var_set_template ( variable_t * var , unsigned argTypeFlag , T val )
2021-12-30 02:52:46 +00:00
{
2024-05-02 17:59:19 +00:00
rc_t rc = kOkRC ;
// it is not legal to set the value of a variable that is connected to a 'source' variable.
if ( var - > src_var ! = nullptr )
2024-05-06 19:44:53 +00:00
return cwLogError ( kInvalidStateRC , " The variable '%s:%i %s:%i' cannot be set because it is connected to a source variable. " , var - > proc - > label , var - > proc - > label_sfx_id , var - > label , var - > label_sfx_id ) ;
2024-05-02 17:59:19 +00:00
2022-01-22 14:49:45 +00:00
2024-04-30 23:58:10 +00:00
// var->type is the allowable type for this var's value.
2024-05-02 17:59:19 +00:00
// It may be set to kInvalidTFl if the type has not yet been determined.
2024-04-30 23:58:10 +00:00
unsigned value_type_flag = var - > type ;
2024-05-02 17:59:19 +00:00
// Pick the slot in local_value[] that we will use to try out this new value.
2022-01-22 14:49:45 +00:00
unsigned next_local_value_idx = ( var - > local_value_idx + 1 ) % kLocalValueN ;
// store the pointer to the current value of this variable
value_t * original_value = var - > value ;
unsigned original_value_idx = var - > local_value_idx ;
2024-04-30 23:58:10 +00:00
2022-01-22 14:49:45 +00:00
// release the previous value in the next slot
_value_release ( & var - > local_value [ next_local_value_idx ] ) ;
2024-04-30 23:58:10 +00:00
// if the value type of this variable has not been established
if ( value_type_flag = = kInvalidTFl )
{
// if the var desc is a single type then use that ....
if ( math : : isPowerOfTwo ( var - > varDesc - > type ) )
2024-05-02 17:59:19 +00:00
{
2024-04-30 23:58:10 +00:00
value_type_flag = var - > varDesc - > type ;
2024-05-02 17:59:19 +00:00
}
2024-04-30 23:58:10 +00:00
else // ... Otherwise select a type from the one of the possible flags given by the var desc
2024-05-02 17:59:19 +00:00
{
2024-04-30 23:58:10 +00:00
value_type_flag = var - > varDesc - > type & argTypeFlag ;
2024-05-02 17:59:19 +00:00
}
2024-04-30 23:58:10 +00:00
// if the incoming type is not in the set of allowable types then it is an error
if ( value_type_flag = = 0 )
{
rc = cwLogError ( kTypeMismatchRC , " The type 0x%x is not valid for the variable: %s:%i %s:%i type:0x%x. " ,
2024-05-06 19:44:53 +00:00
argTypeFlag , var - > proc - > label , var - > proc - > label_sfx_id , var - > label , var - > label_sfx_id , var - > varDesc - > type ) ;
2024-04-30 23:58:10 +00:00
goto errLabel ;
}
}
// set the type of the LHS to force the incoming value to be coerced to this type
var - > local_value [ next_local_value_idx ] . tflag = value_type_flag ;
2024-05-02 17:59:19 +00:00
// set the new local value in var->local_value[next_local_value_idx]
2024-04-30 23:58:10 +00:00
if ( ( rc = _val_set ( var - > local_value + next_local_value_idx , val ) ) ! = kOkRC )
{
2024-05-06 19:44:53 +00:00
rc = cwLogError ( rc , " Value set failed on '%s:%i %s:%i " , var - > proc - > label , var - > proc - > label_sfx_id , var - > label , var - > label_sfx_id ) ;
2024-04-30 23:58:10 +00:00
goto errLabel ;
}
2021-12-30 02:52:46 +00:00
2022-01-22 14:49:45 +00:00
// make the new local value current
var - > value = var - > local_value + next_local_value_idx ;
var - > local_value_idx = next_local_value_idx ;
2024-05-08 14:21:21 +00:00
// If the proc is fully initialized ...
2024-05-06 19:44:53 +00:00
if ( var - > proc - > varMapA ! = nullptr )
2021-12-30 02:52:46 +00:00
{
// ... then inform the proc. that the value changed
2022-01-22 14:49:45 +00:00
// Note 1: We don't want to this call to occur if we are inside or prior to 'proc.create()'
2024-05-08 14:21:21 +00:00
// call because calls' to 'proc.value()' will see the proc in a incomplete state)
2022-01-22 14:49:45 +00:00
// Note 2: If this call returns an error then the value assignment is cancelled
// and the value does not change.
2024-05-02 17:59:19 +00:00
rc = var_call_custom_value_func ( var ) ;
2021-12-30 02:52:46 +00:00
}
2024-05-06 19:44:53 +00:00
//printf("%p set: %s:%s 0x%x\n",var->value, var->proc->label,var->label,var->value->tflag);
2024-04-30 23:58:10 +00:00
2021-12-30 02:52:46 +00:00
if ( rc = = kOkRC )
{
// send the value to connected downstream proc's
rc = _var_broadcast_new_value ( var ) ;
}
2022-01-22 14:49:45 +00:00
else
2021-12-30 02:52:46 +00:00
{
2022-01-22 14:49:45 +00:00
// cancel the assignment and restore the original value
var - > value = original_value ;
var - > local_value_idx = original_value_idx ;
2021-12-30 02:52:46 +00:00
}
2022-01-22 14:49:45 +00:00
errLabel :
2021-12-30 02:52:46 +00:00
return rc ;
2021-08-15 20:07:12 +00:00
}
2024-04-30 23:58:10 +00:00
2021-12-30 02:52:46 +00:00
2024-04-30 23:58:10 +00:00
// 'valueTypeFlag' is the type (tflag) of 'value'
2021-08-23 02:41:33 +00:00
template < typename T >
2024-04-30 23:58:10 +00:00
rc_t _var_set_driver ( variable_t * var , unsigned valueTypeFlag , T value )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
rc_t rc ;
2021-08-15 20:07:12 +00:00
2021-12-30 02:52:46 +00:00
// if this variable is fed from the output of an external proc - then it's local value cannot be set
2024-05-10 19:52:37 +00:00
if ( is_connected_to_source ( var ) )
2024-05-02 17:59:19 +00:00
{
2024-05-08 14:21:21 +00:00
return cwLogError ( kInvalidStateRC , " Cannot set the value on the connected variable %s:%i-%s:%i. " , var - > proc - > label , var - > proc - > label_sfx_id , var - > label , var - > label_sfx_id ) ;
2024-05-02 17:59:19 +00:00
}
2021-12-30 02:52:46 +00:00
2021-08-23 02:41:33 +00:00
// if this assignment targets a specific channel ...
if ( var - > chIdx ! = kAnyChIdx )
{
2024-04-30 23:58:10 +00:00
rc = _var_set_template ( var , valueTypeFlag , value ) ; // ... then set it alone
2021-08-23 02:41:33 +00:00
}
else // ... otherwise set all channels.
{
for ( ; var ! = nullptr ; var = var - > ch_link )
2024-04-30 23:58:10 +00:00
if ( ( rc = _var_set_template ( var , valueTypeFlag , value ) ) ! = kOkRC )
2021-08-23 02:41:33 +00:00
break ;
}
2024-04-30 23:58:10 +00:00
if ( rc ! = kOkRC )
2024-05-06 19:44:53 +00:00
rc = cwLogError ( rc , " Variable value set failed on '%s:%i %s:%i " , cwStringNullGuard ( var - > proc - > label ) , var - > proc - > label_sfx_id , cwStringNullGuard ( var - > label ) , var - > label_sfx_id ) ;
2024-04-30 23:58:10 +00:00
2021-08-23 02:41:33 +00:00
return rc ;
2021-08-15 20:07:12 +00:00
}
2021-08-23 02:41:33 +00:00
2021-08-15 20:07:12 +00:00
2024-05-06 19:44:53 +00:00
rc_t _var_register_and_set ( proc_t * proc , const char * var_label , unsigned sfx_id , unsigned vid , unsigned chIdx , abuf_t * abuf )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
rc_t rc ;
2021-08-15 20:07:12 +00:00
variable_t * var = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_register_and_set ( proc , var_label , sfx_id , vid , chIdx , var ) ) ! = kOkRC )
2021-08-23 02:41:33 +00:00
return rc ;
if ( var ! = nullptr )
2021-12-30 02:52:46 +00:00
_var_set_driver ( var , kABufTFl , abuf ) ;
2021-08-23 02:41:33 +00:00
return rc ;
}
2024-05-06 19:44:53 +00:00
rc_t _var_register_and_set ( proc_t * proc , const char * var_label , unsigned sfx_id , unsigned vid , unsigned chIdx , mbuf_t * mbuf )
2021-08-23 02:41:33 +00:00
{
rc_t rc ;
variable_t * var = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_register_and_set ( proc , var_label , sfx_id , vid , chIdx , var ) ) ! = kOkRC )
2021-08-23 02:41:33 +00:00
return rc ;
if ( var ! = nullptr )
2024-04-06 20:07:46 +00:00
_var_set_driver ( var , kMBufTFl , mbuf ) ;
2021-08-23 02:41:33 +00:00
return rc ;
}
2024-04-06 20:07:46 +00:00
2024-05-06 19:44:53 +00:00
rc_t _var_register_and_set ( proc_t * proc , const char * var_label , unsigned sfx_id , unsigned vid , unsigned chIdx , fbuf_t * fbuf )
2021-08-23 02:41:33 +00:00
{
rc_t rc ;
variable_t * var = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_register_and_set ( proc , var_label , sfx_id , vid , chIdx , var ) ) ! = kOkRC )
2021-08-23 02:41:33 +00:00
return rc ;
if ( var ! = nullptr )
2021-12-30 02:52:46 +00:00
_var_set_driver ( var , kFBufTFl , fbuf ) ;
2021-08-15 20:07:12 +00:00
return rc ;
}
2024-05-06 19:44:53 +00:00
rc_t _var_map_id_to_index ( proc_t * proc , unsigned vid , unsigned chIdx , unsigned & idxRef )
2021-08-23 02:41:33 +00:00
{
2024-05-06 19:44:53 +00:00
unsigned idx = vid * proc - > varMapChN + ( chIdx = = kAnyChIdx ? 0 : ( chIdx + 1 ) ) ;
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
// verify that the map idx is valid
2024-05-06 19:44:53 +00:00
if ( idx > = proc - > varMapN )
2024-05-08 14:21:21 +00:00
return cwLogError ( kAssertFailRC , " The variable map positioning location %i is out of the range %i on proc '%s:%i' vid:%i ch:%i. " , idx , proc - > varMapN , proc - > label , proc - > label_sfx_id , vid , chIdx ) ;
2021-08-23 02:41:33 +00:00
idxRef = idx ;
return kOkRC ;
}
2024-05-06 19:44:53 +00:00
rc_t _var_map_label_to_index ( proc_t * proc , const char * var_label , unsigned sfx_id , unsigned chIdx , unsigned & idxRef )
2021-08-23 02:41:33 +00:00
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
idxRef = kInvalidIdx ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , var_label , sfx_id , chIdx , var ) ) = = kOkRC )
rc = _var_map_id_to_index ( proc , var - > vid , chIdx , idxRef ) ;
2021-08-23 02:41:33 +00:00
return rc ;
}
2024-05-06 19:44:53 +00:00
rc_t _var_add_to_ch_list ( proc_t * proc , variable_t * new_var )
2021-08-23 02:41:33 +00:00
{
rc_t rc = kOkRC ;
variable_t * base_var = nullptr ;
variable_t * v0 = nullptr ;
variable_t * v1 = nullptr ;
if ( new_var - > chIdx = = kAnyChIdx )
return kOkRC ;
2024-05-06 19:44:53 +00:00
if ( ( base_var = _var_find_on_label_and_ch ( proc , new_var - > label , new_var - > label_sfx_id , kAnyChIdx ) ) = = nullptr )
2021-08-23 02:41:33 +00:00
{
2024-05-06 19:44:53 +00:00
rc = cwLogError ( kInvalidStateRC , " The base channel variable does not exist for '%s:%i.%s:%i'. This is an illegal state. " , proc - > label , proc - > label_sfx_id , new_var - > label , new_var - > label_sfx_id ) ;
2021-08-23 02:41:33 +00:00
goto errLabel ;
}
// insert v0 in order by channel number
for ( v0 = base_var , v1 = base_var - > ch_link ; v1 ! = nullptr ; v1 = v1 - > ch_link )
{
if ( v1 - > chIdx > new_var - > chIdx )
break ;
v0 = v1 ;
}
// the new var channel index should never match the previous or next channel index
assert ( v0 - > chIdx ! = new_var - > chIdx & & ( v1 = = nullptr | | v1 - > chIdx ! = new_var - > chIdx ) ) ;
new_var - > ch_link = v1 ;
v0 - > ch_link = new_var ;
errLabel :
return rc ;
}
2024-04-30 23:58:10 +00:00
rc_t _var_set_type ( variable_t * var , unsigned type_flag )
{
rc_t rc = kOkRC ;
if ( cwIsNotFlag ( var - > classVarDesc - > type , kRuntimeTFl ) )
{
2024-06-04 12:45:05 +00:00
rc = cwLogError ( kOpFailRC , " It is invalid to change the type of a static (non-runtime) type variable. " ) ;
2024-04-30 23:58:10 +00:00
goto errLabel ;
}
2024-05-02 17:59:19 +00:00
// Duplicate the varDesc with the 'type' field set to type_flag
2024-04-30 23:58:10 +00:00
if ( var - > localVarDesc = = nullptr )
{
var - > localVarDesc = mem : : allocZ < var_desc_t > ( ) ;
* ( var - > localVarDesc ) = * ( var - > classVarDesc ) ;
var - > localVarDesc - > link = nullptr ;
}
var - > localVarDesc - > type = type_flag ;
var - > varDesc = var - > localVarDesc ;
errLabel :
return rc ;
}
2021-08-23 02:41:33 +00:00
// Create a variable and set it's value from 'value_cfg'.
// If 'value_cfg' is null then use the value from var->varDesc->val_cfg.
2024-05-06 19:44:53 +00:00
rc_t _var_create ( proc_t * proc , const char * var_label , unsigned sfx_id , unsigned id , unsigned chIdx , const object_t * value_cfg , unsigned altTypeFl , variable_t * & varRef )
2021-08-23 02:41:33 +00:00
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
var_desc_t * vd = nullptr ;
varRef = nullptr ;
// if this var already exists - it can't be created again
2024-05-06 19:44:53 +00:00
if ( ( var = _var_find_on_label_and_ch ( proc , var_label , sfx_id , chIdx ) ) ! = nullptr )
2021-08-23 02:41:33 +00:00
{
2024-05-08 14:21:21 +00:00
rc = cwLogError ( kInvalidStateRC , " The variable '%s:%i' ch:%i has already been created on the proc: '%s:%i'. " , var_label , sfx_id , chIdx , proc - > label , proc - > label_sfx_id ) ;
2021-08-23 02:41:33 +00:00
goto errLabel ;
}
// locate the var desc
2024-05-06 19:44:53 +00:00
if ( ( vd = var_desc_find ( proc - > class_desc , var_label ) ) = = nullptr )
2021-08-23 02:41:33 +00:00
{
2024-05-06 19:44:53 +00:00
rc = cwLogError ( kInvalidIdRC , " Unable to locate the variable '%s:%i' in class '%s'. " , var_label , sfx_id , proc - > class_desc - > label ) ;
2021-08-23 02:41:33 +00:00
goto errLabel ;
}
// create the var
var = mem : : allocZ < variable_t > ( ) ;
2024-04-22 20:02:40 +00:00
var - > varDesc = vd ;
2024-04-30 23:58:10 +00:00
var - > classVarDesc = vd ;
2024-05-06 19:44:53 +00:00
var - > proc = proc ;
2024-04-22 20:02:40 +00:00
var - > label = mem : : duplStr ( var_label ) ;
var - > label_sfx_id = sfx_id ;
var - > vid = id ;
var - > chIdx = chIdx ;
var - > value = nullptr ;
2024-04-30 23:58:10 +00:00
var - > type = kInvalidTFl ;
2021-08-23 02:41:33 +00:00
2024-04-30 23:58:10 +00:00
if ( altTypeFl ! = kInvalidTFl )
_var_set_type ( var , altTypeFl ) ;
2021-08-23 02:41:33 +00:00
// if no value was given then set the value to the value given in the class
if ( value_cfg = = nullptr )
value_cfg = var - > varDesc - > val_cfg ;
2024-05-02 17:59:19 +00:00
2021-08-23 02:41:33 +00:00
// if value_cfg is valid set the variable value
2024-04-30 23:58:10 +00:00
if ( value_cfg ! = nullptr & & cwIsNotFlag ( vd - > type , kRuntimeTFl ) )
2024-05-24 20:41:42 +00:00
if ( ( rc = var_set_from_cfg ( var , value_cfg ) ) ! = kOkRC )
2021-08-23 02:41:33 +00:00
goto errLabel ;
2024-05-24 20:41:42 +00:00
// Add the variable to the end of the chain
if ( proc - > varL = = nullptr )
proc - > varL = var ;
else
{
variable_t * v = proc - > varL ;
while ( v - > var_link ! = nullptr )
v = v - > var_link ;
v - > var_link = var ;
}
2021-08-23 02:41:33 +00:00
// link the new var into the ch_link list
2024-05-06 19:44:53 +00:00
if ( ( rc = _var_add_to_ch_list ( proc , var ) ) ! = kOkRC )
2021-08-23 02:41:33 +00:00
goto errLabel ;
errLabel :
if ( rc ! = kOkRC )
{
2024-05-06 19:44:53 +00:00
var_destroy ( var ) ;
cwLogError ( kOpFailRC , " Variable creation failed on '%s:%i.%s:%i' ch:%i. " , proc - > label , proc - > label_sfx_id , var_label , sfx_id , chIdx ) ;
2021-08-23 02:41:33 +00:00
}
else
{
varRef = var ;
2024-05-06 19:44:53 +00:00
cwLogMod ( " Created var: %s:%i.%s:%i ch:%i. " , proc - > label , proc - > label_sfx_id , var_label , sfx_id , chIdx ) ;
2021-08-23 02:41:33 +00:00
}
return rc ;
}
2024-05-05 21:31:42 +00:00
void _class_desc_print ( const class_desc_t * cd )
2021-08-23 02:41:33 +00:00
{
2024-05-05 21:31:42 +00:00
const var_desc_t * vd = cd - > varDescL ;
2024-05-10 02:03:08 +00:00
cwLogPrint ( " %s \n " , cwStringNullGuard ( cd - > label ) ) ;
2021-08-23 02:41:33 +00:00
2024-05-05 21:31:42 +00:00
for ( ; vd ! = nullptr ; vd = vd - > link )
{
2024-05-06 19:44:53 +00:00
const char * srcFlStr = vd - > flags & kSrcVarDescFl ? " src " : " " ;
const char * srcOptFlStr = vd - > flags & kSrcOptVarDescFl ? " srcOpt " : " " ;
const char * plyMltFlStr = vd - > flags & kMultVarDescFl ? " mult " : " " ;
2024-05-05 21:31:42 +00:00
2024-05-10 02:03:08 +00:00
cwLogPrint ( " %10s 0x%08x %s %s %s %s \n " , cwStringNullGuard ( vd - > label ) , vd - > type , srcFlStr , srcOptFlStr , plyMltFlStr , cwStringNullGuard ( vd - > docText ) ) ;
2024-05-05 21:31:42 +00:00
}
2021-08-23 02:41:33 +00:00
}
}
}
2024-06-04 12:45:05 +00:00
void cw : : flow : : value_duplicate ( value_t & dst , const value_t & src )
{
_value_duplicate ( dst , src ) ;
}
2024-05-24 20:41:42 +00:00
void cw : : flow : : value_print ( const value_t * value , bool info_fl )
{
_value_print ( value , info_fl ) ;
}
2021-08-23 02:41:33 +00:00
cw : : flow : : abuf_t * cw : : flow : : abuf_create ( srate_t srate , unsigned chN , unsigned frameN )
{
2024-07-11 15:03:26 +00:00
if ( chN * frameN = = 0 )
{
cwLogError ( kInvalidArgRC , " The %s audio signal parameter cannot be zero. " , chN = = 0 ? " channel count " : " frame count " ) ;
return nullptr ;
}
2024-06-04 12:45:05 +00:00
abuf_t * a = mem : : allocZ < abuf_t > ( ) ;
a - > srate = srate ;
a - > chN = chN ;
a - > frameN = frameN ;
a - > bufAllocSmpN = chN * frameN ;
2024-07-11 15:03:26 +00:00
2024-06-04 12:45:05 +00:00
a - > buf = mem : : allocZ < sample_t > ( a - > bufAllocSmpN ) ;
2021-08-15 20:07:12 +00:00
return a ;
}
2022-01-22 14:49:45 +00:00
void cw : : flow : : abuf_destroy ( abuf_t * & abuf )
2021-08-15 20:07:12 +00:00
{
if ( abuf = = nullptr )
return ;
mem : : release ( abuf - > buf ) ;
mem : : release ( abuf ) ;
}
2024-06-04 12:45:05 +00:00
cw : : flow : : abuf_t * cw : : flow : : abuf_duplicate ( abuf_t * dst , const abuf_t * src )
2021-08-23 02:41:33 +00:00
{
2024-06-04 12:45:05 +00:00
abuf_t * abuf = nullptr ;
if ( dst ! = nullptr & & dst - > bufAllocSmpN < src - > bufAllocSmpN )
mem : : release ( dst - > buf ) ;
if ( dst = = nullptr | | dst - > buf = = nullptr )
abuf = abuf_create ( src - > srate , src - > chN , src - > frameN ) ;
else
abuf = dst ;
2024-07-11 15:03:26 +00:00
if ( abuf ! = nullptr )
vop : : copy ( abuf - > buf , src - > buf , src - > chN * src - > frameN ) ;
2024-06-04 12:45:05 +00:00
return abuf ;
2021-08-23 02:41:33 +00:00
}
2021-08-15 20:07:12 +00:00
cw : : rc_t cw : : flow : : abuf_set_channel ( abuf_t * abuf , unsigned chIdx , const sample_t * v , unsigned vN )
{
rc_t rc = kOkRC ;
if ( vN > abuf - > frameN )
rc = cwLogError ( kInvalidArgRC , " Cannot copy source vector of length %i into an abuf of length %i. " , vN , abuf - > frameN ) ;
else
if ( chIdx > abuf - > chN )
rc = cwLogError ( kInvalidArgRC , " The abuf destination channel %i is out of range. " , chIdx ) ;
else
vop : : copy ( abuf - > buf + ( chIdx * abuf - > frameN ) , v , vN ) ;
return rc ;
}
const cw : : flow : : sample_t * cw : : flow : : abuf_get_channel ( abuf_t * abuf , unsigned chIdx )
{
assert ( abuf - > buf ! = nullptr ) ;
return abuf - > buf + ( chIdx * abuf - > frameN ) ;
}
2024-06-04 12:45:05 +00:00
cw : : flow : : fbuf_t * cw : : flow : : fbuf_create ( srate_t srate , unsigned chN , const unsigned * maxBinN_V , const unsigned * binN_V , const unsigned * hopSmpN_V , const fd_sample_t * * magV , const fd_sample_t * * phsV , const fd_sample_t * * hzV )
{
for ( unsigned i = 0 ; i < chN ; + + i )
if ( binN_V [ i ] > maxBinN_V [ i ] )
{
cwLogError ( kInvalidArgRC , " A channel bin count (%i) execeeds the max bin count (%i). " , binN_V [ i ] , maxBinN_V [ i ] ) ;
return nullptr ; ;
}
fbuf_t * f = mem : : allocZ < fbuf_t > ( ) ;
bool proxy_fl = magV ! = nullptr | | phsV ! = nullptr | | hzV ! = nullptr ;
// Calculate the total count of bins for each data vector.
unsigned maxTotalBinN = proxy_fl ? 0 : vop : : sum ( maxBinN_V , chN ) ;
// calc the total size of memory required for all internal data structures
f - > memByteN
= sizeof ( unsigned ) * chN * kFbufVectN // maxBinN_V[],binN_V[],hopSmpN_V[]
+ sizeof ( fd_sample_t * ) * chN * kFbufVectN // magV[],phsV[],hzV[] (pointer to bin buffers)
+ sizeof ( bool ) * chN * 1 // readyFlV[]
+ sizeof ( fd_sample_t ) * maxTotalBinN * kFbufVectN ; // bin buffer memory
// allocate mory
f - > mem = mem : : allocZ < uint8_t > ( f - > memByteN ) ;
unsigned * base_maxBinV = ( unsigned * ) f - > mem ;
fd_sample_t * * base_bufV = ( fd_sample_t * * ) ( base_maxBinV + kFbufVectN * chN ) ;
bool * base_boolV = ( bool * ) ( base_bufV + kFbufVectN * chN ) ;
fd_sample_t * base_buf = ( fd_sample_t * ) ( base_boolV + chN ) ;
f - > srate = srate ;
f - > chN = chN ;
f - > maxBinN_V = base_maxBinV ;
f - > binN_V = f - > maxBinN_V + chN ;
f - > hopSmpN_V = f - > binN_V + chN ;
f - > magV = base_bufV ;
f - > phsV = f - > magV + chN ;
f - > hzV = f - > phsV + chN ;
f - > readyFlV = base_boolV ;
vop : : copy ( f - > binN_V , binN_V , chN ) ;
vop : : copy ( f - > maxBinN_V , maxBinN_V , chN ) ;
vop : : copy ( f - > hopSmpN_V , hopSmpN_V , chN ) ;
if ( proxy_fl )
{
for ( unsigned chIdx = 0 ; chIdx < chN ; + + chIdx )
{
f - > magV [ chIdx ] = ( fd_sample_t * ) magV [ chIdx ] ;
f - > phsV [ chIdx ] = ( fd_sample_t * ) phsV [ chIdx ] ;
f - > hzV [ chIdx ] = ( fd_sample_t * ) hzV [ chIdx ] ;
}
}
else
{
fd_sample_t * m = base_buf ;
for ( unsigned chIdx = 0 ; chIdx < chN ; + + chIdx )
{
f - > magV [ chIdx ] = m + 0 * f - > binN_V [ chIdx ] ;
f - > phsV [ chIdx ] = m + 1 * f - > binN_V [ chIdx ] ;
f - > hzV [ chIdx ] = m + 2 * f - > binN_V [ chIdx ] ;
m + = f - > maxBinN_V [ chIdx ] ;
assert ( m < = base_buf + kFbufVectN * maxTotalBinN ) ;
}
}
return f ;
}
/*
2024-04-26 21:04:03 +00:00
cw : : flow : : fbuf_t * cw : : flow : : fbuf_create ( srate_t srate , unsigned chN , const unsigned * maxBinN_V , const unsigned * binN_V , const unsigned * hopSmpN_V , const fd_sample_t * * magV , const fd_sample_t * * phsV , const fd_sample_t * * hzV )
2021-08-15 20:07:12 +00:00
{
2022-12-27 23:09:31 +00:00
for ( unsigned i = 0 ; i < chN ; + + i )
if ( binN_V [ i ] > maxBinN_V [ i ] )
{
cwLogError ( kInvalidArgRC , " A channel bin count (%i) execeeds the max bin count (%i). " , binN_V [ i ] , maxBinN_V [ i ] ) ;
return nullptr ; ;
}
2022-12-05 22:19:58 +00:00
2021-08-15 20:07:12 +00:00
fbuf_t * f = mem : : allocZ < fbuf_t > ( ) ;
2022-12-05 22:19:58 +00:00
f - > srate = srate ;
f - > chN = chN ;
2022-12-27 23:09:31 +00:00
f - > maxBinN_V = mem : : allocZ < unsigned > ( chN ) ;
f - > binN_V = mem : : allocZ < unsigned > ( chN ) ;
2022-11-11 18:51:06 +00:00
f - > hopSmpN_V = mem : : allocZ < unsigned > ( chN ) ;
2024-04-26 21:04:03 +00:00
f - > magV = mem : : allocZ < fd_sample_t * > ( chN ) ;
f - > phsV = mem : : allocZ < fd_sample_t * > ( chN ) ;
f - > hzV = mem : : allocZ < fd_sample_t * > ( chN ) ;
2022-12-05 22:19:58 +00:00
f - > readyFlV = mem : : allocZ < bool > ( chN ) ;
2021-08-15 20:07:12 +00:00
2022-12-05 22:19:58 +00:00
vop : : copy ( f - > binN_V , binN_V , chN ) ;
2022-12-27 23:09:31 +00:00
vop : : copy ( f - > maxBinN_V , maxBinN_V , chN ) ;
vop : : copy ( f - > hopSmpN_V , hopSmpN_V , chN ) ;
2022-11-11 18:51:06 +00:00
2021-08-15 20:07:12 +00:00
if ( magV ! = nullptr | | phsV ! = nullptr | | hzV ! = nullptr )
{
for ( unsigned chIdx = 0 ; chIdx < chN ; + + chIdx )
2022-11-11 18:51:06 +00:00
{
2024-04-26 21:04:03 +00:00
f - > magV [ chIdx ] = ( fd_sample_t * ) magV [ chIdx ] ;
f - > phsV [ chIdx ] = ( fd_sample_t * ) phsV [ chIdx ] ;
f - > hzV [ chIdx ] = ( fd_sample_t * ) hzV [ chIdx ] ;
2021-08-15 20:07:12 +00:00
}
}
else
{
2022-12-27 23:09:31 +00:00
unsigned maxTotalBinsN = vop : : sum ( maxBinN_V , chN ) ;
2024-04-26 21:04:03 +00:00
fd_sample_t * buf = mem : : allocZ < fd_sample_t > ( kFbufVectN * maxTotalBinsN ) ;
fd_sample_t * m = buf ;
2022-12-05 22:19:58 +00:00
for ( unsigned chIdx = 0 ; chIdx < chN ; + + chIdx )
2021-08-15 20:07:12 +00:00
{
2022-12-05 22:19:58 +00:00
f - > magV [ chIdx ] = m + 0 * f - > binN_V [ chIdx ] ;
f - > phsV [ chIdx ] = m + 1 * f - > binN_V [ chIdx ] ;
f - > hzV [ chIdx ] = m + 2 * f - > binN_V [ chIdx ] ;
2022-12-27 23:09:31 +00:00
m + = f - > maxBinN_V [ chIdx ] ;
assert ( m < = buf + kFbufVectN * maxTotalBinsN ) ;
2021-08-15 20:07:12 +00:00
}
2022-12-05 22:19:58 +00:00
2021-08-15 20:07:12 +00:00
f - > buf = buf ;
}
2022-12-05 22:19:58 +00:00
return f ;
}
2024-06-04 12:45:05 +00:00
*/
2022-12-05 22:19:58 +00:00
2024-04-26 21:04:03 +00:00
cw : : flow : : fbuf_t * cw : : flow : : fbuf_create ( srate_t srate , unsigned chN , unsigned maxBinN , unsigned binN , unsigned hopSmpN , const fd_sample_t * * magV , const fd_sample_t * * phsV , const fd_sample_t * * hzV )
2022-12-05 22:19:58 +00:00
{
2022-12-27 23:09:31 +00:00
unsigned maxBinN_V [ chN ] ;
2022-12-05 22:19:58 +00:00
unsigned binN_V [ chN ] ;
unsigned hopSmpN_V [ chN ] ;
2022-12-27 23:09:31 +00:00
vop : : fill ( maxBinN_V , chN , maxBinN ) ;
2022-12-05 22:19:58 +00:00
vop : : fill ( binN_V , chN , binN ) ;
vop : : fill ( hopSmpN_V , chN , binN ) ;
2022-12-27 23:09:31 +00:00
return fbuf_create ( srate , chN , maxBinN_V , binN_V , hopSmpN_V , magV , phsV , hzV ) ;
2021-08-15 20:07:12 +00:00
}
2022-01-22 14:49:45 +00:00
void cw : : flow : : fbuf_destroy ( fbuf_t * & fbuf )
2021-08-15 20:07:12 +00:00
{
if ( fbuf = = nullptr )
return ;
2022-11-11 18:51:06 +00:00
2024-06-04 12:45:05 +00:00
mem : : release ( fbuf - > mem ) ;
2021-08-15 20:07:12 +00:00
mem : : release ( fbuf ) ;
}
2024-06-04 12:45:05 +00:00
cw : : flow : : fbuf_t * cw : : flow : : fbuf_duplicate ( fbuf_t * dst , const fbuf_t * src )
2021-08-23 02:41:33 +00:00
{
2024-06-04 12:45:05 +00:00
fbuf_t * fbuf = nullptr ;
if ( dst ! = nullptr & & dst - > memByteN < src - > memByteN )
fbuf_destroy ( dst ) ;
if ( dst = = nullptr )
fbuf = fbuf_create ( src - > srate , src - > chN , src - > maxBinN_V , src - > binN_V , src - > hopSmpN_V ) ;
else
fbuf = dst ;
2022-12-05 22:19:58 +00:00
2021-08-23 02:41:33 +00:00
for ( unsigned i = 0 ; i < fbuf - > chN ; + + i )
{
2022-12-27 23:09:31 +00:00
fbuf - > maxBinN_V [ i ] = src - > maxBinN_V [ i ] ;
2022-11-11 18:51:06 +00:00
fbuf - > binN_V [ i ] = src - > binN_V [ i ] ;
fbuf - > hopSmpN_V [ i ] = src - > hopSmpN_V [ i ] ;
vop : : copy ( fbuf - > magV [ i ] , src - > magV [ i ] , fbuf - > binN_V [ i ] ) ;
vop : : copy ( fbuf - > phsV [ i ] , src - > phsV [ i ] , fbuf - > binN_V [ i ] ) ;
vop : : copy ( fbuf - > hzV [ i ] , src - > hzV [ i ] , fbuf - > binN_V [ i ] ) ;
2021-08-23 02:41:33 +00:00
}
return fbuf ;
}
2024-04-06 20:07:46 +00:00
cw : : flow : : mbuf_t * cw : : flow : : mbuf_create ( const midi : : ch_msg_t * msgA , unsigned msgN )
{
mbuf_t * m = mem : : allocZ < mbuf_t > ( ) ;
m - > msgA = msgA ;
m - > msgN = msgN ;
return m ;
}
void cw : : flow : : mbuf_destroy ( mbuf_t * & buf )
{
mem : : release ( buf ) ;
}
cw : : flow : : mbuf_t * cw : : flow : : mbuf_duplicate ( const mbuf_t * src )
{
return mbuf_create ( src - > msgA , src - > msgN ) ;
}
2021-08-15 20:07:12 +00:00
unsigned cw : : flow : : value_type_label_to_flag ( const char * s )
{
2024-05-06 19:44:53 +00:00
unsigned flags = labelToId ( _typeLabelFlagsA , s , kInvalidTFl ) ;
2021-08-15 20:07:12 +00:00
if ( flags = = kInvalidTFl )
cwLogError ( kInvalidArgRC , " Invalid type flag: '%s' " , cwStringNullGuard ( s ) ) ;
return flags ;
}
2024-04-30 23:58:10 +00:00
const char * cw : : flow : : value_type_flag_to_label ( unsigned flag )
{ return _typeFlagToLabel ( flag ) ; }
2024-05-06 19:44:53 +00:00
cw : : flow : : var_desc_t * cw : : flow : : var_desc_create ( const char * label , const object_t * cfg )
{
var_desc_t * vd = mem : : allocZ < var_desc_t > ( ) ;
vd - > label = label ;
vd - > cfg = cfg ;
return vd ;
}
void cw : : flow : : var_desc_destroy ( var_desc_t * var_desc )
{
if ( var_desc ! = nullptr )
{
mem : : release ( var_desc - > proxyProcLabel ) ;
mem : : release ( var_desc - > proxyVarLabel ) ;
mem : : release ( var_desc ) ;
}
}
unsigned cw : : flow : : var_desc_attr_label_to_flag ( const char * attr_label )
{
return labelToId ( _varDescAttrFlagsA , attr_label , kInvalidVarDescFl ) ;
}
const char * cw : : flow : : var_desc_flag_to_attribute ( unsigned flag )
{
return idToLabel ( _varDescAttrFlagsA , flag , kInvalidVarDescFl ) ;
}
const cw : : idLabelPair_t * cw : : flow : : var_desc_flag_array ( unsigned & array_cnt_ref )
{
array_cnt_ref = sizeof ( _varDescAttrFlagsA ) / sizeof ( _varDescAttrFlagsA [ 0 ] ) ;
return _varDescAttrFlagsA ;
}
void cw : : flow : : class_desc_destroy ( class_desc_t * class_desc )
{
// release the var desc list
var_desc_t * vd0 = class_desc - > varDescL ;
var_desc_t * vd1 = nullptr ;
while ( vd0 ! = nullptr )
{
vd1 = vd0 - > link ;
var_desc_destroy ( vd0 ) ;
vd0 = vd1 ;
}
// release the preset list
2024-05-19 19:24:33 +00:00
class_preset_t * pr0 = class_desc - > presetL ;
class_preset_t * pr1 = nullptr ;
2024-05-06 19:44:53 +00:00
while ( pr0 ! = nullptr )
{
pr1 = pr0 - > link ;
mem : : release ( pr0 ) ;
pr0 = pr1 ;
}
2024-10-12 19:22:17 +00:00
if ( class_desc - > ui ! = nullptr )
{
mem : : release ( class_desc - > ui - > presetA ) ;
mem : : release ( class_desc - > ui ) ;
}
2024-05-06 19:44:53 +00:00
}
2021-08-15 20:07:12 +00:00
cw : : flow : : class_desc_t * cw : : flow : : class_desc_find ( flow_t * p , const char * label )
{
for ( unsigned i = 0 ; i < p - > classDescN ; + + i )
2024-05-05 21:31:42 +00:00
if ( textIsEqual ( p - > classDescA [ i ] . label , label ) )
2021-08-15 20:07:12 +00:00
return p - > classDescA + i ;
2024-05-05 21:31:42 +00:00
2024-09-16 17:43:52 +00:00
for ( unsigned i = 0 ; i < p - > udpDescN ; + + i )
if ( textIsEqual ( p - > udpDescA [ i ] . label , label ) )
return p - > udpDescA + i ;
2024-05-05 21:31:42 +00:00
2021-08-15 20:07:12 +00:00
return nullptr ;
}
2024-05-05 21:31:42 +00:00
const cw : : flow : : var_desc_t * cw : : flow : : var_desc_find ( const class_desc_t * cd , const char * label )
2021-08-15 20:07:12 +00:00
{
2024-05-05 21:31:42 +00:00
const var_desc_t * vd = cd - > varDescL ;
2021-08-15 20:07:12 +00:00
for ( ; vd ! = nullptr ; vd = vd - > link )
if ( textCompare ( vd - > label , label ) = = 0 )
return vd ;
return nullptr ;
}
2024-05-05 21:31:42 +00:00
cw : : flow : : var_desc_t * cw : : flow : : var_desc_find ( class_desc_t * cd , const char * label )
{
return ( var_desc_t * ) var_desc_find ( ( const class_desc_t * ) cd , label ) ;
}
2021-08-15 20:07:12 +00:00
cw : : rc_t cw : : flow : : var_desc_find ( class_desc_t * cd , const char * label , var_desc_t * & vdRef )
{
if ( ( vdRef = var_desc_find ( cd , label ) ) = = nullptr )
return cwLogError ( kInvalidArgRC , " The variable desc. named '%s' could not be found on the class '%s'. " , label , cd - > label ) ;
return kOkRC ;
}
2024-05-19 19:24:33 +00:00
const cw : : flow : : class_preset_t * cw : : flow : : class_preset_find ( const class_desc_t * cd , const char * preset_label )
2024-05-02 17:59:19 +00:00
{
2024-05-19 19:24:33 +00:00
const class_preset_t * pr ;
2024-05-02 17:59:19 +00:00
for ( pr = cd - > presetL ; pr ! = nullptr ; pr = pr - > link )
if ( textCompare ( pr - > label , preset_label ) = = 0 )
return pr ;
return nullptr ;
}
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
void cw : : flow : : class_dict_print ( flow_t * p )
2021-08-15 20:07:12 +00:00
{
for ( unsigned i = 0 ; i < p - > classDescN ; + + i )
2024-05-05 21:31:42 +00:00
_class_desc_print ( p - > classDescA + i ) ;
2024-09-16 17:43:52 +00:00
for ( unsigned i = 0 ; i < p - > udpDescN ; + + i )
_class_desc_print ( p - > udpDescA + i ) ;
2021-08-15 20:07:12 +00:00
}
2024-04-22 20:02:40 +00:00
void cw : : flow : : network_print ( const network_t & net )
2021-08-15 20:07:12 +00:00
{
2024-05-08 14:21:21 +00:00
// for each proc in the network
2024-10-12 19:22:17 +00:00
for ( unsigned i = 0 ; i < net . procN ; + + i )
2021-08-15 20:07:12 +00:00
{
2024-10-12 19:22:17 +00:00
proc_t * proc = net . procA [ i ] ;
2024-05-06 19:44:53 +00:00
proc_print ( proc ) ;
2024-04-22 20:02:40 +00:00
2024-05-08 14:21:21 +00:00
// if this proc has an internal network
2024-05-06 19:44:53 +00:00
if ( proc - > internal_net ! = nullptr )
2024-04-22 20:02:40 +00:00
{
2024-05-10 02:03:08 +00:00
cwLogPrint ( " ------- Begin Nested Network: %s ------- \n " , cwStringNullGuard ( proc - > label ) ) ;
2024-05-06 19:44:53 +00:00
network_print ( * ( proc - > internal_net ) ) ;
2024-05-10 02:03:08 +00:00
cwLogPrint ( " ------- End Nested Network: %s ------- \n " , cwStringNullGuard ( proc - > label ) ) ;
2024-04-22 20:02:40 +00:00
}
2021-08-15 20:07:12 +00:00
2024-04-22 20:02:40 +00:00
}
2024-05-19 19:24:33 +00:00
if ( net . presetN > 0 )
{
cwLogPrint ( " Presets: \n " ) ;
for ( unsigned i = 0 ; i < net . presetN ; + + i )
{
const network_preset_t * net_preset = net . presetA + i ;
cwLogPrint ( " %i %s \n " , i , net_preset - > label ) ;
2024-05-21 22:53:11 +00:00
switch ( net_preset - > tid )
2024-05-19 19:24:33 +00:00
{
2024-05-21 22:53:11 +00:00
case kPresetVListTId :
{
const preset_value_t * net_val = net_preset - > u . vlist . value_head ;
for ( ; net_val ! = nullptr ; net_val = net_val - > link )
{
cwLogPrint ( " %s:%i %s:%i " , cwStringNullGuard ( net_val - > proc - > label ) , net_val - > proc - > label_sfx_id , cwStringNullGuard ( net_val - > var - > label ) , net_val - > var - > label_sfx_id ) ;
_value_print ( & net_val - > value ) ;
cwLogPrint ( " \n " ) ;
}
}
break ;
case kPresetDualTId :
cwLogPrint ( " %s %s %f " , net_preset - > u . dual . pri - > label , net_preset - > u . dual . sec - > label , net_preset - > u . dual . coeff ) ;
break ;
2024-05-19 19:24:33 +00:00
}
}
cwLogPrint ( " \n " ) ;
}
}
2024-07-08 20:57:47 +00:00
void * cw : : flow : : network_global_var ( proc_t * proc , const char * var_label )
{
net_global_var_t * gv ;
assert ( proc - > net ! = nullptr ) ;
for ( gv = proc - > net - > globalVarL ; gv ! = nullptr ; gv = gv - > link )
if ( textIsEqual ( proc - > class_desc - > label , gv - > class_label ) & & textIsEqual ( gv - > var_label , var_label ) )
return gv - > blob ;
return nullptr ;
}
cw : : rc_t cw : : flow : : network_global_var_alloc ( proc_t * proc , const char * var_label , const void * blob , unsigned blobByteN )
{
rc_t rc = kOkRC ;
net_global_var_t * gv ;
void * v ;
unsigned allocWordN = 0 ;
if ( ( v = network_global_var ( proc , var_label ) ) ! = nullptr )
{
rc = cwLogError ( kInvalidArgRC , " The global variable '%s:%s' already exists. " , cwStringNullGuard ( proc - > class_desc - > label ) , cwStringNullGuard ( var_label ) ) ;
goto errLabel ;
}
gv = mem : : allocZ < net_global_var_t > ( ) ;
allocWordN = std : : max ( blobByteN / sizeof ( unsigned ) , 1ul ) ;
gv - > class_label = proc - > class_desc - > label ;
gv - > var_label = mem : : duplStr ( var_label ) ;
gv - > blob = mem : : allocZ < unsigned > ( allocWordN ) ;
gv - > blobByteN = blobByteN ;
memcpy ( gv - > blob , blob , blobByteN ) ;
gv - > link = proc - > net - > globalVarL ;
proc - > net - > globalVarL = gv ;
errLabel :
return rc ;
}
2024-05-19 19:24:33 +00:00
const cw : : flow : : network_preset_t * cw : : flow : : network_preset_from_label ( const network_t & net , const char * preset_label )
{
for ( unsigned i = 0 ; i < net . presetN ; + + i )
if ( textIsEqual ( net . presetA [ i ] . label , preset_label ) )
return net . presetA + i ;
return nullptr ;
}
unsigned cw : : flow : : proc_mult_count ( const network_t & net , const char * proc_label )
{
unsigned multN = 0 ;
2024-10-12 19:22:17 +00:00
for ( unsigned i = 0 ; i < net . procN ; + + i )
if ( textIsEqual ( net . procA [ i ] - > label , proc_label ) )
2024-05-19 19:24:33 +00:00
multN + = 1 ;
return multN ;
}
cw : : rc_t cw : : flow : : proc_mult_sfx_id_array ( const network_t & net , const char * proc_label , unsigned * idA , unsigned idAllocN , unsigned & idN_ref )
{
rc_t rc = kOkRC ;
unsigned multN = 0 ;
idN_ref = 0 ;
2024-10-12 19:22:17 +00:00
for ( unsigned i = 0 ; i < net . procN ; + + i )
if ( textIsEqual ( net . procA [ i ] - > label , proc_label ) )
2024-05-19 19:24:33 +00:00
{
if ( multN > = idAllocN )
{
rc = cwLogError ( kBufTooSmallRC , " The mult-sfx-id result array is too small for the proc:'%s'. " , cwStringNullGuard ( proc_label ) ) ;
goto errLabel ;
}
2024-10-12 19:22:17 +00:00
idA [ multN ] = net . procA [ i ] - > label_sfx_id ;
2024-05-19 19:24:33 +00:00
multN + = 1 ;
}
idN_ref = multN ;
errLabel :
2024-05-29 18:06:54 +00:00
return rc ;
2021-08-15 20:07:12 +00:00
}
2024-09-17 20:33:26 +00:00
unsigned cw : : flow : : network_poly_count ( const network_t & net )
{
unsigned n = 1 ;
for ( const network_t * n0 = net . poly_link ; n0 ! = nullptr ; n0 = n0 - > poly_link )
+ + n ;
return n ;
}
2024-05-06 19:44:53 +00:00
void cw : : flow : : proc_destroy ( proc_t * proc )
{
if ( proc = = nullptr )
return ;
2024-05-24 20:41:42 +00:00
if ( proc - > class_desc - > members ! = nullptr & & proc - > class_desc - > members - > destroy ! = nullptr & & proc - > userPtr ! = nullptr )
2024-05-06 19:44:53 +00:00
proc - > class_desc - > members - > destroy ( proc ) ;
// destroy the proc instance variables
variable_t * var0 = proc - > varL ;
variable_t * var1 = nullptr ;
while ( var0 ! = nullptr )
{
var1 = var0 - > var_link ;
var_destroy ( var0 ) ;
var0 = var1 ;
}
proc - > varL = nullptr ;
mem : : release ( proc - > label ) ;
mem : : release ( proc - > varMapA ) ;
mem : : release ( proc ) ;
}
cw : : rc_t cw : : flow : : proc_validate ( proc_t * proc )
2024-04-30 23:58:10 +00:00
{
rc_t rc = kOkRC ;
2024-05-06 19:44:53 +00:00
for ( variable_t * var = proc - > varL ; var ! = nullptr ; var = var - > var_link )
2024-04-30 23:58:10 +00:00
{
if ( var - > label = = nullptr )
{
rc = cwLogError ( kInvalidStateRC , " A var with no label was encountered. " ) ;
continue ;
}
if ( var - > value = = nullptr )
{
rc = cwLogError ( kInvalidStateRC , " The var '%s:%i' has no value. " , var - > label , var - > label_sfx_id ) ;
continue ;
}
2024-05-02 17:59:19 +00:00
// the assigned value must have exactly one type
2024-04-30 23:58:10 +00:00
if ( ! math : : isPowerOfTwo ( var - > value - > tflag ) )
2021-08-15 20:07:12 +00:00
{
2024-04-30 23:58:10 +00:00
rc = cwLogError ( kInvalidStateRC , " The var '%s:%i' has the invalid type flag:0x%x " , var - > label , var - > label_sfx_id , var - > value - > tflag ) ;
continue ;
}
2024-05-02 17:59:19 +00:00
// if var is using a local value (not connected to a source variable) then the type of the value must be valid with the variable class
2024-05-10 19:52:37 +00:00
if ( ! is_connected_to_source ( var ) & & ! ( var - > varDesc - > type & var - > value - > tflag ) )
2024-04-30 23:58:10 +00:00
{
2024-05-02 17:59:19 +00:00
rc = cwLogError ( kInvalidStateRC , " The value type flag '%s' (0x%x) of '%s:%i-%s:%i' is not found in the variable class type flags: '%s' (0x%x) " ,
2024-04-30 23:58:10 +00:00
_typeFlagToLabel ( var - > value - > tflag ) , var - > value - > tflag ,
2024-05-06 19:44:53 +00:00
var - > proc - > label , var - > proc - > label_sfx_id ,
2024-04-30 23:58:10 +00:00
var - > label , var - > label_sfx_id ,
_typeFlagToLabel ( var - > varDesc - > type ) , var - > varDesc - > type ) ;
continue ;
2021-08-15 20:07:12 +00:00
}
2024-04-30 23:58:10 +00:00
// By setting the var->type field all future assignments to this variable
// must be coercible to this type. See _var_set_template()
var - > type = var - > value - > tflag ;
2021-08-15 20:07:12 +00:00
}
2024-04-30 23:58:10 +00:00
return rc ;
2021-08-15 20:07:12 +00:00
}
2024-05-06 19:44:53 +00:00
cw : : flow : : proc_t * cw : : flow : : proc_find ( network_t & net , const char * proc_label , unsigned sfx_id )
2021-08-15 20:07:12 +00:00
{
2024-09-17 20:33:26 +00:00
2024-10-12 19:22:17 +00:00
for ( unsigned i = 0 ; i < net . procN ; + + i )
2024-09-17 20:33:26 +00:00
{
2024-10-12 19:22:17 +00:00
assert ( net . procA [ i ] ! = nullptr ) ;
2024-09-17 20:33:26 +00:00
2024-10-12 19:22:17 +00:00
if ( net . procA [ i ] - > label_sfx_id = = sfx_id & & textIsEqual ( proc_label , net . procA [ i ] - > label ) )
return net . procA [ i ] ;
2024-09-17 20:33:26 +00:00
}
if ( net . poly_link ! = nullptr )
return proc_find ( * net . poly_link , proc_label , sfx_id ) ;
2021-08-15 20:07:12 +00:00
return nullptr ;
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : proc_find ( network_t & net , const char * proc_label , unsigned sfx_id , proc_t * & procPtrRef )
2021-08-15 20:07:12 +00:00
{
rc_t rc = kOkRC ;
2024-05-06 19:44:53 +00:00
if ( ( procPtrRef = proc_find ( net , proc_label , sfx_id ) ) ! = nullptr )
2021-08-15 20:07:12 +00:00
return rc ;
2024-05-08 14:21:21 +00:00
return cwLogError ( kInvalidArgRC , " The proc '%s:%i' was not found. " , proc_label , sfx_id ) ;
2021-08-15 20:07:12 +00:00
}
2024-04-06 20:07:46 +00:00
cw : : flow : : external_device_t * cw : : flow : : external_device_find ( flow_t * p , const char * device_label , unsigned typeId , unsigned inOrOutFl , const char * midiPortLabel )
2021-12-11 20:17:11 +00:00
{
for ( unsigned i = 0 ; i < p - > deviceN ; + + i )
2024-04-06 20:07:46 +00:00
if ( ( device_label = = nullptr | | cw : : textIsEqual ( p - > deviceA [ i ] . devLabel , device_label ) )
& & p - > deviceA [ i ] . typeId = = typeId
& & cwIsFlag ( p - > deviceA [ i ] . flags , inOrOutFl )
& & ( midiPortLabel = = nullptr | | cw : : textIsEqual ( p - > deviceA [ i ] . portLabel , midiPortLabel ) ) )
2021-12-11 20:17:11 +00:00
return p - > deviceA + i ;
cwLogError ( kInvalidArgRC , " The %s device named '%s' could not be found. " , cwIsFlag ( inOrOutFl , kInFl ) ? " in " : " out " , device_label ) ;
return nullptr ;
}
2021-08-23 02:41:33 +00:00
2024-05-06 19:44:53 +00:00
void cw : : flow : : proc_print ( proc_t * proc )
2021-08-15 20:07:12 +00:00
{
2024-05-10 02:03:08 +00:00
cwLogPrint ( " %s:%i \n " , proc - > label , proc - > label_sfx_id ) ;
2024-05-06 19:44:53 +00:00
for ( variable_t * var = proc - > varL ; var ! = nullptr ; var = var - > var_link )
2021-08-23 02:41:33 +00:00
if ( var - > chIdx = = kAnyChIdx )
for ( variable_t * v0 = var ; v0 ! = nullptr ; v0 = v0 - > ch_link )
_var_print ( v0 ) ;
2024-05-06 19:44:53 +00:00
if ( proc - > class_desc - > members - > report )
proc - > class_desc - > members - > report ( proc ) ;
2021-08-23 02:41:33 +00:00
}
2024-05-06 19:44:53 +00:00
unsigned cw : : flow : : proc_var_count ( proc_t * proc )
2024-04-30 23:58:10 +00:00
{
unsigned n = 0 ;
2024-05-06 19:44:53 +00:00
for ( variable_t * var = proc - > varL ; var ! = nullptr ; var = var - > var_link )
2024-04-30 23:58:10 +00:00
+ + n ;
return n ;
2021-08-23 02:41:33 +00:00
}
2024-05-10 02:03:08 +00:00
char * cw : : flow : : proc_expand_filename ( const proc_t * proc , const char * fname )
{
bool useProjDirFl = proc - > ctx - > proj_dir ! = nullptr & & textLength ( fname ) > 1 & & fname [ 0 ] = = ' $ ' ;
char * fn0 = nullptr ;
if ( useProjDirFl )
fn0 = filesys : : makeFn ( proc - > ctx - > proj_dir , fname + 1 , nullptr , nullptr ) ;
char * fn1 = filesys : : expandPath ( useProjDirFl ? fn0 : fname ) ;
2021-12-11 20:17:11 +00:00
2024-05-10 02:03:08 +00:00
mem : : release ( fn0 ) ;
return fn1 ;
}
2021-12-11 20:17:11 +00:00
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_create ( proc_t * proc , const char * var_label , unsigned sfx_id , unsigned id , unsigned chIdx , const object_t * value_cfg , unsigned altTypeFl , variable_t * & varRef )
{
rc_t rc = kOkRC ;
rc = _var_create ( proc , var_label , sfx_id , id , chIdx , value_cfg , altTypeFl , varRef ) ;
return rc ;
}
2021-12-11 20:17:11 +00:00
2024-05-06 19:44:53 +00:00
void cw : : flow : : var_destroy ( variable_t * var )
2021-08-23 02:41:33 +00:00
{
if ( var ! = nullptr )
2021-08-15 20:07:12 +00:00
{
2022-01-22 14:49:45 +00:00
for ( unsigned i = 0 ; i < kLocalValueN ; + + i )
_value_release ( var - > local_value + i ) ;
2024-04-30 23:58:10 +00:00
if ( var - > localVarDesc ! = nullptr )
mem : : release ( var - > localVarDesc ) ;
2021-08-23 02:41:33 +00:00
mem : : release ( var - > label ) ;
mem : : release ( var ) ;
2021-08-15 20:07:12 +00:00
}
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_channelize ( proc_t * proc , const char * var_label , unsigned sfx_id , unsigned chIdx , const object_t * value_cfg , unsigned vid , variable_t * & varRef )
2021-08-23 02:41:33 +00:00
{
rc_t rc = kOkRC ;
2021-08-15 20:07:12 +00:00
variable_t * var = nullptr ;
2021-08-23 02:41:33 +00:00
variable_t * base_var = nullptr ;
varRef = nullptr ;
2021-08-15 20:07:12 +00:00
2024-05-06 19:44:53 +00:00
if ( ( base_var = _var_find_on_label_and_ch ( proc , var_label , sfx_id , kAnyChIdx ) ) = = nullptr )
2021-08-15 20:07:12 +00:00
{
2024-05-06 19:44:53 +00:00
rc = cwLogError ( kInvalidStateRC , " The base ('any') channel variable could not be located on '%s:%i.%s:%i'. " , proc - > label , proc - > label_sfx_id , var_label , sfx_id ) ;
2021-08-15 20:07:12 +00:00
goto errLabel ;
}
2024-04-26 21:04:03 +00:00
2021-08-23 02:41:33 +00:00
// locate the variable with the stated chIdx
2024-05-06 19:44:53 +00:00
var = _var_find_on_label_and_ch ( proc , var_label , sfx_id , chIdx ) ;
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
// 'src' variables cannot be channelized
2024-05-02 17:59:19 +00:00
/*
2021-08-23 02:41:33 +00:00
if ( cwIsFlag ( base_var - > varDesc - > flags , kSrcVarFl ) )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
rc = cwLogError ( rc , " 'src' variables cannot be channelized. " ) ;
2021-08-15 20:07:12 +00:00
goto errLabel ;
}
2024-05-02 17:59:19 +00:00
*/
2021-08-23 02:41:33 +00:00
// if the requested var was not found then create a new variable with the requested channel index
if ( var = = nullptr & & chIdx ! = kAnyChIdx )
{
// create the channelized var
2024-05-06 19:44:53 +00:00
if ( ( rc = _var_create ( proc , var_label , sfx_id , vid , chIdx , value_cfg , kInvalidTFl , var ) ) ! = kOkRC )
2021-08-23 02:41:33 +00:00
goto errLabel ;
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
// if no value was set then set the value from the 'any' channel
if ( value_cfg = = nullptr )
{
2024-05-02 17:59:19 +00:00
// if the base-var is connected to a source ...
2024-05-10 19:52:37 +00:00
if ( is_connected_to_source ( base_var ) )
2024-05-02 17:59:19 +00:00
{
// ... then connect the new var to a source also
// Attempt to find a matching channel on the source
variable_t * src_ch_var = base_var - > src_var ;
variable_t * last_src_ch_var = base_var - > src_var ;
2024-05-06 19:44:53 +00:00
unsigned src_ch_cnt = 0 ;
bool anyChFl = false ;
bool zeroChFl = false ;
2024-05-02 17:59:19 +00:00
for ( ; src_ch_var ! = nullptr ; src_ch_var = src_ch_var - > ch_link )
{
last_src_ch_var = src_ch_var ;
if ( src_ch_var - > chIdx = = var - > chIdx )
break ;
2024-05-06 19:44:53 +00:00
if ( src_ch_var - > chIdx = = kAnyChIdx )
anyChFl = true ;
2021-08-15 20:07:12 +00:00
2024-05-06 19:44:53 +00:00
if ( src_ch_var - > chIdx = = 0 )
zeroChFl = true ;
2024-05-02 17:59:19 +00:00
src_ch_cnt + = 1 ;
}
2024-05-06 19:44:53 +00:00
// If there is more than one channel available, in addition to the kAnyCh, and the src and dst var's do not have matching ch indexes
2024-05-02 17:59:19 +00:00
// then there is a possibility that this is an unexpected connection between different channels.
2024-05-06 19:44:53 +00:00
// However if there only any-ch and/or ch=0 is available then this is simply a one channel to many channels which is common.
if ( src_ch_var = = nullptr & & ( anyChFl = = false | | ( src_ch_cnt > 1 & & zeroChFl = = false ) ) & & last_src_ch_var - > chIdx ! = var - > chIdx )
{
cwLogWarning ( " A connection is being made where channel src and dst. channels don't match and more than one src channel is available. src:%s:%i-%s:%i ch:%i of %i dst:%s:%i-%s:%i ch:%i " ,
last_src_ch_var - > proc - > label , last_src_ch_var - > proc - > label_sfx_id ,
last_src_ch_var - > label , last_src_ch_var - > label_sfx_id , last_src_ch_var - > chIdx , src_ch_cnt ,
var - > proc - > label , var - > proc - > label_sfx_id ,
var - > label , var - > label_sfx_id , var - > chIdx ) ;
}
2024-05-02 17:59:19 +00:00
// if no matching channel is found connect to the last valid source channel
// (Connecting to the last valid source is better than connecting to base_var->src_var
// because if a var has more than a base var it is unlikely to update the base_var.)
var_connect ( last_src_ch_var , var ) ;
}
2024-05-24 20:41:42 +00:00
else // the base-var is not connected, and no value was provided for the new var
2024-05-02 17:59:19 +00:00
{
// Set the value of the new variable to the value of the 'any' channel
_value_duplicate ( var - > local_value [ var - > local_value_idx ] , base_var - > local_value [ base_var - > local_value_idx ] ) ;
2021-08-15 20:07:12 +00:00
2024-05-02 17:59:19 +00:00
// If the 'any' channel value was set to point to it's local value then do same with this value
if ( base_var - > local_value + base_var - > local_value_idx = = base_var - > value )
var - > value = var - > local_value + var - > local_value_idx ;
}
2021-08-23 02:41:33 +00:00
}
}
2024-05-24 20:41:42 +00:00
else // the var was found - set the value
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
// a correctly channelized var was found - but we still may need to set the value
if ( value_cfg ! = nullptr )
{
2024-05-24 20:41:42 +00:00
rc = var_set_from_cfg ( var , value_cfg ) ;
2021-08-23 02:41:33 +00:00
}
else
{
2024-06-08 21:00:53 +00:00
cwLogWarning ( " An existing var (%s:%i.%s:%i ch:%i) was specified for channelizing but no value was provided. " , cwStringNullGuard ( proc - > label ) , proc - > label_sfx_id , cwStringNullGuard ( var_label ) , sfx_id , chIdx ) ;
2021-08-23 02:41:33 +00:00
}
2021-08-15 20:07:12 +00:00
}
2021-08-23 02:41:33 +00:00
assert ( var ! = nullptr ) ;
varRef = var ;
errLabel :
if ( rc ! = kOkRC )
2024-05-08 14:21:21 +00:00
rc = cwLogError ( rc , " Channelize failed for variable '%s:%i' on proc '%s:%i' ch:%i. " , var_label , sfx_id , proc - > label , proc - > label_sfx_id , chIdx ) ;
2021-08-23 02:41:33 +00:00
2021-08-15 20:07:12 +00:00
return rc ;
}
2024-10-12 19:22:17 +00:00
unsigned cw : : flow : : var_channel_count ( proc_t * proc , const char * var_label , unsigned sfx_id )
{
rc_t rc = kOkRC ;
unsigned chN = kInvalidCnt ;
variable_t * base_var = nullptr ;
if ( ( rc = _var_find_on_label_and_ch ( proc , var_label , sfx_id , kAnyChIdx , base_var ) ) ! = kOkRC | | base_var = = nullptr )
{
cwLogError ( rc , " Var. channel count calc failed. " ) ;
goto errLabel ;
}
chN = 0 ;
for ( base_var = base_var - > ch_link ; base_var ! = nullptr ; base_var = base_var - > ch_link )
if ( base_var - > chIdx + 1 > chN )
chN = base_var - > chIdx + 1 ;
errLabel :
return chN ;
}
2024-04-30 23:58:10 +00:00
cw : : rc_t cw : : flow : : var_call_custom_value_func ( variable_t * var )
{
rc_t rc ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var - > proc - > class_desc - > members - > value ( var - > proc , var ) ) ! = kOkRC )
2024-04-30 23:58:10 +00:00
goto errLabel ;
if ( var - > flags & kLogVarFl )
2024-09-12 21:18:42 +00:00
{
if ( var - > proc - > ctx - > printLogHdrFl )
{
cwLogPrint ( " %s " , " exe cycle: process: id: variable: id vid ch : : : type:value : destination \n " ) ;
cwLogPrint ( " %s " , " ---------- ----------- ----- --------------- -- --- ----- ------------: ------------- \n " ) ;
//: 0 : a: 0: out: 0 vid: 2 ch: -1 : : : <invalid>:
var - > proc - > ctx - > printLogHdrFl = false ;
}
cwLogPrint ( " %8i " , var - > proc - > ctx - > cycleIndex ) ;
2024-05-10 02:03:08 +00:00
cwLogPrint ( " %10s:%5i " , var - > proc - > label , var - > proc - > label_sfx_id ) ;
2024-05-02 17:59:19 +00:00
if ( var - > chIdx = = kAnyChIdx )
2024-05-24 20:41:42 +00:00
{
2024-05-02 17:59:19 +00:00
_var_print ( var ) ;
2024-05-24 20:41:42 +00:00
}
2024-05-02 17:59:19 +00:00
else
{
printf ( " \n " ) ;
for ( variable_t * ch_var = var ; ch_var ! = nullptr ; ch_var = ch_var - > ch_link )
2024-05-24 20:41:42 +00:00
{
2024-05-02 17:59:19 +00:00
_var_print ( ch_var ) ;
2024-05-24 20:41:42 +00:00
}
2024-05-02 17:59:19 +00:00
}
2024-04-30 23:58:10 +00:00
}
errLabel :
return rc ;
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_flags ( proc_t * proc , unsigned chIdx , const char * var_label , unsigned sfx_id , unsigned & flags_ref )
2024-04-30 23:58:10 +00:00
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
flags_ref = 0 ;
2024-05-06 19:44:53 +00:00
if ( ( rc = _var_find_on_label_and_ch ( proc , var_label , sfx_id , chIdx , var ) ) ! = kOkRC )
2024-04-30 23:58:10 +00:00
goto errLabel ;
flags_ref = var - > flags ;
errLabel :
return rc ;
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_set_flags ( proc_t * proc , unsigned chIdx , const char * var_label , unsigned sfx_id , unsigned flag )
2024-04-30 23:58:10 +00:00
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = _var_find_on_label_and_ch ( proc , var_label , sfx_id , chIdx , var ) ) ! = kOkRC )
2024-04-30 23:58:10 +00:00
goto errLabel ;
var - > flags | = flag ;
errLabel :
return rc ;
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_clr_flags ( proc_t * proc , unsigned chIdx , const char * var_label , unsigned sfx_id , unsigned flag )
2024-04-30 23:58:10 +00:00
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
2021-08-23 02:41:33 +00:00
2024-05-06 19:44:53 +00:00
if ( ( rc = _var_find_on_label_and_ch ( proc , var_label , sfx_id , chIdx , var ) ) ! = kOkRC )
2024-04-30 23:58:10 +00:00
goto errLabel ;
var - > flags = cwClrFlag ( var - > flags , flag ) ;
errLabel :
2021-08-15 20:07:12 +00:00
return rc ;
}
2024-05-06 19:44:53 +00:00
bool cw : : flow : : var_exists ( proc_t * proc , const char * label , unsigned sfx_id , unsigned chIdx )
{ return _var_find_on_label_and_ch ( proc , label , sfx_id , chIdx ) ! = nullptr ; }
2021-08-15 20:07:12 +00:00
2024-05-06 19:44:53 +00:00
bool cw : : flow : : var_has_value ( proc_t * proc , const char * label , unsigned sfx_id , unsigned chIdx )
2022-11-11 18:09:07 +00:00
{
variable_t * varPtr = nullptr ;
rc_t rc ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , label , sfx_id , chIdx , varPtr ) ) ! = kOkRC )
2022-11-11 18:09:07 +00:00
return false ;
return varPtr - > value ! = nullptr ;
}
2024-05-06 19:44:53 +00:00
bool cw : : flow : : var_is_a_source ( proc_t * proc , const char * label , unsigned sfx_id , unsigned chIdx )
2024-04-26 21:04:03 +00:00
{
rc_t rc ;
variable_t * varPtr = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , label , sfx_id , chIdx , varPtr ) ) ! = kOkRC )
2024-04-26 21:04:03 +00:00
{
2024-05-06 19:44:53 +00:00
cwLogError ( kEleNotFoundRC , " The variable '%s:%i' was not found on proc:'%s:%i'. 'source' state query is invalid. " , cwStringNullGuard ( label ) , sfx_id , cwStringNullGuard ( proc - > label ) , proc - > label_sfx_id ) ;
2024-04-26 21:04:03 +00:00
return false ;
}
return is_a_source_var ( varPtr ) ;
}
2024-05-06 19:44:53 +00:00
bool cw : : flow : : var_is_a_source ( proc_t * proc , unsigned vid , unsigned chIdx )
2024-04-26 21:04:03 +00:00
{
rc_t rc ;
variable_t * varPtr = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , vid , chIdx , varPtr ) ) ! = kOkRC )
2024-04-26 21:04:03 +00:00
{
2024-05-06 19:44:53 +00:00
cwLogError ( kEleNotFoundRC , " The variable with vid '%i' was not found on proc:'%s:%i'. 'source' state query is invalid. " , vid , cwStringNullGuard ( proc - > label ) , proc - > label_sfx_id ) ;
2024-04-26 21:04:03 +00:00
return false ;
}
return is_a_source_var ( varPtr ) ;
}
2021-08-15 20:07:12 +00:00
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_find ( proc_t * proc , unsigned vid , unsigned chIdx , variable_t * & varRef )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
rc_t rc = kOkRC ;
unsigned idx = kInvalidIdx ;
2021-08-15 20:07:12 +00:00
variable_t * var = nullptr ;
2021-08-23 02:41:33 +00:00
varRef = nullptr ;
2021-08-15 20:07:12 +00:00
2024-05-08 14:21:21 +00:00
// if the varMapA[] has not yet been formed (we are inside the proc constructor) then do a slow lookup of the variable
2024-05-06 19:44:53 +00:00
if ( proc - > varMapA = = nullptr )
2021-08-23 02:41:33 +00:00
{
2024-05-06 19:44:53 +00:00
if ( ( rc = _var_find_on_vid_and_ch ( proc , vid , chIdx , var ) ) ! = kOkRC )
2021-08-23 02:41:33 +00:00
goto errLabel ;
}
else
{
2024-05-06 19:44:53 +00:00
// otherwise do a fast lookup using proc->varMapA[]
if ( ( rc = _var_map_id_to_index ( proc , vid , chIdx , idx ) ) = = kOkRC & & ( idx ! = kInvalidIdx ) )
var = proc - > varMapA [ idx ] ;
2021-08-23 02:41:33 +00:00
else
{
2024-05-08 14:21:21 +00:00
rc = cwLogError ( kInvalidIdRC , " The index of variable vid:%i chIdx:%i on proc '%s:%i' could not be calculated and the variable value could not be retrieved. " , vid , chIdx , proc - > label , proc - > label_sfx_id ) ;
2021-08-23 02:41:33 +00:00
goto errLabel ;
}
}
2021-08-15 20:07:12 +00:00
2024-05-02 17:59:19 +00:00
// if we get here var must be non-null - (was the var registered?)
2021-08-23 02:41:33 +00:00
assert ( var ! = nullptr & & rc = = kOkRC ) ;
varRef = var ;
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
errLabel :
2021-08-15 20:07:12 +00:00
return rc ;
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_find ( proc_t * proc , const char * label , unsigned sfx_id , unsigned chIdx , variable_t * & vRef )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
variable_t * var ;
vRef = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( var = _var_find_on_label_and_ch ( proc , label , sfx_id , chIdx ) ) ! = nullptr )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
vRef = var ;
return kOkRC ;
2021-08-15 20:07:12 +00:00
}
2021-08-23 02:41:33 +00:00
2024-05-08 14:21:21 +00:00
return cwLogError ( kInvalidIdRC , " The proc '%s:%i' does not have a variable named '%s:%i'. " , proc - > label , proc - > label_sfx_id , label , sfx_id ) ;
2021-08-15 20:07:12 +00:00
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_find ( proc_t * proc , const char * label , unsigned sfx_id , unsigned chIdx , const variable_t * & vRef )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
variable_t * v = nullptr ;
2024-05-06 19:44:53 +00:00
rc_t rc = var_find ( proc , label , sfx_id , chIdx , v ) ;
2021-08-23 02:41:33 +00:00
vRef = v ;
2021-08-15 20:07:12 +00:00
return rc ;
}
2024-04-22 20:02:40 +00:00
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_channel_count ( proc_t * proc , const char * label , unsigned sfx_id , unsigned & chCntRef )
2022-01-22 14:49:45 +00:00
{
rc_t rc = kOkRC ;
const variable_t * var = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , label , sfx_id , kAnyChIdx , var ) ) ! = kOkRC )
return cwLogError ( rc , " Channel count was not available because the variable '%s:%i.%s:%i' does not exist. " , cwStringNullGuard ( proc - > label ) , proc - > label_sfx_id , cwStringNullGuard ( label ) , sfx_id ) ;
2022-01-22 14:49:45 +00:00
return var_channel_count ( var , chCntRef ) ;
}
cw : : rc_t cw : : flow : : var_channel_count ( const variable_t * var , unsigned & chCntRef )
{
rc_t rc = kOkRC ;
const variable_t * v ;
chCntRef = 0 ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( var - > proc , var - > label , var - > label_sfx_id , kAnyChIdx , v ) ) ! = kOkRC )
2022-01-22 14:49:45 +00:00
{
2024-05-08 14:21:21 +00:00
rc = cwLogError ( kInvalidStateRC , " The base channel variable proc could not be found for the variable '%s:%i.%s:%i'. " , var - > proc - > label , var - > proc - > label_sfx_id , var - > label , var - > label_sfx_id ) ;
2022-01-22 14:49:45 +00:00
goto errLabel ;
}
for ( v = v - > ch_link ; v ! = nullptr ; v = v - > ch_link )
chCntRef + = 1 ;
errLabel :
return rc ;
}
2021-08-23 02:41:33 +00:00
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_register ( proc_t * proc , const char * var_label , unsigned sfx_id , unsigned vid , unsigned chIdx , const object_t * value_cfg , variable_t * & varRef )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
rc_t rc = kOkRC ;
2021-08-15 20:07:12 +00:00
variable_t * var = nullptr ;
varRef = nullptr ;
2024-05-08 14:21:21 +00:00
// TODO: check for duplicate 'vid'-'chIdx' pairs on this proc
2021-08-23 02:41:33 +00:00
// The concatenation of 'vid' and 'chIdx' should be unique
// if an exact match to label/chIdx was found
2024-05-06 19:44:53 +00:00
if ( ( var = _var_find_on_label_and_ch ( proc , var_label , sfx_id , chIdx ) ) ! = nullptr )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
// if a value was given - then update the value
if ( value_cfg ! = nullptr )
2024-05-24 20:41:42 +00:00
if ( ( rc = var_set_from_cfg ( var , value_cfg ) ) ! = kOkRC )
2021-08-23 02:41:33 +00:00
goto errLabel ;
}
else // an exact match was not found - channelize the variable
{
2024-06-08 21:00:53 +00:00
// if the kAnyChIdx has not been created for this variable ...
if ( ( var = _var_find_on_label_and_ch ( proc , var_label , sfx_id , kAnyChIdx ) ) = = nullptr )
{
variable_t * dum = nullptr ;
// ... then create it here
if ( ( rc = var_create ( proc , var_label , sfx_id , kInvalidId , kAnyChIdx , nullptr , kInvalidTFl , dum ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " An attempt to create the 'any-channel' for '%s:%i' failed. " , cwStringNullGuard ( var_label ) , sfx_id ) ;
goto errLabel ;
}
2024-06-09 20:21:40 +00:00
// if the var being registered is on channel kAnyChIdx
2024-06-08 21:00:53 +00:00
if ( chIdx = = kAnyChIdx )
var = dum ;
}
// don't channelize kAnyChIdx because it must already exist
if ( chIdx ! = kAnyChIdx )
if ( ( rc = var_channelize ( proc , var_label , sfx_id , chIdx , value_cfg , vid , var ) ) ! = kOkRC )
goto errLabel ;
2021-08-15 20:07:12 +00:00
}
2024-06-08 21:00:53 +00:00
assert ( var ! = nullptr ) ;
2021-08-23 02:41:33 +00:00
var - > vid = vid ;
varRef = var ;
2021-12-30 02:52:46 +00:00
2024-06-09 20:21:40 +00:00
// The kAnyChIdx shares the 'vid' with channelized variables - this is by design (vids are unique across variables, but shared across channels)
if ( ( var = _var_find_on_label_and_ch ( proc , var_label , sfx_id , kAnyChIdx ) ) = = nullptr )
2024-05-08 14:21:21 +00:00
rc = cwLogError ( kInvalidStateRC , " The variable '%s:%i' proc '%s:%i' has no base channel. " , var_label , sfx_id , proc - > label , proc - > label_sfx_id , chIdx ) ;
2024-06-09 20:21:40 +00:00
else
{
var - > vid = vid ; // ... this guarantee's that the kAnyChIdx variable has a valid vid
}
2021-08-23 02:41:33 +00:00
errLabel :
if ( rc ! = kOkRC )
2024-05-08 14:21:21 +00:00
rc = cwLogError ( rc , " Registration failed on variable '%s:%i' proc '%s:%i' ch: %i. " , var_label , sfx_id , proc - > label , proc - > label_sfx_id , chIdx ) ;
2021-08-23 02:41:33 +00:00
2021-08-15 20:07:12 +00:00
return rc ;
}
2024-05-10 19:52:37 +00:00
bool cw : : flow : : is_connected_to_source ( const variable_t * var )
2024-04-30 23:58:10 +00:00
{
// if this var does not have a 'src_ptr' then it can't be connected to an external proc
if ( var - > src_var = = nullptr | | var - > value = = nullptr )
return false ;
// if this var is using a local value then it can't be connected to an external proc
for ( unsigned i = 0 ; i < kLocalValueN ; + + i )
if ( var - > value = = var - > local_value + i )
return false ;
return true ;
}
bool cw : : flow : : is_a_source_var ( const variable_t * var )
{ return var - > dst_head ! = nullptr ; }
2024-05-02 17:59:19 +00:00
void cw : : flow : : var_connect ( variable_t * src_var , variable_t * in_var )
{
assert ( in_var - > dst_link = = nullptr ) ;
// connect in_var into src_var's outgoing var chain
if ( src_var - > dst_head = = nullptr )
src_var - > dst_head = in_var ;
else
src_var - > dst_tail - > dst_link = in_var ;
src_var - > dst_tail = in_var ;
in_var - > value = src_var - > value ;
2024-05-10 19:52:37 +00:00
in_var - > src_var = src_var ;
}
2024-05-02 17:59:19 +00:00
2024-05-10 19:52:37 +00:00
void cw : : flow : : var_disconnect ( variable_t * in_var )
{
if ( in_var - > src_var ! = nullptr )
{
// remote the in_var from the src var's output list
variable_t * v0 = nullptr ;
variable_t * v = in_var - > src_var - > dst_head ;
for ( ; v ! = nullptr ; v = v - > dst_link )
{
if ( v = = in_var )
{
if ( v0 = = nullptr )
in_var - > src_var - > dst_head = v - > dst_link ;
else
v0 - > dst_link = v - > dst_link ;
break ;
}
2024-05-02 17:59:19 +00:00
2024-05-10 19:52:37 +00:00
v0 = v ;
}
// the in_var is always in the src-var's output list
assert ( v = = in_var ) ;
2024-05-02 17:59:19 +00:00
2024-05-10 19:52:37 +00:00
in_var - > src_var = nullptr ;
}
2024-05-02 17:59:19 +00:00
}
2024-05-08 14:21:21 +00:00
unsigned cw : : flow : : var_mult_count ( proc_t * proc , const char * var_label )
{
unsigned n = 0 ;
for ( variable_t * var = proc - > varL ; var ! = nullptr ; var = var - > var_link )
if ( textIsEqual ( var - > label , var_label ) )
+ + n ;
return n ;
}
2024-05-02 17:59:19 +00:00
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_mult_sfx_id_array ( proc_t * proc , const char * var_label , unsigned * idA , unsigned idAllocN , unsigned & idN_ref )
2024-04-30 23:58:10 +00:00
{
rc_t rc = kOkRC ;
idN_ref = 0 ;
// for each variable whose 'label' is 'var_label'
2024-05-06 19:44:53 +00:00
for ( variable_t * var = proc - > varL ; var ! = nullptr ; var = var - > var_link )
2024-04-30 23:58:10 +00:00
if ( textIsEqual ( var - > label , var_label ) )
{
// scan idA[] for a matching sfx_id
unsigned i = 0 ;
for ( ; i < idN_ref ; + + i )
if ( idA [ i ] = = var - > label_sfx_id )
break ;
// if the sfx_id of this var has not yet been included in idA[]
if ( i = = idN_ref )
{
// ... and we still have space left in the output arrau
if ( idN_ref > = idAllocN )
{
rc = cwLogError ( kBufTooSmallRC , " The mult-sfx-id result array is too small for the var:'%s'. " , cwStringNullGuard ( var_label ) ) ;
goto errLabel ;
}
// store this sfx_id in idA[]
idA [ idN_ref + + ] = var - > label_sfx_id ;
}
}
errLabel :
if ( rc ! = kOkRC )
idN_ref = 0 ;
return rc ;
}
2021-08-15 20:07:12 +00:00
2024-10-14 18:18:45 +00:00
cw : : rc_t cw : : flow : : var_send_to_ui ( variable_t * var )
{
// var->ui_var_link is set to null when the var is removed from the list
// 1. Atomically set _head to the new node and return 'old-head'
variable_t * prev = var - > proc - > ctx - > ui_var_head . exchange ( var , std : : memory_order_acq_rel ) ;
// Note that at this point only the new node may have the 'old-head' as it's predecssor.
// Other threads may therefore safely interrupt at this point.
// 2. Set the old-head next pointer to the new node (thereby adding the new node to the list)
prev - > ui_var_link . store ( var , std : : memory_order_release ) ; // RELEASE 'next' to consumer
return kOkRC ;
}
cw : : rc_t cw : : flow : : var_send_to_ui ( proc_t * proc , unsigned vid , unsigned chIdx )
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
if ( ( rc = var_find ( proc , vid , chIdx , var ) ) = = kOkRC )
rc = var_send_to_ui ( var ) ;
return rc ;
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_register_and_set ( proc_t * proc , const char * var_label , unsigned sfx_id , unsigned vid , unsigned chIdx , variable_t * & varRef )
2021-08-23 02:41:33 +00:00
{
2024-05-06 19:44:53 +00:00
return var_register ( proc , var_label , sfx_id , vid , chIdx , nullptr , varRef ) ;
2021-08-15 20:07:12 +00:00
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : 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 )
2021-08-15 20:07:12 +00:00
{
2021-08-23 02:41:33 +00:00
rc_t rc = kOkRC ;
abuf_t * abuf ;
if ( ( abuf = abuf_create ( srate , chN , frameN ) ) = = nullptr )
2024-05-08 14:21:21 +00:00
return cwLogError ( kOpFailRC , " abuf create failed on proc:'%s:%i' variable:'%s:%i'. " , proc - > label , proc - > label_sfx_id , var_label , sfx_id ) ;
2021-08-15 20:07:12 +00:00
2024-05-06 19:44:53 +00:00
if ( ( rc = _var_register_and_set ( proc , var_label , sfx_id , vid , chIdx , abuf ) ) ! = kOkRC )
2021-08-23 02:41:33 +00:00
abuf_destroy ( abuf ) ;
2021-08-15 20:07:12 +00:00
return rc ;
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : 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 , const fd_sample_t * * phsV , const fd_sample_t * * hzV )
2021-08-15 20:07:12 +00:00
{
rc_t rc = kOkRC ;
2021-08-23 02:41:33 +00:00
fbuf_t * fbuf ;
2022-12-27 23:09:31 +00:00
if ( ( fbuf = fbuf_create ( srate , chN , maxBinN_V , binN_V , hopSmpN_V , magV , phsV , hzV ) ) = = nullptr )
2024-05-08 14:21:21 +00:00
return cwLogError ( kOpFailRC , " fbuf create failed on proc:'%s:%i' variable:'%s:%i'. " , proc - > label , proc - > label_sfx_id , var_label , sfx_id ) ;
2021-08-15 20:07:12 +00:00
2024-05-06 19:44:53 +00:00
if ( ( rc = _var_register_and_set ( proc , var_label , sfx_id , vid , chIdx , fbuf ) ) ! = kOkRC )
2021-08-23 02:41:33 +00:00
fbuf_destroy ( fbuf ) ;
2021-08-15 20:07:12 +00:00
return rc ;
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_register_and_set ( proc_t * proc , const char * var_label , unsigned sfx_id , unsigned vid , unsigned chIdx , midi : : ch_msg_t * msgA , unsigned msgN )
2024-04-06 20:07:46 +00:00
{
rc_t rc = kOkRC ;
mbuf_t * mbuf ;
if ( ( mbuf = mbuf_create ( msgA , msgN ) ) = = nullptr )
2024-05-08 14:21:21 +00:00
return cwLogError ( kOpFailRC , " mbuf create failed on proc:'%s:%i' variable:'%s:%i'. " , proc - > label , proc - > label_sfx_id , var_label , sfx_id ) ;
2024-04-06 20:07:46 +00:00
2024-05-06 19:44:53 +00:00
if ( ( rc = _var_register_and_set ( proc , var_label , sfx_id , vid , chIdx , mbuf ) ) ! = kOkRC )
2024-04-06 20:07:46 +00:00
mbuf_destroy ( mbuf ) ;
return rc ;
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : 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 , const fd_sample_t * * phsV , const fd_sample_t * * hzV )
2022-12-05 22:19:58 +00:00
{
2022-12-27 23:09:31 +00:00
unsigned maxBinN_V [ chN ] ;
2022-12-05 22:19:58 +00:00
unsigned binN_V [ chN ] ;
unsigned hopSmpN_V [ chN ] ;
2022-12-27 23:09:31 +00:00
vop : : fill ( maxBinN_V , chN , maxBinN ) ;
2022-12-05 22:19:58 +00:00
vop : : fill ( binN_V , chN , binN ) ;
vop : : fill ( hopSmpN_V , chN , hopSmpN ) ;
2024-05-06 19:44:53 +00:00
return var_register_and_set ( proc , var_label , sfx_id , vid , chIdx , srate , chN , maxBinN_V , binN_V , hopSmpN_V , magV , phsV , hzV ) ;
2022-12-05 22:19:58 +00:00
}
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
cw : : rc_t cw : : flow : : var_get ( const variable_t * var , bool & valRef )
2022-01-22 14:49:45 +00:00
{ return _val_get_driver ( var , valRef ) ; }
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
cw : : rc_t cw : : flow : : var_get ( const variable_t * var , uint_t & valRef )
2022-01-22 14:49:45 +00:00
{ return _val_get_driver ( var , valRef ) ; }
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
cw : : rc_t cw : : flow : : var_get ( const variable_t * var , int_t & valRef )
2022-01-22 14:49:45 +00:00
{ return _val_get_driver ( var , valRef ) ; }
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
cw : : rc_t cw : : flow : : var_get ( const variable_t * var , float & valRef )
2022-01-22 14:49:45 +00:00
{ return _val_get_driver ( var , valRef ) ; }
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
cw : : rc_t cw : : flow : : var_get ( const variable_t * var , double & valRef )
2022-01-22 14:49:45 +00:00
{ return _val_get_driver ( var , valRef ) ; }
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
cw : : rc_t cw : : flow : : var_get ( const variable_t * var , const char * & valRef )
2022-01-22 14:49:45 +00:00
{ return _val_get_driver ( var , valRef ) ; }
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
cw : : rc_t cw : : flow : : var_get ( const variable_t * var , const abuf_t * & valRef )
2022-01-22 14:49:45 +00:00
{ return _val_get_driver ( var , valRef ) ; }
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
cw : : rc_t cw : : flow : : var_get ( variable_t * var , abuf_t * & valRef )
2022-01-22 14:49:45 +00:00
{ return _val_get_driver ( var , valRef ) ; }
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
cw : : rc_t cw : : flow : : var_get ( const variable_t * var , const fbuf_t * & valRef )
2022-01-22 14:49:45 +00:00
{ return _val_get_driver ( var , valRef ) ; }
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
cw : : rc_t cw : : flow : : var_get ( variable_t * var , fbuf_t * & valRef )
2022-01-22 14:49:45 +00:00
{ return _val_get_driver ( var , valRef ) ; }
2021-08-15 20:07:12 +00:00
2024-04-06 20:07:46 +00:00
cw : : rc_t cw : : flow : : var_get ( const variable_t * var , const mbuf_t * & valRef )
{ return _val_get_driver ( var , valRef ) ; }
cw : : rc_t cw : : flow : : var_get ( variable_t * var , mbuf_t * & valRef )
{ return _val_get_driver ( var , valRef ) ; }
2024-04-30 23:58:10 +00:00
cw : : rc_t cw : : flow : : var_get ( const variable_t * var , const object_t * & valRef )
{ return _val_get_driver ( var , valRef ) ; }
2024-05-19 19:24:33 +00:00
cw : : rc_t cw : : flow : : cfg_to_value ( const object_t * cfg , value_t & value_ref )
{
rc_t rc = kOkRC ;
switch ( cfg - > type - > id )
{
case kCharTId :
case kUInt8TId :
case kUInt16TId :
case kUInt32TId :
value_ref . tflag = kUIntTFl ;
if ( ( rc = cfg - > value ( value_ref . u . u ) ) ! = kOkRC )
rc = cwLogError ( rc , " Conversion to uint failed. " ) ;
break ;
case kInt8TId :
case kInt16TId :
case kInt32TId :
2024-05-21 22:53:11 +00:00
value_ref . tflag = kIntTFl ;
2024-05-19 19:24:33 +00:00
if ( ( rc = cfg - > value ( value_ref . u . i ) ) ! = kOkRC )
rc = cwLogError ( rc , " Conversion to int failed. " ) ;
break ;
case kInt64TId :
case kUInt64TId :
rc = cwLogError ( kInvalidArgRC , " The flow system does not currently implement 64bit integers. " ) ;
goto errLabel ;
break ;
case kFloatTId :
value_ref . tflag = kFloatTFl ;
if ( ( rc = cfg - > value ( value_ref . u . f ) ) ! = kOkRC )
rc = cwLogError ( rc , " Conversion to float failed. " ) ;
break ;
case kDoubleTId :
value_ref . tflag = kDoubleTFl ;
if ( ( rc = cfg - > value ( value_ref . u . d ) ) ! = kOkRC )
rc = cwLogError ( rc , " Conversion to double failed. " ) ;
break ;
case kBoolTId :
value_ref . tflag = kBoolTFl ;
if ( ( rc = cfg - > value ( value_ref . u . b ) ) ! = kOkRC )
rc = cwLogError ( rc , " Conversion to bool failed. " ) ;
break ;
case kStringTId :
case kCStringTId :
value_ref . tflag = kStringTFl ;
if ( ( rc = cfg - > value ( value_ref . u . s ) ) ! = kOkRC )
rc = cwLogError ( rc , " Conversion to string failed. " ) ;
break ;
default :
value_ref . tflag = kCfgTFl ;
value_ref . u . cfg = cfg ;
}
errLabel :
return rc ;
}
2024-05-24 20:41:42 +00:00
cw : : rc_t cw : : flow : : var_set_from_cfg ( variable_t * var , const object_t * cfg_value )
2024-05-02 17:59:19 +00:00
{
rc_t rc = kOkRC ;
2024-05-24 20:41:42 +00:00
value_t v ;
2024-05-02 17:59:19 +00:00
2024-05-24 20:41:42 +00:00
if ( ( rc = cfg_to_value ( cfg_value , v ) ) ! = kOkRC )
goto errLabel ;
2024-05-02 17:59:19 +00:00
2024-05-24 20:41:42 +00:00
if ( ( rc = var_set ( var , & v ) ) ! = kOkRC )
goto errLabel ;
2024-05-02 17:59:19 +00:00
errLabel :
if ( rc ! = kOkRC )
2024-05-06 19:44:53 +00:00
rc = cwLogError ( kSyntaxErrorRC , " The %s:%i.%s:%i could not extract a type:%s from a configuration value. " , var - > proc - > label , var - > proc - > label_sfx_id , var - > label , var - > label_sfx_id , _typeFlagToLabel ( var - > varDesc - > type & kTypeMask ) ) ;
2024-05-02 17:59:19 +00:00
return rc ;
}
2024-04-30 23:58:10 +00:00
cw : : rc_t cw : : flow : : var_set ( variable_t * var , const value_t * val )
{
rc_t rc = kOkRC ;
switch ( val - > tflag )
{
case kBoolTFl : rc = _var_set_driver ( var , val - > tflag , val - > u . b ) ; break ;
case kUIntTFl : rc = _var_set_driver ( var , val - > tflag , val - > u . u ) ; break ;
case kIntTFl : rc = _var_set_driver ( var , val - > tflag , val - > u . i ) ; break ;
case kFloatTFl : rc = _var_set_driver ( var , val - > tflag , val - > u . f ) ; break ;
case kDoubleTFl : rc = _var_set_driver ( var , val - > tflag , val - > u . d ) ; break ;
case kStringTFl : rc = _var_set_driver ( var , val - > tflag , val - > u . s ) ; break ;
case kCfgTFl : rc = _var_set_driver ( var , val - > tflag , val - > u . cfg ) ; break ;
case kABufTFl : rc = _var_set_driver ( var , val - > tflag , val - > u . abuf ) ; break ;
case kFBufTFl : rc = _var_set_driver ( var , val - > tflag , val - > u . fbuf ) ; break ;
case kMBufTFl : rc = _var_set_driver ( var , val - > tflag , val - > u . mbuf ) ; break ;
default :
rc = cwLogError ( kNotImplementedRC , " The var_set() from value_t has not been implemented for the type 0x%x. " , val - > tflag ) ;
}
return rc ;
}
cw : : rc_t cw : : flow : : var_set ( variable_t * var , bool val ) { return _var_set_driver ( var , kBoolTFl , val ) ; }
cw : : rc_t cw : : flow : : var_set ( variable_t * var , uint_t val ) { return _var_set_driver ( var , kUIntTFl , val ) ; }
cw : : rc_t cw : : flow : : var_set ( variable_t * var , int_t val ) { return _var_set_driver ( var , kIntTFl , val ) ; }
cw : : rc_t cw : : flow : : var_set ( variable_t * var , float val ) { return _var_set_driver ( var , kFloatTFl , val ) ; }
cw : : rc_t cw : : flow : : var_set ( variable_t * var , double val ) { return _var_set_driver ( var , kDoubleTFl , val ) ; }
cw : : rc_t cw : : flow : : var_set ( variable_t * var , const char * val ) { return _var_set_driver ( var , kStringTFl , val ) ; }
cw : : rc_t cw : : flow : : var_set ( variable_t * var , abuf_t * val ) { return _var_set_driver ( var , kABufTFl , val ) ; }
cw : : rc_t cw : : flow : : var_set ( variable_t * var , fbuf_t * val ) { return _var_set_driver ( var , kFBufTFl , val ) ; }
cw : : rc_t cw : : flow : : var_set ( variable_t * var , mbuf_t * val ) { return _var_set_driver ( var , kMBufTFl , val ) ; }
cw : : rc_t cw : : flow : : var_set ( variable_t * var , const object_t * val ) { return _var_set_driver ( var , kCfgTFl , val ) ; }
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_set ( proc_t * proc , unsigned vid , unsigned chIdx , const value_t * val )
2024-04-30 23:58:10 +00:00
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , vid , chIdx , var ) ) = = kOkRC )
2024-04-30 23:58:10 +00:00
rc = var_set ( var , val ) ;
return rc ;
}
2024-04-06 20:07:46 +00:00
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_set ( proc_t * proc , unsigned vid , unsigned chIdx , bool val )
2021-08-15 20:07:12 +00:00
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , vid , chIdx , var ) ) = = kOkRC )
2024-04-30 23:58:10 +00:00
rc = _var_set_driver ( var , kBoolTFl , val ) ;
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
return rc ;
2021-08-15 20:07:12 +00:00
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_set ( proc_t * proc , unsigned vid , unsigned chIdx , uint_t val )
2021-08-15 20:07:12 +00:00
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , vid , chIdx , var ) ) = = kOkRC )
2024-04-30 23:58:10 +00:00
rc = _var_set_driver ( var , kUIntTFl , val ) ;
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
return rc ;
2021-08-15 20:07:12 +00:00
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_set ( proc_t * proc , unsigned vid , unsigned chIdx , int_t val )
2021-08-15 20:07:12 +00:00
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , vid , chIdx , var ) ) = = kOkRC )
2024-04-30 23:58:10 +00:00
rc = _var_set_driver ( var , kIntTFl , val ) ;
2021-08-15 20:07:12 +00:00
2021-08-23 02:41:33 +00:00
return rc ;
2021-08-15 20:07:12 +00:00
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_set ( proc_t * proc , unsigned vid , unsigned chIdx , float val )
2021-08-15 20:07:12 +00:00
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , vid , chIdx , var ) ) = = kOkRC )
2024-04-30 23:58:10 +00:00
rc = _var_set_driver ( var , kFloatTFl , val ) ;
2021-08-15 20:07:12 +00:00
return rc ;
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_set ( proc_t * proc , unsigned vid , unsigned chIdx , double val )
2021-08-15 20:07:12 +00:00
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , vid , chIdx , var ) ) = = kOkRC )
2024-04-30 23:58:10 +00:00
rc = _var_set_driver ( var , kDoubleTFl , val ) ;
2021-08-15 20:07:12 +00:00
return rc ;
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_set ( proc_t * proc , unsigned vid , unsigned chIdx , const char * val )
2021-08-15 20:07:12 +00:00
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , vid , chIdx , var ) ) = = kOkRC )
2024-04-30 23:58:10 +00:00
rc = _var_set_driver ( var , kStringTFl , val ) ;
2021-08-15 20:07:12 +00:00
return rc ;
}
2024-07-03 18:27:50 +00:00
cw : : rc_t cw : : flow : : var_set ( proc_t * proc , unsigned vid , unsigned chIdx , abuf_t * val )
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
if ( ( rc = var_find ( proc , vid , chIdx , var ) ) = = kOkRC )
rc = _var_set_driver ( var , kABufTFl , val ) ;
return rc ;
}
cw : : rc_t cw : : flow : : var_set ( proc_t * proc , unsigned vid , unsigned chIdx , fbuf_t * val )
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
if ( ( rc = var_find ( proc , vid , chIdx , var ) ) = = kOkRC )
rc = _var_set_driver ( var , kFBufTFl , val ) ;
return rc ;
}
cw : : rc_t cw : : flow : : var_set ( proc_t * proc , unsigned vid , unsigned chIdx , mbuf_t * val )
{
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
if ( ( rc = var_find ( proc , vid , chIdx , var ) ) = = kOkRC )
rc = _var_set_driver ( var , kMBufTFl , val ) ;
return rc ;
}
2024-05-06 19:44:53 +00:00
cw : : rc_t cw : : flow : : var_set ( proc_t * proc , unsigned vid , unsigned chIdx , const object_t * val )
2021-08-15 20:07:12 +00:00
{
2024-04-30 23:58:10 +00:00
rc_t rc = kOkRC ;
variable_t * var = nullptr ;
2021-08-15 20:07:12 +00:00
2024-05-06 19:44:53 +00:00
if ( ( rc = var_find ( proc , vid , chIdx , var ) ) = = kOkRC )
2024-04-30 23:58:10 +00:00
rc = _var_set_driver ( var , kCfgTFl , val ) ;
2021-08-15 20:07:12 +00:00
return rc ;
}
2021-08-23 02:41:33 +00:00
2024-04-30 23:58:10 +00:00
2021-08-23 02:41:33 +00:00