diff --git a/Makefile.am b/Makefile.am index 12c1567..71ad803 100644 --- a/Makefile.am +++ b/Makefile.am @@ -77,8 +77,8 @@ cmSRC += src/libcm/cmProcObj.c src/libcm/cmProc.c src/libcm/cmProc2.c src/libcm/ cmHDR += src/libcm/app/cmOnset.h src/libcm/app/cmTimeLine.h src/libcm/app/cmScore.h src/libcm/app/cmScoreProc.h cmSRC += src/libcm/app/cmOnset.c src/libcm/app/cmTimeLine.c src/libcm/app/cmScore.c src/libcm/app/cmScoreProc.c -cmHDR += src/libcm/app/cmSdb.h src/libcm/app/cmTakeSeqBldr.h -cmSRC += src/libcm/app/cmSdb.c src/libcm/app/cmTakeSeqBldr.c +cmHDR += src/libcm/app/cmSdb.h src/libcm/app/cmTakeSeqBldr.h src/libcm/app/cmDspPgmJsonToDot.h +cmSRC += src/libcm/app/cmSdb.c src/libcm/app/cmTakeSeqBldr.c src/libcm/app/cmDspPgmJsonToDot.c cmHDR += src/libcm/app/cmPickup.h src/libcm/cmRbm.h src/libcm/cmTaskMgr.h src/libcm/cmSyncRecd.h cmSRC += src/libcm/app/cmPickup.c src/libcm/cmRbm.c src/libcm/cmTaskMgr.c src/libcm/cmSyncRecd.c diff --git a/app/cmDspPgmJsonToDot.c b/app/cmDspPgmJsonToDot.c new file mode 100644 index 0000000..d6c04e2 --- /dev/null +++ b/app/cmDspPgmJsonToDot.c @@ -0,0 +1,459 @@ +#include "cmPrefix.h" +#include "cmGlobal.h" +#include "cmFloatTypes.h" +#include "cmComplexTypes.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 "cmText.h" +#include "cmDspPgmJsonToDot.h" +#include "cmFile.h" +#include "cmFileSys.h" + +struct cmDotProc_str; + +typedef struct cmDotPort_str +{ + struct cmDotProc_str* proc; + cmChar_t* labelStr; + unsigned portNo; + unsigned connCnt; // count of connections to this port + struct cmDotPort_str* link; +} cmDotPort_t; + +typedef struct cmDotProc_str +{ + cmChar_t* classStr; + cmChar_t* instStr; + cmChar_t* outStr; + unsigned portCnt; + bool skipFl; + + cmDotPort_t* ports; + struct cmDotProc_str* link; +} cmDotProc_t; + +typedef struct cmDotConn_str +{ + cmDotPort_t* srcPort; // output + cmDotPort_t* dstPort; // input + bool skipFl; + struct cmDotConn_str* link; +} cmDotConn_t; + + +typedef struct cmDot_str +{ + cmErr_t err; + cmLHeapH_t lH; + cmDotProc_t* procs; + cmDotConn_t* conns; +} cmDot_t; + +typedef struct +{ + const cmChar_t* s0; + const cmChar_t* s1; +} cmDotSubst_t; + +cmDotSubst_t _cmDotSubstArray[] = +{ + { "Router", "Rtr" }, + { "Scalar", "Sc" }, + { "ScaleRange", "SR" }, + { "MsgList", "ML" }, + { "Button", "Btn" }, + { "PortToSym", "PtS" }, + { "1ofN", "lOfN"}, + { NULL, NULL } +}; + +const cmChar_t* _cmDotSkipClassArray[] = +{ + "Scalar", + NULL +}; + +void _cmDotReplaceDash( cmChar_t* str ) +{ + cmChar_t* s = str; + for(; *s; ++s ) + if( *s == '-' ) + *s = '_'; +} + +cmChar_t* _cmDotSubstitute( cmDot_t* p, const cmChar_t* label ) +{ + unsigned i; + cmChar_t* s = cmLhAllocStr(p->lH,label); + + for(i=0; _cmDotSubstArray[i].s0 != NULL; ++i) + { + unsigned n0 = cmTextLength(_cmDotSubstArray[i].s0); + + if( cmTextCmpN( _cmDotSubstArray[i].s0, s, n0 ) == 0 ) + { + unsigned n1 = cmTextLength(_cmDotSubstArray[i].s1); + assert(n0>=n1); + cmTextShrinkS(s,s+n1,n0-n1); + strncpy(s,_cmDotSubstArray[i].s1,n1); + } + } + + return s; +} + +bool _cmDotIsSkipClass( const cmChar_t* classStr ) +{ + unsigned i; + + for(i=0; _cmDotSkipClassArray[i]!=NULL; ++i) + if( cmTextCmp(_cmDotSkipClassArray[i],classStr) == 0 ) + return true; + + return false; +} + +cmDotPort_t* _cmDotFindPort( cmDotProc_t* proc, const cmChar_t* labelStr ) +{ + cmDotPort_t* port = proc->ports; + for(; port!=NULL; port=port->link) + if( cmTextCmp(port->labelStr,labelStr) == 0 ) + return port; + + return NULL; +} + +cmDotProc_t* _cmDotFindProc( cmDot_t* p, const cmChar_t* instStr ) +{ + cmDotProc_t* dp = p->procs; + for(; dp!=NULL; dp=dp->link) + if( cmTextCmp(dp->instStr,instStr) == 0 ) + return dp; + + return NULL; +} + +cmDotPort_t* _cmDotNewPort( cmDot_t* p, cmDotProc_t* proc, const cmChar_t* labelStr ) +{ + cmDotPort_t* port = NULL; + + if( labelStr==NULL || cmTextLength(labelStr)==0 ) + { + cmErrMsg(&p->err,kInvalidArgDotRC,"A blank port label was encountered."); + return NULL; + } + + if((port = _cmDotFindPort(proc,labelStr)) != NULL ) + return port; + + port = cmLhAllocZ(p->lH,cmDotPort_t,1); + + port->proc = proc; + port->labelStr = cmLhAllocStr(p->lH,labelStr); + port->portNo = proc->portCnt; + + proc->portCnt += 1; + + cmDotPort_t* p0 = NULL; + cmDotPort_t* p1 = proc->ports; + for(; p1!=NULL; p1=p1->link) + p0 = p1; + + if( p0 == NULL ) + proc->ports = port; + else + p0->link = port; + + return port; +} + +cmDotRC_t _cmDotNewConnection( cmDot_t* p, const cmChar_t* srcProcStr, const cmChar_t* srcPortStr, const cmChar_t* dstProcStr, const cmChar_t* dstPortStr ) +{ + cmDotRC_t rc = kOkDotRC; + cmDotProc_t* srcProc; + cmDotProc_t* dstProc; + cmDotPort_t* srcPort; + cmDotPort_t* dstPort; + cmDotConn_t* conn; + cmDotConn_t* c0 = NULL; + cmDotConn_t* c1 = p->conns; + + // find the source (output) proc + if((srcProc = _cmDotFindProc(p,srcProcStr)) == NULL ) + { + rc = cmErrMsg(&p->err,kInvalidArgDotRC,"The connection source proc instance '%s' could not be found.",cmStringNullGuard(srcProcStr)); + goto errLabel; + } + + + // find the dest (input) proc + if((dstProc = _cmDotFindProc(p,dstProcStr)) == NULL ) + { + rc = cmErrMsg(&p->err,kInvalidArgDotRC,"The connection destination proc instance '%s' could not be found.",cmStringNullGuard(dstProcStr)); + goto errLabel; + } + + // find the source port + if((srcPort = _cmDotNewPort(p,srcProc,srcPortStr)) == NULL ) + { + rc = cmErrMsg(&p->err,kInvalidArgDotRC,"The source port %s:%s could not be found or allocated.",cmStringNullGuard(srcProc->instStr),cmStringNullGuard(srcPortStr)); + goto errLabel; + } + + // find the dest port + if((dstPort = _cmDotNewPort(p,dstProc,dstPortStr)) == NULL ) + { + rc = cmErrMsg(&p->err,kInvalidArgDotRC,"The destination port %s:%s could not be found or allocated.",cmStringNullGuard(dstProc->instStr),cmStringNullGuard(dstPortStr)); + goto errLabel; + } + + conn = cmLhAllocZ(p->lH,cmDotConn_t,1); + + conn->srcPort = srcPort; + conn->dstPort = dstPort; + conn->skipFl = _cmDotIsSkipClass(srcProc->classStr) || _cmDotIsSkipClass(dstProc->classStr); + + // track the number of connections to each port + if( !conn->skipFl ) + { + conn->dstPort->connCnt += 1; + conn->srcPort->connCnt += 1; + } + + + // set c0 to point to the last connection record + for(; c1!=NULL; c1=c1->link) + c0 = c1; + + // make conn the last connection record + if( c0 == NULL ) + p->conns = conn; + else + c0->link = conn; + + errLabel: + return rc; +} + + +cmDotRC_t _cmDotNewProc( cmDot_t* p, const cmChar_t* classStr, const cmChar_t* instStr ) +{ + cmDotRC_t rc = kOkDotRC; + + if( instStr==NULL || cmTextLength(instStr)==0 ) + return cmErrMsg(&p->err,kInvalidArgDotRC,"A blank or NULL instance label was encountered."); + + if( _cmDotFindProc( p, instStr ) ) + return cmErrMsg(&p->err,kInvalidArgDotRC,"A duplicate processor instance was encountered ('%s').",instStr); + + cmDotProc_t* ndp = cmLhAllocZ(p->lH,cmDotProc_t,1); + + ndp->classStr = cmLhAllocStr(p->lH,classStr); + ndp->instStr = cmLhAllocStr(p->lH,instStr); + ndp->outStr = _cmDotSubstitute(p,instStr); + ndp->skipFl = _cmDotIsSkipClass(classStr); + + cmDotProc_t* d0p = NULL; + cmDotProc_t* d1p = p->procs; + + for(; d1p!=NULL; d1p=d1p->link ) + d0p = d1p; + + if( d0p == NULL ) + p->procs = ndp; + else + d0p->link = ndp; + + return rc; +} + +unsigned _cmDotProcConnCount( cmDotProc_t* proc ) +{ + unsigned connN = 0; + + cmDotPort_t* port = proc->ports; + for(; port!=NULL; port=port->link) + connN += port->connCnt; + + return connN; +} + +cmDotRC_t _cmDotWriteOutput( cmDot_t* p, const cmChar_t* outFn ) +{ + cmDotRC_t rc = kOkDotRC; + + cmFileH_t fH = cmFileNullHandle; + + cmFileSysPathPart_t* pathParts = cmFsPathParts(outFn); + const cmChar_t* fn = NULL; + + if( pathParts == NULL ) + { + rc = cmErrMsg(&p->err,kFileFailDotRC,"The output file name '%s' could be parsed.",cmStringNullGuard(outFn)); + goto errLabel; + } + + if((fn = cmFsMakeFn( pathParts->dirStr, pathParts->fnStr, "dot", NULL )) == NULL ) + { + rc = cmErrMsg(&p->err,kFileFailDotRC,"The output file name could not be formed."); + goto errLabel; + } + + if( cmFileOpen(&fH,fn,kWriteFileFl,p->err.rpt) != kOkFileRC ) + { + rc = cmErrMsg(&p->err,kFileFailDotRC,"The output file '%s' could not be created.",cmStringNullGuard(outFn)); + goto errLabel; + } + + cmFilePrintf(fH,"digraph dsppgm\n{\n node [shape=record]\n"); + + cmDotProc_t* proc = p->procs; + for(; proc!=NULL; proc=proc->link ) + if( proc->skipFl==false && _cmDotProcConnCount(proc)>0 ) + { + cmFilePrintf(fH,"\"%s\" [label=\" %s",proc->outStr,proc->outStr); + + cmDotPort_t* port = proc->ports; + for(; port!=NULL; port=port->link) + if( port->connCnt > 0 ) + cmFilePrintf(fH,"| %s",port->portNo,port->labelStr); + + cmFilePrintf(fH,"\"];\n"); + } + + cmDotConn_t* c = p->conns; + for(; c!=NULL; c=c->link) + if( !c->skipFl ) + { + cmFilePrintf(fH,"\"%s\":p%i -> \"%s\":p%i;\n", + c->srcPort->proc->outStr,c->srcPort->portNo, + c->dstPort->proc->outStr,c->dstPort->portNo ); + } + + cmFilePrintf(fH,"}\n"); + + errLabel: + cmFileClose(&fH); + cmFsFreeFn(fn); + cmFsFreePathParts(pathParts); + return rc; +} + +cmDotRC_t cmDspPgmJsonToDot( cmCtx_t* ctx, const cmChar_t* inFn, const cmChar_t* outFn ) +{ + cmDotRC_t rc = kOkDotRC; + cmJsonH_t jsH = cmJsonNullHandle; + cmJsonNode_t* arr = NULL; + cmJsonNode_t* rp = NULL; + const char* errLbl = NULL; + cmDot_t dot; + unsigned i; + cmDot_t* p = ˙ + + memset(p,0,sizeof(dot)); + + cmErrSetup(&p->err,&ctx->rpt,"cmDspPgmJsonToDot"); + + // open the pgm description json file + if( cmJsonInitializeFromFile( &jsH, inFn, ctx ) != kOkJsRC ) + return cmErrMsg(&p->err,kJsonFailDotRC,"The program description file '%s' could not be opened.",cmStringNullGuard(inFn)); + + // create an lheap to hold internal data objects + if(cmLHeapIsValid( p->lH = cmLHeapCreate( 8192, ctx))==false ) + { + rc = cmErrMsg(&p->err,kLHeapFailDotRC,"The internal LHeap could not be created."); + goto errLabel; + } + + // locate the proc instance desc. array in the JSON tree + if((arr = cmJsonFindValue(jsH, "inst_array", NULL, kArrayTId )) == NULL ) + { + rc = cmErrMsg(&p->err,kJsonSyntaxErrDotRC,"The 'inst_array' tag was not found."); + goto errLabel; + } + + // get a count of proc instances + unsigned n = cmJsonChildCount(arr); + + // parse each proc instance + for(i=0; ierr,kJsonSyntaxErrDotRC,"The 'inst_array' element %i was not found.",i); + goto errLabel; + } + + cmChar_t* classStr = NULL; + cmChar_t* instStr = NULL; + if( cmJsonMemberValues(rp, &errLbl, + "class", kStringTId, &classStr, + "label", kStringTId, &instStr, + NULL ) != kOkJsRC ) + { + rc = cmErrMsg(&p->err,kJsonSyntaxErrDotRC,"The 'inst_array' element %i parse failed.",i); + goto errLabel; + } + + // create a proc instance data record + _cmDotNewProc( p, classStr, instStr ); + + } + + // locate the connection desc array in the JSON tree + if((arr = cmJsonFindValue(jsH, "conn_array", NULL, kArrayTId)) == NULL ) + { + rc = cmErrMsg(&p->err,kJsonSyntaxErrDotRC,"The 'conn_array' tag was not found."); + goto errLabel; + } + + // get a count of the connections + n = cmJsonChildCount(arr); + + // for each connection + for(i=0; ierr,kJsonSyntaxErrDotRC,"The 'conn_array' element %i was not found.",i); + goto errLabel; + } + + cmChar_t* srcStr = NULL; + cmChar_t* srcPortStr = NULL; + cmChar_t* dstStr = NULL; + cmChar_t* dstPortStr = NULL; + + if( cmJsonMemberValues(rp, &errLbl, + "sid", kStringTId, &srcStr, + "svar", kStringTId, &srcPortStr, + "did", kStringTId, &dstStr, + "dvar", kStringTId, &dstPortStr, + NULL) != kOkJsRC ) + { + rc = cmErrMsg(&p->err,kJsonSyntaxErrDotRC,"The 'conn_array' element %i parse failed.",i); + goto errLabel; + } + + // create a connection data record + _cmDotNewConnection( p, srcStr, srcPortStr, dstStr, dstPortStr ); + + } + + rc = _cmDotWriteOutput(p, outFn ); + + + errLabel: + cmJsonFinalize(&jsH); + cmLHeapDestroy(&p->lH); + + return rc; +} diff --git a/app/cmDspPgmJsonToDot.h b/app/cmDspPgmJsonToDot.h new file mode 100644 index 0000000..59ab618 --- /dev/null +++ b/app/cmDspPgmJsonToDot.h @@ -0,0 +1,30 @@ +#ifndef cmDspPgmJsonToDot_h +#define cmDspPgmJsonToDot_h + +#ifdef __cplusplus +extern "C" { +#endif + + //( { file_desc:"Convert a JSON graph description to a DOT vector graphics file." kw:[file plot]} + + enum + { + kOkDotRC = cmOkRC, + kJsonFailDotRC, + kJsonSyntaxErrDotRC, + kInvalidArgDotRC, + kLHeapFailDotRC, + kFileFailDotRC + }; + + typedef unsigned cmDotRC_t; + + cmDotRC_t cmDspPgmJsonToDot( cmCtx_t* ctx, const cmChar_t* inFn, const cmChar_t* outFn ); + + //) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/app/cmOnset.c b/app/cmOnset.c index da2e4cc..bb41c43 100644 --- a/app/cmOnset.c +++ b/app/cmOnset.c @@ -286,12 +286,13 @@ cmOnRC_t cmOnsetProc( cmOnH_t h, const cmOnsetCfg_t* cfg, const cmChar_t* inAudi p->medFiltFrmCnt = cmMax(3,floor(cfg->medFiltWndMs * p->afInfo.srate / (1000.0 * p->hopSmpCnt))); p->preDelaySmpCnt= floor(cfg->preDelayMs * p->afInfo.srate / 1000.0); + cmRptPrintf(p->err.rpt,"wndFrmCnt:%i preWndMult:%f thresh:%f maxHz:%f filtCoeff:%f filterId:%i preDelayMs:%f\n",cfg->wndFrmCnt,cfg->preWndMult,cfg->threshold,cfg->maxFrqHz,cfg->filtCoeff,cfg->medFiltWndMs,cfg->filterId,cfg->preDelayMs ); cmRptPrintf(p->err.rpt,"Analysis Hop Duration: %8.2f ms %i smp\n",(double)p->hopSmpCnt*1000/p->afInfo.srate,p->hopSmpCnt); cmRptPrintf(p->err.rpt,"Median Filter Window: %8.2f ms %i frames\n",cfg->medFiltWndMs,p->medFiltFrmCnt); cmRptPrintf(p->err.rpt,"Detection Pre-delay: %8.2f ms %i smp\n",cfg->preDelayMs, p->preDelaySmpCnt); // initialize the audio file reader - if( cmAudioFileRdOpen( p->afRdPtr, p->hopSmpCnt, inAudioFn, p->cfg.audioChIdx, 0, cmInvalidIdx ) != cmOkRC ) + if( cmAudioFileRdOpen( p->afRdPtr, p->hopSmpCnt, inAudioFn, p->cfg.audioChIdx, 0, 0 ) != cmOkRC ) { rc = cmErrMsg(&p->err,kDspProcFailOnRC, "The audio file reader open failed."); goto errLabel; diff --git a/app/cmOnset.h b/app/cmOnset.h index a5645e3..397d14e 100644 --- a/app/cmOnset.h +++ b/app/cmOnset.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Musical event onset detector." kw:[audio] } + enum { kOkOnRC = cmOkRC, @@ -65,6 +67,8 @@ extern "C" { cmOnRC_t cmOnsetTest( cmCtx_t* c ); + //) + #ifdef __cplusplus } #endif diff --git a/app/cmPickup.h b/app/cmPickup.h index d25df06..13eff44 100644 --- a/app/cmPickup.h +++ b/app/cmPickup.h @@ -5,7 +5,8 @@ extern "C" { #endif - + //( { file_desc:"'fluxo' channel calibration and gain normalization program." kw:[fluxo]} + enum { kOkPuRC = cmOkRC, @@ -88,7 +89,8 @@ extern "C" { void cmPuReport( cmPuH_t h, cmRpt_t* rpt ); void cmPuTest(cmCtx_t* ctx); - + //) + #ifdef __cplusplus } #endif diff --git a/app/cmScore.c b/app/cmScore.c index ad48090..f5186e6 100644 --- a/app/cmScore.c +++ b/app/cmScore.c @@ -133,19 +133,19 @@ typedef struct cmScEvtRef_t _cmScEvtRefArray[] = { - { kTimeSigEvtScId, 0, "tsg" }, - { kKeySigEvtScId, 0, "ksg" }, - { kTempoEvtScId, 0, "tmp" }, - { kTrackEvtScId, 0, "trk" }, - { kTextEvtScId, 0, "txt" }, - { kNameEvtScId, 0, "nam" }, - { kEOTrackEvtScId, 0, "eot" }, - { kCopyEvtScId, 0, "cpy" }, - { kBlankEvtScId, 0, "blk" }, - { kBarEvtScId, 0, "bar" }, - { kPgmEvtScId, 0, "pgm" }, - { kCtlEvtScId, 0, "ctl" }, - { kNonEvtScId, 0, "non" }, + { kTimeSigEvtScId, kTimeSigMdId, "tsg" }, + { kKeySigEvtScId, kKeySigMdId, "ksg" }, + { kTempoEvtScId, kTempoMdId, "tmp" }, + { kTrackEvtScId, kTrkNameMdId, "trk" }, + { kTextEvtScId, kTextMdId, "txt" }, + { kNameEvtScId, kInstrNameMdId,"nam" }, + { kEOTrackEvtScId, kEndOfTrkMdId, "eot" }, + { kCopyEvtScId, kCopyMdId, "cpy" }, + { kBlankEvtScId, 0, "blk" }, + { kBarEvtScId, 0, "bar" }, + { kPgmEvtScId, kPgmMdId, "pgm" }, + { kCtlEvtScId, kCtlMdId, "ctl" }, + { kNonEvtScId, kNoteOnMdId, "non" }, { kInvalidEvtScId, 0, "***" } }; @@ -196,6 +196,20 @@ const cmChar_t* cmScEvtTypeIdToLabel( unsigned id ) return NULL; } +const cmChar_t* cmScStatusToOpString( unsigned id ) +{ + if( id == 0 ) + return ""; + + cmScEvtRef_t* r = _cmScEvtRefArray; + for(; r->id != kInvalidEvtScId; ++r ) + if( r->flag == id ) + return r->label; + return NULL; + +} + + unsigned _cmScDynLabelToId( const cmChar_t* label ) { cmScEvtRef_t* r = _cmScDynRefArray; @@ -2419,10 +2433,8 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c goto errLabel; } - // Convert the track message 'dtick' field to delta-microseconds. - cmMidiFileTickToMicros(mfH); - - + //printf("secs:%f smps:%f\n",cmMidiFileDurSecs(mfH),cmMidiFileDurSecs(mfH)*96000); + unsigned msgCnt = cmMidiFileMsgCount(mfH); unsigned i; const cmMidiTrackMsg_t** tmpp = cmMidiFileMsgArray(mfH); @@ -2456,14 +2468,15 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c unsigned midiCh = 0; unsigned d0 = 0; unsigned d1 = 0; - unsigned metaId = 0; - double dsecs = (double)tmp->dtick / 1000000.0; + unsigned metaId = 0; + double dsecs = (double)tmp->amicro / 1000000.0; acc_secs += dsecs; if( tmp->status == kMetaStId ) { - opStr = cmMidiMetaStatusToLabel(tmp->metaId); + //opStr = cmMidiMetaStatusToLabel(tmp->metaId); + opStr = cmScStatusToOpString(tmp->metaId); metaId = tmp->metaId; switch( tmp->metaId ) @@ -2474,7 +2487,8 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c } else { - opStr = cmMidiStatusToLabel(tmp->status); + //opStr = cmMidiStatusToLabel(tmp->status); + opStr = cmScStatusToOpString(tmp->status); if( cmMidiIsChStatus( tmp->status ) ) { midiCh = tmp->u.chMsgPtr->ch; @@ -2647,10 +2661,6 @@ void cmScoreFix( cmCtx_t* ctx ) if( cmMidiFileOpen(mfn,&mfH,ctx) != kOkMfRC ) goto errLabel; - cmMidiFileTickToMicros(mfH); - - cmMidiFileCalcNoteDurations(mfH); - mn = cmMidiFileMsgCount(mfH); msg = cmMidiFileMsgArray(mfH); @@ -2680,7 +2690,7 @@ void cmScoreFix( cmCtx_t* ctx ) const cmMidiTrackMsg_t* m = msg[mi]; assert( mi+1 <= id ); - secs += m->dtick/1000000.0; + secs += m->amicro/1000000.0; if( mi+1 != id ) { @@ -2696,7 +2706,7 @@ void cmScoreFix( cmCtx_t* ctx ) ++mi; if( m->status == kNoteOnMdId ) - cmCsvSetCellDouble( csvH, ci, kDSecsColScIdx, m->u.chMsgPtr->durTicks/1000000.0 ); + cmCsvSetCellDouble( csvH, ci, kDSecsColScIdx, m->u.chMsgPtr->durMicros /1000000.0 ); break; } diff --git a/app/cmScore.h b/app/cmScore.h index 5758f0d..1f96ade 100644 --- a/app/cmScore.h +++ b/app/cmScore.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Object for managing musical score data." kw:[score]} + enum { kOkScRC = cmOkRC, @@ -155,7 +157,7 @@ extern "C" { const cmChar_t* cmScEvtTypeIdToLabel( unsigned id ); const cmChar_t* cmScDynIdToLabel( unsigned id ); - + const cmChar_t* cmScStatusToOpString( unsigned id ); // Initialize a score object from a CSV File generated from a score spreadsheet. // The dynRefArray[dynRefCnt] and cbFunc(cbArg) are optional if these @@ -273,7 +275,8 @@ extern "C" { void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn ); - + //) + #ifdef __cplusplus } #endif diff --git a/app/cmScoreProc.h b/app/cmScoreProc.h index 28361a2..4460f51 100644 --- a/app/cmScoreProc.h +++ b/app/cmScoreProc.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Programs for processing cmScore and peformane data." kw:[score seq]} + typedef unsigned cmSpRC_t; enum @@ -21,6 +23,8 @@ extern "C" { cmSpRC_t cmScoreProc(cmCtx_t* ctx ); + //) + #ifdef __cplusplus } #endif diff --git a/app/cmSdb.h b/app/cmSdb.h index 3b4e521..f716c5b 100644 --- a/app/cmSdb.h +++ b/app/cmSdb.h @@ -5,7 +5,8 @@ extern "C" { #endif - /* + /*( { file_desc:"Musical instrument sample database manager and synthetic sequence generator." kw:[audio] } + The CSV file used to initialize a SDB object has the following column syntax. Column Name Type Description @@ -40,7 +41,7 @@ extern "C" { so that their cmSdb value is zero based. See cmSdbLoad(). */ - + enum { kOkSdbRC, @@ -291,7 +292,9 @@ extern "C" { void cmSdbSeqPrint( cmSdbSeqH_t sh, cmRpt_t* rpt ); cmSdbRC_t cmSdbTest( cmCtx_t* ctx ); - + + //) + #ifdef __cplusplus } #endif diff --git a/app/cmTakeSeqBldr.c b/app/cmTakeSeqBldr.c index 66a2e22..6d1a9a6 100644 --- a/app/cmTakeSeqBldr.c +++ b/app/cmTakeSeqBldr.c @@ -956,14 +956,15 @@ cmTsbRC_t cmTakeSeqBldrLoadTake( cmTakeSeqBldrH_t h, unsigned tlMarkUid, bool ov } // convert the dtick field to delta samples - cmMidiFileTickToSamples( mfH, cmTimeLineSampleRate(p->tlH), false ); + //cmMidiFileTickToSamples( mfH, cmTimeLineSampleRate(p->tlH), false ); // calculate MIDI note and pedal durations (see cmMidiChMsg_t.durTicks) cmMidiFileCalcNoteDurations( mfH ); - unsigned i = 0; - unsigned n = cmMidiFileMsgCount(mfH); - const cmMidiTrackMsg_t** a = cmMidiFileMsgArray(mfH); + unsigned i = 0; + unsigned n = cmMidiFileMsgCount(mfH); + const cmMidiTrackMsg_t** a = cmMidiFileMsgArray(mfH); + double srate = cmTimeLineSampleRate(p->tlH); // allocate and link a new take render record cmTakeTsb_t* t = cmMemAllocZ(cmTakeTsb_t,1); @@ -1011,8 +1012,8 @@ cmTsbRC_t cmTakeSeqBldrLoadTake( cmTakeSeqBldrH_t h, unsigned tlMarkUid, bool ov m1->scEvtIdx = stm != NULL ? stm->scEvtIdx : cmInvalidIdx; m1->flags = stm != NULL ? stm->flags : 0; m1->ref = m0; - m1->offsetSmp = mf0 == NULL ? 0 : mf1->dtick; - m1->durSmp = mf1->u.chMsgPtr->durTicks; + m1->offsetSmp = mf0 == NULL ? 0 : round(mf1->amicro * srate / 1000000.0); + m1->durSmp = mf1->u.chMsgPtr->durMicros * srate / 1000000.0; m1->d0 = mf1->u.chMsgPtr->d0; m1->d1 = mf1->u.chMsgPtr->d1; m1->status = mf1->status; diff --git a/app/cmTakeSeqBldr.h b/app/cmTakeSeqBldr.h index 52a5b95..545e13f 100644 --- a/app/cmTakeSeqBldr.h +++ b/app/cmTakeSeqBldr.h @@ -5,7 +5,8 @@ extern "C" { #endif - + //( { file_desc:"Concatenate multipel overlapping MIDI performances into a single virtual performance based by associating score information with the MIDI events." kw:[seq] } + enum { kOkTsbRC = cmOkRC, @@ -123,6 +124,8 @@ extern "C" { cmTsbRC_t cmTakeSeqBldrTest( cmCtx_t* ctx ); + //) + #ifdef __cplusplus } #endif diff --git a/app/cmTimeLine.c b/app/cmTimeLine.c index 555bbb4..b40cbef 100644 --- a/app/cmTimeLine.c +++ b/app/cmTimeLine.c @@ -530,16 +530,14 @@ cmTlRC_t _cmTlAllocRecd2( tp->flags = 0; tp->text = NULL; + //printf("%9i %9i %9i %9i\n",tp->begSmpIdx,tp->durSmpCnt,refPtr==NULL?0:refPtr->obj->seqSmpIdx, tp->seqSmpIdx); + op->obj = tp; op->mem = mem; op->memByteCnt = byteCnt; op->next = NULL; op->prev = NULL; - - //if( seqId == 4 ) - // printf("seq:%i id:%i type:%i accum:%i ref:%i offs:%i %f\n",seqId, tp->uid, tp->typeId, tp->seqSmpIdx, refPtr==NULL?-1:refPtr->obj->uid, begSmpIdx, begSmpIdx/(96000.0*60.0) ); - _cmTlInsertAfter(p, _cmTlFindRecdBefore(p,op), op ); @@ -651,36 +649,36 @@ cmTlRC_t _cmTlProcMidiFile( _cmTl_t* p, _cmTlObj_t* op, cmMidiFileH_t mfH ) const cmMidiTrackMsg_t** mapp = cmMidiFileMsgArray(mfH); unsigned mi = 0; _cmTlObj_t* refOp = op; + double smpPerMicro = p->srate / 1000000.0; + unsigned begSmpIdx0 = 0; mfp->noteOnCnt = 0; // for each midi message for(; midtick; - int durSmpCnt = 0; - unsigned midiTrkMsgByteCnt = cmMidiFilePackTrackMsgBufByteCount( mp ); - unsigned recdByteCnt = sizeof(cmTlMidiEvt_t) + midiTrkMsgByteCnt; - - //if( mfp->obj.seqId==4 && mi<=25 ) - // printf("%s: bsi:%9i acc:%f smp acc:%f min %s\n", mp->status == kNoteOnMdId?"non":" ", begSmpIdx, accum, accum / (p->srate * 60),cmStringNullGuard(mfp->obj.name)); + _cmTlObj_t* meop = NULL; + const cmMidiTrackMsg_t* mp = mapp[mi]; + int begSmpIdx = mp->amicro * smpPerMicro; + int durSmpCnt = 0; + unsigned midiTrkMsgByteCnt = cmMidiFilePackTrackMsgBufByteCount( mp ); + unsigned recdByteCnt = sizeof(cmTlMidiEvt_t) + midiTrkMsgByteCnt; // count the note-on messages if( cmMidiIsNoteOn(mp->status) ) { - durSmpCnt = mp->u.chMsgPtr->durTicks; + durSmpCnt = mp->u.chMsgPtr->durMicros * smpPerMicro; ++mfp->noteOnCnt; } if( cmMidiIsCtl(mp->status) && cmMidiIsSustainPedal(mp->status,mp->u.chMsgPtr->d0) ) - durSmpCnt = mp->u.chMsgPtr->durTicks; + durSmpCnt = mp->u.chMsgPtr->durMicros * smpPerMicro; // allocate the generic time-line object record - if((rc = _cmTlAllocRecd2(p, NULL, refOp, begSmpIdx, durSmpCnt, kMidiEvtTlId, mfp->obj.seqId, recdByteCnt, &meop)) != kOkTlRC ) + if((rc = _cmTlAllocRecd2(p, NULL, refOp, begSmpIdx-begSmpIdx0, durSmpCnt, kMidiEvtTlId, mfp->obj.seqId, recdByteCnt, &meop)) != kOkTlRC ) goto errLabel; + begSmpIdx0 = begSmpIdx; + assert( meop != NULL ); cmTlMidiEvt_t* mep = _cmTimeLineMidiEvtObjPtr(p,meop->obj); @@ -731,7 +729,7 @@ cmTlRC_t _cmTlAllocMidiFileRecd( _cmTl_t* p, const cmChar_t* nameStr, const cmCh unsigned durSmpCnt = floor(cmMidiFileDurSecs(mfH)*p->srate); // convert the midi file from delta ticks to delta samples - cmMidiFileTickToSamples(mfH,p->srate,false); + //cmMidiFileTickToSamples(mfH,p->srate,false); // assign note durations to all note-on msg's cmMidiFileCalcNoteDurations(mfH); @@ -757,6 +755,7 @@ cmTlRC_t _cmTlAllocMidiFileRecd( _cmTl_t* p, const cmChar_t* nameStr, const cmCh op->obj->text = mp->fn; + // insert the events in the midi file as individual time line objects if((rc = _cmTlProcMidiFile(p, op, mfH)) != kOkTlRC ) goto errLabel; @@ -1363,7 +1362,7 @@ cmTlRC_t cmTimeLineReadJson( cmTlH_t* hp, const cmChar_t* ifn ) if( cmJsonMemberValues(jnp,&errLabelPtr, "srate",kRealTId,&p->srate, - "onset",kObjectTId,&cnp, + "onset",kObjectTId | kOptArgJsFl,&cnp, "objArray",kArrayTId,&jnp, NULL) != kOkJsRC ) { @@ -1374,28 +1373,31 @@ cmTlRC_t cmTimeLineReadJson( cmTlH_t* hp, const cmChar_t* ifn ) goto errLabel; } - if((jsRC = cmJsonMemberValues(cnp,&errLabelPtr, - "wndMs", kRealTId, &p->onsetCfg.wndMs, - "hopFact", kIntTId, &p->onsetCfg.hopFact, - "audioChIdx", kIntTId, &p->onsetCfg.audioChIdx, - "wndFrmCnt", kIntTId, &p->onsetCfg.wndFrmCnt, - "preWndMult", kRealTId, &p->onsetCfg.preWndMult, - "threshold", kRealTId, &p->onsetCfg.threshold, - "maxFrqHz", kRealTId, &p->onsetCfg.maxFrqHz, - "filtCoeff", kRealTId, &p->onsetCfg.filtCoeff, - "medFiltWndMs", kRealTId, &p->onsetCfg.medFiltWndMs, - "filterId", kIntTId, &p->onsetCfg.filterId, - "preDelayMs", kRealTId, &p->onsetCfg.preDelayMs, - NULL)) != kOkJsRC ) + if( cnp != NULL ) { + if((jsRC = cmJsonMemberValues(cnp,&errLabelPtr, + "wndMs", kRealTId, &p->onsetCfg.wndMs, + "hopFact", kIntTId, &p->onsetCfg.hopFact, + "audioChIdx", kIntTId, &p->onsetCfg.audioChIdx, + "wndFrmCnt", kIntTId, &p->onsetCfg.wndFrmCnt, + "preWndMult", kRealTId, &p->onsetCfg.preWndMult, + "threshold", kRealTId, &p->onsetCfg.threshold, + "maxFrqHz", kRealTId, &p->onsetCfg.maxFrqHz, + "filtCoeff", kRealTId, &p->onsetCfg.filtCoeff, + "medFiltWndMs", kRealTId, &p->onsetCfg.medFiltWndMs, + "filterId", kIntTId, &p->onsetCfg.filterId, + "preDelayMs", kRealTId, &p->onsetCfg.preDelayMs, + NULL)) != kOkJsRC ) + { - if(jsRC == kNodeNotFoundJsRC ) - rc = cmErrMsg(&p->err,kParseFailTlRC,"The JSON 'time_line' onset analysizer cfg. required field:'%s' was not found in '%s'.",errLabelPtr,cmStringNullGuard(ifn)); - else - rc = cmErrMsg(&p->err,kParseFailTlRC,"The JSON 'time_line' onset analyzer cfg. in '%s'.",cmStringNullGuard(ifn)); - goto errLabel; + if(jsRC == kNodeNotFoundJsRC ) + rc = cmErrMsg(&p->err,kParseFailTlRC,"The JSON 'time_line' onset analysizer cfg. required field:'%s' was not found in '%s'.",errLabelPtr,cmStringNullGuard(ifn)); + else + rc = cmErrMsg(&p->err,kParseFailTlRC,"The JSON 'time_line' onset analyzer cfg. in '%s'.",cmStringNullGuard(ifn)); + goto errLabel; + } } - + for(i=0; ionsetCfg.wndMs == 0 ) + { + rc = cmErrMsg(&p->err,kOnsetFailTlRC,"Audio onset analyzer not-configured."); + goto errLabel; + } + // initialize the audio onset analyzer if( cmOnsetInitialize(&p->ctx, &onsH ) != kOkOnRC ) { diff --git a/app/cmTimeLine.h b/app/cmTimeLine.h index e289267..60087c2 100644 --- a/app/cmTimeLine.h +++ b/app/cmTimeLine.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Manage, save, and restore a time-line containing MIDI files, Audio files, Audio events, and arbitrary markers ." kw[seq] } + typedef cmHandle_t cmTlH_t; @@ -248,6 +250,8 @@ extern "C" { // callback function. cmTlRC_t cmTimeLineDecode( const void* msg, unsigned msgByteCnt, cmTlUiMsg_t* uiMsg ); + //) + #ifdef __cplusplus } #endif diff --git a/cmApBuf.h b/cmApBuf.h index 3583d46..748ed76 100644 --- a/cmApBuf.h +++ b/cmApBuf.h @@ -1,34 +1,33 @@ -/// \file cmApBuf.h -/// \brief Thread-safe audio buffer class. -/// -/// This file defines an audio buffer class which handles -/// buffering incoming (recording) and outgoing (playback) -/// samples in a thread-safe manner. -/// -/// Usage example and testing code: -/// See cmApBufTest() and cmAudioSysTest(). -/// \snippet cmApBuf.c cmApBufExample -/// -/// Notes on channel flags: -/// Disabled channels: kChFl is cleared -/// cmApBufGet() -/// in - return NULL buffer pointers -/// out - return NULL buffer points -/// -/// cmApBufUpdate() -/// in - incoming samples are set to 0. -/// out - outgoing samples are set to 0. -/// -/// Muted channels: kMuteFl is set -/// cmApBufUpdate() -/// in - incoming samples are set to 0. -/// out - outgoing samples are set to 0. -/// -/// Tone channels: kToneFl is set -/// cmApBufUpdate() -/// in - incoming samples are filled with a 1k sine tone -/// out - outgoing samples are filled with a 1k sine tone -/// +//( {file_desc: "Thread safe audio buffer class." kw:[rt audio]} +// +// This file defines an audio buffer class which handles +// buffering incoming (recording) and outgoing (playback) +// samples in a thread-safe manner. +// +// Usage example and testing code: +// See cmApBufTest() and cmAudioSysTest(). +// \snippet cmApBuf.c cmApBufExample +// +// Notes on channel flags: +// Disabled channels: kChFl is cleared +// cmApBufGet() +// in - return NULL buffer pointers +// out - return NULL buffer points +// +// cmApBufUpdate() +// in - incoming samples are set to 0. +// out - outgoing samples are set to 0. +// +// Muted channels: kMuteFl is set +// cmApBufUpdate() +// in - incoming samples are set to 0. +// out - outgoing samples are set to 0. +// +// Tone channels: kToneFl is set +// cmApBufUpdate() +// in - incoming samples are filled with a 1k sine tone +// out - outgoing samples are filled with a 1k sine tone +//) #ifndef cmApBuf_h #define cmApBuf_h @@ -36,199 +35,200 @@ #ifdef __cplusplus extern "C" { #endif - - typedef cmRC_t cmAbRC_t; ///< Result code type + + //( + typedef cmRC_t cmAbRC_t; //< Result code type enum { kOkAbRC = 0 }; - /// Allocate and initialize an audio buffer. - /// devCnt - count of devices this buffer will handle. - /// meterMs - length of the meter buffers in milliseconds (automatically limit to the range:10 to 1000) + // Allocate and initialize an audio buffer. + // devCnt - count of devices this buffer will handle. + // meterMs - length of the meter buffers in milliseconds (automatically limit to the range:10 to 1000) cmAbRC_t cmApBufInitialize( unsigned devCnt, unsigned meterMs ); - /// Deallocate and release any resource held by an audio buffer allocated via cmApBufInitialize(). + // Deallocate and release any resource held by an audio buffer allocated via cmApBufInitialize(). cmAbRC_t cmApBufFinalize(); - /// Configure a buffer for a given device. + // Configure a buffer for a given device. cmAbRC_t cmApBufSetup( - unsigned devIdx, ///< device to setup - double srate, ///< device sample rate (only required for synthesizing the correct test-tone frequency) - unsigned dspFrameCnt, /// dspFrameCnt - count of samples in channel buffers returned via cmApBufGet() - unsigned cycleCnt, ///< number of audio port cycles to store - unsigned inChCnt, ///< input channel count on this device - unsigned inFramesPerCycle, ///< maximum number of incoming sample frames on an audio port cycle - unsigned outChCnt, ///< output channel count on this device - unsigned outFramesPerCycle ///< maximum number of outgoing sample frames in an audio port cycle + unsigned devIdx, //< device to setup + double srate, //< device sample rate (only required for synthesizing the correct test-tone frequency) + unsigned dspFrameCnt, // dspFrameCnt - count of samples in channel buffers returned via cmApBufGet() + unsigned cycleCnt, //< number of audio port cycles to store + unsigned inChCnt, //< input channel count on this device + unsigned inFramesPerCycle, //< maximum number of incoming sample frames on an audio port cycle + unsigned outChCnt, //< output channel count on this device + unsigned outFramesPerCycle //< maximum number of outgoing sample frames in an audio port cycle ); - /// Prime the buffer with 'audioCycleCnt' * outFramesPerCycle samples ready to be played + // Prime the buffer with 'audioCycleCnt' * outFramesPerCycle samples ready to be played cmAbRC_t cmApBufPrimeOutput( unsigned devIdx, unsigned audioCycleCnt ); - /// Notify the audio buffer that a device is being enabled or disabled. + // Notify the audio buffer that a device is being enabled or disabled. void cmApBufOnPortEnable( unsigned devIdx, bool enabelFl ); - /// This function is called asynchronously by the audio device driver to transfer incoming samples to the - /// the buffer and to send outgoing samples to the DAC. This function is - /// intended to be called from the audio port callback function (\see cmApCallbackPtr_t). - /// This function is thread-safe under the condition where the audio device uses - /// different threads for input and output. - /// - /// Enable Flag: - /// Input: If an input channel is disabled then the incoming samples are replaced with zeros. - /// Output: If an output channel is disabled then the packet samples are set to zeros. - /// - /// Tone Flag: - /// Input: If the tone flag is set on an input channel then the incoming samples are set to a sine tone. - /// Output: If the tone flag is set on an output channel then the packet samples are set to a sine tone. - /// - /// The enable flag has higher precedence than the tone flag therefore disabled channels - /// will be set to zero even if the tone flag is set. + // This function is called asynchronously by the audio device driver to transfer incoming samples to the + // the buffer and to send outgoing samples to the DAC. This function is + // intended to be called from the audio port callback function (\see cmApCallbackPtr_t). + // This function is thread-safe under the condition where the audio device uses + // different threads for input and output. + // + // Enable Flag: + // Input: If an input channel is disabled then the incoming samples are replaced with zeros. + // Output: If an output channel is disabled then the packet samples are set to zeros. + // + // Tone Flag: + // Input: If the tone flag is set on an input channel then the incoming samples are set to a sine tone. + // Output: If the tone flag is set on an output channel then the packet samples are set to a sine tone. + // + // The enable flag has higher precedence than the tone flag therefore disabled channels + // will be set to zero even if the tone flag is set. cmAbRC_t cmApBufUpdate( - cmApAudioPacket_t* inPktArray, ///< full audio packets from incoming audio (from ADC) - unsigned inPktCnt, ///< count of incoming audio packets - cmApAudioPacket_t* outPktArray, ///< empty audio packet for outgoing audio (to DAC) - unsigned outPktCnt ///< count of outgoing audio packets + cmApAudioPacket_t* inPktArray, //< full audio packets from incoming audio (from ADC) + unsigned inPktCnt, //< count of incoming audio packets + cmApAudioPacket_t* outPktArray, //< empty audio packet for outgoing audio (to DAC) + unsigned outPktCnt //< count of outgoing audio packets ); - /// Channel flags + // Channel flags enum { - kInApFl = 0x01, ///< Identify an input channel - kOutApFl = 0x02, ///< Identify an output channel - kEnableApFl = 0x04, ///< Set to enable a channel, Clear to disable. + kInApFl = 0x01, //< Identify an input channel + kOutApFl = 0x02, //< Identify an output channel + kEnableApFl = 0x04, //< Set to enable a channel, Clear to disable. - kChApFl = 0x08, ///< Used to enable/disable a channel - kMuteApFl = 0x10, ///< Mute this channel - kToneApFl = 0x20, ///< Generate a tone on this channel - kMeterApFl = 0x40, ///< Turn meter's on/off - kPassApFl = 0x80 ///< Pass input channels throught to the output. Must use cmApBufGetIO() to implement this functionality. + kChApFl = 0x08, //< Used to enable/disable a channel + kMuteApFl = 0x10, //< Mute this channel + kToneApFl = 0x20, //< Generate a tone on this channel + kMeterApFl = 0x40, //< Turn meter's on/off + kPassApFl = 0x80 //< Pass input channels throught to the output. Must use cmApBufGetIO() to implement this functionality. }; - /// Return the meter window period as set by cmApBufInitialize() + // Return the meter window period as set by cmApBufInitialize() unsigned cmApBufMeterMs(); // Set the meter update period. THis function limits the value to between 10 and 1000. void cmApBufSetMeterMs( unsigned meterMs ); - /// Returns the channel count set via cmApBufSetup(). + // Returns the channel count set via cmApBufSetup(). unsigned cmApBufChannelCount( unsigned devIdx, unsigned flags ); - /// Set chIdx to -1 to enable all channels on this device. - /// Set flags to {kInApFl | kOutApFl} | {kChApFl | kToneApFl | kMeterFl} | { kEnableApFl=on | 0=off } + // Set chIdx to -1 to enable all channels on this device. + // Set flags to {kInApFl | kOutApFl} | {kChApFl | kToneApFl | kMeterFl} | { kEnableApFl=on | 0=off } void cmApBufSetFlag( unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Return true if the the flags is set. + // Return true if the the flags is set. bool cmApBufIsFlag( unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Set chIdx to -1 to enable all channels on this device. + // Set chIdx to -1 to enable all channels on this device. void cmApBufEnableChannel( unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Returns true if an input/output channel is enabled on the specified device. + // Returns true if an input/output channel is enabled on the specified device. bool cmApBufIsChannelEnabled(unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Set the state of the tone generator on the specified channel. - /// Set chIdx to -1 to apply the change to all channels on this device. - /// Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off } + // Set the state of the tone generator on the specified channel. + // Set chIdx to -1 to apply the change to all channels on this device. + // Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off } void cmApBufEnableTone( unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Returns true if an input/output tone is enabled on the specified device. + // Returns true if an input/output tone is enabled on the specified device. bool cmApBufIsToneEnabled(unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Mute a specified channel. - /// Set chIdx to -1 to apply the change to all channels on this device. - /// Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off } + // Mute a specified channel. + // Set chIdx to -1 to apply the change to all channels on this device. + // Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off } void cmApBufEnableMute( unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Returns true if an input/output channel is muted on the specified device. + // Returns true if an input/output channel is muted on the specified device. bool cmApBufIsMuteEnabled(unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Set the specified channel to pass through. - /// Set chIdx to -1 to apply the change to all channels on this device. - /// Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off } + // Set the specified channel to pass through. + // Set chIdx to -1 to apply the change to all channels on this device. + // Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off } void cmApBufEnablePass( unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Returns true if pass through is enabled on the specified channel. + // Returns true if pass through is enabled on the specified channel. bool cmApBufIsPassEnabled(unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Turn meter data collection on and off. - /// Set chIdx to -1 to apply the change to all channels on this device. - /// Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off } + // Turn meter data collection on and off. + // Set chIdx to -1 to apply the change to all channels on this device. + // Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off } void cmApBufEnableMeter( unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Returns true if an input/output tone is enabled on the specified device. + // Returns true if an input/output tone is enabled on the specified device. bool cmApBufIsMeterEnabled(unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Return the meter value for the requested channel. - /// Set flags to kInApFl | kOutApFl. + // Return the meter value for the requested channel. + // Set flags to kInApFl | kOutApFl. cmApSample_t cmApBufMeter(unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Set chIdx to -1 to apply the gain to all channels on the specified device. + // Set chIdx to -1 to apply the gain to all channels on the specified device. void cmApBufSetGain( unsigned devIdx, unsigned chIdx, unsigned flags, double gain ); - /// Return the current gain seting for the specified channel. + // Return the current gain seting for the specified channel. double cmApBufGain( unsigned devIdx, unsigned chIdx, unsigned flags ); - /// Get the meter and fault status of the channel input or output channel array of a device. - /// Set 'flags' to { kInApFl | kOutApFl }. - /// The returns value is the count of channels actually written to meterArray. - /// If 'faultCntPtr' is non-NULL then it is set to the faultCnt of the associated devices input or output buffer. + // Get the meter and fault status of the channel input or output channel array of a device. + // Set 'flags' to { kInApFl | kOutApFl }. + // The returns value is the count of channels actually written to meterArray. + // If 'faultCntPtr' is non-NULL then it is set to the faultCnt of the associated devices input or output buffer. unsigned cmApBufGetStatus( unsigned devIdx, unsigned flags, double* meterArray, unsigned meterCnt, unsigned* faultCntPtr ); - /// Do all enabled input/output channels on this device have samples available? - /// 'flags' can be set to either or both kInApFl and kOutApFl + // Do all enabled input/output channels on this device have samples available? + // 'flags' can be set to either or both kInApFl and kOutApFl bool cmApBufIsDeviceReady( unsigned devIdx, unsigned flags ); - /// This function is called by the application to get full incoming sample buffers and - /// to fill empty outgoing sample buffers. - /// Upon return each element in bufArray[bufChCnt] holds a pointer to a buffer assoicated - /// with an audio channel or to NULL if the channel is disabled. - /// 'flags' can be set to kInApFl or kOutApFl but not both. - /// The buffers pointed to by bufArray[] each contain 'dspFrameCnt' samples. Where - /// 'dspFrameCnt' was set in the earlier call to cmApBufSetup() for this device. - /// (see cmApBufInitialize()). - /// Note that this function just returns audio information it does not - /// change any cmApBuf() internal states. + // This function is called by the application to get full incoming sample buffers and + // to fill empty outgoing sample buffers. + // Upon return each element in bufArray[bufChCnt] holds a pointer to a buffer assoicated + // with an audio channel or to NULL if the channel is disabled. + // 'flags' can be set to kInApFl or kOutApFl but not both. + // The buffers pointed to by bufArray[] each contain 'dspFrameCnt' samples. Where + // 'dspFrameCnt' was set in the earlier call to cmApBufSetup() for this device. + // (see cmApBufInitialize()). + // Note that this function just returns audio information it does not + // change any cmApBuf() internal states. void cmApBufGet( unsigned devIdx, unsigned flags, cmApSample_t* bufArray[], unsigned bufChCnt ); - /// This function replaces calls to cmApBufGet() and implements pass-through and output - /// buffer zeroing: - /// - /// 1) cmApBufGet(in); - /// 2) cmApBufGet(out); - /// 3) Copy through channels marked for 'pass' and set the associated oBufArray[i] channel to NULL. - /// 4) Zero all other enabled output channels. - /// - /// Notes: - /// 1) The oBufArray[] channels that are disabled or marked for pass-through will - /// be set to NULL. - /// 2) The client is required to use this function to implement pass-through internally. - /// 3) This function just returns audio information it does not - /// change any cmApBuf() internal states. - /// 4) The timestamp pointers are optional. + // This function replaces calls to cmApBufGet() and implements pass-through and output + // buffer zeroing: + // + // 1) cmApBufGet(in); + // 2) cmApBufGet(out); + // 3) Copy through channels marked for 'pass' and set the associated oBufArray[i] channel to NULL. + // 4) Zero all other enabled output channels. + // + // Notes: + // 1) The oBufArray[] channels that are disabled or marked for pass-through will + // be set to NULL. + // 2) The client is required to use this function to implement pass-through internally. + // 3) This function just returns audio information it does not + // change any cmApBuf() internal states. + // 4) The timestamp pointers are optional. void cmApBufGetIO( unsigned iDevIdx, cmApSample_t* iBufArray[], unsigned iBufChCnt, cmTimeSpec_t* iTimeStampPtr, unsigned oDevIdx, cmApSample_t* oBufArray[], unsigned oBufChCnt, cmTimeSpec_t* oTimeStampPtr ); - /// The application calls this function each time it completes processing of a bufArray[] - /// returned from cmApBufGet(). 'flags' can be set to either or both kInApFl and kOutApFl. - /// This function should only be called from the client thread. + // The application calls this function each time it completes processing of a bufArray[] + // returned from cmApBufGet(). 'flags' can be set to either or both kInApFl and kOutApFl. + // This function should only be called from the client thread. void cmApBufAdvance( unsigned devIdx, unsigned flags ); - /// Copy all available samples incoming samples from an input device to an output device. - /// The source code for this example is a good example of how an application should use cmApBufGet() - /// and cmApBufAdvance(). + // Copy all available samples incoming samples from an input device to an output device. + // The source code for this example is a good example of how an application should use cmApBufGet() + // and cmApBufAdvance(). void cmApBufInputToOutput( unsigned inDevIdx, unsigned outDevIdx ); - /// Print the current buffer state. + // Print the current buffer state. void cmApBufReport( cmRpt_t* rpt ); - /// Run a buffer usage simulation to test the class. cmAudioPortTest.c calls this function. + // Run a buffer usage simulation to test the class. cmAudioPortTest.c calls this function. void cmApBufTest( cmRpt_t* rpt ); - + //) #ifdef __cplusplus diff --git a/cmArray.h b/cmArray.h index 05280c8..8cb9794 100644 --- a/cmArray.h +++ b/cmArray.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc: "Dynamic array container class." kw:[container] } + enum { kOkArRC = cmOkRC, @@ -55,6 +57,8 @@ enum // Zero elements i:i+n-1 #define cmArrayClrN(t,h,i,n) ((t*)cmArraySet(h,i,NULL,n)) + //) + #ifdef __cplusplus } #endif diff --git a/cmAudDsp.c b/cmAudDsp.c index 497783e..8c39c2a 100644 --- a/cmAudDsp.c +++ b/cmAudDsp.c @@ -30,7 +30,7 @@ #include "dsp/cmDspClass.h" #include "dsp/cmDspSys.h" #include "cmAudDsp.h" - +#include "cmDspPgmJsonToDot.h" cmAdH_t cmAdNullHandle = cmSTATIC_NULL_HANDLE; @@ -1005,6 +1005,11 @@ cmAdRC_t _cmAudDspPrintPgm( cmAd_t* p, unsigned asSubSysIdx, const cmChar_t* fn { if( cmDspSysPrintPgm(p->dsSsArray[i].dsH,fn) != kOkDspRC ) rc = cmErrMsg(&p->err,kDspSysFailAdRC,"The program print failed."); + else + { + if( cmDspPgmJsonToDot(&p->ctx,fn,fn) != kOkDspRC ) + rc = cmErrMsg(&p->err,kDspSysFailAdRC,"The program print conversion to DOT failed."); + } break; } diff --git a/cmAudDsp.h b/cmAudDsp.h index 6b83faa..f33077f 100644 --- a/cmAudDsp.h +++ b/cmAudDsp.h @@ -5,8 +5,7 @@ extern "C" { #endif - // This API supports a serialized interface to an internal instance of - // cmAudioSys and cmDspSys. + //( { file_desc: "Supports a serialized interface to an internal instance of cmAudioSys and cmDspSys." kw:[rt]} enum { @@ -50,6 +49,8 @@ extern "C" { // client program to the aud_dsp system. cmAdRC_t cmAudDspReceiveClientMsg( cmAdH_t h, unsigned msgBytecnt, const void* msg ); + //) + #ifdef __cplusplus } diff --git a/cmAudDspIF.h b/cmAudDspIF.h index df4209d..9e4db3e 100644 --- a/cmAudDspIF.h +++ b/cmAudDspIF.h @@ -5,10 +5,24 @@ extern "C" { #endif + //( { file_desc: "Virtual interface to the audio DSP system." kw:[rt]} + // + // This class provides a two-way interface to the audio DSP system. + // It is designed to work independenty of the physical + // method of communication. For example, when used by + // cmAudDspLocal, it supports in memory transfer of messages + // between the application and the audio-DSP engine. + // Another implementation however could use it to support + // a networked communication scheme to a remote audio-DSP + // system. Note that in either case, however, this class + // resides with, and is linked to, the application, and not + // the engine. + // This API has two basic responsibilities: // // 1) Provides a function based interface to the audio DSP system for the - // client application. + // client application. This is more convenient, and safer, than the lower level + // message based interface provided by cmAudDsp.h. // The client calls these API functions to send commands to the audio DSP // system. Internally the cmAdIfxxx functions converts the commands to // raw message packets and passes them to a transmission service @@ -29,9 +43,9 @@ extern "C" { // client provided cmAdIfDispatch_t function (ssInitFunc,statusFunc or uiFunc). // Note that this entire chain of calls occurs in the client thread // and in the context of the cmAdIfDispatchMsgToHost() procedure. - - + //) + //( enum { kOkAiRC = cmOkRC, @@ -163,7 +177,8 @@ extern "C" { */ - + //) + #ifdef __cplusplus } #endif diff --git a/cmAudDspLocal.h b/cmAudDspLocal.h index c90b67d..d5abbba 100644 --- a/cmAudDspLocal.h +++ b/cmAudDspLocal.h @@ -5,6 +5,20 @@ extern "C" { #endif + //( { file_desc: "Implementation of the audio DSP interface for local, in-memory, communication." kw:[rt]} + // + // This class instantiates an audio-DSP engine (cmAudDsp), + // an interface for communicating with it (cmAudDspIF), + // and message delivery functions for copying messages + // in both directions between cmAuDsp and cmAudDspIF. + // + // Note that the underlying inteface which allows an application to + // control, and receive message from, cmAudDsp is provided by + // cmAudDspIF - which this class provides a handle to. + //) + + //( + enum { kOkAdlRC = cmOkRC, @@ -32,6 +46,7 @@ extern "C" { cmAiH_t cmAudDspLocalIF_Handle( cmAdlH_t h ); + //) #ifdef __cplusplus } diff --git a/cmAudLabelFile.h b/cmAudLabelFile.h index 3389fdd..1bc1db1 100644 --- a/cmAudLabelFile.h +++ b/cmAudLabelFile.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Read and write Audacity label files." kw:[audio file] } + enum { kOkAlfRC = cmOkRC, @@ -43,6 +45,8 @@ enum void cmAudLabelFileTest( cmCtx_t* ctx ); + //) + #ifdef __cplusplus } #endif diff --git a/cmAudioAggDev.h b/cmAudioAggDev.h index e174c91..58f5e02 100644 --- a/cmAudioAggDev.h +++ b/cmAudioAggDev.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc: "Audio device driver for cmAudioPort which aggregates multiple hardware devices to appear as a single devices." kw:[rt] } + enum { kOkAgRC = cmOkRC, @@ -95,7 +97,8 @@ extern "C" { int cmApAggTest( bool runFl, cmCtx_t* ctx, int argc, const char* argv[] ); - + //) + #ifdef __cplusplus } #endif diff --git a/cmAudioBuf.h b/cmAudioBuf.h index 464ff0f..18e1da1 100644 --- a/cmAudioBuf.h +++ b/cmAudioBuf.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( {file_desc: "Obsolete audio buffer class. This class is superceded by cmApBuf."} + enum { kOkBaRC = cmOkRC @@ -53,7 +55,7 @@ extern "C" { cmBaRC_t cmAudioBufAdvance( unsigned devIdx, unsigned flags ); - + //) #ifdef __cplusplus diff --git a/cmAudioFile.h b/cmAudioFile.h index 1466b29..62aa925 100644 --- a/cmAudioFile.h +++ b/cmAudioFile.h @@ -1,13 +1,9 @@ -/// \file cmAudioFile.h -/// \brief Audio file reader/writer class. -/// -/// This class supports reading uncompressed AIFF and WAV files and writing uncompressed AIFF files. -/// The reading and writing routines are known to work with 8,16,24, and 32 bit integer sample formats. -/// -/// Testing and example usage for this API can be found in cmProcTest.c cmAudioReadWriteTest(). -/// -/// Usage example: -/// \snippet cmAudioFile.c cmAudioFileExample +//( { file_desc: "Read and write AIFF and WAV audio files." kw:[file audio] } +// +// This class supports reading uncompressed AIFF and WAV files and writing uncompressed AIFF files. +// The reading and writing routines are known to work with 8,16,24, and 32 bit integer sample formats. +// +//) #ifndef cmAudioFile_h #define cmAudioFile_h @@ -16,15 +12,17 @@ extern "C" { #endif + //( + #ifndef cmAudioFile_MAX_FRAME_READ_CNT -/// Maximum number of samples which will be read in one call to fread(). -/// This value is only significant in that an internal buffer is created on the stack -/// whose size must be limited to prevent stack overflows. + // Maximum number of samples which will be read in one call to fread(). + // This value is only significant in that an internal buffer is created on the stack + // whose size must be limited to prevent stack overflows. #define cmAudioFile_MAX_FRAME_READ_CNT (8192) #endif - /// Audio file result codes. + // Audio file result codes. enum { kOkAfRC = 0, @@ -41,18 +39,18 @@ extern "C" { kUnknownErrAfRC }; - /// Informational flags used by audioFileInfo + // Informational flags used by audioFileInfo enum { - kAiffAfFl = 0x01, ///< this is an AIFF file - kWavAfFl = 0x02, ///< this is a WAV file - kSwapAfFl = 0x04, ///< file header bytes must be swapped - kAifcAfFl = 0x08, ///< this is an AIFC file - kSwapSamplesAfFl = 0x10 ///< file sample bytes must be swapped + kAiffAfFl = 0x01, // this is an AIFF file + kWavAfFl = 0x02, // this is a WAV file + kSwapAfFl = 0x04, // file header bytes must be swapped + kAifcAfFl = 0x08, // this is an AIFC file + kSwapSamplesAfFl = 0x10 // file sample bytes must be swapped }; - /// Constants + // Constants enum { kAudioFileLabelCharCnt = 256, @@ -64,7 +62,7 @@ extern "C" { kAfBextOriginTimeN = 8 }; - /// Aiff marker record + // Aiff marker record typedef struct { unsigned id; @@ -72,9 +70,9 @@ extern "C" { char label[kAudioFileLabelCharCnt]; } cmAudioFileMarker_t; - /// Broadcast WAV header record As used by ProTools audio files. See http://en.wikipedia.org/wiki/Broadcast_Wave_Format - /// When generated from Protools the timeRefLow/timeRefHigh values appear to actually refer - /// to the position on the Protools time-line rather than the wall clock time. + // Broadcast WAV header record As used by ProTools audio files. See http://en.wikipedia.org/wiki/Broadcast_Wave_Format + // When generated from Protools the timeRefLow/timeRefHigh values appear to actually refer + // to the position on the Protools time-line rather than the wall clock time. typedef struct { char desc[ kAfBextDescN + 1 ]; @@ -86,102 +84,103 @@ extern "C" { unsigned timeRefHigh; // sample count since midnight high word } cmAudioFileBext_t; - /// Audio file information record used by audioFileNew and audioFileOpen + // Audio file information record used by audioFileNew and audioFileOpen typedef struct { - unsigned bits; ///< bits per sample - unsigned chCnt; ///< count of audio file channels - double srate; ///< audio file sample rate in samples per second - unsigned frameCnt; ///< total number of sample frames in the audio file - unsigned flags; ///< informational flags - unsigned markerCnt; ///< count of markers in markerArray - cmAudioFileMarker_t* markerArray; ///< array of markers - cmAudioFileBext_t bextRecd; ///< only used with Broadcast WAV files + unsigned bits; // bits per sample + unsigned chCnt; // count of audio file channels + double srate; // audio file sample rate in samples per second + unsigned frameCnt; // total number of sample frames in the audio file + unsigned flags; // informational flags + unsigned markerCnt; // count of markers in markerArray + cmAudioFileMarker_t* markerArray; // array of markers + cmAudioFileBext_t bextRecd; // only used with Broadcast WAV files } cmAudioFileInfo_t; - typedef cmHandle_t cmAudioFileH_t; ///< opaque audio file handle - extern cmAudioFileH_t cmNullAudioFileH; ///< NULL audio file handle + typedef cmHandle_t cmAudioFileH_t; // opaque audio file handle + extern cmAudioFileH_t cmNullAudioFileH; // NULL audio file handle - /// Create an audio file handle and optionally use the handle to open an audio file. - /// - /// \param fn The audio file name to open or NULL to create the audio file handle without opening the file. - /// \param infoPtr A pointer to an audioFileInfo record to be filled when the file is open or NULL to ignore. - /// \param rcPtr A pointer to a result code to be set in the event of a runtime error or NULL to ignore. - /// \param rpt A pointer to a cmRpt_t object which error messages from this class will be directed to. - /// \retval cmAudioFileH_t A new audio file handle. - /// + // Create an audio file handle and optionally use the handle to open an audio file. + // + // fn The audio file name to open or NULL to create the audio file handle without opening the file. + // infoPtr A pointer to an audioFileInfo record to be filled when the file is open or NULL to ignore. + // rcPtr A pointer to a result code to be set in the event of a runtime error or NULL to ignore. + // rpt A pointer to a cmRpt_t object which error messages from this class will be directed to. + // Returns cmAudioFileH_t A new audio file handle. + // cmAudioFileH_t cmAudioFileNewOpen( const cmChar_t* fn, cmAudioFileInfo_t* infoPtr, cmRC_t* rcPtr, cmRpt_t* rpt ); - /// Open an audio file for writing + // Open an audio file for writing cmAudioFileH_t cmAudioFileNewCreate( const cmChar_t* fn, double srate, unsigned bits, unsigned chCnt, cmRC_t* rcPtr, cmRpt_t* rpt ); - /// Open an audio file for reading using a handle returned from an earlier call to audioFileNewXXX(). - /// - /// \param h A file handle returned from and earlier call to cmAudioFileNewOpen() or cmAudioFileNewCreate(). - /// \param fn The audio file name to open or NULL to create the audio file handle without opening the file. - /// \param infoPtr A pointer to an audioFileInfo record to be filled when the file is open or NULL to ignore. - /// \retval Returns an cmRC_t value indicating the success (kOkAfRC) or failure of the call. - /// - /// If the audio file handle 'h' refers to an open file then it is automatically closed prior to being - /// reopened with the new file. + // Open an audio file for reading using a handle returned from an earlier call to audioFileNewXXX(). + // + // h A file handle returned from and earlier call to cmAudioFileNewOpen() or cmAudioFileNewCreate(). + // fn The audio file name to open or NULL to create the audio file handle without opening the file. + // infoPtr A pointer to an audioFileInfo record to be filled when the file is open or NULL to ignore. + // Returns an cmRC_t value indicating the success (kOkAfRC) or failure of the call. + // + // If the audio file handle 'h' refers to an open file then it is automatically closed prior to being + // reopened with the new file. cmRC_t cmAudioFileOpen( cmAudioFileH_t h, const cmChar_t* fn, cmAudioFileInfo_t* infoPtr ); - /// Open an audio file for writing. The type of the audio file, AIF or WAV - /// is determined by the file name extension. + // Open an audio file for writing. The type of the audio file, AIF or WAV + // is determined by the file name extension. cmRC_t cmAudioFileCreate( - cmAudioFileH_t h, ///< Handle returned from an earlier call to cmAudioFileNewCreate() or cmAudioFileNewOpen(). - const cmChar_t* fn, ///< File name of the new file. - double srate, ///< Sample rate of the new file. - unsigned bits, ///< Sample word width for the new file in bits (must be 8,16,24 or 32). - unsigned chCnt ///< Audio channel count for the new file. + cmAudioFileH_t h, // Handle returned from an earlier call to cmAudioFileNewCreate() or cmAudioFileNewOpen(). + const cmChar_t* fn, // File name of the new file. + double srate, // Sample rate of the new file. + unsigned bits, // Sample word width for the new file in bits (must be 8,16,24 or 32). + unsigned chCnt // Audio channel count for the new file. ); - /// Close a the file associated with handle 'h' but do not release the handle. - /// If the file was opened for writing (cmAudioFileCreate()) then this function will - /// write the file header prior to closing the file. + // Close a the file associated with handle 'h' but do not release the handle. + // If the file was opened for writing (cmAudioFileCreate()) then this function will + // write the file header prior to closing the file. cmRC_t cmAudioFileClose( cmAudioFileH_t* h ); - /// Close the file associated with handle 'h' (via an internal call to - /// cmAudioFileClose()) and release the handle and any resources - /// associated with it. This is the complement to cmAudioFileOpen/Create(). + // Close the file associated with handle 'h' (via an internal call to + // cmAudioFileClose()) and release the handle and any resources + // associated with it. This is the complement to cmAudioFileOpen/Create(). cmRC_t cmAudioFileDelete( cmAudioFileH_t* h ); - /// Return true if the handle is not closed or deleted. + // Return true if the handle is not closed or deleted. bool cmAudioFileIsValid( cmAudioFileH_t h ); - /// Return true if the handle is open. + // Return true if the handle is open. bool cmAudioFileIsOpen( cmAudioFileH_t h ); - /// Return true if the current file position is at the end of the file. + // Return true if the current file position is at the end of the file. bool cmAudioFileIsEOF( cmAudioFileH_t h ); - /// Return the current file position as a frame index. + // Return the current file position as a frame index. unsigned cmAudioFileTell( cmAudioFileH_t h ); - /// Set the current file position as an offset from the first frame. + // Set the current file position as an offset from the first frame. cmRC_t cmAudioFileSeek( cmAudioFileH_t h, unsigned frmIdx ); - /// \name Sample Reading Functions. - ///@{ - /// Fill a user suppled buffer with up to frmCnt samples. - /// If less than frmCnt samples are available at the specified audio file location then the unused - /// buffer space is set to zero. Check *actualFrmCntPtr for the count of samples actually available - /// in the return buffer. Functions which do not include a begFrmIdx argument begin reading from - /// the current file location (see cmAudioFileSeek()). The buf argument is always a pointer to an - /// array of pointers of length chCnt. Each channel buffer specified in buf[] must contain at least - /// frmCnt samples. - /// - /// \param h An audio file handle returned from an earlier call to audioFileNew() - /// \param fn The name of the audio file to read. - /// \param begFrmIdx The frame index of the first sample to read. Functions that do not use this parameter begin reading at the current file location (See cmAudioFileTell()). - /// \param frmCnt The number of samples allocated in buf. - /// \param chIdx The index of the first channel to read. - /// \param chCnt The count of channels to read. - /// \param buf An array containing chCnt pointers to arrays of frmCnt samples. - /// \param actualFrmCntPtr The number of frames actually written to the return buffer (ignored if NULL) + // Sample Reading Functions. + // + // Fill a user suppled buffer with up to frmCnt samples. + // If less than frmCnt samples are available at the specified audio file location then the unused + // buffer space is set to zero. Check *actualFrmCntPtr for the count of samples actually available + // in the return buffer. Functions which do not include a begFrmIdx argument begin reading from + // the current file location (see cmAudioFileSeek()). The buf argument is always a pointer to an + // array of pointers of length chCnt. Each channel buffer specified in buf[] must contain at least + // frmCnt samples. + // + // + // h An audio file handle returned from an earlier call to audioFileNew() + // fn The name of the audio file to read. + // begFrmIdx The frame index of the first sample to read. Functions that do not use this parameter begin reading at the current file location (See cmAudioFileTell()). + // frmCnt The number of samples allocated in buf. + // chIdx The index of the first channel to read. + // chCnt The count of channels to read. + // buf An array containing chCnt pointers to arrays of frmCnt samples. + // actualFrmCntPtr The number of frames actually written to the return buffer (ignored if NULL) cmRC_t cmAudioFileReadInt( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr ); cmRC_t cmAudioFileReadFloat( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr ); @@ -191,10 +190,7 @@ extern "C" { cmRC_t cmAudioFileGetFloat( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt ); cmRC_t cmAudioFileGetDouble( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt ); - ///@} - - /// \name Sum the returned samples into the output buffer. - ///@{ + // Sum the returned samples into the output buffer. cmRC_t cmAudioFileReadSumInt( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr ); cmRC_t cmAudioFileReadSumFloat( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr ); cmRC_t cmAudioFileReadSumDouble( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr ); @@ -202,12 +198,8 @@ extern "C" { cmRC_t cmAudioFileGetSumInt( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt ); cmRC_t cmAudioFileGetSumFloat( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt ); cmRC_t cmAudioFileGetSumDouble( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt ); - ///@} - ///@} - - /// \name Sample Writing Functions - ///@{ + // Sample Writing Functions cmRC_t cmAudioFileWriteInt( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, int** bufPtrPtr ); cmRC_t cmAudioFileWriteFloat( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, float** bufPtrPtr ); cmRC_t cmAudioFileWriteDouble( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, double** bufPtrPtr ); @@ -215,14 +207,11 @@ extern "C" { cmRC_t cmAudioFileWriteFileInt( const char* fn, double srate, unsigned bit, unsigned frmCnt, unsigned chCnt, int** bufPtrPtr, cmRpt_t* rpt ); cmRC_t cmAudioFileWriteFileFloat( const char* fn, double srate, unsigned bit, unsigned frmCnt, unsigned chCnt, float** bufPtrPtr, cmRpt_t* rpt ); cmRC_t cmAudioFileWriteFileDouble( const char* fn, double srate, unsigned bit, unsigned frmCnt, unsigned chCnt, double** bufPtrPtr, cmRpt_t* rpt ); - ///@} - /// \name cmSample_t and cmReal_t Alias Macros - ///@{ - /// Alias the cmSample_t and cmReal_t sample reading and writing functions to the appropriate - /// type based on #CM_FLOAT_SMP and #CM_FLOAT_REAL. + // Alias the cmSample_t and cmReal_t sample reading and writing functions to the appropriate + // type based on #CM_FLOAT_SMP and #CM_FLOAT_REAL. #if CM_FLOAT_SMP == 1 @@ -263,51 +252,44 @@ extern "C" { #define cmAudioFileWriteFileReal cmAudioFileWriteFileDouble #endif - ///@} - /// \name Minimum, Maximum, Mean - ///@{ - /// Scan an entire audio file and return the minimum, maximum and mean sample value. - /// On error *minPtr, *maxPtr, and *meanPtr are set to -acSample_MAX, cmSample_MAX, and 0 respectively + // Scan an entire audio file and return the minimum, maximum and mean sample value. + // On error *minPtr, *maxPtr, and *meanPtr are set to -acSample_MAX, cmSample_MAX, and 0 respectively cmRC_t cmAudioFileMinMaxMean( cmAudioFileH_t h, unsigned chIdx, cmSample_t* minPtr, cmSample_t* maxPtr, cmSample_t* meanPtr ); cmRC_t cmAudioFileMinMaxMeanFn( const cmChar_t* fn, unsigned chIdx, cmSample_t* minPtr, cmSample_t* maxPtr, cmSample_t* meanPtr, cmRpt_t* rpt ); - ///@} - /// Return the file name associated with a audio file handle. + // Return the file name associated with a audio file handle. const cmChar_t* cmAudioFileName( cmAudioFileH_t h ); - /// Given an error code return the associated message. + // Given an error code return the associated message. const char* cmAudioFileErrorMsg( unsigned rc ); - /// \name Get information about an audio file - ///@{ - - /// Return the cmAudioFileInfo_t record associated with a file. + // Return the cmAudioFileInfo_t record associated with a file. cmRC_t cmAudioFileGetInfo( const cmChar_t* fn, cmAudioFileInfo_t* infoPtr, cmRpt_t* rpt ); - /// Print the cmAudioFileInfo_t to a file. + // Print the cmAudioFileInfo_t to a file. void cmAudioFilePrintInfo( const cmAudioFileInfo_t* infoPtr, cmRpt_t* ); - /// Print the file header information and frmCnt sample values beginning at frame index frmIdx. + // Print the file header information and frmCnt sample values beginning at frame index frmIdx. cmRC_t cmAudioFileReport( cmAudioFileH_t h, cmRpt_t* rpt, unsigned frmIdx, unsigned frmCnt ); - /// Print the file header information and frmCnt sample values beginning at frame index frmIdx. + // Print the file header information and frmCnt sample values beginning at frame index frmIdx. cmRC_t cmAudioFileReportFn( const cmChar_t* fn, unsigned frmIdx, unsigned frmCnt, cmRpt_t* rpt ); - ///@} - /// Change the sample rate value in the header. Note that this function does not resample the audio - /// signal it simply changes the value of the sample rate in the header. + // Change the sample rate value in the header. Note that this function does not resample the audio + // signal it simply changes the value of the sample rate in the header. cmRC_t cmAudioFileSetSrate( const cmChar_t* audioFn, unsigned srate ); // Generate a sine tone and write it to a file. cmRC_t cmAudioFileSine( cmCtx_t* ctx, const cmChar_t* fn, double srate, unsigned bits, double hz, double gain, double secs ); - /// Testing and example routine for functions in cmAudioFile.h. - /// Also see cmProcTest.c cmAudioFileReadWriteTest() + // Testing and example routine for functions in cmAudioFile.h. + // Also see cmProcTest.c cmAudioFileReadWriteTest() void cmAudioFileTest( cmCtx_t* ctx, int argc, const char* argv[] ); - + + //) #ifdef __cplusplus } diff --git a/cmAudioFileDev.h b/cmAudioFileDev.h index bb11852..137a528 100644 --- a/cmAudioFileDev.h +++ b/cmAudioFileDev.h @@ -1,6 +1,11 @@ #ifndef cmAudioFileDev_h #define cmAudioFileDev_h +#ifdef __cplusplus +extern "C" { +#endif + +//( { file_desc:"Implements cmAudioFileDev for reading and writing audio files under control of cmAudioPort.", kw:[audio file rt]} enum { kOkAfdRC = cmOkRC, @@ -72,4 +77,10 @@ void cmAudioFileDevReport( cmAfdH_t h, cmRpt_t* rpt ); void cmAudioFileDevTest( cmRpt_t* rpt ); +//) + +#ifdef __cplusplus +} +#endif + #endif diff --git a/cmAudioFileMgr.h b/cmAudioFileMgr.h index 5cfb9c1..9dde2b4 100644 --- a/cmAudioFileMgr.h +++ b/cmAudioFileMgr.h @@ -4,6 +4,9 @@ #ifdef __cplusplus extern "C" { #endif + + //( { file_desc:"Manages a collection of audio files and maintains downsampled copies of their signals." kw:[audio file] } + enum { kOkAfmRC = cmOkRC, @@ -56,7 +59,7 @@ extern "C" { bool cmAfmIsValid( cmAfmH_t h ); cmAfmFileH_t cmAfmIdToHandle( cmAfmH_t h, unsigned fileId ); - + //) #ifdef __cplusplus diff --git a/cmAudioNrtDev.h b/cmAudioNrtDev.h index cadae9c..cb3c553 100644 --- a/cmAudioNrtDev.h +++ b/cmAudioNrtDev.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Audio device driver which generates the callbacks to run cmAudioPort in a non-real time mode." kw:[audio rt]} + cmApRC_t cmApNrtAllocate( cmRpt_t* rpt ); cmApRC_t cmApNrtFree(); @@ -57,7 +59,8 @@ extern "C" { /// Return true if the device is currently started. bool cmApNrtDeviceIsStarted( unsigned devIdx ); - + //) + #ifdef __cplusplus } #endif diff --git a/cmAudioPort.h b/cmAudioPort.h index 711e343..21fe271 100644 --- a/cmAudioPort.h +++ b/cmAudioPort.h @@ -1,27 +1,24 @@ -/// \file cmAudioPort.h -/// \brief Cross platform audio I/O interface. -/// -/// This interface provides data declarations for platform dependent -/// audio I/O functions. The implementation for the functions are -/// in platform specific modules. See cmAudioPortOsx.c and cmAudioPortAlsa.c. -/// -/// ALSA Notes: -/// Assign capture device to line or mic input: -/// amixer -c 0 cset iface=MIXER,name='Input Source',index=0 Mic -/// amixer -c 0 cset iface=MIXER,name='Input Source',index=0 Line -/// -/// -c 0 select the first card -/// -iface=MIXER the cset is targetting the MIXER component -/// -name='Input Source',index=0 the control to set is the first 'Input Source' -/// Note that the 'Capture' control sets the input gain. -/// -/// See alsamixer for a GUI to accomplish the same thing. -/// -/// -/// Usage example and testing code: -/// See cmApPortTest() and cmAudioSysTest(). -/// \snippet cmAudioPort.c cmAudioPortExample -/// +//( { file_desc: "Cross platform audio device interface." kw:[audio rt] } +// +// This interface provides data declarations for platform dependent +// audio I/O functions. The implementation for the functions are +// in platform specific modules. See cmAudioPortOsx.c and cmAudioPortAlsa.c. +// +// ALSA Notes: +// Assign capture device to line or mic input: +// amixer -c 0 cset iface=MIXER,name='Input Source',index=0 Mic +// amixer -c 0 cset iface=MIXER,name='Input Source',index=0 Line +// +// -c 0 select the first card +// -iface=MIXER the cset is targetting the MIXER component +// -name='Input Source',index=0 the control to set is the first 'Input Source' +// Note that the 'Capture' control sets the input gain. +// +// See alsamixer for a GUI to accomplish the same thing. +// +// +//) + #ifndef cmAudioPort_h #define cmAudioPort_h @@ -29,8 +26,10 @@ extern "C" { #endif - typedef unsigned cmApRC_t; ///< Audio port interface result code. - typedef float cmApSample_t; ///< Audio sample type. + //( + + typedef unsigned cmApRC_t; // Audio port interface result code. + typedef float cmApSample_t; // Audio sample type. enum { @@ -45,81 +44,81 @@ extern "C" { // cmApAudioPacket_t flags enum { - kInterleavedApFl = 0x01, ///< The audio samples are interleaved. - kFloatApFl = 0x02 ///< The audio samples are single precision floating point values. + kInterleavedApFl = 0x01, // The audio samples are interleaved. + kFloatApFl = 0x02 // The audio samples are single precision floating point values. }; - /// Audio packet record used by the cmApAudioPacket_t callback. - /// Audio ports send and receive audio using this data structure. + // Audio packet record used by the cmApAudioPacket_t callback. + // Audio ports send and receive audio using this data structure. typedef struct { - unsigned devIdx; ///< device associated with packet - unsigned begChIdx; ///< first device channel - unsigned chCnt; ///< count of channels - unsigned audioFramesCnt; ///< samples per channel (see note below) - unsigned bitsPerSample; ///< bits per sample word - unsigned flags; ///< kInterleavedApFl | kFloatApFl - void* audioBytesPtr; ///< pointer to sample data - void* userCbPtr; ///< user defined value passed in cmApDeviceSetup() - cmTimeSpec_t timeStamp; ///< Packet time stamp. + unsigned devIdx; // device associated with packet + unsigned begChIdx; // first device channel + unsigned chCnt; // count of channels + unsigned audioFramesCnt; // samples per channel (see note below) + unsigned bitsPerSample; // bits per sample word + unsigned flags; // kInterleavedApFl | kFloatApFl + void* audioBytesPtr; // pointer to sample data + void* userCbPtr; // user defined value passed in cmApDeviceSetup() + cmTimeSpec_t timeStamp; // Packet time stamp. } cmApAudioPacket_t; - /// Audio port callback signature. - /// inPktArray[inPktCnt] are full packets of audio coming from the ADC to the application. - /// outPktArray[outPktCnt] are empty packets of audio which will be filled by the application - /// and then sent to the DAC. - /// - /// The value of audioFrameCnt gives the number of samples per channel which are available - /// in the packet data buffer 'audioBytesPtr'. The callback function may decrease this number in - /// output packets if the number of samples available is less than the size of the buffer. - /// It is the responsibility of the calling audio port to notice this change and pass the new, - /// decreased number of samples to the hardware. - /// - /// In general it should be assmed that this call is made from a system thread which is not - /// the same as the application thread. - /// The usual thread safety precautions should therefore be taken if this function implementation - /// interacts with data structures also handled by the application. The audio buffer class (\see cmApBuf.h) - /// is designed to provide a safe and efficient way to communicate between - /// the audio thread and the application. + // Audio port callback signature. + // inPktArray[inPktCnt] are full packets of audio coming from the ADC to the application. + // outPktArray[outPktCnt] are empty packets of audio which will be filled by the application + // and then sent to the DAC. + // + // The value of audioFrameCnt gives the number of samples per channel which are available + // in the packet data buffer 'audioBytesPtr'. The callback function may decrease this number in + // output packets if the number of samples available is less than the size of the buffer. + // It is the responsibility of the calling audio port to notice this change and pass the new, + // decreased number of samples to the hardware. + // + // In general it should be assmed that this call is made from a system thread which is not + // the same as the application thread. + // The usual thread safety precautions should therefore be taken if this function implementation + // interacts with data structures also handled by the application. The audio buffer class (\see cmApBuf.h) + // is designed to provide a safe and efficient way to communicate between + // the audio thread and the application. typedef void (*cmApCallbackPtr_t)( cmApAudioPacket_t* inPktArray, unsigned inPktCnt, cmApAudioPacket_t* outPktArray, unsigned outPktCnt ); - /// Setup the audio port management object for this machine. + // Setup the audio port management object for this machine. cmApRC_t cmApInitialize( cmRpt_t* rpt ); - /// Stop all audio devices and release any resources held - /// by the audio port management object. + // Stop all audio devices and release any resources held + // by the audio port management object. cmApRC_t cmApFinalize(); - /// Return the count of audio devices attached to this machine. + // Return the count of audio devices attached to this machine. unsigned cmApDeviceCount(); - /// Get a textual description of the device at index 'devIdx'. + // Get a textual description of the device at index 'devIdx'. const char* cmApDeviceLabel( unsigned devIdx ); - /// Given an audio device label return the associated device index. + // Given an audio device label return the associated device index. unsigned cmApDeviceLabelToIndex( const cmChar_t* label ); - /// Get the count of audio input or output channesl on device at index 'devIdx'. + // Get the count of audio input or output channesl on device at index 'devIdx'. unsigned cmApDeviceChannelCount( unsigned devIdx, bool inputFl ); - /// Get the current sample rate of a device. Note that if the device has both - /// input and output capability then the sample rate is the same for both. + // Get the current sample rate of a device. Note that if the device has both + // input and output capability then the sample rate is the same for both. double cmApDeviceSampleRate( unsigned devIdx ); - /// Get the count of samples per callback for the input or output for this device. + // Get the count of samples per callback for the input or output for this device. unsigned cmApDeviceFramesPerCycle( unsigned devIdx, bool inputFl ); - /// Configure a device. - /// All devices must be setup before they are started. - /// framesPerCycle is the requested number of samples per audio callback. The - /// actual number of samples made from a callback may be smaller. See the note - /// regarding this in cmApAudioPacket_t. - /// If the device cannot support the requested configuration then the function - /// will return an error code. - /// If the device is started when this function is called then it will be - /// automatically stopped and then restarted following the reconfiguration. - /// If the reconfiguration fails then the device may not be restared. + // Configure a device. + // All devices must be setup before they are started. + // framesPerCycle is the requested number of samples per audio callback. The + // actual number of samples made from a callback may be smaller. See the note + // regarding this in cmApAudioPacket_t. + // If the device cannot support the requested configuration then the function + // will return an error code. + // If the device is started when this function is called then it will be + // automatically stopped and then restarted following the reconfiguration. + // If the reconfiguration fails then the device may not be restared. cmApRC_t cmApDeviceSetup( unsigned devIdx, double srate, @@ -127,25 +126,26 @@ extern "C" { cmApCallbackPtr_t callbackPtr, void* userCbPtr ); - /// Start a device. Note that the callback may be made prior to this function returning. + // Start a device. Note that the callback may be made prior to this function returning. cmApRC_t cmApDeviceStart( unsigned devIdx ); - /// Stop a device. + // Stop a device. cmApRC_t cmApDeviceStop( unsigned devIdx ); - /// Return true if the device is currently started. + // Return true if the device is currently started. bool cmApDeviceIsStarted( unsigned devIdx ); - /// Print a report of all the current audio device configurations. + // Print a report of all the current audio device configurations. void cmApReport( cmRpt_t* rpt ); - /// Test the audio port by synthesizing a sine signal or passing audio through - /// from the input to the output. This is also a good example of how to - /// use all of the functions in the interface. - /// Set runFl to false to print a report without starting any audio devices. - /// See cmAudiotPortTest.c for usage example for this function. + // Test the audio port by synthesizing a sine signal or passing audio through + // from the input to the output. This is also a good example of how to + // use all of the functions in the interface. + // Set runFl to false to print a report without starting any audio devices. + // See cmAudiotPortTest.c for usage example for this function. int cmApPortTest(bool runFl, cmRpt_t* rpt, int argc, const char* argv[] ); + //) #ifdef __cplusplus } #endif diff --git a/cmAudioPortFile.h b/cmAudioPortFile.h index 9383983..6548928 100644 --- a/cmAudioPortFile.h +++ b/cmAudioPortFile.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"This is an audio device driver for cmAudioPort which supports reading and writing audio files as though they are real-time devices." kw[audio file rt] } + cmApRC_t cmApFileAllocate( cmRpt_t* rpt ); cmApRC_t cmApFileFree(); @@ -41,6 +43,8 @@ extern "C" { void cmApFileReport( cmRpt_t* rpt ); void cmApFileTest( cmRpt_t* rpt ); + //) + #ifdef __cplusplus } #endif diff --git a/cmAudioSys.h b/cmAudioSys.h index f125e00..a6b3246 100644 --- a/cmAudioSys.h +++ b/cmAudioSys.h @@ -1,5 +1,4 @@ -// cmAudioSys.h -// Implements a real-time audio processing engine. +//( { file_desc: "This is the kernel of a real-time audio processing engine." kw:[audio rt] } // // The audio system is composed a collection of independent sub-systems. // Each sub-system maintains a thread which runs asynchrounsly @@ -49,9 +48,7 @@ // delivered to the DSP procedure at the end of the DSP execution // procedure. // -// Usage example and testing code: -// See cmAudioSysTest(). -// \snippet cmAudioSys.c cmAudioSysTest +//) #ifndef cmAudioSys_h #define cmAudioSys_h @@ -59,7 +56,8 @@ #ifdef __cplusplus extern "C" { #endif - + + //( // Audio system result codes enum { @@ -296,7 +294,8 @@ extern "C" { // Audio system test and example function. void cmAudioSysTest( cmRpt_t* rpt, int argc, const char* argv[] ); - + //) + #ifdef __cplusplus } diff --git a/cmAudioSysMsg.h b/cmAudioSysMsg.h index d7b6efa..38c90b8 100644 --- a/cmAudioSysMsg.h +++ b/cmAudioSysMsg.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Constrants and data structures used to communicate messages to and from cmAudioSys" kw:[audio real_time]} + /// Reserved DSP message selector id's (second field of all host<->audio system messages) enum { @@ -112,7 +114,8 @@ extern "C" { } cmAudioSysStatus_t; - + //) + #ifdef __cplusplus } #endif diff --git a/cmComplexTypes.h b/cmComplexTypes.h index d715d89..c2e6742 100644 --- a/cmComplexTypes.h +++ b/cmComplexTypes.h @@ -1,9 +1,15 @@ #ifndef cmComplexTypes_h #define cmComplexTypes_h +#ifdef __cplusplus +extern "C" { +#endif + #include #include +//( { file_desc: "Constants and functions used for working with complex values." kw:[base math] } + #if CM_FLOAT_SMP == 1 #define cmCabsS cabsf @@ -95,5 +101,10 @@ void cmVOCR_Abs( cmSample_t* y, const cmComplexR_t* x, unsigned n ); void cmVOCR_MultVS( cmComplexR_t* y, cmReal_t v, unsigned n ); void cmVOCR_DivVS( cmComplexR_t* y, cmReal_t v, unsigned n ); +//) + +#ifdef __cplusplus +} +#endif #endif diff --git a/cmCsv.h b/cmCsv.h index f4901fc..1635f70 100644 --- a/cmCsv.h +++ b/cmCsv.h @@ -6,6 +6,8 @@ extern "C" { #endif + //( { file_desc:"Comma seperated value file reader and writer." kw[file] } + enum { kOkCsvRC = 0, @@ -146,6 +148,8 @@ extern "C" { cmCsvRC_t cmCsvPrint( cmCsvH_t h, unsigned rowCnt ); + //) + #ifdef __cplusplus } #endif diff --git a/cmCtx.h b/cmCtx.h index fc89c10..55e91a0 100644 --- a/cmCtx.h +++ b/cmCtx.h @@ -1,5 +1,6 @@ -//{ -//( + +//( { file_desc:"Global application context record." kw[base] } +// // cmCtx_t is used to hold application supplied cmRpt_t, cmErr_t and // other global values for easy distribution throughtout a cm based application. // @@ -44,8 +45,7 @@ extern "C" { unsigned mmFlags // Initialization flags used to configure \ref cmMallocDebug.h ); //) - //} - + #ifdef __cplusplus } #endif diff --git a/cmDList.h b/cmDList.h index aff47e1..2be3995 100644 --- a/cmDList.h +++ b/cmDList.h @@ -6,6 +6,8 @@ extern "C" { #endif + //( { file_desc:"Dynamic generic array with user programmable indexing and sorting capablity." kw:[container] } + enum { kOkDlRC = cmOkRC, @@ -86,7 +88,7 @@ extern "C" { // which this iterator is attached to. const void* cmDListIterFind( cmDListIterH_t iH, const void* key, unsigned keyN, unsigned* recdByteNRef); - + //) #ifdef __cplusplus } #endif diff --git a/cmDListTpl.h b/cmDListTpl.h index 50f089f..0448d92 100644 --- a/cmDListTpl.h +++ b/cmDListTpl.h @@ -1,4 +1,6 @@ +//( { file_desc:"Template 'include' code for using cmDList as a template." kw:[container] } + // The following two macros must be defined prior to including this code: // #define cmSFX(a) a##_MySuffix // #define cmTYPE My_Type @@ -117,6 +119,8 @@ const cmTYPE* cmSFX(cmDListIterFind)( cmDListIterH_t iH, const cmTYPE* key #endif // cmGEN_CODE +//) #undef cmSFX #undef cmTYPE + diff --git a/cmData.h b/cmData.h index aa54b72..6b01b9a 100644 --- a/cmData.h +++ b/cmData.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Generic, introspective, data structure." } + /* TODO: 0) Figure out an error handling scheme that does not rely on @@ -688,7 +690,7 @@ extern "C" { void cmDataPrint( const cmData_t* p, cmRpt_t* rpt ); void cmDataTest( cmCtx_t* ctx ); - + //) #ifdef __cplusplus } diff --git a/cmDevCfg.h b/cmDevCfg.h index d1989f8..f9e2fb5 100644 --- a/cmDevCfg.h +++ b/cmDevCfg.h @@ -4,6 +4,9 @@ #ifdef __cplusplus extern "C" { #endif + + //( { file_desc:"A class for managing persistent device configuration information." kw:[audio hardware] } + /* IMPLEMENTATION: 1) A 'cfg' record is a device reference with a 'cfg label'. @@ -210,7 +213,8 @@ extern "C" { // Set 'fn' to NULL to use filename from cmDevCfgAlloc() cmDcRC_t cmDevCfgWrite( cmDevCfgH_t h, const cmChar_t* fn ); - + //) + #ifdef __cplusplus } #endif diff --git a/cmErr.h b/cmErr.h index b23ef98..b172005 100644 --- a/cmErr.h +++ b/cmErr.h @@ -1,5 +1,5 @@ -//{ -//( +//( { file_desc:"Format error messages and track the last error generated." kw:[base]} +// // This class is used to format error messages and track the last error generated. // // Most of the cmHandle_t based classes use cmErr_t to format error messages with a @@ -75,7 +75,6 @@ extern "C" { cmRC_t cmErrClearRC( cmErr_t* err ); //) - //} #ifdef __cplusplus } diff --git a/cmExec.h b/cmExec.h index 60c69ec..5ecc234 100644 --- a/cmExec.h +++ b/cmExec.h @@ -6,6 +6,7 @@ extern "C" { #endif + //( file_desc:"Run a child process via 'execvp()'" kw[system] enum { kOkExRC, @@ -22,6 +23,8 @@ extern "C" { cmExRC_t cmExecV( cmErr_t* err, int* returnValRef, const cmChar_t* pgmFn, va_list vl ); cmExRC_t cmExec( cmErr_t* err, int* returnValRef, const cmChar_t* pgmFn, ... ); + //) + #ifdef __cplusplus } #endif diff --git a/cmFeatFile.c b/cmFeatFile.c index 0ceb58d..7e4b27e 100644 --- a/cmFeatFile.c +++ b/cmFeatFile.c @@ -2106,7 +2106,7 @@ cmFtRC_t cmFtReaderAdvance( cmFtFileH_t h, cmFtFrameDesc_t* fdp ) { if( rc == kOkFtRC ) { - fdp->smpIdx = frameDescPtr->time.sampleIdx; + fdp->smpIdx = frameDescPtr->tm.sampleIdx; fdp->frmIdx = cmFrameFileFrameLoadedIndex(fp->ffH); } else diff --git a/cmFeatFile.h b/cmFeatFile.h index 810838f..0647a11 100644 --- a/cmFeatFile.h +++ b/cmFeatFile.h @@ -1,7 +1,6 @@ -/// \file cmFeatFile.h -/// \brief Audio file acoustic feature analyzer and accompanying file reader. -/// -/// +//( { file_desc:" Audio file acoustic feature analyzer and accompanying file reader." kw:[audio analysis file]} +// +// #ifndef cmFeatFile_h #define cmFeatFile_h @@ -12,7 +11,7 @@ extern "C" { - /// Result codes for all functions in cmFeatFile.h + // Result codes for all functions in cmFeatFile.h enum { kOkFtRC = cmOkRC, @@ -36,241 +35,238 @@ extern "C" { kInvalidFrmIdxFtRC }; - /// Feature Id's + // Feature Id's enum { - kInvalidFtId, ///< 0 - kAmplFtId, ///< 1 Fourier transform amplitude - kDbAmplFtId, ///< 2 Fourier transform decibel - kPowFtId, ///< 3 Fourier transform power - kDbPowFtId, ///< 4 Fourier transform power decibel - kPhaseFtId, ///< 5 Fourier transform phase (not unwrapped) - kBfccFtId, ///< 6 Bark Frequency Cepstral Coeffcients - kMfccFtId, ///< 7 Mel Frequency Cepstral Coefficients - kCepsFtId, ///< 8 Cepstral Coefficients - kConstQFtId, ///< 9 Constant-Q transform - kLogConstQFtId, ///< 10 Log Constant-Q transform - kRmsFtId, ///< 11 Root means square of the audio signal - kDbRmsFtId, ///< 12 RMS in decibels + kInvalidFtId, // 0 + kAmplFtId, // 1 Fourier transform amplitude + kDbAmplFtId, // 2 Fourier transform decibel + kPowFtId, // 3 Fourier transform power + kDbPowFtId, // 4 Fourier transform power decibel + kPhaseFtId, // 5 Fourier transform phase (not unwrapped) + kBfccFtId, // 6 Bark Frequency Cepstral Coeffcients + kMfccFtId, // 7 Mel Frequency Cepstral Coefficients + kCepsFtId, // 8 Cepstral Coefficients + kConstQFtId, // 9 Constant-Q transform + kLogConstQFtId, // 10 Log Constant-Q transform + kRmsFtId, // 11 Root means square of the audio signal + kDbRmsFtId, // 12 RMS in decibels - kD1AmplFtId, ///< 13 1st order difference over time of the Fourier transform amplitude - kD1DbAmplFtId, ///< 14 1st order difference over time of the Fourier transform decibel - kD1PowFtId, ///< 15 1st order difference over time of the Fourier transform power - kD1DbPowFtId, ///< 16 1st order difference over time of the Fourier transform power decibel - kD1PhaseFtId, ///< 17 1st order difference over time of the Fourier transform phase (not unwrapped) - kD1BfccFtId, ///< 18 1st order difference over time of the Bark Frequency Cepstral Coeffcients - kD1MfccFtId, ///< 19 1st order difference over time of the Mel Frequency Cepstral Coefficients - kD1CepsFtId, ///< 20 1st order difference over time of the Cepstral Coefficients - kD1ConstQFtId, ///< 21 1st order difference over time of the Constant-Q transform - kD1LogConstQFtId, ///< 22 1st order difference over time of the Log Constant-Q transform - kD1RmsFtId, ///< 23 1st order difference over time of the Root means square of the audio signal - kD1DbRmsFtId, ///< 24 1st order difference over time of the RMS in decibels + kD1AmplFtId, // 13 1st order difference over time of the Fourier transform amplitude + kD1DbAmplFtId, // 14 1st order difference over time of the Fourier transform decibel + kD1PowFtId, // 15 1st order difference over time of the Fourier transform power + kD1DbPowFtId, // 16 1st order difference over time of the Fourier transform power decibel + kD1PhaseFtId, // 17 1st order difference over time of the Fourier transform phase (not unwrapped) + kD1BfccFtId, // 18 1st order difference over time of the Bark Frequency Cepstral Coeffcients + kD1MfccFtId, // 19 1st order difference over time of the Mel Frequency Cepstral Coefficients + kD1CepsFtId, // 20 1st order difference over time of the Cepstral Coefficients + kD1ConstQFtId, // 21 1st order difference over time of the Constant-Q transform + kD1LogConstQFtId, // 22 1st order difference over time of the Log Constant-Q transform + kD1RmsFtId, // 23 1st order difference over time of the Root means square of the audio signal + kD1DbRmsFtId, // 24 1st order difference over time of the RMS in decibels }; - /// User defined feature parameters + // User defined feature parameters typedef struct { - unsigned id; ///< feature id - unsigned cnt; ///< length of feature vector - bool normFl; ///< normalize this feature - bool enableFl; ///< true if this feature is enabled + unsigned id; // feature id + unsigned cnt; // length of feature vector + bool normFl; // normalize this feature + bool enableFl; // true if this feature is enabled } cmFtAttr_t; - /// Skip input audio range record + // Skip input audio range record typedef struct { - unsigned smpIdx; ///< Index of first sample to skip - unsigned smpCnt; ///< Count of successive samples to skip. + unsigned smpIdx; // Index of first sample to skip + unsigned smpCnt; // Count of successive samples to skip. } cmFtSkip_t; - /// Analysis parameters + // Analysis parameters typedef struct { - const char* audioFn; ///< Audio file name. - const char* featFn; ///< Feature file name. - unsigned chIdx; ///< Audio file channel index - cmReal_t wndMs; ///< Length of the analysis window in milliseconds. - unsigned hopFact; ///< Analysis window overlap factor 1 = 1:1 2=2:1 ... - bool normAudioFl; ///< Normalize the audio over the length of the audio file - cmMidiByte_t constQMinPitch; ///< Used to determine the base const-q octave. - cmMidiByte_t constQMaxPitch; ///< Used to determine the maximum const-q frequency of interest. - unsigned constQBinsPerOctave; ///< Bands per const-q octave. - unsigned onsetMedFiltWndSmpCnt; ///< Complex onset median filter - cmReal_t onsetThreshold; ///< Complex onset threshold - cmReal_t minDb; ///< Fourier Transform magnitude values below minDb are set to minDb. - cmReal_t floorThreshDb; ///< Frames with an RMS below this value will be skipped - cmFtSkip_t* skipArray; ///< skipArray[skipCnt] user defined sample skip ranges - unsigned skipCnt; ///< Count of records in skipArray[]. - cmFtAttr_t* attrArray; ///< attrArray[attrCnt] user defined parameter array - unsigned attrCnt; ///< Count of records in attrArray[]. + const char* audioFn; // Audio file name. + const char* featFn; // Feature file name. + unsigned chIdx; // Audio file channel index + cmReal_t wndMs; // Length of the analysis window in milliseconds. + unsigned hopFact; // Analysis window overlap factor 1 = 1:1 2=2:1 ... + bool normAudioFl; // Normalize the audio over the length of the audio file + cmMidiByte_t constQMinPitch; // Used to determine the base const-q octave. + cmMidiByte_t constQMaxPitch; // Used to determine the maximum const-q frequency of interest. + unsigned constQBinsPerOctave; // Bands per const-q octave. + unsigned onsetMedFiltWndSmpCnt; // Complex onset median filter + cmReal_t onsetThreshold; // Complex onset threshold + cmReal_t minDb; // Fourier Transform magnitude values below minDb are set to minDb. + cmReal_t floorThreshDb; // Frames with an RMS below this value will be skipped + cmFtSkip_t* skipArray; // skipArray[skipCnt] user defined sample skip ranges + unsigned skipCnt; // Count of records in skipArray[]. + cmFtAttr_t* attrArray; // attrArray[attrCnt] user defined parameter array + unsigned attrCnt; // Count of records in attrArray[]. } cmFtParam_t; - /// Feature summary information + // Feature summary information typedef struct { - unsigned id; ///< feature id (same as associated cmFtAttr.id) - unsigned cnt; ///< length of each feature vector (same as associated cmFtAttr.cnt) + unsigned id; // feature id (same as associated cmFtAttr.id) + unsigned cnt; // length of each feature vector (same as associated cmFtAttr.cnt) - /// The raw feature summary values are calculated prior to normalization. - cmReal_t* rawMinV; ///< Vector of min value over time for each feature element. - cmReal_t* rawMaxV; ///< Vector of max value over time for each feature element. - cmReal_t* rawAvgV; ///< Vector of avg value over time for each feature element. - cmReal_t* rawSdvV; ///< Vector of standard deviation values over time for each feature element. - cmReal_t rawMin; ///< Min value of all values for this feature. Equivalent to min(rawMinV). - cmReal_t rawMax; ///< Max value of all values for this feature. Equivalent to max(rawMaxV). + // The raw feature summary values are calculated prior to normalization. + cmReal_t* rawMinV; // Vector of min value over time for each feature element. + cmReal_t* rawMaxV; // Vector of max value over time for each feature element. + cmReal_t* rawAvgV; // Vector of avg value over time for each feature element. + cmReal_t* rawSdvV; // Vector of standard deviation values over time for each feature element. + cmReal_t rawMin; // Min value of all values for this feature. Equivalent to min(rawMinV). + cmReal_t rawMax; // Max value of all values for this feature. Equivalent to max(rawMaxV). - /// normalized feature summary values - cmReal_t* normMinV; ///< Vector of min value over time for each feature element. - cmReal_t* normMaxV; ///< Vector of max value over time for each feature element. - cmReal_t* normAvgV; ///< Vector of avg value over time for each feature element. - cmReal_t* normSdvV; ///< Vector of standard deviation values over time for each feature element. - cmReal_t normMin; ///< Min value of all values for this feature. Equivalent to min(normMinV). - cmReal_t normMax; ///< Max value of all values for this feature. Equivalent to max(rawMaxV). + // normalized feature summary values + cmReal_t* normMinV; // Vector of min value over time for each feature element. + cmReal_t* normMaxV; // Vector of max value over time for each feature element. + cmReal_t* normAvgV; // Vector of avg value over time for each feature element. + cmReal_t* normSdvV; // Vector of standard deviation values over time for each feature element. + cmReal_t normMin; // Min value of all values for this feature. Equivalent to min(normMinV). + cmReal_t normMax; // Max value of all values for this feature. Equivalent to max(rawMaxV). } cmFtSumm_t; - /// Feature file info record + // Feature file info record typedef struct { - unsigned frmCnt; ///< count of frames in the file - cmReal_t srate; ///< audio sample rate - unsigned smpCnt; ///< audio sample count - unsigned fftSmpCnt; ///< FFT window length (always power of 2) - unsigned hopSmpCnt; ///< audio sample hop count - unsigned binCnt; ///< FFT bin count (always fftSmpCnt/2 + 1) - unsigned skipFrmCnt; ///< count of frames skipped based on user skip array - unsigned floorFrmCnt; ///< count of frames skipped because below floorThreshDb - cmFtParam_t param; ///< analysis parameter record used to form this feature file - cmFtSumm_t* summArray; ///< summArray[ param.attrCnt ] feature summary information + unsigned frmCnt; // count of frames in the file + cmReal_t srate; // audio sample rate + unsigned smpCnt; // audio sample count + unsigned fftSmpCnt; // FFT window length (always power of 2) + unsigned hopSmpCnt; // audio sample hop count + unsigned binCnt; // FFT bin count (always fftSmpCnt/2 + 1) + unsigned skipFrmCnt; // count of frames skipped based on user skip array + unsigned floorFrmCnt; // count of frames skipped because below floorThreshDb + cmFtParam_t param; // analysis parameter record used to form this feature file + cmFtSumm_t* summArray; // summArray[ param.attrCnt ] feature summary information } cmFtInfo_t; - /// Data structure returned by cmFtReaderAdvance(). + // Data structure returned by cmFtReaderAdvance(). typedef struct { - unsigned smpIdx; ///< The audio signal sample index this frames information is based on. - unsigned frmIdx; ///< The frame index relative to other frames in this feature file. + unsigned smpIdx; // The audio signal sample index this frames information is based on. + unsigned frmIdx; // The frame index relative to other frames in this feature file. } cmFtFrameDesc_t; - typedef cmHandle_t cmFtH_t; ///< Analyzer handle - typedef cmHandle_t cmFtFileH_t; ///< Feature file handle. - typedef unsigned cmFtRC_t; ///< Result code type used by all functions in cmFeatFile.h. + typedef cmHandle_t cmFtH_t; // Analyzer handle + typedef cmHandle_t cmFtFileH_t; // Feature file handle. + typedef unsigned cmFtRC_t; // Result code type used by all functions in cmFeatFile.h. - extern cmFtH_t cmFtNullHandle; ///< A NULL handle useful for indicating an uninitialized analyzer. - extern cmFtFileH_t cmFtFileNullHandle; ///< A NULL handle useful for indicating an uninitialized feature file. + extern cmFtH_t cmFtNullHandle; // A NULL handle useful for indicating an uninitialized analyzer. + extern cmFtFileH_t cmFtFileNullHandle; // A NULL handle useful for indicating an uninitialized feature file. - /// Given a feature type id return the associated label. + // Given a feature type id return the associated label. const char* cmFtFeatIdToLabel( unsigned featId ); - /// Given a feature type label return the associated id. + // Given a feature type label return the associated id. unsigned cmFtFeatLabelToId( const char* label ); - /// \name Feature Analyzer Related functions - ///@{ + // Feature Analyzer Related functions - /// Initialize the feature analyzer. The memory manager and file system must - /// be initialized (cmMdInitialize(), cmFsInitialize()) prior to calling this function. + // Initialize the feature analyzer. The memory manager and file system must + // be initialized (cmMdInitialize(), cmFsInitialize()) prior to calling this function. cmFtRC_t cmFtInitialize( cmFtH_t* hp, cmCtx_t* ctx ); - /// Finalize a feature analyzer. + // Finalize a feature analyzer. cmFtRC_t cmFtFinalize( cmFtH_t* h ); - /// Return true if the handle represents an initialized feature analyzer. + // Return true if the handle represents an initialized feature analyzer. bool cmFtIsValid( cmFtH_t h ); - /// Parse a JSON file containing a set of analysis parameters. + // Parse a JSON file containing a set of analysis parameters. cmFtRC_t cmFtParse( cmFtH_t h, const char* cfgFn ); - /// Run the analyzer. + // Run the analyzer. cmFtRC_t cmFtAnalyze( cmFtH_t h ); - /// If cmFtAnalyze() is being run in a seperate thread this function - /// can be used to access the analyzers progress. + // If cmFtAnalyze() is being run in a seperate thread this function + // can be used to access the analyzers progress. const char* cmFtAnalyzeProgress( cmFtH_t h, unsigned* passPtr, cmReal_t* percentPtr ); - ///@} - /// \name Feature File Related Functions - ///@{ + // Feature File Related Functions - /// Open a feature file. - /// Note that inforPtrPtr is optional and will be ignored if it is set to NULL. + // Open a feature file. + // Note that inforPtrPtr is optional and will be ignored if it is set to NULL. cmFtRC_t cmFtReaderOpen( cmFtH_t h, cmFtFileH_t* hp, const char* featFn, const cmFtInfo_t** infoPtrPtr ); - /// Close a feature file. + // Close a feature file. cmFtRC_t cmFtReaderClose( cmFtFileH_t* hp ); - /// Return true if the handle reprents an open feature file. + // Return true if the handle reprents an open feature file. bool cmFtReaderIsValid( cmFtFileH_t h ); - /// Return the count of features types this file contains. + // Return the count of features types this file contains. unsigned cmFtReaderFeatCount( cmFtFileH_t h ); - /// Return the feature type id associated with the specified index. + // Return the feature type id associated with the specified index. unsigned cmFtReaderFeatId( cmFtFileH_t h, unsigned index ); - /// Reset the current file location to the first frame but do not load it. - /// The next call to cmFtReadAdvance() will load the next frame. + // Reset the current file location to the first frame but do not load it. + // The next call to cmFtReadAdvance() will load the next frame. cmFtRC_t cmFtReaderRewind( cmFtFileH_t h ); - /// Make frmIdx the current file location. + // Make frmIdx the current file location. cmFtRC_t cmFtReaderSeek( cmFtFileH_t h, unsigned frmIdx ); - /// Load the current frame, advance the current file position, and return - /// a pointer to a cmFtFrameDesc_t record for the loaded frame. - /// Returns kEofFtRC upon reaching end of file. - /// The frameDescPtr is optional. + // Load the current frame, advance the current file position, and return + // a pointer to a cmFtFrameDesc_t record for the loaded frame. + // Returns kEofFtRC upon reaching end of file. + // The frameDescPtr is optional. cmFtRC_t cmFtReaderAdvance( cmFtFileH_t h, cmFtFrameDesc_t* frameDescPtr ); - /// Returns a pointer to a data matrix in the feature identified by featId in the current feature frame. + // Returns a pointer to a data matrix in the feature identified by featId in the current feature frame. cmReal_t* cmFtReaderData( cmFtFileH_t h, unsigned featId, unsigned* cntPtr ); - /// Copy the contents of a given set of frames into buf[frmCnt*elePerFrmCnt]. + // Copy the contents of a given set of frames into buf[frmCnt*elePerFrmCnt]. cmFtRC_t cmFtReaderCopy( cmFtFileH_t h, unsigned featId, unsigned frmIdx, cmReal_t* buf, unsigned frmCnt, unsigned elePerFrmCnt, unsigned* outEleCntPtr ); - /// Data structure used to specify multiple features for use by cmFtReaderMultiSetup(). + // Data structure used to specify multiple features for use by cmFtReaderMultiSetup(). typedef struct { - unsigned featId; ///< Feature id of feature to include in the feature vector - unsigned cnt; ///< Set to count of feat ele's for this feat. Error if greater than avail. Set to -1 to use all avail ele's. - /// returned with actual count used + unsigned featId; // Feature id of feature to include in the feature vector + unsigned cnt; // Set to count of feat ele's for this feat. Error if greater than avail. Set to -1 to use all avail ele's. + // returned with actual count used - unsigned id0; ///< Ignored on input. Used internally by cmFtReaderXXX() - unsigned id1; ///< Ignored on input. Used internally by cmFtReaderXXX() + unsigned id0; // Ignored on input. Used internally by cmFtReaderXXX() + unsigned id1; // Ignored on input. Used internally by cmFtReaderXXX() } cmFtMulti_t; - /// Setup an array of cmFtMulti_t records. The cmFtMulti_t array - /// used by cmFtReaderMulitData() must be initialized by this function. + // Setup an array of cmFtMulti_t records. The cmFtMulti_t array + // used by cmFtReaderMulitData() must be initialized by this function. cmFtRC_t cmFtReaderMultiSetup( cmFtFileH_t h, cmFtMulti_t* multiArray, unsigned multiCnt, unsigned* featVectEleCntPtr ); - /// Fill outV[outN] with a consecutive data from the features specified in the cmFtMulti_t array. - /// Use cmFtReaderMultiSetup() to configure the cmFtMulti_t array prior to calling this function. + // Fill outV[outN] with a consecutive data from the features specified in the cmFtMulti_t array. + // Use cmFtReaderMultiSetup() to configure the cmFtMulti_t array prior to calling this function. cmFtRC_t cmFtReaderMultiData( cmFtFileH_t h, const cmFtMulti_t* multiArray, unsigned multiCnt, cmReal_t* outV, unsigned outN ); - /// Report summary information for the specified feature. + // Report summary information for the specified feature. cmFtRC_t cmFtReaderReport( cmFtFileH_t h, unsigned featId ); - /// Identical to cmFtReaderReport() except the feature file is identified from a file name rather than an open cmFtFileH_t. + // Identical to cmFtReaderReport() except the feature file is identified from a file name rather than an open cmFtFileH_t. cmFtRC_t cmFtReaderReportFn( cmFtH_t h, const cmChar_t* fn, unsigned featId ); - /// Report feature data for the specified set of feature frames. + // Report feature data for the specified set of feature frames. cmFtRC_t cmFtReaderReportFeature( cmFtFileH_t h, unsigned featId, unsigned frmIdx, unsigned frmCnt ); - /// Write a feature into a binary file. - /// Set 'frmCnt' to the cmInvalidCnt to include all frames past frmIdx. - /// The first three unsigned values in the output file - /// contain the row count, maximum column count, and the count of bytes in each data element (4=float,8=double). - /// Each row of the file begins with the count of elements in the row and is followed by a data array. + // Write a feature into a binary file. + // Set 'frmCnt' to the cmInvalidCnt to include all frames past frmIdx. + // The first three unsigned values in the output file + // contain the row count, maximum column count, and the count of bytes in each data element (4=float,8=double). + // Each row of the file begins with the count of elements in the row and is followed by a data array. cmFtRC_t cmFtReaderToBinary( cmFtFileH_t h, unsigned featId, unsigned frmIdx, unsigned frmCnt, const cmChar_t* outFn ); - /// Identical to cmFtReaderToBinary() except it takes a feature file name instead of a file handle. + // Identical to cmFtReaderToBinary() except it takes a feature file name instead of a file handle. cmFtRC_t cmFtReaderToBinaryFn( cmFtH_t h, const cmChar_t* fn, unsigned featId, unsigned frmIdx, unsigned frmCnt, const cmChar_t* outFn ); - ///@} + //) #ifdef __cplusplus } diff --git a/cmFile.c b/cmFile.c index 3640304..d3744a2 100644 --- a/cmFile.c +++ b/cmFile.c @@ -1,3 +1,4 @@ + #include "cmPrefix.h" #include "cmGlobal.h" #include "cmRpt.h" diff --git a/cmFile.h b/cmFile.h index bb97658..a49b8fe 100644 --- a/cmFile.h +++ b/cmFile.h @@ -1,9 +1,3 @@ -//{ -//( -// File abstraction class which slightly extends the C standard file handling routines -// to cm style error handling. -//) -// #ifndef cmFile_h #define cmFile_h @@ -11,7 +5,13 @@ extern "C" { #endif - //( + //( { file_desc: "File abstraction class." kw:[file system base]} + // + // The cmFile API extends the C standard file handling routines + // with cm style error handling. All cm file input and output occurs + // through this interface." + // + enum { kOkFileRC = cmOkRC, @@ -244,7 +244,6 @@ extern "C" { cmFileRC_t cmFileSetRC( cmFileH_t h, cmFileRC_t rc ); //) - //} #ifdef __cplusplus } diff --git a/cmFileSys.h b/cmFileSys.h index e8a6d88..df5109b 100644 --- a/cmFileSys.h +++ b/cmFileSys.h @@ -1,6 +1,5 @@ -//{ -//( -// A collection of file system utility functions. + +//( { file_desc:"A collection of file system utility functions." kw:[system file]} // // Note that cmFileSysInitialize() creates an internal cmLHeapH_t based // heap manager from which it allocates memory for some returned objects. @@ -242,7 +241,6 @@ extern "C" { cmFsRC_t cmFileSysTest( cmCtx_t* ctx ); //) - //} #ifdef __cplusplus } diff --git a/cmFloatTypes.h b/cmFloatTypes.h index 6dfc99c..9ba574a 100644 --- a/cmFloatTypes.h +++ b/cmFloatTypes.h @@ -1,16 +1,3 @@ -/// \file cmFloatTypes.h -/// \brief Declare the types cmReal_t and cmSample_t and define some useful limits. -/// -/// For signal processing functions the cm library uses the types cmSample_t to indicate an audio -/// sample value and cmReal_t to specify a general purpose floating point value. The library -/// is designed in such a way that the actual type, float or double, for these two types may -/// be set at compilation time. Set the preprocessor variable CM_FLOAT_SMP to 1 to indicate -/// that cmSample_t will be of type 'float' otherwise it will be of type 'double'. -/// Set the preprocessor variable CM_FLOAT_REAL to 1 to indicate -/// that cmSample_t will be of type 'float' otherwise it will be of type 'double'. -/// By default cmSample_t is float nad cmReal_t is double. -/// - #ifndef cmFloatTypes_h #define cmFloatTypes_h @@ -19,6 +6,18 @@ extern "C" { #endif + //( { file_desc:"Declare the types cmReal_t and cmSample_t and define some useful limits." kw:[base]} + // + // For signal processing functions the cm library uses the types cmSample_t to indicate an audio + // sample value and cmReal_t to specify a general purpose floating point value. The library + // is designed in such a way that the actual type, float or double, for these two types may + // be set at compilation time. Set the preprocessor variable CM_FLOAT_SMP to 1 to indicate + // that cmSample_t will be of type 'float' otherwise it will be of type 'double'. + // Set the preprocessor variable CM_FLOAT_REAL to 1 to indicate + // that cmSample_t will be of type 'float' otherwise it will be of type 'double'. + // By default cmSample_t is float nad cmReal_t is double. + // + //----------------------------------------------------------------- #ifndef CM_FLOAT_SMP #define CM_FLOAT_SMP 1 @@ -26,27 +25,27 @@ extern "C" { #if CM_FLOAT_SMP == 1 - typedef float cmSample_t; ///< cmSample_t is a float - typedef float _Complex cmComplexS_t;///< cmComplexS_t is single precision. + typedef float cmSample_t; // cmSample_t is a float + typedef float _Complex cmComplexS_t;// cmComplexS_t is single precision. -#define cmSample_EPSILON FLT_EPSILON ///< Minimum increment between 1.0 and the next greaterv value. (1E-5) -#define cmSample_MAX FLT_MAX ///< Maximum representable number (1E+37). -#define cmSample_MIN FLT_MIN ///< Minimum representable number (1E-37). +#define cmSample_EPSILON FLT_EPSILON // Minimum increment between 1.0 and the next greaterv value. (1E-5) +#define cmSample_MAX FLT_MAX // Maximum representable number (1E+37). +#define cmSample_MIN FLT_MIN // Minimum representable number (1E-37). #else - typedef double cmSample_t; ///< cmSample_t is a double - typedef double _Complex cmComplexS_t; ///< cmComplexS_t is doulbe precision. + typedef double cmSample_t; // cmSample_t is a double + typedef double _Complex cmComplexS_t; // cmComplexS_t is doulbe precision. -#define cmSample_EPSILON DBL_EPSILON ///< Minimum increment between 1.0 and the next greaterv value. (1E-9) -#define cmSample_MAX DBL_MAX ///< Maximum representable number (1E+37). -#define cmSample_MIN DBL_MIN ///< Minimum representable number (1E-37). +#define cmSample_EPSILON DBL_EPSILON // Minimum increment between 1.0 and the next greaterv value. (1E-9) +#define cmSample_MAX DBL_MAX // Maximum representable number (1E+37). +#define cmSample_MIN DBL_MIN // Minimum representable number (1E-37). #endif -//----------------------------------------------------------------- -//----------------------------------------------------------------- -//----------------------------------------------------------------- + //----------------------------------------------------------------- + //----------------------------------------------------------------- + //----------------------------------------------------------------- #ifndef CM_FLOAT_REAL #define CM_FLOAT_REAL 0 @@ -54,25 +53,27 @@ extern "C" { #if CM_FLOAT_REAL == 1 - typedef float cmReal_t; ///< cmReal_t is a float - typedef float _Complex cmComplexR_t; ///< cmComplexR_t is single precision. + typedef float cmReal_t; // cmReal_t is a float + typedef float _Complex cmComplexR_t; // cmComplexR_t is single precision. -#define cmReal_EPSILON FLT_EPSILON ///< Minimum increment between 1.0 and the next greaterv value. (1E-5) -#define cmReal_MAX FLT_MAX ///< Maximum representable number (1E+37). -#define cmReal_MIN FLT_MIN ///< Minimum representable number (1E-37). +#define cmReal_EPSILON FLT_EPSILON // Minimum increment between 1.0 and the next greaterv value. (1E-5) +#define cmReal_MAX FLT_MAX // Maximum representable number (1E+37). +#define cmReal_MIN FLT_MIN // Minimum representable number (1E-37). #else - typedef double cmReal_t; ///< cmReal_t is a double. - typedef double _Complex cmComplexR_t; ///< cmComplexR_t is double precision. + typedef double cmReal_t; // cmReal_t is a double. + typedef double _Complex cmComplexR_t; // cmComplexR_t is double precision. -#define cmReal_EPSILON DBL_EPSILON ///< Minimum increment between 1.0 and the next greaterv value (1E-9). -#define cmReal_MAX DBL_MAX ///< Maximum representable number (1E+37). -#define cmReal_MIN DBL_MIN ///< Minimum representable number (1E-37). +#define cmReal_EPSILON DBL_EPSILON // Minimum increment between 1.0 and the next greaterv value (1E-9). +#define cmReal_MAX DBL_MAX // Maximum representable number (1E+37). +#define cmReal_MIN DBL_MIN // Minimum representable number (1E-37). #endif + //) + #ifdef __cplusplus } #endif diff --git a/cmFrameFile.c b/cmFrameFile.c index 4346f98..fecb528 100644 --- a/cmFrameFile.c +++ b/cmFrameFile.c @@ -1031,7 +1031,7 @@ cmFfRC_t cmFrameFileFrameCreate( cmFrameFileH_t h, unsigned frameType, unsigned p->frame.f.mtxCnt = 0; p->frame.f.streamId = streamId; p->frame.f.flags = flags; - p->frame.f.time.seconds = 0; + p->frame.f.tm.seconds = 0; return rc; } @@ -1327,10 +1327,10 @@ cmFfRC_t cmFrameFileFrameNext( cmFrameFileH_t h, unsigned keyFrameTypeId, unsign return rc; if( cmIsFlag(p->frame.f.flags,kSampleIdxTimeFl) ) - p->frame.f.time.sampleIdx = sampleIdx; + p->frame.f.tm.sampleIdx = sampleIdx; if( cmIsFlag(p->frame.f.flags,kSecondsTimeFl) ) - p->frame.f.time.seconds = seconds; + p->frame.f.tm.seconds = seconds; return rc; diff --git a/cmFrameFile.h b/cmFrameFile.h index 4cbb00d..bcb137a 100644 --- a/cmFrameFile.h +++ b/cmFrameFile.h @@ -1,16 +1,17 @@ #ifndef cmFrameFile_h #define cmFrameFile_h -/* - file -> cmFfFile_t frame* - frame -> cmFfFrame_t mtx* - mtx -> cmFfMtx_t data* - */ - #ifdef __cplusplus extern "C" { #endif + //( { file_desc:"File reader and writer for time series data as used by cmFeatFile" kw:[file audio]} + // + // file -> cmFfFile_t frame* + // frame -> cmFfFrame_t mtx* + // mtx -> cmFfMtx_t data* + // + enum { @@ -139,7 +140,7 @@ extern "C" { { unsigned sampleIdx; double seconds; - } time; + } tm; } cmFfFrame_t; @@ -353,6 +354,8 @@ extern "C" { #define kRealFmtId kDoubleFmtId #endif + //) + #ifdef __cplusplus } #endif diff --git a/cmGlobal.h b/cmGlobal.h index fa589c6..7acbd42 100644 --- a/cmGlobal.h +++ b/cmGlobal.h @@ -1,15 +1,14 @@ -//{ -//( -// cmGlobal.h contains the global macros, header files, and -// typedefs availale to all other cm modules. + + +#ifndef cmGlobal_h +#define cmGlobal_h + +//( { file_desc:"This is the globally included prefix file for all 'cm' files." kw:[base] } // // All operating system dependencies should be resolved in this file via // testing for OS_LINUX, OS_OSX, or OS_W32. //) -#ifndef cmGlobal_h -#define cmGlobal_h - //( #include "config.h" // created by 'configure' #include @@ -150,6 +149,5 @@ extern "C" { #endif //) -//} #endif diff --git a/cmGnuPlot.h b/cmGnuPlot.h index af1f1bd..7f74083 100644 --- a/cmGnuPlot.h +++ b/cmGnuPlot.h @@ -1,85 +1,91 @@ #ifndef cmGnuPlot_h #define cmGnuPlot_h -enum -{ - kOkPlRC, - kSignalFailedPlRC, - kPipeFailedPlRC, - kForkFailedPlRC, - kExecFailedPlRC, - kPipeCloseFailedPlRC, - kPlotNotFoundPlRC, - kNoCurPlotPlRC, - kPlotDataFileFailPlRC, - kFopenFailedPlRC, - kFcloseFailedPlRC -}; +#ifdef __cplusplus +extern "C" { +#endif -enum -{ - kInvalidPlotPtId = 0x000, - kPlusPlotPtId = 0x001, - kXPlotPtId = 0x002, - kAsteriskPlotPtId = 0x003, - kSquarePlotPtId = 0x004, - kFillSquarePlotPtId = 0x005, - kCirclePlotPtId = 0x006, - kFillCirclePlotPtId = 0x007, - kTriPlotPtId = 0x008, - kFillTriPlotPtId = 0x009, - kInvTriPlotPtId = 0x00a, - kInvFillTriPlotPtId = 0x00b, - kDiamondPlotPtId = 0x00c, - kFillDiamonPlotPtId = 0x00d, - kPlotPtMask = 0x00f, -}; + //( { file_desc:"Interface to GNU Plot." kw:[plot]} + + enum + { + kOkPlRC, + kSignalFailedPlRC, + kPipeFailedPlRC, + kForkFailedPlRC, + kExecFailedPlRC, + kPipeCloseFailedPlRC, + kPlotNotFoundPlRC, + kNoCurPlotPlRC, + kPlotDataFileFailPlRC, + kFopenFailedPlRC, + kFcloseFailedPlRC + }; -enum -{ - kInvalidPlotLineId = 0x000, // -2 after translation - kSolidPlotLineId = 0x010, // -1 after translation - kDashPlotLineId = 0x020, // 0 after translation - kPlotLineMask = 0x0f0, - kPlotLineShift = 4 -}; + enum + { + kInvalidPlotPtId = 0x000, + kPlusPlotPtId = 0x001, + kXPlotPtId = 0x002, + kAsteriskPlotPtId = 0x003, + kSquarePlotPtId = 0x004, + kFillSquarePlotPtId = 0x005, + kCirclePlotPtId = 0x006, + kFillCirclePlotPtId = 0x007, + kTriPlotPtId = 0x008, + kFillTriPlotPtId = 0x009, + kInvTriPlotPtId = 0x00a, + kInvFillTriPlotPtId = 0x00b, + kDiamondPlotPtId = 0x00c, + kFillDiamonPlotPtId = 0x00d, + kPlotPtMask = 0x00f, + }; -enum -{ - kImpulsePlotFl = 0x100 -}; + enum + { + kInvalidPlotLineId = 0x000, // -2 after translation + kSolidPlotLineId = 0x010, // -1 after translation + kDashPlotLineId = 0x020, // 0 after translation + kPlotLineMask = 0x0f0, + kPlotLineShift = 4 + }; -/// Set terminal to NULL to use the default terminal. -cmRC_t cmPlotInitialize( const char* terminalStr ); + enum + { + kImpulsePlotFl = 0x100 + }; -// Combines initializaion and setup in a single call. -cmRC_t cmPlotInitialize2( const char* terminalStr, const char* title, unsigned rowCnt, unsigned colCnt ); + /// Set terminal to NULL to use the default terminal. + cmRC_t cmPlotInitialize( const char* terminalStr ); -cmRC_t cmPlotFinalize(); + // Combines initializaion and setup in a single call. + cmRC_t cmPlotInitialize2( const char* terminalStr, const char* title, unsigned rowCnt, unsigned colCnt ); -/// Setup the plot page -cmRC_t cmPlotSetup( const char* title, unsigned rowCnt, unsigned colCnt ); + cmRC_t cmPlotFinalize(); -/// Select sub-plot to apply subsequent commands to -cmRC_t cmPlotSelectSubPlot( unsigned ri, unsigned ci ); + /// Setup the plot page + cmRC_t cmPlotSetup( const char* title, unsigned rowCnt, unsigned colCnt ); -/// Clear the current current subplot -cmRC_t cmPlotClear(); + /// Select sub-plot to apply subsequent commands to + cmRC_t cmPlotSelectSubPlot( unsigned ri, unsigned ci ); -/// Set the labels on the current sub-plot -cmRC_t cmPlotSetLabels( const char* title, const char* xLabelStr, const char* yLabelStr, const char* zLabelStr ); + /// Clear the current current subplot + cmRC_t cmPlotClear(); -/// Set the default ranges for the x, y and z axes. To leave the ranges at their current values set the min and max to -1. -/// The range values are used to form data sets when data is not explicitely given. -cmRC_t cmPlotSetRange( double xMin, double xMax, double yMin, double yMax, double zMin, double zMax ); + /// Set the labels on the current sub-plot + cmRC_t cmPlotSetLabels( const char* title, const char* xLabelStr, const char* yLabelStr, const char* zLabelStr ); -/// If x or y is given as NULL then the values will be taken from the range settings xMin:xMax or yMin:yMax. -/// Use the gnuplot command:'test' to see the valid lineType and pointType values for a given terminal -/// Color string may be any of the predefined color labels: show palette colornames or and rgb value: e.g. #FF00FF -cmRC_t cmPlotLineF( const char* legendStr, const float* x, const float* y, const float* z, unsigned n, const char* colorStr, unsigned styleFlags ); -cmRC_t cmPlotLineD( const char* legendStr, const double* x, const double* y, const double* z, unsigned n, const char* colorStr, unsigned styleFlags ); + /// Set the default ranges for the x, y and z axes. To leave the ranges at their current values set the min and max to -1. + /// The range values are used to form data sets when data is not explicitely given. + cmRC_t cmPlotSetRange( double xMin, double xMax, double yMin, double yMax, double zMin, double zMax ); -cmRC_t cmPlotLineMD( const double* x, const double* y, const double* z, unsigned rn, unsigned cn, unsigned styleFlags ); + /// If x or y is given as NULL then the values will be taken from the range settings xMin:xMax or yMin:yMax. + /// Use the gnuplot command:'test' to see the valid lineType and pointType values for a given terminal + /// Color string may be any of the predefined color labels: show palette colornames or and rgb value: e.g. #FF00FF + cmRC_t cmPlotLineF( const char* legendStr, const float* x, const float* y, const float* z, unsigned n, const char* colorStr, unsigned styleFlags ); + cmRC_t cmPlotLineD( const char* legendStr, const double* x, const double* y, const double* z, unsigned n, const char* colorStr, unsigned styleFlags ); + + cmRC_t cmPlotLineMD( const double* x, const double* y, const double* z, unsigned rn, unsigned cn, unsigned styleFlags ); #if CM_FLOAT_SMP == 1 @@ -95,8 +101,14 @@ cmRC_t cmPlotLineMD( const double* x, const double* y, const double* z, unsigned #endif -cmRC_t cmPlotDraw(); -cmRC_t cmPlotPrint( bool printDataFl ); -cmRC_t cmPlotDrawAndPrint( bool printDataFl ); + cmRC_t cmPlotDraw(); + cmRC_t cmPlotPrint( bool printDataFl ); + cmRC_t cmPlotDrawAndPrint( bool printDataFl ); + + //) + +#ifdef __cplusplus +} +#endif #endif diff --git a/cmGr.h b/cmGr.h index 4fec8c9..d25f6c6 100644 --- a/cmGr.h +++ b/cmGr.h @@ -5,6 +5,7 @@ extern "C" { #endif + //( { file_desc:"Low level device independent API for descibing interactive graphics objects." kw:[plot] } enum { kAliceBlueGrId = 0xf0f8ff, @@ -867,6 +868,7 @@ extern "C" { void cmGrReport( cmGrH_t h, cmRpt_t* rpt ); + //) #ifdef __cplusplus } diff --git a/cmGrDevCtx.h b/cmGrDevCtx.h index 3893d09..dd1a8a1 100644 --- a/cmGrDevCtx.h +++ b/cmGrDevCtx.h @@ -4,7 +4,8 @@ #ifdef __cplusplus extern "C" { #endif - + //( { file_desc:"Device independent graphics context object used by cmGr." kw:[plot]} + enum { kOkGrDcRC = cmOkRC, @@ -195,6 +196,8 @@ extern "C" { // Is any of the rectangle visible in this drawing context. bool cmGrDcRectIsVisible( cmGrDcH_t h, const cmGrPExt_t* r ); + //) + #ifdef __cplusplus } #endif diff --git a/cmGrPage.h b/cmGrPage.h index 6d7fd40..034e5d8 100644 --- a/cmGrPage.h +++ b/cmGrPage.h @@ -4,6 +4,8 @@ #ifdef __cplusplus extern "C" { #endif + + //( { file_desc:"Device independent plotting window with one or more plot views." kw:[plot]} enum { @@ -74,7 +76,11 @@ extern "C" { const cmChar_t* cmGrPageLabelFuncLabel( cmGrPgH_t h, unsigned id ); void* cmGrPageLabelFuncArg( cmGrPgH_t h, unsigned id ); - + //---------------------------------------------------------------------------- + //) + //( { label:cmGrView file_desc:"Device independent plotting view." kw:[plot]} + // + // Get a view handle from the view index. cmGrVwH_t cmGrPageViewHandle( cmGrPgH_t h, unsigned vwIdx ); @@ -132,9 +138,14 @@ extern "C" { kSelH_VwId } cmGrViewValueId_t; const cmChar_t* cmGrViewValue( cmGrVwH_t h, cmGrViewValueId_t id, cmChar_t* buf, unsigned bufCharCnt ); - + // Get an axis handle. cmGrAxH_t cmGrViewAxisHandle( cmGrVwH_t h, cmGrAxisIdx_t axisIdx ); + + //---------------------------------------------------------------------------- + //) + //( { label:cmGrAxis file_desc:"Device independent plotting axis." kw:[plot]} + // bool cmGrAxisIsValid( cmGrAxH_t h ); // kHashMarkGrFl | kHashLabelGrFl @@ -161,6 +172,8 @@ extern "C" { // or cmGrPageLabelFuncIndexToId(). void cmGrAxisSetLabelFunc( cmGrAxH_t h, unsigned pgLabelFuncId ); + //) + #ifdef __cplusplus } #endif diff --git a/cmGrPlot.h b/cmGrPlot.h index b3f1c41..fbb1407 100644 --- a/cmGrPlot.h +++ b/cmGrPlot.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Device indenpendent, multi-axis, interactive, plotting system based on cmGrPage, cmGrAxis and cmGr." kw:[plot]} + enum { kOkGrPlRC, @@ -229,6 +231,7 @@ extern "C" { // Set the default object callback and arg. void cmGrPlotSetCb( cmGrPlH_t h, cmGrPlotCbFunc_t func, void* arg ); + //) #ifdef __cplusplus } diff --git a/cmGrPlotAudio.h b/cmGrPlotAudio.h index 0df091d..761c31e 100644 --- a/cmGrPlotAudio.h +++ b/cmGrPlotAudio.h @@ -6,12 +6,15 @@ extern "C" { #endif - + //( { file_desc:"Override a cmGrPlotObj to make an efficient audio plot object." kw:[plot audio]} + cmGrPlRC_t cmGrPlotAudioFileObjCreate( cmGrPlObjH_t oH, cmAfmFileH_t afH, unsigned audioChIdx ); + //) + #ifdef __cplusplus } #endif diff --git a/cmHashTbl.h b/cmHashTbl.h index 0b7cdff..3737756 100644 --- a/cmHashTbl.h +++ b/cmHashTbl.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Hash table for storing arbitary data blobs." kw:[container]} + enum { kOkHtRC, @@ -60,6 +62,8 @@ extern "C" { cmHtRC_t cmHashTblTest( cmCtx_t* ctx ); + //) + #ifdef __cplusplus } #endif diff --git a/cmJson.h b/cmJson.h index eafe350..61aaeb8 100644 --- a/cmJson.h +++ b/cmJson.h @@ -5,8 +5,8 @@ #ifdef __cplusplus extern "C" { #endif - //{ - //( + + //( { file_desc: "JSON reader and writer" kw:[file] } // // Limitations: // @@ -501,7 +501,6 @@ extern "C" { cmJsRC_t cmJsonTest( const char* fn, cmCtx_t* ctx ); //) - //} #ifdef __cplusplus } diff --git a/cmKeyboard.h b/cmKeyboard.h index cc2db66..13e9a93 100644 --- a/cmKeyboard.h +++ b/cmKeyboard.h @@ -1,66 +1,73 @@ #ifndef cmKeyboard_h #define cmKeyboard_h - -enum -{ - kInvalidKId, - kAsciiKId, - kLeftArrowKId, - kRightArrowKId, - kUpArrowKId, - kDownArrowKId, - kHomeKId, - kEndKId, - kPgUpKId, - kPgDownKId, - kInsertKId, - kDeleteKId, - -}; - - - - - -typedef struct -{ - unsigned code; - char ch; - bool ctlFl; - bool altFl; -} cmKbRecd; - -// Set 'p' to NULL if the value of the key is not required. -void cmKeyPress( cmKbRecd* p ); - - -// Return non-zero if a key is waiting to be read otherwise return 0. -// Use getchar() to pick up the key. -// -// Example: -// while( 1 ) -// { -// if( cmIsKeyWaiting() == 0 ) -// usleep(20000); -// else -// { -// char c = getchar(); -// switch(c) -// { -// .... -// } -// } -// -// } -// -// TODO: Note that this function turns off line-buffering on stdin. -// It should be changed to a three function sequence. -// bool org_state = cmSetStdinLineBuffering(false); -// .... -// cmIsKeyWaiting() -// .... -// cmSetStdinLineBuffering(org_state) -int cmIsKeyWaiting(); - +#ifdef __cplusplus +extern "C" { +#endif + + //( { file_desc:"Query and get keypresses directly from the console." kw:[system] } + + enum + { + kInvalidKId, + kAsciiKId, + kLeftArrowKId, + kRightArrowKId, + kUpArrowKId, + kDownArrowKId, + kHomeKId, + kEndKId, + kPgUpKId, + kPgDownKId, + kInsertKId, + kDeleteKId, + + }; + + typedef struct + { + unsigned code; + char ch; + bool ctlFl; + bool altFl; + } cmKbRecd; + + // Set 'p' to NULL if the value of the key is not required. + void cmKeyPress( cmKbRecd* p ); + + + // Return non-zero if a key is waiting to be read otherwise return 0. + // Use getchar() to pick up the key. + // + // Example: + // while( 1 ) + // { + // if( cmIsKeyWaiting() == 0 ) + // usleep(20000); + // else + // { + // char c = getchar(); + // switch(c) + // { + // .... + // } + // } + // + // } + // + // TODO: Note that this function turns off line-buffering on stdin. + // It should be changed to a three function sequence. + // bool org_state = cmSetStdinLineBuffering(false); + // .... + // cmIsKeyWaiting() + // .... + // cmSetStdinLineBuffering(org_state) + int cmIsKeyWaiting(); + + //) + +#ifdef __cplusplus + extern "C" { +#endif + #endif diff --git a/cmLex.c b/cmLex.c index 5f89e7c..f9dd88b 100644 --- a/cmLex.c +++ b/cmLex.c @@ -238,7 +238,8 @@ unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm { unsigned i = 0; bool signFl = false; - + unsigned digitCnt = 0; + for(; inextPtr = (char*)allocPtr; // ... then make it the space to alloc else lbp->freeCnt += *allocPtr; // ... otherwise increase the free count - //(freeCnt tracks unused space that is not at the end of the block and therefore cannot be reused.) + // freeCnt tracks unused space that is not at the end of the block and therefore cannot be reused. // if all the space for this block has been freed then the // next space to allocate must be at the base diff --git a/cmLinkedHeap.h b/cmLinkedHeap.h index 84753f7..59e0074 100644 --- a/cmLinkedHeap.h +++ b/cmLinkedHeap.h @@ -5,8 +5,18 @@ extern "C" { #endif - //{ + //( { file_desc:"Implements a block based memory heap manager." kw:[base]} + // + // There are two advantages to using this memory manager over the cmMallocDebug + // manager. It alleviates memory fragmentation by pre-allocating large blocks of memory + // which are then used to fullfill many small memory requests. Second it can + // act as a garbage collector by releasing all the memory it is managing at once. + // This can reduce code complexity by eliminating for a class instance to release internally + // allocated objects. + //) + //( + typedef cmHandle_t cmLHeapH_t; extern cmLHeapH_t cmLHeapNullHandle; @@ -84,7 +94,6 @@ extern "C" { #endif //) - //} #ifdef __cplusplus } diff --git a/cmMain.c b/cmMain.c index 214364e..1a5f81f 100644 --- a/cmMain.c +++ b/cmMain.c @@ -1,3 +1,5 @@ +//( { file_desc:"Template 'main.c' for 'libcm' based program" kw:[demo]} + #include "cmGlobal.h" #include "cmRpt.h" #include "cmMem.h" @@ -31,3 +33,5 @@ int main(int argc, char* argv[] ) cmMdFinalize(); return 0; } + +//) diff --git a/cmMallocDebug.h b/cmMallocDebug.h index eb55733..3ce1723 100644 --- a/cmMallocDebug.h +++ b/cmMallocDebug.h @@ -1,6 +1,11 @@ -//{ { label:cmMd } -//( -// Implements an extended memory allocation and tracking manager. +#ifndef cmMallocDebug_h +#define cmMallocDebug_h + +#ifdef __cplusplus +extern "C" { +#endif + +//( { file_desc:"Implements an extended memory allocation and tracking manager." kw:[base] } // // cmMallocDebug is a wrapper to cmMem.h for calls to malloc() and free(). // Most of the cmMdXXX() calls are directly associated with same named @@ -8,15 +13,8 @@ // cmMm object where malloc() and free() are the callback functions // provided to cmMmInitialize(). // -//) - -#ifndef cmMallocDebug_h -#define cmMallocDebug_h - -#ifdef __cplusplus -extern "C" { -#endif - //( +// + // Initialize the malloc debug manager. guardByteCnt, alignByteeCnt, flags, and rpt // are used to initialize an internal cmMm object. See cmMm for their semantics. cmMmRC_t cmMdInitialize( unsigned guardByteCnt, unsigned alignByteCnt, unsigned flags, cmRpt_t* rptPtr ); @@ -165,6 +163,4 @@ extern "C" { #endif -//} - #endif diff --git a/cmMath.h b/cmMath.h index b80716e..e50aeac 100644 --- a/cmMath.h +++ b/cmMath.h @@ -1,120 +1,132 @@ #ifndef cmMath_h #define cmMath_h -double cmX80ToDouble( unsigned char s[10] ); -void cmDoubleToX80( double v, unsigned char s[10] ); +#ifdef __cplusplus +extern "C" { +#endif -bool cmIsPowerOfTwo( unsigned i ); -unsigned cmNextPowerOfTwo( unsigned i ); -unsigned cmNearPowerOfTwo( unsigned i ); + //( { file_desc:"Math utility functions" kw:[math] } + + double cmX80ToDouble( unsigned char s[10] ); + void cmDoubleToX80( double v, unsigned char s[10] ); -bool cmIsOddU( unsigned v ); -bool cmIsEvenU( unsigned v ); -unsigned cmNextOddU( unsigned v ); -unsigned cmPrevOddU( unsigned v ); -unsigned cmNextEvenU( unsigned v ); -unsigned cmPrevEvenU( unsigned v ); + bool cmIsPowerOfTwo( unsigned i ); + unsigned cmNextPowerOfTwo( unsigned i ); + unsigned cmNearPowerOfTwo( unsigned i ); -/// Increment or decrement 'idx' by 'delta' always wrapping the result into the range -/// 0 to (maxN-1). -/// 'idx': initial value -/// 'delta': incremental amount -/// 'maxN' - 1 : maximum return value. -unsigned cmModIncr(int idx, int delta, int maxN ); + bool cmIsOddU( unsigned v ); + bool cmIsEvenU( unsigned v ); + unsigned cmNextOddU( unsigned v ); + unsigned cmPrevOddU( unsigned v ); + unsigned cmNextEvenU( unsigned v ); + unsigned cmPrevEvenU( unsigned v ); -// modified bessel function of first kind, order 0 -// ref: orfandis appendix B io.m -double cmBessel0( double x ); + /// Increment or decrement 'idx' by 'delta' always wrapping the result into the range + /// 0 to (maxN-1). + /// 'idx': initial value + /// 'delta': incremental amount + /// 'maxN' - 1 : maximum return value. + unsigned cmModIncr(int idx, int delta, int maxN ); + + // modified bessel function of first kind, order 0 + // ref: orfandis appendix B io.m + double cmBessel0( double x ); -//================================================================= -// The following elliptic-related function approximations come from -// Parks & Burrus, Digital Filter Design, Appendix program 9, pp. 317-326 -// which in turn draws directly on other sources + //================================================================= + // The following elliptic-related function approximations come from + // Parks & Burrus, Digital Filter Design, Appendix program 9, pp. 317-326 + // which in turn draws directly on other sources -// calculate complete elliptic integral (quarter period) K -// given *complimentary* modulus kc -cmReal_t cmEllipK( cmReal_t kc ); + // calculate complete elliptic integral (quarter period) K + // given *complimentary* modulus kc + cmReal_t cmEllipK( cmReal_t kc ); -// calculate elliptic modulus k -// given ratio of complete elliptic integrals r = K/K' -// (solves the "degree equation" for fixed N = K*K1'/K'K1) -cmReal_t cmEllipDeg( cmReal_t r ); + // calculate elliptic modulus k + // given ratio of complete elliptic integrals r = K/K' + // (solves the "degree equation" for fixed N = K*K1'/K'K1) + cmReal_t cmEllipDeg( cmReal_t r ); -// calculate arc elliptic tangent u (elliptic integral of the 1st kind) -// given argument x = sc(u,k) and *complimentary* modulus kc -cmReal_t cmEllipArcSc( cmReal_t x, cmReal_t kc ); + // calculate arc elliptic tangent u (elliptic integral of the 1st kind) + // given argument x = sc(u,k) and *complimentary* modulus kc + cmReal_t cmEllipArcSc( cmReal_t x, cmReal_t kc ); -// calculate Jacobi elliptic functions sn, cn, and dn -// given argument u and *complimentary* modulus kc -cmRC_t cmEllipJ( cmReal_t u, cmReal_t kc, cmReal_t* sn, cmReal_t* cn, cmReal_t* dn ); + // calculate Jacobi elliptic functions sn, cn, and dn + // given argument u and *complimentary* modulus kc + cmRC_t cmEllipJ( cmReal_t u, cmReal_t kc, cmReal_t* sn, cmReal_t* cn, cmReal_t* dn ); -//================================================================= -// bilinear transform -// z = (2*sr + s)/(2*sr - s) -cmRC_t cmBlt( unsigned n, cmReal_t sr, cmReal_t* rp, cmReal_t* ip ); + //================================================================= + // bilinear transform + // z = (2*sr + s)/(2*sr - s) + cmRC_t cmBlt( unsigned n, cmReal_t sr, cmReal_t* rp, cmReal_t* ip ); -//================================================================= -// Pitch conversion -unsigned cmHzToMidi( double hz ); -float cmMidiToHz( unsigned midi ); + //================================================================= + // Pitch conversion + unsigned cmHzToMidi( double hz ); + float cmMidiToHz( unsigned midi ); -//================================================================= -// Floating point byte swapping -unsigned cmFfSwapFloatToUInt( float v ); -float cmFfSwapUIntToFloat( unsigned v ); -unsigned long long cmFfSwapDoubleToULLong( double v ); -double cmFfSwapULLongToDouble( unsigned long long v ); + //================================================================= + // Floating point byte swapping + unsigned cmFfSwapFloatToUInt( float v ); + float cmFfSwapUIntToFloat( unsigned v ); + unsigned long long cmFfSwapDoubleToULLong( double v ); + double cmFfSwapULLongToDouble( unsigned long long v ); -//================================================================= -int cmRandInt( int min, int max ); -unsigned cmRandUInt( unsigned min, unsigned max ); -float cmRandFloat( float min, float max ); -double cmRandDouble( double min, double max ); + //================================================================= + int cmRandInt( int min, int max ); + unsigned cmRandUInt( unsigned min, unsigned max ); + float cmRandFloat( float min, float max ); + double cmRandDouble( double min, double max ); -//================================================================= -bool cmIsCloseD( double x0, double x1, double eps ); -bool cmIsCloseF( float x0, float x1, double eps ); -bool cmIsCloseI( int x0, int x1, double eps ); -bool cmIsCloseU( unsigned x0, unsigned x1, double eps ); + //================================================================= + bool cmIsCloseD( double x0, double x1, double eps ); + bool cmIsCloseF( float x0, float x1, double eps ); + bool cmIsCloseI( int x0, int x1, double eps ); + bool cmIsCloseU( unsigned x0, unsigned x1, double eps ); -//================================================================= -// Run a length 'lfsrN' linear feedback shift register (LFSR) for 'yN' iterations to -// produce a length 'yN' bit string in yV[yN]. -// 'lfsrN' count of bits in the shift register range: 2<= lfsrN <= 32. -// 'tapMask' is a bit mask which gives the tap indexes positions for the LFSR. -// The least significant bit corresponds to the maximum delay tap position. -// The min tap position is therefore denoted by the tap mask bit location 1 << (lfsrN-1). -// A minimum of two taps must exist. -// 'seed' sets the initial delay state. -// 'yV[yN]' is the the output vector -// 'yN' is count of elements in yV. -// The function resturn kOkAtRC on success or kInvalidArgsRCRC if any arguments are invalid. -// /sa cmLFSR_Test. -void cmLFSR( unsigned lfsrN, unsigned tapMask, unsigned seed, unsigned* yV, unsigned yN ); + //================================================================= + // Run a length 'lfsrN' linear feedback shift register (LFSR) for 'yN' iterations to + // produce a length 'yN' bit string in yV[yN]. + // 'lfsrN' count of bits in the shift register range: 2<= lfsrN <= 32. + // 'tapMask' is a bit mask which gives the tap indexes positions for the LFSR. + // The least significant bit corresponds to the maximum delay tap position. + // The min tap position is therefore denoted by the tap mask bit location 1 << (lfsrN-1). + // A minimum of two taps must exist. + // 'seed' sets the initial delay state. + // 'yV[yN]' is the the output vector + // 'yN' is count of elements in yV. + // The function resturn kOkAtRC on success or kInvalidArgsRCRC if any arguments are invalid. + // /sa cmLFSR_Test. + void cmLFSR( unsigned lfsrN, unsigned tapMask, unsigned seed, unsigned* yV, unsigned yN ); -// Example and test code for cmLFSR() -bool cmLFSR_Test(); + // Example and test code for cmLFSR() + bool cmLFSR_Test(); -// Generate a set of 'goldN' Gold codes using the Maximum Length Sequences (MLS) generated -// by a length 'lfsrN' linear feedback shift register. -// 'err' is an error object to be set if the the function fails. -// 'lfsrN' is the length of the Linear Feedback Shift Registers (LFSR) used to generate the MLS. -// 'poly_coeff0' tap mask for the first LFSR. -// 'coeff1' tap mask the the second LFSR. -// 'goldN' is the count of Gold codes to generate. -// 'yM[mlsN', goldN] is a column major output matrix where each column contains a Gold code. -// 'mlsN' is the length of the maximum length sequence for each Gold code which can be -// calculated as mlsN = (1 << a->lfsrN) - 1. -// Note that values of 'lfsrN' and the 'poly_coeffx' must be carefully selected such that -// they will produce a MLS. For example to generate a MLS with length 31 set 'lfsrN' to 5 and -// then select poly_coeff from two different elements of the set {0x12 0x14 0x17 0x1B 0x1D 0x1E}. -// See http://www.ece.cmu.edu/~koopman/lfsr/index.html for a complete set of MSL polynomial -// coefficients for given LFSR lengths. -// Returns false if insufficient balanced pairs exist. -bool cmGenGoldCodes( unsigned lfsrN, unsigned poly_coeff0, unsigned poly_coeff1, unsigned goldN, int* yM, unsigned mlsN ); + // Generate a set of 'goldN' Gold codes using the Maximum Length Sequences (MLS) generated + // by a length 'lfsrN' linear feedback shift register. + // 'err' is an error object to be set if the the function fails. + // 'lfsrN' is the length of the Linear Feedback Shift Registers (LFSR) used to generate the MLS. + // 'poly_coeff0' tap mask for the first LFSR. + // 'coeff1' tap mask the the second LFSR. + // 'goldN' is the count of Gold codes to generate. + // 'yM[mlsN', goldN] is a column major output matrix where each column contains a Gold code. + // 'mlsN' is the length of the maximum length sequence for each Gold code which can be + // calculated as mlsN = (1 << a->lfsrN) - 1. + // Note that values of 'lfsrN' and the 'poly_coeffx' must be carefully selected such that + // they will produce a MLS. For example to generate a MLS with length 31 set 'lfsrN' to 5 and + // then select poly_coeff from two different elements of the set {0x12 0x14 0x17 0x1B 0x1D 0x1E}. + // See http://www.ece.cmu.edu/~koopman/lfsr/index.html for a complete set of MSL polynomial + // coefficients for given LFSR lengths. + // Returns false if insufficient balanced pairs exist. + bool cmGenGoldCodes( unsigned lfsrN, unsigned poly_coeff0, unsigned poly_coeff1, unsigned goldN, int* yM, unsigned mlsN ); + + //) + +#ifdef __cplusplus +} +#endif #endif diff --git a/cmMem.h b/cmMem.h index 679dec2..3ad1055 100644 --- a/cmMem.h +++ b/cmMem.h @@ -1,6 +1,4 @@ -//{ -//( -// The cmMem class implements a memory allocation manager interface. +//( { file_desc: "Implements a memory allocation manager interface." kw:[ base ]} // // // Using cmMem allows memory leaks and some instances of memory corruption @@ -19,13 +17,16 @@ // 1. A client memory manager creates and configures a cmMm object via cmMmInitialize(). // As part of the configuration the client gives callback functions which implement // actual memory allocation and release. In practice this means the callback probably -// call malloc() or free(). +// call malloc() or free(). +// // 2. At some point later when the client needs to allocate a block of memory it calls // cmMmAllocate() with the size of the requested block. cmMm translates this request // into a call to the client provided memory allocation callback to get a block of raw // memory which is slightly larger than the request block. +// // 3. Given the raw memory block cmMm conditions it in the following ways and returns // it to the client. +// // * The base of the blocks data area is shifted such that it is has an arbitrary // address aligned according to the value set by the alignByteCnt parameter to cmMmInitialize(). // Address aligment is sometimes required by routines which make use of the the SIMD @@ -54,9 +55,11 @@ // writes to freed memory areas. When deferred release is enabled the freeFunc() is not called // on any blocks until cmMmFinalize(). If the program continually allocates memory over the // life of the program this may mean that the program will eventually exhaust physical memory. +// // 2. If tracking is enabled (kTrackMmFl) then the block pointer is looked up in the internal database. // If the pointer is not found then a kMissingRecdRC is returned indicating an attempt to release -// a non-allocated block. +// a non-allocated block. +// // 3. If tracking is enabled (kTrackMmFl) then the block is marked as released in the // internal tracking database. At the end of the program all blocks should be marked for release // otherwise they are considered leaks. @@ -223,7 +226,6 @@ extern "C" { cmMmRC_t cmMmCheckAllGuards( cmMmH_t h ); //) - //} #ifdef __cplusplus } #endif diff --git a/cmMidi.h b/cmMidi.h index 51373d4..b6b0da8 100644 --- a/cmMidi.h +++ b/cmMidi.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"MIDI utility constants and functions." kw:[midi]} + enum { kMidiChCnt = 16, @@ -154,6 +156,8 @@ extern "C" { // of this range will be returned as kInvalidMidiPitch. cmMidiByte_t cmSciPitchToMidi( const char* sciPitchStr ); + //) + #ifdef __cplusplus } #endif diff --git a/cmMidiFile.c b/cmMidiFile.c index dffd468..2476aa1 100644 --- a/cmMidiFile.c +++ b/cmMidiFile.c @@ -246,7 +246,7 @@ cmMfRC_t _cmMidiFileReadChannelMsg( _cmMidiFile_t* mfp, cmMidiByte_t* rsPtr, cmM tmp->byteCnt = sizeof(cmMidiChMsg_t); tmp->status = statusCh & 0xf0; p->ch = statusCh & 0x0f; - p->durTicks = 0; + p->durMicros = 0; unsigned byteN = cmMidiStatusToByteCount(tmp->status); @@ -416,8 +416,6 @@ cmMfRC_t _cmMidiFileReadHdr( _cmMidiFile_t* mfp ) int _cmMidiFileSortFunc( const void *p0, const void* p1 ) { - //printf("%i %i\n",(*(cmMidiTrackMsg_t**)p0)->dticks,(*(cmMidiTrackMsg_t**)p1)->dticks); - if( (*(cmMidiTrackMsg_t**)p0)->atick == (*(cmMidiTrackMsg_t**)p1)->atick ) return 0; @@ -526,12 +524,20 @@ cmMfRC_t cmMidiFileOpen( const char* fn, cmMidiFileH_t* hPtr, cmCtx_t* ctx ) // store a pointer to every trk msg in msgV[] // and convert tick to absolute tick mfp->nextUid = 0; + + double microsPerQN = 60000000/120; // default tempo; + double microsPerTick; + unsigned i = 0; for(trkIdx=0; trkIdxtrkN; ++trkIdx) { unsigned tick = 0; cmMidiTrackMsg_t* tmp = mfp->trkV[ trkIdx ].base; + + microsPerTick = microsPerQN / mfp->ticksPerQN; + + while( tmp != NULL ) { assert( i < mfp->msgN); @@ -540,6 +546,14 @@ cmMfRC_t cmMidiFileOpen( const char* fn, cmMidiFileH_t* hPtr, cmCtx_t* ctx ) tmp->atick = tick; tmp->uid = mfp->nextUid++; // assign the msg uid mfp->msgV[i] = tmp; + + // track tempo changes + if( tmp->status == kMetaStId && tmp->metaId == kTempoMdId ) + microsPerTick = tmp->u.iVal / mfp->ticksPerQN; + + // convert dtick to microseconds + tmp->dmicro = round(tmp->dtick * microsPerTick); + tmp = tmp->link; ++i; } @@ -548,6 +562,31 @@ cmMfRC_t cmMidiFileOpen( const char* fn, cmMidiFileH_t* hPtr, cmCtx_t* ctx ) // sort msgV[] in ascending order on atick qsort( mfp->msgV, mfp->msgN, sizeof(cmMidiTrackMsg_t*), _cmMidiFileSortFunc ); + // set the amicro field of each midi message to the + // absolute time offset in microseconds + unsigned mi; + unsigned amicro = 0; + microsPerTick = microsPerQN / mfp->ticksPerQN; + + for(mi=0; mimsgN; ++mi) + { + cmMidiTrackMsg_t* mp = mfp->msgV[mi]; + + // track tempo changes + if( mp->status == kMetaStId && mp->metaId == kTempoMdId ) + microsPerTick = mp->u.iVal / mfp->ticksPerQN; + + unsigned dtick = 0; + if( mi > 0 ) + { + assert( mp->atick >= mfp->msgV[mi-1]->atick ); + dtick = mp->atick - mfp->msgV[mi-1]->atick; + } + + amicro += round(microsPerTick*dtick); + mp->amicro = amicro; + } + //for(i=0; i<25; ++i) // printf("%i 0x%x 0x%x\n",mfp->msgV[i]->tick,mfp->msgV[i]->status,mfp->msgV[i]->metaId); @@ -1054,15 +1093,25 @@ unsigned cmMidiFileSeekUsecs( cmMidiFileH_t h, unsigned offsUSecs, unsigned* ms for(mi=0; mimsgN; ++mi) { const cmMidiTrackMsg_t* mp = p->msgV[mi]; - + /* if( mp->status == kMetaStId && mp->metaId == kTempoMdId ) microsPerTick = mp->u.iVal / p->ticksPerQN; - accUSecs += mp->dtick * microsPerTick ; + unsigned dtick = 0; + if( mi > 0 ) + { + assert( mp->atick >= p->msgV[mi-1]->atick ) + dtick = mp->atick - p->msgV[mi-1]->atick; + } + + accUSecs += dtick * microsPerTick ; if( accUSecs >= offsUSecs ) break; + */ + if( mp->amicro >= offsUSecs ) + break; } if( mi == p->msgN ) @@ -1080,92 +1129,17 @@ unsigned cmMidiFileSeekUsecs( cmMidiFileH_t h, unsigned offsUSecs, unsigned* ms double cmMidiFileDurSecs( cmMidiFileH_t h ) { _cmMidiFile_t* mfp = _cmMidiFileHandleToPtr(h); - unsigned mi; - double durSecs = 0; - double r = 1.0; //1000.0/(1000-.8); - double microsPerQN = r*60000000.0/120.0; - double microsPerTick = microsPerQN / mfp->ticksPerQN; - for(mi=0; mimsgN; ++mi) - { - cmMidiTrackMsg_t* mp = mfp->msgV[mi]; - - if( mp->status == kMetaStId && mp->metaId == kTempoMdId ) - microsPerTick = r*mp->u.iVal / mfp->ticksPerQN; - - // update the accumulated seconds - durSecs += (mp->dtick * microsPerTick) / 1000000.0; - - } - - return durSecs; -} - -void cmMidiFileTickToMicros( cmMidiFileH_t h ) -{ - _cmMidiFile_t* p; - - if((p = _cmMidiFileHandleToPtr(h)) == NULL ) - return; - - if( p->msgN == 0 ) - return; - - unsigned mi; - double r = 1.0; //1000.0/(1000-.8); - double microsPerQN = r*60000000/120; // default tempo - double microsPerTick = microsPerQN / p->ticksPerQN; - - for(mi=0; mimsgN; ++mi) - { - cmMidiTrackMsg_t* mp = p->msgV[mi]; - - if( mp->status == kMetaStId && mp->metaId == kTempoMdId ) - microsPerTick = r*mp->u.iVal / p->ticksPerQN; - - mp->dtick = round(microsPerTick*mp->dtick); - } + if( mfp->msgN == 0 ) + return 0; + return mfp->msgV[ mfp->msgN-1 ]->amicro / 1000000.0; } -void cmMidiFileTickToSamples( cmMidiFileH_t h, double srate, bool absFl ) -{ - _cmMidiFile_t* p; - - if((p = _cmMidiFileHandleToPtr(h)) == NULL ) - return; - - if( p->msgN == 0 ) - return; - - unsigned mi; - double r = 1.0; //1000.0/(1000-.8); - double microsPerQN = r*60000000/120; // default tempo - double microsPerTick = microsPerQN / p->ticksPerQN; - double absSmp = 0; - - for(mi=0; mimsgN; ++mi) - { - cmMidiTrackMsg_t* mp = p->msgV[mi]; - - if( mp->status == kMetaStId && mp->metaId == kTempoMdId ) - microsPerTick = r*mp->u.iVal / p->ticksPerQN; - - double delta = microsPerTick*mp->dtick*srate/1000000.0; - - absSmp += delta; - - mp->dtick = round(absFl ? absSmp : delta); - - } - -} - - typedef struct _cmMidiVoice_str { const cmMidiTrackMsg_t* mp; - unsigned durTicks; + unsigned durMicros; bool sustainFl; struct _cmMidiVoice_str* link; } _cmMidiVoice_t; @@ -1178,7 +1152,7 @@ void _cmMidFileCalcNoteDurationReleaseNote( _cmMidiVoice_t** listPtrPtr, _cmMidi // store the duration of the note into the track msg // assoc'd with the note-on msg cmMidiChMsg_t* cmp = (cmMidiChMsg_t*)vp->mp->u.chMsgPtr; // cast away const - cmp->durTicks = vp->durTicks; + cmp->durMicros = vp->durMicros; _cmMidiVoice_t* np = vp->link; @@ -1226,13 +1200,20 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h ) { cmMidiTrackMsg_t* mp = p->msgV[mi]; + unsigned d_amicro = 0; + if( mi > 0 ) + { + assert( mp->amicro >= p->msgV[mi-1]->amicro ); + d_amicro = mp->amicro - p->msgV[mi-1]->amicro; + } + // update the duration of the sounding notes for(vp = list; vp!=NULL; vp=vp->link) - vp->durTicks += mp->dtick; + vp->durMicros += d_amicro; // update the sustain pedal duration if( sustainPedalDownMsg != NULL ) - ((cmMidiChMsg_t*)(sustainPedalDownMsg->u.chMsgPtr))->durTicks += mp->dtick; // cast away const + ((cmMidiChMsg_t*)(sustainPedalDownMsg->u.chMsgPtr))->durMicros += d_amicro; // cast away const // // If this is sustain pedal msg @@ -1257,7 +1238,7 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h ) else { sustainPedalDownMsg = mp; - ((cmMidiChMsg_t*)(sustainPedalDownMsg->u.chMsgPtr))->durTicks = 0; // cast away const + ((cmMidiChMsg_t*)(sustainPedalDownMsg->u.chMsgPtr))->durMicros = 0; // cast away const } _cmMidiFileCalcNoteDurationsAllocVoice( &list, mp, true ); @@ -1389,16 +1370,51 @@ cmMidiTrackMsg_t* cmMidiFilePackTrackMsg( const cmMidiTrackMsg_t* m, void* b return (cmMidiTrackMsg_t*)buf; } - - -void cmMidiFilePrint( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt ) +void _cmMidiFilePrintHdr( const _cmMidiFile_t* mfp, cmRpt_t* rpt ) { - const _cmMidiFile_t* mfp = _cmMidiFileHandleToPtr(h); - if( mfp->fn != NULL ) cmRptPrintf(rpt,"%s ",mfp->fn); cmRptPrintf(rpt,"fmt:%i ticksPerQN:%i tracks:%i\n",mfp->fmtId,mfp->ticksPerQN,mfp->trkN); +} + +void _cmMidiFilePrintMsg( cmRpt_t* rpt, const cmMidiTrackMsg_t* tmp ) +{ + cmRptPrintf(rpt,"%8i %8i %8i %8i : ", tmp->dtick, tmp->dmicro, tmp->atick, tmp->amicro ); + + if( tmp->status == kMetaStId ) + cmRptPrintf(rpt,"%s ", cmMidiMetaStatusToLabel(tmp->metaId)); + else + { + cmRptPrintf(rpt,"%4s %3i %3i %3i", cmMidiStatusToLabel(tmp->status),tmp->u.chMsgPtr->ch,tmp->u.chMsgPtr->d0,tmp->u.chMsgPtr->d1); + + } + + cmRptPrintf(rpt,"\n"); +} + +void cmMidiFilePrintMsgs( cmMidiFileH_t h, cmRpt_t* rpt ) +{ + const _cmMidiFile_t* p = _cmMidiFileHandleToPtr(h); + unsigned mi; + + _cmMidiFilePrintHdr(p,rpt); + + for(mi=0; mimsgN; ++mi) + { + cmMidiTrackMsg_t* mp = p->msgV[mi]; + + if( mp != NULL ) + _cmMidiFilePrintMsg(rpt,mp); + } + +} + +void cmMidiFilePrintTracks( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt ) +{ + const _cmMidiFile_t* mfp = _cmMidiFileHandleToPtr(h); + + _cmMidiFilePrintHdr(mfp,rpt); int i = trkIdx == cmInvalidIdx ? 0 : trkIdx; int n = trkIdx == cmInvalidIdx ? mfp->trkN : trkIdx+1; @@ -1410,17 +1426,7 @@ void cmMidiFilePrint( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt ) cmMidiTrackMsg_t* tmp = mfp->trkV[i].base; while( tmp != NULL ) { - cmRptPrintf(rpt,"%5i ", tmp->dtick ); - - if( tmp->status == kMetaStId ) - cmRptPrintf(rpt,"%s ", cmMidiMetaStatusToLabel(tmp->metaId)); - else - { - cmRptPrintf(rpt,"%4s %3i %3i %3i", cmMidiStatusToLabel(tmp->status),tmp->u.chMsgPtr->ch,tmp->u.chMsgPtr->d0,tmp->u.chMsgPtr->d1); - - } - - cmRptPrintf(rpt,"\n"); + _cmMidiFilePrintMsg(rpt,tmp); tmp = tmp->link; } } @@ -1475,7 +1481,14 @@ void cmMidiFileTest( const char* fn, cmCtx_t* ctx ) return; } - if(1) + if( 1 ) + { + //cmMidiFileTickToMicros( h ); + //cmMidiFileTickToSamples(h,96000,false); + cmMidiFilePrintMsgs(h,&ctx->rpt); + } + + if( 0 ) { //cmMidiFilePrint(h,cmMidiFileTrackCount(h)-1,&ctx->rpt); //cmMidiFilePrint(h,cmInvalidIdx,&ctx->rpt); diff --git a/cmMidiFile.h b/cmMidiFile.h index 088cbc4..7dfcd93 100644 --- a/cmMidiFile.h +++ b/cmMidiFile.h @@ -5,6 +5,7 @@ extern "C" { #endif + //( { file_desc:"MIDI file reader and writer." kw:[midi file]} // MIDI file timing: // Messages in the MIDI file are time tagged with a delta offset in 'ticks' // from the previous message in the same track. @@ -22,9 +23,9 @@ extern "C" { // // As part of the file reading process, the status byte of note-on messages // with velocity=0 are is changed to a note-off message. See _cmMidiFileReadChannelMsg(). - - - + //) + + //( typedef cmHandle_t cmMidiFileH_t; typedef unsigned cmMfRC_t; @@ -56,15 +57,17 @@ extern "C" { cmMidiByte_t ch; cmMidiByte_t d0; cmMidiByte_t d1; - unsigned durTicks; // note duration calc'd by cmMidiFileCalcNoteDurations(); + unsigned durMicros; // note duration in microseconds (corrected for tempo changes) } cmMidiChMsg_t; typedef struct cmMidiTrackMsg_str { unsigned uid; // uid's are unique among all msg's in the file - unsigned dtick; // delta ticks - unsigned atick; // accumulated ticks + unsigned dtick; // delta ticks between events on this track + unsigned dmicro; // delta microseconds between events on this track adjusted for tempo changes + unsigned atick; // global (all tracks interleaved) accumulated ticks + unsigned amicro; // global (all tracks interleaved) accumulated microseconds adjusted for tempo changes cmMidiByte_t status; // ch msg's have the channel value removed (it is stored in u.chMsgPtr->ch) cmMidiByte_t metaId; // unsigned short trkIdx; // @@ -152,13 +155,6 @@ extern "C" { double cmMidiFileDurSecs( cmMidiFileH_t h ); - // Convert the track message 'dtick' field to delta-microseconds. - void cmMidiFileTickToMicros( cmMidiFileH_t h ); - - // Convert the track message 'dtick' field to samples. - // If the absFl is set then the delta times are converted to absolute time. - void cmMidiFileTickToSamples( cmMidiFileH_t h, double srate, bool absFl ); - // Calculate Note Duration void cmMidiFileCalcNoteDurations( cmMidiFileH_t h ); @@ -171,10 +167,13 @@ extern "C" { cmMidiTrackMsg_t* cmMidiFilePackTrackMsg( const cmMidiTrackMsg_t* m, void* buf, unsigned bufByteCnt ); unsigned cmMidiFilePackTrackMsgBufByteCount( const cmMidiTrackMsg_t* m ); - void cmMidiFilePrint( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt ); + void cmMidiFilePrintMsgs( cmMidiFileH_t h, cmRpt_t* rpt ); + void cmMidiFilePrintTrack( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt ); bool cmMidiFileIsNull( cmMidiFileH_t h ); void cmMidiFileTest( const char* fn, cmCtx_t* ctx ); + //) + #ifdef __cplusplus } #endif diff --git a/cmMidiFilePlay.c b/cmMidiFilePlay.c index f1b0457..56b1ea4 100644 --- a/cmMidiFilePlay.c +++ b/cmMidiFilePlay.c @@ -148,9 +148,6 @@ cmMfpRC_t cmMfpLoadHandle( cmMfpH_t h, cmMidiFileH_t mfH ) p->mtime = 0; p->closeFileFl= false; - //if( p->msgIdx > 0 ) - // p->mtime = p->msgV[0]->tick * p->microsPerTick; - return kOkMfpRC; } @@ -213,35 +210,31 @@ cmMfpRC_t cmMfpClock( cmMfpH_t h, unsigned dusecs ) // sent and the end of the time window for this mfpClock() cycle p->etime += dusecs; - //printf("init e:%i d:%i\n",p->etime, p->mtime); - // if the elapsed time (etime) since the last msg is greater or equal // to the delta time to the next msg (mtime) while( p->etime >= p->mtime ) { - //printf("e:%i d:%i\n",p->etime, p->mtime); - if( mp->status == kMetaStId && mp->metaId == kTempoMdId ) - _cmMfpUpdateMicrosPerTick(p,mp->u.iVal ); - - + // send the current message p->cbFunc( p->userCbPtr, p->mtime, mp ); - + + unsigned amicro = mp->amicro; + ++(p->msgIdx); if( p->msgIdx >= p->msgN ) break; // get the next msg to send - mp = p->msgV[p->msgIdx]; + mp = p->msgV[p->msgIdx]; + // we probably went past the actual mtime - so update etime // with the delta usecs from the msg just sent and the current time p->etime -= p->mtime; // calc the delta usecs from the message just sent to the next msg to send - //p->mtime = (mp->tick - p->msgV[p->msgIdx-1]->tick) * p->microsPerTick; - p->mtime = mp->dtick * p->microsPerTick; + p->mtime = mp->amicro - amicro; } diff --git a/cmMidiFilePlay.h b/cmMidiFilePlay.h index 35afbad..ace61d7 100644 --- a/cmMidiFilePlay.h +++ b/cmMidiFilePlay.h @@ -5,53 +5,57 @@ extern "C" { #endif -typedef cmHandle_t cmMfpH_t; -typedef cmRC_t cmMfpRC_t; - -typedef void (*cmMfpCallback_t)( void* userCbPtr, unsigned dmicros, const cmMidiTrackMsg_t* msgPtr ); - -enum -{ - kOkMfpRC = cmOkRC, // 0 - kInvalidHandleMfpRC, // 1 - kFileOpenFailMfpRC, // 2 - kInvalidFileMfpRC, // 3 - kMemAllocFailMfpRC, // 4 - kSmpteTickNotImpleMfpRC, // 5 - kEndOfFileMfpRC, // 6 - kSmpteTickNotImplMfpRC // 7 + //( { file_desc:"Device indepenent MIDI file player." kw:[midi]} -}; + typedef cmHandle_t cmMfpH_t; + typedef cmRC_t cmMfpRC_t; -extern cmMfpH_t cmMfpNullHandle; + typedef void (*cmMfpCallback_t)( void* userCbPtr, unsigned dmicros, const cmMidiTrackMsg_t* msgPtr ); -cmMfpRC_t cmMfpCreate( cmMfpH_t* hp, cmMfpCallback_t cbFunc, void* userCbPtr, cmCtx_t* ctx ); -cmMfpRC_t cmMfpDestroy( cmMfpH_t* hp ); -bool cmMfpIsValid( cmMfpH_t h ); + enum + { + kOkMfpRC = cmOkRC, // 0 + kInvalidHandleMfpRC, // 1 + kFileOpenFailMfpRC, // 2 + kInvalidFileMfpRC, // 3 + kMemAllocFailMfpRC, // 4 + kSmpteTickNotImpleMfpRC, // 5 + kEndOfFileMfpRC, // 6 + kSmpteTickNotImplMfpRC // 7 + + }; -// Load a MIDI file into the player. This MIDI file will be automatically -// closed when a new file is loaded at a later time or the MIDI file player handle is destroyed. -cmMfpRC_t cmMfpLoadFile( cmMfpH_t h, const char* fn ); + extern cmMfpH_t cmMfpNullHandle; -// Load a MIDI file into the player using a file owned by the host. -// This file will NOT be closed when a new file is loaded at a later time -// or the MIDI file player handle is destroyed. -cmMfpRC_t cmMfpLoadHandle( cmMfpH_t h, cmMidiFileH_t mfH ); + cmMfpRC_t cmMfpCreate( cmMfpH_t* hp, cmMfpCallback_t cbFunc, void* userCbPtr, cmCtx_t* ctx ); + cmMfpRC_t cmMfpDestroy( cmMfpH_t* hp ); + bool cmMfpIsValid( cmMfpH_t h ); -// Reset the play position of the player to an offset in microseconds from -// the beginning of the file. If there are no message at or after 'offsMicrosecs' -// then the function will return kEndOfFileMfpRC. -cmMfpRC_t cmMfpSeek( cmMfpH_t h, unsigned offsMicrosecs ); + // Load a MIDI file into the player. This MIDI file will be automatically + // closed when a new file is loaded at a later time or the MIDI file player handle is destroyed. + cmMfpRC_t cmMfpLoadFile( cmMfpH_t h, const char* fn ); -// This is the driving clock call for the player. 'deltaMicroSecs' is the -// elapsed time in microseconds since the last call to this function. -// Call to 'cbFunc', as set in by cmMfpCreate() occur from this function. -cmMfpRC_t cmMfpClock( cmMfpH_t h, unsigned deltaMicroSecs ); + // Load a MIDI file into the player using a file owned by the host. + // This file will NOT be closed when a new file is loaded at a later time + // or the MIDI file player handle is destroyed. + cmMfpRC_t cmMfpLoadHandle( cmMfpH_t h, cmMidiFileH_t mfH ); -cmMfpRC_t cmMfpTest( const char* fn, cmCtx_t* ctx ); + // Reset the play position of the player to an offset in microseconds from + // the beginning of the file. If there are no message at or after 'offsMicrosecs' + // then the function will return kEndOfFileMfpRC. + cmMfpRC_t cmMfpSeek( cmMfpH_t h, unsigned offsMicrosecs ); -cmRC_t cmMfpTest2( const char* midiFn, const char* audioFn, cmCtx_t* ctx ); + // This is the driving clock call for the player. 'deltaMicroSecs' is the + // elapsed time in microseconds since the last call to this function. + // Call to 'cbFunc', as set in by cmMfpCreate() occur from this function. + cmMfpRC_t cmMfpClock( cmMfpH_t h, unsigned deltaMicroSecs ); + cmMfpRC_t cmMfpTest( const char* fn, cmCtx_t* ctx ); + + cmRC_t cmMfpTest2( const char* midiFn, const char* audioFn, cmCtx_t* ctx ); + + //) + #ifdef __cplusplus } #endif diff --git a/cmMidiPort.h b/cmMidiPort.h index 96283c4..bb4a2aa 100644 --- a/cmMidiPort.h +++ b/cmMidiPort.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Device independent MIDI port related code." kw:[midi]} + typedef unsigned cmMpRC_t; // Flags used to identify input and output ports on MIDI devices @@ -30,7 +32,9 @@ extern "C" { }; typedef void (*cmMpCallback_t)( const cmMidiPacket_t* pktArray, unsigned pktCnt ); - + + //) + //( { label:cmMpParser file_desc:"MIDI event parser converts raw MIDI events into cmMidiPacket_t messages." kw:[midi]} //=============================================================================================== // MIDI Parser @@ -62,6 +66,8 @@ extern "C" { // Returns true if the parser uses the given callback. bool cmMpParserHasCallback( cmMpParserH_t h, cmMpCallback_t cbFunc, void* cbDataPtr ); + //) + //( { label:cmMidiPort file_desc:"Device independent MIDI port." kw:[midi]} //=============================================================================================== // MIDI Device Interface @@ -92,7 +98,8 @@ extern "C" { void cmMpReport( cmRpt_t* rpt ); void cmMpTest( cmCtx_t* ctx ); - + //) + #ifdef __cplusplus } #endif diff --git a/cmMsgProtocol.h b/cmMsgProtocol.h index 18128c4..1c7854a 100644 --- a/cmMsgProtocol.h +++ b/cmMsgProtocol.h @@ -7,6 +7,7 @@ extern "C" { #endif + //( { file_desc:"Global constants and data structures for transmiting messages between threads and network nodes.", kw:[real_time]} #define cmAudDspSys_FILENAME "aud_dsp.js" @@ -134,6 +135,8 @@ extern "C" { cmMsgRC_t cmMsgPeekInstId( const void* msgArray[], unsigned msgByteCntArray[], unsigned segCnt, unsigned* retValPtr ); cmMsgRC_t cmMsgPeekInstVarId( const void* msgArray[], unsigned msgByteCntArray[], unsigned segCnt, unsigned* retValPtr ); + //) + #ifdef __cplusplus } #endif diff --git a/cmPgmOpts.c b/cmPgmOpts.c index 9f13d0b..8c0d703 100644 --- a/cmPgmOpts.c +++ b/cmPgmOpts.c @@ -1250,7 +1250,7 @@ void cmPgmOptPrintHelp( cmPgmOptH_t h, cmRpt_t* rpt ) reqLabel = reqStr; if( mstr != NULL ) - cmRptPrintf(rpt,"Enumerated group: %s %s",mstr->mstrStr==NULL ? "" : mstr->mstrStr, cmIsFlag(mstr->cflags,kReqPoFl) ? reqStr : "" ); + cmRptPrintf(rpt,"Enumerated group: %s %s\n",mstr->mstrStr==NULL ? "" : mstr->mstrStr, cmIsFlag(mstr->cflags,kReqPoFl) ? reqStr : "" ); cmRptPrintf(rpt,"%s-%c --%s %s %s",indentStr,r->charId,r->wordId,valueTypeLabel,reqLabel); diff --git a/cmPgmOpts.h b/cmPgmOpts.h index bcee202..46c533e 100644 --- a/cmPgmOpts.h +++ b/cmPgmOpts.h @@ -1,8 +1,8 @@ #ifndef cmPgmOpts_h #define cmPgmOpts_h -//{ -//( +//( { file_desc:"Command line argument description and parsing API." kw:[base]} +// // Command line program option syntax: // // @@ -206,7 +206,6 @@ extern "C" { void cmPgmOptPrintParms( cmPgmOptH_t h, cmRpt_t* rpt ); //) - //} #ifdef __cplusplus } diff --git a/cmPrefs.h b/cmPrefs.h index 2f048ad..80f90ec 100644 --- a/cmPrefs.h +++ b/cmPrefs.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Manage persistent application preferences." kw:[base] } + typedef unsigned cmPrRC_t; typedef cmHandle_t cmPrH_t; @@ -188,7 +190,8 @@ extern "C" { void cmPrefsTest( cmCtx_t* ctx, const char* ifn, const char* ofn ); - + //) + #ifdef __cplusplus } #endif diff --git a/cmProc.h b/cmProc.h index bead204..2f2242b 100644 --- a/cmProc.h +++ b/cmProc.h @@ -5,7 +5,10 @@ extern "C" { #endif - //------------------------------------------------------------------------------------------------------------ + //( { file_desc:"Processor Library 1" kw:[proclib]} + //) + + //( { label:cmAudioFileRd file_desc:"Audio file reader based on cmAudioFile" kw:[proc] } typedef struct { cmObj obj; @@ -23,28 +26,30 @@ extern "C" { cmMtxFile* mfp; } cmAudioFileRd; - /// set p to NULL to dynamically allocate the object - /// fn and chIdx are optional - set fn to NULL to allocate the reader without opening a file. - /// If fn is valid then chIdx must also be valid. - /// Set 'endSmpIdx' to cmInvalidIdx to return the entire signal in cmAudioFileRdRead(). - /// Set 'endSmpIdx' to 0 to return all samples between 0 and the end of the file. + // set p to NULL to dynamically allocate the object + // fn and chIdx are optional - set fn to NULL to allocate the reader without opening a file. + // If fn is valid then chIdx must also be valid. + // Set 'endSmpIdx' to cmInvalidIdx to return the entire signal in cmAudioFileRdRead(). + // Set 'endSmpIdx' to 0 to return all samples between 0 and the end of the file. cmAudioFileRd* cmAudioFileRdAlloc( cmCtx* c, cmAudioFileRd* p, unsigned procSmpCnt, const char* fn, unsigned chIdx, unsigned begSmpIdx, unsigned endSmpIdx ); cmRC_t cmAudioFileRdFree( cmAudioFileRd** p ); cmRC_t cmAudioFileRdOpen( cmAudioFileRd* p, unsigned procSmpCnt, const cmChar_t* fn, unsigned chIdx, unsigned begSmpIdx, unsigned endSmpIdx ); cmRC_t cmAudioFileRdClose( cmAudioFileRd* p ); - /// Returns cmEofRC if the end of file is encountered. + // Returns cmEofRC if the end of file is encountered. cmRC_t cmAudioFileRdRead( cmAudioFileRd* p ); cmRC_t cmAudioFileRdSeek( cmAudioFileRd* p, unsigned frmIdx ); - /// Find the overall minimum, maximum, and mean sample values without changing the current file location. + // Find the overall minimum, maximum, and mean sample values without changing the current file location. cmRC_t cmAudioFileRdMinMaxMean( cmAudioFileRd* p, unsigned chIdx, cmSample_t* minPtr, cmSample_t* maxPtr, cmSample_t* meanPtr ); + //) + //( { label:cmShiftBuf file_desc:"Audio shift buffer processor" kw:[proc] } //------------------------------------------------------------------------------------------------------------ - /// The buffer is intended to synchronize sample block rates between processes and to provide an overlapped - /// input buffer. + // The buffer is intended to synchronize sample block rates between processes and to provide an overlapped + // input buffer. typedef struct cmShiftBuf_str { cmObj obj; @@ -61,89 +66,36 @@ extern "C" { - /// Set p to NULL to dynamically allocate the object. hopSmpCnt must be <= wndSmpCnt. + // Set p to NULL to dynamically allocate the object. hopSmpCnt must be <= wndSmpCnt. cmShiftBuf* cmShiftBufAlloc( cmCtx* c, cmShiftBuf* p, unsigned procSmpCnt, unsigned wndSmpCnt, unsigned hopSmpCnt ); cmRC_t cmShiftBufFree( cmShiftBuf** p ); cmRC_t cmShiftBufInit( cmShiftBuf* p, unsigned procSmpCnt, unsigned wndSmpCnt, unsigned hopSmpCnt ); cmRC_t cmShiftBufFinal( cmShiftBuf* p ); - /// Returns true if a new hop is ready to be read otherwise returns false. - /// In general cmShiftBufExec() should be called in a loop until it returns false. - /// Note that 'sp' and 'sn' are ignored except for the first call after the function returns false. - /// This means that when called in a loop 'sp' and 'sn' are only used on the first time through the loop. - /// When procSmpCnt is less than hopSmpCnt the loop will only execute when at least wndSmpCnt - /// new samples have been buffered. - /// When procSmpCnt is greater than hopSmpCnt the loop will execute multiple times until less + // Returns true if a new hop is ready to be read otherwise returns false. + // In general cmShiftBufExec() should be called in a loop until it returns false. + // Note that 'sp' and 'sn' are ignored except for the first call after the function returns false. + // This means that when called in a loop 'sp' and 'sn' are only used on the first time through the loop. + // When procSmpCnt is less than hopSmpCnt the loop will only execute when at least wndSmpCnt + // new samples have been buffered. + // When procSmpCnt is greater than hopSmpCnt the loop will execute multiple times until less // than wndSmpCnt new samples are available. - /// Note that 'sn' must always be less than or equal to procSmpCnt. - /// - /// Example: - /// while( fill(sp,sn) ) // fill sp[] with sn samples - /// { - /// // shift by hopSmpCnt samples on all passes - insert new samples on first pass - /// while( cmShiftBufExec(p,sp,sn) ) - /// proc(p->outV,p->outN); // process p->outV[wndSmpCnt] - /// } + // Note that 'sn' must always be less than or equal to procSmpCnt. + // + // Example: + // while( fill(sp,sn) ) // fill sp[] with sn samples + // { + // // shift by hopSmpCnt samples on all passes - insert new samples on first pass + // while( cmShiftBufExec(p,sp,sn) ) + // proc(p->outV,p->outN); // process p->outV[wndSmpCnt] + // } bool cmShiftBufExec( cmShiftBuf* p, const cmSample_t* sp, unsigned sn ); void cmShiftBufTest( cmCtx* c ); - - //------------------------------------------------------------------------------------------------------------ - /* - typedef struct - { - cmComplexS_t* complexV; - cmSample_t* outV; - cmFftPlanS_t plan; - } cmIFftObjS; + //) - typedef struct - { - cmComplexR_t* complexV; - cmReal_t* outV; - cmFftPlanR_t plan; - } cmIFftObjR; - - typedef struct - { - cmObj obj; - unsigned binCnt; - unsigned outN; - - union - { - cmIFftObjS sr; - cmIFftObjR rr; - }u; - - } cmIFft; - - cmIFft* cmIFftAllocS( cmCtx* c, cmIFft* p, unsigned binCnt ); - cmIFft* cmIFftAllocR( cmCtx* c, cmIFft* p, unsigned binCnt ); - - cmRC_t cmIFftFreeS( cmIFft** pp ); - cmRC_t cmIFftFreeR( cmIFft** pp ); - - cmRC_t cmIFftInitS( cmIFft* p, unsigned binCnt ); - cmRC_t cmIFftInitR( cmIFft* p, unsigned binCnt ); - - cmRC_t cmIFftFinalS( cmIFft* p ); - cmRC_t cmIFftFinalR( cmIFft* p ); - - // x must contain 'binCnt' elements. - cmRC_t cmIFftExecS( cmIFft* p, cmComplexS_t* x ); - cmRC_t cmIFftExecR( cmIFft* p, cmComplexR_t* x ); - - cmRC_t cmIFftExecPolarS( cmIFft* p, const cmReal_t* magV, const cmReal_t* phsV ); - cmRC_t cmIFftExecPolarR( cmIFft* p, const cmReal_t* magV, const cmReal_t* phsV ); - - cmRC_t cmIFftExecRectS( cmIFft* p, const cmReal_t* rV, const cmReal_t* iV ); - cmRC_t cmIFftExecPolarR( cmIFft* p, const cmReal_t* magV, const cmReal_t* phsV ); - - void cmIFftTest( cmRpt_t* rptFuncPtr ); - */ - //------------------------------------------------------------------------------------------------------------ + //( { label:cmWindowFunc file_desc:"Fourier Transform window function generator." kw:[proc]} enum { @@ -174,8 +126,8 @@ extern "C" { cmMtxFile* mfp; } cmWndFunc; - /// Set p to NULL to dynamically allocate the object - /// if wndId is set to a valid value this function will internally call cmWndFuncInit() + // Set p to NULL to dynamically allocate the object + // if wndId is set to a valid value this function will internally call cmWndFuncInit() cmWndFunc* cmWndFuncAlloc( cmCtx* c, cmWndFunc* p, unsigned wndId, unsigned wndSmpCnt, double kaierSideLobeRejectDb ); cmRC_t cmWndFuncFree( cmWndFunc** pp ); cmRC_t cmWndFuncInit( cmWndFunc* p, unsigned wndId, unsigned wndSmpCnt, double kaiserSideLobeRejectDb ); @@ -184,9 +136,11 @@ extern "C" { void cmWndFuncTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); - //------------------------------------------------------------------------------------------------------------ - /// Spectral frame delay. A circular buffer for spectral (or other fixed length) vectors. + //) + + //( { label:cmSpecDelay file_desc:"Spectral frame delay. A circular buffer for spectral (or other fixed length) vectors." kw:[proc]} + typedef struct { cmObj obj; @@ -197,24 +151,25 @@ extern "C" { } cmSpecDelay; - /// Set p to NULL to dynamically allocate the object. - /// Allocate a spectral frame delay capable of delaying for 'maxDelayCnt' hops and - /// where each vector contains 'binCnt' elements. + // Set p to NULL to dynamically allocate the object. + // Allocate a spectral frame delay capable of delaying for 'maxDelayCnt' hops and + // where each vector contains 'binCnt' elements. cmSpecDelay* cmSpecDelayAlloc( cmCtx* c, cmSpecDelay* p, unsigned maxDelayCnt, unsigned binCnt ); cmRC_t cmSpecDelayFree( cmSpecDelay** p ); cmRC_t cmSpecDelayInit( cmSpecDelay* p, unsigned maxDelayCnt, unsigned binCnt ); cmRC_t cmSpecDelayFinal(cmSpecDelay* p ); - /// Give an input vector to the delay. 'sn' must <= binCnt + // Give an input vector to the delay. 'sn' must <= binCnt cmRC_t cmSpecDelayExec( cmSpecDelay* p, const cmSample_t* sp, unsigned sn ); - /// Get a pointer to a delayed vector. 'delayCnt' indicates the length of the delay in hops. - /// (e.g. 1 is the previous hop, 2 is two hops previous, ... ) + // Get a pointer to a delayed vector. 'delayCnt' indicates the length of the delay in hops. + // (e.g. 1 is the previous hop, 2 is two hops previous, ... ) const cmSample_t* cmSpecDelayOutPtr(cmSpecDelay* p, unsigned delayCnt ); - - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmFilter file_desc:"General purpose, LTI, Octave compatible, filter." kw:[proc] } typedef struct cmFilter_str { cmObj obj; @@ -257,9 +212,10 @@ extern "C" { void cmFilterTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); void cmFilterFilterTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); - - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmComplexDetect file_desc:"Complex domain onset detection function." kw:[proc] } typedef struct { cmObj obj; @@ -271,14 +227,16 @@ extern "C" { //unsigned cdfSpRegId; } cmComplexDetect; - /// Set p to NULL to dynamically allocate the object. + // Set p to NULL to dynamically allocate the object. cmComplexDetect* cmComplexDetectAlloc(cmCtx* c, cmComplexDetect* p, unsigned binCnt ); cmRC_t cmComplexDetectFree( cmComplexDetect** pp); cmRC_t cmComplexDetectInit( cmComplexDetect* p, unsigned binCnt ); cmRC_t cmComplexDetectFinal(cmComplexDetect* p); cmRC_t cmComplexDetectExec( cmComplexDetect* p, const cmSample_t* magV, const cmSample_t* phsV, unsigned binCnt ); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmComplexOnset file_desc:"Complex onset detection function" kw:[proc]} typedef struct { cmObj obj; @@ -298,8 +256,10 @@ extern "C" { cmRC_t cmComplexOnsetFinal( cmComplexOnset* p); cmRC_t cmComplexOnsetExec( cmComplexOnset* p, cmSample_t cdf ); cmRC_t cmComplexOnsetCalc( cmComplexOnset* p ); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmMfcc file_desc:"Mel Frequency Cepstral Coefficient (MFCC) measurement function." kw:[proc] } typedef struct { cmObj obj; @@ -321,8 +281,10 @@ extern "C" { cmRC_t cmMfccExecPower( cmMfcc* p, const cmReal_t* magPowV, unsigned binCnt ); cmRC_t cmMfccExecAmplitude( cmMfcc* p, const cmReal_t* magAmpV, unsigned binCnt ); void cmMfccTest(); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmSones file_desc:"Sones measurement function." kw:[proc] } typedef struct { cmObj obj; @@ -350,8 +312,10 @@ extern "C" { cmRC_t cmSonesExec( cmSones* p, const cmReal_t* magPowV, unsigned binCnt ); void cmSonesTest(); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label: cmAudioOffsetScale file_desc:"Audio signal pre-processing normalizer." kw:[proc] } typedef struct { cmObj obj; @@ -371,15 +335,15 @@ extern "C" { } cmAudioOffsetScale; - /// This processor adds an offset to an audio signal and scales into dB (SPL) using one of two techniques - /// 1) Measures the effective sound pressure (via RMS) and then scales the signal to the reference dB (SPL) - /// In this case dBref is commonly set to 70. See Timony, 2004, Implementing Loudness Models in Matlab. - /// - /// 2) treats the dBref as the maximum dB (SPL) and scales the signal by this amount without regard - /// measured signal level. In this case dBref is commonly set to 96 (max. dB (SPL) value for 16 bits) - /// and rmsWndSecs is ignored. - /// - /// Note that setting rmsWndSecs to zero has the effect of using procSmpCnt as the window length. + // This processor adds an offset to an audio signal and scales into dB (SPL) using one of two techniques + // 1) Measures the effective sound pressure (via RMS) and then scales the signal to the reference dB (SPL) + // In this case dBref is commonly set to 70. See Timony, 2004, Implementing Loudness Models in Matlab. + // + // 2) treats the dBref as the maximum dB (SPL) and scales the signal by this amount without regard + // measured signal level. In this case dBref is commonly set to 96 (max. dB (SPL) value for 16 bits) + // and rmsWndSecs is ignored. + // + // Note that setting rmsWndSecs to zero has the effect of using procSmpCnt as the window length. enum { kNoAudioScaleFl=0x01, kRmsAudioScaleFl=0x02, kFixedAudioScaleFl=0x04 }; @@ -388,8 +352,10 @@ extern "C" { cmRC_t cmAudioOffsetScaleInit( cmAudioOffsetScale* p, unsigned procSmpCnt, double srate, cmSample_t offset, double rmsWndSecs, double dBref, unsigned flags ); cmRC_t cmAudioOffsetScaleFinal( cmAudioOffsetScale* p ); cmRC_t cmAudioOffsetScaleExec( cmAudioOffsetScale* p, const cmSample_t* sp, unsigned sn ); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmSpecMeas file_desc:"Measure a signals RMS, High-Frequency Content, Spectral Centroid, and Spectral Spread." kw:[proc]} typedef struct { cmObj obj; @@ -422,10 +388,10 @@ extern "C" { unsigned ssSpRegId; } cmSpecMeas; - /// Set wndFrmCnt to the number of spectral frames to take the measurement over. - /// Setting wndFrmCnt to 1 has the effect of calculating the value on the current frame only. - /// Set flags = kWholeSigSpecMeasFl to ignore wndFrmCnt and calculate the result on the entire signal. - /// In effect this treats the entire signal as the length of the measurement window. + // Set wndFrmCnt to the number of spectral frames to take the measurement over. + // Setting wndFrmCnt to 1 has the effect of calculating the value on the current frame only. + // Set flags = kWholeSigSpecMeasFl to ignore wndFrmCnt and calculate the result on the entire signal. + // In effect this treats the entire signal as the length of the measurement window. enum { kWholeSigSpecMeasFl=0x00, kUseWndSpecMeasFl=0x01 }; cmSpecMeas* cmSpecMeasAlloc( cmCtx* c, cmSpecMeas* p, double srate, unsigned binCnt, unsigned wndFrmCnt, unsigned flags ); @@ -433,8 +399,10 @@ extern "C" { cmRC_t cmSpecMeasInit( cmSpecMeas* p, double srate, unsigned binCnt, unsigned wndFrmCnt, unsigned flags ); cmRC_t cmSpecMeasFinal( cmSpecMeas* p ); cmRC_t cmSpecMeasExec( cmSpecMeas* p, const cmReal_t* magPowV, unsigned binCnt ); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmSigMeas file_desc:"Measure a time domain signals zero crossing rate." kw:[proc]} typedef struct { cmObj obj; @@ -456,8 +424,10 @@ extern "C" { cmRC_t cmSigMeasInit( cmSigMeas* p, double srate, unsigned procSmpCnt, unsigned measSmpCnt ); cmRC_t cmSigMeasFinal( cmSigMeas* p ); cmRC_t cmSigMeasExec( cmSigMeas* p, const cmSample_t* sigV, unsigned smpCnt ); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmSRC file_desc:"Sample rate converter" kw:[proc] } typedef struct { cmObj obj; @@ -476,7 +446,7 @@ extern "C" { } cmSRC; - /// The srate paramater is the sample rate of the source signal provided via cmSRCExec() + // The srate paramater is the sample rate of the source signal provided via cmSRCExec() cmSRC* cmSRCAlloc( cmCtx* c, cmSRC* p, double srate, unsigned procSmpCnt, unsigned upFact, unsigned dnFact ); cmRC_t cmSRCFree( cmSRC** pp ); cmRC_t cmSRCInit( cmSRC* p, double srate, unsigned procSmpCnt, unsigned upFact, unsigned dnFact ); @@ -484,8 +454,10 @@ extern "C" { cmRC_t cmSRCExec( cmSRC* p, const cmSample_t* sp, unsigned sn ); void cmSRCTest(); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmConstQ file_desc:"Contant-Q transform." kw:[proc] } typedef struct { cmObj obj; @@ -510,9 +482,10 @@ extern "C" { cmRC_t cmConstQInit( cmConstQ* p, double srate, unsigned minMidiPitch, unsigned maxMidiPitch, unsigned binsPerOctave, double thresh ); cmRC_t cmConstQFinal( cmConstQ* p ); cmRC_t cmConstQExec( cmConstQ* p, const cmComplexR_t* ftV, unsigned binCnt ); - - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmTuneHpcp file_desc:"Generate a tuned chromagram." kw:[proc]} typedef struct { cmObj obj; @@ -545,10 +518,10 @@ extern "C" { cmRC_t cmTunedHpcpFinal( cmHpcp* p ); cmRC_t cmTunedHpcpExec( cmHpcp* p, const cmComplexR_t* constQBinPtr, unsigned constQBinCnt ); cmRC_t cmTunedHpcpTuneAndFilter( cmHpcp* p); - - - //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmBeatHist file_desc:"Generate a beat candidate histogram." kw:[proc]} struct cmFftRR_str; struct cmIFftRR_str; @@ -579,9 +552,11 @@ extern "C" { cmRC_t cmBeatHistFinal( cmBeatHist* p ); cmRC_t cmBeatHistExec( cmBeatHist* p, cmSample_t df ); cmRC_t cmBeatHistCalc( cmBeatHist* p ); - //------------------------------------------------------------------------------------------------------------ - // Gaussian Mixture Model containing N Gaussian PDF's each of dimension D + //) + + //( { label:cmGmm file_desc"Gaussian Mixture Model containing N Gaussian PDF's each of dimension D." kw:[proc model]} + typedef struct { cmObj obj; @@ -639,9 +614,11 @@ extern "C" { void cmGmmPrint( cmGmm_t* p, bool detailsFl ); void cmGmmTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); - //------------------------------------------------------------------------------------------------------------ - // Continuous Hidden Markov Model + //) + + //( { label:cmChmm file_desc:"Continuous Hidden Markov Model" kw:[proc model]} + typedef struct { cmObj obj; @@ -652,9 +629,7 @@ extern "C" { cmReal_t* aM; // aM[ N x N] transition probability mtx cmGmm_t** bV; // bV[ N ] observation probability mtx (array of pointers to GMM's) cmReal_t* bM; // bM[ N,T] state-observation probability matrix - cmMtxFile* mfp; - } cmChmm_t; // Continuous HMM consisting of stateN states where the observations @@ -706,10 +681,11 @@ extern "C" { void cmChmmPrint( cmChmm_t* p ); void cmChmmTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); - - //------------------------------------------------------------------------------------------------------------ - // Chord recognizer + //) + + + //( { label:cmChord file_desc:"HMM based chord recognizer." kw:[proc]} typedef struct { @@ -739,14 +715,16 @@ extern "C" { cmReal_t cdtsVar; } cmChord; - + cmChord* cmChordAlloc( cmCtx* c, cmChord* p, const cmReal_t* chromaM, unsigned T ); cmRC_t cmChordFree( cmChord** p ); cmRC_t cmChordInit( cmChord* p, const cmReal_t* chromaM, unsigned T ); cmRC_t cmChordFinal( cmChord* p ); void cmChordTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); - + //------------------------------------------------------------------------------------------------------------ + //) + #ifdef __cplusplus } #endif diff --git a/cmProc2.c b/cmProc2.c index cb9c379..7dc3273 100644 --- a/cmProc2.c +++ b/cmProc2.c @@ -5950,7 +5950,8 @@ cmSpecDist_t* cmSpecDistAlloc( cmCtx* ctx,cmSpecDist_t* ap, unsigned procSmpCnt, //p->iSpecVa = cmVectArrayAlloc(ctx,kRealVaFl); //p->oSpecVa = cmVectArrayAlloc(ctx,kRealVaFl); - + p->statVa = cmVectArrayAlloc(ctx,kDoubleVaFl); + if( procSmpCnt != 0 ) { if( cmSpecDistInit( p, procSmpCnt, srate, wndSmpCnt, hopFcmt, olaWndTypeId ) != cmOkRC ) @@ -5971,6 +5972,7 @@ cmRC_t cmSpecDistFree( cmSpecDist_t** pp ) cmSpecDistFinal(p); //cmVectArrayFree(&p->iSpecVa); //cmVectArrayFree(&p->oSpecVa); + cmVectArrayFree(&p->statVa); cmMemPtrFree(&p->hzV); cmMemPtrFree(&p->iSpecM); cmMemPtrFree(&p->oSpecM); @@ -6095,7 +6097,8 @@ cmRC_t cmSpecDistFinal(cmSpecDist_t* p ) //cmVectArrayWrite(p->iSpecVa, "/home/kevin/temp/frqtrk/iSpec.va"); //cmVectArrayWrite(p->oSpecVa, "/home/kevin/temp/expand/oSpec.va"); - + //cmVectArrayWrite(p->statVa, "/Users/kevin/temp/kc/state.va"); + cmPvAnlFree(&p->pva); cmPvSynFree(&p->pvs); //cmFrqTrkFree(&p->ft); @@ -6111,6 +6114,7 @@ void _cmSpecDistBasicMode0(cmSpecDist_t* p, cmReal_t* X1m, unsigned binCnt, cmRe // octave> -abs(abs(X1m+thresh)-(X1m+thresh)) - thresh // octave> ans = -64 -62 -60 -60 + /* unsigned i=0; for(i=0; ibinCnt; ++i) + { + X1m[i] = -fabs(fabs(X1m[i]-thresh) - (X1m[i]-thresh)) - thresh; + } } @@ -6322,6 +6332,8 @@ cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn ) cmVOR_MeanM2(p->iSpecV, p->iSpecM, p->hN, p->pva->binCnt, 0, cmMin(p->fi+1,p->hN)); } + cmVOR_PowVS(X1m,p->pva->binCnt,2.0); + cmVOR_AmplToDbVV(X1m, p->pva->binCnt, p->pva->magV, -1000.0 ); //cmVOR_AmplToDbVV(X1m, p->pva->binCnt, X1m, -1000.0 ); @@ -6369,7 +6381,6 @@ cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn ) cmVOR_DbToAmplVV(X1m, p->pva->binCnt, X1m ); - // run and apply the tracker/supressor //cmFrqTrkExec(p->ft, X1m, p->pva->phsV, NULL ); //cmVOR_MultVV(X1m, p->pva->binCnt,p->ft->aV ); @@ -6393,6 +6404,12 @@ cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn ) p->ogain *= a0; } + double g = u0/u1; + p->ogain0 = g + (p->ogain0 * .98); + + //double v[] = { u0, u1, p->ogain, p->ogain0 }; + //cmVectArrayAppendD(p->statVa,v,sizeof(v)/sizeof(v[0])); + cmVOR_MultVS(X1m,p->pva->binCnt,cmMin(4.0,p->ogain)); diff --git a/cmProc2.h b/cmProc2.h index 3ca481d..cbeb2a9 100644 --- a/cmProc2.h +++ b/cmProc2.h @@ -5,7 +5,11 @@ extern "C" { #endif - //------------------------------------------------------------------------------------------------------------ + //( { file_desc:"Processor Library 2" kw:[proclib]} + //) + + //( { label:cmArray file_desc:"Expandable array designed to work easily with the cmProcObj model" kw:[proc]} + // cmArray is an expandable array designed to work easily with the alloc/init/final/free model // used by this library. The arrays can be safely used by using the cmArrayAllocXXX macros // with static cmArray member fields during object allocation. cmArrayResizeXXX macros are then @@ -53,8 +57,10 @@ extern "C" { #define cmArrayPtr( type, p ) (type*)(p)->ptr #define cmArrayCount( p ) (p)->eleCnt - //------------------------------------------------------------------------------------------------------------ + //) + //( { label:cmAudioFileWr file_desc:"Audio file writer" kw:[proc]} + typedef struct { cmObj obj; @@ -72,8 +78,10 @@ extern "C" { cmRC_t cmAudioFileWrFinal( cmAudioFileWr* p ); cmRC_t cmAudioFileWrExec( cmAudioFileWr* p, unsigned chIdx, const cmSample_t* sp, unsigned sn ); void cmAudioFileWrTest(); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmMatrixBuf file_desc:"Store and recall real values in matrix form." kw:[proc]} typedef struct { cmObj obj; @@ -98,6 +106,9 @@ extern "C" { //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmSigGen file_desc:"Generate periodic and noise signals." kw:[proc]} enum { @@ -139,6 +150,9 @@ extern "C" { cmRC_t cmSigGenExec( cmSigGen* p ); //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmDelay file_desc:"Fixed length audio delay." kw:[proc]} typedef struct { cmObj* obj; @@ -160,8 +174,10 @@ extern "C" { cmRC_t cmDelayAdvance( cmDelay* p, unsigned sn ); cmRC_t cmDelayExec( cmDelay* p, const cmSample_t* sp, unsigned sn, bool bypassFl ); void cmDelayTest(); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmFIR file_desc:"Finite impulse response filter." kw:[proc]} typedef struct { cmObj obj; @@ -192,10 +208,11 @@ extern "C" { cmRC_t cmFIRExec( cmFIR* p, const cmSample_t* sp, unsigned sn ); void cmFIRTest0( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); void cmFIRTest1( cmCtx* ctx ); - - //------------------------------------------------------------------------------------------------------------ - // Apply a generic function to a windowed signal with a one sample hop size. + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmFuncFilter file_desc:"Apply a generic function to a windowed signal with a one sample hop size.." kw:[proc]} typedef cmSample_t (*cmFuncFiltPtr_t)( const cmSample_t* sp, unsigned sn, void* userPtr ); typedef struct @@ -217,8 +234,10 @@ extern "C" { cmRC_t cmFuncFilterFinal( cmFuncFilter* p ); cmRC_t cmFuncFilterExec( cmFuncFilter* p, const cmSample_t* sp, unsigned sn ); void cmFuncFilterTest(); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmDhmm file_desc:"Discrete observation HMM" kw:[proc]} typedef struct { cmObj obj; @@ -245,6 +264,9 @@ extern "C" { void cmDhmmTest(); //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmConvolve file_desc:"Convolve a signal with an impulse response." kw:[proc]} typedef struct { cmObj obj; @@ -285,6 +307,9 @@ extern "C" { cmRC_t cmConvolveTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmBfcc file_desc:"Generate Bark Frequency Cepstral Coefficients from STFT frames." kw:[proc]} typedef struct { cmObj obj; @@ -304,6 +329,8 @@ extern "C" { void cmBfccTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); //------------------------------------------------------------------------------------------------------------ + //) + //( { label:cmCepstrum file_desc:"Generate Cepstral Coefficients from STFT frames." kw:[proc]} typedef struct { cmObj obj; @@ -324,7 +351,10 @@ extern "C" { cmRC_t cmCepsFinal( cmCeps* p ); cmRC_t cmCepsExec( cmCeps* p, const cmReal_t* magV, const cmReal_t* phsV, unsigned binCnt ); + //------------------------------------------------------------------------------------------------------------ + //) + //( { label:cmOla file_desc:"Generate a signal from an via overlap-add." kw:[proc]} //------------------------------------------------------------------------------------------------------------ typedef struct { @@ -355,9 +385,10 @@ extern "C" { cmRC_t cmOlaExecS( cmOla* p, const cmSample_t* xV, unsigned xN ); cmRC_t cmOlaExecR( cmOla* p, const cmReal_t* xV, unsigned xN ); const cmSample_t* cmOlaExecOut(cmOla* p ); + //------------------------------------------------------------------------------------------------------------ + //) - - + //( { label:cmPhsToFrq file_desc:"Given STFT phase spectrum frames return the instantaneous frequency." kw:[proc]} //------------------------------------------------------------------------------------------------------------ typedef struct @@ -380,9 +411,11 @@ extern "C" { cmRC_t cmPhsToFrqFinal(cmPhsToFrq* p ); cmRC_t cmPhsToFrqExec( cmPhsToFrq* p, const cmReal_t* phsV ); - //------------------------------------------------------------------------------------------------------------ - + //) + + //( { label:cmPvAnl file_desc:"Perform the phase-vocoder analysis stage." kw:[proc]} + enum { kNoCalcHzPvaFl = 0x00, @@ -420,6 +453,8 @@ extern "C" { bool cmPvAnlExec( cmPvAnl* p, const cmSample_t* x, unsigned xN ); //------------------------------------------------------------------------------------------------------------ + //) + //( { label:cmPvSyn file_desc:"Perform the phase-vocoder synthesis stage." kw:[proc]} typedef struct { @@ -451,11 +486,10 @@ extern "C" { cmRC_t cmPvSynExec( cmPvSyn* p, const cmReal_t* magV, const cmReal_t* phsV ); const cmSample_t* cmPvSynExecOut(cmPvSyn* p ); - - //------------------------------------------------------------------------------------------------------------ - - + //) + + //( { label:cmMidiSynth file_desc:"Synthesis independent MIDI synthesizer control structure." kw:[proc]} // callback selector values enum { @@ -532,8 +566,10 @@ extern "C" { cmRC_t cmMidiSynthOnMidi(cmMidiSynth* p, const cmMidiPacket_t* pktArray, unsigned pktCnt ); cmRC_t cmMidiSynthExec( cmMidiSynth* p, cmSample_t** outChArray, unsigned outChCnt ); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmWtVoice file_desc:"Wavetable oscillator implementation for use with cmMidiSyn." kw:[proc]} // state id's enum @@ -568,6 +604,8 @@ extern "C" { //------------------------------------------------------------------------------------------------------------ + //) + //( { label:cmWtVoiceBank file_desc:"A bank of cmWtVoice oscillator for use with cmMidiSynth." kw:[proc]} typedef struct { @@ -596,8 +634,9 @@ extern "C" { int cmWtVoiceBankExec( cmWtVoiceBank* p, struct cmMidiVoice_str* voicePtr, unsigned sel, cmSample_t* chArray[], unsigned chCnt ); - //------------------------------------------------------------------------------------------------------------ + //) + //( { label:cmAudioFileBuf file_desc:"Generate a signal by caching all or part of an audio file." kw:[proc]} typedef struct { @@ -620,8 +659,10 @@ extern "C" { // If less than outN samples are available then the remaining samples are set to 0. unsigned cmAudioFileBufExec( cmAudioFileBuf* p, unsigned smpIdx, cmSample_t* outV, unsigned outN, bool sumIntoOutFl ); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmMDelay file_desc:"Multi-tap audio delay with feedback." kw:[proc]} // Multi-delay. Each of the taps of this delay operates as a independent delay with feedback. // Delay line specification. @@ -657,6 +698,9 @@ extern "C" { void cmMDelayReport( cmMDelay* p, cmRpt_t* rpt ); //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmAudioSegPlayer file_desc:"Buffer and playback an arbitrary number of audio signals." kw:[proc]} enum { kEnableAspFl = 0x01, @@ -696,9 +740,9 @@ extern "C" { cmRC_t cmAudioSegPlayerEnable( cmAudioSegPlayer* p, unsigned id, bool enableFl, unsigned outSmpIdx ); cmRC_t cmAudioSegPlayerReset( cmAudioSegPlayer* p ); cmRC_t cmAudioSegPlayerExec( cmAudioSegPlayer* p, cmSample_t** outChPtr, unsigned chCnt, unsigned outSmpCnt ); - - //------------------------------------------------------------------------------------------------------------ + //) + /* cmReal_t (*cmCluster0DistFunc_t)( void* userPtr, const cmReal_t* v0, const cmReal_t* v1, unsigned binCnt ); @@ -729,7 +773,7 @@ extern "C" { cmRC_t cmCluster0Exec( cmCluster0* p, const cmReal_t* v, unsigned vn ); */ - //------------------------------------------------------------------------------------------------------------ + //( { label:cmNmf file_desc:"Non-negative matrix factorization implementation." kw:[proc]} typedef struct { cmObj obj; @@ -770,8 +814,10 @@ extern "C" { // cmRC_t cmNmfExec( cmNmf_t* p, const cmReal_t* v, unsigned cn ); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmVectArray file_desc:"Store and recall arrays of arbitrary length numeric vectors." kw:[proc]} // cmVectArray buffers row vectors of arbitrary length in memory. // The buffers may then be access using the cmVectArrayGetXXX() functions. // The entire contents of the file may be written to a file using atVectArrayWrite(). @@ -943,7 +989,10 @@ extern "C" { cmRC_t cmVectArrayFormVectColU( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt, unsigned colIdx, unsigned** vRef, unsigned* vnRef ); cmRC_t cmVectArrayTest( cmCtx* ctx, const char* fn, bool genFl ); - //----------------------------------------------------------------------------------------------------------------------- + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmWhFilt file_desc:"Spectral whitening filter." kw:[proc]} // Spectral whitening filter. // Based on: Klapuri, A., 2006: Multiple fundamental frequency estimation by summing // harmonic amplitudes. @@ -967,6 +1016,9 @@ extern "C" { cmRC_t cmWhFiltExec( cmWhFilt* p, const cmReal_t* xV, cmReal_t* yV, unsigned xyN ); //----------------------------------------------------------------------------------------------------------------------- + //) + + //( { label:cmFrqTrk file_desc:"Track sinusoids from STFT frame data." kw:[proc]} typedef enum { kNoStateFrqTrkId, @@ -1089,8 +1141,10 @@ extern "C" { cmRC_t cmFrqTrkExec( cmFrqTrk* p, const cmReal_t* magV, const cmReal_t* phsV, const cmReal_t* hzV ); void cmFrqTrkPrint( cmFrqTrk* p ); - //------------------------------------------------------------------------------------------------------------ - + //----------------------------------------------------------------------------------------------------------------------- + //) + + //( { label:cmFbCtl file_desc:"Perform acoustic feedback control by attenuating loud sinusoid signals." kw:[proc]} typedef struct { double srate; @@ -1122,7 +1176,10 @@ extern "C" { cmRC_t cmFbCtlFinal(cmFbCtl_t* p ); cmRC_t cmFbCtlExec( cmFbCtl_t* p, const cmReal_t* xV ); - //----------------------------------------------------------------------------------------------------------------------- + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmExpander file_desc:"Expander implementation for audio dynamics processing." kw:[proc]} typedef struct { @@ -1148,7 +1205,11 @@ extern "C" { cmRC_t cmExpanderFinal( cmExpander* p ); cmRC_t cmExpanderExec( cmExpander* p, cmSample_t* x, cmSample_t* y, unsigned xyN ); cmRC_t cmExpanderExecD( cmExpander* p, double* x, double* y, unsigned xyN ); + //----------------------------------------------------------------------------------------------------------------------- + //) + + //( { label:cmExpanderBank file_desc:"Bank of audio dynamics expanders based on cmExpander." kw:[proc]} typedef struct { cmObj obj; @@ -1166,8 +1227,10 @@ extern "C" { cmRC_t cmExpanderBankExec( cmExpanderBank* p, cmSample_t* x, unsigned bandN ); cmRC_t cmExpanderBankExecD( cmExpanderBank* p, double* x, unsigned bandN ); - - //------------------------------------------------------------------------------------------------------------ + //----------------------------------------------------------------------------------------------------------------------- + //) + + //( { label:cmSpecDist file_desc:"Spectral distortion algorithm based on non-linear transform." kw:[proc]} enum { @@ -1224,6 +1287,7 @@ extern "C" { cmReal_t aeUnit; cmReal_t ogain; + cmReal_t ogain0; unsigned phaseModIndex; @@ -1236,6 +1300,7 @@ extern "C" { cmReal_t* oSpecM; // oSpecMtx[hN binN] cmReal_t* oSpecV; // mean of rows of oSpecM cmVectArray_t* oSpecVa; + cmVectArray_t* statVa; } cmSpecDist_t; @@ -1246,8 +1311,11 @@ extern "C" { cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn ); const cmSample_t* cmSpecDistOut( cmSpecDist_t* p ); - //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmBinMtxFile file_desc:"Write a binary matrix which can be read by readBinFile.m." kw:[proc]} + // Write a binary matrix file in the format acceppted by the octave function readBinFile.m typedef struct cmBinMtxFile_str @@ -1289,7 +1357,7 @@ extern "C" { // Use cmBinMtxFileSize() to determine the buffer size prior to calling this function. // colCntV[colCnt] is optional. cmRC_t cmBinMtxFileRead( cmCtx_t* ctx, const cmChar_t* fn, unsigned rowCnt, unsigned colCnt, unsigned eleByteCnt, void* buf, unsigned* colCntV ); - + //) diff --git a/cmProc3.h b/cmProc3.h index c1fd407..6e354d7 100644 --- a/cmProc3.h +++ b/cmProc3.h @@ -4,6 +4,10 @@ #ifdef __cplusplus extern "C" { #endif + //( { file_desc:"Processor Library 3" kw:[proclib]} + //) + + //( { label:cmPitchShift file_desc:"Time-domain pitch shifter based on sample rate conversion." kw:[proc]} typedef struct { @@ -45,7 +49,9 @@ extern "C" { cmRC_t cmPitchShiftFinal(cmPitchShift* p ); cmRC_t cmPitchShiftExec( cmPitchShift* p, const cmSample_t* x, cmSample_t* y, unsigned n, double shiftRatio, bool bypassFl ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + //( { label:cmLoopRecord file_desc:"Audio interactive loop recorder." kw:[proc]} typedef struct { @@ -90,7 +96,9 @@ extern "C" { cmRC_t cmLoopRecordExec( cmLoopRecord* p, const cmSample_t* x, cmSample_t* y, unsigned xn, bool bypassFl, bool recdFl, bool playFl, double ratio, double pgain, double rgain ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + //( { label:cmGateDetector file_desc:"Detect when a signal onsets and offsets." kw:[proc]} typedef struct { cmObj obj; @@ -115,8 +123,9 @@ extern "C" { cmRC_t cmGateDetectFinal(cmGateDetect* p ); cmRC_t cmGateDetectExec( cmGateDetect* p, const cmSample_t* x, unsigned xn ); - - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + //( { label:cmGateDetector2 file_desc:"Improved gate detector to detect when a signal onsets and offsets." kw:[proc]} typedef struct { unsigned medCnt; // length of the median filter @@ -164,14 +173,17 @@ extern "C" { cmGateDetect2* cmGateDetectAlloc2( cmCtx* c, cmGateDetect2* p, unsigned procSmpCnt, const cmGateDetectParams* args ); - cmRC_t cmGateDetectFree2( cmGateDetect2** p ); - cmRC_t cmGateDetectInit2( cmGateDetect2* p, unsigned procSmpCnt, const cmGateDetectParams* args ); - cmRC_t cmGateDetectFinal2(cmGateDetect2* p ); - cmRC_t cmGateDetectExec2( cmGateDetect2* p, const cmSample_t* x, unsigned xn ); - void cmGateDetectSetOnThreshDb2( cmGateDetect2* p, cmReal_t db ); - void cmGateDetectSetOffThreshDb2( cmGateDetect2* p, cmReal_t db ); + cmRC_t cmGateDetectFree2( cmGateDetect2** p ); + cmRC_t cmGateDetectInit2( cmGateDetect2* p, unsigned procSmpCnt, const cmGateDetectParams* args ); + cmRC_t cmGateDetectFinal2(cmGateDetect2* p ); + cmRC_t cmGateDetectExec2( cmGateDetect2* p, const cmSample_t* x, unsigned xn ); + void cmGateDetectSetOnThreshDb2( cmGateDetect2* p, cmReal_t db ); + void cmGateDetectSetOffThreshDb2( cmGateDetect2* p, cmReal_t db ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmAutoGain file_desc:"Automatically balance a set of audio signals by adjusting their level." kw:[proc fluxo]} // // Calculate a set of automatic gain adjustments for a set of audio channels. @@ -230,7 +242,10 @@ extern "C" { void cmAutoGainPrint( cmAutoGain* p, cmRpt_t* rpt ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmChCfg file_desc:"Configure a 'fluxo' pickup channel." kw:[proc fluxo]} typedef struct { unsigned ch; @@ -261,8 +276,11 @@ extern "C" { void cmChCfgPrint( cmChCfg* p, cmRpt_t* rpt ); unsigned cmChCfgChannelCount( cmCtx_t* ctx, const cmChar_t* fn, unsigned* nsChCntPtr ); unsigned cmChCfgChannelIndex( cmCtx_t* ctx, const cmChar_t* fn, unsigned chIdx ); + + //------------------------------------------------------------------------------------------------------------ + //) - //======================================================================================================================= + //( { label:cmChordDetector file_desc:"Chord detector based on evaluating signals from cmGateDetector2." kw:[proc]} typedef struct { @@ -293,7 +311,10 @@ extern "C" { cmRC_t cmChordDetectExec( cmChordDetect* p, unsigned procSmpCnt, const bool* gateV, const cmReal_t* rmsV, unsigned chCnt ); cmRC_t cmChordDetectSetSpanMs( cmChordDetect* p, cmReal_t maxTimeSpanMs ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmXfader file_desc:"Audio cross fade controller." kw:[proc]} // This object is not really a cross-fader. It is really just a multichannel // fader - which just calculates the fade gain but does not actually apply it // to the audio signal - unless you use cmXfaderExecAudio() @@ -335,7 +356,10 @@ extern "C" { void cmXfaderAllOff( cmXfader* p ); void cmXfaderJumpToDestinationGain( cmXfader* p ); // jump to dest. gain based on gate state - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmFader file_desc:"Fade in/out an audio signal based on the state of a gate control signal." kw:[proc]} // This fader object accepts a gate signal. When the gate is high it increments // the gain until it reaches 1.0. When the gate is low it decrements the gain // until it reaches 0.0. The fade time is the lenght of time the gain will take @@ -355,7 +379,10 @@ extern "C" { cmRC_t cmFaderExec( cmFader* p, unsigned procSmpCnt, bool gateFl, bool mixFl, const cmSample_t* x, cmSample_t* y ); void cmFaderSetFadeTime( cmFader* p, cmReal_t fadeTimeMs ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmCombFilt file_desc:"Comb and Inverse Comb filter algorithm with a variable fractional delay." kw:[proc]} struct cmIDelay_str; typedef struct { @@ -384,7 +411,10 @@ extern "C" { void cmCombFiltSetAlpha( cmCombFilt* p, cmReal_t alpha ); cmRC_t cmCombFiltSetHz( cmCombFilt* p, cmReal_t hz ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmDcFilt file_desc:"DC Filter algorithm." kw:[proc]} typedef struct { @@ -402,9 +432,10 @@ extern "C" { cmRC_t cmDcFiltFinal( cmDcFilt* p ); cmRC_t cmDcFiltExec( cmDcFilt* p, const cmSample_t* x, cmSample_t* y, unsigned n ); - //======================================================================================================================= - - // interpolating delay - used by the comb filter + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmIDelay file_desc:"Variable interpolating fractional audio delay line." kw:[proc]} typedef struct cmIDelay_str { @@ -429,7 +460,10 @@ extern "C" { cmRC_t cmIDelaySetTapMs( cmIDelay* p, unsigned tapIdx, cmReal_t tapMs ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmGroupSel file_desc:"Assign channel to dynamic groups under gate control." kw:[proc]} // This object sequentially assigns channels to groups when their gates go high. // 'chsPerGroup' channels will be assigned to each group. No channel will be @@ -481,7 +515,10 @@ extern "C" { // and groups that will be removed on the next cycle have their 'releaseFl' set. cmRC_t cmGroupSelExec( cmGroupSel* p ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmAudioNofM file_desc:"Route N of M possible input channels to N output channels under gate control." kw:[proc]} // Route N of M input channels to N output channels. // The N channels are selected from the first N gates to go high. @@ -526,7 +563,10 @@ extern "C" { cmRC_t cmAudioNofMSetFadeMs( cmAudioNofM* p, cmReal_t fadeTimeMs ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmAdsr file_desc:"ADSR audio evelope generator." kw:[proc]} enum { kDlyAdsrId, kAtkAdsrId, kDcyAdsrId, kSusAdsrId, kRlsAdsrId, kDoneAdsrId }; @@ -546,9 +586,6 @@ extern "C" { cmReal_t susLevel; int rlsSmp; - - - unsigned state; // current state int durSmp; // time in current state cmReal_t level; // current level @@ -575,7 +612,10 @@ extern "C" { void cmAdsrSetLevel( cmAdsr* p, cmReal_t level, unsigned id ); void cmAdsrReport( cmAdsr* p, cmRpt_t* rpt ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmCompressor file_desc:"Audio dynamics compressor algorithm." kw:[proc]} enum { kAtkCompId, kRlsCompId }; typedef struct @@ -616,7 +656,11 @@ extern "C" { void cmCompressorSetThreshDb( cmCompressor* p, cmReal_t thresh ); void cmCompressorSetRmsWndMs( cmCompressor* p, cmReal_t ms ); - //======================================================================================================================= + + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmBiQuad file_desc:"General purpose Biquad filter algorithm." kw:[proc]} // BiQuad Audio Eq's based on Robert Bristow-Johnson's recipes. // http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt @@ -660,7 +704,10 @@ extern "C" { void cmBiQuadEqSet( cmBiQuadEq* p, unsigned mode, cmReal_t f0Hz, cmReal_t Q, cmReal_t gainDb ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmDistDs file_desc:"Guitar style distortion effect." kw:[proc]} typedef struct { cmObj obj; @@ -686,7 +733,10 @@ extern "C" { cmRC_t cmDistDsInit( cmDistDs* p, cmReal_t srate, cmReal_t inGain, cmReal_t downSrate, cmReal_t bits, bool rectFl, bool fullFl, cmReal_t clipDb, cmReal_t outGain, bool bypassFl ); cmRC_t cmDistDsFinal( cmDistDs* p ); cmRC_t cmDistDsExec( cmDistDs* p, const cmSample_t* x, cmSample_t* y, unsigned n ); + //------------------------------------------------------------------------------------------------------------ + //) + //======================================================================================================================= /* typedef struct diff --git a/cmProc4.c b/cmProc4.c index bc7a8e7..bffb21a 100644 --- a/cmProc4.c +++ b/cmProc4.c @@ -2693,6 +2693,7 @@ typedef struct _cmScModTypeMap_t _cmScModTypeArray[] = { + { kDeclModTId, 0, "decl" }, { kSetModTId, 1, "set" }, { kLineModTId, 2, "line" }, { kSetLineModTId, 3, "sline" }, @@ -3164,6 +3165,7 @@ cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep ) switch( ep->typeId ) { + case kDeclModTId: case kSetModTId: break; @@ -3220,6 +3222,11 @@ bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp ) switch( vp->entry->typeId ) { + case kDeclModTId: + sendFl = false; + fl = true; + break; + case kSetModTId: { if((rc = _cmScModGetParam(p,&vp->entry->beg,&vp->value)) != cmOkRC ) diff --git a/cmProc4.h b/cmProc4.h index a2c5c44..e18d2b1 100644 --- a/cmProc4.h +++ b/cmProc4.h @@ -5,11 +5,12 @@ extern "C" { #endif + //( { file_desc:"Processor Library 4" kw:[proclib]} + //) - //======================================================================================================================= - // - // Simplified string alignment function based on Levenshtein edit distance. - // + + //( { label:cmEditDist file_desc:"Simplified string alignment function based on Levenshtein edit distance." kw:[proc] } + enum { kEdMinIdx, kEdSubIdx, kEdDelIdx, kEdInsIdx, kEdCnt }; typedef struct @@ -87,7 +88,10 @@ extern "C" { // Main test function. void ed_main(); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmScoreMatch file_desc:"Event oriented local score matching algorithm based on edit distance." kw:[proc] } enum { kSmMinIdx, // @@ -200,9 +204,10 @@ extern "C" { // necessarily an error. cmRC_t cmScMatchExec( cmScMatch* p, unsigned locIdx, unsigned locN, const cmScMatchMidi_t* midiV, unsigned midiN, double min_cost ); - //======================================================================================================================= - + //------------------------------------------------------------------------------------------------------------ + //) + //( { label:cmScoreMatcher file_desc:"MIDI score following algorithm based cmScoreMatch." kw:[proc] } typedef struct { unsigned locIdx; // index into cmScMatch_t.loc[] @@ -246,8 +251,6 @@ extern "C" { bool printFl; } cmScMatcher; - - cmScMatcher* cmScMatcherAlloc( cmCtx* c, // Program context. cmScMatcher* p, // Existing cmScMatcher to reallocate or NULL to allocate a new cmScMatcher. @@ -310,7 +313,10 @@ extern "C" { void cmScMatcherPrint( cmScMatcher* p ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmScMeas file_desc:"Measure and report some differences between the score and the performance." kw:[proc] } typedef struct { @@ -391,7 +397,10 @@ extern "C" { // notes in each marker region and the score. void cmScAlignScanMarkers( cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmScMod file_desc:"Store and recall parameter information under score follower control." kw:[proc] } /* Syntax: - score location @@ -421,6 +430,7 @@ extern "C" { enum { kInvalidModTId, + kDeclModTId, // declare a variable but do not associate a value with it (allows a variable to be connected to w/o sending a value) kSetModTId, // set variable to parray[0] at scLocIdx kLineModTId, // linear ramp variable to parray[0] over parray[1] seconds kSetLineModTId, // set variable to parray[0] and ramp to parray[1] over parray[2] seconds @@ -522,7 +532,10 @@ extern "C" { cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx ); cmRC_t cmScModulatorDump( cmScModulator* p ); - //======================================================================================================================= + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmRecdPlay file_desc:"Record fragments of audio, store them,and play them back at a later time." kw:[proc] } // // Record fragments of audio, store them, and play them back at a later time. // @@ -593,7 +606,9 @@ extern "C" { cmRC_t cmRecdPlayBeginFade( cmRecdPlay* p, unsigned labelSymId, double fadeDbPerSec ); cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt ); + //) + #ifdef __cplusplus } #endif diff --git a/cmProc5.h b/cmProc5.h index ac3dfed..9e2af00 100644 --- a/cmProc5.h +++ b/cmProc5.h @@ -5,10 +5,11 @@ extern "C" { #endif + //( { file_desc:"Process Library 5", kw:[proclib]} + //) - //======================================================================================================================= - // Goertzel Filter - // + + //( { label:cmGoertzel file_desc:"Goertzel tone detection filter." kw:[proc]} typedef struct { @@ -38,10 +39,10 @@ extern "C" { cmRC_t cmGoertzelSetFcHz( cmGoertzel* p, unsigned chIdx, double hz ); cmRC_t cmGoertzelExec( cmGoertzel* p, const cmSample_t* in, unsigned procSmpCnt, double* outV, unsigned chCnt ); + //------------------------------------------------------------------------------------------------------------ + //) - //======================================================================================================================= - // Gold Code Signal Generator - // + //( { label:cmGoldCode file_desc:"Gold code random generator." kw:[proc]} typedef struct { @@ -110,9 +111,10 @@ extern "C" { cmRC_t cmGoldSigTest( cmCtx* ctx ); - //======================================================================================================================= - // Phase aligned transform generalized cross correlator - // + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmPhat file_desc:"Phase-aligned transform for generalized cross correlator." kw:[proc]} // Flags for use with the 'flags' argument to cmPhatAlloc() enum @@ -192,9 +194,10 @@ extern "C" { cmRC_t cmPhatWrite( cmPhat_t* p, const char* dirStr ); - //======================================================================================================================= - // - // + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmReflectCal file_desc:"Calculate the time of flight of Gold code acoustic reflections." kw:[proc]} typedef struct @@ -225,9 +228,11 @@ extern "C" { cmRC_t cmReflectCalcExec( cmReflectCalc_t* p, const cmSample_t* xV, cmSample_t* yV, unsigned xyN ); cmRC_t cmReflectCalcWrite( cmReflectCalc_t* p, const char* dirStr ); - //======================================================================================================================= - // - // + //------------------------------------------------------------------------------------------------------------ + //) + + //( { label:cmNlms file_desc:"Normalized least mean squares echo canceller." kw:[proc]} + typedef struct { cmObj obj; @@ -260,7 +265,8 @@ extern "C" { void cmNlmsEcSetMu( cmNlmsEc_t* p, float mu ); void cmNlmsEcSetDelayN( cmNlmsEc_t* p, unsigned delayN ); void cmNlmsEcSetIrN( cmNlmsEc_t* p, unsigned irN ); - + //) + #ifdef __cplusplus } diff --git a/cmProcObj.h b/cmProcObj.h index 39f1b9d..5baf876 100644 --- a/cmProcObj.h +++ b/cmProcObj.h @@ -5,7 +5,7 @@ extern "C" { #endif - /* + /*( { file_desc:"Base class for all 'proc' objects." kw:[proclib] } The first field in all objects must be an cmObj record. @@ -164,7 +164,8 @@ extern "C" { #define cmMtxFileRealExecN(f,p,n,s) cmMtxFileDoubleExec((f),(p),(n),(s)) #endif - + //) + #ifdef __cplusplus } #endif diff --git a/cmRbm.h b/cmRbm.h index a805740..59deebd 100644 --- a/cmRbm.h +++ b/cmRbm.h @@ -5,6 +5,7 @@ extern "C" { #endif + //( { file_desc:"Restricted Bolzmann Machine object." kw:[model] } enum { kOkRbmRC = cmOkRC, @@ -38,6 +39,8 @@ enum void cmRbmBinaryTest(cmCtx_t* ctx); + //) + #ifdef __cplusplus } #endif diff --git a/cmRpt.c b/cmRpt.c index b941353..716c599 100644 --- a/cmRpt.c +++ b/cmRpt.c @@ -11,7 +11,7 @@ cmRpt_t cmRptNull = { NULL, NULL, NULL }; void _cmDefaultPrint( void* userPtr, const cmChar_t* text ) { if( text != NULL ) - fputs(text,stdin); + fputs(text,stdout); } void _cmDefaultError( void* userPtr, const cmChar_t* text ) diff --git a/cmRpt.h b/cmRpt.h index a9f9f7f..f2e3c33 100644 --- a/cmRpt.h +++ b/cmRpt.h @@ -5,12 +5,10 @@ #ifdef __cplusplus extern "C" { #endif - //{ - //( + //( { file_desc: "The cmRpt class provides console style output for all objects in the cm system." kw:[base]} // - // The cmRpt class provides console style output for all objects in the cm system. // // The cmRpt class provides console output style output, like stdout and stderr // for most of the classes in the cm library. @@ -51,7 +49,6 @@ extern "C" { void cmRptVErrorf( cmRpt_t* rpt, const cmChar_t* fmt, va_list vl ); void cmRptErrorf( cmRpt_t* rpt, const cmChar_t* fmt, ... ); //) - //} #ifdef __cplusplus } diff --git a/cmRtNet.h b/cmRtNet.h index b8472ed..964ce31 100644 --- a/cmRtNet.h +++ b/cmRtNet.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"rtSys networking component." kw:[rtsys network] } + /* Nodes and Endpoints: --------------------- @@ -202,7 +204,8 @@ extern "C" { 4) The symbol -=- in the flow chart implies a network transmission. */ - + //) + #ifdef __cplusplus } #endif diff --git a/cmRtSys.h b/cmRtSys.h index 4774f81..e889d73 100644 --- a/cmRtSys.h +++ b/cmRtSys.h @@ -1,5 +1,4 @@ -// cmRtSys.h -// Implements a real-time audio processing engine. +//( { file_desc:"Improved real-time audio processing engine." kw:[rtsys] } // // The audio system is composed a collection of independent sub-systems. // Each sub-system maintains a thread which runs asynchrounsly @@ -48,10 +47,7 @@ // Messages arriving while the mutex is locked are queued and // delivered to the DSP procedure at the end of the DSP execution // procedure. -// -// Usage example and testing code: -// See cmRtSysTest(). -// \snippet cmRtSys.c cmRtSysTest +//) #ifndef cmRtSys_h #define cmRtSys_h @@ -60,6 +56,7 @@ extern "C" { #endif + //( // Audio system result codes enum { @@ -329,7 +326,7 @@ extern "C" { cmRtRC_t cmRtSysNetReport( cmRtSysH_t h ); cmRtRC_t cmRtSysNetReportSyncEnable( cmRtSysH_t h, bool enableFl ); cmRtRC_t cmRtSysNetGetHandle( cmRtSysH_t h, unsigned rtSubIdx, cmRtNetH_t* hp ); - + //) #ifdef __cplusplus } diff --git a/cmRtSysMsg.h b/cmRtSysMsg.h index 9492905..1c52698 100644 --- a/cmRtSysMsg.h +++ b/cmRtSysMsg.h @@ -4,7 +4,8 @@ #ifdef __cplusplus extern "C" { #endif - + //( { file_desc:"rtSys message contants and data structures." kw:[rtsys] } + // Reserved DSP message selector id's (second field of all // host<->audio system messages) enum @@ -105,7 +106,8 @@ extern "C" { // char msg[ msgByteCnt ] } cmRtNetMsg_t; - + //) + #ifdef __cplusplus } #endif diff --git a/cmSerialize.h b/cmSerialize.h index 701cebb..4780632 100644 --- a/cmSerialize.h +++ b/cmSerialize.h @@ -5,14 +5,8 @@ extern "C" { #endif - //{ - //( - // cmSerialize is an API for serializing data structures into - // byte streams and then deserializing them back into data structures. - // - //) - - //( + //( { file_desc:" An API for serializing data structures into byte streams and then deserializing them back into data structures." kw:[base]} + // Result codes enum @@ -299,7 +293,6 @@ extern "C" { cmSrRC_t cmSrTest( cmCtx_t* ctx ); //) - //} #ifdef __cplusplus } diff --git a/cmStack.h b/cmStack.h index 189acc2..9b6691b 100644 --- a/cmStack.h +++ b/cmStack.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Push-down stack data structure for binary blobs." kw:[container] } + enum { kOkStRC = cmOkRC, @@ -62,7 +64,8 @@ extern "C" { #define cmStackEle(h,t,i) (*(t*)cmStackGet(h,i)) - + //) + #ifdef __cplusplus } #endif diff --git a/cmStrStream.h b/cmStrStream.h index beb5867..81b872f 100644 --- a/cmStrStream.h +++ b/cmStrStream.h @@ -6,6 +6,8 @@ extern "C" { #endif + //( { file_desc:"String stream text sink." kw:[text] } + enum { kOkSsRC = cmOkRC, @@ -34,6 +36,8 @@ extern "C" { void* cmOStrStreamAllocBuf( cmStrStreamH_t h ); cmChar_t* cmOStrStreamAllocText( cmStrStreamH_t h ); + //) + #ifdef __cplusplus } #endif diff --git a/cmSymTbl.h b/cmSymTbl.h index d123e3b..3482ed5 100644 --- a/cmSymTbl.h +++ b/cmSymTbl.h @@ -4,13 +4,8 @@ #ifdef __cplusplus extern "C" { #endif - //{ - //( - // Symbol table component. - //) - + //( { file_desc:"Symbol table object." kw:[base] } - //( typedef cmHandle_t cmSymTblH_t; extern cmSymTblH_t cmSymTblNullHandle; @@ -61,7 +56,6 @@ extern "C" { void cmSymTblTest(cmCtx_t* ctx); //) - //} #ifdef __cplusplus } diff --git a/cmTagFile.h b/cmTagFile.h index d3e28a3..8e96128 100644 --- a/cmTagFile.h +++ b/cmTagFile.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Read a 'ctags' output file." kw:[file] } + // Read a ctags file generated by: // // ctags --c-kinds=+p --fields=+n file.h @@ -61,6 +63,8 @@ extern "C" { cmTfRC_t cmTfTest( cmCtx_t* ctx, const cmChar_t* fn ); + //) + #ifdef __cplusplus } #endif diff --git a/cmTaskMgr.h b/cmTaskMgr.h index 2c150cb..4b80a32 100644 --- a/cmTaskMgr.h +++ b/cmTaskMgr.h @@ -5,7 +5,8 @@ extern "C" { #endif - /* + /*( { file_desc:"Task manager for controlling and monitoring tasks running in independent thread." kw:[parallel]} + Usage: 1) Use cmTaskMgrInstall() to register a worker function (cmTaskMgrFunc_t) with the task manager. @@ -353,7 +354,8 @@ extern "C" { cmTmWorkerRC_t cmTaskMgrWorkerMsgSend( cmTaskMgrFuncArg_t* a, const void* buf, unsigned bufByteCnt ); cmTmRC_t cmTaskMgrTest(cmCtx_t* ctx); - + //) + #ifdef __cplusplus } #endif diff --git a/cmText.h b/cmText.h index dfc10f6..58b3be0 100644 --- a/cmText.h +++ b/cmText.h @@ -5,8 +5,8 @@ extern "C" { #endif - //{ - //( + //( { file_desc:"Text processing functions." kw:[text]} + // // The cmText API supports two basic tasks: the generation of // formatted text into dynamic arrays and text to number parsing. // @@ -297,7 +297,6 @@ extern "C" { //) - //} #ifdef __cplusplus } diff --git a/cmTextTemplate.h b/cmTextTemplate.h index 4a139fb..7a7dbd4 100644 --- a/cmTextTemplate.h +++ b/cmTextTemplate.h @@ -1,55 +1,61 @@ #ifndef cmTextTemplate_h #define cmTextTemplate_h +#ifdef __cplusplus +extern "C" { +#endif -enum -{ - kOkTtRC = cmOkRC, - kFileFailTtRC, - kLHeapFailTtRC, - kSyntaxErrTtRC, - kFindFailTtRC, - kInvalidTypeTtRC, - kJsonFailTtRC -}; + //( { file_desc:"Generate text using templates with replaceable variables." kw:[text] } + enum + { + kOkTtRC = cmOkRC, + kFileFailTtRC, + kLHeapFailTtRC, + kSyntaxErrTtRC, + kFindFailTtRC, + kInvalidTypeTtRC, + kJsonFailTtRC + }; -typedef cmHandle_t cmTtH_t; -typedef unsigned cmTtRC_t; -extern cmTtH_t cmTtNullHandle; + typedef cmHandle_t cmTtH_t; + typedef unsigned cmTtRC_t; + extern cmTtH_t cmTtNullHandle; -// Initialize a template file. -cmTtRC_t cmTextTemplateInitialize( cmCtx_t* ctx, cmTtH_t* hp, const cmChar_t* fn ); + // Initialize a template file. + cmTtRC_t cmTextTemplateInitialize( cmCtx_t* ctx, cmTtH_t* hp, const cmChar_t* fn ); -// Finalize a template file -cmTtRC_t cmTextTemplateFinalize( cmTtH_t* hp ); + // Finalize a template file + cmTtRC_t cmTextTemplateFinalize( cmTtH_t* hp ); -// Return true if the template file is intialized. -bool cmTextTemplateIsValid( cmTtH_t h ); + // Return true if the template file is intialized. + bool cmTextTemplateIsValid( cmTtH_t h ); -// Set the value of a template variable. -// The node identified by { label,index, label, index ... } must -// be a variable node. The function will fail if a 'set' or 'text' node -// is identified. -// Set 'value' to NULL to erase a previously set value. -cmTtRC_t cmTextTemplateSetValue( cmTtH_t h, const cmChar_t* value, const cmChar_t* label, unsigned index, ... ); + // Set the value of a template variable. + // The node identified by { label,index, label, index ... } must + // be a variable node. The function will fail if a 'set' or 'text' node + // is identified. + // Set 'value' to NULL to erase a previously set value. + cmTtRC_t cmTextTemplateSetValue( cmTtH_t h, const cmChar_t* value, const cmChar_t* label, unsigned index, ... ); -// Create a copy of the sub-tree identified by the variable path -// and insert it as the left sibling of the sub-tree's root. -cmTtRC_t cmTextTemplateRepeat( cmTtH_t h, const cmChar_t* label, unsigned index, ... ); + // Create a copy of the sub-tree identified by the variable path + // and insert it as the left sibling of the sub-tree's root. + cmTtRC_t cmTextTemplateRepeat( cmTtH_t h, const cmChar_t* label, unsigned index, ... ); -// Write the template file. -cmTtRC_t cmTextTemplateWrite( cmTtH_t h, const cmChar_t* fn ); + // Write the template file. + cmTtRC_t cmTextTemplateWrite( cmTtH_t h, const cmChar_t* fn ); -// Apply a template value JSON file to this template -cmTtRC_t cmTextTemplateApply( cmTtH_t h, const cmChar_t* fn ); - - -// Print an annotated template tree. -void cmTtPrintTree( cmTtH_t h, cmRpt_t* rpt ); - - -cmTtRC_t cmTextTemplateTest( cmCtx_t* ctx, const cmChar_t* fn ); + // Apply a template value JSON file to this template + cmTtRC_t cmTextTemplateApply( cmTtH_t h, const cmChar_t* fn ); + // Print an annotated template tree. + void cmTtPrintTree( cmTtH_t h, cmRpt_t* rpt ); + cmTtRC_t cmTextTemplateTest( cmCtx_t* ctx, const cmChar_t* fn ); + + //) + +#ifdef __cplusplus +} +#endif #endif diff --git a/cmThread.h b/cmThread.h index 112f3c1..5970d0c 100644 --- a/cmThread.h +++ b/cmThread.h @@ -4,6 +4,7 @@ #ifdef __cplusplus extern "C" { #endif + //( { file_desc:"Threads and thread safe containers." kw:[parallel] } typedef cmHandle_t cmThreadH_t; typedef unsigned cmThRC_t; @@ -85,8 +86,10 @@ extern "C" { void cmThreadSetWaitTimeOutMicros( cmThreadH_t h, unsigned usecs ); void cmThreadTest( cmRpt_t* rpt ); + //) - + //( { label:cmThreadMutex file_desc:"Thread mutex object." kw[parallel]} + //============================================================================ typedef struct { void* h; @@ -109,6 +112,9 @@ extern "C" { cmThRC_t cmThreadMutexSignalCondVar( cmThreadMutexH_t h ); + //) + //( { label:cmTsQueue file_desc:"Thread safe message queue." kw[parallel]} + //============================================================================ // cmThread safe message queue. // @@ -190,6 +196,9 @@ extern "C" { bool cmTsQueueIsValid( cmTsQueueH_t h); + //) + //( { label:cmTs1p1c file_desc:"Single producer/Single consumer non-blocking thread safe queue." kw[parallel]} + //============================================================================ // Single producer / Single consumer thread-safe queue. // These functions have identical semantics and return values @@ -221,6 +230,9 @@ extern "C" { bool cmTs1p1cIsValid( cmTs1p1cH_t h ); + //) + //( { label:cmThCAS file_desc:"Non-blocking primitive operations." kw[parallel]} + //============================================================================ // Thread safe compare-and-swap (actualy compare-and-test). // Returns true if the *addr==new when the function returns @@ -241,6 +253,9 @@ extern "C" { void cmThUIntDecr( unsigned* addr, unsigned decr ); void cmThFloatDecr(float* addr, float decr ); + //) + //( { label:cmMp1c file_desc:"Multiple producer, single consumer non-blocking thread-safe queue." kw[parallel]} + //============================================================================ // Multiple producer / Single consumer thread-safe queue. // These functions have identical semantics and return values // to the same named cmTsQueueXXXX() calls above. @@ -272,15 +287,17 @@ extern "C" { bool cmTsMp1cIsValid( cmTsMp1cH_t h ); - - // Sleep functions - void cmSleepUs( unsigned microseconds ); - void cmSleepMs( unsigned milliseconds ); - - void cmTsQueueTest( cmRpt_t* rpt ); void cmTs1p1cTest( cmRpt_t* rpt ); void cmTsMp1cTest( cmRpt_t* rpt ); + + //) + //( { label:cmSleep file_desc:"Sleep related functions." kw:[time] } + // Sleep functions + void cmSleepUs( unsigned microseconds ); + void cmSleepMs( unsigned milliseconds ); + //) + #ifdef __cplusplus } #endif diff --git a/cmTime.h b/cmTime.h index 212ba81..d161db2 100644 --- a/cmTime.h +++ b/cmTime.h @@ -1,8 +1,7 @@ -//{ { label:cmTime -// kw: [ time ] } +//( { file_desc:"Time cand clock related functions." kw: [ time system ] } +// // -//( // This interface is used to read the systems high resolution timer and // calculate elapsed time. //) @@ -16,12 +15,9 @@ extern "C" { #endif //( - typedef struct timespec cmTimeSpec_t; - /* - get the time - */ + // Get the time void cmTimeGet( cmTimeSpec_t* t ); // Return the elapsed time (t1 - t0) in microseconds @@ -51,7 +47,6 @@ extern "C" { void cmTimeSetZero( cmTimeSpec_t* t0 ); //) - //} #ifdef __cplusplus } diff --git a/cmUdpNet.h b/cmUdpNet.h index 6731e7c..efb2e23 100644 --- a/cmUdpNet.h +++ b/cmUdpNet.h @@ -5,7 +5,7 @@ extern "C" { #endif -/* +/*( { file_desc:"UDP based network object." kw:[network] } A cmUdpNet is a wrapper around a single cmUdpPort. This object maintains an array of remote nodes which map application defined node label/id's to IP address/port. This allows the application @@ -136,6 +136,8 @@ void cmUdpNetReport( cmUdpNetH_t h, cmRpt_t* rpt ); cmRC_t cmUdpNetTest( cmCtx_t* ctx, int argc, const char* argv[] ); + //) + #ifdef __cplusplus } #endif diff --git a/cmUdpPort.h b/cmUdpPort.h index 3a91487..418774f 100644 --- a/cmUdpPort.h +++ b/cmUdpPort.h @@ -4,7 +4,8 @@ #ifdef __cplusplus extern "C" { #endif - + //( { file_desc:"UDP socket interface class." kw:[network] } + #include enum @@ -140,6 +141,8 @@ extern "C" { cmUdpRC_t cmUdpTest( cmCtx_t* ctx, const char* remoteIpAddr, cmUdpPort_t port ); cmUdpRC_t cmUdpTestV( cmCtx_t* ctx, unsigned argc, const char* argv[]); + //) + #ifdef __cplusplus } #endif diff --git a/cmUi.h b/cmUi.h index 9e42e98..60d2f67 100644 --- a/cmUi.h +++ b/cmUi.h @@ -4,7 +4,8 @@ #ifdef __cplusplus extern "C" { #endif - /* + /*( { file_desc:"UI control manager for rtSys." kw:[rtSys]} + cmUI implements a platform independent UI control manager for multiple simultaneous applications. In this context an 'application' can be seen as a plug-in style program. @@ -108,8 +109,10 @@ extern "C" { 7) There is no duplex model for validating and then displaying the value of a control. - */ - + */ + //) + + //( typedef cmHandle_t cmUiH_t; @@ -384,7 +387,8 @@ extern "C" { cmUiRC_t cmUiLastRC( cmUiH_t uiH ); cmUiRC_t cmUiSetRC( cmUiH_t uiH, cmUiRC_t rc ); - + //) + #ifdef __cplusplus } #endif diff --git a/cmUiDrvr.h b/cmUiDrvr.h index 7299fc4..5196e6f 100644 --- a/cmUiDrvr.h +++ b/cmUiDrvr.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( {file_desc:"UI independent driver used by an rtSys application to communicate with the UI." kw:[rtsys]} + typedef unsigned cmUiRC_t; // cmUi result codes @@ -170,6 +172,7 @@ extern "C" { double cmUiDriverArgGetDouble( const cmUiDriverArg_t* a ); const cmChar_t* cmUiDriverArgGetString( const cmUiDriverArg_t* a ); + //) #ifdef __cplusplus } diff --git a/cmUiRtSysMstr.h b/cmUiRtSysMstr.h index 10f1aec..06fda30 100644 --- a/cmUiRtSysMstr.h +++ b/cmUiRtSysMstr.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Application side API for communicating with the UI audio master controls and meters." kw:[rtsys]} + enum { kOkAmRC = cmOkRC, @@ -33,6 +35,8 @@ extern "C" { // Clear the status indicators. void cmUiRtSysMstrClearStatus( cmUiRtMstrH_t h ); + //) + #ifdef __cplusplus } #endif diff --git a/cmVirtNet.h b/cmVirtNet.h index c3faaaf..7b22dcc 100644 --- a/cmVirtNet.h +++ b/cmVirtNet.h @@ -5,6 +5,7 @@ extern "C" { #endif + //( { file_desc:"Wrapper object for cmUdpNet to handle UDP network communications." kw:[network]} enum { kOkVnRC = cmOkRC, @@ -66,6 +67,8 @@ extern "C" { cmVnRC_t cmVnTest( cmCtx_t* ctx ); + //) + #ifdef __cplusplus } #endif diff --git a/dsp/cmDspBuiltIn.c b/dsp/cmDspBuiltIn.c index 3fec5b7..771b0c8 100644 --- a/dsp/cmDspBuiltIn.c +++ b/dsp/cmDspBuiltIn.c @@ -1,3 +1,5 @@ +//( { file_desc:"Built-in 'snap' processor units." kw:[snap]} + #include "cmPrefix.h" #include "cmGlobal.h" #include "cmFloatTypes.h" @@ -46,411 +48,10 @@ #include "sa/cmSaProc.h" -/* -About variables: -1) Variables represent data fields within a DSP object. -2) Variables may also act as input (kInDsvFl) and/or output (kOutDsvFl) ports. - A. Audio Ports - - Audio output ports (kAudioBufDsvFl) publish a buffer of samples to subscribing - audio input ports on other instances. (See cmDspSysConnectAudio(). ) - - - Output audio ports are instantiated with physical buffers to hold samples of - audio. Input audio ports contain internal pointers with point to the - audio buffers of connected output ports. - - - Set cmDspVarArg_t.cn to the number of channels of audio the buffer will contain. - - B. Non-Audio Ports - - Non-audio input ports may register to be called when output port values change. - via cmDspSysInstallCb(). - - - Type checking is done to guarantee that the output port data type matches one of the - input port types or can be converted to one of the input port types. - [TODO: Check how this is handled in cmDspSetEvent(). Let's say that an input port - takes either a number or string. This conversion is not possible within the - cmDspValue() framework - and yet it should work - or give an error ] - - -3) Creating variable instances. - A. All variables must be given default values in the instance constructor - _cmDspXXXAlloc(). This can be done automatically be giving default values - in the var args section of the cmDspSysAllocInst() call or by explicitely - setting default values via cmDspSetDefaultXXX() in _cmDspXXXAlloc(). - - B. The _cmDspXXXReset() function automatically resets all the instance variables to their - default value. By default, variables do not transmit their values when they are - reset to their default value - unless the variable is marked with the kSendDfltDsvFl. - (See cmDspClass.c:cmDspApplyDefault()). The 'out' port on cmDspScalar_t and cmDspButton_t - are examples of instances that transmit their default value on reset. - - The order that instances are reset is determined by the order that they were created. - - A subtle case can arise when relying on default values to set the initial value of - another object. Given two object instances A and B. Where The output of A has the - the kSendDfltDsvFl set and is connected to an input port on B. If instance A was - created before instance B then instance A will reset before instance B. During reset - the output port of A will transmit it's default value to B - as expected. However - when reset is called on instance B it will overwrite this value with it's own - default value. - - In order for this scenario to work - that is the output of instance A sets the initial - value of instance B - instance B must be created first. - - Since creation order also determines execution order this solution may not always - be possible. It may be that we would simultaneously like instance A to exeute first - and also recieve its initial value from instance B. Given the above example however - these two goals are mutually exclusive. - - [*] This could be solved by explicitely allowing a variable to be reset via - a callback. In this case if a variable was set via a callback during reset - then it would not overwrite that value with its own internal value. This - functionality would need to be set on a per instance bases - which might - not work well with the current cmDspSysAllocInst() var args scheme. - - When a single output port is connected to multiple input ports the input ports - are called in the order that the connections were made. - - To overcome this problem the reset cycle has been broken into two parts. - In the first part the resetFunc is called on each instance in creation order. - (as described above). Following this pass a second pass is made where the - sysRecvFunc on any instance tagged with the '_reset' attribute is called. - This allows an event callback chain to be executed prior to the first - set of execFunc calls. Note that the event callback chain(s) are programmed - by cmDspInstallCb() connections which are setup on a per application basis. - This allows the initial state of the network to be set outside of the - creation order. - - The 'button' instance implements a sysRecvFunc which will send the buttons - value and symbol when called with the '_reset' attribute symbol. If a - 'reset' button is created and assigned the '_reset' attribute symbol - (via cmDspSysAssignAttrSymbol()) then the output of the button can be used - to drive a networks initial state in an order determined by the application - programmer. - - - [TODO: Add a check that all instance variables have default values at the end of - the network reset. This should be easy because the instance variable flag - kDfltSetDsvFl is set in cmDspValueSet() when the default value is set.] - - C. The default value of variables may be set via the var args portion of cmDspSysAllocInst(). - - There is currently a weakness during variable instance creation function - cmDspInstAlloc() uses the cmDspVarArg_t.flags to determine the type of the var arg - argument. cmDspVarArg_t.flags can therefore only be set to one DSV type - and the - actual argument in the cmDspSysAllocInst() call must match that type. This is very - easy to mess up - for example by setting the flag to kIntDsvFl and then putting - 0.0 as the var arg value. This limitation also prevents ports which are also - required arguments to cmDspSysAllocInst() (i.e. kReqArgDsvFl) from supporting - multiple types. - - There are two possible ways to fix this: - 1) Include the type flag in the var args list. - 2) Specify a seperate var args flag in cmDspVarArg_t. - Option 1 seems better because: - a. [**] It would allow setting other per instance flags in the cmDspSysAllocInst() call [*]. - b. It would support setting a var arg termination flag rather than relying on the current - explicit argument count. - c. This is also the method used in cmJsonMemberValues() and it has worked well there. - Either of these options requires a substantial change to existing code. - This change should therefore be made sooner rather than later. - - As the system currently works it is possible, and it often happens, that - an instance's recv function will be called before it is reset. It seems like - this is a bad thing. Maybe the process of resetting and transmitting dflt - values should be broken into seperate passes. This idea could be extended - to type checking as follows: - a. a reset-0 pass is made to set the internal state of each instance to - known values. - - b. a type check pass is made where each output port - sends a type msg to all connected input ports to provide the types that - it will send. - - c. a reset-1 pass is made allowing all of the type information to be - used to determine the initial state. - - d. an initial default value transmission pass is made where some instances - (like scalars) may transmit initial values - - e. a reset-2 pass is made allowing the initial values to be acted on. - - f. runtime occurs - - D. Questions: - 0) What are the ways that an instance variable can get set? - a. cmDspValueSet() - This is the canonical value setting function. - All other value setting function call this function. - The cmDspSetXXX() are type safe wrappers to this function. - - b. cmDspApplyDefault() - assign the default value to the actual variable - via a call to cmDspValueSet(). This function is automatically called - by cmDspApplyAllDefaults() which is usually in the instance reset function. - - c. cmDspSetEvent() - assign the value embedded in an event message - to a variable. This is a wrapper function for cmDspValueSet() which - checks to see if the value need to be echoed to the UI. See - more about UI echoing in the next section. - - 1) Where do events arriving at an instance receive function originate from? - There are two sources of events: - 1. The output ports of other instances. - 2. The UI (client application). - - Events arriving from the UI can be distinguished from events arriving - from other instances because they have the evt.kUiDspFl flag set. - - 2) How does UI updating and echoing actually work? - a. Overview: - On creation (in cmDsUi.c) variables whose value must be reflected to the UI - are marked with the kUiDsvFl - these variables are called 'UI variables'. - When a UI variable receive a new value - the new value must be reflected in the associated UI GUI control. - - When and how this is accomplished depends on the source of the new - variable value. There are two sources of events arriving at - an instance's receive function: the output port of another instance - or the UI. - - Events which originate from the UI are marked with a evt.kUiDspFl. - (cmDspSys.c:_cmDspSysHandleUiMsg()) - - When a UI variable receives a value from the output port of another - instance (i.e. kUiDspFl not set) then it must always send that value to - the UI. In other words if the evt.kUiDspFl is NOT set then the - value must be sent to the UI. - - When a UI variable receives a value from the UI (i.e. the evt.kUiDspFl is set) - it may or may not need to reflect the value. If the UI already - reflects the value then the value does not need to be sent back - otherwise it does. - - The UI control determines whether it wants to receive the value it - is sending back by setting the kDuplexDuiFl flag in it's msg to the engine. - Upon receipt of this msg, in cmDspSys.c:_cmDspSysHandleUiMsg(), - the system converts the msg to an event. If the kDuplexDuiFl - is set then the kUiEchoDspFl is set in the event. - - When a UI variable receives a value from the UI and the evt.kUiEchoDspFl - is set then the value must be reflected, otherwise it must not. - - The rules for updating UI variables (var. w/ kUiDsvFl set) can - be summarized as follows: - - kUiDspFl kUiEchoDspFl Send to UI Notes - -------- ------------ ---------- ------------------------------------------------------------- - 0 0 Yes The value originated from another port and therefore must be reflected. - 0 1 If kUiEchoDspFl is set then so must kUiDspFl. - 1 0 No - 1 1 Yes The value originated from the UI and ehco was requested. - - This logic is automatically handled together by - cmDspSetEvent() and cmDspValueSet(). - - - b. Variable values are sent and received to and from the UI using - kValueDuiId messages. - - c. It is possible to prevent values generated in the engine from being - reflected to the UI by setting the kNoUpdateUiDspFl in the call to - cmDspValueSet(). - - d. Instance variables are marked as UI variables by the cmDspUIXXXCreate() - functions. Note that instances that have assoicated UI controls generally - have multiple UI variables. (e.g. min,max,step,label,value). - - e. Messages arriving from the UI are handled by cmDspSys.c:_cmDspSysHandleUiMsg() - where they are converted to cmDspEvt_t's. All events generated from - msgs arriving from the UI are marked with the kUiDspFl. If the msg kDuplexDuiFl - is set then the event flag kUiEchoDspFl is set - to indicate that the instance - should send the value back to the UI. - - This leads to the following potential situation: The msg with kUiEchoDspFl - set arrives at its target instance - which in turn calls cmDspSetEvent() to update - the target variable value. Because kUiEchoDspFl is set the value is automatically - reflected to the UI as expected. However as part of the call to - cmDspValueSet() within cmDspSetEvent() the event is also sent to any connected - instances - a problem would occur if kUiEchoDspFl remained set when it - was sent to the connected instances - because they might then also try to update - their own UI inappropriately. In fact this is not a problem because - _cmDspSendEvt() zeros the the evt.flags value prior to resending the event. - - - 3) Proposed Data Typing Framework: - a. Instance variables are assigned 3 data types: - 1. cmDspSysAllocInst() var args type. This is the type that the var args argument - to the instance constructor must be. The value provided by this method - becomes the default value for the variable. This type must be unique - multiple - type flags cannot be used for this value. - - 2. Strict data type. This is the type used to define the variable value. - Any values which will be used to set the value of this variable must be able - to be converted to this type. - - If the variable is used as on input then the system will warn if an output port - is assigned which cannot be converted to this type. If the variable is used as - an output then this is the type the variable will publish as the output type. - - All values arriving at the functions 'recv' function are guaranteed to be - able to be converted to this type. - - 3. Alternate data types. Multiple types may be given to this type. - If no strict data type is given then this will be the set of types accepted - for input and reported for output. - - All value messages for the instance which do not fit the strict data type, - but do fit the alternate data type, will be sent to the 'altRecvFunc' - function. The data type of events arriving at this function may therefore - need to be decoded in order to use the assoicated values. - - b. Connections from an output with a strict data type can be type checked in - advance - since they are guaranteed to emit a specific data type. - - Connections from outputs without strict data types can only be type checked - at runtime - since it is possible for the type to change once the execution - starts. - - c. Other notes about data types: - It seems like cmDsvValues() should in general only allow one type flag (along with - the kMtxDsvFl) to be set at a time if the flag state is legal. Is this always the - case? Can a macro be included to routinely check this? Are we careful to - not confuse the actual and possible type flags in DSP instance variables? - This is important when checking the types of variables arriving at in input port. - Include a macro to test the legality of the actual value type leaving output ports - and entering input ports. - - Note that the cmXXXDsvFl flags have the problem that it is not possible to - specify some multiple types. For example it is not possible to specify both - scalar and matrix types simultaneously. Once the matrix flag is set it must - be assumed that all specific data types then are matrices. - THIS IS A FUNDAMENTAL PROBLEM THAT MUST BE ADDRESSED. - - Note that scalar numeric values can easily be cheaply converted to other numeric - types. It could be expensive however if vectors required conversion. - Vectors are currently being passed as pointers. No conversion is occurring. - - d. Another proposal: - Following connection time there is a type determination pass. The network - is traversed in execution order. Each instance computes and emits the single - type assigned to each of its output ports. Once emited these types will not - change during runtime. - - Note that this does not preclude an input receiving multiple types. - If a variable arrives at an input port which does not match the type of - the variable associated with that type then it is sent to the NoTypeRecv() - instance function. - - - - 2. Do values only get sent on change? If not - why not? - No - based on cmDspClass.ccmDspValueSet() values are transmitted - whenever they are set - there is not check for a change of value. - - - 3. Write a function to support generating multiple enumerated - ports - as is required by AMix or ASplit. - (This is now done: See cmDspClass.h:cmDspArgSetup() ) - Update the existing code to use this scheme. (This still needs to be done.) - Similar functions need to be written for connecting groups of ports - in cmDspPgm.c. (This still needs to be done.) - - - 5. It does not appear that the kInDsvFl and kOutDsvFl are actually used during - the connection process. This means that a variable marked as an output - could be used as an input and v.v.. Likewise variable marked as neither input - nor output could be accessed. What are the input and output flags actually - used for? - - In fact kInDsvFl and kOutDsvFl are not used at all. (3/18/12). - - It might be nice to allow everything to be an output - but to - force inputs to be explicitely named. - - - 6. Is there any implication for marking a variable as both an input and an output? - 7. The audio buffers allocated in cmDspInstAlloc() may not be memory aligned. - 8. Is there a way to add a generic enable/disable function to all instances? - 9. Should all output audio buffers be zeroed by default during _cmDspXXXReset()? - 10. Is the kConstDsvFl used? respected? necessary? - yes - it is necessary because some variables cannot be changed after the constructor - is completed. For example any instance that take an argument giving the - number of ports as a variable. The port count argument cannot change because it - might invalidate connections which had been already made to the existing ports. - TODO: find all variables which cannot be changed after the constructor and mark - them as const and prevent them from being the target of connections or events. - - 11. Is it OK to not assign a variable as either an input or an output. (this would - allow it to be set from cmDspSysAllocInst() but then only changed internally). - - 12. Write some template DSP instances that provide commented examples of the - common scenarios which an actual instance might encounter. - - 13. All errors in instances should use cmDspClassErr() or cmDspInstErr() not cmErrMsg(). - Update existing code. - - 14. The way that the master controls are created is wrong. The master controls should - be created during the cmDspSysLoad() process rather than being created in kcApp.cpp. - This would make them essentially identical to other controls - and would allow the - master controls to be manipulated easily from inside a DSP instance. - - 15. The code for creating and decoding messages seems to be distributed everywhere. - All of this functionality should be moved to cmMsgProtocol.c. See the code - for encoding/decoding messages in cmAudioSys.c as an example. - - 16. The default behavior of buttons should be to to NOT send out their default values or - symbols on instance reset. Determining whether an output value is sent on instance - reset (as they all are currently ??? or are only UI sent out on reset???) - could be another argument flag setting [**]. - - 17. cmDspInstAlloc() should include another version called cmDspInstAllocV() - which takes the cmDspArg_t fields as var args. This would allow - array variables which currently use cmDspArgSetupN() to be given - in one call - which would be less error prone than using cmDspArgSetupN(). - - 18. Add helper functions to create common dsp instances like: - scalar,button,check,file,audio in,audio out. These functions should - support default values through literals or through resource paths. - - 19. Design a sub-net function for making sub-nets of instance nets - that can then be treated like instances themselves. - For example make a network of audio sources: - audio file, signal generator, audio input, with gain and frequency - controls. - - 20. Network construction (cmDspPgm.c) is divided into two parts. - First the instances are allocated and then they are connected. - There should always be a test for a failure between construction - phase and the connection phase and then again after the connection phase. - - 21. The existing instances are not using cmReal_t and cmSample_t as they should. - - 22. It is possible for cmDspInstAlloc() to fail in an instance constructor and - yet we are not testing for it in many instances. - When a failure occurs after cmDspInstAlloc() how is the instance deleted - prior to returning? ... is it necessary to delete it prior to returning? - - 23. For instances which act as files and which take a file name as at an input - port - the correct way to implement the object is to open/reopen the file - both on reset and when a new file name is received. - The reset open covers the case where the default filename is used. - The receieve open covers the case where a filename is received via the input port. - - 24. After each call to an instance member function (reset,recv,exec,etc.) the - interal error object should be checked. This way an invalid state can - be signaled inside one of the functions without having to worry about - propagating the error to the return value. THis means that as long as - a member function can report and safely complete it doesn't have to do - much error handling internally. - - 25. As it is currently implemented all audio system sub-system share a - single UDP network managers. This is NOT thread-safe. If more than - one audio sub-system is actually used the program will crash. - This can be solved by giving each sub-system it's own UDP network - manager, where each sub-system is given it's own port number. - -*/ - -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspPrinter file_desc:"Console printing unit." kw:[sunit] } enum { kLblPrId, @@ -513,7 +114,7 @@ cmDspRC_t _cmDspPrinterRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return kOkDspRC; } -struct cmDspClass_str* cmPrinterClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmPrinterClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmPrinterDC,ctx,"Printer", NULL, @@ -529,7 +130,9 @@ struct cmDspClass_str* cmPrinterClassCons( cmDspCtx_t* ctx ) return &_cmPrinterDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspCounter file_desc:"Counter unit." kw:[sunit] } enum { kMinCntId, @@ -691,7 +294,7 @@ cmDspRC_t _cmDspCounterRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t -struct cmDspClass_str* cmCounterClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmCounterClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmCounterDC,ctx,"Counter", NULL, @@ -708,8 +311,10 @@ struct cmDspClass_str* cmCounterClassCons( cmDspCtx_t* ctx ) } +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspPhasor file_desc:"Ramp signal generator." kw:[sunit] } -//========================================================================================================================================== enum { kMaxPhId, @@ -799,7 +404,7 @@ cmDspRC_t _cmDspPhasorRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return kOkDspRC; } -struct cmDspClass_str* cmPhasorClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmPhasorClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmPhasorDC,ctx,"Phasor", NULL, @@ -815,7 +420,9 @@ struct cmDspClass_str* cmPhasorClassCons( cmDspCtx_t* ctx ) return &_cmPhasorDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspSigGen file_desc:"Programmable periodic and noise signal generator." kw:[sunit] } enum { kHzSgId, @@ -974,7 +581,7 @@ cmDspRC_t _cmDspSigGenRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* -struct cmDspClass_str* cmSigGenClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmSigGenClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmSigGenDC,ctx,"SigGen", NULL, @@ -990,7 +597,9 @@ struct cmDspClass_str* cmSigGenClassCons( cmDspCtx_t* ctx ) return &_cmSigGenDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspMidiIn file_desc:"MIDI input port." kw:[sunit] } enum { kDeviceMiId, @@ -1045,7 +654,7 @@ cmDspRC_t _cmDspMidiInReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return rc; } -cmDspRC_t _cmDspMidiInRecvFunc( cmDspCtx_t* ctx, struct cmDspInst_str* inst, unsigned attrSymId, const cmDspValue_t* value ) +cmDspRC_t _cmDspMidiInRecvFunc( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned attrSymId, const cmDspValue_t* value ) { cmDspMidiIn_t* p = (cmDspMidiIn_t*)inst; @@ -1083,7 +692,7 @@ cmDspRC_t _cmDspMidiInRecvFunc( cmDspCtx_t* ctx, struct cmDspInst_str* inst, return kOkDspRC; } -struct cmDspClass_str* cmMidiInClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmMidiInClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmMidiInDC,ctx,"MidiIn", NULL, @@ -1099,7 +708,9 @@ struct cmDspClass_str* cmMidiInClassCons( cmDspCtx_t* ctx ) return &_cmMidiInDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspMidiOut file_desc:"MIDI output port." kw:[sunit] } enum { kDeviceMoId, @@ -1239,7 +850,7 @@ cmDspRC_t _cmDspMidiOutRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return kOkDspRC; } -struct cmDspClass_str* cmMidiOutClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmMidiOutClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmMidiOutDC,ctx,"MidiOut", NULL, @@ -1255,7 +866,9 @@ struct cmDspClass_str* cmMidiOutClassCons( cmDspCtx_t* ctx ) return &_cmMidiOutDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspAudioIn file_desc:"Audio input port." kw:[sunit] } enum { kChAiId, @@ -1356,7 +969,7 @@ cmDspRC_t _cmDspAudioInRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return rc; } -struct cmDspClass_str* cmAudioInClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmAudioInClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmAudioInDC,ctx,"AudioIn", NULL, @@ -1375,7 +988,9 @@ struct cmDspClass_str* cmAudioInClassCons( cmDspCtx_t* ctx ) -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspAudioOut file_desc:"Audio output port." kw:[sunit] } enum { kChAoId, @@ -1471,7 +1086,7 @@ cmDspRC_t _cmDspAudioOutRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return rc; } -struct cmDspClass_str* cmAudioOutClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmAudioOutClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmAudioOutDC,ctx,"AudioOut", NULL, @@ -1486,7 +1101,9 @@ struct cmDspClass_str* cmAudioOutClassCons( cmDspCtx_t* ctx ) return &_cmAudioOutDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspAudioFileOut file_desc:"Audio output port which is sent to an audio file." kw:[sunit] } enum { kFnAofId, @@ -1669,7 +1286,7 @@ cmDspRC_t _cmDspAudioFileOutRecv( cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDs return rc; } -cmDspRC_t _cmDspAudioFileOutFree( cmDspCtx_t* ctx, struct cmDspInst_str* inst, const cmDspEvt_t* evtPtr ) +cmDspRC_t _cmDspAudioFileOutFree( cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evtPtr ) { cmDspAudioFileOut_t* p = (cmDspAudioFileOut_t*)inst; @@ -1681,7 +1298,7 @@ cmDspRC_t _cmDspAudioFileOutFree( cmDspCtx_t* ctx, struct cmDspInst_str* inst, return kOkDspRC; } -struct cmDspClass_str* cmAudioFileOutClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmAudioFileOutClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmAudioFileOutDC,ctx,"AudioFileOut", NULL, @@ -1696,7 +1313,9 @@ struct cmDspClass_str* cmAudioFileOutClassCons( cmDspCtx_t* ctx ) return &_cmAudioFileOutDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspScalar file_desc:"User interface unit which represents a single scalar value." kw:[sunit] } enum { kTypScId, @@ -1783,7 +1402,7 @@ cmDspRC_t _cmDspScalarPresetRdWr( cmDspCtx_t* ctx, cmDspInst_t* inst, bool st return cmDspVarPresetRdWr(ctx,inst,kValScId,storeFl); } -struct cmDspClass_str* cmScalarClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmScalarClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmScalarDC,ctx,"Scalar", NULL, @@ -1799,7 +1418,9 @@ struct cmDspClass_str* cmScalarClassCons( cmDspCtx_t* ctx ) return &_cmScalarDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspText file_desc:"User interface unit which allows text input." kw:[sunit] } enum { kValTxId, @@ -1852,7 +1473,7 @@ cmDspRC_t _cmDspTextRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* e return kOkDspRC; } -struct cmDspClass_str* cmTextClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmTextClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmTextDC,ctx,"Text", NULL, @@ -1868,7 +1489,9 @@ struct cmDspClass_str* cmTextClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspMeter file_desc:"User interface progress bar which displays the current value of a scalar variable." kw:[sunit] } enum { kInMtId, @@ -1970,7 +1593,7 @@ cmDspRC_t _cmDspMeterRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* } -struct cmDspClass_str* cmMeterClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmMeterClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmMeterDC,ctx,"Meter", NULL, @@ -1986,7 +1609,9 @@ struct cmDspClass_str* cmMeterClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspLabel file_desc:"User interface unit which displays read-only text." kw:[sunit] } enum { kInLbId, @@ -2030,7 +1655,7 @@ cmDspRC_t _cmDspLabelRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return cmDspSetEvent(ctx,inst,evt); } -struct cmDspClass_str* cmLabelClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmLabelClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmLabelDC,ctx,"Label", NULL, @@ -2046,7 +1671,9 @@ struct cmDspClass_str* cmLabelClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspButton file_desc:"User interface sends a user defined value from a graphic button press." kw:[sunit] } enum { kTypBtId, @@ -2141,7 +1768,7 @@ cmDspRC_t _cmDspButtonPresetRdWr( cmDspCtx_t* ctx, cmDspInst_t* inst, bool st return rc; } -cmDspRC_t _cmDspButtonSysRecvFunc( cmDspCtx_t* ctx, struct cmDspInst_str* inst, unsigned attrSymId, const cmDspValue_t* value ) +cmDspRC_t _cmDspButtonSysRecvFunc( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned attrSymId, const cmDspValue_t* value ) { cmDspButton_t* p = (cmDspButton_t*)inst; if( attrSymId == p->resetSymId ) @@ -2153,7 +1780,7 @@ cmDspRC_t _cmDspButtonSysRecvFunc( cmDspCtx_t* ctx, struct cmDspInst_str* ins return kOkDspRC; } -struct cmDspClass_str* cmButtonClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmButtonClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmButtonDC,ctx,"Button", NULL, @@ -2169,7 +1796,9 @@ struct cmDspClass_str* cmButtonClassCons( cmDspCtx_t* ctx ) return &_cmButtonDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspCheckbox file_desc:"Graphic checkbox user interface unit." kw:[sunit] } enum { kLblCbId, @@ -2312,7 +1941,7 @@ cmDspRC_t _cmDspCheckboxPresetRdWr( cmDspCtx_t* ctx, cmDspInst_t* inst, bool return cmDspVarPresetRdWr(ctx,inst,kOutCbId,storeFl); } -cmDspRC_t _cmDspCheckboxSysRecvFunc( cmDspCtx_t* ctx, struct cmDspInst_str* inst, unsigned attrSymId, const cmDspValue_t* value ) +cmDspRC_t _cmDspCheckboxSysRecvFunc( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned attrSymId, const cmDspValue_t* value ) { cmDspCheckbox_t* p = (cmDspCheckbox_t*)inst; if( attrSymId == p->resetSymId ) @@ -2324,7 +1953,7 @@ cmDspRC_t _cmDspCheckboxSysRecvFunc( cmDspCtx_t* ctx, struct cmDspInst_str* i return kOkDspRC; } -struct cmDspClass_str* cmCheckboxClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmCheckboxClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmCheckboxDC,ctx,"Checkbox", NULL, @@ -2340,7 +1969,10 @@ struct cmDspClass_str* cmCheckboxClassCons( cmDspCtx_t* ctx ) return &_cmCheckboxDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspReorder file_desc:"Collect inputs in any order and transmit them in a defined order." kw:[sunit] } + cmDspClass_t _cmReorderDC; typedef struct @@ -2467,7 +2099,7 @@ cmDspRC_t _cmDspReorderRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return rc; } -struct cmDspClass_str* cmReorderClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmReorderClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmReorderDC,ctx,"Reorder", NULL, @@ -2482,8 +2114,9 @@ struct cmDspClass_str* cmReorderClassCons( cmDspCtx_t* ctx ) return &_cmReorderDC; } - -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspFname file_desc:"User interface file or directory name input unit." kw:[sunit] } enum { kDirFnId, @@ -2557,7 +2190,7 @@ cmDspRC_t _cmDspFnameRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return kOkDspRC; } -struct cmDspClass_str* cmFnameClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmFnameClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmFnameDC,ctx,"Fname", NULL, @@ -2572,7 +2205,9 @@ struct cmDspClass_str* cmFnameClassCons( cmDspCtx_t* ctx ) return &_cmFnameDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspMsgList file_desc:"User interface list unit." kw:[sunit] } cmDspClass_t _cmMsgListDC; @@ -3169,7 +2804,7 @@ cmDspRC_t _cmDspMsgListPresetRdWr( cmDspCtx_t* ctx, cmDspInst_t* inst, bool s } -struct cmDspClass_str* cmMsgListClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmMsgListClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmMsgListDC,ctx,"MsgList", NULL, @@ -3185,7 +2820,9 @@ struct cmDspClass_str* cmMsgListClassCons( cmDspCtx_t* ctx ) return &_cmMsgListDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspWavetable file_desc:"Programmable wavetable unit." kw:[sunit] } enum { @@ -3259,7 +2896,7 @@ cmDspInst_t* _cmDspWaveTableAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsi cmDspVarArg_t args[] = { { "len", kLenWtId, 0, 0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "Wave table length in samples" }, - { "shape", kShapeWtId, 0, 0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "Wave shape 0=silent 1=file 2=sine 3=white" }, + { "shape", kShapeWtId, 0, 0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "Wave shape 0=silent 1=file 2=white 3=pink 4=sine, 5=cos 6=sqr 7=tri 8=saw 9=pulse 10=impulse 11=phasor" }, { "fn", kFnWtId, 0, 0, kInDsvFl | kStrzDsvFl | kOptArgDsvFl, "Optional audio file name" }, { "loop", kLoopWtId, 0, 0, kInDsvFl | kIntDsvFl | kOptArgDsvFl, "-1=loop forever >0=loop count (dflt:-1)"}, { "beg", kBegWtId, 0, 0, kInDsvFl | kIntDsvFl | kOptArgDsvFl, "File begin sample index" }, @@ -3841,7 +3478,7 @@ cmDspRC_t _cmDspWaveTableRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt -struct cmDspClass_str* cmWaveTableClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmWaveTableClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmWaveTableDC,ctx,"WaveTable", NULL, @@ -3857,7 +3494,9 @@ struct cmDspClass_str* cmWaveTableClassCons( cmDspCtx_t* ctx ) return &_cmWaveTableDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspSprintf file_desc:"Printf like string formatting unit." kw:[sunit] } enum { kFmtSpId, @@ -4218,7 +3857,7 @@ cmDspRC_t _cmDspSprintfRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return rc; } -struct cmDspClass_str* cmSprintfClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmSprintfClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmSprintfDC,ctx,"Sprintf", NULL, @@ -4233,7 +3872,9 @@ struct cmDspClass_str* cmSprintfClassCons( cmDspCtx_t* ctx ) return &_cmSprintfDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspAMix file_desc:"Audio mixer." kw:[sunit] } enum { kOutAmId, @@ -4372,7 +4013,7 @@ cmDspRC_t _cmDspAMixRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* e return rc; } -struct cmDspClass_str* cmAMixClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmAMixClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmAMixDC,ctx,"AMix", NULL, @@ -4387,7 +4028,9 @@ struct cmDspClass_str* cmAMixClassCons( cmDspCtx_t* ctx ) return &_cmAMixDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspASplit file_desc:"Audio splitter with individual gain control." kw:[sunit] } enum { kInAsId, @@ -4527,7 +4170,7 @@ cmDspRC_t _cmDspASplitRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return rc; } -struct cmDspClass_str* cmASplitClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmASplitClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmASplitDC,ctx,"ASplit", NULL, @@ -4542,7 +4185,9 @@ struct cmDspClass_str* cmASplitClassCons( cmDspCtx_t* ctx ) return &_cmASplitDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspAMeter file_desc:"Audio level meter." kw:[sunit] } enum { kInAmId, @@ -4645,7 +4290,7 @@ cmDspRC_t _cmDspAMeterExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* } -struct cmDspClass_str* cmAMeterClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmAMeterClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmAMeterDC,ctx,"AMeter", NULL, @@ -4660,7 +4305,9 @@ struct cmDspClass_str* cmAMeterClassCons( cmDspCtx_t* ctx ) return &_cmAMeterDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspTextFile file_desc:"Create text files which can be read by the Octave function cmTextFile.m." kw:[sunit] } // // @@ -4790,7 +4437,7 @@ cmDspRC_t _cmDspTextFileRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return kOkDspRC; } -struct cmDspClass_str* cmTextFileClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmTextFileClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmTextFileDC,ctx,"TextFile", NULL, @@ -4805,7 +4452,9 @@ struct cmDspClass_str* cmTextFileClassCons( cmDspCtx_t* ctx ) return &_cmTextFileDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspArray file_desc:"Read in a symbol/value list from a resource and selectively transmit values." kw:[sunit] } enum { kRsrcArId, @@ -4949,7 +4598,7 @@ cmDspRC_t _cmDspArrayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return kOkDspRC; } -struct cmDspClass_str* cmArrayClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmArrayClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmArrayDC,ctx,"Array", NULL, @@ -4965,7 +4614,9 @@ struct cmDspClass_str* cmArrayClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspPitchCvt file_desc:"Convert between MIDI,scientific pitch, and pitch ratio values." kw:[sunit] } enum { @@ -5058,7 +4709,7 @@ cmDspRC_t _cmDspPitchCvtRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return rc; } -struct cmDspClass_str* cmPitchCvtClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmPitchCvtClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmPitchCvtDC,ctx,"PitchCvt", NULL, @@ -5073,13 +4724,10 @@ struct cmDspClass_str* cmPitchCvtClassCons( cmDspCtx_t* ctx ) return &_cmPitchCvtDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspBinMtx file_desc:"Create a file which can be read by the Octave function readBinFile.m." kw:[sunit] } -// -// -// Create a file which can be read by readBinFile.m -// -// enum { @@ -5210,7 +4858,7 @@ cmDspRC_t _cmDspBinMtxFileRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv return rc; } -struct cmDspClass_str* cmBinMtxFileClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmBinMtxFileClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmBinMtxFileDC,ctx,"BinMtxFile", NULL, @@ -5226,7 +4874,9 @@ struct cmDspClass_str* cmBinMtxFileClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspShiftBuf file_desc:"Real-time shift buffer." kw:[sunit] } enum { kHopMsSbId, @@ -5330,7 +4980,7 @@ cmDspRC_t _cmDspShiftBufExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return kOkDspRC; } -struct cmDspClass_str* cmShiftBufClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmShiftBufClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmShiftBufDC,ctx,"ShiftBuf", NULL, @@ -5345,7 +4995,9 @@ struct cmDspClass_str* cmShiftBufClassCons( cmDspCtx_t* ctx ) return &_cmShiftBufDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspNetSend file_desc:"Transmit a value to a remote 'snap' host over the 'snap' UDP network." kw:[sunit] } enum { kInNsId @@ -5388,7 +5040,7 @@ cmDspRC_t _cmDspNetSendRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return _cmDspSysNetSendEvent(ctx->dspH, p->srcConnPtr->dstNetNodeId, p->srcConnPtr->dstId, evt ); } -struct cmDspClass_str* cmNetSendClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmNetSendClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmNetSendDC,ctx,"NetSend", NULL, @@ -5403,7 +5055,9 @@ struct cmDspClass_str* cmNetSendClassCons( cmDspCtx_t* ctx ) return &_cmNetSendDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspRsrWr file_desc:"Set a 'snap' resource value." kw:[sunit] } enum { kBaseInPtsId, @@ -5500,7 +5154,7 @@ cmDspRC_t _cmDspRsrcWrRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return rc; } -struct cmDspClass_str* cmRsrcWrClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmRsrcWrClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmRsrcWrDC,ctx,"RsrcWr", NULL, @@ -5516,7 +5170,10 @@ struct cmDspClass_str* cmRsrcWrClassCons( cmDspCtx_t* ctx ) return &_cmRsrcWrDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspBinEnc file_desc:"HRTF binaural encoder." kw:[sunit] } + enum { kModeBeId, @@ -5649,7 +5306,7 @@ cmDspRC_t _cmDspBinEncRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return rc; } -struct cmDspClass_str* cmBinEncClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmBinEncClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmBeDC,ctx,"BinauralEnc", NULL, @@ -5664,7 +5321,9 @@ struct cmDspClass_str* cmBinEncClassCons( cmDspCtx_t* ctx ) return &_cmBeDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDsp2d file_desc:"Two dimension graphic user interface controller." kw:[sunit] } enum { kX2dId, @@ -5718,7 +5377,7 @@ cmDspRC_t _cmDsp2dRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt } -struct cmDspClass_str* cm2dClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cm2dClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cm2dDC,ctx,"twod", NULL, @@ -5733,12 +5392,10 @@ struct cmDspClass_str* cm2dClassCons( cmDspCtx_t* ctx ) return &_cm2dDC; } - +//) //========================================================================================================================================== - -//========================================================================================================================================== - +//( cmDspClassConsFunc_t _cmDspClassBuiltInArray[] = { @@ -5851,3 +5508,4 @@ cmDspClassConsFunc_t cmDspClassGetBuiltIn( unsigned index ) return _cmDspClassBuiltInArray[index]; } +//) diff --git a/dsp/cmDspClass.c b/dsp/cmDspClass.c index bb2c32e..e4b3b78 100644 --- a/dsp/cmDspClass.c +++ b/dsp/cmDspClass.c @@ -372,18 +372,19 @@ cmDspRC_t cmDspInstRemoveAttrSym( cmDspCtx_t* ctx, cmDspInst_t* inst, unsign } -cmDspRC_t _cmDspClassErrV( cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned instId, cmDspRC_t rc, const cmChar_t* fmt, va_list vl ) +cmDspRC_t _cmDspClassErrV( cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned instId, const cmChar_t* instLbl, cmDspRC_t rc, const cmChar_t* fmt, va_list vl ) { va_list vl2; va_copy(vl2,vl); unsigned n = vsnprintf(NULL,0,fmt,vl2)+1; + cmChar_t buf[n+1]; vsnprintf(buf,n,fmt,vl); if( instId == cmInvalidId ) cmErrMsg( &classPtr->err, rc, "%s DSP Class:%s",buf, classPtr->labelStr); else - cmErrMsg( &classPtr->err, rc, "%s DSP Class:%s Inst:%i",buf, classPtr->labelStr,instId); + cmErrMsg( &classPtr->err, rc, "%s DSP Class:%s Inst:%i %s",buf, classPtr->labelStr,instId,instLbl==NULL?"":instLbl); va_end(vl2); return rc; @@ -393,7 +394,7 @@ cmDspRC_t cmDspClassErr( cmDspCtx_t* ctx, cmDspClass_t* classPtr, cmDspRC_t rc { va_list vl; va_start(vl,fmt); - rc = _cmDspClassErrV(ctx,classPtr,cmInvalidId,rc,fmt,vl); + rc = _cmDspClassErrV(ctx,classPtr,cmInvalidId,NULL,rc,fmt,vl); va_end(vl); return rc; } @@ -402,7 +403,7 @@ cmDspRC_t cmDspInstErr( cmDspCtx_t* ctx, cmDspInst_t* inst, cmDspRC_t rc, const { va_list vl; va_start(vl,fmt); - rc = _cmDspClassErrV(ctx,inst->classPtr,inst->id,rc,fmt,vl); + rc = _cmDspClassErrV(ctx,inst->classPtr,inst->id,cmSymTblLabel(ctx->stH,inst->symId),rc,fmt,vl); va_end(vl); return rc; } diff --git a/dsp/cmDspClass.h b/dsp/cmDspClass.h index 224dfb0..a6bcfe6 100644 --- a/dsp/cmDspClass.h +++ b/dsp/cmDspClass.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"'snap' unit processor interface." kw:[snap] } + typedef unsigned cmDspRC_t; enum @@ -416,7 +418,8 @@ extern "C" { cmDspRC_t cmDspUiMsgListCreate(cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned height, unsigned listVarId, unsigned selVarId ); - + //) + #ifdef __cplusplus } #endif diff --git a/dsp/cmDspFx.c b/dsp/cmDspFx.c index 1fc4f3e..baf5ed5 100644 --- a/dsp/cmDspFx.c +++ b/dsp/cmDspFx.c @@ -1,3 +1,5 @@ +//( { file_desc:"'snap' audio effects processor units." kw:[snap]} + #include "cmPrefix.h" #include "cmGlobal.h" #include "cmFloatTypes.h" @@ -40,7 +42,9 @@ #include "cmDspSys.h" -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspDelay file_desc:"Simple audio delay with feedback." kw:[sunit] } enum { kBypassDyId, @@ -155,7 +159,7 @@ cmDspRC_t _cmDspDelayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return rc; } -struct cmDspClass_str* cmDelayClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmDelayClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmDelayDC,ctx,"Delay", NULL, @@ -170,7 +174,9 @@ struct cmDspClass_str* cmDelayClassCons( cmDspCtx_t* ctx ) return &_cmDelayDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspMtDelay file_desc:"Multi-tap audio delay with feedback." kw:[sunit] } enum { kBypassMtId, @@ -345,7 +351,7 @@ cmDspRC_t _cmDspMtDelayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return rc; } -cmDspRC_t _cmDspMtDelayRecvFunc( cmDspCtx_t* ctx, struct cmDspInst_str* inst, unsigned attrSymId, const cmDspValue_t* value ) +cmDspRC_t _cmDspMtDelayRecvFunc( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned attrSymId, const cmDspValue_t* value ) { cmDspRC_t rc = kOkDspRC; cmDspMtDelay_t* p = (cmDspMtDelay_t*)inst; @@ -364,7 +370,7 @@ cmDspRC_t _cmDspMtDelayRecvFunc( cmDspCtx_t* ctx, struct cmDspInst_str* inst, } -struct cmDspClass_str* cmMtDelayClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmMtDelayClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmMtDelayDC,ctx,"MtDelay", NULL, @@ -380,7 +386,9 @@ struct cmDspClass_str* cmMtDelayClassCons( cmDspCtx_t* ctx ) return &_cmMtDelayDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspPShift file_desc:"Time-domain pitch shifter." kw:[sunit] } enum { kBypassPsId, @@ -468,7 +476,7 @@ cmDspRC_t _cmDspPShiftRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return cmDspSetEvent(ctx,inst,evt); } -struct cmDspClass_str* cmPShiftClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmPShiftClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmPShiftDC,ctx,"PShift", NULL, @@ -483,7 +491,9 @@ struct cmDspClass_str* cmPShiftClassCons( cmDspCtx_t* ctx ) return &_cmPShiftDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspLoopRecd file_desc:"Loop recorder." kw:[sunit] } enum { kTimeLrId, @@ -616,7 +626,7 @@ cmDspRC_t _cmDspLoopRecdRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return rc; } -struct cmDspClass_str* cmLoopRecdClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmLoopRecdClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmLoopRecdDC,ctx,"LoopRecd", NULL, @@ -631,7 +641,9 @@ struct cmDspClass_str* cmLoopRecdClassCons( cmDspCtx_t* ctx ) return &_cmLoopRecdDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspRectify file_desc:"Full-wave rectifier." kw:[sunit] } enum { kBypassRcId, @@ -715,7 +727,7 @@ cmDspRC_t _cmDspRectifyRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return cmDspSetEvent(ctx,inst,evt); } -struct cmDspClass_str* cmRectifyClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmRectifyClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmRectifyDC,ctx,"Rectify", NULL, @@ -731,7 +743,9 @@ struct cmDspClass_str* cmRectifyClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspGateDetect file_desc:"Track the onset and offset of an incoming signal." kw:[sunit] } enum { kWndMsGdId, @@ -862,7 +876,7 @@ cmDspRC_t _cmDspGateDetectRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv return rc; } -struct cmDspClass_str* cmGateDetectClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmGateDetectClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmGateDetectDC,ctx,"GateDetect", NULL, @@ -878,62 +892,62 @@ struct cmDspClass_str* cmGateDetectClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== -/* - The purpose of this object is to calculate, store and retrieve gain coefficents - for a set of audio channels. The gain coefficients are designed to balance the - volume of each channel relative to the others. During gain calibration - a sample of each channel is taken and it's average volume is determined. - After an example of all channels has been received a new set of gain coefficients - is calculated which decreases the volume of loud channels and increases the - volume of quiet channels. - - The gain coefficents are made available via a set of 'gain-###' output ports. - - This object acts as an interface to the cmAutoGain processor. - - As input it takes a channel configuration JSON file of the form: - { - ch_array : - [ ["ch","ssi","pitch","midi","gain"] - [ 0, 0, "C4", 60, 1.0 ] - .... - [ n 0, "C5", 72, 1.0 ] - ] - } - - Each array in 'ch_array' gives the configuration of a channel. - - - It also requires a JSON resource object of the form - gdParms: - { - medCnt: 5 - avgCnt: 9 - suprCnt: 6 - offCnt: 3 - suprCoeff: 1.400000 - onThreshDb: -53.000000 - offThreshDb: -80.000000 - } - - These arguments are used to configure the cmAutoGain Proessor gate detector function. - - During runtime the object accepts the following action selector symbol id's: - a. start - begin a new calibration session - b. proc - end a calibration session and calculate new gain coeff's - c. cancel - cancel a calibration session - d. write - write the channel configuration file - e. print - print the current auto gain calibration state - - After a 'start' msg the object accepts channel id's throught its 'id' input port. - Each 'id' identifies the channel which it will process next. - Upon reception of a channel id the object routes subsequent audio to its - internal cmAutoGain processor until it receives the next channel id - or a 'proc' or 'cancel' symbol. +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspAutoGain file_desc:"Normalize a set of audio input signals to acheive a consistent level." kw:[sunit] } +// The purpose of this object is to calculate, store and retrieve gain coefficents +// for a set of audio channels. The gain coefficients are designed to balance the +// volume of each channel relative to the others. During gain calibration +// a sample of each channel is taken and it's average volume is determined. +// After an example of all channels has been received a new set of gain coefficients +// is calculated which decreases the volume of loud channels and increases the +// volume of quiet channels. +// +// The gain coefficents are made available via a set of 'gain-###' output ports. +// +// This object acts as an interface to the cmAutoGain processor. +// +// As input it takes a channel configuration JSON file of the form: +// { +// ch_array : +// [ ["ch","ssi","pitch","midi","gain"] +// [ 0, 0, "C4", 60, 1.0 ] +// .... +// [ n 0, "C5", 72, 1.0 ] +// ] +// } +// +// Each array in 'ch_array' gives the configuration of a channel. +// +// +// It also requires a JSON resource object of the form +// gdParms: +// { +// medCnt: 5 +// avgCnt: 9 +// suprCnt: 6 +// offCnt: 3 +// suprCoeff: 1.400000 +// onThreshDb: -53.000000 +// offThreshDb: -80.000000 +// } +// +// These arguments are used to configure the cmAutoGain Proessor gate detector function. +// +// During runtime the object accepts the following action selector symbol id's: +// a. start - begin a new calibration session +// b. proc - end a calibration session and calculate new gain coeff's +// c. cancel - cancel a calibration session +// d. write - write the channel configuration file +// e. print - print the current auto gain calibration state +// +// After a 'start' msg the object accepts channel id's throught its 'id' input port. +// Each 'id' identifies the channel which it will process next. +// Upon reception of a channel id the object routes subsequent audio to its +// internal cmAutoGain processor until it receives the next channel id +// or a 'proc' or 'cancel' symbol. -*/ //========================================================================================================================================== enum { @@ -1202,7 +1216,7 @@ cmDspRC_t _cmDspAutoGainRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return rc; } -struct cmDspClass_str* cmAutoGainClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmAutoGainClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmAutoGainDC,ctx,"AutoGain", NULL, @@ -1217,7 +1231,9 @@ struct cmDspClass_str* cmAutoGainClassCons( cmDspCtx_t* ctx ) return &_cmAutoGainDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspEnvFollow file_desc:"Generate a control signal from by analyzing the power envelope of an incoming audio signal." kw:[sunit] } enum { kHopMsEfId, // RMS window length in milliseconds @@ -1388,7 +1404,7 @@ cmDspRC_t _cmDspEnvFollowRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt return rc; } -struct cmDspClass_str* cmEnvFollowClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmEnvFollowClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmEnvFollowDC,ctx,"EnvFollow", NULL, @@ -1403,7 +1419,9 @@ struct cmDspClass_str* cmEnvFollowClassCons( cmDspCtx_t* ctx ) return &_cmEnvFollowDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspXfader file_desc:"Gate controlled fader bank." kw:[sunit] } // Fade in and out an arbitrary number of audio signals based on gate signals. // When the gate is high the signal fades in and when the gate is low the signal fades out. // Constructor Args: @@ -1564,26 +1582,18 @@ cmDspRC_t _cmDspXfaderExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* } if( p->xfdp->chArray[i].onFl ) + { cmDspSetBool(ctx,inst,p->stateBaseXfId+i,true); - + } + if( p->xfdp->chArray[i].offFl ) + { cmDspSetBool(ctx,inst,p->stateBaseXfId+i,false); - + } + // send the gain output cmDspSetDouble(ctx,inst,p->gainBaseXfId+i,gain); - /* - if( gain > 0 ) - printf("(%i %f %i %i %i %f)", - i, - gain, - p->chGateV[i], - cmDspBool(inst,p->stateBaseXfId+i), - p->xfdp->chArray[i].gateFl, - p->xfdp->chArray[i].gain); - */ - - } if( p->xfdp->onFl ) @@ -1654,7 +1664,7 @@ cmDspRC_t _cmDspXfaderRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return rc; } -struct cmDspClass_str* cmXfaderClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmXfaderClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmXfaderDC,ctx,"Xfader", NULL, @@ -1670,7 +1680,9 @@ struct cmDspClass_str* cmXfaderClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspChCfg file_desc:"Configure a 'fluxo' channel." kw:[sunit] } enum { @@ -1872,7 +1884,7 @@ cmDspRC_t _cmDspChCfgRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return rc; } -struct cmDspClass_str* cmChCfgClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmChCfgClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmChCfgDC,ctx,"ChCfg", NULL, @@ -1887,7 +1899,9 @@ struct cmDspClass_str* cmChCfgClassCons( cmDspCtx_t* ctx ) return &_cmChCfgDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspChordDetect file_desc:"Detect a predefined chord based on signal gates." kw:[sunit] } enum { kRsrcCdId, @@ -2070,7 +2084,7 @@ cmDspRC_t _cmDspChordDetectRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspE return rc; } -struct cmDspClass_str* cmChordDetectClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmChordDetectClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmChordDetectDC,ctx,"ChordDetect", NULL, @@ -2085,7 +2099,10 @@ struct cmDspClass_str* cmChordDetectClassCons( cmDspCtx_t* ctx ) return &_cmChordDetectDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspFader file_desc:"Single channel gate controlled fader." kw:[sunit] } + enum { kTimeFaId, @@ -2176,7 +2193,7 @@ cmDspRC_t _cmDspFaderRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return rc; } -struct cmDspClass_str* cmFaderClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmFaderClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmFaderDC,ctx,"Fader", NULL, @@ -2191,7 +2208,9 @@ struct cmDspClass_str* cmFaderClassCons( cmDspCtx_t* ctx ) return &_cmFaderDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspNoteSelect file_desc:"'fluxo' gate based logic controller." kw:[sunit fluxo] } enum { kChCntNsId, @@ -2429,7 +2448,7 @@ cmDspRC_t _cmDspNoteSelectRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv return rc; } -struct cmDspClass_str* cmNoteSelectClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmNoteSelectClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmNoteSelectDC,ctx,"NoteSelect", NULL, @@ -2444,7 +2463,9 @@ struct cmDspClass_str* cmNoteSelectClassCons( cmDspCtx_t* ctx ) return &_cmNoteSelectDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspNetNoteSelect file_desc:"'fluxo' transmit gate information over the UDP network." kw:[sunit fluxo] } enum { @@ -2716,7 +2737,7 @@ cmDspRC_t _cmDspNetNoteSelectRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDs return rc; } -struct cmDspClass_str* cmNetNoteSelectClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmNetNoteSelectClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmNetNoteSelectDC,ctx,"NetNoteSelect", NULL, @@ -2732,7 +2753,9 @@ struct cmDspClass_str* cmNetNoteSelectClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspCombFilt file_desc:"Comb and Inverse comb filter." kw:[sunit] } enum { kBypassCfId, @@ -2848,7 +2871,7 @@ cmDspRC_t _cmDspCombFiltRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return rc; } -struct cmDspClass_str* cmCombFiltClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmCombFiltClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmCombFiltDC,ctx,"CombFilt", NULL, @@ -2863,7 +2886,9 @@ struct cmDspClass_str* cmCombFiltClassCons( cmDspCtx_t* ctx ) return &_cmCombFiltDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspScalarOp file_desc:"Perform arithmetic functions on scalar values." kw:[sunit] } enum { kPortCntSoId, @@ -3020,7 +3045,7 @@ cmDspRC_t _cmDspScalarOpRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return rc; } -struct cmDspClass_str* cmScalarOpClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmScalarOpClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmScalarOpDC,ctx,"ScalarOp", NULL, @@ -3035,7 +3060,9 @@ struct cmDspClass_str* cmScalarOpClassCons( cmDspCtx_t* ctx ) return &_cmScalarOpDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspGroupSel file_desc:"Select one group of audio channels from a set of audio channel groups." kw:[sunit] } enum { @@ -3190,7 +3217,7 @@ cmDspRC_t _cmDspGroupSelRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return rc; } -struct cmDspClass_str* cmGroupSelClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmGroupSelClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmGroupSelDC,ctx,"GroupSel", NULL, @@ -3206,7 +3233,9 @@ struct cmDspClass_str* cmGroupSelClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspNofM file_desc:"Select N channels from a set of M channels based on their current gate states." kw:[sunit] } enum { @@ -3356,7 +3385,7 @@ cmDspRC_t _cmDspAudioNofM_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv return rc; } -struct cmDspClass_str* cmAudioNofMClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmAudioNofMClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmAudioNofM_DC,ctx,"AudioNofM", NULL, @@ -3373,7 +3402,9 @@ struct cmDspClass_str* cmAudioNofMClassCons( cmDspCtx_t* ctx ) -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspRingMod file_desc:"Ring modulator." kw:[sunit] } enum { kInChCntRmId, @@ -3475,7 +3506,7 @@ cmDspRC_t _cmDspRingModRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return cmDspSetEvent(ctx,inst,evt); } -struct cmDspClass_str* cmRingModClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmRingModClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmRingModDC,ctx,"RingMod", NULL, @@ -3490,7 +3521,9 @@ struct cmDspClass_str* cmRingModClassCons( cmDspCtx_t* ctx ) return &_cmRingModDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspMsgDelay file_desc:"Delay an arbitrary value." kw:[sunit] } enum { kMaxCntMdId, @@ -3711,7 +3744,7 @@ cmDspRC_t _cmDspMsgDelayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return rc; } -struct cmDspClass_str* cmMsgDelayClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmMsgDelayClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmMsgDelayDC,ctx,"MsgDelay", NULL, @@ -3726,7 +3759,9 @@ struct cmDspClass_str* cmMsgDelayClassCons( cmDspCtx_t* ctx ) return &_cmMsgDelayDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspLine file_desc:"Programmable line generator." kw:[sunit] } enum { kBegLnId, @@ -3882,7 +3917,7 @@ cmDspRC_t _cmDspLineRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* e return rc; } -struct cmDspClass_str* cmLineClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmLineClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmLineDC,ctx,"Line", NULL, @@ -3898,7 +3933,10 @@ struct cmDspClass_str* cmLineClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspAdsr file_desc:"ADSR envelope generator." kw:[sunit] } + enum { kTrigModeAdId, @@ -4015,14 +4053,12 @@ cmDspRC_t _cmDspAdsrExec( cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* // HACK HACK HACK HACK // - /* - double db = rms<0.00001 ? -100.0 : 20.0*log10(rms); - double dbMax = -15.0; - double dbMin = -58.0; - - db = cmMin(dbMax,cmMax(dbMin,db)); - double scale = (db - dbMin) / (dbMax-dbMin); - */ + // double db = rms<0.00001 ? -100.0 : 20.0*log10(rms); + // double dbMax = -15.0; + // double dbMin = -58.0; + // + // db = cmMin(dbMax,cmMax(dbMin,db)); + // double scale = (db - dbMin) / (dbMax-dbMin); cmReal_t out = cmAdsrExec( p->p, cmDspSamplesPerCycle(ctx), gateFl, tscale, ascale ); @@ -4091,7 +4127,7 @@ cmDspRC_t _cmDspAdsrRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* e return rc; } -struct cmDspClass_str* cmAdsrClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmAdsrClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmAdsrDC,ctx,"Adsr", NULL, @@ -4106,7 +4142,9 @@ struct cmDspClass_str* cmAdsrClassCons( cmDspCtx_t* ctx ) return &_cmAdsrDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspAdsr file_desc:"Audio dynamics compressor." kw:[sunit] } enum { kBypassCmId, @@ -4259,7 +4297,7 @@ cmDspRC_t _cmDspCompressorRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv return rc; } -struct cmDspClass_str* cmCompressorClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmCompressorClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmCompressorDC,ctx,"Compressor", NULL, @@ -4274,7 +4312,9 @@ struct cmDspClass_str* cmCompressorClassCons( cmDspCtx_t* ctx ) return &_cmCompressorDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspBiquad file_desc:"Programmable Biquad EQ filter." kw:[sunit] } enum { kBypassBqId, @@ -4443,7 +4483,7 @@ cmDspRC_t _cmDspBiQuadEqRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return rc; } -struct cmDspClass_str* cmBiQuadEqClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmBiQuadEqClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmBiQuadEqDC,ctx,"BiQuadEq", NULL, @@ -4458,7 +4498,10 @@ struct cmDspClass_str* cmBiQuadEqClassCons( cmDspCtx_t* ctx ) return &_cmBiQuadEqDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspDistDs file_desc:"Guitar style distortion effect." kw:[sunit] } + enum { kBypassDsId, @@ -4601,7 +4644,7 @@ cmDspRC_t _cmDspDistDsRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return rc; } -struct cmDspClass_str* cmDistDsClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmDistDsClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmDistDsDC,ctx,"DistDs", NULL, @@ -4616,7 +4659,9 @@ struct cmDspClass_str* cmDistDsClassCons( cmDspCtx_t* ctx ) return &_cmDistDsDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspDbToLin file_desc:"Convert decibel units to linear units." kw:[sunit] } enum { kInDlId, @@ -4668,7 +4713,7 @@ cmDspRC_t _cmDspDbToLinRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return rc; } -struct cmDspClass_str* cmDbToLinClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmDbToLinClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmDbToLinDC,ctx,"DbToLin", NULL, @@ -4683,7 +4728,10 @@ struct cmDspClass_str* cmDbToLinClassCons( cmDspCtx_t* ctx ) return &_cmDbToLinDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspNofM2 file_desc:"Pass an N of M possible inputs to the output." kw:[sunit] } + // Pass any N of M inputs enum { @@ -5063,7 +5111,7 @@ cmDspRC_t _cmDspNofM_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return rc; } -struct cmDspClass_str* cmNofMClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmNofMClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmNofM_DC,ctx,"NofM", NULL, @@ -5079,7 +5127,9 @@ struct cmDspClass_str* cmNofMClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDsp1ofN file_desc:"Pass 1 or N possible inputs to the output." kw:[sunit] } enum { @@ -5255,7 +5305,7 @@ cmDspRC_t _cmDsp1ofN_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return rc; } -struct cmDspClass_str* cm1ofNClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cm1ofNClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cm1ofN_DC,ctx,"1ofN", NULL, @@ -5270,7 +5320,10 @@ struct cmDspClass_str* cm1ofNClassCons( cmDspCtx_t* ctx ) return &_cm1ofN_DC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDsp1Up file_desc:"Send 'true' on the selected channel and 'false' on the deselected channel." kw:[sunit] } + // Send a 'true' out on the selected channel. // Send a 'false' out on the deselected channel. enum @@ -5366,7 +5419,7 @@ cmDspRC_t _cmDsp1Up_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* e return rc; } -struct cmDspClass_str* cm1UpClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cm1UpClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cm1Up_DC,ctx,"1Up", NULL, @@ -5381,8 +5434,10 @@ struct cmDspClass_str* cm1UpClassCons( cmDspCtx_t* ctx ) return &_cm1Up_DC; } -//========================================================================================================================================== -// Convert a 'true'/'false' gate to an 'on'/'off' symbol +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspGateToSym file_desc:"Convert a 'true'/'false' gate to an 'on'/'off' symbol." kw:[sunit] } +// enum { kOnSymGsId, @@ -5464,7 +5519,7 @@ cmDspRC_t _cmDspGateToSym_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv return rc; } -struct cmDspClass_str* cmGateToSymClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmGateToSymClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmGateToSym_DC,ctx,"GateToSym", NULL, @@ -5479,7 +5534,9 @@ struct cmDspClass_str* cmGateToSymClassCons( cmDspCtx_t* ctx ) return &_cmGateToSym_DC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspPortToSym file_desc:"Send a pre-defined symbol every time a message arrives a given input port." kw:[sunit] } enum { kOutPtsId, @@ -5579,7 +5636,7 @@ cmDspRC_t _cmDspPortToSym_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv return rc; } -struct cmDspClass_str* cmPortToSymClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmPortToSymClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmPortToSym_DC,ctx,"PortToSym", NULL, @@ -5594,7 +5651,9 @@ struct cmDspClass_str* cmPortToSymClassCons( cmDspCtx_t* ctx ) return &_cmPortToSym_DC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspRouter file_desc:"Route the input value to one of multiple output ports." kw:[sunit] } enum { @@ -5698,6 +5757,7 @@ cmDspRC_t _cmDspRouter_Reset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ unsigned i; for(i=0; ioChCnt; ++i) cmDspZeroAudioBuf(ctx,inst,p->baseOutAudioRtId+i); + } return rc; @@ -5736,7 +5796,12 @@ cmDspRC_t _cmDspRouter_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return kOkDspRC; } - +// if( evt->dstVarId == kOutChIdxRtId && cmDsvGetUInt(evt->valuePtr) < p->oChCnt ) +// { +// const cmChar_t* symLbl = cmSymTblLabel(ctx->stH,inst->symId); +// cmDspInstErr(ctx,inst,kOkDspRC,"Router: ch:%i %s\n",cmDsvGetUInt(evt->valuePtr),symLbl==NULL?"":symLbl); +// } + // store the incoming value if( evt->dstVarId < p->baseBaseOutRtId ) if((rc = cmDspSetEvent(ctx,inst,evt)) != kOkDspRC ) @@ -5763,7 +5828,7 @@ cmDspRC_t _cmDspRouter_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return rc; } -struct cmDspClass_str* cmRouterClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmRouterClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmRouter_DC,ctx,"Router", NULL, @@ -5778,7 +5843,10 @@ struct cmDspClass_str* cmRouterClassCons( cmDspCtx_t* ctx ) return &_cmRouter_DC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspAvailCh file_desc:"Track active an inactive processing channels." kw:[sunit] } +// // Purpose: AvailCh can be used to implement a channel switching circuit. // // Inputs: @@ -5797,6 +5865,11 @@ struct cmDspClass_str* cmRouterClassCons( cmDspCtx_t* ctx ) // 'false' is transmitted to notify the channel that it should shutdown. // The channel is not considered actually shutdown until dis[i] // recieves a 'false'. +// ch The next prospective next available channel is sent whenever it +// becomes available. A next channel becomes available when +// a channel is marked as inactive via dis[i] or when +// a new channel is made active, via trigger, and another +// channel active channel exists. // Notes: // The gate[] output is designed to work with the gate[] input of Xfader. When // availCh.gate[] goes high Xfader fades in, when availCh.gate[] goes low @@ -5825,6 +5898,8 @@ typedef struct unsigned baseDisInAvId; unsigned baseGateOutAvId; bool* stateArray; + unsigned nextAvailChIdx; + unsigned audioCycleCnt; } cmDspAvailCh_t; cmDspInst_t* _cmDspAvailCh_Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl ) @@ -5864,16 +5939,18 @@ cmDspInst_t* _cmDspAvailCh_Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsig p->baseDisInAvId = baseDisInAvId; p->baseGateOutAvId = baseGateOutAvId; + p->nextAvailChIdx = cmInvalidIdx; + p->audioCycleCnt = 0; unsigned i; for(i=0; iinst, baseDisInAvId+i, false, false ); + cmDspSetDefaultBool( ctx, &p->inst, baseDisInAvId+i, false, false ); cmDspSetDefaultBool( ctx, &p->inst, baseGateOutAvId+i, false, false ); } cmDspSetDefaultUInt( ctx, &p->inst, kModeAvId, 0, kExclusiveModeAvId ); - cmDspSetDefaultUInt( ctx, &p->inst, kChIdxAvId, 0, cmInvalidIdx ); - + cmDspSetDefaultUInt( ctx, &p->inst, kChIdxAvId, 0, 0 ); + va_end(vl1); return &p->inst; @@ -5884,12 +5961,111 @@ cmDspRC_t _cmDspAvailCh_Free(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return kOkDspRC; } -cmDspRC_t _cmDspAvailCh_Reset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) +cmDspRC_t _cmDspAvailCh_DoReset( cmDspCtx_t* ctx, cmDspInst_t* inst ) { - return cmDspApplyAllDefaults(ctx,inst); + unsigned i; + cmDspAvailCh_t* p = (cmDspAvailCh_t*)inst; + + + // ch 0 is the channel receiving parameters + cmDspSetUInt(ctx,inst,kChIdxAvId,0); + + for(i=0; ichCnt; ++i) + { + cmDspSetBool(ctx, inst, p->baseDisInAvId + i, i==0); // disable all channels except ch zero + cmDspSetBool(ctx, inst, p->baseGateOutAvId + i, i==0); // enable channel 0 + } + + p->audioCycleCnt = 0; + p->nextAvailChIdx = cmInvalidIdx; + + // transmit reset + cmDspSetBool(ctx,inst, kResetAvId, false ); + + return kOkDspRC; } +cmDspRC_t _cmDspAvailCh_Reset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) +{ + cmDspRC_t rc; + if((rc = cmDspApplyAllDefaults(ctx,inst)) == kOkDspRC ) + { + rc = _cmDspAvailCh_DoReset(ctx,inst); + } + return rc; +} + +void _cmDspAvailCh_SetNextAvailCh( cmDspCtx_t* ctx, cmDspInst_t* inst, bool warnFl, const char* label ) +{ + cmDspAvailCh_t* p = (cmDspAvailCh_t*)inst; + unsigned i; + + // if a valid next avail ch already exists then do nothing + if( p->nextAvailChIdx != cmInvalidIdx ) + return; + + // for each channel + for(i=0; ichCnt; ++i) + { + // the channel's active state is held in the 'dis' variable. + bool activeFl = cmDspBool(inst,p->baseDisInAvId+i); + + // if ch[i] is the first avail inactive channel + if( !activeFl ) + { + p->nextAvailChIdx = i; // then make it the next available channel + break; + } + + } + + // if no available channels were found + if( p->nextAvailChIdx == cmInvalidIdx ) + { + if( warnFl ) + cmDspInstErr(ctx,inst,kInvalidStateDspRC,"No available channels exist."); + } + else + { + // Notify the external world which channel is to be used next. + // This allows routers which are switching parameters between + // xfade channels to switch new parameter values to go to the + // next available channel rather than the current channel. + // The next available channel will then be faded up with the + // new parameters on the next trigger command. + cmDspSetUInt(ctx,inst,kChIdxAvId,p->nextAvailChIdx); + } +} + +cmDspRC_t _cmDspAvailCh_Exec( cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) +{ + cmDspRC_t rc = kOkDspRC; + cmDspAvailCh_t* p = (cmDspAvailCh_t*)inst; + + p->audioCycleCnt += 1; + + // Setting the next available channel here solves the problem of sending the + // first 'ch' output after the program starts executing. + // The problem is that 'ch' should be set to 0 for the first + // execution cycle so that parameters may be set to the initial active channel + // during the first cycle. After the first cycle however parameters should be + // sent to the next channel which will be faded up. Setting + // 'ch' here accomplishes this without relying on an external signal. + // Note that we wait until the second cycle because we don't know where + // this 'availCh' will be in the execution cycle relative to other processors. + // If it is at the beginning then other processors that might be setting + // initial parameters will not have had a chance to run before the + // 'ch' change. Waiting unitl the second cycle guarantees that all the + // other processors had at least one chance to run. + if( p->audioCycleCnt == 2 ) + { + _cmDspAvailCh_SetNextAvailCh(ctx,inst,true,"exec"); + } + + return rc; +} + cmDspRC_t _cmDspAvailCh_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) { cmDspRC_t rc = kOkDspRC; @@ -5897,79 +6073,55 @@ cmDspRC_t _cmDspAvailCh_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ bool exclModeFl = cmDspUInt(inst, kModeAvId ) == kExclusiveModeAvId; + // if this is a reset if( evt->dstVarId == kResetAvId ) { - unsigned i; - - cmDspSetUInt(ctx,inst,kChIdxAvId,0); - - for(i=0; ichCnt; ++i) - { - bool fl = i==0; - cmDspSetBool(ctx, inst, p->baseDisInAvId + i, !fl); - cmDspSetBool(ctx, inst, p->baseGateOutAvId + i, fl); - } - - cmDspSetBool(ctx,inst, kResetAvId, false ); - - return rc; + return _cmDspAvailCh_DoReset(ctx,inst); } // if this is a trigger if( evt->dstVarId == kTrigAvId ) { - unsigned i,j=-1; - bool fl = true; - for(i=0; ichCnt; ++i) - { - // the channel's active state is held in the 'dis' variable. - bool activeFl = cmDspBool(inst,p->baseDisInAvId+i); - - // if ch[i] is the first avail inactive channel - if( fl && !activeFl ) - { - // activate the available channel - //cmDspSetUInt(ctx,inst,kChIdxAvId,j); - //cmDspSetBool(ctx, inst, p->baseDisInAvId + j, true); - //cmDspSetBool(ctx, inst, p->baseGateOutAvId + j, true); - - j = i; - fl = false; - } - - // if ch[i] is active - then request that it shutdown - //if( activeFl && exclModeFl) - // cmDspSetBool(ctx, inst, p->baseGateOutAvId + i, false); - - } - - if( j==-1 ) - cmDspInstErr(ctx,inst,kInvalidStateDspRC,"No available channels exist."); + // if no available channels were previously found + if( p->nextAvailChIdx == cmInvalidIdx ) + cmDspInstErr(ctx,inst,kInvalidStateDspRC,"There are no available channels to trigger."); else { - // activate the available channel - cmDspSetUInt(ctx,inst,kChIdxAvId,j); - cmDspSetBool(ctx, inst, p->baseDisInAvId + j, true); - cmDspSetBool(ctx, inst, p->baseGateOutAvId + j, true); + // indicate that ch[nexAvailChIdx] is no longer available + cmDspSetBool(ctx, inst, p->baseDisInAvId + p->nextAvailChIdx, true); + + // raise the gate to start the xfade. + cmDspSetBool(ctx, inst, p->baseGateOutAvId + p->nextAvailChIdx, true); if( exclModeFl ) { + unsigned i; for(i=0; ichCnt; ++i) - if( i!=j && cmDspBool(inst,p->baseDisInAvId+i) ) + if( i!=p->nextAvailChIdx && cmDspBool(inst,p->baseDisInAvId+i) ) cmDspSetBool(ctx,inst, p->baseGateOutAvId+i, false ); } + + // invalidate nextAvailChIdx + p->nextAvailChIdx = cmInvalidIdx; + + // It may be possible to know the next avail ch so try to set it here. + _cmDspAvailCh_SetNextAvailCh(ctx, inst, false, "trig" ); + } return rc; } - - // if this is an incoming disable message. if( p->baseDisInAvId <= evt->dstVarId && evt->dstVarId < p->baseDisInAvId+p->chCnt && cmDsvGetBool(evt->valuePtr) == false) - { + { cmDspSetEvent(ctx,inst,evt); + + // a channel was disabled so a new channel should be available for selection + if( p->audioCycleCnt > 0 ) + _cmDspAvailCh_SetNextAvailCh(ctx, inst, true, "dis" ); + if( !exclModeFl ) cmDspSetBool(ctx, inst, p->baseGateOutAvId + (evt->dstVarId - p->baseDisInAvId), false); } @@ -5977,14 +6129,14 @@ cmDspRC_t _cmDspAvailCh_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return rc; } -struct cmDspClass_str* cmAvailChClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmAvailChClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmAvailCh_DC,ctx,"AvailCh", NULL, _cmDspAvailCh_Alloc, _cmDspAvailCh_Free, _cmDspAvailCh_Reset, - NULL, + _cmDspAvailCh_Exec, _cmDspAvailCh_Recv, NULL,NULL, "Enable the next availabled channel"); @@ -5993,7 +6145,9 @@ struct cmDspClass_str* cmAvailChClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspPreset file_desc:"Store and recall preset. Show a preset list user interface unit." kw:[sunit] } enum { @@ -6249,7 +6403,7 @@ cmDspRC_t _cmDspPreset_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return rc; } -struct cmDspClass_str* cmPresetClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmPresetClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmPreset_DC,ctx,"Preset", NULL, @@ -6265,7 +6419,9 @@ struct cmDspClass_str* cmPresetClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspBcastSym file_desc:"Broadcast a symbol/value to all units registered to listen for the symbol." kw:[sunit] } enum { @@ -6328,7 +6484,7 @@ cmDspRC_t _cmDspBcastSym_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt return rc; } -struct cmDspClass_str* cmBcastSymClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmBcastSymClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmBcastSym_DC,ctx,"BcastSym", NULL, @@ -6343,7 +6499,9 @@ struct cmDspClass_str* cmBcastSymClassCons( cmDspCtx_t* ctx ) return &_cmBcastSym_DC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspSegLine file_desc:"Line segment generator." kw:[sunit] } enum { kRsrcSlId, @@ -6461,7 +6619,7 @@ cmDspRC_t _cmDspSegLineRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return rc; } -struct cmDspClass_str* cmSegLineClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmSegLineClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmSegLineDC,ctx,"SegLine", NULL, @@ -6476,3 +6634,4 @@ struct cmDspClass_str* cmSegLineClassCons( cmDspCtx_t* ctx ) return &_cmSegLineDC; } +//) diff --git a/dsp/cmDspKr.c b/dsp/cmDspKr.c index 987e285..e47e8cb 100644 --- a/dsp/cmDspKr.c +++ b/dsp/cmDspKr.c @@ -18,6 +18,8 @@ #include "cmThread.h" #include "cmUdpPort.h" #include "cmUdpNet.h" +//( { file_desc:"'snap' audio effects performance analysis units." kw:[snap]} + #include "cmTime.h" #include "cmAudioSys.h" #include "cmDspCtx.h" @@ -45,6 +47,10 @@ #include "cmSyncRecd.h" #include "cmTakeSeqBldr.h" +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspKr file_desc:"Spectral non-linear distortion effect." kw:[sunit] } + enum { kWndSmpCntKrId, @@ -71,8 +77,6 @@ typedef struct cmDspClass_t _cmKrDC; -//========================================================================================================================================== - cmDspInst_t* _cmDspKrAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl ) { cmDspVarArg_t args[] = @@ -262,7 +266,7 @@ cmDspRC_t _cmDspKrRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt return rc; } -struct cmDspClass_str* cmKrClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmKrClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmKrDC,ctx,"Kr", NULL, @@ -277,9 +281,9 @@ struct cmDspClass_str* cmKrClassCons( cmDspCtx_t* ctx ) return &_cmKrDC; } - -//========================================================================================================================================== -// Time Line UI Object +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspTimeLine file_desc:"Time line user interface unit." kw:[sunit] } enum { @@ -446,7 +450,7 @@ cmDspRC_t _cmDspTimeLineRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return kOkDspRC; } -struct cmDspClass_str* cmTimeLineClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmTimeLineClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmTimeLineDC,ctx,"TimeLine", NULL, @@ -461,8 +465,9 @@ struct cmDspClass_str* cmTimeLineClassCons( cmDspCtx_t* ctx ) return &_cmTimeLineDC; } -//========================================================================================================================================== -// Score UI Object +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspScore file_desc:"Musical score user interface unit." kw:[sunit] } enum { @@ -637,7 +642,7 @@ cmDspRC_t _cmDspScoreRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return kOkDspRC; } -struct cmDspClass_str* cmScoreClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmScoreClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmScoreDC,ctx,"Score", NULL, @@ -652,8 +657,9 @@ struct cmDspClass_str* cmScoreClassCons( cmDspCtx_t* ctx ) return &_cmScoreDC; } -//========================================================================================================================================== -// MIDI File Player +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspMidiFilePlay file_desc:"MIDI file player." kw:[sunit] } enum { @@ -684,14 +690,12 @@ typedef struct bool errFl; } cmDspMidiFilePlay_t; -/* - 'bsi' and 'esi' give the starting and ending sample for MIDI file playback. - These indexes are relative to the start of the file. - When the player recieves a 'start' msg it sets the current sample index - 'si' to 'bsi' and begins scanning for the next note to play. - On each call to the _cmDspMidiFilePlayExec() msgs that fall in the interval - si:si+sPc-1 will be transmitted. (where sPc are the number of samples per DSP cycle). - */ +// 'bsi' and 'esi' give the starting and ending sample for MIDI file playback. +// These indexes are relative to the start of the file. +// When the player recieves a 'start' msg it sets the current sample index +// 'si' to 'bsi' and begins scanning for the next note to play. +// On each call to the _cmDspMidiFilePlayExec() msgs that fall in the interval +// si:si+sPc-1 will be transmitted. (where sPc are the number of samples per DSP cycle). cmDspInst_t* _cmDspMidiFilePlayAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl ) { @@ -752,7 +756,7 @@ unsigned _cmDspMidiFilePlaySeekMsgIdx( cmDspCtx_t* ctx, cmDspInst_t* inst, unsig const cmMidiTrackMsg_t** a = cmMidiFileMsgArray(p->mfH); for(i=0; idtick > smpIdx ) + if( (a[i]->amicro * cmDspSampleRate(ctx) / 1000000.0) >= smpIdx ) break; return i==n ? cmInvalidIdx : i; @@ -782,7 +786,7 @@ cmDspRC_t _cmDspMidiFilePlayOpen(cmDspCtx_t* ctx, cmDspInst_t* inst ) cmMidiFileSetDelay(p->mfH, cmMidiFileTicksPerQN(p->mfH) ); // convert midi msg times to absolute time in samples - cmMidiFileTickToSamples(p->mfH,cmDspSampleRate(ctx),true); + //cmMidiFileTickToSamples(p->mfH,cmDspSampleRate(ctx),true); } return rc; @@ -816,23 +820,37 @@ cmDspRC_t _cmDspMidiFilePlayExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDsp const cmMidiTrackMsg_t** mpp = cmMidiFileMsgArray(p->mfH); unsigned msgN = cmMidiFileMsgCount(p->mfH); - - for(; p->curMsgIdx < msgN && p->csi <= mpp[p->curMsgIdx]->dtick && mpp[p->curMsgIdx]->dtick < (p->csi + sPc); ++p->curMsgIdx ) + + do { + if( p->curMsgIdx >= msgN ) + break; + const cmMidiTrackMsg_t* mp = mpp[p->curMsgIdx]; + + // convert the absolute time in microseconds to samples + unsigned curMsgTimeSmp = round(mp->amicro * cmDspSampleRate(ctx) / 1000000.0); + + // if this midi event falls inside this execution window + if( p->csi > curMsgTimeSmp || curMsgTimeSmp >= (p->csi + sPc)) + break; + switch( mp->status ) { case kNoteOffMdId: case kNoteOnMdId: case kCtlMdId: - cmDspSetUInt(ctx,inst, kSmpIdxMfId, mp->dtick); + cmDspSetUInt(ctx,inst, kSmpIdxMfId, curMsgTimeSmp); cmDspSetUInt(ctx,inst, kD1MfId, mp->u.chMsgPtr->d1); cmDspSetUInt(ctx,inst, kD0MfId, mp->u.chMsgPtr->d0); cmDspSetUInt(ctx,inst, kStatusMfId, mp->status); cmDspSetUInt(ctx,inst, kIdMfId, mp->uid); break; } - } + + p->curMsgIdx += 1; + + }while(1); } p->csi += sPc; @@ -866,7 +884,7 @@ cmDspRC_t _cmDspMidiFilePlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDsp return kOkDspRC; } -struct cmDspClass_str* cmMidiFilePlayClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmMidiFilePlayClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmMidiFilePlayDC,ctx,"MidiFilePlay", NULL, @@ -881,7 +899,10 @@ struct cmDspClass_str* cmMidiFilePlayClassCons( cmDspCtx_t* ctx ) return &_cmMidiFilePlayDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspScFol file_desc:"MIDI performance score follower." kw:[sunit] } + enum { kFnSfId, @@ -1003,27 +1024,25 @@ void _cmScFolMatcherCb( cmScMatcher* p, void* arg, cmScMatcherResult_t* rp ) if(ap->sfp->smp->set[i].value != DBL_MAX ) { - /* - switch( ap->sfp->smp->set[i].sp->varId ) - { - case kEvenVarScId: - cmDspSetDouble(ap->ctx,inst,kEvenSfId,ap->sfp->smp->set[i].value); - break; - - case kDynVarScId: - cmDspSetDouble(ap->ctx,inst,kDynSfId,ap->sfp->smp->set[i].value); - break; - - case kTempoVarScId: - cmDspSetDouble(ap->ctx,inst,kTempoSfId,ap->sfp->smp->set[i].value); - break; - - default: - { assert(0); } - } - - cmDspSetDouble(ap->ctx,inst,kCostSfId,ap->sfp->smp->set[i].match_cost); - */ +// switch( ap->sfp->smp->set[i].sp->varId ) +// { +// case kEvenVarScId: +// cmDspSetDouble(ap->ctx,inst,kEvenSfId,ap->sfp->smp->set[i].value); +// break; +// +// case kDynVarScId: +// cmDspSetDouble(ap->ctx,inst,kDynSfId,ap->sfp->smp->set[i].value); +// break; +// +// case kTempoVarScId: +// cmDspSetDouble(ap->ctx,inst,kTempoSfId,ap->sfp->smp->set[i].value); +// break; +// +// 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; @@ -1051,15 +1070,13 @@ void _cmScFolMatcherCb( cmScMatcher* p, void* arg, cmScMatcherResult_t* rp ) } - /* - // trigger 'section' starts - for(i=ap->sfp->smp->vsli; isfp->smp->nsli; ++i) - { - const cmScoreLoc_t* locPtr = cmScoreLoc(ap->sfp->smp->mp->scH,i); - if( locPtr->begSectPtr != NULL ) - cmDspSetUInt(ap->ctx,inst,kSectIndexSfId,locPtr->begSectPtr->index); - } - */ +// // trigger 'section' starts +// for(i=ap->sfp->smp->vsli; isfp->smp->nsli; ++i) +// { +// const cmScoreLoc_t* locPtr = cmScoreLoc(ap->sfp->smp->mp->scH,i); +// if( locPtr->begSectPtr != NULL ) +// cmDspSetUInt(ap->ctx,inst,kSectIndexSfId,locPtr->begSectPtr->index); +// } } } @@ -1184,7 +1201,7 @@ cmDspRC_t _cmDspScFolRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return rc; } -struct cmDspClass_str* cmScFolClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmScFolClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmScFolDC,ctx,"ScFol", NULL, @@ -1199,7 +1216,9 @@ struct cmDspClass_str* cmScFolClassCons( cmDspCtx_t* ctx ) return &_cmScFolDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspScMod file_desc:"Score driven parameter automation." kw:[sunit] } enum { @@ -1221,6 +1240,7 @@ typedef struct unsigned onSymId; unsigned offSymId; unsigned postSymId; + unsigned dumpSymId; } cmDspScMod_t; void _cmDspScModCb( void* arg, unsigned varSymId, double value, bool postFl ) @@ -1307,6 +1327,7 @@ cmDspInst_t* _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned p->onSymId = cmSymTblId(ctx->stH,"on"); p->offSymId = cmSymTblId(ctx->stH,"off"); p->postSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"post"); + p->dumpSymId = cmSymTblId(ctx->stH,"dump"); mp->cbArg = p; // set the modulator callback arg @@ -1358,6 +1379,9 @@ cmDspRC_t _cmDspScModRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* unsigned symId = cmDspSymbol(inst,kCmdMdId); if( symId == p->onSymId ) cmScModulatorReset(p->mp, ctx->cmCtx, cmDspUInt(inst,kScLocIdxMdId)); + + if( symId == p->dumpSymId ) + cmScModulatorDump(p->mp); } break; @@ -1380,7 +1404,7 @@ cmDspRC_t _cmDspScModExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return rc; } -struct cmDspClass_str* cmScModClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmScModClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmModulatorDC,ctx,"ScMod", NULL, @@ -1395,7 +1419,9 @@ struct cmDspClass_str* cmScModClassCons( cmDspCtx_t* ctx ) return &_cmModulatorDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspGSwitch file_desc:"Route all inputs to one of a group of outputs." kw:[sunit] } enum { @@ -1578,7 +1604,7 @@ cmDspRC_t _cmDspGSwitchRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t } -struct cmDspClass_str* cmGSwitchClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmGSwitchClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmGSwitchDC,ctx,"GSwitch", NULL, @@ -1594,7 +1620,9 @@ struct cmDspClass_str* cmGSwitchClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspScaleRange file_desc:"Offset and scale a scalar value." kw:[sunit] } enum { @@ -1679,7 +1707,7 @@ cmDspRC_t _cmDspScaleRangeRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv } -struct cmDspClass_str* cmScaleRangeClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmScaleRangeClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmScaleRangeDC,ctx,"ScaleRange", NULL, @@ -1695,7 +1723,9 @@ struct cmDspClass_str* cmScaleRangeClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspActiveMeas file_desc:"Issue stored parameter values at specified score locations." kw:[sunit] } enum { @@ -1725,12 +1755,10 @@ typedef struct cmDspAmRecd_str } cmDspAmRecd_t; -/* -int cmDspActiveMeasRecdCompare(const void * p0, const void * p1) -{ - return ((int)((cmDspActiveMeasRecd_t*)p0)->loc) - (int)(((cmDspActiveMeasRecd_t*)p1)->loc); -} -*/ +//int cmDspActiveMeasRecdCompare(const void * p0, const void * p1) +//{ +// return ((int)((cmDspActiveMeasRecd_t*)p0)->loc) - (int)(((cmDspActiveMeasRecd_t*)p1)->loc); +//} typedef struct { @@ -1980,96 +2008,94 @@ cmDspRC_t _cmDspActiveMeasRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv } - /* - switch( evt->dstVarId ) - { - case kSflocAmId: - if( p->nextFullIdx != cmInvalidIdx ) - { - // get the recv'd score location - unsigned sflocIdx = cmDspUInt(inst,kSflocAmId); - - unsigned prvLoc = cmInvalidIdx; - - // for each remaining avail record - for(; p->nextFullIdx < p->nextEmptyIdx; p->nextFullIdx++) - { - cmDspActiveMeasRecd_t* r = p->array + p->nextFullIdx; - - // if this records score location is after the recv'd score loc then we're done - if( r->loc > sflocIdx ) - break; - - // deterimine the records type - unsigned varId = cmInvalidId; - switch( r->type ) - { - case kEvenVarScId: varId = kEvenAmId; break; - case kDynVarScId: varId = kDynAmId; break; - case kTempoVarScId: varId = kTempoAmId; break; - default: - { assert(0); } - } - - // if this score location has not yet been sent then send it now - if( prvLoc != r->loc ) - cmDspSetUInt(ctx,inst,kScLocAmId,r->loc); - - // transmit the records value and cost - cmDspSetDouble(ctx,inst,varId,r->value); - cmDspSetDouble(ctx,inst,kCostAmId,r->cost); - - prvLoc = r->loc; - } - - - } - break; - - case kCmdAmId: - { - unsigned cmdSymId = cmDspSymbol(inst,kCmdAmId); - - if( cmdSymId == p->addSymId ) - { - if( p->nextEmptyIdx >= p->cnt ) - cmDspInstErr(ctx,inst,kProcFailDspRC,"The active measurement list is full cnt=%i.",p->cnt); - else - { - cmDspActiveMeasRecd_t* r = p->array + p->nextEmptyIdx; - r->loc = cmDspUInt( inst,kLocAmId); - r->type = cmDspUInt( inst,kTypeAmId); - r->value = cmDspDouble(inst,kValueAmId); - r->cost = cmDspDouble(inst,kCstAmId); - p->nextEmptyIdx += 1; - - qsort(p->array,p->nextEmptyIdx,sizeof(p->array[0]),cmDspActiveMeasRecdCompare); - - if( p->nextEmptyIdx == 1 && p->nextFullIdx == cmInvalidIdx ) - p->nextFullIdx = 0; - - } - } - - if( cmdSymId == p->clearSymId ) - rc = _cmDspActiveMeasClear(ctx,p); - else - if( cmdSymId == p->printSymId ) - rc = _cmDspActiveMeasPrint(ctx,p); - else - if(cmdSymId == p->rewindSymId ) - p->nextFullIdx = 0; - } - break; - - } - */ + // switch( evt->dstVarId ) + // { + // case kSflocAmId: + // if( p->nextFullIdx != cmInvalidIdx ) + // { + // // get the recv'd score location + // unsigned sflocIdx = cmDspUInt(inst,kSflocAmId); + // + // unsigned prvLoc = cmInvalidIdx; + // + // // for each remaining avail record + // for(; p->nextFullIdx < p->nextEmptyIdx; p->nextFullIdx++) + // { + // cmDspActiveMeasRecd_t* r = p->array + p->nextFullIdx; + // + // // if this records score location is after the recv'd score loc then we're done + // if( r->loc > sflocIdx ) + // break; + // + // // deterimine the records type + // unsigned varId = cmInvalidId; + // switch( r->type ) + // { + // case kEvenVarScId: varId = kEvenAmId; break; + // case kDynVarScId: varId = kDynAmId; break; + // case kTempoVarScId: varId = kTempoAmId; break; + // default: + // { assert(0); } + // } + // + // // if this score location has not yet been sent then send it now + // if( prvLoc != r->loc ) + // cmDspSetUInt(ctx,inst,kScLocAmId,r->loc); + // + // // transmit the records value and cost + // cmDspSetDouble(ctx,inst,varId,r->value); + // cmDspSetDouble(ctx,inst,kCostAmId,r->cost); + // + // prvLoc = r->loc; + // } + // + // + // } + // break; + // + // case kCmdAmId: + // { + // unsigned cmdSymId = cmDspSymbol(inst,kCmdAmId); + // + // if( cmdSymId == p->addSymId ) + // { + // if( p->nextEmptyIdx >= p->cnt ) + // cmDspInstErr(ctx,inst,kProcFailDspRC,"The active measurement list is full cnt=%i.",p->cnt); + // else + // { + // cmDspActiveMeasRecd_t* r = p->array + p->nextEmptyIdx; + // r->loc = cmDspUInt( inst,kLocAmId); + // r->type = cmDspUInt( inst,kTypeAmId); + // r->value = cmDspDouble(inst,kValueAmId); + // r->cost = cmDspDouble(inst,kCstAmId); + // p->nextEmptyIdx += 1; + // + // qsort(p->array,p->nextEmptyIdx,sizeof(p->array[0]),cmDspActiveMeasRecdCompare); + // + // if( p->nextEmptyIdx == 1 && p->nextFullIdx == cmInvalidIdx ) + // p->nextFullIdx = 0; + // + // } + // } + // + // if( cmdSymId == p->clearSymId ) + // rc = _cmDspActiveMeasClear(ctx,p); + // else + // if( cmdSymId == p->printSymId ) + // rc = _cmDspActiveMeasPrint(ctx,p); + // else + // if(cmdSymId == p->rewindSymId ) + // p->nextFullIdx = 0; + // } + // break; + // + // } return rc; } -struct cmDspClass_str* cmActiveMeasClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmActiveMeasClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmActiveMeasDC,ctx,"ActiveMeas", NULL, @@ -2084,33 +2110,35 @@ struct cmDspClass_str* cmActiveMeasClassCons( cmDspCtx_t* ctx ) return &_cmActiveMeasDC; } -//========================================================================================================================================== -// Audio MIDI Sync -/* - Usage: - 1) In the program resource file setup a list of sync points. - 'asmp' refers to a sample offset into the audio file 'af' - which should match to the midi event index 'mid' in the - midi file 'mf'. +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspAmSync file_desc:"Calculate MIDI to Audio latency offsets." kw:[sunit] } +// +// +// Usage: +// 1) In the program resource file setup a list of sync points. +// 'asmp' refers to a sample offset into the audio file 'af' +// which should match to the midi event index 'mid' in the +// midi file 'mf'. +// +// amSync : +// [ +// { af:"af-16" asmp:34735276 mf:"mf-10" mid:350 } +// { af:"af-16" asmp:71802194 mf:"mf-10" mid:787 } +// ] +// +// 2) Feed the 'fidx' output from a wave table loaded with 'af' into the 'asmp' input port of this amSync object. +// Feed the 'id' output from the MIDI file player loaded with 'mf' into the 'mid' input port of this amSync object. +// +// 3) Run the players. +// 4) When the run is complete send any message to the 'sel' port of this amSync object. +// The 'frm:' field of the printed output gives the difference in samples between +// MIDI and audio sync points. +// +// If the value is positive then the MIDI point is after the Audio point. +// If the value is negative then the MIDI point is before the audio point. +// - amSync : - [ - { af:"af-16" asmp:34735276 mf:"mf-10" mid:350 } - { af:"af-16" asmp:71802194 mf:"mf-10" mid:787 } - ] - - 2) Feed the 'fidx' output from a wave table loaded with 'af' into the 'asmp' input port of this amSync object. - Feed the 'id' output from the MIDI file player loaded with 'mf' into the 'mid' input port of this amSync object. - - 3) Run the players. - 4) When the run is complete send any message to the 'sel' port of this amSync object. - The 'frm:' field of the printed output gives the difference in samples between - MIDI and audio sync points. - - If the value is positive then the MIDI point is after the Audio point. - If the value is negative then the MIDI point is before the audio point. - -*/ enum { @@ -2345,7 +2373,7 @@ cmDspRC_t _cmDspAmSyncRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* return kOkDspRC; } -struct cmDspClass_str* cmAmSyncClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmAmSyncClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmAmSyncDC,ctx,"AmSync", NULL, @@ -2360,7 +2388,10 @@ struct cmDspClass_str* cmAmSyncClassCons( cmDspCtx_t* ctx ) return &_cmAmSyncDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspNanoMap file_desc:"Control a MIDI synth." kw:[sunit] } + enum { kPgmNmId, @@ -2469,7 +2500,7 @@ cmDspRC_t _cmDspNanoMapRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t return kOkDspRC; } -struct cmDspClass_str* cmNanoMapClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmNanoMapClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmNanoMapDC,ctx,"NanoMap", NULL, @@ -2485,7 +2516,10 @@ struct cmDspClass_str* cmNanoMapClassCons( cmDspCtx_t* ctx ) return &_cmNanoMapDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspRecdPlay file_desc:"Record audio segments from a live perfromance and play them back at a later time" kw:[sunit] } + enum { kChCntPrId, @@ -2845,7 +2879,7 @@ cmDspRC_t _cmDspRecdPlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return kOkDspRC; } -struct cmDspClass_str* cmRecdPlayClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmRecdPlayClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmRecdPlayDC,ctx,"RecdPlay", NULL, @@ -2861,7 +2895,9 @@ struct cmDspClass_str* cmRecdPlayClassCons( cmDspCtx_t* ctx ) return &_cmRecdPlayDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspGoertzel file_desc:"Goertzel tone detection filter" kw:[sunit] } enum { kHopFactGrId, @@ -3020,7 +3056,7 @@ cmDspRC_t _cmDspGoertzelRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return kOkDspRC; } -struct cmDspClass_str* cmGoertzelClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmGoertzelClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmGoertzelDC,ctx,"Goertzel", NULL, @@ -3036,7 +3072,10 @@ struct cmDspClass_str* cmGoertzelClassCons( cmDspCtx_t* ctx ) return &_cmGoertzelDC; } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspSyncRecd file_desc:"Time align a MIDI and associated audio recording" kw:[sunit] } + enum { kRecdDirSrId, @@ -3221,7 +3260,7 @@ cmDspRC_t _cmDspSyncRecdRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ return rc; } -struct cmDspClass_str* cmSyncRecdClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmSyncRecdClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmSyncRecdDC,ctx,"SyncRecd", NULL, @@ -3238,7 +3277,10 @@ struct cmDspClass_str* cmSyncRecdClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspTakeSeqBldr file_desc:"User interface unit for creating a single sequence from multiple, score aligned, MIDI fragments." kw:[sunit] } + enum { kFnTsbId, @@ -3350,7 +3392,7 @@ cmDspRC_t _cmDspTakeSeqBldrRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspE return kOkDspRC; } -struct cmDspClass_str* cmTakeSeqBldrClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmTakeSeqBldrClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmTakeSeqBldrDC,ctx,"TakeSeqBldr", NULL, @@ -3369,7 +3411,9 @@ struct cmDspClass_str* cmTakeSeqBldrClassCons( cmDspCtx_t* ctx ) -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspTakeSeqRend file_desc:"User interface unit for graphically rendering the MIDI sequences created by cmDspTakeSeqBldr." kw:[sunit] } enum { kBldrTsrId, @@ -3571,7 +3615,7 @@ cmDspRC_t _cmDspTakeSeqRendRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspE return kOkDspRC; } -struct cmDspClass_str* cmTakeSeqRendClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmTakeSeqRendClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmTakeSeqRendDC,ctx,"TakeSeqRend", NULL, @@ -3588,7 +3632,9 @@ struct cmDspClass_str* cmTakeSeqRendClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspReflectCalc file_desc:"Estimate the time-of-flight of from an acoustic signal from a speaker to a microphone." kw:[sunit] } enum { kLfsrN_RcId, @@ -3617,13 +3663,11 @@ typedef struct cmDspInst_t* _cmDspReflectCalcAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl ) { - /* - if( va_cnt !=3 ) - { - cmDspClassErr(ctx,classPtr,kVarArgParseFailDspRC,"The 'ReflectCalc' constructor must have two arguments: a channel count and frequency array."); - return NULL; - } - */ + // if( va_cnt !=3 ) + // { + // cmDspClassErr(ctx,classPtr,kVarArgParseFailDspRC,"The 'ReflectCalc' constructor must have two arguments: a channel count and frequency array."); + // return NULL; + // } cmDspReflectCalc_t* p = cmDspInstAllocV(cmDspReflectCalc_t,ctx,classPtr,instSymId,id,storeSymId,va_cnt,vl, 1, "lfsrN", kLfsrN_RcId, 0,0, kInDsvFl | kUIntDsvFl, "Gold code generator LFSR length", @@ -3729,7 +3773,7 @@ cmDspRC_t _cmDspReflectCalcRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspE return kOkDspRC; } -struct cmDspClass_str* cmReflectCalcClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmReflectCalcClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmReflectCalcDC,ctx,"ReflectCalc", NULL, @@ -3746,12 +3790,15 @@ struct cmDspClass_str* cmReflectCalcClassCons( cmDspCtx_t* ctx ) } -//========================================================================================================================================== +//------------------------------------------------------------------------------------------------------------ +//) +//( { label:cmDspEchoCancel file_desc:"Normalized least mean squares echo canceller." kw:[sunit] } enum { kMuEcId, kImpRespN_EcId, kDelayN_EcId, + kBypassEcId, kUnfiltInEcId, kFiltInEcId, kOutEcId @@ -3769,18 +3816,17 @@ typedef struct cmDspInst_t* _cmDspEchoCancelAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl ) { - /* - if( va_cnt !=3 ) - { - cmDspClassErr(ctx,classPtr,kVarArgParseFailDspRC,"The 'EchoCancel' constructor must have two arguments: a channel count and frequency array."); - return NULL; - } - */ + // if( va_cnt !=3 ) + // { + // cmDspClassErr(ctx,classPtr,kVarArgParseFailDspRC,"The 'EchoCancel' constructor must have two arguments: a channel count and frequency array."); + // return NULL; + // } cmDspEchoCancel_t* p = cmDspInstAllocV(cmDspEchoCancel_t,ctx,classPtr,instSymId,id,storeSymId,va_cnt,vl, 1, "mu", kMuEcId, 0,0, kInDsvFl | kDoubleDsvFl, "NLSM mu coefficient.", 1, "irN", kImpRespN_EcId, 0,0, kInDsvFl | kUIntDsvFl, "Filter impulse response length in samples.", 1, "delayN", kDelayN_EcId, 0,0, kInDsvFl | kUIntDsvFl, "Fixed feedback delay in samples.", + 1, "bypass", kBypassEcId, 0,0, kInDsvFl | kBoolDsvFl, "Bypass enable flag.", 1, "uf_in", kUnfiltInEcId, 0,1, kInDsvFl | kAudioBufDsvFl, "Unfiltered audio input", 1, "f_in", kFiltInEcId, 0,1, kInDsvFl | kAudioBufDsvFl, "Filtered audio input", 1, "out", kOutEcId, 0,1, kOutDsvFl | kAudioBufDsvFl, "Audio output", @@ -3791,7 +3837,8 @@ cmDspInst_t* _cmDspEchoCancelAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, uns cmDspSetDefaultDouble( ctx, &p->inst, kMuEcId, 0, 0.1); cmDspSetDefaultUInt( ctx, &p->inst, kImpRespN_EcId, 0, 2048); - cmDspSetDefaultUInt( ctx, &p->inst, kDelayN_EcId, 0, 1906); + cmDspSetDefaultUInt( ctx, &p->inst, kDelayN_EcId, 0, 1765); + cmDspSetDefaultBool( ctx, &p->inst, kBypassEcId, 0, false); return &p->inst; } @@ -3835,7 +3882,7 @@ cmDspRC_t _cmDspEchoCancelExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv { cmDspRC_t rc = kOkDspRC; cmDspEchoCancel_t* p = (cmDspEchoCancel_t*)inst; - bool bypassFl = false; + bool bypassFl = true; //cmDspBool(inst,kBypassEcId); const cmSample_t* fV = cmDspAudioBuf(ctx,inst,kFiltInEcId,0); unsigned fN = cmDspAudioBufSmpCount(ctx,inst,kFiltInEcId,0); @@ -3850,7 +3897,7 @@ cmDspRC_t _cmDspEchoCancelExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv if( bypassFl ) { - cmVOS_Copy(yV,yN,fV); + cmVOS_Copy(yV,yN,uV); } else { @@ -3885,6 +3932,10 @@ cmDspRC_t _cmDspEchoCancelRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv case kDelayN_EcId: cmNlmsEcSetDelayN( p->r, cmDspUInt(inst,kDelayN_EcId)); break; + + case kBypassEcId: + printf("EC bypass:%i\n",cmDspBool(inst,kBypassEcId)); + break; } } @@ -3893,7 +3944,7 @@ cmDspRC_t _cmDspEchoCancelRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv return kOkDspRC; } -struct cmDspClass_str* cmEchoCancelClassCons( cmDspCtx_t* ctx ) +cmDspClass_t* cmEchoCancelClassCons( cmDspCtx_t* ctx ) { cmDspClassSetup(&_cmEchoCancelDC,ctx,"EchoCancel", NULL, @@ -3908,3 +3959,4 @@ struct cmDspClass_str* cmEchoCancelClassCons( cmDspCtx_t* ctx ) return &_cmEchoCancelDC; } +//) diff --git a/dsp/cmDspNet.h b/dsp/cmDspNet.h index dfa7d17..9d8e9f1 100644 --- a/dsp/cmDspNet.h +++ b/dsp/cmDspNet.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"'snap' distributed host UDP networking implementation." kw:[snap]} + #define cmDspSys_PARENT_SYM_TBL_BASE_ID 10000 #define cmDspSys_AsSubIdx_Zero (0) @@ -115,6 +117,8 @@ extern "C" { cmDspRC_t _cmDspSysNetSendEvent( cmDspSysH_t h, unsigned dstNetNodeId, unsigned dstId, const cmDspEvt_t* evt ); + //) + #ifdef __cplusplus } #endif diff --git a/dsp/cmDspPgm.c b/dsp/cmDspPgm.c index c0d6d80..177908a 100644 --- a/dsp/cmDspPgm.c +++ b/dsp/cmDspPgm.c @@ -1,3 +1,4 @@ +//( { file_desc:"'snap' programs." kw:[snap] } #include "cmPrefix.h" #include "cmGlobal.h" #include "cmFloatTypes.h" @@ -25,7 +26,8 @@ #include "cmDspPgm.h" #include "cmDspPgmPP.h" #include "cmDspPgmKr.h" - +//) +//( { label:cmDspPgm_ReflecCalc file_desc:"Acoustic time-of-flight measurement program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_ReflectCalc( cmDspSysH_t h, void** userPtrPtr ) { @@ -71,6 +73,10 @@ cmDspRC_t _cmDspSysPgm_ReflectCalc( cmDspSysH_t h, void** userPtrPtr ) return kOkDspRC; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_SyncRecd file_desc:"Generate MIDI / Audio synchronization data with cmDspSyncRecd." kw:[spgm] } + cmDspRC_t _cmDspSysPgm_SyncRecd( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -115,6 +121,9 @@ cmDspRC_t _cmDspSysPgm_SyncRecd( cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_MidiFilePlay file_desc:"MIDI file player example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_MidiFilePlay( cmDspSysH_t h, void** userPtrPtr ) { @@ -198,7 +207,9 @@ cmDspRC_t _cmDspSysPgm_MidiFilePlay( cmDspSysH_t h, void** userPtrPtr ) } - +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Midi_Test file_desc:"MIDI input/output example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Test_Midi( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -250,6 +261,9 @@ cmDspRC_t _cmDspSysPgm_Test_Midi( cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Stereo_Through file_desc:"Stereo audio through example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Stereo_Through( cmDspSysH_t h, void** userPtrPtr ) { @@ -260,12 +274,12 @@ cmDspRC_t _cmDspSysPgm_Stereo_Through( cmDspSysH_t h, void** userPtrPtr ) cmDspInst_t* php = cmDspSysAllocInst(h,"Phasor", NULL, 0 ); cmDspInst_t* wtp = cmDspSysAllocInst(h,"WaveTable",NULL, 2, cmDspSysSampleRate(h), 2 ); - cmDspInst_t* ai0p = cmDspSysAllocInst(h,"AudioIn", NULL, 1, 2 ); - cmDspInst_t* ai1p = cmDspSysAllocInst(h,"AudioIn", NULL, 1, 3 ); + cmDspInst_t* ai0p = cmDspSysAllocInst(h,"AudioIn", NULL, 1, 0 ); + cmDspInst_t* ai1p = cmDspSysAllocInst(h,"AudioIn", NULL, 1, 1 ); // MOTU Traveler: Use channels 2&3 (out plugs:3&4) because 0&1 do not show up on plugs 1&2. - cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL, 1, 0 ); - cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL, 1, 1 ); + cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL, 1, 2 ); + cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL, 1, 3 ); cmDspInst_t* im0p = cmDspSysAllocInst(h,"AMeter","In 0", 0); cmDspInst_t* im1p = cmDspSysAllocInst(h,"AMeter","In 1", 0); @@ -299,6 +313,9 @@ cmDspRC_t _cmDspSysPgm_Stereo_Through( cmDspSysH_t h, void** userPtrPtr ) return kOkDspRC; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Stereo_Fx file_desc:"Stereo audio effects example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Stereo_Fx( cmDspSysH_t h, void** userPtrPtr ) { bool useBuiltInFl = true; @@ -367,6 +384,9 @@ cmDspRC_t _cmDspSysPgm_Stereo_Fx( cmDspSysH_t h, void** userPtrPtr ) return kOkDspRC; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_PlaySine file_desc:"Play a sine signal." kw:[spgm] } cmDspRC_t _cmDspSysPgm_PlaySine( cmDspSysH_t h, void** userPtrPtr ) { bool useBuiltInFl = true; @@ -424,6 +444,9 @@ cmDspRC_t _cmDspSysPgm_PlayFile( cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_MultiOut file_desc:"Play to multiple output channels example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_MultiOut( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -486,6 +509,9 @@ cmDspRC_t _cmDspSysPgm_MultiOut( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_MultiIn file_desc:"Multiple audio inputs example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_MultiIn(cmDspSysH_t h, void** userPtrPtr) { int chCnt = 8; @@ -516,6 +542,9 @@ cmDspRC_t _cmDspSysPgm_MultiIn(cmDspSysH_t h, void** userPtrPtr) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_GateDetect file_desc:"Gate detector example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_GateDetect( cmDspSysH_t h, void** userPtrPtr ) { bool useBuiltInFl = true; @@ -556,6 +585,9 @@ cmDspRC_t _cmDspSysPgm_GateDetect( cmDspSysH_t h, void** userPtrPtr ) return kOkDspRC; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Record file_desc:"Record audio to an audio file." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Record(cmDspSysH_t h, void** userPtrPtr) { int chCnt = 8; @@ -593,6 +625,9 @@ cmDspRC_t _cmDspSysPgm_Record(cmDspSysH_t h, void** userPtrPtr) return kOkDspRC; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_PitchShift file_desc:"Pitch-shifter example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_PitchShiftFile( cmDspSysH_t h, void** userPtrPtr ) { bool useBuiltInFl = true; @@ -634,6 +669,9 @@ cmDspRC_t _cmDspSysPgm_PitchShiftFile( cmDspSysH_t h, void** userPtrPtr ) return kOkDspRC; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_LoopRecd file_desc:"Loop-recorder example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_LoopRecd( cmDspSysH_t h, void** userPtrPtr ) { bool useBuiltInFl = true; @@ -670,6 +708,9 @@ cmDspRC_t _cmDspSysPgm_LoopRecd( cmDspSysH_t h, void** userPtrPtr ) +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_UiTest file_desc:"User Interface example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_UiTest(cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -716,6 +757,9 @@ cmDspRC_t _cmDspSysPgm_UiTest(cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Xfade file_desc:"Cross fader example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Xfade( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -779,6 +823,9 @@ cmDspRC_t _cmDspSysPgm_Xfade( cmDspSysH_t h, void** userPtrPtr ) return cmDspSysLastRC(h); } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Pgm6 file_desc:"Stereo strectral non-linear distortion example." kw:[spgm] } cmDspRC_t _cmDspSysPgm6( cmDspSysH_t h, void* audioDir ) { cmDspRC_t rc = kOkDspRC; @@ -917,6 +964,9 @@ cmDspRC_t _cmDspSysPgm6( cmDspSysH_t h, void* audioDir ) return cmDspSysLastRC(h); } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Guitar file_desc:"Similiar to Pgm6." kw:[spgm] } cmDspRC_t _cmDspSysPgmGuitar( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -1056,6 +1106,9 @@ cmDspRC_t _cmDspSysPgmGuitar( cmDspSysH_t h, void** userPtrPtr ) +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Pickups0 file_desc:"'fluxo' with loop-record, echo, rectify, and pitch-shift." kw:[spgm fluxo] } cmDspRC_t _cmDspSysPgm_Pickups0( cmDspSysH_t h, void** userPtrPtr ) { @@ -1169,6 +1222,10 @@ cmDspRC_t _cmDspSysPgm_Pickups0( cmDspSysH_t h, void** userPtrPtr ) return kOkDspRC; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_AutoGain file_desc:"'fluxo' channel calibration program." kw:[spgm fluxo] } + #include "cmAudioFile.h" #include "cmProcObj.h" #include "cmProc.h" @@ -1414,6 +1471,9 @@ cmDspRC_t _cmDspSysPgm_AutoGain( cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_PickupFxFile file_desc:"'fluxo' noise shapers." kw:[spgm fluxo] } cmDspRC_t _cmDspSysPgm_PickupFxFile( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -1509,6 +1569,9 @@ cmDspRC_t _cmDspSysPgm_PickupFxFile( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_NoiseTails file_desc:"'fluxo' noise shapers." kw:[spgm fluxo] } cmDspRC_t _cmDspSysPgm_NoiseTails( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -1609,6 +1672,9 @@ cmDspRC_t _cmDspSysPgm_NoiseTails( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_NoiseTails2 file_desc:"'fluxo' noise shapers." kw:[spgm fluxo] } cmDspRC_t _cmDspSysPgm_NoiseTails2( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -1781,6 +1847,9 @@ cmDspRC_t _cmDspSysPgm_NoiseTails2( cmDspSysH_t h, void** userPtrPtr ) +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_CombFilt file_desc:"Comb filter example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_CombFilt( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -1808,6 +1877,9 @@ cmDspRC_t _cmDspSysPgm_CombFilt( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_ScalarOp file_desc:"Scalar operations example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_ScalarOp( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc; @@ -1839,6 +1911,9 @@ cmDspRC_t _cmDspSysPgm_ScalarOp( cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_RingMod file_desc:"Ring modulation example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_RingMod( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -1948,6 +2023,9 @@ cmDspRC_t _cmDspSysPgm_RingMod( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_RingMod2 file_desc:"Ring modulation example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_RingMod2( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -2037,6 +2115,9 @@ cmDspRC_t _cmDspSysPgm_RingMod2( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_MsgDelay file_desc:"Message delay example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_MsgDelay( cmDspSysH_t h, void** userPtrPtr ) { @@ -2059,6 +2140,9 @@ cmDspRC_t _cmDspSysPgm_MsgDelay( cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Adsr file_desc:"ADSR envelope generator example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Adsr( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc; @@ -2108,6 +2192,10 @@ cmDspRC_t _cmDspSysPgm_Adsr( cmDspSysH_t h, void** userPtrPtr ) } + +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Adsr file_desc:"Dynamics compressor example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Compressor( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc; @@ -2170,6 +2258,9 @@ cmDspRC_t _cmDspSysPgm_Compressor( cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_BiQuadEq file_desc:"Biquad EQ example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_BiQuadEq( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -2218,6 +2309,9 @@ cmDspRC_t _cmDspSysPgm_BiQuadEq( cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_DistDs file_desc:"Guitar distortion example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_DistDs( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -2274,6 +2368,9 @@ cmDspRC_t _cmDspSysPgm_DistDs( cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Seq file_desc:"Message list 'seq' mode example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Seq( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc; @@ -2300,6 +2397,9 @@ cmDspRC_t _cmDspSysPgm_Seq( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_ThunkNet file_desc:"UDP network receiver example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_ThunkNet( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc; @@ -2318,6 +2418,9 @@ cmDspRC_t _cmDspSysPgm_ThunkNet( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_WhirlNet file_desc:"UDP network sender example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_WhirlNet( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc; @@ -2335,6 +2438,9 @@ cmDspRC_t _cmDspSysPgm_WhirlNet( cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_NofM file_desc:"Select NofM example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_NofM( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc; @@ -2403,6 +2509,9 @@ cmDspRC_t _cmDspSysPgm_NofM( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_1ofM file_desc:"Select 1 of N example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_1ofN( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc; @@ -2438,6 +2547,9 @@ cmDspRC_t _cmDspSysPgm_1ofN( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Router file_desc:"Router example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Router( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc; @@ -2476,6 +2588,9 @@ cmDspRC_t _cmDspSysPgm_Router( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Preset file_desc:"Preset save/restore example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Preset( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc; @@ -2516,6 +2631,9 @@ cmDspRC_t _cmDspSysPgm_Preset( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_RsrcWr file_desc:"Set a resource value example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_RsrcWr( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -2545,6 +2663,9 @@ cmDspRC_t _cmDspSysPgm_RsrcWr( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_1Up file_desc:"1Up example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_1Up( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc; @@ -2572,6 +2693,9 @@ cmDspRC_t _cmDspSysPgm_1Up( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_PortToSym file_desc:"PortToSym example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_PortToSym( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -2606,6 +2730,9 @@ cmDspRC_t _cmDspSysPgm_PortToSym( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Line file_desc:"Line generator example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Line( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -2637,6 +2764,9 @@ cmDspRC_t _cmDspSysPgm_Line( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Array file_desc:"Array and pitch converter example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Array( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -2683,6 +2813,9 @@ cmDspRC_t _cmDspSysPgm_SegLine( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_AvailCh file_desc:"AvailCh and XFader example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_AvailCh( cmDspSysH_t h, void** userPtrPtr ) { double frqHz = 440.0; @@ -2690,9 +2823,11 @@ cmDspRC_t _cmDspSysPgm_AvailCh( cmDspSysH_t h, void** userPtrPtr ) double xfadeMs = 250.0; bool xfadeInitFl = false; - const char* fn = "/home/kevin/media/audio/20110723-Kriesberg/Audio Files/Piano 3_01.wav"; + const char* fn = "/Users/kevin/media/audio/20110723-Kriesberg/Audio Files/Piano 3_01.wav"; cmDspInst_t* chk0 = cmDspSysAllocInst(h,"Button", "0", 2, kButtonDuiId, 0.0 ); + cmDspInst_t* hz = cmDspSysAllocScalar( h, "hz",0.0, 10000.0, 0.01, 1.0 ); + //cmDspInst_t* chk1 = cmDspSysAllocInst(h,"Button", "1", 2, kCheckDuiId, 0.0 ); cmDspInst_t* achp = cmDspSysAllocInst( h, "AvailCh", NULL, 1, xfadeChCnt ); @@ -2703,7 +2838,7 @@ cmDspRC_t _cmDspSysPgm_AvailCh( cmDspSysH_t h, void** userPtrPtr ) cmDspInst_t* fwtp = cmDspSysAllocInst( h, "WaveTable", NULL, 5, ((int)cmDspSysSampleRate(h)), 1, fn, -1, 7000000 ); cmDspInst_t* fad0 = cmDspSysAllocInst( h, "Xfader", NULL, 3, xfadeChCnt, xfadeMs, xfadeInitFl ); - //cmDspInst_t* prp = cmDspSysAllocInst( h, "Printer", NULL, 1, ">" ); + cmDspInst_t* prp = cmDspSysAllocInst( h, "Printer", NULL, 1, ">" ); cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 0 ); cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 1 ); @@ -2722,18 +2857,26 @@ cmDspRC_t _cmDspSysPgm_AvailCh( cmDspSysH_t h, void** userPtrPtr ) //cmDspSysInstallCb(h, chk0, "out", fad0, "gate-0", NULL); //cmDspSysInstallCb(h, chk1, "out", fad0, "gate-1", NULL); - cmDspSysInstallCb(h, chk0, "sym", achp, "trig", NULL); - cmDspSysInstallCb(h, achp, "gate-0", fad0, "gate-0", NULL ); - cmDspSysInstallCb(h, fad0, "state-0", achp, "dis-0", NULL ); + cmDspSysInstallCb(h, chk0, "sym", achp, "trig", NULL); // btn->availCh.trig + cmDspSysInstallCb(h, achp, "ch", prp, "in", NULL); // availCh.ch -> printer + + + cmDspSysInstallCb(h, achp, "gate-0", fad0, "gate-0", NULL ); // availCh.gate->xfad.gate + cmDspSysInstallCb(h, fad0, "state-0", achp, "dis-0", NULL ); // xfad->state ->availCh.dis cmDspSysInstallCb(h, achp, "gate-1", fad0, "gate-1", NULL ); - cmDspSysInstallCb(h, fad0, "state-1", achp, "dis-1", NULL ); + cmDspSysInstallCb(h, fad0, "state-1", achp, "dis-1", NULL ); + + cmDspSysInstallCb(h, hz, "val", sphp, "mult", NULL ); return kOkDspRC; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Goertzel file_desc:"Goertzel detector example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Goertzel( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc; @@ -2794,6 +2937,9 @@ cmDspRC_t _cmDspSysPgm_Goertzel( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_TakeSeqBldr file_desc:"Take sequence builder example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_TakeSeqBldr( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -2852,6 +2998,9 @@ cmDspRC_t _cmDspSysPgm_TakeSeqBldr( cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_TwoD file_desc:"Two dimensional controller example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_TwoD( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -2871,6 +3020,9 @@ cmDspRC_t _cmDspSysPgm_TwoD( cmDspSysH_t h, void** userPtrPtr ) return rc; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_BinEnc file_desc:"HRTF binaural encoder example program." kw:[spgm] } cmDspRC_t _cmDspSysPgm_BinEnc( cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -2943,8 +3095,8 @@ cmDspRC_t _cmDspSysPgm_BinEnc( cmDspSysH_t h, void** userPtrPtr ) errLabel: return rc; } - - +//) +//( _cmDspSysPgm_t _cmDspSysPgmArray[] = { { "reflect", _cmDspSysPgm_ReflectCalc, NULL, NULL }, @@ -3008,3 +3160,4 @@ _cmDspSysPgm_t* _cmDspSysPgmArrayBase() } +//) diff --git a/dsp/cmDspPgmKr.c b/dsp/cmDspPgmKr.c index a7db88b..b09db92 100644 --- a/dsp/cmDspPgmKr.c +++ b/dsp/cmDspPgmKr.c @@ -1,3 +1,5 @@ +//( { file_desc:"'snap' Performance analysis related programs." kw:[snap]} + #include "cmPrefix.h" #include "cmGlobal.h" #include "cmFloatTypes.h" @@ -89,10 +91,10 @@ const cmChar_t* _mlbl(const cmChar_t* prefix, unsigned ch ) } #define mlbl(a) _mlbl(a,mch) -#define lbl(a) cmDspSysPrintLabel(a,ch) +#define lbl(a) cmDspSysPrintLabel(a,ach) -void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpSymId, unsigned cmpPreGrpSymId, cmDspInst_t* modp, unsigned ch, unsigned mch ) +void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpSymId, unsigned cmpPreGrpSymId, cmDspInst_t* modp, unsigned ach, unsigned mch ) { unsigned measRtrChCnt = 6; // note: router channel 6 is not connected @@ -123,7 +125,7 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpS cmDspInst_t* cost_sr = cmDspSysAllocInst(h, "ScaleRange", NULL, 4, 0.0, 1.0, 0.001, 1.0 ); // Measurement -> parameter mappers - cmDspInst_t* even_rt = cmDspSysAllocInst(h, "Router", NULL, 2, measRtrChCnt, measRtrChCnt-1 ); + cmDspInst_t* even_rt = cmDspSysAllocInst(h, "Router", lbl("even_rt"), 2, measRtrChCnt, measRtrChCnt-1 ); cmDspInst_t* dynm_rt = cmDspSysAllocInst(h, "Router", NULL, 2, measRtrChCnt, measRtrChCnt-1 ); cmDspInst_t* tmpo_rt = cmDspSysAllocInst(h, "Router", NULL, 2, measRtrChCnt, measRtrChCnt-1 ); cmDspInst_t* cost_rt = cmDspSysAllocInst(h, "Router", NULL, 2, measRtrChCnt, measRtrChCnt-1 ); @@ -138,7 +140,7 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpS // Parameter-> kr routers (routers used to cross-fade between the two kr units) unsigned paramRtChCnt = 2; - cmDspInst_t* mod_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 ); + cmDspInst_t* mod_rt = cmDspSysAllocInst(h, "Router", lbl("mod_rt"), 2, paramRtChCnt, paramRtChCnt-1 ); cmDspInst_t* wnd_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 ); cmDspInst_t* hop_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 ); cmDspInst_t* thr_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 ); @@ -150,15 +152,14 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpS // Audio processors cmDspInst_t* kr0 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact ); - //cmDspInst_t* kr1 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact ); + cmDspInst_t* kr1 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact ); cmDspInst_t* xfad = cmDspSysAllocInst(h, "Xfader", NULL, 3, xfadeChCnt, xfadeMs, xfadeInitFl ); cmDspInst_t* mix = cmDspSysAllocInst(h, "AMix", NULL, 3, xfadeChCnt, mixGain, mixGain ); cmDspInst_t* cmp = cmDspSysAllocInst(h, "Compressor", NULL, 8, cmpBypassFl, cmpThreshDb, cmpRatio_num, cmpAtkMs, cmpRlsMs, cmpMakeup, cmpWndMs, cmpWndMaxMs ); - // Internal audio connections cmDspSysConnectAudio(h, kr0, "out", xfad, "in-0"); - //cmDspSysConnectAudio(h, kr1, "out", xfad, "in-1"); + cmDspSysConnectAudio(h, kr1, "out", xfad, "in-1"); cmDspSysConnectAudio(h, xfad, "out-0", mix, "in-0"); cmDspSysConnectAudio(h, xfad, "out-1", mix, "in-1"); cmDspSysConnectAudio(h, mix, "out", cmp, "in" ); @@ -232,22 +233,23 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpS cmDspInst_t* lwr_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Lwr slope"), 0.3, 10.0, 0.01, 2.0 ); cmDspInst_t* off_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Offset"), 0.0, 100.0, 0.01, 20.0 ); cmDspInst_t* inv_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Invert"), 0.0, 1.0, 1.0, 0.0 ); - cmDspInst_t* wet_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Wet Dry"), 0.0, 1.0, 0.001, 1.0 ); + cmDspInst_t* wet_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Wet Dry"), 0.0, 1.0, 0.001, 1.0 ); + cmDspSysInstallCb(h, mod_ctl, "val", mod_rt, "f-in", NULL ); cmDspSysInstallCb(h, achan, "ch", mod_rt, "sel", NULL ); // ach->rt sel cmDspSysInstallCb(h, mod_rt, "f-out-0", kr0, "mode", NULL ); // mode->kr - //cmDspSysInstallCb(h, mod_rt, "f-out-1", kr1, "mode", NULL ); // mode->kr + cmDspSysInstallCb(h, mod_rt, "f-out-1", kr1, "mode", NULL ); // mode->kr cmDspSysInstallCb(h, wnd_ctl, "out", wnd_rt, "f-in", NULL ); cmDspSysInstallCb(h, achan, "ch", wnd_rt, "sel", NULL ); // ach->rt sel cmDspSysInstallCb(h, wnd_rt, "f-out-0", kr0, "wndn", NULL ); // wndn->kr - //cmDspSysInstallCb(h, wnd_rt, "f-out-1", kr1, "wndn", NULL ); // wndn->kr + cmDspSysInstallCb(h, wnd_rt, "f-out-1", kr1, "wndn", NULL ); // wndn->kr cmDspSysInstallCb(h, hop_ctl, "out", hop_rt, "f-in", NULL ); cmDspSysInstallCb(h, achan, "ch", hop_rt, "sel", NULL ); // ach->rt sel cmDspSysInstallCb(h, hop_rt, "f-out-0", kr0, "hopf", NULL ); // hopf->kr - //cmDspSysInstallCb(h, hop_rt, "f-out-1", kr1, "hopf", NULL ); // hopf->kr + cmDspSysInstallCb(h, hop_rt, "f-out-1", kr1, "hopf", NULL ); // hopf->kr cmDspSysInstallCb(h, min_thr_ctl, "val", thr_sr, "min_out", NULL ); cmDspSysInstallCb(h, max_thr_ctl, "val", thr_sr, "max_out", NULL ); @@ -259,7 +261,7 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpS cmDspSysInstallCb(h, thr_ctl, "val", thr_rt, "f-in", NULL ); cmDspSysInstallCb(h, achan, "ch", thr_rt, "sel", NULL ); // ach->rt sel cmDspSysInstallCb(h, thr_rt, "f-out-0", kr0, "thrh", NULL ); // thr->kr - //cmDspSysInstallCb(h, thr_rt, "f-out-1", kr1, "thrh", NULL ); // thr->kr + cmDspSysInstallCb(h, thr_rt, "f-out-1", kr1, "thrh", NULL ); // thr->kr cmDspSysInstallCb(h, min_upr_ctl, "val", upr_sr, "min_out", NULL ); cmDspSysInstallCb(h, max_upr_ctl, "val", upr_sr, "max_out", NULL ); @@ -271,7 +273,7 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpS cmDspSysInstallCb(h, upr_ctl, "val", upr_rt, "f-in", NULL ); cmDspSysInstallCb(h, achan, "ch", upr_rt, "sel", NULL ); // ach->rt sel cmDspSysInstallCb(h, upr_rt, "f-out-0", kr0, "uprs", NULL ); // upr->kr - //cmDspSysInstallCb(h, upr_rt, "f-out-1", kr1, "uprs", NULL ); // upr->kr + cmDspSysInstallCb(h, upr_rt, "f-out-1", kr1, "uprs", NULL ); // upr->kr cmDspSysInstallCb(h, min_lwr_ctl, "val", lwr_sr, "min_out", NULL ); cmDspSysInstallCb(h, max_lwr_ctl, "val", lwr_sr, "max_out", NULL ); @@ -283,7 +285,7 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpS cmDspSysInstallCb(h, lwr_ctl, "val", lwr_rt, "f-in", NULL ); cmDspSysInstallCb(h, achan, "ch", lwr_rt, "sel", NULL ); // ach->rt sel cmDspSysInstallCb(h, lwr_rt, "f-out-0", kr0, "lwrs", NULL ); // lwr->kr - //cmDspSysInstallCb(h, lwr_rt, "f-out-1", kr1, "lwrs", NULL ); // lwr->kr + cmDspSysInstallCb(h, lwr_rt, "f-out-1", kr1, "lwrs", NULL ); // lwr->kr cmDspSysInstallCb(h, min_off_ctl, "val", off_sr, "min_out", NULL ); cmDspSysInstallCb(h, max_off_ctl, "val", off_sr, "max_out", NULL ); @@ -295,12 +297,12 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpS cmDspSysInstallCb(h, off_ctl, "val", off_rt, "f-in", NULL ); cmDspSysInstallCb(h, achan, "ch", off_rt, "sel", NULL ); // ach->rt sel cmDspSysInstallCb(h, off_rt, "f-out-0", kr0, "offs", NULL ); // off->kr - //cmDspSysInstallCb(h, off_rt, "f-out-1", kr1, "offs", NULL ); // off->kr + cmDspSysInstallCb(h, off_rt, "f-out-1", kr1, "offs", NULL ); // off->kr cmDspSysInstallCb(h, inv_ctl, "val", inv_rt, "f-in", NULL ); cmDspSysInstallCb(h, achan, "ch", inv_rt, "sel", NULL ); // ach->rt sel cmDspSysInstallCb(h, inv_rt, "f-out-0", kr0, "invt", NULL ); // inv->kr - //cmDspSysInstallCb(h, inv_rt, "f-out-1", kr1, "invt", NULL ); // inv->kr + cmDspSysInstallCb(h, inv_rt, "f-out-1", kr1, "invt", NULL ); // inv->kr cmDspSysInstallCb(h, min_wet_ctl, "val", wet_sr, "min_out", NULL ); cmDspSysInstallCb(h, max_wet_ctl, "val", wet_sr, "max_out", NULL ); @@ -313,7 +315,7 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpS cmDspSysInstallCb(h, wet_ctl, "val", wet_rt, "f-in", NULL ); cmDspSysInstallCb(h, achan, "ch", wet_rt, "sel", NULL ); // ach->rt sel cmDspSysInstallCb(h, wet_rt, "f-out-0", kr0, "wet", NULL ); // wet->kr - //cmDspSysInstallCb(h, wet_rt, "f-out-1", kr1, "wet", NULL ); // wet->kr + cmDspSysInstallCb(h, wet_rt, "f-out-1", kr1, "wet", NULL ); // wet->kr cmDspSysNewColumn(h,0); @@ -368,13 +370,18 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpS cmDspSysInstallCb(h, modp, mlbl("maxo"), max_off_ctl, "val", NULL ); cmDspSysInstallCb(h, modp, mlbl("sw"), achan, "trig", NULL ); // See also: amp.sfloc->achan.trig + c->achan = achan; c->kr0 = kr0; - //c->kr1 = kr1; + c->kr1 = kr1; c->cmp = cmp; } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_TimeLine file_desc:"Audio/MIDI sequencer for analyzing the score vs. the performance and generating related audio transforms." kw:[spgm] } + cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) { cmDspRC_t rc = kOkDspRC; @@ -385,7 +392,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) bool useWtFl = false; bool useChain1Fl = true; bool useInputEqFl = false; - bool useInCompFl = true; + bool useInCompFl = false; unsigned wtLoopCnt = 1; // 1=play once (-1=loop forever) unsigned wtInitMode = 0; // initial wt mode is 'silence' @@ -1198,17 +1205,20 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_Tksb file_desc:"Audio/MIDI sequencer for analyzing the score vs. the performance from user selected MIDI fragments and generating related audio transforms." kw:[spgm] } cmDspRC_t _cmDspSysPgm_Tksb(cmDspSysH_t h, void** userPtrPtr ) { - cmDspRC_t rc = kOkDspRC; - cmCtx_t* cmCtx = cmDspSysPgmCtx(h); - cmErr_t err; - krRsrc_t r; - bool fragFl = false; - bool useWtFl = false; - bool useChain1Fl = true; - bool useInputEqFl = false; - bool useInCompFl = true; + cmDspRC_t rc = kOkDspRC; + cmCtx_t* cmCtx = cmDspSysPgmCtx(h); + cmErr_t err; + krRsrc_t r; + bool fragFl = false; + bool useWtFl = false; + bool useChain1Fl = true; + bool useInputEqFl = false; + bool useInCompFl = true; unsigned sfBufCnt = 7; // length of the MIDI event buffer unsigned sfMaxWndCnt = 10; // length of the score event buffer @@ -2037,6 +2047,9 @@ cmDspRC_t _cmDspSysPgm_Tksb(cmDspSysH_t h, void** userPtrPtr ) } +//------------------------------------------------------------------------------ +//) +//( { label:cmDspPgm_TksbLIst file_desc:"A simplified version of cmDspSysPgm_Tksb." kw:[spgm] } cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ) { @@ -2057,7 +2070,10 @@ cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ) return rc; cmDspInst_t* ai0p = cmDspSysAllocInst(h,"AudioIn", NULL, 1, 0); - cmDspInst_t* ec0 = cmDspSysAllocInst(h,"EchoCancel", NULL, 1, 0,1 ); + cmDspInst_t* ai1p = cmDspSysAllocInst(h,"AudioIn", NULL, 1, 1); + + //cmDspInst_t* ec0 = cmDspSysAllocInst(h,"EchoCancel", NULL, 1, 0,1 ); + //cmDspInst_t* ec1 = cmDspSysAllocInst(h,"EchoCancel", NULL, 1, 0,1 ); cmDspInst_t* bldr = cmDspSysAllocInst( h,"TakeSeqBldr", NULL, 1, r.tksbFn ); cmDspInst_t* rndr = cmDspSysAllocInst( h,"TakeSeqRend", NULL, 0 ); @@ -2068,17 +2084,18 @@ cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ) cmDspInst_t* mop = cmDspSysAllocInst(h,"MidiOut", NULL, 2, r.midiDevice,r.midiOutPort); cmDspInst_t* mo2p = cmDspSysAllocInst(h,"MidiOut", NULL, 2, r.midiDevice,r.midiOutPort2); cmDspInst_t* sfp = cmDspSysAllocInst(h,"ScFol", NULL, 1, r.scFn, sfBufCnt, sfMaxWndCnt, sfMinVel, sfEnaMeasFl ); - cmDspInst_t* amp = cmDspSysAllocInst(h,"ActiveMeas", NULL, 1, 100 ); + //cmDspInst_t* amp = cmDspSysAllocInst(h,"ActiveMeas", NULL, 1, 100 ); cmDspInst_t* modp = cmDspSysAllocInst(h,"ScMod", NULL, 2, r.modFn, "m1" ); - cmDspInst_t* modr = cmDspSysAllocInst(h,"ScMod", NULL, 2, r.modFn, "m1" ); unsigned preGrpSymId = cmDspSysPresetRegisterGroup(h,"tl"); unsigned cmpPreGrpSymId = cmDspSysPresetRegisterGroup(h,"tl_cmp"); - cmDspTlXform_t c0; + cmDspTlXform_t c0,c1; cmDspSysNewPage(h,"Controls-0"); _cmDspSys_TlXformChain(h, &c0, preGrpSymId, cmpPreGrpSymId, modp, 0, 0 ); + cmDspSysNewPage(h,"Controls-1"); + _cmDspSys_TlXformChain(h, &c1, preGrpSymId, cmpPreGrpSymId, modp, 1, 1 ); cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 2 ); @@ -2092,43 +2109,50 @@ cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ) cmDspInst_t* onb = cmDspSysAllocInst(h,"Button", "start", 2, kButtonDuiId, 1.0 ); cmDspInst_t* offb = cmDspSysAllocInst(h,"Button", "stop", 2, kButtonDuiId, 1.0 ); cmDspInst_t* prp = cmDspSysAllocInst(h,"Printer", NULL, 1, ">" ); - cmDspInst_t* prd = cmDspSysAllocInst(h,"Printer", NULL, 1, "DYN:" ); - cmDspInst_t* pre = cmDspSysAllocInst(h,"Printer", NULL, 1, "EVEN:" ); - cmDspInst_t* prt = cmDspSysAllocInst(h,"Printer", NULL, 1, "TEMPO:"); - cmDspInst_t* prc = cmDspSysAllocInst(h,"Printer", NULL, 1, "COST:"); + //cmDspInst_t* prd = cmDspSysAllocInst(h,"Printer", NULL, 1, "DYN:" ); + //cmDspInst_t* pre = cmDspSysAllocInst(h,"Printer", NULL, 1, "EVEN:" ); + //cmDspInst_t* prt = cmDspSysAllocInst(h,"Printer", NULL, 1, "TEMPO:"); + //cmDspInst_t* prc = cmDspSysAllocInst(h,"Printer", NULL, 1, "COST:"); + cmDspInst_t* pra0 = cmDspSysAllocInst(h,"Printer", NULL, 1, "ACh0:"); + cmDspInst_t* pra1 = cmDspSysAllocInst(h,"Printer", NULL, 1, "ACh1:"); // Record <-> Live switches - cmDspInst_t* tlRt = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0); // time line swich + cmDspInst_t* tlRt = cmDspSysAllocInst(h,"Router", "tlRt", 2, 2, 0); // time line swich cmDspInst_t* wtRt = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0); cmDspInst_t* mfpRt = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0); cmDspInst_t* amRt = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0); cmDspInst_t* au0Sw = cmDspSysAllocInst(h,"1ofN", NULL, 2, 2, 0); cmDspInst_t* au1Sw = cmDspSysAllocInst(h,"1ofN", NULL, 2, 2, 0); - cmDspInst_t* siRt = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0); + cmDspInst_t* siRt = cmDspSysAllocInst(h,"Router", "siRT", 2, 2, 0); cmDspInst_t* muRt = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0); cmDspInst_t* d0Rt = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0); cmDspInst_t* d1Rt = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0); cmDspInst_t* stRt = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0); cmDspSysNewColumn(h,0); - cmDspInst_t* igain0 = cmDspSysAllocInst(h,"Scalar", "In Gain-0", 5, kNumberDuiId, 0.0, 100.0,0.01, 0.0 ); + cmDspInst_t* igain0 = cmDspSysAllocInst(h,"Scalar", "In Gain-0", 5, kNumberDuiId, 0.0, 100.0,0.01, 2.0 ); cmDspSysNewColumn(h,0); - cmDspInst_t* ogain0 = cmDspSysAllocInst(h,"Scalar", "Out Gain-0", 5, kNumberDuiId, 0.0, 10.0, 0.01, 0.0 ); + cmDspInst_t* ogain0 = cmDspSysAllocInst(h,"Scalar", "Out Gain-0", 5, kNumberDuiId, 0.0, 10.0, 0.01, 3.0 ); + /* cmDspInst_t* ec_mu = cmDspSysAllocInst(h,"Scalar", "EC mu", 5, kNumberDuiId, 0.0, 1.0, 0.01, 0.1 ); - cmDspInst_t* ec_di = cmDspSysAllocInst(h,"Scalar", "EC Delay", 5, kNumberDuiId, 0.0, cmDspSysSampleRate(h), 1.0, 2000.0 ); - cmDspInst_t* ec_hn = cmDspSysAllocInst(h,"Scalar", "EC IR N", 5, kNumberDuiId, 0.0, cmDspSysSampleRate(h), 1.0, 2048.0 ); + cmDspInst_t* ec_di = cmDspSysAllocInst(h,"Scalar", "EC Delay", 5, kNumberDuiId, 0.0, cmDspSysSampleRate(h), 1.0, 1765.0 ); + cmDspInst_t* ec_hn = cmDspSysAllocInst(h,"Scalar", "EC IR N", 5, kNumberDuiId, 0.0, cmDspSysSampleRate(h), 1.0, 2048.0 ); + cmDspInst_t* ec_byp= cmDspSysAllocCheck( h, "EC Bypass", 1.0 ); + */ // Audio file recording cmDspInst_t* recdGain= cmDspSysAllocInst(h,"Scalar", "Recd Gain", 5, kNumberDuiId, 0.0, 100.0,0.01, 1.5 ); cmDspInst_t* recdChk = cmDspSysAllocInst(h,"Button", "Record", 2, kCheckDuiId, 0.0 ); cmDspInst_t* recdPtS = cmDspSysAllocInst(h,"GateToSym", NULL, 2, cmSymTblRegisterStaticSymbol(cmDspSysSymbolTable(h),"open"),cmSymTblRegisterStaticSymbol(cmDspSysSymbolTable(h),"close")); cmDspInst_t* afop = cmDspSysAllocInst(h,"AudioFileOut",NULL, 2, r.recordDir,2); - cmDspInst_t* mi0p = cmDspSysAllocInst(h,"AMeter","In 0", 0); - + cmDspInst_t* mi0p = cmDspSysAllocInst(h,"AMeter","In 0", 0); + cmDspInst_t* mi1p = cmDspSysAllocInst(h,"AMeter","In 1", 0); + cmDspInst_t* mo0p = cmDspSysAllocInst(h,"AMeter","Out 0", 0); + cmDspInst_t* mo1p = cmDspSysAllocInst(h,"AMeter","Out 1", 0); //--------------- Preset controls cmDspSysNewColumn(h,0); @@ -2146,9 +2170,9 @@ cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ) cmDspSysNewColumn(h,0); //--------------- Recorded performance evaluation and Active Measurement related controls - cmDspInst_t* clrBtn = cmDspSysAllocButton( h, "clear", 0); - cmDspInst_t* prtBtn = cmDspSysAllocButton( h, "dump", 0); - cmDspInst_t* mlst = cmDspSysAllocInst( h, "MsgList", NULL, 3, "meas", r.measFn, 2); + //cmDspInst_t* clrBtn = cmDspSysAllocButton( h, "clear", 0); + //cmDspInst_t* prtBtn = cmDspSysAllocButton( h, "dump", 0); + //cmDspInst_t* mlst = cmDspSysAllocInst( h, "MsgList", NULL, 3, "meas", r.measFn, 2); cmDspInst_t* amCmd = cmDspSysAllocInst( h, "PortToSym", NULL, 2, "add", "rewind" ); @@ -2167,17 +2191,29 @@ cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ) // Audio connections cmDspSysConnectAudio(h, ai0p, "out", mi0p, "in"); // ain -> meter - cmDspSysConnectAudio(h, ai0p, "out", ec0, "f_in" ); // ain -> echo_cancel cmDspSysConnectAudio(h, ai0p, "out", c0.kr0, "in" ); // ain -> kr - - cmDspSysConnectAudio(h, c0.cmp, "out", ec0, "uf_in" ); // kr -> echo_cancel - cmDspSysConnectAudio(h, ec0, "out", ao0p, "in" ); // ec -> aout 0 - cmDspSysConnectAudio(h, ec0, "out", ao1p, "in" ); // ec -> aout 1 - cmDspSysConnectAudio(h, ec0, "out", afop, "in0" ); // ec -> audio_file + cmDspSysConnectAudio(h, ai0p, "out", c0.kr1, "in" ); + //cmDspSysConnectAudio(h, ai0p, "out", ec0, "f_in" ); // ain -> echo_cancel + //cmDspSysConnectAudio(h, c0.cmp, "out", ec0, "uf_in" ); // kr -> echo_cancel + //cmDspSysConnectAudio(h, ec0, "out", ao0p, "in" ); // ec -> aout 0 + cmDspSysConnectAudio(h, c0.cmp, "out", ao0p, "in" ); // kr -> echo_cancel + cmDspSysConnectAudio(h, c0.cmp, "out", afop, "in0" ); // ec -> audio_file + cmDspSysConnectAudio(h, c0.cmp, "out", mo0p, "in" ); // + cmDspSysConnectAudio(h, ai1p, "out", mi1p, "in"); // ain -> meter + cmDspSysConnectAudio(h, ai1p, "out", c1.kr0, "in" ); // ain -> kr + cmDspSysConnectAudio(h, ai1p, "out", c1.kr1, "in" ); + //cmDspSysConnectAudio(h, ai1p, "out", ec1, "f_in" ); // ain -> echo_cancel + //cmDspSysConnectAudio(h, c1.cmp, "out", ec1, "uf_in" ); // kr -> echo_cancel + //cmDspSysConnectAudio(h, ec1, "out", ao1p, "in" ); // ec -> aout 0 + cmDspSysConnectAudio(h, c1.cmp, "out", ao1p, "in" ); // kr -> echo_cancel + cmDspSysConnectAudio(h, c1.cmp, "out", afop, "in1"); + cmDspSysConnectAudio(h, c1.cmp, "out", mo1p, "in" ); // + /* cmDspSysInstallCb( h, clrBtn, "sym", amp, "cmd", NULL ); // clear active meas. cmDspSysInstallCb( h, prtBtn, "sym", amp, "cmd", NULL ); // print active meas + cmDspSysInstallCb( h, prtBtn, "sym", modp,"cmd", NULL ); // print modulator cmDspSysInstallCb( h, amCmd, "add", amp, "cmd", NULL ); // add active meas cmDspSysInstallCb( h, amCmd, "rewind", amp, "cmd", NULL ); // rewind active meas cmDspSysInstallCb( h, mlst, "loc", amp, "loc", NULL ); // recorded meas's list to active meas unit @@ -2193,6 +2229,9 @@ cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ) cmDspSysInstallCb( h, sfp, "vcost",amp, "cst", NULL ); // cmDspSysInstallCb( h, sfp, "vtyp", amp, "type", NULL ); // cmDspSysInstallCb( h, sfp, "vtyp", amCmd, "add", NULL); // + */ + + /* // ***** delete this to prevent the score follower from driving the active-measure unit in 'live' mode cmDspSysInstallCb( h, amRt, "f-out-1",amp, "sfloc", NULL ); @@ -2200,12 +2239,13 @@ cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ) // active measure loc to xfad channel trigger cmDspSysInstallCb( h, amp, "scloc", c0.achan, "trig", NULL ); // See Also: modp.sw ->achan.trig + cmDspSysInstallCb( h, amp, "scloc", c1.achan, "trig", NULL ); // See Also: modp.sw ->achan.trig cmDspSysInstallCb( h, amp, "even", pre, "in", NULL ); // active meas output to printers cmDspSysInstallCb( h, amp, "dyn", prd, "in", NULL ); cmDspSysInstallCb( h, amp, "tempo", prt, "in", NULL ); cmDspSysInstallCb( h, amp, "cost", prc, "in", NULL ); - + */ // 'live' button -> live router selector switch cmDspSysInstallCb(h, liveb, "out", wtRt, "sel", NULL ); @@ -2242,14 +2282,16 @@ cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ) cmDspSysInstallCb(h, pts, "on", wtRt, "s-in", NULL ); cmDspSysInstallCb(h, pts, "on", modp, "cmd", NULL ); - cmDspSysInstallCb(h, pts, "on", modr, "cmd", NULL ); cmDspSysInstallCb(h, onb, "sym", amCmd, "rewind",NULL ); cmDspSysInstallCb(h, onb, "out", c0.achan,"reset", NULL ); + cmDspSysInstallCb(h, onb, "out", c1.achan,"reset", NULL ); + + cmDspSysInstallCb(h, c0.achan, "ch", pra0, "in", NULL ); + cmDspSysInstallCb(h, c1.achan, "ch", pra1, "in", NULL ); // stop connections cmDspSysInstallCb(h, offb, "sym", pts, "off", NULL ); cmDspSysInstallCb(h, pts, "off", modp, "cmd", NULL ); - cmDspSysInstallCb(h, pts, "off", modr, "cmd", NULL ); cmDspSysInstallCb(h, offb, "sym", mop, "reset", NULL ); cmDspSysInstallCb(h, offb, "sym", mo2p, "reset", NULL ); cmDspSysInstallCb(h, pts, "off", rndr, "cmd", NULL ); @@ -2257,7 +2299,6 @@ cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ) // score to score follower - to set initial search location cmDspSysInstallCb(h, bldr, "sel", sfp, "index", NULL ); cmDspSysInstallCb(h, bldr, "sel", modp,"reset", NULL ); - cmDspSysInstallCb(h, bldr, "sel", modr,"reset", NULL ); cmDspSysInstallCb(h, bldr, "sel", prp, "in", NULL ); @@ -2278,8 +2319,8 @@ cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ) cmDspSysInstallCb(h, rndr, "d0", d0Rt, "f-in", NULL ); cmDspSysInstallCb(h, d0Rt, "f-out-1", sfp, "d0", NULL ); - cmDspSysInstallCb(h, d0Rt, "f-out-1", nmp, "d0", NULL ); - cmDspSysInstallCb(h, nmp, "d0", mop, "d0", NULL ); + cmDspSysInstallCb(h, d0Rt, "f-out-1", nmp, "d0", NULL ); + cmDspSysInstallCb(h, nmp, "d0", mop, "d0", NULL ); cmDspSysInstallCb(h, nmp, "d0", mo2p, "d0", NULL ); cmDspSysInstallCb(h, rndr, "status", stRt, "f-in", NULL ); @@ -2295,13 +2336,23 @@ cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ) cmDspSysInstallCb(h, sfp, "recent", prp, "in", NULL ); // report 'recent' but only act on 'max' loc index cmDspSysInstallCb(h, igain0, "val", ai0p, "gain", NULL ); // input gain control + cmDspSysInstallCb(h, igain0, "val", ai1p, "gain", NULL ); // input gain control + /* cmDspSysInstallCb(h, ec_mu, "val", ec0, "mu", NULL ); cmDspSysInstallCb(h, ec_di, "val", ec0, "delayN", NULL ); cmDspSysInstallCb(h, ec_hn, "val", ec0, "irN", NULL ); + cmDspSysInstallCb(h, ec_byp,"out", ec0, "bypass", NULL ); + cmDspSysInstallCb(h, ec_mu, "val", ec1, "mu", NULL ); + cmDspSysInstallCb(h, ec_di, "val", ec1, "delayN", NULL ); + cmDspSysInstallCb(h, ec_hn, "val", ec1, "irN", NULL ); + cmDspSysInstallCb(h, ec_byp,"out", ec1, "bypass", NULL ); + */ + cmDspSysInstallCb(h, ogain0, "val", ao0p, "gain", NULL ); // output gain control cmDspSysInstallCb(h, ogain0, "val", ao1p, "gain", NULL ); return rc; } +//) diff --git a/dsp/cmDspPgmPP.h b/dsp/cmDspPgmPP.h index 409280c..9e015eb 100644 --- a/dsp/cmDspPgmPP.h +++ b/dsp/cmDspPgmPP.h @@ -5,10 +5,14 @@ extern "C" { #endif +//( { file_desc:"'fluxo' 'snap' programs." kw:[sunit fluxo] } + cmDspRC_t _cmDspSysPgm_NoiseTails3( cmDspSysH_t h, void** userPtrPtr ); cmDspRC_t _cmDspSysPgm_ChordDetect( cmDspSysH_t h, void** userPtrPtr ); cmDspRC_t _cmDspSysPgm_CdFx( cmDspSysH_t h, void** userPtrPtr ); cmDspRC_t _cmDspSysPgm_Main( cmDspSysH_t h, void** userPtrPtr ); + +//) #ifdef __cplusplus } diff --git a/dsp/cmDspPreset.h b/dsp/cmDspPreset.h index 0aa863b..cfecd5f 100644 --- a/dsp/cmDspPreset.h +++ b/dsp/cmDspPreset.h @@ -6,6 +6,8 @@ extern "C" { #endif + //( { file_desc:"'snap' unit state store/recall implementation." kw:[snap] } + typedef struct _cmDspPreVar_str { unsigned symId; @@ -73,7 +75,8 @@ extern "C" { cmDspRC_t _cmDspPresetRecallInstance( cmDspPresetMgr_t* p, unsigned instSymId ); cmDspRC_t _cmDspPresetRecallVar( cmDspPresetMgr_t* p, unsigned varSymId, cmDspValue_t* valPtr ); - + //) + #ifdef __cplusplus } #endif diff --git a/dsp/cmDspStore.h b/dsp/cmDspStore.h index 292c047..89fb876 100644 --- a/dsp/cmDspStore.h +++ b/dsp/cmDspStore.h @@ -5,6 +5,7 @@ extern "C" { #endif + //( { file_desc:"'snap' global variable interface used by units for getting and setting global variables." kw:[snap]} extern cmDspStoreH_t cmDspStoreNullHandle; cmDspRC_t cmDspStoreAlloc( cmCtx_t* ctx, cmDspStoreH_t* hp, unsigned initStoreCnt, unsigned growStoreCnt ); @@ -23,6 +24,8 @@ extern "C" { // Returns the 'id' of the variable. unsigned cmDspStoreSetValueViaSym( cmDspStoreH_t h, unsigned symId, const cmDspValue_t* val ); + //) + #ifdef __cplusplus } #endif diff --git a/dsp/cmDspSys.h b/dsp/cmDspSys.h index 4beea2d..8ca79ac 100644 --- a/dsp/cmDspSys.h +++ b/dsp/cmDspSys.h @@ -4,7 +4,8 @@ #ifdef __cplusplus extern "C" { #endif - + //( { file_desc:"Host application interface to the 'snap' data flow system." kw:[snap] } + extern cmDspSysH_t cmDspNullHandle; @@ -274,6 +275,7 @@ extern "C" { cmDspRC_t cmDspRsrcWriteString( cmDspSysH_t h, const cmChar_t* v, ... ); + //) #ifdef __cplusplus } diff --git a/dsp/cmDspValue.h b/dsp/cmDspValue.h index 86e0c1a..dee73fd 100644 --- a/dsp/cmDspValue.h +++ b/dsp/cmDspValue.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"'snap' variable value class." kw:[snap] } + typedef unsigned cmDsvRC_t; enum @@ -330,6 +332,8 @@ extern "C" { void cmDsvPrint( const cmDspValue_t* vp, const cmChar_t* label, cmRpt_t* rpt ); + //) + #define cmDsvCopy( d, s ) (*(d)) = (*(s)) #ifdef __cplusplus diff --git a/vop/cmVectOps.c b/vop/cmVectOps.c index e5d3b12..239efc4 100644 --- a/vop/cmVectOps.c +++ b/vop/cmVectOps.c @@ -26,6 +26,7 @@ #define cmVectOpsRICode_h #include "cmVectOpsTemplateMain.h" +unsigned _cmVOU_Abs( unsigned x ) { return x; } void cmVOU_VPrint( cmRpt_t* rpt, const char* fmt, ... ) { diff --git a/vop/cmVectOps.h b/vop/cmVectOps.h index 2b85053..27efe53 100644 --- a/vop/cmVectOps.h +++ b/vop/cmVectOps.h @@ -103,9 +103,12 @@ cmReal_t cmVOI_Variance(const int* sp, unsigned sn, const cmReal_t* mean); // Complex vector * matrix multiply // dbp[1,dn] = v[1,vn] * m[vn,dn] cmComplexR_t* cmVORC_MultVVM( cmComplexR_t* dbp, unsigned dn, const cmComplexR_t* vp, unsigned vn, const cmComplexR_t* m ); + + unsigned _cmVOU_Abs(unsigned x ); + +#define cmAbs(x) _Generic((x), double:fabs, float:fabsf, unsigned:_cmVOU_Abs, char:abs, int:abs, bool:_cmVOU_Abs )(x) +#define cmIsClose(x0,x1,eps) _Generic((x0), double:cmIsCloseD, float:cmIsCloseF, int:cmIsCloseI, unsigned:cmIsCloseU, default:cmIsCloseD)(x0,x1,eps) -#define cmAbs(x) _Generic((x), double:fabs, float:fabsf, int:abs, unsigned:abs, default:fabs )(x) -#define cmIsClose(x0,x1,eps) _Generic((x0), double:cmIsCloseD, float:cmIsCloseF, int:cmIsCloseI, unsigned:cmIsCloseU, default:cmIsCloseD)(x0,x1,eps) #ifdef __cplusplus } diff --git a/vop/cmVectOpsTemplateCode.h b/vop/cmVectOpsTemplateCode.h index 6fa204c..e8d9f55 100644 --- a/vop/cmVectOpsTemplateCode.h +++ b/vop/cmVectOpsTemplateCode.h @@ -1897,7 +1897,7 @@ unsigned VECT_OP_FUNC(SynthImpulse)( VECT_OP_TYPE* dbp, unsigned dn, unsi unsigned j=dn; while(1) { - double samplesPerCycle = srate / hz; + //double samplesPerCycle = srate / hz; j = round( (srate * i + phase) / hz);