diff --git a/cmProc4.c b/cmProc4.c index dbba19c..afcb46f 100644 --- a/cmProc4.c +++ b/cmProc4.c @@ -2707,6 +2707,8 @@ _cmScModTypeMap_t _cmScModTypeArray[] = { kSetLineModTId, 3, "sline" }, { kPostModTId, 4, "post" }, { kExecModTId, 5, "exec" }, + { kInputModTId, 6, "input" }, + { kCrossModTId, 7, "cross" }, { kInvalidModTId, 0, ""} }; @@ -2748,7 +2750,7 @@ cmScModVar_t* _cmScModulatorInsertVar( cmScModulator* p, unsigned varSymId, unsi { vp = cmMemAllocZ(cmScModVar_t,1); vp->varSymId = varSymId; - vp->outVarId = cmInvalidId; + vp->varId = cmInvalidId; vp->vlink = p->vlist; p->vlist = vp; } @@ -2771,15 +2773,10 @@ cmScModEntry_t* _cmScModulatorInsertEntry(cmScModulator* p, cmScModEntryGroup_t* g->earray[idx].scLocIdx = scLocIdx; 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; } - /* { [ @@ -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(""); + break; + + case kLiteralModPId: + if( pp->val == DBL_MAX ) + printf(" "); + 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(" " ); + 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 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 unsigned paramCnt = cmJsonChildCount(onp); + // fill the entry record and find or create the target var cmScModEntry_t* ep = _cmScModulatorInsertEntry(p,g,i,scLocIdx,varSymId,map->typeId,paramCnt); + typedef struct { const cmChar_t* label; @@ -2932,6 +3039,7 @@ cmRC_t _cmScModParseEntryGroup( cmScModulator* p, cmCtx_t* ctx, cmJsonH_t jsH, c { "val", &ep->beg }, { "end", &ep->end }, { "dur", &ep->dur }, + { "arg", &ep->arg }, { NULL, NULL } }; @@ -2939,7 +3047,21 @@ cmRC_t _cmScModParseEntryGroup( cmScModulator* p, cmCtx_t* ctx, cmJsonH_t jsH, c for(j=0; mapArray[j].param!=NULL; ++j) if((dnp = cmJsonFindValue(jsH,mapArray[j].label, onp, kInvalidTId )) != NULL ) 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: @@ -3022,6 +3144,8 @@ cmRC_t _cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx, p->elist = NULL; p->nei = 0; p->outVarCnt = 0; + p->inVarCnt = 0; + // reload the file 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; for(; g!=NULL; g=g->link) for(i=0; ien; ++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 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; ien; ++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; // if the var does not exist .... @@ -3137,6 +3277,14 @@ cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, doubl 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); vp->min = min; @@ -3146,6 +3294,15 @@ cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, doubl 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 ) { @@ -3171,50 +3328,6 @@ void _cmScModUnlinkActive( cmScModulator* p, cmScModVar_t* vp, cmScModVar_t* pp 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 _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)); } + +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 - cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep ) { @@ -3277,6 +3433,12 @@ cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep ) rc = _cmScModActivateGroup(p,ep); break; + case kInputModTId: + break; + + case kCrossModTId: + break; + default: { assert(0); } } @@ -3306,6 +3468,7 @@ cmRC_t _cmScModExecSendValue( cmScModulator* p, cmScModVar_t* vp ) return rc; } +// Execute a variable. // Return true if vp should be deactivated otherwise return false. bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp ) { @@ -3322,6 +3485,7 @@ bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp ) case kSetModTId: { + // Get a new value for the variable *vp. if((rc = _cmScModGetParam(p,&vp->entry->beg,&vp->value)) != cmOkRC ) goto errLabel; @@ -3343,6 +3507,7 @@ bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp ) if((rc = _cmScModGetParam(p,&vp->entry->dur,&td)) != cmOkRC) goto errLabel; + // update the value of the var *vp 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 ) @@ -3360,6 +3525,16 @@ bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp ) sendFl = false; 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: { 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(""); - break; - - case kLiteralModPId: - if( pp->val == DBL_MAX ) - printf(" "); - 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(" " ); - 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 rc = cmOkRC; 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"); cmScModEntryGroup_t* g = p->glist; @@ -3513,19 +3643,9 @@ cmRC_t cmScModulatorDump( cmScModulator* p ) for(i=0; ien; ++i) { cmScModEntry_t* ep = g->earray + i; - const _cmScModTypeMap_t* tm = _cmScModTypeIdToMap( ep->typeId ); - printf("%3i ",i); - - 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"); + + _cmScModDumpEntry(p,ep); } } diff --git a/cmProc4.h b/cmProc4.h index 6604bbd..b2d3fcb 100644 --- a/cmProc4.h +++ b/cmProc4.h @@ -402,11 +402,21 @@ extern "C" { //( { label:cmScMod file_desc:"Store and recall parameter information under score follower control." kw:[proc] } /* + + File format: + { + entry_group_label : + [ + // entry record + ] + } + + Syntax: - score location - name of the modulator - variable name - - type of operation + - type of operation (see Types: note below) @@ -416,6 +426,7 @@ extern "C" { - type dependent value - see 'Types' below. - ending value for a ramping variable - determines the length of time to get to the ending value + - set to '1' to indicate that this is an input variable The value of parameters may be literal numeric values or may refer to variables by their name. @@ -426,6 +437,8 @@ extern "C" { sline = set to and ramp to over seconds post = send a 'post' msg after each transmission (can be used to change the cross-fader after each msg) exec = execute the entry group + input = declare an 'input' variable and set its and . + cross = generate an output value by interpolating between two preset values. */ enum @@ -436,13 +449,16 @@ extern "C" { 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 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 { 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; @@ -461,11 +477,12 @@ extern "C" { double val; // value of literals } cmScModParam_t; + // cmScModVar_t is used to track the value of a variable. typedef struct cmScModVar_str { unsigned flags; // see kXXXModFl flags above. unsigned varSymId; // variable name - unsigned outVarId; // output var id + unsigned varId; // var id double value; // current value of this variable double v0; // reserved internal variable unsigned phase; // cycle phase since activation @@ -489,6 +506,7 @@ extern "C" { cmScModParam_t min; // min 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 arg; // cross input variable cmScModVar_t* varPtr; // target variable } cmScModEntry_t; @@ -515,11 +533,12 @@ extern "C" { cmScModVar_t* vlist; // variable list cmScModVar_t* alist; // active variable 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 inVarCnt; bool postFl; // send a 'post' msg after each transmission - cmScModEntryGroup_t* xlist; - cmScModEntryGroup_t* glist; + cmScModEntryGroup_t* xlist; // entry group to execute + cmScModEntryGroup_t* glist; // entry group list } cmScModulator; @@ -532,9 +551,14 @@ extern "C" { unsigned cmScModulatorOutVarCount( cmScModulator* p ); // 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 cmScModulatorExec( cmScModulator* p, unsigned scLocIdx ); diff --git a/dsp/cmDspKr.c b/dsp/cmDspKr.c index 2ad5943..23f66f2 100644 --- a/dsp/cmDspKr.c +++ b/dsp/cmDspKr.c @@ -1307,6 +1307,7 @@ void _cmScFolMatcherCb( cmScMatcher* p, void* arg, cmScMatcherResult_t* rp ) cmDsvSetDouble(&vv,ap->sfp->smp->set[i].value); cmDsvSetDouble(&cv,ap->sfp->smp->set[i].match_cost); + for(j=0; jsfp->smp->set[i].sp->sectCnt; ++j) { cmDspStoreSetValueViaSym(ap->ctx->dsH, ap->sfp->smp->set[i].sp->symArray[j], &vv ); @@ -1381,7 +1382,7 @@ cmDspRC_t _cmDspScFolReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* cmDspRC_t rc; if((rc = cmDspApplyAllDefaults(ctx,inst)) != kOkDspRC ) return rc; - + return _cmDspScFolOpenScore(ctx,inst); } @@ -1499,6 +1500,10 @@ typedef struct unsigned offSymId; unsigned postSymId; unsigned dumpSymId; + unsigned minInVarId; + unsigned maxInVarId; + unsigned* inVarIdMap; + unsigned inVarIdOffs; } cmDspScMod_t; 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; } 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 ]; unsigned i; - + unsigned* inVarIdMap = cmMemAllocZ( unsigned, inVarCnt ); cmDspArgCopy( a, argCnt, 0, args, fixArgCnt ); for(i=fixArgCnt; istH, 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 cmDspScMod_t* p = cmDspInstAlloc(cmDspScMod_t,ctx,classPtr,a,instSymId,id,storeSymId,va_cnt,vl); - p->fn = cmMemAllocStr(fn); - p->modLabel = cmMemAllocStr(modLabel); - p->mp = mp; - p->onSymId = cmSymTblId(ctx->stH,"on"); - p->offSymId = cmSymTblId(ctx->stH,"off"); - p->postSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"post"); - p->dumpSymId = cmSymTblId(ctx->stH,"dump"); + p->fn = cmMemAllocStr(fn); + p->modLabel = cmMemAllocStr(modLabel); + p->mp = mp; + p->onSymId = cmSymTblId(ctx->stH,"on"); + p->offSymId = cmSymTblId(ctx->stH,"off"); + p->postSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"post"); + 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 @@ -1609,6 +1626,7 @@ cmDspRC_t _cmDspScModFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* cmMemFree(p->fn); cmMemFree(p->modLabel); + cmMemFree(p->inVarIdMap); return rc; } @@ -1627,6 +1645,13 @@ cmDspRC_t _cmDspScModRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* cmDspScMod_t* p = (cmDspScMod_t*)inst; 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 ) {