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
cmSRC += src/libcm/app/cmOnset.c src/libcm/app/cmTimeLine.c src/libcm/app/cmScore.c src/libcm/app/cmScoreProc.c
cmHDR += src/libcm/app/cmSdb.h src/libcm/app/cmTakeSeqBldr.h
cmSRC += src/libcm/app/cmSdb.c src/libcm/app/cmTakeSeqBldr.c
cmHDR += src/libcm/app/cmSdb.h src/libcm/app/cmTakeSeqBldr.h src/libcm/app/cmDspPgmJsonToDot.h
cmSRC += src/libcm/app/cmSdb.c src/libcm/app/cmTakeSeqBldr.c src/libcm/app/cmDspPgmJsonToDot.c
cmHDR += src/libcm/app/cmPickup.h src/libcm/cmRbm.h src/libcm/cmTaskMgr.h src/libcm/cmSyncRecd.h
cmSRC += src/libcm/app/cmPickup.c src/libcm/cmRbm.c src/libcm/cmTaskMgr.c src/libcm/cmSyncRecd.c

459
app/cmDspPgmJsonToDot.c Normal file
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->preDelaySmpCnt= floor(cfg->preDelayMs * p->afInfo.srate / 1000.0);
cmRptPrintf(p->err.rpt,"wndFrmCnt:%i preWndMult:%f thresh:%f maxHz:%f filtCoeff:%f filterId:%i preDelayMs:%f\n",cfg->wndFrmCnt,cfg->preWndMult,cfg->threshold,cfg->maxFrqHz,cfg->filtCoeff,cfg->medFiltWndMs,cfg->filterId,cfg->preDelayMs );
cmRptPrintf(p->err.rpt,"Analysis Hop Duration: %8.2f ms %i smp\n",(double)p->hopSmpCnt*1000/p->afInfo.srate,p->hopSmpCnt);
cmRptPrintf(p->err.rpt,"Median Filter Window: %8.2f ms %i frames\n",cfg->medFiltWndMs,p->medFiltFrmCnt);
cmRptPrintf(p->err.rpt,"Detection Pre-delay: %8.2f ms %i smp\n",cfg->preDelayMs, p->preDelaySmpCnt);
// initialize the audio file reader
if( cmAudioFileRdOpen( p->afRdPtr, p->hopSmpCnt, inAudioFn, p->cfg.audioChIdx, 0, cmInvalidIdx ) != cmOkRC )
if( cmAudioFileRdOpen( p->afRdPtr, p->hopSmpCnt, inAudioFn, p->cfg.audioChIdx, 0, 0 ) != cmOkRC )
{
rc = cmErrMsg(&p->err,kDspProcFailOnRC, "The audio file reader open failed.");
goto errLabel;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,8 @@
extern "C" {
#endif
/*
/*( { file_desc:"Musical instrument sample database manager and synthetic sequence generator." kw:[audio] }
The CSV file used to initialize a SDB object has the following column syntax.
Column Name Type Description
@ -292,6 +293,8 @@ extern "C" {
cmSdbRC_t cmSdbTest( cmCtx_t* ctx );
//)
#ifdef __cplusplus
}
#endif

View File

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

View File

@ -5,6 +5,7 @@
extern "C" {
#endif
//( { file_desc:"Concatenate multipel overlapping MIDI performances into a single virtual performance based by associating score information with the MIDI events." kw:[seq] }
enum
{
@ -123,6 +124,8 @@ extern "C" {
cmTsbRC_t cmTakeSeqBldrTest( cmCtx_t* ctx );
//)
#ifdef __cplusplus
}
#endif

View File

@ -530,16 +530,14 @@ cmTlRC_t _cmTlAllocRecd2(
tp->flags = 0;
tp->text = NULL;
//printf("%9i %9i %9i %9i\n",tp->begSmpIdx,tp->durSmpCnt,refPtr==NULL?0:refPtr->obj->seqSmpIdx, tp->seqSmpIdx);
op->obj = tp;
op->mem = mem;
op->memByteCnt = byteCnt;
op->next = NULL;
op->prev = NULL;
//if( seqId == 4 )
// printf("seq:%i id:%i type:%i accum:%i ref:%i offs:%i %f\n",seqId, tp->uid, tp->typeId, tp->seqSmpIdx, refPtr==NULL?-1:refPtr->obj->uid, begSmpIdx, begSmpIdx/(96000.0*60.0) );
_cmTlInsertAfter(p, _cmTlFindRecdBefore(p,op), op );
@ -651,36 +649,36 @@ cmTlRC_t _cmTlProcMidiFile( _cmTl_t* p, _cmTlObj_t* op, cmMidiFileH_t mfH )
const cmMidiTrackMsg_t** mapp = cmMidiFileMsgArray(mfH);
unsigned mi = 0;
_cmTlObj_t* refOp = op;
double smpPerMicro = p->srate / 1000000.0;
unsigned begSmpIdx0 = 0;
mfp->noteOnCnt = 0;
// for each midi message
for(; mi<mn; ++mi)
{
_cmTlObj_t* meop = NULL;
const cmMidiTrackMsg_t* mp = mapp[mi];
int begSmpIdx = mp->dtick;
int durSmpCnt = 0;
unsigned midiTrkMsgByteCnt = cmMidiFilePackTrackMsgBufByteCount( mp );
unsigned recdByteCnt = sizeof(cmTlMidiEvt_t) + midiTrkMsgByteCnt;
//if( mfp->obj.seqId==4 && mi<=25 )
// printf("%s: bsi:%9i acc:%f smp acc:%f min %s\n", mp->status == kNoteOnMdId?"non":" ", begSmpIdx, accum, accum / (p->srate * 60),cmStringNullGuard(mfp->obj.name));
_cmTlObj_t* meop = NULL;
const cmMidiTrackMsg_t* mp = mapp[mi];
int begSmpIdx = mp->amicro * smpPerMicro;
int durSmpCnt = 0;
unsigned midiTrkMsgByteCnt = cmMidiFilePackTrackMsgBufByteCount( mp );
unsigned recdByteCnt = sizeof(cmTlMidiEvt_t) + midiTrkMsgByteCnt;
// count the note-on messages
if( cmMidiIsNoteOn(mp->status) )
{
durSmpCnt = mp->u.chMsgPtr->durTicks;
durSmpCnt = mp->u.chMsgPtr->durMicros * smpPerMicro;
++mfp->noteOnCnt;
}
if( cmMidiIsCtl(mp->status) && cmMidiIsSustainPedal(mp->status,mp->u.chMsgPtr->d0) )
durSmpCnt = mp->u.chMsgPtr->durTicks;
durSmpCnt = mp->u.chMsgPtr->durMicros * smpPerMicro;
// allocate the generic time-line object record
if((rc = _cmTlAllocRecd2(p, NULL, refOp, begSmpIdx, durSmpCnt, kMidiEvtTlId, mfp->obj.seqId, recdByteCnt, &meop)) != kOkTlRC )
if((rc = _cmTlAllocRecd2(p, NULL, refOp, begSmpIdx-begSmpIdx0, durSmpCnt, kMidiEvtTlId, mfp->obj.seqId, recdByteCnt, &meop)) != kOkTlRC )
goto errLabel;
begSmpIdx0 = begSmpIdx;
assert( meop != NULL );
cmTlMidiEvt_t* mep = _cmTimeLineMidiEvtObjPtr(p,meop->obj);
@ -731,7 +729,7 @@ cmTlRC_t _cmTlAllocMidiFileRecd( _cmTl_t* p, const cmChar_t* nameStr, const cmCh
unsigned durSmpCnt = floor(cmMidiFileDurSecs(mfH)*p->srate);
// convert the midi file from delta ticks to delta samples
cmMidiFileTickToSamples(mfH,p->srate,false);
//cmMidiFileTickToSamples(mfH,p->srate,false);
// assign note durations to all note-on msg's
cmMidiFileCalcNoteDurations(mfH);
@ -757,6 +755,7 @@ cmTlRC_t _cmTlAllocMidiFileRecd( _cmTl_t* p, const cmChar_t* nameStr, const cmCh
op->obj->text = mp->fn;
// insert the events in the midi file as individual time line objects
if((rc = _cmTlProcMidiFile(p, op, mfH)) != kOkTlRC )
goto errLabel;
@ -1363,7 +1362,7 @@ cmTlRC_t cmTimeLineReadJson( cmTlH_t* hp, const cmChar_t* ifn )
if( cmJsonMemberValues(jnp,&errLabelPtr,
"srate",kRealTId,&p->srate,
"onset",kObjectTId,&cnp,
"onset",kObjectTId | kOptArgJsFl,&cnp,
"objArray",kArrayTId,&jnp,
NULL) != kOkJsRC )
{
@ -1374,26 +1373,29 @@ cmTlRC_t cmTimeLineReadJson( cmTlH_t* hp, const cmChar_t* ifn )
goto errLabel;
}
if((jsRC = cmJsonMemberValues(cnp,&errLabelPtr,
"wndMs", kRealTId, &p->onsetCfg.wndMs,
"hopFact", kIntTId, &p->onsetCfg.hopFact,
"audioChIdx", kIntTId, &p->onsetCfg.audioChIdx,
"wndFrmCnt", kIntTId, &p->onsetCfg.wndFrmCnt,
"preWndMult", kRealTId, &p->onsetCfg.preWndMult,
"threshold", kRealTId, &p->onsetCfg.threshold,
"maxFrqHz", kRealTId, &p->onsetCfg.maxFrqHz,
"filtCoeff", kRealTId, &p->onsetCfg.filtCoeff,
"medFiltWndMs", kRealTId, &p->onsetCfg.medFiltWndMs,
"filterId", kIntTId, &p->onsetCfg.filterId,
"preDelayMs", kRealTId, &p->onsetCfg.preDelayMs,
NULL)) != kOkJsRC )
if( cnp != NULL )
{
if((jsRC = cmJsonMemberValues(cnp,&errLabelPtr,
"wndMs", kRealTId, &p->onsetCfg.wndMs,
"hopFact", kIntTId, &p->onsetCfg.hopFact,
"audioChIdx", kIntTId, &p->onsetCfg.audioChIdx,
"wndFrmCnt", kIntTId, &p->onsetCfg.wndFrmCnt,
"preWndMult", kRealTId, &p->onsetCfg.preWndMult,
"threshold", kRealTId, &p->onsetCfg.threshold,
"maxFrqHz", kRealTId, &p->onsetCfg.maxFrqHz,
"filtCoeff", kRealTId, &p->onsetCfg.filtCoeff,
"medFiltWndMs", kRealTId, &p->onsetCfg.medFiltWndMs,
"filterId", kIntTId, &p->onsetCfg.filterId,
"preDelayMs", kRealTId, &p->onsetCfg.preDelayMs,
NULL)) != kOkJsRC )
{
if(jsRC == kNodeNotFoundJsRC )
rc = cmErrMsg(&p->err,kParseFailTlRC,"The JSON 'time_line' onset analysizer cfg. required field:'%s' was not found in '%s'.",errLabelPtr,cmStringNullGuard(ifn));
else
rc = cmErrMsg(&p->err,kParseFailTlRC,"The JSON 'time_line' onset analyzer cfg. in '%s'.",cmStringNullGuard(ifn));
goto errLabel;
if(jsRC == kNodeNotFoundJsRC )
rc = cmErrMsg(&p->err,kParseFailTlRC,"The JSON 'time_line' onset analysizer cfg. required field:'%s' was not found in '%s'.",errLabelPtr,cmStringNullGuard(ifn));
else
rc = cmErrMsg(&p->err,kParseFailTlRC,"The JSON 'time_line' onset analyzer cfg. in '%s'.",cmStringNullGuard(ifn));
goto errLabel;
}
}
for(i=0; i<cmJsonChildCount(jnp); ++i)
@ -1478,6 +1480,12 @@ cmTlRC_t cmTimeLineGenOnsetMarks( cmTlH_t h, unsigned seqId )
unsigned i,j;
unsigned smpIdx;
if( p->onsetCfg.wndMs == 0 )
{
rc = cmErrMsg(&p->err,kOnsetFailTlRC,"Audio onset analyzer not-configured.");
goto errLabel;
}
// initialize the audio onset analyzer
if( cmOnsetInitialize(&p->ctx, &onsH ) != kOkOnRC )
{

View File

@ -5,6 +5,8 @@
extern "C" {
#endif
//( { file_desc:"Manage, save, and restore a time-line containing MIDI files, Audio files, Audio events, and arbitrary markers ." kw[seq] }
typedef cmHandle_t cmTlH_t;
@ -248,6 +250,8 @@ extern "C" {
// callback function.
cmTlRC_t cmTimeLineDecode( const void* msg, unsigned msgByteCnt, cmTlUiMsg_t* uiMsg );
//)
#ifdef __cplusplus
}
#endif

286
cmApBuf.h
View File

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

View File

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

View File

@ -30,7 +30,7 @@
#include "dsp/cmDspClass.h"
#include "dsp/cmDspSys.h"
#include "cmAudDsp.h"
#include "cmDspPgmJsonToDot.h"
cmAdH_t cmAdNullHandle = cmSTATIC_NULL_HANDLE;
@ -1005,6 +1005,11 @@ cmAdRC_t _cmAudDspPrintPgm( cmAd_t* p, unsigned asSubSysIdx, const cmChar_t* fn
{
if( cmDspSysPrintPgm(p->dsSsArray[i].dsH,fn) != kOkDspRC )
rc = cmErrMsg(&p->err,kDspSysFailAdRC,"The program print failed.");
else
{
if( cmDspPgmJsonToDot(&p->ctx,fn,fn) != kOkDspRC )
rc = cmErrMsg(&p->err,kDspSysFailAdRC,"The program print conversion to DOT failed.");
}
break;
}

View File

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

View File

@ -5,10 +5,24 @@
extern "C" {
#endif
//( { file_desc: "Virtual interface to the audio DSP system." kw:[rt]}
//
// This class provides a two-way interface to the audio DSP system.
// It is designed to work independenty of the physical
// method of communication. For example, when used by
// cmAudDspLocal, it supports in memory transfer of messages
// between the application and the audio-DSP engine.
// Another implementation however could use it to support
// a networked communication scheme to a remote audio-DSP
// system. Note that in either case, however, this class
// resides with, and is linked to, the application, and not
// the engine.
// This API has two basic responsibilities:
//
// 1) Provides a function based interface to the audio DSP system for the
// client application.
// client application. This is more convenient, and safer, than the lower level
// message based interface provided by cmAudDsp.h.
// The client calls these API functions to send commands to the audio DSP
// system. Internally the cmAdIfxxx functions converts the commands to
// raw message packets and passes them to a transmission service
@ -29,9 +43,9 @@ extern "C" {
// client provided cmAdIfDispatch_t function (ssInitFunc,statusFunc or uiFunc).
// Note that this entire chain of calls occurs in the client thread
// and in the context of the cmAdIfDispatchMsgToHost() procedure.
//)
//(
enum
{
kOkAiRC = cmOkRC,
@ -163,6 +177,7 @@ extern "C" {
*/
//)
#ifdef __cplusplus
}

View File

@ -5,6 +5,20 @@
extern "C" {
#endif
//( { file_desc: "Implementation of the audio DSP interface for local, in-memory, communication." kw:[rt]}
//
// This class instantiates an audio-DSP engine (cmAudDsp),
// an interface for communicating with it (cmAudDspIF),
// and message delivery functions for copying messages
// in both directions between cmAuDsp and cmAudDspIF.
//
// Note that the underlying inteface which allows an application to
// control, and receive message from, cmAudDsp is provided by
// cmAudDspIF - which this class provides a handle to.
//)
//(
enum
{
kOkAdlRC = cmOkRC,
@ -32,6 +46,7 @@ extern "C" {
cmAiH_t cmAudDspLocalIF_Handle( cmAdlH_t h );
//)
#ifdef __cplusplus
}

View File

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

View File

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

View File

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

View File

@ -1,13 +1,9 @@
/// \file cmAudioFile.h
/// \brief Audio file reader/writer class.
///
/// This class supports reading uncompressed AIFF and WAV files and writing uncompressed AIFF files.
/// The reading and writing routines are known to work with 8,16,24, and 32 bit integer sample formats.
///
/// Testing and example usage for this API can be found in cmProcTest.c cmAudioReadWriteTest().
///
/// Usage example:
/// \snippet cmAudioFile.c cmAudioFileExample
//( { file_desc: "Read and write AIFF and WAV audio files." kw:[file audio] }
//
// This class supports reading uncompressed AIFF and WAV files and writing uncompressed AIFF files.
// The reading and writing routines are known to work with 8,16,24, and 32 bit integer sample formats.
//
//)
#ifndef cmAudioFile_h
#define cmAudioFile_h
@ -16,15 +12,17 @@
extern "C" {
#endif
//(
#ifndef cmAudioFile_MAX_FRAME_READ_CNT
/// Maximum number of samples which will be read in one call to fread().
/// This value is only significant in that an internal buffer is created on the stack
/// whose size must be limited to prevent stack overflows.
// Maximum number of samples which will be read in one call to fread().
// This value is only significant in that an internal buffer is created on the stack
// whose size must be limited to prevent stack overflows.
#define cmAudioFile_MAX_FRAME_READ_CNT (8192)
#endif
/// Audio file result codes.
// Audio file result codes.
enum
{
kOkAfRC = 0,
@ -41,18 +39,18 @@ extern "C" {
kUnknownErrAfRC
};
/// Informational flags used by audioFileInfo
// Informational flags used by audioFileInfo
enum
{
kAiffAfFl = 0x01, ///< this is an AIFF file
kWavAfFl = 0x02, ///< this is a WAV file
kSwapAfFl = 0x04, ///< file header bytes must be swapped
kAifcAfFl = 0x08, ///< this is an AIFC file
kSwapSamplesAfFl = 0x10 ///< file sample bytes must be swapped
kAiffAfFl = 0x01, // this is an AIFF file
kWavAfFl = 0x02, // this is a WAV file
kSwapAfFl = 0x04, // file header bytes must be swapped
kAifcAfFl = 0x08, // this is an AIFC file
kSwapSamplesAfFl = 0x10 // file sample bytes must be swapped
};
/// Constants
// Constants
enum
{
kAudioFileLabelCharCnt = 256,
@ -64,7 +62,7 @@ extern "C" {
kAfBextOriginTimeN = 8
};
/// Aiff marker record
// Aiff marker record
typedef struct
{
unsigned id;
@ -72,9 +70,9 @@ extern "C" {
char label[kAudioFileLabelCharCnt];
} cmAudioFileMarker_t;
/// Broadcast WAV header record As used by ProTools audio files. See http://en.wikipedia.org/wiki/Broadcast_Wave_Format
/// When generated from Protools the timeRefLow/timeRefHigh values appear to actually refer
/// to the position on the Protools time-line rather than the wall clock time.
// Broadcast WAV header record As used by ProTools audio files. See http://en.wikipedia.org/wiki/Broadcast_Wave_Format
// When generated from Protools the timeRefLow/timeRefHigh values appear to actually refer
// to the position on the Protools time-line rather than the wall clock time.
typedef struct
{
char desc[ kAfBextDescN + 1 ];
@ -86,102 +84,103 @@ extern "C" {
unsigned timeRefHigh; // sample count since midnight high word
} cmAudioFileBext_t;
/// Audio file information record used by audioFileNew and audioFileOpen
// Audio file information record used by audioFileNew and audioFileOpen
typedef struct
{
unsigned bits; ///< bits per sample
unsigned chCnt; ///< count of audio file channels
double srate; ///< audio file sample rate in samples per second
unsigned frameCnt; ///< total number of sample frames in the audio file
unsigned flags; ///< informational flags
unsigned markerCnt; ///< count of markers in markerArray
cmAudioFileMarker_t* markerArray; ///< array of markers
cmAudioFileBext_t bextRecd; ///< only used with Broadcast WAV files
unsigned bits; // bits per sample
unsigned chCnt; // count of audio file channels
double srate; // audio file sample rate in samples per second
unsigned frameCnt; // total number of sample frames in the audio file
unsigned flags; // informational flags
unsigned markerCnt; // count of markers in markerArray
cmAudioFileMarker_t* markerArray; // array of markers
cmAudioFileBext_t bextRecd; // only used with Broadcast WAV files
} cmAudioFileInfo_t;
typedef cmHandle_t cmAudioFileH_t; ///< opaque audio file handle
extern cmAudioFileH_t cmNullAudioFileH; ///< NULL audio file handle
typedef cmHandle_t cmAudioFileH_t; // opaque audio file handle
extern cmAudioFileH_t cmNullAudioFileH; // NULL audio file handle
/// Create an audio file handle and optionally use the handle to open an audio file.
///
/// \param fn The audio file name to open or NULL to create the audio file handle without opening the file.
/// \param infoPtr A pointer to an audioFileInfo record to be filled when the file is open or NULL to ignore.
/// \param rcPtr A pointer to a result code to be set in the event of a runtime error or NULL to ignore.
/// \param rpt A pointer to a cmRpt_t object which error messages from this class will be directed to.
/// \retval cmAudioFileH_t A new audio file handle.
///
// Create an audio file handle and optionally use the handle to open an audio file.
//
// fn The audio file name to open or NULL to create the audio file handle without opening the file.
// infoPtr A pointer to an audioFileInfo record to be filled when the file is open or NULL to ignore.
// rcPtr A pointer to a result code to be set in the event of a runtime error or NULL to ignore.
// rpt A pointer to a cmRpt_t object which error messages from this class will be directed to.
// Returns cmAudioFileH_t A new audio file handle.
//
cmAudioFileH_t cmAudioFileNewOpen( const cmChar_t* fn, cmAudioFileInfo_t* infoPtr, cmRC_t* rcPtr, cmRpt_t* rpt );
/// Open an audio file for writing
// Open an audio file for writing
cmAudioFileH_t cmAudioFileNewCreate( const cmChar_t* fn, double srate, unsigned bits, unsigned chCnt, cmRC_t* rcPtr, cmRpt_t* rpt );
/// Open an audio file for reading using a handle returned from an earlier call to audioFileNewXXX().
///
/// \param h A file handle returned from and earlier call to cmAudioFileNewOpen() or cmAudioFileNewCreate().
/// \param fn The audio file name to open or NULL to create the audio file handle without opening the file.
/// \param infoPtr A pointer to an audioFileInfo record to be filled when the file is open or NULL to ignore.
/// \retval Returns an cmRC_t value indicating the success (kOkAfRC) or failure of the call.
///
/// If the audio file handle 'h' refers to an open file then it is automatically closed prior to being
/// reopened with the new file.
// Open an audio file for reading using a handle returned from an earlier call to audioFileNewXXX().
//
// h A file handle returned from and earlier call to cmAudioFileNewOpen() or cmAudioFileNewCreate().
// fn The audio file name to open or NULL to create the audio file handle without opening the file.
// infoPtr A pointer to an audioFileInfo record to be filled when the file is open or NULL to ignore.
// Returns an cmRC_t value indicating the success (kOkAfRC) or failure of the call.
//
// If the audio file handle 'h' refers to an open file then it is automatically closed prior to being
// reopened with the new file.
cmRC_t cmAudioFileOpen( cmAudioFileH_t h, const cmChar_t* fn, cmAudioFileInfo_t* infoPtr );
/// Open an audio file for writing. The type of the audio file, AIF or WAV
/// is determined by the file name extension.
// Open an audio file for writing. The type of the audio file, AIF or WAV
// is determined by the file name extension.
cmRC_t cmAudioFileCreate(
cmAudioFileH_t h, ///< Handle returned from an earlier call to cmAudioFileNewCreate() or cmAudioFileNewOpen().
const cmChar_t* fn, ///< File name of the new file.
double srate, ///< Sample rate of the new file.
unsigned bits, ///< Sample word width for the new file in bits (must be 8,16,24 or 32).
unsigned chCnt ///< Audio channel count for the new file.
cmAudioFileH_t h, // Handle returned from an earlier call to cmAudioFileNewCreate() or cmAudioFileNewOpen().
const cmChar_t* fn, // File name of the new file.
double srate, // Sample rate of the new file.
unsigned bits, // Sample word width for the new file in bits (must be 8,16,24 or 32).
unsigned chCnt // Audio channel count for the new file.
);
/// Close a the file associated with handle 'h' but do not release the handle.
/// If the file was opened for writing (cmAudioFileCreate()) then this function will
/// write the file header prior to closing the file.
// Close a the file associated with handle 'h' but do not release the handle.
// If the file was opened for writing (cmAudioFileCreate()) then this function will
// write the file header prior to closing the file.
cmRC_t cmAudioFileClose( cmAudioFileH_t* h );
/// Close the file associated with handle 'h' (via an internal call to
/// cmAudioFileClose()) and release the handle and any resources
/// associated with it. This is the complement to cmAudioFileOpen/Create().
// Close the file associated with handle 'h' (via an internal call to
// cmAudioFileClose()) and release the handle and any resources
// associated with it. This is the complement to cmAudioFileOpen/Create().
cmRC_t cmAudioFileDelete( cmAudioFileH_t* h );
/// Return true if the handle is not closed or deleted.
// Return true if the handle is not closed or deleted.
bool cmAudioFileIsValid( cmAudioFileH_t h );
/// Return true if the handle is open.
// Return true if the handle is open.
bool cmAudioFileIsOpen( cmAudioFileH_t h );
/// Return true if the current file position is at the end of the file.
// Return true if the current file position is at the end of the file.
bool cmAudioFileIsEOF( cmAudioFileH_t h );
/// Return the current file position as a frame index.
// Return the current file position as a frame index.
unsigned cmAudioFileTell( cmAudioFileH_t h );
/// Set the current file position as an offset from the first frame.
// Set the current file position as an offset from the first frame.
cmRC_t cmAudioFileSeek( cmAudioFileH_t h, unsigned frmIdx );
/// \name Sample Reading Functions.
///@{
/// Fill a user suppled buffer with up to frmCnt samples.
/// If less than frmCnt samples are available at the specified audio file location then the unused
/// buffer space is set to zero. Check *actualFrmCntPtr for the count of samples actually available
/// in the return buffer. Functions which do not include a begFrmIdx argument begin reading from
/// the current file location (see cmAudioFileSeek()). The buf argument is always a pointer to an
/// array of pointers of length chCnt. Each channel buffer specified in buf[] must contain at least
/// frmCnt samples.
///
/// \param h An audio file handle returned from an earlier call to audioFileNew()
/// \param fn The name of the audio file to read.
/// \param begFrmIdx The frame index of the first sample to read. Functions that do not use this parameter begin reading at the current file location (See cmAudioFileTell()).
/// \param frmCnt The number of samples allocated in buf.
/// \param chIdx The index of the first channel to read.
/// \param chCnt The count of channels to read.
/// \param buf An array containing chCnt pointers to arrays of frmCnt samples.
/// \param actualFrmCntPtr The number of frames actually written to the return buffer (ignored if NULL)
// Sample Reading Functions.
//
// Fill a user suppled buffer with up to frmCnt samples.
// If less than frmCnt samples are available at the specified audio file location then the unused
// buffer space is set to zero. Check *actualFrmCntPtr for the count of samples actually available
// in the return buffer. Functions which do not include a begFrmIdx argument begin reading from
// the current file location (see cmAudioFileSeek()). The buf argument is always a pointer to an
// array of pointers of length chCnt. Each channel buffer specified in buf[] must contain at least
// frmCnt samples.
//
//
// h An audio file handle returned from an earlier call to audioFileNew()
// fn The name of the audio file to read.
// begFrmIdx The frame index of the first sample to read. Functions that do not use this parameter begin reading at the current file location (See cmAudioFileTell()).
// frmCnt The number of samples allocated in buf.
// chIdx The index of the first channel to read.
// chCnt The count of channels to read.
// buf An array containing chCnt pointers to arrays of frmCnt samples.
// actualFrmCntPtr The number of frames actually written to the return buffer (ignored if NULL)
cmRC_t cmAudioFileReadInt( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr );
cmRC_t cmAudioFileReadFloat( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr );
@ -191,10 +190,7 @@ extern "C" {
cmRC_t cmAudioFileGetFloat( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
cmRC_t cmAudioFileGetDouble( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
///@}
/// \name Sum the returned samples into the output buffer.
///@{
// Sum the returned samples into the output buffer.
cmRC_t cmAudioFileReadSumInt( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr );
cmRC_t cmAudioFileReadSumFloat( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr );
cmRC_t cmAudioFileReadSumDouble( cmAudioFileH_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr );
@ -202,12 +198,8 @@ extern "C" {
cmRC_t cmAudioFileGetSumInt( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
cmRC_t cmAudioFileGetSumFloat( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
cmRC_t cmAudioFileGetSumDouble( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr, cmAudioFileInfo_t* afInfoPtr, cmRpt_t* rpt );
///@}
///@}
/// \name Sample Writing Functions
///@{
// Sample Writing Functions
cmRC_t cmAudioFileWriteInt( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, int** bufPtrPtr );
cmRC_t cmAudioFileWriteFloat( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, float** bufPtrPtr );
cmRC_t cmAudioFileWriteDouble( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, double** bufPtrPtr );
@ -215,14 +207,11 @@ extern "C" {
cmRC_t cmAudioFileWriteFileInt( const char* fn, double srate, unsigned bit, unsigned frmCnt, unsigned chCnt, int** bufPtrPtr, cmRpt_t* rpt );
cmRC_t cmAudioFileWriteFileFloat( const char* fn, double srate, unsigned bit, unsigned frmCnt, unsigned chCnt, float** bufPtrPtr, cmRpt_t* rpt );
cmRC_t cmAudioFileWriteFileDouble( const char* fn, double srate, unsigned bit, unsigned frmCnt, unsigned chCnt, double** bufPtrPtr, cmRpt_t* rpt );
///@}
/// \name cmSample_t and cmReal_t Alias Macros
///@{
/// Alias the cmSample_t and cmReal_t sample reading and writing functions to the appropriate
/// type based on #CM_FLOAT_SMP and #CM_FLOAT_REAL.
// Alias the cmSample_t and cmReal_t sample reading and writing functions to the appropriate
// type based on #CM_FLOAT_SMP and #CM_FLOAT_REAL.
#if CM_FLOAT_SMP == 1
@ -263,51 +252,44 @@ extern "C" {
#define cmAudioFileWriteFileReal cmAudioFileWriteFileDouble
#endif
///@}
/// \name Minimum, Maximum, Mean
///@{
/// Scan an entire audio file and return the minimum, maximum and mean sample value.
/// On error *minPtr, *maxPtr, and *meanPtr are set to -acSample_MAX, cmSample_MAX, and 0 respectively
// Scan an entire audio file and return the minimum, maximum and mean sample value.
// On error *minPtr, *maxPtr, and *meanPtr are set to -acSample_MAX, cmSample_MAX, and 0 respectively
cmRC_t cmAudioFileMinMaxMean( cmAudioFileH_t h, unsigned chIdx, cmSample_t* minPtr, cmSample_t* maxPtr, cmSample_t* meanPtr );
cmRC_t cmAudioFileMinMaxMeanFn( const cmChar_t* fn, unsigned chIdx, cmSample_t* minPtr, cmSample_t* maxPtr, cmSample_t* meanPtr, cmRpt_t* rpt );
///@}
/// Return the file name associated with a audio file handle.
// Return the file name associated with a audio file handle.
const cmChar_t* cmAudioFileName( cmAudioFileH_t h );
/// Given an error code return the associated message.
// Given an error code return the associated message.
const char* cmAudioFileErrorMsg( unsigned rc );
/// \name Get information about an audio file
///@{
/// Return the cmAudioFileInfo_t record associated with a file.
// Return the cmAudioFileInfo_t record associated with a file.
cmRC_t cmAudioFileGetInfo( const cmChar_t* fn, cmAudioFileInfo_t* infoPtr, cmRpt_t* rpt );
/// Print the cmAudioFileInfo_t to a file.
// Print the cmAudioFileInfo_t to a file.
void cmAudioFilePrintInfo( const cmAudioFileInfo_t* infoPtr, cmRpt_t* );
/// Print the file header information and frmCnt sample values beginning at frame index frmIdx.
// Print the file header information and frmCnt sample values beginning at frame index frmIdx.
cmRC_t cmAudioFileReport( cmAudioFileH_t h, cmRpt_t* rpt, unsigned frmIdx, unsigned frmCnt );
/// Print the file header information and frmCnt sample values beginning at frame index frmIdx.
// Print the file header information and frmCnt sample values beginning at frame index frmIdx.
cmRC_t cmAudioFileReportFn( const cmChar_t* fn, unsigned frmIdx, unsigned frmCnt, cmRpt_t* rpt );
///@}
/// Change the sample rate value in the header. Note that this function does not resample the audio
/// signal it simply changes the value of the sample rate in the header.
// Change the sample rate value in the header. Note that this function does not resample the audio
// signal it simply changes the value of the sample rate in the header.
cmRC_t cmAudioFileSetSrate( const cmChar_t* audioFn, unsigned srate );
// Generate a sine tone and write it to a file.
cmRC_t cmAudioFileSine( cmCtx_t* ctx, const cmChar_t* fn, double srate, unsigned bits, double hz, double gain, double secs );
/// Testing and example routine for functions in cmAudioFile.h.
/// Also see cmProcTest.c cmAudioFileReadWriteTest()
// Testing and example routine for functions in cmAudioFile.h.
// Also see cmProcTest.c cmAudioFileReadWriteTest()
void cmAudioFileTest( cmCtx_t* ctx, int argc, const char* argv[] );
//)
#ifdef __cplusplus
}

View File

@ -1,6 +1,11 @@
#ifndef cmAudioFileDev_h
#define cmAudioFileDev_h
#ifdef __cplusplus
extern "C" {
#endif
//( { file_desc:"Implements cmAudioFileDev for reading and writing audio files under control of cmAudioPort.", kw:[audio file rt]}
enum
{
kOkAfdRC = cmOkRC,
@ -72,4 +77,10 @@ void cmAudioFileDevReport( cmAfdH_t h, cmRpt_t* rpt );
void cmAudioFileDevTest( cmRpt_t* rpt );
//)
#ifdef __cplusplus
}
#endif
#endif

View File

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

View File

@ -5,6 +5,8 @@
extern "C" {
#endif
//( { file_desc:"Audio device driver which generates the callbacks to run cmAudioPort in a non-real time mode." kw:[audio rt]}
cmApRC_t cmApNrtAllocate( cmRpt_t* rpt );
cmApRC_t cmApNrtFree();
@ -57,6 +59,7 @@ extern "C" {
/// Return true if the device is currently started.
bool cmApNrtDeviceIsStarted( unsigned devIdx );
//)
#ifdef __cplusplus
}

View File

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

View File

@ -5,6 +5,8 @@
extern "C" {
#endif
//( { file_desc:"This is an audio device driver for cmAudioPort which supports reading and writing audio files as though they are real-time devices." kw[audio file rt] }
cmApRC_t cmApFileAllocate( cmRpt_t* rpt );
cmApRC_t cmApFileFree();
@ -41,6 +43,8 @@ extern "C" {
void cmApFileReport( cmRpt_t* rpt );
void cmApFileTest( cmRpt_t* rpt );
//)
#ifdef __cplusplus
}
#endif

View File

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

View File

@ -5,6 +5,8 @@
extern "C" {
#endif
//( { file_desc:"Constrants and data structures used to communicate messages to and from cmAudioSys" kw:[audio real_time]}
/// Reserved DSP message selector id's (second field of all host<->audio system messages)
enum
{
@ -112,6 +114,7 @@ extern "C" {
} cmAudioSysStatus_t;
//)
#ifdef __cplusplus
}

View File

@ -1,9 +1,15 @@
#ifndef cmComplexTypes_h
#define cmComplexTypes_h
#ifdef __cplusplus
extern "C" {
#endif
#include <complex.h>
#include <fftw3.h>
//( { file_desc: "Constants and functions used for working with complex values." kw:[base math] }
#if CM_FLOAT_SMP == 1
#define cmCabsS cabsf
@ -95,5 +101,10 @@ void cmVOCR_Abs( cmSample_t* y, const cmComplexR_t* x, unsigned n );
void cmVOCR_MultVS( cmComplexR_t* y, cmReal_t v, unsigned n );
void cmVOCR_DivVS( cmComplexR_t* y, cmReal_t v, unsigned n );
//)
#ifdef __cplusplus
}
#endif
#endif

View File

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

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
// other global values for easy distribution throughtout a cm based application.
//
@ -44,7 +45,6 @@ extern "C" {
unsigned mmFlags // Initialization flags used to configure \ref cmMallocDebug.h
);
//)
//}
#ifdef __cplusplus
}

View File

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

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:
// #define cmSFX(a) a##_MySuffix
// #define cmTYPE My_Type
@ -117,6 +119,8 @@ const cmTYPE* cmSFX(cmDListIterFind)( cmDListIterH_t iH, const cmTYPE* key
#endif // cmGEN_CODE
//)
#undef cmSFX
#undef cmTYPE

View File

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

View File

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

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.
//
// Most of the cmHandle_t based classes use cmErr_t to format error messages with a
@ -75,7 +75,6 @@ extern "C" {
cmRC_t cmErrClearRC( cmErr_t* err );
//)
//}
#ifdef __cplusplus
}

View File

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

View File

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

View File

@ -1,7 +1,6 @@
/// \file cmFeatFile.h
/// \brief Audio file acoustic feature analyzer and accompanying file reader.
///
///
//( { file_desc:" Audio file acoustic feature analyzer and accompanying file reader." kw:[audio analysis file]}
//
//
#ifndef cmFeatFile_h
#define cmFeatFile_h
@ -12,7 +11,7 @@ extern "C" {
/// Result codes for all functions in cmFeatFile.h
// Result codes for all functions in cmFeatFile.h
enum
{
kOkFtRC = cmOkRC,
@ -36,241 +35,238 @@ extern "C" {
kInvalidFrmIdxFtRC
};
/// Feature Id's
// Feature Id's
enum
{
kInvalidFtId, ///< 0
kAmplFtId, ///< 1 Fourier transform amplitude
kDbAmplFtId, ///< 2 Fourier transform decibel
kPowFtId, ///< 3 Fourier transform power
kDbPowFtId, ///< 4 Fourier transform power decibel
kPhaseFtId, ///< 5 Fourier transform phase (not unwrapped)
kBfccFtId, ///< 6 Bark Frequency Cepstral Coeffcients
kMfccFtId, ///< 7 Mel Frequency Cepstral Coefficients
kCepsFtId, ///< 8 Cepstral Coefficients
kConstQFtId, ///< 9 Constant-Q transform
kLogConstQFtId, ///< 10 Log Constant-Q transform
kRmsFtId, ///< 11 Root means square of the audio signal
kDbRmsFtId, ///< 12 RMS in decibels
kInvalidFtId, // 0
kAmplFtId, // 1 Fourier transform amplitude
kDbAmplFtId, // 2 Fourier transform decibel
kPowFtId, // 3 Fourier transform power
kDbPowFtId, // 4 Fourier transform power decibel
kPhaseFtId, // 5 Fourier transform phase (not unwrapped)
kBfccFtId, // 6 Bark Frequency Cepstral Coeffcients
kMfccFtId, // 7 Mel Frequency Cepstral Coefficients
kCepsFtId, // 8 Cepstral Coefficients
kConstQFtId, // 9 Constant-Q transform
kLogConstQFtId, // 10 Log Constant-Q transform
kRmsFtId, // 11 Root means square of the audio signal
kDbRmsFtId, // 12 RMS in decibels
kD1AmplFtId, ///< 13 1st order difference over time of the Fourier transform amplitude
kD1DbAmplFtId, ///< 14 1st order difference over time of the Fourier transform decibel
kD1PowFtId, ///< 15 1st order difference over time of the Fourier transform power
kD1DbPowFtId, ///< 16 1st order difference over time of the Fourier transform power decibel
kD1PhaseFtId, ///< 17 1st order difference over time of the Fourier transform phase (not unwrapped)
kD1BfccFtId, ///< 18 1st order difference over time of the Bark Frequency Cepstral Coeffcients
kD1MfccFtId, ///< 19 1st order difference over time of the Mel Frequency Cepstral Coefficients
kD1CepsFtId, ///< 20 1st order difference over time of the Cepstral Coefficients
kD1ConstQFtId, ///< 21 1st order difference over time of the Constant-Q transform
kD1LogConstQFtId, ///< 22 1st order difference over time of the Log Constant-Q transform
kD1RmsFtId, ///< 23 1st order difference over time of the Root means square of the audio signal
kD1DbRmsFtId, ///< 24 1st order difference over time of the RMS in decibels
kD1AmplFtId, // 13 1st order difference over time of the Fourier transform amplitude
kD1DbAmplFtId, // 14 1st order difference over time of the Fourier transform decibel
kD1PowFtId, // 15 1st order difference over time of the Fourier transform power
kD1DbPowFtId, // 16 1st order difference over time of the Fourier transform power decibel
kD1PhaseFtId, // 17 1st order difference over time of the Fourier transform phase (not unwrapped)
kD1BfccFtId, // 18 1st order difference over time of the Bark Frequency Cepstral Coeffcients
kD1MfccFtId, // 19 1st order difference over time of the Mel Frequency Cepstral Coefficients
kD1CepsFtId, // 20 1st order difference over time of the Cepstral Coefficients
kD1ConstQFtId, // 21 1st order difference over time of the Constant-Q transform
kD1LogConstQFtId, // 22 1st order difference over time of the Log Constant-Q transform
kD1RmsFtId, // 23 1st order difference over time of the Root means square of the audio signal
kD1DbRmsFtId, // 24 1st order difference over time of the RMS in decibels
};
/// User defined feature parameters
// User defined feature parameters
typedef struct
{
unsigned id; ///< feature id
unsigned cnt; ///< length of feature vector
bool normFl; ///< normalize this feature
bool enableFl; ///< true if this feature is enabled
unsigned id; // feature id
unsigned cnt; // length of feature vector
bool normFl; // normalize this feature
bool enableFl; // true if this feature is enabled
} cmFtAttr_t;
/// Skip input audio range record
// Skip input audio range record
typedef struct
{
unsigned smpIdx; ///< Index of first sample to skip
unsigned smpCnt; ///< Count of successive samples to skip.
unsigned smpIdx; // Index of first sample to skip
unsigned smpCnt; // Count of successive samples to skip.
} cmFtSkip_t;
/// Analysis parameters
// Analysis parameters
typedef struct
{
const char* audioFn; ///< Audio file name.
const char* featFn; ///< Feature file name.
unsigned chIdx; ///< Audio file channel index
cmReal_t wndMs; ///< Length of the analysis window in milliseconds.
unsigned hopFact; ///< Analysis window overlap factor 1 = 1:1 2=2:1 ...
bool normAudioFl; ///< Normalize the audio over the length of the audio file
cmMidiByte_t constQMinPitch; ///< Used to determine the base const-q octave.
cmMidiByte_t constQMaxPitch; ///< Used to determine the maximum const-q frequency of interest.
unsigned constQBinsPerOctave; ///< Bands per const-q octave.
unsigned onsetMedFiltWndSmpCnt; ///< Complex onset median filter
cmReal_t onsetThreshold; ///< Complex onset threshold
cmReal_t minDb; ///< Fourier Transform magnitude values below minDb are set to minDb.
cmReal_t floorThreshDb; ///< Frames with an RMS below this value will be skipped
cmFtSkip_t* skipArray; ///< skipArray[skipCnt] user defined sample skip ranges
unsigned skipCnt; ///< Count of records in skipArray[].
cmFtAttr_t* attrArray; ///< attrArray[attrCnt] user defined parameter array
unsigned attrCnt; ///< Count of records in attrArray[].
const char* audioFn; // Audio file name.
const char* featFn; // Feature file name.
unsigned chIdx; // Audio file channel index
cmReal_t wndMs; // Length of the analysis window in milliseconds.
unsigned hopFact; // Analysis window overlap factor 1 = 1:1 2=2:1 ...
bool normAudioFl; // Normalize the audio over the length of the audio file
cmMidiByte_t constQMinPitch; // Used to determine the base const-q octave.
cmMidiByte_t constQMaxPitch; // Used to determine the maximum const-q frequency of interest.
unsigned constQBinsPerOctave; // Bands per const-q octave.
unsigned onsetMedFiltWndSmpCnt; // Complex onset median filter
cmReal_t onsetThreshold; // Complex onset threshold
cmReal_t minDb; // Fourier Transform magnitude values below minDb are set to minDb.
cmReal_t floorThreshDb; // Frames with an RMS below this value will be skipped
cmFtSkip_t* skipArray; // skipArray[skipCnt] user defined sample skip ranges
unsigned skipCnt; // Count of records in skipArray[].
cmFtAttr_t* attrArray; // attrArray[attrCnt] user defined parameter array
unsigned attrCnt; // Count of records in attrArray[].
} cmFtParam_t;
/// Feature summary information
// Feature summary information
typedef struct
{
unsigned id; ///< feature id (same as associated cmFtAttr.id)
unsigned cnt; ///< length of each feature vector (same as associated cmFtAttr.cnt)
unsigned id; // feature id (same as associated cmFtAttr.id)
unsigned cnt; // length of each feature vector (same as associated cmFtAttr.cnt)
/// The raw feature summary values are calculated prior to normalization.
cmReal_t* rawMinV; ///< Vector of min value over time for each feature element.
cmReal_t* rawMaxV; ///< Vector of max value over time for each feature element.
cmReal_t* rawAvgV; ///< Vector of avg value over time for each feature element.
cmReal_t* rawSdvV; ///< Vector of standard deviation values over time for each feature element.
cmReal_t rawMin; ///< Min value of all values for this feature. Equivalent to min(rawMinV).
cmReal_t rawMax; ///< Max value of all values for this feature. Equivalent to max(rawMaxV).
// The raw feature summary values are calculated prior to normalization.
cmReal_t* rawMinV; // Vector of min value over time for each feature element.
cmReal_t* rawMaxV; // Vector of max value over time for each feature element.
cmReal_t* rawAvgV; // Vector of avg value over time for each feature element.
cmReal_t* rawSdvV; // Vector of standard deviation values over time for each feature element.
cmReal_t rawMin; // Min value of all values for this feature. Equivalent to min(rawMinV).
cmReal_t rawMax; // Max value of all values for this feature. Equivalent to max(rawMaxV).
/// normalized feature summary values
cmReal_t* normMinV; ///< Vector of min value over time for each feature element.
cmReal_t* normMaxV; ///< Vector of max value over time for each feature element.
cmReal_t* normAvgV; ///< Vector of avg value over time for each feature element.
cmReal_t* normSdvV; ///< Vector of standard deviation values over time for each feature element.
cmReal_t normMin; ///< Min value of all values for this feature. Equivalent to min(normMinV).
cmReal_t normMax; ///< Max value of all values for this feature. Equivalent to max(rawMaxV).
// normalized feature summary values
cmReal_t* normMinV; // Vector of min value over time for each feature element.
cmReal_t* normMaxV; // Vector of max value over time for each feature element.
cmReal_t* normAvgV; // Vector of avg value over time for each feature element.
cmReal_t* normSdvV; // Vector of standard deviation values over time for each feature element.
cmReal_t normMin; // Min value of all values for this feature. Equivalent to min(normMinV).
cmReal_t normMax; // Max value of all values for this feature. Equivalent to max(rawMaxV).
} cmFtSumm_t;
/// Feature file info record
// Feature file info record
typedef struct
{
unsigned frmCnt; ///< count of frames in the file
cmReal_t srate; ///< audio sample rate
unsigned smpCnt; ///< audio sample count
unsigned fftSmpCnt; ///< FFT window length (always power of 2)
unsigned hopSmpCnt; ///< audio sample hop count
unsigned binCnt; ///< FFT bin count (always fftSmpCnt/2 + 1)
unsigned skipFrmCnt; ///< count of frames skipped based on user skip array
unsigned floorFrmCnt; ///< count of frames skipped because below floorThreshDb
cmFtParam_t param; ///< analysis parameter record used to form this feature file
cmFtSumm_t* summArray; ///< summArray[ param.attrCnt ] feature summary information
unsigned frmCnt; // count of frames in the file
cmReal_t srate; // audio sample rate
unsigned smpCnt; // audio sample count
unsigned fftSmpCnt; // FFT window length (always power of 2)
unsigned hopSmpCnt; // audio sample hop count
unsigned binCnt; // FFT bin count (always fftSmpCnt/2 + 1)
unsigned skipFrmCnt; // count of frames skipped based on user skip array
unsigned floorFrmCnt; // count of frames skipped because below floorThreshDb
cmFtParam_t param; // analysis parameter record used to form this feature file
cmFtSumm_t* summArray; // summArray[ param.attrCnt ] feature summary information
} cmFtInfo_t;
/// Data structure returned by cmFtReaderAdvance().
// Data structure returned by cmFtReaderAdvance().
typedef struct
{
unsigned smpIdx; ///< The audio signal sample index this frames information is based on.
unsigned frmIdx; ///< The frame index relative to other frames in this feature file.
unsigned smpIdx; // The audio signal sample index this frames information is based on.
unsigned frmIdx; // The frame index relative to other frames in this feature file.
} cmFtFrameDesc_t;
typedef cmHandle_t cmFtH_t; ///< Analyzer handle
typedef cmHandle_t cmFtFileH_t; ///< Feature file handle.
typedef unsigned cmFtRC_t; ///< Result code type used by all functions in cmFeatFile.h.
typedef cmHandle_t cmFtH_t; // Analyzer handle
typedef cmHandle_t cmFtFileH_t; // Feature file handle.
typedef unsigned cmFtRC_t; // Result code type used by all functions in cmFeatFile.h.
extern cmFtH_t cmFtNullHandle; ///< A NULL handle useful for indicating an uninitialized analyzer.
extern cmFtFileH_t cmFtFileNullHandle; ///< A NULL handle useful for indicating an uninitialized feature file.
extern cmFtH_t cmFtNullHandle; // A NULL handle useful for indicating an uninitialized analyzer.
extern cmFtFileH_t cmFtFileNullHandle; // A NULL handle useful for indicating an uninitialized feature file.
/// Given a feature type id return the associated label.
// Given a feature type id return the associated label.
const char* cmFtFeatIdToLabel( unsigned featId );
/// Given a feature type label return the associated id.
// Given a feature type label return the associated id.
unsigned cmFtFeatLabelToId( const char* label );
/// \name Feature Analyzer Related functions
///@{
// Feature Analyzer Related functions
/// Initialize the feature analyzer. The memory manager and file system must
/// be initialized (cmMdInitialize(), cmFsInitialize()) prior to calling this function.
// Initialize the feature analyzer. The memory manager and file system must
// be initialized (cmMdInitialize(), cmFsInitialize()) prior to calling this function.
cmFtRC_t cmFtInitialize( cmFtH_t* hp, cmCtx_t* ctx );
/// Finalize a feature analyzer.
// Finalize a feature analyzer.
cmFtRC_t cmFtFinalize( cmFtH_t* h );
/// Return true if the handle represents an initialized feature analyzer.
// Return true if the handle represents an initialized feature analyzer.
bool cmFtIsValid( cmFtH_t h );
/// Parse a JSON file containing a set of analysis parameters.
// Parse a JSON file containing a set of analysis parameters.
cmFtRC_t cmFtParse( cmFtH_t h, const char* cfgFn );
/// Run the analyzer.
// Run the analyzer.
cmFtRC_t cmFtAnalyze( cmFtH_t h );
/// If cmFtAnalyze() is being run in a seperate thread this function
/// can be used to access the analyzers progress.
// If cmFtAnalyze() is being run in a seperate thread this function
// can be used to access the analyzers progress.
const char* cmFtAnalyzeProgress( cmFtH_t h, unsigned* passPtr, cmReal_t* percentPtr );
///@}
/// \name Feature File Related Functions
///@{
// Feature File Related Functions
/// Open a feature file.
/// Note that inforPtrPtr is optional and will be ignored if it is set to NULL.
// Open a feature file.
// Note that inforPtrPtr is optional and will be ignored if it is set to NULL.
cmFtRC_t cmFtReaderOpen( cmFtH_t h, cmFtFileH_t* hp, const char* featFn, const cmFtInfo_t** infoPtrPtr );
/// Close a feature file.
// Close a feature file.
cmFtRC_t cmFtReaderClose( cmFtFileH_t* hp );
/// Return true if the handle reprents an open feature file.
// Return true if the handle reprents an open feature file.
bool cmFtReaderIsValid( cmFtFileH_t h );
/// Return the count of features types this file contains.
// Return the count of features types this file contains.
unsigned cmFtReaderFeatCount( cmFtFileH_t h );
/// Return the feature type id associated with the specified index.
// Return the feature type id associated with the specified index.
unsigned cmFtReaderFeatId( cmFtFileH_t h, unsigned index );
/// Reset the current file location to the first frame but do not load it.
/// The next call to cmFtReadAdvance() will load the next frame.
// Reset the current file location to the first frame but do not load it.
// The next call to cmFtReadAdvance() will load the next frame.
cmFtRC_t cmFtReaderRewind( cmFtFileH_t h );
/// Make frmIdx the current file location.
// Make frmIdx the current file location.
cmFtRC_t cmFtReaderSeek( cmFtFileH_t h, unsigned frmIdx );
/// Load the current frame, advance the current file position, and return
/// a pointer to a cmFtFrameDesc_t record for the loaded frame.
/// Returns kEofFtRC upon reaching end of file.
/// The frameDescPtr is optional.
// Load the current frame, advance the current file position, and return
// a pointer to a cmFtFrameDesc_t record for the loaded frame.
// Returns kEofFtRC upon reaching end of file.
// The frameDescPtr is optional.
cmFtRC_t cmFtReaderAdvance( cmFtFileH_t h, cmFtFrameDesc_t* frameDescPtr );
/// Returns a pointer to a data matrix in the feature identified by featId in the current feature frame.
// Returns a pointer to a data matrix in the feature identified by featId in the current feature frame.
cmReal_t* cmFtReaderData( cmFtFileH_t h, unsigned featId, unsigned* cntPtr );
/// Copy the contents of a given set of frames into buf[frmCnt*elePerFrmCnt].
// Copy the contents of a given set of frames into buf[frmCnt*elePerFrmCnt].
cmFtRC_t cmFtReaderCopy( cmFtFileH_t h, unsigned featId, unsigned frmIdx, cmReal_t* buf, unsigned frmCnt, unsigned elePerFrmCnt, unsigned* outEleCntPtr );
/// Data structure used to specify multiple features for use by cmFtReaderMultiSetup().
// Data structure used to specify multiple features for use by cmFtReaderMultiSetup().
typedef struct
{
unsigned featId; ///< Feature id of feature to include in the feature vector
unsigned cnt; ///< Set to count of feat ele's for this feat. Error if greater than avail. Set to -1 to use all avail ele's.
/// returned with actual count used
unsigned featId; // Feature id of feature to include in the feature vector
unsigned cnt; // Set to count of feat ele's for this feat. Error if greater than avail. Set to -1 to use all avail ele's.
// returned with actual count used
unsigned id0; ///< Ignored on input. Used internally by cmFtReaderXXX()
unsigned id1; ///< Ignored on input. Used internally by cmFtReaderXXX()
unsigned id0; // Ignored on input. Used internally by cmFtReaderXXX()
unsigned id1; // Ignored on input. Used internally by cmFtReaderXXX()
} cmFtMulti_t;
/// Setup an array of cmFtMulti_t records. The cmFtMulti_t array
/// used by cmFtReaderMulitData() must be initialized by this function.
// Setup an array of cmFtMulti_t records. The cmFtMulti_t array
// used by cmFtReaderMulitData() must be initialized by this function.
cmFtRC_t cmFtReaderMultiSetup( cmFtFileH_t h, cmFtMulti_t* multiArray, unsigned multiCnt, unsigned* featVectEleCntPtr );
/// Fill outV[outN] with a consecutive data from the features specified in the cmFtMulti_t array.
/// Use cmFtReaderMultiSetup() to configure the cmFtMulti_t array prior to calling this function.
// Fill outV[outN] with a consecutive data from the features specified in the cmFtMulti_t array.
// Use cmFtReaderMultiSetup() to configure the cmFtMulti_t array prior to calling this function.
cmFtRC_t cmFtReaderMultiData( cmFtFileH_t h, const cmFtMulti_t* multiArray, unsigned multiCnt, cmReal_t* outV, unsigned outN );
/// Report summary information for the specified feature.
// Report summary information for the specified feature.
cmFtRC_t cmFtReaderReport( cmFtFileH_t h, unsigned featId );
/// Identical to cmFtReaderReport() except the feature file is identified from a file name rather than an open cmFtFileH_t.
// Identical to cmFtReaderReport() except the feature file is identified from a file name rather than an open cmFtFileH_t.
cmFtRC_t cmFtReaderReportFn( cmFtH_t h, const cmChar_t* fn, unsigned featId );
/// Report feature data for the specified set of feature frames.
// Report feature data for the specified set of feature frames.
cmFtRC_t cmFtReaderReportFeature( cmFtFileH_t h, unsigned featId, unsigned frmIdx, unsigned frmCnt );
/// Write a feature into a binary file.
/// Set 'frmCnt' to the cmInvalidCnt to include all frames past frmIdx.
/// The first three unsigned values in the output file
/// contain the row count, maximum column count, and the count of bytes in each data element (4=float,8=double).
/// Each row of the file begins with the count of elements in the row and is followed by a data array.
// Write a feature into a binary file.
// Set 'frmCnt' to the cmInvalidCnt to include all frames past frmIdx.
// The first three unsigned values in the output file
// contain the row count, maximum column count, and the count of bytes in each data element (4=float,8=double).
// Each row of the file begins with the count of elements in the row and is followed by a data array.
cmFtRC_t cmFtReaderToBinary( cmFtFileH_t h, unsigned featId, unsigned frmIdx, unsigned frmCnt, const cmChar_t* outFn );
/// Identical to cmFtReaderToBinary() except it takes a feature file name instead of a file handle.
// Identical to cmFtReaderToBinary() except it takes a feature file name instead of a file handle.
cmFtRC_t cmFtReaderToBinaryFn( cmFtH_t h, const cmChar_t* fn, unsigned featId, unsigned frmIdx, unsigned frmCnt, const cmChar_t* outFn );
///@}
//)
#ifdef __cplusplus
}

View File

@ -1,3 +1,4 @@
#include "cmPrefix.h"
#include "cmGlobal.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
#define cmFile_h
@ -11,7 +5,13 @@
extern "C" {
#endif
//(
//( { file_desc: "File abstraction class." kw:[file system base]}
//
// The cmFile API extends the C standard file handling routines
// with cm style error handling. All cm file input and output occurs
// through this interface."
//
enum
{
kOkFileRC = cmOkRC,
@ -244,7 +244,6 @@ extern "C" {
cmFileRC_t cmFileSetRC( cmFileH_t h, cmFileRC_t rc );
//)
//}
#ifdef __cplusplus
}

View File

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

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
#define cmFloatTypes_h
@ -19,6 +6,18 @@
extern "C" {
#endif
//( { file_desc:"Declare the types cmReal_t and cmSample_t and define some useful limits." kw:[base]}
//
// For signal processing functions the cm library uses the types cmSample_t to indicate an audio
// sample value and cmReal_t to specify a general purpose floating point value. The library
// is designed in such a way that the actual type, float or double, for these two types may
// be set at compilation time. Set the preprocessor variable CM_FLOAT_SMP to 1 to indicate
// that cmSample_t will be of type 'float' otherwise it will be of type 'double'.
// Set the preprocessor variable CM_FLOAT_REAL to 1 to indicate
// that cmSample_t will be of type 'float' otherwise it will be of type 'double'.
// By default cmSample_t is float nad cmReal_t is double.
//
//-----------------------------------------------------------------
#ifndef CM_FLOAT_SMP
#define CM_FLOAT_SMP 1
@ -26,27 +25,27 @@ extern "C" {
#if CM_FLOAT_SMP == 1
typedef float cmSample_t; ///< cmSample_t is a float
typedef float _Complex cmComplexS_t;///< cmComplexS_t is single precision.
typedef float cmSample_t; // cmSample_t is a float
typedef float _Complex cmComplexS_t;// cmComplexS_t is single precision.
#define cmSample_EPSILON FLT_EPSILON ///< Minimum increment between 1.0 and the next greaterv value. (1E-5)
#define cmSample_MAX FLT_MAX ///< Maximum representable number (1E+37).
#define cmSample_MIN FLT_MIN ///< Minimum representable number (1E-37).
#define cmSample_EPSILON FLT_EPSILON // Minimum increment between 1.0 and the next greaterv value. (1E-5)
#define cmSample_MAX FLT_MAX // Maximum representable number (1E+37).
#define cmSample_MIN FLT_MIN // Minimum representable number (1E-37).
#else
typedef double cmSample_t; ///< cmSample_t is a double
typedef double _Complex cmComplexS_t; ///< cmComplexS_t is doulbe precision.
typedef double cmSample_t; // cmSample_t is a double
typedef double _Complex cmComplexS_t; // cmComplexS_t is doulbe precision.
#define cmSample_EPSILON DBL_EPSILON ///< Minimum increment between 1.0 and the next greaterv value. (1E-9)
#define cmSample_MAX DBL_MAX ///< Maximum representable number (1E+37).
#define cmSample_MIN DBL_MIN ///< Minimum representable number (1E-37).
#define cmSample_EPSILON DBL_EPSILON // Minimum increment between 1.0 and the next greaterv value. (1E-9)
#define cmSample_MAX DBL_MAX // Maximum representable number (1E+37).
#define cmSample_MIN DBL_MIN // Minimum representable number (1E-37).
#endif
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//-----------------------------------------------------------------
#ifndef CM_FLOAT_REAL
#define CM_FLOAT_REAL 0
@ -54,25 +53,27 @@ extern "C" {
#if CM_FLOAT_REAL == 1
typedef float cmReal_t; ///< cmReal_t is a float
typedef float _Complex cmComplexR_t; ///< cmComplexR_t is single precision.
typedef float cmReal_t; // cmReal_t is a float
typedef float _Complex cmComplexR_t; // cmComplexR_t is single precision.
#define cmReal_EPSILON FLT_EPSILON ///< Minimum increment between 1.0 and the next greaterv value. (1E-5)
#define cmReal_MAX FLT_MAX ///< Maximum representable number (1E+37).
#define cmReal_MIN FLT_MIN ///< Minimum representable number (1E-37).
#define cmReal_EPSILON FLT_EPSILON // Minimum increment between 1.0 and the next greaterv value. (1E-5)
#define cmReal_MAX FLT_MAX // Maximum representable number (1E+37).
#define cmReal_MIN FLT_MIN // Minimum representable number (1E-37).
#else
typedef double cmReal_t; ///< cmReal_t is a double.
typedef double _Complex cmComplexR_t; ///< cmComplexR_t is double precision.
typedef double cmReal_t; // cmReal_t is a double.
typedef double _Complex cmComplexR_t; // cmComplexR_t is double precision.
#define cmReal_EPSILON DBL_EPSILON ///< Minimum increment between 1.0 and the next greaterv value (1E-9).
#define cmReal_MAX DBL_MAX ///< Maximum representable number (1E+37).
#define cmReal_MIN DBL_MIN ///< Minimum representable number (1E-37).
#define cmReal_EPSILON DBL_EPSILON // Minimum increment between 1.0 and the next greaterv value (1E-9).
#define cmReal_MAX DBL_MAX // Maximum representable number (1E+37).
#define cmReal_MIN DBL_MIN // Minimum representable number (1E-37).
#endif
//)
#ifdef __cplusplus
}
#endif

View File

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

View File

@ -1,16 +1,17 @@
#ifndef cmFrameFile_h
#define cmFrameFile_h
/*
file -> cmFfFile_t frame*
frame -> cmFfFrame_t mtx*
mtx -> cmFfMtx_t data*
*/
#ifdef __cplusplus
extern "C" {
#endif
//( { file_desc:"File reader and writer for time series data as used by cmFeatFile" kw:[file audio]}
//
// file -> cmFfFile_t frame*
// frame -> cmFfFrame_t mtx*
// mtx -> cmFfMtx_t data*
//
enum
{
@ -139,7 +140,7 @@ extern "C" {
{
unsigned sampleIdx;
double seconds;
} time;
} tm;
} cmFfFrame_t;
@ -353,6 +354,8 @@ extern "C" {
#define kRealFmtId kDoubleFmtId
#endif
//)
#ifdef __cplusplus
}
#endif

View File

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

View File

@ -1,85 +1,91 @@
#ifndef cmGnuPlot_h
#define cmGnuPlot_h
enum
{
kOkPlRC,
kSignalFailedPlRC,
kPipeFailedPlRC,
kForkFailedPlRC,
kExecFailedPlRC,
kPipeCloseFailedPlRC,
kPlotNotFoundPlRC,
kNoCurPlotPlRC,
kPlotDataFileFailPlRC,
kFopenFailedPlRC,
kFcloseFailedPlRC
};
#ifdef __cplusplus
extern "C" {
#endif
enum
{
kInvalidPlotPtId = 0x000,
kPlusPlotPtId = 0x001,
kXPlotPtId = 0x002,
kAsteriskPlotPtId = 0x003,
kSquarePlotPtId = 0x004,
kFillSquarePlotPtId = 0x005,
kCirclePlotPtId = 0x006,
kFillCirclePlotPtId = 0x007,
kTriPlotPtId = 0x008,
kFillTriPlotPtId = 0x009,
kInvTriPlotPtId = 0x00a,
kInvFillTriPlotPtId = 0x00b,
kDiamondPlotPtId = 0x00c,
kFillDiamonPlotPtId = 0x00d,
kPlotPtMask = 0x00f,
};
//( { file_desc:"Interface to GNU Plot." kw:[plot]}
enum
{
kInvalidPlotLineId = 0x000, // -2 after translation
kSolidPlotLineId = 0x010, // -1 after translation
kDashPlotLineId = 0x020, // 0 after translation
kPlotLineMask = 0x0f0,
kPlotLineShift = 4
};
enum
{
kOkPlRC,
kSignalFailedPlRC,
kPipeFailedPlRC,
kForkFailedPlRC,
kExecFailedPlRC,
kPipeCloseFailedPlRC,
kPlotNotFoundPlRC,
kNoCurPlotPlRC,
kPlotDataFileFailPlRC,
kFopenFailedPlRC,
kFcloseFailedPlRC
};
enum
{
kImpulsePlotFl = 0x100
};
enum
{
kInvalidPlotPtId = 0x000,
kPlusPlotPtId = 0x001,
kXPlotPtId = 0x002,
kAsteriskPlotPtId = 0x003,
kSquarePlotPtId = 0x004,
kFillSquarePlotPtId = 0x005,
kCirclePlotPtId = 0x006,
kFillCirclePlotPtId = 0x007,
kTriPlotPtId = 0x008,
kFillTriPlotPtId = 0x009,
kInvTriPlotPtId = 0x00a,
kInvFillTriPlotPtId = 0x00b,
kDiamondPlotPtId = 0x00c,
kFillDiamonPlotPtId = 0x00d,
kPlotPtMask = 0x00f,
};
/// Set terminal to NULL to use the default terminal.
cmRC_t cmPlotInitialize( const char* terminalStr );
enum
{
kInvalidPlotLineId = 0x000, // -2 after translation
kSolidPlotLineId = 0x010, // -1 after translation
kDashPlotLineId = 0x020, // 0 after translation
kPlotLineMask = 0x0f0,
kPlotLineShift = 4
};
// Combines initializaion and setup in a single call.
cmRC_t cmPlotInitialize2( const char* terminalStr, const char* title, unsigned rowCnt, unsigned colCnt );
enum
{
kImpulsePlotFl = 0x100
};
cmRC_t cmPlotFinalize();
/// Set terminal to NULL to use the default terminal.
cmRC_t cmPlotInitialize( const char* terminalStr );
/// Setup the plot page
cmRC_t cmPlotSetup( const char* title, unsigned rowCnt, unsigned colCnt );
// Combines initializaion and setup in a single call.
cmRC_t cmPlotInitialize2( const char* terminalStr, const char* title, unsigned rowCnt, unsigned colCnt );
/// Select sub-plot to apply subsequent commands to
cmRC_t cmPlotSelectSubPlot( unsigned ri, unsigned ci );
cmRC_t cmPlotFinalize();
/// Clear the current current subplot
cmRC_t cmPlotClear();
/// Setup the plot page
cmRC_t cmPlotSetup( const char* title, unsigned rowCnt, unsigned colCnt );
/// Set the labels on the current sub-plot
cmRC_t cmPlotSetLabels( const char* title, const char* xLabelStr, const char* yLabelStr, const char* zLabelStr );
/// Select sub-plot to apply subsequent commands to
cmRC_t cmPlotSelectSubPlot( unsigned ri, unsigned ci );
/// Set the default ranges for the x, y and z axes. To leave the ranges at their current values set the min and max to -1.
/// The range values are used to form data sets when data is not explicitely given.
cmRC_t cmPlotSetRange( double xMin, double xMax, double yMin, double yMax, double zMin, double zMax );
/// Clear the current current subplot
cmRC_t cmPlotClear();
/// If x or y is given as NULL then the values will be taken from the range settings xMin:xMax or yMin:yMax.
/// Use the gnuplot command:'test' to see the valid lineType and pointType values for a given terminal
/// Color string may be any of the predefined color labels: show palette colornames or and rgb value: e.g. #FF00FF
cmRC_t cmPlotLineF( const char* legendStr, const float* x, const float* y, const float* z, unsigned n, const char* colorStr, unsigned styleFlags );
cmRC_t cmPlotLineD( const char* legendStr, const double* x, const double* y, const double* z, unsigned n, const char* colorStr, unsigned styleFlags );
/// Set the labels on the current sub-plot
cmRC_t cmPlotSetLabels( const char* title, const char* xLabelStr, const char* yLabelStr, const char* zLabelStr );
cmRC_t cmPlotLineMD( const double* x, const double* y, const double* z, unsigned rn, unsigned cn, unsigned styleFlags );
/// Set the default ranges for the x, y and z axes. To leave the ranges at their current values set the min and max to -1.
/// The range values are used to form data sets when data is not explicitely given.
cmRC_t cmPlotSetRange( double xMin, double xMax, double yMin, double yMax, double zMin, double zMax );
/// If x or y is given as NULL then the values will be taken from the range settings xMin:xMax or yMin:yMax.
/// Use the gnuplot command:'test' to see the valid lineType and pointType values for a given terminal
/// Color string may be any of the predefined color labels: show palette colornames or and rgb value: e.g. #FF00FF
cmRC_t cmPlotLineF( const char* legendStr, const float* x, const float* y, const float* z, unsigned n, const char* colorStr, unsigned styleFlags );
cmRC_t cmPlotLineD( const char* legendStr, const double* x, const double* y, const double* z, unsigned n, const char* colorStr, unsigned styleFlags );
cmRC_t cmPlotLineMD( const double* x, const double* y, const double* z, unsigned rn, unsigned cn, unsigned styleFlags );
#if CM_FLOAT_SMP == 1
@ -95,8 +101,14 @@ cmRC_t cmPlotLineMD( const double* x, const double* y, const double* z, unsigned
#endif
cmRC_t cmPlotDraw();
cmRC_t cmPlotPrint( bool printDataFl );
cmRC_t cmPlotDrawAndPrint( bool printDataFl );
cmRC_t cmPlotDraw();
cmRC_t cmPlotPrint( bool printDataFl );
cmRC_t cmPlotDrawAndPrint( bool printDataFl );
//)
#ifdef __cplusplus
}
#endif
#endif

2
cmGr.h
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,66 +1,73 @@
#ifndef cmKeyboard_h
#define cmKeyboard_h
#ifdef __cplusplus
extern "C" {
#endif
enum
{
kInvalidKId,
kAsciiKId,
kLeftArrowKId,
kRightArrowKId,
kUpArrowKId,
kDownArrowKId,
kHomeKId,
kEndKId,
kPgUpKId,
kPgDownKId,
kInsertKId,
kDeleteKId,
//( { file_desc:"Query and get keypresses directly from the console." kw:[system] }
};
enum
{
kInvalidKId,
kAsciiKId,
kLeftArrowKId,
kRightArrowKId,
kUpArrowKId,
kDownArrowKId,
kHomeKId,
kEndKId,
kPgUpKId,
kPgDownKId,
kInsertKId,
kDeleteKId,
};
typedef struct
{
unsigned code;
char ch;
bool ctlFl;
bool altFl;
} cmKbRecd;
// Set 'p' to NULL if the value of the key is not required.
void cmKeyPress( cmKbRecd* p );
// Return non-zero if a key is waiting to be read otherwise return 0.
// Use getchar() to pick up the key.
//
// Example:
// while( 1 )
// {
// if( cmIsKeyWaiting() == 0 )
// usleep(20000);
// else
// {
// char c = getchar();
// switch(c)
// {
// ....
// }
// }
//
// }
//
// TODO: Note that this function turns off line-buffering on stdin.
// It should be changed to a three function sequence.
// bool org_state = cmSetStdinLineBuffering(false);
// ....
// cmIsKeyWaiting()
// ....
// cmSetStdinLineBuffering(org_state)
int cmIsKeyWaiting();
//)
typedef struct
{
unsigned code;
char ch;
bool ctlFl;
bool altFl;
} cmKbRecd;
// Set 'p' to NULL if the value of the key is not required.
void cmKeyPress( cmKbRecd* p );
// Return non-zero if a key is waiting to be read otherwise return 0.
// Use getchar() to pick up the key.
//
// Example:
// while( 1 )
// {
// if( cmIsKeyWaiting() == 0 )
// usleep(20000);
// else
// {
// char c = getchar();
// switch(c)
// {
// ....
// }
// }
//
// }
//
// TODO: Note that this function turns off line-buffering on stdin.
// It should be changed to a three function sequence.
// bool org_state = cmSetStdinLineBuffering(false);
// ....
// cmIsKeyWaiting()
// ....
// cmSetStdinLineBuffering(org_state)
int cmIsKeyWaiting();
#ifdef __cplusplus
extern "C" {
#endif
#endif

View File

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

View File

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

View File

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

View File

@ -141,7 +141,7 @@ bool _cmLHeapFree( cmLHeap_t* lhp, void* dataPtr )
lbp->nextPtr = (char*)allocPtr; // ... then make it the space to alloc
else
lbp->freeCnt += *allocPtr; // ... otherwise increase the free count
//(freeCnt tracks unused space that is not at the end of the block and therefore cannot be reused.)
// freeCnt tracks unused space that is not at the end of the block and therefore cannot be reused.
// if all the space for this block has been freed then the
// next space to allocate must be at the base

View File

@ -5,8 +5,18 @@
extern "C" {
#endif
//{
//( { file_desc:"Implements a block based memory heap manager." kw:[base]}
//
// There are two advantages to using this memory manager over the cmMallocDebug
// manager. It alleviates memory fragmentation by pre-allocating large blocks of memory
// which are then used to fullfill many small memory requests. Second it can
// act as a garbage collector by releasing all the memory it is managing at once.
// This can reduce code complexity by eliminating for a class instance to release internally
// allocated objects.
//)
//(
typedef cmHandle_t cmLHeapH_t;
extern cmLHeapH_t cmLHeapNullHandle;
@ -84,7 +94,6 @@ extern "C" {
#endif
//)
//}
#ifdef __cplusplus
}

View File

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

View File

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

200
cmMath.h
View File

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

10
cmMem.h
View File

@ -1,6 +1,4 @@
//{
//(
// The cmMem class implements a memory allocation manager interface.
//( { file_desc: "Implements a memory allocation manager interface." kw:[ base ]}
//
//
// Using cmMem allows memory leaks and some instances of memory corruption
@ -20,12 +18,15 @@
// As part of the configuration the client gives callback functions which implement
// actual memory allocation and release. In practice this means the callback probably
// call malloc() or free().
//
// 2. At some point later when the client needs to allocate a block of memory it calls
// cmMmAllocate() with the size of the requested block. cmMm translates this request
// into a call to the client provided memory allocation callback to get a block of raw
// memory which is slightly larger than the request block.
//
// 3. Given the raw memory block cmMm conditions it in the following ways and returns
// it to the client.
//
// * The base of the blocks data area is shifted such that it is has an arbitrary
// address aligned according to the value set by the alignByteCnt parameter to cmMmInitialize().
// Address aligment is sometimes required by routines which make use of the the SIMD
@ -54,9 +55,11 @@
// writes to freed memory areas. When deferred release is enabled the freeFunc() is not called
// on any blocks until cmMmFinalize(). If the program continually allocates memory over the
// life of the program this may mean that the program will eventually exhaust physical memory.
//
// 2. If tracking is enabled (kTrackMmFl) then the block pointer is looked up in the internal database.
// If the pointer is not found then a kMissingRecdRC is returned indicating an attempt to release
// a non-allocated block.
//
// 3. If tracking is enabled (kTrackMmFl) then the block is marked as released in the
// internal tracking database. At the end of the program all blocks should be marked for release
// otherwise they are considered leaks.
@ -223,7 +226,6 @@ extern "C" {
cmMmRC_t cmMmCheckAllGuards( cmMmH_t h );
//)
//}
#ifdef __cplusplus
}
#endif

View File

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

View File

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

View File

@ -5,6 +5,7 @@
extern "C" {
#endif
//( { file_desc:"MIDI file reader and writer." kw:[midi file]}
// MIDI file timing:
// Messages in the MIDI file are time tagged with a delta offset in 'ticks'
// from the previous message in the same track.
@ -22,9 +23,9 @@ extern "C" {
//
// As part of the file reading process, the status byte of note-on messages
// with velocity=0 are is changed to a note-off message. See _cmMidiFileReadChannelMsg().
//)
//(
typedef cmHandle_t cmMidiFileH_t;
typedef unsigned cmMfRC_t;
@ -56,15 +57,17 @@ extern "C" {
cmMidiByte_t ch;
cmMidiByte_t d0;
cmMidiByte_t d1;
unsigned durTicks; // note duration calc'd by cmMidiFileCalcNoteDurations();
unsigned durMicros; // note duration in microseconds (corrected for tempo changes)
} cmMidiChMsg_t;
typedef struct cmMidiTrackMsg_str
{
unsigned uid; // uid's are unique among all msg's in the file
unsigned dtick; // delta ticks
unsigned atick; // accumulated ticks
unsigned dtick; // delta ticks between events on this track
unsigned dmicro; // delta microseconds between events on this track adjusted for tempo changes
unsigned atick; // global (all tracks interleaved) accumulated ticks
unsigned amicro; // global (all tracks interleaved) accumulated microseconds adjusted for tempo changes
cmMidiByte_t status; // ch msg's have the channel value removed (it is stored in u.chMsgPtr->ch)
cmMidiByte_t metaId; //
unsigned short trkIdx; //
@ -152,13 +155,6 @@ extern "C" {
double cmMidiFileDurSecs( cmMidiFileH_t h );
// Convert the track message 'dtick' field to delta-microseconds.
void cmMidiFileTickToMicros( cmMidiFileH_t h );
// Convert the track message 'dtick' field to samples.
// If the absFl is set then the delta times are converted to absolute time.
void cmMidiFileTickToSamples( cmMidiFileH_t h, double srate, bool absFl );
// Calculate Note Duration
void cmMidiFileCalcNoteDurations( cmMidiFileH_t h );
@ -171,10 +167,13 @@ extern "C" {
cmMidiTrackMsg_t* cmMidiFilePackTrackMsg( const cmMidiTrackMsg_t* m, void* buf, unsigned bufByteCnt );
unsigned cmMidiFilePackTrackMsgBufByteCount( const cmMidiTrackMsg_t* m );
void cmMidiFilePrint( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt );
void cmMidiFilePrintMsgs( cmMidiFileH_t h, cmRpt_t* rpt );
void cmMidiFilePrintTrack( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt );
bool cmMidiFileIsNull( cmMidiFileH_t h );
void cmMidiFileTest( const char* fn, cmCtx_t* ctx );
//)
#ifdef __cplusplus
}
#endif

View File

@ -148,9 +148,6 @@ cmMfpRC_t cmMfpLoadHandle( cmMfpH_t h, cmMidiFileH_t mfH )
p->mtime = 0;
p->closeFileFl= false;
//if( p->msgIdx > 0 )
// p->mtime = p->msgV[0]->tick * p->microsPerTick;
return kOkMfpRC;
}
@ -213,35 +210,31 @@ cmMfpRC_t cmMfpClock( cmMfpH_t h, unsigned dusecs )
// sent and the end of the time window for this mfpClock() cycle
p->etime += dusecs;
//printf("init e:%i d:%i\n",p->etime, p->mtime);
// if the elapsed time (etime) since the last msg is greater or equal
// to the delta time to the next msg (mtime)
while( p->etime >= p->mtime )
{
//printf("e:%i d:%i\n",p->etime, p->mtime);
if( mp->status == kMetaStId && mp->metaId == kTempoMdId )
_cmMfpUpdateMicrosPerTick(p,mp->u.iVal );
// send the current message
p->cbFunc( p->userCbPtr, p->mtime, mp );
unsigned amicro = mp->amicro;
++(p->msgIdx);
if( p->msgIdx >= p->msgN )
break;
// get the next msg to send
mp = p->msgV[p->msgIdx];
mp = p->msgV[p->msgIdx];
// we probably went past the actual mtime - so update etime
// with the delta usecs from the msg just sent and the current time
p->etime -= p->mtime;
// calc the delta usecs from the message just sent to the next msg to send
//p->mtime = (mp->tick - p->msgV[p->msgIdx-1]->tick) * p->microsPerTick;
p->mtime = mp->dtick * p->microsPerTick;
p->mtime = mp->amicro - amicro;
}

View File

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

View File

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

View File

@ -7,6 +7,7 @@
extern "C" {
#endif
//( { file_desc:"Global constants and data structures for transmiting messages between threads and network nodes.", kw:[real_time]}
#define cmAudDspSys_FILENAME "aud_dsp.js"
@ -134,6 +135,8 @@ extern "C" {
cmMsgRC_t cmMsgPeekInstId( const void* msgArray[], unsigned msgByteCntArray[], unsigned segCnt, unsigned* retValPtr );
cmMsgRC_t cmMsgPeekInstVarId( const void* msgArray[], unsigned msgByteCntArray[], unsigned segCnt, unsigned* retValPtr );
//)
#ifdef __cplusplus
}
#endif

View File

@ -1250,7 +1250,7 @@ void cmPgmOptPrintHelp( cmPgmOptH_t h, cmRpt_t* rpt )
reqLabel = reqStr;
if( mstr != NULL )
cmRptPrintf(rpt,"Enumerated group: %s %s",mstr->mstrStr==NULL ? "" : mstr->mstrStr, cmIsFlag(mstr->cflags,kReqPoFl) ? reqStr : "" );
cmRptPrintf(rpt,"Enumerated group: %s %s\n",mstr->mstrStr==NULL ? "" : mstr->mstrStr, cmIsFlag(mstr->cflags,kReqPoFl) ? reqStr : "" );
cmRptPrintf(rpt,"%s-%c --%s %s %s",indentStr,r->charId,r->wordId,valueTypeLabel,reqLabel);

View File

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

View File

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

244
cmProc.h
View File

@ -5,7 +5,10 @@
extern "C" {
#endif
//------------------------------------------------------------------------------------------------------------
//( { file_desc:"Processor Library 1" kw:[proclib]}
//)
//( { label:cmAudioFileRd file_desc:"Audio file reader based on cmAudioFile" kw:[proc] }
typedef struct
{
cmObj obj;
@ -23,28 +26,30 @@ extern "C" {
cmMtxFile* mfp;
} cmAudioFileRd;
/// set p to NULL to dynamically allocate the object
/// fn and chIdx are optional - set fn to NULL to allocate the reader without opening a file.
/// If fn is valid then chIdx must also be valid.
/// Set 'endSmpIdx' to cmInvalidIdx to return the entire signal in cmAudioFileRdRead().
/// Set 'endSmpIdx' to 0 to return all samples between 0 and the end of the file.
// set p to NULL to dynamically allocate the object
// fn and chIdx are optional - set fn to NULL to allocate the reader without opening a file.
// If fn is valid then chIdx must also be valid.
// Set 'endSmpIdx' to cmInvalidIdx to return the entire signal in cmAudioFileRdRead().
// Set 'endSmpIdx' to 0 to return all samples between 0 and the end of the file.
cmAudioFileRd* cmAudioFileRdAlloc( cmCtx* c, cmAudioFileRd* p, unsigned procSmpCnt, const char* fn, unsigned chIdx, unsigned begSmpIdx, unsigned endSmpIdx );
cmRC_t cmAudioFileRdFree( cmAudioFileRd** p );
cmRC_t cmAudioFileRdOpen( cmAudioFileRd* p, unsigned procSmpCnt, const cmChar_t* fn, unsigned chIdx, unsigned begSmpIdx, unsigned endSmpIdx );
cmRC_t cmAudioFileRdClose( cmAudioFileRd* p );
/// Returns cmEofRC if the end of file is encountered.
// Returns cmEofRC if the end of file is encountered.
cmRC_t cmAudioFileRdRead( cmAudioFileRd* p );
cmRC_t cmAudioFileRdSeek( cmAudioFileRd* p, unsigned frmIdx );
/// Find the overall minimum, maximum, and mean sample values without changing the current file location.
// Find the overall minimum, maximum, and mean sample values without changing the current file location.
cmRC_t cmAudioFileRdMinMaxMean( cmAudioFileRd* p, unsigned chIdx, cmSample_t* minPtr, cmSample_t* maxPtr, cmSample_t* meanPtr );
//)
//( { label:cmShiftBuf file_desc:"Audio shift buffer processor" kw:[proc] }
//------------------------------------------------------------------------------------------------------------
/// The buffer is intended to synchronize sample block rates between processes and to provide an overlapped
/// input buffer.
// The buffer is intended to synchronize sample block rates between processes and to provide an overlapped
// input buffer.
typedef struct cmShiftBuf_str
{
cmObj obj;
@ -61,89 +66,36 @@ extern "C" {
/// Set p to NULL to dynamically allocate the object. hopSmpCnt must be <= wndSmpCnt.
// Set p to NULL to dynamically allocate the object. hopSmpCnt must be <= wndSmpCnt.
cmShiftBuf* cmShiftBufAlloc( cmCtx* c, cmShiftBuf* p, unsigned procSmpCnt, unsigned wndSmpCnt, unsigned hopSmpCnt );
cmRC_t cmShiftBufFree( cmShiftBuf** p );
cmRC_t cmShiftBufInit( cmShiftBuf* p, unsigned procSmpCnt, unsigned wndSmpCnt, unsigned hopSmpCnt );
cmRC_t cmShiftBufFinal( cmShiftBuf* p );
/// Returns true if a new hop is ready to be read otherwise returns false.
/// In general cmShiftBufExec() should be called in a loop until it returns false.
/// Note that 'sp' and 'sn' are ignored except for the first call after the function returns false.
/// This means that when called in a loop 'sp' and 'sn' are only used on the first time through the loop.
/// When procSmpCnt is less than hopSmpCnt the loop will only execute when at least wndSmpCnt
/// new samples have been buffered.
/// When procSmpCnt is greater than hopSmpCnt the loop will execute multiple times until less
// Returns true if a new hop is ready to be read otherwise returns false.
// In general cmShiftBufExec() should be called in a loop until it returns false.
// Note that 'sp' and 'sn' are ignored except for the first call after the function returns false.
// This means that when called in a loop 'sp' and 'sn' are only used on the first time through the loop.
// When procSmpCnt is less than hopSmpCnt the loop will only execute when at least wndSmpCnt
// new samples have been buffered.
// When procSmpCnt is greater than hopSmpCnt the loop will execute multiple times until less
// than wndSmpCnt new samples are available.
/// Note that 'sn' must always be less than or equal to procSmpCnt.
///
/// Example:
/// while( fill(sp,sn) ) // fill sp[] with sn samples
/// {
/// // shift by hopSmpCnt samples on all passes - insert new samples on first pass
/// while( cmShiftBufExec(p,sp,sn) )
/// proc(p->outV,p->outN); // process p->outV[wndSmpCnt]
/// }
// Note that 'sn' must always be less than or equal to procSmpCnt.
//
// Example:
// while( fill(sp,sn) ) // fill sp[] with sn samples
// {
// // shift by hopSmpCnt samples on all passes - insert new samples on first pass
// while( cmShiftBufExec(p,sp,sn) )
// proc(p->outV,p->outN); // process p->outV[wndSmpCnt]
// }
bool cmShiftBufExec( cmShiftBuf* p, const cmSample_t* sp, unsigned sn );
void cmShiftBufTest( cmCtx* c );
//------------------------------------------------------------------------------------------------------------
/*
typedef struct
{
cmComplexS_t* complexV;
cmSample_t* outV;
cmFftPlanS_t plan;
} cmIFftObjS;
//)
typedef struct
{
cmComplexR_t* complexV;
cmReal_t* outV;
cmFftPlanR_t plan;
} cmIFftObjR;
typedef struct
{
cmObj obj;
unsigned binCnt;
unsigned outN;
union
{
cmIFftObjS sr;
cmIFftObjR rr;
}u;
} cmIFft;
cmIFft* cmIFftAllocS( cmCtx* c, cmIFft* p, unsigned binCnt );
cmIFft* cmIFftAllocR( cmCtx* c, cmIFft* p, unsigned binCnt );
cmRC_t cmIFftFreeS( cmIFft** pp );
cmRC_t cmIFftFreeR( cmIFft** pp );
cmRC_t cmIFftInitS( cmIFft* p, unsigned binCnt );
cmRC_t cmIFftInitR( cmIFft* p, unsigned binCnt );
cmRC_t cmIFftFinalS( cmIFft* p );
cmRC_t cmIFftFinalR( cmIFft* p );
// x must contain 'binCnt' elements.
cmRC_t cmIFftExecS( cmIFft* p, cmComplexS_t* x );
cmRC_t cmIFftExecR( cmIFft* p, cmComplexR_t* x );
cmRC_t cmIFftExecPolarS( cmIFft* p, const cmReal_t* magV, const cmReal_t* phsV );
cmRC_t cmIFftExecPolarR( cmIFft* p, const cmReal_t* magV, const cmReal_t* phsV );
cmRC_t cmIFftExecRectS( cmIFft* p, const cmReal_t* rV, const cmReal_t* iV );
cmRC_t cmIFftExecPolarR( cmIFft* p, const cmReal_t* magV, const cmReal_t* phsV );
void cmIFftTest( cmRpt_t* rptFuncPtr );
*/
//------------------------------------------------------------------------------------------------------------
//( { label:cmWindowFunc file_desc:"Fourier Transform window function generator." kw:[proc]}
enum
{
@ -174,8 +126,8 @@ extern "C" {
cmMtxFile* mfp;
} cmWndFunc;
/// Set p to NULL to dynamically allocate the object
/// if wndId is set to a valid value this function will internally call cmWndFuncInit()
// Set p to NULL to dynamically allocate the object
// if wndId is set to a valid value this function will internally call cmWndFuncInit()
cmWndFunc* cmWndFuncAlloc( cmCtx* c, cmWndFunc* p, unsigned wndId, unsigned wndSmpCnt, double kaierSideLobeRejectDb );
cmRC_t cmWndFuncFree( cmWndFunc** pp );
cmRC_t cmWndFuncInit( cmWndFunc* p, unsigned wndId, unsigned wndSmpCnt, double kaiserSideLobeRejectDb );
@ -184,9 +136,11 @@ extern "C" {
void cmWndFuncTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
//------------------------------------------------------------------------------------------------------------
/// Spectral frame delay. A circular buffer for spectral (or other fixed length) vectors.
//)
//( { label:cmSpecDelay file_desc:"Spectral frame delay. A circular buffer for spectral (or other fixed length) vectors." kw:[proc]}
typedef struct
{
cmObj obj;
@ -197,24 +151,25 @@ extern "C" {
} cmSpecDelay;
/// Set p to NULL to dynamically allocate the object.
/// Allocate a spectral frame delay capable of delaying for 'maxDelayCnt' hops and
/// where each vector contains 'binCnt' elements.
// Set p to NULL to dynamically allocate the object.
// Allocate a spectral frame delay capable of delaying for 'maxDelayCnt' hops and
// where each vector contains 'binCnt' elements.
cmSpecDelay* cmSpecDelayAlloc( cmCtx* c, cmSpecDelay* p, unsigned maxDelayCnt, unsigned binCnt );
cmRC_t cmSpecDelayFree( cmSpecDelay** p );
cmRC_t cmSpecDelayInit( cmSpecDelay* p, unsigned maxDelayCnt, unsigned binCnt );
cmRC_t cmSpecDelayFinal(cmSpecDelay* p );
/// Give an input vector to the delay. 'sn' must <= binCnt
// Give an input vector to the delay. 'sn' must <= binCnt
cmRC_t cmSpecDelayExec( cmSpecDelay* p, const cmSample_t* sp, unsigned sn );
/// Get a pointer to a delayed vector. 'delayCnt' indicates the length of the delay in hops.
/// (e.g. 1 is the previous hop, 2 is two hops previous, ... )
// Get a pointer to a delayed vector. 'delayCnt' indicates the length of the delay in hops.
// (e.g. 1 is the previous hop, 2 is two hops previous, ... )
const cmSample_t* cmSpecDelayOutPtr(cmSpecDelay* p, unsigned delayCnt );
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmFilter file_desc:"General purpose, LTI, Octave compatible, filter." kw:[proc] }
typedef struct cmFilter_str
{
cmObj obj;
@ -257,9 +212,10 @@ extern "C" {
void cmFilterTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
void cmFilterFilterTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmComplexDetect file_desc:"Complex domain onset detection function." kw:[proc] }
typedef struct
{
cmObj obj;
@ -271,14 +227,16 @@ extern "C" {
//unsigned cdfSpRegId;
} cmComplexDetect;
/// Set p to NULL to dynamically allocate the object.
// Set p to NULL to dynamically allocate the object.
cmComplexDetect* cmComplexDetectAlloc(cmCtx* c, cmComplexDetect* p, unsigned binCnt );
cmRC_t cmComplexDetectFree( cmComplexDetect** pp);
cmRC_t cmComplexDetectInit( cmComplexDetect* p, unsigned binCnt );
cmRC_t cmComplexDetectFinal(cmComplexDetect* p);
cmRC_t cmComplexDetectExec( cmComplexDetect* p, const cmSample_t* magV, const cmSample_t* phsV, unsigned binCnt );
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmComplexOnset file_desc:"Complex onset detection function" kw:[proc]}
typedef struct
{
cmObj obj;
@ -298,8 +256,10 @@ extern "C" {
cmRC_t cmComplexOnsetFinal( cmComplexOnset* p);
cmRC_t cmComplexOnsetExec( cmComplexOnset* p, cmSample_t cdf );
cmRC_t cmComplexOnsetCalc( cmComplexOnset* p );
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmMfcc file_desc:"Mel Frequency Cepstral Coefficient (MFCC) measurement function." kw:[proc] }
typedef struct
{
cmObj obj;
@ -321,8 +281,10 @@ extern "C" {
cmRC_t cmMfccExecPower( cmMfcc* p, const cmReal_t* magPowV, unsigned binCnt );
cmRC_t cmMfccExecAmplitude( cmMfcc* p, const cmReal_t* magAmpV, unsigned binCnt );
void cmMfccTest();
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmSones file_desc:"Sones measurement function." kw:[proc] }
typedef struct
{
cmObj obj;
@ -350,8 +312,10 @@ extern "C" {
cmRC_t cmSonesExec( cmSones* p, const cmReal_t* magPowV, unsigned binCnt );
void cmSonesTest();
//------------------------------------------------------------------------------------------------------------
//)
//( { label: cmAudioOffsetScale file_desc:"Audio signal pre-processing normalizer." kw:[proc] }
typedef struct
{
cmObj obj;
@ -371,15 +335,15 @@ extern "C" {
} cmAudioOffsetScale;
/// This processor adds an offset to an audio signal and scales into dB (SPL) using one of two techniques
/// 1) Measures the effective sound pressure (via RMS) and then scales the signal to the reference dB (SPL)
/// In this case dBref is commonly set to 70. See Timony, 2004, Implementing Loudness Models in Matlab.
///
/// 2) treats the dBref as the maximum dB (SPL) and scales the signal by this amount without regard
/// measured signal level. In this case dBref is commonly set to 96 (max. dB (SPL) value for 16 bits)
/// and rmsWndSecs is ignored.
///
/// Note that setting rmsWndSecs to zero has the effect of using procSmpCnt as the window length.
// This processor adds an offset to an audio signal and scales into dB (SPL) using one of two techniques
// 1) Measures the effective sound pressure (via RMS) and then scales the signal to the reference dB (SPL)
// In this case dBref is commonly set to 70. See Timony, 2004, Implementing Loudness Models in Matlab.
//
// 2) treats the dBref as the maximum dB (SPL) and scales the signal by this amount without regard
// measured signal level. In this case dBref is commonly set to 96 (max. dB (SPL) value for 16 bits)
// and rmsWndSecs is ignored.
//
// Note that setting rmsWndSecs to zero has the effect of using procSmpCnt as the window length.
enum { kNoAudioScaleFl=0x01, kRmsAudioScaleFl=0x02, kFixedAudioScaleFl=0x04 };
@ -388,8 +352,10 @@ extern "C" {
cmRC_t cmAudioOffsetScaleInit( cmAudioOffsetScale* p, unsigned procSmpCnt, double srate, cmSample_t offset, double rmsWndSecs, double dBref, unsigned flags );
cmRC_t cmAudioOffsetScaleFinal( cmAudioOffsetScale* p );
cmRC_t cmAudioOffsetScaleExec( cmAudioOffsetScale* p, const cmSample_t* sp, unsigned sn );
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmSpecMeas file_desc:"Measure a signals RMS, High-Frequency Content, Spectral Centroid, and Spectral Spread." kw:[proc]}
typedef struct
{
cmObj obj;
@ -422,10 +388,10 @@ extern "C" {
unsigned ssSpRegId;
} cmSpecMeas;
/// Set wndFrmCnt to the number of spectral frames to take the measurement over.
/// Setting wndFrmCnt to 1 has the effect of calculating the value on the current frame only.
/// Set flags = kWholeSigSpecMeasFl to ignore wndFrmCnt and calculate the result on the entire signal.
/// In effect this treats the entire signal as the length of the measurement window.
// Set wndFrmCnt to the number of spectral frames to take the measurement over.
// Setting wndFrmCnt to 1 has the effect of calculating the value on the current frame only.
// Set flags = kWholeSigSpecMeasFl to ignore wndFrmCnt and calculate the result on the entire signal.
// In effect this treats the entire signal as the length of the measurement window.
enum { kWholeSigSpecMeasFl=0x00, kUseWndSpecMeasFl=0x01 };
cmSpecMeas* cmSpecMeasAlloc( cmCtx* c, cmSpecMeas* p, double srate, unsigned binCnt, unsigned wndFrmCnt, unsigned flags );
@ -433,8 +399,10 @@ extern "C" {
cmRC_t cmSpecMeasInit( cmSpecMeas* p, double srate, unsigned binCnt, unsigned wndFrmCnt, unsigned flags );
cmRC_t cmSpecMeasFinal( cmSpecMeas* p );
cmRC_t cmSpecMeasExec( cmSpecMeas* p, const cmReal_t* magPowV, unsigned binCnt );
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmSigMeas file_desc:"Measure a time domain signals zero crossing rate." kw:[proc]}
typedef struct
{
cmObj obj;
@ -456,8 +424,10 @@ extern "C" {
cmRC_t cmSigMeasInit( cmSigMeas* p, double srate, unsigned procSmpCnt, unsigned measSmpCnt );
cmRC_t cmSigMeasFinal( cmSigMeas* p );
cmRC_t cmSigMeasExec( cmSigMeas* p, const cmSample_t* sigV, unsigned smpCnt );
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmSRC file_desc:"Sample rate converter" kw:[proc] }
typedef struct
{
cmObj obj;
@ -476,7 +446,7 @@ extern "C" {
} cmSRC;
/// The srate paramater is the sample rate of the source signal provided via cmSRCExec()
// The srate paramater is the sample rate of the source signal provided via cmSRCExec()
cmSRC* cmSRCAlloc( cmCtx* c, cmSRC* p, double srate, unsigned procSmpCnt, unsigned upFact, unsigned dnFact );
cmRC_t cmSRCFree( cmSRC** pp );
cmRC_t cmSRCInit( cmSRC* p, double srate, unsigned procSmpCnt, unsigned upFact, unsigned dnFact );
@ -484,8 +454,10 @@ extern "C" {
cmRC_t cmSRCExec( cmSRC* p, const cmSample_t* sp, unsigned sn );
void cmSRCTest();
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmConstQ file_desc:"Contant-Q transform." kw:[proc] }
typedef struct
{
cmObj obj;
@ -510,9 +482,10 @@ extern "C" {
cmRC_t cmConstQInit( cmConstQ* p, double srate, unsigned minMidiPitch, unsigned maxMidiPitch, unsigned binsPerOctave, double thresh );
cmRC_t cmConstQFinal( cmConstQ* p );
cmRC_t cmConstQExec( cmConstQ* p, const cmComplexR_t* ftV, unsigned binCnt );
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmTuneHpcp file_desc:"Generate a tuned chromagram." kw:[proc]}
typedef struct
{
cmObj obj;
@ -545,10 +518,10 @@ extern "C" {
cmRC_t cmTunedHpcpFinal( cmHpcp* p );
cmRC_t cmTunedHpcpExec( cmHpcp* p, const cmComplexR_t* constQBinPtr, unsigned constQBinCnt );
cmRC_t cmTunedHpcpTuneAndFilter( cmHpcp* p);
//------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmBeatHist file_desc:"Generate a beat candidate histogram." kw:[proc]}
struct cmFftRR_str;
struct cmIFftRR_str;
@ -579,9 +552,11 @@ extern "C" {
cmRC_t cmBeatHistFinal( cmBeatHist* p );
cmRC_t cmBeatHistExec( cmBeatHist* p, cmSample_t df );
cmRC_t cmBeatHistCalc( cmBeatHist* p );
//------------------------------------------------------------------------------------------------------------
// Gaussian Mixture Model containing N Gaussian PDF's each of dimension D
//)
//( { label:cmGmm file_desc"Gaussian Mixture Model containing N Gaussian PDF's each of dimension D." kw:[proc model]}
typedef struct
{
cmObj obj;
@ -639,9 +614,11 @@ extern "C" {
void cmGmmPrint( cmGmm_t* p, bool detailsFl );
void cmGmmTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
//------------------------------------------------------------------------------------------------------------
// Continuous Hidden Markov Model
//)
//( { label:cmChmm file_desc:"Continuous Hidden Markov Model" kw:[proc model]}
typedef struct
{
cmObj obj;
@ -652,9 +629,7 @@ extern "C" {
cmReal_t* aM; // aM[ N x N] transition probability mtx
cmGmm_t** bV; // bV[ N ] observation probability mtx (array of pointers to GMM's)
cmReal_t* bM; // bM[ N,T] state-observation probability matrix
cmMtxFile* mfp;
} cmChmm_t;
// Continuous HMM consisting of stateN states where the observations
@ -706,10 +681,11 @@ extern "C" {
void cmChmmPrint( cmChmm_t* p );
void cmChmmTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
//------------------------------------------------------------------------------------------------------------
// Chord recognizer
//)
//( { label:cmChord file_desc:"HMM based chord recognizer." kw:[proc]}
typedef struct
{
@ -746,6 +722,8 @@ extern "C" {
cmRC_t cmChordFinal( cmChord* p );
void cmChordTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
//------------------------------------------------------------------------------------------------------------
//)
#ifdef __cplusplus
}

View File

@ -5950,6 +5950,7 @@ cmSpecDist_t* cmSpecDistAlloc( cmCtx* ctx,cmSpecDist_t* ap, unsigned procSmpCnt,
//p->iSpecVa = cmVectArrayAlloc(ctx,kRealVaFl);
//p->oSpecVa = cmVectArrayAlloc(ctx,kRealVaFl);
p->statVa = cmVectArrayAlloc(ctx,kDoubleVaFl);
if( procSmpCnt != 0 )
{
@ -5971,6 +5972,7 @@ cmRC_t cmSpecDistFree( cmSpecDist_t** pp )
cmSpecDistFinal(p);
//cmVectArrayFree(&p->iSpecVa);
//cmVectArrayFree(&p->oSpecVa);
cmVectArrayFree(&p->statVa);
cmMemPtrFree(&p->hzV);
cmMemPtrFree(&p->iSpecM);
cmMemPtrFree(&p->oSpecM);
@ -6095,6 +6097,7 @@ cmRC_t cmSpecDistFinal(cmSpecDist_t* p )
//cmVectArrayWrite(p->iSpecVa, "/home/kevin/temp/frqtrk/iSpec.va");
//cmVectArrayWrite(p->oSpecVa, "/home/kevin/temp/expand/oSpec.va");
//cmVectArrayWrite(p->statVa, "/Users/kevin/temp/kc/state.va");
cmPvAnlFree(&p->pva);
cmPvSynFree(&p->pvs);
@ -6111,6 +6114,7 @@ void _cmSpecDistBasicMode0(cmSpecDist_t* p, cmReal_t* X1m, unsigned binCnt, cmRe
// octave> -abs(abs(X1m+thresh)-(X1m+thresh)) - thresh
// octave> ans = -64 -62 -60 -60
/*
unsigned i=0;
for(i=0; i<binCnt; ++i)
{
@ -6123,7 +6127,13 @@ void _cmSpecDistBasicMode0(cmSpecDist_t* p, cmReal_t* X1m, unsigned binCnt, cmRe
X1m[i] -= 2*d;
}
*/
unsigned i=0;
for(i=0; i>binCnt; ++i)
{
X1m[i] = -fabs(fabs(X1m[i]-thresh) - (X1m[i]-thresh)) - thresh;
}
}
@ -6322,6 +6332,8 @@ cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn )
cmVOR_MeanM2(p->iSpecV, p->iSpecM, p->hN, p->pva->binCnt, 0, cmMin(p->fi+1,p->hN));
}
cmVOR_PowVS(X1m,p->pva->binCnt,2.0);
cmVOR_AmplToDbVV(X1m, p->pva->binCnt, p->pva->magV, -1000.0 );
//cmVOR_AmplToDbVV(X1m, p->pva->binCnt, X1m, -1000.0 );
@ -6369,7 +6381,6 @@ cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn )
cmVOR_DbToAmplVV(X1m, p->pva->binCnt, X1m );
// run and apply the tracker/supressor
//cmFrqTrkExec(p->ft, X1m, p->pva->phsV, NULL );
//cmVOR_MultVV(X1m, p->pva->binCnt,p->ft->aV );
@ -6393,6 +6404,12 @@ cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn )
p->ogain *= a0;
}
double g = u0/u1;
p->ogain0 = g + (p->ogain0 * .98);
//double v[] = { u0, u1, p->ogain, p->ogain0 };
//cmVectArrayAppendD(p->statVa,v,sizeof(v)/sizeof(v[0]));
cmVOR_MultVS(X1m,p->pva->binCnt,cmMin(4.0,p->ogain));

118
cmProc2.h
View File

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

106
cmProc3.h
View File

@ -4,6 +4,10 @@
#ifdef __cplusplus
extern "C" {
#endif
//( { file_desc:"Processor Library 3" kw:[proclib]}
//)
//( { label:cmPitchShift file_desc:"Time-domain pitch shifter based on sample rate conversion." kw:[proc]}
typedef struct
{
@ -45,7 +49,9 @@ extern "C" {
cmRC_t cmPitchShiftFinal(cmPitchShift* p );
cmRC_t cmPitchShiftExec( cmPitchShift* p, const cmSample_t* x, cmSample_t* y, unsigned n, double shiftRatio, bool bypassFl );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmLoopRecord file_desc:"Audio interactive loop recorder." kw:[proc]}
typedef struct
{
@ -90,7 +96,9 @@ extern "C" {
cmRC_t cmLoopRecordExec( cmLoopRecord* p, const cmSample_t* x, cmSample_t* y, unsigned xn, bool bypassFl, bool recdFl, bool playFl, double ratio, double pgain, double rgain );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmGateDetector file_desc:"Detect when a signal onsets and offsets." kw:[proc]}
typedef struct
{
cmObj obj;
@ -115,8 +123,9 @@ extern "C" {
cmRC_t cmGateDetectFinal(cmGateDetect* p );
cmRC_t cmGateDetectExec( cmGateDetect* p, const cmSample_t* x, unsigned xn );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmGateDetector2 file_desc:"Improved gate detector to detect when a signal onsets and offsets." kw:[proc]}
typedef struct
{
unsigned medCnt; // length of the median filter
@ -164,14 +173,17 @@ extern "C" {
cmGateDetect2* cmGateDetectAlloc2( cmCtx* c, cmGateDetect2* p, unsigned procSmpCnt, const cmGateDetectParams* args );
cmRC_t cmGateDetectFree2( cmGateDetect2** p );
cmRC_t cmGateDetectInit2( cmGateDetect2* p, unsigned procSmpCnt, const cmGateDetectParams* args );
cmRC_t cmGateDetectFinal2(cmGateDetect2* p );
cmRC_t cmGateDetectExec2( cmGateDetect2* p, const cmSample_t* x, unsigned xn );
void cmGateDetectSetOnThreshDb2( cmGateDetect2* p, cmReal_t db );
void cmGateDetectSetOffThreshDb2( cmGateDetect2* p, cmReal_t db );
cmRC_t cmGateDetectFree2( cmGateDetect2** p );
cmRC_t cmGateDetectInit2( cmGateDetect2* p, unsigned procSmpCnt, const cmGateDetectParams* args );
cmRC_t cmGateDetectFinal2(cmGateDetect2* p );
cmRC_t cmGateDetectExec2( cmGateDetect2* p, const cmSample_t* x, unsigned xn );
void cmGateDetectSetOnThreshDb2( cmGateDetect2* p, cmReal_t db );
void cmGateDetectSetOffThreshDb2( cmGateDetect2* p, cmReal_t db );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmAutoGain file_desc:"Automatically balance a set of audio signals by adjusting their level." kw:[proc fluxo]}
//
// Calculate a set of automatic gain adjustments for a set of audio channels.
@ -230,7 +242,10 @@ extern "C" {
void cmAutoGainPrint( cmAutoGain* p, cmRpt_t* rpt );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmChCfg file_desc:"Configure a 'fluxo' pickup channel." kw:[proc fluxo]}
typedef struct
{
unsigned ch;
@ -262,7 +277,10 @@ extern "C" {
unsigned cmChCfgChannelCount( cmCtx_t* ctx, const cmChar_t* fn, unsigned* nsChCntPtr );
unsigned cmChCfgChannelIndex( cmCtx_t* ctx, const cmChar_t* fn, unsigned chIdx );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmChordDetector file_desc:"Chord detector based on evaluating signals from cmGateDetector2." kw:[proc]}
typedef struct
{
@ -293,7 +311,10 @@ extern "C" {
cmRC_t cmChordDetectExec( cmChordDetect* p, unsigned procSmpCnt, const bool* gateV, const cmReal_t* rmsV, unsigned chCnt );
cmRC_t cmChordDetectSetSpanMs( cmChordDetect* p, cmReal_t maxTimeSpanMs );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmXfader file_desc:"Audio cross fade controller." kw:[proc]}
// This object is not really a cross-fader. It is really just a multichannel
// fader - which just calculates the fade gain but does not actually apply it
// to the audio signal - unless you use cmXfaderExecAudio()
@ -335,7 +356,10 @@ extern "C" {
void cmXfaderAllOff( cmXfader* p );
void cmXfaderJumpToDestinationGain( cmXfader* p ); // jump to dest. gain based on gate state
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmFader file_desc:"Fade in/out an audio signal based on the state of a gate control signal." kw:[proc]}
// This fader object accepts a gate signal. When the gate is high it increments
// the gain until it reaches 1.0. When the gate is low it decrements the gain
// until it reaches 0.0. The fade time is the lenght of time the gain will take
@ -355,7 +379,10 @@ extern "C" {
cmRC_t cmFaderExec( cmFader* p, unsigned procSmpCnt, bool gateFl, bool mixFl, const cmSample_t* x, cmSample_t* y );
void cmFaderSetFadeTime( cmFader* p, cmReal_t fadeTimeMs );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmCombFilt file_desc:"Comb and Inverse Comb filter algorithm with a variable fractional delay." kw:[proc]}
struct cmIDelay_str;
typedef struct
{
@ -384,7 +411,10 @@ extern "C" {
void cmCombFiltSetAlpha( cmCombFilt* p, cmReal_t alpha );
cmRC_t cmCombFiltSetHz( cmCombFilt* p, cmReal_t hz );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmDcFilt file_desc:"DC Filter algorithm." kw:[proc]}
typedef struct
{
@ -402,9 +432,10 @@ extern "C" {
cmRC_t cmDcFiltFinal( cmDcFilt* p );
cmRC_t cmDcFiltExec( cmDcFilt* p, const cmSample_t* x, cmSample_t* y, unsigned n );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
// interpolating delay - used by the comb filter
//( { label:cmIDelay file_desc:"Variable interpolating fractional audio delay line." kw:[proc]}
typedef struct cmIDelay_str
{
@ -429,7 +460,10 @@ extern "C" {
cmRC_t cmIDelaySetTapMs( cmIDelay* p, unsigned tapIdx, cmReal_t tapMs );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmGroupSel file_desc:"Assign channel to dynamic groups under gate control." kw:[proc]}
// This object sequentially assigns channels to groups when their gates go high.
// 'chsPerGroup' channels will be assigned to each group. No channel will be
@ -481,7 +515,10 @@ extern "C" {
// and groups that will be removed on the next cycle have their 'releaseFl' set.
cmRC_t cmGroupSelExec( cmGroupSel* p );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmAudioNofM file_desc:"Route N of M possible input channels to N output channels under gate control." kw:[proc]}
// Route N of M input channels to N output channels.
// The N channels are selected from the first N gates to go high.
@ -526,7 +563,10 @@ extern "C" {
cmRC_t cmAudioNofMSetFadeMs( cmAudioNofM* p, cmReal_t fadeTimeMs );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmAdsr file_desc:"ADSR audio evelope generator." kw:[proc]}
enum { kDlyAdsrId, kAtkAdsrId, kDcyAdsrId, kSusAdsrId, kRlsAdsrId, kDoneAdsrId };
@ -546,9 +586,6 @@ extern "C" {
cmReal_t susLevel;
int rlsSmp;
unsigned state; // current state
int durSmp; // time in current state
cmReal_t level; // current level
@ -575,7 +612,10 @@ extern "C" {
void cmAdsrSetLevel( cmAdsr* p, cmReal_t level, unsigned id );
void cmAdsrReport( cmAdsr* p, cmRpt_t* rpt );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmCompressor file_desc:"Audio dynamics compressor algorithm." kw:[proc]}
enum { kAtkCompId, kRlsCompId };
typedef struct
@ -616,7 +656,11 @@ extern "C" {
void cmCompressorSetThreshDb( cmCompressor* p, cmReal_t thresh );
void cmCompressorSetRmsWndMs( cmCompressor* p, cmReal_t ms );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmBiQuad file_desc:"General purpose Biquad filter algorithm." kw:[proc]}
// BiQuad Audio Eq's based on Robert Bristow-Johnson's recipes.
// http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
@ -660,7 +704,10 @@ extern "C" {
void cmBiQuadEqSet( cmBiQuadEq* p, unsigned mode, cmReal_t f0Hz, cmReal_t Q, cmReal_t gainDb );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmDistDs file_desc:"Guitar style distortion effect." kw:[proc]}
typedef struct
{
cmObj obj;
@ -686,6 +733,9 @@ extern "C" {
cmRC_t cmDistDsInit( cmDistDs* p, cmReal_t srate, cmReal_t inGain, cmReal_t downSrate, cmReal_t bits, bool rectFl, bool fullFl, cmReal_t clipDb, cmReal_t outGain, bool bypassFl );
cmRC_t cmDistDsFinal( cmDistDs* p );
cmRC_t cmDistDsExec( cmDistDs* p, const cmSample_t* x, cmSample_t* y, unsigned n );
//------------------------------------------------------------------------------------------------------------
//)
//=======================================================================================================================
/*

View File

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

View File

@ -5,11 +5,12 @@
extern "C" {
#endif
//( { file_desc:"Processor Library 4" kw:[proclib]}
//)
//( { label:cmEditDist file_desc:"Simplified string alignment function based on Levenshtein edit distance." kw:[proc] }
//=======================================================================================================================
//
// Simplified string alignment function based on Levenshtein edit distance.
//
enum { kEdMinIdx, kEdSubIdx, kEdDelIdx, kEdInsIdx, kEdCnt };
typedef struct
@ -87,7 +88,10 @@ extern "C" {
// Main test function.
void ed_main();
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmScoreMatch file_desc:"Event oriented local score matching algorithm based on edit distance." kw:[proc] }
enum
{
kSmMinIdx, //
@ -200,9 +204,10 @@ extern "C" {
// necessarily an error.
cmRC_t cmScMatchExec( cmScMatch* p, unsigned locIdx, unsigned locN, const cmScMatchMidi_t* midiV, unsigned midiN, double min_cost );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmScoreMatcher file_desc:"MIDI score following algorithm based cmScoreMatch." kw:[proc] }
typedef struct
{
unsigned locIdx; // index into cmScMatch_t.loc[]
@ -246,8 +251,6 @@ extern "C" {
bool printFl;
} cmScMatcher;
cmScMatcher* cmScMatcherAlloc(
cmCtx* c, // Program context.
cmScMatcher* p, // Existing cmScMatcher to reallocate or NULL to allocate a new cmScMatcher.
@ -310,7 +313,10 @@ extern "C" {
void cmScMatcherPrint( cmScMatcher* p );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmScMeas file_desc:"Measure and report some differences between the score and the performance." kw:[proc] }
typedef struct
{
@ -391,7 +397,10 @@ extern "C" {
// notes in each marker region and the score.
void cmScAlignScanMarkers( cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmScMod file_desc:"Store and recall parameter information under score follower control." kw:[proc] }
/*
Syntax: <loc> <mod> <var> <type> <params>
<loc> - score location
@ -421,6 +430,7 @@ extern "C" {
enum
{
kInvalidModTId,
kDeclModTId, // declare a variable but do not associate a value with it (allows a variable to be connected to w/o sending a value)
kSetModTId, // set variable to parray[0] at scLocIdx
kLineModTId, // linear ramp variable to parray[0] over parray[1] seconds
kSetLineModTId, // set variable to parray[0] and ramp to parray[1] over parray[2] seconds
@ -522,7 +532,10 @@ extern "C" {
cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx );
cmRC_t cmScModulatorDump( cmScModulator* p );
//=======================================================================================================================
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmRecdPlay file_desc:"Record fragments of audio, store them,and play them back at a later time." kw:[proc] }
//
// Record fragments of audio, store them, and play them back at a later time.
//
@ -593,6 +606,8 @@ extern "C" {
cmRC_t cmRecdPlayBeginFade( cmRecdPlay* p, unsigned labelSymId, double fadeDbPerSec );
cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt );
//)
#ifdef __cplusplus
}

View File

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

View File

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

View File

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

View File

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

View File

@ -5,12 +5,10 @@
#ifdef __cplusplus
extern "C" {
#endif
//{
//(
//( { file_desc: "The cmRpt class provides console style output for all objects in the cm system." kw:[base]}
//
// The cmRpt class provides console style output for all objects in the cm system.
//
// The cmRpt class provides console output style output, like stdout and stderr
// for most of the classes in the cm library.
@ -51,7 +49,6 @@ extern "C" {
void cmRptVErrorf( cmRpt_t* rpt, const cmChar_t* fmt, va_list vl );
void cmRptErrorf( cmRpt_t* rpt, const cmChar_t* fmt, ... );
//)
//}
#ifdef __cplusplus
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,55 +1,61 @@
#ifndef cmTextTemplate_h
#define cmTextTemplate_h
#ifdef __cplusplus
extern "C" {
#endif
enum
{
kOkTtRC = cmOkRC,
kFileFailTtRC,
kLHeapFailTtRC,
kSyntaxErrTtRC,
kFindFailTtRC,
kInvalidTypeTtRC,
kJsonFailTtRC
};
//( { file_desc:"Generate text using templates with replaceable variables." kw:[text] }
enum
{
kOkTtRC = cmOkRC,
kFileFailTtRC,
kLHeapFailTtRC,
kSyntaxErrTtRC,
kFindFailTtRC,
kInvalidTypeTtRC,
kJsonFailTtRC
};
typedef cmHandle_t cmTtH_t;
typedef unsigned cmTtRC_t;
extern cmTtH_t cmTtNullHandle;
typedef cmHandle_t cmTtH_t;
typedef unsigned cmTtRC_t;
extern cmTtH_t cmTtNullHandle;
// Initialize a template file.
cmTtRC_t cmTextTemplateInitialize( cmCtx_t* ctx, cmTtH_t* hp, const cmChar_t* fn );
// Initialize a template file.
cmTtRC_t cmTextTemplateInitialize( cmCtx_t* ctx, cmTtH_t* hp, const cmChar_t* fn );
// Finalize a template file
cmTtRC_t cmTextTemplateFinalize( cmTtH_t* hp );
// Finalize a template file
cmTtRC_t cmTextTemplateFinalize( cmTtH_t* hp );
// Return true if the template file is intialized.
bool cmTextTemplateIsValid( cmTtH_t h );
// Return true if the template file is intialized.
bool cmTextTemplateIsValid( cmTtH_t h );
// Set the value of a template variable.
// The node identified by { label,index, label, index ... } must
// be a variable node. The function will fail if a 'set' or 'text' node
// is identified.
// Set 'value' to NULL to erase a previously set value.
cmTtRC_t cmTextTemplateSetValue( cmTtH_t h, const cmChar_t* value, const cmChar_t* label, unsigned index, ... );
// Set the value of a template variable.
// The node identified by { label,index, label, index ... } must
// be a variable node. The function will fail if a 'set' or 'text' node
// is identified.
// Set 'value' to NULL to erase a previously set value.
cmTtRC_t cmTextTemplateSetValue( cmTtH_t h, const cmChar_t* value, const cmChar_t* label, unsigned index, ... );
// Create a copy of the sub-tree identified by the variable path
// and insert it as the left sibling of the sub-tree's root.
cmTtRC_t cmTextTemplateRepeat( cmTtH_t h, const cmChar_t* label, unsigned index, ... );
// Create a copy of the sub-tree identified by the variable path
// and insert it as the left sibling of the sub-tree's root.
cmTtRC_t cmTextTemplateRepeat( cmTtH_t h, const cmChar_t* label, unsigned index, ... );
// Write the template file.
cmTtRC_t cmTextTemplateWrite( cmTtH_t h, const cmChar_t* fn );
// Write the template file.
cmTtRC_t cmTextTemplateWrite( cmTtH_t h, const cmChar_t* fn );
// Apply a template value JSON file to this template
cmTtRC_t cmTextTemplateApply( cmTtH_t h, const cmChar_t* fn );
// Apply a template value JSON file to this template
cmTtRC_t cmTextTemplateApply( cmTtH_t h, const cmChar_t* fn );
// Print an annotated template tree.
void cmTtPrintTree( cmTtH_t h, cmRpt_t* rpt );
// Print an annotated template tree.
void cmTtPrintTree( cmTtH_t h, cmRpt_t* rpt );
cmTtRC_t cmTextTemplateTest( cmCtx_t* ctx, const cmChar_t* fn );
cmTtRC_t cmTextTemplateTest( cmCtx_t* ctx, const cmChar_t* fn );
//)
#ifdef __cplusplus
}
#endif
#endif

View File

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

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