cmProc4.h/c, cmDspKr.c : Initial changes to support scMod 'in' and 'cross'.

This commit is contained in:
kevin 2017-10-20 14:53:11 -04:00
parent 3dd3d9818a
commit 286a303d04
3 changed files with 303 additions and 134 deletions

338
cmProc4.c
View File

@ -2707,6 +2707,8 @@ _cmScModTypeMap_t _cmScModTypeArray[] =
{ kSetLineModTId, 3, "sline" }, { kSetLineModTId, 3, "sline" },
{ kPostModTId, 4, "post" }, { kPostModTId, 4, "post" },
{ kExecModTId, 5, "exec" }, { kExecModTId, 5, "exec" },
{ kInputModTId, 6, "input" },
{ kCrossModTId, 7, "cross" },
{ kInvalidModTId, 0, "<invalid>"} { kInvalidModTId, 0, "<invalid>"}
}; };
@ -2748,7 +2750,7 @@ cmScModVar_t* _cmScModulatorInsertVar( cmScModulator* p, unsigned varSymId, unsi
{ {
vp = cmMemAllocZ(cmScModVar_t,1); vp = cmMemAllocZ(cmScModVar_t,1);
vp->varSymId = varSymId; vp->varSymId = varSymId;
vp->outVarId = cmInvalidId; vp->varId = cmInvalidId;
vp->vlink = p->vlist; vp->vlink = p->vlist;
p->vlist = vp; p->vlist = vp;
} }
@ -2771,15 +2773,10 @@ cmScModEntry_t* _cmScModulatorInsertEntry(cmScModulator* p, cmScModEntryGroup_t*
g->earray[idx].scLocIdx = scLocIdx; g->earray[idx].scLocIdx = scLocIdx;
g->earray[idx].typeId = typeId; g->earray[idx].typeId = typeId;
g->earray[idx].varPtr = _cmScModulatorInsertVar(p,varSymId,0);
if( g->earray[idx].varPtr->outVarId == cmInvalidIdx )
g->earray[idx].varPtr->outVarId = p->outVarCnt++;
return g->earray + idx; return g->earray + idx;
} }
/* /*
{ {
[ [
@ -2833,6 +2830,114 @@ cmRC_t _cmScModulatorParseParam( cmScModulator* p, cmSymTblH_t stH, cmJsonNode_t
} }
// If the requested parameter has a value then return it in *valPtr.
// If it does not then do nothing. This function applies scaling to RHS values.
cmRC_t _cmScModGetParam( cmScModulator* p, const cmScModParam_t* pp, double* valPtr )
{
cmRC_t rc = cmOkRC;
switch( pp->pid )
{
case kInvalidModPId:
rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "An invalid parameter was encountered.");
goto errLabel;
break;
case kLiteralModPId:
*valPtr = pp->val;
break;
case kSymbolModPId:
{
cmScModVar_t* vp;
// get a pointer to the parameter variable
if((vp = _cmScModSymToVar(p, pp->symId )) == NULL )
{
rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Variable '%s' not found.",cmSymTblLabel(p->stH,pp->symId));
goto errLabel;
}
// if this is not a 'calculated' paramter then scale it here.
if( cmIsFlag(vp->flags,kCalcModFl ) && vp->min!=DBL_MAX && vp->max!=DBL_MAX )
*valPtr = (vp->value - vp->min)/(vp->max-vp->min);
else
*valPtr = vp->value;
}
break;
default:
{ assert(0); }
}
errLabel:
return rc;
}
void _cmScModDumpParam( cmScModulator* p, const cmChar_t* label, const cmScModParam_t* pp )
{
printf("%s: ",label);
switch( pp->pid )
{
case kInvalidModPId:
printf("<invalid>");
break;
case kLiteralModPId:
if( pp->val == DBL_MAX )
printf("<max> ");
else
printf("%f ",pp->val);
break;
case kSymbolModPId:
printf("%s ",cmSymTblLabel(p->stH,pp->symId));
break;
default:
{ assert(0); }
}
}
void _cmScModDumpVal( cmChar_t* label, double val )
{
printf("%s:",label);
if( val == DBL_MAX )
printf("<max> " );
else
printf("%f ",val);
}
void _cmScModDumpVar( cmScModulator* p, const cmScModVar_t* vp )
{
printf("%7s %3i fl:0x%x entry:%p alink:%p %s",cmSymTblLabel(p->stH,vp->varSymId),vp->varId,vp->flags,vp->entry,vp->alink, cmIsFlag(vp->flags,kInputModFl)?"input":"");
_cmScModDumpVal("val",vp->value);
_cmScModDumpVal("min",vp->min);
_cmScModDumpVal("max",vp->max);
_cmScModDumpVal("rate",vp->rate);
_cmScModDumpVal("v0",vp->v0);
}
void _cmScModDumpEntry( cmScModulator* p, const cmScModEntry_t* ep)
{
const _cmScModTypeMap_t* tm = _cmScModTypeIdToMap( ep->typeId );
printf("%10i ",ep->scLocIdx);
printf("%5s %7s", tm==NULL ? "invld" : tm->label, cmSymTblLabel(p->stH,ep->varPtr->varSymId));
_cmScModDumpParam(p," beg", &ep->beg);
_cmScModDumpParam(p," end", &ep->end);
_cmScModDumpParam(p," min", &ep->min);
_cmScModDumpParam(p," max", &ep->max);
_cmScModDumpParam(p," rate",&ep->rate);
printf("\n");
}
cmRC_t _cmScModParseEntryGroup( cmScModulator* p, cmCtx_t* ctx, cmJsonH_t jsH, cmSymTblH_t stH, cmJsonNode_t* jnp, cmScModEntryGroup_t* g, const cmChar_t* fn ) cmRC_t _cmScModParseEntryGroup( cmScModulator* p, cmCtx_t* ctx, cmJsonH_t jsH, cmSymTblH_t stH, cmJsonNode_t* jnp, cmScModEntryGroup_t* g, const cmChar_t* fn )
{ {
cmRC_t rc = cmOkRC; cmRC_t rc = cmOkRC;
@ -2914,9 +3019,11 @@ cmRC_t _cmScModParseEntryGroup( cmScModulator* p, cmCtx_t* ctx, cmJsonH_t jsH, c
// get the count of the elmenets in the data array // get the count of the elmenets in the data array
unsigned paramCnt = cmJsonChildCount(onp); unsigned paramCnt = cmJsonChildCount(onp);
// fill the entry record and find or create the target var // fill the entry record and find or create the target var
cmScModEntry_t* ep = _cmScModulatorInsertEntry(p,g,i,scLocIdx,varSymId,map->typeId,paramCnt); cmScModEntry_t* ep = _cmScModulatorInsertEntry(p,g,i,scLocIdx,varSymId,map->typeId,paramCnt);
typedef struct typedef struct
{ {
const cmChar_t* label; const cmChar_t* label;
@ -2932,6 +3039,7 @@ cmRC_t _cmScModParseEntryGroup( cmScModulator* p, cmCtx_t* ctx, cmJsonH_t jsH, c
{ "val", &ep->beg }, { "val", &ep->beg },
{ "end", &ep->end }, { "end", &ep->end },
{ "dur", &ep->dur }, { "dur", &ep->dur },
{ "arg", &ep->arg },
{ NULL, NULL } { NULL, NULL }
}; };
@ -2940,6 +3048,20 @@ cmRC_t _cmScModParseEntryGroup( cmScModulator* p, cmCtx_t* ctx, cmJsonH_t jsH, c
if((dnp = cmJsonFindValue(jsH,mapArray[j].label, onp, kInvalidTId )) != NULL ) if((dnp = cmJsonFindValue(jsH,mapArray[j].label, onp, kInvalidTId )) != NULL )
if((rc = _cmScModulatorParseParam(p,stH,dnp,mapArray[j].param)) != cmOkRC ) if((rc = _cmScModulatorParseParam(p,stH,dnp,mapArray[j].param)) != cmOkRC )
goto errLabel; goto errLabel;
// create the variable associated with this entry
ep->varPtr = _cmScModulatorInsertVar(p,varSymId, ep->typeId==kInputModTId ? kInputModFl : 0);
// set the variable id value
if( ep->varPtr->varId == cmInvalidIdx )
{
if( ep->typeId != kInputModTId )
ep->varPtr->varId = p->outVarCnt++;
else
ep->varPtr->varId = p->inVarCnt++;
}
} }
errLabel: errLabel:
@ -3022,6 +3144,8 @@ cmRC_t _cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx,
p->elist = NULL; p->elist = NULL;
p->nei = 0; p->nei = 0;
p->outVarCnt = 0; p->outVarCnt = 0;
p->inVarCnt = 0;
// reload the file // reload the file
if((rc = _cmScModulatorParse(p,ctx,p->stH,p->fn)) != cmOkRC ) if((rc = _cmScModulatorParse(p,ctx,p->stH,p->fn)) != cmOkRC )
@ -3120,13 +3244,29 @@ cmScModVar_t* cmScModulatorOutVar( cmScModulator* p, unsigned idx )
cmScModEntryGroup_t* g = p->glist; cmScModEntryGroup_t* g = p->glist;
for(; g!=NULL; g=g->link) for(; g!=NULL; g=g->link)
for(i=0; i<g->en; ++i) for(i=0; i<g->en; ++i)
if( g->earray[i].varPtr->outVarId == idx ) if( cmIsNotFlag(g->earray[i].varPtr->flags,kInputModFl) && g->earray[i].varPtr->varId == idx )
return g->earray[i].varPtr; return g->earray[i].varPtr;
return NULL; return NULL;
} }
cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, double value, double min, double max ) unsigned cmScModulatorInVarCount( cmScModulator* p )
{ return p->inVarCnt; }
cmScModVar_t* cmScModulatorInVar( cmScModulator* p, unsigned idx )
{
unsigned i;
cmScModEntryGroup_t* g = p->glist;
for(; g!=NULL; g=g->link)
for(i=0; i<g->en; ++i)
if( cmIsFlag(g->earray[i].varPtr->flags,kInputModFl) && g->earray[i].varPtr->varId == idx )
return g->earray[i].varPtr;
return NULL;
}
cmScModVar_t* _cmScModSetValuePrefix( cmScModulator* p, unsigned varSymId )
{ {
cmScModVar_t* vp; cmScModVar_t* vp;
// if the var does not exist .... // if the var does not exist ....
@ -3137,6 +3277,14 @@ cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, doubl
assert(vp!=NULL); assert(vp!=NULL);
} }
return vp;
}
cmRC_t cmScModulatorSetValueMinMax( cmScModulator* p, unsigned varSymId, double value, double min, double max )
{
cmScModVar_t* vp = _cmScModSetValuePrefix(p, varSymId );
assert( min <= max); assert( min <= max);
vp->min = min; vp->min = min;
@ -3146,6 +3294,15 @@ cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, doubl
return cmOkRC; return cmOkRC;
} }
cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, double value )
{
cmScModVar_t* vp = _cmScModSetValuePrefix(p, varSymId );
vp->value = value;
return cmOkRC;
}
cmRC_t cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx, unsigned entryGroupSymId ) cmRC_t cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx, unsigned entryGroupSymId )
{ {
@ -3171,50 +3328,6 @@ void _cmScModUnlinkActive( cmScModulator* p, cmScModVar_t* vp, cmScModVar_t* pp
vp->entry = NULL; vp->entry = NULL;
} }
// If the requested parameter has a value then return it in *valPtr.
// If it does not then do nothing. This function applies scaling to RHS values.
cmRC_t _cmScModGetParam( cmScModulator* p, const cmScModParam_t* pp, double* valPtr )
{
cmRC_t rc = cmOkRC;
switch( pp->pid )
{
case kInvalidModPId:
rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "An invalid parameter was encountered.");
goto errLabel;
break;
case kLiteralModPId:
*valPtr = pp->val;
break;
case kSymbolModPId:
{
cmScModVar_t* vp;
// get a pointer to the parameter variable
if((vp = _cmScModSymToVar(p, pp->symId )) == NULL )
{
rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Variable '%s' not found.",cmSymTblLabel(p->stH,pp->symId));
goto errLabel;
}
// if this is not a 'calculated' paramter then scale it here.
if( cmIsFlag(vp->flags,kCalcModFl ) && vp->min!=DBL_MAX && vp->max!=DBL_MAX )
*valPtr = (vp->value - vp->min)/(vp->max-vp->min);
else
*valPtr = vp->value;
}
break;
default:
{ assert(0); }
}
errLabel:
return rc;
}
cmRC_t _cmScModActivateEntries( cmScModulator* p, cmScModEntry_t* earray, unsigned* idxRef, unsigned cnt, unsigned scLocIdx ); cmRC_t _cmScModActivateEntries( cmScModulator* p, cmScModEntry_t* earray, unsigned* idxRef, unsigned cnt, unsigned scLocIdx );
cmRC_t _cmScModActivateGroup( cmScModulator* p, cmScModEntry_t* ep ) cmRC_t _cmScModActivateGroup( cmScModulator* p, cmScModEntry_t* ep )
@ -3231,6 +3344,49 @@ cmRC_t _cmScModActivateGroup( cmScModulator* p, cmScModEntry_t* ep )
return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Entry group '%s' not found.",cmSymTblLabel(p->stH,ep->beg.symId)); return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Entry group '%s' not found.",cmSymTblLabel(p->stH,ep->beg.symId));
} }
cmRC_t _cmScModGetCrossParam( cmScModulator* p, cmScModEntry_t* ep, cmScModParam_t* pp, const cmChar_t* label, double* valRef )
{
cmRC_t rc;
if((rc = _cmScModGetParam(p, pp, valRef )) != cmOkRC )
rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Invalid %s parameter for cross variable:%s",label,cmSymTblLabel(p->stH,ep->varPtr->varSymId) );
return rc;
}
cmRC_t _cmScModExecCross( cmScModulator* p, cmScModEntry_t* ep )
{
cmRC_t rc = cmOkRC;
double x = 0.0;
//double x0 = 0.0, x1 = 0.0;
double y0 = 0.0, y1 = 0.0;
if((rc = _cmScModGetCrossParam(p, ep, &ep->arg, "src var", &x )) != cmOkRC )
return rc;
//if((rc = _cmScModGetCrossParam(p, ep, &ep->beg, "src min", &x0 )) != cmOkRC )
// return rc;
//if((rc = _cmScModGetCrossParam(p, ep, &ep->end, "src max", &x1 )) != cmOkRC )
// return rc;
if((rc = _cmScModGetCrossParam(p, ep, &ep->min, "dst min", &y0 )) != cmOkRC )
return rc;
if((rc = _cmScModGetCrossParam(p, ep, &ep->max, "dst max", &y1 )) != cmOkRC )
return rc;
//double xx = x0 + (x-x0) / (x1-x0);
printf("%s x:%f y0:%f y1:%f\n",__FUNCTION__,x,y0,y1);
ep->varPtr->value = y0 + x * (y1-y0);
return rc;
}
// Type specific variable activation - // Type specific variable activation -
cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep ) cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep )
{ {
@ -3277,6 +3433,12 @@ cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep )
rc = _cmScModActivateGroup(p,ep); rc = _cmScModActivateGroup(p,ep);
break; break;
case kInputModTId:
break;
case kCrossModTId:
break;
default: default:
{ assert(0); } { assert(0); }
} }
@ -3306,6 +3468,7 @@ cmRC_t _cmScModExecSendValue( cmScModulator* p, cmScModVar_t* vp )
return rc; return rc;
} }
// Execute a variable.
// Return true if vp should be deactivated otherwise return false. // Return true if vp should be deactivated otherwise return false.
bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp ) bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp )
{ {
@ -3322,6 +3485,7 @@ bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp )
case kSetModTId: case kSetModTId:
{ {
// Get a new value for the variable *vp.
if((rc = _cmScModGetParam(p,&vp->entry->beg,&vp->value)) != cmOkRC ) if((rc = _cmScModGetParam(p,&vp->entry->beg,&vp->value)) != cmOkRC )
goto errLabel; goto errLabel;
@ -3343,6 +3507,7 @@ bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp )
if((rc = _cmScModGetParam(p,&vp->entry->dur,&td)) != cmOkRC) if((rc = _cmScModGetParam(p,&vp->entry->dur,&td)) != cmOkRC)
goto errLabel; goto errLabel;
// update the value of the var *vp
double v = vp->v0 + (v1-vp->v0) * (vp->phase * p->samplesPerCycle) / (p->srate * td); double v = vp->v0 + (v1-vp->v0) * (vp->phase * p->samplesPerCycle) / (p->srate * td);
if((fl = (vp->value <= v1 && v >= v1) || (vp->value >= v1 && v <= v1 )) == true ) if((fl = (vp->value <= v1 && v >= v1) || (vp->value >= v1 && v <= v1 )) == true )
@ -3360,6 +3525,16 @@ bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp )
sendFl = false; sendFl = false;
break; break;
case kInputModTId:
sendFl = false;
break;
case kCrossModTId:
_cmScModExecCross(p,vp->entry);
vp->phase = 0; // force the value to be sent
fl = true;
break;
default: default:
{ assert(0); } { assert(0); }
} }
@ -3451,58 +3626,13 @@ cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx )
} }
void _cmScModDumpParam( cmScModulator* p, const cmChar_t* label, cmScModParam_t* pp )
{
printf("%s: ",label);
switch( pp->pid )
{
case kInvalidModPId:
printf("<invalid>");
break;
case kLiteralModPId:
if( pp->val == DBL_MAX )
printf("<max> ");
else
printf("%f ",pp->val);
break;
case kSymbolModPId:
printf("%s ",cmSymTblLabel(p->stH,pp->symId));
break;
default:
{ assert(0); }
}
}
void _cmScModDumpVal( cmChar_t* label, double val )
{
printf("%s:",label);
if( val == DBL_MAX )
printf("<max> " );
else
printf("%f ",val);
}
void _cmScModDumpVar( cmScModulator* p, const cmScModVar_t* vp )
{
printf("%7s %3i fl:0x%x entry:%p alink:%p ",cmSymTblLabel(p->stH,vp->varSymId),vp->outVarId,vp->flags,vp->entry,vp->alink);
_cmScModDumpVal("val",vp->value);
_cmScModDumpVal("min",vp->min);
_cmScModDumpVal("max",vp->max);
_cmScModDumpVal("rate",vp->rate);
_cmScModDumpVal("v0",vp->v0);
}
cmRC_t cmScModulatorDump( cmScModulator* p ) cmRC_t cmScModulatorDump( cmScModulator* p )
{ {
cmRC_t rc = cmOkRC; cmRC_t rc = cmOkRC;
printf("MOD:\n"); printf("MOD:\n");
printf("nei:%i alist:%p outVarCnt:%i\n",p->nei,p->alist,p->outVarCnt); printf("nei:%i alist:%p outVarCnt:%i inVarCnt:%i\n",p->nei,p->alist,p->outVarCnt,p->inVarCnt);
printf("ENTRIES:\n"); printf("ENTRIES:\n");
cmScModEntryGroup_t* g = p->glist; cmScModEntryGroup_t* g = p->glist;
@ -3513,19 +3643,9 @@ cmRC_t cmScModulatorDump( cmScModulator* p )
for(i=0; i<g->en; ++i) for(i=0; i<g->en; ++i)
{ {
cmScModEntry_t* ep = g->earray + i; cmScModEntry_t* ep = g->earray + i;
const _cmScModTypeMap_t* tm = _cmScModTypeIdToMap( ep->typeId );
printf("%3i ",i); printf("%3i ",i);
printf("%10i ",ep->scLocIdx); _cmScModDumpEntry(p,ep);
printf("%5s %7s", tm==NULL ? "invld" : tm->label, cmSymTblLabel(p->stH,ep->varPtr->varSymId));
_cmScModDumpParam(p," beg", &ep->beg);
_cmScModDumpParam(p," end", &ep->end);
_cmScModDumpParam(p," min", &ep->min);
_cmScModDumpParam(p," max", &ep->max);
_cmScModDumpParam(p," rate",&ep->rate);
printf("\n");
} }
} }

View File

@ -402,11 +402,21 @@ extern "C" {
//( { label:cmScMod file_desc:"Store and recall parameter information under score follower control." kw:[proc] } //( { label:cmScMod file_desc:"Store and recall parameter information under score follower control." kw:[proc] }
/* /*
File format:
{
entry_group_label :
[
<loc> <mod> <var> <type> <params> // entry record
]
}
Syntax: <loc> <mod> <var> <type> <params> Syntax: <loc> <mod> <var> <type> <params>
<loc> - score location <loc> - score location
<mod> - name of the modulator <mod> - name of the modulator
<var> - variable name <var> - variable name
<type> - type of operation <type> - type of operation (see Types: note below)
<params> <params>
@ -416,6 +426,7 @@ extern "C" {
<val> - type dependent value - see 'Types' below. <val> - type dependent value - see 'Types' below.
<end> - ending value for a ramping variable <end> - ending value for a ramping variable
<dur> - determines the length of time to get to the ending value <dur> - determines the length of time to get to the ending value
<in> - set to '1' to indicate that this is an input variable
The value of parameters may be literal numeric values or may refer to The value of parameters may be literal numeric values or may refer to
variables by their name. variables by their name.
@ -426,6 +437,8 @@ extern "C" {
sline = set <var> to <val> and ramp to <end> over <dur> seconds sline = set <var> to <val> and ramp to <end> over <dur> seconds
post = send a 'post' msg after each transmission (can be used to change the cross-fader after each msg) post = send a 'post' msg after each transmission (can be used to change the cross-fader after each msg)
exec = execute the entry group <val> exec = execute the entry group <val>
input = declare an 'input' variable and set its <min> and <max>.
cross = generate an output value by interpolating between two preset values.
*/ */
enum enum
@ -436,13 +449,16 @@ extern "C" {
kLineModTId, // linear ramp variable to parray[0] over parray[1] seconds kLineModTId, // linear ramp variable to parray[0] over parray[1] seconds
kSetLineModTId, // set variable to parray[0] and ramp to parray[1] over parray[2] seconds kSetLineModTId, // set variable to parray[0] and ramp to parray[1] over parray[2] seconds
kPostModTId, // kPostModTId, //
kExecModTId // execute an entry group kExecModTId, // execute an entry group
kInputModTId, // This is an 'input' variable.
kCrossModTId // generate an output value by interpolating between two preset variable values
}; };
enum enum
{ {
kActiveModFl = 0x01, // this variable is on the 'active' list kActiveModFl = 0x01, // this variable is on the 'active' list
kCalcModFl = 0x02 // when this variable is used as a parameter it's value must be calculated rather than used directly. kCalcModFl = 0x02, // when this variable is used as a parameter it's value must be calculated rather than used directly.
kInputModFl = 0x04 // this is an input variable
}; };
struct cmScModEntry_str; struct cmScModEntry_str;
@ -461,11 +477,12 @@ extern "C" {
double val; // value of literals double val; // value of literals
} cmScModParam_t; } cmScModParam_t;
// cmScModVar_t is used to track the value of a variable.
typedef struct cmScModVar_str typedef struct cmScModVar_str
{ {
unsigned flags; // see kXXXModFl flags above. unsigned flags; // see kXXXModFl flags above.
unsigned varSymId; // variable name unsigned varSymId; // variable name
unsigned outVarId; // output var id unsigned varId; // var id
double value; // current value of this variable double value; // current value of this variable
double v0; // reserved internal variable double v0; // reserved internal variable
unsigned phase; // cycle phase since activation unsigned phase; // cycle phase since activation
@ -489,6 +506,7 @@ extern "C" {
cmScModParam_t min; // min value for this variable cmScModParam_t min; // min value for this variable
cmScModParam_t max; // max value for this variable cmScModParam_t max; // max value for this variable
cmScModParam_t rate; // update rate in milliseconds (DBL_MAX to disable) cmScModParam_t rate; // update rate in milliseconds (DBL_MAX to disable)
cmScModParam_t arg; // cross input variable
cmScModVar_t* varPtr; // target variable cmScModVar_t* varPtr; // target variable
} cmScModEntry_t; } cmScModEntry_t;
@ -515,11 +533,12 @@ extern "C" {
cmScModVar_t* vlist; // variable list cmScModVar_t* vlist; // variable list
cmScModVar_t* alist; // active variable list cmScModVar_t* alist; // active variable list
cmScModVar_t* elist; // last element on the active list cmScModVar_t* elist; // last element on the active list
unsigned nei; // next entry index unsigned nei; // next entry index in xlist->earray[] to examine for activation
unsigned outVarCnt; // count of unique vars that are targets of entry recds unsigned outVarCnt; // count of unique vars that are targets of entry recds
unsigned inVarCnt;
bool postFl; // send a 'post' msg after each transmission bool postFl; // send a 'post' msg after each transmission
cmScModEntryGroup_t* xlist; cmScModEntryGroup_t* xlist; // entry group to execute
cmScModEntryGroup_t* glist; cmScModEntryGroup_t* glist; // entry group list
} cmScModulator; } cmScModulator;
@ -534,7 +553,12 @@ extern "C" {
// Return a pointer to the variable at vlist[idx]. // Return a pointer to the variable at vlist[idx].
cmScModVar_t* cmScModulatorOutVar( cmScModulator* p, unsigned idx ); cmScModVar_t* cmScModulatorOutVar( cmScModulator* p, unsigned idx );
cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, double value, double min, double max ); unsigned cmScModulatorInVarCount( cmScModulator* p );
cmScModVar_t* cmScModulatorInVar( cmScModulator* p, unsigned idx );
cmRC_t cmScModulatorSetValueMinMax( cmScModulator* p, unsigned varSymId, double value, double min, double max );
cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, double value );
cmRC_t cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx, unsigned entryGroupSymId ); cmRC_t cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx, unsigned entryGroupSymId );
cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx ); cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx );

