cmDspFx.h/c : Added IntToSym

This commit is contained in:
kevin 2020-07-27 17:40:01 -04:00
parent 50f5d15145
commit ebecf50417
2 changed files with 177 additions and 1 deletions

View File

@ -5587,6 +5587,7 @@ cmDspInst_t* _cmDspPortToSym_Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, uns
// register the symbol
symIdArray[i] = cmSymTblRegisterSymbol(ctx->stH,symLabel);
// input port - any msg in this port will generate an output from 'out' as well as the associated output port
cmDspArgSetup(ctx, args+kBaseInPtsId+i, symLabel, cmInvalidId, kBaseInPtsId+i, 0, 0, kInDsvFl | kTypeDsvMask, cmTsPrintfH(ctx->lhH,"%s Input.",symLabel) );
cmDspArgSetup(ctx, args+baseOutPtsId+i, symLabel, cmInvalidId, baseOutPtsId+i, 0, 0, kOutDsvFl | kSymDsvFl, cmTsPrintfH(ctx->lhH,"%s Output.",symLabel) );
@ -5631,7 +5632,7 @@ cmDspRC_t _cmDspPortToSym_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv
unsigned idx = evt->dstVarId - kBaseInPtsId;
assert( idx < p->symIdCnt );
cmDspSetSymbol(ctx,inst,p->baseOutPtsId + idx, p->symIdArray[idx]);
return cmDspSetSymbol(ctx,inst,kOutPtsId,p->symIdArray[ evt->dstVarId - kBaseInPtsId ]);
return cmDspSetSymbol(ctx,inst,kOutPtsId, p->symIdArray[idx]);
}
return rc;
@ -5652,6 +5653,180 @@ cmDspClass_t* cmPortToSymClassCons( cmDspCtx_t* ctx )
return &_cmPortToSym_DC;
}
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmDspIntToSym file_desc:"Send a pre-defined symbol every time a message arrives a given input port." kw:[sunit] }
enum
{
kInItsId,
kOutItsId,
kBaseInItsId
};
cmDspClass_t _cmIntToSym_DC;
typedef struct
{
cmDspInst_t inst;
int* intArray;
unsigned* symIdArray;
unsigned symIdCnt;
unsigned baseIntItsId;
unsigned baseOutItsId;
} cmDspIntToSym_t;
cmDspInst_t* _cmDspIntToSym_Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
{
va_list vl1;
va_copy(vl1,vl);
if( va_cnt < 2 || va_cnt % 2 !=0 )
{
va_end(vl1);
cmDspClassErr(ctx,classPtr,kVarArgParseFailDspRC,"The 'IntToSym' constructor argument list must contain at least one int/symbol pair and all pairs must be complete.");
return NULL;
}
unsigned symCnt = va_cnt/2;
unsigned argCnt = 2 + 3*symCnt;
cmDspVarArg_t args[argCnt+1];
unsigned* symIdArray = cmMemAllocZ(unsigned,symCnt);
int* intArray = cmMemAllocZ(int,symCnt);
unsigned baseIntItsId = kBaseInItsId + symCnt;
unsigned baseOutItsId = baseIntItsId + symCnt;
// setup the integer input and symbol output port arg recd
cmDspArgSetup(ctx,args, "in", cmInvalidId, kInItsId, 0, 0, kInDsvFl | kIntDsvFl, "Integer input" );
cmDspArgSetup(ctx,args+1,"out", cmInvalidId, kOutItsId, 0, 0, kOutDsvFl | kSymDsvFl, "Output" );
unsigned i;
for(i=0; i<symCnt; ++i)
{
// get the integer value
intArray[i] = va_arg(vl,int);
// get the symbol label
const cmChar_t* symLabel = va_arg(vl,const char*);
assert( symLabel != NULL );
unsigned intLabelN = (symLabel==NULL ? 0 : strlen(symLabel)) + 5;
cmChar_t intLabel[ intLabelN ];
snprintf(intLabel,intLabelN,"%s%s", symLabel==NULL ? "" : symLabel, "-int" );
// register the symbol
symIdArray[i] = cmSymTblRegisterSymbol(ctx->stH,symLabel);
// trigger port associated with this symbol (any msg on this port will trigger an output)
cmDspArgSetup(ctx, args+kBaseInItsId+i, symLabel, cmInvalidId, kBaseInItsId+i, 0, 0, kInDsvFl | kTypeDsvMask, cmTsPrintfH(ctx->lhH,"%s Input.",symLabel) );
// this port is used to set the integer value associated with this symbol
cmDspArgSetup(ctx, args+baseIntItsId+i, intLabel, cmInvalidId, baseIntItsId+i, 0, 0, kInDsvFl | kIntDsvFl, cmTsPrintfH(ctx->lhH,"Set the integer value associated with %s.",symLabel) );
// symbol output port - when ever this symbol is sent out it will go out this port as well as the 'out' port
cmDspArgSetup(ctx, args+baseOutItsId+i, symLabel, cmInvalidId, baseOutItsId+i, 0, 0, kOutDsvFl | kSymDsvFl, cmTsPrintfH(ctx->lhH,"%s Output.",symLabel) );
}
cmDspArgSetupNull(args + argCnt);
cmDspIntToSym_t* p = cmDspInstAlloc(cmDspIntToSym_t,ctx,classPtr,args,instSymId,id,storeSymId,0,vl1);
p->symIdCnt = symCnt;
p->intArray = intArray;
p->symIdArray = symIdArray;
p->baseOutItsId = baseOutItsId;
p->baseIntItsId = baseIntItsId;
cmDspSetDefaultSymbol(ctx,&p->inst,kOutItsId,cmInvalidId);
va_end(vl1);
return &p->inst;
}
cmDspRC_t _cmDspIntToSym_Free(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
{
cmDspIntToSym_t* p = (cmDspIntToSym_t*)inst;
cmMemFree(p->symIdArray);
return kOkDspRC;
}
cmDspRC_t _cmDspIntToSym_Reset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
{
return cmDspApplyAllDefaults(ctx,inst);
}
cmDspRC_t _cmDspIntToSymSendOut( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned idx )
{
cmDspIntToSym_t* p = (cmDspIntToSym_t*)inst;
assert( idx < p->symIdCnt );
cmDspSetSymbol(ctx,inst,p->baseOutItsId + idx, p->symIdArray[idx]);
return cmDspSetSymbol(ctx, inst, kOutItsId, p->symIdArray[ idx ]);
}
cmDspRC_t _cmDspIntToSym_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
{
cmDspRC_t rc = kOkDspRC;
cmDspIntToSym_t* p = (cmDspIntToSym_t*)inst;
unsigned idx = cmInvalidIdx;
// if an integer arrived at 'in'
if( evt->dstVarId == kInItsId )
{
unsigned i;
int intVal = cmDspInt(inst,kInItsId);
for(i=0; i<p->symIdCnt; ++i)
if( intVal == p->intArray[i] )
{
rc = _cmDspIntToSymSendOut( ctx, inst, idx );
idx = i;
break;
}
}
else
{
// if a msg of any type is recieved on an input port - send out the associated symbol
if( kBaseInItsId <= evt->dstVarId && evt->dstVarId < kBaseInItsId + p->symIdCnt )
{
_cmDspIntToSymSendOut( ctx, inst, evt->dstVarId - kBaseInItsId );
}
else
// if this is a new interger value for this symbol
if( p->baseIntItsId <= evt->dstVarId && evt->dstVarId < p->baseIntItsId + p->symIdCnt )
{
cmDspSetEvent(ctx,inst,evt);
int x = cmDspInt( inst, evt->dstVarId );
printf("%i %i\n", x, p->symIdArray[evt->dstVarId - p->baseIntItsId] );
p->intArray[ evt->dstVarId - p->baseIntItsId ] = x;
}
}
return rc;
}
cmDspClass_t* cmIntToSymClassCons( cmDspCtx_t* ctx )
{
cmDspClassSetup(&_cmIntToSym_DC,ctx,"IntToSym",
NULL,
_cmDspIntToSym_Alloc,
_cmDspIntToSym_Free,
_cmDspIntToSym_Reset,
NULL,
_cmDspIntToSym_Recv,
NULL,NULL,
"If a message of any kind is received on a port then send the symbol associated with the port.");
return &_cmIntToSym_DC;
}
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmDspRouter file_desc:"Route the input value to one of multiple output ports." kw:[sunit] }

View File

@ -36,6 +36,7 @@ extern "C" {
struct cmDspClass_str* cm1UpClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmGateToSymClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmPortToSymClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmIntToSymClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmRouterClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmAvailChClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmPresetClassCons( cmDspCtx_t* ctx );