|
@@ -31,9 +31,11 @@ typedef struct cmScTrkMidiTsb_str
|
31
|
31
|
// Score Tracking info. from a single take (time-line marker)
|
32
|
32
|
typedef struct cmScTrkTakeTsb_str
|
33
|
33
|
{
|
34
|
|
- unsigned markerUid; // marker time line uid assoc'd with this take
|
|
34
|
+ unsigned tlMarkerUid; // marker time line uid assoc'd with this take
|
35
|
35
|
cmScTrkMidiTsb_t* midiV; // midiV[midiN] score to midi file map recd. array.
|
36
|
|
- unsigned midiN;
|
|
36
|
+ unsigned midiN;
|
|
37
|
+ unsigned minMuid; // min MIDI muid in midiV[]
|
|
38
|
+ unsigned maxMuid; // max MIDI muid in midiV[]
|
37
|
39
|
bool failFl;
|
38
|
40
|
} cmScTrkTakeTsb_t;
|
39
|
41
|
|
|
@@ -45,35 +47,28 @@ enum
|
45
|
47
|
};
|
46
|
48
|
|
47
|
49
|
//
|
48
|
|
-typedef struct cmMidiEvt_str
|
|
50
|
+typedef struct cmMidiTsb_str
|
49
|
51
|
{
|
50
|
52
|
unsigned srcId; // marker uid or -1 if this event was manually inserted
|
|
53
|
+ unsigned scEvtIdx; // score event assocd with this midi event
|
51
|
54
|
unsigned flags; // note | pedal | enable
|
52
|
|
- struct cmMidiEvt_str* ref; // previous MIDI event in time
|
|
55
|
+ struct cmMidiTsb_str* ref; // previous MIDI event in time
|
53
|
56
|
unsigned offsetSmp; // time offset from *ref
|
54
|
57
|
unsigned durSmp; // duration of this MIDI event
|
55
|
58
|
unsigned d0; // d0 MIDI channel msg data.
|
56
|
59
|
unsigned d1; // d1 MIDI channel msg data
|
57
|
|
- struct cmMidiEvt_str* link; // pointer to next MIDI event in list
|
58
|
|
-} cmMidiEvt_t;
|
59
|
|
-
|
60
|
|
-// This record represents a note or pedal score event
|
61
|
|
-typedef struct cmScEvtTsb_str
|
62
|
|
-{
|
63
|
|
- unsigned flags; // note | pedal
|
64
|
|
- unsigned scEvtIdx; // score event index (into scH)
|
65
|
|
- cmMidiEvt_t* evtList; // list of alternate MIDI events which may render this event
|
66
|
|
-} cmScEvtTsb_t;
|
|
60
|
+ struct cmMidiTsb_str* link; // pointer to next MIDI event in list
|
|
61
|
+} cmMidiTsb_t;
|
67
|
62
|
|
68
|
63
|
// This record contains all the score events and and score synchronized MIDI events
|
69
|
64
|
// associated with a given take. Each call to cmTakeSeqBldrLoadTake() creates
|
70
|
65
|
// one of these records.
|
71
|
|
-typedef struct cmTakeScEvtArrayTsb_str
|
|
66
|
+typedef struct cmTakeTsb_str
|
72
|
67
|
{
|
73
|
|
- unsigned tlMarkerUid; // time-line marker uid associated with this take
|
74
|
|
- cmScEvtTsb_t* scEvtV; // scEvtV[scEvtN] array of score events contained by this take
|
75
|
|
- unsigned scEvtN; // count of score events in this take
|
76
|
|
-} cmTakeScEvtArrayTsb_t;
|
|
68
|
+ unsigned tlMarkerUid; // time-line marker uid associated with this take
|
|
69
|
+ cmMidiTsb_t* midi; // midi events contained by this take
|
|
70
|
+ struct cmTakeTsb_str* link;
|
|
71
|
+} cmTakeTsb_t;
|
77
|
72
|
|
78
|
73
|
typedef struct
|
79
|
74
|
{
|
|
@@ -89,10 +84,10 @@ typedef struct
|
89
|
84
|
cmScTrkTakeTsb_t* scTrkTakeV; // score tracker scTrkTakeV[ scTrkTakeN ]
|
90
|
85
|
unsigned scTrkTakeN;
|
91
|
86
|
|
92
|
|
- cmTakeScEvtArrayTsb_t* takes; // list of scEvt arrays used by this sequence
|
93
|
|
- cmTakeScEvtArrayTsb_t* manual; // list of manually inserted MIDI events
|
|
87
|
+ cmTakeTsb_t* takes; // list of loaded takes
|
|
88
|
+ cmTakeTsb_t* manual; // list of manually inserted MIDI events
|
94
|
89
|
|
95
|
|
- cmTakeScEvtArrayTsb_t* out; // render list
|
|
90
|
+ cmTakeTsb_t* out; // render list
|
96
|
91
|
|
97
|
92
|
} cmTsb_t;
|
98
|
93
|
|
|
@@ -134,6 +129,44 @@ cmTsbRC_t _cmTsbScoreTrkFree( cmTsb_t* p )
|
134
|
129
|
}
|
135
|
130
|
|
136
|
131
|
|
|
132
|
+// Free a take record. Note that the record must be unlinked
|
|
133
|
+// unlinked from p->takes (See _cmTakeTsbUnlink().) prior to calling this function.
|
|
134
|
+void _cmTsbTakeFree( cmTsb_t* p, cmTakeTsb_t* t )
|
|
135
|
+{
|
|
136
|
+ cmMidiTsb_t* m = t->midi;
|
|
137
|
+
|
|
138
|
+ while( m != NULL )
|
|
139
|
+ {
|
|
140
|
+ cmMidiTsb_t* nm = m->link;
|
|
141
|
+ cmMemFree(m);
|
|
142
|
+ m = nm;
|
|
143
|
+ }
|
|
144
|
+
|
|
145
|
+ cmMemFree(t);
|
|
146
|
+}
|
|
147
|
+
|
|
148
|
+// Unlink a 'take' record from p->takes.
|
|
149
|
+cmTakeTsb_t* _cmTsbTakeUnlink( cmTsb_t* p, cmTakeTsb_t* t )
|
|
150
|
+{
|
|
151
|
+ cmTakeTsb_t* t0 = NULL;
|
|
152
|
+ cmTakeTsb_t* t1 = p->takes;
|
|
153
|
+
|
|
154
|
+ while( t1 != NULL )
|
|
155
|
+ {
|
|
156
|
+ if( t1 == t )
|
|
157
|
+ {
|
|
158
|
+ if( t0 == NULL )
|
|
159
|
+ p->takes = t->link;
|
|
160
|
+ else
|
|
161
|
+ t0->link = t1->link;
|
|
162
|
+
|
|
163
|
+ return t;
|
|
164
|
+ }
|
|
165
|
+ }
|
|
166
|
+ return NULL;
|
|
167
|
+}
|
|
168
|
+
|
|
169
|
+
|
137
|
170
|
cmTsbRC_t _cmTsbFree( cmTsb_t* p )
|
138
|
171
|
{
|
139
|
172
|
cmTsbRC_t rc = kOkTsbRC;
|
|
@@ -141,12 +174,39 @@ cmTsbRC_t _cmTsbFree( cmTsb_t* p )
|
141
|
174
|
if((rc = _cmTsbScoreTrkFree(p)) != kOkTsbRC )
|
142
|
175
|
goto errLabel;
|
143
|
176
|
|
|
177
|
+ cmTakeTsb_t* t = p->takes;
|
|
178
|
+
|
|
179
|
+ while( t != NULL )
|
|
180
|
+ {
|
|
181
|
+ cmTakeTsb_t* nt = t->link;
|
|
182
|
+ _cmTsbTakeFree(p,t);
|
|
183
|
+ t = nt;
|
|
184
|
+ }
|
|
185
|
+
|
144
|
186
|
cmMemFree(p);
|
145
|
187
|
|
146
|
188
|
errLabel:
|
147
|
189
|
return rc;
|
148
|
190
|
}
|
149
|
191
|
|
|
192
|
+cmScTrkTakeTsb_t* _cmTsbMarkerIdToScTrkTake( cmTsb_t* p, unsigned markerUid )
|
|
193
|
+{
|
|
194
|
+ unsigned i;
|
|
195
|
+ for(i=0; p->scTrkTakeN; ++i)
|
|
196
|
+ if( p->scTrkTakeV[i].tlMarkerUid == markerUid )
|
|
197
|
+ return p->scTrkTakeV + i;
|
|
198
|
+ return NULL;
|
|
199
|
+}
|
|
200
|
+
|
|
201
|
+cmScTrkMidiTsb_t* _cmTsbMuidToScTrkMidi( cmScTrkTakeTsb_t* t, unsigned muid )
|
|
202
|
+{
|
|
203
|
+ unsigned i;
|
|
204
|
+ for(i=0; i<t->midiN; ++i)
|
|
205
|
+ if( t->midiV[i].muid == muid )
|
|
206
|
+ return t->midiV + i;
|
|
207
|
+ return NULL;
|
|
208
|
+}
|
|
209
|
+
|
150
|
210
|
|
151
|
211
|
cmTsbRC_t _cmTsbLoadScoreTrkFile( cmTsb_t* p, const cmChar_t* scoreTrkFn )
|
152
|
212
|
{
|
|
@@ -188,9 +248,10 @@ cmTsbRC_t _cmTsbLoadScoreTrkFile( cmTsb_t* p, const cmChar_t* scoreTrkFn )
|
188
|
248
|
// for each take record
|
189
|
249
|
for(i=0; i<p->scTrkTakeN; ++i)
|
190
|
250
|
{
|
191
|
|
- cmJsonNode_t* takeObj = NULL;
|
192
|
|
- cmJsonNode_t* noteArrObj = NULL;
|
193
|
|
- unsigned j;
|
|
251
|
+ cmJsonNode_t* takeObj = NULL;
|
|
252
|
+ cmJsonNode_t* noteArrObj = NULL;
|
|
253
|
+ cmScTrkTakeTsb_t* t = p->scTrkTakeV + i;
|
|
254
|
+ unsigned j;
|
194
|
255
|
|
195
|
256
|
// get a pointer to the take record JSON object
|
196
|
257
|
if((takeObj = cmJsonArrayElement(tkArrObj,i)) == NULL )
|
|
@@ -201,8 +262,8 @@ cmTsbRC_t _cmTsbLoadScoreTrkFile( cmTsb_t* p, const cmChar_t* scoreTrkFn )
|
201
|
262
|
|
202
|
263
|
// parse the take record
|
203
|
264
|
if((jsRC = cmJsonMemberValues( takeObj, &errMsg,
|
204
|
|
- "markerUid",kIntTId, &p->scTrkTakeV[i].markerUid,
|
205
|
|
- "failFl", kIntTId, &p->scTrkTakeV[i].failFl,
|
|
265
|
+ "markerUid",kIntTId, &t->tlMarkerUid,
|
|
266
|
+ "failFl", kIntTId, &t->failFl,
|
206
|
267
|
"array", kArrayTId, ¬eArrObj,
|
207
|
268
|
NULL)) != kOkJsRC )
|
208
|
269
|
{
|
|
@@ -215,13 +276,15 @@ cmTsbRC_t _cmTsbLoadScoreTrkFile( cmTsb_t* p, const cmChar_t* scoreTrkFn )
|
215
|
276
|
}
|
216
|
277
|
|
217
|
278
|
// get the count of note records
|
218
|
|
- p->scTrkTakeV[i].midiN = cmJsonChildCount(noteArrObj);
|
|
279
|
+ t->midiN = cmJsonChildCount(noteArrObj);
|
219
|
280
|
|
220
|
281
|
// allocate a note record array for this take
|
221
|
|
- p->scTrkTakeV[i].midiV = cmMemAllocZ(cmScTrkMidiTsb_t, p->scTrkTakeV[i].midiN);
|
|
282
|
+ t->midiV = cmMemAllocZ(cmScTrkMidiTsb_t, t->midiN);
|
|
283
|
+ t->minMuid = INT_MAX;
|
|
284
|
+ t->maxMuid = 0;
|
222
|
285
|
|
223
|
286
|
// for each note record
|
224
|
|
- for(j=0; j<p->scTrkTakeV[i].midiN; ++j)
|
|
287
|
+ for(j=0; j<t->midiN; ++j)
|
225
|
288
|
{
|
226
|
289
|
cmJsonNode_t* noteObj = NULL;
|
227
|
290
|
|
|
@@ -234,10 +297,10 @@ cmTsbRC_t _cmTsbLoadScoreTrkFile( cmTsb_t* p, const cmChar_t* scoreTrkFn )
|
234
|
297
|
|
235
|
298
|
// parse the note record
|
236
|
299
|
if((jsRC = cmJsonMemberValues( noteObj, &errMsg,
|
237
|
|
- "mni", kIntTId, &p->scTrkTakeV[i].midiV[j].mni,
|
238
|
|
- "muid", kIntTId, &p->scTrkTakeV[i].midiV[j].muid,
|
239
|
|
- "scEvtIdx", kIntTId, &p->scTrkTakeV[i].midiV[j].scEvtIdx,
|
240
|
|
- "flags", kIntTId, &p->scTrkTakeV[i].midiV[j].flags,
|
|
300
|
+ "mni", kIntTId, &t->midiV[j].mni,
|
|
301
|
+ "muid", kIntTId, &t->midiV[j].muid,
|
|
302
|
+ "scEvtIdx", kIntTId, &t->midiV[j].scEvtIdx,
|
|
303
|
+ "flags", kIntTId, &t->midiV[j].flags,
|
241
|
304
|
NULL)) != kOkJsRC )
|
242
|
305
|
{
|
243
|
306
|
if( jsRC == kNodeNotFoundJsRC && errMsg != NULL )
|
|
@@ -247,6 +310,13 @@ cmTsbRC_t _cmTsbLoadScoreTrkFile( cmTsb_t* p, const cmChar_t* scoreTrkFn )
|
247
|
310
|
|
248
|
311
|
goto errLabel;
|
249
|
312
|
}
|
|
313
|
+
|
|
314
|
+ if( t->midiV[j].muid < t->minMuid )
|
|
315
|
+ t->minMuid = t->midiV[j].muid;
|
|
316
|
+
|
|
317
|
+ if( t->midiV[j].muid > t->maxMuid )
|
|
318
|
+ t->maxMuid = t->midiV[j].muid;
|
|
319
|
+
|
250
|
320
|
}
|
251
|
321
|
}
|
252
|
322
|
|
|
@@ -257,31 +327,6 @@ cmTsbRC_t _cmTsbLoadScoreTrkFile( cmTsb_t* p, const cmChar_t* scoreTrkFn )
|
257
|
327
|
return rc;
|
258
|
328
|
}
|
259
|
329
|
|
260
|
|
-// Return the count of score events inside a given marker.
|
261
|
|
-unsigned _cmTsbScoreTrkMarkerEventCount( cmTsb_t* p, unsigned markUid )
|
262
|
|
-{
|
263
|
|
- unsigned i,j;
|
264
|
|
- unsigned minScEvtIdx = INT_MAX;
|
265
|
|
- unsigned maxScEvtIdx = 0;
|
266
|
|
-
|
267
|
|
- for(i=0; i<p->scTrkTakeN; ++i)
|
268
|
|
- for(j=0; j<p->scTrkTakeV[i].midiN; ++j)
|
269
|
|
- if( p->scTrkTakeV[i].midiV[j].scEvtIdx != cmInvalidIdx )
|
270
|
|
- {
|
271
|
|
- if( p->scTrkTakeV[i].midiV[j].scEvtIdx < minScEvtIdx )
|
272
|
|
- minScEvtIdx = p->scTrkTakeV[i].midiV[j].scEvtIdx;
|
273
|
|
-
|
274
|
|
- if( p->scTrkTakeV[i].midiV[j].scEvtIdx > maxScEvtIdx )
|
275
|
|
- maxScEvtIdx = p->scTrkTakeV[i].midiV[j].scEvtIdx;
|
276
|
|
- }
|
277
|
|
-
|
278
|
|
- if( maxScEvtIdx < minScEvtIdx )
|
279
|
|
- return 0;
|
280
|
|
-
|
281
|
|
- return (maxScEvtIdx - minScEvtIdx) + 1;
|
282
|
|
-
|
283
|
|
-}
|
284
|
|
-
|
285
|
330
|
cmTsbRC_t cmTakeSeqBldrAlloc( cmCtx_t* ctx, cmTakeSeqBldrH_t* hp )
|
286
|
331
|
{
|
287
|
332
|
cmTsbRC_t rc;
|
|
@@ -359,6 +404,15 @@ cmTsbRC_t cmTakeSeqBldrInitialize( cmTakeSeqBldrH_t h, const cmChar_t* scoreTrkF
|
359
|
404
|
return rc;
|
360
|
405
|
}
|
361
|
406
|
|
|
407
|
+cmTakeTsb_t* _cmTsbMarkerUidToTake( cmTsb_t* p, unsigned tlMarkerUid )
|
|
408
|
+{
|
|
409
|
+ cmTakeTsb_t* t = p->takes;
|
|
410
|
+ for(; t != NULL; t=t->link)
|
|
411
|
+ if( t->tlMarkerUid == tlMarkerUid )
|
|
412
|
+ return t;
|
|
413
|
+ return NULL;
|
|
414
|
+}
|
|
415
|
+
|
362
|
416
|
cmTsbRC_t cmTakeSeqBldrLoadTake( cmTakeSeqBldrH_t h, unsigned tlMarkUid, bool overwriteFL )
|
363
|
417
|
{
|
364
|
418
|
cmTsbRC_t rc = kOkTsbRC;
|
|
@@ -366,26 +420,28 @@ cmTsbRC_t cmTakeSeqBldrLoadTake( cmTakeSeqBldrH_t h, unsigned tlMarkUid, bool ov
|
366
|
420
|
cmTlMarker_t* mark = NULL;
|
367
|
421
|
cmTlMidiFile_t* mf = NULL;
|
368
|
422
|
cmMidiFileH_t mfH = cmMidiFileNullHandle;
|
369
|
|
- unsigned scEvtN = 0;
|
370
|
|
- cmScEvtTsb_t* scEvtV = NULL;
|
|
423
|
+ cmScTrkTakeTsb_t* stt = NULL;
|
371
|
424
|
|
372
|
|
- // get a pointer to the time-line marker object
|
373
|
|
- if((mark = cmTlMarkerObjPtr( p->tlH, cmTimeLineIdToObj( p->tlH, cmInvalidId, tlMarkUid))) == NULL )
|
|
425
|
+ // verify that the requested take has not already been loaded
|
|
426
|
+ if( _cmTsbMarkerUidToTake( p, tlMarkUid ) != NULL )
|
374
|
427
|
{
|
375
|
|
- rc = cmErrMsg(&p->err,kInvalidArgTsbRC,"The time-line marker uid '%i' is not valid.",tlMarkUid);
|
|
428
|
+ rc = cmErrMsg(&p->err,kInvalidArgTsbRC,"The take indicated by marker id %i has already been loaded.",tlMarkUid );
|
376
|
429
|
goto errLabel;
|
377
|
430
|
}
|
378
|
431
|
|
379
|
|
- // get the count of score events in the take marker
|
380
|
|
- if((scEvtN = _cmTsbScoreTrkMarkerEventCount(p,tlMarkUid)) == 0 )
|
|
432
|
+ // find the score tracked take for the requested marker
|
|
433
|
+ if((stt = _cmTsbMarkerIdToScTrkTake(p,tlMarkUid )) == NULL )
|
381
|
434
|
{
|
382
|
|
- rc = cmErrMsg(&p->err,kInvalidArgTsbRC,"The selected take marker does not appear to contain any score events.");
|
|
435
|
+ rc = cmErrMsg(&p->err,kInvalidArgTsbRC,"The score tracked take indicated by marker id %i could not be found.", tlMarkUid );
|
383
|
436
|
goto errLabel;
|
384
|
437
|
}
|
385
|
438
|
|
386
|
|
- // allocate a score event array
|
387
|
|
- scEvtV = cmMemAllocZ(cmScEvtTsb_t,scEvtN);
|
388
|
|
-
|
|
439
|
+ // get a pointer to the time-line marker object
|
|
440
|
+ if((mark = cmTlMarkerObjPtr( p->tlH, cmTimeLineIdToObj( p->tlH, cmInvalidId, tlMarkUid))) == NULL )
|
|
441
|
+ {
|
|
442
|
+ rc = cmErrMsg(&p->err,kInvalidArgTsbRC,"The time-line marker uid '%i' is not valid.",tlMarkUid);
|
|
443
|
+ goto errLabel;
|
|
444
|
+ }
|
389
|
445
|
|
390
|
446
|
// get the name of the MIDI file which contains the marker
|
391
|
447
|
if((mf = cmTimeLineMidiFileAtTime( p->tlH, mark->obj.seqId, mark->obj.seqSmpIdx )) == NULL )
|
|
@@ -407,56 +463,93 @@ cmTsbRC_t cmTakeSeqBldrLoadTake( cmTakeSeqBldrH_t h, unsigned tlMarkUid, bool ov
|
407
|
463
|
// calculate MIDI note and pedal durations (see cmMidiChMsg_t.durTicks)
|
408
|
464
|
cmMidiFileCalcNoteDurations( mfH );
|
409
|
465
|
|
410
|
|
- // convert the marker beg/end sample position to be relative to the MIDI file start time
|
411
|
|
- unsigned bsi = mark->obj.seqSmpIdx - mf->obj.seqSmpIdx;
|
412
|
|
- unsigned esi = mark->obj.seqSmpIdx + mark->obj.durSmpCnt - mf->obj.seqSmpIdx;
|
413
|
466
|
unsigned i = 0;
|
414
|
467
|
unsigned n = cmMidiFileMsgCount(mfH);
|
415
|
468
|
const cmMidiTrackMsg_t** a = cmMidiFileMsgArray(mfH);
|
416
|
469
|
|
417
|
|
- // seek to the first MIDI msg after sample index bsi in the MIDI file
|
418
|
|
- for(i=0; i<n; ++i)
|
419
|
|
- if( a[i]->dtick >= bsi )
|
420
|
|
- break;
|
|
470
|
+ // allocate and link a new take render record
|
|
471
|
+ cmTakeTsb_t* t = cmMemAllocZ(cmTakeTsb_t,1);
|
|
472
|
+
|
|
473
|
+ t->tlMarkerUid = tlMarkUid;
|
|
474
|
+ if( p->takes != NULL )
|
|
475
|
+ p->takes->link = t;
|
|
476
|
+
|
|
477
|
+ p->takes = t;
|
421
|
478
|
|
422
|
|
- // if bsi is after the file then the MIDI file finished before the marker
|
423
|
|
- if( i == n )
|
424
|
|
- {
|
425
|
|
- rc = cmErrMsg(&p->err,kInvalidArgTsbRC,"No MIDI events were found in the marker.");
|
426
|
|
- goto errLabel;
|
427
|
|
- }
|
428
|
479
|
|
429
|
|
- // for each MIDI message between bsi and esi
|
430
|
|
- for(; i<n && a[i]->dtick < esi; ++i)
|
|
480
|
+ cmMidiTsb_t* m0 = NULL;
|
|
481
|
+ const cmMidiTrackMsg_t* mf0 = NULL;
|
|
482
|
+
|
|
483
|
+ // for each MIDI message in the file
|
|
484
|
+ for(i=0; i<n; ++i)
|
431
|
485
|
{
|
432
|
|
- const cmMidiTrackMsg_t* m = a[i];
|
433
|
|
- switch( m->status )
|
|
486
|
+ const cmMidiTrackMsg_t* mf1 = a[i];
|
|
487
|
+
|
|
488
|
+ // we are only interested in rendering notes and control msgs
|
|
489
|
+ switch( mf1->status )
|
434
|
490
|
{
|
435
|
|
- case kNoteOffMdId:
|
436
|
491
|
case kNoteOnMdId:
|
437
|
|
- case kCtlMdId:
|
438
|
|
-
|
|
492
|
+ case kNoteOffMdId:
|
|
493
|
+ case kCtlMdId:
|
439
|
494
|
break;
|
|
495
|
+
|
|
496
|
+ default:
|
|
497
|
+ continue;
|
440
|
498
|
}
|
441
|
|
- }
|
|
499
|
+
|
|
500
|
+ // if this MIDI message is inside the tracked region of the take
|
|
501
|
+ if( stt->minMuid > mf1->uid || mf1->uid > stt->maxMuid )
|
|
502
|
+ continue;
|
442
|
503
|
|
|
504
|
+ // get a pointer to the tracking map
|
|
505
|
+ cmScTrkMidiTsb_t* stm = _cmTsbMuidToScTrkMidi(stt, mf1->uid );
|
443
|
506
|
|
|
507
|
+ // create a MIDI render event
|
|
508
|
+ cmMidiTsb_t* m1 = cmMemAllocZ(cmMidiTsb_t,1);
|
|
509
|
+
|
|
510
|
+ m1->srcId = tlMarkUid;
|
|
511
|
+ m1->scEvtIdx = stm != NULL ? stm->scEvtIdx : cmInvalidIdx;
|
|
512
|
+ m1->flags = stm != NULL ? stm->flags : 0;
|
|
513
|
+ m1->ref = m0;
|
|
514
|
+ m1->offsetSmp = mf0 == NULL ? 0 : mf1->dtick - mf0->dtick;
|
|
515
|
+ m1->durSmp = mf1->u.chMsgPtr->durTicks;
|
|
516
|
+ m1->d0 = mf1->u.chMsgPtr->d0;
|
|
517
|
+ m1->d1 = mf1->u.chMsgPtr->d1;
|
|
518
|
+ m1->link = NULL;
|
|
519
|
+
|
|
520
|
+ if( m0 != NULL )
|
|
521
|
+ m0->link = m1;
|
|
522
|
+
|
|
523
|
+ if( t->midi == NULL )
|
|
524
|
+ t->midi = m1;
|
|
525
|
+
|
|
526
|
+ m0 = m1;
|
|
527
|
+ mf0 = mf1;
|
|
528
|
+
|
|
529
|
+ }
|
444
|
530
|
|
445
|
531
|
errLabel:
|
446
|
532
|
if( cmMidiFileClose(&mfH) != kOkMfRC )
|
447
|
533
|
rc = cmErrMsg(&p->err,kMidiFileFailTsbRC,"MIDI file close failed.");
|
448
|
534
|
|
449
|
|
- if( rc != kOkTsbRC )
|
450
|
|
- {
|
451
|
|
- cmMemFree(scEvtV);
|
452
|
|
- }
|
453
|
|
-
|
454
|
535
|
return rc;
|
455
|
536
|
}
|
456
|
537
|
|
457
|
538
|
cmTsbRC_t cmTakeSeqBldrUnloadTake( cmTakeSeqBldrH_t h, unsigned tlMarkUid )
|
458
|
539
|
{
|
459
|
|
- cmTsbRC_t rc = kOkTsbRC;
|
|
540
|
+ cmTsbRC_t rc = kOkTsbRC;
|
|
541
|
+ cmTsb_t* p = _cmTsbHandleToPtr(h);
|
|
542
|
+ cmTakeTsb_t* t;
|
|
543
|
+
|
|
544
|
+ if((t = _cmTsbMarkerUidToTake(p, tlMarkUid )) == NULL )
|
|
545
|
+ return cmErrMsg(&p->err,kInvalidArgTsbRC,"The take indicated by marker id %i could not be found.",tlMarkUid);
|
|
546
|
+
|
|
547
|
+ t = _cmTsbTakeUnlink(p,t);
|
|
548
|
+
|
|
549
|
+ assert( t != NULL );
|
|
550
|
+
|
|
551
|
+ _cmTsbTakeFree(p,t);
|
|
552
|
+
|
460
|
553
|
return rc;
|
461
|
554
|
}
|
462
|
555
|
|