diff --git a/cwFlowTypes.cpp b/cwFlowTypes.cpp index 4994730..585347c 100644 --- a/cwFlowTypes.cpp +++ b/cwFlowTypes.cpp @@ -14,6 +14,7 @@ #include "cwMidiDecls.h" #include "cwFlowDecl.h" #include "cwFlow.h" +#include "cwFlowValue.h" #include "cwFlowTypes.h" @@ -34,685 +35,6 @@ namespace cw }; - idLabelPair_t _typeLabelFlagsA[] = { - - { kBoolTFl, "bool" }, - { kUIntTFl, "uint" }, - { kIntTFl, "int", }, - { kFloatTFl, "float"}, - { kDoubleTFl,"double"}, - - { kBoolMtxTFl, "bool_mtx" }, - { kUIntMtxTFl, "uint_mtx" }, - { kIntMtxTFl, "int_mtx" }, - { kFloatMtxTFl, "float_mtx" }, - { kDoubleMtxTFl,"double_mtx" }, - - { kABufTFl, "audio" }, - { kFBufTFl, "spectrum" }, - { kMBufTFl, "midi" }, - { kStringTFl, "string" }, - { kTimeTFl, "time" }, - { kCfgTFl, "cfg" }, - - // alias types to map to cwDspTypes.h - { kFloatTFl, "srate"}, - { kFloatTFl, "sample"}, - { kFloatTFl, "coeff"}, - { kDoubleTFl, "ftime" }, - - { kNumericTFl, "numeric" }, - { kAllTFl, "all" }, - - { kRuntimeTFl, "runtime" }, - - { kInvalidTFl, "" } - }; - - const char* _typeFlagToLabel( unsigned flag ) - { - return idToLabel(_typeLabelFlagsA,flag,kInvalidTFl); - } - - - void _value_release( value_t* v ) - { - if( v == nullptr ) - return; - - switch( v->tflag & kTypeMask ) - { - case kInvalidTFl: - break; - - case kBoolTFl: - case kUIntTFl: - case kIntTFl: - case kFloatTFl: - case kDoubleTFl: - break; - - case kABufTFl: - abuf_destroy( v->u.abuf ); - break; - - case kFBufTFl: - fbuf_destroy( v->u.fbuf ); - break; - - case kMBufTFl: - mbuf_destroy( v->u.mbuf ); - break; - - case kBoolMtxTFl: - case kUIntMtxTFl: - case kIntMtxTFl: - case kFloatMtxTFl: - case kDoubleMtxTFl: - assert(0); // not implemeneted - break; - - case kStringTFl: - mem::release( v->u.s ); - break; - - case kTimeTFl: - assert(0); - break; - - case kCfgTFl: - break; - - default: - assert(0); - break; - } - - v->tflag = kInvalidTFl; - } - - void _value_duplicate( value_t& dst, const value_t& src ) - { - switch( src.tflag & kTypeMask ) - { - case kInvalidTFl: - break; - - case kBoolTFl: - case kUIntTFl: - case kIntTFl: - case kFloatTFl: - case kDoubleTFl: - dst = src; - break; - - case kABufTFl: - - dst.u.abuf = src.u.abuf == nullptr ? nullptr : abuf_duplicate(dst.u.abuf,src.u.abuf); - dst.tflag = src.tflag; - break; - - case kFBufTFl: - dst.u.fbuf = src.u.fbuf == nullptr ? nullptr : fbuf_duplicate(dst.u.fbuf,src.u.fbuf); - dst.tflag = src.tflag; - break; - - case kMBufTFl: - dst.u.mbuf = src.u.mbuf == nullptr ? nullptr : mbuf_duplicate(src.u.mbuf); - dst.tflag = src.tflag; - break; - - case kBoolMtxTFl: - case kUIntMtxTFl: - case kIntMtxTFl: - case kFloatMtxTFl: - case kDoubleMtxTFl: - assert(0); // not implemeneted - break; - - case kStringTFl: - dst.u.s = mem::duplStr( dst.u.s ); - dst.tflag = src.tflag; - break; - - case kTimeTFl: - assert(0); - break; - - case kCfgTFl: - dst = src; - break; - - default: - assert(0); - break; - } - - } - - void _value_print( const value_t* v, bool info_fl=true ) - { - if( v == nullptr ) - return; - - switch( v->tflag & kTypeMask ) - { - case kInvalidTFl: - cwLogPrint(""); - break; - - 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; - - case kABufTFl: - if( info_fl ) - { - if( v->u.abuf == nullptr ) - cwLogPrint("abuf: "); - else - cwLogPrint("abuf: chN:%i frameN:%i srate:%8.1f ", v->u.abuf->chN, v->u.abuf->frameN, v->u.abuf->srate ); - } - else - { - bool null_fl = v->u.abuf==nullptr || v->u.abuf->buf == nullptr; - cwLogPrint("("); - for(unsigned i=0; iu.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(") "); - } - break; - - case kFBufTFl: - if( info_fl ) - { - if( v->u.fbuf == nullptr ) - cwLogPrint("fbuf: "); - else - { - cwLogPrint("fbuf: chN:%i srate:%8.1f ", v->u.fbuf->chN, v->u.fbuf->srate ); - for(unsigned i=0; iu.fbuf->chN; ++i) - cwLogPrint("(binN:%i hopSmpN:%i) ", v->u.fbuf->binN_V[i], v->u.fbuf->hopSmpN_V[i] ); - } - } - else - { - - bool null_fl = v->u.fbuf==nullptr || v->u.fbuf->magV == nullptr; - cwLogPrint("("); - for(unsigned i=0; iu.fbuf->chN; ++i) - cwLogPrint("%f ",null_fl ? 0.0 : vop::mean(v->u.fbuf->magV[i], v->u.fbuf->binN_V[i])); - cwLogPrint(") "); - - } - break; - - case kMBufTFl: - if( info_fl ) - { - if( v->u.mbuf == nullptr ) - cwLogPrint("mbuf: "); - else - { - cwLogPrint("mbuf: cnt: %i", v->u.mbuf->msgN ); - } - } - else - { - //bool null_fl = v->u.mbuf==nullptr || v->u.mbuf->msgA == nullptr; - for(unsigned i=0; iu.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); - } - break; - - case kBoolMtxTFl: - case kUIntMtxTFl: - case kIntMtxTFl: - case kFloatMtxTFl: - case kDoubleMtxTFl: - assert(0); // not implemeneted - break; - - case kStringTFl: - cwLogPrint("s:%s ", v->u.s); - break; - - case kTimeTFl: - assert(0); - break; - - case kCfgTFl: - cwLogPrint("c:"); - if( v->u.cfg != nullptr ) - v->u.cfg->print(); - break; - - default: - assert(0); - break; - } - - } - - - rc_t _val_get( const value_t* val, bool& valRef ) - { - rc_t rc = kOkRC; - switch( val->tflag & kTypeMask ) - { - 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; - 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; - - default: - rc = cwLogError(kTypeMismatchRC,"A bool could not be converted to a %s (0x%x).",_typeFlagToLabel(val->tflag),val->tflag); - } - - return rc; - } - - rc_t _val_get( const value_t* val, uint_t& valRef ) - { - rc_t rc = kOkRC; - switch( val->tflag & kTypeMask ) - { - 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: - rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to a uint.",_typeFlagToLabel(val->tflag),val->tflag); - } - return rc; - } - - rc_t _val_set( value_t* val, uint_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.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; - } - - rc_t _val_get( const value_t* val, int_t& valRef ) - { - rc_t rc = kOkRC; - switch( val->tflag & kTypeMask ) - { - 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: - rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to an int.",_typeFlagToLabel(val->tflag),val->tflag); - - } - return rc; - } - - 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); - } - - return rc; - } - - - rc_t _val_get( const value_t* val, float& valRef ) - { - rc_t rc = kOkRC; - switch( val->tflag & kTypeMask ) - { - 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: - rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to a float.",_typeFlagToLabel(val->tflag),val->tflag); - } - return rc; - } - - 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; - } - - rc_t _val_get( const value_t* val, double& valRef ) - { - rc_t rc = kOkRC; - switch( val->tflag & kTypeMask ) - { - 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: - rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to a double.",_typeFlagToLabel(val->tflag),val->tflag); - } - return rc; - } - - 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; - } - - rc_t _val_get( const value_t* val, const char*& valRef ) - { - rc_t rc = kOkRC; - if( cwIsFlag(val->tflag & kTypeMask, kStringTFl) ) - valRef = val->u.s; - else - { - rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to a string.",_typeFlagToLabel(val->tflag),val->tflag); - valRef = nullptr; - } - - return rc; - } - - 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; - } - - rc_t _val_get( value_t* val, abuf_t*& valRef ) - { - rc_t rc = kOkRC; - if( cwIsFlag(val->tflag & kTypeMask, kABufTFl) ) - valRef = val->u.abuf; - else - { - rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to an abuf.",_typeFlagToLabel(val->tflag),val->tflag); - 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; - } - - 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; - } - - rc_t _val_get( value_t* val, fbuf_t*& valRef ) - { - rc_t rc = kOkRC; - if( cwIsFlag(val->tflag & kTypeMask, kFBufTFl) ) - valRef = val->u.fbuf; - else - { - valRef = nullptr; - rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to an fbuf.",_typeFlagToLabel(val->tflag),val->tflag); - } - 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; - } - - rc_t _val_set( value_t* val, fbuf_t* v ) - { - rc_t rc = kOkRC; - - switch( val->tflag & kTypeMask ) - { - case kFBufTFl: - val->u.fbuf=v; - break; - - case kInvalidTFl: - val->u.fbuf=v; - val->tflag = kFBufTFl; - break; - - default: - rc = cwLogError(kTypeMismatchRC,"A spectrum signal could not be converted to a %s (0x%x).",_typeFlagToLabel(val->tflag),val->tflag); - } - - return rc; - } - - rc_t _val_get( value_t* val, mbuf_t*& valRef ) - { - rc_t rc = kOkRC; - if( cwIsFlag(val->tflag & kTypeMask, kMBufTFl) ) - valRef = val->u.mbuf; - else - { - valRef = nullptr; - rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to an mbuf.",_typeFlagToLabel(val->tflag),val->tflag); - } - return rc; - } - - rc_t _val_set( value_t* val, mbuf_t* v ) - { - rc_t rc = kOkRC; - - switch( val->tflag & kTypeMask ) - { - 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); - } - - return rc; - } - - - 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; - } - - 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); - - } - return rc; - } - - 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; - - default: - rc = cwLogError(kTypeMismatchRC,"A cfg. could not be converted to a %s (0x%x).",_typeFlagToLabel(val->tflag),val->tflag); - } - - return rc; - } - template< typename T > rc_t _val_get_driver( const variable_t* var, T& valRef ) { @@ -722,7 +44,7 @@ namespace cw if( var->value == nullptr ) 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); - return _val_get(var->value,valRef); + return value_get(var->value,valRef); } @@ -787,9 +109,9 @@ namespace cw cwLogPrint(" %12s:%3i vid:%3i ch:%3i : %s : ", var->label, var->label_sfx_id, var->vid, var->chIdx, conn_label ); if( var->value == nullptr ) - _value_print( &var->local_value[0] ); + value_print( &var->local_value[0] ); else - _value_print( var->value ); + value_print( var->value ); if( var->src_var != nullptr ) 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); @@ -855,7 +177,7 @@ namespace cw // release the previous value in the next slot - _value_release(&var->local_value[next_local_value_idx]); + value_release(&var->local_value[next_local_value_idx]); // if the value type of this variable has not been established if( value_type_flag == kInvalidTFl ) @@ -883,7 +205,7 @@ namespace cw var->local_value[ next_local_value_idx ].tflag = value_type_flag; // set the new local value in var->local_value[next_local_value_idx] - if((rc = _val_set(var->local_value + next_local_value_idx, val )) != kOkRC ) + if((rc = value_set(var->local_value + next_local_value_idx, val )) != kOkRC ) { 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); goto errLabel; @@ -981,7 +303,21 @@ namespace cw return rc; } + + rc_t _var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, rbuf_t* rbuf ) + { + rc_t rc; + variable_t* var = nullptr; + if((rc = var_register_and_set( proc, var_label, sfx_id, vid, chIdx, var)) != kOkRC ) + return rc; + + if( var != nullptr ) + _var_set_driver( var, kRBufTFl, rbuf ); + + return rc; + } + rc_t _var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, fbuf_t* fbuf ) { rc_t rc; @@ -1178,296 +514,13 @@ namespace cw cwLogPrint(" %10s 0x%08x %s %s %s %s\n", cwStringNullGuard(vd->label), vd->type, srcFlStr, srcOptFlStr, plyMltFlStr, cwStringNullGuard(vd->docText) ); } } + + - } -} - -void cw::flow::value_duplicate( value_t& dst, const value_t& src ) -{ - _value_duplicate(dst,src); -} - -void cw::flow::value_print( const value_t* value, bool info_fl) -{ - _value_print(value,info_fl); -} - - -cw::flow::abuf_t* cw::flow::abuf_create( srate_t srate, unsigned chN, unsigned frameN ) -{ - if( chN*frameN == 0 ) - { - cwLogError(kInvalidArgRC,"The %s audio signal parameter cannot be zero.", chN==0 ? "channel count" : "frame count"); - return nullptr; - } - - abuf_t* a = mem::allocZ(); - a->srate = srate; - a->chN = chN; - a->frameN = frameN; - a->bufAllocSmpN = chN*frameN; - - - a->buf = mem::allocZ(a->bufAllocSmpN); - - return a; -} - -void cw::flow::abuf_destroy( abuf_t*& abuf ) -{ - if( abuf == nullptr ) - return; - - mem::release(abuf->buf); - mem::release(abuf); -} - -cw::flow::abuf_t* cw::flow::abuf_duplicate( abuf_t* dst, const abuf_t* src ) -{ - 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; - - if( abuf != nullptr ) - vop::copy(abuf->buf,src->buf,src->chN*src->frameN); - - return abuf; -} - - -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); -} - - -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 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(); - - 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(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; chIdxmagV[ 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; chIdxmagV[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; -} - -/* -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 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(); - - f->srate = srate; - f->chN = chN; - f->maxBinN_V = mem::allocZ(chN); - f->binN_V = mem::allocZ(chN); - f->hopSmpN_V = mem::allocZ(chN); - f->magV = mem::allocZ(chN); - f->phsV = mem::allocZ(chN); - f->hzV = mem::allocZ(chN); - f->readyFlV = mem::allocZ(chN); - - 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( magV != nullptr || phsV != nullptr || hzV != nullptr ) - { - for(unsigned chIdx=0; chIdxmagV[ chIdx ] = (fd_sample_t*)magV[chIdx]; - f->phsV[ chIdx ] = (fd_sample_t*)phsV[chIdx]; - f->hzV[ chIdx ] = (fd_sample_t*)hzV[chIdx]; - } - } - else - { - unsigned maxTotalBinsN = vop::sum( maxBinN_V, chN ); - - fd_sample_t* buf = mem::allocZ( kFbufVectN * maxTotalBinsN ); - fd_sample_t* m = buf; - for(unsigned chIdx=0; chIdxmagV[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 <= buf + kFbufVectN * maxTotalBinsN ); - } - - f->buf = buf; - - } - - return f; -} -*/ - -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 ) -{ - unsigned maxBinN_V[ chN ]; - unsigned binN_V[ chN ]; - unsigned hopSmpN_V[ chN ]; - - vop::fill( maxBinN_V, chN, maxBinN ); - vop::fill( binN_V, chN, binN ); - vop::fill( hopSmpN_V, chN, binN ); - return fbuf_create( srate, chN, maxBinN_V, binN_V, hopSmpN_V, magV, phsV, hzV ); -} - -void cw::flow::fbuf_destroy( fbuf_t*& fbuf ) -{ - if( fbuf == nullptr ) - return; - - mem::release( fbuf->mem); - mem::release( fbuf); -} - -cw::flow::fbuf_t* cw::flow::fbuf_duplicate( fbuf_t* dst, const fbuf_t* src ) -{ - 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; - - for(unsigned i=0; ichN; ++i) - { - fbuf->maxBinN_V[i] = src->maxBinN_V[i]; - 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] ); - } - return fbuf; -} - - -cw::flow::mbuf_t* cw::flow::mbuf_create( const midi::ch_msg_t* msgA, unsigned msgN ) -{ - mbuf_t* m = mem::allocZ(); - 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); -} - -unsigned cw::flow::value_type_label_to_flag( const char* s ) -{ - unsigned flags = labelToId(_typeLabelFlagsA,s,kInvalidTFl); - if( flags == kInvalidTFl ) - cwLogError(kInvalidArgRC,"Invalid type flag: '%s'",cwStringNullGuard(s)); - return flags; -} + } // flow +} // cw -const char* cw::flow::value_type_flag_to_label( unsigned flag ) -{ return _typeFlagToLabel(flag); } cw::flow::var_desc_t* cw::flow::var_desc_create( const char* label, const object_t* cfg ) { @@ -1621,7 +674,7 @@ void cw::flow::network_print( const network_t& net ) 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 ); + value_print( &net_val->value ); cwLogPrint("\n"); } } @@ -1790,10 +843,10 @@ cw::rc_t cw::flow::proc_validate( proc_t* proc ) if( !is_connected_to_source(var) && !(var->varDesc->type & var->value->tflag) ) { 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)", - _typeFlagToLabel(var->value->tflag),var->value->tflag, + value_type_flag_to_label(var->value->tflag),var->value->tflag, var->proc->label,var->proc->label_sfx_id, var->label,var->label_sfx_id, - _typeFlagToLabel(var->varDesc->type),var->varDesc->type); + value_type_flag_to_label(var->varDesc->type),var->varDesc->type); continue; } @@ -1899,7 +952,7 @@ void cw::flow::var_destroy( variable_t* var ) if( var != nullptr ) { for(unsigned i=0; ilocal_value+i); + value_release(var->local_value+i); if( var->localVarDesc != nullptr ) mem::release(var->localVarDesc); @@ -1993,7 +1046,7 @@ cw::rc_t cw::flow::var_channelize( proc_t* proc, const char* var_label, unsigne { // 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 ] ); + value_duplicate( var->local_value[ var->local_value_idx], base_var->local_value[ base_var->local_value_idx ] ); // 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 ) @@ -2512,6 +1565,19 @@ cw::rc_t cw::flow::var_register_and_set( proc_t* proc, const char* var_la return rc; } +cw::rc_t cw::flow::var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, const recd_type_t* recd_type, recd_t* recdA, unsigned recdN ) +{ + rc_t rc = kOkRC; + + rbuf_t* rbuf; + if((rbuf = rbuf_create(recd_type,recdA,recdN)) == nullptr ) + return cwLogError(kOpFailRC,"rbuf create failed on proc:'%s:%i' variable:'%s:%i'.", proc->label, proc->label_sfx_id, var_label, sfx_id); + + if((rc = _var_register_and_set( proc, var_label, sfx_id, vid, chIdx, rbuf )) != kOkRC ) + rbuf_destroy(rbuf); + + return rc; +} 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 ) { @@ -2561,6 +1627,12 @@ cw::rc_t cw::flow::var_get( const variable_t* var, const mbuf_t*& valRef ) cw::rc_t cw::flow::var_get( variable_t* var, mbuf_t*& valRef ) { return _val_get_driver(var,valRef); } +cw::rc_t cw::flow::var_get( const variable_t* var, const rbuf_t*& valRef ) +{ return _val_get_driver(var,valRef); } + +cw::rc_t cw::flow::var_get( variable_t* var, rbuf_t*& valRef ) +{ return _val_get_driver(var,valRef); } + cw::rc_t cw::flow::var_get( const variable_t* var, const object_t*& valRef ) { return _val_get_driver(var,valRef); } @@ -2642,7 +1714,7 @@ cw::rc_t cw::flow::var_set_from_cfg( variable_t* var, const object_t* cfg_value errLabel: if( rc != kOkRC ) - 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)); + 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,value_type_flag_to_label(var->varDesc->type & kTypeMask)); return rc; @@ -2664,6 +1736,7 @@ cw::rc_t cw::flow::var_set( variable_t* var, const value_t* val ) 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; + case kRBufTFl: rc = _var_set_driver(var,val->tflag,val->u.rbuf); break; default: rc = cwLogError(kNotImplementedRC,"The var_set() from value_t has not been implemented for the type 0x%x.",val->tflag); } @@ -2681,6 +1754,7 @@ cw::rc_t cw::flow::var_set( variable_t* var, const char* val ) { return _var 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, rbuf_t* val ) { return _var_set_driver(var,kRBufTFl,val); } cw::rc_t cw::flow::var_set( variable_t* var, const object_t* val ) { return _var_set_driver(var,kCfgTFl,val); } cw::rc_t cw::flow::var_set( proc_t* proc, unsigned vid, unsigned chIdx, const value_t* val ) @@ -2793,6 +1867,16 @@ cw::rc_t cw::flow::var_set( proc_t* proc, unsigned vid, unsigned chIdx, mbuf_t* return rc; } +cw::rc_t cw::flow::var_set( proc_t* proc, unsigned vid, unsigned chIdx, rbuf_t* val ) +{ + rc_t rc = kOkRC; + variable_t* var = nullptr; + + if((rc = var_find(proc, vid, chIdx, var )) == kOkRC ) + rc = _var_set_driver(var,kRBufTFl,val); + + return rc; +} cw::rc_t cw::flow::var_set( proc_t* proc, unsigned vid, unsigned chIdx, const object_t* val ) { diff --git a/cwFlowTypes.h b/cwFlowTypes.h index 68216dd..15e9e19 100644 --- a/cwFlowTypes.h +++ b/cwFlowTypes.h @@ -3,128 +3,6 @@ namespace cw namespace flow { - typedef dsp::coeff_t coeff_t; - typedef dsp::sample_t sample_t; - typedef dsp::fd_sample_t fd_sample_t; - typedef dsp::srate_t srate_t; - typedef dsp::ftime_t ftime_t; - typedef unsigned uint_t; - typedef int int_t; - - - typedef unsigned vid_t; - - enum { - kBaseSfxId = 0, - kFbufVectN = 3, // count of signal vectors in fbuf (mag,phs,hz) - kAnyChIdx = kInvalidIdx, - kLocalValueN = 2, - kDefaultFramesPerCycle=64, - kDefaultSampleRate=48000 - }; - - typedef struct abuf_str - { - srate_t srate; // Signal sample rate - unsigned chN; // Count of channels - unsigned frameN; // Count of sample frames per channel - unsigned bufAllocSmpN; // Size of allocated buf[] in samples. - sample_t* buf; // buf[ chN ][ frameN ] - } abuf_t; - - - typedef struct fbuf_str - { - unsigned memByteN; // Count of bytes in mem[]. - void* mem; // mem[ memByteN ] All dynamically allocated memory used by this fbuf. - - srate_t srate; // signal sample rate - unsigned flags; // See kXXXFbufFl - unsigned chN; // count of channels - unsigned* maxBinN_V; // maxBinN_V[chN] max value that binN_V[i] is allowed to take - unsigned* binN_V; // binN_V[ chN ] count of sample frames per channel - unsigned* hopSmpN_V; // hopSmpN_V[ chN ] hop sample count - fd_sample_t** magV; // magV[ chN ][ binN ] - fd_sample_t** phsV; // phsV[ chN ][ binN ] - fd_sample_t** hzV; // hzV[ chN ][ binN ] - bool* readyFlV; // readyFlV[chN] true if this channel is ready to be processed (used to sync. fbuf rate to abuf rate) - } fbuf_t; - - typedef struct mbuf_str - { - const midi::ch_msg_t* msgA; - unsigned msgN; - } mbuf_t; - - enum - { - kInvalidTFl = 0x00000000, - kBoolTFl = 0x00000001, - kUIntTFl = 0x00000002, - kIntTFl = 0x00000004, - kFloatTFl = 0x00000008, - kDoubleTFl = 0x00000010, - - kBoolMtxTFl = 0x00000020, - kUIntMtxTFl = 0x00000040, - kIntMtxTFl = 0x00000080, - kFloatMtxTFl = 0x00000100, - kDoubleMtxTFl= 0x00000200, - - kABufTFl = 0x00000400, - kFBufTFl = 0x00000800, - kMBufTFl = 0x00001000, - kStringTFl = 0x00002000, - kTimeTFl = 0x00004000, - kCfgTFl = 0x00008000, - - kTypeMask = 0x0000ffff, - - kRuntimeTFl = 0x80000000, - - kNumericTFl = kBoolTFl | kUIntTFl | kIntTFl | kFloatTFl | kDoubleTFl, - kMtxTFl = kBoolMtxTFl | kUIntMtxTFl | kIntMtxTFl | kFloatMtxTFl | kDoubleMtxTFl, - kAllTFl = kTypeMask - }; - - typedef struct mtx_str - { - union { - struct mtx::mtx_str< unsigned >* u; - struct mtx::mtx_str< int >* i; - struct mtx::mtx_str< float >* f; - struct mtx::mtx_str< double >* d; - } u; - } mtx_t; - - typedef struct value_str - { - unsigned tflag; - - union { - bool b; - uint_t u; - int_t i; - float f; - double d; - - mtx_t* mtx; - abuf_t* abuf; - fbuf_t* fbuf; - mbuf_t* mbuf; - - char* s; - - const object_t* cfg; - void* p; - - } u; - - struct value_str* link; - - } value_t; - - struct proc_str; struct variable_str; @@ -390,49 +268,9 @@ namespace cw } flow_t; - //------------------------------------------------------------------------------------------------------------------------ - // - // Value Only - // - - inline void set_null( value_t& v, unsigned tflag ) { v.tflag=tflag; v.u.p=nullptr; } - inline bool is_numeric( const value_t* v ) { return cwIsFlag(v->tflag,kNumericTFl); } - inline bool is_matrix( const value_t* v ) { return cwIsFlag(v->tflag,kMtxTFl); } - - // if all of the src flags are set in the dst flags then the two types are convertable. - inline bool can_convert( unsigned src_tflag, unsigned dst_tflag ) { return (src_tflag&dst_tflag)==src_tflag; } + - abuf_t* abuf_create( srate_t srate, unsigned chN, unsigned frameN ); - void abuf_destroy( abuf_t*& buf ); - - // If 'dst' is null then a new abuf is allocated, filled with the contents of 'src'. - // If 'dst' is non-null and there is enough space for the contents of 'src' then only a copy is executed. - // If there is not enough space then dst is reallocated. - abuf_t* abuf_duplicate( abuf_t* dst, const abuf_t* src ); - rc_t abuf_set_channel( abuf_t* buf, unsigned chIdx, const sample_t* v, unsigned vN ); - const sample_t* abuf_get_channel( abuf_t* buf, unsigned chIdx ); - - fbuf_t* fbuf_create( srate_t srate, unsigned chN, const unsigned* maxBinN_V, const unsigned* binN_V, const unsigned* hopSmpN_V, const fd_sample_t** magV=nullptr, const fd_sample_t** phsV=nullptr, const fd_sample_t** hzV=nullptr ); - fbuf_t* fbuf_create( srate_t srate, unsigned chN, unsigned maxBinN, unsigned binN, unsigned hopSmpN, const fd_sample_t** magV=nullptr, const fd_sample_t** phsV=nullptr, const fd_sample_t** hzV=nullptr ); - void fbuf_destroy( fbuf_t*& buf ); - - // Memory allocation will only occur if dst is null, or the size of dst's internal buffer are too small. - fbuf_t* fbuf_duplicate( fbuf_t* dst, const fbuf_t* src ); - - mbuf_t* mbuf_create( const midi::ch_msg_t* msgA=nullptr, unsigned msgN=0 ); - void mbuf_destroy( mbuf_t*& buf ); - mbuf_t* mbuf_duplicate( const mbuf_t* src ); - - inline bool value_is_abuf( const value_t* v ) { return v->tflag & kABufTFl; } - inline bool value_is_fbuf( const value_t* v ) { return v->tflag & kFBufTFl; } - - unsigned value_type_label_to_flag( const char* type_desc ); - const char* value_type_flag_to_label( unsigned flag ); - - void value_duplicate( value_t& dst, const value_t& src ); - - void value_print( const value_t* value, bool info_fl=false); //------------------------------------------------------------------------------------------------------------------------ // @@ -637,6 +475,7 @@ namespace cw rc_t var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned frameN ); rc_t var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, midi::ch_msg_t* midiA, unsigned midiN ); + rc_t var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, const recd_type_t* recd_type, recd_t* recdA, unsigned recdN ); rc_t var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, const unsigned* maxBinN_V, const unsigned* binN_V, const unsigned* hopSmpN_V, const fd_sample_t** magV=nullptr, const fd_sample_t** phsV=nullptr, const fd_sample_t** hzV=nullptr ); rc_t var_register_and_set( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned maxBinN, unsigned binN, unsigned hopSmpN, const fd_sample_t** magV=nullptr, const fd_sample_t** phsV=nullptr, const fd_sample_t** hzV=nullptr ); @@ -702,6 +541,8 @@ namespace cw rc_t var_get( variable_t* var, fbuf_t*& valRef ); rc_t var_get( const variable_t* var, const mbuf_t*& valRef ); rc_t var_get( variable_t* var, mbuf_t*& valRef ); + rc_t var_get( const variable_t* var, const rbuf_t*& valRef ); + rc_t var_get( variable_t* var, rbuf_t*& valRef ); rc_t var_get( const variable_t* var, const object_t*& valRef ); template< typename T> @@ -740,6 +581,7 @@ namespace cw rc_t var_set( variable_t* var, abuf_t* val ); rc_t var_set( variable_t* var, fbuf_t* val ); rc_t var_set( variable_t* var, mbuf_t* val ); + rc_t var_set( variable_t* var, rbuf_t* val ); rc_t var_set( variable_t* var, const object_t* val ); rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, const value_t* val ); @@ -752,6 +594,7 @@ namespace cw rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, abuf_t* val ); rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, fbuf_t* val ); rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, mbuf_t* val ); + rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, rbuf_t* val ); rc_t var_set( proc_t* proc, unsigned vid, unsigned chIdx, const object_t* val ); diff --git a/cwFlowValue.cpp b/cwFlowValue.cpp new file mode 100644 index 0000000..2a0b223 --- /dev/null +++ b/cwFlowValue.cpp @@ -0,0 +1,1646 @@ +#include "cwCommon.h" +#include "cwLog.h" +#include "cwCommonImpl.h" +#include "cwTest.h" +#include "cwMem.h" +#include "cwMath.h" +#include "cwText.h" +#include "cwObject.h" +#include "cwFileSys.h" +#include "cwVectOps.h" +#include "cwMtx.h" +#include "cwDspTypes.h" // real_t, sample_t +#include "cwTime.h" +#include "cwMidiDecls.h" +#include "cwFlowValue.h" + +namespace cw +{ + namespace flow + { + + idLabelPair_t _typeLabelFlagsA[] = { + + { kBoolTFl, "bool" }, + { kUIntTFl, "uint" }, + { kIntTFl, "int", }, + { kFloatTFl, "float"}, + { kDoubleTFl,"double"}, + + { kBoolMtxTFl, "bool_mtx" }, + { kUIntMtxTFl, "uint_mtx" }, + { kIntMtxTFl, "int_mtx" }, + { kFloatMtxTFl, "float_mtx" }, + { kDoubleMtxTFl,"double_mtx" }, + + { kABufTFl, "audio" }, + { kFBufTFl, "spectrum" }, + { kMBufTFl, "midi" }, + { kRBufTFl, "record" }, + { kStringTFl, "string" }, + { kTimeTFl, "time" }, + { kCfgTFl, "cfg" }, + { kMidiTFl, "m3" }, + + // alias types to map to cwDspTypes.h + { kFloatTFl, "srate"}, + { kFloatTFl, "sample"}, + { kFloatTFl, "coeff"}, + { kDoubleTFl, "ftime" }, + + { kNumericTFl, "numeric" }, + { kAllTFl, "all" }, + + { kRuntimeTFl, "runtime" }, + + { kInvalidTFl, "" } + }; + + const char* _typeFlagToLabel( unsigned flag ) + { + return idToLabel(_typeLabelFlagsA,flag,kInvalidTFl); + } + + void _recd_type_destroy_field_list( recd_field_t* f ) + { + while( f != nullptr ) + { + recd_field_t* f0 = f->link; + + if( f->group_fl ) + _recd_type_destroy_field_list(f->u.group_fieldL); + + mem::release(f->label); + mem::release(f); + + f = f0; + } + } + + rc_t _recd_type_add_field( recd_field_t*& fieldL_ref, const char* field_label, recd_field_t*& new_field_ref ) + { + rc_t rc = kOkRC; + recd_field_t* f = nullptr; + recd_field_t* new_field = nullptr; + + new_field_ref = nullptr; + + if( textLength(field_label) == 0 ) + { + rc = cwLogError(kInvalidArgRC,"A blank msg field was encountered."); + goto errLabel; + } + + for(f=fieldL_ref; f!=nullptr; f=f->link) + { + if( textIsEqual(field_label,f->label)) + { + rc = cwLogError(kInvalidArgRC,"A duplicate msg field '%s' has been encountered.", field_label); + goto errLabel; + } + + // add the new field to the end of the list + if( f->link == nullptr ) + break; + } + + new_field = mem::allocZ(); + new_field->label = mem::duplStr(field_label); + + if( f == nullptr ) + fieldL_ref = new_field; + else + f->link = new_field; + + new_field_ref = new_field; + + + errLabel: + return rc; + } + + + rc_t _recd_type_add_value_field( recd_field_t*& fieldL_ref, const char* field_label, unsigned index ) + { + rc_t rc; + + recd_field_t* new_field = nullptr; + + if((rc = _recd_type_add_field( fieldL_ref, field_label, new_field )) != kOkRC ) + { + rc = cwLogError(rc,"Record add value field '%s' failed.",cwStringNullGuard(field_label)); + goto errLabel; + } + + new_field->group_fl = false; + new_field->u.index = index; + + errLabel: + return rc; + } + + rc_t _recd_type_add_group_field( recd_field_t*& fieldL_ref, const char* field_label, recd_field_t*& new_field_ref ) + { + rc_t rc; + + if((rc = _recd_type_add_field( fieldL_ref, field_label, new_field_ref )) != kOkRC ) + { + rc = cwLogError(rc,"Record add group field '%s' failed.",cwStringNullGuard(field_label)); + goto errLabel; + } + + new_field_ref->group_fl = true; + + errLabel: + return rc; + } + + + rc_t _recd_type_add_value_fields( recd_type_t* recd_type, recd_field_t*& fieldL_ref, const char* field_labels ) + { + rc_t rc = kOkRC; + const char* s0 = field_labels; + + while(s0 != nullptr) + { + s0 = nextNonWhiteChar(s0); + + const char* s1 = nextWhiteChar(s0); + + unsigned sn = s1==nullptr ? textLength(s0) : s1-s0; + char s[sn+1]; + strncpy(s,s0,sn); + s[sn] = 0; + + if((rc = _recd_type_add_value_field(fieldL_ref, s, recd_type->fieldN)) != kOkRC ) + { + goto errLabel; + } + + recd_type->fieldN += 1; + + s0 = s1; + } + + errLabel: + + return rc; + } + + + const recd_field_t* _find_field( const recd_field_t* fieldL, const char* label, unsigned label_charN, bool group_fl ) + { + for(const recd_field_t* f = fieldL; f!=nullptr; f=f->link) + { + unsigned n = textLength(f->label); + + if( (f->group_fl == group_fl) && n==label_charN && textIsEqual(f->label,label,label_charN) ) + return f; + } + return nullptr; + } + + const recd_field_t* _find_value_field( const recd_field_t* fieldL, const char* field_label) + { + const char* period = firstMatchChar( field_label, '.' ); + const recd_field_t* f = nullptr;; + + // if we are searching for a value field label + if( period == nullptr ) + { + if((f = _find_field( fieldL, field_label, textLength(field_label), false )) == nullptr ) + { + goto errLabel; + } + } + else // otherwise we are searching for a group + { + if((f = _find_field( fieldL, field_label, period-field_label, true )) == nullptr ) + { + goto errLabel; + } + + return _find_value_field(f->u.group_fieldL,period+1); + + } + + errLabel: + return f; + } + + unsigned _calc_value_field_index( const recd_type_t* recd_type, const char* field_label) + { + const recd_field_t* f; + unsigned index = kInvalidIdx; + + // if the field label is in the local record + if((f = _find_value_field( recd_type->fieldL, field_label )) != nullptr ) + { + assert(f->group_fl == false ); + index = f->u.index; + } + else + { + // recursively look for the field in the base type + if( recd_type->base != nullptr ) + { + if(( index = _calc_value_field_index( recd_type->base, field_label )) != kInvalidIdx ) + index += recd_type->fieldN; + } + } + + return index; + } + + void _recd_type_print_fields( const recd_type_t* rt0, const recd_field_t* fieldL, const char* group_label, unsigned indent ) + { + const recd_field_t* f; + + char indent_str[ indent+1 ]; + for(unsigned i=0; ilink) + if( f->group_fl == false ) + { + unsigned labelN = textLength(f->label) + textLength(group_label) + 2; + char label[ labelN ]; + label[0] = 0; + label[labelN-1] = 0; + + if( group_label != nullptr ) + { + strcpy(label,group_label); + strcat(label,"."); + } + strcat(label,f->label); + + unsigned field_idx = recd_type_field_index( rt0, label); + cwLogPrint("%s%i %i %s\n",indent_str,field_idx,f->u.index,f->label); + } + + // print group fields next + for(f=fieldL; f!=nullptr; f=f->link) + if( f->group_fl ) + { + cwLogPrint("%s %s:\n",indent_str,f->label); + _recd_type_print_fields(rt0,f->u.group_fieldL,f->label,indent+2); + } + + } + + void _recd_type_print( const recd_type_t* rt0, const recd_type_t* rt ) + { + if( rt->base != nullptr ) + _recd_type_print( rt0, rt->base ); + + _recd_type_print_fields(rt0,rt->fieldL,nullptr,0); + } + + void _recd_print_field( const char* group_label, const recd_field_t* fieldL, const value_t* valA ) + { + const recd_field_t* f; + for(f=fieldL; f!=nullptr; f=f->link) + if(f->group_fl) + _recd_print_field(f->label,f->u.group_fieldL,valA); + else + { + if( group_label != nullptr ) + cwLogPrint("%i %s.%s ",f->u.index,group_label,f->label); + else + cwLogPrint("%i %s ",f->u.index,f->label); + value_print(valA + f->u.index,true); + cwLogPrint("\n"); + } + } + + + rc_t _recd_print( const recd_type_t* rt, const recd_t* r ) + { + rc_t rc = kOkRC; + + if(rt->base != nullptr ) + { + if( r->base == nullptr ) + { + rc = cwLogError(kInvalidStateRC,"recd with base type does not have a base instance."); + goto errLabel; + } + + _recd_print( rt->base, r->base ); + } + + _recd_print_field( nullptr,rt->fieldL, r->valA ); + + errLabel: + return rc; + + } + + } // flow +} // cw + +cw::flow::abuf_t* cw::flow::abuf_create( srate_t srate, unsigned chN, unsigned frameN ) +{ + if( chN*frameN == 0 ) + { + cwLogError(kInvalidArgRC,"The %s audio signal parameter cannot be zero.", chN==0 ? "channel count" : "frame count"); + return nullptr; + } + + abuf_t* a = mem::allocZ(); + a->srate = srate; + a->chN = chN; + a->frameN = frameN; + a->bufAllocSmpN = chN*frameN; + + + a->buf = mem::allocZ(a->bufAllocSmpN); + + return a; +} + +void cw::flow::abuf_destroy( abuf_t*& abuf ) +{ + if( abuf == nullptr ) + return; + + mem::release(abuf->buf); + mem::release(abuf); +} + +cw::flow::abuf_t* cw::flow::abuf_duplicate( abuf_t* dst, const abuf_t* src ) +{ + 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; + + if( abuf != nullptr ) + vop::copy(abuf->buf,src->buf,src->chN*src->frameN); + + return abuf; +} + + +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); +} + + +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 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(); + + 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(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; chIdxmagV[ 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; chIdxmagV[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; +} + +/* +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 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(); + + f->srate = srate; + f->chN = chN; + f->maxBinN_V = mem::allocZ(chN); + f->binN_V = mem::allocZ(chN); + f->hopSmpN_V = mem::allocZ(chN); + f->magV = mem::allocZ(chN); + f->phsV = mem::allocZ(chN); + f->hzV = mem::allocZ(chN); + f->readyFlV = mem::allocZ(chN); + + 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( magV != nullptr || phsV != nullptr || hzV != nullptr ) + { + for(unsigned chIdx=0; chIdxmagV[ chIdx ] = (fd_sample_t*)magV[chIdx]; + f->phsV[ chIdx ] = (fd_sample_t*)phsV[chIdx]; + f->hzV[ chIdx ] = (fd_sample_t*)hzV[chIdx]; + } + } + else + { + unsigned maxTotalBinsN = vop::sum( maxBinN_V, chN ); + + fd_sample_t* buf = mem::allocZ( kFbufVectN * maxTotalBinsN ); + fd_sample_t* m = buf; + for(unsigned chIdx=0; chIdxmagV[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 <= buf + kFbufVectN * maxTotalBinsN ); + } + + f->buf = buf; + + } + + return f; +} +*/ + +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 ) +{ + unsigned maxBinN_V[ chN ]; + unsigned binN_V[ chN ]; + unsigned hopSmpN_V[ chN ]; + + vop::fill( maxBinN_V, chN, maxBinN ); + vop::fill( binN_V, chN, binN ); + vop::fill( hopSmpN_V, chN, binN ); + return fbuf_create( srate, chN, maxBinN_V, binN_V, hopSmpN_V, magV, phsV, hzV ); +} + +void cw::flow::fbuf_destroy( fbuf_t*& fbuf ) +{ + if( fbuf == nullptr ) + return; + + mem::release( fbuf->mem); + mem::release( fbuf); +} + +cw::flow::fbuf_t* cw::flow::fbuf_duplicate( fbuf_t* dst, const fbuf_t* src ) +{ + 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; + + for(unsigned i=0; ichN; ++i) + { + fbuf->maxBinN_V[i] = src->maxBinN_V[i]; + 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] ); + } + return fbuf; +} + + +cw::flow::mbuf_t* cw::flow::mbuf_create( const midi::ch_msg_t* msgA, unsigned msgN ) +{ + mbuf_t* m = mem::allocZ(); + 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); +} + + +cw::flow::rbuf_t* cw::flow::rbuf_create( const recd_type_t* type, const recd_t* recdA, unsigned recdN ) +{ + rbuf_t* m = mem::allocZ(); + m->type = type; + m->recdA = recdA; + m->recdN = recdN; + return m; +} + +void cw::flow::rbuf_destroy( rbuf_t*& buf ) +{ + mem::release(buf); +} + +cw::flow::rbuf_t* cw::flow::rbuf_duplicate( const rbuf_t* src ) +{ + return rbuf_create(src->type,src->recdA,src->recdN); +} + +void cw::flow::rbuf_setup( rbuf_t* rbuf, recd_type_t* type, recd_t* recdA, unsigned recdN ) +{ + rbuf->type = type; + rbuf->recdA = recdA; + rbuf->recdN = recdN; +} + + + +unsigned cw::flow::value_type_label_to_flag( const char* s ) +{ + unsigned flags = labelToId(_typeLabelFlagsA,s,kInvalidTFl); + if( flags == kInvalidTFl ) + cwLogError(kInvalidArgRC,"Invalid type flag: '%s'",cwStringNullGuard(s)); + + return flags; +} + +const char* cw::flow::value_type_flag_to_label( unsigned flag ) +{ return _typeFlagToLabel(flag); } + + +void cw::flow::value_release( value_t* v ) +{ + if( v == nullptr ) + return; + + switch( v->tflag & kTypeMask ) + { + case kInvalidTFl: + break; + + case kBoolTFl: + case kUIntTFl: + case kIntTFl: + case kFloatTFl: + case kDoubleTFl: + break; + + case kABufTFl: + abuf_destroy( v->u.abuf ); + break; + + case kFBufTFl: + fbuf_destroy( v->u.fbuf ); + break; + + case kMBufTFl: + mbuf_destroy( v->u.mbuf ); + break; + + case kRBufTFl: + rbuf_destroy( v->u.rbuf ); + break; + + case kBoolMtxTFl: + case kUIntMtxTFl: + case kIntMtxTFl: + case kFloatMtxTFl: + case kDoubleMtxTFl: + assert(0); // not implemeneted + break; + + case kStringTFl: + mem::release( v->u.s ); + break; + + case kTimeTFl: + assert(0); + break; + + case kCfgTFl: + break; + + case kMidiTFl: + break; + + default: + assert(0); + break; + } + + v->tflag = kInvalidTFl; +} + + +void cw::flow::value_duplicate( value_t& dst, const value_t& src ) +{ + switch( src.tflag & kTypeMask ) + { + case kInvalidTFl: + break; + + case kBoolTFl: + case kUIntTFl: + case kIntTFl: + case kFloatTFl: + case kDoubleTFl: + dst = src; + break; + + case kABufTFl: + + dst.u.abuf = src.u.abuf == nullptr ? nullptr : abuf_duplicate(dst.u.abuf,src.u.abuf); + dst.tflag = src.tflag; + break; + + case kFBufTFl: + dst.u.fbuf = src.u.fbuf == nullptr ? nullptr : fbuf_duplicate(dst.u.fbuf,src.u.fbuf); + dst.tflag = src.tflag; + break; + + case kMBufTFl: + dst.u.mbuf = src.u.mbuf == nullptr ? nullptr : mbuf_duplicate(src.u.mbuf); + dst.tflag = src.tflag; + break; + + case kRBufTFl: + dst.u.rbuf = src.u.rbuf == nullptr ? nullptr : rbuf_duplicate(src.u.rbuf); + dst.tflag = src.tflag; + break; + + case kBoolMtxTFl: + case kUIntMtxTFl: + case kIntMtxTFl: + case kFloatMtxTFl: + case kDoubleMtxTFl: + assert(0); // not implemeneted + break; + + case kStringTFl: + dst.u.s = mem::duplStr( dst.u.s ); + dst.tflag = src.tflag; + break; + + case kTimeTFl: + assert(0); + break; + + case kCfgTFl: + dst = src; + break; + + case kMidiTFl: + dst.u.midi = src.u.midi; + break; + + default: + assert(0); + break; + } + +} + +void cw::flow::value_print( const value_t* v, bool info_fl ) +{ + if( v == nullptr ) + return; + + switch( v->tflag & kTypeMask ) + { + case kInvalidTFl: + cwLogPrint(""); + break; + + 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; + + case kABufTFl: + if( info_fl ) + { + if( v->u.abuf == nullptr ) + cwLogPrint("abuf: "); + else + cwLogPrint("abuf: chN:%i frameN:%i srate:%8.1f ", v->u.abuf->chN, v->u.abuf->frameN, v->u.abuf->srate ); + } + else + { + bool null_fl = v->u.abuf==nullptr || v->u.abuf->buf == nullptr; + cwLogPrint("("); + for(unsigned i=0; iu.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(") "); + } + break; + + case kFBufTFl: + if( info_fl ) + { + if( v->u.fbuf == nullptr ) + cwLogPrint("fbuf: "); + else + { + cwLogPrint("fbuf: chN:%i srate:%8.1f ", v->u.fbuf->chN, v->u.fbuf->srate ); + for(unsigned i=0; iu.fbuf->chN; ++i) + cwLogPrint("(binN:%i hopSmpN:%i) ", v->u.fbuf->binN_V[i], v->u.fbuf->hopSmpN_V[i] ); + } + } + else + { + + bool null_fl = v->u.fbuf==nullptr || v->u.fbuf->magV == nullptr; + cwLogPrint("("); + for(unsigned i=0; iu.fbuf->chN; ++i) + cwLogPrint("%f ",null_fl ? 0.0 : vop::mean(v->u.fbuf->magV[i], v->u.fbuf->binN_V[i])); + cwLogPrint(") "); + + } + break; + + case kMBufTFl: + if( info_fl ) + { + if( v->u.mbuf == nullptr ) + cwLogPrint("mbuf: "); + else + { + cwLogPrint("mbuf: cnt: %i", v->u.mbuf->msgN ); + } + } + else + { + //bool null_fl = v->u.mbuf==nullptr || v->u.mbuf->msgA == nullptr; + for(unsigned i=0; iu.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); + } + break; + + + case kRBufTFl: + if( info_fl ) + { + if( v->u.rbuf == nullptr ) + cwLogPrint("rbuf: "); + else + { + cwLogPrint("rbuf: cnt: %i", v->u.rbuf->recdN ); + } + } + else + { + for(unsigned i=0; iu.rbuf->recdN; ++i) + { + assert(0); + // BUG BUG BUG + // implement _print_record() + } + } + break; + + case kBoolMtxTFl: + case kUIntMtxTFl: + case kIntMtxTFl: + case kFloatMtxTFl: + case kDoubleMtxTFl: + assert(0); // not implemeneted + break; + + case kStringTFl: + cwLogPrint("s:%s ", v->u.s); + break; + + case kTimeTFl: + assert(0); + break; + + case kCfgTFl: + cwLogPrint("c:"); + if( v->u.cfg != nullptr ) + v->u.cfg->print(); + break; + + case kMidiTFl: + cwLogPrint("m:"); + if( v->u.midi != nullptr ) + cwLogPrint("dev:%i port:%i uid:%i ch:%i st:0x%x d0:0x%x d1:0x%x",v->u.midi->devIdx,v->u.midi->portIdx,v->u.midi->uid,v->u.midi->ch,v->u.midi->status,v->u.midi->d0,v->u.midi->d1); + break; + + default: + assert(0); + break; + } + +} + + + +cw::rc_t cw::flow::value_get( const value_t* val, bool& valRef ) +{ + rc_t rc = kOkRC; + switch( val->tflag & kTypeMask ) + { + 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; + 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; +} + +cw::rc_t cw::flow::value_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; + + default: + rc = cwLogError(kTypeMismatchRC,"A bool could not be converted to a %s (0x%x).",_typeFlagToLabel(val->tflag),val->tflag); + } + + return rc; +} + +cw::rc_t cw::flow::value_get( const value_t* val, uint_t& valRef ) +{ + rc_t rc = kOkRC; + switch( val->tflag & kTypeMask ) + { + 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: + rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to a uint.",_typeFlagToLabel(val->tflag),val->tflag); + } + return rc; +} + +cw::rc_t cw::flow::value_set( value_t* val, uint_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.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; +} + +cw::rc_t cw::flow::value_get( const value_t* val, int_t& valRef ) +{ + rc_t rc = kOkRC; + switch( val->tflag & kTypeMask ) + { + 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: + rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to an int.",_typeFlagToLabel(val->tflag),val->tflag); + + } + return rc; +} + +cw::rc_t cw::flow::value_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); + } + + return rc; +} + + +cw::rc_t cw::flow::value_get( const value_t* val, float& valRef ) +{ + rc_t rc = kOkRC; + switch( val->tflag & kTypeMask ) + { + 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: + rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to a float.",_typeFlagToLabel(val->tflag),val->tflag); + } + return rc; +} + +cw::rc_t cw::flow::value_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; +} + +cw::rc_t cw::flow::value_get( const value_t* val, double& valRef ) +{ + rc_t rc = kOkRC; + switch( val->tflag & kTypeMask ) + { + 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: + rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to a double.",_typeFlagToLabel(val->tflag),val->tflag); + } + return rc; +} + +cw::rc_t cw::flow::value_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; +} + +cw::rc_t cw::flow::value_get( const value_t* val, const char*& valRef ) +{ + rc_t rc = kOkRC; + if( cwIsFlag(val->tflag & kTypeMask, kStringTFl) ) + valRef = val->u.s; + else + { + rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to a string.",_typeFlagToLabel(val->tflag),val->tflag); + valRef = nullptr; + } + + return rc; +} + +cw::rc_t cw::flow::value_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; +} + +cw::rc_t cw::flow::value_get( value_t* val, abuf_t*& valRef ) +{ + rc_t rc = kOkRC; + if( cwIsFlag(val->tflag & kTypeMask, kABufTFl) ) + valRef = val->u.abuf; + else + { + rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to an abuf.",_typeFlagToLabel(val->tflag),val->tflag); + valRef = nullptr; + } + return rc; +} + +cw::rc_t cw::flow::value_get( value_t* val, const abuf_t*& valRef ) +{ + abuf_t* non_const_val; + rc_t rc = kOkRC; + if((rc = value_get(val,non_const_val)) == kOkRC ) + valRef = non_const_val; + return rc; +} + +cw::rc_t cw::flow::value_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; +} + +cw::rc_t cw::flow::value_get( value_t* val, fbuf_t*& valRef ) +{ + rc_t rc = kOkRC; + if( cwIsFlag(val->tflag & kTypeMask, kFBufTFl) ) + valRef = val->u.fbuf; + else + { + valRef = nullptr; + rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to an fbuf.",_typeFlagToLabel(val->tflag),val->tflag); + } + return rc; +} + +cw::rc_t cw::flow::value_get( value_t* val, const fbuf_t*& valRef ) +{ + fbuf_t* non_const_val; + rc_t rc = kOkRC; + if((rc = value_get(val,non_const_val)) == kOkRC ) + valRef = non_const_val; + return rc; +} + +cw::rc_t cw::flow::value_set( value_t* val, fbuf_t* v ) +{ + rc_t rc = kOkRC; + + switch( val->tflag & kTypeMask ) + { + case kFBufTFl: + val->u.fbuf=v; + break; + + case kInvalidTFl: + val->u.fbuf=v; + val->tflag = kFBufTFl; + break; + + default: + rc = cwLogError(kTypeMismatchRC,"A spectrum signal could not be converted to a %s (0x%x).",_typeFlagToLabel(val->tflag),val->tflag); + } + + return rc; +} + +cw::rc_t cw::flow::value_get( value_t* val, mbuf_t*& valRef ) +{ + rc_t rc = kOkRC; + if( cwIsFlag(val->tflag & kTypeMask, kMBufTFl) ) + valRef = val->u.mbuf; + else + { + valRef = nullptr; + rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to an mbuf.",_typeFlagToLabel(val->tflag),val->tflag); + } + return rc; +} + +cw::rc_t cw::flow::value_get( value_t* val, const mbuf_t*& valRef ) +{ + mbuf_t* non_const_val; + rc_t rc = kOkRC; + if((rc = value_get(val,non_const_val)) == kOkRC ) + valRef = non_const_val; + return rc; +} + + +cw::rc_t cw::flow::value_set( value_t* val, mbuf_t* v ) +{ + rc_t rc = kOkRC; + + switch( val->tflag & kTypeMask ) + { + 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); + } + + return rc; +} + + +cw::rc_t cw::flow::value_get( value_t* val, rbuf_t*& valRef ) +{ + rc_t rc = kOkRC; + if( cwIsFlag(val->tflag & kTypeMask, kRBufTFl) ) + valRef = val->u.rbuf; + else + { + valRef = nullptr; + rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to an rbuf.",_typeFlagToLabel(val->tflag),val->tflag); + } + return rc; +} + +cw::rc_t cw::flow::value_get( value_t* val, const rbuf_t*& valRef ) +{ + rbuf_t* non_const_val; + rc_t rc = kOkRC; + if((rc = value_get(val,non_const_val)) == kOkRC ) + valRef = non_const_val; + return rc; +} + +cw::rc_t cw::flow::value_set( value_t* val, rbuf_t* v ) +{ + rc_t rc = kOkRC; + + switch( val->tflag & kTypeMask ) + { + case kRBufTFl: + val->u.rbuf=v; + break; + + case kInvalidTFl: + val->u.rbuf=v; + val->tflag = kRBufTFl; + break; + + default: + rc = cwLogError(kTypeMismatchRC,"A recd-buf could not be converted to a %s (0x%x).",_typeFlagToLabel(val->tflag),val->tflag); + } + + return rc; +} + + +cw::rc_t cw::flow::value_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); + + } + return rc; +} + +cw::rc_t cw::flow::value_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; + + default: + rc = cwLogError(kTypeMismatchRC,"A cfg. could not be converted to a %s (0x%x).",_typeFlagToLabel(val->tflag),val->tflag); + } + + return rc; +} + + +cw::rc_t cw::flow::value_get( const value_t* val, midi::ch_msg_t*& valRef ) +{ + rc_t rc = kOkRC; + + if( cwIsFlag(val->tflag & kTypeMask, kMidiTFl) ) + valRef = val->u.midi; + else + { + valRef = nullptr; + rc = cwLogError(kTypeMismatchRC,"The type %s (0x%x) could not be converted to a MIDI record.",_typeFlagToLabel(val->tflag),val->tflag); + + } + return rc; +} + +cw::rc_t cw::flow::value_set(value_t* val, midi::ch_msg_t* v ) +{ + rc_t rc = kOkRC; + + switch( val->tflag & kTypeMask ) + { + case kMidiTFl: + val->u.midi=v; + break; + + case kInvalidTFl: + val->u.midi=v; + val->tflag = kCfgTFl; + break; + + default: + rc = cwLogError(kTypeMismatchRC,"A MIDI record could not be converted to a %s (0x%x).",_typeFlagToLabel(val->tflag),val->tflag); + } + + return rc; +} + + +cw::rc_t cw::flow::recd_type_create( recd_type_t*& recd_type_ref, const recd_type_t* base, const char* fields_str ) +{ + rc_t rc = kOkRC; + recd_type_t* recd_type = mem::allocZ(); + + recd_type_ref = nullptr; + + if((rc = recd_type_add_value_fields( recd_type, fields_str )) != kOkRC ) + { + goto errLabel; + } + + recd_type->base = base; + recd_type_ref = recd_type; + +errLabel: + if( rc != kOkRC && recd_type != nullptr ) + { + rc = cwLogError(rc,"recd_type create failed."); + recd_type_destroy(recd_type); + } + + return rc; +} + +void cw::flow::recd_type_destroy( recd_type_t*& recd_type_ref ) +{ + if( recd_type_ref == nullptr ) + return; + + _recd_type_destroy_field_list(recd_type_ref->fieldL); + mem::release(recd_type_ref); +} + +cw::rc_t cw::flow::recd_type_add_value_fields( recd_type_t* recd_type, const char* field_labels ) +{ + return _recd_type_add_value_fields( recd_type, recd_type->fieldL, field_labels ); +} + +cw::rc_t cw::flow::recd_type_add_group( recd_type_t* recd_type, const char* group_label, const char* field_labels ) +{ + rc_t rc; + + recd_field_t* f = nullptr; + + if((rc = _recd_type_add_group_field( recd_type->fieldL, group_label, f )) != kOkRC ) + { + goto errLabel; + } + + if((rc = _recd_type_add_value_fields( recd_type, f->u.group_fieldL, field_labels )) != kOkRC ) + { + goto errLabel; + } + +errLabel: + + if( rc !=kOkRC ) + rc = cwLogError(rc,"Record group add failed."); + + return rc; +} + +unsigned cw::flow::recd_type_max_field_count( const recd_type_t* recd_type ) +{ + unsigned n = 0; + for(const recd_type_t* t = recd_type; t!=nullptr; t=t->base) + n += t->fieldN; + return n; +} + +unsigned cw::flow::recd_type_field_index( const recd_type_t* recd_type, const char* field_label) +{ + unsigned index; + + if((index = _calc_value_field_index( recd_type, field_label)) == kInvalidIdx ) + { + cwLogError(kInvalidArgRC,"The record field label '%s' was not found.",cwStringNullGuard(field_label)); + goto errLabel; + } + +errLabel: + return index; +} + +void cw::flow::recd_type_print( const recd_type_t* recd_type ) +{ + _recd_type_print(recd_type,recd_type); +} + +cw::rc_t cw::flow::recd_print( const recd_type_t* rt, const recd_t* r ) +{ return _recd_print( rt, r ); } + + + +cw::rc_t cw::flow::recd_array_create( recd_array_t*& recd_array_ref, recd_type_t* recd_type, unsigned allocRecdN ) +{ + rc_t rc = kOkRC; + recd_array_t* recd_array = mem::allocZ(); + + recd_array_ref = nullptr; + + recd_array->type = recd_type; + recd_array->valA = mem::allocZ(recd_array->type->fieldN * allocRecdN); + recd_array->recdA = mem::allocZ(allocRecdN); + recd_array->allocRecdN = allocRecdN; + + for(unsigned i=0; irecdA[i].valA = recd_array->valA + (i*recd_array->type->fieldN); + + recd_array_ref = recd_array; + + //if( rc != kOkRC ) + // recd_array_destroy(recd_array); + + return rc; +} + +cw::rc_t cw::flow::recd_array_destroy( recd_array_t*& recd_array_ref ) +{ + if( recd_array_ref != nullptr ) + { + mem::release(recd_array_ref->valA); + mem::release(recd_array_ref->recdA); + mem::release(recd_array_ref); + } + + return kOkRC; +} + + +cw::rc_t cw::flow::value_test( const test::test_args_t& args ) +{ + rc_t rc = kOkRC; + recd_type_t* rt0 = nullptr; + recd_type_t* rt1 = nullptr; + recd_array_t* ra0 = nullptr; + recd_array_t* ra1 = nullptr; + + if((rc = recd_type_create( rt0, nullptr, "a b c" )) != kOkRC ) + { + rc = cwLogError(rc,"rt0 create failed."); + goto errLabel; + } + + if((rc = recd_type_add_group( rt0, "g0", "a b c" )) != kOkRC ) + { + rc = cwLogError(rc,"rt.g0 group create failed."); + goto errLabel; + } + + if((rc = recd_type_create( rt1, rt0, "d e f" )) != kOkRC ) + { + rc = cwLogError(rc,"rt0 create failed."); + goto errLabel; + } + + if((rc = recd_type_add_group( rt1, "g1", "a b c" )) != kOkRC ) + { + rc = cwLogError(rc,"rt.g0 group create failed."); + goto errLabel; + } + + recd_type_print( rt0 ); + recd_type_print( rt1 ); + + if((rc = recd_array_create(ra0,rt0,10)) != kOkRC ) + { + rc = cwLogError(rc,"ra0 alloc failed."); + goto errLabel; + } + + if((rc = recd_array_create(ra1,rt1,10)) != kOkRC ) + { + rc = cwLogError(rc,"ra1 alloc failed."); + goto errLabel; + } + + for(unsigned i=0; iallocRecdN; ++i) + { + recd_t* r = ra0->recdA + i; + rc_t rc0 = recd_set( ra0->type, nullptr, r, recd_type_field_index(ra0->type,"a"), 0*i); + rc_t rc1 = recd_set( ra0->type, nullptr, r, recd_type_field_index(ra0->type,"b"), 1*i); + rc_t rc2 = recd_set( ra0->type, nullptr, r, recd_type_field_index(ra0->type,"c"), 2*i); + rc_t rc3 = recd_set( ra0->type, nullptr, r, recd_type_field_index(ra0->type,"g0.a"), 4.0*i); + rc_t rc4 = recd_set( ra0->type, nullptr, r, recd_type_field_index(ra0->type,"g0.b"), 5.0*i); + rc_t rc5 = recd_set( ra0->type, nullptr, r, recd_type_field_index(ra0->type,"g0.c"), 6.0*i); + + if((rc = rcSelect(rc0,rc1,rc2,rc3,rc4,rc5)) != kOkRC ) + { + rc = cwLogError(rc,"recd_set() failed on ra0."); + goto errLabel; + } + } + + for(unsigned i=0; iallocRecdN; ++i) + recd_print(ra0->type,ra0->recdA+i); + + for(unsigned i=0; iallocRecdN; ++i) + { + recd_t* r = ra1->recdA + i; + recd_t* r_base = ra0->recdA + i; + rc_t rc0 = recd_set( ra1->type, r_base, r, recd_type_field_index(ra1->type,"d"), 0*i*2); + rc_t rc1 = recd_set( ra1->type, r_base, r, recd_type_field_index(ra1->type,"e"), 1*i*2); + rc_t rc2 = recd_set( ra1->type, r_base, r, recd_type_field_index(ra1->type,"f"), 2*i*2); + rc_t rc3 = recd_set( ra1->type, r_base, r, recd_type_field_index(ra1->type,"g1.a"), 4.0*i*2); + rc_t rc4 = recd_set( ra1->type, r_base, r, recd_type_field_index(ra1->type,"g1.b"), 5.0*i*2); + rc_t rc5 = recd_set( ra1->type, r_base, r, recd_type_field_index(ra1->type,"g1.c"), 6.0*i*2); + + if((rc = rcSelect(rc0,rc1,rc2,rc3,rc4,rc5)) != kOkRC ) + { + rc = cwLogError(rc,"recd_set() failed on ra1."); + goto errLabel; + } + } + + for(unsigned i=0; iallocRecdN; ++i) + recd_print(ra1->type,ra1->recdA+i); + + recd_array_destroy(ra0); + recd_array_destroy(ra1); + recd_type_destroy(rt0); + recd_type_destroy(rt1); + +errLabel: + return rc; +} diff --git a/cwFlowValue.h b/cwFlowValue.h new file mode 100644 index 0000000..0203dca --- /dev/null +++ b/cwFlowValue.h @@ -0,0 +1,333 @@ +#ifndef cwFlowValue_h +#define cwFLowValue_h + +namespace cw +{ + namespace flow + { + typedef dsp::coeff_t coeff_t; + typedef dsp::sample_t sample_t; + typedef dsp::fd_sample_t fd_sample_t; + typedef dsp::srate_t srate_t; + typedef dsp::ftime_t ftime_t; + typedef unsigned uint_t; + typedef int int_t; + + typedef unsigned vid_t; + + enum { + kBaseSfxId = 0, + kFbufVectN = 3, // count of signal vectors in fbuf (mag,phs,hz) + kAnyChIdx = kInvalidIdx, + kLocalValueN = 2, + kDefaultFramesPerCycle=64, + kDefaultSampleRate=48000 + }; + + typedef struct abuf_str + { + srate_t srate; // Signal sample rate + unsigned chN; // Count of channels + unsigned frameN; // Count of sample frames per channel + unsigned bufAllocSmpN; // Size of allocated buf[] in samples. + sample_t* buf; // buf[ chN ][ frameN ] + } abuf_t; + + + typedef struct fbuf_str + { + unsigned memByteN; // Count of bytes in mem[]. + void* mem; // mem[ memByteN ] All dynamically allocated memory used by this fbuf. + + srate_t srate; // signal sample rate + unsigned flags; // See kXXXFbufFl + unsigned chN; // count of channels + unsigned* maxBinN_V; // maxBinN_V[chN] max value that binN_V[i] is allowed to take + unsigned* binN_V; // binN_V[ chN ] count of sample frames per channel + unsigned* hopSmpN_V; // hopSmpN_V[ chN ] hop sample count + fd_sample_t** magV; // magV[ chN ][ binN ] + fd_sample_t** phsV; // phsV[ chN ][ binN ] + fd_sample_t** hzV; // hzV[ chN ][ binN ] + bool* readyFlV; // readyFlV[chN] true if this channel is ready to be processed (used to sync. fbuf rate to abuf rate) + } fbuf_t; + + typedef struct mbuf_str + { + const midi::ch_msg_t* msgA; + unsigned msgN; + } mbuf_t; + + enum + { + kInvalidTFl = 0x00000000, + kBoolTFl = 0x00000001, + kUIntTFl = 0x00000002, + kIntTFl = 0x00000004, + kFloatTFl = 0x00000008, + kDoubleTFl = 0x00000010, + + kBoolMtxTFl = 0x00000020, + kUIntMtxTFl = 0x00000040, + kIntMtxTFl = 0x00000080, + kFloatMtxTFl = 0x00000100, + kDoubleMtxTFl= 0x00000200, + + kABufTFl = 0x00000400, + kFBufTFl = 0x00000800, + kMBufTFl = 0x00001000, + kRBufTFl = 0x00002000, + kStringTFl = 0x00004000, + kTimeTFl = 0x00008000, + kCfgTFl = 0x00010000, + kMidiTFl = 0x00020000, + + kTypeMask = 0x0003ffff, + + kRuntimeTFl = 0x80000000, + + kNumericTFl = kBoolTFl | kUIntTFl | kIntTFl | kFloatTFl | kDoubleTFl, + kMtxTFl = kBoolMtxTFl | kUIntMtxTFl | kIntMtxTFl | kFloatMtxTFl | kDoubleMtxTFl, + kAllTFl = kTypeMask + }; + + typedef struct mtx_str + { + union { + struct mtx::mtx_str< unsigned >* u; + struct mtx::mtx_str< int >* i; + struct mtx::mtx_str< float >* f; + struct mtx::mtx_str< double >* d; + } u; + } mtx_t; + + typedef struct recd_field_str + { + bool group_fl; // set if this field record is a group + char* label; // field or group label + union + { + unsigned index; // index into recd_t.valA of the value associated with this field + struct recd_field_str* group_fieldL; + } u; + + struct recd_field_str* link; + } recd_field_t; + + typedef struct recd_type_str + { + recd_field_t* fieldL; // linked list of field spec's + unsigned fieldN; // length of fieldL list (fieldN + base->fieldN) is total field count + const struct recd_type_str* base; + } recd_type_t; + + struct value_str; + typedef struct recd_str + { + struct value_str* valA; // varA[ fieldN ] array of field values + const struct recd_str* base; // base record fields + } recd_t; + + typedef struct rbuf_str + { + const recd_type_t* type; // all msgs are formed from this type + const recd_t* recdA; // recdA[ recdN ] + unsigned recdN; // + } rbuf_t; + + typedef struct value_str + { + unsigned tflag; + + union { + bool b; + uint_t u; + int_t i; + float f; + double d; + + mtx_t* mtx; + abuf_t* abuf; + fbuf_t* fbuf; + mbuf_t* mbuf; + rbuf_t* rbuf; + + char* s; + + const object_t* cfg; + midi::ch_msg_t* midi; + void* p; + + + } u; + + struct value_str* link; + + } value_t; + + + + //------------------------------------------------------------------------------------------------------------------------ + // + // Value Only + // + + inline void set_null( value_t& v, unsigned tflag ) { v.tflag=tflag; v.u.p=nullptr; } + inline bool is_numeric( const value_t* v ) { return cwIsFlag(v->tflag,kNumericTFl); } + inline bool is_matrix( const value_t* v ) { return cwIsFlag(v->tflag,kMtxTFl); } + + // if all of the src flags are set in the dst flags then the two types are convertable. + inline bool can_convert( unsigned src_tflag, unsigned dst_tflag ) { return (src_tflag&dst_tflag)==src_tflag; } + + + abuf_t* abuf_create( srate_t srate, unsigned chN, unsigned frameN ); + void abuf_destroy( abuf_t*& buf ); + + // If 'dst' is null then a new abuf is allocated, filled with the contents of 'src'. + // If 'dst' is non-null and there is enough space for the contents of 'src' then only a copy is executed. + // If there is not enough space then dst is reallocated. + abuf_t* abuf_duplicate( abuf_t* dst, const abuf_t* src ); + rc_t abuf_set_channel( abuf_t* buf, unsigned chIdx, const sample_t* v, unsigned vN ); + const sample_t* abuf_get_channel( abuf_t* buf, unsigned chIdx ); + + fbuf_t* fbuf_create( srate_t srate, unsigned chN, const unsigned* maxBinN_V, const unsigned* binN_V, const unsigned* hopSmpN_V, const fd_sample_t** magV=nullptr, const fd_sample_t** phsV=nullptr, const fd_sample_t** hzV=nullptr ); + fbuf_t* fbuf_create( srate_t srate, unsigned chN, unsigned maxBinN, unsigned binN, unsigned hopSmpN, const fd_sample_t** magV=nullptr, const fd_sample_t** phsV=nullptr, const fd_sample_t** hzV=nullptr ); + void fbuf_destroy( fbuf_t*& buf ); + + // Memory allocation will only occur if dst is null, or the size of dst's internal buffer are too small. + fbuf_t* fbuf_duplicate( fbuf_t* dst, const fbuf_t* src ); + + mbuf_t* mbuf_create( const midi::ch_msg_t* msgA=nullptr, unsigned msgN=0 ); + void mbuf_destroy( mbuf_t*& buf ); + mbuf_t* mbuf_duplicate( const mbuf_t* src ); + + rbuf_t* rbuf_create( const recd_type_t* type=nullptr, const recd_t* recdA=nullptr, unsigned recdN=0 ); + void rbuf_destroy( rbuf_t*& buf ); + rbuf_t* rbuf_duplicate( const rbuf_t* src ); + void rbuf_setup( rbuf_t* rbuf, recd_type_t* type, recd_t* recdA, unsigned recdN ); + + + inline bool value_is_abuf( const value_t* v ) { return v->tflag & kABufTFl; } + inline bool value_is_fbuf( const value_t* v ) { return v->tflag & kFBufTFl; } + + unsigned value_type_label_to_flag( const char* type_desc ); + const char* value_type_flag_to_label( unsigned flag ); + + void value_release( value_t* v ); + void value_duplicate( value_t& dst, const value_t& src ); + + void value_print( const value_t* value, bool info_fl=false); + + rc_t value_get( const value_t* val, bool& valRef ); + rc_t value_set( value_t* val, bool v ); + + rc_t value_get( const value_t* val, uint_t& valRef ); + rc_t value_set( value_t* val, uint_t v ); + + rc_t value_get( const value_t* val, int_t& valRef ); + rc_t value_set( value_t* val, int_t v ); + + rc_t value_get( const value_t* val, float& valRef ); + rc_t value_set( value_t* val, float v ); + + rc_t value_get( const value_t* val, double& valRef ); + rc_t value_set( value_t* val, double v ); + + rc_t value_get( const value_t* val, const char*& valRef ); + rc_t value_set( value_t* val, const char* v ); + + rc_t value_get( value_t* val, abuf_t*& valRef ); + rc_t value_get( value_t* val, const abuf_t*& valRef ); + rc_t value_set( value_t* val, abuf_t* v ); + + rc_t value_get( value_t* val, fbuf_t*& valRef ); + rc_t value_get( value_t* val, const fbuf_t*& valRef ); + rc_t value_set( value_t* val, fbuf_t* v ); + + rc_t value_get( value_t* val, mbuf_t*& valRef ); + rc_t value_get( value_t* val, const mbuf_t*& valRef ); + rc_t value_set( value_t* val, mbuf_t* v ); + + rc_t value_get( value_t* val, rbuf_t*& valRef ); + rc_t value_get( value_t* val, const rbuf_t*& valRef ); + rc_t value_set( value_t* val, rbuf_t* v ); + + rc_t value_get( value_t* val, const object_t*& valRef ); + rc_t value_set( value_t* val, const object_t* v ); + + rc_t value_get( const value_t* val, midi::ch_msg_t*& valRef ); + rc_t value_set( value_t* val, midi::ch_msg_t* v ); + + + + //------------------------------------------------------------------------------------------------------------------------ + // + // Record + // + + + typedef struct recd_array_str + { + recd_type_t* type; + value_t* valA; // valA[ allocRecdN * type->fieldN ] + recd_t* recdA; + unsigned allocRecdN; + } recd_array_t; + + rc_t recd_type_create( recd_type_t*& recd_type_ref, const recd_type_t* base_type, const char* fields_string=nullptr ); + void recd_type_destroy( recd_type_t*& recd_type ); + + rc_t recd_type_add_value_fields( recd_type_t* recd_type, const char* field_labels ); + rc_t recd_type_add_group( recd_type_t* recd_type, const char* group_label, const char* field_labels ); + + // Count of fields combined local and base record types. + rc_t recd_type_max_field_count( const recd_type_t* recd_type ); + + // use '.' notation to separate groups from fields. + // Note if this is a 'local' field then the high bit in the returned index will be set. + unsigned recd_type_field_index( const recd_type_t* recd_type, const char* field_label); + + void recd_type_print( const recd_type_t* recd_type ); + + template< typename T > + rc_t recd_get( const recd_type_t* type, const recd_t* recd, unsigned field_idx, T& val_ref ) + { + if( field_idx < type->fieldN ) + return value_get( recd->valA + field_idx, val_ref ); + + return recd_get( type->base, recd->base, field_idx - type->fieldN, val_ref ); + } + + inline rc_t recd_set_base( const recd_type_t* type, recd_t* recd, const recd_t* base ) + { + // if we are setting base then the type must have a base type + assert( (type->base == nullptr && base==nullptr) || (type->base!=nullptr && base!=nullptr) ); + + recd->base = base; + return kOkRC; + } + + template< typename T > + rc_t recd_set( const recd_type_t* type, const recd_t* base, recd_t* recd, unsigned field_idx, const T& val ) + { + if( field_idx >= type->fieldN ) + return cwLogError(kInvalidArgRC,"Only 'local' record value may be set."); + + // set the base of this record + recd_set_base(type,recd,base); + + return value_set( recd->valA + field_idx, val ); + } + + rc_t recd_print( const recd_type_t* recd_type, const recd_t* r ); + + rc_t recd_array_create( recd_array_t*& recd_array_ref, recd_type_t* recd_type, unsigned allocRecdN ); + rc_t recd_array_destroy( recd_array_t*& recd_array_ref ); + + rc_t value_test( const test::test_args_t& args ); + + + } +} + + +#endif