From caffeb4b0a9e3794732917ab59ca820f16565c26 Mon Sep 17 00:00:00 2001 From: kevin Date: Wed, 24 Aug 2016 13:59:03 -0400 Subject: [PATCH] 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. --- app/cmTimeLine.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/app/cmTimeLine.c b/app/cmTimeLine.c index bc381d0..9ebc521 100644 --- a/app/cmTimeLine.c +++ b/app/cmTimeLine.c @@ -134,7 +134,7 @@ cmTlMidiFile_t* _cmTlMidiFileObjPtr( _cmTl_t* p, cmTlObj_t* op, bool errFl ) if( op==NULL || op->typeId != kMidiFileTlId ) { 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; } @@ -147,7 +147,7 @@ cmTlMidiEvt_t* _cmTlMidiEvtObjPtr( _cmTl_t* p, cmTlObj_t* op, bool errFl ) if( op==NULL || op->typeId != kMidiEvtTlId ) { 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; } @@ -173,7 +173,7 @@ cmTlAudioEvt_t* _cmTlAudioEvtObjPtr( _cmTl_t* p, cmTlObj_t* op, bool errFl ) if( op==NULL || op->typeId != kAudioEvtTlId ) { 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 (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( 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 (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* min_op = NULL; unsigned minDist = UINT_MAX; - + bool inFl = false; + + // for each object in the requested sequence for(; op!=NULL; op=op->next) 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))) - 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 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; - // 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 - if( d0 < minDist ) + if( d0 < minDist && (inFl==false || inFl==in0Fl)) { minDist = d0; min_op = op; } - if( d1 < minDist ) + if( d1 < minDist && (inFl==false || inFl==in0Fl)) { minDist = d1; min_op = op;