cmProc4.h/c, cmDspKr.c : Changed cmScModulator to use entry groups rather than a single entry list.

This commit is contained in:
kevin 2016-07-13 16:43:01 -04:00
parent 6331cb1753
commit 7ff73452e2
3 changed files with 150 additions and 269 deletions

369
cmProc4.c
View File

@ -2686,8 +2686,8 @@ cmRC_t cmScModulatorFree( cmScModulator** pp )
if((rc = cmScModulatorFinal(p)) != cmOkRC ) if((rc = cmScModulatorFinal(p)) != cmOkRC )
return rc; return rc;
cmMemFree(p->earray); //cmMemFree(p->earray);
cmMemFree(p->xlist); //cmMemFree(p->xlist);
cmObjFree(pp); cmObjFree(pp);
return rc; return rc;
} }
@ -2743,6 +2743,7 @@ cmScModVar_t* _cmScModulatorInsertVar( cmScModulator* p, unsigned varSymId, unsi
{ {
cmScModVar_t* vp = _cmScModSymToVar(p,varSymId); cmScModVar_t* vp = _cmScModSymToVar(p,varSymId);
// if the specified variable was not found then create one
if( vp == NULL ) if( vp == NULL )
{ {
vp = cmMemAllocZ(cmScModVar_t,1); vp = cmMemAllocZ(cmScModVar_t,1);
@ -2764,19 +2765,18 @@ cmScModVar_t* _cmScModulatorInsertVar( cmScModulator* p, unsigned varSymId, unsi
return vp; return vp;
} }
cmScModEntry_t* _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocIdx, unsigned modSymId, unsigned varSymId, unsigned typeId, unsigned entryFlags, unsigned paramCnt ) cmScModEntry_t* _cmScModulatorInsertEntry(cmScModulator* p, cmScModEntryGroup_t* g, unsigned idx, unsigned scLocIdx, unsigned varSymId, unsigned typeId, unsigned paramCnt )
{ {
assert( idx < p->en ); assert( idx < g->en );
p->earray[idx].scLocIdx = scLocIdx; g->earray[idx].scLocIdx = scLocIdx;
p->earray[idx].typeId = typeId; g->earray[idx].typeId = typeId;
p->earray[idx].varPtr = _cmScModulatorInsertVar(p,varSymId,0); g->earray[idx].varPtr = _cmScModulatorInsertVar(p,varSymId,0);
p->earray[idx].flags = entryFlags;
if( p->earray[idx].varPtr->outVarId == cmInvalidIdx ) if( g->earray[idx].varPtr->outVarId == cmInvalidIdx )
p->earray[idx].varPtr->outVarId = p->outVarCnt++; g->earray[idx].varPtr->outVarId = p->outVarCnt++;
return p->earray + idx; return g->earray + idx;
} }
@ -2833,169 +2833,36 @@ cmScModEntry_t* _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsign
} }
void _cmScProcessEntryGroups( cmScModulator* p ) cmRC_t _cmScModParseEntryGroup( cmScModulator* p, cmCtx_t* ctx, cmJsonH_t jsH, cmSymTblH_t stH, cmJsonNode_t* jnp, cmScModEntryGroup_t* g, const cmChar_t* fn )
{
unsigned i=0;
cmScModEntryGroup_t* g0 = NULL;
cmScModEntryGroup_t* g1 = p->glist;
while( i<p->en )
{
// if this is the first entry in a group
if( cmIsFlag(p->earray[i].flags , kLocLabelEntryFl ) )
{
// if no group record is avaiable ...
if( g1 == NULL )
{
// ... then allocate one and ...
g1 = cmMemAllocZ(cmScModEntryGroup_t,1);
// ... link it to the end of the group list
if( g0 == NULL )
p->glist = g1;
else
g0->link = g1;
}
unsigned j;
g1->n = 0;
// get a count of the entries in this group
while( i<p->en && p->earray[i+g1->n].scLocIdx == p->earray[i].scLocIdx )
g1->n += 1;
// allocate an array to hold the group
g1->base = cmMemResizeZ(cmScModEntry_t*,g1->base,g1->n);
for(j=0; j<g1->n; ++j)
g1->base[j] = p->earray + i + j;
i += g1->n;
// make the next group record available
g0 = g1;
g1 = g1->link;
}
else
{
i += 1;
}
}
// set successive records as invalid
for(; g1 != NULL; g1=g1->link)
g1->base = NULL;
}
void _cmScProcessExecList( cmScModulator* p )
{
unsigned i,j;
unsigned n = 0;
for(i=0; i<p->en; ++i)
if( cmIsNotFlag(p->earray[i].flags,kLocLabelEntryFl) )
n += 1;
p->xlist = cmMemResizeZ(cmScModEntry_t*,p->xlist,n);
p->xn = n;
for(i=0,j=0; i<p->en; ++i)
if( cmIsNotFlag(p->earray[i].flags,kLocLabelEntryFl) )
p->xlist[j++] = p->earray + i;
assert( j == p->xn );
}
cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, const cmChar_t* fn )
{ {
cmRC_t rc = cmOkRC; cmRC_t rc = cmOkRC;
cmJsonNode_t* jnp = NULL; unsigned prvScLocIdx = cmInvalidIdx;
cmJsonH_t jsH = cmJsonNullHandle; const cmChar_t* prvVarLabel = "<dummy>";
unsigned i = cmInvalidIdx; const cmChar_t* prvTypeLabel = NULL;
unsigned j = cmInvalidIdx; unsigned i;
// read the JSON file
if( cmJsonInitializeFromFile(&jsH, fn, ctx ) != kOkJsRC )
return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "JSON file parse failed on the modulator file: %s.",cmStringNullGuard(fn) );
jnp = cmJsonRoot(jsH);
// validate that the first child as an array
if( jnp==NULL || ((jnp = cmJsonNodeMemberValue(jnp,"array")) == NULL) || cmJsonIsArray(jnp)==false )
{
rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Modulator file header syntax error in file:%s",cmStringNullGuard(fn) );
goto errLabel;
}
// allocate the entry array // allocate the entry array
unsigned entryCnt = cmJsonChildCount(jnp); unsigned entryCnt = cmJsonChildCount(jnp);
p->earray = cmMemResizeZ(cmScModEntry_t,p->earray,entryCnt); g->earray = cmMemResizeZ(cmScModEntry_t,g->earray,entryCnt);
p->en = entryCnt; g->en = entryCnt;
unsigned prvScLocIdx = cmInvalidIdx;
const cmChar_t* prvModLabel = NULL;
const cmChar_t* prvVarLabel = NULL;
const cmChar_t* prvTypeLabel = NULL;
unsigned prvEntryFlags = 0;
for(i=0; i<entryCnt; ++i) for(i=0; i<entryCnt; ++i)
{ {
cmJsRC_t jsRC = kOkJsRC; cmJsRC_t jsRC = kOkJsRC;
const char* errLabelPtr = NULL; const char* errLabelPtr = NULL;
unsigned scLocIdx = cmInvalidIdx; unsigned scLocIdx = cmInvalidIdx;
const cmChar_t* modLabel = NULL;
const cmChar_t* varLabel = NULL; const cmChar_t* varLabel = NULL;
const cmChar_t* typeLabel = NULL; const cmChar_t* typeLabel = NULL;
cmJsonNode_t* onp = cmJsonArrayElement(jnp,i); cmJsonNode_t* onp = cmJsonArrayElement(jnp,i);
cmJsonNode_t* dnp = NULL; cmJsonNode_t* dnp = NULL;
const _cmScModTypeMap_t* map = NULL; const _cmScModTypeMap_t* map = NULL;
unsigned locTypeId = kIntTId;
unsigned entryFlags = cmInvalidId;
// if a 'loc' field was specified for this label
if( cmJsonFindPair( onp, "loc" ) != NULL )
{
const cmChar_t* locLabel = NULL;
// get the type of the 'loc' value field
if( cmJsonMemberType(onp, "loc", &locTypeId) == kOkJsRC )
{
// read the 'loc' value field
if( locTypeId == kStringTId )
rc = cmJsonStringMember( onp, "loc", &locLabel );
else
rc = cmJsonUIntMember( onp, "loc", &scLocIdx);
}
// check for parsing errors
if( rc != kOkJsRC )
{
rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Error:Reading 'loc' field on record at index %i in file:%s",i,cmStringNullGuard(fn) );
goto errLabel;
}
// if a label was given then convert it to a symbol id
if( locLabel != NULL )
{
scLocIdx = cmSymTblRegisterSymbol(stH,locLabel);
entryFlags = kLocLabelEntryFl;
}
}
if((jsRC = cmJsonMemberValues( onp, &errLabelPtr, if((jsRC = cmJsonMemberValues( onp, &errLabelPtr,
"mod", kStringTId | kOptArgJsFl, &modLabel,
"var", kStringTId | kOptArgJsFl, &varLabel, "var", kStringTId | kOptArgJsFl, &varLabel,
"type",kStringTId | kOptArgJsFl, &typeLabel, "type",kStringTId | kOptArgJsFl, &typeLabel,
"loc", kIntTId | kOptArgJsFl, &scLocIdx,
NULL )) != kOkJsRC ) NULL )) != kOkJsRC )
{ {
if( errLabelPtr == NULL ) if( errLabelPtr == NULL )
@ -3011,24 +2878,6 @@ cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, con
else else
prvScLocIdx = scLocIdx; prvScLocIdx = scLocIdx;
// if the flags field was not specified
if( entryFlags == cmInvalidId )
entryFlags = prvEntryFlags;
else
prvEntryFlags = entryFlags;
// if the mod label was not given use the previous one
if( modLabel == NULL )
modLabel = prvModLabel;
else
prvModLabel = modLabel;
if( modLabel == NULL )
{
rc = cmCtxRtCondition(&p->obj, cmInvalidArgRC, "No 'mod' label has been set in mod file '%s'.",cmStringNullGuard(fn));
goto errLabel;
}
// if the var label was not given use the previous one // if the var label was not given use the previous one
if( varLabel == NULL ) if( varLabel == NULL )
varLabel = prvVarLabel; varLabel = prvVarLabel;
@ -3060,21 +2909,13 @@ cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, con
goto errLabel; goto errLabel;
} }
unsigned modSymId = cmSymTblRegisterSymbol(stH,modLabel);
unsigned varSymId = cmSymTblRegisterSymbol(stH,varLabel); unsigned varSymId = cmSymTblRegisterSymbol(stH,varLabel);
// the mod entry label must match the modulators label
if( p->modSymId != modSymId )
{
--p->en;
continue;
}
// 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,i,scLocIdx,modSymId,varSymId,map->typeId,entryFlags,paramCnt); cmScModEntry_t* ep = _cmScModulatorInsertEntry(p,g,i,scLocIdx,varSymId,map->typeId,paramCnt);
typedef struct typedef struct
{ {
@ -3103,10 +2944,68 @@ cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, con
errLabel: errLabel:
if( rc != cmOkRC ) return rc;
cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Error parsing in Modulator 'data' record at index %i value index %i in file:%s",i,j,cmStringNullGuard(fn) ); }
cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, const cmChar_t* fn )
{
cmRC_t rc = cmOkRC;
cmJsonNode_t* jnp = NULL;
cmJsonH_t jsH = cmJsonNullHandle;
unsigned i = cmInvalidIdx;
cmScModEntryGroup_t* g0 = NULL;
cmScModEntryGroup_t* g1 = p->glist;
// read the JSON file
if( cmJsonInitializeFromFile(&jsH, fn, ctx ) != kOkJsRC )
return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "JSON file parse failed on the modulator file: %s.",cmStringNullGuard(fn) );
jnp = cmJsonRoot(jsH);
unsigned groupCnt = cmJsonChildCount(jnp);
// for each entry group
for(i=0; i<groupCnt; ++i)
{
// get the entry group record
if( g1 == NULL )
{
g1 = cmMemAllocZ(cmScModEntryGroup_t,1);
if( g0 == NULL )
p->glist = g1;
else
g0->link = g1;
}
// get the entry group pair node
cmJsonNode_t* gnp = cmJsonMemberAtIndex(jnp,i);
if( gnp == NULL || !cmJsonIsPair(gnp) )
{
rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Invalid entry group at index %i in score modulator file:%s",i,cmStringNullGuard(fn) );
goto errLabel;
}
// store the group label
g1->symId = cmSymTblRegisterSymbol(stH,cmJsonPairLabel(gnp));
// get and validate the group array value
if( (gnp = cmJsonPairValue(gnp))==NULL || cmJsonIsArray(gnp)==false )
return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Group entry '%s' does not contain an array of entries in file:%s",cmStringNullGuard(cmJsonPairLabel(gnp)),cmStringNullGuard(fn) );
// parse the entry group
if((rc = _cmScModParseEntryGroup( p, ctx, jsH, stH, gnp, g1, fn )) != cmOkRC )
{
rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Syntax error in entry group at index %i in score modulator file:%s",i,cmStringNullGuard(fn) );
goto errLabel;
}
g0 = g1;
g1 = g1->link;
}
errLabel:
// release the JSON tree // release the JSON tree
if( cmJsonIsValid(jsH) ) if( cmJsonIsValid(jsH) )
cmJsonFinalize(&jsH); cmJsonFinalize(&jsH);
@ -3115,7 +3014,7 @@ cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, con
} }
cmRC_t _cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx ) cmRC_t _cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx, unsigned entryGroupSymId )
{ {
cmRC_t rc = cmOkRC; cmRC_t rc = cmOkRC;
@ -3128,10 +3027,27 @@ cmRC_t _cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx )
if((rc = _cmScModulatorParse(p,ctx,p->stH,p->fn)) != cmOkRC ) if((rc = _cmScModulatorParse(p,ctx,p->stH,p->fn)) != cmOkRC )
goto errLabel; goto errLabel;
_cmScProcessEntryGroups(p); // fill p->glist // select the entry group to execute
if( entryGroupSymId != cmInvalidId )
{
cmScModEntryGroup_t* g = p->glist;
for(; g!=NULL; g=g->link)
if( g->symId == entryGroupSymId )
{
cmCtxPrint(p->obj.ctx,"%s selected.\n",cmSymTblLabel(p->stH,entryGroupSymId));
p->xlist = p->glist;
break;
}
}
_cmScProcessExecList(p); // fill p->xlist // if an active entry group has not been set - set it to the first entry group
if( p->xlist == NULL )
{
if( entryGroupSymId != cmInvalidId )
cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The modulator entry group '%s' was not found. The active entry group was set to the first group in the file.",cmSymTblLabel(p->stH,entryGroupSymId) );
p->xlist = p->glist;
}
// clear the active flag on all variables // clear the active flag on all variables
cmScModVar_t* vp = p->vlist; cmScModVar_t* vp = p->vlist;
@ -3160,11 +3076,10 @@ cmRC_t cmScModulatorInit( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, doub
p->samplesPerCycle = samplesPerCycle; p->samplesPerCycle = samplesPerCycle;
p->srate = srate; p->srate = srate;
if( rc != cmOkRC ) if( rc != cmOkRC )
cmScModulatorFinal(p); cmScModulatorFinal(p);
else else
_cmScModulatorReset(p,ctx,0); _cmScModulatorReset(p,ctx,0,cmInvalidId);
return rc; return rc;
} }
@ -3187,7 +3102,7 @@ cmRC_t cmScModulatorFinal( cmScModulator* p )
while( g != NULL ) while( g != NULL )
{ {
cmScModEntryGroup_t* g0 = g->link; cmScModEntryGroup_t* g0 = g->link;
cmMemFree(g->base); cmMemFree(g->earray);
cmMemFree(g); cmMemFree(g);
g = g0; g = g0;
} }
@ -3202,9 +3117,11 @@ unsigned cmScModulatorOutVarCount( cmScModulator* p )
cmScModVar_t* cmScModulatorOutVar( cmScModulator* p, unsigned idx ) cmScModVar_t* cmScModulatorOutVar( cmScModulator* p, unsigned idx )
{ {
unsigned i; unsigned i;
for(i=0; i<p->en; ++i) cmScModEntryGroup_t* g = p->glist;
if( p->earray[i].varPtr->outVarId == idx ) for(; g!=NULL; g=g->link)
return p->earray[i].varPtr; for(i=0; i<g->en; ++i)
if( g->earray[i].varPtr->outVarId == idx )
return g->earray[i].varPtr;
return NULL; return NULL;
} }
@ -3230,9 +3147,9 @@ cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, doubl
} }
cmRC_t cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx ) cmRC_t cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx, unsigned entryGroupSymId )
{ {
_cmScModulatorReset(p,ctx,scLocIdx); _cmScModulatorReset(p,ctx,scLocIdx,entryGroupSymId);
return cmScModulatorExec(p,scLocIdx); return cmScModulatorExec(p,scLocIdx);
} }
@ -3298,17 +3215,17 @@ cmRC_t _cmScModGetParam( cmScModulator* p, const cmScModParam_t* pp, double* va
return rc; return rc;
} }
cmRC_t _cmScModExecEntries( cmScModulator* p, cmScModEntry_t** xparray, unsigned* idxRef, unsigned cnt, unsigned scLocIdx ); cmRC_t _cmScModActivateEntries( cmScModulator* p, cmScModEntry_t* earray, unsigned* idxRef, unsigned cnt, unsigned scLocIdx );
cmRC_t _cmScModExecGroup( cmScModulator* p, cmScModEntry_t* ep ) cmRC_t _cmScModActivateGroup( cmScModulator* p, cmScModEntry_t* ep )
{ {
cmScModEntryGroup_t* g = p->glist; cmScModEntryGroup_t* g = p->glist;
for(; g!=NULL; g=g->link) for(; g!=NULL; g=g->link)
if( g->base != NULL && g->base[0]->scLocIdx == ep->beg.symId ) if( g->symId == ep->beg.symId )
{ {
unsigned idx = 0; unsigned idx = 0;
return _cmScModExecEntries( p, g->base, &idx, g->n, ep->beg.symId ); return _cmScModActivateEntries( p, g->earray, &idx, g->en, ep->beg.symId );
} }
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));
@ -3357,7 +3274,7 @@ cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep )
break; break;
case kExecModTId: case kExecModTId:
rc = _cmScModExecGroup(p,ep); rc = _cmScModActivateGroup(p,ep);
break; break;
default: default:
@ -3466,7 +3383,7 @@ bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp )
// Execute the entries in xparray[] begining with entry xparray[idx] and continuing until: // Execute the entries in xparray[] begining with entry xparray[idx] and continuing until:
// 1) cnt - idx entries have been executed // 1) cnt - idx entries have been executed
// 2) an entry is located whose scLocIdx != scLocIdx and also not -1 // 2) an entry is located whose scLocIdx != scLocIdx and also not -1
cmRC_t _cmScModExecEntries( cmScModulator* p, cmScModEntry_t** xparray, unsigned* idxRef, unsigned cnt, unsigned scLocIdx ) cmRC_t _cmScModActivateEntries( cmScModulator* p, cmScModEntry_t* earray, unsigned* idxRef, unsigned cnt, unsigned scLocIdx )
{ {
assert( idxRef != NULL ); assert( idxRef != NULL );
@ -3475,9 +3392,9 @@ cmRC_t _cmScModExecEntries( cmScModulator* p, cmScModEntry_t** xparray, unsigne
unsigned idx = *idxRef; unsigned idx = *idxRef;
// trigger entries that have expired since the last call to this function // trigger entries that have expired since the last call to this function
for(; idx<cnt && (xparray[idx]->scLocIdx==-1 || xparray[idx]->scLocIdx<=scLocIdx); ++idx) for(; idx<cnt && (earray[idx].scLocIdx==-1 || earray[idx].scLocIdx<=scLocIdx); ++idx)
{ {
cmScModEntry_t* ep = xparray[idx]; cmScModEntry_t* ep = earray + idx;
// if the variable assoc'd with this entry is not on the active list ... // if the variable assoc'd with this entry is not on the active list ...
if( cmIsFlag(ep->varPtr->flags,kActiveModFl) == false ) if( cmIsFlag(ep->varPtr->flags,kActiveModFl) == false )
@ -3516,44 +3433,8 @@ cmRC_t _cmScModExecEntries( cmScModulator* p, cmScModEntry_t** xparray, unsigne
cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx ) cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx )
{ {
cmRC_t rc = cmOkRC; cmRC_t rc = cmOkRC;
/*
cmRC_t trc;
// trigger entries that have expired since the last call to this function rc = _cmScModActivateEntries(p, p->xlist->earray, &p->nei, p->xlist->en, scLocIdx );
for(; p->nei<p->xn && (p->xlist[p->nei]->scLocIdx==-1 || p->xlist[p->nei]->scLocIdx<=scLocIdx); ++p->nei)
{
cmScModEntry_t* ep = p->xlist[p->nei];
// if the variable assoc'd with this entry is not on the active list ...
if( cmIsFlag(ep->varPtr->flags,kActiveModFl) == false )
{
// ... then append it to the end of the active list ...
ep->varPtr->flags |= kActiveModFl;
if( p->elist == NULL )
p->elist = ep->varPtr;
else
{
p->elist->alink = ep->varPtr;
p->elist = ep->varPtr;
}
p->elist->alink = NULL;
if( p->alist == NULL )
p->alist = ep->varPtr;
}
// do type specific activation
if((trc = _cmScModActivate(p,ep)) != cmOkRC )
rc = trc;
ep->varPtr->entry = ep;
}
*/
rc = _cmScModExecEntries(p, p->xlist, &p->nei, p->xn, scLocIdx );
// Update the active variables // Update the active variables
cmScModVar_t* pp = NULL; cmScModVar_t* pp = NULL;
@ -3624,17 +3505,18 @@ cmRC_t cmScModulatorDump( cmScModulator* p )
printf("nei:%i alist:%p outVarCnt:%i\n",p->nei,p->alist,p->outVarCnt); printf("nei:%i alist:%p outVarCnt:%i\n",p->nei,p->alist,p->outVarCnt);
printf("ENTRIES:\n"); printf("ENTRIES:\n");
unsigned i; cmScModEntryGroup_t* g = p->glist;
for(i=0; i<p->en; ++i) for(; g!=NULL; g=g->link)
{ {
cmScModEntry_t* ep = p->earray + i; printf("%s\n",cmSymTblLabel(p->stH,g->symId));
unsigned i;
for(i=0; i<g->en; ++i)
{
cmScModEntry_t* ep = g->earray + i;
const _cmScModTypeMap_t* tm = _cmScModTypeIdToMap( ep->typeId ); const _cmScModTypeMap_t* tm = _cmScModTypeIdToMap( ep->typeId );
printf("%3i ",i); printf("%3i ",i);
if( cmIsFlag(ep->flags,kLocLabelEntryFl) )
printf("%10s ",cmSymTblLabel(p->stH,ep->scLocIdx));
else
printf("%10i ",ep->scLocIdx); printf("%10i ",ep->scLocIdx);
printf("%5s %7s", tm==NULL ? "invld" : tm->label, cmSymTblLabel(p->stH,ep->varPtr->varSymId)); printf("%5s %7s", tm==NULL ? "invld" : tm->label, cmSymTblLabel(p->stH,ep->varPtr->varSymId));
@ -3645,6 +3527,7 @@ cmRC_t cmScModulatorDump( cmScModulator* p )
_cmScModDumpParam(p," rate",&ep->rate); _cmScModDumpParam(p," rate",&ep->rate);
printf("\n"); printf("\n");
} }
}
printf("VARIABLES\n"); printf("VARIABLES\n");
cmScModVar_t* vp = p->vlist; cmScModVar_t* vp = p->vlist;

View File

@ -477,13 +477,10 @@ extern "C" {
struct cmScModVar_str* alink; // p->alist link struct cmScModVar_str* alink; // p->alist link
} cmScModVar_t; } cmScModVar_t;
enum { kLocLabelEntryFl = 0x01 };
// Each entry gives a time tagged location and some parameters // Each entry gives a time tagged location and some parameters
// for an algorthm which is used to set/modulate a value. // for an algorthm which is used to set/modulate a value.
typedef struct cmScModEntry_str typedef struct cmScModEntry_str
{ {
unsigned flags; // { kLocLabelEntryFl }
unsigned scLocIdx; // entry start time unsigned scLocIdx; // entry start time
unsigned typeId; // variable type unsigned typeId; // variable type
cmScModParam_t beg; // parameter values cmScModParam_t beg; // parameter values
@ -497,8 +494,9 @@ extern "C" {
typedef struct cmScModEntryGroup_str typedef struct cmScModEntryGroup_str
{ {
cmScModEntry_t** base; unsigned symId; // this groups label
unsigned n; cmScModEntry_t* earray; // entries associated with this group
unsigned en; // earray[en]
struct cmScModEntryGroup_str* link; struct cmScModEntryGroup_str* link;
} cmScModEntryGroup_t; } cmScModEntryGroup_t;
@ -514,16 +512,13 @@ extern "C" {
void* cbArg; // first arg to cbFunc() void* cbArg; // first arg to cbFunc()
unsigned samplesPerCycle; // interval in samples between calls to cmScModulatorExec() unsigned samplesPerCycle; // interval in samples between calls to cmScModulatorExec()
double srate; // system sample rate double srate; // system sample rate
cmScModEntry_t* earray; // earray[en] - entry array sorted on ascending cmScModEntry_t.scLocIdx
unsigned en; // count
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
unsigned outVarCnt; // count of unique vars that are targets of entry recds unsigned outVarCnt; // count of unique vars that are targets of entry recds
bool postFl; // send a 'post' msg after each transmission bool postFl; // send a 'post' msg after each transmission
cmScModEntry_t** xlist; cmScModEntryGroup_t* xlist;
unsigned xn;
cmScModEntryGroup_t* glist; cmScModEntryGroup_t* glist;
} cmScModulator; } cmScModulator;
@ -541,7 +536,7 @@ extern "C" {
cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, double value, double min, double max ); cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, double value, double min, double max );
cmRC_t cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx ); 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 );
cmRC_t cmScModulatorDump( cmScModulator* p ); cmRC_t cmScModulatorDump( cmScModulator* p );

View File

@ -1236,6 +1236,7 @@ enum
kScLocIdxMdId, kScLocIdxMdId,
kResetIdxMdId, kResetIdxMdId,
kCmdMdId, kCmdMdId,
kSelMdId,
kPostMdId kPostMdId
}; };
@ -1279,6 +1280,7 @@ cmDspInst_t* _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
{ "index", kScLocIdxMdId, 0,0, kInDsvFl | kUIntDsvFl, "Score follower index input."}, { "index", kScLocIdxMdId, 0,0, kInDsvFl | kUIntDsvFl, "Score follower index input."},
{ "reset", kResetIdxMdId, 0,0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "Reset the modulator and go to the score index."}, { "reset", kResetIdxMdId, 0,0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "Reset the modulator and go to the score index."},
{ "cmd", kCmdMdId, 0,0, kInDsvFl | kSymDsvFl | kOptArgDsvFl, "on | off."}, { "cmd", kCmdMdId, 0,0, kInDsvFl | kSymDsvFl | kOptArgDsvFl, "on | off."},
{ "sel", kSelMdId, 0,0, kInDsvFl | kSymDsvFl | kOptArgDsvFl, "Set the next active entry group name."},
{ "post", kPostMdId, 0,0, kOutDsvFl | kSymDsvFl, "Sends 'post' symbol after a message transmission if the 'post' flag is set in scMod."}, { "post", kPostMdId, 0,0, kOutDsvFl | kSymDsvFl, "Sends 'post' symbol after a message transmission if the 'post' flag is set in scMod."},
{ NULL, 0, 0, 0, 0 } { NULL, 0, 0, 0, 0 }
}; };
@ -1346,6 +1348,7 @@ cmDspInst_t* _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
cmDspSetDefaultUInt(ctx,&p->inst,kScLocIdxMdId,0,0); cmDspSetDefaultUInt(ctx,&p->inst,kScLocIdxMdId,0,0);
cmDspSetDefaultSymbol(ctx,&p->inst,kCmdMdId,p->offSymId); cmDspSetDefaultSymbol(ctx,&p->inst,kCmdMdId,p->offSymId);
cmDspSetDefaultSymbol(ctx,&p->inst,kSelMdId,cmInvalidId);
return &p->inst; return &p->inst;
} }
@ -1389,7 +1392,7 @@ cmDspRC_t _cmDspScModRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
{ {
unsigned symId = cmDspSymbol(inst,kCmdMdId); unsigned symId = cmDspSymbol(inst,kCmdMdId);
if( symId == p->onSymId ) if( symId == p->onSymId )
cmScModulatorReset(p->mp, ctx->cmCtx, cmDspUInt(inst,kScLocIdxMdId)); cmScModulatorReset(p->mp, ctx->cmCtx, cmDspUInt(inst,kScLocIdxMdId), cmDspSymbol(inst,kSelMdId));
if( symId == p->dumpSymId ) if( symId == p->dumpSymId )
cmScModulatorDump(p->mp); cmScModulatorDump(p->mp);