Merge with upstream.

This commit is contained in:
Kevin Larke 2015-12-09 12:46:33 -05:00
commit 11bf5b63a0
123 changed files with 3414 additions and 2427 deletions

View File

@ -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 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 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 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 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 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 cmSRC += src/libcm/app/cmPickup.c src/libcm/cmRbm.c src/libcm/cmTaskMgr.c src/libcm/cmSyncRecd.c

459
app/cmDspPgmJsonToDot.c Normal file
View 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 = &dot;
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
View 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

View File

@ -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->medFiltFrmCnt = cmMax(3,floor(cfg->medFiltWndMs * p->afInfo.srate / (1000.0 * p->hopSmpCnt)));
p->preDelaySmpCnt= floor(cfg->preDelayMs * p->afInfo.srate / 1000.0); 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,"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,"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); cmRptPrintf(p->err.rpt,"Detection Pre-delay: %8.2f ms %i smp\n",cfg->preDelayMs, p->preDelaySmpCnt);
// initialize the audio file reader // 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."); rc = cmErrMsg(&p->err,kDspProcFailOnRC, "The audio file reader open failed.");
goto errLabel; goto errLabel;

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Musical event onset detector." kw:[audio] }
enum enum
{ {
kOkOnRC = cmOkRC, kOkOnRC = cmOkRC,
@ -65,6 +67,8 @@ extern "C" {
cmOnRC_t cmOnsetTest( cmCtx_t* c ); cmOnRC_t cmOnsetTest( cmCtx_t* c );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -5,6 +5,7 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"'fluxo' channel calibration and gain normalization program." kw:[fluxo]}
enum enum
{ {
@ -88,6 +89,7 @@ extern "C" {
void cmPuReport( cmPuH_t h, cmRpt_t* rpt ); void cmPuReport( cmPuH_t h, cmRpt_t* rpt );
void cmPuTest(cmCtx_t* ctx); void cmPuTest(cmCtx_t* ctx);
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -133,19 +133,19 @@ typedef struct
cmScEvtRef_t _cmScEvtRefArray[] = cmScEvtRef_t _cmScEvtRefArray[] =
{ {
{ kTimeSigEvtScId, 0, "tsg" }, { kTimeSigEvtScId, kTimeSigMdId, "tsg" },
{ kKeySigEvtScId, 0, "ksg" }, { kKeySigEvtScId, kKeySigMdId, "ksg" },
{ kTempoEvtScId, 0, "tmp" }, { kTempoEvtScId, kTempoMdId, "tmp" },
{ kTrackEvtScId, 0, "trk" }, { kTrackEvtScId, kTrkNameMdId, "trk" },
{ kTextEvtScId, 0, "txt" }, { kTextEvtScId, kTextMdId, "txt" },
{ kNameEvtScId, 0, "nam" }, { kNameEvtScId, kInstrNameMdId,"nam" },
{ kEOTrackEvtScId, 0, "eot" }, { kEOTrackEvtScId, kEndOfTrkMdId, "eot" },
{ kCopyEvtScId, 0, "cpy" }, { kCopyEvtScId, kCopyMdId, "cpy" },
{ kBlankEvtScId, 0, "blk" }, { kBlankEvtScId, 0, "blk" },
{ kBarEvtScId, 0, "bar" }, { kBarEvtScId, 0, "bar" },
{ kPgmEvtScId, 0, "pgm" }, { kPgmEvtScId, kPgmMdId, "pgm" },
{ kCtlEvtScId, 0, "ctl" }, { kCtlEvtScId, kCtlMdId, "ctl" },
{ kNonEvtScId, 0, "non" }, { kNonEvtScId, kNoteOnMdId, "non" },
{ kInvalidEvtScId, 0, "***" } { kInvalidEvtScId, 0, "***" }
}; };
@ -196,6 +196,20 @@ const cmChar_t* cmScEvtTypeIdToLabel( unsigned id )
return NULL; 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 ) unsigned _cmScDynLabelToId( const cmChar_t* label )
{ {
cmScEvtRef_t* r = _cmScDynRefArray; cmScEvtRef_t* r = _cmScDynRefArray;
@ -2419,9 +2433,7 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c
goto errLabel; goto errLabel;
} }
// Convert the track message 'dtick' field to delta-microseconds. //printf("secs:%f smps:%f\n",cmMidiFileDurSecs(mfH),cmMidiFileDurSecs(mfH)*96000);
cmMidiFileTickToMicros(mfH);
unsigned msgCnt = cmMidiFileMsgCount(mfH); unsigned msgCnt = cmMidiFileMsgCount(mfH);
unsigned i; unsigned i;
@ -2457,13 +2469,14 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c
unsigned d0 = 0; unsigned d0 = 0;
unsigned d1 = 0; unsigned d1 = 0;
unsigned metaId = 0; unsigned metaId = 0;
double dsecs = (double)tmp->dtick / 1000000.0; double dsecs = (double)tmp->amicro / 1000000.0;
acc_secs += dsecs; acc_secs += dsecs;
if( tmp->status == kMetaStId ) if( tmp->status == kMetaStId )
{ {
opStr = cmMidiMetaStatusToLabel(tmp->metaId); //opStr = cmMidiMetaStatusToLabel(tmp->metaId);
opStr = cmScStatusToOpString(tmp->metaId);
metaId = tmp->metaId; metaId = tmp->metaId;
switch( tmp->metaId ) switch( tmp->metaId )
@ -2474,7 +2487,8 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c
} }
else else
{ {
opStr = cmMidiStatusToLabel(tmp->status); //opStr = cmMidiStatusToLabel(tmp->status);
opStr = cmScStatusToOpString(tmp->status);
if( cmMidiIsChStatus( tmp->status ) ) if( cmMidiIsChStatus( tmp->status ) )
{ {
midiCh = tmp->u.chMsgPtr->ch; midiCh = tmp->u.chMsgPtr->ch;
@ -2647,10 +2661,6 @@ void cmScoreFix( cmCtx_t* ctx )
if( cmMidiFileOpen(mfn,&mfH,ctx) != kOkMfRC ) if( cmMidiFileOpen(mfn,&mfH,ctx) != kOkMfRC )
goto errLabel; goto errLabel;
cmMidiFileTickToMicros(mfH);
cmMidiFileCalcNoteDurations(mfH);
mn = cmMidiFileMsgCount(mfH); mn = cmMidiFileMsgCount(mfH);
msg = cmMidiFileMsgArray(mfH); msg = cmMidiFileMsgArray(mfH);
@ -2680,7 +2690,7 @@ void cmScoreFix( cmCtx_t* ctx )
const cmMidiTrackMsg_t* m = msg[mi]; const cmMidiTrackMsg_t* m = msg[mi];
assert( mi+1 <= id ); assert( mi+1 <= id );
secs += m->dtick/1000000.0; secs += m->amicro/1000000.0;
if( mi+1 != id ) if( mi+1 != id )
{ {
@ -2696,7 +2706,7 @@ void cmScoreFix( cmCtx_t* ctx )
++mi; ++mi;
if( m->status == kNoteOnMdId ) 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; break;
} }

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Object for managing musical score data." kw:[score]}
enum enum
{ {
kOkScRC = cmOkRC, kOkScRC = cmOkRC,
@ -155,7 +157,7 @@ extern "C" {
const cmChar_t* cmScEvtTypeIdToLabel( unsigned id ); const cmChar_t* cmScEvtTypeIdToLabel( unsigned id );
const cmChar_t* cmScDynIdToLabel( 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. // Initialize a score object from a CSV File generated from a score spreadsheet.
// The dynRefArray[dynRefCnt] and cbFunc(cbArg) are optional if these // 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 ); void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Programs for processing cmScore and peformane data." kw:[score seq]}
typedef unsigned cmSpRC_t; typedef unsigned cmSpRC_t;
enum enum
@ -21,6 +23,8 @@ extern "C" {
cmSpRC_t cmScoreProc(cmCtx_t* ctx ); cmSpRC_t cmScoreProc(cmCtx_t* ctx );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -5,7 +5,8 @@
extern "C" { extern "C" {
#endif #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. The CSV file used to initialize a SDB object has the following column syntax.
Column Name Type Description Column Name Type Description
@ -292,6 +293,8 @@ extern "C" {
cmSdbRC_t cmSdbTest( cmCtx_t* ctx ); cmSdbRC_t cmSdbTest( cmCtx_t* ctx );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -956,7 +956,7 @@ cmTsbRC_t cmTakeSeqBldrLoadTake( cmTakeSeqBldrH_t h, unsigned tlMarkUid, bool ov
} }
// convert the dtick field to delta samples // 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) // calculate MIDI note and pedal durations (see cmMidiChMsg_t.durTicks)
cmMidiFileCalcNoteDurations( mfH ); cmMidiFileCalcNoteDurations( mfH );
@ -964,6 +964,7 @@ cmTsbRC_t cmTakeSeqBldrLoadTake( cmTakeSeqBldrH_t h, unsigned tlMarkUid, bool ov
unsigned i = 0; unsigned i = 0;
unsigned n = cmMidiFileMsgCount(mfH); unsigned n = cmMidiFileMsgCount(mfH);
const cmMidiTrackMsg_t** a = cmMidiFileMsgArray(mfH); const cmMidiTrackMsg_t** a = cmMidiFileMsgArray(mfH);
double srate = cmTimeLineSampleRate(p->tlH);
// allocate and link a new take render record // allocate and link a new take render record
cmTakeTsb_t* t = cmMemAllocZ(cmTakeTsb_t,1); 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->scEvtIdx = stm != NULL ? stm->scEvtIdx : cmInvalidIdx;
m1->flags = stm != NULL ? stm->flags : 0; m1->flags = stm != NULL ? stm->flags : 0;
m1->ref = m0; m1->ref = m0;
m1->offsetSmp = mf0 == NULL ? 0 : mf1->dtick; m1->offsetSmp = mf0 == NULL ? 0 : round(mf1->amicro * srate / 1000000.0);
m1->durSmp = mf1->u.chMsgPtr->durTicks; m1->durSmp = mf1->u.chMsgPtr->durMicros * srate / 1000000.0;
m1->d0 = mf1->u.chMsgPtr->d0; m1->d0 = mf1->u.chMsgPtr->d0;
m1->d1 = mf1->u.chMsgPtr->d1; m1->d1 = mf1->u.chMsgPtr->d1;
m1->status = mf1->status; m1->status = mf1->status;

View File

@ -5,6 +5,7 @@
extern "C" { extern "C" {
#endif #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 enum
{ {
@ -123,6 +124,8 @@ extern "C" {
cmTsbRC_t cmTakeSeqBldrTest( cmCtx_t* ctx ); cmTsbRC_t cmTakeSeqBldrTest( cmCtx_t* ctx );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -530,16 +530,14 @@ cmTlRC_t _cmTlAllocRecd2(
tp->flags = 0; tp->flags = 0;
tp->text = NULL; 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->obj = tp;
op->mem = mem; op->mem = mem;
op->memByteCnt = byteCnt; op->memByteCnt = byteCnt;
op->next = NULL; op->next = NULL;
op->prev = 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 ); _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); const cmMidiTrackMsg_t** mapp = cmMidiFileMsgArray(mfH);
unsigned mi = 0; unsigned mi = 0;
_cmTlObj_t* refOp = op; _cmTlObj_t* refOp = op;
double smpPerMicro = p->srate / 1000000.0;
unsigned begSmpIdx0 = 0;
mfp->noteOnCnt = 0; mfp->noteOnCnt = 0;
// for each midi message // for each midi message
@ -658,29 +658,27 @@ cmTlRC_t _cmTlProcMidiFile( _cmTl_t* p, _cmTlObj_t* op, cmMidiFileH_t mfH )
{ {
_cmTlObj_t* meop = NULL; _cmTlObj_t* meop = NULL;
const cmMidiTrackMsg_t* mp = mapp[mi]; const cmMidiTrackMsg_t* mp = mapp[mi];
int begSmpIdx = mp->amicro * smpPerMicro;
int begSmpIdx = mp->dtick;
int durSmpCnt = 0; int durSmpCnt = 0;
unsigned midiTrkMsgByteCnt = cmMidiFilePackTrackMsgBufByteCount( mp ); unsigned midiTrkMsgByteCnt = cmMidiFilePackTrackMsgBufByteCount( mp );
unsigned recdByteCnt = sizeof(cmTlMidiEvt_t) + midiTrkMsgByteCnt; 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 // count the note-on messages
if( cmMidiIsNoteOn(mp->status) ) if( cmMidiIsNoteOn(mp->status) )
{ {
durSmpCnt = mp->u.chMsgPtr->durTicks; durSmpCnt = mp->u.chMsgPtr->durMicros * smpPerMicro;
++mfp->noteOnCnt; ++mfp->noteOnCnt;
} }
if( cmMidiIsCtl(mp->status) && cmMidiIsSustainPedal(mp->status,mp->u.chMsgPtr->d0) ) 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 // 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; goto errLabel;
begSmpIdx0 = begSmpIdx;
assert( meop != NULL ); assert( meop != NULL );
cmTlMidiEvt_t* mep = _cmTimeLineMidiEvtObjPtr(p,meop->obj); 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); unsigned durSmpCnt = floor(cmMidiFileDurSecs(mfH)*p->srate);
// convert the midi file from delta ticks to delta samples // 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 // assign note durations to all note-on msg's
cmMidiFileCalcNoteDurations(mfH); cmMidiFileCalcNoteDurations(mfH);
@ -757,6 +755,7 @@ cmTlRC_t _cmTlAllocMidiFileRecd( _cmTl_t* p, const cmChar_t* nameStr, const cmCh
op->obj->text = mp->fn; op->obj->text = mp->fn;
// insert the events in the midi file as individual time line objects // insert the events in the midi file as individual time line objects
if((rc = _cmTlProcMidiFile(p, op, mfH)) != kOkTlRC ) if((rc = _cmTlProcMidiFile(p, op, mfH)) != kOkTlRC )
goto errLabel; goto errLabel;
@ -1363,7 +1362,7 @@ cmTlRC_t cmTimeLineReadJson( cmTlH_t* hp, const cmChar_t* ifn )
if( cmJsonMemberValues(jnp,&errLabelPtr, if( cmJsonMemberValues(jnp,&errLabelPtr,
"srate",kRealTId,&p->srate, "srate",kRealTId,&p->srate,
"onset",kObjectTId,&cnp, "onset",kObjectTId | kOptArgJsFl,&cnp,
"objArray",kArrayTId,&jnp, "objArray",kArrayTId,&jnp,
NULL) != kOkJsRC ) NULL) != kOkJsRC )
{ {
@ -1374,6 +1373,8 @@ cmTlRC_t cmTimeLineReadJson( cmTlH_t* hp, const cmChar_t* ifn )
goto errLabel; goto errLabel;
} }
if( cnp != NULL )
{
if((jsRC = cmJsonMemberValues(cnp,&errLabelPtr, if((jsRC = cmJsonMemberValues(cnp,&errLabelPtr,
"wndMs", kRealTId, &p->onsetCfg.wndMs, "wndMs", kRealTId, &p->onsetCfg.wndMs,
"hopFact", kIntTId, &p->onsetCfg.hopFact, "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)); rc = cmErrMsg(&p->err,kParseFailTlRC,"The JSON 'time_line' onset analyzer cfg. in '%s'.",cmStringNullGuard(ifn));
goto errLabel; goto errLabel;
} }
}
for(i=0; i<cmJsonChildCount(jnp); ++i) for(i=0; i<cmJsonChildCount(jnp); ++i)
{ {
@ -1478,6 +1480,12 @@ cmTlRC_t cmTimeLineGenOnsetMarks( cmTlH_t h, unsigned seqId )
unsigned i,j; unsigned i,j;
unsigned smpIdx; unsigned smpIdx;
if( p->onsetCfg.wndMs == 0 )
{
rc = cmErrMsg(&p->err,kOnsetFailTlRC,"Audio onset analyzer not-configured.");
goto errLabel;
}
// initialize the audio onset analyzer // initialize the audio onset analyzer
if( cmOnsetInitialize(&p->ctx, &onsH ) != kOkOnRC ) if( cmOnsetInitialize(&p->ctx, &onsH ) != kOkOnRC )
{ {

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #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; typedef cmHandle_t cmTlH_t;
@ -248,6 +250,8 @@ extern "C" {
// callback function. // callback function.
cmTlRC_t cmTimeLineDecode( const void* msg, unsigned msgByteCnt, cmTlUiMsg_t* uiMsg ); cmTlRC_t cmTimeLineDecode( const void* msg, unsigned msgByteCnt, cmTlUiMsg_t* uiMsg );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

286
cmApBuf.h
View File

@ -1,34 +1,33 @@
/// \file cmApBuf.h //( {file_desc: "Thread safe audio buffer class." kw:[rt audio]}
/// \brief Thread-safe audio buffer class. //
/// // This file defines an audio buffer class which handles
/// This file defines an audio buffer class which handles // buffering incoming (recording) and outgoing (playback)
/// buffering incoming (recording) and outgoing (playback) // samples in a thread-safe manner.
/// samples in a thread-safe manner. //
/// // Usage example and testing code:
/// Usage example and testing code: // See cmApBufTest() and cmAudioSysTest().
/// See cmApBufTest() and cmAudioSysTest(). // \snippet cmApBuf.c cmApBufExample
/// \snippet cmApBuf.c cmApBufExample //
/// // Notes on channel flags:
/// Notes on channel flags: // Disabled channels: kChFl is cleared
/// Disabled channels: kChFl is cleared // cmApBufGet()
/// cmApBufGet() // in - return NULL buffer pointers
/// in - return NULL buffer pointers // out - return NULL buffer points
/// out - return NULL buffer points //
/// // cmApBufUpdate()
/// cmApBufUpdate() // in - incoming samples are set to 0.
/// in - incoming samples are set to 0. // out - outgoing samples are set to 0.
/// out - outgoing samples are set to 0. //
/// // Muted channels: kMuteFl is set
/// Muted channels: kMuteFl is set // cmApBufUpdate()
/// cmApBufUpdate() // in - incoming samples are set to 0.
/// in - incoming samples are set to 0. // out - outgoing samples are set to 0.
/// out - outgoing samples are set to 0. //
/// // Tone channels: kToneFl is set
/// Tone channels: kToneFl is set // cmApBufUpdate()
/// cmApBufUpdate() // in - incoming samples are filled with a 1k sine tone
/// in - incoming samples are filled with a 1k sine tone // out - outgoing samples are filled with a 1k sine tone
/// out - outgoing samples are filled with a 1k sine tone //)
///
#ifndef cmApBuf_h #ifndef cmApBuf_h
#define cmApBuf_h #define cmApBuf_h
@ -37,198 +36,199 @@
extern "C" { extern "C" {
#endif #endif
typedef cmRC_t cmAbRC_t; ///< Result code type //(
typedef cmRC_t cmAbRC_t; //< Result code type
enum enum
{ {
kOkAbRC = 0 kOkAbRC = 0
}; };
/// Allocate and initialize an audio buffer. // Allocate and initialize an audio buffer.
/// devCnt - count of devices this buffer will handle. // devCnt - count of devices this buffer will handle.
/// meterMs - length of the meter buffers in milliseconds (automatically limit to the range:10 to 1000) // meterMs - length of the meter buffers in milliseconds (automatically limit to the range:10 to 1000)
cmAbRC_t cmApBufInitialize( unsigned devCnt, unsigned meterMs ); 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(); cmAbRC_t cmApBufFinalize();
/// Configure a buffer for a given device. // Configure a buffer for a given device.
cmAbRC_t cmApBufSetup( cmAbRC_t cmApBufSetup(
unsigned devIdx, ///< device to setup unsigned devIdx, //< device to setup
double srate, ///< device sample rate (only required for synthesizing the correct test-tone frequency) 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 dspFrameCnt, // dspFrameCnt - count of samples in channel buffers returned via cmApBufGet()
unsigned cycleCnt, ///< number of audio port cycles to store unsigned cycleCnt, //< number of audio port cycles to store
unsigned inChCnt, ///< input channel count on this device unsigned inChCnt, //< input channel count on this device
unsigned inFramesPerCycle, ///< maximum number of incoming sample frames on an audio port cycle unsigned inFramesPerCycle, //< maximum number of incoming sample frames on an audio port cycle
unsigned outChCnt, ///< output channel count on this device unsigned outChCnt, //< output channel count on this device
unsigned outFramesPerCycle ///< maximum number of outgoing sample frames in an audio port cycle 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 ); 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 ); void cmApBufOnPortEnable( unsigned devIdx, bool enabelFl );
/// This function is called asynchronously by the audio device driver to transfer incoming samples to the // 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 // 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). // 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 // This function is thread-safe under the condition where the audio device uses
/// different threads for input and output. // different threads for input and output.
/// //
/// Enable Flag: // Enable Flag:
/// Input: If an input channel is disabled then the incoming samples are replaced with zeros. // 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. // Output: If an output channel is disabled then the packet samples are set to zeros.
/// //
/// Tone Flag: // Tone Flag:
/// Input: If the tone flag is set on an input channel then the incoming samples are set to a sine tone. // 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. // 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 // 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. // will be set to zero even if the tone flag is set.
cmAbRC_t cmApBufUpdate( cmAbRC_t cmApBufUpdate(
cmApAudioPacket_t* inPktArray, ///< full audio packets from incoming audio (from ADC) cmApAudioPacket_t* inPktArray, //< full audio packets from incoming audio (from ADC)
unsigned inPktCnt, ///< count of incoming audio packets unsigned inPktCnt, //< count of incoming audio packets
cmApAudioPacket_t* outPktArray, ///< empty audio packet for outgoing audio (to DAC) cmApAudioPacket_t* outPktArray, //< empty audio packet for outgoing audio (to DAC)
unsigned outPktCnt ///< count of outgoing audio packets unsigned outPktCnt //< count of outgoing audio packets
); );
/// Channel flags // Channel flags
enum enum
{ {
kInApFl = 0x01, ///< Identify an input channel kInApFl = 0x01, //< Identify an input channel
kOutApFl = 0x02, ///< Identify an output channel kOutApFl = 0x02, //< Identify an output channel
kEnableApFl = 0x04, ///< Set to enable a channel, Clear to disable. kEnableApFl = 0x04, //< Set to enable a channel, Clear to disable.
kChApFl = 0x08, ///< Used to enable/disable a channel kChApFl = 0x08, //< Used to enable/disable a channel
kMuteApFl = 0x10, ///< Mute this channel kMuteApFl = 0x10, //< Mute this channel
kToneApFl = 0x20, ///< Generate a tone on this channel kToneApFl = 0x20, //< Generate a tone on this channel
kMeterApFl = 0x40, ///< Turn meter's on/off kMeterApFl = 0x40, //< Turn meter's on/off
kPassApFl = 0x80 ///< Pass input channels throught to the output. Must use cmApBufGetIO() to implement this functionality. 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(); unsigned cmApBufMeterMs();
// Set the meter update period. THis function limits the value to between 10 and 1000. // Set the meter update period. THis function limits the value to between 10 and 1000.
void cmApBufSetMeterMs( unsigned meterMs ); void cmApBufSetMeterMs( unsigned meterMs );
/// Returns the channel count set via cmApBufSetup(). // Returns the channel count set via cmApBufSetup().
unsigned cmApBufChannelCount( unsigned devIdx, unsigned flags ); unsigned cmApBufChannelCount( unsigned devIdx, unsigned flags );
/// Set chIdx to -1 to enable all channels on this device. // Set chIdx to -1 to enable all channels on this device.
/// Set flags to {kInApFl | kOutApFl} | {kChApFl | kToneApFl | kMeterFl} | { kEnableApFl=on | 0=off } // Set flags to {kInApFl | kOutApFl} | {kChApFl | kToneApFl | kMeterFl} | { kEnableApFl=on | 0=off }
void cmApBufSetFlag( unsigned devIdx, unsigned chIdx, unsigned flags ); 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 ); 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 ); 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 ); bool cmApBufIsChannelEnabled(unsigned devIdx, unsigned chIdx, unsigned flags );
/// Set the state of the tone generator on the specified channel. // 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 chIdx to -1 to apply the change to all channels on this device.
/// Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off } // Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off }
void cmApBufEnableTone( unsigned devIdx, unsigned chIdx, unsigned flags ); 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 ); bool cmApBufIsToneEnabled(unsigned devIdx, unsigned chIdx, unsigned flags );
/// Mute a specified channel. // Mute a specified channel.
/// Set chIdx to -1 to apply the change to all channels on this device. // Set chIdx to -1 to apply the change to all channels on this device.
/// Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off } // Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off }
void cmApBufEnableMute( unsigned devIdx, unsigned chIdx, unsigned flags ); 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 ); bool cmApBufIsMuteEnabled(unsigned devIdx, unsigned chIdx, unsigned flags );
/// Set the specified channel to pass through. // Set the specified channel to pass through.
/// Set chIdx to -1 to apply the change to all channels on this device. // Set chIdx to -1 to apply the change to all channels on this device.
/// Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off } // Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off }
void cmApBufEnablePass( unsigned devIdx, unsigned chIdx, unsigned flags ); 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 ); bool cmApBufIsPassEnabled(unsigned devIdx, unsigned chIdx, unsigned flags );
/// Turn meter data collection on and off. // Turn meter data collection on and off.
/// Set chIdx to -1 to apply the change to all channels on this device. // Set chIdx to -1 to apply the change to all channels on this device.
/// Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off } // Set flags to {kInApFl | kOutApFl} | { kEnableApFl=on | 0=off }
void cmApBufEnableMeter( unsigned devIdx, unsigned chIdx, unsigned flags ); 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 ); bool cmApBufIsMeterEnabled(unsigned devIdx, unsigned chIdx, unsigned flags );
/// Return the meter value for the requested channel. // Return the meter value for the requested channel.
/// Set flags to kInApFl | kOutApFl. // Set flags to kInApFl | kOutApFl.
cmApSample_t cmApBufMeter(unsigned devIdx, unsigned chIdx, unsigned flags ); 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 ); 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 ); 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. // Get the meter and fault status of the channel input or output channel array of a device.
/// Set 'flags' to { kInApFl | kOutApFl }. // Set 'flags' to { kInApFl | kOutApFl }.
/// The returns value is the count of channels actually written to meterArray. // 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. // 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 ); unsigned cmApBufGetStatus( unsigned devIdx, unsigned flags, double* meterArray, unsigned meterCnt, unsigned* faultCntPtr );
/// Do all enabled input/output channels on this device have samples available? // Do all enabled input/output channels on this device have samples available?
/// 'flags' can be set to either or both kInApFl and kOutApFl // 'flags' can be set to either or both kInApFl and kOutApFl
bool cmApBufIsDeviceReady( unsigned devIdx, unsigned flags ); bool cmApBufIsDeviceReady( unsigned devIdx, unsigned flags );
/// This function is called by the application to get full incoming sample buffers and // This function is called by the application to get full incoming sample buffers and
/// to fill empty outgoing sample buffers. // to fill empty outgoing sample buffers.
/// Upon return each element in bufArray[bufChCnt] holds a pointer to a buffer assoicated // 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. // with an audio channel or to NULL if the channel is disabled.
/// 'flags' can be set to kInApFl or kOutApFl but not both. // 'flags' can be set to kInApFl or kOutApFl but not both.
/// The buffers pointed to by bufArray[] each contain 'dspFrameCnt' samples. Where // The buffers pointed to by bufArray[] each contain 'dspFrameCnt' samples. Where
/// 'dspFrameCnt' was set in the earlier call to cmApBufSetup() for this device. // 'dspFrameCnt' was set in the earlier call to cmApBufSetup() for this device.
/// (see cmApBufInitialize()). // (see cmApBufInitialize()).
/// Note that this function just returns audio information it does not // Note that this function just returns audio information it does not
/// change any cmApBuf() internal states. // change any cmApBuf() internal states.
void cmApBufGet( unsigned devIdx, unsigned flags, cmApSample_t* bufArray[], unsigned bufChCnt ); void cmApBufGet( unsigned devIdx, unsigned flags, cmApSample_t* bufArray[], unsigned bufChCnt );
/// This function replaces calls to cmApBufGet() and implements pass-through and output // This function replaces calls to cmApBufGet() and implements pass-through and output
/// buffer zeroing: // buffer zeroing:
/// //
/// 1) cmApBufGet(in); // 1) cmApBufGet(in);
/// 2) cmApBufGet(out); // 2) cmApBufGet(out);
/// 3) Copy through channels marked for 'pass' and set the associated oBufArray[i] channel to NULL. // 3) Copy through channels marked for 'pass' and set the associated oBufArray[i] channel to NULL.
/// 4) Zero all other enabled output channels. // 4) Zero all other enabled output channels.
/// //
/// Notes: // Notes:
/// 1) The oBufArray[] channels that are disabled or marked for pass-through will // 1) The oBufArray[] channels that are disabled or marked for pass-through will
/// be set to NULL. // be set to NULL.
/// 2) The client is required to use this function to implement pass-through internally. // 2) The client is required to use this function to implement pass-through internally.
/// 3) This function just returns audio information it does not // 3) This function just returns audio information it does not
/// change any cmApBuf() internal states. // change any cmApBuf() internal states.
/// 4) The timestamp pointers are optional. // 4) The timestamp pointers are optional.
void cmApBufGetIO( unsigned iDevIdx, cmApSample_t* iBufArray[], unsigned iBufChCnt, cmTimeSpec_t* iTimeStampPtr, void cmApBufGetIO( unsigned iDevIdx, cmApSample_t* iBufArray[], unsigned iBufChCnt, cmTimeSpec_t* iTimeStampPtr,
unsigned oDevIdx, cmApSample_t* oBufArray[], unsigned oBufChCnt, cmTimeSpec_t* oTimeStampPtr ); unsigned oDevIdx, cmApSample_t* oBufArray[], unsigned oBufChCnt, cmTimeSpec_t* oTimeStampPtr );
/// The application calls this function each time it completes processing of a bufArray[] // 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. // returned from cmApBufGet(). 'flags' can be set to either or both kInApFl and kOutApFl.
/// This function should only be called from the client thread. // This function should only be called from the client thread.
void cmApBufAdvance( unsigned devIdx, unsigned flags ); void cmApBufAdvance( unsigned devIdx, unsigned flags );
/// Copy all available samples incoming samples from an input device to an output device. // 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() // The source code for this example is a good example of how an application should use cmApBufGet()
/// and cmApBufAdvance(). // and cmApBufAdvance().
void cmApBufInputToOutput( unsigned inDevIdx, unsigned outDevIdx ); void cmApBufInputToOutput( unsigned inDevIdx, unsigned outDevIdx );
/// Print the current buffer state. // Print the current buffer state.
void cmApBufReport( cmRpt_t* rpt ); 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 ); void cmApBufTest( cmRpt_t* rpt );
//)
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc: "Dynamic array container class." kw:[container] }
enum enum
{ {
kOkArRC = cmOkRC, kOkArRC = cmOkRC,
@ -55,6 +57,8 @@ enum
// Zero elements i:i+n-1 // Zero elements i:i+n-1
#define cmArrayClrN(t,h,i,n) ((t*)cmArraySet(h,i,NULL,n)) #define cmArrayClrN(t,h,i,n) ((t*)cmArraySet(h,i,NULL,n))
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -30,7 +30,7 @@
#include "dsp/cmDspClass.h" #include "dsp/cmDspClass.h"
#include "dsp/cmDspSys.h" #include "dsp/cmDspSys.h"
#include "cmAudDsp.h" #include "cmAudDsp.h"
#include "cmDspPgmJsonToDot.h"
cmAdH_t cmAdNullHandle = cmSTATIC_NULL_HANDLE; 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 ) if( cmDspSysPrintPgm(p->dsSsArray[i].dsH,fn) != kOkDspRC )
rc = cmErrMsg(&p->err,kDspSysFailAdRC,"The program print failed."); 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; break;
} }

View File

@ -5,8 +5,7 @@
extern "C" { extern "C" {
#endif #endif
// This API supports a serialized interface to an internal instance of //( { file_desc: "Supports a serialized interface to an internal instance of cmAudioSys and cmDspSys." kw:[rt]}
// cmAudioSys and cmDspSys.
enum enum
{ {
@ -50,6 +49,8 @@ extern "C" {
// client program to the aud_dsp system. // client program to the aud_dsp system.
cmAdRC_t cmAudDspReceiveClientMsg( cmAdH_t h, unsigned msgBytecnt, const void* msg ); cmAdRC_t cmAudDspReceiveClientMsg( cmAdH_t h, unsigned msgBytecnt, const void* msg );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,10 +5,24 @@
extern "C" { extern "C" {
#endif #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: // This API has two basic responsibilities:
// //
// 1) Provides a function based interface to the audio DSP system for the // 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 // The client calls these API functions to send commands to the audio DSP
// system. Internally the cmAdIfxxx functions converts the commands to // system. Internally the cmAdIfxxx functions converts the commands to
// raw message packets and passes them to a transmission service // 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). // client provided cmAdIfDispatch_t function (ssInitFunc,statusFunc or uiFunc).
// Note that this entire chain of calls occurs in the client thread // Note that this entire chain of calls occurs in the client thread
// and in the context of the cmAdIfDispatchMsgToHost() procedure. // and in the context of the cmAdIfDispatchMsgToHost() procedure.
//)
//(
enum enum
{ {
kOkAiRC = cmOkRC, kOkAiRC = cmOkRC,
@ -163,6 +177,7 @@ extern "C" {
*/ */
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,6 +5,20 @@
extern "C" { extern "C" {
#endif #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 enum
{ {
kOkAdlRC = cmOkRC, kOkAdlRC = cmOkRC,
@ -32,6 +46,7 @@ extern "C" {
cmAiH_t cmAudDspLocalIF_Handle( cmAdlH_t h ); cmAiH_t cmAudDspLocalIF_Handle( cmAdlH_t h );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Read and write Audacity label files." kw:[audio file] }
enum enum
{ {
kOkAlfRC = cmOkRC, kOkAlfRC = cmOkRC,
@ -43,6 +45,8 @@ enum
void cmAudLabelFileTest( cmCtx_t* ctx ); void cmAudLabelFileTest( cmCtx_t* ctx );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc: "Audio device driver for cmAudioPort which aggregates multiple hardware devices to appear as a single devices." kw:[rt] }
enum enum
{ {
kOkAgRC = cmOkRC, kOkAgRC = cmOkRC,
@ -95,6 +97,7 @@ extern "C" {
int cmApAggTest( bool runFl, cmCtx_t* ctx, int argc, const char* argv[] ); int cmApAggTest( bool runFl, cmCtx_t* ctx, int argc, const char* argv[] );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( {file_desc: "Obsolete audio buffer class. This class is superceded by cmApBuf."}
enum enum
{ {
kOkBaRC = cmOkRC kOkBaRC = cmOkRC
@ -53,7 +55,7 @@ extern "C" {
cmBaRC_t cmAudioBufAdvance( unsigned devIdx, unsigned flags ); cmBaRC_t cmAudioBufAdvance( unsigned devIdx, unsigned flags );
//)
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,13 +1,9 @@
/// \file cmAudioFile.h //( { file_desc: "Read and write AIFF and WAV audio files." kw:[file audio] }
/// \brief Audio file reader/writer class. //
/// // This class supports reading uncompressed AIFF and WAV files and writing uncompressed AIFF files.
/// 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.
/// 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
#ifndef cmAudioFile_h #ifndef cmAudioFile_h
#define cmAudioFile_h #define cmAudioFile_h
@ -16,15 +12,17 @@
extern "C" { extern "C" {
#endif #endif
//(
#ifndef cmAudioFile_MAX_FRAME_READ_CNT #ifndef cmAudioFile_MAX_FRAME_READ_CNT
/// Maximum number of samples which will be read in one call to fread(). // 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 // This value is only significant in that an internal buffer is created on the stack
/// whose size must be limited to prevent stack overflows. // whose size must be limited to prevent stack overflows.
#define cmAudioFile_MAX_FRAME_READ_CNT (8192) #define cmAudioFile_MAX_FRAME_READ_CNT (8192)
#endif #endif
/// Audio file result codes. // Audio file result codes.
enum enum
{ {
kOkAfRC = 0, kOkAfRC = 0,
@ -41,18 +39,18 @@ extern "C" {
kUnknownErrAfRC kUnknownErrAfRC
}; };
/// Informational flags used by audioFileInfo // Informational flags used by audioFileInfo
enum enum
{ {
kAiffAfFl = 0x01, ///< this is an AIFF file kAiffAfFl = 0x01, // this is an AIFF file
kWavAfFl = 0x02, ///< this is a WAV file kWavAfFl = 0x02, // this is a WAV file
kSwapAfFl = 0x04, ///< file header bytes must be swapped kSwapAfFl = 0x04, // file header bytes must be swapped
kAifcAfFl = 0x08, ///< this is an AIFC file kAifcAfFl = 0x08, // this is an AIFC file
kSwapSamplesAfFl = 0x10 ///< file sample bytes must be swapped kSwapSamplesAfFl = 0x10 // file sample bytes must be swapped
}; };
/// Constants // Constants
enum enum
{ {
kAudioFileLabelCharCnt = 256, kAudioFileLabelCharCnt = 256,
@ -64,7 +62,7 @@ extern "C" {
kAfBextOriginTimeN = 8 kAfBextOriginTimeN = 8
}; };
/// Aiff marker record // Aiff marker record
typedef struct typedef struct
{ {
unsigned id; unsigned id;
@ -72,9 +70,9 @@ extern "C" {
char label[kAudioFileLabelCharCnt]; char label[kAudioFileLabelCharCnt];
} cmAudioFileMarker_t; } cmAudioFileMarker_t;
/// Broadcast WAV header record As used by ProTools audio files. See http://en.wikipedia.org/wiki/Broadcast_Wave_Format // 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 // 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. // to the position on the Protools time-line rather than the wall clock time.
typedef struct typedef struct
{ {
char desc[ kAfBextDescN + 1 ]; char desc[ kAfBextDescN + 1 ];
@ -86,102 +84,103 @@ extern "C" {
unsigned timeRefHigh; // sample count since midnight high word unsigned timeRefHigh; // sample count since midnight high word
} cmAudioFileBext_t; } cmAudioFileBext_t;
/// Audio file information record used by audioFileNew and audioFileOpen // Audio file information record used by audioFileNew and audioFileOpen
typedef struct typedef struct
{ {
unsigned bits; ///< bits per sample unsigned bits; // bits per sample
unsigned chCnt; ///< count of audio file channels unsigned chCnt; // count of audio file channels
double srate; ///< audio file sample rate in samples per second double srate; // audio file sample rate in samples per second
unsigned frameCnt; ///< total number of sample frames in the audio file unsigned frameCnt; // total number of sample frames in the audio file
unsigned flags; ///< informational flags unsigned flags; // informational flags
unsigned markerCnt; ///< count of markers in markerArray unsigned markerCnt; // count of markers in markerArray
cmAudioFileMarker_t* markerArray; ///< array of markers cmAudioFileMarker_t* markerArray; // array of markers
cmAudioFileBext_t bextRecd; ///< only used with Broadcast WAV files cmAudioFileBext_t bextRecd; // only used with Broadcast WAV files
} cmAudioFileInfo_t; } cmAudioFileInfo_t;
typedef cmHandle_t cmAudioFileH_t; ///< opaque audio file handle typedef cmHandle_t cmAudioFileH_t; // opaque audio file handle
extern cmAudioFileH_t cmNullAudioFileH; ///< NULL 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. // 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. // 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. // 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. // 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. // 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. // Returns cmAudioFileH_t A new audio file handle.
/// //
cmAudioFileH_t cmAudioFileNewOpen( const cmChar_t* fn, cmAudioFileInfo_t* infoPtr, cmRC_t* rcPtr, cmRpt_t* rpt ); 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 ); 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(). // 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(). // 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. // 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. // 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. // 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 // If the audio file handle 'h' refers to an open file then it is automatically closed prior to being
/// reopened with the new file. // reopened with the new file.
cmRC_t cmAudioFileOpen( cmAudioFileH_t h, const cmChar_t* fn, cmAudioFileInfo_t* infoPtr ); 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 // Open an audio file for writing. The type of the audio file, AIF or WAV
/// is determined by the file name extension. // is determined by the file name extension.
cmRC_t cmAudioFileCreate( cmRC_t cmAudioFileCreate(
cmAudioFileH_t h, ///< Handle returned from an earlier call to cmAudioFileNewCreate() or cmAudioFileNewOpen(). cmAudioFileH_t h, // Handle returned from an earlier call to cmAudioFileNewCreate() or cmAudioFileNewOpen().
const cmChar_t* fn, ///< File name of the new file. const cmChar_t* fn, // File name of the new file.
double srate, ///< Sample rate 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 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. unsigned chCnt // Audio channel count for the new file.
); );
/// Close a the file associated with handle 'h' but do not release the handle. // 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 // If the file was opened for writing (cmAudioFileCreate()) then this function will
/// write the file header prior to closing the file. // write the file header prior to closing the file.
cmRC_t cmAudioFileClose( cmAudioFileH_t* h ); cmRC_t cmAudioFileClose( cmAudioFileH_t* h );
/// Close the file associated with handle 'h' (via an internal call to // Close the file associated with handle 'h' (via an internal call to
/// cmAudioFileClose()) and release the handle and any resources // cmAudioFileClose()) and release the handle and any resources
/// associated with it. This is the complement to cmAudioFileOpen/Create(). // associated with it. This is the complement to cmAudioFileOpen/Create().
cmRC_t cmAudioFileDelete( cmAudioFileH_t* h ); 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 ); bool cmAudioFileIsValid( cmAudioFileH_t h );
/// Return true if the handle is open. // Return true if the handle is open.
bool cmAudioFileIsOpen( cmAudioFileH_t h ); 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 ); 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 ); 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 ); cmRC_t cmAudioFileSeek( cmAudioFileH_t h, unsigned frmIdx );
/// \name Sample Reading Functions. // Sample Reading Functions.
///@{ //
/// Fill a user suppled buffer with up to frmCnt samples. // 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 // 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 // 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 // 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 // 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 // array of pointers of length chCnt. Each channel buffer specified in buf[] must contain at least
/// frmCnt samples. // 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. // h An audio file handle returned from an earlier call to audioFileNew()
/// \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()). // fn The name of the audio file to read.
/// \param frmCnt The number of samples allocated in buf. // 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 chIdx The index of the first channel to read. // frmCnt The number of samples allocated in buf.
/// \param chCnt The count of channels to read. // chIdx The index of the first channel to read.
/// \param buf An array containing chCnt pointers to arrays of frmCnt samples. // chCnt The count of channels to read.
/// \param actualFrmCntPtr The number of frames actually written to the return buffer (ignored if NULL) // 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 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 ); 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 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 ); cmRC_t cmAudioFileGetDouble( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
///@} // Sum the returned samples into the output buffer.
/// \name 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 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 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 ); 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 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 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 ); cmRC_t cmAudioFileGetSumDouble( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
///@}
///@} // Sample Writing Functions
/// \name Sample Writing Functions
///@{
cmRC_t cmAudioFileWriteInt( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, int** bufPtrPtr ); 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 cmAudioFileWriteFloat( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, float** bufPtrPtr );
cmRC_t cmAudioFileWriteDouble( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, double** 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 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 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 ); 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 #if CM_FLOAT_SMP == 1
@ -263,51 +252,44 @@ extern "C" {
#define cmAudioFileWriteFileReal cmAudioFileWriteFileDouble #define cmAudioFileWriteFileReal cmAudioFileWriteFileDouble
#endif #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 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 ); 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 ); 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 ); 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 ); 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* ); 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 ); 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 ); 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 // 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. // signal it simply changes the value of the sample rate in the header.
cmRC_t cmAudioFileSetSrate( const cmChar_t* audioFn, unsigned srate ); cmRC_t cmAudioFileSetSrate( const cmChar_t* audioFn, unsigned srate );
// Generate a sine tone and write it to a file. // 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 ); 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. // Testing and example routine for functions in cmAudioFile.h.
/// Also see cmProcTest.c cmAudioFileReadWriteTest() // Also see cmProcTest.c cmAudioFileReadWriteTest()
void cmAudioFileTest( cmCtx_t* ctx, int argc, const char* argv[] ); void cmAudioFileTest( cmCtx_t* ctx, int argc, const char* argv[] );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,6 +1,11 @@
#ifndef cmAudioFileDev_h #ifndef cmAudioFileDev_h
#define 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 enum
{ {
kOkAfdRC = cmOkRC, kOkAfdRC = cmOkRC,
@ -72,4 +77,10 @@ void cmAudioFileDevReport( cmAfdH_t h, cmRpt_t* rpt );
void cmAudioFileDevTest( cmRpt_t* rpt ); void cmAudioFileDevTest( cmRpt_t* rpt );
//)
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -4,6 +4,9 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Manages a collection of audio files and maintains downsampled copies of their signals." kw:[audio file] }
enum enum
{ {
kOkAfmRC = cmOkRC, kOkAfmRC = cmOkRC,
@ -56,7 +59,7 @@ extern "C" {
bool cmAfmIsValid( cmAfmH_t h ); bool cmAfmIsValid( cmAfmH_t h );
cmAfmFileH_t cmAfmIdToHandle( cmAfmH_t h, unsigned fileId ); cmAfmFileH_t cmAfmIdToHandle( cmAfmH_t h, unsigned fileId );
//)
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #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 cmApNrtAllocate( cmRpt_t* rpt );
cmApRC_t cmApNrtFree(); cmApRC_t cmApNrtFree();
@ -57,6 +59,7 @@ extern "C" {
/// Return true if the device is currently started. /// Return true if the device is currently started.
bool cmApNrtDeviceIsStarted( unsigned devIdx ); bool cmApNrtDeviceIsStarted( unsigned devIdx );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,27 +1,24 @@
/// \file cmAudioPort.h //( { file_desc: "Cross platform audio device interface." kw:[audio rt] }
/// \brief Cross platform audio I/O interface. //
/// // This interface provides data declarations for platform dependent
/// This interface provides data declarations for platform dependent // audio I/O functions. The implementation for the functions are
/// audio I/O functions. The implementation for the functions are // in platform specific modules. See cmAudioPortOsx.c and cmAudioPortAlsa.c.
/// in platform specific modules. See cmAudioPortOsx.c and cmAudioPortAlsa.c. //
/// // ALSA Notes:
/// ALSA Notes: // Assign capture device to line or mic input:
/// 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 Mic // amixer -c 0 cset iface=MIXER,name='Input Source',index=0 Line
/// amixer -c 0 cset iface=MIXER,name='Input Source',index=0 Line //
/// // -c 0 select the first card
/// -c 0 select the first card // -iface=MIXER the cset is targetting the MIXER component
/// -iface=MIXER the cset is targetting the MIXER component // -name='Input Source',index=0 the control to set is the first 'Input Source'
/// -name='Input Source',index=0 the control to set is the first 'Input Source' // Note that the 'Capture' control sets the input gain.
/// Note that the 'Capture' control sets the input gain. //
/// // See alsamixer for a GUI to accomplish the same thing.
/// See alsamixer for a GUI to accomplish the same thing. //
/// //
/// //)
/// Usage example and testing code:
/// See cmApPortTest() and cmAudioSysTest().
/// \snippet cmAudioPort.c cmAudioPortExample
///
#ifndef cmAudioPort_h #ifndef cmAudioPort_h
#define cmAudioPort_h #define cmAudioPort_h
@ -29,8 +26,10 @@
extern "C" { extern "C" {
#endif #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 enum
{ {
@ -45,81 +44,81 @@ extern "C" {
// cmApAudioPacket_t flags // cmApAudioPacket_t flags
enum enum
{ {
kInterleavedApFl = 0x01, ///< The audio samples are interleaved. kInterleavedApFl = 0x01, // The audio samples are interleaved.
kFloatApFl = 0x02 ///< The audio samples are single precision floating point values. kFloatApFl = 0x02 // The audio samples are single precision floating point values.
}; };
/// Audio packet record used by the cmApAudioPacket_t callback. // Audio packet record used by the cmApAudioPacket_t callback.
/// Audio ports send and receive audio using this data structure. // Audio ports send and receive audio using this data structure.
typedef struct typedef struct
{ {
unsigned devIdx; ///< device associated with packet unsigned devIdx; // device associated with packet
unsigned begChIdx; ///< first device channel unsigned begChIdx; // first device channel
unsigned chCnt; ///< count of channels unsigned chCnt; // count of channels
unsigned audioFramesCnt; ///< samples per channel (see note below) unsigned audioFramesCnt; // samples per channel (see note below)
unsigned bitsPerSample; ///< bits per sample word unsigned bitsPerSample; // bits per sample word
unsigned flags; ///< kInterleavedApFl | kFloatApFl unsigned flags; // kInterleavedApFl | kFloatApFl
void* audioBytesPtr; ///< pointer to sample data void* audioBytesPtr; // pointer to sample data
void* userCbPtr; ///< user defined value passed in cmApDeviceSetup() void* userCbPtr; // user defined value passed in cmApDeviceSetup()
cmTimeSpec_t timeStamp; ///< Packet time stamp. cmTimeSpec_t timeStamp; // Packet time stamp.
} cmApAudioPacket_t; } cmApAudioPacket_t;
/// Audio port callback signature. // Audio port callback signature.
/// inPktArray[inPktCnt] are full packets of audio coming from the ADC to the application. // 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 // outPktArray[outPktCnt] are empty packets of audio which will be filled by the application
/// and then sent to the DAC. // and then sent to the DAC.
/// //
/// The value of audioFrameCnt gives the number of samples per channel which are available // 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 // 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. // 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, // It is the responsibility of the calling audio port to notice this change and pass the new,
/// decreased number of samples to the hardware. // 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 // 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 same as the application thread.
/// The usual thread safety precautions should therefore be taken if this function implementation // 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) // 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 // is designed to provide a safe and efficient way to communicate between
/// the audio thread and the application. // the audio thread and the application.
typedef void (*cmApCallbackPtr_t)( cmApAudioPacket_t* inPktArray, unsigned inPktCnt, cmApAudioPacket_t* outPktArray, unsigned outPktCnt ); 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 ); cmApRC_t cmApInitialize( cmRpt_t* rpt );
/// Stop all audio devices and release any resources held // Stop all audio devices and release any resources held
/// by the audio port management object. // by the audio port management object.
cmApRC_t cmApFinalize(); 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(); 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 ); 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 ); 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 ); unsigned cmApDeviceChannelCount( unsigned devIdx, bool inputFl );
/// Get the current sample rate of a device. Note that if the device has 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. // input and output capability then the sample rate is the same for both.
double cmApDeviceSampleRate( unsigned devIdx ); 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 ); unsigned cmApDeviceFramesPerCycle( unsigned devIdx, bool inputFl );
/// Configure a device. // Configure a device.
/// All devices must be setup before they are started. // All devices must be setup before they are started.
/// framesPerCycle is the requested number of samples per audio callback. The // 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 // actual number of samples made from a callback may be smaller. See the note
/// regarding this in cmApAudioPacket_t. // regarding this in cmApAudioPacket_t.
/// If the device cannot support the requested configuration then the function // If the device cannot support the requested configuration then the function
/// will return an error code. // will return an error code.
/// If the device is started when this function is called then it will be // If the device is started when this function is called then it will be
/// automatically stopped and then restarted following the reconfiguration. // automatically stopped and then restarted following the reconfiguration.
/// If the reconfiguration fails then the device may not be restared. // If the reconfiguration fails then the device may not be restared.
cmApRC_t cmApDeviceSetup( cmApRC_t cmApDeviceSetup(
unsigned devIdx, unsigned devIdx,
double srate, double srate,
@ -127,25 +126,26 @@ extern "C" {
cmApCallbackPtr_t callbackPtr, cmApCallbackPtr_t callbackPtr,
void* userCbPtr ); 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 ); cmApRC_t cmApDeviceStart( unsigned devIdx );
/// Stop a device. // Stop a device.
cmApRC_t cmApDeviceStop( unsigned devIdx ); 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 ); 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 ); void cmApReport( cmRpt_t* rpt );
/// Test the audio port by synthesizing a sine signal or passing audio through // 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 // from the input to the output. This is also a good example of how to
/// use all of the functions in the interface. // use all of the functions in the interface.
/// Set runFl to false to print a report without starting any audio devices. // Set runFl to false to print a report without starting any audio devices.
/// See cmAudiotPortTest.c for usage example for this function. // See cmAudiotPortTest.c for usage example for this function.
int cmApPortTest(bool runFl, cmRpt_t* rpt, int argc, const char* argv[] ); int cmApPortTest(bool runFl, cmRpt_t* rpt, int argc, const char* argv[] );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #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 cmApFileAllocate( cmRpt_t* rpt );
cmApRC_t cmApFileFree(); cmApRC_t cmApFileFree();
@ -41,6 +43,8 @@ extern "C" {
void cmApFileReport( cmRpt_t* rpt ); void cmApFileReport( cmRpt_t* rpt );
void cmApFileTest( cmRpt_t* rpt ); void cmApFileTest( cmRpt_t* rpt );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,5 +1,4 @@
// cmAudioSys.h //( { file_desc: "This is the kernel of a real-time audio processing engine." kw:[audio rt] }
// Implements a real-time audio processing engine.
// //
// The audio system is composed a collection of independent sub-systems. // The audio system is composed a collection of independent sub-systems.
// Each sub-system maintains a thread which runs asynchrounsly // 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 // delivered to the DSP procedure at the end of the DSP execution
// procedure. // procedure.
// //
// Usage example and testing code: //)
// See cmAudioSysTest().
// \snippet cmAudioSys.c cmAudioSysTest
#ifndef cmAudioSys_h #ifndef cmAudioSys_h
#define cmAudioSys_h #define cmAudioSys_h
@ -60,6 +57,7 @@
extern "C" { extern "C" {
#endif #endif
//(
// Audio system result codes // Audio system result codes
enum enum
{ {
@ -296,6 +294,7 @@ extern "C" {
// Audio system test and example function. // Audio system test and example function.
void cmAudioSysTest( cmRpt_t* rpt, int argc, const char* argv[] ); void cmAudioSysTest( cmRpt_t* rpt, int argc, const char* argv[] );
//)
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #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) /// Reserved DSP message selector id's (second field of all host<->audio system messages)
enum enum
{ {
@ -112,6 +114,7 @@ extern "C" {
} cmAudioSysStatus_t; } cmAudioSysStatus_t;
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,9 +1,15 @@
#ifndef cmComplexTypes_h #ifndef cmComplexTypes_h
#define cmComplexTypes_h #define cmComplexTypes_h
#ifdef __cplusplus
extern "C" {
#endif
#include <complex.h> #include <complex.h>
#include <fftw3.h> #include <fftw3.h>
//( { file_desc: "Constants and functions used for working with complex values." kw:[base math] }
#if CM_FLOAT_SMP == 1 #if CM_FLOAT_SMP == 1
#define cmCabsS cabsf #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_MultVS( cmComplexR_t* y, cmReal_t v, unsigned n );
void cmVOCR_DivVS( cmComplexR_t* y, cmReal_t v, unsigned n ); void cmVOCR_DivVS( cmComplexR_t* y, cmReal_t v, unsigned n );
//)
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -6,6 +6,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Comma seperated value file reader and writer." kw[file] }
enum enum
{ {
kOkCsvRC = 0, kOkCsvRC = 0,
@ -146,6 +148,8 @@ extern "C" {
cmCsvRC_t cmCsvPrint( cmCsvH_t h, unsigned rowCnt ); cmCsvRC_t cmCsvPrint( cmCsvH_t h, unsigned rowCnt );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -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 // cmCtx_t is used to hold application supplied cmRpt_t, cmErr_t and
// other global values for easy distribution throughtout a cm based application. // 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 unsigned mmFlags // Initialization flags used to configure \ref cmMallocDebug.h
); );
//) //)
//}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -6,6 +6,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Dynamic generic array with user programmable indexing and sorting capablity." kw:[container] }
enum enum
{ {
kOkDlRC = cmOkRC, kOkDlRC = cmOkRC,
@ -86,7 +88,7 @@ extern "C" {
// which this iterator is attached to. // which this iterator is attached to.
const void* cmDListIterFind( cmDListIterH_t iH, const void* key, unsigned keyN, unsigned* recdByteNRef); const void* cmDListIterFind( cmDListIterH_t iH, const void* key, unsigned keyN, unsigned* recdByteNRef);
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -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: // The following two macros must be defined prior to including this code:
// #define cmSFX(a) a##_MySuffix // #define cmSFX(a) a##_MySuffix
// #define cmTYPE My_Type // #define cmTYPE My_Type
@ -117,6 +119,8 @@ const cmTYPE* cmSFX(cmDListIterFind)( cmDListIterH_t iH, const cmTYPE* key
#endif // cmGEN_CODE #endif // cmGEN_CODE
//)
#undef cmSFX #undef cmSFX
#undef cmTYPE #undef cmTYPE

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Generic, introspective, data structure." }
/* /*
TODO: TODO:
0) Figure out an error handling scheme that does not rely on 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 cmDataPrint( const cmData_t* p, cmRpt_t* rpt );
void cmDataTest( cmCtx_t* ctx ); void cmDataTest( cmCtx_t* ctx );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -4,6 +4,9 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"A class for managing persistent device configuration information." kw:[audio hardware] }
/* /*
IMPLEMENTATION: IMPLEMENTATION:
1) A 'cfg' record is a device reference with a 'cfg label'. 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() // Set 'fn' to NULL to use filename from cmDevCfgAlloc()
cmDcRC_t cmDevCfgWrite( cmDevCfgH_t h, const cmChar_t* fn ); cmDcRC_t cmDevCfgWrite( cmDevCfgH_t h, const cmChar_t* fn );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -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. // 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 // 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 ); cmRC_t cmErrClearRC( cmErr_t* err );
//) //)
//}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -6,6 +6,7 @@
extern "C" { extern "C" {
#endif #endif
//( file_desc:"Run a child process via 'execvp()'" kw[system]
enum enum
{ {
kOkExRC, kOkExRC,
@ -22,6 +23,8 @@ extern "C" {
cmExRC_t cmExecV( cmErr_t* err, int* returnValRef, const cmChar_t* pgmFn, va_list vl ); 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, ... ); cmExRC_t cmExec( cmErr_t* err, int* returnValRef, const cmChar_t* pgmFn, ... );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -2106,7 +2106,7 @@ cmFtRC_t cmFtReaderAdvance( cmFtFileH_t h, cmFtFrameDesc_t* fdp )
{ {
if( rc == kOkFtRC ) if( rc == kOkFtRC )
{ {
fdp->smpIdx = frameDescPtr->time.sampleIdx; fdp->smpIdx = frameDescPtr->tm.sampleIdx;
fdp->frmIdx = cmFrameFileFrameLoadedIndex(fp->ffH); fdp->frmIdx = cmFrameFileFrameLoadedIndex(fp->ffH);
} }
else else

View File

@ -1,7 +1,6 @@
/// \file cmFeatFile.h //( { file_desc:" Audio file acoustic feature analyzer and accompanying file reader." kw:[audio analysis file]}
/// \brief Audio file acoustic feature analyzer and accompanying file reader. //
/// //
///
#ifndef cmFeatFile_h #ifndef cmFeatFile_h
#define 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 enum
{ {
kOkFtRC = cmOkRC, kOkFtRC = cmOkRC,
@ -36,241 +35,238 @@ extern "C" {
kInvalidFrmIdxFtRC kInvalidFrmIdxFtRC
}; };
/// Feature Id's // Feature Id's
enum enum
{ {
kInvalidFtId, ///< 0 kInvalidFtId, // 0
kAmplFtId, ///< 1 Fourier transform amplitude kAmplFtId, // 1 Fourier transform amplitude
kDbAmplFtId, ///< 2 Fourier transform decibel kDbAmplFtId, // 2 Fourier transform decibel
kPowFtId, ///< 3 Fourier transform power kPowFtId, // 3 Fourier transform power
kDbPowFtId, ///< 4 Fourier transform power decibel kDbPowFtId, // 4 Fourier transform power decibel
kPhaseFtId, ///< 5 Fourier transform phase (not unwrapped) kPhaseFtId, // 5 Fourier transform phase (not unwrapped)
kBfccFtId, ///< 6 Bark Frequency Cepstral Coeffcients kBfccFtId, // 6 Bark Frequency Cepstral Coeffcients
kMfccFtId, ///< 7 Mel Frequency Cepstral Coefficients kMfccFtId, // 7 Mel Frequency Cepstral Coefficients
kCepsFtId, ///< 8 Cepstral Coefficients kCepsFtId, // 8 Cepstral Coefficients
kConstQFtId, ///< 9 Constant-Q transform kConstQFtId, // 9 Constant-Q transform
kLogConstQFtId, ///< 10 Log Constant-Q transform kLogConstQFtId, // 10 Log Constant-Q transform
kRmsFtId, ///< 11 Root means square of the audio signal kRmsFtId, // 11 Root means square of the audio signal
kDbRmsFtId, ///< 12 RMS in decibels kDbRmsFtId, // 12 RMS in decibels
kD1AmplFtId, ///< 13 1st order difference over time of the Fourier transform amplitude kD1AmplFtId, // 13 1st order difference over time of the Fourier transform amplitude
kD1DbAmplFtId, ///< 14 1st order difference over time of the Fourier transform decibel kD1DbAmplFtId, // 14 1st order difference over time of the Fourier transform decibel
kD1PowFtId, ///< 15 1st order difference over time of the Fourier transform power 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 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) 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 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 kD1MfccFtId, // 19 1st order difference over time of the Mel Frequency Cepstral Coefficients
kD1CepsFtId, ///< 20 1st order difference over time of the 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 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 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 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 kD1DbRmsFtId, // 24 1st order difference over time of the RMS in decibels
}; };
/// User defined feature parameters // User defined feature parameters
typedef struct typedef struct
{ {
unsigned id; ///< feature id unsigned id; // feature id
unsigned cnt; ///< length of feature vector unsigned cnt; // length of feature vector
bool normFl; ///< normalize this feature bool normFl; // normalize this feature
bool enableFl; ///< true if this feature is enabled bool enableFl; // true if this feature is enabled
} cmFtAttr_t; } cmFtAttr_t;
/// Skip input audio range record // Skip input audio range record
typedef struct typedef struct
{ {
unsigned smpIdx; ///< Index of first sample to skip unsigned smpIdx; // Index of first sample to skip
unsigned smpCnt; ///< Count of successive samples to skip. unsigned smpCnt; // Count of successive samples to skip.
} cmFtSkip_t; } cmFtSkip_t;
/// Analysis parameters // Analysis parameters
typedef struct typedef struct
{ {
const char* audioFn; ///< Audio file name. const char* audioFn; // Audio file name.
const char* featFn; ///< Feature file name. const char* featFn; // Feature file name.
unsigned chIdx; ///< Audio file channel index unsigned chIdx; // Audio file channel index
cmReal_t wndMs; ///< Length of the analysis window in milliseconds. cmReal_t wndMs; // Length of the analysis window in milliseconds.
unsigned hopFact; ///< Analysis window overlap factor 1 = 1:1 2=2:1 ... unsigned hopFact; // Analysis window overlap factor 1 = 1:1 2=2:1 ...
bool normAudioFl; ///< Normalize the audio over the length of the audio file 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 constQMinPitch; // Used to determine the base const-q octave.
cmMidiByte_t constQMaxPitch; ///< Used to determine the maximum const-q frequency of interest. cmMidiByte_t constQMaxPitch; // Used to determine the maximum const-q frequency of interest.
unsigned constQBinsPerOctave; ///< Bands per const-q octave. unsigned constQBinsPerOctave; // Bands per const-q octave.
unsigned onsetMedFiltWndSmpCnt; ///< Complex onset median filter unsigned onsetMedFiltWndSmpCnt; // Complex onset median filter
cmReal_t onsetThreshold; ///< Complex onset threshold cmReal_t onsetThreshold; // Complex onset threshold
cmReal_t minDb; ///< Fourier Transform magnitude values below minDb are set to minDb. 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 cmReal_t floorThreshDb; // Frames with an RMS below this value will be skipped
cmFtSkip_t* skipArray; ///< skipArray[skipCnt] user defined sample skip ranges cmFtSkip_t* skipArray; // skipArray[skipCnt] user defined sample skip ranges
unsigned skipCnt; ///< Count of records in skipArray[]. unsigned skipCnt; // Count of records in skipArray[].
cmFtAttr_t* attrArray; ///< attrArray[attrCnt] user defined parameter array cmFtAttr_t* attrArray; // attrArray[attrCnt] user defined parameter array
unsigned attrCnt; ///< Count of records in attrArray[]. unsigned attrCnt; // Count of records in attrArray[].
} cmFtParam_t; } cmFtParam_t;
/// Feature summary information // Feature summary information
typedef struct typedef struct
{ {
unsigned id; ///< feature id (same as associated cmFtAttr.id) unsigned id; // feature id (same as associated cmFtAttr.id)
unsigned cnt; ///< length of each feature vector (same as associated cmFtAttr.cnt) unsigned cnt; // length of each feature vector (same as associated cmFtAttr.cnt)
/// The raw feature summary values are calculated prior to normalization. // 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* 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* 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* 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* 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 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). cmReal_t rawMax; // Max value of all values for this feature. Equivalent to max(rawMaxV).
/// normalized feature summary values // normalized feature summary values
cmReal_t* normMinV; ///< Vector of min value over time for each feature element. 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* 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* 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* 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 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). cmReal_t normMax; // Max value of all values for this feature. Equivalent to max(rawMaxV).
} cmFtSumm_t; } cmFtSumm_t;
/// Feature file info record // Feature file info record
typedef struct typedef struct
{ {
unsigned frmCnt; ///< count of frames in the file unsigned frmCnt; // count of frames in the file
cmReal_t srate; ///< audio sample rate cmReal_t srate; // audio sample rate
unsigned smpCnt; ///< audio sample count unsigned smpCnt; // audio sample count
unsigned fftSmpCnt; ///< FFT window length (always power of 2) unsigned fftSmpCnt; // FFT window length (always power of 2)
unsigned hopSmpCnt; ///< audio sample hop count unsigned hopSmpCnt; // audio sample hop count
unsigned binCnt; ///< FFT bin count (always fftSmpCnt/2 + 1) unsigned binCnt; // FFT bin count (always fftSmpCnt/2 + 1)
unsigned skipFrmCnt; ///< count of frames skipped based on user skip array unsigned skipFrmCnt; // count of frames skipped based on user skip array
unsigned floorFrmCnt; ///< count of frames skipped because below floorThreshDb unsigned floorFrmCnt; // count of frames skipped because below floorThreshDb
cmFtParam_t param; ///< analysis parameter record used to form this feature file cmFtParam_t param; // analysis parameter record used to form this feature file
cmFtSumm_t* summArray; ///< summArray[ param.attrCnt ] feature summary information cmFtSumm_t* summArray; // summArray[ param.attrCnt ] feature summary information
} cmFtInfo_t; } cmFtInfo_t;
/// Data structure returned by cmFtReaderAdvance(). // Data structure returned by cmFtReaderAdvance().
typedef struct typedef struct
{ {
unsigned smpIdx; ///< The audio signal sample index this frames information is based on. 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 frmIdx; // The frame index relative to other frames in this feature file.
} cmFtFrameDesc_t; } cmFtFrameDesc_t;
typedef cmHandle_t cmFtH_t; ///< Analyzer handle typedef cmHandle_t cmFtH_t; // Analyzer handle
typedef cmHandle_t cmFtFileH_t; ///< Feature file handle. typedef cmHandle_t cmFtFileH_t; // Feature file handle.
typedef unsigned cmFtRC_t; ///< Result code type used by all functions in cmFeatFile.h. 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 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 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 ); 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 ); 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 // Initialize the feature analyzer. The memory manager and file system must
/// be initialized (cmMdInitialize(), cmFsInitialize()) prior to calling this function. // be initialized (cmMdInitialize(), cmFsInitialize()) prior to calling this function.
cmFtRC_t cmFtInitialize( cmFtH_t* hp, cmCtx_t* ctx ); cmFtRC_t cmFtInitialize( cmFtH_t* hp, cmCtx_t* ctx );
/// Finalize a feature analyzer. // Finalize a feature analyzer.
cmFtRC_t cmFtFinalize( cmFtH_t* h ); 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 ); 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 ); cmFtRC_t cmFtParse( cmFtH_t h, const char* cfgFn );
/// Run the analyzer. // Run the analyzer.
cmFtRC_t cmFtAnalyze( cmFtH_t h ); cmFtRC_t cmFtAnalyze( cmFtH_t h );
/// If cmFtAnalyze() is being run in a seperate thread this function // If cmFtAnalyze() is being run in a seperate thread this function
/// can be used to access the analyzers progress. // can be used to access the analyzers progress.
const char* cmFtAnalyzeProgress( cmFtH_t h, unsigned* passPtr, cmReal_t* percentPtr ); const char* cmFtAnalyzeProgress( cmFtH_t h, unsigned* passPtr, cmReal_t* percentPtr );
///@}
/// \name Feature File Related Functions // Feature File Related Functions
///@{
/// Open a feature file. // Open a feature file.
/// Note that inforPtrPtr is optional and will be ignored if it is set to NULL. // 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 ); 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 ); 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 ); 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 ); 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 ); unsigned cmFtReaderFeatId( cmFtFileH_t h, unsigned index );
/// Reset the current file location to the first frame but do not load it. // Reset the current file location to the first frame but do not load it.
/// The next call to cmFtReadAdvance() will load the next frame. // The next call to cmFtReadAdvance() will load the next frame.
cmFtRC_t cmFtReaderRewind( cmFtFileH_t h ); 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 ); cmFtRC_t cmFtReaderSeek( cmFtFileH_t h, unsigned frmIdx );
/// Load the current frame, advance the current file position, and return // Load the current frame, advance the current file position, and return
/// a pointer to a cmFtFrameDesc_t record for the loaded frame. // a pointer to a cmFtFrameDesc_t record for the loaded frame.
/// Returns kEofFtRC upon reaching end of file. // Returns kEofFtRC upon reaching end of file.
/// The frameDescPtr is optional. // The frameDescPtr is optional.
cmFtRC_t cmFtReaderAdvance( cmFtFileH_t h, cmFtFrameDesc_t* frameDescPtr ); 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 ); 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 ); 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 typedef struct
{ {
unsigned featId; ///< Feature id of feature to include in the feature vector 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. 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 // returned with actual count used
unsigned id0; ///< 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() unsigned id1; // Ignored on input. Used internally by cmFtReaderXXX()
} cmFtMulti_t; } cmFtMulti_t;
/// Setup an array of cmFtMulti_t records. The cmFtMulti_t array // Setup an array of cmFtMulti_t records. The cmFtMulti_t array
/// used by cmFtReaderMulitData() must be initialized by this function. // used by cmFtReaderMulitData() must be initialized by this function.
cmFtRC_t cmFtReaderMultiSetup( cmFtFileH_t h, cmFtMulti_t* multiArray, unsigned multiCnt, unsigned* featVectEleCntPtr ); 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. // 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. // 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 ); 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 ); 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 ); 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 ); cmFtRC_t cmFtReaderReportFeature( cmFtFileH_t h, unsigned featId, unsigned frmIdx, unsigned frmCnt );
/// Write a feature into a binary file. // Write a feature into a binary file.
/// Set 'frmCnt' to the cmInvalidCnt to include all frames past frmIdx. // Set 'frmCnt' to the cmInvalidCnt to include all frames past frmIdx.
/// The first three unsigned values in the output file // 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). // 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. // 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 ); 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 ); cmFtRC_t cmFtReaderToBinaryFn( cmFtH_t h, const cmChar_t* fn, unsigned featId, unsigned frmIdx, unsigned frmCnt, const cmChar_t* outFn );
///@} //)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,3 +1,4 @@
#include "cmPrefix.h" #include "cmPrefix.h"
#include "cmGlobal.h" #include "cmGlobal.h"
#include "cmRpt.h" #include "cmRpt.h"

View File

@ -1,9 +1,3 @@
//{
//(
// File abstraction class which slightly extends the C standard file handling routines
// to cm style error handling.
//)
//
#ifndef cmFile_h #ifndef cmFile_h
#define cmFile_h #define cmFile_h
@ -11,7 +5,13 @@
extern "C" { extern "C" {
#endif #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 enum
{ {
kOkFileRC = cmOkRC, kOkFileRC = cmOkRC,
@ -244,7 +244,6 @@ extern "C" {
cmFileRC_t cmFileSetRC( cmFileH_t h, cmFileRC_t rc ); cmFileRC_t cmFileSetRC( cmFileH_t h, cmFileRC_t rc );
//) //)
//}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,6 +1,5 @@
//{
//( //( { file_desc:"A collection of file system utility functions." kw:[system file]}
// A collection of file system utility functions.
// //
// Note that cmFileSysInitialize() creates an internal cmLHeapH_t based // Note that cmFileSysInitialize() creates an internal cmLHeapH_t based
// heap manager from which it allocates memory for some returned objects. // heap manager from which it allocates memory for some returned objects.
@ -242,7 +241,6 @@ extern "C" {
cmFsRC_t cmFileSysTest( cmCtx_t* ctx ); cmFsRC_t cmFileSysTest( cmCtx_t* ctx );
//) //)
//}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -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 #ifndef cmFloatTypes_h
#define cmFloatTypes_h #define cmFloatTypes_h
@ -19,6 +6,18 @@
extern "C" { extern "C" {
#endif #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 #ifndef CM_FLOAT_SMP
#define CM_FLOAT_SMP 1 #define CM_FLOAT_SMP 1
@ -26,27 +25,27 @@ extern "C" {
#if CM_FLOAT_SMP == 1 #if CM_FLOAT_SMP == 1
typedef float cmSample_t; ///< cmSample_t is a float typedef float cmSample_t; // cmSample_t is a float
typedef float _Complex cmComplexS_t;///< cmComplexS_t is single precision. 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_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_MAX FLT_MAX // Maximum representable number (1E+37).
#define cmSample_MIN FLT_MIN ///< Minimum representable number (1E-37). #define cmSample_MIN FLT_MIN // Minimum representable number (1E-37).
#else #else
typedef double cmSample_t; ///< cmSample_t is a double typedef double cmSample_t; // cmSample_t is a double
typedef double _Complex cmComplexS_t; ///< cmComplexS_t is doulbe precision. 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_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_MAX DBL_MAX // Maximum representable number (1E+37).
#define cmSample_MIN DBL_MIN ///< Minimum representable number (1E-37). #define cmSample_MIN DBL_MIN // Minimum representable number (1E-37).
#endif #endif
//----------------------------------------------------------------- //-----------------------------------------------------------------
//----------------------------------------------------------------- //-----------------------------------------------------------------
//----------------------------------------------------------------- //-----------------------------------------------------------------
#ifndef CM_FLOAT_REAL #ifndef CM_FLOAT_REAL
#define CM_FLOAT_REAL 0 #define CM_FLOAT_REAL 0
@ -54,25 +53,27 @@ extern "C" {
#if CM_FLOAT_REAL == 1 #if CM_FLOAT_REAL == 1
typedef float cmReal_t; ///< cmReal_t is a float typedef float cmReal_t; // cmReal_t is a float
typedef float _Complex cmComplexR_t; ///< cmComplexR_t is single precision. 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_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_MAX FLT_MAX // Maximum representable number (1E+37).
#define cmReal_MIN FLT_MIN ///< Minimum representable number (1E-37). #define cmReal_MIN FLT_MIN // Minimum representable number (1E-37).
#else #else
typedef double cmReal_t; ///< cmReal_t is a double. typedef double cmReal_t; // cmReal_t is a double.
typedef double _Complex cmComplexR_t; ///< cmComplexR_t is double precision. 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_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_MAX DBL_MAX // Maximum representable number (1E+37).
#define cmReal_MIN DBL_MIN ///< Minimum representable number (1E-37). #define cmReal_MIN DBL_MIN // Minimum representable number (1E-37).
#endif #endif
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1031,7 +1031,7 @@ cmFfRC_t cmFrameFileFrameCreate( cmFrameFileH_t h, unsigned frameType, unsigned
p->frame.f.mtxCnt = 0; p->frame.f.mtxCnt = 0;
p->frame.f.streamId = streamId; p->frame.f.streamId = streamId;
p->frame.f.flags = flags; p->frame.f.flags = flags;
p->frame.f.time.seconds = 0; p->frame.f.tm.seconds = 0;
return rc; return rc;
} }
@ -1327,10 +1327,10 @@ cmFfRC_t cmFrameFileFrameNext( cmFrameFileH_t h, unsigned keyFrameTypeId, unsign
return rc; return rc;
if( cmIsFlag(p->frame.f.flags,kSampleIdxTimeFl) ) 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) ) if( cmIsFlag(p->frame.f.flags,kSecondsTimeFl) )
p->frame.f.time.seconds = seconds; p->frame.f.tm.seconds = seconds;
return rc; return rc;

View File

@ -1,16 +1,17 @@
#ifndef cmFrameFile_h #ifndef cmFrameFile_h
#define cmFrameFile_h #define cmFrameFile_h
/*
file -> cmFfFile_t frame*
frame -> cmFfFrame_t mtx*
mtx -> cmFfMtx_t data*
*/
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 enum
{ {
@ -139,7 +140,7 @@ extern "C" {
{ {
unsigned sampleIdx; unsigned sampleIdx;
double seconds; double seconds;
} time; } tm;
} cmFfFrame_t; } cmFfFrame_t;
@ -353,6 +354,8 @@ extern "C" {
#define kRealFmtId kDoubleFmtId #define kRealFmtId kDoubleFmtId
#endif #endif
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,15 +1,14 @@
//{
//(
// cmGlobal.h contains the global macros, header files, and #ifndef cmGlobal_h
// typedefs availale to all other cm modules. #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 // All operating system dependencies should be resolved in this file via
// testing for OS_LINUX, OS_OSX, or OS_W32. // testing for OS_LINUX, OS_OSX, or OS_W32.
//) //)
#ifndef cmGlobal_h
#define cmGlobal_h
//( //(
#include "config.h" // created by 'configure' #include "config.h" // created by 'configure'
#include <stdio.h> #include <stdio.h>
@ -150,6 +149,5 @@ extern "C" {
#endif #endif
//) //)
//}
#endif #endif

View File

@ -1,8 +1,14 @@
#ifndef cmGnuPlot_h #ifndef cmGnuPlot_h
#define cmGnuPlot_h #define cmGnuPlot_h
enum #ifdef __cplusplus
{ extern "C" {
#endif
//( { file_desc:"Interface to GNU Plot." kw:[plot]}
enum
{
kOkPlRC, kOkPlRC,
kSignalFailedPlRC, kSignalFailedPlRC,
kPipeFailedPlRC, kPipeFailedPlRC,
@ -14,10 +20,10 @@ enum
kPlotDataFileFailPlRC, kPlotDataFileFailPlRC,
kFopenFailedPlRC, kFopenFailedPlRC,
kFcloseFailedPlRC kFcloseFailedPlRC
}; };
enum enum
{ {
kInvalidPlotPtId = 0x000, kInvalidPlotPtId = 0x000,
kPlusPlotPtId = 0x001, kPlusPlotPtId = 0x001,
kXPlotPtId = 0x002, kXPlotPtId = 0x002,
@ -33,53 +39,53 @@ enum
kDiamondPlotPtId = 0x00c, kDiamondPlotPtId = 0x00c,
kFillDiamonPlotPtId = 0x00d, kFillDiamonPlotPtId = 0x00d,
kPlotPtMask = 0x00f, kPlotPtMask = 0x00f,
}; };
enum enum
{ {
kInvalidPlotLineId = 0x000, // -2 after translation kInvalidPlotLineId = 0x000, // -2 after translation
kSolidPlotLineId = 0x010, // -1 after translation kSolidPlotLineId = 0x010, // -1 after translation
kDashPlotLineId = 0x020, // 0 after translation kDashPlotLineId = 0x020, // 0 after translation
kPlotLineMask = 0x0f0, kPlotLineMask = 0x0f0,
kPlotLineShift = 4 kPlotLineShift = 4
}; };
enum enum
{ {
kImpulsePlotFl = 0x100 kImpulsePlotFl = 0x100
}; };
/// Set terminal to NULL to use the default terminal. /// Set terminal to NULL to use the default terminal.
cmRC_t cmPlotInitialize( const char* terminalStr ); cmRC_t cmPlotInitialize( const char* terminalStr );
// Combines initializaion and setup in a single call. // Combines initializaion and setup in a single call.
cmRC_t cmPlotInitialize2( const char* terminalStr, const char* title, unsigned rowCnt, unsigned colCnt ); cmRC_t cmPlotInitialize2( const char* terminalStr, const char* title, unsigned rowCnt, unsigned colCnt );
cmRC_t cmPlotFinalize(); cmRC_t cmPlotFinalize();
/// Setup the plot page /// Setup the plot page
cmRC_t cmPlotSetup( const char* title, unsigned rowCnt, unsigned colCnt ); cmRC_t cmPlotSetup( const char* title, unsigned rowCnt, unsigned colCnt );
/// Select sub-plot to apply subsequent commands to /// Select sub-plot to apply subsequent commands to
cmRC_t cmPlotSelectSubPlot( unsigned ri, unsigned ci ); cmRC_t cmPlotSelectSubPlot( unsigned ri, unsigned ci );
/// Clear the current current subplot /// Clear the current current subplot
cmRC_t cmPlotClear(); cmRC_t cmPlotClear();
/// Set the labels on the current sub-plot /// Set the labels on the current sub-plot
cmRC_t cmPlotSetLabels( const char* title, const char* xLabelStr, const char* yLabelStr, const char* zLabelStr ); 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. /// 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. /// The range values are used to form data sets when data is not explicitely given.
cmRC_t cmPlotSetRange( double xMin, double xMax, double yMin, double yMax, double zMin, double zMax ); cmRC_t 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. /// 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 /// 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 /// 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 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 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 #if CM_FLOAT_SMP == 1
@ -95,8 +101,14 @@ cmRC_t cmPlotLineMD( const double* x, const double* y, const double* z, unsigned
#endif #endif
cmRC_t cmPlotDraw(); cmRC_t cmPlotDraw();
cmRC_t cmPlotPrint( bool printDataFl ); cmRC_t cmPlotPrint( bool printDataFl );
cmRC_t cmPlotDrawAndPrint( bool printDataFl ); cmRC_t cmPlotDrawAndPrint( bool printDataFl );
//)
#ifdef __cplusplus
}
#endif
#endif #endif

2
cmGr.h
View File

@ -5,6 +5,7 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Low level device independent API for descibing interactive graphics objects." kw:[plot] }
enum enum
{ {
kAliceBlueGrId = 0xf0f8ff, kAliceBlueGrId = 0xf0f8ff,
@ -867,6 +868,7 @@ extern "C" {
void cmGrReport( cmGrH_t h, cmRpt_t* rpt ); void cmGrReport( cmGrH_t h, cmRpt_t* rpt );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -4,6 +4,7 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Device independent graphics context object used by cmGr." kw:[plot]}
enum enum
{ {
@ -195,6 +196,8 @@ extern "C" {
// Is any of the rectangle visible in this drawing context. // Is any of the rectangle visible in this drawing context.
bool cmGrDcRectIsVisible( cmGrDcH_t h, const cmGrPExt_t* r ); bool cmGrDcRectIsVisible( cmGrDcH_t h, const cmGrPExt_t* r );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Device independent plotting window with one or more plot views." kw:[plot]}
enum enum
{ {
kHashMarkGrFl = 0x10, kHashMarkGrFl = 0x10,
@ -74,6 +76,10 @@ extern "C" {
const cmChar_t* cmGrPageLabelFuncLabel( cmGrPgH_t h, unsigned id ); const cmChar_t* cmGrPageLabelFuncLabel( cmGrPgH_t h, unsigned id );
void* cmGrPageLabelFuncArg( 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. // Get a view handle from the view index.
cmGrVwH_t cmGrPageViewHandle( cmGrPgH_t h, unsigned vwIdx ); cmGrVwH_t cmGrPageViewHandle( cmGrPgH_t h, unsigned vwIdx );
@ -136,6 +142,11 @@ extern "C" {
// Get an axis handle. // Get an axis handle.
cmGrAxH_t cmGrViewAxisHandle( cmGrVwH_t h, cmGrAxisIdx_t axisIdx ); cmGrAxH_t cmGrViewAxisHandle( cmGrVwH_t h, cmGrAxisIdx_t axisIdx );
//----------------------------------------------------------------------------
//)
//( { label:cmGrAxis file_desc:"Device independent plotting axis." kw:[plot]}
//
bool cmGrAxisIsValid( cmGrAxH_t h ); bool cmGrAxisIsValid( cmGrAxH_t h );
// kHashMarkGrFl | kHashLabelGrFl // kHashMarkGrFl | kHashLabelGrFl
void cmGrAxisSetCfg( cmGrAxH_t h, unsigned cfgFlags ); void cmGrAxisSetCfg( cmGrAxH_t h, unsigned cfgFlags );
@ -161,6 +172,8 @@ extern "C" {
// or cmGrPageLabelFuncIndexToId(). // or cmGrPageLabelFuncIndexToId().
void cmGrAxisSetLabelFunc( cmGrAxH_t h, unsigned pgLabelFuncId ); void cmGrAxisSetLabelFunc( cmGrAxH_t h, unsigned pgLabelFuncId );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Device indenpendent, multi-axis, interactive, plotting system based on cmGrPage, cmGrAxis and cmGr." kw:[plot]}
enum enum
{ {
kOkGrPlRC, kOkGrPlRC,
@ -229,6 +231,7 @@ extern "C" {
// Set the default object callback and arg. // Set the default object callback and arg.
void cmGrPlotSetCb( cmGrPlH_t h, cmGrPlotCbFunc_t func, void* arg ); void cmGrPlotSetCb( cmGrPlH_t h, cmGrPlotCbFunc_t func, void* arg );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -6,12 +6,15 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Override a cmGrPlotObj to make an efficient audio plot object." kw:[plot audio]}
cmGrPlRC_t cmGrPlotAudioFileObjCreate( cmGrPlRC_t cmGrPlotAudioFileObjCreate(
cmGrPlObjH_t oH, cmGrPlObjH_t oH,
cmAfmFileH_t afH, cmAfmFileH_t afH,
unsigned audioChIdx ); unsigned audioChIdx );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Hash table for storing arbitary data blobs." kw:[container]}
enum enum
{ {
kOkHtRC, kOkHtRC,
@ -60,6 +62,8 @@ extern "C" {
cmHtRC_t cmHashTblTest( cmCtx_t* ctx ); cmHtRC_t cmHashTblTest( cmCtx_t* ctx );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -5,8 +5,8 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
//{
//( //( { file_desc: "JSON reader and writer" kw:[file] }
// //
// Limitations: // Limitations:
// //
@ -501,7 +501,6 @@ extern "C" {
cmJsRC_t cmJsonTest( const char* fn, cmCtx_t* ctx ); cmJsRC_t cmJsonTest( const char* fn, cmCtx_t* ctx );
//) //)
//}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,9 +1,14 @@
#ifndef cmKeyboard_h #ifndef cmKeyboard_h
#define 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, kInvalidKId,
kAsciiKId, kAsciiKId,
kLeftArrowKId, kLeftArrowKId,
@ -17,50 +22,52 @@ enum
kInsertKId, kInsertKId,
kDeleteKId, kDeleteKId,
}; };
typedef struct
{
typedef struct
{
unsigned code; unsigned code;
char ch; char ch;
bool ctlFl; bool ctlFl;
bool altFl; bool altFl;
} cmKbRecd; } cmKbRecd;
// Set 'p' to NULL if the value of the key is not required. // Set 'p' to NULL if the value of the key is not required.
void cmKeyPress( cmKbRecd* p ); void cmKeyPress( cmKbRecd* p );
// Return non-zero if a key is waiting to be read otherwise return 0. // Return non-zero if a key is waiting to be read otherwise return 0.
// Use getchar() to pick up the key. // Use getchar() to pick up the key.
// //
// Example: // Example:
// while( 1 ) // while( 1 )
// { // {
// if( cmIsKeyWaiting() == 0 ) // if( cmIsKeyWaiting() == 0 )
// usleep(20000); // usleep(20000);
// else // else
// { // {
// char c = getchar(); // char c = getchar();
// switch(c) // switch(c)
// { // {
// .... // ....
// } // }
// } // }
// //
// } // }
// //
// TODO: Note that this function turns off line-buffering on stdin. // TODO: Note that this function turns off line-buffering on stdin.
// It should be changed to a three function sequence. // It should be changed to a three function sequence.
// bool org_state = cmSetStdinLineBuffering(false); // bool org_state = cmSetStdinLineBuffering(false);
// .... // ....
// cmIsKeyWaiting() // cmIsKeyWaiting()
// .... // ....
// cmSetStdinLineBuffering(org_state) // cmSetStdinLineBuffering(org_state)
int cmIsKeyWaiting(); int cmIsKeyWaiting();
//)
#ifdef __cplusplus
extern "C" {
#endif
#endif #endif

View File

@ -238,6 +238,7 @@ unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
{ {
unsigned i = 0; unsigned i = 0;
bool signFl = false; bool signFl = false;
unsigned digitCnt = 0;
for(; i<cn; ++i) for(; i<cn; ++i)
{ {
@ -249,6 +250,8 @@ unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
if( !isdigit(cp[i]) ) if( !isdigit(cp[i]) )
break; break;
++digitCnt;
} }
// BUG BUG BUG // 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. // containing a decimal point as reals.
// if no integer was found // if no integer was found
if( (signFl && i==0) || i==0 ) if( digitCnt==0)
return 0; return 0;

View File

@ -1,11 +1,8 @@
#ifndef cmLex_h #ifndef cmLex_h
#define cmLex_h #define cmLex_h
//{
//(
//)
//( //( { file_desc:"User configurable lexer for tokenizing text files." kw:[text]}
// Predefined Lexer Id's // Predefined Lexer Id's
@ -158,6 +155,5 @@ const cmChar_t* cmLexRcToMsg( unsigned rc );
void cmLexTest( cmRpt_t* rpt ); void cmLexTest( cmRpt_t* rpt );
//) //)
//}
#endif #endif

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Manage shared-libraries and query them for known symbols." kw:[system]}
enum enum
{ {
kOkLibRC = cmOkRC, kOkLibRC = cmOkRC,
@ -54,7 +56,7 @@ extern "C" {
// Return the libraries file name. // Return the libraries file name.
const cmChar_t* cmLibName( cmLibH_t h, unsigned libId ); const cmChar_t* cmLibName( cmLibH_t h, unsigned libId );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -141,7 +141,7 @@ bool _cmLHeapFree( cmLHeap_t* lhp, void* dataPtr )
lbp->nextPtr = (char*)allocPtr; // ... then make it the space to alloc lbp->nextPtr = (char*)allocPtr; // ... then make it the space to alloc
else else
lbp->freeCnt += *allocPtr; // ... otherwise increase the free count 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 // if all the space for this block has been freed then the
// next space to allocate must be at the base // next space to allocate must be at the base

View File

@ -5,8 +5,18 @@
extern "C" { extern "C" {
#endif #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; typedef cmHandle_t cmLHeapH_t;
extern cmLHeapH_t cmLHeapNullHandle; extern cmLHeapH_t cmLHeapNullHandle;
@ -84,7 +94,6 @@ extern "C" {
#endif #endif
//) //)
//}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,3 +1,5 @@
//( { file_desc:"Template 'main.c' for 'libcm' based program" kw:[demo]}
#include "cmGlobal.h" #include "cmGlobal.h"
#include "cmRpt.h" #include "cmRpt.h"
#include "cmMem.h" #include "cmMem.h"
@ -31,3 +33,5 @@ int main(int argc, char* argv[] )
cmMdFinalize(); cmMdFinalize();
return 0; return 0;
} }
//)

View File

@ -1,6 +1,11 @@
//{ { label:cmMd } #ifndef cmMallocDebug_h
//( #define cmMallocDebug_h
// Implements an extended memory allocation and tracking manager.
#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(). // cmMallocDebug is a wrapper to cmMem.h for calls to malloc() and free().
// Most of the cmMdXXX() calls are directly associated with same named // 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 // cmMm object where malloc() and free() are the callback functions
// provided to cmMmInitialize(). // provided to cmMmInitialize().
// //
//) //
#ifndef cmMallocDebug_h
#define cmMallocDebug_h
#ifdef __cplusplus
extern "C" {
#endif
//(
// Initialize the malloc debug manager. guardByteCnt, alignByteeCnt, flags, and rpt // Initialize the malloc debug manager. guardByteCnt, alignByteeCnt, flags, and rpt
// are used to initialize an internal cmMm object. See cmMm for their semantics. // 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 ); cmMmRC_t cmMdInitialize( unsigned guardByteCnt, unsigned alignByteCnt, unsigned flags, cmRpt_t* rptPtr );
@ -165,6 +163,4 @@ extern "C" {
#endif #endif
//}
#endif #endif

200
cmMath.h
View File

@ -1,120 +1,132 @@
#ifndef cmMath_h #ifndef cmMath_h
#define cmMath_h #define cmMath_h
double cmX80ToDouble( unsigned char s[10] ); #ifdef __cplusplus
void cmDoubleToX80( double v, unsigned char s[10] ); extern "C" {
#endif
bool cmIsPowerOfTwo( unsigned i ); //( { file_desc:"Math utility functions" kw:[math] }
unsigned cmNextPowerOfTwo( unsigned i );
unsigned cmNearPowerOfTwo( unsigned i );
bool cmIsOddU( unsigned v ); double cmX80ToDouble( unsigned char s[10] );
bool cmIsEvenU( unsigned v ); void cmDoubleToX80( double v, unsigned char s[10] );
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 bool cmIsPowerOfTwo( unsigned i );
/// 0 to (maxN-1). unsigned cmNextPowerOfTwo( unsigned i );
/// 'idx': initial value unsigned cmNearPowerOfTwo( unsigned i );
/// 'delta': incremental amount
/// 'maxN' - 1 : maximum return value.
unsigned cmModIncr(int idx, int delta, int maxN );
// modified bessel function of first kind, order 0 bool cmIsOddU( unsigned v );
// ref: orfandis appendix B io.m bool cmIsEvenU( unsigned v );
double cmBessel0( double x ); 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 // The following elliptic-related function approximations come from
// Parks & Burrus, Digital Filter Design, Appendix program 9, pp. 317-326 // Parks & Burrus, Digital Filter Design, Appendix program 9, pp. 317-326
// which in turn draws directly on other sources // which in turn draws directly on other sources
// calculate complete elliptic integral (quarter period) K // calculate complete elliptic integral (quarter period) K
// given *complimentary* modulus kc // given *complimentary* modulus kc
cmReal_t cmEllipK( cmReal_t kc ); cmReal_t cmEllipK( cmReal_t kc );
// calculate elliptic modulus k // calculate elliptic modulus k
// given ratio of complete elliptic integrals r = K/K' // given ratio of complete elliptic integrals r = K/K'
// (solves the "degree equation" for fixed N = K*K1'/K'K1) // (solves the "degree equation" for fixed N = K*K1'/K'K1)
cmReal_t cmEllipDeg( cmReal_t r ); cmReal_t cmEllipDeg( cmReal_t r );
// calculate arc elliptic tangent u (elliptic integral of the 1st kind) // calculate arc elliptic tangent u (elliptic integral of the 1st kind)
// given argument x = sc(u,k) and *complimentary* modulus kc // given argument x = sc(u,k) and *complimentary* modulus kc
cmReal_t cmEllipArcSc( cmReal_t x, cmReal_t kc ); cmReal_t cmEllipArcSc( cmReal_t x, cmReal_t kc );
// calculate Jacobi elliptic functions sn, cn, and dn // calculate Jacobi elliptic functions sn, cn, and dn
// given argument u and *complimentary* modulus kc // 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 ); cmRC_t cmEllipJ( cmReal_t u, cmReal_t kc, cmReal_t* sn, cmReal_t* cn, cmReal_t* dn );
//================================================================= //=================================================================
// bilinear transform // bilinear transform
// z = (2*sr + s)/(2*sr - s) // z = (2*sr + s)/(2*sr - s)
cmRC_t cmBlt( unsigned n, cmReal_t sr, cmReal_t* rp, cmReal_t* ip ); cmRC_t cmBlt( unsigned n, cmReal_t sr, cmReal_t* rp, cmReal_t* ip );
//================================================================= //=================================================================
// Pitch conversion // Pitch conversion
unsigned cmHzToMidi( double hz ); unsigned cmHzToMidi( double hz );
float cmMidiToHz( unsigned midi ); float cmMidiToHz( unsigned midi );
//================================================================= //=================================================================
// Floating point byte swapping // Floating point byte swapping
unsigned cmFfSwapFloatToUInt( float v ); unsigned cmFfSwapFloatToUInt( float v );
float cmFfSwapUIntToFloat( unsigned v ); float cmFfSwapUIntToFloat( unsigned v );
unsigned long long cmFfSwapDoubleToULLong( double v ); unsigned long long cmFfSwapDoubleToULLong( double v );
double cmFfSwapULLongToDouble( unsigned long long v ); double cmFfSwapULLongToDouble( unsigned long long v );
//================================================================= //=================================================================
int cmRandInt( int min, int max ); int cmRandInt( int min, int max );
unsigned cmRandUInt( unsigned min, unsigned max ); unsigned cmRandUInt( unsigned min, unsigned max );
float cmRandFloat( float min, float max ); float cmRandFloat( float min, float max );
double cmRandDouble( double min, double max ); double cmRandDouble( double min, double max );
//================================================================= //=================================================================
bool cmIsCloseD( double x0, double x1, double eps ); bool cmIsCloseD( double x0, double x1, double eps );
bool cmIsCloseF( float x0, float x1, double eps ); bool cmIsCloseF( float x0, float x1, double eps );
bool cmIsCloseI( int x0, int x1, double eps ); bool cmIsCloseI( int x0, int x1, double eps );
bool cmIsCloseU( unsigned x0, unsigned x1, double eps ); bool cmIsCloseU( unsigned x0, unsigned x1, double eps );
//================================================================= //=================================================================
// Run a length 'lfsrN' linear feedback shift register (LFSR) for 'yN' iterations to // Run a length 'lfsrN' linear feedback shift register (LFSR) for 'yN' iterations to
// produce a length 'yN' bit string in yV[yN]. // produce a length 'yN' bit string in yV[yN].
// 'lfsrN' count of bits in the shift register range: 2<= lfsrN <= 32. // '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. // '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 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). // The min tap position is therefore denoted by the tap mask bit location 1 << (lfsrN-1).
// A minimum of two taps must exist. // A minimum of two taps must exist.
// 'seed' sets the initial delay state. // 'seed' sets the initial delay state.
// 'yV[yN]' is the the output vector // 'yV[yN]' is the the output vector
// 'yN' is count of elements in yV. // 'yN' is count of elements in yV.
// The function resturn kOkAtRC on success or kInvalidArgsRCRC if any arguments are invalid. // The function resturn kOkAtRC on success or kInvalidArgsRCRC if any arguments are invalid.
// /sa cmLFSR_Test. // /sa cmLFSR_Test.
void cmLFSR( unsigned lfsrN, unsigned tapMask, unsigned seed, unsigned* yV, unsigned yN ); void cmLFSR( unsigned lfsrN, unsigned tapMask, unsigned seed, unsigned* yV, unsigned yN );
// Example and test code for cmLFSR() // Example and test code for cmLFSR()
bool cmLFSR_Test(); bool cmLFSR_Test();
// Generate a set of 'goldN' Gold codes using the Maximum Length Sequences (MLS) generated // Generate a set of 'goldN' Gold codes using the Maximum Length Sequences (MLS) generated
// by a length 'lfsrN' linear feedback shift register. // by a length 'lfsrN' linear feedback shift register.
// 'err' is an error object to be set if the the function fails. // '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. // 'lfsrN' is the length of the Linear Feedback Shift Registers (LFSR) used to generate the MLS.
// 'poly_coeff0' tap mask for the first LFSR. // 'poly_coeff0' tap mask for the first LFSR.
// 'coeff1' tap mask the the second LFSR. // 'coeff1' tap mask the the second LFSR.
// 'goldN' is the count of Gold codes to generate. // '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. // '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 // 'mlsN' is the length of the maximum length sequence for each Gold code which can be
// calculated as mlsN = (1 << a->lfsrN) - 1. // calculated as mlsN = (1 << a->lfsrN) - 1.
// Note that values of 'lfsrN' and the 'poly_coeffx' must be carefully selected such that // 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 // 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}. // 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 // See http://www.ece.cmu.edu/~koopman/lfsr/index.html for a complete set of MSL polynomial
// coefficients for given LFSR lengths. // coefficients for given LFSR lengths.
// Returns false if insufficient balanced pairs exist. // Returns false if insufficient balanced pairs exist.
bool cmGenGoldCodes( unsigned lfsrN, unsigned poly_coeff0, unsigned poly_coeff1, unsigned goldN, int* yM, unsigned mlsN ); bool cmGenGoldCodes( unsigned lfsrN, unsigned poly_coeff0, unsigned poly_coeff1, unsigned goldN, int* yM, unsigned mlsN );
//)
#ifdef __cplusplus
}
#endif
#endif #endif

10
cmMem.h
View File

@ -1,6 +1,4 @@
//{ //( { file_desc: "Implements a memory allocation manager interface." kw:[ base ]}
//(
// The cmMem class implements a memory allocation manager interface.
// //
// //
// Using cmMem allows memory leaks and some instances of memory corruption // 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 // As part of the configuration the client gives callback functions which implement
// actual memory allocation and release. In practice this means the callback probably // actual memory allocation and release. In practice this means the callback probably
// call malloc() or free(). // call malloc() or free().
//
// 2. At some point later when the client needs to allocate a block of memory it calls // 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 // 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 // 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. // memory which is slightly larger than the request block.
//
// 3. Given the raw memory block cmMm conditions it in the following ways and returns // 3. Given the raw memory block cmMm conditions it in the following ways and returns
// it to the client. // it to the client.
//
// * The base of the blocks data area is shifted such that it is has an arbitrary // * 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 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 // 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 // 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 // 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. // 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. // 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 // If the pointer is not found then a kMissingRecdRC is returned indicating an attempt to release
// a non-allocated block. // a non-allocated block.
//
// 3. If tracking is enabled (kTrackMmFl) then the block is marked as released in the // 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 // internal tracking database. At the end of the program all blocks should be marked for release
// otherwise they are considered leaks. // otherwise they are considered leaks.
@ -223,7 +226,6 @@ extern "C" {
cmMmRC_t cmMmCheckAllGuards( cmMmH_t h ); cmMmRC_t cmMmCheckAllGuards( cmMmH_t h );
//) //)
//}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"MIDI utility constants and functions." kw:[midi]}
enum enum
{ {
kMidiChCnt = 16, kMidiChCnt = 16,
@ -154,6 +156,8 @@ extern "C" {
// of this range will be returned as kInvalidMidiPitch. // of this range will be returned as kInvalidMidiPitch.
cmMidiByte_t cmSciPitchToMidi( const char* sciPitchStr ); cmMidiByte_t cmSciPitchToMidi( const char* sciPitchStr );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -246,7 +246,7 @@ cmMfRC_t _cmMidiFileReadChannelMsg( _cmMidiFile_t* mfp, cmMidiByte_t* rsPtr, cmM
tmp->byteCnt = sizeof(cmMidiChMsg_t); tmp->byteCnt = sizeof(cmMidiChMsg_t);
tmp->status = statusCh & 0xf0; tmp->status = statusCh & 0xf0;
p->ch = statusCh & 0x0f; p->ch = statusCh & 0x0f;
p->durTicks = 0; p->durMicros = 0;
unsigned byteN = cmMidiStatusToByteCount(tmp->status); unsigned byteN = cmMidiStatusToByteCount(tmp->status);
@ -416,8 +416,6 @@ cmMfRC_t _cmMidiFileReadHdr( _cmMidiFile_t* mfp )
int _cmMidiFileSortFunc( const void *p0, const void* p1 ) 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 ) if( (*(cmMidiTrackMsg_t**)p0)->atick == (*(cmMidiTrackMsg_t**)p1)->atick )
return 0; 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[] // store a pointer to every trk msg in msgV[]
// and convert tick to absolute tick // and convert tick to absolute tick
mfp->nextUid = 0; mfp->nextUid = 0;
double microsPerQN = 60000000/120; // default tempo;
double microsPerTick;
unsigned i = 0; unsigned i = 0;
for(trkIdx=0; trkIdx<mfp->trkN; ++trkIdx) for(trkIdx=0; trkIdx<mfp->trkN; ++trkIdx)
{ {
unsigned tick = 0; unsigned tick = 0;
cmMidiTrackMsg_t* tmp = mfp->trkV[ trkIdx ].base; cmMidiTrackMsg_t* tmp = mfp->trkV[ trkIdx ].base;
microsPerTick = microsPerQN / mfp->ticksPerQN;
while( tmp != NULL ) while( tmp != NULL )
{ {
assert( i < mfp->msgN); assert( i < mfp->msgN);
@ -540,6 +546,14 @@ cmMfRC_t cmMidiFileOpen( const char* fn, cmMidiFileH_t* hPtr, cmCtx_t* ctx )
tmp->atick = tick; tmp->atick = tick;
tmp->uid = mfp->nextUid++; // assign the msg uid tmp->uid = mfp->nextUid++; // assign the msg uid
mfp->msgV[i] = tmp; 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; tmp = tmp->link;
++i; ++i;
} }
@ -548,6 +562,31 @@ cmMfRC_t cmMidiFileOpen( const char* fn, cmMidiFileH_t* hPtr, cmCtx_t* ctx )
// sort msgV[] in ascending order on atick // sort msgV[] in ascending order on atick
qsort( mfp->msgV, mfp->msgN, sizeof(cmMidiTrackMsg_t*), _cmMidiFileSortFunc ); 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) //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); // 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) for(mi=0; mi<p->msgN; ++mi)
{ {
const cmMidiTrackMsg_t* mp = p->msgV[mi]; const cmMidiTrackMsg_t* mp = p->msgV[mi];
/*
if( mp->status == kMetaStId && mp->metaId == kTempoMdId ) if( mp->status == kMetaStId && mp->metaId == kTempoMdId )
microsPerTick = mp->u.iVal / p->ticksPerQN; 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 ) if( accUSecs >= offsUSecs )
break; break;
*/
if( mp->amicro >= offsUSecs )
break;
} }
if( mi == p->msgN ) if( mi == p->msgN )
@ -1080,92 +1129,17 @@ unsigned cmMidiFileSeekUsecs( cmMidiFileH_t h, unsigned offsUSecs, unsigned* ms
double cmMidiFileDurSecs( cmMidiFileH_t h ) double cmMidiFileDurSecs( cmMidiFileH_t h )
{ {
_cmMidiFile_t* mfp = _cmMidiFileHandleToPtr(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) if( mfp->msgN == 0 )
{ return 0;
cmMidiTrackMsg_t* mp = mfp->msgV[mi];
if( mp->status == kMetaStId && mp->metaId == kTempoMdId ) return mfp->msgV[ mfp->msgN-1 ]->amicro / 1000000.0;
microsPerTick = r*mp->u.iVal / mfp->ticksPerQN;
// update the accumulated seconds
durSecs += (mp->dtick * microsPerTick) / 1000000.0;
}
return durSecs;
} }
void cmMidiFileTickToMicros( cmMidiFileH_t h )
{
_cmMidiFile_t* p;
if((p = _cmMidiFileHandleToPtr(h)) == NULL )
return;
if( p->msgN == 0 )
return;
unsigned mi;
double r = 1.0; //1000.0/(1000-.8);
double microsPerQN = r*60000000/120; // default tempo
double microsPerTick = microsPerQN / p->ticksPerQN;
for(mi=0; 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 typedef struct _cmMidiVoice_str
{ {
const cmMidiTrackMsg_t* mp; const cmMidiTrackMsg_t* mp;
unsigned durTicks; unsigned durMicros;
bool sustainFl; bool sustainFl;
struct _cmMidiVoice_str* link; struct _cmMidiVoice_str* link;
} _cmMidiVoice_t; } _cmMidiVoice_t;
@ -1178,7 +1152,7 @@ void _cmMidFileCalcNoteDurationReleaseNote( _cmMidiVoice_t** listPtrPtr, _cmMidi
// store the duration of the note into the track msg // store the duration of the note into the track msg
// assoc'd with the note-on msg // assoc'd with the note-on msg
cmMidiChMsg_t* cmp = (cmMidiChMsg_t*)vp->mp->u.chMsgPtr; // cast away const 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; _cmMidiVoice_t* np = vp->link;
@ -1226,13 +1200,20 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
{ {
cmMidiTrackMsg_t* mp = p->msgV[mi]; 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 // update the duration of the sounding notes
for(vp = list; vp!=NULL; vp=vp->link) for(vp = list; vp!=NULL; vp=vp->link)
vp->durTicks += mp->dtick; vp->durMicros += d_amicro;
// update the sustain pedal duration // update the sustain pedal duration
if( sustainPedalDownMsg != NULL ) 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 // If this is sustain pedal msg
@ -1257,7 +1238,7 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
else else
{ {
sustainPedalDownMsg = mp; 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 ); _cmMidiFileCalcNoteDurationsAllocVoice( &list, mp, true );
@ -1389,16 +1370,51 @@ cmMidiTrackMsg_t* cmMidiFilePackTrackMsg( const cmMidiTrackMsg_t* m, void* b
return (cmMidiTrackMsg_t*)buf; return (cmMidiTrackMsg_t*)buf;
} }
void _cmMidiFilePrintHdr( const _cmMidiFile_t* mfp, cmRpt_t* rpt )
void cmMidiFilePrint( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt )
{ {
const _cmMidiFile_t* mfp = _cmMidiFileHandleToPtr(h);
if( mfp->fn != NULL ) if( mfp->fn != NULL )
cmRptPrintf(rpt,"%s ",mfp->fn); cmRptPrintf(rpt,"%s ",mfp->fn);
cmRptPrintf(rpt,"fmt:%i ticksPerQN:%i tracks:%i\n",mfp->fmtId,mfp->ticksPerQN,mfp->trkN); 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 i = trkIdx == cmInvalidIdx ? 0 : trkIdx;
int n = trkIdx == cmInvalidIdx ? mfp->trkN : trkIdx+1; 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; cmMidiTrackMsg_t* tmp = mfp->trkV[i].base;
while( tmp != NULL ) while( tmp != NULL )
{ {
cmRptPrintf(rpt,"%5i ", tmp->dtick ); _cmMidiFilePrintMsg(rpt,tmp);
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");
tmp = tmp->link; tmp = tmp->link;
} }
} }
@ -1475,7 +1481,14 @@ void cmMidiFileTest( const char* fn, cmCtx_t* ctx )
return; 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,cmMidiFileTrackCount(h)-1,&ctx->rpt);
//cmMidiFilePrint(h,cmInvalidIdx,&ctx->rpt); //cmMidiFilePrint(h,cmInvalidIdx,&ctx->rpt);

View File

@ -5,6 +5,7 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"MIDI file reader and writer." kw:[midi file]}
// MIDI file timing: // MIDI file timing:
// Messages in the MIDI file are time tagged with a delta offset in 'ticks' // Messages in the MIDI file are time tagged with a delta offset in 'ticks'
// from the previous message in the same track. // 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 // 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(). // with velocity=0 are is changed to a note-off message. See _cmMidiFileReadChannelMsg().
//)
//(
typedef cmHandle_t cmMidiFileH_t; typedef cmHandle_t cmMidiFileH_t;
typedef unsigned cmMfRC_t; typedef unsigned cmMfRC_t;
@ -56,15 +57,17 @@ extern "C" {
cmMidiByte_t ch; cmMidiByte_t ch;
cmMidiByte_t d0; cmMidiByte_t d0;
cmMidiByte_t d1; cmMidiByte_t d1;
unsigned durTicks; // note duration calc'd by cmMidiFileCalcNoteDurations(); unsigned durMicros; // note duration in microseconds (corrected for tempo changes)
} cmMidiChMsg_t; } cmMidiChMsg_t;
typedef struct cmMidiTrackMsg_str typedef struct cmMidiTrackMsg_str
{ {
unsigned uid; // uid's are unique among all msg's in the file unsigned uid; // uid's are unique among all msg's in the file
unsigned dtick; // delta ticks unsigned dtick; // delta ticks between events on this track
unsigned atick; // accumulated ticks 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 status; // ch msg's have the channel value removed (it is stored in u.chMsgPtr->ch)
cmMidiByte_t metaId; // cmMidiByte_t metaId; //
unsigned short trkIdx; // unsigned short trkIdx; //
@ -152,13 +155,6 @@ extern "C" {
double cmMidiFileDurSecs( cmMidiFileH_t h ); 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 // Calculate Note Duration
void cmMidiFileCalcNoteDurations( cmMidiFileH_t h ); void cmMidiFileCalcNoteDurations( cmMidiFileH_t h );
@ -171,10 +167,13 @@ extern "C" {
cmMidiTrackMsg_t* cmMidiFilePackTrackMsg( const cmMidiTrackMsg_t* m, void* buf, unsigned bufByteCnt ); cmMidiTrackMsg_t* cmMidiFilePackTrackMsg( const cmMidiTrackMsg_t* m, void* buf, unsigned bufByteCnt );
unsigned cmMidiFilePackTrackMsgBufByteCount( const cmMidiTrackMsg_t* m ); 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 ); bool cmMidiFileIsNull( cmMidiFileH_t h );
void cmMidiFileTest( const char* fn, cmCtx_t* ctx ); void cmMidiFileTest( const char* fn, cmCtx_t* ctx );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -148,9 +148,6 @@ cmMfpRC_t cmMfpLoadHandle( cmMfpH_t h, cmMidiFileH_t mfH )
p->mtime = 0; p->mtime = 0;
p->closeFileFl= false; p->closeFileFl= false;
//if( p->msgIdx > 0 )
// p->mtime = p->msgV[0]->tick * p->microsPerTick;
return kOkMfpRC; 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 // sent and the end of the time window for this mfpClock() cycle
p->etime += dusecs; 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 // if the elapsed time (etime) since the last msg is greater or equal
// to the delta time to the next msg (mtime) // to the delta time to the next msg (mtime)
while( p->etime >= p->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 ); p->cbFunc( p->userCbPtr, p->mtime, mp );
unsigned amicro = mp->amicro;
++(p->msgIdx); ++(p->msgIdx);
if( p->msgIdx >= p->msgN ) if( p->msgIdx >= p->msgN )
@ -235,13 +228,13 @@ cmMfpRC_t cmMfpClock( cmMfpH_t h, unsigned dusecs )
// get the next msg to send // get the next msg to send
mp = p->msgV[p->msgIdx]; mp = p->msgV[p->msgIdx];
// we probably went past the actual mtime - so update etime // we probably went past the actual mtime - so update etime
// with the delta usecs from the msg just sent and the current time // with the delta usecs from the msg just sent and the current time
p->etime -= p->mtime; p->etime -= p->mtime;
// calc the delta usecs from the message just sent to the next msg to send // 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->amicro - amicro;
p->mtime = mp->dtick * p->microsPerTick;
} }

View File

@ -5,13 +5,15 @@
extern "C" { extern "C" {
#endif #endif
typedef cmHandle_t cmMfpH_t; //( { file_desc:"Device indepenent MIDI file player." kw:[midi]}
typedef cmRC_t cmMfpRC_t;
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 kOkMfpRC = cmOkRC, // 0
kInvalidHandleMfpRC, // 1 kInvalidHandleMfpRC, // 1
kFileOpenFailMfpRC, // 2 kFileOpenFailMfpRC, // 2
@ -21,36 +23,38 @@ enum
kEndOfFileMfpRC, // 6 kEndOfFileMfpRC, // 6
kSmpteTickNotImplMfpRC // 7 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 cmMfpCreate( cmMfpH_t* hp, cmMfpCallback_t cbFunc, void* userCbPtr, cmCtx_t* ctx );
cmMfpRC_t cmMfpDestroy( cmMfpH_t* hp ); cmMfpRC_t cmMfpDestroy( cmMfpH_t* hp );
bool cmMfpIsValid( cmMfpH_t h ); bool cmMfpIsValid( cmMfpH_t h );
// Load a MIDI file into the player. This MIDI file will be automatically // 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. // 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 ); cmMfpRC_t cmMfpLoadFile( cmMfpH_t h, const char* fn );
// Load a MIDI file into the player using a file owned by the host. // 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 // This file will NOT be closed when a new file is loaded at a later time
// or the MIDI file player handle is destroyed. // or the MIDI file player handle is destroyed.
cmMfpRC_t cmMfpLoadHandle( cmMfpH_t h, cmMidiFileH_t mfH ); cmMfpRC_t cmMfpLoadHandle( cmMfpH_t h, cmMidiFileH_t mfH );
// Reset the play position of the player to an offset in microseconds from // 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' // the beginning of the file. If there are no message at or after 'offsMicrosecs'
// then the function will return kEndOfFileMfpRC. // then the function will return kEndOfFileMfpRC.
cmMfpRC_t cmMfpSeek( cmMfpH_t h, unsigned offsMicrosecs ); cmMfpRC_t cmMfpSeek( cmMfpH_t h, unsigned offsMicrosecs );
// This is the driving clock call for the player. 'deltaMicroSecs' is the // This is the driving clock call for the player. 'deltaMicroSecs' is the
// elapsed time in microseconds since the last call to this function. // elapsed time in microseconds since the last call to this function.
// Call to 'cbFunc', as set in by cmMfpCreate() occur from this function. // Call to 'cbFunc', as set in by cmMfpCreate() occur from this function.
cmMfpRC_t cmMfpClock( cmMfpH_t h, unsigned deltaMicroSecs ); 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 #ifdef __cplusplus
} }

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Device independent MIDI port related code." kw:[midi]}
typedef unsigned cmMpRC_t; typedef unsigned cmMpRC_t;
// Flags used to identify input and output ports on MIDI devices // 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 ); 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 // MIDI Parser
@ -62,6 +66,8 @@ extern "C" {
// Returns true if the parser uses the given callback. // Returns true if the parser uses the given callback.
bool cmMpParserHasCallback( cmMpParserH_t h, cmMpCallback_t cbFunc, void* cbDataPtr ); bool cmMpParserHasCallback( cmMpParserH_t h, cmMpCallback_t cbFunc, void* cbDataPtr );
//)
//( { label:cmMidiPort file_desc:"Device independent MIDI port." kw:[midi]}
//=============================================================================================== //===============================================================================================
// MIDI Device Interface // MIDI Device Interface
@ -92,6 +98,7 @@ extern "C" {
void cmMpReport( cmRpt_t* rpt ); void cmMpReport( cmRpt_t* rpt );
void cmMpTest( cmCtx_t* ctx ); void cmMpTest( cmCtx_t* ctx );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -7,6 +7,7 @@
extern "C" { extern "C" {
#endif #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" #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 cmMsgPeekInstId( const void* msgArray[], unsigned msgByteCntArray[], unsigned segCnt, unsigned* retValPtr );
cmMsgRC_t cmMsgPeekInstVarId( const void* msgArray[], unsigned msgByteCntArray[], unsigned segCnt, unsigned* retValPtr ); cmMsgRC_t cmMsgPeekInstVarId( const void* msgArray[], unsigned msgByteCntArray[], unsigned segCnt, unsigned* retValPtr );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1250,7 +1250,7 @@ void cmPgmOptPrintHelp( cmPgmOptH_t h, cmRpt_t* rpt )
reqLabel = reqStr; reqLabel = reqStr;
if( mstr != NULL ) 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); cmRptPrintf(rpt,"%s-%c --%s %s %s",indentStr,r->charId,r->wordId,valueTypeLabel,reqLabel);

View File

@ -1,8 +1,8 @@
#ifndef cmPgmOpts_h #ifndef cmPgmOpts_h
#define cmPgmOpts_h #define cmPgmOpts_h
//{ //( { file_desc:"Command line argument description and parsing API." kw:[base]}
//( //
// Command line program option syntax: // Command line program option syntax:
// //
// //
@ -206,7 +206,6 @@ extern "C" {
void cmPgmOptPrintParms( cmPgmOptH_t h, cmRpt_t* rpt ); void cmPgmOptPrintParms( cmPgmOptH_t h, cmRpt_t* rpt );
//) //)
//}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Manage persistent application preferences." kw:[base] }
typedef unsigned cmPrRC_t; typedef unsigned cmPrRC_t;
typedef cmHandle_t cmPrH_t; typedef cmHandle_t cmPrH_t;
@ -188,6 +190,7 @@ extern "C" {
void cmPrefsTest( cmCtx_t* ctx, const char* ifn, const char* ofn ); void cmPrefsTest( cmCtx_t* ctx, const char* ifn, const char* ofn );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

244
cmProc.h
View File

@ -5,7 +5,10 @@
extern "C" { extern "C" {
#endif #endif
//------------------------------------------------------------------------------------------------------------ //( { file_desc:"Processor Library 1" kw:[proclib]}
//)
//( { label:cmAudioFileRd file_desc:"Audio file reader based on cmAudioFile" kw:[proc] }
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -23,28 +26,30 @@ extern "C" {
cmMtxFile* mfp; cmMtxFile* mfp;
} cmAudioFileRd; } cmAudioFileRd;
/// set p to NULL to dynamically allocate the object // 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. // 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. // If fn is valid then chIdx must also be valid.
/// Set 'endSmpIdx' to cmInvalidIdx to return the entire signal in cmAudioFileRdRead(). // 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 '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 ); cmAudioFileRd* cmAudioFileRdAlloc( cmCtx* c, cmAudioFileRd* p, unsigned procSmpCnt, const char* fn, unsigned chIdx, unsigned begSmpIdx, unsigned endSmpIdx );
cmRC_t cmAudioFileRdFree( cmAudioFileRd** p ); cmRC_t cmAudioFileRdFree( cmAudioFileRd** p );
cmRC_t cmAudioFileRdOpen( cmAudioFileRd* p, unsigned procSmpCnt, const cmChar_t* fn, unsigned chIdx, unsigned begSmpIdx, unsigned endSmpIdx ); cmRC_t cmAudioFileRdOpen( cmAudioFileRd* p, unsigned procSmpCnt, const cmChar_t* fn, unsigned chIdx, unsigned begSmpIdx, unsigned endSmpIdx );
cmRC_t cmAudioFileRdClose( cmAudioFileRd* p ); 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 cmAudioFileRdRead( cmAudioFileRd* p );
cmRC_t cmAudioFileRdSeek( cmAudioFileRd* p, unsigned frmIdx ); 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 ); 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 // The buffer is intended to synchronize sample block rates between processes and to provide an overlapped
/// input buffer. // input buffer.
typedef struct cmShiftBuf_str typedef struct cmShiftBuf_str
{ {
cmObj obj; 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 ); cmShiftBuf* cmShiftBufAlloc( cmCtx* c, cmShiftBuf* p, unsigned procSmpCnt, unsigned wndSmpCnt, unsigned hopSmpCnt );
cmRC_t cmShiftBufFree( cmShiftBuf** p ); cmRC_t cmShiftBufFree( cmShiftBuf** p );
cmRC_t cmShiftBufInit( cmShiftBuf* p, unsigned procSmpCnt, unsigned wndSmpCnt, unsigned hopSmpCnt ); cmRC_t cmShiftBufInit( cmShiftBuf* p, unsigned procSmpCnt, unsigned wndSmpCnt, unsigned hopSmpCnt );
cmRC_t cmShiftBufFinal( cmShiftBuf* p ); cmRC_t cmShiftBufFinal( cmShiftBuf* p );
/// Returns true if a new hop is ready to be read otherwise returns false. // 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. // 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. // 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. // 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 // When procSmpCnt is less than hopSmpCnt the loop will only execute when at least wndSmpCnt
/// new samples have been buffered. // new samples have been buffered.
/// When procSmpCnt is greater than hopSmpCnt the loop will execute multiple times until less // When procSmpCnt is greater than hopSmpCnt the loop will execute multiple times until less
// than wndSmpCnt new samples are available. // than wndSmpCnt new samples are available.
/// Note that 'sn' must always be less than or equal to procSmpCnt. // Note that 'sn' must always be less than or equal to procSmpCnt.
/// //
/// Example: // Example:
/// while( fill(sp,sn) ) // fill sp[] with sn samples // while( fill(sp,sn) ) // fill sp[] with sn samples
/// { // {
/// // shift by hopSmpCnt samples on all passes - insert new samples on first pass // // shift by hopSmpCnt samples on all passes - insert new samples on first pass
/// while( cmShiftBufExec(p,sp,sn) ) // while( cmShiftBufExec(p,sp,sn) )
/// proc(p->outV,p->outN); // process p->outV[wndSmpCnt] // proc(p->outV,p->outN); // process p->outV[wndSmpCnt]
/// } // }
bool cmShiftBufExec( cmShiftBuf* p, const cmSample_t* sp, unsigned sn ); bool cmShiftBufExec( cmShiftBuf* p, const cmSample_t* sp, unsigned sn );
void cmShiftBufTest( cmCtx* c ); void cmShiftBufTest( cmCtx* c );
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
/* //)
typedef struct
{
cmComplexS_t* complexV;
cmSample_t* outV;
cmFftPlanS_t plan;
} cmIFftObjS;
typedef struct //( { label:cmWindowFunc file_desc:"Fourier Transform window function generator." kw:[proc]}
{
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 );
*/
//------------------------------------------------------------------------------------------------------------
enum enum
{ {
@ -174,8 +126,8 @@ extern "C" {
cmMtxFile* mfp; cmMtxFile* mfp;
} cmWndFunc; } cmWndFunc;
/// Set p to NULL to dynamically allocate the object // Set p to NULL to dynamically allocate the object
/// if wndId is set to a valid value this function will internally call cmWndFuncInit() // 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 ); cmWndFunc* cmWndFuncAlloc( cmCtx* c, cmWndFunc* p, unsigned wndId, unsigned wndSmpCnt, double kaierSideLobeRejectDb );
cmRC_t cmWndFuncFree( cmWndFunc** pp ); cmRC_t cmWndFuncFree( cmWndFunc** pp );
cmRC_t cmWndFuncInit( cmWndFunc* p, unsigned wndId, unsigned wndSmpCnt, double kaiserSideLobeRejectDb ); 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 ); 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 typedef struct
{ {
cmObj obj; cmObj obj;
@ -197,24 +151,25 @@ extern "C" {
} cmSpecDelay; } cmSpecDelay;
/// Set p to NULL to dynamically allocate the object. // Set p to NULL to dynamically allocate the object.
/// Allocate a spectral frame delay capable of delaying for 'maxDelayCnt' hops and // Allocate a spectral frame delay capable of delaying for 'maxDelayCnt' hops and
/// where each vector contains 'binCnt' elements. // where each vector contains 'binCnt' elements.
cmSpecDelay* cmSpecDelayAlloc( cmCtx* c, cmSpecDelay* p, unsigned maxDelayCnt, unsigned binCnt ); cmSpecDelay* cmSpecDelayAlloc( cmCtx* c, cmSpecDelay* p, unsigned maxDelayCnt, unsigned binCnt );
cmRC_t cmSpecDelayFree( cmSpecDelay** p ); cmRC_t cmSpecDelayFree( cmSpecDelay** p );
cmRC_t cmSpecDelayInit( cmSpecDelay* p, unsigned maxDelayCnt, unsigned binCnt ); cmRC_t cmSpecDelayInit( cmSpecDelay* p, unsigned maxDelayCnt, unsigned binCnt );
cmRC_t cmSpecDelayFinal(cmSpecDelay* p ); 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 ); 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. // 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, ... ) // (e.g. 1 is the previous hop, 2 is two hops previous, ... )
const cmSample_t* cmSpecDelayOutPtr(cmSpecDelay* p, unsigned delayCnt ); const cmSample_t* cmSpecDelayOutPtr(cmSpecDelay* p, unsigned delayCnt );
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmFilter file_desc:"General purpose, LTI, Octave compatible, filter." kw:[proc] }
typedef struct cmFilter_str typedef struct cmFilter_str
{ {
cmObj obj; cmObj obj;
@ -257,9 +212,10 @@ extern "C" {
void cmFilterTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); void cmFilterTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
void cmFilterFilterTest( 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 typedef struct
{ {
cmObj obj; cmObj obj;
@ -271,14 +227,16 @@ extern "C" {
//unsigned cdfSpRegId; //unsigned cdfSpRegId;
} cmComplexDetect; } 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 ); cmComplexDetect* cmComplexDetectAlloc(cmCtx* c, cmComplexDetect* p, unsigned binCnt );
cmRC_t cmComplexDetectFree( cmComplexDetect** pp); cmRC_t cmComplexDetectFree( cmComplexDetect** pp);
cmRC_t cmComplexDetectInit( cmComplexDetect* p, unsigned binCnt ); cmRC_t cmComplexDetectInit( cmComplexDetect* p, unsigned binCnt );
cmRC_t cmComplexDetectFinal(cmComplexDetect* p); cmRC_t cmComplexDetectFinal(cmComplexDetect* p);
cmRC_t cmComplexDetectExec( cmComplexDetect* p, const cmSample_t* magV, const cmSample_t* phsV, unsigned binCnt ); 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 typedef struct
{ {
cmObj obj; cmObj obj;
@ -298,8 +256,10 @@ extern "C" {
cmRC_t cmComplexOnsetFinal( cmComplexOnset* p); cmRC_t cmComplexOnsetFinal( cmComplexOnset* p);
cmRC_t cmComplexOnsetExec( cmComplexOnset* p, cmSample_t cdf ); cmRC_t cmComplexOnsetExec( cmComplexOnset* p, cmSample_t cdf );
cmRC_t cmComplexOnsetCalc( cmComplexOnset* p ); cmRC_t cmComplexOnsetCalc( cmComplexOnset* p );
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmMfcc file_desc:"Mel Frequency Cepstral Coefficient (MFCC) measurement function." kw:[proc] }
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -321,8 +281,10 @@ extern "C" {
cmRC_t cmMfccExecPower( cmMfcc* p, const cmReal_t* magPowV, unsigned binCnt ); cmRC_t cmMfccExecPower( cmMfcc* p, const cmReal_t* magPowV, unsigned binCnt );
cmRC_t cmMfccExecAmplitude( cmMfcc* p, const cmReal_t* magAmpV, unsigned binCnt ); cmRC_t cmMfccExecAmplitude( cmMfcc* p, const cmReal_t* magAmpV, unsigned binCnt );
void cmMfccTest(); void cmMfccTest();
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmSones file_desc:"Sones measurement function." kw:[proc] }
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -350,8 +312,10 @@ extern "C" {
cmRC_t cmSonesExec( cmSones* p, const cmReal_t* magPowV, unsigned binCnt ); cmRC_t cmSonesExec( cmSones* p, const cmReal_t* magPowV, unsigned binCnt );
void cmSonesTest(); void cmSonesTest();
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label: cmAudioOffsetScale file_desc:"Audio signal pre-processing normalizer." kw:[proc] }
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -371,15 +335,15 @@ extern "C" {
} cmAudioOffsetScale; } cmAudioOffsetScale;
/// This processor adds an offset to an audio signal and scales into dB (SPL) using one of two techniques // 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) // 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. // 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 // 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) // measured signal level. In this case dBref is commonly set to 96 (max. dB (SPL) value for 16 bits)
/// and rmsWndSecs is ignored. // and rmsWndSecs is ignored.
/// //
/// Note that setting rmsWndSecs to zero has the effect of using procSmpCnt as the window length. // Note that setting rmsWndSecs to zero has the effect of using procSmpCnt as the window length.
enum { kNoAudioScaleFl=0x01, kRmsAudioScaleFl=0x02, kFixedAudioScaleFl=0x04 }; 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 cmAudioOffsetScaleInit( cmAudioOffsetScale* p, unsigned procSmpCnt, double srate, cmSample_t offset, double rmsWndSecs, double dBref, unsigned flags );
cmRC_t cmAudioOffsetScaleFinal( cmAudioOffsetScale* p ); cmRC_t cmAudioOffsetScaleFinal( cmAudioOffsetScale* p );
cmRC_t cmAudioOffsetScaleExec( cmAudioOffsetScale* p, const cmSample_t* sp, unsigned sn ); 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 typedef struct
{ {
cmObj obj; cmObj obj;
@ -422,10 +388,10 @@ extern "C" {
unsigned ssSpRegId; unsigned ssSpRegId;
} cmSpecMeas; } cmSpecMeas;
/// Set wndFrmCnt to the number of spectral frames to take the measurement over. // 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. // 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. // 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. // In effect this treats the entire signal as the length of the measurement window.
enum { kWholeSigSpecMeasFl=0x00, kUseWndSpecMeasFl=0x01 }; enum { kWholeSigSpecMeasFl=0x00, kUseWndSpecMeasFl=0x01 };
cmSpecMeas* cmSpecMeasAlloc( cmCtx* c, cmSpecMeas* p, double srate, unsigned binCnt, unsigned wndFrmCnt, unsigned flags ); 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 cmSpecMeasInit( cmSpecMeas* p, double srate, unsigned binCnt, unsigned wndFrmCnt, unsigned flags );
cmRC_t cmSpecMeasFinal( cmSpecMeas* p ); cmRC_t cmSpecMeasFinal( cmSpecMeas* p );
cmRC_t cmSpecMeasExec( cmSpecMeas* p, const cmReal_t* magPowV, unsigned binCnt ); 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 typedef struct
{ {
cmObj obj; cmObj obj;
@ -456,8 +424,10 @@ extern "C" {
cmRC_t cmSigMeasInit( cmSigMeas* p, double srate, unsigned procSmpCnt, unsigned measSmpCnt ); cmRC_t cmSigMeasInit( cmSigMeas* p, double srate, unsigned procSmpCnt, unsigned measSmpCnt );
cmRC_t cmSigMeasFinal( cmSigMeas* p ); cmRC_t cmSigMeasFinal( cmSigMeas* p );
cmRC_t cmSigMeasExec( cmSigMeas* p, const cmSample_t* sigV, unsigned smpCnt ); cmRC_t cmSigMeasExec( cmSigMeas* p, const cmSample_t* sigV, unsigned smpCnt );
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmSRC file_desc:"Sample rate converter" kw:[proc] }
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -476,7 +446,7 @@ extern "C" {
} cmSRC; } 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 ); cmSRC* cmSRCAlloc( cmCtx* c, cmSRC* p, double srate, unsigned procSmpCnt, unsigned upFact, unsigned dnFact );
cmRC_t cmSRCFree( cmSRC** pp ); cmRC_t cmSRCFree( cmSRC** pp );
cmRC_t cmSRCInit( cmSRC* p, double srate, unsigned procSmpCnt, unsigned upFact, unsigned dnFact ); 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 ); cmRC_t cmSRCExec( cmSRC* p, const cmSample_t* sp, unsigned sn );
void cmSRCTest(); void cmSRCTest();
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmConstQ file_desc:"Contant-Q transform." kw:[proc] }
typedef struct typedef struct
{ {
cmObj obj; 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 cmConstQInit( cmConstQ* p, double srate, unsigned minMidiPitch, unsigned maxMidiPitch, unsigned binsPerOctave, double thresh );
cmRC_t cmConstQFinal( cmConstQ* p ); cmRC_t cmConstQFinal( cmConstQ* p );
cmRC_t cmConstQExec( cmConstQ* p, const cmComplexR_t* ftV, unsigned binCnt ); cmRC_t cmConstQExec( cmConstQ* p, const cmComplexR_t* ftV, unsigned binCnt );
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmTuneHpcp file_desc:"Generate a tuned chromagram." kw:[proc]}
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -545,10 +518,10 @@ extern "C" {
cmRC_t cmTunedHpcpFinal( cmHpcp* p ); cmRC_t cmTunedHpcpFinal( cmHpcp* p );
cmRC_t cmTunedHpcpExec( cmHpcp* p, const cmComplexR_t* constQBinPtr, unsigned constQBinCnt ); cmRC_t cmTunedHpcpExec( cmHpcp* p, const cmComplexR_t* constQBinPtr, unsigned constQBinCnt );
cmRC_t cmTunedHpcpTuneAndFilter( cmHpcp* p); cmRC_t cmTunedHpcpTuneAndFilter( cmHpcp* p);
//------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmBeatHist file_desc:"Generate a beat candidate histogram." kw:[proc]}
struct cmFftRR_str; struct cmFftRR_str;
struct cmIFftRR_str; struct cmIFftRR_str;
@ -579,9 +552,11 @@ extern "C" {
cmRC_t cmBeatHistFinal( cmBeatHist* p ); cmRC_t cmBeatHistFinal( cmBeatHist* p );
cmRC_t cmBeatHistExec( cmBeatHist* p, cmSample_t df ); cmRC_t cmBeatHistExec( cmBeatHist* p, cmSample_t df );
cmRC_t cmBeatHistCalc( cmBeatHist* p ); 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 typedef struct
{ {
cmObj obj; cmObj obj;
@ -639,9 +614,11 @@ extern "C" {
void cmGmmPrint( cmGmm_t* p, bool detailsFl ); void cmGmmPrint( cmGmm_t* p, bool detailsFl );
void cmGmmTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); 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 typedef struct
{ {
cmObj obj; cmObj obj;
@ -652,9 +629,7 @@ extern "C" {
cmReal_t* aM; // aM[ N x N] transition probability mtx cmReal_t* aM; // aM[ N x N] transition probability mtx
cmGmm_t** bV; // bV[ N ] observation probability mtx (array of pointers to GMM's) cmGmm_t** bV; // bV[ N ] observation probability mtx (array of pointers to GMM's)
cmReal_t* bM; // bM[ N,T] state-observation probability matrix cmReal_t* bM; // bM[ N,T] state-observation probability matrix
cmMtxFile* mfp; cmMtxFile* mfp;
} cmChmm_t; } cmChmm_t;
// Continuous HMM consisting of stateN states where the observations // Continuous HMM consisting of stateN states where the observations
@ -706,10 +681,11 @@ extern "C" {
void cmChmmPrint( cmChmm_t* p ); void cmChmmPrint( cmChmm_t* p );
void cmChmmTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); 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 typedef struct
{ {
@ -746,6 +722,8 @@ extern "C" {
cmRC_t cmChordFinal( cmChord* p ); cmRC_t cmChordFinal( cmChord* p );
void cmChordTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); void cmChordTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
//------------------------------------------------------------------------------------------------------------
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5950,6 +5950,7 @@ cmSpecDist_t* cmSpecDistAlloc( cmCtx* ctx,cmSpecDist_t* ap, unsigned procSmpCnt,
//p->iSpecVa = cmVectArrayAlloc(ctx,kRealVaFl); //p->iSpecVa = cmVectArrayAlloc(ctx,kRealVaFl);
//p->oSpecVa = cmVectArrayAlloc(ctx,kRealVaFl); //p->oSpecVa = cmVectArrayAlloc(ctx,kRealVaFl);
p->statVa = cmVectArrayAlloc(ctx,kDoubleVaFl);
if( procSmpCnt != 0 ) if( procSmpCnt != 0 )
{ {
@ -5971,6 +5972,7 @@ cmRC_t cmSpecDistFree( cmSpecDist_t** pp )
cmSpecDistFinal(p); cmSpecDistFinal(p);
//cmVectArrayFree(&p->iSpecVa); //cmVectArrayFree(&p->iSpecVa);
//cmVectArrayFree(&p->oSpecVa); //cmVectArrayFree(&p->oSpecVa);
cmVectArrayFree(&p->statVa);
cmMemPtrFree(&p->hzV); cmMemPtrFree(&p->hzV);
cmMemPtrFree(&p->iSpecM); cmMemPtrFree(&p->iSpecM);
cmMemPtrFree(&p->oSpecM); cmMemPtrFree(&p->oSpecM);
@ -6095,6 +6097,7 @@ cmRC_t cmSpecDistFinal(cmSpecDist_t* p )
//cmVectArrayWrite(p->iSpecVa, "/home/kevin/temp/frqtrk/iSpec.va"); //cmVectArrayWrite(p->iSpecVa, "/home/kevin/temp/frqtrk/iSpec.va");
//cmVectArrayWrite(p->oSpecVa, "/home/kevin/temp/expand/oSpec.va"); //cmVectArrayWrite(p->oSpecVa, "/home/kevin/temp/expand/oSpec.va");
//cmVectArrayWrite(p->statVa, "/Users/kevin/temp/kc/state.va");
cmPvAnlFree(&p->pva); cmPvAnlFree(&p->pva);
cmPvSynFree(&p->pvs); 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> -abs(abs(X1m+thresh)-(X1m+thresh)) - thresh
// octave> ans = -64 -62 -60 -60 // octave> ans = -64 -62 -60 -60
/*
unsigned i=0; unsigned i=0;
for(i=0; i<binCnt; ++i) 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; 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_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, p->pva->magV, -1000.0 );
//cmVOR_AmplToDbVV(X1m, p->pva->binCnt, X1m, -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 ); cmVOR_DbToAmplVV(X1m, p->pva->binCnt, X1m );
// run and apply the tracker/supressor // run and apply the tracker/supressor
//cmFrqTrkExec(p->ft, X1m, p->pva->phsV, NULL ); //cmFrqTrkExec(p->ft, X1m, p->pva->phsV, NULL );
//cmVOR_MultVV(X1m, p->pva->binCnt,p->ft->aV ); //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; 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)); cmVOR_MultVS(X1m,p->pva->binCnt,cmMin(4.0,p->ogain));

118
cmProc2.h
View File

@ -5,7 +5,11 @@
extern "C" { extern "C" {
#endif #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 // 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 // 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 // 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 cmArrayPtr( type, p ) (type*)(p)->ptr
#define cmArrayCount( p ) (p)->eleCnt #define cmArrayCount( p ) (p)->eleCnt
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmAudioFileWr file_desc:"Audio file writer" kw:[proc]}
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -72,8 +78,10 @@ extern "C" {
cmRC_t cmAudioFileWrFinal( cmAudioFileWr* p ); cmRC_t cmAudioFileWrFinal( cmAudioFileWr* p );
cmRC_t cmAudioFileWrExec( cmAudioFileWr* p, unsigned chIdx, const cmSample_t* sp, unsigned sn ); cmRC_t cmAudioFileWrExec( cmAudioFileWr* p, unsigned chIdx, const cmSample_t* sp, unsigned sn );
void cmAudioFileWrTest(); void cmAudioFileWrTest();
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmMatrixBuf file_desc:"Store and recall real values in matrix form." kw:[proc]}
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -98,6 +106,9 @@ extern "C" {
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmSigGen file_desc:"Generate periodic and noise signals." kw:[proc]}
enum enum
{ {
@ -139,6 +150,9 @@ extern "C" {
cmRC_t cmSigGenExec( cmSigGen* p ); cmRC_t cmSigGenExec( cmSigGen* p );
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmDelay file_desc:"Fixed length audio delay." kw:[proc]}
typedef struct typedef struct
{ {
cmObj* obj; cmObj* obj;
@ -160,8 +174,10 @@ extern "C" {
cmRC_t cmDelayAdvance( cmDelay* p, unsigned sn ); cmRC_t cmDelayAdvance( cmDelay* p, unsigned sn );
cmRC_t cmDelayExec( cmDelay* p, const cmSample_t* sp, unsigned sn, bool bypassFl ); cmRC_t cmDelayExec( cmDelay* p, const cmSample_t* sp, unsigned sn, bool bypassFl );
void cmDelayTest(); void cmDelayTest();
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmFIR file_desc:"Finite impulse response filter." kw:[proc]}
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -194,8 +210,9 @@ extern "C" {
void cmFIRTest1( cmCtx* ctx ); 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 cmSample_t (*cmFuncFiltPtr_t)( const cmSample_t* sp, unsigned sn, void* userPtr );
typedef struct typedef struct
@ -217,8 +234,10 @@ extern "C" {
cmRC_t cmFuncFilterFinal( cmFuncFilter* p ); cmRC_t cmFuncFilterFinal( cmFuncFilter* p );
cmRC_t cmFuncFilterExec( cmFuncFilter* p, const cmSample_t* sp, unsigned sn ); cmRC_t cmFuncFilterExec( cmFuncFilter* p, const cmSample_t* sp, unsigned sn );
void cmFuncFilterTest(); void cmFuncFilterTest();
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmDhmm file_desc:"Discrete observation HMM" kw:[proc]}
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -245,6 +264,9 @@ extern "C" {
void cmDhmmTest(); void cmDhmmTest();
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmConvolve file_desc:"Convolve a signal with an impulse response." kw:[proc]}
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -285,6 +307,9 @@ extern "C" {
cmRC_t cmConvolveTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); 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 typedef struct
{ {
cmObj obj; cmObj obj;
@ -304,6 +329,8 @@ extern "C" {
void cmBfccTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH ); 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 typedef struct
{ {
cmObj obj; cmObj obj;
@ -324,7 +351,10 @@ extern "C" {
cmRC_t cmCepsFinal( cmCeps* p ); cmRC_t cmCepsFinal( cmCeps* p );
cmRC_t cmCepsExec( cmCeps* p, const cmReal_t* magV, const cmReal_t* phsV, unsigned binCnt ); 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 typedef struct
{ {
@ -355,9 +385,10 @@ extern "C" {
cmRC_t cmOlaExecS( cmOla* p, const cmSample_t* xV, unsigned xN ); cmRC_t cmOlaExecS( cmOla* p, const cmSample_t* xV, unsigned xN );
cmRC_t cmOlaExecR( cmOla* p, const cmReal_t* xV, unsigned xN ); cmRC_t cmOlaExecR( cmOla* p, const cmReal_t* xV, unsigned xN );
const cmSample_t* cmOlaExecOut(cmOla* p ); const cmSample_t* cmOlaExecOut(cmOla* p );
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmPhsToFrq file_desc:"Given STFT phase spectrum frames return the instantaneous frequency." kw:[proc]}
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
typedef struct typedef struct
@ -380,8 +411,10 @@ extern "C" {
cmRC_t cmPhsToFrqFinal(cmPhsToFrq* p ); cmRC_t cmPhsToFrqFinal(cmPhsToFrq* p );
cmRC_t cmPhsToFrqExec( cmPhsToFrq* p, const cmReal_t* phsV ); cmRC_t cmPhsToFrqExec( cmPhsToFrq* p, const cmReal_t* phsV );
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmPvAnl file_desc:"Perform the phase-vocoder analysis stage." kw:[proc]}
enum enum
{ {
@ -420,6 +453,8 @@ extern "C" {
bool cmPvAnlExec( cmPvAnl* p, const cmSample_t* x, unsigned xN ); bool cmPvAnlExec( cmPvAnl* p, const cmSample_t* x, unsigned xN );
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmPvSyn file_desc:"Perform the phase-vocoder synthesis stage." kw:[proc]}
typedef struct typedef struct
{ {
@ -451,11 +486,10 @@ extern "C" {
cmRC_t cmPvSynExec( cmPvSyn* p, const cmReal_t* magV, const cmReal_t* phsV ); cmRC_t cmPvSynExec( cmPvSyn* p, const cmReal_t* magV, const cmReal_t* phsV );
const cmSample_t* cmPvSynExecOut(cmPvSyn* p ); const cmSample_t* cmPvSynExecOut(cmPvSyn* p );
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmMidiSynth file_desc:"Synthesis independent MIDI synthesizer control structure." kw:[proc]}
// callback selector values // callback selector values
enum enum
{ {
@ -532,8 +566,10 @@ extern "C" {
cmRC_t cmMidiSynthOnMidi(cmMidiSynth* p, const cmMidiPacket_t* pktArray, unsigned pktCnt ); cmRC_t cmMidiSynthOnMidi(cmMidiSynth* p, const cmMidiPacket_t* pktArray, unsigned pktCnt );
cmRC_t cmMidiSynthExec( cmMidiSynth* p, cmSample_t** outChArray, unsigned outChCnt ); 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 // state id's
enum enum
@ -568,6 +604,8 @@ extern "C" {
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmWtVoiceBank file_desc:"A bank of cmWtVoice oscillator for use with cmMidiSynth." kw:[proc]}
typedef struct typedef struct
{ {
@ -596,8 +634,9 @@ extern "C" {
int cmWtVoiceBankExec( cmWtVoiceBank* p, struct cmMidiVoice_str* voicePtr, unsigned sel, cmSample_t* chArray[], unsigned chCnt ); 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 typedef struct
{ {
@ -620,8 +659,10 @@ extern "C" {
// If less than outN samples are available then the remaining samples are set to 0. // 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 ); 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. // Multi-delay. Each of the taps of this delay operates as a independent delay with feedback.
// Delay line specification. // Delay line specification.
@ -657,6 +698,9 @@ extern "C" {
void cmMDelayReport( cmMDelay* p, cmRpt_t* rpt ); void cmMDelayReport( cmMDelay* p, cmRpt_t* rpt );
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmAudioSegPlayer file_desc:"Buffer and playback an arbitrary number of audio signals." kw:[proc]}
enum enum
{ {
kEnableAspFl = 0x01, kEnableAspFl = 0x01,
@ -696,9 +740,9 @@ extern "C" {
cmRC_t cmAudioSegPlayerEnable( cmAudioSegPlayer* p, unsigned id, bool enableFl, unsigned outSmpIdx ); cmRC_t cmAudioSegPlayerEnable( cmAudioSegPlayer* p, unsigned id, bool enableFl, unsigned outSmpIdx );
cmRC_t cmAudioSegPlayerReset( cmAudioSegPlayer* p ); cmRC_t cmAudioSegPlayerReset( cmAudioSegPlayer* p );
cmRC_t cmAudioSegPlayerExec( cmAudioSegPlayer* p, cmSample_t** outChPtr, unsigned chCnt, unsigned outSmpCnt ); 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 ); 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 ); cmRC_t cmCluster0Exec( cmCluster0* p, const cmReal_t* v, unsigned vn );
*/ */
//------------------------------------------------------------------------------------------------------------ //( { label:cmNmf file_desc:"Non-negative matrix factorization implementation." kw:[proc]}
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -770,8 +814,10 @@ extern "C" {
// //
cmRC_t cmNmfExec( cmNmf_t* p, const cmReal_t* v, unsigned cn ); 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. // cmVectArray buffers row vectors of arbitrary length in memory.
// The buffers may then be access using the cmVectArrayGetXXX() functions. // The buffers may then be access using the cmVectArrayGetXXX() functions.
// The entire contents of the file may be written to a file using atVectArrayWrite(). // 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 cmVectArrayFormVectColU( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt, unsigned colIdx, unsigned** vRef, unsigned* vnRef );
cmRC_t cmVectArrayTest( cmCtx* ctx, const char* fn, bool genFl ); cmRC_t cmVectArrayTest( cmCtx* ctx, const char* fn, bool genFl );
//----------------------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmWhFilt file_desc:"Spectral whitening filter." kw:[proc]}
// Spectral whitening filter. // Spectral whitening filter.
// Based on: Klapuri, A., 2006: Multiple fundamental frequency estimation by summing // Based on: Klapuri, A., 2006: Multiple fundamental frequency estimation by summing
// harmonic amplitudes. // harmonic amplitudes.
@ -967,6 +1016,9 @@ extern "C" {
cmRC_t cmWhFiltExec( cmWhFilt* p, const cmReal_t* xV, cmReal_t* yV, unsigned xyN ); 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 typedef enum
{ {
kNoStateFrqTrkId, kNoStateFrqTrkId,
@ -1089,8 +1141,10 @@ extern "C" {
cmRC_t cmFrqTrkExec( cmFrqTrk* p, const cmReal_t* magV, const cmReal_t* phsV, const cmReal_t* hzV ); cmRC_t cmFrqTrkExec( cmFrqTrk* p, const cmReal_t* magV, const cmReal_t* phsV, const cmReal_t* hzV );
void cmFrqTrkPrint( cmFrqTrk* p ); void cmFrqTrkPrint( cmFrqTrk* p );
//------------------------------------------------------------------------------------------------------------ //-----------------------------------------------------------------------------------------------------------------------
//)
//( { label:cmFbCtl file_desc:"Perform acoustic feedback control by attenuating loud sinusoid signals." kw:[proc]}
typedef struct typedef struct
{ {
double srate; double srate;
@ -1122,7 +1176,10 @@ extern "C" {
cmRC_t cmFbCtlFinal(cmFbCtl_t* p ); cmRC_t cmFbCtlFinal(cmFbCtl_t* p );
cmRC_t cmFbCtlExec( cmFbCtl_t* p, const cmReal_t* xV ); cmRC_t cmFbCtlExec( cmFbCtl_t* p, const cmReal_t* xV );
//----------------------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmExpander file_desc:"Expander implementation for audio dynamics processing." kw:[proc]}
typedef struct typedef struct
{ {
@ -1148,7 +1205,11 @@ extern "C" {
cmRC_t cmExpanderFinal( cmExpander* p ); cmRC_t cmExpanderFinal( cmExpander* p );
cmRC_t cmExpanderExec( cmExpander* p, cmSample_t* x, cmSample_t* y, unsigned xyN ); cmRC_t cmExpanderExec( cmExpander* p, cmSample_t* x, cmSample_t* y, unsigned xyN );
cmRC_t cmExpanderExecD( cmExpander* p, double* x, double* 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 typedef struct
{ {
cmObj obj; cmObj obj;
@ -1166,8 +1227,10 @@ extern "C" {
cmRC_t cmExpanderBankExec( cmExpanderBank* p, cmSample_t* x, unsigned bandN ); cmRC_t cmExpanderBankExec( cmExpanderBank* p, cmSample_t* x, unsigned bandN );
cmRC_t cmExpanderBankExecD( cmExpanderBank* p, double* 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 enum
{ {
@ -1224,6 +1287,7 @@ extern "C" {
cmReal_t aeUnit; cmReal_t aeUnit;
cmReal_t ogain; cmReal_t ogain;
cmReal_t ogain0;
unsigned phaseModIndex; unsigned phaseModIndex;
@ -1236,6 +1300,7 @@ extern "C" {
cmReal_t* oSpecM; // oSpecMtx[hN binN] cmReal_t* oSpecM; // oSpecMtx[hN binN]
cmReal_t* oSpecV; // mean of rows of oSpecM cmReal_t* oSpecV; // mean of rows of oSpecM
cmVectArray_t* oSpecVa; cmVectArray_t* oSpecVa;
cmVectArray_t* statVa;
} cmSpecDist_t; } cmSpecDist_t;
@ -1246,8 +1311,11 @@ extern "C" {
cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn ); cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn );
const cmSample_t* cmSpecDistOut( cmSpecDist_t* p ); 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 // Write a binary matrix file in the format acceppted by the octave function readBinFile.m
typedef struct cmBinMtxFile_str typedef struct cmBinMtxFile_str
@ -1289,7 +1357,7 @@ extern "C" {
// Use cmBinMtxFileSize() to determine the buffer size prior to calling this function. // Use cmBinMtxFileSize() to determine the buffer size prior to calling this function.
// colCntV[colCnt] is optional. // colCntV[colCnt] is optional.
cmRC_t cmBinMtxFileRead( cmCtx_t* ctx, const cmChar_t* fn, unsigned rowCnt, unsigned colCnt, unsigned eleByteCnt, void* buf, unsigned* colCntV ); cmRC_t cmBinMtxFileRead( cmCtx_t* ctx, const cmChar_t* fn, unsigned rowCnt, unsigned colCnt, unsigned eleByteCnt, void* buf, unsigned* colCntV );
//)

View File

@ -4,6 +4,10 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 typedef struct
{ {
@ -45,7 +49,9 @@ extern "C" {
cmRC_t cmPitchShiftFinal(cmPitchShift* p ); cmRC_t cmPitchShiftFinal(cmPitchShift* p );
cmRC_t cmPitchShiftExec( cmPitchShift* p, const cmSample_t* x, cmSample_t* y, unsigned n, double shiftRatio, bool bypassFl ); 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 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 ); 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 typedef struct
{ {
cmObj obj; cmObj obj;
@ -115,8 +123,9 @@ extern "C" {
cmRC_t cmGateDetectFinal(cmGateDetect* p ); cmRC_t cmGateDetectFinal(cmGateDetect* p );
cmRC_t cmGateDetectExec( cmGateDetect* p, const cmSample_t* x, unsigned xn ); 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 typedef struct
{ {
unsigned medCnt; // length of the median filter unsigned medCnt; // length of the median filter
@ -171,7 +180,10 @@ extern "C" {
void cmGateDetectSetOnThreshDb2( cmGateDetect2* p, cmReal_t db ); void cmGateDetectSetOnThreshDb2( cmGateDetect2* p, cmReal_t db );
void cmGateDetectSetOffThreshDb2( 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. // 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 ); void cmAutoGainPrint( cmAutoGain* p, cmRpt_t* rpt );
//======================================================================================================================= //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmChCfg file_desc:"Configure a 'fluxo' pickup channel." kw:[proc fluxo]}
typedef struct typedef struct
{ {
unsigned ch; unsigned ch;
@ -262,7 +277,10 @@ extern "C" {
unsigned cmChCfgChannelCount( cmCtx_t* ctx, const cmChar_t* fn, unsigned* nsChCntPtr ); unsigned cmChCfgChannelCount( cmCtx_t* ctx, const cmChar_t* fn, unsigned* nsChCntPtr );
unsigned cmChCfgChannelIndex( cmCtx_t* ctx, const cmChar_t* fn, unsigned chIdx ); 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 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 cmChordDetectExec( cmChordDetect* p, unsigned procSmpCnt, const bool* gateV, const cmReal_t* rmsV, unsigned chCnt );
cmRC_t cmChordDetectSetSpanMs( cmChordDetect* p, cmReal_t maxTimeSpanMs ); 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 // 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 // fader - which just calculates the fade gain but does not actually apply it
// to the audio signal - unless you use cmXfaderExecAudio() // to the audio signal - unless you use cmXfaderExecAudio()
@ -335,7 +356,10 @@ extern "C" {
void cmXfaderAllOff( cmXfader* p ); void cmXfaderAllOff( cmXfader* p );
void cmXfaderJumpToDestinationGain( cmXfader* p ); // jump to dest. gain based on gate state 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 // 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 // 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 // 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 ); 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 ); 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; struct cmIDelay_str;
typedef struct typedef struct
{ {
@ -384,7 +411,10 @@ extern "C" {
void cmCombFiltSetAlpha( cmCombFilt* p, cmReal_t alpha ); void cmCombFiltSetAlpha( cmCombFilt* p, cmReal_t alpha );
cmRC_t cmCombFiltSetHz( cmCombFilt* p, cmReal_t hz ); cmRC_t cmCombFiltSetHz( cmCombFilt* p, cmReal_t hz );
//======================================================================================================================= //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmDcFilt file_desc:"DC Filter algorithm." kw:[proc]}
typedef struct typedef struct
{ {
@ -402,9 +432,10 @@ extern "C" {
cmRC_t cmDcFiltFinal( cmDcFilt* p ); cmRC_t cmDcFiltFinal( cmDcFilt* p );
cmRC_t cmDcFiltExec( cmDcFilt* p, const cmSample_t* x, cmSample_t* y, unsigned n ); 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 typedef struct cmIDelay_str
{ {
@ -429,7 +460,10 @@ extern "C" {
cmRC_t cmIDelaySetTapMs( cmIDelay* p, unsigned tapIdx, cmReal_t tapMs ); 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. // This object sequentially assigns channels to groups when their gates go high.
// 'chsPerGroup' channels will be assigned to each group. No channel will be // '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. // and groups that will be removed on the next cycle have their 'releaseFl' set.
cmRC_t cmGroupSelExec( cmGroupSel* p ); 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. // Route N of M input channels to N output channels.
// The N channels are selected from the first N gates to go high. // 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 ); 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 }; enum { kDlyAdsrId, kAtkAdsrId, kDcyAdsrId, kSusAdsrId, kRlsAdsrId, kDoneAdsrId };
@ -546,9 +586,6 @@ extern "C" {
cmReal_t susLevel; cmReal_t susLevel;
int rlsSmp; int rlsSmp;
unsigned state; // current state unsigned state; // current state
int durSmp; // time in current state int durSmp; // time in current state
cmReal_t level; // current level cmReal_t level; // current level
@ -575,7 +612,10 @@ extern "C" {
void cmAdsrSetLevel( cmAdsr* p, cmReal_t level, unsigned id ); void cmAdsrSetLevel( cmAdsr* p, cmReal_t level, unsigned id );
void cmAdsrReport( cmAdsr* p, cmRpt_t* rpt ); void cmAdsrReport( cmAdsr* p, cmRpt_t* rpt );
//======================================================================================================================= //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmCompressor file_desc:"Audio dynamics compressor algorithm." kw:[proc]}
enum { kAtkCompId, kRlsCompId }; enum { kAtkCompId, kRlsCompId };
typedef struct typedef struct
@ -616,7 +656,11 @@ extern "C" {
void cmCompressorSetThreshDb( cmCompressor* p, cmReal_t thresh ); void cmCompressorSetThreshDb( cmCompressor* p, cmReal_t thresh );
void cmCompressorSetRmsWndMs( cmCompressor* p, cmReal_t ms ); 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. // BiQuad Audio Eq's based on Robert Bristow-Johnson's recipes.
// http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt // 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 ); 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 typedef struct
{ {
cmObj obj; 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 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 cmDistDsFinal( cmDistDs* p );
cmRC_t cmDistDsExec( cmDistDs* p, const cmSample_t* x, cmSample_t* y, unsigned n ); cmRC_t cmDistDsExec( cmDistDs* p, const cmSample_t* x, cmSample_t* y, unsigned n );
//------------------------------------------------------------------------------------------------------------
//)
//======================================================================================================================= //=======================================================================================================================
/* /*

View File

@ -2693,6 +2693,7 @@ typedef struct
_cmScModTypeMap_t _cmScModTypeArray[] = _cmScModTypeMap_t _cmScModTypeArray[] =
{ {
{ kDeclModTId, 0, "decl" },
{ kSetModTId, 1, "set" }, { kSetModTId, 1, "set" },
{ kLineModTId, 2, "line" }, { kLineModTId, 2, "line" },
{ kSetLineModTId, 3, "sline" }, { kSetLineModTId, 3, "sline" },
@ -3164,6 +3165,7 @@ cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep )
switch( ep->typeId ) switch( ep->typeId )
{ {
case kDeclModTId:
case kSetModTId: case kSetModTId:
break; break;
@ -3220,6 +3222,11 @@ bool _cmScModExec( cmScModulator* p, cmScModVar_t* vp )
switch( vp->entry->typeId ) switch( vp->entry->typeId )
{ {
case kDeclModTId:
sendFl = false;
fl = true;
break;
case kSetModTId: case kSetModTId:
{ {
if((rc = _cmScModGetParam(p,&vp->entry->beg,&vp->value)) != cmOkRC ) if((rc = _cmScModGetParam(p,&vp->entry->beg,&vp->value)) != cmOkRC )

View File

@ -5,11 +5,12 @@
extern "C" { extern "C" {
#endif #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 }; enum { kEdMinIdx, kEdSubIdx, kEdDelIdx, kEdInsIdx, kEdCnt };
typedef struct typedef struct
@ -87,7 +88,10 @@ extern "C" {
// Main test function. // Main test function.
void ed_main(); void ed_main();
//======================================================================================================================= //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmScoreMatch file_desc:"Event oriented local score matching algorithm based on edit distance." kw:[proc] }
enum enum
{ {
kSmMinIdx, // kSmMinIdx, //
@ -200,9 +204,10 @@ extern "C" {
// necessarily an error. // necessarily an error.
cmRC_t cmScMatchExec( cmScMatch* p, unsigned locIdx, unsigned locN, const cmScMatchMidi_t* midiV, unsigned midiN, double min_cost ); 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 typedef struct
{ {
unsigned locIdx; // index into cmScMatch_t.loc[] unsigned locIdx; // index into cmScMatch_t.loc[]
@ -246,8 +251,6 @@ extern "C" {
bool printFl; bool printFl;
} cmScMatcher; } cmScMatcher;
cmScMatcher* cmScMatcherAlloc( cmScMatcher* cmScMatcherAlloc(
cmCtx* c, // Program context. cmCtx* c, // Program context.
cmScMatcher* p, // Existing cmScMatcher to reallocate or NULL to allocate a new cmScMatcher. cmScMatcher* p, // Existing cmScMatcher to reallocate or NULL to allocate a new cmScMatcher.
@ -310,7 +313,10 @@ extern "C" {
void cmScMatcherPrint( cmScMatcher* p ); void cmScMatcherPrint( cmScMatcher* p );
//======================================================================================================================= //------------------------------------------------------------------------------------------------------------
//)
//( { label:cmScMeas file_desc:"Measure and report some differences between the score and the performance." kw:[proc] }
typedef struct typedef struct
{ {
@ -391,7 +397,10 @@ extern "C" {
// notes in each marker region and the score. // notes in each marker region and the score.
void cmScAlignScanMarkers( cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH ); 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> Syntax: <loc> <mod> <var> <type> <params>
<loc> - score location <loc> - score location
@ -421,6 +430,7 @@ extern "C" {
enum enum
{ {
kInvalidModTId, 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 kSetModTId, // set variable to parray[0] at scLocIdx
kLineModTId, // linear ramp variable to parray[0] over parray[1] seconds 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 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 cmScModulatorExec( cmScModulator* p, unsigned scLocIdx );
cmRC_t cmScModulatorDump( cmScModulator* p ); 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. // 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 cmRecdPlayBeginFade( cmRecdPlay* p, unsigned labelSymId, double fadeDbPerSec );
cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt ); cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,10 +5,11 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Process Library 5", kw:[proclib]}
//)
//=======================================================================================================================
// Goertzel Filter //( { label:cmGoertzel file_desc:"Goertzel tone detection filter." kw:[proc]}
//
typedef struct typedef struct
{ {
@ -38,10 +39,10 @@ extern "C" {
cmRC_t cmGoertzelSetFcHz( cmGoertzel* p, unsigned chIdx, double hz ); cmRC_t cmGoertzelSetFcHz( cmGoertzel* p, unsigned chIdx, double hz );
cmRC_t cmGoertzelExec( cmGoertzel* p, const cmSample_t* in, unsigned procSmpCnt, double* outV, unsigned chCnt ); cmRC_t cmGoertzelExec( cmGoertzel* p, const cmSample_t* in, unsigned procSmpCnt, double* outV, unsigned chCnt );
//------------------------------------------------------------------------------------------------------------
//)
//======================================================================================================================= //( { label:cmGoldCode file_desc:"Gold code random generator." kw:[proc]}
// Gold Code Signal Generator
//
typedef struct typedef struct
{ {
@ -110,9 +111,10 @@ extern "C" {
cmRC_t cmGoldSigTest( cmCtx* ctx ); 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() // Flags for use with the 'flags' argument to cmPhatAlloc()
enum enum
@ -192,9 +194,10 @@ extern "C" {
cmRC_t cmPhatWrite( cmPhat_t* p, const char* dirStr ); 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 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 cmReflectCalcExec( cmReflectCalc_t* p, const cmSample_t* xV, cmSample_t* yV, unsigned xyN );
cmRC_t cmReflectCalcWrite( cmReflectCalc_t* p, const char* dirStr ); cmRC_t cmReflectCalcWrite( cmReflectCalc_t* p, const char* dirStr );
//======================================================================================================================= //------------------------------------------------------------------------------------------------------------
// //)
//
//( { label:cmNlms file_desc:"Normalized least mean squares echo canceller." kw:[proc]}
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
@ -260,6 +265,7 @@ extern "C" {
void cmNlmsEcSetMu( cmNlmsEc_t* p, float mu ); void cmNlmsEcSetMu( cmNlmsEc_t* p, float mu );
void cmNlmsEcSetDelayN( cmNlmsEc_t* p, unsigned delayN ); void cmNlmsEcSetDelayN( cmNlmsEc_t* p, unsigned delayN );
void cmNlmsEcSetIrN( cmNlmsEc_t* p, unsigned irN ); void cmNlmsEcSetIrN( cmNlmsEc_t* p, unsigned irN );
//)
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -5,7 +5,7 @@
extern "C" { extern "C" {
#endif #endif
/* /*( { file_desc:"Base class for all 'proc' objects." kw:[proclib] }
The first field in all objects must be an cmObj record. 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)) #define cmMtxFileRealExecN(f,p,n,s) cmMtxFileDoubleExec((f),(p),(n),(s))
#endif #endif
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,6 +5,7 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Restricted Bolzmann Machine object." kw:[model] }
enum enum
{ {
kOkRbmRC = cmOkRC, kOkRbmRC = cmOkRC,
@ -38,6 +39,8 @@ enum
void cmRbmBinaryTest(cmCtx_t* ctx); void cmRbmBinaryTest(cmCtx_t* ctx);
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -11,7 +11,7 @@ cmRpt_t cmRptNull = { NULL, NULL, NULL };
void _cmDefaultPrint( void* userPtr, const cmChar_t* text ) void _cmDefaultPrint( void* userPtr, const cmChar_t* text )
{ {
if( text != NULL ) if( text != NULL )
fputs(text,stdin); fputs(text,stdout);
} }
void _cmDefaultError( void* userPtr, const cmChar_t* text ) void _cmDefaultError( void* userPtr, const cmChar_t* text )

View File

@ -5,12 +5,10 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 // The cmRpt class provides console output style output, like stdout and stderr
// for most of the classes in the cm library. // 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 cmRptVErrorf( cmRpt_t* rpt, const cmChar_t* fmt, va_list vl );
void cmRptErrorf( cmRpt_t* rpt, const cmChar_t* fmt, ... ); void cmRptErrorf( cmRpt_t* rpt, const cmChar_t* fmt, ... );
//) //)
//}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"rtSys networking component." kw:[rtsys network] }
/* /*
Nodes and Endpoints: Nodes and Endpoints:
--------------------- ---------------------
@ -202,6 +204,7 @@ extern "C" {
4) The symbol -=- in the flow chart implies a network transmission. 4) The symbol -=- in the flow chart implies a network transmission.
*/ */
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,5 +1,4 @@
// cmRtSys.h //( { file_desc:"Improved real-time audio processing engine." kw:[rtsys] }
// Implements a real-time audio processing engine.
// //
// The audio system is composed a collection of independent sub-systems. // The audio system is composed a collection of independent sub-systems.
// Each sub-system maintains a thread which runs asynchrounsly // Each sub-system maintains a thread which runs asynchrounsly
@ -48,10 +47,7 @@
// Messages arriving while the mutex is locked are queued and // Messages arriving while the mutex is locked are queued and
// delivered to the DSP procedure at the end of the DSP execution // delivered to the DSP procedure at the end of the DSP execution
// procedure. // procedure.
// //)
// Usage example and testing code:
// See cmRtSysTest().
// \snippet cmRtSys.c cmRtSysTest
#ifndef cmRtSys_h #ifndef cmRtSys_h
#define cmRtSys_h #define cmRtSys_h
@ -60,6 +56,7 @@
extern "C" { extern "C" {
#endif #endif
//(
// Audio system result codes // Audio system result codes
enum enum
{ {
@ -329,7 +326,7 @@ extern "C" {
cmRtRC_t cmRtSysNetReport( cmRtSysH_t h ); cmRtRC_t cmRtSysNetReport( cmRtSysH_t h );
cmRtRC_t cmRtSysNetReportSyncEnable( cmRtSysH_t h, bool enableFl ); cmRtRC_t cmRtSysNetReportSyncEnable( cmRtSysH_t h, bool enableFl );
cmRtRC_t cmRtSysNetGetHandle( cmRtSysH_t h, unsigned rtSubIdx, cmRtNetH_t* hp ); cmRtRC_t cmRtSysNetGetHandle( cmRtSysH_t h, unsigned rtSubIdx, cmRtNetH_t* hp );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -4,6 +4,7 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"rtSys message contants and data structures." kw:[rtsys] }
// Reserved DSP message selector id's (second field of all // Reserved DSP message selector id's (second field of all
// host<->audio system messages) // host<->audio system messages)
@ -105,6 +106,7 @@ extern "C" {
// char msg[ msgByteCnt ] // char msg[ msgByteCnt ]
} cmRtNetMsg_t; } cmRtNetMsg_t;
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,14 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//{ //( { file_desc:" An API for serializing data structures into byte streams and then deserializing them back into data structures." kw:[base]}
//(
// cmSerialize is an API for serializing data structures into
// byte streams and then deserializing them back into data structures.
//
//)
//(
// Result codes // Result codes
enum enum
@ -299,7 +293,6 @@ extern "C" {
cmSrRC_t cmSrTest( cmCtx_t* ctx ); cmSrRC_t cmSrTest( cmCtx_t* ctx );
//) //)
//}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Push-down stack data structure for binary blobs." kw:[container] }
enum enum
{ {
kOkStRC = cmOkRC, kOkStRC = cmOkRC,
@ -62,6 +64,7 @@ extern "C" {
#define cmStackEle(h,t,i) (*(t*)cmStackGet(h,i)) #define cmStackEle(h,t,i) (*(t*)cmStackGet(h,i))
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -6,6 +6,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"String stream text sink." kw:[text] }
enum enum
{ {
kOkSsRC = cmOkRC, kOkSsRC = cmOkRC,
@ -34,6 +36,8 @@ extern "C" {
void* cmOStrStreamAllocBuf( cmStrStreamH_t h ); void* cmOStrStreamAllocBuf( cmStrStreamH_t h );
cmChar_t* cmOStrStreamAllocText( cmStrStreamH_t h ); cmChar_t* cmOStrStreamAllocText( cmStrStreamH_t h );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -4,13 +4,8 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
//{ //( { file_desc:"Symbol table object." kw:[base] }
//(
// Symbol table component.
//)
//(
typedef cmHandle_t cmSymTblH_t; typedef cmHandle_t cmSymTblH_t;
extern cmSymTblH_t cmSymTblNullHandle; extern cmSymTblH_t cmSymTblNullHandle;
@ -61,7 +56,6 @@ extern "C" {
void cmSymTblTest(cmCtx_t* ctx); void cmSymTblTest(cmCtx_t* ctx);
//) //)
//}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,6 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Read a 'ctags' output file." kw:[file] }
// Read a ctags file generated by: // Read a ctags file generated by:
// //
// ctags --c-kinds=+p --fields=+n file.h // ctags --c-kinds=+p --fields=+n file.h
@ -61,6 +63,8 @@ extern "C" {
cmTfRC_t cmTfTest( cmCtx_t* ctx, const cmChar_t* fn ); cmTfRC_t cmTfTest( cmCtx_t* ctx, const cmChar_t* fn );
//)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -5,7 +5,8 @@
extern "C" { extern "C" {
#endif #endif
/* /*( { file_desc:"Task manager for controlling and monitoring tasks running in independent thread." kw:[parallel]}
Usage: Usage:
1) Use cmTaskMgrInstall() to register a worker function 1) Use cmTaskMgrInstall() to register a worker function
(cmTaskMgrFunc_t) with the task manager. (cmTaskMgrFunc_t) with the task manager.
@ -353,6 +354,7 @@ extern "C" {
cmTmWorkerRC_t cmTaskMgrWorkerMsgSend( cmTaskMgrFuncArg_t* a, const void* buf, unsigned bufByteCnt ); cmTmWorkerRC_t cmTaskMgrWorkerMsgSend( cmTaskMgrFuncArg_t* a, const void* buf, unsigned bufByteCnt );
cmTmRC_t cmTaskMgrTest(cmCtx_t* ctx); cmTmRC_t cmTaskMgrTest(cmCtx_t* ctx);
//)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,8 +5,8 @@
extern "C" { extern "C" {
#endif #endif
//{ //( { file_desc:"Text processing functions." kw:[text]}
//( //
// The cmText API supports two basic tasks: the generation of // The cmText API supports two basic tasks: the generation of
// formatted text into dynamic arrays and text to number parsing. // formatted text into dynamic arrays and text to number parsing.
// //
@ -297,7 +297,6 @@ extern "C" {
//) //)
//}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,9 +1,13 @@
#ifndef cmTextTemplate_h #ifndef cmTextTemplate_h
#define 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, kOkTtRC = cmOkRC,
kFileFailTtRC, kFileFailTtRC,
kLHeapFailTtRC, kLHeapFailTtRC,
@ -11,45 +15,47 @@ enum
kFindFailTtRC, kFindFailTtRC,
kInvalidTypeTtRC, kInvalidTypeTtRC,
kJsonFailTtRC kJsonFailTtRC
}; };
typedef cmHandle_t cmTtH_t; typedef cmHandle_t cmTtH_t;
typedef unsigned cmTtRC_t; typedef unsigned cmTtRC_t;
extern cmTtH_t cmTtNullHandle; extern cmTtH_t cmTtNullHandle;
// Initialize a template file. // Initialize a template file.
cmTtRC_t cmTextTemplateInitialize( cmCtx_t* ctx, cmTtH_t* hp, const cmChar_t* fn ); cmTtRC_t cmTextTemplateInitialize( cmCtx_t* ctx, cmTtH_t* hp, const cmChar_t* fn );
// Finalize a template file // Finalize a template file
cmTtRC_t cmTextTemplateFinalize( cmTtH_t* hp ); cmTtRC_t cmTextTemplateFinalize( cmTtH_t* hp );
// Return true if the template file is intialized. // Return true if the template file is intialized.
bool cmTextTemplateIsValid( cmTtH_t h ); bool cmTextTemplateIsValid( cmTtH_t h );
// Set the value of a template variable. // Set the value of a template variable.
// The node identified by { label,index, label, index ... } must // The node identified by { label,index, label, index ... } must
// be a variable node. The function will fail if a 'set' or 'text' node // be a variable node. The function will fail if a 'set' or 'text' node
// is identified. // is identified.
// Set 'value' to NULL to erase a previously set value. // 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, ... ); 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 // 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. // 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, ... ); cmTtRC_t cmTextTemplateRepeat( cmTtH_t h, const cmChar_t* label, unsigned index, ... );
// Write the template file. // Write the template file.
cmTtRC_t cmTextTemplateWrite( cmTtH_t h, const cmChar_t* fn ); cmTtRC_t cmTextTemplateWrite( cmTtH_t h, const cmChar_t* fn );
// Apply a template value JSON file to this template // Apply a template value JSON file to this template
cmTtRC_t cmTextTemplateApply( cmTtH_t h, const cmChar_t* fn ); 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. cmTtRC_t cmTextTemplateTest( cmCtx_t* ctx, const cmChar_t* fn );
void cmTtPrintTree( cmTtH_t h, cmRpt_t* rpt );
cmTtRC_t cmTextTemplateTest( cmCtx_t* ctx, const cmChar_t* fn );
//)
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -4,6 +4,7 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
//( { file_desc:"Threads and thread safe containers." kw:[parallel] }
typedef cmHandle_t cmThreadH_t; typedef cmHandle_t cmThreadH_t;
typedef unsigned cmThRC_t; typedef unsigned cmThRC_t;
@ -85,8 +86,10 @@ extern "C" {
void cmThreadSetWaitTimeOutMicros( cmThreadH_t h, unsigned usecs ); void cmThreadSetWaitTimeOutMicros( cmThreadH_t h, unsigned usecs );
void cmThreadTest( cmRpt_t* rpt ); void cmThreadTest( cmRpt_t* rpt );
//)
//( { label:cmThreadMutex file_desc:"Thread mutex object." kw[parallel]}
//============================================================================
typedef struct typedef struct
{ {
void* h; void* h;
@ -109,6 +112,9 @@ extern "C" {
cmThRC_t cmThreadMutexSignalCondVar( cmThreadMutexH_t h ); cmThRC_t cmThreadMutexSignalCondVar( cmThreadMutexH_t h );
//)
//( { label:cmTsQueue file_desc:"Thread safe message queue." kw[parallel]}
//============================================================================
// cmThread safe message queue. // cmThread safe message queue.
// //
@ -190,6 +196,9 @@ extern "C" {
bool cmTsQueueIsValid( cmTsQueueH_t h); 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. // Single producer / Single consumer thread-safe queue.
// These functions have identical semantics and return values // These functions have identical semantics and return values
@ -221,6 +230,9 @@ extern "C" {
bool cmTs1p1cIsValid( cmTs1p1cH_t h ); bool cmTs1p1cIsValid( cmTs1p1cH_t h );
//)
//( { label:cmThCAS file_desc:"Non-blocking primitive operations." kw[parallel]}
//============================================================================
// Thread safe compare-and-swap (actualy compare-and-test). // Thread safe compare-and-swap (actualy compare-and-test).
// Returns true if the *addr==new when the function returns // Returns true if the *addr==new when the function returns
@ -241,6 +253,9 @@ extern "C" {
void cmThUIntDecr( unsigned* addr, unsigned decr ); void cmThUIntDecr( unsigned* addr, unsigned decr );
void cmThFloatDecr(float* addr, float 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. // Multiple producer / Single consumer thread-safe queue.
// These functions have identical semantics and return values // These functions have identical semantics and return values
// to the same named cmTsQueueXXXX() calls above. // to the same named cmTsQueueXXXX() calls above.
@ -272,15 +287,17 @@ extern "C" {
bool cmTsMp1cIsValid( cmTsMp1cH_t h ); bool cmTsMp1cIsValid( cmTsMp1cH_t h );
// Sleep functions
void cmSleepUs( unsigned microseconds );
void cmSleepMs( unsigned milliseconds );
void cmTsQueueTest( cmRpt_t* rpt ); void cmTsQueueTest( cmRpt_t* rpt );
void cmTs1p1cTest( cmRpt_t* rpt ); void cmTs1p1cTest( cmRpt_t* rpt );
void cmTsMp1cTest( 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 #ifdef __cplusplus
} }
#endif #endif

Some files were not shown because too many files have changed in this diff Show More