cmTimeLine.c : _cmTimeLineObjAtTime() changed such that when an object contains

the search point that the returned object also contains the search point.
The returned object will be the one containing the search point whose begin or
end point is closest to the search point.
This commit is contained in:
kevin 2016-08-24 13:59:03 -04:00
parent bd1d645e81
commit caffeb4b0a

View File

@ -134,7 +134,7 @@ cmTlMidiFile_t* _cmTlMidiFileObjPtr( _cmTl_t* p, cmTlObj_t* op, bool errFl )
if( op==NULL || op->typeId != kMidiFileTlId ) if( op==NULL || op->typeId != kMidiFileTlId )
{ {
if( errFl && p != NULL) if( errFl && p != NULL)
cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion failed."); cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion to MIDI file failed.");
return NULL; return NULL;
} }
@ -147,7 +147,7 @@ cmTlMidiEvt_t* _cmTlMidiEvtObjPtr( _cmTl_t* p, cmTlObj_t* op, bool errFl )
if( op==NULL || op->typeId != kMidiEvtTlId ) if( op==NULL || op->typeId != kMidiEvtTlId )
{ {
if( errFl && p != NULL ) if( errFl && p != NULL )
cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion failed."); cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion to MIDI event failed.");
return NULL; return NULL;
} }
@ -173,7 +173,7 @@ cmTlAudioEvt_t* _cmTlAudioEvtObjPtr( _cmTl_t* p, cmTlObj_t* op, bool errFl )
if( op==NULL || op->typeId != kAudioEvtTlId ) if( op==NULL || op->typeId != kAudioEvtTlId )
{ {
if( errFl && p != NULL) if( errFl && p != NULL)
cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion failed."); cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion to audio event failed.");
return NULL; return NULL;
} }
return (cmTlAudioEvt_t*)op; return (cmTlAudioEvt_t*)op;
@ -186,7 +186,7 @@ cmTlMarker_t* _cmTlMarkerObjPtr( _cmTl_t* p, cmTlObj_t* op, bool errFl )
if( op==NULL || op->typeId != kMarkerTlId ) if( op==NULL || op->typeId != kMarkerTlId )
{ {
if( errFl && p != NULL) if( errFl && p != NULL)
cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion failed."); cmErrMsg(&p->err,kTypeCvtFailTlRC,"A time line object type promotion to marker object failed.");
return NULL; return NULL;
} }
return (cmTlMarker_t*)op; return (cmTlMarker_t*)op;
@ -1227,31 +1227,37 @@ _cmTlObj_t* _cmTimeLineObjAtTime( _cmTl_t* p, unsigned seqId, unsigned seqSmpIdx
_cmTlObj_t* op = p->seq[seqId].first; _cmTlObj_t* op = p->seq[seqId].first;
_cmTlObj_t* min_op = NULL; _cmTlObj_t* min_op = NULL;
unsigned minDist = UINT_MAX; unsigned minDist = UINT_MAX;
bool inFl = false;
// for each object in the requested sequence
for(; op!=NULL; op=op->next) for(; op!=NULL; op=op->next)
if( typeId==cmInvalidId || op->obj->typeId == typeId ) if( typeId==cmInvalidId || op->obj->typeId == typeId )
{ {
// if seqSmpIdx is inside this object - then return it as the solution bool in0Fl = false;
// if seqSmpIdx is inside this object - then the returned object must contain seqSmpIdx
// (but the ideal point to return is the one which contains seqSmpIdx and also has
// a begin or end point very close to seqSmpIdx - so this defer selecting an object
// until all objects which may contain seqSmpIdx have been examined
if((op->obj->seqSmpIdx <= seqSmpIdx && seqSmpIdx < (op->obj->seqSmpIdx + op->obj->durSmpCnt))) if((op->obj->seqSmpIdx <= seqSmpIdx && seqSmpIdx < (op->obj->seqSmpIdx + op->obj->durSmpCnt)))
return op; {
inFl = true; // the returned object must contain seqSmpIdx
in0Fl = true; // this object contains seqSmpIdx
}
// measure the distance from seqSmpIdx to the begin and end of this object // measure the distance from seqSmpIdx to the begin and end of this object
unsigned d0 = op->obj->seqSmpIdx < seqSmpIdx ? seqSmpIdx - op->obj->seqSmpIdx : op->obj->seqSmpIdx - seqSmpIdx; unsigned d0 = op->obj->seqSmpIdx < seqSmpIdx ? seqSmpIdx - op->obj->seqSmpIdx : op->obj->seqSmpIdx - seqSmpIdx;
unsigned d1 = op->obj->seqSmpIdx+op->obj->durSmpCnt < seqSmpIdx ? seqSmpIdx - op->obj->seqSmpIdx+op->obj->durSmpCnt : op->obj->seqSmpIdx+op->obj->durSmpCnt - seqSmpIdx; unsigned d1 = op->obj->seqSmpIdx+op->obj->durSmpCnt < seqSmpIdx ? seqSmpIdx - op->obj->seqSmpIdx+op->obj->durSmpCnt : op->obj->seqSmpIdx+op->obj->durSmpCnt - seqSmpIdx;
// d0 and d1 should decrease as the cur object approaches seqSmpIdx
// If they do not then the search is over - return the closest point.
if( d0>minDist && d1>minDist)
break;
// track the min dist and the assoc'd obj // track the min dist and the assoc'd obj
if( d0 < minDist ) if( d0 < minDist && (inFl==false || inFl==in0Fl))
{ {
minDist = d0; minDist = d0;
min_op = op; min_op = op;
} }
if( d1 < minDist ) if( d1 < minDist && (inFl==false || inFl==in0Fl))
{ {
minDist = d1; minDist = d1;
min_op = op; min_op = op;