Merge branch 'master' of klarke.webfactional.com:webapps/git/repos/libcm with
spat lab mac.
This commit is contained in:
commit
c946234fde
560
app/cmScore.c
560
app/cmScore.c
@ -6,6 +6,7 @@
|
|||||||
#include "cmCtx.h"
|
#include "cmCtx.h"
|
||||||
#include "cmMem.h"
|
#include "cmMem.h"
|
||||||
#include "cmMallocDebug.h"
|
#include "cmMallocDebug.h"
|
||||||
|
#include "cmLinkedHeap.h"
|
||||||
#include "cmMidi.h"
|
#include "cmMidi.h"
|
||||||
#include "cmLex.h"
|
#include "cmLex.h"
|
||||||
#include "cmCsv.h"
|
#include "cmCsv.h"
|
||||||
@ -13,6 +14,7 @@
|
|||||||
#include "cmMidiFile.h"
|
#include "cmMidiFile.h"
|
||||||
#include "cmAudioFile.h"
|
#include "cmAudioFile.h"
|
||||||
#include "cmTimeLine.h"
|
#include "cmTimeLine.h"
|
||||||
|
#include "cmText.h"
|
||||||
#include "cmScore.h"
|
#include "cmScore.h"
|
||||||
#include "cmVectOpsTemplateMain.h"
|
#include "cmVectOpsTemplateMain.h"
|
||||||
|
|
||||||
@ -41,7 +43,8 @@ enum
|
|||||||
kFracColScIdx = 18,
|
kFracColScIdx = 18,
|
||||||
kDynColScIdx = 19,
|
kDynColScIdx = 19,
|
||||||
kSectionColScIdx = 20,
|
kSectionColScIdx = 20,
|
||||||
kRemarkColScIdx = 21
|
kRecdPlayColScIdx = 21,
|
||||||
|
kRemarkColScIdx = 22
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -75,6 +78,15 @@ typedef struct cmScSet_str
|
|||||||
struct cmScSet_str* link; //
|
struct cmScSet_str* link; //
|
||||||
} cmScSet_t;
|
} cmScSet_t;
|
||||||
|
|
||||||
|
typedef struct cmScMark_str
|
||||||
|
{
|
||||||
|
cmMarkScMId_t cmdId;
|
||||||
|
unsigned labelSymId;
|
||||||
|
unsigned scoreIdx;
|
||||||
|
unsigned csvRowIdx;
|
||||||
|
struct cmScMark_str* link;
|
||||||
|
} cmScMark_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
cmErr_t err;
|
cmErr_t err;
|
||||||
@ -94,11 +106,15 @@ typedef struct
|
|||||||
cmScoreSection_t* sect;
|
cmScoreSection_t* sect;
|
||||||
unsigned sectCnt;
|
unsigned sectCnt;
|
||||||
|
|
||||||
|
unsigned* markLabelArray; // one symId per unique cmScoreMarker_t.labelSymId;
|
||||||
|
unsigned markLabelCnt;
|
||||||
|
|
||||||
unsigned sciPitchLexTId; // sci pitch and section id lexer token id's
|
unsigned sciPitchLexTId; // sci pitch and section id lexer token id's
|
||||||
unsigned sectionLexTId;
|
unsigned sectionLexTId;
|
||||||
|
|
||||||
cmScSect_t* sectList; // lists used during parsing
|
cmScSect_t* sectList; // lists used during parsing
|
||||||
cmScSet_t* setList;
|
cmScSet_t* setList;
|
||||||
|
cmScMark_t* markList;
|
||||||
|
|
||||||
cmScoreSet_t* sets;
|
cmScoreSet_t* sets;
|
||||||
unsigned setCnt;
|
unsigned setCnt;
|
||||||
@ -313,6 +329,17 @@ unsigned _cmScLexSectionIdMatcher( const cmChar_t* cp, unsigned cn )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _cmScFreeMarkList( cmScMark_t* markList )
|
||||||
|
{
|
||||||
|
cmScMark_t* mp = markList;
|
||||||
|
while( mp!=NULL )
|
||||||
|
{
|
||||||
|
cmScMark_t* np = mp->link;
|
||||||
|
cmMemFree(mp);
|
||||||
|
mp = np;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _cmScFreeSetList( cmScSet_t* setList )
|
void _cmScFreeSetList( cmScSet_t* setList )
|
||||||
{
|
{
|
||||||
cmScSet_t* tp = setList;
|
cmScSet_t* tp = setList;
|
||||||
@ -366,6 +393,8 @@ cmScRC_t _cmScFinalize( cmSc_t* p )
|
|||||||
|
|
||||||
_cmScFreeSetList(p->setList);
|
_cmScFreeSetList(p->setList);
|
||||||
|
|
||||||
|
_cmScFreeMarkList(p->markList);
|
||||||
|
|
||||||
if( p->loc != NULL )
|
if( p->loc != NULL )
|
||||||
{
|
{
|
||||||
for(i=0; i<p->locCnt; ++i)
|
for(i=0; i<p->locCnt; ++i)
|
||||||
@ -373,12 +402,23 @@ cmScRC_t _cmScFinalize( cmSc_t* p )
|
|||||||
cmMemFree(p->loc[i].evtArray);
|
cmMemFree(p->loc[i].evtArray);
|
||||||
if( p->loc[i].begSectPtr != NULL )
|
if( p->loc[i].begSectPtr != NULL )
|
||||||
cmMemFree(p->loc[i].begSectPtr->setArray);
|
cmMemFree(p->loc[i].begSectPtr->setArray);
|
||||||
|
|
||||||
|
// free the marker list assoc'd with this location
|
||||||
|
cmScoreMarker_t* smp = p->loc[i].markList;
|
||||||
|
while( smp!=NULL )
|
||||||
|
{
|
||||||
|
cmScoreMarker_t* np = smp->link;
|
||||||
|
cmMemFree(smp);
|
||||||
|
smp = np;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
cmMemFree(p->loc);
|
cmMemFree(p->loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmMemPtrFree(&p->dynRefArray);
|
|
||||||
|
|
||||||
|
cmMemPtrFree(&p->dynRefArray);
|
||||||
|
cmMemFree(p->markLabelArray);
|
||||||
cmMemFree(p->sect);
|
cmMemFree(p->sect);
|
||||||
cmMemFree(p->fn);
|
cmMemFree(p->fn);
|
||||||
cmMemFree(p->array);
|
cmMemFree(p->array);
|
||||||
@ -557,6 +597,79 @@ cmScRC_t _cmScParseAttr(cmSc_t* p, unsigned scoreIdx, const cmChar_t* text, unsi
|
|||||||
return kOkScRC;
|
return kOkScRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse a record/playback string
|
||||||
|
cmScRC_t _cmScParseMarkers( cmSc_t* p, unsigned scoreIdx, const cmChar_t* text, unsigned rowIdx )
|
||||||
|
{
|
||||||
|
const cmChar_t* cp = text;
|
||||||
|
const cmChar_t* ip;
|
||||||
|
const cmChar_t* ep;
|
||||||
|
|
||||||
|
// if no symbol table has been registered then don't bother storing markers.
|
||||||
|
// (NOTE - THIS IS A HACK BECAUSE THE SCORE OBJECT USED IN THE cmdIf DOES NOT HAVE
|
||||||
|
// A SYMBOL TABLE - WE COULD EASILY ADD ONE IF IT EVENTUALLY NEEDS ACCESS TO THE MARKERS
|
||||||
|
// - OR A SYMBOL TABLE COULD BE ADDED TO THE SCORE ITSELF.)
|
||||||
|
if( cmSymTblIsValid(p->stH) == false )
|
||||||
|
return kOkScRC;
|
||||||
|
|
||||||
|
// go to command/id space
|
||||||
|
if((ip = cmTextNextWhiteOrEosC(text)) == NULL )
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
|
// goto label
|
||||||
|
if((ip = cmTextNextNonWhiteC(ip)) == NULL )
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
|
// goto end of label
|
||||||
|
if((ep = cmTextNextWhiteOrEosC(ip)) == NULL )
|
||||||
|
goto errLabel;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned n = (ep-ip)+1;
|
||||||
|
cmChar_t markTextStr[n+1];
|
||||||
|
strncpy(markTextStr,ip,n);
|
||||||
|
|
||||||
|
// for each command code
|
||||||
|
// (there may be more than one character)
|
||||||
|
for(; *cp && !isspace(*cp); ++cp)
|
||||||
|
{
|
||||||
|
cmMarkScMId_t cmdId = kInvalidScMId;
|
||||||
|
|
||||||
|
switch( *cp )
|
||||||
|
{
|
||||||
|
case 'c': cmdId = kRecdBegScMId; break;
|
||||||
|
case 'e': cmdId = kRecdEndScMId; break;
|
||||||
|
case 'p': cmdId = kPlayBegScMId; break;
|
||||||
|
case 'd': cmdId = kPlayEndScMId; break;
|
||||||
|
case 'f': cmdId = kFadeScMId; break;
|
||||||
|
default:
|
||||||
|
return cmErrMsg(&p->err,kSyntaxErrScRC,"Unrecognized marker command character '%c' at row index %i.",*cp,rowIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmScMark_t* mp = cmMemAllocZ(cmScMark_t,1);
|
||||||
|
mp->cmdId = cmdId;
|
||||||
|
mp->labelSymId = cmSymTblRegisterSymbol(p->stH,markTextStr);
|
||||||
|
mp->scoreIdx = scoreIdx;
|
||||||
|
mp->csvRowIdx = rowIdx;
|
||||||
|
|
||||||
|
// insert the new mark at the end of the list
|
||||||
|
if( p->markList == NULL )
|
||||||
|
p->markList = mp;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmScMark_t* ep = p->markList;
|
||||||
|
while( ep->link != NULL )
|
||||||
|
ep = ep->link;
|
||||||
|
|
||||||
|
ep->link = mp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return kOkScRC;
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
return cmErrMsg(&p->err,kSyntaxErrScRC,"Invalid record/playback field ('%s') on row index:%i.",cmStringNullGuard(text),rowIdx);
|
||||||
|
}
|
||||||
|
|
||||||
void _cmScPrintSets( const cmChar_t* label, cmScSet_t* setList )
|
void _cmScPrintSets( const cmChar_t* label, cmScSet_t* setList )
|
||||||
{
|
{
|
||||||
printf("%s\n",label);
|
printf("%s\n",label);
|
||||||
@ -598,7 +711,7 @@ cmScRC_t _cmScParseNoteOn( cmSc_t* p, unsigned rowIdx, cmScoreEvt_t* s, unsigned
|
|||||||
return cmErrMsg(&p->err,kSyntaxErrScRC,"Expected a scientific pitch value");
|
return cmErrMsg(&p->err,kSyntaxErrScRC,"Expected a scientific pitch value");
|
||||||
|
|
||||||
if((midiPitch = cmSciPitchToMidi(sciPitch)) == kInvalidMidiPitch)
|
if((midiPitch = cmSciPitchToMidi(sciPitch)) == kInvalidMidiPitch)
|
||||||
return cmErrMsg(&p->err,kSyntaxErrScRC,"Unable to convert the scientific pitch '%s' to a MIDI value. ");
|
return cmErrMsg(&p->err,kSyntaxErrScRC,"Unable to convert the scientific pitch '%s' to a MIDI value. ");
|
||||||
|
|
||||||
// it is possible that note delta-secs field is empty - so default to 0
|
// it is possible that note delta-secs field is empty - so default to 0
|
||||||
if((secs = cmCsvCellDouble(p->cH, rowIdx, kSecsColScIdx )) == DBL_MAX) // Returns DBL_MAX on error.
|
if((secs = cmCsvCellDouble(p->cH, rowIdx, kSecsColScIdx )) == DBL_MAX) // Returns DBL_MAX on error.
|
||||||
@ -658,6 +771,14 @@ cmScRC_t _cmScParseNoteOn( cmSc_t* p, unsigned rowIdx, cmScoreEvt_t* s, unsigned
|
|||||||
durSecs = 0.25;
|
durSecs = 0.25;
|
||||||
|
|
||||||
|
|
||||||
|
// parse the recd/play markers
|
||||||
|
if((attr = cmCsvCellText(p->cH,rowIdx,kRecdPlayColScIdx)) != NULL )
|
||||||
|
{
|
||||||
|
if((rc = _cmScParseMarkers(p,scoreIdx,attr,rowIdx)) != kOkScRC )
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
s->type = kNonEvtScId;
|
s->type = kNonEvtScId;
|
||||||
s->secs = secs;
|
s->secs = secs;
|
||||||
s->pitch = midiPitch;
|
s->pitch = midiPitch;
|
||||||
@ -870,6 +991,8 @@ cmScRC_t _cmScProcSets( cmSc_t* p )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cmScRC_t _cmScProcSections( cmSc_t* p, cmScSect_t* sectList )
|
cmScRC_t _cmScProcSections( cmSc_t* p, cmScSect_t* sectList )
|
||||||
{
|
{
|
||||||
cmScRC_t rc = kOkScRC;
|
cmScRC_t rc = kOkScRC;
|
||||||
@ -935,6 +1058,153 @@ cmScRC_t _cmScProcSections( cmSc_t* p, cmScSect_t* sectList )
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cmScoreLoc_t* _cmScFindMarkLoc( cmSc_t* p, cmMarkScMId_t cmdId, unsigned labelSymId, const cmScoreMarker_t** markRef )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for(i=0; i<p->locCnt; ++i)
|
||||||
|
{
|
||||||
|
cmScoreMarker_t* smp = p->loc[i].markList;
|
||||||
|
for(; smp!=NULL; smp=smp->link)
|
||||||
|
{
|
||||||
|
if( smp->markTypeId==cmdId && smp->labelSymId==labelSymId )
|
||||||
|
return p->loc + i;
|
||||||
|
|
||||||
|
if( markRef != NULL )
|
||||||
|
*markRef = smp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned _cmScMarkerLabelIndex( cmSc_t* p, unsigned labelSymId )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for(i=0; i<p->markLabelCnt; ++i)
|
||||||
|
if( p->markLabelArray[i] == labelSymId )
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return cmInvalidIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Verify that the record/play begin/end and fade markers fall in the correct time order.
|
||||||
|
// (e.g. 'begin' must be before 'end' and 'fade' must be between and 'begin' and 'end').
|
||||||
|
cmScRC_t _cmScValidateMarkers( cmSc_t* p )
|
||||||
|
{
|
||||||
|
cmScRC_t rc = kOkScRC;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for(i=0; i<p->locCnt; ++i)
|
||||||
|
{
|
||||||
|
cmScoreMarker_t* sm0p = p->loc[i].markList;
|
||||||
|
for(; sm0p!=NULL; sm0p=sm0p->link)
|
||||||
|
{
|
||||||
|
const cmScoreLoc_t* sl0p;
|
||||||
|
const cmScoreLoc_t* sl1p;
|
||||||
|
|
||||||
|
switch( sm0p->markTypeId )
|
||||||
|
{
|
||||||
|
case kRecdBegScMId:
|
||||||
|
if((sl0p = _cmScFindMarkLoc(p,kRecdEndScMId, sm0p->labelSymId, NULL )) == NULL )
|
||||||
|
rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'record begin' marker at CSV row index %i does not have an associated 'record end' marker.",sm0p->csvRowIdx);
|
||||||
|
else
|
||||||
|
if( sl0p->index <= p->loc[i].index )
|
||||||
|
rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'record end' marker comes before associated with the 'record begin' marker at CSV row index %i.",sm0p->csvRowIdx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kRecdEndScMId:
|
||||||
|
if((sl0p = _cmScFindMarkLoc(p,kRecdBegScMId, sm0p->labelSymId, NULL )) == NULL )
|
||||||
|
rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'record end' marker at CSV row index %i does not have an associated 'record begin' marker.",sm0p->csvRowIdx);
|
||||||
|
else
|
||||||
|
if( sl0p->index > p->loc[i].index )
|
||||||
|
rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'record begin' marker comes after the associated with the 'record end' marker at CSV row index %i.",sm0p->csvRowIdx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kFadeScMId:
|
||||||
|
if((sl0p = _cmScFindMarkLoc(p,kRecdBegScMId, sm0p->labelSymId, NULL )) == NULL )
|
||||||
|
rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'fade' marker at CSV row index %i does not have an associated 'record begin' marker.",sm0p->csvRowIdx);
|
||||||
|
else
|
||||||
|
if((sl1p = _cmScFindMarkLoc(p,kRecdEndScMId, sm0p->labelSymId, NULL )) == NULL )
|
||||||
|
rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'fade' marker at CSV row index %i does not have an associated 'record end' marker.",sm0p->csvRowIdx);
|
||||||
|
else
|
||||||
|
if( sl0p->index > p->loc[i].index || sl1p->index < p->loc[i].index )
|
||||||
|
rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'fade' marker at CSV row index %i is not between it's associated 'record begin' and 'record end' markers.",sm0p->csvRowIdx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kPlayBegScMId:
|
||||||
|
if((sl0p = _cmScFindMarkLoc(p,kPlayEndScMId, sm0p->labelSymId, NULL )) == NULL )
|
||||||
|
rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'play begin' marker at CSV row index %i does not have an associated 'play end' marker.",sm0p->csvRowIdx);
|
||||||
|
else
|
||||||
|
if( sl0p->index <= p->loc[i].index )
|
||||||
|
rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'play end' marker comes before associated with the 'play begin' marker at CSV row index %i.",sm0p->csvRowIdx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kPlayEndScMId:
|
||||||
|
if((sl0p = _cmScFindMarkLoc(p,kPlayBegScMId, sm0p->labelSymId, NULL )) == NULL )
|
||||||
|
rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'play end' marker at CSV row index %i does not have an associated 'play begin' marker.",sm0p->csvRowIdx);
|
||||||
|
else
|
||||||
|
if( sl0p->index > p->loc[i].index )
|
||||||
|
rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'play begin' marker comes after the associated with the 'play end' marker at CSV row index %i.",sm0p->csvRowIdx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cmScRC_t _cmScProcMarkers( cmSc_t* p )
|
||||||
|
{
|
||||||
|
// for each marker in the p->markList
|
||||||
|
// (p->markList is created by _cmScParseMarkers() during CSV file parsing.)
|
||||||
|
cmScMark_t* mp = p->markList;
|
||||||
|
for(; mp!=NULL; mp=mp->link)
|
||||||
|
{
|
||||||
|
assert( mp->scoreIdx < p->cnt );
|
||||||
|
|
||||||
|
// get the score location assoc'd with this marker
|
||||||
|
unsigned locIdx = p->array[ mp->scoreIdx ].locIdx;
|
||||||
|
assert( locIdx < p->locCnt );
|
||||||
|
|
||||||
|
cmScoreLoc_t* slp = p->loc + locIdx;
|
||||||
|
|
||||||
|
// create a cmScoreMarker record.
|
||||||
|
cmScoreMarker_t* smp = cmMemAllocZ(cmScoreMarker_t,1);
|
||||||
|
smp->markTypeId = mp->cmdId;
|
||||||
|
smp->labelSymId = mp->labelSymId;
|
||||||
|
smp->csvRowIdx = mp->csvRowIdx;
|
||||||
|
smp->scoreLocPtr = slp;
|
||||||
|
|
||||||
|
// attach the new scoreMarker record to the assoc'd score loc. recd
|
||||||
|
if( slp->markList == NULL )
|
||||||
|
slp->markList = smp;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmScoreMarker_t* sm0p = slp->markList;
|
||||||
|
while( sm0p->link != NULL )
|
||||||
|
sm0p = sm0p->link;
|
||||||
|
sm0p->link = smp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the id represented by this marker
|
||||||
|
if( _cmScMarkerLabelIndex(p,smp->labelSymId) == cmInvalidIdx )
|
||||||
|
{
|
||||||
|
p->markLabelArray = cmMemResizeP(unsigned,p->markLabelArray,p->markLabelCnt+1);
|
||||||
|
p->markLabelArray[p->markLabelCnt] = smp->labelSymId;
|
||||||
|
p->markLabelCnt += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate the markers
|
||||||
|
return _cmScValidateMarkers(p);
|
||||||
|
}
|
||||||
|
|
||||||
cmScRC_t _cmScParseFile( cmSc_t* p, cmCtx_t* ctx, const cmChar_t* fn )
|
cmScRC_t _cmScParseFile( cmSc_t* p, cmCtx_t* ctx, const cmChar_t* fn )
|
||||||
{
|
{
|
||||||
cmScRC_t rc = kOkScRC;
|
cmScRC_t rc = kOkScRC;
|
||||||
@ -1036,27 +1306,30 @@ cmScRC_t _cmScParseFile( cmSc_t* p, cmCtx_t* ctx, const cmChar_t* fn )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( secs != DBL_MAX )
|
if( rc == kOkScRC )
|
||||||
cur_secs = secs;
|
|
||||||
|
|
||||||
// form the section list
|
|
||||||
if( j > 0 )
|
|
||||||
if((rc = _cmScParseSectionColumn(p,i,j-1,p->sectList)) != kOkScRC )
|
|
||||||
break;
|
|
||||||
|
|
||||||
// the bar lines don't have times so set the time of the bar line to the
|
|
||||||
// time of the first event in the bar.
|
|
||||||
if( barEvtIdx != cmInvalidIdx && secs != DBL_MAX )
|
|
||||||
{
|
{
|
||||||
assert( p->array[ barEvtIdx ].type == kBarEvtScId );
|
if( secs != DBL_MAX )
|
||||||
p->array[ barEvtIdx ].secs = secs;
|
cur_secs = secs;
|
||||||
|
|
||||||
// handle the case where the previous bar had no events
|
// form the section list
|
||||||
// BUG BUG BUG this is a hack which will fail if the first bar does not have events.
|
if( j > 0 )
|
||||||
if( barEvtIdx>=1 && p->array[ barEvtIdx-1].type == kBarEvtScId )
|
if((rc = _cmScParseSectionColumn(p,i,j-1,p->sectList)) != kOkScRC )
|
||||||
p->array[ barEvtIdx-1].secs = secs;
|
break;
|
||||||
|
|
||||||
barEvtIdx = cmInvalidIdx;
|
// the bar lines don't have times so set the time of the bar line to the
|
||||||
|
// time of the first event in the bar.
|
||||||
|
if( barEvtIdx != cmInvalidIdx && secs != DBL_MAX )
|
||||||
|
{
|
||||||
|
assert( p->array[ barEvtIdx ].type == kBarEvtScId );
|
||||||
|
p->array[ barEvtIdx ].secs = secs;
|
||||||
|
|
||||||
|
// handle the case where the previous bar had no events
|
||||||
|
// BUG BUG BUG this is a hack which will fail if the first bar does not have events.
|
||||||
|
if( barEvtIdx>=1 && p->array[ barEvtIdx-1].type == kBarEvtScId )
|
||||||
|
p->array[ barEvtIdx-1].secs = secs;
|
||||||
|
|
||||||
|
barEvtIdx = cmInvalidIdx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1164,6 +1437,9 @@ cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, doubl
|
|||||||
if((rc = _cmScProcSections(p,p->sectList)) != kOkScRC )
|
if((rc = _cmScProcSections(p,p->sectList)) != kOkScRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
|
if((rc = _cmScProcMarkers(p)) != kOkScRC )
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
// load the dynamic reference array
|
// load the dynamic reference array
|
||||||
if( dynRefArray != NULL && dynRefCnt > 0)
|
if( dynRefArray != NULL && dynRefCnt > 0)
|
||||||
{
|
{
|
||||||
@ -1409,6 +1685,30 @@ unsigned cmScoreSetCount( cmScH_t h )
|
|||||||
return p->setCnt;
|
return p->setCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned cmScoreMarkerLabelCount( cmScH_t h )
|
||||||
|
{
|
||||||
|
cmSc_t* p = _cmScHandleToPtr(h);
|
||||||
|
return p->markLabelCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned cmScoreMarkerLabelSymbolId( cmScH_t h, unsigned idx )
|
||||||
|
{
|
||||||
|
cmSc_t* p = _cmScHandleToPtr(h);
|
||||||
|
assert( idx < p->markLabelCnt );
|
||||||
|
return p->markLabelArray[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
const cmScoreMarker_t* cmScoreMarker( cmScH_t h, cmMarkScMId_t markMId, unsigned labelSymId )
|
||||||
|
{
|
||||||
|
cmSc_t* p = _cmScHandleToPtr(h);
|
||||||
|
const cmScoreMarker_t* smp = NULL;
|
||||||
|
if( _cmScFindMarkLoc(p, markMId, labelSymId, &smp ) == NULL )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return smp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cmScRC_t cmScoreSeqNotify( cmScH_t h )
|
cmScRC_t cmScoreSeqNotify( cmScH_t h )
|
||||||
{
|
{
|
||||||
cmScRC_t rc = kOkScRC;
|
cmScRC_t rc = kOkScRC;
|
||||||
@ -1502,7 +1802,7 @@ void _cmScPerfSortTimes( unsigned *v, unsigned n )
|
|||||||
fl = true;
|
fl = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
--n;
|
--n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1568,13 +1868,13 @@ bool _cmScPerfEven(cmSc_t* p, cmScoreSet_t* stp, bool printMissFl)
|
|||||||
if(printFl)
|
if(printFl)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
for(i=0; i<stp->eleCnt; ++i)
|
for(i=0; i<stp->eleCnt; ++i)
|
||||||
{
|
{
|
||||||
printf("%i %i ",i,v[i]);
|
printf("%i %i ",i,v[i]);
|
||||||
if( i > 0 )
|
if( i > 0 )
|
||||||
printf("%i ", d[i-1]);
|
printf("%i ", d[i-1]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
printf("%s EVENESS:%f\n",sortFl?"SORTED ":"",stp->value);
|
printf("%s EVENESS:%f\n",sortFl?"SORTED ":"",stp->value);
|
||||||
}
|
}
|
||||||
@ -1955,6 +2255,214 @@ void cmScorePrint( cmScH_t h, cmRpt_t* rpt )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* scoreFn )
|
||||||
|
{
|
||||||
|
cmScRC_t rc = kOkScRC;
|
||||||
|
cmMidiFileH_t mfH = cmMidiFileNullHandle;
|
||||||
|
cmCsvH_t csvH = cmCsvNullHandle;
|
||||||
|
cmErr_t err;
|
||||||
|
cmChar_t* titles[] = {"id","trk","evt","opcode","dticks","micros","status","meta","ch","d0","d1","arg0","arg1","bar","skip","even","grace","tempo","t frac","dyn","section","remark", NULL };
|
||||||
|
|
||||||
|
cmErrSetup(&err,&ctx->rpt,"MIDI to Score");
|
||||||
|
|
||||||
|
if( cmMidiFileOpen(midiFn, &mfH, ctx ) != kOkMfRC )
|
||||||
|
return cmErrMsg(&err,kMidiFileFailScRC,"Unable to open the MIDI file '%s'.",midiFn);
|
||||||
|
|
||||||
|
if( cmCsvInitialize(&csvH,ctx) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Unable to initialize the CSV file: '%s'.",scoreFn);
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the track message 'dtick' field to delta-microseconds.
|
||||||
|
cmMidiFileTickToMicros(mfH);
|
||||||
|
|
||||||
|
|
||||||
|
unsigned msgCnt = cmMidiFileMsgCount(mfH);
|
||||||
|
unsigned i;
|
||||||
|
const cmMidiTrackMsg_t** tmpp = cmMidiFileMsgArray(mfH);
|
||||||
|
double acc_secs = 0;
|
||||||
|
unsigned lexTId = 0;
|
||||||
|
cmCsvCell_t* cp = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if( cmCsvAppendRow(csvH, &cp, cmCsvInsertSymText(csvH,titles[0]), kStrCsvTFl, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'id' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=1; titles[i]!=NULL; ++i)
|
||||||
|
{
|
||||||
|
if( cmCsvInsertTextColAfter(csvH, cp, &cp, titles[i], lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting column index '%i' label in '%s'.",i,cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for(i=0; i<msgCnt; ++i)
|
||||||
|
{
|
||||||
|
const cmMidiTrackMsg_t* tmp = tmpp[i];
|
||||||
|
const cmChar_t* opStr = NULL;
|
||||||
|
unsigned midiCh = 0;
|
||||||
|
unsigned d0 = 0;
|
||||||
|
unsigned d1 = 0;
|
||||||
|
unsigned metaId = 0;
|
||||||
|
double dsecs = (double)tmp->dtick / 1000000.0;
|
||||||
|
|
||||||
|
acc_secs += dsecs;
|
||||||
|
|
||||||
|
if( tmp->status == kMetaStId )
|
||||||
|
{
|
||||||
|
opStr = cmMidiMetaStatusToLabel(tmp->metaId);
|
||||||
|
metaId = tmp->metaId;
|
||||||
|
|
||||||
|
switch( tmp->metaId )
|
||||||
|
{
|
||||||
|
case kTempoMdId:
|
||||||
|
d0 = tmp->u.iVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
opStr = cmMidiStatusToLabel(tmp->status);
|
||||||
|
if( cmMidiIsChStatus( tmp->status ) )
|
||||||
|
{
|
||||||
|
midiCh = tmp->u.chMsgPtr->ch;
|
||||||
|
d0 = tmp->u.chMsgPtr->d0;
|
||||||
|
d1 = tmp->u.chMsgPtr->d1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cp = NULL;
|
||||||
|
|
||||||
|
// skip note-off messages
|
||||||
|
if( tmp->status == kNoteOffMdId )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( cmCsvAppendRow(csvH, &cp, cmCsvInsertSymUInt(csvH,i), kIntCsvTFl, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'id' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->trkIdx, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'trk' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmCsvInsertUIntColAfter(csvH, cp, &cp, 0, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'evt' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmCsvInsertTextColAfter(csvH, cp, &cp, opStr, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'opcode' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmCsvInsertDoubleColAfter(csvH, cp, &cp, dsecs, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'dticks' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmCsvInsertDoubleColAfter(csvH, cp, &cp, acc_secs, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'micros' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmCsvInsertHexColAfter(csvH, cp, &cp, tmp->status, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'status' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmCsvInsertUIntColAfter(csvH, cp, &cp, metaId, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'meta' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmCsvInsertUIntColAfter(csvH, cp, &cp, midiCh, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'ch' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmCsvInsertUIntColAfter(csvH, cp, &cp, d0, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'd0' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmCsvInsertUIntColAfter(csvH, cp, &cp, d1, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'd1' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( tmp->status )
|
||||||
|
{
|
||||||
|
case kNoteOnMdId:
|
||||||
|
if( cmCsvInsertTextColAfter(csvH, cp, &cp, cmMidiToSciPitch(tmp->u.chMsgPtr->d0,NULL,0), lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'opcode' column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
case kMetaStId:
|
||||||
|
switch( tmp->metaId )
|
||||||
|
{
|
||||||
|
case kTimeSigMdId:
|
||||||
|
if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->u.timeSigPtr->num, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting time sign. numerator column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->u.timeSigPtr->den, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting time sign. denominator column in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kTempoMdId:
|
||||||
|
if( cmCsvInsertUIntColAfter(csvH, cp, &cp, 60000000/tmp->u.iVal, lexTId ) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"Error inserting 'tempo' in '%s'.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmCsvWrite(csvH,scoreFn) != kOkCsvRC )
|
||||||
|
{
|
||||||
|
cmErrMsg(&err,kCsvFailScRC,"The score output file '%s' could not be written.",cmStringNullGuard(scoreFn));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
cmMidiFileClose(&mfH);
|
||||||
|
cmCsvFinalize(&csvH);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
|
void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
|
||||||
{
|
{
|
||||||
cmScH_t h = cmScNullHandle;
|
cmScH_t h = cmScNullHandle;
|
||||||
|
@ -12,8 +12,8 @@ extern "C" {
|
|||||||
kSyntaxErrScRC,
|
kSyntaxErrScRC,
|
||||||
kInvalidIdxScRC,
|
kInvalidIdxScRC,
|
||||||
kTimeLineFailScRC,
|
kTimeLineFailScRC,
|
||||||
kInvalidDynRefCntScRC
|
kInvalidDynRefCntScRC,
|
||||||
|
kMidiFileFailScRC
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -36,12 +36,12 @@ extern "C" {
|
|||||||
// Flags used by cmScoreEvt_t.flags
|
// Flags used by cmScoreEvt_t.flags
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kEvenScFl = 0x01, // This note is marked for evenness measurement
|
kEvenScFl = 0x001, // This note is marked for evenness measurement
|
||||||
kDynScFl = 0x02, // This note is marked for dynamics measurement
|
kDynScFl = 0x002, // This note is marked for dynamics measurement
|
||||||
kTempoScFl = 0x04, // This note is marked for tempo measurement
|
kTempoScFl = 0x004, // This note is marked for tempo measurement
|
||||||
kSkipScFl = 0x08, // This isn't a real event (e.g. tied note) skip over it
|
kSkipScFl = 0x008, // This isn't a real event (e.g. tied note) skip over it
|
||||||
kGraceScFl = 0x10, // This is a grace note
|
kGraceScFl = 0x010, // This is a grace note
|
||||||
kInvalidScFl = 0x20 // This note has a calculated time
|
kInvalidScFl = 0x020 // This note has a calculated time
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -104,6 +104,25 @@ extern "C" {
|
|||||||
struct cmScoreSet_str* llink; // cmScoreLoc_t setList link
|
struct cmScoreSet_str* llink; // cmScoreLoc_t setList link
|
||||||
} cmScoreSet_t;
|
} cmScoreSet_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
kInvalidScMId,
|
||||||
|
kRecdBegScMId,
|
||||||
|
kRecdEndScMId,
|
||||||
|
kFadeScMId,
|
||||||
|
kPlayBegScMId,
|
||||||
|
kPlayEndScMId
|
||||||
|
} cmMarkScMId_t;
|
||||||
|
|
||||||
|
// score markers
|
||||||
|
typedef struct cmScoreMarker_str
|
||||||
|
{
|
||||||
|
cmMarkScMId_t markTypeId; // marker type
|
||||||
|
unsigned labelSymId; // marker label
|
||||||
|
struct cmScoreLoc_str* scoreLocPtr; // score location of the marker
|
||||||
|
unsigned csvRowIdx; // score CSV file line assoc'd w/ this marker
|
||||||
|
struct cmScoreMarker_str* link; // cmScoreLoc_t.markList links
|
||||||
|
} cmScoreMarker_t;
|
||||||
|
|
||||||
// All events which are simultaneous are collected into a single
|
// All events which are simultaneous are collected into a single
|
||||||
// cmScoreLoc_t record.
|
// cmScoreLoc_t record.
|
||||||
@ -116,6 +135,7 @@ extern "C" {
|
|||||||
unsigned barNumb; // Bar number this event is contained by.
|
unsigned barNumb; // Bar number this event is contained by.
|
||||||
cmScoreSet_t* setList; // Set's which end on this time location (linked through cmScoreSet_t.llink)
|
cmScoreSet_t* setList; // Set's which end on this time location (linked through cmScoreSet_t.llink)
|
||||||
cmScoreSection_t* begSectPtr; // NULL if this location does not start a section
|
cmScoreSection_t* begSectPtr; // NULL if this location does not start a section
|
||||||
|
cmScoreMarker_t* markList; // List of markers assigned to this location
|
||||||
} cmScoreLoc_t;
|
} cmScoreLoc_t;
|
||||||
|
|
||||||
typedef void (*cmScCb_t)( void* arg, const void* data, unsigned byteCnt );
|
typedef void (*cmScCb_t)( void* arg, const void* data, unsigned byteCnt );
|
||||||
@ -170,6 +190,10 @@ extern "C" {
|
|||||||
// Return the count of sets.
|
// Return the count of sets.
|
||||||
unsigned cmScoreSetCount( cmScH_t h );
|
unsigned cmScoreSetCount( cmScH_t h );
|
||||||
|
|
||||||
|
unsigned cmScoreMarkerLabelCount( cmScH_t h );
|
||||||
|
unsigned cmScoreMarkerLabelSymbolId( cmScH_t h, unsigned idx );
|
||||||
|
const cmScoreMarker_t* cmScoreMarker( cmScH_t h, cmMarkScMId_t markMId, unsigned labelSymId );
|
||||||
|
|
||||||
// Make callbacks for all events in the score. The callbacks
|
// Make callbacks for all events in the score. The callbacks
|
||||||
// contain cmScMsg_t records serialized as a byte stream.
|
// contain cmScMsg_t records serialized as a byte stream.
|
||||||
// Use cmScoreDecode() to convert the byte string to a
|
// Use cmScoreDecode() to convert the byte string to a
|
||||||
@ -235,6 +259,9 @@ extern "C" {
|
|||||||
|
|
||||||
void cmScorePrint( cmScH_t h, cmRpt_t* rpt );
|
void cmScorePrint( cmScH_t h, cmRpt_t* rpt );
|
||||||
|
|
||||||
|
// Generate a new score file from a MIDI file.
|
||||||
|
cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* scoreFn );
|
||||||
|
|
||||||
void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn );
|
void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn );
|
||||||
|
|
||||||
|
|
||||||
|
58
cmCsv.c
58
cmCsv.c
@ -729,6 +729,20 @@ unsigned cmCsvInsertSymUInt( cmCsvH_t h, unsigned v )
|
|||||||
return cmInvalidId;
|
return cmInvalidId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned cmCsvInsertSymHex( cmCsvH_t h, unsigned v )
|
||||||
|
{
|
||||||
|
const char* fmt = "0x%x";
|
||||||
|
unsigned n = snprintf(NULL,0,fmt,v)+1;
|
||||||
|
char buf[n];
|
||||||
|
|
||||||
|
buf[0]= 0;
|
||||||
|
if( snprintf(buf,n,fmt,v) == n-1 )
|
||||||
|
return cmCsvInsertSymText(h,buf);
|
||||||
|
|
||||||
|
_cmCsvError(_cmCsvHandleToPtr(h),kDataCvtErrCsvRC,"The unsigned int 0x%x could not be converted to text.",v);
|
||||||
|
return cmInvalidId;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned cmCsvInsertSymFloat( cmCsvH_t h, float v )
|
unsigned cmCsvInsertSymFloat( cmCsvH_t h, float v )
|
||||||
{
|
{
|
||||||
const char* fmt = "%f";
|
const char* fmt = "%f";
|
||||||
@ -812,6 +826,24 @@ cmCsvRC_t cmCsvSetCellUInt( cmCsvH_t h, unsigned row, unsigned col, unsigned
|
|||||||
return kOkCsvRC;
|
return kOkCsvRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmCsvRC_t cmCsvSetCellHex( cmCsvH_t h, unsigned row, unsigned col, unsigned v )
|
||||||
|
{
|
||||||
|
cmCsvCell_t* cp;
|
||||||
|
unsigned symId;
|
||||||
|
|
||||||
|
if((cp = _cmCsvCellPtr(h,row,col)) == NULL )
|
||||||
|
return cmErrLastRC(&_cmCsvHandleToPtr(h)->err);
|
||||||
|
|
||||||
|
if((symId = cmCsvInsertSymHex(h,v)) == cmInvalidId )
|
||||||
|
return cmErrLastRC(&_cmCsvHandleToPtr(h)->err);
|
||||||
|
|
||||||
|
cp->symId = symId;
|
||||||
|
cp->flags &= !kTypeTMask;
|
||||||
|
cp->flags |= kIntCsvTFl;
|
||||||
|
|
||||||
|
return kOkCsvRC;
|
||||||
|
}
|
||||||
|
|
||||||
cmCsvRC_t cmCsvSetCellFloat( cmCsvH_t h, unsigned row, unsigned col, float v )
|
cmCsvRC_t cmCsvSetCellFloat( cmCsvH_t h, unsigned row, unsigned col, float v )
|
||||||
{
|
{
|
||||||
cmCsvCell_t* cp;
|
cmCsvCell_t* cp;
|
||||||
@ -985,7 +1017,7 @@ cmCsvRC_t cmCsvInsertTextColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCs
|
|||||||
cmCsvCell_t* ncp;
|
cmCsvCell_t* ncp;
|
||||||
|
|
||||||
if( cellPtrPtr != NULL )
|
if( cellPtrPtr != NULL )
|
||||||
cellPtrPtr = NULL;
|
*cellPtrPtr = NULL;
|
||||||
|
|
||||||
if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC )
|
if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC )
|
||||||
if((rc = cmCsvSetCellText(h, ncp->row, ncp->col, text )) == kOkCsvRC )
|
if((rc = cmCsvSetCellText(h, ncp->row, ncp->col, text )) == kOkCsvRC )
|
||||||
@ -1001,7 +1033,7 @@ cmCsvRC_t cmCsvInsertIntColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCs
|
|||||||
cmCsvCell_t* ncp;
|
cmCsvCell_t* ncp;
|
||||||
|
|
||||||
if( cellPtrPtr != NULL )
|
if( cellPtrPtr != NULL )
|
||||||
cellPtrPtr = NULL;
|
*cellPtrPtr = NULL;
|
||||||
|
|
||||||
if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC )
|
if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC )
|
||||||
if((rc = cmCsvSetCellInt(h, ncp->row, ncp->col, val )) == kOkCsvRC )
|
if((rc = cmCsvSetCellInt(h, ncp->row, ncp->col, val )) == kOkCsvRC )
|
||||||
@ -1017,7 +1049,7 @@ cmCsvRC_t cmCsvInsertUIntColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCs
|
|||||||
cmCsvCell_t* ncp;
|
cmCsvCell_t* ncp;
|
||||||
|
|
||||||
if( cellPtrPtr != NULL )
|
if( cellPtrPtr != NULL )
|
||||||
cellPtrPtr = NULL;
|
*cellPtrPtr = NULL;
|
||||||
|
|
||||||
if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC )
|
if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC )
|
||||||
if((rc = cmCsvSetCellUInt(h, ncp->row, ncp->col, val )) == kOkCsvRC )
|
if((rc = cmCsvSetCellUInt(h, ncp->row, ncp->col, val )) == kOkCsvRC )
|
||||||
@ -1027,13 +1059,29 @@ cmCsvRC_t cmCsvInsertUIntColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCs
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmCsvRC_t cmCsvInsertHexColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, unsigned val, unsigned lexTId )
|
||||||
|
{
|
||||||
|
cmCsvRC_t rc;
|
||||||
|
cmCsvCell_t* ncp;
|
||||||
|
|
||||||
|
if( cellPtrPtr != NULL )
|
||||||
|
*cellPtrPtr = NULL;
|
||||||
|
|
||||||
|
if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC )
|
||||||
|
if((rc = cmCsvSetCellHex(h, ncp->row, ncp->col, val )) == kOkCsvRC )
|
||||||
|
if( cellPtrPtr != NULL )
|
||||||
|
*cellPtrPtr = ncp;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
cmCsvRC_t cmCsvInsertFloatColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, float val, unsigned lexTId )
|
cmCsvRC_t cmCsvInsertFloatColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, float val, unsigned lexTId )
|
||||||
{
|
{
|
||||||
cmCsvRC_t rc;
|
cmCsvRC_t rc;
|
||||||
cmCsvCell_t* ncp;
|
cmCsvCell_t* ncp;
|
||||||
|
|
||||||
if( cellPtrPtr != NULL )
|
if( cellPtrPtr != NULL )
|
||||||
cellPtrPtr = NULL;
|
*cellPtrPtr = NULL;
|
||||||
|
|
||||||
if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC )
|
if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC )
|
||||||
if((rc = cmCsvSetCellFloat(h, ncp->row, ncp->col, val )) == kOkCsvRC )
|
if((rc = cmCsvSetCellFloat(h, ncp->row, ncp->col, val )) == kOkCsvRC )
|
||||||
@ -1049,7 +1097,7 @@ cmCsvRC_t cmCsvInsertDoubleColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCs
|
|||||||
cmCsvCell_t* ncp;
|
cmCsvCell_t* ncp;
|
||||||
|
|
||||||
if( cellPtrPtr != NULL )
|
if( cellPtrPtr != NULL )
|
||||||
cellPtrPtr = NULL;
|
*cellPtrPtr = NULL;
|
||||||
|
|
||||||
if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC )
|
if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC )
|
||||||
if((rc = cmCsvSetCellDouble(h, ncp->row, ncp->col, val )) == kOkCsvRC )
|
if((rc = cmCsvSetCellDouble(h, ncp->row, ncp->col, val )) == kOkCsvRC )
|
||||||
|
4
cmCsv.h
4
cmCsv.h
@ -109,13 +109,16 @@ extern "C" {
|
|||||||
unsigned cmCsvInsertSymText( cmCsvH_t h, const char* text );
|
unsigned cmCsvInsertSymText( cmCsvH_t h, const char* text );
|
||||||
unsigned cmCsvInsertSymInt( cmCsvH_t h, int v );
|
unsigned cmCsvInsertSymInt( cmCsvH_t h, int v );
|
||||||
unsigned cmCsvInsertSymUInt( cmCsvH_t h, unsigned v );
|
unsigned cmCsvInsertSymUInt( cmCsvH_t h, unsigned v );
|
||||||
|
unsigned cmCsvInsertSymHex( cmCsvH_t h, unsigned v );
|
||||||
unsigned cmCsvInsertSymFloat( cmCsvH_t h, float v );
|
unsigned cmCsvInsertSymFloat( cmCsvH_t h, float v );
|
||||||
unsigned cmCsvInsertSymDouble( cmCsvH_t h, double v );
|
unsigned cmCsvInsertSymDouble( cmCsvH_t h, double v );
|
||||||
|
|
||||||
|
|
||||||
// Set the value associated with a cell.
|
// Set the value associated with a cell.
|
||||||
cmCsvRC_t cmCsvSetCellText( cmCsvH_t h, unsigned row, unsigned col, const char* text );
|
cmCsvRC_t cmCsvSetCellText( cmCsvH_t h, unsigned row, unsigned col, const char* text );
|
||||||
cmCsvRC_t cmCsvSetCellInt( cmCsvH_t h, unsigned row, unsigned col, int v );
|
cmCsvRC_t cmCsvSetCellInt( cmCsvH_t h, unsigned row, unsigned col, int v );
|
||||||
cmCsvRC_t cmCsvSetCellUInt( cmCsvH_t h, unsigned row, unsigned col, unsigned v );
|
cmCsvRC_t cmCsvSetCellUInt( cmCsvH_t h, unsigned row, unsigned col, unsigned v );
|
||||||
|
cmCsvRC_t cmCsvSetCellHex( cmCsvH_t h, unsigned row, unsigned col, unsigned v );
|
||||||
cmCsvRC_t cmCsvSetCellFloat( cmCsvH_t h, unsigned row, unsigned col, float v );
|
cmCsvRC_t cmCsvSetCellFloat( cmCsvH_t h, unsigned row, unsigned col, float v );
|
||||||
cmCsvRC_t cmCsvSetCellDouble( cmCsvH_t h, unsigned row, unsigned col, double v );
|
cmCsvRC_t cmCsvSetCellDouble( cmCsvH_t h, unsigned row, unsigned col, double v );
|
||||||
|
|
||||||
@ -134,6 +137,7 @@ extern "C" {
|
|||||||
cmCsvRC_t cmCsvInsertTextColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, const char* val, unsigned lexTId );
|
cmCsvRC_t cmCsvInsertTextColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, const char* val, unsigned lexTId );
|
||||||
cmCsvRC_t cmCsvInsertIntColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, int val, unsigned lexTId );
|
cmCsvRC_t cmCsvInsertIntColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, int val, unsigned lexTId );
|
||||||
cmCsvRC_t cmCsvInsertUIntColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, unsigned val, unsigned lexTId );
|
cmCsvRC_t cmCsvInsertUIntColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, unsigned val, unsigned lexTId );
|
||||||
|
cmCsvRC_t cmCsvInsertHexColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, unsigned val, unsigned lexTId );
|
||||||
cmCsvRC_t cmCsvInsertFloatColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, float val, unsigned lexTId );
|
cmCsvRC_t cmCsvInsertFloatColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, float val, unsigned lexTId );
|
||||||
cmCsvRC_t cmCsvInsertDoubleColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, double val, unsigned lexTId );
|
cmCsvRC_t cmCsvInsertDoubleColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, double val, unsigned lexTId );
|
||||||
|
|
||||||
|
600
cmData.h
600
cmData.h
@ -5,129 +5,6 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
kOkDtRC = cmOkRC,
|
|
||||||
kCvtErrDtRC,
|
|
||||||
kVarArgErrDtRC,
|
|
||||||
kMissingFieldDtRC,
|
|
||||||
kEolDtRC
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
kInvalidDtChar = 0xff,
|
|
||||||
kInvalidDtUChar = 0xff,
|
|
||||||
kInvalidDtShort = 0xffff,
|
|
||||||
kInvalidDtUShort = 0xffff,
|
|
||||||
kInvalidDtInt = 0xffffffff,
|
|
||||||
kInvalidDtUInt = 0xffffffff,
|
|
||||||
kInvalidDtLong = 0xffffffff,
|
|
||||||
kInvalidDtULong = 0xffffffff,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
kInvalidDtId,
|
|
||||||
|
|
||||||
kMinValDtId,
|
|
||||||
|
|
||||||
kNullDtId = kMinValDtId,
|
|
||||||
kUCharDtId,
|
|
||||||
kCharDtId,
|
|
||||||
kUShortDtId,
|
|
||||||
kShortDtId,
|
|
||||||
kUIntDtId,
|
|
||||||
kIntDtId,
|
|
||||||
kULongDtId,
|
|
||||||
kLongDtId,
|
|
||||||
kFloatDtId,
|
|
||||||
kDoubleDtId,
|
|
||||||
|
|
||||||
kStrDtId,
|
|
||||||
kConstStrDtId,
|
|
||||||
kMaxValDtId = kConstStrDtId,
|
|
||||||
|
|
||||||
kMinPtrDtId,
|
|
||||||
kUCharPtrDtId = kMinPtrDtId, // cnt=array element count
|
|
||||||
kCharPtrDtId,
|
|
||||||
kUShortPtrDtId,
|
|
||||||
kShortPtrDtId,
|
|
||||||
kUIntPtrDtId,
|
|
||||||
kIntPtrDtId,
|
|
||||||
kULongPtrDtId,
|
|
||||||
kLongPtrDtId,
|
|
||||||
kFloatPtrDtId,
|
|
||||||
kDoublePtrDtId,
|
|
||||||
kVoidPtrDtId,
|
|
||||||
kMaxPtrDtId = kVoidPtrDtId,
|
|
||||||
|
|
||||||
kMinStructDtId,
|
|
||||||
kListDtId = kMinStructDtId, // children nodes are array elements, cnt=child count
|
|
||||||
kPairDtId, // key/value pairs, cnt=2, first child is key, second is value
|
|
||||||
kRecordDtId, // children nodes are pairs, cnt=pair count
|
|
||||||
kMaxStructDtId,
|
|
||||||
|
|
||||||
kOptArgDtFl = 0x80000000
|
|
||||||
} cmDataFmtId_t;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
kDynObjDtFl = 0x01, // object was dynamically allocated
|
|
||||||
kDynPtrDtFl = 0x02 // ptr array was dynamically allocated
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct cmData_str
|
|
||||||
{
|
|
||||||
cmDataFmtId_t tid; // data format id
|
|
||||||
unsigned flags; //
|
|
||||||
struct cmData_str* parent; // this childs parent
|
|
||||||
struct cmData_str* sibling; // this childs left sibling
|
|
||||||
unsigned cnt; // array ele count
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
unsigned char uc;
|
|
||||||
short s;
|
|
||||||
unsigned short us;
|
|
||||||
int i;
|
|
||||||
unsigned int ui;
|
|
||||||
long l;
|
|
||||||
unsigned long ul;
|
|
||||||
float f;
|
|
||||||
double d;
|
|
||||||
|
|
||||||
cmChar_t* z;
|
|
||||||
const cmChar_t* cz;
|
|
||||||
|
|
||||||
void* vp;
|
|
||||||
|
|
||||||
char* cp;
|
|
||||||
unsigned char* ucp;
|
|
||||||
short* sp;
|
|
||||||
unsigned short* usp;
|
|
||||||
int* ip;
|
|
||||||
unsigned int* uip;
|
|
||||||
long* lp;
|
|
||||||
unsigned long* ulp;
|
|
||||||
float* fp;
|
|
||||||
double* dp;
|
|
||||||
|
|
||||||
|
|
||||||
struct cmData_str* child; // first child (array,record,pair)
|
|
||||||
} u;
|
|
||||||
|
|
||||||
} cmData_t;
|
|
||||||
|
|
||||||
typedef unsigned cmDtRC_t;
|
|
||||||
|
|
||||||
extern cmData_t cmDataNull;
|
|
||||||
|
|
||||||
bool cmDataIsValue( const cmData_t* p );
|
|
||||||
bool cmDataIsPtr( const cmData_t* p );
|
|
||||||
bool cmDataIsStruct( const cmData_t* p ); // is a pair,list or record
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO:
|
TODO:
|
||||||
0) Figure out a error handling scheme that does not rely on
|
0) Figure out a error handling scheme that does not rely on
|
||||||
@ -144,7 +21,7 @@ extern "C" {
|
|||||||
the array space. This will allow dynamic allocattion to
|
the array space. This will allow dynamic allocattion to
|
||||||
occur at runtime. Make var args functions for list and
|
occur at runtime. Make var args functions for list and
|
||||||
record objects which also take this flag.
|
record objects which also take this flag.
|
||||||
Where ever a function may be implemented using
|
Whereever a function may be implemented using
|
||||||
static/dynamic allocation this flag should be present.
|
static/dynamic allocation this flag should be present.
|
||||||
(e.g. string allocation for pair labels)
|
(e.g. string allocation for pair labels)
|
||||||
This choice is common enough that it may be worth
|
This choice is common enough that it may be worth
|
||||||
@ -170,40 +47,227 @@ extern "C" {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool canConvertType( cmDataFmtId_t srcId, cmDataFmtId_t dstId );
|
enum
|
||||||
bool willTruncate( cmDataFmtId_t srcId, cmDataFmtId_t dstId );
|
{
|
||||||
bool canConvertObj( const cmData_t* srcObj, cmData_t* dstObj );
|
kOkDtRC = cmOkRC,
|
||||||
bool willTruncateObj(const cmData_t* srcObj, cmData_t* dstObj );
|
kAssertErrDtRC,
|
||||||
|
kConstErrDtRC,
|
||||||
|
kCvtErrDtRC,
|
||||||
|
kInvalidContDtRC,
|
||||||
|
kInvalidTypeDtRC,
|
||||||
|
kEolDtRC
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef unsigned cmDtRC_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
kInvalidTypeDtId,// 0
|
||||||
|
kNullDtId, // 1 the data object exists but it has no data
|
||||||
|
kUCharDtId, // 2
|
||||||
|
kCharDtId, // 3
|
||||||
|
kUShortDtId, // 4
|
||||||
|
kShortDtId, // 5
|
||||||
|
kUIntDtId, // 6
|
||||||
|
kIntDtId, // 7
|
||||||
|
kULongDtId, // 8
|
||||||
|
kLongDtId, // 9
|
||||||
|
kFloatDtId, // 10
|
||||||
|
kDoubleDtId, // 11
|
||||||
|
kStrDtId, // 12 zero terminated string
|
||||||
|
kBlobDtId, // 13 application defined raw memory object
|
||||||
|
kStructDtId // 14 node is a pair,list, or recd
|
||||||
|
} cmDataTypeId_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
kInvalidCntDtId, // 0
|
||||||
|
kScalarDtId, // 1
|
||||||
|
kArrayDtId, // 2
|
||||||
|
kPairDtId, // 3
|
||||||
|
kListDtId, // 4
|
||||||
|
kRecordDtId // 5
|
||||||
|
} cmDataContainerId_t;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kNoFlagsDtFl = 0x00,
|
||||||
|
|
||||||
|
// Indicate that the memory used by the data object
|
||||||
|
// was dynamically allocated and should be released
|
||||||
|
// by cmDataFree().
|
||||||
|
kFreeObjDtFl = 0x01,
|
||||||
|
|
||||||
|
// Indicate that the memory used by strings, blobs
|
||||||
|
// and arrays should be freed by cmDataFree().
|
||||||
|
kFreeValueDtFl = 0x02,
|
||||||
|
|
||||||
|
// Indicate that the value of the object cannot be changed.
|
||||||
|
// (but the object could be reassigned as a new type).
|
||||||
|
kConstValueDtFl = 0x04,
|
||||||
|
|
||||||
|
// Indicate that the type of the object cannot be changed.
|
||||||
|
// (but the value may be changed).
|
||||||
|
kConstObjDtFl = 0x08,
|
||||||
|
|
||||||
|
// Indicate that the array or string should not be
|
||||||
|
// internally reallocated but rather the source pointer
|
||||||
|
// should be taken as the new value of the object.
|
||||||
|
kNoCopyDtFl = 0x10,
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct cmData_str
|
||||||
|
{
|
||||||
|
cmDataTypeId_t tid; // data format id
|
||||||
|
cmDataContainerId_t cid; // container id
|
||||||
|
unsigned flags; //
|
||||||
|
struct cmData_str* parent; // this childs parent
|
||||||
|
struct cmData_str* sibling; // this childs left sibling
|
||||||
|
unsigned cnt; // byte cnt for strings/blobs and ele count for arrays
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
unsigned char uc;
|
||||||
|
short s;
|
||||||
|
unsigned short us;
|
||||||
|
int i;
|
||||||
|
unsigned int ui;
|
||||||
|
long l;
|
||||||
|
unsigned long ul;
|
||||||
|
float f;
|
||||||
|
double d;
|
||||||
|
|
||||||
|
cmChar_t* z;
|
||||||
|
|
||||||
|
void* vp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
char* cp;
|
||||||
|
unsigned char* ucp;
|
||||||
|
short* sp;
|
||||||
|
unsigned short* usp;
|
||||||
|
int* ip;
|
||||||
|
unsigned int* uip;
|
||||||
|
long* lp;
|
||||||
|
unsigned long* ulp;
|
||||||
|
float* fp;
|
||||||
|
double* dp;
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct cmData_str* child; // first child (list,record,pair)
|
||||||
|
} u;
|
||||||
|
|
||||||
|
} cmData_t;
|
||||||
|
|
||||||
|
extern cmData_t cmDataNull;
|
||||||
|
|
||||||
|
const cmChar_t* cmDataTypeToLabel( cmDataTypeId_t tid );
|
||||||
|
cmDataTypeId_t cmDataLabelToType( const cmChar_t* typeLabelStr );
|
||||||
|
|
||||||
|
// Returns 1 for kStrDtId.
|
||||||
|
// Returns cmInvalidCnt if tid is not recognized.
|
||||||
|
unsigned dmDataByteWidth( cmDataTypeId_t tid );
|
||||||
|
|
||||||
|
const cmChar_t* cmDataContainerIdToLabel( cmDataContainerId_t tid );
|
||||||
|
cmDataContainerId_t cmDataLabelToContainerId( const cmChar_t* contLabelStr );
|
||||||
|
|
||||||
|
bool cmDataIsConstObj( const cmData_t* d );
|
||||||
|
void cmDataEnableConstObj( cmData_t* d, bool enaFl );
|
||||||
|
|
||||||
|
bool cmDataIsConstValue( const cmData_t* d );
|
||||||
|
void cmDataEnableConstValue( cmData_t* d, bool enaFl );
|
||||||
|
|
||||||
|
bool cmDataIsFreeValue( const cmData_t* d );
|
||||||
|
void cmDataEnableFreeValue( cmData_t* d, bool enaFl );
|
||||||
|
|
||||||
|
// Returns true if this is a scalar or array node.
|
||||||
|
bool cmDataIsLeaf( const cmData_t* d);
|
||||||
|
|
||||||
|
// Return true if this is NOT a scalar or array node.
|
||||||
|
bool cmDataIsStruct( const cmData_t* d );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Get the value of an object without conversion.
|
//----------------------------------------------------------------------------
|
||||||
// The data type id must match the return type or the
|
// Scalar related functions
|
||||||
// conversion must be an automatic C conversion.
|
//
|
||||||
char cmDataChar( const cmData_t* p );
|
|
||||||
unsigned char cmDataUChar( const cmData_t* p );
|
|
||||||
short cmDataShort( const cmData_t* p );
|
|
||||||
unsigned short cmDataUShort( const cmData_t* p );
|
|
||||||
int cmDataInt( const cmData_t* p );
|
|
||||||
unsigned int cmDataUInt( const cmData_t* p );
|
|
||||||
long cmDataLong( const cmData_t* p );
|
|
||||||
unsigned long cmDataULong( const cmData_t* p );
|
|
||||||
float cmDataFloat( const cmData_t* p );
|
|
||||||
double cmDataDouble( const cmData_t* p );
|
|
||||||
cmChar_t* cmDataStr( const cmData_t* p );
|
|
||||||
const cmChar_t* cmDataConstStr( const cmData_t* p );
|
|
||||||
void* cmDataVoidPtr( const cmData_t* p );
|
|
||||||
char* cmDataCharPtr( const cmData_t* p );
|
|
||||||
unsigned char* cmDataUCharPtr( const cmData_t* p );
|
|
||||||
short* cmDataShortPtr( const cmData_t* p );
|
|
||||||
unsigned short* cmDataUShortPtr( const cmData_t* p );
|
|
||||||
int* cmDataIntPtr( const cmData_t* p );
|
|
||||||
unsigned int* cmDataUIntPtr( const cmData_t* p );
|
|
||||||
long* cmDataLongPtr( const cmData_t* p );
|
|
||||||
unsigned long* cmDataULongPtr( const cmData_t* p );
|
|
||||||
float* cmDataFloatPtr( const cmData_t* p );
|
|
||||||
double* cmDataDoublePtr( const cmData_t* p );
|
|
||||||
|
|
||||||
|
// Dynamically allocate a scalar object and set it's value.
|
||||||
|
// The 'flags' argument may include kConstValueDtFl and kConstObjDtFl.
|
||||||
|
// The string and blob constructors may also use the
|
||||||
|
// kNoCopyDtFl and the kFreeValueDtFl.
|
||||||
|
|
||||||
|
// Generic:
|
||||||
|
// 'byteCnt' is ignored for all types other than strings and blobs.
|
||||||
|
cmDtRC_t cmDataNewScalar( cmData_t* parent, cmDataTypeId_t tid, unsigned flags, void* vp, unsigned byteCnt, cmData_t** ref );
|
||||||
|
|
||||||
|
// Type specific
|
||||||
|
cmDtRC_t cmDataNewNull( cmData_t* parent, unsigned flags, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewChar( cmData_t* parent, unsigned flags, char v, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewUChar( cmData_t* parent, unsigned flags, unsigned char v, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewShort( cmData_t* parent, unsigned flags, short v, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewUShort( cmData_t* parent, unsigned flags, unsigned short v, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewInt( cmData_t* parent, unsigned flags, int v, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewUInt( cmData_t* parent, unsigned flags, unsigned int v, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewLong( cmData_t* parent, unsigned flags, long v, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewULong( cmData_t* parent, unsigned flags, unsigned long v, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewFloat( cmData_t* parent, unsigned flags, float v, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewDouble( cmData_t* parent, unsigned flags, double v, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewStr( cmData_t* parent, unsigned flags, cmChar_t* str, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewConstStr( cmData_t* parent, unsigned flags, const cmChar_t* str, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewStrN( cmData_t* parent, unsigned flags, cmChar_t* str, unsigned charCnt, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewConstStrN(cmData_t* parent, unsigned flags, const cmChar_t* str, unsigned charCnt, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewBlob( cmData_t* parent, unsigned flags, void* vp, unsigned byteCnt, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewConstBlob(cmData_t* parent, unsigned flags, const void* vp, unsigned byteCnt, cmData_t** ref );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Set the value and type of an existing scalar object.
|
||||||
|
// These functions begin by releasing any resources held by *p
|
||||||
|
// prior to resetting the type and value of the object.
|
||||||
|
// The 'flags' argument to cmDataSetStr() and cmDataSetConstStr()
|
||||||
|
// may use the kNoCopyDtFl and the kFreeValueDtFl
|
||||||
|
cmDtRC_t cmDataSetScalarValue( cmData_t* d, cmDataTypeId_t tid, void* vp, unsigned byteCnt, unsigned flags );
|
||||||
|
|
||||||
|
cmDtRC_t cmDataSetNull( cmData_t* p );
|
||||||
|
cmDtRC_t cmDataSetChar( cmData_t* p, char v );
|
||||||
|
cmDtRC_t cmDataSetUChar( cmData_t* p, unsigned char v );
|
||||||
|
cmDtRC_t cmDataSetShort( cmData_t* p, short v );
|
||||||
|
cmDtRC_t cmDataSetUShort( cmData_t* p, unsigned short v );
|
||||||
|
cmDtRC_t cmDataSetInt( cmData_t* p, int v );
|
||||||
|
cmDtRC_t cmDataSetUInt( cmData_t* p, unsigned int v );
|
||||||
|
cmDtRC_t cmDataSetLong( cmData_t* p, long v );
|
||||||
|
cmDtRC_t cmDataSetULong( cmData_t* p, unsigned long v );
|
||||||
|
cmDtRC_t cmDataSetFloat( cmData_t* p, float v );
|
||||||
|
cmDtRC_t cmDataSetDouble( cmData_t* p, double v );
|
||||||
|
cmDtRC_t cmDataSetStr( cmData_t* p, unsigned flags, cmChar_t* s );
|
||||||
|
cmDtRC_t cmDataSetConstStr( cmData_t* p, unsigned flags, const cmChar_t* s );
|
||||||
|
cmDtRC_t cmDataSetStrN( cmData_t* p, unsigned flags, cmChar_t* s, unsigned charCnt );
|
||||||
|
cmDtRC_t cmDataSetConstStrN( cmData_t* p, unsigned flags, const cmChar_t* s, unsigned charCnt );
|
||||||
|
cmDtRC_t cmDataSetBlob( cmData_t* p, unsigned flags, void* v, unsigned byteCnt );
|
||||||
|
cmDtRC_t cmDataSetConstBlob( cmData_t* p, unsigned flags, const void* v, unsigned byteCnt );
|
||||||
|
|
||||||
|
// Get the value of an object. No conversion is applied the
|
||||||
|
// type must match exactly or an error is generated.
|
||||||
|
cmDtRC_t cmDataChar( const cmData_t* p, char* v );
|
||||||
|
cmDtRC_t cmDataUChar( const cmData_t* p, unsigned char* v );
|
||||||
|
cmDtRC_t cmDataShort( const cmData_t* p, short* v );
|
||||||
|
cmDtRC_t cmDataUShort( const cmData_t* p, unsigned short* v );
|
||||||
|
cmDtRC_t cmDataInt( const cmData_t* p, int* v );
|
||||||
|
cmDtRC_t cmDataUInt( const cmData_t* p, unsigned int* v );
|
||||||
|
cmDtRC_t cmDataLong( const cmData_t* p, long* v );
|
||||||
|
cmDtRC_t cmDataULong( const cmData_t* p, unsigned long* v );
|
||||||
|
cmDtRC_t cmDataFloat( const cmData_t* p, float* v );
|
||||||
|
cmDtRC_t cmDataDouble( const cmData_t* p, double* v );
|
||||||
|
cmDtRC_t cmDataStr( const cmData_t* p, cmChar_t** v );
|
||||||
|
cmDtRC_t cmDataConstStr( const cmData_t* p, const cmChar_t** v );
|
||||||
|
cmDtRC_t cmDataBlob( const cmData_t* p, cmChar_t** v, unsigned* byteCntRef );
|
||||||
|
cmDtRC_t cmDataConstBlob( const cmData_t* p, const cmChar_t** v, unsigned* byteCntRef );
|
||||||
|
|
||||||
// Get the value of an object with conversion.
|
// Get the value of an object with conversion.
|
||||||
cmDtRC_t cmDataGetChar( const cmData_t* p, char* v );
|
cmDtRC_t cmDataGetChar( const cmData_t* p, char* v );
|
||||||
@ -217,124 +281,95 @@ extern "C" {
|
|||||||
cmDtRC_t cmDataGetFloat( const cmData_t* p, float* v );
|
cmDtRC_t cmDataGetFloat( const cmData_t* p, float* v );
|
||||||
cmDtRC_t cmDataGetDouble( const cmData_t* p, double* v );
|
cmDtRC_t cmDataGetDouble( const cmData_t* p, double* v );
|
||||||
|
|
||||||
// Returns the pointer - does not copy the data.
|
|
||||||
cmDtRC_t cmDataGetStr( const cmData_t* p, char** v );
|
|
||||||
cmDtRC_t cmDataGetConstStr( const cmData_t* p, const char** v );
|
|
||||||
cmDtRC_t cmDataGetVoidPtr( const cmData_t* p, void** v );
|
|
||||||
cmDtRC_t cmDataGetCharPtr( const cmData_t* p, char** v );
|
|
||||||
cmDtRC_t cmDataGetUCharPtr( const cmData_t* p, unsigned char** v );
|
|
||||||
cmDtRC_t cmDataGetShortPtr( const cmData_t* p, short** v );
|
|
||||||
cmDtRC_t cmDataGetUShortPtr( const cmData_t* p, unsigned short** v );
|
|
||||||
cmDtRC_t cmDataGetIntPtr( const cmData_t* p, int** v );
|
|
||||||
cmDtRC_t cmDataGetUIntPtr( const cmData_t* p, unsigned int** v );
|
|
||||||
cmDtRC_t cmDataGetLongPtr( const cmData_t* p, long** v );
|
|
||||||
cmDtRC_t cmDataGetULongPtr( const cmData_t* p, unsigned long** v );
|
|
||||||
cmDtRC_t cmDataGetFloatPtr( const cmData_t* p, float** v );
|
|
||||||
cmDtRC_t cmDataGetDoublePtr( const cmData_t* p, double** v );
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Array related functions
|
||||||
|
//
|
||||||
|
|
||||||
|
// Notes:
|
||||||
|
// 1) string arrays are arrays of string pointers.
|
||||||
|
// 2) blob arrays (array of void pointers) are not supported because
|
||||||
|
// there is no direct way to determine the length of each blob
|
||||||
|
// and therefore they cannot be internally duplicated - a special scheme
|
||||||
|
// could be devised (length goes in first 4 bytes) to make this
|
||||||
|
// work but we will defer that until the need arises.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Dynamically allocate a new array data object.
|
||||||
|
//
|
||||||
|
// eleCnt referes to the number of elements in the array pointed
|
||||||
|
// to by 'vp'. The number of bytes pointed to by 'vp' is then
|
||||||
|
// cmDataByteWidth(tid)*eleCnt.
|
||||||
|
//
|
||||||
|
// If no flags are set then the array pointed to by 'vp' is reallocated
|
||||||
|
// and kDataFreeDtFl is set.
|
||||||
|
//
|
||||||
|
// If kFreeValueDtFl is set then the object will take responsibility for
|
||||||
|
// releasing the memory pointed to by 'vp' when the object is destroyed
|
||||||
|
// or the array is reassigned.
|
||||||
|
//
|
||||||
|
// If kNoCopyDtFl is set then 'vp' becomes the internal array
|
||||||
|
// value (vp[cnt]) is NOT reallocated). In this case the client is
|
||||||
|
// responsibile for eventually releasing the associated memory - when
|
||||||
|
// the data object is no longer valid.
|
||||||
|
cmDtRC_t cmDataNewArray( cmData_t* parent, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
|
||||||
|
cmDtRC_t cmDataNewCharArray( cmData_t* parent, char* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewUCharArray( cmData_t* parent, unsigned char* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewShortArray( cmData_t* parent, short* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewUShortArray( cmData_t* parent, unsigned short* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewIntArray( cmData_t* parent, int* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewUIntArray( cmData_t* parent, unsigned int* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewLongArray( cmData_t* parent, long* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewULongArray( cmData_t* parent, unsigned long* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewFloatArray( cmData_t* parent, float* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewDoubleArray( cmData_t* parent, double* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewStrArray( cmData_t* parent, cmChar_t** v, unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
cmDtRC_t cmDataNewConstStrArray( cmData_t* parent, const cmChar_t** v,unsigned eleCnt, unsigned flags, cmData_t** ref );
|
||||||
|
|
||||||
// Set the value and type of an existing scalar object.
|
// Set the value and type of an existing scalar object.
|
||||||
|
//
|
||||||
// These functions begin by releasing any resources held by *p
|
// These functions begin by releasing any resources held by *p
|
||||||
// prior to resetting the type and value of the object.
|
// prior to resetting the type and value of the object.
|
||||||
cmData_t* cmDataSetNull( cmData_t* p );
|
// The 'flags' argument may include kConstValueDtFl, kConstObjDtFl,
|
||||||
cmData_t* cmDataSetChar( cmData_t* p, char v );
|
// kNoCopyDtFl and the kFreeValueDtFl.
|
||||||
cmData_t* cmDataSetUChar( cmData_t* p, unsigned char v );
|
|
||||||
cmData_t* cmDataSetShort( cmData_t* p, short v );
|
|
||||||
cmData_t* cmDataSetUShort( cmData_t* p, unsigned short v );
|
|
||||||
cmData_t* cmDataSetInt( cmData_t* p, int v );
|
|
||||||
cmData_t* cmDataSetUInt( cmData_t* p, unsigned int v );
|
|
||||||
cmData_t* cmDataSetLong( cmData_t* p, long v );
|
|
||||||
cmData_t* cmDataSetULong( cmData_t* p, unsigned long v );
|
|
||||||
cmData_t* cmDataSetFloat( cmData_t* p, float v );
|
|
||||||
cmData_t* cmDataSetDouble( cmData_t* p, double v );
|
|
||||||
cmData_t* cmDataSetStr( cmData_t* p, cmChar_t* s );
|
|
||||||
cmData_t* cmDataSetConstStr( cmData_t* p, const cmChar_t* s );
|
|
||||||
|
|
||||||
// Set the type and value of an existing data object to an external array.
|
// Generic set array functions. 'vp' is assumed to point to an array
|
||||||
// These functions begin by releasing any resources help by *p.
|
// of the type defined by 'tid'.
|
||||||
// The array pointed to by 'vp' is not copied or duplicated.
|
cmDtRC_t cmDataSetArrayValue( cmData_t* dt, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags );
|
||||||
// 'vp' is simply assigned as the data space for the object and therefore must remain
|
|
||||||
// valid for the life of the object.
|
|
||||||
cmData_t* cmDataSetVoidPtr( cmData_t* p, void* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetCharPtr( cmData_t* p, char* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetUCharPtr( cmData_t* p, unsigned char* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetShortPtr( cmData_t* p, short* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetUShortPtr( cmData_t* p, unsigned short* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetIntPtr( cmData_t* p, int* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetUIntPtr( cmData_t* p, unsigned int* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetLongPtr( cmData_t* p, long* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetULongPtr( cmData_t* p, unsigned long* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetFloatPtr( cmData_t* p, float* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetDoublePtr( cmData_t* p, double* vp, unsigned cnt );
|
|
||||||
|
|
||||||
// Set the value of an existing array based data object.
|
// Type sepctific set array functions.
|
||||||
// These functions begin by releasing any resources help by *p
|
cmDtRC_t cmDataSetCharArray( cmData_t* d, char* v, unsigned eleCnt, unsigned flags );
|
||||||
// and then dynamically allocate the internal array and copy
|
cmDtRC_t cmDataSetUCharArray( cmData_t* d, unsigned char* v, unsigned eleCnt, unsigned flags );
|
||||||
// the array data into it.
|
cmDtRC_t cmDataSetShortArray( cmData_t* d, short* v, unsigned eleCnt, unsigned flags );
|
||||||
cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s );
|
cmDtRC_t cmDataSetUShortArray( cmData_t* d, unsigned short* v, unsigned eleCnt, unsigned flags );
|
||||||
cmData_t* cmDataSetConstStrAlloc( cmData_t* p, const cmChar_t* s );
|
cmDtRC_t cmDataSetIntArray( cmData_t* d, int* v, unsigned eleCnt, unsigned flags );
|
||||||
cmData_t* cmDataSetVoidAllocPtr( cmData_t* p, const void* vp, unsigned cnt );
|
cmDtRC_t cmDataSetUIntArray( cmData_t* d, unsigned int* v, unsigned eleCnt, unsigned flags );
|
||||||
cmData_t* cmDataSetCharAllocPtr( cmData_t* p, const char* vp, unsigned cnt );
|
cmDtRC_t cmDataSetLongArray( cmData_t* d, long* v, unsigned eleCnt, unsigned flags );
|
||||||
cmData_t* cmDataSetUCharAllocPtr( cmData_t* p, const unsigned char* vp, unsigned cnt );
|
cmDtRC_t cmDataSetULongArray( cmData_t* d, unsigned long* v, unsigned eleCnt, unsigned flags );
|
||||||
cmData_t* cmDataSetShortAllocPtr( cmData_t* p, const short* vp, unsigned cnt );
|
cmDtRC_t cmDataSetFloatArray( cmData_t* d, float* v, unsigned eleCnt, unsigned flags );
|
||||||
cmData_t* cmDataSetUShortAllocPtr( cmData_t* p, const unsigned short* vp, unsigned cnt );
|
cmDtRC_t cmDataSetDoubleArray( cmData_t* d, double* v, unsigned eleCnt, unsigned flags );
|
||||||
cmData_t* cmDataSetIntAllocPtr( cmData_t* p, const int* vp, unsigned cnt );
|
cmDtRC_t cmDataSetStrArray( cmData_t* d, cmChar_t** v, unsigned eleCnt, unsigned flags );
|
||||||
cmData_t* cmDataSetUIntAllocPtr( cmData_t* p, const unsigned int* vp, unsigned cnt );
|
cmDtRC_t cmDataSetConstStrArray(cmData_t* d,const cmChar_t** v,unsigned eleCnt, unsigned flags );
|
||||||
cmData_t* cmDataSetLongAllocPtr( cmData_t* p, const long* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetULongAllocPtr( cmData_t* p, const unsigned long* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetFloatAllocPtr( cmData_t* p, const float* vp, unsigned cnt );
|
|
||||||
cmData_t* cmDataSetDoubleAllocPtr( cmData_t* p, const double* vp, unsigned cnt );
|
|
||||||
|
|
||||||
|
// Return the count of elements in a n array.
|
||||||
|
unsigned cmDataArrayEleCount( const cmData_t* d );
|
||||||
|
|
||||||
// Dynamically allocate a data object and set it's value.
|
// Get a pointer to the base of an array.
|
||||||
cmData_t* cmDataAllocNull( cmData_t* parent );
|
// The type must match exactly or an error is generated.
|
||||||
cmData_t* cmDataAllocChar( cmData_t* parent, char v );
|
// Use cmDataEleCount() to determine the number of elements in the array.
|
||||||
cmData_t* cmDataAllocUChar( cmData_t* parent, unsigned char v );
|
cmDtRC_t cmDataCharArray( const cmData_t* d, char** v );
|
||||||
cmData_t* cmDataAllocShort( cmData_t* parent, short v );
|
cmDtRC_t cmDataUCharArray( const cmData_t* d, unsigned char** v );
|
||||||
cmData_t* cmDataAllocUShort( cmData_t* parent, unsigned short v );
|
cmDtRC_t cmDataShortArray( const cmData_t* d, short** v );
|
||||||
cmData_t* cmDataAllocInt( cmData_t* parent, int v );
|
cmDtRC_t cmDataUShortArray( const cmData_t* d, unsigned short** v );
|
||||||
cmData_t* cmDataAllocUInt( cmData_t* parent, unsigned int v );
|
cmDtRC_t cmDataIntArray( const cmData_t* d, int** v );
|
||||||
cmData_t* cmDataAllocLong( cmData_t* parent, long v );
|
cmDtRC_t cmDataUIntArray( const cmData_t* d, unsigned int** v );
|
||||||
cmData_t* cmDataAllocULong( cmData_t* parent, unsigned long v );
|
cmDtRC_t cmDataLongArray( const cmData_t* d, long** v );
|
||||||
cmData_t* cmDataAllocFloat( cmData_t* parent, float v );
|
cmDtRC_t cmDataULongArray( const cmData_t* d, unsigned long** v );
|
||||||
cmData_t* cmDataAllocDouble( cmData_t* parent, double v );
|
cmDtRC_t cmDataFloatArray( const cmData_t* d, float** v );
|
||||||
|
cmDtRC_t cmDataDoubleArray( const cmData_t* d, double** v );
|
||||||
// Dynamically allocate a data object and set its array value to an external
|
cmDtRC_t cmDataStrArray( const cmData_t* d, cmChar_t*** v );
|
||||||
// array. v[cnt] is assigned as the internal data space for the object and
|
cmDtRC_t cmDataConstStrArray( const cmData_t* d, const cmChar_t*** v );
|
||||||
// therefore must remain valid for the life of the object.
|
|
||||||
// See the cmDataXXXAlocPtr() for equivalent functions which dynamically
|
|
||||||
// allocate the intenal data space.
|
|
||||||
cmData_t* cmDataAllocStr( cmData_t* parent, cmChar_t* str );
|
|
||||||
cmData_t* cmDataAllocConstStr( cmData_t* parent, const cmChar_t* str );
|
|
||||||
cmData_t* cmDataAllocCharPtr( cmData_t* parent, char* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataAllocUCharPtr( cmData_t* parent, unsigned char* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataAllocShortPtr( cmData_t* parent, short* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataAllocUShortPtr( cmData_t* parent, unsigned short* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataAllocIntPtr( cmData_t* parent, int* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataAllocUIntPtr( cmData_t* parent, unsigned int* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataAllocLongPtr( cmData_t* parent, long* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataAllocULongPtr( cmData_t* parent, unsigned long* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataAllocFloatPtr( cmData_t* parent, float* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataAllocDoublePtr( cmData_t* parent, double* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataAllocVoidPtr( cmData_t* parent, void* v, unsigned cnt );
|
|
||||||
|
|
||||||
|
|
||||||
// Dynamically allocate a data object and its array value.
|
|
||||||
// These functions dynamically allocate the internal array data space
|
|
||||||
// and copy v[cnt] into it.
|
|
||||||
cmData_t* cmDataStrAlloc( cmData_t* parent, cmChar_t* str );
|
|
||||||
cmData_t* cmDataConstStrAlloc( cmData_t* parent, const cmChar_t* str );
|
|
||||||
cmData_t* cmDataCharAllocPtr( cmData_t* parent, const char* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataUCharAllocPtr( cmData_t* parent, const unsigned char* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataShortAllocPtr( cmData_t* parent, const short* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataUShortAllocPtr( cmData_t* parent, const unsigned short* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataIntAllocPtr( cmData_t* parent, const int* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataUIntAllocPtr( cmData_t* parent, const unsigned int* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataLongAllocPtr( cmData_t* parent, const long* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataULongAllocPtr( cmData_t* parent, const unsigned long* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataFloatAllocPtr( cmData_t* parent, const float* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataDoubleAllocPtr( cmData_t* parent, const double* v, unsigned cnt );
|
|
||||||
cmData_t* cmDataVoidAllocPtr( cmData_t* parent, const void* v, unsigned cnt );
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Structure related functions
|
// Structure related functions
|
||||||
@ -428,6 +463,7 @@ extern "C" {
|
|||||||
cmData_t* cmDataAllocPairId( cmData_t* parent, unsigned keyId, cmData_t* value );
|
cmData_t* cmDataAllocPairId( cmData_t* parent, unsigned keyId, cmData_t* value );
|
||||||
|
|
||||||
// Dynamically allocate the label but link (w/o realloc) the value.
|
// Dynamically allocate the label but link (w/o realloc) the value.
|
||||||
|
cmData_t* cmDataAllocPairLabelN(cmData_t* parent, const cmChar_t* label, unsigned charCnt, cmData_t* value);
|
||||||
cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t* label, cmData_t* value );
|
cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t* label, cmData_t* value );
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -445,15 +481,15 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
// Var-args fmt:
|
// Var-args fmt:
|
||||||
// <typeId> <value> {<cnt>}
|
// <contId> {<typeId>} <value> {<cnt>}
|
||||||
// scalar types: <value> is literal,<cnt> is not included
|
// scalar types: <value> is literal,<cnt> is not included
|
||||||
// null has no <value> or <cnt>
|
// null has no <value> or <cnt>
|
||||||
// ptr types: <value> is pointer,<cnt> is element count
|
// array types: <value> is pointer,<cnt> is element count
|
||||||
// struct types: <value> is cmData_t, <cnt> is not included
|
// struct types: <value> is cmData_t, <typeId> and <cnt> is not included
|
||||||
// Indicate the end of argument list by setting <typeId> to kInvalidDtId.
|
// Indicate the end of argument list by setting <typeId> to kInvalidDtId.
|
||||||
// The memory for array based data types is dynamically allocated.
|
// The memory for array based data types is dynamically allocated.
|
||||||
cmData_t* cmDataListAllocV(cmData_t* parent, va_list vl );
|
cmRC_t cmDataListAllocV(cmData_t* parent, cmData_t** ref, va_list vl );
|
||||||
cmData_t* cmDataListAllocA(cmData_t* parent, ... );
|
cmRC_t cmDataListAllocA(cmData_t* parent, cmData_t** ref, ... );
|
||||||
|
|
||||||
// Returns a ptr to 'ele'.
|
// Returns a ptr to 'ele'.
|
||||||
cmData_t* cmDataListAppendEle( cmData_t* p, cmData_t* ele );
|
cmData_t* cmDataListAppendEle( cmData_t* p, cmData_t* ele );
|
||||||
@ -464,9 +500,6 @@ extern "C" {
|
|||||||
cmData_t* cmDataListInsertEle( cmData_t* p, unsigned index, cmData_t* ele );
|
cmData_t* cmDataListInsertEle( cmData_t* p, unsigned index, cmData_t* ele );
|
||||||
cmData_t* cmDataListInsertEleN(cmData_t* p, unsigned index, cmData_t* ele[], unsigned n );
|
cmData_t* cmDataListInsertEleN(cmData_t* p, unsigned index, cmData_t* ele[], unsigned n );
|
||||||
|
|
||||||
cmData_t* cmDataListUnlink( cmData_t* p, unsigned index );
|
|
||||||
cmData_t* cmDataListFree( cmData_t* p, unsigned index );
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Record related functions
|
// Record related functions
|
||||||
//
|
//
|
||||||
@ -487,17 +520,17 @@ extern "C" {
|
|||||||
unsigned cmDataRecdKeyId( cmData_t* p, unsigned index );
|
unsigned cmDataRecdKeyId( cmData_t* p, unsigned index );
|
||||||
const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index );
|
const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index );
|
||||||
|
|
||||||
cmData_t* cmRecdMake( cmData_t* parent, cmData_t* p );
|
cmData_t* cmDataRecdMake( cmData_t* parent, cmData_t* p );
|
||||||
cmData_t* cmRecdAlloc( cmData_t* parent );
|
cmData_t* cmDataRecdAlloc( cmData_t* parent );
|
||||||
|
|
||||||
// Append a pair node by linking the pair node 'pair' to the record node 'p'.
|
// Append a pair node by linking the pair node 'pair' to the record node 'p'.
|
||||||
// 'pair' is simply linked to 'p' via cmDataAppendChild() no
|
// 'pair' is simply linked to 'p' via cmDataAppendChild() no
|
||||||
// reallocation or duplicattion takes place.
|
// reallocation or duplicattion takes place.
|
||||||
cmData_t* cmRecdAppendPair( cmData_t* p, cmData_t* pair );
|
cmData_t* cmDataRecdAppendPair( cmData_t* p, cmData_t* pair );
|
||||||
|
|
||||||
|
|
||||||
// Var-args format:
|
// Var-args format:
|
||||||
// <label|id> <typeId> <value> {<cnt>}
|
// <label|id> {<cid>} <typeId> <value> {<cnt>}
|
||||||
// scalar types: <value> is literal,<cnt> is not included
|
// scalar types: <value> is literal,<cnt> is not included
|
||||||
// null type: has no <value> or <cnt>
|
// null type: has no <value> or <cnt>
|
||||||
// ptr types: <value> is pointer, <cnt> is element count
|
// ptr types: <value> is pointer, <cnt> is element count
|
||||||
@ -530,12 +563,27 @@ extern "C" {
|
|||||||
cmDtRC_t cmDataSerialize( const cmData_t* p, void* buf, unsigned bufByteCnt );
|
cmDtRC_t cmDataSerialize( const cmData_t* p, void* buf, unsigned bufByteCnt );
|
||||||
cmDtRC_t cmDataDeserialize( const void* buf, unsigned bufByteCnt, cmData_t** pp );
|
cmDtRC_t cmDataDeserialize( const void* buf, unsigned bufByteCnt, cmData_t** pp );
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
typedef cmHandle_t cmDataParserH_t;
|
||||||
|
//static cmDataParserH_t cmDataParserNullHandle;
|
||||||
|
|
||||||
|
cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp );
|
||||||
|
cmDtRC_t cmDataParserDestroy( cmDataParserH_t* hp );
|
||||||
|
bool cmDataParserIsValid( cmDataParserH_t h );
|
||||||
|
|
||||||
|
// Parse a text representation into a 'record' type.
|
||||||
|
// Note that the text is wrapped with implied curly braces
|
||||||
|
// (e.g. "{ text }"). The contents of the text should therefore
|
||||||
|
// fit the record syntax (e.g. the first token should be a
|
||||||
|
// 'pair' label.
|
||||||
|
cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** pp );
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void cmDataPrint( const cmData_t* p, cmRpt_t* rpt );
|
void cmDataPrint( const cmData_t* p, cmRpt_t* rpt );
|
||||||
|
|
||||||
void cmDataTest( cmCtx_t* ctx );
|
void cmDataTest( cmCtx_t* ctx );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -60,7 +60,11 @@ extern "C" {
|
|||||||
// Draw the page.
|
// Draw the page.
|
||||||
void cmGrPageDraw( cmGrPgH_t h, cmGrDcH_t dcH );
|
void cmGrPageDraw( cmGrPgH_t h, cmGrDcH_t dcH );
|
||||||
|
|
||||||
|
// Label callback functions are used to translate numeric axis values to
|
||||||
|
// text strings. Multiple label callback functions can be registered with
|
||||||
|
// a page and then assigned to a given view axis via cmGrViewSetLabelFunc().
|
||||||
typedef void (*cmGrLabelFunc_t)( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value );
|
typedef void (*cmGrLabelFunc_t)( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value );
|
||||||
|
|
||||||
// Returns id of the new page label function.
|
// Returns id of the new page label function.
|
||||||
unsigned cmGrPageLabelFuncRegister( cmGrPgH_t h, cmGrLabelFunc_t func, void* arg, const cmChar_t* label );
|
unsigned cmGrPageLabelFuncRegister( cmGrPgH_t h, cmGrLabelFunc_t func, void* arg, const cmChar_t* label );
|
||||||
unsigned cmGrPageLabelFuncCount( cmGrPgH_t h );
|
unsigned cmGrPageLabelFuncCount( cmGrPgH_t h );
|
||||||
|
171
cmLex.c
171
cmLex.c
@ -7,6 +7,12 @@
|
|||||||
#include "cmMallocDebug.h"
|
#include "cmMallocDebug.h"
|
||||||
#include "cmFile.h"
|
#include "cmFile.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kRealFloatLexFl = 0x01,
|
||||||
|
kIntUnsignedLexFl = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned code;
|
unsigned code;
|
||||||
@ -29,6 +35,7 @@ cmLexErrorRecd cmLexErrorArray[] =
|
|||||||
{ kMemAllocErrLexRC, "An attempted memory allocation failed"},
|
{ kMemAllocErrLexRC, "An attempted memory allocation failed"},
|
||||||
{ kEofRC, "The end of the input text was encountered (this is a normal condition not an error)"},
|
{ kEofRC, "The end of the input text was encountered (this is a normal condition not an error)"},
|
||||||
{ kInvalidLexTIdLexRC, "An invalid token id was encountered."},
|
{ kInvalidLexTIdLexRC, "An invalid token id was encountered."},
|
||||||
|
{ kSignErrorLexRC, "A signed integer has a 'u' or 'U' suffix."},
|
||||||
{ kInvalidLexRC, "Unknown lexer error code." }
|
{ kInvalidLexRC, "Unknown lexer error code." }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,6 +82,7 @@ typedef struct cmLex_str
|
|||||||
|
|
||||||
cmChar_t* textBuf; // text buf used by cmLexSetFile()
|
cmChar_t* textBuf; // text buf used by cmLexSetFile()
|
||||||
|
|
||||||
|
unsigned attrFlags; // used to store the int and real suffix type flags
|
||||||
} cmLex;
|
} cmLex;
|
||||||
|
|
||||||
|
|
||||||
@ -148,7 +156,7 @@ unsigned _cmLexRealMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
|||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
unsigned n = 0; // decimal point counter
|
unsigned n = 0; // decimal point counter
|
||||||
unsigned d = 0; // digit counter
|
unsigned d = 0; // digit counter
|
||||||
bool fl = false; // true if this real includes an exponent
|
bool fl = false; // expo flag
|
||||||
|
|
||||||
for(; i<cn && n<=1; ++i)
|
for(; i<cn && n<=1; ++i)
|
||||||
{
|
{
|
||||||
@ -170,10 +178,12 @@ unsigned _cmLexRealMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
|||||||
// if there was at least one digit and the next char is an 'e'
|
// if there was at least one digit and the next char is an 'e'
|
||||||
if( d>0 && i<cn && (cp[i] == 'e' || cp[i] == 'E') )
|
if( d>0 && i<cn && (cp[i] == 'e' || cp[i] == 'E') )
|
||||||
{
|
{
|
||||||
d=0;
|
unsigned e=0;
|
||||||
++i;
|
++i;
|
||||||
unsigned j = i;
|
unsigned j = i;
|
||||||
|
|
||||||
|
fl = false;
|
||||||
|
|
||||||
for(; i<cn; ++i)
|
for(; i<cn; ++i)
|
||||||
{
|
{
|
||||||
if( i==j && cp[i]=='-' ) // allow the char following the e to be '-'
|
if( i==j && cp[i]=='-' ) // allow the char following the e to be '-'
|
||||||
@ -181,6 +191,7 @@ unsigned _cmLexRealMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
|||||||
|
|
||||||
if( isdigit(cp[i]) )
|
if( isdigit(cp[i]) )
|
||||||
{
|
{
|
||||||
|
++e;
|
||||||
++d;
|
++d;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -190,17 +201,42 @@ unsigned _cmLexRealMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
|||||||
}
|
}
|
||||||
|
|
||||||
// an exp exists if digits follwed the 'e'
|
// an exp exists if digits follwed the 'e'
|
||||||
fl = d > 0;
|
fl = e > 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return i>1 && (n==1 || fl) ? i : 0;
|
// if at least one digit was found
|
||||||
|
if( d>0 )
|
||||||
|
{
|
||||||
|
// Note that this path allows a string w/o a decimal pt to trigger a match.
|
||||||
|
|
||||||
|
if(i<cn)
|
||||||
|
{
|
||||||
|
// if the real has a suffix
|
||||||
|
switch(cp[i])
|
||||||
|
{
|
||||||
|
case 'F':
|
||||||
|
case 'f':
|
||||||
|
p->attrFlags = cmSetFlag(p->attrFlags,kRealFloatLexFl);
|
||||||
|
++i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// match w/o suffix return
|
||||||
|
if( d>0 && (fl || n==1 || cmIsFlag(p->attrFlags,kRealFloatLexFl)) )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // no-match return
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cmChar_t* keyStr )
|
unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cmChar_t* keyStr )
|
||||||
{
|
{
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
bool signFl = false;
|
bool signFl = false;
|
||||||
|
|
||||||
for(; i<cn; ++i)
|
for(; i<cn; ++i)
|
||||||
{
|
{
|
||||||
if( i==0 && cp[i]=='-' )
|
if( i==0 && cp[i]=='-' )
|
||||||
@ -223,8 +259,34 @@ unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
|||||||
// The current implementation recognizes all numeric strings
|
// The current implementation recognizes all numeric strings
|
||||||
// containing a decimal point as reals.
|
// containing a decimal point as reals.
|
||||||
|
|
||||||
|
// if no integer was found
|
||||||
|
if( (signFl && i==0) || i==0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
return signFl && i==1 ? 0 : i;
|
|
||||||
|
// check for suffix
|
||||||
|
if(i<cn )
|
||||||
|
{
|
||||||
|
|
||||||
|
switch(cp[i])
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
case 'U':
|
||||||
|
if( signFl )
|
||||||
|
_cmLexError(p,kSignErrorLexRC,"A signed integer has a 'u' or 'U' suffix.");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->attrFlags = cmSetFlag(p->attrFlags,kIntUnsignedLexFl);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned _cmLexHexMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cmChar_t* keyStr )
|
unsigned _cmLexHexMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cmChar_t* keyStr )
|
||||||
@ -387,23 +449,6 @@ cmLexH cmLexInit( const cmChar_t* cp, unsigned cn, unsigned flags, cmRpt_t* rpt
|
|||||||
|
|
||||||
_cmLexSetTextBuffer( p, cp, cn );
|
_cmLexSetTextBuffer( p, cp, cn );
|
||||||
|
|
||||||
/*
|
|
||||||
p->cp = (cn==0) ? NULL : cp;
|
|
||||||
p->cn = (cp==NULL) ? 0 : cn;
|
|
||||||
|
|
||||||
p->ci = 0;
|
|
||||||
|
|
||||||
|
|
||||||
p->curTokenId = kErrorLexTId;
|
|
||||||
p->curTokenCharIdx = cmInvalidIdx;
|
|
||||||
p->curTokenCharCnt = 0;
|
|
||||||
|
|
||||||
p->curLine = 0;
|
|
||||||
p->curCol = 0;
|
|
||||||
p->nextLine = 0;
|
|
||||||
p->nextCol = 0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
int init_mfn = 10;
|
int init_mfn = 10;
|
||||||
p->mfp = cmMemAllocZ( cmLexMatcher, init_mfn );
|
p->mfp = cmMemAllocZ( cmLexMatcher, init_mfn );
|
||||||
p->mfn = init_mfn;
|
p->mfn = init_mfn;
|
||||||
@ -537,70 +582,6 @@ cmRC_t cmLexSetFile( cmLexH h, const cmChar_t* fn )
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
cmRC_t cmLexSetFile( cmLexH h, const cmChar_t* fn )
|
|
||||||
{
|
|
||||||
cmRC_t rc = kOkLexRC;
|
|
||||||
FILE* fp = NULL;
|
|
||||||
cmLex* p = _cmLexHandleToPtr(h);
|
|
||||||
unsigned n = 0;
|
|
||||||
|
|
||||||
assert( fn != NULL && p != NULL );
|
|
||||||
|
|
||||||
// open the file
|
|
||||||
if((fp = fopen(fn,"rb")) == NULL )
|
|
||||||
return _cmLexError(p,kFileOpenErrLexRC,"Unable to open the file:'%s'.",fn);
|
|
||||||
|
|
||||||
// seek to the end
|
|
||||||
if( fseek(fp,0,SEEK_END) != 0 )
|
|
||||||
{
|
|
||||||
rc= _cmLexError(p,kFileSeekErrLexRC,"Unable to seek to the end of '%s'.",fn);
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the length of the file
|
|
||||||
if( (n=ftell(fp)) == 0 )
|
|
||||||
{
|
|
||||||
rc = _cmLexError(p,kFileOpenErrLexRC,"The file '%s' appears to be empty.",fn);
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rewind the file
|
|
||||||
if( fseek(fp,0,SEEK_SET) != 0 )
|
|
||||||
{
|
|
||||||
rc = _cmLexError(p,kFileSeekErrLexRC,"Unable to seek to the beginning of '%s'.",fn);
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate the text buffer
|
|
||||||
if((p->textBuf = cmMemResizeZ( char, p->textBuf, n+1)) == NULL )
|
|
||||||
{
|
|
||||||
rc = _cmLexError(p,kMemAllocErrLexRC,"Unable to allocate the text file buffer for:'%s'.",fn);
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read the file into the text buffer
|
|
||||||
if( fread(p->textBuf,n,1,fp) != 1 )
|
|
||||||
{
|
|
||||||
rc = _cmLexError(p,kFileReadErrLexRC,"File read failed on:'%s'.",fn);
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((rc = _cmLexSetTextBuffer( p, p->textBuf, n )) != kOkLexRC )
|
|
||||||
goto errLabel;
|
|
||||||
|
|
||||||
errLabel:
|
|
||||||
|
|
||||||
// close the file
|
|
||||||
if( fclose(fp) != 0 )
|
|
||||||
{
|
|
||||||
rc = _cmLexError(p,kFileCloseErrLexRC,"File close failed on:'%s'.",fn);
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
cmLexMatcher* _cmLexFindUserToken( cmLex* p, unsigned id, const cmChar_t* tokenStr )
|
cmLexMatcher* _cmLexFindUserToken( cmLex* p, unsigned id, const cmChar_t* tokenStr )
|
||||||
{
|
{
|
||||||
@ -689,9 +670,9 @@ unsigned cmLexGetNextToken( cmLexH h )
|
|||||||
p->curTokenId = kErrorLexTId;
|
p->curTokenId = kErrorLexTId;
|
||||||
p->curTokenCharIdx = cmInvalidIdx;
|
p->curTokenCharIdx = cmInvalidIdx;
|
||||||
p->curTokenCharCnt = 0;
|
p->curTokenCharCnt = 0;
|
||||||
|
p->attrFlags = 0;
|
||||||
|
|
||||||
|
// try each matcher
|
||||||
// try each mater
|
|
||||||
for(; mi<p->mfi; ++mi)
|
for(; mi<p->mfi; ++mi)
|
||||||
if( p->mfp[mi].enableFl )
|
if( p->mfp[mi].enableFl )
|
||||||
{
|
{
|
||||||
@ -701,6 +682,7 @@ unsigned cmLexGetNextToken( cmLexH h )
|
|||||||
else
|
else
|
||||||
charCnt = p->mfp[mi].userPtr( p->cp + p->ci, p->cn - p->ci);
|
charCnt = p->mfp[mi].userPtr( p->cp + p->ci, p->cn - p->ci);
|
||||||
|
|
||||||
|
// notice if the matcher set the error code
|
||||||
if( cmErrLastRC(&p->err) != kOkLexRC )
|
if( cmErrLastRC(&p->err) != kOkLexRC )
|
||||||
return kErrorLexTId;
|
return kErrorLexTId;
|
||||||
|
|
||||||
@ -823,6 +805,19 @@ float cmLexTokenFloat( cmLexH h )
|
|||||||
double cmLexTokenDouble( cmLexH h )
|
double cmLexTokenDouble( cmLexH h )
|
||||||
{ return strtod( cmLexTokenText(h),NULL ); }
|
{ return strtod( cmLexTokenText(h),NULL ); }
|
||||||
|
|
||||||
|
|
||||||
|
bool cmLexTokenIsUnsigned( cmLexH h )
|
||||||
|
{
|
||||||
|
cmLex* p = _cmLexHandleToPtr(h);
|
||||||
|
return p->curTokenId == kIntLexTId && cmIsFlag(p->attrFlags,kIntUnsignedLexFl);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmLexTokenIsSinglePrecision( cmLexH h )
|
||||||
|
{
|
||||||
|
cmLex* p = _cmLexHandleToPtr(h);
|
||||||
|
return p->curTokenId == kRealLexTId && cmIsFlag(p->attrFlags,kRealFloatLexFl);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned cmLexCurrentLineNumber( cmLexH h )
|
unsigned cmLexCurrentLineNumber( cmLexH h )
|
||||||
{
|
{
|
||||||
cmLex* p = _cmLexHandleToPtr(h);
|
cmLex* p = _cmLexHandleToPtr(h);
|
||||||
|
15
cmLex.h
15
cmLex.h
@ -50,7 +50,8 @@ enum
|
|||||||
kMemAllocErrLexRC, //< 10 An attempted memory allocation failed
|
kMemAllocErrLexRC, //< 10 An attempted memory allocation failed
|
||||||
kEofRC, //< 11 The end of the input text was encountered (this is a normal condition not an error)
|
kEofRC, //< 11 The end of the input text was encountered (this is a normal condition not an error)
|
||||||
kInvalidLexTIdLexRC, //< 12 An invalid lex token id was encountered.
|
kInvalidLexTIdLexRC, //< 12 An invalid lex token id was encountered.
|
||||||
kInvalidLexRC //< 13 Sentinal value.
|
kSignErrorLexRC, //< 13 An signed integer has a 'u' or 'U' suffix."
|
||||||
|
kInvalidLexRC //< 1r Sentinal value.
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -119,15 +120,23 @@ unsigned cmLexTokenCharCount( cmLexH h );
|
|||||||
// Return the value of the current token as an integer.
|
// Return the value of the current token as an integer.
|
||||||
int cmLexTokenInt( cmLexH h );
|
int cmLexTokenInt( cmLexH h );
|
||||||
|
|
||||||
// Return the value of the current token as an integer.
|
// Return the value of the current token as an unsigned integer.
|
||||||
unsigned cmLexTokenUInt( cmLexH h );
|
unsigned cmLexTokenUInt( cmLexH h );
|
||||||
|
|
||||||
// Return the value of the current token as an integer.
|
// Return the value of the current token as a float.
|
||||||
float cmLexTokenFloat( cmLexH h );
|
float cmLexTokenFloat( cmLexH h );
|
||||||
|
|
||||||
// Return the value of the current token as a double.
|
// Return the value of the current token as a double.
|
||||||
double cmLexTokenDouble( cmLexH h );
|
double cmLexTokenDouble( cmLexH h );
|
||||||
|
|
||||||
|
// Return true if the current token is an int and it was suffixed
|
||||||
|
// with 'u' to indicate that it is unsigned.
|
||||||
|
bool cmLexTokenIsUnsigned( cmLexH h );
|
||||||
|
|
||||||
|
// Return true if the current token is a real and it was suffexed
|
||||||
|
// with 'f' to indicate that it is a single precision float.
|
||||||
|
bool cmLexTokenIsSinglePrecision( cmLexH h );
|
||||||
|
|
||||||
// Return the line number associated with the current token
|
// Return the line number associated with the current token
|
||||||
unsigned cmLexCurrentLineNumber( cmLexH h );
|
unsigned cmLexCurrentLineNumber( cmLexH h );
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ extern "C" {
|
|||||||
{
|
{
|
||||||
unsigned uid; // uid's are unique among all msg's in the file
|
unsigned uid; // uid's are unique among all msg's in the file
|
||||||
unsigned dtick; // delta ticks
|
unsigned dtick; // delta ticks
|
||||||
unsigned atick;
|
unsigned atick; // accumulated ticks
|
||||||
cmMidiByte_t status; // ch msg's have the channel value removed (it is stored in u.chMsgPtr->ch)
|
cmMidiByte_t status; // ch msg's have the channel value removed (it is stored in u.chMsgPtr->ch)
|
||||||
cmMidiByte_t metaId; //
|
cmMidiByte_t metaId; //
|
||||||
unsigned short trkIdx; //
|
unsigned short trkIdx; //
|
||||||
|
353
cmProc4.c
353
cmProc4.c
@ -4135,3 +4135,356 @@ cmRC_t cmScModulatorDump( cmScModulator* p )
|
|||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================================================================
|
||||||
|
cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs )
|
||||||
|
{
|
||||||
|
cmRecdPlay* op = cmObjAlloc(cmRecdPlay,c,p);
|
||||||
|
|
||||||
|
if( cmRecdPlayInit(op,srate,fragCnt,chCnt,initFragSecs,maxLaSecs,curLaSecs) != cmOkRC )
|
||||||
|
cmRecdPlayFree(&op);
|
||||||
|
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayFree( cmRecdPlay** pp )
|
||||||
|
{
|
||||||
|
cmRC_t rc = cmOkRC;
|
||||||
|
if( pp==NULL || *pp==NULL )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
cmRecdPlay* p = *pp;
|
||||||
|
if((rc = cmRecdPlayFinal(p)) != cmOkRC )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
cmObjFree(pp);
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs )
|
||||||
|
{
|
||||||
|
cmRC_t rc;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if( curLaSecs > maxLaSecs )
|
||||||
|
return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The initial look-ahead time %f is greater than the maximum look-ahead time %f.",curLaSecs,maxLaSecs);
|
||||||
|
|
||||||
|
if((rc = cmRecdPlayFinal(p)) != cmOkRC )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if( chCnt == 0 )
|
||||||
|
return cmOkRC;
|
||||||
|
|
||||||
|
p->frags = cmMemAllocZ(cmRecdPlayFrag,fragCnt);
|
||||||
|
p->fragCnt = fragCnt;
|
||||||
|
p->srate = srate;
|
||||||
|
p->chCnt = chCnt;
|
||||||
|
p->initFragSecs = initFragSecs;
|
||||||
|
p->maxLaSmpCnt = floor(maxLaSecs*srate);
|
||||||
|
p->curLaSmpCnt = floor(curLaSecs*srate);
|
||||||
|
p->laChs = cmMemAllocZ(cmSample_t*,chCnt);
|
||||||
|
p->laSmpIdx = 0;
|
||||||
|
|
||||||
|
for(i=0; i<chCnt; ++i)
|
||||||
|
p->laChs[i] = cmMemAllocZ(cmSample_t,p->maxLaSmpCnt);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayFinal( cmRecdPlay* p )
|
||||||
|
{
|
||||||
|
unsigned i,j;
|
||||||
|
// free the fragments
|
||||||
|
for(i=0; i<p->fragCnt; ++i)
|
||||||
|
{
|
||||||
|
for(j=0; j<p->chCnt; ++j)
|
||||||
|
cmMemFree(p->frags[i].chArray[j]);
|
||||||
|
|
||||||
|
cmMemFree(p->frags[i].chArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
// free the look-ahead buffers
|
||||||
|
for(i=0; i<p->chCnt; ++i)
|
||||||
|
cmMemFree(p->laChs[i]);
|
||||||
|
|
||||||
|
cmMemPtrFree(&p->laChs);
|
||||||
|
cmMemPtrFree(&p->frags);
|
||||||
|
p->fragCnt = 0;
|
||||||
|
p->chCnt = 0;
|
||||||
|
p->rlist = NULL;
|
||||||
|
p->plist = NULL;
|
||||||
|
return cmOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayRegisterFrag( cmRecdPlay* p, unsigned fragIdx, unsigned labelSymId )
|
||||||
|
{
|
||||||
|
assert( fragIdx < p->fragCnt );
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
p->frags[ fragIdx ].labelSymId = labelSymId;
|
||||||
|
|
||||||
|
p->frags[ fragIdx ].chArray = cmMemResizeZ(cmSample_t*,p->frags[fragIdx].chArray,p->chCnt);
|
||||||
|
|
||||||
|
for(i=0; i<p->chCnt; ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
p->frags[ fragIdx ].allocCnt = floor(p->initFragSecs * p->srate);
|
||||||
|
p->frags[ fragIdx ].chArray[i] = cmMemResizeZ(cmSample_t,p->frags[ fragIdx ].chArray[i],p->frags[fragIdx].allocCnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayRewind( cmRecdPlay* p )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
p->laSmpIdx = 0;
|
||||||
|
|
||||||
|
while( p->plist != NULL )
|
||||||
|
cmRecdPlayEndPlay(p,p->plist->labelSymId);
|
||||||
|
|
||||||
|
while( p->rlist != NULL )
|
||||||
|
cmRecdPlayEndRecord(p,p->plist->labelSymId);
|
||||||
|
|
||||||
|
for(i=0; i<p->fragCnt; ++i)
|
||||||
|
p->frags[i].playIdx = 0;
|
||||||
|
|
||||||
|
return cmOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for(i=0; i<p->fragCnt; ++i)
|
||||||
|
if( p->frags[i].labelSymId == labelSymId )
|
||||||
|
{
|
||||||
|
// if the frag is not already on the recd list
|
||||||
|
if( p->frags[i].rlink == NULL )
|
||||||
|
{
|
||||||
|
p->frags[i].recdIdx = 0;
|
||||||
|
p->frags[i].playIdx = 0;
|
||||||
|
p->frags[i].rlink = p->rlist;
|
||||||
|
p->rlist = p->frags + i;
|
||||||
|
|
||||||
|
// handle LA buf longer than frag buf.
|
||||||
|
int cpyCnt = cmMin(p->curLaSmpCnt,p->frags[i].allocCnt);
|
||||||
|
|
||||||
|
// go backwards in LA buf from newest sample to find init src offset
|
||||||
|
int srcOffs = p->laSmpIdx - cpyCnt;
|
||||||
|
|
||||||
|
// if the src is before the first sample in the LA buf then wrap to end of buf
|
||||||
|
if( srcOffs < 0 )
|
||||||
|
srcOffs += p->maxLaSmpCnt;
|
||||||
|
|
||||||
|
assert( 0 <= srcOffs && srcOffs < p->maxLaSmpCnt );
|
||||||
|
|
||||||
|
// cnt of samples to copy from LA buf (limited by end of LA buf)
|
||||||
|
int n0 = cmMin(cpyCnt,p->maxLaSmpCnt - srcOffs);
|
||||||
|
|
||||||
|
// if necessary wrap to begin of LA buf for remaining samples
|
||||||
|
int n1 = cpyCnt>n0 ? n1 = cpyCnt-n0 : 0;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
assert(n0+n1 == cpyCnt );
|
||||||
|
|
||||||
|
for(j=0; j<p->chCnt; ++j)
|
||||||
|
cmVOS_Copy(p->frags[i].chArray[j],n0,p->laChs[j]+srcOffs);
|
||||||
|
|
||||||
|
if( n1 > 0 )
|
||||||
|
{
|
||||||
|
for(j=0; j<p->chCnt; ++j)
|
||||||
|
cmVOS_Copy(p->frags[i].chArray[j]+n0,n1,p->laChs[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
p->frags[i].recdIdx = cpyCnt;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'begin record'.",labelSymId);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayEndRecord( cmRecdPlay* p, unsigned labelSymId )
|
||||||
|
{
|
||||||
|
cmRecdPlayFrag* fp = p->rlist;
|
||||||
|
cmRecdPlayFrag* pp = NULL;
|
||||||
|
|
||||||
|
for(; fp != NULL; fp=fp->rlink )
|
||||||
|
{
|
||||||
|
if( fp->labelSymId == labelSymId )
|
||||||
|
{
|
||||||
|
if( pp == NULL )
|
||||||
|
p->rlist = fp->rlink;
|
||||||
|
else
|
||||||
|
pp->rlink = fp->rlink;
|
||||||
|
|
||||||
|
fp->rlink = NULL;
|
||||||
|
|
||||||
|
return cmOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp = fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'end record'.",labelSymId);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayBeginPlay( cmRecdPlay* p, unsigned labelSymId )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for(i=0; i<p->fragCnt; ++i)
|
||||||
|
if( p->frags[i].labelSymId == labelSymId )
|
||||||
|
{
|
||||||
|
// if the frag is not already on the play list
|
||||||
|
if( p->frags[i].plink == NULL )
|
||||||
|
{
|
||||||
|
p->frags[i].playIdx = 0;
|
||||||
|
p->frags[i].fadeSmpIdx = 0;
|
||||||
|
p->frags[i].fadeDbPerSec = 0.0;
|
||||||
|
p->frags[i].plink = p->plist;
|
||||||
|
p->plist = p->frags + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'begin play'.",labelSymId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayEndPlay( cmRecdPlay* p, unsigned labelSymId )
|
||||||
|
{
|
||||||
|
cmRecdPlayFrag* fp = p->plist;
|
||||||
|
cmRecdPlayFrag* pp = NULL;
|
||||||
|
|
||||||
|
for(; fp != NULL; fp=fp->plink )
|
||||||
|
{
|
||||||
|
if( fp->labelSymId == labelSymId )
|
||||||
|
{
|
||||||
|
if( pp == NULL )
|
||||||
|
p->plist = fp->plink;
|
||||||
|
else
|
||||||
|
pp->plink = fp->plink;
|
||||||
|
|
||||||
|
fp->plink = NULL;
|
||||||
|
|
||||||
|
return cmOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp = fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'end play'.",labelSymId);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayBeginFade( cmRecdPlay* p, unsigned labelSymId, double fadeDbPerSec )
|
||||||
|
{
|
||||||
|
cmRecdPlayFrag* fp = p->plist;
|
||||||
|
|
||||||
|
for(; fp != NULL; fp=fp->plink )
|
||||||
|
if( fp->labelSymId == labelSymId )
|
||||||
|
{
|
||||||
|
fp->fadeDbPerSec = -fabs(fadeDbPerSec);
|
||||||
|
return cmOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'fade begin'.",labelSymId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
chCnt = cmMin(chCnt, p->chCnt);
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// copy incoming audio into the look-head buffers
|
||||||
|
//
|
||||||
|
|
||||||
|
// if the number of incoming samples is longer than the look-head buffer
|
||||||
|
// then copy exactly maxLaSmpCnt samples from the end of the incoming sample
|
||||||
|
// buffer to the look-ahead buffer.
|
||||||
|
unsigned srcOffs = 0;
|
||||||
|
unsigned srcSmpCnt = smpCnt;
|
||||||
|
if( srcSmpCnt > p->maxLaSmpCnt )
|
||||||
|
{
|
||||||
|
// advance incoming sample buffer so that there are maxLaSmpCnt samples remaining
|
||||||
|
srcOffs = smpCnt-p->maxLaSmpCnt;
|
||||||
|
srcSmpCnt = p->maxLaSmpCnt; // decrease the total samples to copy
|
||||||
|
}
|
||||||
|
|
||||||
|
// count of samples from cur posn to end of the LA buffer.
|
||||||
|
unsigned n0 = cmMin(srcSmpCnt, p->maxLaSmpCnt - p->laSmpIdx );
|
||||||
|
|
||||||
|
// count of samples past the end of the LA buffer to be wrapped into begin of buffer
|
||||||
|
unsigned n1 = srcSmpCnt>n0 ? srcSmpCnt-n0 : 0;
|
||||||
|
|
||||||
|
assert(n0+n1 == srcSmpCnt);
|
||||||
|
|
||||||
|
// copy first block to end of LA buffer
|
||||||
|
for(i=0; i<chCnt; ++i)
|
||||||
|
cmVOS_Copy(p->laChs[i]+p->laSmpIdx,n0,iChs[i] + srcOffs);
|
||||||
|
|
||||||
|
p->laSmpIdx += n0;
|
||||||
|
|
||||||
|
if( n1!=0)
|
||||||
|
{
|
||||||
|
// copy second block to begin of LA buffer
|
||||||
|
for(i=0; i<chCnt; ++i)
|
||||||
|
cmVOS_Copy(p->laChs[i],n1,iChs[i] + srcOffs + n0);
|
||||||
|
|
||||||
|
p->laSmpIdx = n1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// copy incoming audio into the active record buffers
|
||||||
|
//
|
||||||
|
cmRecdPlayFrag* fp = p->rlist;
|
||||||
|
|
||||||
|
for(; fp!=NULL; fp=fp->rlink)
|
||||||
|
{
|
||||||
|
assert( fp->recdIdx <= fp->allocCnt);
|
||||||
|
unsigned n = cmMin(fp->allocCnt - fp->recdIdx,smpCnt);
|
||||||
|
unsigned i;
|
||||||
|
for(i=0; i<p->chCnt; ++i)
|
||||||
|
{
|
||||||
|
cmVOS_Copy(fp->chArray[i] + fp->recdIdx, n, iChs[i] );
|
||||||
|
fp->recdIdx += n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// copy outgoing audio out of the active play buffers
|
||||||
|
//
|
||||||
|
fp = p->plist;
|
||||||
|
for(; fp!=NULL; fp=fp->rlink)
|
||||||
|
{
|
||||||
|
assert( fp->playIdx <= fp->recdIdx);
|
||||||
|
|
||||||
|
double gain = pow(10.0,((fp->fadeSmpIdx / p->srate) * fp->fadeDbPerSec)/20.0);
|
||||||
|
unsigned n = cmMin(fp->recdIdx - fp->playIdx,smpCnt);
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for(i=0; i<p->chCnt; ++i)
|
||||||
|
{
|
||||||
|
cmVOS_MultVVS(oChs[i],n,fp->chArray[i] + fp->playIdx,gain);
|
||||||
|
fp->playIdx += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if a fade rate has been set then advance the fade phase
|
||||||
|
if(fp->fadeDbPerSec!=0.0)
|
||||||
|
fp->fadeSmpIdx += smpCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmOkRC;
|
||||||
|
}
|
||||||
|
49
cmProc4.h
49
cmProc4.h
@ -626,6 +626,55 @@ extern "C" {
|
|||||||
cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx );
|
cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx );
|
||||||
cmRC_t cmScModulatorDump( cmScModulator* p );
|
cmRC_t cmScModulatorDump( cmScModulator* p );
|
||||||
|
|
||||||
|
//=======================================================================================================================
|
||||||
|
|
||||||
|
typedef struct cmRecdPlayFrag_str
|
||||||
|
{
|
||||||
|
unsigned labelSymId; // this fragments label
|
||||||
|
cmSample_t** chArray; // record buffer chArray[cmRecdPlay.chCnt][allocCnt]
|
||||||
|
unsigned allocCnt; // count of samples allocated to each channel
|
||||||
|
unsigned playIdx; // index of next sample to play
|
||||||
|
unsigned recdIdx; // index of next sample to receieve audio (count of full samples)
|
||||||
|
double fadeDbPerSec; // fade rate in dB per second
|
||||||
|
unsigned fadeSmpIdx;
|
||||||
|
struct cmRecdPlayFrag_str* rlink; // cmRecdPlay.rlist link
|
||||||
|
struct cmRecdPlayFrag_str* plink; // cmRecdPlay.plist link
|
||||||
|
} cmRecdPlayFrag;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
cmObj obj;
|
||||||
|
cmRecdPlayFrag* frags; // frags[fragCnt] fragment array
|
||||||
|
unsigned fragCnt; // count of fragments
|
||||||
|
double srate; // system sample rate
|
||||||
|
unsigned chCnt; // count of input and output audio channels
|
||||||
|
double initFragSecs; // size initial memory allocated to each frag in seconds
|
||||||
|
unsigned maxLaSmpCnt; // samples allocated to each channel of the look-ahead buffers.
|
||||||
|
unsigned curLaSmpCnt; // current look-ahead time in samples (curLaSmpCnt<=maxLaSmpCnt)
|
||||||
|
cmSample_t** laChs; // laChs[chCnt][maxLaSmpCnt] - look-ahead buffers
|
||||||
|
int laSmpIdx; // next look-ahead buffer index to receive a sample
|
||||||
|
cmRecdPlayFrag* plist; // currently playing frags
|
||||||
|
cmRecdPlayFrag* rlist; // currently recording frags
|
||||||
|
} cmRecdPlay;
|
||||||
|
|
||||||
|
|
||||||
|
cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs );
|
||||||
|
cmRC_t cmRecdPlayFree( cmRecdPlay** pp );
|
||||||
|
cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs );
|
||||||
|
cmRC_t cmRecdPlayFinal( cmRecdPlay* p );
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayRegisterFrag( cmRecdPlay* p, unsigned fragIdx, unsigned labelSymId );
|
||||||
|
|
||||||
|
cmRC_t cmRecdPlayRewind( cmRecdPlay* p );
|
||||||
|
cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId );
|
||||||
|
cmRC_t cmRecdPlayEndRecord( cmRecdPlay* p, unsigned labelSymId );
|
||||||
|
cmRC_t cmRecdPlayBeginPlay( cmRecdPlay* p, unsigned labelSymId );
|
||||||
|
cmRC_t cmRecdPlayEndPlay( cmRecdPlay* p, unsigned labelSymId );
|
||||||
|
|
||||||
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -42,12 +42,15 @@ extern "C" {
|
|||||||
const void* cmStackTop( cmStackH_t h );
|
const void* cmStackTop( cmStackH_t h );
|
||||||
|
|
||||||
// Set the value of 'dataEleCnt' elements on the stack.
|
// Set the value of 'dataEleCnt' elements on the stack.
|
||||||
|
// The top element is at index cmStackCount() - 1.
|
||||||
cmStRC_t cmStackSet( cmStackH_t h, unsigned index, const void* data, unsigned dataEleCnt );
|
cmStRC_t cmStackSet( cmStackH_t h, unsigned index, const void* data, unsigned dataEleCnt );
|
||||||
|
|
||||||
// Copy 'dataEleCnt' elements into the buffer pointed to by 'data'.
|
// Copy 'dataEleCnt' elements into the buffer pointed to by 'data'.
|
||||||
|
// The top element is at index cmStackCount() - 1.
|
||||||
cmStRC_t cmStackGetN( cmStackH_t h, unsigned index, void* data, unsigned dataEleCnt );
|
cmStRC_t cmStackGetN( cmStackH_t h, unsigned index, void* data, unsigned dataEleCnt );
|
||||||
|
|
||||||
// Return a pointer to a single element on the stack.
|
// Return a pointer to a single element on the stack.
|
||||||
|
// The top element is at index cmStackCount() - 1.
|
||||||
const void* cmStackGet( cmStackH_t h, unsigned index );
|
const void* cmStackGet( cmStackH_t h, unsigned index );
|
||||||
|
|
||||||
// Convert the internal representation of the stack to a linear array and return
|
// Convert the internal representation of the stack to a linear array and return
|
||||||
|
@ -5418,6 +5418,7 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
|
|||||||
cmActiveMeasClassCons,
|
cmActiveMeasClassCons,
|
||||||
cmAmSyncClassCons,
|
cmAmSyncClassCons,
|
||||||
cmNanoMapClassCons,
|
cmNanoMapClassCons,
|
||||||
|
cmRecdPlayClassCons,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
261
dsp/cmDspKr.c
261
dsp/cmDspKr.c
@ -572,7 +572,7 @@ cmDspRC_t _cmDspScoreReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
|||||||
}
|
}
|
||||||
|
|
||||||
if((tlFn = cmDspStrcz(inst, kFnScId )) != NULL )
|
if((tlFn = cmDspStrcz(inst, kFnScId )) != NULL )
|
||||||
if( cmScoreInitialize(ctx->cmCtx, &p->scH, tlFn, cmDspSampleRate(ctx), dynRefArray, dynRefCnt, _cmDspScoreCb, p, cmSymTblNullHandle ) != kOkTlRC )
|
if( cmScoreInitialize(ctx->cmCtx, &p->scH, tlFn, cmDspSampleRate(ctx), dynRefArray, dynRefCnt, _cmDspScoreCb, p, ctx->stH ) != kOkTlRC )
|
||||||
rc = cmErrMsg(&inst->classPtr->err, kInstResetFailDspRC, "Score file open failed.");
|
rc = cmErrMsg(&inst->classPtr->err, kInstResetFailDspRC, "Score file open failed.");
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
@ -2264,3 +2264,262 @@ struct cmDspClass_str* cmNanoMapClassCons( cmDspCtx_t* ctx )
|
|||||||
|
|
||||||
return &_cmNanoMapDC;
|
return &_cmNanoMapDC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================================================================================
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kChCntPrId,
|
||||||
|
kFnPrId,
|
||||||
|
kSecsPrId,
|
||||||
|
kMaxLaSecsPrId,
|
||||||
|
kCurLaSecsPrId,
|
||||||
|
kFadeRatePrId,
|
||||||
|
kScLocIdxPrId,
|
||||||
|
kCmdPrId,
|
||||||
|
kInAudioBasePrId
|
||||||
|
};
|
||||||
|
|
||||||
|
cmDspClass_t _cmRecdPlayDC;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
cmDspInst_t inst;
|
||||||
|
cmRecdPlay* rcdply;
|
||||||
|
cmScH_t scH;
|
||||||
|
unsigned onSymId;
|
||||||
|
unsigned offSymId;
|
||||||
|
unsigned audioOutBaseId;
|
||||||
|
unsigned chCnt;
|
||||||
|
unsigned scLocIdx;
|
||||||
|
} cmDspRecdPlay_t;
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspRecdPlayOpenScore( cmDspCtx_t* ctx, cmDspInst_t* inst )
|
||||||
|
{
|
||||||
|
cmDspRC_t rc =kOkDspRC;
|
||||||
|
const cmChar_t* fn;
|
||||||
|
|
||||||
|
cmDspRecdPlay_t* p = (cmDspRecdPlay_t*)inst;
|
||||||
|
|
||||||
|
p->scLocIdx = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if((fn = cmDspStrcz(inst,kFnPrId)) == NULL || strlen(fn)==0 )
|
||||||
|
return cmErrMsg(&inst->classPtr->err, kInvalidArgDspRC, "No score file name supplied.");
|
||||||
|
|
||||||
|
if( cmScoreInitialize(ctx->cmCtx, &p->scH, fn, cmDspSampleRate(ctx), NULL, 0, NULL, NULL, ctx->stH ) != kOkScRC )
|
||||||
|
return cmErrMsg(&inst->classPtr->err, kSubSysFailDspRC, "Unable to open the score '%s'.",fn);
|
||||||
|
|
||||||
|
if( cmScoreIsValid(p->scH) )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
unsigned markerCnt = cmScoreMarkerLabelCount(p->scH);
|
||||||
|
double initFragSecs = cmDspDouble(inst,kSecsPrId);
|
||||||
|
double maxLaSecs = cmDspDouble(inst,kMaxLaSecsPrId);
|
||||||
|
double curLaSecs = cmDspDouble(inst,kCurLaSecsPrId);
|
||||||
|
|
||||||
|
if((p->rcdply = cmRecdPlayAlloc(ctx->cmProcCtx, NULL, cmDspSampleRate(ctx), markerCnt, p->chCnt, initFragSecs, maxLaSecs, curLaSecs)) == NULL)
|
||||||
|
return cmErrMsg(&inst->classPtr->err,kSubSysFailDspRC,"Unable to create the internal recorder-player object.");
|
||||||
|
|
||||||
|
for(i=0; i<markerCnt; ++i)
|
||||||
|
cmRecdPlayRegisterFrag(p->rcdply,i, cmScoreMarkerLabelSymbolId(p->scH,i ));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cmDspInst_t* _cmDspRecdPlayAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( va_cnt < 1 )
|
||||||
|
{
|
||||||
|
cmDspClassErr(ctx,classPtr,kVarArgParseFailDspRC,"The 'RecdPlay' constructor must have a count of input ports.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list vl1;
|
||||||
|
va_copy(vl1,vl);
|
||||||
|
|
||||||
|
int chCnt = va_arg(vl,int);
|
||||||
|
unsigned audioOutBase = kInAudioBasePrId + chCnt;
|
||||||
|
|
||||||
|
cmDspRecdPlay_t* p = cmDspInstAllocV(cmDspRecdPlay_t,ctx,classPtr,instSymId,id,storeSymId,va_cnt,vl1,
|
||||||
|
1, "chs", kChCntPrId, 0,0, kUIntDsvFl | kReqArgDsvFl, "channel count.",
|
||||||
|
1, "fn", kFnPrId, 0,0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "Score file." ,
|
||||||
|
1, "secs", kSecsPrId, 0,0, kInDsvFl | kDoubleDsvFl | kReqArgDsvFl, "Initial fragment allocation in seconds.",
|
||||||
|
1, "maxla", kMaxLaSecsPrId, 0,0, kInDsvFl | kDoubleDsvFl, "Maximum look-ahead buffer in seconds.",
|
||||||
|
1, "curla", kCurLaSecsPrId, 0,0, kInDsvFl | kDoubleDsvFl, "Current look-head buffer in seconds.",
|
||||||
|
1, "frate", kFadeRatePrId, 0,0, kInDsvFl | kDoubleDsvFl, "Fade rate in dB per second.",
|
||||||
|
1, "index", kScLocIdxPrId, 0,0, kInDsvFl | kUIntDsvFl, "Score follower location index.",
|
||||||
|
1, "cmd", kCmdPrId, 0,0, kInDsvFl | kSymDsvFl, "on=reset off=stop.",
|
||||||
|
chCnt, "in", kInAudioBasePrId,0,1, kInDsvFl | kAudioBufDsvFl, "Audio input",
|
||||||
|
chCnt, "out", audioOutBase, 0,1, kOutDsvFl | kAudioBufDsvFl, "Audio output",
|
||||||
|
0 );
|
||||||
|
|
||||||
|
va_end(vl1);
|
||||||
|
|
||||||
|
p->onSymId = cmSymTblId(ctx->stH,"on");
|
||||||
|
p->offSymId = cmSymTblId(ctx->stH,"off");
|
||||||
|
p->audioOutBaseId = audioOutBase;
|
||||||
|
p->chCnt = chCnt;
|
||||||
|
p->scLocIdx = 0;
|
||||||
|
|
||||||
|
cmDspSetDefaultDouble(ctx,&p->inst, kSecsPrId, 0, 10.0 );
|
||||||
|
cmDspSetDefaultDouble(ctx,&p->inst, kMaxLaSecsPrId,0, 2.0);
|
||||||
|
cmDspSetDefaultDouble(ctx,&p->inst, kCurLaSecsPrId,0, 0.5);
|
||||||
|
cmDspSetDefaultDouble(ctx,&p->inst, kFadeRatePrId, 0, 1.0);
|
||||||
|
|
||||||
|
return &p->inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspRecdPlayFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
|
{
|
||||||
|
cmDspRC_t rc = kOkDspRC;
|
||||||
|
cmDspRecdPlay_t* p = (cmDspRecdPlay_t*)inst;
|
||||||
|
|
||||||
|
cmRecdPlayFree(&p->rcdply);
|
||||||
|
|
||||||
|
cmScoreFinalize(&p->scH);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspRecdPlayReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
|
{
|
||||||
|
cmDspApplyAllDefaults(ctx,inst);
|
||||||
|
|
||||||
|
return _cmDspRecdPlayOpenScore(ctx,inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspRecdPlayExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
|
{
|
||||||
|
cmDspRC_t rc = kOkDspRC;
|
||||||
|
|
||||||
|
cmDspRecdPlay_t* p = (cmDspRecdPlay_t*)inst;
|
||||||
|
|
||||||
|
const cmSample_t* x[ p->chCnt ];
|
||||||
|
cmSample_t* y[ p->chCnt ];
|
||||||
|
unsigned n;
|
||||||
|
unsigned i;
|
||||||
|
unsigned actChCnt = 0;
|
||||||
|
|
||||||
|
for(i=0; i<p->chCnt; ++i)
|
||||||
|
{
|
||||||
|
if( i==0 )
|
||||||
|
n = cmDspAudioBufSmpCount(ctx,inst,kInAudioBasePrId+i,0);
|
||||||
|
else
|
||||||
|
{ assert( n == cmDspAudioBufSmpCount(ctx,inst,kInAudioBasePrId+i,0)); }
|
||||||
|
|
||||||
|
x[i] = cmDspAudioBuf(ctx,inst,kInAudioBasePrId+i,0);
|
||||||
|
|
||||||
|
if( x[i] != NULL )
|
||||||
|
{
|
||||||
|
y[i] = cmDspAudioBuf(ctx,inst,p->audioOutBaseId+i,0);
|
||||||
|
|
||||||
|
if( y[i] != NULL )
|
||||||
|
{
|
||||||
|
assert( n == cmDspAudioBufSmpCount(ctx,inst,p->audioOutBaseId+i,0));
|
||||||
|
|
||||||
|
cmVOS_Zero(y[i],n);
|
||||||
|
|
||||||
|
actChCnt += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRecdPlayExec(p->rcdply,x,y,actChCnt,n);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspRecdPlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
|
{
|
||||||
|
cmDspRecdPlay_t* p = (cmDspRecdPlay_t*)inst;
|
||||||
|
|
||||||
|
cmDspSetEvent(ctx,inst,evt);
|
||||||
|
|
||||||
|
switch( evt->dstVarId )
|
||||||
|
{
|
||||||
|
case kCmdPrId:
|
||||||
|
if( cmDspSymbol(inst,kCmdPrId) == p->onSymId )
|
||||||
|
{
|
||||||
|
printf("rewind\n");
|
||||||
|
cmRecdPlayRewind(p->rcdply);
|
||||||
|
p->scLocIdx = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( cmDspSymbol(inst,kCmdPrId) == p->offSymId )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kCurLaSecsPrId:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kScLocIdxPrId:
|
||||||
|
{
|
||||||
|
unsigned endScLocIdx = cmDspUInt(inst,kScLocIdxPrId) ;
|
||||||
|
|
||||||
|
for(; p->scLocIdx<=endScLocIdx; p->scLocIdx+=1)
|
||||||
|
{
|
||||||
|
cmScoreLoc_t* loc = cmScoreLoc(p->scH, p->scLocIdx );
|
||||||
|
cmScoreMarker_t* mp = loc->markList;
|
||||||
|
|
||||||
|
for(; mp!=NULL; mp=mp->link)
|
||||||
|
switch( mp->markTypeId )
|
||||||
|
{
|
||||||
|
case kRecdBegScMId:
|
||||||
|
printf("recd-beg\n");
|
||||||
|
cmRecdPlayBeginRecord(p->rcdply, mp->labelSymId );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kRecdEndScMId:
|
||||||
|
printf("recd-end\n");
|
||||||
|
cmRecdPlayEndRecord(p->rcdply, mp->labelSymId );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kPlayBegScMId:
|
||||||
|
printf("play-beg\n");
|
||||||
|
cmRecdPlayBeginPlay(p->rcdply, mp->labelSymId );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kPlayEndScMId:
|
||||||
|
printf("play-end\n");
|
||||||
|
cmRecdPlayEndPlay(p->rcdply, mp->labelSymId );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kFadeScMId:
|
||||||
|
printf("fade-beg\n");
|
||||||
|
cmRecdPlayBeginFade(p->rcdply, mp->labelSymId, cmDspDouble(inst,kFadeRatePrId) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p->scLocIdx = endScLocIdx+1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kOkDspRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cmDspClass_str* cmRecdPlayClassCons( cmDspCtx_t* ctx )
|
||||||
|
{
|
||||||
|
cmDspClassSetup(&_cmRecdPlayDC,ctx,"RecdPlay",
|
||||||
|
NULL,
|
||||||
|
_cmDspRecdPlayAlloc,
|
||||||
|
_cmDspRecdPlayFree,
|
||||||
|
_cmDspRecdPlayReset,
|
||||||
|
_cmDspRecdPlayExec,
|
||||||
|
_cmDspRecdPlayRecv,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"Score controlled live recorder/player");
|
||||||
|
|
||||||
|
return &_cmRecdPlayDC;
|
||||||
|
}
|
||||||
|
@ -16,6 +16,7 @@ extern "C" {
|
|||||||
struct cmDspClass_str* cmActiveMeasClassCons( cmDspCtx_t* ctx );
|
struct cmDspClass_str* cmActiveMeasClassCons( cmDspCtx_t* ctx );
|
||||||
struct cmDspClass_str* cmAmSyncClassCons( cmDspCtx_t* ctx );
|
struct cmDspClass_str* cmAmSyncClassCons( cmDspCtx_t* ctx );
|
||||||
struct cmDspClass_str* cmNanoMapClassCons( cmDspCtx_t* ctx );
|
struct cmDspClass_str* cmNanoMapClassCons( cmDspCtx_t* ctx );
|
||||||
|
struct cmDspClass_str* cmRecdPlayClassCons( cmDspCtx_t* ctx );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,10 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
|
|||||||
double cmpWndMaxMs = 1000.0;
|
double cmpWndMaxMs = 1000.0;
|
||||||
double cmpWndMs = 200.0;
|
double cmpWndMs = 200.0;
|
||||||
|
|
||||||
|
double recdPlayInitAllocSecs = 10.0;
|
||||||
|
double recdPlayMaxLaSecs = 2.0;
|
||||||
|
double recdPlayCurLaSecs = 0.1;
|
||||||
|
double recdPlayFadeRateDbPerSec = 4.0;
|
||||||
|
|
||||||
memset(&r,0,sizeof(r));
|
memset(&r,0,sizeof(r));
|
||||||
cmErrSetup(&err,&cmCtx->rpt,"Kr Timeline");
|
cmErrSetup(&err,&cmCtx->rpt,"Kr Timeline");
|
||||||
@ -122,6 +125,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
|
|||||||
cmDspInst_t* mop = cmDspSysAllocInst(h,"MidiOut", NULL, 2, r.midiDevice,r.midiOutPort);
|
cmDspInst_t* mop = cmDspSysAllocInst(h,"MidiOut", NULL, 2, r.midiDevice,r.midiOutPort);
|
||||||
cmDspInst_t* sfp = cmDspSysAllocInst(h,"ScFol", NULL, 1, r.scFn );
|
cmDspInst_t* sfp = cmDspSysAllocInst(h,"ScFol", NULL, 1, r.scFn );
|
||||||
cmDspInst_t* amp = cmDspSysAllocInst(h,"ActiveMeas", NULL, 1, 100 );
|
cmDspInst_t* amp = cmDspSysAllocInst(h,"ActiveMeas", NULL, 1, 100 );
|
||||||
|
cmDspInst_t* rpp = cmDspSysAllocInst(h,"RecdPlay", NULL, 4, 2, r.scFn, recdPlayInitAllocSecs, recdPlayMaxLaSecs, recdPlayCurLaSecs, recdPlayFadeRateDbPerSec );
|
||||||
cmDspInst_t* modp = cmDspSysAllocInst(h,"ScMod", NULL, 2, r.modFn, "m1" );
|
cmDspInst_t* modp = cmDspSysAllocInst(h,"ScMod", NULL, 2, r.modFn, "m1" );
|
||||||
cmDspInst_t* asp = cmDspSysAllocInst(h,"AmSync", NULL, 0 );
|
cmDspInst_t* asp = cmDspSysAllocInst(h,"AmSync", NULL, 0 );
|
||||||
|
|
||||||
@ -173,14 +177,14 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
|
|||||||
cmDspInst_t* kr00 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact );
|
cmDspInst_t* kr00 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact );
|
||||||
cmDspInst_t* kr01 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact );
|
cmDspInst_t* kr01 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact );
|
||||||
cmDspInst_t* fad0 = cmDspSysAllocInst(h, "Xfader", NULL, 3, xfadeChCnt, xfadeMs, xfadeInitFl );
|
cmDspInst_t* fad0 = cmDspSysAllocInst(h, "Xfader", NULL, 3, xfadeChCnt, xfadeMs, xfadeInitFl );
|
||||||
cmDspInst_t* mix0 = cmDspSysAllocInst(h, "AMix", NULL, 3, xfadeChCnt, mixGain, mixGain );
|
cmDspInst_t* mix0 = cmDspSysAllocInst(h, "AMix", NULL, 4, xfadeChCnt+1, mixGain, mixGain, mixGain );
|
||||||
cmDspInst_t* cmp0 = cmDspSysAllocInst(h,"Compressor", NULL, 8, cmpBypassFl, cmpThreshDb, cmpRatio_num, cmpAtkMs, cmpRlsMs, cmpMakeup, cmpWndMs, cmpWndMaxMs );
|
cmDspInst_t* cmp0 = cmDspSysAllocInst(h,"Compressor", NULL, 8, cmpBypassFl, cmpThreshDb, cmpRatio_num, cmpAtkMs, cmpRlsMs, cmpMakeup, cmpWndMs, cmpWndMaxMs );
|
||||||
cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 0 );
|
cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 0 );
|
||||||
|
|
||||||
cmDspInst_t* kr10 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact );
|
cmDspInst_t* kr10 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact );
|
||||||
cmDspInst_t* kr11 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact );
|
cmDspInst_t* kr11 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact );
|
||||||
cmDspInst_t* fad1 = cmDspSysAllocInst(h, "Xfader", NULL, 3, xfadeChCnt, xfadeMs, xfadeInitFl );
|
cmDspInst_t* fad1 = cmDspSysAllocInst(h, "Xfader", NULL, 3, xfadeChCnt, xfadeMs, xfadeInitFl );
|
||||||
cmDspInst_t* mix1 = cmDspSysAllocInst(h, "AMix", NULL, 3, xfadeChCnt, mixGain, mixGain );
|
cmDspInst_t* mix1 = cmDspSysAllocInst(h, "AMix", NULL, 4, xfadeChCnt+1, mixGain, mixGain, mixGain );
|
||||||
cmDspInst_t* cmp1 = cmDspSysAllocInst(h,"Compressor", NULL, 8, cmpBypassFl, cmpThreshDb, cmpRatio_num, cmpAtkMs, cmpRlsMs, cmpMakeup, cmpWndMs, cmpWndMaxMs );
|
cmDspInst_t* cmp1 = cmDspSysAllocInst(h,"Compressor", NULL, 8, cmpBypassFl, cmpThreshDb, cmpRatio_num, cmpAtkMs, cmpRlsMs, cmpMakeup, cmpWndMs, cmpWndMaxMs );
|
||||||
cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 1 );
|
cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 1 );
|
||||||
|
|
||||||
@ -378,12 +382,14 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
|
|||||||
cmDspSysConnectAudio(h, wtp, "out", au0Sw, "a-in-0" ); // wt -> sw
|
cmDspSysConnectAudio(h, wtp, "out", au0Sw, "a-in-0" ); // wt -> sw
|
||||||
cmDspSysConnectAudio(h, ai0p, "out", au0Sw, "a-in-1" ); // ain -> sw
|
cmDspSysConnectAudio(h, ai0p, "out", au0Sw, "a-in-1" ); // ain -> sw
|
||||||
cmDspSysConnectAudio(h, ai0p, "out", mi0p, "in" );
|
cmDspSysConnectAudio(h, ai0p, "out", mi0p, "in" );
|
||||||
|
cmDspSysConnectAudio(h, au0Sw,"a-out", rpp, "in-0"); // sw -> rcdply
|
||||||
cmDspSysConnectAudio(h, au0Sw,"a-out", kr00, "in" ); // sw -> kr
|
cmDspSysConnectAudio(h, au0Sw,"a-out", kr00, "in" ); // sw -> kr
|
||||||
cmDspSysConnectAudio(h, kr00, "out", fad0, "in-0"); // kr -> fad
|
cmDspSysConnectAudio(h, kr00, "out", fad0, "in-0"); // kr -> fad
|
||||||
cmDspSysConnectAudio(h, fad0, "out-0", mix0, "in-0"); // fad -> mix
|
cmDspSysConnectAudio(h, fad0, "out-0", mix0, "in-0"); // fad -> mix
|
||||||
cmDspSysConnectAudio(h, au0Sw,"a-out", kr01, "in" ); // sw -> kr
|
cmDspSysConnectAudio(h, au0Sw,"a-out", kr01, "in" ); // sw -> kr
|
||||||
cmDspSysConnectAudio(h, kr01, "out", fad0, "in-1"); // kr -> fad
|
cmDspSysConnectAudio(h, kr01, "out", fad0, "in-1"); // kr -> fad
|
||||||
cmDspSysConnectAudio(h, fad0, "out-1", mix0, "in-1"); // fad -> mix
|
cmDspSysConnectAudio(h, fad0, "out-1", mix0, "in-1"); // fad -> mix
|
||||||
|
cmDspSysConnectAudio(h, rpp, "out-0", mix0, "in-2");
|
||||||
cmDspSysConnectAudio(h, mix0, "out", cmp0, "in"); // mix -> cmp
|
cmDspSysConnectAudio(h, mix0, "out", cmp0, "in"); // mix -> cmp
|
||||||
cmDspSysConnectAudio(h, cmp0, "out", ao0p, "in" ); // cmp -> aout
|
cmDspSysConnectAudio(h, cmp0, "out", ao0p, "in" ); // cmp -> aout
|
||||||
|
|
||||||
@ -391,12 +397,14 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
|
|||||||
cmDspSysConnectAudio(h, wtp, "out", au1Sw, "a-in-0" ); // wt -> kr
|
cmDspSysConnectAudio(h, wtp, "out", au1Sw, "a-in-0" ); // wt -> kr
|
||||||
cmDspSysConnectAudio(h, ai1p, "out", au1Sw, "a-in-1" );
|
cmDspSysConnectAudio(h, ai1p, "out", au1Sw, "a-in-1" );
|
||||||
cmDspSysConnectAudio(h, ai1p, "out", mi1p, "in" );
|
cmDspSysConnectAudio(h, ai1p, "out", mi1p, "in" );
|
||||||
|
cmDspSysConnectAudio(h, au1Sw,"a-out", rpp, "in-1"); // sw -> rcdply
|
||||||
cmDspSysConnectAudio(h, au1Sw,"a-out", kr10, "in" );
|
cmDspSysConnectAudio(h, au1Sw,"a-out", kr10, "in" );
|
||||||
cmDspSysConnectAudio(h, kr10, "out", fad1, "in-0");
|
cmDspSysConnectAudio(h, kr10, "out", fad1, "in-0");
|
||||||
cmDspSysConnectAudio(h, fad1, "out-0", mix1, "in-0");
|
cmDspSysConnectAudio(h, fad1, "out-0", mix1, "in-0");
|
||||||
cmDspSysConnectAudio(h, au1Sw,"a-out", kr11, "in" ); // wt -> kr
|
cmDspSysConnectAudio(h, au1Sw,"a-out", kr11, "in" ); // wt -> kr
|
||||||
cmDspSysConnectAudio(h, kr11, "out", fad1, "in-1");
|
cmDspSysConnectAudio(h, kr11, "out", fad1, "in-1");
|
||||||
cmDspSysConnectAudio(h, fad1, "out-1", mix1, "in-1");
|
cmDspSysConnectAudio(h, fad1, "out-1", mix1, "in-1");
|
||||||
|
cmDspSysConnectAudio(h, rpp, "out-0", mix1, "in-2");
|
||||||
cmDspSysConnectAudio(h, mix1, "out", cmp1, "in");
|
cmDspSysConnectAudio(h, mix1, "out", cmp1, "in");
|
||||||
cmDspSysConnectAudio(h, cmp1, "out", ao1p, "in" ); // comp -> aout
|
cmDspSysConnectAudio(h, cmp1, "out", ao1p, "in" ); // comp -> aout
|
||||||
|
|
||||||
@ -437,6 +445,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
|
|||||||
cmDspSysInstallCb(h, pts, "on", wtRt, "s-in", NULL );
|
cmDspSysInstallCb(h, pts, "on", wtRt, "s-in", NULL );
|
||||||
cmDspSysInstallCb(h, wtRt,"s-out-0", wtp, "cmd", NULL );
|
cmDspSysInstallCb(h, wtRt,"s-out-0", wtp, "cmd", NULL );
|
||||||
cmDspSysInstallCb(h, pts, "on", modp, "cmd", NULL );
|
cmDspSysInstallCb(h, pts, "on", modp, "cmd", NULL );
|
||||||
|
cmDspSysInstallCb(h, pts, "on", rpp, "cmd", NULL );
|
||||||
cmDspSysInstallCb(h, onb, "sym", amCmd, "rewind",NULL );
|
cmDspSysInstallCb(h, onb, "sym", amCmd, "rewind",NULL );
|
||||||
cmDspSysInstallCb(h, onb, "out", achan0,"reset", NULL );
|
cmDspSysInstallCb(h, onb, "out", achan0,"reset", NULL );
|
||||||
cmDspSysInstallCb(h, onb, "out", achan1,"reset", NULL );
|
cmDspSysInstallCb(h, onb, "out", achan1,"reset", NULL );
|
||||||
@ -493,7 +502,8 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
|
|||||||
cmDspSysInstallCb(h, mip, "d0", sfp, "d0", NULL );
|
cmDspSysInstallCb(h, mip, "d0", sfp, "d0", NULL );
|
||||||
cmDspSysInstallCb(h, mip, "status", sfp, "status", NULL );
|
cmDspSysInstallCb(h, mip, "status", sfp, "status", NULL );
|
||||||
|
|
||||||
// score follower to modulator and printers
|
// score follower to recd_play,modulator and printers
|
||||||
|
cmDspSysInstallCb(h, sfp, "out", rpp, "index", NULL );
|
||||||
cmDspSysInstallCb(h, sfp, "out", modp, "index", NULL );
|
cmDspSysInstallCb(h, sfp, "out", modp, "index", NULL );
|
||||||
cmDspSysInstallCb(h, sfp, "recent", prp, "in", NULL ); // report 'recent' but only act on 'max' loc index
|
cmDspSysInstallCb(h, sfp, "recent", prp, "in", NULL ); // report 'recent' but only act on 'max' loc index
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user