|
@@ -1193,6 +1193,87 @@ cmTlMidiFile_t* cmTimeLineFindMidiFile( cmTlH_t h, const cmChar_t* fn )
|
1193
|
1193
|
return NULL;
|
1194
|
1194
|
}
|
1195
|
1195
|
|
|
1196
|
+_cmTlObj_t* _cmTimeLineObjAtTime( _cmTl_t* p, unsigned seqId, unsigned seqSmpIdx, unsigned typeId )
|
|
1197
|
+{
|
|
1198
|
+ assert( seqId < p->seqCnt );
|
|
1199
|
+ _cmTlObj_t* op = p->seq[seqId].first;
|
|
1200
|
+ _cmTlObj_t* min_op = NULL;
|
|
1201
|
+ unsigned minDist = UINT_MAX;
|
|
1202
|
+
|
|
1203
|
+ for(; op!=NULL; op=op->next)
|
|
1204
|
+ if( typeId==cmInvalidId || op->obj->typeId == typeId )
|
|
1205
|
+ {
|
|
1206
|
+ // if seqSmpIdx is inside this object - then return it as the solution
|
|
1207
|
+ if((op->obj->seqSmpIdx <= seqSmpIdx && seqSmpIdx < (op->obj->seqSmpIdx + op->obj->durSmpCnt)))
|
|
1208
|
+ return op;
|
|
1209
|
+
|
|
1210
|
+ // measure the distance from seqSmpIdx to the begin and end of this object
|
|
1211
|
+ unsigned d0 = op->obj->seqSmpIdx < seqSmpIdx ? seqSmpIdx - op->obj->seqSmpIdx : op->obj->seqSmpIdx - seqSmpIdx;
|
|
1212
|
+ unsigned d1 = op->obj->seqSmpIdx+op->obj->durSmpCnt < seqSmpIdx ? seqSmpIdx - op->obj->seqSmpIdx+op->obj->durSmpCnt : op->obj->seqSmpIdx+op->obj->durSmpCnt - seqSmpIdx;
|
|
1213
|
+
|
|
1214
|
+ // d0 and d1 should decrease as the cur object approaches seqSmpIdx
|
|
1215
|
+ // If they do not then the search is over - return the closest point.
|
|
1216
|
+ if( d0>minDist && d1>minDist)
|
|
1217
|
+ break;
|
|
1218
|
+
|
|
1219
|
+ // track the min dist and the assoc'd obj
|
|
1220
|
+ if( d0 < minDist )
|
|
1221
|
+ {
|
|
1222
|
+ minDist = d0;
|
|
1223
|
+ min_op = op;
|
|
1224
|
+ }
|
|
1225
|
+
|
|
1226
|
+ if( d1 < minDist )
|
|
1227
|
+ {
|
|
1228
|
+ minDist = d1;
|
|
1229
|
+ min_op = op;
|
|
1230
|
+ }
|
|
1231
|
+
|
|
1232
|
+ }
|
|
1233
|
+
|
|
1234
|
+ return min_op;
|
|
1235
|
+}
|
|
1236
|
+
|
|
1237
|
+cmTlAudioFile_t* cmTimeLineAudioFileAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx )
|
|
1238
|
+{
|
|
1239
|
+ _cmTl_t* p = _cmTlHandleToPtr(h);
|
|
1240
|
+ _cmTlObj_t* op;
|
|
1241
|
+ if((op = _cmTimeLineObjAtTime(p,seqId,seqSmpIdx,kAudioFileTlId)) == NULL )
|
|
1242
|
+ return NULL;
|
|
1243
|
+
|
|
1244
|
+ return _cmTlAudioFileObjPtr(p,op->obj,false);
|
|
1245
|
+}
|
|
1246
|
+
|
|
1247
|
+cmTlMidiFile_t* cmTimeLineMidiFileAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx )
|
|
1248
|
+{
|
|
1249
|
+ _cmTl_t* p = _cmTlHandleToPtr(h);
|
|
1250
|
+ _cmTlObj_t* op;
|
|
1251
|
+ if((op = _cmTimeLineObjAtTime(p,seqId,seqSmpIdx,kMidiFileTlId)) == NULL )
|
|
1252
|
+ return NULL;
|
|
1253
|
+
|
|
1254
|
+ return _cmTlMidiFileObjPtr(p,op->obj,false);
|
|
1255
|
+}
|
|
1256
|
+
|
|
1257
|
+cmTlMidiEvt_t* cmTimeLineMidiEvtAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx )
|
|
1258
|
+{
|
|
1259
|
+ _cmTl_t* p = _cmTlHandleToPtr(h);
|
|
1260
|
+ _cmTlObj_t* op;
|
|
1261
|
+ if((op = _cmTimeLineObjAtTime(p,seqId,seqSmpIdx,kMidiEvtTlId)) == NULL )
|
|
1262
|
+ return NULL;
|
|
1263
|
+
|
|
1264
|
+ return _cmTlMidiEvtObjPtr(p,op->obj,false);
|
|
1265
|
+}
|
|
1266
|
+
|
|
1267
|
+cmTlMarker_t* cmTimeLineMarkerAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx )
|
|
1268
|
+{
|
|
1269
|
+ _cmTl_t* p = _cmTlHandleToPtr(h);
|
|
1270
|
+ _cmTlObj_t* op;
|
|
1271
|
+ if((op = _cmTimeLineObjAtTime(p,seqId,seqSmpIdx,kMarkerTlId)) == NULL )
|
|
1272
|
+ return NULL;
|
|
1273
|
+
|
|
1274
|
+ return _cmTlMarkerObjPtr(p,op->obj,false);
|
|
1275
|
+}
|
|
1276
|
+
|
1196
|
1277
|
|
1197
|
1278
|
cmTlRC_t _cmTlParseErr( cmErr_t* err, const cmChar_t* errLabelPtr, unsigned idx, const cmChar_t* fn )
|
1198
|
1279
|
{
|