diff --git a/Makefile.am b/Makefile.am index 52b9f5a..b5d5469 100644 --- a/Makefile.am +++ b/Makefile.am @@ -39,8 +39,8 @@ cmHDR += src/libcm/cmGr.h src/libcm/cmGrDevCtx.h src/libcm/cmGrPage.h src/libcm/ cmHDR += src/libcm/dsp/cmDspSys.h src/libcm/dsp/cmDspClass.h src/libcm/dsp/cmDspValue.h src/libcm/dsp/cmDspUi.h src/libcm/dsp/cmDspPreset.h src/libcm/dsp/cmDspNet.h cmSRC += src/libcm/dsp/cmDspSys.c src/libcm/dsp/cmDspClass.c src/libcm/dsp/cmDspValue.c src/libcm/dsp/cmDspUi.c src/libcm/dsp/cmDspPreset.c src/libcm/dsp/cmDspNet.c -cmHDR += src/libcm/dsp/cmDspBuiltIn.h src/libcm/dsp/cmDspFx.h -cmSRC += src/libcm/dsp/cmDspBuiltIn.c src/libcm/dsp/cmDspFx.c +cmHDR += src/libcm/dsp/cmDspStore.h src/libcm/dsp/cmDspBuiltIn.h src/libcm/dsp/cmDspFx.h +cmSRC += src/libcm/dsp/cmDspStore.c src/libcm/dsp/cmDspBuiltIn.c src/libcm/dsp/cmDspFx.c cmHDR += src/libcm/dsp/cmDspPgm.h src/libcm/dsp/cmDspPgmPP.h src/libcm/dsp/cmDspPgmPPMain.h cmSRC += src/libcm/dsp/cmDspPgm.c src/libcm/dsp/cmDspPgmPP.c src/libcm/dsp/cmDspPgmPPMain.c diff --git a/app/cmScore.c b/app/cmScore.c index a945be6..8e10bf2 100644 --- a/app/cmScore.c +++ b/app/cmScore.c @@ -9,6 +9,7 @@ #include "cmMidi.h" #include "cmLex.h" #include "cmCsv.h" +#include "cmSymTbl.h" #include "cmMidiFile.h" #include "cmAudioFile.h" #include "cmTimeLine.h" @@ -78,6 +79,7 @@ typedef struct { cmErr_t err; cmCsvH_t cH; + cmSymTblH_t stH; cmScCb_t cbFunc; void* cbArg; cmChar_t* fn; @@ -355,7 +357,9 @@ cmScRC_t _cmScFinalize( cmSc_t* p ) for(i=0; isetCnt; ++i) { cmMemFree(p->sets[i].eleArray); - //cmMemFree(p->sets[i].sectArray); + cmMemFree(p->sets[i].sectArray); + cmMemFree(p->sets[i].symArray); + cmMemFree(p->sets[i].costSymArray); } cmMemFree(p->sets); } @@ -708,6 +712,7 @@ cmScoreSection_t* _cmScLabelToSection( cmSc_t* p, const cmChar_t* label ) } + // Calculate the total number of all types of sets and // then convert each of the cmScSet_t linked list's to // a single linear cmScoreSet_t list (p->sets[]). @@ -778,8 +783,10 @@ cmScRC_t _cmScProcSets( cmSc_t* p ) // allocate the section array p->sets[i].varId = _cmScVarFlagToId(sp->typeFl); - //p->sets[i].sectCnt = en; - //p->sets[i].sectArray = cmMemAllocZ(cmScoreSection_t*,en); + p->sets[i].sectCnt = en; + p->sets[i].sectArray = cmMemAllocZ(cmScoreSection_t*,en); + p->sets[i].symArray = cmMemAllocZ(unsigned,en); + p->sets[i].costSymArray = cmMemAllocZ(unsigned,en); // fill in the section array with sections which this set will be applied to ep = sp->sects; @@ -791,7 +798,18 @@ cmScRC_t _cmScProcSets( cmSc_t* p ) rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The section labelled '%s' could not be found for the set which includes row number %i.",ep->label,rowNumb); else { - //= p->sets[i].sectArray[j]; + if( cmSymTblIsValid(p->stH) ) + { + p->sets[i].symArray[j] = cmSymTblRegisterFmt(p->stH,"%c-%s", _cmScVarIdToChar(p->sets[i].varId),ep->label); + p->sets[i].costSymArray[j] = cmSymTblRegisterFmt(p->stH,"c%c-%s",_cmScVarIdToChar(p->sets[i].varId),ep->label); + } + else + { + p->sets[i].symArray[j] = cmInvalidId; + p->sets[i].symArray[j] = cmInvalidId; + } + + p->sets[i].sectArray[j] = sp; sp->setArray = cmMemResizeP(cmScoreSet_t*,sp->setArray,++sp->setCnt); sp->setArray[sp->setCnt-1] = p->sets + i; @@ -1107,7 +1125,7 @@ cmScRC_t _cmScInitLocArray( cmSc_t* p ) } -cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, double srate, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg ) +cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, double srate, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg, cmSymTblH_t stH ) { cmScRC_t rc = kOkScRC; if((rc = cmScoreFinalize(hp)) != kOkScRC ) @@ -1117,6 +1135,8 @@ cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, doubl cmErrSetup(&p->err,&ctx->rpt,"Score"); + p->stH = stH; + if((rc = _cmScParseFile(p,ctx,fn)) != kOkScRC ) goto errLabel; @@ -1881,7 +1901,7 @@ void cmScorePrint( cmScH_t h, cmRpt_t* rpt ) void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn ) { cmScH_t h = cmScNullHandle; - if( cmScoreInitialize(ctx,&h,fn,0,NULL,0,NULL,NULL) != kOkScRC ) + if( cmScoreInitialize(ctx,&h,fn,0,NULL,0,NULL,NULL, cmSymTblNullHandle ) != kOkScRC ) return; cmScorePrint(h,&ctx->rpt); diff --git a/app/cmScore.h b/app/cmScore.h index a2bba53..c9df525 100644 --- a/app/cmScore.h +++ b/app/cmScore.h @@ -94,6 +94,10 @@ extern "C" { unsigned varId; // See kXXXVarScId flags above cmScoreEvt_t** eleArray; // Events that make up this set in time order unsigned eleCnt; // + cmScoreSection_t** sectArray; // Sections this set will be applied to + unsigned sectCnt; // + unsigned* symArray; // symArray[sectCnt] - symbol name of all variables represented by this set (e.g '1a-e', '1b-e', '2-t', etc) + unsigned* costSymArray; // costSymArray[sectCnt] - same as symbols in symArray[] with 'c' prepended to front bool doneFl; double value; struct cmScoreSet_str* llink; // cmScoreLoc_t setList link @@ -132,7 +136,8 @@ extern "C" { // If provided the dynRefArray[] is copied into an internal array. // The physical array passed here therefore does not need to remain valid. // Set 'srate' to zero if the score will not be used to perform measurement calculations. - cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, double srate, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg ); + // The symbol table is only necessary if valid symbols are to be assigned to the cmScoreSet_t.symArray[]. + cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, double srate, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg, cmSymTblH_t stH ); cmScRC_t cmScoreFinalize( cmScH_t* hp ); // Filename of last successfuly loaded score file. diff --git a/cmAudDsp.c b/cmAudDsp.c index 43801be..ddab770 100644 --- a/cmAudDsp.c +++ b/cmAudDsp.c @@ -14,6 +14,7 @@ #include "cmAudioPort.h" #include "cmAudioAggDev.h" #include "cmAudioNrtDev.h" +#include "cmAudioPortFile.h" #include "cmApBuf.h" #include "cmMidi.h" #include "cmMidiPort.h" @@ -62,6 +63,15 @@ typedef struct unsigned cbPeriodMs; } cmAdNrtDev_t; +typedef struct +{ + const cmChar_t* label; + const cmChar_t* inAudioFn; + const cmChar_t* outAudioFn; + unsigned oBits; + unsigned oChCnt; +} cmAdAfpDev_t; + typedef struct { cmErr_t err; @@ -84,6 +94,9 @@ typedef struct cmAdNrtDev_t* nrtDevArray; unsigned nrtDevCnt; + cmAdAfpDev_t* afpDevArray; + unsigned afpDevCnt; + cmAdAsCfg_t* asCfgArray; unsigned asCfgCnt; @@ -151,6 +164,7 @@ cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p ) cmJsonNode_t* asCfgArrNodePtr = NULL; cmJsonNode_t* aggDevArrNodePtr = NULL; cmJsonNode_t* nrtDevArrNodePtr = NULL; + cmJsonNode_t* afpDevArrNodePtr = NULL; cmJsonNode_t* audDspNodePtr = NULL; const cmChar_t* errLabelPtr = NULL; unsigned i; @@ -171,6 +185,7 @@ cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p ) "audioSysCfgArray", kArrayTId, &asCfgArrNodePtr, "aggDevArray", kArrayTId | kOptArgJsFl, &aggDevArrNodePtr, "nrtDevArray", kArrayTId | kOptArgJsFl, &nrtDevArrNodePtr, + "afpDevArray", kArrayTId | kOptArgJsFl, &afpDevArrNodePtr, NULL )) != kOkJsRC ) { rc = _cmAdParseMemberErr(p, jsRC, errLabelPtr, "aud_dsp" ); @@ -242,6 +257,34 @@ cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p ) } } + + } + + // parse the audio file device specifications into p->afpDevArray[]. + if( afpDevArrNodePtr != NULL && (p->afpDevCnt = cmJsonChildCount(afpDevArrNodePtr)) > 0) + { + // alloc the non-real-time spec. array + p->afpDevArray = cmMemResizeZ( cmAdAfpDev_t, p->afpDevArray, p->afpDevCnt ); + + // for each afp. device spec. recd + for(i=0; iafpDevCnt; ++i) + { + const cmJsonNode_t* np = cmJsonArrayElementC(afpDevArrNodePtr,i); + + // read afpDevArray record values + if(( jsRC = cmJsonMemberValues( np, &errLabelPtr, + "label", kStringTId, &p->afpDevArray[i].label, + "iAudioFn", kStringTId | kOptArgJsFl, &p->afpDevArray[i].inAudioFn, + "oAudioFn", kStringTId | kOptArgJsFl, &p->afpDevArray[i].outAudioFn, + "oBits", kIntTId | kOptArgJsFl, &p->afpDevArray[i].oBits, + "oChCnt", kIntTId | kOptArgJsFl, &p->afpDevArray[i].oChCnt, + NULL )) != kOkJsRC ) + { + rc = _cmAdParseMemberErr(p, jsRC, errLabelPtr, cmStringNullGuard(p->afpDevArray[i].label) ); + goto errLabel; + } + + } } @@ -368,6 +411,26 @@ cmAdRC_t _cmAdCreateNrtDevices( cmAd_t* p ) return rc; } +cmAdRC_t _cmAdCreateAfpDevices( cmAd_t* p ) +{ + cmAdRC_t rc = kOkAdRC; + + if( cmApFileAllocate(p->err.rpt) != kOkApRC ) + return cmErrMsg(&p->err,kAfpDevSysFailAdRC,"The audio file device system allocation failed."); + + unsigned i; + // create the audio file devices + for(i=0; iafpDevCnt; ++i) + { + //const cmAudioSysFilePort_t* afp = cfg->afpArray + i; + cmAdAfpDev_t* afp = p->afpDevArray + i; + if( cmApFileDeviceCreate( afp->label, afp->inAudioFn, afp->outAudioFn, afp->oBits, afp->oChCnt ) != kOkApRC ) + rc = cmErrMsg(&p->err,kAfpDevSysFailAdRC,"The audio file device '%s' creation failed.",cmStringNullGuard(afp->label)); + } + + return rc; +} + cmAdRC_t _cmAdSendAudioSysCfgLabels( cmAd_t* p) { cmAdRC_t rc = kOkAdRC; @@ -480,9 +543,15 @@ cmAdRC_t _cmAudDspFree( cmAd_t* p ) goto errLabel; } + if( cmApFileFree() != kOkApRC ) + { + rc = cmErrMsg(&p->err,kAfpDevSysFailAdRC,"The audio file device system release failed."); + goto errLabel; + } + if( cmApNrtFree() != kOkAgRC ) { - rc = cmErrMsg(&p->err,kNrtDevSysFailAdRC,"The non-real-time device system realease failed."); + rc = cmErrMsg(&p->err,kNrtDevSysFailAdRC,"The non-real-time device system release failed."); goto errLabel; } @@ -562,6 +631,10 @@ cmAdRC_t cmAudDspAlloc( cmCtx_t* ctx, cmAdH_t* hp, cmMsgSendFuncPtr_t cbFunc, vo if( _cmAdCreateNrtDevices(p) != kOkAdRC ) goto errLabel; + // create the audio file devices + if( _cmAdCreateAfpDevices(p) != kOkAdRC ) + goto errLabel; + // initialize the audio device system if( cmApInitialize(&ctx->rpt) != kOkApRC ) { diff --git a/cmAudDsp.h b/cmAudDsp.h index 04edff4..6b83faa 100644 --- a/cmAudDsp.h +++ b/cmAudDsp.h @@ -25,6 +25,7 @@ extern "C" { kAggDevSysFailAdRC, kAggDevCreateFailAdRC, kNrtDevSysFailAdRC, + kAfpDevSysFailAdRC, kNetSysFailAdRC }; diff --git a/cmAudioFileDev.c b/cmAudioFileDev.c index 3929b37..8be3080 100644 --- a/cmAudioFileDev.c +++ b/cmAudioFileDev.c @@ -220,8 +220,6 @@ cmAfdRC_t cmAudioFileDevInitialize( goto errLabel; } - - p->iPkt.devIdx = devIdx; p->iPkt.begChIdx = 0; p->iPkt.chCnt = afInfo.chCnt; // setting iPkt.chCnt to a non-zero value marks the input file as active @@ -294,6 +292,7 @@ bool cmAudioFileDevIsValid( cmAfdH_t h ) cmAfdRC_t cmAudioFileDevSetup( cmAfdH_t h, + unsigned baseDevIdx, double srate, unsigned framesPerCycle, cmApCallbackPtr_t callbackPtr, @@ -344,13 +343,14 @@ cmAfdRC_t cmAudioFileDevSetup( cmApSample_t* bp = (cmApSample_t*)p->oPkt.audioBytesPtr; - p->oPkt.devIdx = p->devIdx; + p->oPkt.devIdx = p->devIdx + baseDevIdx; p->oPkt.begChIdx = 0; p->oPkt.chCnt = p->oChCnt; p->oPkt.audioFramesCnt = framesPerCycle; p->oPkt.bitsPerSample = p->oBits; p->oPkt.flags = kFloatApFl; p->oPkt.audioBytesPtr = bp = cmMemResizeZ( cmApSample_t, bp, framesPerCycle*p->oChCnt ); + p->oPkt.userCbPtr = cbDataPtr; p->oChArray = cmMemResizeZ( cmApSample_t*, p->oChArray, p->oChCnt ); for(i=0; ioChCnt; ++i) @@ -362,8 +362,10 @@ cmAfdRC_t cmAudioFileDevSetup( { cmApSample_t* bp = (cmApSample_t*)p->iPkt.audioBytesPtr; + p->iPkt.devIdx = p->devIdx + baseDevIdx; p->iPkt.audioFramesCnt = framesPerCycle; p->iPkt.audioBytesPtr = bp = cmMemResizeZ( cmApSample_t, bp, framesPerCycle*p->iPkt.chCnt ); ; + p->iPkt.userCbPtr = cbDataPtr; for(i=0; iiPkt.chCnt; ++i) p->iChArray[i] = bp + (i*framesPerCycle); } @@ -534,7 +536,7 @@ void cmAudioFileDevTest( cmRpt_t* rpt ) if( cmAudioFileDevInitialize(&afdH,"file",devIdx,iFn,oFn,oBits,oChCnt,rpt) != kOkAfdRC ) goto errLabel; - if( cmAudioFileDevSetup(afdH,srate,framesPerCycle,_cmAfdCallback,cbDataPtr) != kOkAfdRC ) + if( cmAudioFileDevSetup(afdH,0,srate,framesPerCycle,_cmAfdCallback,cbDataPtr) != kOkAfdRC ) goto errLabel; char c; diff --git a/cmAudioFileDev.h b/cmAudioFileDev.h index 1acce13..bb11852 100644 --- a/cmAudioFileDev.h +++ b/cmAudioFileDev.h @@ -37,6 +37,7 @@ bool cmAudioFileDevIsValid( cmAfdH_t h ); /// Setup the device. This function must be called prior to cmAudioFileDevStart(). cmAfdRC_t cmAudioFileDevSetup( cmAfdH_t h, + unsigned baseApDevIdx, double srate, unsigned framesPerCycle, cmApCallbackPtr_t callbackPtr, diff --git a/cmAudioNrtDev.c b/cmAudioNrtDev.c index 1b8817b..08ac125 100644 --- a/cmAudioNrtDev.c +++ b/cmAudioNrtDev.c @@ -25,7 +25,7 @@ typedef struct typedef struct cmApNrtDev_str { unsigned flags; - unsigned devIdx; // nrt device index + unsigned devIdx; // nrt device index unsigned baseApDevIdx; // global audio device index for first nrt device cmChar_t* label; unsigned iChCnt; diff --git a/cmAudioPortFile.c b/cmAudioPortFile.c index 71b8a86..3b57e0e 100644 --- a/cmAudioPortFile.c +++ b/cmAudioPortFile.c @@ -11,6 +11,8 @@ typedef struct { cmAfdH_t devH; + unsigned devIdx; // afp dev idx + unsigned baseApDevIdx; // global audio device index for first afp device } cmApDev_t; typedef struct @@ -18,19 +20,53 @@ typedef struct cmErr_t err; cmApDev_t* devArray; unsigned devCnt; + unsigned baseApDevIdx; } cmApf_t; cmApf_t* _cmApf = NULL; -cmApRC_t cmApFileInitialize( cmRpt_t* rpt, unsigned baseApDevIdx ) +cmApRC_t cmApFileAllocate( cmRpt_t* rpt ) { - cmApRC_t rc; - if((rc = cmApFileFinalize()) != kOkApRC ) - return rc; + cmApRC_t rc = kOkApRC; + + if( _cmApf != NULL ) + cmApFileFree(); _cmApf = cmMemAllocZ(cmApf_t,1); cmErrSetup(&_cmApf->err,rpt,"Audio Port File"); + _cmApf->devArray = NULL; + _cmApf->devCnt = 0; + _cmApf->baseApDevIdx = 0; + + return rc; +} + +cmApRC_t cmApFileFree() +{ + cmApRC_t rc = kOkApRC; + + if( _cmApf == NULL ) + return rc; + + if((rc = cmApFileFinalize()) != kOkApRC ) + return rc; + + cmMemFree(_cmApf); + _cmApf = NULL; + return rc; +} + + +cmApRC_t cmApFileInitialize( cmRpt_t* rpt, unsigned baseApDevIdx ) +{ + cmApRC_t rc = kOkApRC; + + unsigned i = 0; + for(; i<_cmApf->devCnt; ++i) + _cmApf->devArray[i].baseApDevIdx = baseApDevIdx; + + _cmApf->baseApDevIdx = baseApDevIdx; return rc; } @@ -85,7 +121,12 @@ unsigned cmApFileDeviceCreate( { cmErrMsg(&_cmApf->err,kAudioPortFileFailApRC,"The audio file device initialization failed."); i = cmInvalidIdx; + goto errLabel; } + + _cmApf->devArray[i].devIdx = i; + + errLabel: return i; } @@ -134,7 +175,7 @@ cmApRC_t cmApFileDeviceSetup( { assert( devIdx < cmApFileDeviceCount()); - if( cmAudioFileDevSetup( _cmApf->devArray[devIdx].devH,srate,framesPerCycle,callbackPtr,userCbPtr) != kOkAfdRC ) + if( cmAudioFileDevSetup( _cmApf->devArray[devIdx].devH,_cmApf->baseApDevIdx,srate,framesPerCycle,callbackPtr,userCbPtr) != kOkAfdRC ) return cmErrMsg(&_cmApf->err,kAudioPortFileFailApRC,"The audio file device setup failed."); return kOkApRC; diff --git a/cmAudioPortFile.h b/cmAudioPortFile.h index b2d1a9b..9383983 100644 --- a/cmAudioPortFile.h +++ b/cmAudioPortFile.h @@ -5,6 +5,8 @@ extern "C" { #endif + cmApRC_t cmApFileAllocate( cmRpt_t* rpt ); + cmApRC_t cmApFileFree(); cmApRC_t cmApFileInitialize( cmRpt_t* rpt, unsigned baseApDevIdx ); cmApRC_t cmApFileFinalize(); diff --git a/cmAudioSys.c b/cmAudioSys.c index 03adbbc..bb7e64a 100644 --- a/cmAudioSys.c +++ b/cmAudioSys.c @@ -729,11 +729,13 @@ cmAsRC_t cmAudioSysInitialize( cmAudioSysH_t h, const cmAudioSysCfg_t* cfg ) return rc; // create the audio file devices + /* for(i=0; iafpCnt; ++i) { const cmAudioSysFilePort_t* afp = cfg->afpArray + i; cmApFileDeviceCreate( afp->devLabel, afp->inAudioFn, afp->outAudioFn, afp->oBits, afp->oChCnt ); } + */ p->ssArray = cmMemAllocZ( _cmAsCfg_t, cfg->ssCnt ); p->ssCnt = cfg->ssCnt; @@ -1281,8 +1283,8 @@ void cmAudioSysTest( cmRpt_t* rpt, int argc, const char* argv[] ) cfg.ssArray = &ss; cfg.ssCnt = 1; - cfg.afpArray= NULL; - cfg.afpCnt = 0; + //cfg.afpArray= NULL; + //cfg.afpCnt = 0; cfg.meterMs = 50; if(_cmAsGetBoolOpt(argc,argv,"-h",false)) diff --git a/cmAudioSys.h b/cmAudioSys.h index cd62915..0e0bbbb 100644 --- a/cmAudioSys.h +++ b/cmAudioSys.h @@ -172,6 +172,7 @@ extern "C" { } cmAudioSysCtx_t; + /* typedef struct { const cmChar_t* devLabel; @@ -180,15 +181,15 @@ extern "C" { unsigned oBits; unsigned oChCnt; } cmAudioSysFilePort_t; - + */ /// Audio system configuration record used by cmAudioSysAllocate(). typedef struct cmAudioSysCfg_str { cmAudioSysSubSys_t* ssArray; ///< sub-system cfg record array unsigned ssCnt; ///< count of sub-systems - cmAudioSysFilePort_t* afpArray; ///< audio port file cfg recd array - unsigned afpCnt; ///< audio port file cnt + //cmAudioSysFilePort_t* afpArray; ///< audio port file cfg recd array + //unsigned afpCnt; ///< audio port file cnt unsigned meterMs; ///< Meter sample period in milliseconds void* clientCbData; ///< User arg. for clientCbFunc(). cmTsQueueCb_t clientCbFunc; ///< Called by cmAudioSysReceiveMsg() to deliver internally generated msg's to the host. diff --git a/cmGlobal.h b/cmGlobal.h index ac04953..fa589c6 100644 --- a/cmGlobal.h +++ b/cmGlobal.h @@ -99,6 +99,7 @@ extern "C" { #define cmStringNullGuard(p) ((p)==NULL?"":(p)) //< If 'p'==NULL return the static string "" otherwise return 'p'. +#define cmStringLen(s) ((s)==NULL? 0 : strlen(s)) // Default return code indicating successful function completion. #define cmOkRC (0) diff --git a/cmLinkedHeap.h b/cmLinkedHeap.h index f49dac4..7271151 100644 --- a/cmLinkedHeap.h +++ b/cmLinkedHeap.h @@ -52,10 +52,10 @@ extern "C" { #define cmLhResizeN( h,t,p,n) ((t*)cmLHeapAllocate(h,p, n,sizeof(t), kAlignMmFl, NULL,NULL,0)) #define cmLhResizeNZ(h,t,p,n) ((t*)cmLHeapAllocate(h,p, n,sizeof(t), kAlignMmFl | kZeroMmFl, NULL,NULL,0)) -#define cmLhAllocStr( h, str ) cmLHeapAllocStr( h, NULL, str, strlen(str), kAlignMmFl, NULL,NULL,0 ) -#define cmLhAllocStrN( h, str, n ) cmLHeapAllocStr( h, NULL, str, n, kAlignMmFl, NULL,NULL,0 ) -#define cmLhResizeStr( h, p, str ) cmLHeapAllocStr( h, p, str, strlen(str), kAlignMmFl, NULL,NULL,0 ) -#define cmLhResizeStrN( h, p, str, n ) cmLHeapAllocStr( h, p, str, n, kAlignMmFl, NULL,NULL,0 ) +#define cmLhAllocStr( h, str ) cmLHeapAllocStr( h, NULL, str, cmStringLen(str), kAlignMmFl, NULL,NULL,0 ) +#define cmLhAllocStrN( h, str, n ) cmLHeapAllocStr( h, NULL, str, n, kAlignMmFl, NULL,NULL,0 ) +#define cmLhResizeStr( h, p, str ) cmLHeapAllocStr( h, p, str, cmStringLen(str), kAlignMmFl, NULL,NULL,0 ) +#define cmLhResizeStrN( h, p, str, n ) cmLHeapAllocStr( h, p, str, n, kAlignMmFl, NULL,NULL,0 ) #define cmLhFree( h, p ) cmLHeapFree( h, p ) #define cmLhFreePtr(h, p ) cmLHeapFreePtr( h, p ) @@ -70,10 +70,10 @@ extern "C" { #define cmLhResizeN( h,t,p,n) ((t*)cmLHeapAllocate(h,p, n,sizeof(t), kAlignMmFl, __FILE__,__FUNCTION__,__LINE__)) #define cmLhResizeNZ(h,t,p,n) ((t*)cmLHeapAllocate(h,p, n,sizeof(t), kAlignMmFl | kZeroMmFl, __FILE__,__FUNCTION__,__LINE__)) -#define cmLhAllocStr( h, str ) cmLHeapAllocStr( h, NULL, str, strlen(str), kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ ) -#define cmLhAllocStrN( h, str, n ) cmLHeapAllocStr( h, NULL, str, n, kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ ) -#define cmLhResizeStr( h, p, str ) cmLHeapAllocStr( h, p, str, strlen(str), kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ ) -#define cmLhResizeStrN( h, p, str, n ) cmLHeapAllocStr( h, p, str, n, kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ ) +#define cmLhAllocStr( h, str ) cmLHeapAllocStr( h, NULL, str, cmStringLen(str), kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ ) +#define cmLhAllocStrN( h, str, n ) cmLHeapAllocStr( h, NULL, str, n, kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ ) +#define cmLhResizeStr( h, p, str ) cmLHeapAllocStr( h, p, str, cmStringLen(str), kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ ) +#define cmLhResizeStrN( h, p, str, n ) cmLHeapAllocStr( h, p, str, n, kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ ) #define cmLhFree( h, p ) cmLHeapFreeDebug( h, p, __FILE__,__FUNCTION__,__LINE__ ) #define cmLhFreePtr(h, p ) cmLHeapFreePtrDebug( h, p, __FILE__,__FUNCTION__,__LINE__ ) diff --git a/cmMallocDebug.h b/cmMallocDebug.h index 54c91bc..eb55733 100644 --- a/cmMallocDebug.h +++ b/cmMallocDebug.h @@ -93,6 +93,8 @@ extern "C" { // An example and test function for the cmMallocDebug manager. void cmMdTest( cmRpt_t* rpt ); + + #if cmDEBUG_FL == 0 // Memory Allocation and Release Macros: @@ -101,20 +103,20 @@ extern "C" { // #define cmMemAllocate( type, p, eleCnt, fl ) ((type*)cmMdAllocate( p, eleCnt, sizeof(type), fl )) -#define cmMemMalloc( byteCnt ) cmMdAllocate( NULL, byteCnt, 1, kAlignMmFl) -#define cmMemMallocZ( byteCnt ) cmMdAllocate( NULL, byteCnt, 1, kAlignMmFl | kZeroMmFl) -#define cmMemAlloc( type, eleCnt ) ((type*)cmMdAllocate( NULL, eleCnt, sizeof(type), kAlignMmFl)) -#define cmMemAllocZ( type, eleCnt ) ((type*)cmMdAllocate( NULL, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl)) -#define cmMemAllocStr( str ) cmMdAllocStr( NULL, str, strlen(str), kAlignMmFl ) -#define cmMemAllocStrN( str, charCnt ) cmMdAllocStr( NULL, str, charCnt, kAlignMmFl ) -#define cmMemResizeStr( p, str ) cmMdAllocStr( p, str, strlen(str), kAlignMmFl ) -#define cmMemResizeStrN(p, str, charCnt ) cmMdAllocStr( p, str, charCnt, kAlignMmFl ) -#define cmMemResizeN( n, p, eleCnt ) (cmMdAllocate( p, eleCnt, n, kAlignMmFl)) -#define cmMemResizeNZ( n, p, eleCnt ) (cmMdAllocate( p, eleCnt, n, kAlignMmFl | kZeroMmFl )) -#define cmMemResize( type, p, eleCnt ) ((type*)cmMdAllocate( p, eleCnt, sizeof(type), kAlignMmFl)) -#define cmMemResizeZ( type, p, eleCnt ) ((type*)cmMdAllocate( p, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl)) -#define cmMemResizeP( type, p, eleCnt ) ((type*)cmMdAllocate( p, eleCnt, sizeof(type), kAlignMmFl | kPreserveMmFl)) -#define cmMemResizePZ( type, p, eleCnt ) ((type*)cmMdAllocate( p, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl | kPreserveMmFl)) +#define cmMemMalloc( byteCnt ) cmMdAllocate( NULL, byteCnt, 1, kAlignMmFl) +#define cmMemMallocZ( byteCnt ) cmMdAllocate( NULL, byteCnt, 1, kAlignMmFl | kZeroMmFl) +#define cmMemAlloc( type, eleCnt ) ((type*)cmMdAllocate( NULL, eleCnt, sizeof(type), kAlignMmFl)) +#define cmMemAllocZ( type, eleCnt ) ((type*)cmMdAllocate( NULL, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl)) +#define cmMemAllocStr( str ) cmMdAllocStr( NULL, str, cmStringLen(str), kAlignMmFl ) +#define cmMemAllocStrN( str, charCnt ) cmMdAllocStr( NULL, str, charCnt, kAlignMmFl ) +#define cmMemResizeStr( p, str ) cmMdAllocStr( p, str, cmStringLen(str), kAlignMmFl ) +#define cmMemResizeStrN(p, str, charCnt ) cmMdAllocStr( p, str, charCnt, kAlignMmFl ) +#define cmMemResizeN( n, p, eleCnt ) (cmMdAllocate( p, eleCnt, n, kAlignMmFl)) +#define cmMemResizeNZ( n, p, eleCnt ) (cmMdAllocate( p, eleCnt, n, kAlignMmFl | kZeroMmFl )) +#define cmMemResize( type, p, eleCnt ) ((type*)cmMdAllocate( p, eleCnt, sizeof(type), kAlignMmFl)) +#define cmMemResizeZ( type, p, eleCnt ) ((type*)cmMdAllocate( p, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl)) +#define cmMemResizeP( type, p, eleCnt ) ((type*)cmMdAllocate( p, eleCnt, sizeof(type), kAlignMmFl | kPreserveMmFl)) +#define cmMemResizePZ( type, p, eleCnt ) ((type*)cmMdAllocate( p, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl | kPreserveMmFl)) #define cmMemFree( ptr ) cmMdFree( ptr ) #define cmMemPtrFree( ptrPtr ) cmMdFreePtr(ptrPtr); @@ -130,20 +132,20 @@ extern "C" { // // #define cmMemAllocate( type, p, eleCnt, pre, fl ) ((type*)cmMdAllocateDebug( p, eleCnt, sizeof(type), fl, __FUNCTION__, __FILE__, __LINE__ )) -#define cmMemMalloc( byteCnt ) cmMdAllocateDebug( NULL, 1, byteCnt, kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ ) -#define cmMemMallocZ( byteCnt ) cmMdAllocateDebug( NULL, 1, byteCnt, kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ ) -#define cmMemAlloc( type, eleCnt ) ((type*)cmMdAllocateDebug( NULL, eleCnt, sizeof(type), kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ )) -#define cmMemAllocZ( type, eleCnt ) ((type*)cmMdAllocateDebug( NULL, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ )) -#define cmMemAllocStr( str ) (cmMdAllocStrDebug( NULL, str, strlen(str), kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ )) -#define cmMemAllocStrN(str, charCnt ) (cmMdAllocStrDebug( NULL, str, charCnt, kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ )) -#define cmMemResizeStr(p, str ) (cmMdAllocStrDebug( p, str, strlen(str), kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ )) -#define cmMemResizeStrN(p, str, charCnt ) (cmMdAllocStrDebug( p, str, charCnt, kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ )) -#define cmMemResizeN( n, p, eleCnt ) (cmMdAllocateDebug( p, eleCnt, n, kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ )) -#define cmMemResizeNZ( n, p, eleCnt ) (cmMdAllocateDebug( p, eleCnt, n, kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ )) -#define cmMemResize( type, p, eleCnt ) ((type*)cmMdAllocateDebug( p, eleCnt, sizeof(type), kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ )) -#define cmMemResizeZ( type, p, eleCnt ) ((type*)cmMdAllocateDebug( p, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ )) -#define cmMemResizeP( type, p, eleCnt ) ((type*)cmMdAllocateDebug( p, eleCnt, sizeof(type), kAlignMmFl | kPreserveMmFl, __FUNCTION__, __FILE__, __LINE__ )) -#define cmMemResizePZ( type, p, eleCnt ) ((type*)cmMdAllocateDebug( p, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl | kPreserveMmFl, __FUNCTION__, __FILE__, __LINE__ )) +#define cmMemMalloc( byteCnt ) cmMdAllocateDebug( NULL, 1, byteCnt, kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ ) +#define cmMemMallocZ( byteCnt ) cmMdAllocateDebug( NULL, 1, byteCnt, kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ ) +#define cmMemAlloc( type, eleCnt ) ((type*)cmMdAllocateDebug( NULL, eleCnt, sizeof(type), kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ )) +#define cmMemAllocZ( type, eleCnt ) ((type*)cmMdAllocateDebug( NULL, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ )) +#define cmMemAllocStr( str ) (cmMdAllocStrDebug( NULL, str, cmStringLen(str), kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ )) +#define cmMemAllocStrN(str, charCnt ) (cmMdAllocStrDebug( NULL, str, charCnt, kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ )) +#define cmMemResizeStr(p, str ) (cmMdAllocStrDebug( p, str, cmStringLen(str), kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ )) +#define cmMemResizeStrN(p, str, charCnt ) (cmMdAllocStrDebug( p, str, charCnt, kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ )) +#define cmMemResizeN( n, p, eleCnt ) (cmMdAllocateDebug( p, eleCnt, n, kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ )) +#define cmMemResizeNZ( n, p, eleCnt ) (cmMdAllocateDebug( p, eleCnt, n, kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ )) +#define cmMemResize( type, p, eleCnt ) ((type*)cmMdAllocateDebug( p, eleCnt, sizeof(type), kAlignMmFl, __FUNCTION__, __FILE__, __LINE__ )) +#define cmMemResizeZ( type, p, eleCnt ) ((type*)cmMdAllocateDebug( p, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ )) +#define cmMemResizeP( type, p, eleCnt ) ((type*)cmMdAllocateDebug( p, eleCnt, sizeof(type), kAlignMmFl | kPreserveMmFl, __FUNCTION__, __FILE__, __LINE__ )) +#define cmMemResizePZ( type, p, eleCnt ) ((type*)cmMdAllocateDebug( p, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl | kPreserveMmFl, __FUNCTION__, __FILE__, __LINE__ )) #define cmMemFree( ptr ) cmMdFreeDebug( ptr, __FUNCTION__, __FILE__, __LINE__ ) #define cmMemPtrFree( ptrPtr ) cmMdFreePtrDebug( (void**)ptrPtr, __FUNCTION__, __FILE__, __LINE__ ) diff --git a/cmProc.h b/cmProc.h index 0f31725..7908c46 100644 --- a/cmProc.h +++ b/cmProc.h @@ -48,7 +48,7 @@ extern "C" { { cmObj obj; unsigned bufSmpCnt; // wndSmpCnt + hopSmpCnt - cmSample_t* bufV; + cmSample_t* bufV; // bufV[bufSmpCnt] all other pointers use this memory cmSample_t* outV; // output window outV[ outN ] unsigned outN; // outN == wndSmpCnt unsigned procSmpCnt; // input sample count diff --git a/cmProc2.c b/cmProc2.c index 8732b80..32cc04a 100644 --- a/cmProc2.c +++ b/cmProc2.c @@ -2300,11 +2300,10 @@ cmRC_t cmPvAnlInit( cmPvAnl* p, unsigned procSmpCnt, double srate, unsigned cmRC_t cmPvAnlFinal(cmPvAnl* p ) { return cmOkRC; } - bool cmPvAnlExec( cmPvAnl* p, const cmSample_t* x, unsigned xN ) { bool fl = false; - if( cmShiftBufExec(&p->sb,x,xN) ) + while( cmShiftBufExec(&p->sb,x,xN) ) { cmWndFuncExec(&p->wf, p->sb.outV, p->sb.wndSmpCnt ); @@ -2421,13 +2420,12 @@ cmRC_t cmPvSynExec( cmPvSyn* p, const cmReal_t* magV, const cmReal_t* phsV ) double twoPi = 2.0 * M_PI; unsigned k; - for(k=0; kbinCnt; ++k) { // phase dist between cur and prv frame cmReal_t dp = phsV[k] - p->phs0V[k]; - // dist must be positive (cmcum phase always increases) + // dist must be positive (accum phase always increases) if( dp < -0.00001 ) dp += twoPi; @@ -2449,8 +2447,9 @@ cmRC_t cmPvSynExec( cmPvSyn* p, const cmReal_t* magV, const cmReal_t* phsV ) p->phs0V[k] = phsV[k]; p->mag0V[k] = magV[k]; } - - cmIFftExecPolarRS( &p->ft, p->magV, p->phsV ); + + cmIFftExecPolarRS( &p->ft, magV, phsV ); + cmOlaExecS( &p->ola, p->ft.outV, p->ft.outN ); //printf("%i %i\n",p->binCnt,p->ft.binCnt ); @@ -2462,6 +2461,16 @@ cmRC_t cmPvSynExec( cmPvSyn* p, const cmReal_t* magV, const cmReal_t* phsV ) return cmOkRC; } +cmRC_t cmPvSynDoIt( cmPvSyn* p, const cmSample_t* v ) +{ + cmOlaExecS( &p->ola, v, p->wndSmpCnt ); + + //printf("%f\n",cmVOS_RMS(s,p->wndSmpCnt,p->wndSmpCnt)); + + return cmOkRC; +} + + const cmSample_t* cmPvSynExecOut(cmPvSyn* p ) { return cmOlaExecOut(&p->ola); } @@ -3653,9 +3662,14 @@ cmRC_t cmNmfExec( cmNmf_t* p, const cmReal_t* vM, unsigned cn ) cmSpecDist_t* cmSpecDistAlloc( cmCtx* ctx,cmSpecDist_t* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId ) { cmSpecDist_t* p = cmObjAlloc( cmSpecDist_t, ctx, ap ); + + if( procSmpCnt != 0 ) + { if( cmSpecDistInit( p, procSmpCnt, srate, wndSmpCnt, hopFcmt, olaWndTypeId ) != cmOkRC ) cmSpecDistFree(&p); + } + return p; } @@ -3666,7 +3680,7 @@ cmRC_t cmSpecDistFree( cmSpecDist_t** pp ) return cmOkRC; cmSpecDist_t* p = *pp; - + cmSpecDistFinal(p); cmMemPtrFree(&p->hzV); cmObjFree(pp); @@ -3713,8 +3727,10 @@ cmRC_t cmSpecDistInit( cmSpecDist_t* p, unsigned procSmpCnt, double srate, unsig p->aeMin = 1000; p->aeMax = -1000; + //p->bypOut = cmMemResizeZ(cmSample_t, p->bypOut, procSmpCnt ); + return rc; } @@ -3723,6 +3739,7 @@ cmRC_t cmSpecDistFinal(cmSpecDist_t* p ) cmRC_t rc = cmOkRC; cmPvAnlFree(&p->pva); cmPvSynFree(&p->pvs); + return rc; } @@ -3746,6 +3763,7 @@ void _cmSpecDistBasicMode0(cmSpecDist_t* p, cmReal_t* X1m, unsigned binCnt, cmRe } + } void _cmSpecDistBasicMode(cmSpecDist_t* p, cmReal_t* X1m, unsigned binCnt, cmReal_t thresh ) @@ -3856,19 +3874,18 @@ void _cmSpecDistAmpEnvMode( cmSpecDist_t* p, cmReal_t* X1m ) } - cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn ) { assert( sn == p->procSmpCnt ); - + // cmPvAnlExec() returns true when it calc's a new spectral output frame if( cmPvAnlExec( p->pva, sp, sn ) ) { cmReal_t X1m[p->pva->binCnt]; cmVOR_AmplToDbVV(X1m, p->pva->binCnt, p->pva->magV, -1000.0 ); - + switch( p->mode ) { case kBypassModeSdId: @@ -3904,17 +3921,21 @@ cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn ) default: break; } - + cmVOR_DbToAmplVV(X1m, p->pva->binCnt, X1m ); cmPvSynExec(p->pvs, X1m, p->pva->phsV ); - + } + return cmOkRC; } + const cmSample_t* cmSpecDistOut( cmSpecDist_t* p ) -{ return cmPvSynExecOut(p->pvs); } +{ + return cmPvSynExecOut(p->pvs); +} //------------------------------------------------------------------------------------------------------------ diff --git a/cmProc4.c b/cmProc4.c index 51c9e19..3a50bd9 100644 --- a/cmProc4.c +++ b/cmProc4.c @@ -1630,16 +1630,14 @@ cmRC_t cmScMatchExec( cmScMatch* p, unsigned locIdx, unsigned locN, const cmScMa } // Traverse the least cost path and: -// 1) Set p->esi to the score location index of the last MIDI note +// 1) Return, esi, the score location index of the last MIDI note // which has a positive match with the score and assign // the internal score index to cp->locIdx. // // 2) Set cmScAlignPath_t.locIdx - index into p->loc[] associated // with each path element that is a 'substitute' or an 'insert'. // -// 3) Set p->missCnt: the count of trailing non-positive matches. -// p->missCnt is eventually used in cmScAlignStep() to track the number -// of consecutive trailing missed notes. +// 3) Set *missCnPtr: the count of trailing non-positive matches. // // i_opt is index into p->loc[] of p->p_opt. unsigned cmScMatchDoSync( cmScMatch* p, unsigned i_opt, cmScMatchMidi_t* midiBuf, unsigned midiN, unsigned* missCntPtr ) @@ -1961,6 +1959,7 @@ cmRC_t cmScMatcherInit( cmScMatcher* p, double srate, cmScH_t scH, unsigned scW p->cbArg = cbArg; p->mn = midiWndN; p->midiBuf = cmMemResizeZ(cmScMatchMidi_t,p->midiBuf,p->mn); + p->initHopCnt = 50; p->stepCnt = 3; p->maxMissCnt = p->stepCnt+1; p->rn = 2 * cmScoreEvtCount(scH); @@ -2083,7 +2082,7 @@ void cmScMatcherPrintPath( cmScMatcher* p ) _cmScMatchPrintPath(p->mp, p->mp->p_opt, p->begSyncLocIdx, p->midiBuf ); } -unsigned cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned scanCnt ) +unsigned cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned hopCnt ) { assert( p->mp != NULL && p->mp->mmn > 0 ); @@ -2102,7 +2101,7 @@ unsigned cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned scanCnt ) return cmInvalidIdx; // calc the edit distance from pitchV[] to a sliding score window - for(i=0; rc==cmOkRC && (scanCnt==cmInvalidCnt || imp, bli + i, p->mp->msn, p->midiBuf, p->mp->mmn, s_opt ); @@ -2227,7 +2226,7 @@ cmRC_t cmScMatcherExec( cmScMatcher* p, unsigned smpIdx, unsigned status, c { bool fl = p->mbi > 0; cmRC_t rc = cmOkRC; - unsigned eli = p->eli; + unsigned org_eli = p->eli; if( scLocIdxPtr != NULL ) *scLocIdxPtr = cmInvalidIdx; @@ -2239,7 +2238,7 @@ cmRC_t cmScMatcherExec( cmScMatcher* p, unsigned smpIdx, unsigned status, c // if the MIDI buffer transitioned to full then perform an initial scan sync. if( fl && p->mbi == 0 ) { - if( (p->begSyncLocIdx = cmScMatcherScan(p,p->ili,cmInvalidCnt)) == cmInvalidIdx ) + if( (p->begSyncLocIdx = cmScMatcherScan(p,p->ili,p->initHopCnt)) == cmInvalidIdx ) rc = cmInvalidArgRC; // signal init. scan sync. fail else { @@ -2253,8 +2252,21 @@ cmRC_t cmScMatcherExec( cmScMatcher* p, unsigned smpIdx, unsigned status, c rc = cmScMatcherStep(p); } - if( scLocIdxPtr!=NULL && p->eli != eli ) - *scLocIdxPtr = p->mp->loc[p->eli].scLocIdx; + // if we lost sync + if( p->eli == cmInvalidIdx ) + { + // IF WE LOST SYNC THEN WE BETTER DO SOMETHING - LIKE INCREASE THE SCAN HOPS + // ON THE NEXT EVENT. + p->eli = org_eli; + } + else + { + if( scLocIdxPtr!=NULL && p->eli != org_eli ) + { + //printf("LOC:%i bar:%i\n",p->eli,p->mp->loc[p->eli].barNumb); + *scLocIdxPtr = p->mp->loc[p->eli].scLocIdx; + } + } return rc; } @@ -2645,7 +2657,11 @@ cmRC_t cmScMeasReset( cmScMeas* p ) unsigned i; for(i=0; isn; ++i) + { p->set[i].value = DBL_MAX; + p->set[i].tempo = 0; + p->set[i].match_cost = 0; + } return rc; } @@ -3028,7 +3044,10 @@ void _cmScMeasCalcVal( cmScMeas* p, cmScMeasSet_t* sp, int n_mii ) // sync the score and MIDI based on the match information if( cmScMatchDoSync(p->mp, bli, mb, mn, NULL ) == cmInvalidIdx ) return; - + + if( p->mp->opt_cost != DBL_MAX ) + sp->match_cost = p->mp->opt_cost / sp->sp->eleCnt; + switch( sp->sp->varId ) { case kEvenVarScId: @@ -3050,7 +3069,7 @@ void _cmScMeasCalcVal( cmScMeas* p, cmScMeasSet_t* sp, int n_mii ) sp->tempo = r.tempo; // print the result - _cmScMeasPrintResult(p, sp, &r, bli, mb ); + //_cmScMeasPrintResult(p, sp, &r, bli, mb ); MEAS_MATCH_CNT++; } @@ -3378,38 +3397,53 @@ const _cmScModTypeMap_t* _cmScModTypeLabelToMap( const cmChar_t* label ) return NULL; } -cmScModVar_t* _cmScModulatorInsertValue( cmScModulator* p, unsigned varSymId ) +cmScModVar_t* _cmScModSymToVar( cmScModulator* p, unsigned varSymId ) { cmScModVar_t* vp = p->vlist; for(; vp!=NULL; vp=vp->vlink) if( varSymId == vp->varSymId ) return vp; + return NULL; +} - vp = cmMemAllocZ(cmScModVar_t,1); - vp->varSymId = varSymId; - vp->vlink = p->vlist; - p->vlist = vp; +cmScModVar_t* _cmScModulatorInsertVar( cmScModulator* p, unsigned varSymId, unsigned flags ) +{ + cmScModVar_t* vp = _cmScModSymToVar(p,varSymId); + + if( vp == NULL ) + { + vp = cmMemAllocZ(cmScModVar_t,1); + vp->varSymId = varSymId; + vp->outVarId = cmInvalidId; + vp->vlink = p->vlist; + p->vlist = vp; + } + + vp->flags = flags; + vp->value = DBL_MAX; + vp->min = DBL_MAX; + vp->max = DBL_MAX; + vp->rate = DBL_MAX; + vp->phase = 0; + vp->entry = NULL; + vp->alink = NULL; + return vp; } -cmRC_t _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocIdx, unsigned modSymId, unsigned varSymId, unsigned typeId, const double* av, unsigned an) +cmScModEntry_t* _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocIdx, unsigned modSymId, unsigned varSymId, unsigned typeId, unsigned paramCnt ) { assert( idx < p->en ); - if( p->modSymId != modSymId ) - return cmOkRC; - p->earray[idx].scLocIdx = scLocIdx; p->earray[idx].typeId = typeId; - p->earray[idx].parray = an==0 ? NULL : cmMemAllocZ(double,an); - p->earray[idx].pn = an; - p->earray[idx].valPtr = _cmScModulatorInsertValue(p,varSymId); + p->earray[idx].varPtr = _cmScModulatorInsertVar(p,varSymId,0); - unsigned i; - for(i=0; iearray[idx].parray[i] = av[i]; - return cmOkRC; + if( p->earray[idx].varPtr->outVarId == cmInvalidIdx ) + p->earray[idx].varPtr->outVarId = p->outVarCnt++; + + return p->earray + idx; } @@ -3421,12 +3455,57 @@ cmRC_t _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocI } */ - cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, const cmChar_t* fn ) + // Parameter values are found as values of the 'data','min' or 'max' fields. + // A parameter value may be either a symbol identifier (mapped to a variable) + // or a literal number. This function determines which form the paramter + // value takes and parses it accordingly. + cmRC_t _cmScModulatorParseParam( cmScModulator* p, cmSymTblH_t stH, cmJsonNode_t* np, cmScModParam_t* pp ) +{ + cmRC_t rc = cmOkRC; + + switch( np->typeId ) + { + case kIntTId: + case kRealTId: + if( cmJsonRealValue(np, &pp->val ) != kOkJsRC ) + { + rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Error parsing in Modulator literal value." ); + goto errLabel; + } + pp->pid = kLiteralModPId; + break; + + case kStringTId: + { + const cmChar_t* label = NULL; + if( cmJsonStringValue(np, &label) != kOkJsRC ) + { + rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Error parsing in Modulator symbol label." ); + goto errLabel; + } + + pp->symId = cmSymTblRegisterSymbol(stH,label); + pp->pid = kSymbolModPId; + } + break; + + default: + rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Parameter value is not a number or identifier." ); + goto errLabel; + break; + } + + errLabel: + return rc; +} + +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; + unsigned i = cmInvalidIdx; + unsigned j = cmInvalidIdx; // read the JSON file if( cmJsonInitializeFromFile(&jsH, fn, ctx ) != kOkJsRC ) @@ -3442,12 +3521,13 @@ cmRC_t _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocI } // allocate the entry array - p->en = cmJsonChildCount(jnp); - p->earray = cmMemResizeZ(cmScModEntry_t,p->earray,p->en); + unsigned entryCnt = cmJsonChildCount(jnp); + p->earray = cmMemResizeZ(cmScModEntry_t,p->earray,entryCnt); + p->en = entryCnt; - for(i=0; ien; ++i) + for(i=0; iobj, cmInvalidArgRC, "Synax error in Modulator 'data' record at index %i in file:%s",i,cmStringNullGuard(fn) ); - goto errLabel; - } - unsigned modSymId = cmSymTblRegisterSymbol(stH,modLabel); unsigned varSymId = cmSymTblRegisterSymbol(stH,varLabel); - // the data may be an array of doubles .... - if( cmJsonIsArray(dnp) ) + // the mod entry label must match the modulators label + if( p->modSymId != modSymId ) { - unsigned an = cmJsonChildCount(dnp); - double av[an]; - unsigned j; + --p->en; + continue; + } - // read each element in the data array - for(j=0; jobj, cmInvalidArgRC, "Error parsing in Modulator 'data' record at index %i value index %i in file:%s",i,j,cmStringNullGuard(fn) ); - goto errLabel; - } - _cmScModulatorInsertEntry(p,i,scLocIdx,modSymId,varSymId,map->typeId,av,an); - } - else // ... or a scalar + // 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,i,scLocIdx,modSymId,varSymId,map->typeId,paramCnt); + + typedef struct { - double v; - if( cmJsonRealValue(dnp,&v) != kOkJsRC ) - { - rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Error paring in Modulator 'data' on record index %i.",i,cmStringNullGuard(fn)); - goto errLabel; - } + const cmChar_t* label; + cmScModParam_t* param; + } map_t; - _cmScModulatorInsertEntry(p,i,scLocIdx,modSymId,varSymId,map->typeId,&v,1); + // parse the var and parameter records + map_t mapArray[] = + { + { "min", &ep->min }, + { "max", &ep->max }, + { "rate",&ep->rate }, + { "val", &ep->beg }, + { "end", &ep->end }, + { "dur", &ep->dur }, + { NULL, NULL } + }; - } + unsigned j=0; + 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; } errLabel: + if( rc != cmOkRC ) + cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Error parsing in Modulator 'data' record at index %i value index %i in file:%s",i,j,cmStringNullGuard(fn) ); + + // release the JSON tree if( cmJsonIsValid(jsH) ) cmJsonFinalize(&jsH); @@ -3528,6 +3613,32 @@ cmRC_t _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocI return rc; } +cmRC_t _cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx ) +{ + cmRC_t rc = cmOkRC; + + p->alist = NULL; + p->elist = NULL; + p->nei = 0; + p->outVarCnt = 0; + + // reload the file + if((rc = _cmScModulatorParse(p,ctx,p->stH,p->fn)) != cmOkRC ) + goto errLabel; + + + // clear the active flag on all variables + cmScModVar_t* vp = p->vlist; + for(; vp!=NULL; vp=vp->vlink) + { + vp->flags = cmClrFlag(vp->flags,kActiveModFl); + vp->alink = NULL; + } + + errLabel: + return rc; +} + cmRC_t cmScModulatorInit( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, double srate, unsigned samplesPerCycle, const cmChar_t* fn, const cmChar_t* modLabel, cmScModCb_t cbFunc, void* cbArg ) { cmRC_t rc; @@ -3535,29 +3646,28 @@ cmRC_t cmScModulatorInit( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, doub if((rc = cmScModulatorFinal(p)) != cmOkRC ) return rc; + p->fn = cmMemAllocStr(fn); + p->stH = stH; p->modSymId = cmSymTblRegisterSymbol(stH,modLabel); p->cbFunc = cbFunc; p->cbArg = cbArg; p->samplesPerCycle = samplesPerCycle; p->srate = srate; + - if((rc = _cmScModulatorParse(p,ctx,stH,fn)) != cmOkRC ) - goto errLabel; - - errLabel: if( rc != cmOkRC ) cmScModulatorFinal(p); else - cmScModulatorReset(p,0); + _cmScModulatorReset(p,ctx,0); return rc; } cmRC_t cmScModulatorFinal( cmScModulator* p ) { - unsigned i; + cmMemFree(p->fn); - // release each value record + // release each var record cmScModVar_t* vp = p->vlist; while( vp!=NULL ) { @@ -3566,61 +3676,126 @@ cmRC_t cmScModulatorFinal( cmScModulator* p ) vp=np; } - // release each entry record + return cmOkRC; +} + +unsigned cmScModulatorOutVarCount( cmScModulator* p ) +{ return p->outVarCnt; } + +cmScModVar_t* cmScModulatorOutVar( cmScModulator* p, unsigned idx ) +{ + unsigned i; for(i=0; ien; ++i) - cmMemFree(p->earray[i].parray); + if( p->earray[i].varPtr->outVarId == idx ) + return p->earray[i].varPtr; + + return NULL; +} + +cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, double value, double min, double max ) +{ + cmScModVar_t* vp; + // if the var does not exist .... + if((vp = _cmScModSymToVar(p, varSymId )) == NULL ) + { + // ... then create it + vp = _cmScModulatorInsertVar(p,varSymId,kCalcModFl); + assert(vp!=NULL); + } + + assert( min <= max); + + vp->min = min; + vp->max = max; + vp->value = value; return cmOkRC; } -unsigned cmScModulatorVarCount( cmScModulator* p ) + +cmRC_t cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx ) { - unsigned n = 0; - const cmScModVar_t* vp = p->vlist; - for(; vp!=NULL; vp=vp->vlink) - ++n; - - return n; -} - -cmScModVar_t* cmScModulatorVar( cmScModulator* p, unsigned idx ) -{ - unsigned n = 0; - cmScModVar_t* vp = p->vlist; - for(; vp!=NULL; vp=vp->vlink,++n) - if( n == idx ) - return vp; - - assert(0); - return NULL; -} - -cmRC_t cmScModulatorReset( cmScModulator* p, unsigned scLocIdx ) -{ - p->alist = NULL; - p->nei = 0; - + _cmScModulatorReset(p,ctx,scLocIdx); return cmScModulatorExec(p,scLocIdx); } -void _cmScModUnlink( cmScModulator* p, cmScModVar_t* vp, cmScModVar_t* pp ) +void _cmScModUnlinkActive( cmScModulator* p, cmScModVar_t* vp, cmScModVar_t* pp ) { - if( pp == NULL ) + // if vp is the first link on the chain + if( vp == p->alist ) p->alist = vp->alink; - else - pp->alink = vp->alink; - vp->flags = 0; + // if vp is the last link on the chain + if( vp == p->elist ) + p->elist = pp; + + if( pp != NULL ) + pp->alink = vp->alink; + + vp->flags = cmClrFlag(vp->flags,kActiveModFl); vp->alink = NULL; vp->entry = NULL; } -// Type specific variable activation +// 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: + 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; +} + +// Type specific variable activation - cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep ) { cmRC_t rc = cmOkRC; - cmScModVar_t* vp = ep->valPtr; + cmScModVar_t* vp = ep->varPtr; + + // optionally update the min/max/rate values in the target var + if((rc = _cmScModGetParam(p,&ep->min,&vp->min)) != cmOkRC ) + goto errLabel; + + if((rc = _cmScModGetParam(p,&ep->max,&vp->max)) != cmOkRC ) + goto errLabel; + + if((rc = _cmScModGetParam(p,&ep->rate,&vp->rate)) != cmOkRC ) + goto errLabel; + switch( ep->typeId ) { @@ -3633,49 +3808,94 @@ cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep ) break; case kSetLineModTId: - vp->value = ep->parray[0]; - vp->v0 = ep->parray[0]; - vp->phase = 0; - ep->parray[0] = ep->parray[1]; - ep->parray[1] = ep->parray[2]; + _cmScModGetParam(p,&ep->beg,&vp->value); // starting value + vp->v0 = vp->value; // set initial value + vp->phase = 0; // reset phase break; default: { assert(0); } } + errLabel: + return rc; +} + +// Callback the application with a new variable value. +cmRC_t _cmScModExecSendValue( cmScModulator* p, cmScModVar_t* vp ) +{ + cmRC_t rc = cmOkRC; + bool sendFl = true; + double v = vp->value; + + // scale the output value - this is equiv to scaling the LHS + if( cmIsFlag(vp->flags,kCalcModFl) && vp->min!=DBL_MAX && vp->max!=DBL_MAX ) + v = vp->min + v * (vp->max - vp->min); + + // if an output rate throttle is in effect .... + if( vp->rate!=DBL_MAX && vp->phase!=0 ) + sendFl = remainder(vp->phase*p->samplesPerCycle, p->srate*vp->rate/1000 ) < p->samplesPerCycle; + + if(sendFl) + p->cbFunc(p->cbArg,vp->varSymId,v); + return rc; } // Return true if vp should be deactivated otherwise return false. bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp ) { - bool fl = false; + cmRC_t rc = cmOkRC; + bool fl = false; + switch( vp->entry->typeId ) { case kSetModTId: - p->cbFunc(p->cbArg,vp->varSymId,vp->entry->parray[0]); - fl = true; + { + if((rc = _cmScModGetParam(p,&vp->entry->beg,&vp->value)) != cmOkRC ) + goto errLabel; + + vp->phase = 0; // force the value to be sent + fl = true; + } break; case kSetLineModTId: case kLineModTId: { - double v1 = vp->entry->parray[0]; - double v = vp->value + (v1-vp->v0) * (vp->phase * p->samplesPerCycle) / (p->srate * vp->entry->parray[1]); + double v1, td; + + // get the target value + if((rc = _cmScModGetParam(p,&vp->entry->end,&v1)) != cmOkRC) + goto errLabel; + + // get the time duration + if((rc = _cmScModGetParam(p,&vp->entry->dur,&td)) != cmOkRC) + goto errLabel; + + 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 ) v = v1; - vp->phase += 1; vp->value = v; - p->cbFunc(p->cbArg,vp->varSymId,v); } break; default: { assert(0); } } + + // notify the application that a new variable value has been generated + rc = _cmScModExecSendValue(p,vp); + + // increment the phase - after send because send notices when phase is zero + vp->phase += 1; + + errLabel: + if( rc != cmOkRC ) + fl = true; + return fl; } @@ -3686,25 +3906,35 @@ cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx ) cmRC_t rc = cmOkRC; // trigger entries that have expired since the last call to this function - for(; p->neien && p->earray[p->nei].scLocIdx<=scLocIdx; ++p->nei) + for(; p->neien && (p->earray[p->nei].scLocIdx==-1 || p->earray[p->nei].scLocIdx<=scLocIdx); ++p->nei) { cmScModEntry_t* ep = p->earray + p->nei; // if the variable assoc'd with this entry is not on the active list ... - if( cmIsFlag(ep->valPtr->flags,kActiveModFl) == false ) + if( cmIsFlag(ep->varPtr->flags,kActiveModFl) == false ) { - // ... then push it onto the front of the active list ... - ep->valPtr->flags = kActiveModFl; - ep->valPtr->alink = p->alist; - p->alist = ep->valPtr; - } + // ... 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->valPtr->entry = ep; + ep->varPtr->entry = ep; } @@ -3714,10 +3944,90 @@ cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx ) for(; vp!=NULL; vp=vp->alink) { if( _cmScModExec(p,vp) ) - _cmScModUnlink(p,vp,pp); + _cmScModUnlinkActive(p,vp,pp); else pp = vp; } return rc; } + + +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("ENTRIES:\n"); + unsigned i; + for(i=0; ien; ++i) + { + cmScModEntry_t* ep = p->earray + i; + printf("%3i %4i %2i %7s ", i, ep->scLocIdx, ep->typeId, 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"); + } + + printf("VARIABLES\n"); + cmScModVar_t* vp = p->vlist; + for(; vp!=NULL; vp=vp->vlink) + { + _cmScModDumpVar(p,vp); + printf("\n"); + } + + return rc; + +} diff --git a/cmProc4.h b/cmProc4.h index d1a80cc..af5bc83 100644 --- a/cmProc4.h +++ b/cmProc4.h @@ -5,8 +5,6 @@ extern "C" { #endif - - typedef struct { unsigned smpIdx; // time tag sample index for val @@ -340,16 +338,17 @@ typedef void (*cmScMatcherCb_t)( struct cmScMatcher_str* p, void* arg, cmScMatch unsigned ri; // next avail res[] recd. double s_opt; // - unsigned missCnt; // count of consecutive trailing non-matches + unsigned missCnt; // current count of consecutive trailing non-matches unsigned ili; // index into loc[] to start scan following reset unsigned eli; // index into loc[] of the last positive match. - unsigned mni; // track the count of MIDI events since the last call to cmScMatcherReset() - unsigned mbi; // index of oldest MIDI event in midiBuf[]; 0 when the buffer is full. + unsigned mni; // current count of MIDI events since the last call to cmScMatcherReset() + unsigned mbi; // index of oldest MIDI event in midiBuf[]; stays at 0 when the buffer is full. unsigned begSyncLocIdx; // start of score window, in mp->loc[], of best match in previous scan + unsigned initHopCnt; // max window hops during the initial (when the MIDI buffer fills for first time) sync scan unsigned stepCnt; // count of forward/backward score loc's to examine for a match during cmScMatcherStep(). unsigned maxMissCnt; // max. number of consecutive non-matches during step prior to executing a scan. - unsigned scanCnt; // count of time scan was executed inside cmScMatcherStep() - + unsigned scanCnt; // current count of times a resync-scan was executed during cmScMatcherStep() + bool printFl; } cmScMatcher; @@ -363,13 +362,13 @@ cmRC_t cmScMatcherFinal( cmScMatcher* p ); // 'scLocIdx' is a score index as used by cmScoreLoc(scH) not into p->mp->loc[]. cmRC_t cmScMatcherReset( cmScMatcher* p, unsigned scLocIdx ); -// Slide a score window scanCnt times, beginning at 'bli' (an +// Slide a score window hopCnt times, beginning at 'bli' (an // index int p->mp->loc[]) looking for the best match to p->midiBuf[]. // The score window contain scWndN (p->mp->mcn-1) score locations. // Returns the index into p->mp->loc[] of the start of the best // match score window. The score associated // with this match is stored in s_opt. -unsigned cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned scanCnt ); +unsigned cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned hopCnt ); // Step forward/back by p->stepCnt from p->eli. // p->eli must therefore be valid prior to calling this function. @@ -385,7 +384,7 @@ cmRC_t cmScMatcherStep( cmScMatcher* p ); // If the MIDI note passed by the call results in a successful match then // p->eli will be updated to the location in p->mp->loc[] of the latest // match, the MIDI note in p->midiBuf[] associated with this match -// will be assigned valid locIdx and scLocIdx values, and *scLocIdxPtr +// will be assigned a valid locIdx and scLocIdx values, and *scLocIdxPtr // will be set with the matched scLocIdx of the match. // If this call does not result in a successful match *scLocIdxPtr is set // to cmInvalidIdx. @@ -413,7 +412,9 @@ typedef struct unsigned eli; // double value; // DBL_MAX if the value has not yet been set - double tempo; // DBL_MAX until set + double tempo; // + double match_cost; // cost of the match to the performance divided by sp->eleCnt + } cmScMeasSet_t; @@ -488,30 +489,57 @@ enum enum { - kActiveModFl = 0x01 + 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. }; struct cmScModEntry_str; +typedef enum +{ + kInvalidModPId, + kLiteralModPId, // this is a literal value + kSymbolModPId // +} cmScModPId_t; + +typedef struct cmScModParam_str +{ + cmScModPId_t pid; // parameter type: literal or symbol + unsigned symId; // symbol of external and internal variables + double val; // value of literals +} cmScModParam_t; + typedef struct cmScModVar_str { unsigned flags; // see kXXXModFl flags above. unsigned varSymId; // variable name - double value; // current value + unsigned outVarId; // output var id + double value; // current value of this variable double v0; // reserved internal variable - unsigned phase; // cycle phase since activation + unsigned phase; // cycle phase since activation + double min; + double max; + double rate; // output rate in milliseconds struct cmScModEntry_str* entry; // last entry assoc'd with this value struct cmScModVar_str* vlink; // p->vlist link struct cmScModVar_str* alink; // p->alist link } cmScModVar_t; + + +// Each entry gives a time tagged location and some parameters +// for an algorthm which is used to set/modulate a value. typedef struct cmScModEntry_str { - unsigned scLocIdx; // entry start time - unsigned typeId; // variable type - double* parray; // parray[pn] - parameter array - unsigned pn; // parameter count - cmScModVar_t* valPtr; // target variable + unsigned scLocIdx; // entry start time + unsigned typeId; // variable type + cmScModParam_t beg; // parameter values + cmScModParam_t end; // + cmScModParam_t dur; // + 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) + cmScModVar_t* varPtr; // target variable } cmScModEntry_t; typedef void (*cmScModCb_t)( void* cbArg, unsigned varSymId, double value ); @@ -519,7 +547,9 @@ typedef void (*cmScModCb_t)( void* cbArg, unsigned varSymId, double value ); typedef struct { cmObj obj; + cmChar_t* fn; // modulator score file unsigned modSymId; // modulator name + cmSymTblH_t stH; // symbol table used by this modulator cmScModCb_t cbFunc; // active value callback function void* cbArg; // first arg to cbFunc() unsigned samplesPerCycle; // interval in samples between calls to cmScModulatorExec() @@ -528,7 +558,9 @@ typedef struct unsigned en; // count 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 outVarCnt; // count of unique vars that are targets of entry recds } cmScModulator; @@ -538,13 +570,16 @@ cmRC_t cmScModulatorInit( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t s cmRC_t cmScModulatorFinal( cmScModulator* p ); // Return count of variables. -unsigned cmScModulatorVarCount( cmScModulator* p ); +unsigned cmScModulatorOutVarCount( cmScModulator* p ); // Return a pointer to the variable at vlist[idx]. -cmScModVar_t* cmScModulatorVar( cmScModulator* p, unsigned idx ); +cmScModVar_t* cmScModulatorOutVar( cmScModulator* p, unsigned idx ); -cmRC_t cmScModulatorReset( cmScModulator* p, unsigned scLocIdx ); +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 cmScModulatorExec( cmScModulator* p, unsigned scLocIdx ); +cmRC_t cmScModulatorDump( cmScModulator* p ); #ifdef __cplusplus } diff --git a/cmProcObj.c b/cmProcObj.c index 96aae81..949a008 100644 --- a/cmProcObj.c +++ b/cmProcObj.c @@ -182,7 +182,7 @@ cmRC_t cmMtxFileClose( cmMtxFile* p ) return cmOkRC; } -cmRC_t cmMtxFileFloatExec( cmMtxFile* p, const float* inPtr, unsigned inCnt, unsigned inStride ) +cmRC_t cmMtxFileFloatExec( cmMtxFile* p, const float* inPtr, unsigned inCnt, unsigned inStride ) { const float* ep = inPtr + (inCnt * inStride); for(; inPtr < ep; inPtr+=inStride ) @@ -191,7 +191,7 @@ cmRC_t cmMtxFileFloatExec( cmMtxFile* p, const float* inPtr, unsigned return cmOkRC; } -cmRC_t cmMtxFileDoubleExec( cmMtxFile* p, const double* inPtr, unsigned inCnt, unsigned inStride ) +cmRC_t cmMtxFileDoubleExec( cmMtxFile* p, const double* inPtr, unsigned inCnt, unsigned inStride ) { const double* ep = inPtr + (inCnt * inStride); for(; inPtr < ep; inPtr+=inStride ) @@ -201,7 +201,7 @@ cmRC_t cmMtxFileDoubleExec( cmMtxFile* p, const double* inPtr, unsigned return cmOkRC; } -cmRC_t cmMtxFileComplexExec( cmMtxFile* p, const cmComplexR_t* inPtr, unsigned inCnt, unsigned inStride ) +cmRC_t cmMtxFileComplexExec( cmMtxFile* p, const cmComplexR_t* inPtr, unsigned inCnt, unsigned inStride ) { const cmComplexR_t* sp = inPtr; const cmComplexR_t* ep = inPtr + (inCnt * inStride); diff --git a/cmSymTbl.c b/cmSymTbl.c index c90bbb5..6d74b84 100644 --- a/cmSymTbl.c +++ b/cmSymTbl.c @@ -261,6 +261,22 @@ unsigned cmSymTblRegisterSymbol( cmSymTblH_t h, const char* label ) unsigned cmSymTblRegisterStaticSymbol( cmSymTblH_t h, const char* label ) { return cmSymTblRegister( h, label, true ); } +unsigned cmSymTblRegisterVFmt( cmSymTblH_t h, const cmChar_t* fmt, va_list vl ) +{ + unsigned n = vsnprintf(NULL,0,fmt,vl); + cmChar_t b[n+1]; + vsnprintf(b,n,fmt,vl); + return cmSymTblRegister(h,fmt,vl); + +} + +unsigned cmSymTblRegisterFmt( cmSymTblH_t h, const cmChar_t* fmt, ... ) +{ + va_list vl; + va_start(vl,fmt); + cmSymTblRegisterVFmt(h,fmt,vl); + va_end(vl); +} bool cmSymTblRemove( cmSymTblH_t h, unsigned symId ) diff --git a/cmSymTbl.h b/cmSymTbl.h index 51a3fc5..d123e3b 100644 --- a/cmSymTbl.h +++ b/cmSymTbl.h @@ -37,6 +37,9 @@ extern "C" { unsigned cmSymTblRegisterSymbol( cmSymTblH_t h, const char* label ); unsigned cmSymTblRegisterStaticSymbol( cmSymTblH_t h, const char* label ); + unsigned cmSymTblRegisterVFmt( cmSymTblH_t h, const cmChar_t* fmt, va_list vl ); + unsigned cmSymTblRegisterFmt( cmSymTblH_t h, const cmChar_t* fmt, ... ); + bool cmSymTblRemove( cmSymTblH_t h, unsigned symId ); // Given a symbol id return the associated label. diff --git a/dsp/cmDspBuiltIn.c b/dsp/cmDspBuiltIn.c index 6ac2593..dcf7b14 100644 --- a/dsp/cmDspBuiltIn.c +++ b/dsp/cmDspBuiltIn.c @@ -1298,47 +1298,44 @@ cmDspRC_t _cmDspAudioFileOutReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDs return rc; } - cmDspRC_t _cmDspAudioFileOutExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) { cmDspRC_t rc = kOkDspRC; cmDspAudioFileOut_t* p = (cmDspAudioFileOut_t*)inst;; - unsigned fpc = cmDspSamplesPerCycle(ctx); - unsigned chCnt = cmDspUInt(inst,kChCntAofId); + unsigned chCnt = cmMin(2,cmDspUInt(inst,kChCntAofId)); + unsigned smpCnt = 0; cmSample_t* chArray[chCnt]; - unsigned i; + unsigned i,j; - // Assume that both channls have the same number of samples. - // (cmAudioWriteFile() has the same constraint ) - int sn = cmDspAudioBufSmpCount(ctx,inst,kIn0AofId,0); - - // This code can handle the case where the input channels contain - // more than or less than cmDspSamplesPerCycle(). - - while(sn>0) + for(i=0,j=0; ismpBuf + i*fpc; - const cmSample_t* sp = i==0 ? cmDspAudioBuf(ctx,inst,kIn0AofId,0) : cmDspAudioBuf(ctx,inst,kIn1AofId,0); - cmSample_t gain = i==0 ? cmDspDouble(inst,kGain0AofId) : cmDspDouble(inst,kGain1AofId); + chArray[j] = NULL; + } + else + { + cmSample_t gain = cmDspSample(inst,i==0?kGain0AofId:kGain1AofId); // get ch gain + + chArray[j] = cmDspAudioBuf(ctx,inst,chVarId,i); // get incoming audio buf ptr - cmVOS_MultVVS(chArray[i], n, sp, (cmSample_t)gain); + if( gain != 1.0 ) + cmVOS_MultVVS(chArray[j], iSmpCnt, chArray[j], gain); // apply gain + ++j; // incr chArray[] index + assert( smpCnt==0 || iSmpCnt==smpCnt); + smpCnt = iSmpCnt; // set outgoing sample count } - // write the samples - if( cmAudioFileWriteSample(p->afH, n, chCnt, chArray ) != kOkAfRC ) - rc = cmDspClassErr(ctx,inst->classPtr,kFileWriteFailDspRC,"An audio output file write failed."); - - } + // write the samples + if( cmAudioFileWriteSample(p->afH, smpCnt, j, chArray ) != kOkAfRC ) + rc = cmDspClassErr(ctx,inst->classPtr,kFileWriteFailDspRC,"An audio output file write failed."); + return rc; } @@ -5020,6 +5017,8 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] = cmMidiFilePlayClassCons, cmScFolClassCons, cmScModClassCons, + cmGSwitchClassCons, + NULL, }; diff --git a/dsp/cmDspClass.c b/dsp/cmDspClass.c index e7bb63e..83d2c6b 100644 --- a/dsp/cmDspClass.c +++ b/dsp/cmDspClass.c @@ -411,7 +411,7 @@ void cmDspArgSetup( { lp = label; label[labelCharCnt] = 0; - snprintf(label,labelCharCnt,"%s-%i",labelPrefix,labelId); + snprintf(label,labelCharCnt,"%s-%i",labelPrefix,labelId); } // use the symbol table to hold the label string @@ -898,6 +898,14 @@ cmDspRC_t cmDspValueSet( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, c cmDsvSetDouble(dvp, cmDsvGetDouble(svp)); break; + case kSampleDsvFl: + cmDsvSetSample(dvp, cmDsvGetSample(svp)); + break; + + case kRealDsvFl: + cmDsvSetReal(dvp, cmDsvGetReal(svp)); + break; + case kSymDsvFl: cmDsvSetSymbol(dvp, cmDsvGetSymbol(svp)); break; diff --git a/dsp/cmDspClass.h b/dsp/cmDspClass.h index 636700c..cb7d221 100644 --- a/dsp/cmDspClass.h +++ b/dsp/cmDspClass.h @@ -18,6 +18,7 @@ extern "C" { kThreadFailDspRC, // 6 kNetFailDspRC, // 7 kCsvFailDspRC, // 8 + kDspStoreFailDspRC, kProcFailDspRC, @@ -150,6 +151,7 @@ extern "C" { const cmChar_t* doc; // document string } cmDspVar_t; + typedef struct { const char* label; diff --git a/dsp/cmDspCtx.h b/dsp/cmDspCtx.h index 8a49b53..45e618c 100644 --- a/dsp/cmDspCtx.h +++ b/dsp/cmDspCtx.h @@ -6,8 +6,11 @@ extern "C" { #endif typedef cmHandle_t cmDspSysH_t; + typedef cmHandle_t cmDspStoreH_t; + struct cmAudioSysCtx_str; + struct cmDspGlobalVar_str; // DSP system context passed to many DSP instance functions typedef struct @@ -20,9 +23,11 @@ extern "C" { cmLHeapH_t lhH; cmJsonH_t jsH; cmSymTblH_t stH; + cmDspStoreH_t dsH; cmJsonH_t rsrcJsH; unsigned cycleCnt; // count of DSP execution cycles (multiply by cmDspSamplesPerCycle() to get time since start of DSP system in samples) + unsigned _disableSymId; unsigned _enableSymId; diff --git a/dsp/cmDspFx.c b/dsp/cmDspFx.c index fab4ac5..3115d96 100644 --- a/dsp/cmDspFx.c +++ b/dsp/cmDspFx.c @@ -1587,7 +1587,6 @@ cmDspRC_t _cmDspXfaderRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* case kMstrGateXfId: { bool fl = cmDspBool(inst,kMstrGateXfId); - printf("mstr:%i\n",fl); unsigned i; for(i=0; ichCnt; ++i) p->chGateV[i] = fl; @@ -4510,7 +4509,7 @@ struct cmDspClass_str* cmDistDsClassCons( cmDspCtx_t* ctx ) _cmDspDistDsExec, _cmDspDistDsRecv, NULL,NULL, - "Comb Filter"); + "Distortion and Downsampler"); return &_cmDistDsDC; } diff --git a/dsp/cmDspKr.c b/dsp/cmDspKr.c index 3884459..81a5c9a 100644 --- a/dsp/cmDspKr.c +++ b/dsp/cmDspKr.c @@ -21,6 +21,7 @@ #include "cmAudioSys.h" #include "cmDspCtx.h" #include "cmDspClass.h" +#include "cmDspStore.h" #include "cmDspUi.h" #include "cmDspSys.h" #include "cmMath.h" @@ -51,6 +52,8 @@ enum kUprSlopeKrId, kOffsetKrId, kInvertKrId, + kBypassKrId, + kWetKrId, kAudioInKrId, kAudioOutKrId }; @@ -79,6 +82,8 @@ cmDspClass_t _cmKrDC; { "uprs", kUprSlopeKrId, 0, 0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Upper Slope"}, { "offs", kOffsetKrId, 0, 0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Offset"}, { "invt", kInvertKrId, 0, 0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "Invert"}, + { "bypass", kBypassKrId, 0, 0, kInDsvFl | kBoolDsvFl | kOptArgDsvFl, "Bypass enable flag." }, + { "wet", kWetKrId, 0, 0, kInDsvFl | kSampleDsvFl, "Wet mix level."}, { "in", kAudioInKrId, 0, 0, kInDsvFl | kAudioBufDsvFl, "Audio Input" }, { "out", kAudioOutKrId, 0, 1, kOutDsvFl | kAudioBufDsvFl, "Audio Output" }, { NULL, 0, 0, 0, 0 } @@ -96,6 +101,9 @@ cmDspClass_t _cmKrDC; cmDspSetDefaultDouble( ctx,&p->inst, kUprSlopeKrId, 0, 0.0 ); cmDspSetDefaultDouble( ctx,&p->inst, kOffsetKrId, 0, 30.0); cmDspSetDefaultUInt( ctx,&p->inst, kInvertKrId, 0, 0 ); + cmDspSetDefaultUInt( ctx,&p->inst, kBypassKrId, 0, 0 ); + cmDspSetDefaultSample( ctx,&p->inst, kWetKrId, 0, 1.0); + //_cmDspKrCmInit(ctx,p); // initialize the cm library p->ctx = cmCtxAlloc(NULL,ctx->rpt,ctx->lhH,ctx->stH); @@ -122,9 +130,10 @@ cmDspRC_t _cmDspKrSetup(cmDspCtx_t* ctx, cmDspKr_t* p ) cmDspRC_t rc = kOkDspRC; unsigned wndSmpCnt = cmDspUInt(&p->inst,kWndSmpCntKrId); unsigned hopFact = cmDspUInt(&p->inst,kHopFactKrId); - unsigned olaWndTypeId = kHannWndId; + unsigned olaWndTypeId =kHannWndId; cmSpecDistFree(&p->sdp); + p->sdp = cmSpecDistAlloc(p->ctx, NULL, cmDspSamplesPerCycle(ctx), cmDspSampleRate(ctx), wndSmpCnt, hopFact, olaWndTypeId); assert(p->sdp != NULL ); @@ -165,11 +174,18 @@ cmDspRC_t _cmDspKrExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt unsigned oSmpCnt = cmDspVarRows(inst,kAudioOutKrId); const cmSample_t* sp; + cmSample_t wet = cmDspSample(inst,kWetKrId); + cmSpecDistExec(p->sdp,ip,iSmpCnt); if((sp = cmSpecDistOut(p->sdp)) != NULL ) - cmVOS_Copy(op,oSmpCnt,sp); - + { + cmVOS_MultVVS(op,oSmpCnt,sp,wet); + } + + if( wet<1.0 ) + cmVOS_MultSumVVS(op,oSmpCnt,ip,1.0-wet); + return rc; } @@ -178,6 +194,7 @@ cmDspRC_t _cmDspKrRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt cmDspKr_t* p = (cmDspKr_t*)inst; cmDspRC_t rc = kOkDspRC; + cmDspSetEvent(ctx,inst,evt); switch( evt->dstVarId ) @@ -185,6 +202,22 @@ cmDspRC_t _cmDspKrRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt case kWndSmpCntKrId: case kHopFactKrId: _cmDspKrSetup(ctx,p); + + // THIS IS A HACK + // WHEN WND OR HOP CHANGE THE RESULTING CHANGES + // SHOULD BE ISOLATED IN cmSpecDist() AND THE + // CURRENT STATE OF THE PARAMETERS SHOULD NOT BE + // LOST - IF THE CHANGES WERE ISOLATED WITHIN PVANL + // AND PVSYN IT MIGHT BE POSSIBLE TO DO WITH + // MINIMAL AUDIO INTERUPTION. + + p->sdp->mode = cmDspUInt(inst,kModeKrId); + p->sdp->thresh = cmDspDouble(inst,kThreshKrId); + p->sdp->uprSlope = cmDspDouble(inst,kUprSlopeKrId); + p->sdp->lwrSlope = cmDspDouble(inst,kLwrSlopeKrId); + p->sdp->offset = cmDspDouble(inst,kOffsetKrId); + p->sdp->invertFl = cmDspUInt(inst,kInvertKrId)!=0; + printf("wsn:%i hsn:%i\n",p->sdp->wndSmpCnt,p->sdp->hopSmpCnt); break; @@ -195,16 +228,17 @@ cmDspRC_t _cmDspKrRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt case kThreshKrId: p->sdp->thresh = cmDspDouble(inst,kThreshKrId); + //printf("thr:p:%p sdp:%p %f\n",p,p->sdp,p->sdp->thresh); break; case kUprSlopeKrId: p->sdp->uprSlope = cmDspDouble(inst,kUprSlopeKrId); - printf("upr slope:%f\n",p->sdp->uprSlope); + //printf("upr slope:%f\n",p->sdp->uprSlope); break; case kLwrSlopeKrId: p->sdp->lwrSlope = cmDspDouble(inst,kLwrSlopeKrId); - printf("upr slope:%f\n",p->sdp->lwrSlope); + //printf("upr slope:%f\n",p->sdp->lwrSlope); break; case kOffsetKrId: @@ -215,6 +249,9 @@ cmDspRC_t _cmDspKrRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt p->sdp->invertFl = cmDspUInt(inst,kInvertKrId)!=0; break; + case kWetKrId: + break; + default: { assert(0); } } @@ -517,7 +554,7 @@ cmDspRC_t _cmDspScoreReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* } if((tlFn = cmDspStrcz(inst, kFnScId )) != NULL ) - if( cmScoreInitialize(ctx->cmCtx, &p->scH, tlFn, cmDspSampleRate(ctx), dynRefArray, dynRefCnt, _cmDspScoreCb, p ) != kOkTlRC ) + if( cmScoreInitialize(ctx->cmCtx, &p->scH, tlFn, cmDspSampleRate(ctx), dynRefArray, dynRefCnt, _cmDspScoreCb, p, cmSymTblNullHandle ) != kOkTlRC ) rc = cmErrMsg(&inst->classPtr->err, kInstResetFailDspRC, "Score file open failed."); errLabel: @@ -822,7 +859,9 @@ enum kOutSfId, kDynSfId, kEvenSfId, - kTempoSfId + kTempoSfId, + kCostSfId, + kSymSfId }; cmDspClass_t _cmScFolDC; @@ -864,6 +903,8 @@ cmDspInst_t* _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned { "dyn", kDynSfId, 0, 0, kOutDsvFl| kDoubleDsvFl, "Dynamic value."}, { "even", kEvenSfId, 0, 0, kOutDsvFl| kDoubleDsvFl, "Evenness value."}, { "tempo", kTempoSfId, 0, 0, kOutDsvFl| kDoubleDsvFl, "Tempo value."}, + { "cost", kCostSfId, 0, 0, kOutDsvFl| kDoubleDsvFl, "Match cost value."}, + { "sym", kSymSfId, 0, 0, kOutDsvFl| kSymDsvFl, "Symbol associated with a global variable which has changed value."}, { NULL, 0, 0, 0, 0, NULL } }; @@ -886,6 +927,7 @@ cmDspInst_t* _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned cmDspSetDefaultDouble( ctx, &p->inst, kDynSfId, 0, 0); cmDspSetDefaultDouble( ctx, &p->inst, kEvenSfId, 0, 0); cmDspSetDefaultDouble( ctx, &p->inst, kTempoSfId, 0, 0); + cmDspSetDefaultDouble( ctx, &p->inst, kCostSfId, 0, 0); cmDspSetDefaultSymbol(ctx,&p->inst, kCmdSfId, p->quietSymId ); @@ -916,6 +958,7 @@ void _cmScFolMatcherCb( cmScMatcher* p, void* arg, cmScMatcherResult_t* rp ) unsigned i; for(i=ap->sfp->smp->vsi; isfp->smp->nsi; ++i) { + switch( ap->sfp->smp->set[i].sp->varId ) { case kEvenVarScId: @@ -933,6 +976,26 @@ void _cmScFolMatcherCb( cmScMatcher* p, void* arg, cmScMatcherResult_t* rp ) default: { assert(0); } } + + cmDspSetDouble(ap->ctx,inst,kCostSfId,ap->sfp->smp->set[i].match_cost); + + + // Set the values in the global variable storage + cmDspValue_t vv,cv; + unsigned j; + 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 ); + cmDspStoreSetValueViaSym(ap->ctx->dsH, ap->sfp->smp->set[i].sp->costSymArray[j], &cv ); + + cmDspSetSymbol(ap->ctx,inst,kSymSfId,ap->sfp->smp->set[i].sp->symArray[j]); + cmDspSetSymbol(ap->ctx,inst,kSymSfId,ap->sfp->smp->set[i].sp->costSymArray[j]); + } + + } /* @@ -957,7 +1020,7 @@ cmDspRC_t _cmDspScFolOpenScore( cmDspCtx_t* ctx, cmDspInst_t* inst ) if((fn = cmDspStrcz(inst,kFnSfId)) == NULL || strlen(fn)==0 ) return cmErrMsg(&inst->classPtr->err, kInvalidArgDspRC, "No score file name supplied."); - if( cmScoreInitialize(ctx->cmCtx, &p->scH, fn, cmDspSampleRate(ctx), NULL, 0, NULL, NULL ) != kOkScRC ) + if( cmScoreInitialize(ctx->cmCtx, &p->scH, fn, cmDspSampleRate(ctx), NULL, 0, NULL, NULL, ctx->stH ) != kOkScRC ) return cmErrMsg(&inst->classPtr->err, kSubSysFailDspRC, "Unable to open the score '%s'.",fn); if( cmScoreIsValid(p->scH) ) @@ -1070,7 +1133,9 @@ struct cmDspClass_str* cmScFolClassCons( cmDspCtx_t* ctx ) enum { - kScLocIdxMdId + kScLocIdxMdId, + kResetIdxMdId, + kCmdMdId }; cmDspClass_t _cmModulatorDC; @@ -1080,6 +1145,10 @@ typedef struct cmDspInst_t inst; cmScModulator* mp; cmDspCtx_t* tmp_ctx; // used to temporarily hold the current cmDspCtx during callback + cmChar_t* fn; + cmChar_t* modLabel; + unsigned onSymId; + unsigned offSymId; } cmDspScMod_t; void _cmDspScModCb( void* arg, unsigned varSymId, double value ) @@ -1101,7 +1170,9 @@ cmDspInst_t* _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned cmDspVarArg_t args[] = { - { "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."}, + { "cmd", kCmdMdId, 0,0, kInDsvFl | kSymDsvFl | kOptArgDsvFl, "on | off."}, { NULL, 0, 0, 0, 0 } }; @@ -1116,6 +1187,8 @@ cmDspInst_t* _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned const cmChar_t* fn = va_arg(vl1,const cmChar_t*); const cmChar_t* modLabel = va_arg(vl1,const cmChar_t*); + va_end(vl1); + // validate the file if( fn==NULL || cmFsIsFile(fn)==false ) { @@ -1131,8 +1204,8 @@ cmDspInst_t* _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned cmDspClassErr(ctx,classPtr,kInvalidArgDspRC,"The internal modulator object initialization failed."); return NULL; } - unsigned fixArgCnt = 1; - unsigned argCnt = fixArgCnt + cmScModulatorVarCount(mp); + unsigned fixArgCnt = sizeof(args)/sizeof(args[0]) - 1; + unsigned argCnt = fixArgCnt + cmScModulatorOutVarCount(mp); cmDspVarArg_t a[ argCnt+1 ]; unsigned i; @@ -1141,7 +1214,7 @@ cmDspInst_t* _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned for(i=fixArgCnt; istH, vp->varSymId ); const cmChar_t* docStr = cmTsPrintfS("Variable output for %s",label); @@ -1149,13 +1222,21 @@ cmDspInst_t* _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned } cmDspArgSetupNull(a+argCnt); // set terminating arg. flags - cmDspScMod_t* p = cmDspInstAlloc(cmDspScMod_t,ctx,classPtr,a,instSymId,id,storeSymId,0,vl); + 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->mp = mp; mp->cbArg = p; // set the modulator callback arg - cmDspSetDefaultUInt(ctx,&p->inst,kScLocIdxMdId,0,0); + + cmDspSetDefaultUInt(ctx,&p->inst,kScLocIdxMdId,0,0); + cmDspSetDefaultSymbol(ctx,&p->inst,kCmdMdId,p->offSymId); return &p->inst; } @@ -1164,9 +1245,12 @@ cmDspRC_t _cmDspScModFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* cmDspRC_t rc = kOkDspRC; cmDspScMod_t* p = (cmDspScMod_t*)inst; + if( cmScModulatorFree(&p->mp) != kOkTlRC ) return cmErrMsg(&inst->classPtr->err, kInstFinalFailDspRC, "Modulator release failed."); + cmMemFree(p->fn); + cmMemFree(p->modLabel); return rc; } @@ -1182,8 +1266,25 @@ cmDspRC_t _cmDspScModReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* cmDspRC_t _cmDspScModRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) { + cmDspScMod_t* p = (cmDspScMod_t*)inst; cmDspSetEvent(ctx,inst,evt); + + switch( evt->dstVarId ) + { + case kResetIdxMdId: + cmDspSetUInt(ctx,inst,kScLocIdxMdId,cmDspUInt(inst,kResetIdxMdId)); + break; + + case kCmdMdId: + { + unsigned symId = cmDspSymbol(inst,kCmdMdId); + if( symId == p->onSymId ) + cmScModulatorReset(p->mp, ctx->cmCtx, cmDspUInt(inst,kScLocIdxMdId)); + } + break; + + } return kOkDspRC; } @@ -1193,8 +1294,12 @@ cmDspRC_t _cmDspScModExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* cmDspRC_t rc = kOkDspRC; cmDspScMod_t* p = (cmDspScMod_t*)inst; - p->tmp_ctx = ctx; - cmScModulatorExec(p->mp,cmDspUInt(inst,kScLocIdxMdId)); + if( cmDspSymbol(inst,kCmdMdId) != p->offSymId ) + { + p->tmp_ctx = ctx; + cmScModulatorExec(p->mp,cmDspUInt(inst,kScLocIdxMdId)); + } + return rc; } @@ -1212,3 +1317,201 @@ struct cmDspClass_str* cmScModClassCons( cmDspCtx_t* ctx ) return &_cmModulatorDC; } + +//========================================================================================================================================== + +enum +{ + kInChCntGsId, + kOutGroupCntGsId, + kGroupSelIdxGsId, + kBaseInFloatGsId +}; + +cmDspClass_t _cmGSwitchDC; + +typedef struct +{ + cmDspInst_t inst; + + unsigned iChCnt; + unsigned oGroupCnt; + + unsigned baseInFloatGsId; + unsigned baseInSymGsId; + unsigned baseInBoolGsId; + + unsigned baseOutFloatGsId; + unsigned baseOutSymGsId; + unsigned baseOutBoolGsId; + +} cmDspGSwitch_t; + + +cmDspInst_t* _cmDspGSwitchAlloc(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); + + cmDspVarArg_t args[] = + { + { "ichs", kInChCntGsId, 0,0, kUIntDsvFl | kReqArgDsvFl, "Input channel count."}, + { "ochs", kOutGroupCntGsId, 0,0, kUIntDsvFl | kReqArgDsvFl, "Output group count."}, + { "sel", kGroupSelIdxGsId, 0,0, kInDsvFl | kUIntDsvFl, "Group select index."}, + { NULL, 0, 0, 0, 0 } + }; + + // validate the argument count + if( va_cnt != 2 ) + { + cmDspClassErr(ctx,classPtr,kInvalidArgDspRC,"The GSwitch requires at least two arguments."); + return NULL; + } + + // read the input ch and output group count + unsigned iChCnt = va_arg(vl1,unsigned); + unsigned oGroupCnt = va_arg(vl1,unsigned); + + va_end(vl1); + + // validate the channel counts + if( iChCnt == 0 || oGroupCnt==0 ) + { + cmDspClassErr(ctx,classPtr,kInvalidArgDspRC,"The GSwitch input channel count and group count must be greater than zero."); + return NULL; + } + + unsigned typeCnt = 3; // i.e. float,sym,bool + unsigned baseInFloatGsId = kBaseInFloatGsId; + unsigned baseInSymGsId = baseInFloatGsId + iChCnt; + unsigned baseInBoolGsId = baseInSymGsId + iChCnt; + unsigned baseOutFloatGsId = baseInBoolGsId + iChCnt; + unsigned baseOutSymGsId = baseOutFloatGsId + (iChCnt * oGroupCnt); + unsigned baseOutBoolGsId = baseOutSymGsId + (iChCnt * oGroupCnt); + + unsigned fixArgCnt = 3; + unsigned varArgCnt = (iChCnt * typeCnt) + (iChCnt * typeCnt * oGroupCnt); + unsigned argCnt = fixArgCnt + varArgCnt; + cmDspVarArg_t a[ argCnt+1 ]; + unsigned i; + + cmDspArgCopy( a, argCnt, 0, args, fixArgCnt ); + cmDspArgSetupN( ctx, a, argCnt, baseInFloatGsId, iChCnt, "f-in", baseInFloatGsId, 0, 0, kInDsvFl | kDoubleDsvFl, "Float input"); + cmDspArgSetupN( ctx, a, argCnt, baseInSymGsId, iChCnt, "s-in", baseInSymGsId, 0, 0, kInDsvFl | kSymDsvFl, "Symbol input"); + cmDspArgSetupN( ctx, a, argCnt, baseInBoolGsId, iChCnt, "b-in", baseInBoolGsId, 0, 0, kInDsvFl | kBoolDsvFl, "Bool input"); + + unsigned labelCharCnt = 63; + cmChar_t label[labelCharCnt+1]; + label[labelCharCnt] = 0; + + unsigned gsid = baseOutFloatGsId; + for(i=0; iiChCnt = iChCnt; + p->oGroupCnt = oGroupCnt; + p->baseInFloatGsId = baseInFloatGsId; + p->baseInSymGsId = baseInSymGsId; + p->baseInBoolGsId = baseInBoolGsId; + p->baseOutFloatGsId = baseOutFloatGsId; + p->baseOutSymGsId = baseOutSymGsId; + p->baseOutBoolGsId = baseOutBoolGsId; + + cmDspSetDefaultUInt(ctx,&p->inst,kGroupSelIdxGsId,0,0); + + return &p->inst; +} + +cmDspRC_t _cmDspGSwitchReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) +{ + cmDspRC_t rc = kOkDspRC; + + cmDspApplyAllDefaults(ctx,inst); + + return rc; +} + +cmDspRC_t _cmDspGSwitchRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) +{ + cmDspRC_t rc = kOkDspRC; + cmDspGSwitch_t* p = (cmDspGSwitch_t*)inst; + + // if this is the group selector + if( evt->dstVarId == kGroupSelIdxGsId ) + { + unsigned idx; + if( (idx = cmDsvGetUInt(evt->valuePtr)) > p->oGroupCnt ) + cmDspInstErr(ctx,inst,kInvalidArgDspRC,"The GSwitch group select index %i is out of range %i.",idx,p->oGroupCnt); + else + cmDspSetEvent(ctx,inst,evt); + return rc; + } + + // get the group selector + unsigned groupIdx = cmDspUInt(inst,kGroupSelIdxGsId); + assert( groupIdx < p->oGroupCnt); + + + // if this is a float input + if( p->baseInFloatGsId <= evt->dstVarId && evt->dstVarId < p->baseInFloatGsId + p->iChCnt ) + { + unsigned outVarId = p->baseOutFloatGsId + (groupIdx * p->iChCnt) + (evt->dstVarId - p->baseInFloatGsId); + cmDspValueSet(ctx, inst, outVarId, evt->valuePtr, 0 ); + return rc; + } + + // if this is a symbol input + if( p->baseInSymGsId <= evt->dstVarId && evt->dstVarId < p->baseInSymGsId + p->iChCnt ) + { + unsigned outVarId = p->baseOutSymGsId + (groupIdx * p->iChCnt) + (evt->dstVarId - p->baseInSymGsId); + cmDspValueSet(ctx, inst, outVarId, evt->valuePtr, 0 ); + return rc; + } + + // if this is a bool input + if( p->baseInBoolGsId <= evt->dstVarId && evt->dstVarId < p->baseInBoolGsId + p->iChCnt ) + { + unsigned outVarId = p->baseOutBoolGsId + (groupIdx * p->iChCnt) + (evt->dstVarId - p->baseInBoolGsId); + cmDspValueSet(ctx, inst, outVarId, evt->valuePtr, 0 ); + return rc; + } + + return rc; +} + + +struct cmDspClass_str* cmGSwitchClassCons( cmDspCtx_t* ctx ) +{ + cmDspClassSetup(&_cmGSwitchDC,ctx,"GSwitch", + NULL, + _cmDspGSwitchAlloc, + NULL, + _cmDspGSwitchReset, + NULL, + _cmDspGSwitchRecv, + NULL,NULL, + "Ganged switch."); + + return &_cmGSwitchDC; +} diff --git a/dsp/cmDspKr.h b/dsp/cmDspKr.h index b933342..09e46c9 100644 --- a/dsp/cmDspKr.h +++ b/dsp/cmDspKr.h @@ -11,6 +11,7 @@ extern "C" { struct cmDspClass_str* cmMidiFilePlayClassCons( cmDspCtx_t* ctx ); struct cmDspClass_str* cmScFolClassCons( cmDspCtx_t* ctx ); struct cmDspClass_str* cmScModClassCons( cmDspCtx_t* ctx ); + struct cmDspClass_str* cmGSwitchClassCons( cmDspCtx_t* ctx ); #ifdef __cplusplus } diff --git a/dsp/cmDspNet.c b/dsp/cmDspNet.c index cfa1f44..49a5e0a 100644 --- a/dsp/cmDspNet.c +++ b/dsp/cmDspNet.c @@ -20,6 +20,7 @@ #include "cmProcObj.h" #include "cmDspCtx.h" #include "cmDspClass.h" +#include "cmDspStore.h" #include "cmDspSys.h" #include "cmDspPreset.h" #include "cmDspNet.h" diff --git a/dsp/cmDspNet.h b/dsp/cmDspNet.h index 70e2026..dfa7d17 100644 --- a/dsp/cmDspNet.h +++ b/dsp/cmDspNet.h @@ -62,6 +62,7 @@ extern "C" { cmDspCtx_t ctx; cmLHeapH_t lhH; // DSP system lHeap used for system memory (DSP instance memory uses ctx->lhH so that it can be removed independent of the DSP system memory) cmSymTblH_t stH; // DSP system symbol table (holds class based symbols) (DSP instances use ctx->stH) + cmDspStoreH_t dsH; // DSP system global variable storate table cmJsonH_t jsH; // DSP json for use by the system const cmChar_t* rsrcFn; // name of the JSON file containing resource specific resource _cmDspClass_t* classList; diff --git a/dsp/cmDspPgm.c b/dsp/cmDspPgm.c index f0d34d1..61aa51f 100644 --- a/dsp/cmDspPgm.c +++ b/dsp/cmDspPgm.c @@ -2366,6 +2366,7 @@ cmDspRC_t _cmDspSysPgm_AvailCh( cmDspSysH_t h, void** userPtrPtr ) _cmDspSysPgm_t _cmDspSysPgmArray[] = { { "time_line", _cmDspSysPgm_TimeLine, NULL, NULL }, + { "switcher", _cmDspSysPgm_Switcher, NULL, NULL }, { "main", _cmDspSysPgm_Main, NULL, NULL }, { "array", _cmDspSysPgm_Array, NULL, NULL }, { "line", _cmDspSysPgm_Line, NULL, NULL }, diff --git a/dsp/cmDspPgmKr.c b/dsp/cmDspPgmKr.c index 1c1af53..915d82f 100644 --- a/dsp/cmDspPgmKr.c +++ b/dsp/cmDspPgmKr.c @@ -64,11 +64,14 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmCtx_t* cmCtx = cmDspSysPgmCtx(h); cmErr_t err; krRsrc_t r; - unsigned wtLoopCnt = 1; // 1=play once (-1=loop forever) + unsigned wtLoopCnt = 1; // 1=play once (-1=loop forever) unsigned wtInitMode = 0; // initial wt mode is 'silence' unsigned wtSmpCnt = floor(cmDspSysSampleRate(h)); // wt length == srate int krWndSmpCnt = 2048; int krHopFact = 4; + unsigned xfadOutChCnt = 2; + double xfadMs = 200; + bool xfadAllOnFl = true; memset(&r,0,sizeof(r)); cmErrSetup(&err,&cmCtx->rpt,"Kr Timeline"); @@ -83,11 +86,15 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspInst_t* pts = cmDspSysAllocInst(h,"PortToSym", NULL, 2, "on", "off" ); cmDspInst_t* mfp = cmDspSysAllocInst(h,"MidiFilePlay",NULL, 0 ); cmDspInst_t* sfp = cmDspSysAllocInst(h,"ScFol", NULL, 1, r.scFn ); + cmDspInst_t* modp = cmDspSysAllocInst(h,"ScMod", NULL, 2, r.modFn, "m1" ); cmDspInst_t* kr0p = cmDspSysAllocInst(h,"Kr", NULL, 2, krWndSmpCnt, krHopFact ); cmDspInst_t* kr1p = cmDspSysAllocInst(h,"Kr", NULL, 2, krWndSmpCnt, krHopFact ); + cmDspInst_t* xfad = cmDspSysAllocInst(h,"Xfader", NULL, 3, xfadOutChCnt, xfadMs, xfadAllOnFl ); + cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 0 ); cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 1 ); + //cmDspInst_t* af0p = cmDspSysAllocInst(h,"AudioFileOut",NULL, 2, "/home/kevin/temp/debug0.wav",1); cmDspSysNewPage(h,"Controls"); cmDspInst_t* onb = cmDspSysAllocInst(h,"Button", "start", 2, kButtonDuiId, 1.0 ); @@ -109,6 +116,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspInst_t* ls0p = cmDspSysAllocInst(h,"Scalar", "lwr slope", 5, kNumberDuiId, 0.3, 10.0, 0.01, 2.0 ); cmDspInst_t* of0p = cmDspSysAllocInst(h,"Scalar", "offset", 5, kNumberDuiId, 0.0, 100.0, 0.01, 30.0 ); cmDspInst_t* iv0p = cmDspSysAllocInst(h,"Scalar", "invert", 5, kNumberDuiId, 0.0, 1.0, 1.0, 0.0 ); + cmDspInst_t* wet0 = cmDspSysAllocInst(h,"Scalar", "wet", 5, kNumberDuiId, 0.0, 1.0,0.001, 1.0 ); cmDspSysNewColumn(h,0); //cmDspInst_t* al1p = cmDspSysAllocInst(h,"MsgList","audFiles", 2, "audFiles",NULL); @@ -122,20 +130,37 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspInst_t* ls1p = cmDspSysAllocInst(h,"Scalar", "lwr slope1", 5, kNumberDuiId, 0.3, 10.0, 0.01, 2.0 ); cmDspInst_t* of1p = cmDspSysAllocInst(h,"Scalar", "offset1", 5, kNumberDuiId, 0.0, 100.0, 0.01, 30.0 ); cmDspInst_t* iv1p = cmDspSysAllocInst(h,"Scalar", "invert1", 5, kNumberDuiId, 0.0, 1.0, 1.0, 0.0 ); + cmDspInst_t* wet1 = cmDspSysAllocInst(h,"Scalar", "wet1", 5, kNumberDuiId, 0.0, 1.0,0.001, 1.0 ); + + cmDspSysNewColumn(h,0); + cmDspInst_t* ogain = cmDspSysAllocInst(h,"Scalar", "Out Gain", 5, kNumberDuiId, 0.0, 10.0,0.01, 3.0 ); + //cmDspInst_t* reload = cmDspSysAllocInst(h,"Button", "Reload", 2, kButtonDuiId, 0.0 ); if((rc = cmDspSysLastRC(h)) != kOkDspRC ) return rc; // phasor->wt->aout - cmDspSysConnectAudio(h, php, "out", wtp, "phs" ); // phs -> wt - //cmDspSysConnectAudio(h, wtp, "out", kr0p, "in" ); // wt->kr - //cmDspSysConnectAudio(h, wtp, "out", kr1p, "in" ); - //cmDspSysConnectAudio(h, kr0p, "out", ao0p, "in"); // kr->aout- 0 - //cmDspSysConnectAudio(h, kr1p, "out", ao1p, "in"); - cmDspSysConnectAudio(h, wtp, "out", ao0p, "in" ); // wt -> aout0 - cmDspSysConnectAudio(h, wtp, "out", ao1p, "in" ); // wt -> aout1 + cmDspSysConnectAudio(h, php, "out", wtp, "phs" ); // phs -> wt + + if(1) + { + cmDspSysConnectAudio(h, wtp, "out", kr0p, "in" ); // wt->kr + cmDspSysConnectAudio(h, wtp, "out", kr1p, "in" ); + cmDspSysConnectAudio(h, kr0p, "out", xfad, "in-0"); // kr->aout + cmDspSysConnectAudio(h, kr1p, "out", xfad, "in-1"); + cmDspSysConnectAudio(h, xfad, "out-0", ao0p, "in"); // kr->aout + cmDspSysConnectAudio(h, xfad, "out-1", ao1p, "in"); + } + else + { + cmDspSysConnectAudio(h, wtp, "out", ao0p, "in" ); // wt -> aout0 + cmDspSysConnectAudio(h, wtp, "out", ao1p, "in" ); // wt -> aout1 + //cmDspSysConnectAudio(h, wtp, "out", af0p, "in0" ); // wt -> audio file + } + + // wave-table to time-line cursor cmDspSysInstallCb( h, wtp, "fidx",tlp, "curs", NULL); // start connections @@ -144,6 +169,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspSysInstallCb(h, onb, "sym", mfp, "sel", NULL ); cmDspSysInstallCb(h, onb, "sym", pts, "on", NULL ); cmDspSysInstallCb(h, pts, "on", wtp, "cmd", NULL ); + cmDspSysInstallCb(h, pts, "on", modp,"cmd", NULL ); // stop connections cmDspSysInstallCb(h, wtp, "done",offb,"in", NULL ); // 'done' from WT simulates pressing Stop btn. @@ -151,6 +177,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspSysInstallCb(h, offb, "sym", mfp, "sel", NULL ); cmDspSysInstallCb(h, offb, "sym", pts, "off", NULL ); cmDspSysInstallCb(h, pts, "off", wtp, "cmd", NULL ); + cmDspSysInstallCb(h, pts, "off", modp,"cmd", NULL ); // time-line to wave-table selection cmDspSysInstallCb(h, tlp, "absi", wtp, "beg", NULL ); @@ -161,25 +188,32 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspSysInstallCb(h, tlp, "mbsi", mfp, "bsi", NULL ); cmDspSysInstallCb(h, tlp, "mesi", mfp, "esi", NULL ); cmDspSysInstallCb(h, tlp, "mfn", mfp, "fn", NULL ); - // score to score follower - to set initial search location cmDspSysInstallCb(h, scp, "sel", sfp, "index", NULL ); + //cmDspSysInstallCb(h, scp, "sel", prv, "in", NULL ); + cmDspSysInstallCb(h, scp, "sel", modp,"reset", NULL ); - - // MIDI file player to score-follower and score - the order of connections is the same - // as the msg transmision order from MFP - //cmDspSysInstallCb(h, mfp, "smpidx", scp, "smpidx", NULL ); - cmDspSysInstallCb(h, mfp, "smpidx", sfp, "smpidx", NULL ); - //cmDspSysInstallCb(h, mfp, "d1", scp, "d1", NULL ); - cmDspSysInstallCb(h, mfp, "d1", sfp, "d1", NULL ); - //cmDspSysInstallCb(h, mfp, "d0", scp, "d0", NULL ); - cmDspSysInstallCb(h, mfp, "d0", sfp, "d0", NULL ); - //cmDspSysInstallCb(h, mfp, "status", scp, "status", NULL ); - cmDspSysInstallCb(h, mfp, "status", sfp, "status", NULL ); + //cmDspSysInstallCb(h, reload,"out", modp, "reload", NULL ); - // score follower to score - //cmDspSysInstallCb(h, sfp, "out", modp, "index", NULL ); + // MIDI file play er to score follower + if(1) + { + cmDspSysInstallCb(h, mfp, "smpidx", sfp, "smpidx", NULL ); + cmDspSysInstallCb(h, mfp, "d1", sfp, "d1", NULL ); + cmDspSysInstallCb(h, mfp, "d0", sfp, "d0", NULL ); + cmDspSysInstallCb(h, mfp, "status", sfp, "status", NULL ); + } + + // score follower to modulator and printers + cmDspSysInstallCb(h, sfp, "out", modp, "index", NULL ); + cmDspSysInstallCb(h, sfp, "out", prp, "in", NULL ); + cmDspSysInstallCb(h, sfp, "even", pre, "in", NULL ); + cmDspSysInstallCb(h, sfp, "dyn", prd, "in", NULL ); + cmDspSysInstallCb(h, sfp, "tempo",prt, "in", NULL ); + + cmDspSysInstallCb(h, prtb, "sym", sfp, "cmd", NULL ); + cmDspSysInstallCb(h, qtb, "sym", sfp, "cmd", NULL ); cmDspSysInstallCb(h, ws0p, "out", kr0p, "wndn", NULL ); // wndSmpCnt->kr @@ -190,6 +224,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspSysInstallCb(h, us0p, "val", kr0p, "uprs", NULL ); // uprSlope->kr cmDspSysInstallCb(h, of0p, "val", kr0p, "offs", NULL ); // offset->kr cmDspSysInstallCb(h, iv0p, "val", kr0p, "invt", NULL ); // invert->kr + cmDspSysInstallCb(h, wet0, "val", kr0p, "wet", NULL ); // wet->kr cmDspSysInstallCb(h, ws1p, "out", kr1p, "wndn", NULL ); // wndSmpCnt->kr cmDspSysInstallCb(h, hf1p, "out", kr1p, "hopf", NULL ); // hopFact->kr @@ -199,23 +234,134 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspSysInstallCb(h, us1p, "val", kr1p, "uprs", NULL ); // uprSlope->kr cmDspSysInstallCb(h, of1p, "val", kr1p, "offs", NULL ); // offset->kr cmDspSysInstallCb(h, iv1p, "val", kr1p, "invt", NULL ); // invert->kr + cmDspSysInstallCb(h, wet1, "val", kr1p, "wet", NULL ); // wet->kr + + cmDspSysInstallCb(h, ogain, "val", ao0p, "gain", NULL ); // output gain control + cmDspSysInstallCb(h, ogain, "val", ao1p, "gain", NULL ); // Printer connections cmDspSysInstallCb(h, tlp, "afn", prp, "in", NULL ); cmDspSysInstallCb(h, tlp, "mfn", prp, "in", NULL ); cmDspSysInstallCb(h, tlp, "sel", prp, "in", NULL ); - cmDspSysInstallCb(h, sfp, "out", prp, "in", NULL ); - cmDspSysInstallCb(h, sfp, "even", pre, "in", NULL ); - cmDspSysInstallCb(h, sfp, "dyn", prd, "in", NULL ); - cmDspSysInstallCb(h, sfp, "tempo",prt, "in", NULL ); - //cmDspSysInstallCb(h, modp,"v0", prv, "in", NULL ); - //cmDspSysInstallCb(h, modp,"v1", prv, "in", NULL ); - //cmDspSysInstallCb(h, modp,"v2", prv, "in", NULL ); + cmDspSysInstallCb(h, modp, "mod0", md0p, "val", NULL ); + cmDspSysInstallCb(h, modp, "win0", kr0p, "wndn",NULL ); + cmDspSysInstallCb(h, modp, "thr0", th0p, "val", NULL ); + cmDspSysInstallCb(h, modp, "upr0", us0p, "val", NULL ); + cmDspSysInstallCb(h, modp, "lwr0", ls0p, "val", NULL ); + cmDspSysInstallCb(h, modp, "off0", of0p, "val", NULL ); + cmDspSysInstallCb(h, modp, "inv0", iv0p, "val", NULL ); + cmDspSysInstallCb(h, modp, "wet0", wet0, "val", NULL ); + cmDspSysInstallCb(h, modp, "xf0", xfad, "gate-0", NULL ); + cmDspSysInstallCb(h, modp, "mod1", md1p, "val", NULL ); + cmDspSysInstallCb(h, modp, "win1", kr1p, "wndn",NULL ); + cmDspSysInstallCb(h, modp, "thr1", th1p, "val", NULL ); + cmDspSysInstallCb(h, modp, "upr1", us1p, "val", NULL ); + cmDspSysInstallCb(h, modp, "lwr1", ls1p, "val", NULL ); + cmDspSysInstallCb(h, modp, "off1", of1p, "val", NULL ); + cmDspSysInstallCb(h, modp, "inv1", iv1p, "val", NULL ); + cmDspSysInstallCb(h, modp, "wet1", wet1, "val", NULL ); + cmDspSysInstallCb(h, modp, "xf1", xfad, "gate-1", NULL ); - cmDspSysInstallCb(h, prtb, "sym", sfp, "cmd", NULL ); - cmDspSysInstallCb(h, qtb, "sym", sfp, "cmd", NULL ); return rc; } + +cmDspRC_t _cmDspSysPgm_Switcher(cmDspSysH_t h, void** userPtrPtr ) +{ + cmDspRC_t rc = kOkDspRC; + + const char* fn0 = "media/audio/20110723-Kriesberg/Audio Files/Piano 3_01.wav"; + const cmChar_t* fn = cmFsMakeFn(cmFsUserDir(),fn0,NULL,NULL ); + + bool bypassFl = false; + double inGain = 1.0; + double dsrate = 96000.0; + double bits = 24.0; + bool rectifyFl = false; + bool fullRectFl = false; + double clipDb = -10.0; + + double cfMinHz = 20.0; + double cfHz = 1000.0; + double cfAlpha = 0.9; + bool cfFbFl = true; + bool cfBypassFl = false; + + unsigned outChCnt = 2; + double xfadeMs = 250; + + + cmDspInst_t* gsw = cmDspSysAllocInst(h,"GSwitch", NULL, 2, 12,2 ); + + cmDspInst_t* ofp = cmDspSysAllocInst(h,"Scalar", "Offset", 5, kNumberDuiId, 0.0, cmDspSysSampleRate(h)*600.0, 1.0, 6900000.0); + cmDspInst_t* fnp = cmDspSysAllocInst(h,"Fname", NULL, 3, false,"Audio Files (*.wav,*.aiff,*.aif)\tAudio Files (*.{wav,aiff,aif})",fn); + cmDspInst_t* php = cmDspSysAllocInst(h,"Phasor", NULL, 0 ); + cmDspInst_t* wtp = cmDspSysAllocInst(h,"WaveTable",NULL, 2, ((int)cmDspSysSampleRate(h)), 1 ); + + cmDspInst_t* dst = cmDspSysAllocInst(h,"DistDs", NULL, 3, bypassFl, inGain, dsrate, bits ); + cmDspInst_t* cf = cmDspSysAllocInst( h,"CombFilt", NULL, 5, cfBypassFl, cfMinHz, cfFbFl, cfMinHz, cfAlpha ); + + cmDspInst_t* xfad = cmDspSysAllocInst(h,"Xfader", NULL, 2, outChCnt, xfadeMs ); + + + cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL, 1, 0 ); + cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL, 1, 1 ); + + + cmDspInst_t* ign = cmDspSysAllocScalar( h, "In Gain", 0.0, 10.0, 0.01, 1.0); + cmDspInst_t* rct = cmDspSysAllocCheck( h, "Rectify", rectifyFl); + cmDspInst_t* ful = cmDspSysAllocCheck( h, "Full/Half", fullRectFl); + cmDspInst_t* dsr = cmDspSysAllocScalar( h, "Srate", 0.0, 96000, 1.0, dsrate); + cmDspInst_t* dbt = cmDspSysAllocScalar( h, "bits", 2.0, 32.0, 1.0, bits); + cmDspInst_t* clip = cmDspSysAllocScalar( h, "Clip dB", -100.0, 0.0, 0.1, clipDb); + cmDspInst_t* ogn = cmDspSysAllocScalar( h, "Out Gain", 0.0, 10.0, 0.01, 1.0); + + cmDspInst_t* cfhz = cmDspSysAllocScalar( h, "CF Hz", 25, 10000, 1, cfHz ); + cmDspInst_t* cfalpha = cmDspSysAllocScalar( h, "CF Alpha", 0.0, 2.0, 0.001, cfAlpha); + cmDspInst_t* cfgain = cmDspSysAllocScalar( h, "CF Gain", 0.0, 20.0, 0.001, 1.0); + cmDspInst_t* cffb = cmDspSysAllocInst( h,"Button", "CF Fb", 2, kCheckDuiId, 0.0 ); + + cmDspInst_t* dfdb = cmDspSysAllocInst( h,"Button", "Dist Fade", 2, kCheckDuiId, 0.0 ); + cmDspInst_t* cfdb = cmDspSysAllocInst( h,"Button", "CF Fade", 2, kCheckDuiId, 0.0 ); + + + if((rc = cmDspSysLastRC(h)) != kOkDspRC ) + return rc; + + cmDspSysConnectAudio(h, php, "out", wtp, "phs" ); // phasor -> wave table + + cmDspSysConnectAudio(h, wtp, "out", dst, "in" ); // wt -> dist + cmDspSysConnectAudio(h, dst, "out", xfad, "in-0"); // dist -> xfad + cmDspSysConnectAudio(h, xfad,"out-0",ao0p, "in" ); // xfad -> aout + + cmDspSysConnectAudio(h, wtp, "out", cf, "in" ); // wt -> xfad + cmDspSysConnectAudio(h, cf, "out", xfad, "in-1"); // xfad -> cf + cmDspSysConnectAudio(h, xfad,"out-1",ao1p, "in" ); // cf -> aout + + cmDspSysInstallCb(h, ofp, "val", wtp, "beg", NULL ); // offset -> wavetable + cmDspSysInstallCb(h, fnp, "out", wtp, "fn", NULL); // filename -> wavetable + + + // Distortion control connections + cmDspSysInstallCb(h, ign, "val", dst, "igain", NULL ); + cmDspSysInstallCb(h, dsr, "val", dst, "srate", NULL ); + cmDspSysInstallCb(h, dbt, "val", dst, "bits", NULL ); + cmDspSysInstallCb(h, rct, "out", dst, "rect", NULL ); + cmDspSysInstallCb(h, ful, "out", dst, "full", NULL ); + cmDspSysInstallCb(h, clip, "val", dst, "clip", NULL ); + + cmDspSysInstallCb(h, ogn, "val", dst, "ogain", NULL ); + + cmDspSysInstallCb(h, cfhz, "val", cf, "hz", NULL ); + cmDspSysInstallCb(h, cfalpha, "val", cf, "alpha", NULL ); + cmDspSysInstallCb(h, cffb, "out", cf, "fb", NULL ); + cmDspSysInstallCb(h, cfgain, "val", ao1p, "gain", NULL ); + + cmDspSysInstallCb(h, dfdb, "out", xfad, "gate-0", NULL); + cmDspSysInstallCb(h, cfdb, "out", xfad, "gate-1", NULL); + + return cmDspSysLastRC(h); +} + diff --git a/dsp/cmDspPgmKr.h b/dsp/cmDspPgmKr.h index 401e538..1d4904a 100644 --- a/dsp/cmDspPgmKr.h +++ b/dsp/cmDspPgmKr.h @@ -6,6 +6,7 @@ extern "C" { #endif cmDspRC_t _cmDspSysPgm_TimeLine( cmDspSysH_t h, void** userPtrPtr ); + cmDspRC_t _cmDspSysPgm_Switcher( cmDspSysH_t h, void** userPtrPtr ); #ifdef __cplusplus } diff --git a/dsp/cmDspStore.c b/dsp/cmDspStore.c new file mode 100644 index 0000000..2019cdd --- /dev/null +++ b/dsp/cmDspStore.c @@ -0,0 +1,179 @@ +#include "cmPrefix.h" +#include "cmGlobal.h" +#include "cmFloatTypes.h" +#include "cmRpt.h" +#include "cmErr.h" +#include "cmCtx.h" +#include "cmMem.h" +#include "cmMallocDebug.h" +#include "cmLinkedHeap.h" +#include "cmSymTbl.h" +#include "cmJson.h" +#include "cmDspValue.h" +#include "cmDspCtx.h" +#include "cmDspClass.h" +#include "cmDspStore.h" + +typedef struct +{ + unsigned symId; + cmDspValue_t value; +} cmDspStoreVar_t; + +typedef struct +{ + cmErr_t err; + cmDspStoreVar_t* array; + unsigned allocCnt; + unsigned growCnt; + unsigned curCnt; +} cmDspStore_t; + + +cmDspStoreH_t cmDspStoreNullHandle = cmSTATIC_NULL_HANDLE; + +cmDspStore_t* _cmDspStoreHandleToPtr( cmDspStoreH_t h ) +{ + cmDspStore_t* p = (cmDspStore_t*)h.h; + assert( p != NULL ); + return p; +} + +cmDspRC_t _cmDspStoreFree( cmDspStore_t* p ) +{ + cmMemFree(p->array); + cmMemFree(p); + return kOkDspRC; +} + + +cmDspRC_t cmDspStoreAlloc( cmCtx_t* ctx, cmDspStoreH_t* hp, unsigned initStoreCnt, unsigned growStoreCnt ) +{ + cmDspRC_t rc; + if((rc = cmDspStoreFree(hp)) != kOkDspRC ) + return rc; + + cmDspStore_t* p = cmMemAllocZ(cmDspStore_t,1); + + cmErrSetup(&p->err,&ctx->rpt,"cmDspStore"); + + p->array = cmMemAllocZ(cmDspStoreVar_t,initStoreCnt); + p->allocCnt = initStoreCnt; + p->curCnt = 0; + p->growCnt = growStoreCnt; + + hp->h = p; + + return rc; +} + +cmDspRC_t cmDspStoreFree( cmDspStoreH_t *hp ) +{ + cmDspRC_t rc = kOkDspRC; + if(hp==NULL || cmDspStoreIsValid(*hp)==false ) + return rc; + + cmDspStore_t* p = _cmDspStoreHandleToPtr(*hp); + + if((rc = _cmDspStoreFree(p)) != kOkDspRC ) + return rc; + + hp->h = NULL; + + return rc; +} + +bool cmDspStoreIsValid( cmDspStoreH_t h ) +{ return h.h; } + + +cmDspStoreVar_t* _cmDspStoreSymToPtr( cmDspStore_t* p, unsigned symId ) +{ + cmDspStoreVar_t* vp = p->array; + cmDspStoreVar_t* ep = p->array + p->curCnt; + for(; vpsymId == symId ) + return vp; + return NULL; +} + +cmDspStoreVar_t* _cmDspStoreIdToPtr( cmDspStore_t* p, unsigned id ) +{ + if( id < p->curCnt ) + return p->array + id; + + return NULL; +} + +cmDspStoreVar_t* _cmDspStoreAppend( cmDspStore_t* p ) +{ + cmDspStoreVar_t* vp = NULL; + + if( p->curCnt >= p->allocCnt ) + { + p->allocCnt += p->growCnt; + p->array = cmMemResizePZ(cmDspStoreVar_t,p->array,p->allocCnt); + } + + vp = p->array + p->curCnt; + + p->curCnt += 1; + + return vp; +} + +unsigned cmDspStoreSymToId( cmDspStoreH_t h, unsigned symId ) +{ + cmDspStore_t* p = _cmDspStoreHandleToPtr(h); + const cmDspStoreVar_t* vp; + if((vp = _cmDspStoreSymToPtr(p,symId)) == NULL ) + return cmInvalidId; + return vp - p->array; +} + +unsigned cmDspStoreIdToSym( cmDspStoreH_t h, unsigned id ) +{ + cmDspStore_t* p = _cmDspStoreHandleToPtr(h); + const cmDspStoreVar_t* vp; + if((vp = _cmDspStoreIdToPtr(p,id)) == NULL ) + return cmInvalidId; + return vp->symId; +} + +const cmDspValue_t* cmDspStoreIdToValue( cmDspStoreH_t h, unsigned id ) +{ + cmDspStore_t* p = _cmDspStoreHandleToPtr(h); + const cmDspStoreVar_t* vp; + if((vp = _cmDspStoreIdToPtr(p,id)) == NULL ) + return NULL; + return &vp->value; +} + +cmDspRC_t cmDspStoreSetValueViaId( cmDspStoreH_t h, unsigned id, const cmDspValue_t* val ) +{ + cmDspRC_t rc = kOkDspRC; + cmDspStore_t* p = _cmDspStoreHandleToPtr(h); + cmDspStoreVar_t* vp = NULL; + + if((vp = _cmDspStoreIdToPtr(p,id)) == NULL ) + return cmErrMsg(&p->err,kVarNotFoundDspRC,"There is not global variable at with id:%i\n",id); + + cmDsvCopy(&vp->value,val); + return rc; +} + +unsigned cmDspStoreSetValueViaSym( cmDspStoreH_t h, unsigned symId, const cmDspValue_t* val ) +{ + cmDspStore_t* p = _cmDspStoreHandleToPtr(h); + cmDspStoreVar_t* vp = NULL; + + if((vp = _cmDspStoreSymToPtr(p,symId)) == NULL ) + vp = _cmDspStoreAppend(p); + + assert(vp != NULL ); + + cmDsvCopy(&vp->value,val); + vp->symId = symId; + + return vp - p->array; +} diff --git a/dsp/cmDspStore.h b/dsp/cmDspStore.h new file mode 100644 index 0000000..292c047 --- /dev/null +++ b/dsp/cmDspStore.h @@ -0,0 +1,30 @@ +#ifndef cmDspStore_h +#define cmDspStore_h + +#ifdef __cplusplus +extern "C" { +#endif + + extern cmDspStoreH_t cmDspStoreNullHandle; + + cmDspRC_t cmDspStoreAlloc( cmCtx_t* ctx, cmDspStoreH_t* hp, unsigned initStoreCnt, unsigned growStoreCnt ); + + cmDspRC_t cmDspStoreFree( cmDspStoreH_t *hp ); + + bool cmDspStoreIsValid( cmDspStoreH_t h ); + + unsigned cmDspStoreSymToId( cmDspStoreH_t h, unsigned symId ); + unsigned cmDspStoreIdToSym( cmDspStoreH_t h, unsigned id ); + const cmDspValue_t* cmDspStoreIdToValue( cmDspStoreH_t h, unsigned id ); + + cmDspRC_t cmDspStoreSetValueViaId( cmDspStoreH_t h, unsigned id, const cmDspValue_t* val ); + + // Sets the variable to the value (and creates it if it does not exist). + // Returns the 'id' of the variable. + unsigned cmDspStoreSetValueViaSym( cmDspStoreH_t h, unsigned symId, const cmDspValue_t* val ); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/dsp/cmDspSys.c b/dsp/cmDspSys.c index 06ee2a3..5d3fc73 100644 --- a/dsp/cmDspSys.c +++ b/dsp/cmDspSys.c @@ -21,6 +21,7 @@ #include "cmProcObj.h" #include "cmDspCtx.h" #include "cmDspClass.h" +#include "cmDspStore.h" #include "cmDspSys.h" #include "cmDspBuiltIn.h" #include "cmDspPgm.h" @@ -140,6 +141,8 @@ cmDspRC_t _cmDspSysFinalize( cmDsp_t* p ) if( cmCtxFree(&p->ctx.cmProcCtx) != cmOkRC ) rc = cmErrMsg(&p->err,kProcFailDspRC,"The proc context finalizatoin failed."); + cmDspStoreFree(&p->dsH); + if( cmSymTblIsValid(p->stH) ) cmSymTblDestroy(&p->stH); @@ -195,6 +198,13 @@ cmDspRC_t cmDspSysInitialize( cmCtx_t* ctx, cmDspSysH_t* hp, cmUdpNetH_t netH ) goto errLabel; } + // allocate the DSP system variable storage object + if( cmDspStoreAlloc(ctx,&p->dsH,10,10) != kOkDspRC ) + { + rc = cmErrMsg(&p->err,kDspStoreFailDspRC,"DSP store allocation failed."); + goto errLabel; + } + // initialize the proc context if( (p->ctx.cmProcCtx = cmCtxAlloc(NULL,&ctx->rpt,p->lhH,p->stH)) == NULL ) { @@ -214,6 +224,7 @@ cmDspRC_t cmDspSysInitialize( cmCtx_t* ctx, cmDspSysH_t* hp, cmUdpNetH_t netH ) p->ctx.lhH = p->lhH; p->ctx.jsH = p->jsH; p->ctx.stH = p->stH; + p->ctx.dsH = p->dsH; p->ctx.rsrcJsH = cmJsonNullHandle; p->ctx.rpt = &ctx->rpt; p->ctx.cmCtx = &p->cmCtx;