View File

@ -1307,6 +1307,7 @@ void _cmScFolMatcherCb( cmScMatcher* p, void* arg, cmScMatcherResult_t* rp )
cmDsvSetDouble(&vv,ap->sfp->smp->set[i].value); cmDsvSetDouble(&vv,ap->sfp->smp->set[i].value);
cmDsvSetDouble(&cv,ap->sfp->smp->set[i].match_cost); cmDsvSetDouble(&cv,ap->sfp->smp->set[i].match_cost);
for(j=0; j<ap->sfp->smp->set[i].sp->sectCnt; ++j) for(j=0; j<ap->sfp->smp->set[i].sp->sectCnt; ++j)
{ {
cmDspStoreSetValueViaSym(ap->ctx->dsH, ap->sfp->smp->set[i].sp->symArray[j], &vv ); cmDspStoreSetValueViaSym(ap->ctx->dsH, ap->sfp->smp->set[i].sp->symArray[j], &vv );
@ -1499,6 +1500,10 @@ typedef struct
unsigned offSymId; unsigned offSymId;
unsigned postSymId; unsigned postSymId;
unsigned dumpSymId; unsigned dumpSymId;
unsigned minInVarId;
unsigned maxInVarId;
unsigned* inVarIdMap;
unsigned inVarIdOffs;
} cmDspScMod_t; } cmDspScMod_t;
void _cmDspScModCb( void* arg, unsigned varSymId, double value, bool postFl ) void _cmDspScModCb( void* arg, unsigned varSymId, double value, bool postFl )
@ -1560,33 +1565,45 @@ cmDspInst_t* _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
return NULL; return NULL;
} }
unsigned fixArgCnt = sizeof(args)/sizeof(args[0]) - 1; unsigned fixArgCnt = sizeof(args)/sizeof(args[0]) - 1;
unsigned argCnt = fixArgCnt + cmScModulatorOutVarCount(mp); unsigned outVarCnt = cmScModulatorOutVarCount(mp);
unsigned inVarCnt = cmScModulatorInVarCount(mp);
unsigned argCnt = fixArgCnt + inVarCnt + outVarCnt;
cmDspVarArg_t a[ argCnt+1 ]; cmDspVarArg_t a[ argCnt+1 ];
unsigned i; unsigned i;
unsigned* inVarIdMap = cmMemAllocZ( unsigned, inVarCnt );
cmDspArgCopy( a, argCnt, 0, args, fixArgCnt ); cmDspArgCopy( a, argCnt, 0, args, fixArgCnt );
for(i=fixArgCnt; i<argCnt; ++i) for(i=fixArgCnt; i<argCnt; ++i)
{ {
unsigned varIdx = i - fixArgCnt; unsigned inVarIdx = i - fixArgCnt;
const cmScModVar_t* vp = cmScModulatorOutVar(mp,varIdx); unsigned outVarIdx = inVarIdx - inVarCnt;
bool inputFl = inVarIdx < inVarCnt;
const cmScModVar_t* vp = inputFl ? cmScModulatorInVar(mp,inVarIdx) : cmScModulatorOutVar(mp,outVarIdx);
const cmChar_t* label = cmSymTblLabel( ctx->stH, vp->varSymId ); const cmChar_t* label = cmSymTblLabel( ctx->stH, vp->varSymId );
const cmChar_t* docStr = cmTsPrintfS("Variable output for %s",label); const cmChar_t* docStr = cmTsPrintfS("Variable %s for %s",inputFl?"input":"output",label);
unsigned flags = inputFl ? kInDsvFl : kOutDsvFl;
cmDspArgSetup(ctx, a + i, label, cmInvalidId, i, 0, 0, kOutDsvFl | kDoubleDsvFl, docStr ); if( inputFl )
inVarIdMap[ inVarIdx ] = vp->varSymId;
cmDspArgSetup(ctx, a + i, label, cmInvalidId, i, 0, 0, flags | kDoubleDsvFl, docStr );
} }
cmDspArgSetupNull(a+argCnt); // set terminating arg. flags cmDspArgSetupNull(a+argCnt); // set terminating arg. flags
cmDspScMod_t* p = cmDspInstAlloc(cmDspScMod_t,ctx,classPtr,a,instSymId,id,storeSymId,va_cnt,vl); cmDspScMod_t* p = cmDspInstAlloc(cmDspScMod_t,ctx,classPtr,a,instSymId,id,storeSymId,va_cnt,vl);
p->fn = cmMemAllocStr(fn); p->fn = cmMemAllocStr(fn);
p->modLabel = cmMemAllocStr(modLabel); p->modLabel = cmMemAllocStr(modLabel);
p->mp = mp; p->mp = mp;
p->onSymId = cmSymTblId(ctx->stH,"on"); p->onSymId = cmSymTblId(ctx->stH,"on");
p->offSymId = cmSymTblId(ctx->stH,"off"); p->offSymId = cmSymTblId(ctx->stH,"off");
p->postSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"post"); p->postSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"post");
p->dumpSymId = cmSymTblId(ctx->stH,"dump"); p->dumpSymId = cmSymTblId(ctx->stH,"dump");
p->minInVarId = fixArgCnt;
p->maxInVarId = p->minInVarId + inVarCnt - 1;
p->inVarIdMap = inVarIdMap;
p->inVarIdOffs = fixArgCnt;
mp->cbArg = p; // set the modulator callback arg mp->cbArg = p; // set the modulator callback arg
@ -1609,6 +1626,7 @@ cmDspRC_t _cmDspScModFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
cmMemFree(p->fn); cmMemFree(p->fn);
cmMemFree(p->modLabel); cmMemFree(p->modLabel);
cmMemFree(p->inVarIdMap);
return rc; return rc;
} }
@ -1628,6 +1646,13 @@ cmDspRC_t _cmDspScModRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
cmDspSetEvent(ctx,inst,evt); cmDspSetEvent(ctx,inst,evt);
if( p->minInVarId <= evt->dstVarId && evt->dstVarId <= p->maxInVarId )
{
double v = cmDspDouble(inst,evt->dstVarId);
printf("%s : %i %f\n",__FUNCTION__,evt->dstVarId,v);
cmScModulatorSetValue( p->mp, p->inVarIdMap[ evt->dstVarId - p->inVarIdOffs ], v );
}
switch( evt->dstVarId ) switch( evt->dstVarId )
{ {
case kResetIdxMdId: case kResetIdxMdId: