Merge with upstream.
This commit is contained in:
commit
11bf5b63a0
@ -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
|
||||
|
459
app/cmDspPgmJsonToDot.c
Normal file
459
app/cmDspPgmJsonToDot.c
Normal file
@ -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=\"<n> %s",proc->outStr,proc->outStr);
|
||||
|
||||
cmDotPort_t* port = proc->ports;
|
||||
for(; port!=NULL; port=port->link)
|
||||
if( port->connCnt > 0 )
|
||||
cmFilePrintf(fH,"|<p%i> %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; i<n; ++i)
|
||||
{
|
||||
|
||||
if((rp = cmJsonArrayElement(arr,i)) == NULL )
|
||||
{
|
||||
rc = cmErrMsg(&p->err,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; i<n; ++i)
|
||||
{
|
||||
|
||||
if((rp = cmJsonArrayElement(arr,i)) == NULL )
|
||||
{
|
||||
rc = cmErrMsg(&p->err,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;
|
||||
}
|
30
app/cmDspPgmJsonToDot.h
Normal file
30
app/cmDspPgmJsonToDot.h
Normal file
@ -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
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -5,6 +5,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//( { file_desc:"'fluxo' channel calibration and gain normalization program." kw:[fluxo]}
|
||||
|
||||
enum
|
||||
{
|
||||
@ -88,6 +89,7 @@ extern "C" {
|
||||
void cmPuReport( cmPuH_t h, cmRpt_t* rpt );
|
||||
|
||||
void cmPuTest(cmCtx_t* ctx);
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -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" },
|
||||
{ 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, 0, "pgm" },
|
||||
{ kCtlEvtScId, 0, "ctl" },
|
||||
{ kNonEvtScId, 0, "non" },
|
||||
{ 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 "<unknown>";
|
||||
|
||||
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,9 +2433,7 @@ 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;
|
||||
@ -2457,13 +2469,14 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c
|
||||
unsigned d0 = 0;
|
||||
unsigned d1 = 0;
|
||||
unsigned metaId = 0;
|
||||
double dsecs = (double)tmp->dtick / 1000000.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;
|
||||
}
|
||||
|
||||
|
@ -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,6 +275,7 @@ extern "C" {
|
||||
|
||||
void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn );
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -292,6 +293,8 @@ extern "C" {
|
||||
|
||||
cmSdbRC_t cmSdbTest( cmCtx_t* ctx );
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -956,7 +956,7 @@ 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 );
|
||||
@ -964,6 +964,7 @@ cmTsbRC_t cmTakeSeqBldrLoadTake( cmTakeSeqBldrH_t h, unsigned tlMarkUid, bool ov
|
||||
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;
|
||||
|
@ -5,6 +5,7 @@
|
||||
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
|
||||
{
|
||||
@ -123,6 +124,8 @@ extern "C" {
|
||||
|
||||
cmTsbRC_t cmTakeSeqBldrTest( cmCtx_t* ctx );
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -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,6 +649,8 @@ 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
|
||||
@ -658,29 +658,27 @@ cmTlRC_t _cmTlProcMidiFile( _cmTl_t* p, _cmTlObj_t* op, cmMidiFileH_t mfH )
|
||||
{
|
||||
_cmTlObj_t* meop = NULL;
|
||||
const cmMidiTrackMsg_t* mp = mapp[mi];
|
||||
|
||||
int begSmpIdx = mp->dtick;
|
||||
int begSmpIdx = mp->amicro * smpPerMicro;
|
||||
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));
|
||||
|
||||
// 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,6 +1373,8 @@ cmTlRC_t cmTimeLineReadJson( cmTlH_t* hp, const cmChar_t* ifn )
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if( cnp != NULL )
|
||||
{
|
||||
if((jsRC = cmJsonMemberValues(cnp,&errLabelPtr,
|
||||
"wndMs", kRealTId, &p->onsetCfg.wndMs,
|
||||
"hopFact", kIntTId, &p->onsetCfg.hopFact,
|
||||
@ -1395,6 +1396,7 @@ cmTlRC_t cmTimeLineReadJson( cmTlH_t* hp, const cmChar_t* ifn )
|
||||
rc = cmErrMsg(&p->err,kParseFailTlRC,"The JSON 'time_line' onset analyzer cfg. in '%s'.",cmStringNullGuard(ifn));
|
||||
goto errLabel;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<cmJsonChildCount(jnp); ++i)
|
||||
{
|
||||
@ -1478,6 +1480,12 @@ cmTlRC_t cmTimeLineGenOnsetMarks( cmTlH_t h, unsigned seqId )
|
||||
unsigned i,j;
|
||||
unsigned smpIdx;
|
||||
|
||||
if( p->onsetCfg.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 )
|
||||
{
|
||||
|
@ -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
|
||||
|
286
cmApBuf.h
286
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
|
||||
@ -37,198 +36,199 @@
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
21
cmAudDspIF.h
21
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,6 +177,7 @@ extern "C" {
|
||||
|
||||
*/
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,6 +97,7 @@ extern "C" {
|
||||
|
||||
int cmApAggTest( bool runFl, cmCtx_t* ctx, int argc, const char* argv[] );
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -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
|
||||
|
230
cmAudioFile.h
230
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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,6 +59,7 @@ extern "C" {
|
||||
/// Return true if the device is currently started.
|
||||
bool cmApNrtDeviceIsStarted( unsigned devIdx );
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
170
cmAudioPort.h
170
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -60,6 +57,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//(
|
||||
// Audio system result codes
|
||||
enum
|
||||
{
|
||||
@ -296,6 +294,7 @@ extern "C" {
|
||||
// Audio system test and example function.
|
||||
void cmAudioSysTest( cmRpt_t* rpt, int argc, const char* argv[] );
|
||||
|
||||
//)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -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,6 +114,7 @@ extern "C" {
|
||||
|
||||
} cmAudioSysStatus_t;
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,9 +1,15 @@
|
||||
#ifndef cmComplexTypes_h
|
||||
#define cmComplexTypes_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <complex.h>
|
||||
#include <fftw3.h>
|
||||
|
||||
//( { 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
|
||||
|
4
cmCsv.h
4
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
|
||||
|
6
cmCtx.h
6
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,7 +45,6 @@ extern "C" {
|
||||
unsigned mmFlags // Initialization flags used to configure \ref cmMallocDebug.h
|
||||
);
|
||||
//)
|
||||
//}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
4
cmData.h
4
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
|
||||
}
|
||||
|
@ -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,6 +213,7 @@ extern "C" {
|
||||
// Set 'fn' to NULL to use filename from cmDevCfgAlloc()
|
||||
cmDcRC_t cmDevCfgWrite( cmDevCfgH_t h, const cmChar_t* fn );
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
5
cmErr.h
5
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
|
||||
}
|
||||
|
3
cmExec.h
3
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
|
||||
|
@ -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
|
||||
|
282
cmFeatFile.h
282
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
|
||||
}
|
||||
|
15
cmFile.h
15
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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
14
cmGlobal.h
14
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 <stdio.h>
|
||||
@ -150,6 +149,5 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
//)
|
||||
//}
|
||||
|
||||
#endif
|
||||
|
86
cmGnuPlot.h
86
cmGnuPlot.h
@ -1,8 +1,14 @@
|
||||
#ifndef cmGnuPlot_h
|
||||
#define cmGnuPlot_h
|
||||
|
||||
enum
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//( { file_desc:"Interface to GNU Plot." kw:[plot]}
|
||||
|
||||
enum
|
||||
{
|
||||
kOkPlRC,
|
||||
kSignalFailedPlRC,
|
||||
kPipeFailedPlRC,
|
||||
@ -14,10 +20,10 @@ enum
|
||||
kPlotDataFileFailPlRC,
|
||||
kFopenFailedPlRC,
|
||||
kFcloseFailedPlRC
|
||||
};
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
enum
|
||||
{
|
||||
kInvalidPlotPtId = 0x000,
|
||||
kPlusPlotPtId = 0x001,
|
||||
kXPlotPtId = 0x002,
|
||||
@ -33,53 +39,53 @@ enum
|
||||
kDiamondPlotPtId = 0x00c,
|
||||
kFillDiamonPlotPtId = 0x00d,
|
||||
kPlotPtMask = 0x00f,
|
||||
};
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
enum
|
||||
{
|
||||
kInvalidPlotLineId = 0x000, // -2 after translation
|
||||
kSolidPlotLineId = 0x010, // -1 after translation
|
||||
kDashPlotLineId = 0x020, // 0 after translation
|
||||
kPlotLineMask = 0x0f0,
|
||||
kPlotLineShift = 4
|
||||
};
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
enum
|
||||
{
|
||||
kImpulsePlotFl = 0x100
|
||||
};
|
||||
};
|
||||
|
||||
/// Set terminal to NULL to use the default terminal.
|
||||
cmRC_t cmPlotInitialize( const char* terminalStr );
|
||||
/// Set terminal to NULL to use the default terminal.
|
||||
cmRC_t cmPlotInitialize( const char* terminalStr );
|
||||
|
||||
// Combines initializaion and setup in a single call.
|
||||
cmRC_t cmPlotInitialize2( const char* terminalStr, const char* title, unsigned rowCnt, unsigned colCnt );
|
||||
// Combines initializaion and setup in a single call.
|
||||
cmRC_t cmPlotInitialize2( const char* terminalStr, const char* title, unsigned rowCnt, unsigned colCnt );
|
||||
|
||||
cmRC_t cmPlotFinalize();
|
||||
cmRC_t cmPlotFinalize();
|
||||
|
||||
/// Setup the plot page
|
||||
cmRC_t cmPlotSetup( const char* title, unsigned rowCnt, unsigned colCnt );
|
||||
/// Setup the plot page
|
||||
cmRC_t cmPlotSetup( const char* title, unsigned rowCnt, unsigned colCnt );
|
||||
|
||||
/// Select sub-plot to apply subsequent commands to
|
||||
cmRC_t cmPlotSelectSubPlot( unsigned ri, unsigned ci );
|
||||
/// Select sub-plot to apply subsequent commands to
|
||||
cmRC_t cmPlotSelectSubPlot( unsigned ri, unsigned ci );
|
||||
|
||||
/// Clear the current current subplot
|
||||
cmRC_t cmPlotClear();
|
||||
/// Clear the current current subplot
|
||||
cmRC_t cmPlotClear();
|
||||
|
||||
/// Set the labels on the current sub-plot
|
||||
cmRC_t cmPlotSetLabels( const char* title, const char* xLabelStr, const char* yLabelStr, const char* zLabelStr );
|
||||
/// Set the labels on the current sub-plot
|
||||
cmRC_t cmPlotSetLabels( const char* title, const char* xLabelStr, const char* yLabelStr, const char* zLabelStr );
|
||||
|
||||
/// 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 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 );
|
||||
|
||||
/// 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 );
|
||||
/// 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 );
|
||||
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
|
||||
|
2
cmGr.h
2
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
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
//( { file_desc:"Device independent graphics context object used by cmGr." kw:[plot]}
|
||||
|
||||
enum
|
||||
{
|
||||
@ -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
|
||||
|
13
cmGrPage.h
13
cmGrPage.h
@ -5,6 +5,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//( { file_desc:"Device independent plotting window with one or more plot views." kw:[plot]}
|
||||
|
||||
enum
|
||||
{
|
||||
kHashMarkGrFl = 0x10,
|
||||
@ -74,6 +76,10 @@ 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 );
|
||||
@ -136,6 +142,11 @@ extern "C" {
|
||||
// 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
|
||||
void cmGrAxisSetCfg( cmGrAxH_t h, unsigned cfgFlags );
|
||||
@ -161,6 +172,8 @@ extern "C" {
|
||||
// or cmGrPageLabelFuncIndexToId().
|
||||
void cmGrAxisSetLabelFunc( cmGrAxH_t h, unsigned pgLabelFuncId );
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
5
cmJson.h
5
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
|
||||
}
|
||||
|
85
cmKeyboard.h
85
cmKeyboard.h
@ -1,9 +1,14 @@
|
||||
#ifndef cmKeyboard_h
|
||||
#define cmKeyboard_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
//( { file_desc:"Query and get keypresses directly from the console." kw:[system] }
|
||||
|
||||
enum
|
||||
{
|
||||
kInvalidKId,
|
||||
kAsciiKId,
|
||||
kLeftArrowKId,
|
||||
@ -17,50 +22,52 @@ enum
|
||||
kInsertKId,
|
||||
kDeleteKId,
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
unsigned code;
|
||||
char ch;
|
||||
bool ctlFl;
|
||||
bool altFl;
|
||||
} cmKbRecd;
|
||||
} cmKbRecd;
|
||||
|
||||
// Set 'p' to NULL if the value of the key is not required.
|
||||
void cmKeyPress( cmKbRecd* p );
|
||||
// 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();
|
||||
// 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
|
||||
|
5
cmLex.c
5
cmLex.c
@ -238,6 +238,7 @@ unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
||||
{
|
||||
unsigned i = 0;
|
||||
bool signFl = false;
|
||||
unsigned digitCnt = 0;
|
||||
|
||||
for(; i<cn; ++i)
|
||||
{
|
||||
@ -249,6 +250,8 @@ unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
||||
|
||||
if( !isdigit(cp[i]) )
|
||||
break;
|
||||
|
||||
++digitCnt;
|
||||
}
|
||||
|
||||
// BUG BUG BUG
|
||||
@ -262,7 +265,7 @@ unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
||||
// containing a decimal point as reals.
|
||||
|
||||
// if no integer was found
|
||||
if( (signFl && i==0) || i==0 )
|
||||
if( digitCnt==0)
|
||||
return 0;
|
||||
|
||||
|
||||
|
6
cmLex.h
6
cmLex.h
@ -1,11 +1,8 @@
|
||||
#ifndef cmLex_h
|
||||
#define cmLex_h
|
||||
|
||||
//{
|
||||
//(
|
||||
//)
|
||||
|
||||
//(
|
||||
//( { file_desc:"User configurable lexer for tokenizing text files." kw:[text]}
|
||||
|
||||
|
||||
// Predefined Lexer Id's
|
||||
@ -158,6 +155,5 @@ const cmChar_t* cmLexRcToMsg( unsigned rc );
|
||||
void cmLexTest( cmRpt_t* rpt );
|
||||
|
||||
//)
|
||||
//}
|
||||
|
||||
#endif
|
||||
|
4
cmLib.h
4
cmLib.h
@ -5,6 +5,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//( { file_desc:"Manage shared-libraries and query them for known symbols." kw:[system]}
|
||||
|
||||
enum
|
||||
{
|
||||
kOkLibRC = cmOkRC,
|
||||
@ -54,7 +56,7 @@ extern "C" {
|
||||
// Return the libraries file name.
|
||||
const cmChar_t* cmLibName( cmLibH_t h, unsigned libId );
|
||||
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ bool _cmLHeapFree( cmLHeap_t* lhp, void* dataPtr )
|
||||
lbp->nextPtr = (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
|
||||
|
@ -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
|
||||
}
|
||||
|
4
cmMain.c
4
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;
|
||||
}
|
||||
|
||||
//)
|
||||
|
@ -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
|
||||
|
200
cmMath.h
200
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] }
|
||||
|
||||
bool cmIsOddU( unsigned v );
|
||||
bool cmIsEvenU( unsigned v );
|
||||
unsigned cmNextOddU( unsigned v );
|
||||
unsigned cmPrevOddU( unsigned v );
|
||||
unsigned cmNextEvenU( unsigned v );
|
||||
unsigned cmPrevEvenU( unsigned v );
|
||||
double cmX80ToDouble( unsigned char s[10] );
|
||||
void cmDoubleToX80( double v, unsigned char s[10] );
|
||||
|
||||
/// 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 cmIsPowerOfTwo( unsigned i );
|
||||
unsigned cmNextPowerOfTwo( unsigned i );
|
||||
unsigned cmNearPowerOfTwo( unsigned i );
|
||||
|
||||
// modified bessel function of first kind, order 0
|
||||
// ref: orfandis appendix B io.m
|
||||
double cmBessel0( double x );
|
||||
bool cmIsOddU( unsigned v );
|
||||
bool cmIsEvenU( unsigned v );
|
||||
unsigned cmNextOddU( unsigned v );
|
||||
unsigned cmPrevOddU( unsigned v );
|
||||
unsigned cmNextEvenU( unsigned v );
|
||||
unsigned cmPrevEvenU( unsigned v );
|
||||
|
||||
/// 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
|
||||
|
10
cmMem.h
10
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
|
||||
@ -20,12 +18,15 @@
|
||||
// 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().
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
|
4
cmMidi.h
4
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
|
||||
|
223
cmMidiFile.c
223
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; trkIdx<mfp->trkN; ++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; mi<mfp->msgN; ++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; mi<p->msgN; ++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; mi<mfp->msgN; ++mi)
|
||||
{
|
||||
cmMidiTrackMsg_t* mp = mfp->msgV[mi];
|
||||
if( mfp->msgN == 0 )
|
||||
return 0;
|
||||
|
||||
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;
|
||||
return mfp->msgV[ mfp->msgN-1 ]->amicro / 1000000.0;
|
||||
}
|
||||
|
||||
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; mi<p->msgN; ++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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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; mi<p->msgN; ++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; mi<p->msgN; ++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);
|
||||
|
25
cmMidiFile.h
25
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
|
||||
|
@ -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,20 +210,16 @@ 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 )
|
||||
@ -235,13 +228,13 @@ cmMfpRC_t cmMfpClock( cmMfpH_t h, unsigned dusecs )
|
||||
// get the next msg to send
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
@ -5,13 +5,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef cmHandle_t cmMfpH_t;
|
||||
typedef cmRC_t cmMfpRC_t;
|
||||
//( { file_desc:"Device indepenent MIDI file player." kw:[midi]}
|
||||
|
||||
typedef void (*cmMfpCallback_t)( void* userCbPtr, unsigned dmicros, const cmMidiTrackMsg_t* msgPtr );
|
||||
typedef cmHandle_t cmMfpH_t;
|
||||
typedef cmRC_t cmMfpRC_t;
|
||||
|
||||
enum
|
||||
{
|
||||
typedef void (*cmMfpCallback_t)( void* userCbPtr, unsigned dmicros, const cmMidiTrackMsg_t* msgPtr );
|
||||
|
||||
enum
|
||||
{
|
||||
kOkMfpRC = cmOkRC, // 0
|
||||
kInvalidHandleMfpRC, // 1
|
||||
kFileOpenFailMfpRC, // 2
|
||||
@ -21,36 +23,38 @@ enum
|
||||
kEndOfFileMfpRC, // 6
|
||||
kSmpteTickNotImplMfpRC // 7
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
extern cmMfpH_t cmMfpNullHandle;
|
||||
extern cmMfpH_t cmMfpNullHandle;
|
||||
|
||||
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 );
|
||||
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 );
|
||||
|
||||
// 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 );
|
||||
// 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 );
|
||||
|
||||
// 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 );
|
||||
// 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 );
|
||||
|
||||
// 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 );
|
||||
// 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 );
|
||||
|
||||
// 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 );
|
||||
// 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 );
|
||||
cmMfpRC_t cmMfpTest( const char* fn, cmCtx_t* ctx );
|
||||
|
||||
cmRC_t cmMfpTest2( const char* midiFn, const char* audioFn, cmCtx_t* ctx );
|
||||
cmRC_t cmMfpTest2( const char* midiFn, const char* audioFn, cmCtx_t* ctx );
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -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
|
||||
@ -31,6 +33,8 @@ 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,6 +98,7 @@ extern "C" {
|
||||
void cmMpReport( cmRpt_t* rpt );
|
||||
|
||||
void cmMpTest( cmCtx_t* ctx );
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,6 +190,7 @@ extern "C" {
|
||||
|
||||
void cmPrefsTest( cmCtx_t* ctx, const char* ifn, const char* ofn );
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
244
cmProc.h
244
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
|
||||
{
|
||||
@ -746,6 +722,8 @@ extern "C" {
|
||||
cmRC_t cmChordFinal( cmChord* p );
|
||||
|
||||
void cmChordTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
19
cmProc2.c
19
cmProc2.c
@ -5950,6 +5950,7 @@ 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 )
|
||||
{
|
||||
@ -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,6 +6097,7 @@ 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);
|
||||
@ -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; i<binCnt; ++i)
|
||||
{
|
||||
@ -6123,7 +6127,13 @@ void _cmSpecDistBasicMode0(cmSpecDist_t* p, cmReal_t* X1m, unsigned binCnt, cmRe
|
||||
X1m[i] -= 2*d;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
unsigned i=0;
|
||||
for(i=0; i>binCnt; ++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));
|
||||
|
||||
|
||||
|
118
cmProc2.h
118
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;
|
||||
@ -194,8 +210,9 @@ extern "C" {
|
||||
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,8 +411,10 @@ 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
|
||||
{
|
||||
@ -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 );
|
||||
|
||||
//)
|
||||
|
||||
|
||||
|
||||
|
94
cmProc3.h
94
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
|
||||
@ -171,7 +180,10 @@ extern "C" {
|
||||
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;
|
||||
@ -262,7 +277,10 @@ extern "C" {
|
||||
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,6 +733,9 @@ 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 );
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
//)
|
||||
|
||||
|
||||
//=======================================================================================================================
|
||||
/*
|
||||
|
@ -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 )
|
||||
|
39
cmProc4.h
39
cmProc4.h
@ -5,11 +5,12 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//( { file_desc:"Processor Library 4" kw:[proclib]}
|
||||
//)
|
||||
|
||||
|
||||
//( { label:cmEditDist file_desc:"Simplified string alignment function based on Levenshtein edit distance." kw:[proc] }
|
||||
|
||||
//=======================================================================================================================
|
||||
//
|
||||
// Simplified string alignment function based on Levenshtein edit distance.
|
||||
//
|
||||
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: <loc> <mod> <var> <type> <params>
|
||||
<loc> - 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,6 +606,8 @@ 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
|
||||
}
|
||||
|
36
cmProc5.h
36
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,6 +265,7 @@ 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
|
||||
|
@ -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,6 +164,7 @@ extern "C" {
|
||||
#define cmMtxFileRealExecN(f,p,n,s) cmMtxFileDoubleExec((f),(p),(n),(s))
|
||||
#endif
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
3
cmRbm.h
3
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
|
||||
|
2
cmRpt.c
2
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 )
|
||||
|
5
cmRpt.h
5
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
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//( { file_desc:"rtSys networking component." kw:[rtsys network] }
|
||||
|
||||
/*
|
||||
Nodes and Endpoints:
|
||||
---------------------
|
||||
@ -202,6 +204,7 @@ extern "C" {
|
||||
4) The symbol -=- in the flow chart implies a network transmission.
|
||||
|
||||
*/
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
11
cmRtSys.h
11
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
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#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)
|
||||
@ -105,6 +106,7 @@ extern "C" {
|
||||
// char msg[ msgByteCnt ]
|
||||
} cmRtNetMsg_t;
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//( { file_desc:"Push-down stack data structure for binary blobs." kw:[container] }
|
||||
|
||||
enum
|
||||
{
|
||||
kOkStRC = cmOkRC,
|
||||
@ -62,6 +64,7 @@ extern "C" {
|
||||
|
||||
#define cmStackEle(h,t,i) (*(t*)cmStackGet(h,i))
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,6 +354,7 @@ extern "C" {
|
||||
cmTmWorkerRC_t cmTaskMgrWorkerMsgSend( cmTaskMgrFuncArg_t* a, const void* buf, unsigned bufByteCnt );
|
||||
|
||||
cmTmRC_t cmTaskMgrTest(cmCtx_t* ctx);
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
5
cmText.h
5
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
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
#ifndef cmTextTemplate_h
|
||||
#define cmTextTemplate_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
//( { file_desc:"Generate text using templates with replaceable variables." kw:[text] }
|
||||
enum
|
||||
{
|
||||
kOkTtRC = cmOkRC,
|
||||
kFileFailTtRC,
|
||||
kLHeapFailTtRC,
|
||||
@ -11,45 +15,47 @@ enum
|
||||
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 );
|
||||
// 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 );
|
||||
|
||||
// Print an annotated template tree.
|
||||
void cmTtPrintTree( cmTtH_t h, cmRpt_t* rpt );
|
||||
|
||||
|
||||
cmTtRC_t cmTextTemplateTest( cmCtx_t* ctx, const cmChar_t* fn );
|
||||
cmTtRC_t cmTextTemplateTest( cmCtx_t* ctx, const cmChar_t* fn );
|
||||
|
||||
//)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
31
cmThread.h
31
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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user