From e25a9abaac7b4cb500cf40270ff99ece66a5cec9 Mon Sep 17 00:00:00 2001 From: kevin Date: Sat, 25 Jan 2014 16:13:13 -0500 Subject: [PATCH 1/6] Makefile.am : Added references to cmSdb.h/c cmHashTbl.h/c. --- Makefile.am | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 8653389..013f9a4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,8 +6,11 @@ cmSRC = cmHDR += src/libcm/cmErr.h src/libcm/cmCtx.h src/libcm/cmRpt.h src/libcm/cmGlobal.h src/libcm/cmComplexTypes.h src/libcm/cmFloatTypes.h src/libcm/cmPrefix.h cmSRC += src/libcm/cmErr.c src/libcm/cmCtx.c src/libcm/cmRpt.c src/libcm/cmGlobal.c -cmHDR += src/libcm/cmSerialize.h src/libcm/cmSymTbl.h src/libcm/cmFileSys.h src/libcm/cmFile.h src/libcm/cmMem.h src/libcm/cmTime.h src/libcm/cmPgmOpts.h -cmSRC += src/libcm/cmSerialize.c src/libcm/cmSymTbl.c src/libcm/cmFileSys.c src/libcm/cmFile.c src/libcm/cmMem.c src/libcm/cmTime.c src/libcm/cmPgmOpts.c +cmHDR += src/libcm/cmSerialize.h src/libcm/cmSymTbl.h src/libcm/cmHashTbl.h src/libcm/cmFileSys.h src/libcm/cmFile.h +cmSRC += src/libcm/cmSerialize.c src/libcm/cmSymTbl.c src/libcm/cmHashTbl.c src/libcm/cmFileSys.c src/libcm/cmFile.c + +cmHDR += src/libcm/cmMem.h src/libcm/cmTime.h src/libcm/cmPgmOpts.h +cmSRC += src/libcm/cmMem.c src/libcm/cmTime.c src/libcm/cmPgmOpts.c cmHDR += src/libcm/cmData.h src/libcm/cmLib.h src/libcm/cmText.h src/libcm/cmTextTemplate.h cmSRC += src/libcm/cmData.c src/libcm/cmLib.c src/libcm/cmText.c src/libcm/cmTextTemplate.c @@ -71,6 +74,9 @@ 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 +cmSRC += src/libcm/app/cmSdb.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 From f95d93a4f8127ad51a67d86ae9d26e1be0d912e6 Mon Sep 17 00:00:00 2001 From: kevin Date: Sat, 25 Jan 2014 16:13:42 -0500 Subject: [PATCH 2/6] app/cmSdb.h/c : Sample database reader object. Initial commit. --- app/cmSdb.c | 724 ++++++++++++++++++++++++++++++++++++++++++++++++++++ app/cmSdb.h | 169 ++++++++++++ 2 files changed, 893 insertions(+) create mode 100644 app/cmSdb.c create mode 100644 app/cmSdb.h diff --git a/app/cmSdb.c b/app/cmSdb.c new file mode 100644 index 0000000..6bf4346 --- /dev/null +++ b/app/cmSdb.c @@ -0,0 +1,724 @@ +#include "cmGlobal.h" +#include "cmRpt.h" +#include "cmErr.h" +#include "cmCtx.h" +#include "cmMem.h" +#include "cmMallocDebug.h" +#include "cmLinkedHeap.h" +#include "cmLex.h" +#include "cmCsv.h" +#include "cmSdb.h" +#include "cmText.h" + +typedef enum +{ + kUuidColIdx, + kBaseUuidColIdx, + kChIdxColIdx, + kObiColIdx, + kIbiColIdx, + kIeiColIdx, + kOeiColIdx, + kSrcColIdx, + kMidiColIdx, + kInstrColIdx, + kSrateColIdx, + kChCntColIdx, + kNotesColIdx, + kAfnColIdx, + kInvalidColIdx +} cmSdbColIdx_t; + +struct cmSdb_str; + +typedef struct cmSdbRspBlk_str +{ + unsigned* indexV; // indexV[ cmSdb_t.blkIdxAllocCnt ] + unsigned cnt; // count of indexes used + struct cmSdbRspBlk_str* link; // cmSdbRsp_t.blocks link +} cmSdbRspBlk_t; + +typedef struct cmSdbRsp_str +{ + struct cmSdb_str* p; // + cmSdbRspBlk_t* blocks; // first block ptr + cmSdbRspBlk_t* ebp; // end block ptr + unsigned cnt; // total count of indexes + struct cmSdbRsp_str* link; // cmSdb_t.responses link +} cmSdbRsp_t; + +typedef struct cmSdb_str +{ + cmCtx_t ctx; + cmLHeapH_t lhH; + cmCsvH_t csvH; + cmSdbEvent_t* eV; + unsigned eN; + unsigned blkIdxAllocCnt; + struct cmSdbRsp_str* responses; +} cmSdb_t; + +cmSdbH_t cmSdbNullHandle = cmSTATIC_NULL_HANDLE; +cmSdbResponseH_t cmSdbResponseNullHandle = cmSTATIC_NULL_HANDLE; + +cmSdb_t* _cmSdbHandleToPtr( cmSdbH_t h ) +{ + cmSdb_t* p = (cmSdb_t*)h.h; + assert( p != NULL ); + return p; +} + +cmSdbRsp_t* _cmSdbRspHandleToPtr( cmSdbResponseH_t h ) +{ + cmSdbRsp_t* p = (cmSdbRsp_t*)h.h; + assert( p != NULL ); + return p; +} + +void _cmSdbRspBlkFree( cmSdb_t* p, cmSdbRspBlk_t* bp ) +{ + cmLhFree(p->lhH, bp->indexV); + cmLhFree(p->lhH, bp); +} + + +cmSdbRspBlk_t* _cmSdbRspBlkUnlink( cmSdbRsp_t* rp, cmSdbRspBlk_t* bp ) +{ + cmSdbRspBlk_t* dp = rp->blocks; + cmSdbRspBlk_t* pp = NULL; + for(; dp!=NULL; dp=dp->link) + { + if( dp == bp ) + { + if( pp == NULL ) + rp->blocks = dp->link; + else + pp->link = dp->link; + + return bp; + } + + pp = dp; + } + + assert(0); + return NULL; +} + +void _cmSdbRspInsertIndex( cmSdb_t* p, cmSdbRsp_t* rp, unsigned evtIndex ) +{ + + if( rp->ebp == NULL || rp->ebp->cnt == p->blkIdxAllocCnt ) + { + cmSdbRspBlk_t* bp = cmLhAllocZ(p->lhH,cmSdbRspBlk_t,1); + bp->indexV = cmLhAllocZ(p->lhH,unsigned,p->blkIdxAllocCnt); + + if( rp->ebp != NULL ) + rp->ebp->link = bp; + + if( rp->blocks == NULL ) + rp->blocks = bp; + + rp->ebp = bp; + + } + + assert( rp->ebp!=NULL && rp->ebp->cnt < p->blkIdxAllocCnt ); + + rp->ebp->indexV[ rp->ebp->cnt++ ] = evtIndex; + rp->cnt += 1; +} + +void _cmSdbRspRelease( cmSdbRsp_t* rp ) +{ + while( rp->blocks != NULL ) + { + cmSdbRspBlk_t* np = rp->blocks->link; + cmSdbRspBlk_t* bp; + + if((bp = _cmSdbRspBlkUnlink(rp,rp->blocks)) != NULL ) + _cmSdbRspBlkFree(rp->p,bp); + + rp->blocks = np; + } + + cmLhFree(rp->p->lhH,rp); +} + +cmSdbRsp_t* _cmSdbRspUnlink( cmSdbRsp_t* rp ) +{ + cmSdb_t* p = rp->p; + cmSdbRsp_t* dp = p->responses; + cmSdbRsp_t* pp = NULL; + + for(; dp!=NULL; dp=dp->link) + { + if( dp == rp ) + { + if( pp == NULL ) + p->responses = dp->link; + else + pp->link = dp->link; + + return rp; + } + + pp = dp; + } + + assert( 0 ); + + return NULL; +} + + +void _cmSdbRspFree( cmSdbRsp_t* rp ) +{ + _cmSdbRspUnlink(rp); + _cmSdbRspRelease(rp); +} + +cmSdbRsp_t* _cmSdbRspAlloc( cmSdb_t* p, cmSdbResponseH_t* rhp ) +{ + if( cmSdbResponseFree(rhp) != kOkSdbRC ) + return NULL; + + cmSdbRsp_t* rp = cmLhAllocZ(p->lhH,cmSdbRsp_t,1); + rp->p = p; + rp->link = p->responses; + p->responses = rp; + + rhp->h = rp; + + return rp; +} + +cmSdbRC_t _cmSdbDestroy( cmSdb_t* p ) +{ + cmSdbRC_t rc = kOkSdbRC; + + if( cmCsvFinalize(&p->csvH) != kOkCsvRC ) + rc = cmErrMsg(&p->ctx.err,kCsvFailSdbRC,"CSV file finalize failed."); + + while( p->responses != NULL ) + _cmSdbRspRelease(p->responses); + + cmLHeapDestroy(&p->lhH); + cmMemFree(p); + return rc; +} + +cmSdbRC_t cmSdbCreate( cmCtx_t* ctx, cmSdbH_t* hp, const cmChar_t* audioDir, const cmChar_t* csvFn ) +{ + cmSdbRC_t rc; + if((rc = cmSdbDestroy(hp)) != kOkSdbRC ) + return rc; + + cmSdb_t* p = cmMemAllocZ(cmSdb_t,1); + p->ctx = *ctx; + p->blkIdxAllocCnt = 1024; + + cmErrSetup(&p->ctx.err,&ctx->rpt,"sdb"); + + if( cmLHeapIsValid( p->lhH = cmLHeapCreate(8192,ctx)) == false ) + { + rc = cmErrMsg(&p->ctx.err,kLHeapFailSdbRC,"Linked heap mgr. allocation failed."); + goto errLabel; + } + + hp->h = p; + + if( csvFn != NULL ) + if((rc = cmSdbLoad(*hp,csvFn)) != kOkSdbRC ) + goto errLabel; + + errLabel: + if( rc != kOkSdbRC ) + _cmSdbDestroy(p); + + return rc; +} + +cmSdbRC_t cmSdbDestroy( cmSdbH_t* hp ) +{ + cmSdbRC_t rc = kOkSdbRC; + + if( hp==NULL || cmSdbIsValid(*hp)==false ) + return rc; + + cmSdb_t* p = _cmSdbHandleToPtr(*hp); + + if((rc = _cmSdbDestroy(p)) != kOkSdbRC ) + return rc; + + hp->h = NULL; + + return rc; +} + +bool cmSdbIsValid( cmSdbH_t h ) +{ return h.h != NULL; } + + +cmSdbRC_t _cmSdbSyntaxError(cmSdb_t* p, const cmChar_t* csvFn, unsigned rowIdx, unsigned colIdx, const cmChar_t* colLabel ) +{ + return cmErrMsg(&p->ctx.err,kSyntaxErrSdbRC,"A syntax error was found at row %i col %i (label:%s) in '%s'.",rowIdx+1,colIdx+1,cmStringNullGuard(colLabel),cmStringNullGuard(csvFn)); +} + + +cmSdbRC_t cmSdbLoad( cmSdbH_t h, const cmChar_t* csvFn ) +{ + cmSdbRC_t rc = kOkSdbRC; + unsigned i; + + cmSdb_t* p = _cmSdbHandleToPtr(h); + + if( cmCsvInitializeFromFile(&p->csvH, csvFn, 0, &p->ctx ) != kOkCsvRC ) + { + rc = cmErrMsg(&p->ctx.err,kCsvFailSdbRC,"CSV file load fail on '%s'.",cmStringNullGuard(csvFn)); + goto errLabel; + } + + p->eN = cmCsvRowCount(p->csvH)-1; + + // release all the memory held by the linked heap + cmLHeapClear(p->lhH,true); + + p->eV = cmLhAllocZ(p->lhH,cmSdbEvent_t,p->eN); + + + for(i=0; rc==kOkSdbRC && ieN; ++i) + { + unsigned rowIdx = i+1; + + if((p->eV[i].uuid = cmCsvCellUInt(p->csvH,rowIdx,kUuidColIdx)) == UINT_MAX ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kUuidColIdx,"uuid"); + + if((p->eV[i].baseUuid = cmCsvCellUInt(p->csvH,rowIdx,kBaseUuidColIdx)) == UINT_MAX ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kBaseUuidColIdx,"baseUuid"); + + if((p->eV[i].chIdx = cmCsvCellUInt(p->csvH,rowIdx,kChIdxColIdx)) == UINT_MAX ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kChIdxColIdx,"chIdx"); + else + p->eV[i].chIdx -= 1; // CSV channel index is 1 based + + if((p->eV[i].obi = cmCsvCellUInt(p->csvH,rowIdx,kObiColIdx)) == UINT_MAX ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kObiColIdx,"obi"); + else + p->eV[i].obi -= 1; + + if((p->eV[i].ibi = cmCsvCellUInt(p->csvH,rowIdx,kIbiColIdx)) == UINT_MAX ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kIbiColIdx,"ibi"); + else + p->eV[i].ibi -= 1; + + if((p->eV[i].iei = cmCsvCellUInt(p->csvH,rowIdx,kIeiColIdx)) == UINT_MAX ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kIeiColIdx,"obi"); + else + p->eV[i].iei -= 1; + + if((p->eV[i].oei = cmCsvCellUInt(p->csvH,rowIdx,kOeiColIdx)) == UINT_MAX ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kOeiColIdx,"ibi"); + else + p->eV[i].oei -= 1; + + if((p->eV[i].src = cmCsvCellText(p->csvH,rowIdx,kSrcColIdx)) == NULL ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kSrcColIdx,"src"); + + if((p->eV[i].midi = cmCsvCellInt(p->csvH,rowIdx,kMidiColIdx)) == INT_MAX ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kMidiColIdx,"midi"); + + if((p->eV[i].instr = cmCsvCellText(p->csvH,rowIdx,kInstrColIdx)) == NULL ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kInstrColIdx,"instr"); + + if((p->eV[i].srate = cmCsvCellUInt(p->csvH,rowIdx,kSrateColIdx)) == UINT_MAX ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kSrateColIdx,"srate"); + + if((p->eV[i].chCnt = cmCsvCellUInt(p->csvH,rowIdx,kChCntColIdx)) == UINT_MAX ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kChCntColIdx,"chCnt"); + + + cmCsvCell_t* c; + if((c = cmCsvCellPtr(p->csvH,rowIdx,kNotesColIdx)) == NULL ) + { + rc = cmErrMsg(&p->ctx.err,kSyntaxErrSdbRC,"Syntax Error: No 'notes' or 'audio file name' field for row %i in '%s'.",rowIdx+1,cmStringNullGuard(csvFn)); + goto errLabel; + } + + // count the number of 'notes' + unsigned nn = 0; + for(; c->rowPtr != NULL; c=c->rowPtr) + ++nn; + + if( nn > 0 ) + { + unsigned k = 0; + + // allocate the 'notes' ptr array - the last entry is set to NULL. + p->eV[i].notesV = cmLhAllocZ(p->lhH,const cmChar_t*,nn+1); + + // read each note + for(c=cmCsvCellPtr(p->csvH,rowIdx,kNotesColIdx); c!=NULL&&c->rowPtr!=NULL; c=c->rowPtr,++k) + if(( p->eV[i].notesV[k] = cmCsvCellText(p->csvH,rowIdx,kNotesColIdx+k)) == NULL ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kNotesColIdx+k,"notes"); + + assert(k==nn); + } + + // read the audio file name + if((p->eV[i].afn = cmCsvCellText(p->csvH,rowIdx,kNotesColIdx+nn)) == NULL ) + rc = _cmSdbSyntaxError(p,csvFn,rowIdx,kNotesColIdx+nn,"afn"); + + } + + errLabel: + + return rc; + +} + +// Compare 'label' to every string in tV[i] and return true if any comparision is a match. +// If 'subFlV[i]' is set then 'label' must only contain tV[i] as a substring to match. +// If 'negFlV[i]' is set then return true if any comparision is a mismatch. +bool _cmSdbSelectText( const cmSdbEvent_t* r, const cmChar_t** tV, const bool* subFlV, const bool* negFlV, const cmChar_t* label ) +{ + unsigned i; + + if( label == NULL ) + return false; + + if( tV == NULL ) + return true; + + for(i=0; tV[i]!=NULL; ++i) + { + bool matchFl = false; + if( subFlV[i] ) + matchFl = strstr(label,tV[i]) != NULL; + else + matchFl = strcmp(tV[i],label)==0; + + if( negFlV[i] ) + matchFl = !matchFl; + + if(matchFl) + return true; + } + + return false; +} + +unsigned _cmSdbStrVectCnt( const cmChar_t** v ) +{ + unsigned n = 0; + unsigned i = 0; + + if( v == NULL ) + return 0; + + for(i=0; v[i]!=NULL; ++i) + ++n; + return n; +} + +void _cmSdbStrVectFlags( const cmChar_t** v, bool* sV, bool* nV ) +{ + unsigned i = 0; + if( v == NULL ) + return; + + for(i=0; v[i]!=NULL; ++i) + { + nV[i] = false; + sV[i] = false; + + if( strncmp(v[i],"*!",2)==0 || strncmp(v[i],"!*",2)==0) + { + sV[i] = nV[i] = true; + v[i] += 2; + } + else + { + if( strncmp(v[i],"!",1)==0 ) + { + nV[i] = true; + v[i] += 1; + } + + if( strncmp(v[i],"*",1)==0 ) + { + sV[i] = true; + v[i] += 1; + } + } + + + } +} + +cmSdbRC_t cmSdbSelect( + cmSdbH_t h, + double srate, + const cmChar_t** instrV, + const cmChar_t** srcV, + const cmChar_t** notesV, + double minDurSec, + double maxDurSec, + unsigned minChCnt, + cmSdbResponseH_t* rhp ) +{ + cmSdbRC_t rc = kOkSdbRC; + cmSdb_t* p = _cmSdbHandleToPtr(h); + unsigned i; + + cmSdbRsp_t* rp = _cmSdbRspAlloc(p,rhp); + + // get the length of each string vector + unsigned srcN = _cmSdbStrVectCnt(srcV); + unsigned insN = _cmSdbStrVectCnt(instrV); + unsigned notN = _cmSdbStrVectCnt(notesV); + + // allocate flag vectors + bool srcSubFlV[ srcN ]; + bool srcNegFlV[ srcN ]; + bool insSubFlV[ insN ]; + bool insNegFlV[ insN ]; + bool notSubFlV[ notN ]; + bool notNegFlV[ notN ]; + + // fill the flag vectors + _cmSdbStrVectFlags(srcV, srcSubFlV,srcNegFlV); + _cmSdbStrVectFlags(instrV,insSubFlV,insNegFlV); + _cmSdbStrVectFlags(notesV,notSubFlV,notNegFlV); + + for(i=0; ieN; ++i) + { + const cmSdbEvent_t* r = p->eV + i; + double durSec = (double)r->srate * (r->oei - r->obi); + unsigned j; + + if( srate!=0 && srate!=r->srate ) + continue; + + if( durSec < minDurSec || (maxDurSec!=0 && maxDurSec < durSec) ) + continue; + + if( minChCnt!=0 && r->chCnt > minChCnt ) + continue; + + if( !_cmSdbSelectText(r,srcV,srcSubFlV,srcNegFlV,r->src) ) + continue; + + if( !_cmSdbSelectText(r,instrV,insSubFlV,insNegFlV,r->instr) ) + continue; + + if( r->notesV != NULL ) + for(j=0; r->notesV[j]!=NULL; ++j) + if( _cmSdbSelectText(r,notesV,notSubFlV,notNegFlV,r->notesV[j]) == true ) + break; + + if( r->notesV[j]==NULL ) + continue; + + + _cmSdbRspInsertIndex(p,rp,i); + } + + return rc; +} + +cmSdbRC_t cmSdbSelectChPairs( cmSdbH_t h, const cmSdbEvent_t* ep, cmSdbResponseH_t* rhp ) +{ + cmSdbRC_t rc = kOkSdbRC; + cmSdb_t* p = _cmSdbHandleToPtr(h); + cmSdbRsp_t* rp = _cmSdbRspAlloc(p,rhp); + unsigned i; + + // for each channel of this event + for(i=0; ichCnt; ++i) + { + // if i channel is not the known events channel + if( ep->chIdx != i ) + { + unsigned j; + + // examine each record + for(j=0; jeN; ++j) + // if eV[j] shares a baseUuid but is on a different channel than *ep ... + if( p->eV[j].baseUuid == ep->baseUuid && p->eV[j].chIdx==i ) + { + // .. then a match has been found + _cmSdbRspInsertIndex(p,rp,j); + break; + } + + if( j== p->eN ) + { + rc = cmErrMsg(&p->ctx.err,kChPairNotFoundSdbRC,"The channel pair associated with 'id:%i instr:%s src:%s ch index:%i could not be found.",ep->uuid,cmStringNullGuard(ep->instr),cmStringNullGuard(ep->src),ep->chIdx); + } + } + } + + return rc; + +} + + +unsigned cmSdbResponseCount( cmSdbResponseH_t rh ) +{ + cmSdbRsp_t* rp = _cmSdbRspHandleToPtr(rh); + return rp->cnt; +} + +const cmSdbEvent_t* cmSdbResponseEvent( cmSdbResponseH_t rh, unsigned index ) +{ + cmSdbRsp_t* rp = _cmSdbRspHandleToPtr(rh); + + if( index >= rp->cnt ) + return NULL; + + cmSdbRspBlk_t* bp = rp->blocks; + unsigned i; + for(i=0; bp!=NULL; i+=bp->cnt,bp=bp->link) + if( i <= index && index < (i + bp->cnt) ) + return rp->p->eV + bp->indexV[index-i]; + + cmErrMsg(&rp->p->ctx.err,kInvalidRspIdxSdbRC,"Invalid query response index=%i.",index); + return NULL; +} + +bool cmSdbResponseIsValid( cmSdbResponseH_t rh ) +{ return rh.h != NULL; } + +cmSdbRC_t cmSdbResponseFree( cmSdbResponseH_t* rhp ) +{ + cmSdbRC_t rc = kOkSdbRC; + + if( rhp == NULL || cmSdbResponseIsValid(*rhp)==false ) + return rc; + + cmSdbRsp_t* rp = _cmSdbRspHandleToPtr(*rhp); + + _cmSdbRspFree(rp); + + rhp->h = NULL; + + return rc; +} + +void cmSdbResponsePrint( cmSdbResponseH_t rh, cmRpt_t* rpt ) +{ + unsigned n = cmSdbResponseCount(rh); + unsigned i; + for(i=0; iuuid,e->baseUuid,e->chIdx,e->obi,e->ibi,e->iei,e->oei,e->midi,e->srate,e->chCnt, + cmStringNullGuard(e->src), cmStringNullGuard(e->instr) ); + } +} + +cmSdbRC_t cmSdbSyncChPairs( cmSdbH_t h ) +{ + cmSdbRC_t rc = kOkSdbRC; + cmSdb_t* p = _cmSdbHandleToPtr(h); + unsigned i; + // for each multi-channel event + for(i=0; ieN; ++i) + if(p->eV[i].chCnt > 1 ) + { + const cmSdbEvent_t* ep = p->eV + i; + unsigned iV[ep->chCnt]; + unsigned j,k; + + // load iV[] with the event indexes of the channel pairs + for(j=0,k=0; jeN && kchCnt; ++j) + if( p->eV[j].baseUuid == ep->baseUuid ) + { + assert( p->eV[j].chIdx < ep->chCnt ); + + iV[p->eV[j].chIdx] = j; + ++k; + } + + if( k != ep->chCnt ) + rc = cmErrMsg(&p->ctx.err,kChPairNotFoundSdbRC,"The channel pair associated with 'id:%i instr:%s src:%s ch index:%i could not be found.",ep->uuid,cmStringNullGuard(ep->instr),cmStringNullGuard(ep->src),ep->chIdx); + else + { + unsigned mobi = ep->obi; + unsigned mibi = ep->ibi; + unsigned miei = ep->iei; + unsigned moei = ep->oei; + + // get the min onsets and max offsets + for(j=0; jchCnt; ++j) + { + mobi = cmMin(mobi,p->eV[ iV[j] ].obi); + mibi = cmMin(mibi,p->eV[ iV[j] ].ibi); + miei = cmMax(miei,p->eV[ iV[j] ].iei); + moei = cmMax(moei,p->eV[ iV[j] ].oei); + } + + // set the onsets to the min onset / offsets to max offsets + for(j=0; jchCnt; ++j) + { + p->eV[ iV[j] ].obi = mobi; + p->eV[ iV[j] ].ibi = mibi; + p->eV[ iV[j] ].iei = miei; + p->eV[ iV[j] ].oei = moei; + } + } + } + + return rc; +} + + +cmSdbRC_t cmSdbTest( cmCtx_t* ctx ) +{ + cmSdbRC_t rc = kOkSdbRC; + cmSdbH_t h = cmSdbNullHandle; + const cmChar_t* audioDir = "/home/kevin/media/audio"; + const cmChar_t* csvFn = "/home/kevin/temp/sdb0/sdb_master.csv"; + cmErr_t err; + + cmErrSetup(&err,&ctx->rpt,"sdb test"); + + if((rc = cmSdbCreate(ctx, &h, audioDir, csvFn )) != kOkSdbRC ) + { + rc = cmErrMsg(&err,rc,"sdb create failed."); + goto errLabel; + } + + if((rc = cmSdbSyncChPairs(h)) != kOkSdbRC ) + { + rc = cmErrMsg(&err,rc,"sdb sync-ch-pairs failed."); + goto errLabel; + } + + if(0) + { + cmSdbResponseH_t rH = cmSdbResponseNullHandle; + + const cmChar_t* instrV[] = { "*viol", NULL }; + + if((rc = cmSdbSelect(h,0,instrV,NULL,NULL,0,0,0,&rH)) != kOkSdbRC ) + { + rc = cmErrMsg(&err,rc,"sdb query failed."); + goto errLabel; + } + + + cmSdbResponsePrint(rH,&ctx->rpt); + + cmSdbResponseFree(&rH); + } + + errLabel: + if((rc = cmSdbDestroy(&h)) != kOkSdbRC ) + rc = cmErrMsg(&err,rc,"sdb destroy failed."); + + return rc; +} diff --git a/app/cmSdb.h b/app/cmSdb.h new file mode 100644 index 0000000..4a8b30f --- /dev/null +++ b/app/cmSdb.h @@ -0,0 +1,169 @@ +#ifndef cmSdb_h +#define cmSdb_h + +#ifdef __cplusplus +extern "C" { +#endif + + /* + The data for this object is stored in a CSV file with the following column syntax. + + Column Name Type Description + ------ -------- ----- ----------------------------------------------------- + 1 uuid uint Unique integer identifier for this event + 2 baseUuid uint uuid of channel 0 for this event + 3 chIdx uint Channel index (stereo: 1=left 2=right) + 4 obi uint Outer onset sample index into 'afn'. + 5 ibi uint Inner onset sample index into 'afn'. + 6 iei uint Inner offset sample index into 'afn'. + 7 oei uint Outer offset sample index into 'afn'. + 8 src text Source label for this event (e.g. mcgill, ui ) + 9 midi uint MIDI pitch number or -1 if the sample is not pitched + 10 instr text Instrument label. + 11 srate uint Sample rate of audio file reference by 'afn'. + 10 chCnt uint Count of channels for this event. + * notes text 0 or more free form double quoted text notes. + * afn text File name of the audio file this event occurs in. + + Notes: + #. Each event represents a mono audio signal. If the event is drawn + from a multi-channel audio file then the 'chCnt' field will be + greater than one. If 'chCnt' is greater than one then the associated + samples can be found by collecting all events that share the + same 'baseUuid'. + + #. There may be zero or more columns of 'notes'. If there are no + notes then the 'afn' field is in column 11. + + #. The index values (chIdx,obi,ibi,iei,oei) as stored in the CSV file + are 1 based. These values are decreased by 1 by the cmSdb CSV reader + so that their cmSdb value is zero based. See cmSdbLoad(). + + */ + + enum + { + kOkSdbRC, + kLHeapFailSdbRC, + kCsvFailSdbRC, + kSyntaxErrSdbRC, + kInvalidRspIdxSdbRC, + kChPairNotFoundSdbRC + }; + + typedef cmHandle_t cmSdbH_t; + typedef cmHandle_t cmSdbResponseH_t; + + typedef cmRC_t cmSdbRC_t; + extern cmSdbH_t cmSdbNullHandle_t; + extern cmSdbResponseH_t cmSdbResponseNullHandle_t; + + typedef struct + { + unsigned uuid; // unique id of this sample + unsigned baseUuid; // uuid of channel 0 + unsigned chIdx; // channel index (0=left,1=right) + unsigned obi; // outer onset + unsigned ibi; // inner onset + unsigned iei; // inner offset + unsigned oei; // outer offset + unsigned midi; // MIDI pitch or -1 for unpitched instruments + unsigned srate; // sample rate + unsigned chCnt; // source channel count + const cmChar_t* src; // sample source (e.g. mcgill, ui ) + const cmChar_t* instr; // instrument label + const cmChar_t* afn; // audio file name + const cmChar_t** notesV; // NULL terminated list of terms describing the event. + } cmSdbEvent_t; + + + cmSdbRC_t cmSdbCreate( cmCtx_t* ctx, cmSdbH_t* hp, const cmChar_t* audioDir, const cmChar_t* csvFn ); + cmSdbRC_t cmSdbDestroy( cmSdbH_t* hp ); + + bool cmSdbIsValid( cmSdbH_t h ); + + cmSdbRC_t cmSdbLoad( cmSdbH_t h, const cmChar_t* csvFn ); + + // Select a set of events from the sample database. + // + // The possible selection criteria are: + // sample rate + // instrument label + // source label + // notes labels + // event duration + // + // In order to match an event all active criteria + // must match. In other words the match implies a + // logical AND operation on each match criteria. + // Each of the criteria can be made inactive by + // specifying particular key values. + // sample rate = 0 + // instrument label = NULL + // source label = NULL + // notes labels = NULL + // event duration = minDurSec=0 maxDurSec=0 + // + // For the text array arguments (instrV,srcV,notesV) + // each element of the array is a key which is attempts to + // match the associated field in each event record. + // By default a match is triggered if the key text is identical to the + // event field text. The match algorithm can be modified by + // specifying a '*' as the first character in the key field. + // In this case a the key need only be a substring of the + // event field to trigger a match. For example "*viol" + // will return events that match both "violin" and "viola". + // + // To specify a mismatch as a successful match + // (i.e. to return events which do not match the key text) + // prefix the key with a '!' character. + // + // Note that it is legal to specify both '!' and '*'. In + // which case a match will be triggered by fields where + // the key text is not a substring of the field text. + // + // All query response handles returned from this function + // should eventualy be released by the application via a call to + // cmSdbResponseFree(). + cmSdbRC_t cmSdbSelect( + cmSdbH_t h, + double srate, // event sample rate or 0 to ignore + const cmChar_t** instrV, // array of instrument labels to match + const cmChar_t** srcV, // array of 'src' labels to match + const cmChar_t** notesV, // array of text 'notes' to match + double minDurSec, // min event duration + double maxDurSec, // max event duration or 0 to ignore + unsigned minChCnt, // min ch cnt or 0 to ignore + cmSdbResponseH_t* rhp ); + + // Given the event 'ep' locate the channel pairs associated with that event. + // The response handle returned from this function must be released + // by a call to cmSdbResponseFree(). + cmSdbRC_t cmSdbSelectChPairs( cmSdbH_t h, const cmSdbEvent_t* ep, cmSdbResponseH_t* rhp ); + + // Return the count of events in a query response. + unsigned cmSdbResponseCount( cmSdbResponseH_t rh ); + + // Return the event at 'index' in from a query response. + // Legal 'index' range: 0<=index<=cmSdbResponseCount(). + const cmSdbEvent_t* cmSdbResponseEvent( cmSdbResponseH_t rh, unsigned index ); + + // Return true if the 'rh' is a non-NULL query response handle. + bool cmSdbResponseIsValid( cmSdbResponseH_t rh ); + + // Release the resource held by a query response. + cmSdbRC_t cmSdbResponseFree( cmSdbResponseH_t* rhp ); + void cmSdbResponsePrint( cmSdbResponseH_t rh, cmRpt_t* rpt ); + + // Time align all channel pairs by setting the onset times to + // the minimum time among all the pairs and the offset times to + // the maximum among all the pairs. + cmSdbRC_t cmSdbSyncChPairs( cmSdbH_t h ); + + cmSdbRC_t cmSdbTest( cmCtx_t* ctx ); + +#ifdef __cplusplus +} +#endif + +#endif From 9b3aa4c7988772da52bd82616d2a51cde1aed2fd Mon Sep 17 00:00:00 2001 From: kevin Date: Sat, 25 Jan 2014 16:13:57 -0500 Subject: [PATCH 3/6] cmHashTbl.h/c : Initial commit. --- cmHashTbl.c | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++++ cmHashTbl.h | 67 ++++++++ 2 files changed, 531 insertions(+) create mode 100644 cmHashTbl.c create mode 100644 cmHashTbl.h diff --git a/cmHashTbl.c b/cmHashTbl.c new file mode 100644 index 0000000..c4f628a --- /dev/null +++ b/cmHashTbl.c @@ -0,0 +1,464 @@ +#include "cmGlobal.h" +#include "cmFloatTypes.h" +#include "cmRpt.h" +#include "cmErr.h" +#include "cmCtx.h" +#include "cmMem.h" +#include "cmLinkedHeap.h" +#include "cmMallocDebug.h" +#include "cmMath.h" +#include "cmHashTbl.h" +#include "cmText.h" + +enum +{ + kFreeHtFl = 0x01, +}; + +typedef struct cmHtValue_str +{ + unsigned flags; // See kXXXHtFl above. + unsigned id; // unique id associated with this value + void* value; // value blob + unsigned byteCnt; // size of value blob in bytes + struct cmHtValue_str* link; // cmHtBucket_t.list link +} cmHtValue_t; + +typedef struct +{ + cmHtValue_t* list; // value list + cmHtValue_t* avail; // available value slots - formed from cmHashTblRemoved() values. + unsigned nextIdx; // next unused index for this bucket +} cmHtBucket_t; + +typedef struct +{ + cmErr_t err; + cmLHeapH_t lhH; // memory for hash table buckets, values, value blobs. + unsigned bucketCnt; // hash table bucket cnt + unsigned linkCnt; // max length of collision list for each bucket + unsigned mask; // hash id bucket index mask (masks the MSB's of the hash-id) + unsigned maskShift; // shift required to move the lowest 'mask' bit to the LSB. + cmHtBucket_t* b; // b[bucketCnt] bucket array +} cmHt_t; + +cmHashTblH_t cmHashTblNullHandle = cmSTATIC_NULL_HANDLE; + +#define _cmHtBucketIndex( p, id ) (((id) & (p)->mask) >> (p)->maskShift) + +cmHt_t* _cmHtHandleToPtr( cmHashTblH_t h ) +{ + cmHt_t* p = (cmHt_t*)h.h; + assert(p!=NULL); + return p; +} + +// Return the bucket index portion of the hash id. +unsigned _cmHtGenId( cmHt_t* p, const void* v, unsigned byteCnt ) +{ + unsigned i,j; + const char* cv = v; + unsigned h = 0; + + for(i=0,j=3; imask; +} + + +// Given an id find the value. +cmHtValue_t* _cmHtIdToValue( cmHt_t* p, unsigned id ) +{ + if( id == cmInvalidId ) + return NULL; + + unsigned bi = _cmHtBucketIndex(p,id); + + assert(bi < p->bucketCnt); + + cmHtValue_t* v = p->b[bi].list; + for(; v!=NULL; v=v->link) + if( v->id == id ) + return v; + + return NULL; +} + +// Given a value find the id +cmHtValue_t* _cmHtValueToId( cmHt_t* p, const void* value, unsigned byteCnt, unsigned id ) +{ + if( id == cmInvalidId ) + id = _cmHtGenId(p,value,byteCnt); + + unsigned bi = _cmHtBucketIndex(p,id); + + assert(bi < p->bucketCnt); + + cmHtValue_t* v = p->b[bi].list; + for(; v!=NULL; v=v->link) + if( v->byteCnt==byteCnt && memcmp(value,v->value,byteCnt)==0 ) + return v; + + return NULL; +} + +cmHtRC_t _cmHtDestroy( cmHt_t* p ) +{ + cmHtRC_t rc = kOkHtRC; + cmLHeapDestroy(&p->lhH); + cmMemFree(p->b); + cmMemFree(p); + return rc; +} + +cmHtRC_t cmHashTblCreate( cmCtx_t* ctx, cmHashTblH_t* hp, unsigned bucketCnt ) +{ + cmHtRC_t rc; + if((rc = cmHashTblDestroy(hp)) != kOkHtRC ) + return rc; + + cmHt_t* p = cmMemAllocZ(cmHt_t,1); + + cmErrSetup(&p->err,&ctx->rpt,"hash table"); + + if(cmLHeapIsValid(p->lhH = cmLHeapCreate(8192,ctx)) == false ) + { + cmErrMsg(&p->err,kLHeapFailHtRC,"Internal linked heap mgr. create failed."); + goto errLabel; + } + + // force the bucket count to be a power of two + p->bucketCnt = cmNextPowerOfTwo(bucketCnt); + p->mask = p->bucketCnt - 1; + + // calcluate the hash-id bucket mask + for(p->maskShift=0; (0x80000000 & p->mask) == 0; ++p->maskShift ) + p->mask <<= 1; + + // calculate the maximum collisions per bucket mask + p->linkCnt = ~p->mask; + + // allocate the bucket array + p->b = cmMemAllocZ(cmHtBucket_t,p->bucketCnt); + + hp->h = p; + + errLabel: + if( rc != kOkHtRC ) + _cmHtDestroy(p); + return rc; +} + +cmHtRC_t cmHashTblDestroy( cmHashTblH_t* hp ) +{ + cmHtRC_t rc = kOkHtRC; + if(hp==NULL || cmHashTblIsValid(*hp)==false ) + return rc; + + cmHt_t* p = _cmHtHandleToPtr(*hp); + + if((rc = _cmHtDestroy(p)) != kOkHtRC ) + return rc; + + hp->h = NULL; + + return rc; +} + +bool cmHashTblIsValid( cmHashTblH_t h ) +{ return h.h!=NULL; } + +unsigned cmHashTblStoreBase( cmHashTblH_t h, void* v, unsigned byteCnt, bool staticFl ) +{ + cmHt_t* p = _cmHtHandleToPtr(h); + cmHtValue_t* vp = NULL; + unsigned id = _cmHtGenId(p, v, byteCnt ); + + // if the value is already stored then there is nothing else to do + if((vp = _cmHtValueToId(p,v,byteCnt,id)) != NULL ) + return vp->id; + + unsigned bi = _cmHtBucketIndex(p,id); + + assert(bi < p->bucketCnt ); + + cmHtBucket_t* b = p->b + bi; + + if( b->avail != NULL ) + { + vp = b->avail; + b->avail = b->avail->link; + } + else + { + if( b->nextIdx == p->linkCnt || (id + b->nextIdx) == cmInvalidId ) + { + cmErrMsg(&p->err,kHashFaultHtRC,"The hash table bucket at index %i is exhaused.",bi); + return cmInvalidId; + } + + vp = cmLhAllocZ(p->lhH,cmHtValue_t,1); + vp->id = id + b->nextIdx++; + } + + + assert( vp->id != cmInvalidId ); + + vp->link = b->list; + b->list = vp; + vp->byteCnt = byteCnt; + + if( staticFl ) + vp->value = v; + else + { + vp->value = cmLhAlloc(p->lhH,char,byteCnt); + memcpy(vp->value,v,byteCnt); + vp->flags = cmSetFlag(vp->flags,kFreeHtFl); + } + + return vp->id; +} + +unsigned cmHashTblStore( cmHashTblH_t h, void* v, unsigned byteCnt ) +{ return cmHashTblStoreBase(h,v,byteCnt,false); } + +unsigned cmHashTblStoreStatic( cmHashTblH_t h, void* v, unsigned byteCnt ) +{ return cmHashTblStoreBase(h,v,byteCnt,true); } + +unsigned _cmHashTblStoreStr( cmHashTblH_t h, const cmChar_t* s, bool staticFl ) +{ + unsigned n = cmTextLength(s); + if( n == 0 ) + { + s = ""; + n = 1; + } + +return cmHashTblStoreBase(h,(void*)s,n+1,staticFl); +} + +unsigned cmHashTblStoreStr( cmHashTblH_t h, const cmChar_t* s ) +{ return _cmHashTblStoreStr(h,s,false); } + +unsigned cmhashTblStoreStaticStr( cmHashTblH_t h, const cmChar_t* s ) +{ return _cmHashTblStoreStr(h,s,true); } + +unsigned cmHashTblStoreV( cmHashTblH_t h, const cmChar_t* fmt, va_list vl ) +{ + cmChar_t* s = NULL; + s = cmTsVPrintfP(s,fmt,vl); + unsigned id = _cmHashTblStoreStr(h,s,false); + cmMemFree(s); + return id; +} + +unsigned cmHashTblStoreF( cmHashTblH_t h, const cmChar_t* fmt, ... ) +{ + va_list vl; + va_start(vl,fmt); + unsigned id = cmHashTblStoreV(h,fmt,vl); + va_end(vl); + return id; +} + +unsigned cmHashTblId( cmHashTblH_t h, const void* value, unsigned byteCnt ) +{ + cmHt_t* p = _cmHtHandleToPtr(h); + cmHtValue_t* vp; + + if((vp = _cmHtValueToId(p,value,byteCnt,cmInvalidId)) == NULL ) + return cmInvalidId; + + return vp->id; +} + +unsigned cmHashTblStrToId( cmHashTblH_t h, const cmChar_t* str ) +{ + if( str == NULL ) + return cmInvalidId; + + return cmHashTblId(h,str,cmTextLength(str)+1); +} + + +const void* cmHashTblValue( cmHashTblH_t h, unsigned id, unsigned* byteCntRef ) +{ + cmHt_t* p = _cmHtHandleToPtr(h); + cmHtValue_t* vp; + + if((vp = _cmHtIdToValue(p, id)) != NULL ) + { + if( byteCntRef != NULL ) + *byteCntRef = vp->byteCnt; + + return vp->value; + } + + return NULL; +} + + +const cmChar_t* cmHashTblStr( cmHashTblH_t h, unsigned id ) +{ return (const cmChar_t*)cmHashTblValue(h,id,NULL); } + + +cmHtRC_t cmHashTblRemove( cmHashTblH_t h, unsigned id ) +{ + cmHt_t* p = _cmHtHandleToPtr(h); + unsigned bi = _cmHtBucketIndex(p,id); + + + + assert(bi < p->bucketCnt); + + cmHtBucket_t* b = p->b + bi; + + cmHtValue_t* vp = b->list; + cmHtValue_t* pp = NULL; + + for(; vp!=NULL; vp=vp->link) + { + if( vp->id == id ) + { + if( pp == NULL ) + b->list = vp->link; + else + pp->link = vp->link; + + break; + } + + pp = vp; + } + + if( vp == NULL ) + return cmErrMsg(&p->err,kInvalidIdHtRC,"A value could not be found for the hash id 0x%x.",id); + + if( cmIsFlag(vp->flags,kFreeHtFl ) ) + cmLhFree(p->lhH,vp->value); + + + vp->flags = 0; + vp->value = NULL; + vp->byteCnt = 0; + + // Note: Do not set the id to zero since we want to consert id's + // and this recd will be reused by the next call to cmHashTblStoreBase(). + + return kOkHtRC; + +} + + +cmHtRC_t cmHashTblLastRC( cmHashTblH_t h ) +{ + cmHt_t* p = _cmHtHandleToPtr(h); + return cmErrLastRC(&p->err); +} + +void _cmHashTblBucketReport( cmHtBucket_t* b, cmRpt_t* rpt ) +{ + cmHtValue_t* vp = b->list; + unsigned i; + for(i=0; vp!=NULL && i<10; vp=vp->link,++i) + cmRptPrintf(rpt,"0x%x : %s\n",vp->id,((const cmChar_t*)vp->value)); + + cmRptPrintf(rpt,"\n"); +} + +void cmHashTblReport( cmHashTblH_t h, cmRpt_t* rpt ) +{ + cmHt_t* p = _cmHtHandleToPtr(h); + unsigned i; + for(i=0; ibucketCnt; ++i) + { + //if( p->b[i].nextIdx > 0 ) + // cmRptPrintf(rpt,"%i,%i\n",i,p->b[i].nextIdx); + + if( p->b[i].nextIdx > 100 ) + _cmHashTblBucketReport(p->b + i,rpt); + } +} + + +cmHtRC_t cmHashTblTest( cmCtx_t* ctx ) +{ + cmHtRC_t rc = kOkHtRC; + cmHashTblH_t h = cmHashTblNullHandle; + cmErr_t err; + cmErrSetup(&err,&ctx->rpt,"hash table test"); + + if((rc = cmHashTblCreate(ctx,&h,8192)) != kOkHtRC ) + return cmErrMsg(&err,rc,"Hash table create failed."); + + const cmChar_t* arr[] = + { + "1", + "12", + "123", + "1234", + "12345", + "123456", + "123456", + "123456", + NULL + }; + + unsigned n = sizeof(arr)/sizeof(arr[0]); + unsigned ids[ n ]; + int i = 0; + + // store the values from arr[] + for(; arr[i]!=NULL; ++i) + if((ids[i] = cmHashTblStoreStr(h,arr[i])) == cmInvalidId ) + { + rc = cmErrMsg(&err,cmHashTblLastRC(h),"Hash store failed on: '%s.",cmStringNullGuard(arr[i])); + goto errLabel; + } + + /* + // remove a value + unsigned rem_idx = 3; + if((rc = cmHashTblRemove(h, ids[rem_idx] )) != kOkHtRC ) + { + rc = cmErrMsg(&err,rc,"Hash removed failed."); + goto errLabel; + } + + // insert the same value - which should restore the removed value + if((ids[rem_idx] = cmHashTblStoreStr(h,arr[rem_idx])) == cmInvalidId ) + { + rc = cmErrMsg(&err,cmHashTblLastRC(h),"Hash store failed on: '%s.",cmStringNullGuard(arr[rem_idx])); + goto errLabel; + } + */ + + // lookup all the stored values by id + for(--i; i>=0; --i) + { + const cmChar_t* s; + + if((s = cmHashTblStr(h,ids[i])) == NULL ) + rc = cmErrMsg(&err,kInvalidIdHtRC,"The value associated with hash-id:0x%x could not be found.",ids[i]); + else + printf("%i : %s\n",i,cmStringNullGuard(s)); + } + + + for(i=0; arr[i]!=NULL; ++i) + { + unsigned id = cmHashTblStrToId(h, arr[i]); + printf("%i : 0x%x : %s\n",i, id, cmStringNullGuard(cmHashTblStr(h, id))); + } + + + cmHashTblReport(h, &ctx->rpt ); + + + errLabel: + cmHashTblDestroy(&h); + return rc; + +} diff --git a/cmHashTbl.h b/cmHashTbl.h new file mode 100644 index 0000000..0b7cdff --- /dev/null +++ b/cmHashTbl.h @@ -0,0 +1,67 @@ +#ifndef cmHashTbl_h +#define cmHashTbl_h + +#ifdef __cplusplus +extern "C" { +#endif + + enum + { + kOkHtRC, + kLHeapFailHtRC, + kHashFaultHtRC, + kInvalidIdHtRC + }; + + typedef cmRC_t cmHtRC_t; + typedef cmHandle_t cmHashTblH_t; + extern cmHashTblH_t cmHashTblNullHandle; + + cmHtRC_t cmHashTblCreate( cmCtx_t* ctx, cmHashTblH_t* hp, unsigned bucketCnt ); + + cmHtRC_t cmHashTblDestroy( cmHashTblH_t* hp ); + + bool cmHashTblIsValid( cmHashTblH_t h ); + + // cmhashTblStoreBase() is the canonical store function. + // Set 'staticFl' to true if the value does not need to be reallocated + // and copied into the internal storage space. + // Returns a value which uniquely identifies the value. If a unique + // identifier cannot be generated then the function returns cmInvalidId + // and sets the hash table error code to kHashFaultRC. + unsigned cmHashTblStoreBase( cmHashTblH_t h, void* v, unsigned byteCnt, bool staticFl ); + + unsigned cmHashTblStore( cmHashTblH_t h, void* v, unsigned byteCnt ); + unsigned cmHashTblStoreStatic( cmHashTblH_t h, void* v, unsigned byteCnt ); + unsigned cmHashTblStoreStr( cmHashTblH_t h, const cmChar_t* s ); + unsigned cmhashTblStoreStaticStr( cmHashTblH_t h, const cmChar_t* s ); + unsigned cmHashTblStoreV( cmHashTblH_t h, const cmChar_t* fmt, va_list vl ); + unsigned cmHashTblStoreF( cmHashTblH_t h, const cmChar_t* fmt, ... ); + + // Given a value find an id. + unsigned cmHashTblId( cmHashTblH_t h, const void* value, unsigned byteCnt ); + unsigned cmHashTblStrToId( cmHashTblH_t h, const cmChar_t* str ); + + // Returns NULL if no value is associated with 'id'. + // 'byteCntRef' is optional. + const void* cmHashTblValue( cmHashTblH_t h, unsigned id, unsigned* byteCntRef ); + + // Wrapper around cmHashTblValue() which assumes that the stored value is a + // zero terminated string. + const cmChar_t* cmHashTblStr( cmHashTblH_t h, unsigned id ); + + // Remove a value. + cmHtRC_t cmHashTblRemove( cmHashTblH_t h, unsigned id ); + + // Return the last error id generated by the cmHashTbl object. + cmHtRC_t cmHashTblLastRC( cmHashTblH_t h ); + + void cmHashTblReport( cmHashTblH_t h, cmRpt_t* rpt ); + + cmHtRC_t cmHashTblTest( cmCtx_t* ctx ); + +#ifdef __cplusplus +} +#endif + +#endif From c8d4648af5d8b53a238b4a7c14745a51ffc72e81 Mon Sep 17 00:00:00 2001 From: kevin Date: Sat, 25 Jan 2014 16:15:09 -0500 Subject: [PATCH 4/6] cmSyncRecd.h/c : Changed result codes from cmXXXSrRC to cmXXXSyRc to avoid conflicts with same named result codes from cmSerialize.h. --- cmSyncRecd.c | 123 ++++++++++++++++++++++++++------------------------- cmSyncRecd.h | 22 ++++----- 2 files changed, 73 insertions(+), 72 deletions(-) diff --git a/cmSyncRecd.c b/cmSyncRecd.c index df54839..774a369 100644 --- a/cmSyncRecd.c +++ b/cmSyncRecd.c @@ -11,6 +11,7 @@ #include "cmSyncRecd.h" #include "cmVectOpsTemplateMain.h" #include "cmMidi.h" + typedef enum { kInvalidSrId, @@ -76,44 +77,44 @@ cmSr_t* _cmSrHtoP( cmSyncRecdH_t h ) return p; } -cmSrRC_t _cmSrWriteCache( cmSr_t* p ) +cmSyRC_t _cmSrWriteCache( cmSr_t* p ) { if( cmFileWrite(p->fH,p->cache,p->ci * sizeof(cmSrRecd_t)) != kOkFileRC ) - return cmErrMsg(&p->err,kFileFailSrRC,"File write failed."); + return cmErrMsg(&p->err,kFileFailSyRC,"File write failed."); p->fn += p->ci; p->ci = 0; - return kOkSrRC; + return kOkSyRC; } -cmSrRC_t _cmSrFinal( cmSr_t* p ) +cmSyRC_t _cmSrFinal( cmSr_t* p ) { - cmSrRC_t rc = kOkSrRC; + cmSyRC_t rc = kOkSyRC; // write any remaining cache records if( cmIsFlag(p->flags,kReadSrFl) == false ) { - if((rc = _cmSrWriteCache(p)) == kOkSrRC ) + if((rc = _cmSrWriteCache(p)) == kOkSyRC ) { if(cmFileSeek(p->fH,kBeginFileFl,p->offs) != kOkFileRC ) - rc = cmErrMsg(&p->err,kFileFailSrRC, "File seek fail on file offset positioning."); + rc = cmErrMsg(&p->err,kFileFailSyRC, "File seek fail on file offset positioning."); else if(cmFileWriteUInt(p->fH,&p->fn,1) != kOkFileRC ) - rc = cmErrMsg(&p->err,kFileFailSrRC, "File write failed on record count."); + rc = cmErrMsg(&p->err,kFileFailSyRC, "File write failed on record count."); } } // release the audio file object if( cmAudioFileIsValid(p->afH) ) if( cmAudioFileDelete(&p->afH) != kOkAfRC ) - return cmErrMsg(&p->err,kAudioFileFailSrRC,"Audio file object delete failed."); + return cmErrMsg(&p->err,kAudioFileFailSyRC,"Audio file object delete failed."); // release the sync-recd file object if( cmFileIsValid(p->fH) ) if( cmFileClose(&p->fH) != kOkFileRC ) - return cmErrMsg(&p->err,kFileFailSrRC,"File close failed."); + return cmErrMsg(&p->err,kFileFailSyRC,"File close failed."); cmMemFree(p->cache); cmMemFree(p->map); @@ -134,27 +135,27 @@ cmSr_t* _cmSrAlloc( cmCtx_t* ctx, unsigned flags ) return p; } -cmSrRC_t cmSyncRecdCreate( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn, const cmChar_t* audioFn, double srate, unsigned chCnt, unsigned bits ) +cmSyRC_t cmSyncRecdCreate( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn, const cmChar_t* audioFn, double srate, unsigned chCnt, unsigned bits ) { - cmSrRC_t rc = kOkSrRC; + cmSyRC_t rc = kOkSyRC; cmRC_t afRC = kOkAfRC; assert( audioFn != NULL ); - if((rc = cmSyncRecdFinal(hp)) != kOkSrRC ) + if((rc = cmSyncRecdFinal(hp)) != kOkSyRC ) return rc; cmSr_t* p = _cmSrAlloc(ctx,0); if( cmFileOpen(&p->fH,srFn,kWriteFileFl,&ctx->rpt) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"Unable to create the sync-recd file '%s'.",cmStringNullGuard(srFn)); + rc = cmErrMsg(&p->err,kFileFailSyRC,"Unable to create the sync-recd file '%s'.",cmStringNullGuard(srFn)); goto errLabel; } if( cmAudioFileIsValid(p->afH = cmAudioFileNewCreate(audioFn,srate,bits,chCnt,&afRC,&ctx->rpt))==false) { - rc = cmErrMsg(&p->err,kAudioFileFailSrRC,"Unable to create the sync-recd audio file '%s'.",cmStringNullGuard(audioFn)); + rc = cmErrMsg(&p->err,kAudioFileFailSyRC,"Unable to create the sync-recd audio file '%s'.",cmStringNullGuard(audioFn)); goto errLabel; } @@ -163,47 +164,47 @@ cmSrRC_t cmSyncRecdCreate( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn if( cmFileWriteUInt(p->fH,&fileUUId,1) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"File write failed on UUID."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"File write failed on UUID."); goto errLabel; } if( cmFileWriteUInt(p->fH,&audioFnCnt,1) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"File write failed on audio file length write count."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"File write failed on audio file length write count."); goto errLabel; } if( cmFileWriteChar(p->fH,audioFn,audioFnCnt) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"File write failed on audio file string."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"File write failed on audio file string."); goto errLabel; } if( cmFileTell(p->fH,&p->offs) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"Unable to determine file offset."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"Unable to determine file offset."); goto errLabel; } if( cmFileWriteUInt(p->fH,&p->fn,1) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"File write failed on initial record count."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"File write failed on initial record count."); goto errLabel; } hp->h = p; errLabel: - if( rc != kOkSrRC ) + if( rc != kOkSyRC ) _cmSrFinal(p); return rc; } -cmSrRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn ) +cmSyRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn ) { - cmSrRC_t rc = kOkSrRC; + cmSyRC_t rc = kOkSyRC; cmRC_t afRC = kOkAfRC; unsigned fileUUId = cmInvalidId; unsigned audioFnCnt = 0; @@ -213,26 +214,26 @@ cmSrRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn unsigned mcnt = 0; unsigned* tiV = NULL; - if((rc = cmSyncRecdFinal(hp)) != kOkSrRC ) + if((rc = cmSyncRecdFinal(hp)) != kOkSyRC ) return rc; cmSr_t* p = _cmSrAlloc(ctx,kReadSrFl); if( cmFileOpen(&p->fH,srFn,kReadFileFl,&ctx->rpt) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"Unable to open the sync-recd file '%s'.",cmStringNullGuard(srFn)); + rc = cmErrMsg(&p->err,kFileFailSyRC,"Unable to open the sync-recd file '%s'.",cmStringNullGuard(srFn)); goto errLabel; } if( cmFileReadUInt(p->fH,&fileUUId,1) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"File read failed on UUId."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"File read failed on UUId."); goto errLabel; } if( cmFileReadUInt(p->fH,&audioFnCnt,1) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"File read failed on audio file name count."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"File read failed on audio file name count."); goto errLabel; } @@ -240,20 +241,20 @@ cmSrRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn if( cmFileReadChar(p->fH,audioFn,audioFnCnt) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"File read failed on audio file string."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"File read failed on audio file string."); goto errLabel; } if( cmFileReadUInt(p->fH,&p->fn,1) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"File read failed on record count."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"File read failed on record count."); goto errLabel; } // store the file offset to the first recd if( cmFileTell(p->fH,&p->offs) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"Unable to determine the current file offset."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"Unable to determine the current file offset."); goto errLabel; } @@ -264,7 +265,7 @@ cmSrRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn cmSrRecd_t r; if( cmFileRead(p->fH,&r,sizeof(r)) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"Unable to read the record at index %i."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"Unable to read the record at index %i."); goto errLabel; } @@ -288,7 +289,7 @@ cmSrRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn // rewind to the begining of the records if( cmFileSeek(p->fH,kBeginFileFl,p->offs) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"Unable to seek to first recd offset."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"Unable to seek to first recd offset."); goto errLabel; } @@ -303,7 +304,7 @@ cmSrRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn { if( cmFileRead(p->fH,p->cache + p->ci,sizeof(cmSrRecd_t)) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"Unable to read the record at index %i."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"Unable to read the record at index %i."); goto errLabel; } @@ -317,7 +318,7 @@ cmSrRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn // rewind to the first recd if( cmFileSeek(p->fH,kBeginFileFl,p->offs) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"Unable to seek to first recd offset."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"Unable to seek to first recd offset."); goto errLabel; } @@ -328,7 +329,7 @@ cmSrRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn cmSrRecd_t r; if( cmFileRead(p->fH,&r,sizeof(r)) != kOkFileRC ) { - rc = cmErrMsg(&p->err,kFileFailSrRC,"Unable to read the record at index %i."); + rc = cmErrMsg(&p->err,kFileFailSyRC,"Unable to read the record at index %i."); goto errLabel; } @@ -358,7 +359,7 @@ cmSrRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn // open the audio file if( cmAudioFileIsValid(p->afH = cmAudioFileNewOpen(audioFn,&p->afInfo,&afRC,&ctx->rpt ))==false) { - rc = cmErrMsg(&p->err,kAudioFileFailSrRC,"Unable to open the sync-recd audio file '%s'.",cmStringNullGuard(audioFn)); + rc = cmErrMsg(&p->err,kAudioFileFailSyRC,"Unable to open the sync-recd audio file '%s'.",cmStringNullGuard(audioFn)); goto errLabel; } @@ -371,22 +372,22 @@ cmSrRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn cmMemFree(tiV); cmMemFree(audioFn); - if( rc != kOkSrRC ) + if( rc != kOkSyRC ) _cmSrFinal(p); return rc; } -cmSrRC_t cmSyncRecdFinal( cmSyncRecdH_t* hp ) +cmSyRC_t cmSyncRecdFinal( cmSyncRecdH_t* hp ) { - cmSrRC_t rc = kOkSrRC; + cmSyRC_t rc = kOkSyRC; if( hp==NULL || cmSyncRecdIsValid(*hp)==false) return rc; cmSr_t* p = _cmSrHtoP(*hp); - if((rc = _cmSrFinal(p)) != kOkSrRC ) + if((rc = _cmSrFinal(p)) != kOkSyRC ) return rc; hp->h = NULL; @@ -397,9 +398,9 @@ cmSrRC_t cmSyncRecdFinal( cmSyncRecdH_t* hp ) bool cmSyncRecdIsValid( cmSyncRecdH_t h ) { return h.h != NULL; } -cmSrRC_t cmSyncRecdMidiWrite( cmSyncRecdH_t h, const cmTimeSpec_t* timestamp, unsigned status, unsigned d0, unsigned d1 ) +cmSyRC_t cmSyncRecdMidiWrite( cmSyncRecdH_t h, const cmTimeSpec_t* timestamp, unsigned status, unsigned d0, unsigned d1 ) { - cmSrRC_t rc = kOkSrRC; + cmSyRC_t rc = kOkSyRC; cmSr_t* p = _cmSrHtoP(h); cmSrRecd_t* rp = p->cache + p->ci; rp->tid = kMidiSrId; @@ -416,9 +417,9 @@ cmSrRC_t cmSyncRecdMidiWrite( cmSyncRecdH_t h, const cmTimeSpec_t* timestamp, u return rc; } -cmSrRC_t cmSyncRecdAudioWrite( cmSyncRecdH_t h, const cmTimeSpec_t* timestamp, unsigned smpIdx, const cmSample_t* ch[], unsigned chCnt, unsigned frmCnt ) +cmSyRC_t cmSyncRecdAudioWrite( cmSyncRecdH_t h, const cmTimeSpec_t* timestamp, unsigned smpIdx, const cmSample_t* ch[], unsigned chCnt, unsigned frmCnt ) { - cmSrRC_t rc = kOkSrRC; + cmSyRC_t rc = kOkSyRC; cmSr_t* p = _cmSrHtoP(h); cmSrRecd_t* rp = p->cache + p->ci; rp->tid = kAudioSrId; @@ -428,25 +429,25 @@ cmSrRC_t cmSyncRecdAudioWrite( cmSyncRecdH_t h, const cmTimeSpec_t* timestamp, u p->ci += 1; if( p->ci == p->cn ) - if((rc = _cmSrWriteCache(p)) != kOkSrRC ) + if((rc = _cmSrWriteCache(p)) != kOkSyRC ) goto errLabel; if( cmAudioFileWriteSample(p->afH,frmCnt,chCnt,(cmSample_t**)ch) != kOkAfRC ) - rc = cmErrMsg(&p->err,kAudioFileFailSrRC,"Audio file write failed."); + rc = cmErrMsg(&p->err,kAudioFileFailSyRC,"Audio file write failed."); errLabel: return rc; } -cmSrRC_t cmSyncRecdPrint( cmSyncRecdH_t h ) +cmSyRC_t cmSyncRecdPrint( cmSyncRecdH_t h ) { - cmSrRC_t rc = kOkSrRC; + cmSyRC_t rc = kOkSyRC; cmSr_t* p = _cmSrHtoP(h); unsigned i; if( cmIsFlag(p->flags,kReadSrFl)==false) - return cmErrMsg(&p->err,kInvalidOpSrRC,"The 'print' operation is only valid on sync-recd files opened for reading."); + return cmErrMsg(&p->err,kInvalidOpSyRC,"The 'print' operation is only valid on sync-recd files opened for reading."); for(i=0; icn; ++i) { @@ -457,9 +458,9 @@ cmSrRC_t cmSyncRecdPrint( cmSyncRecdH_t h ) return rc; } -cmSrRC_t cmSyncRecdAudioFile( cmSyncRecdH_t h, const cmChar_t* fn ) +cmSyRC_t cmSyncRecdAudioFile( cmSyncRecdH_t h, const cmChar_t* fn ) { - cmSrRC_t rc = kOkSrRC; + cmSyRC_t rc = kOkSyRC; cmSr_t* p = _cmSrHtoP(h); cmAudioFileH_t afH = cmNullAudioFileH; unsigned chCnt = 2; @@ -474,19 +475,19 @@ cmSrRC_t cmSyncRecdAudioFile( cmSyncRecdH_t h, const cmChar_t* fn ) chs[1] = buf+frmCnt; if( cmIsFlag(p->flags,kReadSrFl)==false) - return cmErrMsg(&p->err,kInvalidOpSrRC,"The 'audio-file-output' operation is only valid on sync-recd files opened for reading."); + return cmErrMsg(&p->err,kInvalidOpSyRC,"The 'audio-file-output' operation is only valid on sync-recd files opened for reading."); /// Open an audio file for writing if(cmAudioFileIsValid(afH = cmAudioFileNewCreate(fn, p->afInfo.srate, p->afInfo.bits, chCnt, &afRC, p->err.rpt))==false) { - rc = cmErrMsg(&p->err,kAudioFileFailSrRC,"Unable to create the synchronized audio file '%s'.",cmStringNullGuard(fn)); + rc = cmErrMsg(&p->err,kAudioFileFailSyRC,"Unable to create the synchronized audio file '%s'.",cmStringNullGuard(fn)); goto errLabel; } // rewind the input audio file if( cmAudioFileSeek(p->afH,0) != kOkAfRC ) { - rc = cmErrMsg(&p->err,kAudioFileFailSrRC,"Seek failed during synchronized audio file output."); + rc = cmErrMsg(&p->err,kAudioFileFailSyRC,"Seek failed during synchronized audio file output."); goto errLabel; } @@ -500,7 +501,7 @@ cmSrRC_t cmSyncRecdAudioFile( cmSyncRecdH_t h, const cmChar_t* fn ) // read frmCnt samples from the first channel of the input audio file if( cmAudioFileReadSample(p->afH, frmCnt, chIdx, 1, chs, &actFrmCnt ) != kOkAfRC ) { - rc = cmErrMsg(&p->err,kAudioFileFailSrRC,"Audio file read failed."); + rc = cmErrMsg(&p->err,kAudioFileFailSyRC,"Audio file read failed."); break; } @@ -515,7 +516,7 @@ cmSrRC_t cmSyncRecdAudioFile( cmSyncRecdH_t h, const cmChar_t* fn ) // write the audio output samples if( cmAudioFileWriteSample(afH, frmCnt, chCnt, chs ) != kOkAfRC ) { - rc = cmErrMsg(&p->err,kAudioFileFailSrRC,"Synchronized audio file write failed."); + rc = cmErrMsg(&p->err,kAudioFileFailSyRC,"Synchronized audio file write failed."); break; } @@ -523,12 +524,12 @@ cmSrRC_t cmSyncRecdAudioFile( cmSyncRecdH_t h, const cmChar_t* fn ) errLabel: if( cmAudioFileDelete(&afH) != kOkAfRC ) - rc = cmErrMsg(&p->err,kAudioFileFailSrRC,"Synchronized audio file close failed."); + rc = cmErrMsg(&p->err,kAudioFileFailSyRC,"Synchronized audio file close failed."); return rc; } -cmSrRC_t cmSyncRecdTest( cmCtx_t* ctx ) +cmSyRC_t cmSyncRecdTest( cmCtx_t* ctx ) { enum { @@ -536,7 +537,7 @@ cmSrRC_t cmSyncRecdTest( cmCtx_t* ctx ) kTestFailRC, }; - cmSrRC_t rc = kOkSrRC; + cmSyRC_t rc = kOkSyRC; const cmChar_t* srFn = "/home/kevin/temp/kr/sr/sr0.sr"; const cmChar_t* aFn = "/home/kevin/temp/kr/sr/sync_af.aiff"; cmErr_t err; @@ -545,7 +546,7 @@ cmSrRC_t cmSyncRecdTest( cmCtx_t* ctx ) cmErrSetup(&err,&ctx->rpt,"SyncRecdTest"); - if((rc = cmSyncRecdOpen(ctx, &srH, srFn )) != kOkSrRC ) + if((rc = cmSyncRecdOpen(ctx, &srH, srFn )) != kOkSyRC ) { cmErrMsg(&err,kTestFailRC,"Sync-recd open failed."); goto errLabel; @@ -555,7 +556,7 @@ cmSrRC_t cmSyncRecdTest( cmCtx_t* ctx ) cmSyncRecdAudioFile(srH,aFn); errLabel: - if((rc = cmSyncRecdFinal(&srH)) != kOkSrRC ) + if((rc = cmSyncRecdFinal(&srH)) != kOkSyRC ) cmErrMsg(&err,kTestFailRC,"Sync-recd close failed."); return rc; diff --git a/cmSyncRecd.h b/cmSyncRecd.h index e1f93e9..d5fdd1d 100644 --- a/cmSyncRecd.h +++ b/cmSyncRecd.h @@ -7,26 +7,26 @@ extern "C" { enum { - kOkSrRC, - kFileFailSrRC, - kAudioFileFailSrRC, - kInvalidOpSrRC + kOkSyRC, + kFileFailSyRC, + kAudioFileFailSyRC, + kInvalidOpSyRC }; typedef cmHandle_t cmSyncRecdH_t; - typedef cmRC_t cmSrRC_t; + typedef cmRC_t cmSyRC_t; extern cmSyncRecdH_t cmSyncRecdNullHandle; - cmSrRC_t cmSyncRecdCreate( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn, const cmChar_t* audioFn, double srate, unsigned chCnt, unsigned bits ); - cmSrRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn ); - cmSrRC_t cmSyncRecdFinal( cmSyncRecdH_t* hp ); + cmSyRC_t cmSyncRecdCreate( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn, const cmChar_t* audioFn, double srate, unsigned chCnt, unsigned bits ); + cmSyRC_t cmSyncRecdOpen( cmCtx_t* ctx, cmSyncRecdH_t* hp, const cmChar_t* srFn ); + cmSyRC_t cmSyncRecdFinal( cmSyncRecdH_t* hp ); bool cmSyncRecdIsValid( cmSyncRecdH_t h ); - cmSrRC_t cmSyncRecdMidiWrite( cmSyncRecdH_t h, const cmTimeSpec_t* timestamp, unsigned status, unsigned d0, unsigned d1 ); - cmSrRC_t cmSyncRecdAudioWrite( cmSyncRecdH_t h, const cmTimeSpec_t* timestamp, unsigned smpIdx, const cmSample_t* ch[], unsigned chCnt, unsigned frmCnt ); + cmSyRC_t cmSyncRecdMidiWrite( cmSyncRecdH_t h, const cmTimeSpec_t* timestamp, unsigned status, unsigned d0, unsigned d1 ); + cmSyRC_t cmSyncRecdAudioWrite( cmSyncRecdH_t h, const cmTimeSpec_t* timestamp, unsigned smpIdx, const cmSample_t* ch[], unsigned chCnt, unsigned frmCnt ); - cmSrRC_t cmSyncRecdTest( cmCtx_t* ctx ); + cmSyRC_t cmSyncRecdTest( cmCtx_t* ctx ); #ifdef __cplusplus } From 2cac6143ad3343589f77dba47f97bd8040ce1970 Mon Sep 17 00:00:00 2001 From: kevin Date: Sat, 25 Jan 2014 16:16:06 -0500 Subject: [PATCH 5/6] cmCsv.h/c: CSV reader now uses a hash table rather than symbol table. --- cmCsv.c | 48 ++++++++++++++++++++++++------------------------ cmCsv.h | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/cmCsv.c b/cmCsv.c index e18373e..229df1f 100644 --- a/cmCsv.c +++ b/cmCsv.c @@ -7,7 +7,7 @@ #include "cmMallocDebug.h" #include "cmLex.h" #include "cmLinkedHeap.h" -#include "cmSymTbl.h" +#include "cmHashTbl.h" #include "cmCsv.h" #include "cmText.h" @@ -48,9 +48,9 @@ typedef struct cmCsvUdef_str typedef struct { cmErr_t err; - void* rptDataPtr; // - cmLexH lexH; // parsing lexer - cmSymTblH_t symTblH; // all XML identifiers and data is stored as a symbol in this table + void* rptDataPtr; // + cmLexH lexH; // parsing lexer + cmHashTblH_t htH; // hash table handle cmLHeapH_t heapH; cmCsvBind_t* bindPtr; // base of the binder linked list cmCsvCell_t* curRowPtr; // used by the parser to track the row being filled @@ -95,15 +95,15 @@ cmCsvRC_t cmCsvInitialize( cmCsvH_t *hp, cmCtx_t* ctx ) cmErrSetup(&p->err,&ctx->rpt,"CSV"); - // create the symbol table - if( cmSymTblIsValid(p->symTblH = cmSymTblCreate(cmSymTblNullHandle,0,ctx)) == false ) + // create the hash table + if( cmHashTblCreate(ctx,&p->htH,8192) != kOkHtRC ) { - rc = _cmCsvError(p,kSymTblErrCsvRC,"Symbol table creation failed."); + rc = _cmCsvError(p,kHashTblErrCsvRC,"Hash table creation failed."); goto errLabel; } // allocate the linked heap mgr - if( cmLHeapIsValid(p->heapH = cmLHeapCreate(1024,ctx)) == false ) + if( cmLHeapIsValid(p->heapH = cmLHeapCreate(8192,ctx)) == false ) { rc = _cmCsvError(p,kMemAllocErrCsvRC,"Linked heap object allocation failed."); goto errLabel; @@ -161,8 +161,8 @@ cmCsvRC_t cmCsvFinalize( cmCsvH_t *hp ) if((lexRC = cmLexFinal(&p->lexH)) != kOkLexRC ) return _cmCsvError(p,kLexErrCsvRC,"Lexer finalization failed.\nLexer Error:%s",cmLexRcToMsg(lexRC)); - // free the symbol table - cmSymTblDestroy(&p->symTblH); + // free the hash table + cmHashTblDestroy(&p->htH); // free the handle cmMemPtrFree(&hp->h); @@ -352,8 +352,8 @@ cmCsvRC_t _cmCsvCreateCell( cmCsv_t* p, const char* tokenText, unsigned flags, u cmCsvRC_t rc = kOkCsvRC; // register the token text as a symbol - if((symId = cmSymTblRegisterSymbol(p->symTblH,tokenText)) == cmInvalidId ) - return _cmCsvError(p,kSymTblErrCsvRC,"Symbol registration failed. for '%s' on line %i column %i.",tokenText,lexRow,lexCol); + if((symId = cmHashTblStoreStr(p->htH,tokenText)) == cmInvalidId ) + return _cmCsvError(p,kHashTblErrCsvRC,"Symbol registration failed. for '%s' on line %i column %i.",tokenText,lexRow,lexCol); // allocate a cell if((rc = _cmCsvAllocCell(p,symId,flags,cellRow,cellCol,&cp,lexTId)) != kOkCsvRC ) @@ -561,8 +561,8 @@ const char* cmCsvCellSymText( cmCsvH_t h, unsigned symId ) cmCsv_t* p = _cmCsvHandleToPtr(h); const char* cp; - if((cp = cmSymTblLabel(p->symTblH,symId)) == NULL ) - _cmCsvError(p,kSymTblErrCsvRC,"The text associated with the symbol '%i' was not found.",symId); + if((cp = cmHashTblStr(p->htH,symId)) == NULL ) + _cmCsvError(p,kHashTblErrCsvRC,"The text associated with the symbol '%i' was not found.",symId); return cp; } @@ -573,7 +573,7 @@ cmCsvRC_t cmCsvCellSymInt( cmCsvH_t h, unsigned symId, int* vp ) cmCsv_t* p = _cmCsvHandleToPtr(h); if((cp = cmCsvCellSymText(h,symId)) == NULL ) - return kSymTblErrCsvRC; + return kHashTblErrCsvRC; if( cmTextToInt(cp,vp,&p->err) != kOkTxRC ) return _cmCsvError(p,kDataCvtErrCsvRC,"CSV text to int value failed."); @@ -587,7 +587,7 @@ cmCsvRC_t cmCsvCellSymUInt( cmCsvH_t h, unsigned symId, unsigned* vp ) cmCsv_t* p = _cmCsvHandleToPtr(h); if((cp = cmCsvCellSymText(h,symId)) == NULL ) - return kSymTblErrCsvRC; + return kHashTblErrCsvRC; if( cmTextToUInt(cp,vp,&p->err) != kOkTxRC ) return _cmCsvError(p,kDataCvtErrCsvRC,"CSV text to uint value failed."); @@ -601,7 +601,7 @@ cmCsvRC_t cmCsvCellSymFloat( cmCsvH_t h, unsigned symId, float* vp ) cmCsv_t* p = _cmCsvHandleToPtr(h); if((cp = cmCsvCellSymText(h,symId)) == NULL ) - return kSymTblErrCsvRC; + return kHashTblErrCsvRC; if( cmTextToFloat(cp,vp,&p->err) != kOkTxRC ) return _cmCsvError(p,kDataCvtErrCsvRC,"CSV text to float value failed."); @@ -615,7 +615,7 @@ cmCsvRC_t cmCsvCellSymDouble( cmCsvH_t h, unsigned symId, double* vp ) cmCsv_t* p = _cmCsvHandleToPtr(h); if((cp = cmCsvCellSymText(h,symId)) == NULL ) - return kSymTblErrCsvRC; + return kHashTblErrCsvRC; if( cmTextToDouble(cp,vp,&p->err) != kOkTxRC ) return _cmCsvError(p,kDataCvtErrCsvRC,"CSV text to double value failed."); @@ -695,8 +695,8 @@ unsigned cmCsvInsertSymText( cmCsvH_t h, const char* text ) cmCsv_t* p = _cmCsvHandleToPtr(h); unsigned symId; - if((symId = cmSymTblRegisterSymbol(p->symTblH,text)) == cmInvalidId ) - _cmCsvError(p,kSymTblErrCsvRC,"'%s' could not be inserted into the symbol table.",text); + if((symId = cmHashTblStoreStr(p->htH,text)) == cmInvalidId ) + _cmCsvError(p,kHashTblErrCsvRC,"'%s' could not be inserted into the symbol table.",text); return symId; } @@ -1134,8 +1134,8 @@ cmCsvRC_t cmCsvWrite( cmCsvH_t h, const char* fn ) { const char* tp; - if((tp = cmSymTblLabel(p->symTblH,cp->symId)) == NULL ) - return _cmCsvError(p,kSymTblErrCsvRC,"Unable to locate the symbol text for cell at row:%i col:%i.",cp->row,cp->col); + if((tp = cmHashTblStr(p->htH,cp->symId)) == NULL ) + return _cmCsvError(p,kHashTblErrCsvRC,"Unable to locate the symbol text for cell at row:%i col:%i.",cp->row,cp->col); if( cmIsFlag(cp->flags,kTextTMask) ) fprintf(fp,"\""); @@ -1179,8 +1179,8 @@ cmCsvRC_t cmCsvPrint( cmCsvH_t h, unsigned rowCnt ) { const char* tp; - if((tp = cmSymTblLabel(p->symTblH,cp->symId)) == NULL ) - _cmCsvError(p,kSymTblErrCsvRC,"The text associated with the symbol '%i' was not found.",cp->symId); + if((tp = cmHashTblStr(p->htH,cp->symId)) == NULL ) + _cmCsvError(p,kHashTblErrCsvRC,"The text associated with the symbol '%i' was not found.",cp->symId); fputs(tp,stdin); } diff --git a/cmCsv.h b/cmCsv.h index e686c1c..f4901fc 100644 --- a/cmCsv.h +++ b/cmCsv.h @@ -11,7 +11,7 @@ extern "C" { kOkCsvRC = 0, kMemAllocErrCsvRC, kLexErrCsvRC, - kSymTblErrCsvRC, + kHashTblErrCsvRC, kSyntaxErrCsvRC, kFileOpenErrCsvRC, kFileCreateErrCsvRC, From 1e26484c74eb2487ff92fdfd7ebf8292363bdf5a Mon Sep 17 00:00:00 2001 From: kevin Date: Sat, 25 Jan 2014 16:17:50 -0500 Subject: [PATCH 6/6] cmDspKr.c: Removed declaration of unused variable in _cmDspNanMapRecv() to eliminate compiler warning. --- dsp/cmDspKr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dsp/cmDspKr.c b/dsp/cmDspKr.c index 5512919..6c44150 100644 --- a/dsp/cmDspKr.c +++ b/dsp/cmDspKr.c @@ -2383,7 +2383,7 @@ cmDspRC_t _cmDspNanoMapSend( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned st, un void _cmDspNanoMapPgm( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned pgm ) { - cmDspNanoMap_t* p = (cmDspNanoMap_t*)inst; + //cmDspNanoMap_t* p = (cmDspNanoMap_t*)inst; unsigned i; @@ -2430,7 +2430,7 @@ cmDspRC_t _cmDspNanoMapReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ cmDspRC_t _cmDspNanoMapRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) { - cmDspNanoMap_t* p = (cmDspNanoMap_t*)inst; + //cmDspNanoMap_t* p = (cmDspNanoMap_t*)inst; switch( evt->dstVarId ) { @@ -3070,7 +3070,7 @@ cmDspRC_t _cmDspSyncRecdCreateFile( cmDspCtx_t* ctx, cmDspInst_t* inst ) return cmDspInstErr(ctx,&p->inst,kFileSysFailDspRC,"Sync-recd file name generation failed for dir='%s' and prefix='%s'.",cmStringNullGuard(dir),cmStringNullGuard(srFn)); unsigned bits = cmDspUInt(inst,kBitsSrId); - if( cmSyncRecdCreate( ctx->cmCtx, &p->srH, p->srFn, p->aFn, cmDspSampleRate(ctx), p->chCnt, bits ) != kOkSrRC ) + if( cmSyncRecdCreate( ctx->cmCtx, &p->srH, p->srFn, p->aFn, cmDspSampleRate(ctx), p->chCnt, bits ) != kOkSyRC ) return cmDspInstErr(ctx,&p->inst,kSubSysFailDspRC,"Sync-recd file create failed for '%s'.",p->srFn); p->smpIdx = 0; @@ -3152,7 +3152,7 @@ cmDspRC_t _cmDspSyncRecdExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ } if( n>0 && cmSyncRecdIsValid(p->srH ) ) - if( cmSyncRecdAudioWrite( p->srH, &ctx->ctx->iTimeStamp, p->smpIdx, x, p->chCnt, n ) != kOkSrRC ) + if( cmSyncRecdAudioWrite( p->srH, &ctx->ctx->iTimeStamp, p->smpIdx, x, p->chCnt, n ) != kOkSyRC ) return cmDspInstErr(ctx,&p->inst,kSubSysFailDspRC,"Sync-recd audio update failed."); p->smpIdx += n; @@ -3179,7 +3179,7 @@ cmDspRC_t _cmDspSyncRecdRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ //printf("%i %i\n",cmDspUInt(inst,kD1SrId),cmTimeElapsedMicros(&ts,&p->ats)); if( cmSyncRecdIsValid(p->srH ) ) - if( cmSyncRecdMidiWrite(p->srH, &ts, cmDspUInt(inst,kStatusSrId), cmDspUInt(inst,kD0SrId), cmDspUInt(inst,kD1SrId) ) != kOkSrRC ) + if( cmSyncRecdMidiWrite(p->srH, &ts, cmDspUInt(inst,kStatusSrId), cmDspUInt(inst,kD0SrId), cmDspUInt(inst,kD1SrId) ) != kOkSyRC ) return cmDspInstErr(ctx,&p->inst,kSubSysFailDspRC,"Sync-recd MIDI update failed."); } break;