Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/MD_package/MDSequence.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 181 - (show annotations) (download) (as text)
Sat Feb 29 15:29:29 2020 UTC (4 years, 2 months ago) by toshinagata1964
File MIME type: text/x-csrc
File size: 29802 byte(s)
Keyswitch will be sent while prerolling
1 /*
2 MDSequence.c
3 Created by Toshi Nagata, 2000.11.24.
4
5 Copyright (c) 2000-2016 Toshi Nagata. All rights reserved.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 2 of the License.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 */
16
17 #include "MDHeaders.h"
18
19 #include <stdio.h> /* for sprintf() */
20 #include <stdlib.h> /* for malloc(), realloc(), and free() */
21 #include <string.h> /* for memset() */
22 #include <limits.h> /* for LONG_MAX */
23 #include <pthread.h> /* for mutex */
24
25 #ifdef __MWERKS__
26 #pragma mark ====== Private definitions ======
27 #endif
28
29 struct MDSequence {
30 int32_t refCount; /* the reference count */
31 int32_t timebase; /* the timebase */
32 int32_t num; /* the number of tracks (including the conductor track) */
33 unsigned char single; /* non-zero if single channel mode */
34 MDArray * tracks; /* the array of tracks (the 0-th is the conductor track) */
35 MDCalibrator * calib; /* the first MDCalibrator related to this sequence */
36 /* MDMerger * merger; *//* the first MDMerger related to this sequence */
37 pthread_mutex_t *mutex; /* the mutex for lock/unlock */
38 };
39
40 #if 0
41 /* A private struct for MDMerger */
42 typedef struct MDMergerInfo {
43 MDTrack * track;
44 MDPointer * ptr;
45 MDEvent * eptr;
46 MDTickType tick;
47 MDTickType lastTick;
48 } MDMergerInfo;
49
50 struct MDMerger {
51 int32_t refCount;
52 MDSequence * sequence;
53 MDMerger * next;
54 int32_t currentTrack;
55 MDEvent * eptr;
56 MDTickType tick;
57 MDArray *info; // MDMergerInfo ��� array
58 };
59 #endif
60
61 #ifdef __MWERKS__
62 #pragma mark -
63 #pragma mark ====== MDSequence functions ======
64 #endif
65
66 #ifdef __MWERKS__
67 #pragma mark ====== New/Retain/Release ======
68 #endif
69
70 /* --------------------------------------
71 ��� MDSequenceNew
72 -------------------------------------- */
73 MDSequence *
74 MDSequenceNew(void)
75 {
76 MDSequence *newSequence = (MDSequence *)malloc(sizeof(*newSequence));
77 if (newSequence == NULL)
78 return NULL; /* out of memory */
79 memset(newSequence, 0, sizeof(MDSequence));
80 newSequence->num = 0;
81 newSequence->refCount = 1;
82 newSequence->timebase = 480;
83 newSequence->tracks = MDArrayNew(sizeof(MDTrack *));
84 if (newSequence->tracks == NULL) {
85 free(newSequence);
86 return NULL;
87 }
88 newSequence->calib = NULL;
89 return newSequence;
90 }
91
92 /* --------------------------------------
93 ��� MDSequenceRetain
94 -------------------------------------- */
95 void
96 MDSequenceRetain(MDSequence *inSequence)
97 {
98 inSequence->refCount++;
99 }
100
101 /* --------------------------------------
102 ��� MDSequenceRelease
103 -------------------------------------- */
104 void
105 MDSequenceRelease(MDSequence *inSequence)
106 {
107 if (--inSequence->refCount == 0) {
108
109 MDSequenceClear(inSequence);
110 MDArrayRelease(inSequence->tracks);
111
112 /* Remove the MDCache's from the linked list */
113 /* while (inSequence->calib != NULL)
114 MDCacheSetSequence(inSequence->cache, NULL);
115 */
116 free(inSequence);
117 }
118 }
119
120 /* --------------------------------------
121 ��� MDSequenceClear
122 -------------------------------------- */
123 void
124 MDSequenceClear(MDSequence *inSequence)
125 {
126 MDTrack *track;
127 int i;
128 if (inSequence->num != 0) {
129 for (i = 0; i < inSequence->num; i++) {
130 track = MDSequenceGetTrack(inSequence, i);
131 if (track != NULL) {
132 MDTrackClear(track);
133 MDTrackRelease(track);
134 }
135 }
136 MDArrayEmpty(inSequence->tracks);
137 inSequence->num = 0;
138 }
139 }
140
141 #ifdef __MWERKS__
142 #pragma mark ====== MDCalibrator manipulations ======
143 #endif
144
145 static void
146 MDSequenceRemoveCalibratorForTrack(MDSequence *inSequence, MDTrack *inTrack)
147 {
148 MDCalibrator *calib;
149 int index;
150 MDTrack *track;
151 if (inSequence == NULL || inTrack == NULL)
152 return;
153 for (calib = inSequence->calib; calib != NULL; calib = MDCalibratorNextInList(calib)) {
154 index = 0;
155 while (MDCalibratorGetInfo(calib, index, &track, NULL, NULL) == kMDNoError) {
156 if (track == inTrack) {
157 MDCalibratorRemoveAtIndex(calib, index);
158 } else index++;
159 }
160 }
161 }
162
163 void
164 MDSequenceAttachCalibrator(MDSequence *inSequence, MDCalibrator *inCalib)
165 {
166 if (inSequence == NULL || inCalib == NULL)
167 return;
168 MDCalibratorSetNextInList(inCalib, inSequence->calib);
169 inSequence->calib = inCalib;
170 }
171
172 void
173 MDSequenceDetachCalibrator(MDSequence *inSequence, MDCalibrator *inCalib)
174 {
175 MDCalibrator *curr, *prev, *next;
176 if (inSequence == NULL || inCalib == NULL)
177 return;
178 curr = inSequence->calib;
179 prev = NULL;
180 next = MDCalibratorNextInList(inCalib);
181 while (curr != NULL) {
182 if (curr == inCalib) {
183 if (prev == NULL) {
184 inSequence->calib = next;
185 } else {
186 MDCalibratorSetNextInList(prev, next);
187 }
188 break;
189 }
190 prev = curr;
191 curr = MDCalibratorNextInList(curr);
192 }
193 }
194
195 #ifdef __MWERKS__
196 #pragma mark ====== Accessor functions ======
197 #endif
198
199 /* --------------------------------------
200 ��� MDSequenceSetTimebase
201 -------------------------------------- */
202 void
203 MDSequenceSetTimebase(MDSequence *inSequence, int32_t inTimebase)
204 {
205 inSequence->timebase = inTimebase;
206 }
207
208 /* --------------------------------------
209 ��� MDSequenceGetTimebase
210 -------------------------------------- */
211 int32_t
212 MDSequenceGetTimebase(const MDSequence *inSequence)
213 {
214 return inSequence->timebase;
215 }
216
217 /* --------------------------------------
218 ��� MDSequenceGetNumberOfTracks
219 -------------------------------------- */
220 int32_t
221 MDSequenceGetNumberOfTracks(const MDSequence *inSequence)
222 {
223 return inSequence->num;
224 }
225
226 /* --------------------------------------
227 ��� MDSequenceGetDuration
228 -------------------------------------- */
229 MDTickType
230 MDSequenceGetDuration(const MDSequence *inSequence)
231 {
232 MDTrack *track;
233 int32_t n;
234 MDTickType duration, maxDuration;
235 maxDuration = 0;
236 for (n = inSequence->num - 1; n >= 0; n--) {
237 track = MDSequenceGetTrack(inSequence, n);
238 if (track != NULL) {
239 duration = MDTrackGetDuration(track);
240 if (duration > maxDuration)
241 maxDuration = duration;
242 }
243 }
244 return maxDuration;
245 }
246
247 /* --------------------------------------
248 ��� MDSequenceGetTrack
249 -------------------------------------- */
250 MDTrack *
251 MDSequenceGetTrack(const MDSequence *inSequence, int32_t index)
252 {
253 MDTrack *track;
254 if (MDArrayFetch(inSequence->tracks, index, 1, &track) == 1)
255 return track;
256 else return NULL;
257 }
258
259 /* --------------------------------------
260 ��� MDSequenceFindTrack
261 -------------------------------------- */
262 int32_t
263 MDSequenceFindTrack(const MDSequence *inSequence, const MDTrack *inTrack)
264 {
265 int32_t i;
266 for (i = 0; i < inSequence->num; i++) {
267 MDTrack *track;
268 MDArrayFetch(inSequence->tracks, i, 1, &track);
269 if (track == inTrack)
270 return i;
271 }
272 return -1;
273 }
274
275 #ifdef __MWERKS__
276 #pragma mark ====== MDTrack attribute manipulations ======
277 #endif
278
279 void
280 MDSequenceUpdateMuteBySoloFlag(MDSequence *inSequence)
281 {
282 MDTrack *track;
283 int32_t n, solo;
284 MDTrackAttribute attr;
285 solo = 0;
286 for (n = inSequence->num - 1; n >= 0; n--) {
287 track = MDSequenceGetTrack(inSequence, n);
288 if (track != NULL) {
289 attr = MDTrackGetAttribute(track);
290 if (attr & kMDTrackAttributeSolo)
291 solo++;
292 }
293 }
294 for (n = inSequence->num - 1; n >= 0; n--) {
295 track = MDSequenceGetTrack(inSequence, n);
296 if (track != NULL) {
297 attr = MDTrackGetAttribute(track);
298 if (solo > 0)
299 attr = (attr & ~kMDTrackAttributeMuteBySolo) |
300 ((attr & kMDTrackAttributeSolo) ? 0 : kMDTrackAttributeMuteBySolo);
301 else
302 attr = (attr & ~kMDTrackAttributeMuteBySolo);
303 MDTrackSetAttribute(track, attr);
304 }
305 }
306 }
307
308 /* --------------------------------------
309 ��� MDSequenceSetRecordFlagOnTrack
310 -------------------------------------- */
311 int
312 MDSequenceSetRecordFlagOnTrack(MDSequence *inSequence, int32_t index, int flag)
313 {
314 MDTrack *track;
315 int32_t n;
316 MDTrackAttribute attr, newAttr;
317 if (index < 0 || index >= inSequence->num || (track = MDSequenceGetTrack(inSequence, index)) == NULL)
318 return 0;
319 attr = MDTrackGetAttribute(track);
320 if (flag < 0)
321 attr ^= kMDTrackAttributeRecord;
322 else {
323 newAttr = (attr & ~kMDTrackAttributeRecord) | (flag ? kMDTrackAttributeRecord : 0);
324 if (newAttr == attr)
325 return 0;
326 attr = newAttr;
327 }
328 MDTrackSetAttribute(track, attr);
329 if (attr & kMDTrackAttributeRecord) {
330 for (n = inSequence->num - 1; n >= 0; n--) {
331 if (n == index || (track = MDSequenceGetTrack(inSequence, n)) == NULL)
332 continue;
333 attr = MDTrackGetAttribute(track);
334 attr &= ~kMDTrackAttributeRecord;
335 MDTrackSetAttribute(track, attr);
336 }
337 }
338 return 1;
339 }
340
341 /* --------------------------------------
342 ��� MDSequenceSetSoloFlagOnTrack
343 -------------------------------------- */
344 int
345 MDSequenceSetSoloFlagOnTrack(MDSequence *inSequence, int32_t index, int flag)
346 {
347 MDTrack *track;
348 MDTrackAttribute attr, newAttr;
349 if (index < 0 || index >= inSequence->num || (track = MDSequenceGetTrack(inSequence, index)) == NULL)
350 return 0;
351 attr = MDTrackGetAttribute(track);
352 if (flag < 0)
353 attr ^= kMDTrackAttributeSolo;
354 else {
355 newAttr = (attr & ~kMDTrackAttributeSolo) | (flag ? kMDTrackAttributeSolo : 0);
356 if (attr == newAttr)
357 return 0;
358 attr = newAttr;
359 }
360 MDTrackSetAttribute(track, attr);
361 MDSequenceUpdateMuteBySoloFlag(inSequence);
362 return 1;
363 }
364
365 /* --------------------------------------
366 ��� MDSequenceSetMuteFlagOnTrack
367 -------------------------------------- */
368 int
369 MDSequenceSetMuteFlagOnTrack(MDSequence *inSequence, int32_t index, int flag)
370 {
371 MDTrack *track;
372 MDTrackAttribute attr, newAttr;
373 if (index < 0 || index >= inSequence->num || (track = MDSequenceGetTrack(inSequence, index)) == NULL)
374 return 0;
375 attr = MDTrackGetAttribute(track);
376 if (flag < 0)
377 attr ^= kMDTrackAttributeMute;
378 else {
379 newAttr = (attr & ~kMDTrackAttributeMute) | (flag ? kMDTrackAttributeMute : 0);
380 if (attr == newAttr)
381 return 0;
382 attr = newAttr;
383 }
384 MDTrackSetAttribute(track, attr);
385 return 1;
386 }
387
388 /* --------------------------------------
389 ��� MDSequenceGetIndexOfRecordingTrack
390 -------------------------------------- */
391 int32_t
392 MDSequenceGetIndexOfRecordingTrack(MDSequence *inSequence)
393 {
394 int32_t index;
395 for (index = 0; index < inSequence->num; index++) {
396 MDTrack *track = MDSequenceGetTrack(inSequence, index);
397 if (track != NULL && (MDTrackGetAttribute(track) & kMDTrackAttributeRecord) != 0)
398 return index;
399 }
400 return -1;
401 }
402
403 #ifdef __MWERKS__
404 #pragma mark ====== MDTrack Insert/Delete ======
405 #endif
406
407 /* --------------------------------------
408 ��� MDSequenceInsertTrack
409 -------------------------------------- */
410 int32_t
411 MDSequenceInsertTrack(MDSequence *inSequence, int32_t index, MDTrack *inTrack)
412 {
413 if (index < -1)
414 index = 0;
415 else if (index == -1 || index > inSequence->num)
416 index = inSequence->num;
417 if (MDArrayInsert(inSequence->tracks, index, 1, &inTrack) == kMDNoError) {
418 inSequence->num++;
419 MDTrackRetain(inTrack);
420
421 /* Check track attributes */
422 if (MDTrackGetAttribute(inTrack) & kMDTrackAttributeRecord)
423 MDSequenceSetRecordFlagOnTrack(inSequence, index, 1);
424 MDSequenceUpdateMuteBySoloFlag(inSequence);
425
426 return index;
427 } else return -1;
428 }
429
430 /* --------------------------------------
431 ��� MDSequenceDeleteTrack
432 -------------------------------------- */
433 int32_t
434 MDSequenceDeleteTrack(MDSequence *inSequence, int32_t index)
435 {
436 MDTrack *track;
437 if (index < 0 || index >= inSequence->num)
438 return -1;
439 track = MDSequenceGetTrack(inSequence, index);
440 MDSequenceRemoveCalibratorForTrack(inSequence, track);
441 if (MDArrayDelete(inSequence->tracks, index, 1) == kMDNoError) {
442 inSequence->num--;
443 if (track != NULL)
444 MDTrackRelease(track);
445 MDSequenceUpdateMuteBySoloFlag(inSequence);
446 return index;
447 } else return -1;
448 }
449
450 /* --------------------------------------
451 ��� MDSequenceReplaceTrack
452 -------------------------------------- */
453 int32_t
454 MDSequenceReplaceTrack(MDSequence *inSequence, int32_t index, MDTrack *inTrack)
455 {
456 int32_t n;
457 if (index < 0 || index >= inSequence->num)
458 return -1;
459 n = MDSequenceDeleteTrack(inSequence, index);
460 if (n >= 0)
461 return MDSequenceInsertTrack(inSequence, index, inTrack);
462 else return n;
463 }
464
465 /* --------------------------------------
466 ��� MDSequenceResetCalibrators
467 -------------------------------------- */
468 void
469 MDSequenceResetCalibrators(MDSequence *inSequence)
470 {
471 MDCalibrator *calib;
472 for (calib = inSequence->calib; calib != NULL; calib = MDCalibratorNextInList(calib)) {
473 MDCalibratorReset(calib);
474 }
475 }
476
477 #ifdef __MWERKS__
478 #pragma mark ====== Single/Multi channel mode ======
479 #endif
480
481 /* --------------------------------------
482 ��� MDSequenceSingleChannelMode
483 -------------------------------------- */
484 MDStatus
485 MDSequenceSingleChannelMode(MDSequence *inSequence, int separate)
486 {
487 int32_t n;
488 int32_t nch[16];
489 MDStatus sts = kMDNoError;
490
491 if (inSequence == NULL)
492 return kMDNoError;
493
494 /* Pass 1: Separate multi-channel tracks */
495 if (separate) {
496 for (n = inSequence->num - 1; n >= 0; n--) {
497 MDTrack *track, *ntrack[16];
498 MDPointer *pt;
499 IntGroup *pset;
500 int nnch, i;
501 track = MDSequenceGetTrack(inSequence, n);
502 nnch = 0;
503 for (i = 0; i < 16; i++) {
504 nch[i] = MDTrackGetNumberOfChannelEvents(track, i);
505 if (nch[i] > 0)
506 nnch++;
507 }
508 if (nnch <= 1)
509 continue;
510 memset(ntrack, 0, sizeof(ntrack));
511 ntrack[0] = MDTrackNewFromTrack(track); /* Duplicate */
512 if (ntrack[0] == NULL)
513 return kMDErrorOutOfMemory;
514 pt = MDPointerNew(ntrack[0]);
515 pset = IntGroupNew();
516 if (pt == NULL || pset == NULL)
517 return kMDErrorOutOfMemory;
518 for (i = 15; i >= 1; i--) {
519 MDEvent *ep;
520 if (nch[i] == 0)
521 continue;
522 MDPointerSetPosition(pt, -1);
523 IntGroupClear(pset);
524 while ((ep = MDPointerForward(pt)) != NULL) {
525 if (MDIsChannelEvent(ep) && MDGetChannel(ep) == i) {
526 sts = IntGroupAdd(pset, MDPointerGetPosition(pt), 1);
527 if (sts != kMDNoError)
528 break;
529 }
530 }
531 if (sts == kMDNoError)
532 sts = MDTrackUnmerge(ntrack[0], &ntrack[i], pset);
533 if (sts == kMDNoError) {
534 nnch--;
535 if (nnch == 1)
536 break;
537 } else break;
538 }
539 IntGroupRelease(pset);
540 MDPointerRelease(pt);
541 if (sts == kMDNoError) {
542 for (i = 15; i >= 0; i--) {
543 if (ntrack[i] == NULL)
544 continue;
545 if (MDSequenceInsertTrack(inSequence, n + 1, ntrack[i]) < 0) {
546 sts = kMDErrorOutOfMemory;
547 break;
548 } else {
549 ntrack[i] = NULL;
550 }
551 }
552 }
553 if (sts == kMDNoError) {
554 MDSequenceDeleteTrack(inSequence, n);
555 } else {
556 /* Dispose all temporary objects and returns error */
557 for (i = 0; i < 16; i++) {
558 if (ntrack[i] != NULL)
559 MDTrackRelease(ntrack[i]);
560 }
561 return sts;
562 }
563 }
564 }
565
566 /* Pass 2: Remap all events to MIDI channel 0, and set the track channels */
567 for (n = inSequence->num - 1; n >= 0; n--) {
568 MDTrack *track;
569 int i, nnch;
570 unsigned char newch[16];
571 track = MDSequenceGetTrack(inSequence, n);
572 if (track == NULL)
573 continue;
574 memset(newch, 0, 16);
575 nnch = 0;
576 /* Set the track channel */
577 for (i = 0; i < 16; i++) {
578 if (MDTrackGetNumberOfChannelEvents(track, i) > 0) {
579 MDTrackSetTrackChannel(track, i);
580 if (separate && nnch++ > 0)
581 fprintf(stderr, "Warning: Internal inconsistency in function MDSequenceSingleChannelMode, file %s, line %d\n", __FILE__, __LINE__);
582 }
583 }
584 MDTrackRemapChannel(track, newch);
585 }
586
587 inSequence->single = 1;
588
589 return kMDNoError;
590 }
591
592 /* --------------------------------------
593 ��� MDSequenceMultiChannelMode
594 -------------------------------------- */
595 MDStatus
596 MDSequenceMultiChannelMode(MDSequence *inSequence)
597 {
598 int32_t n;
599 MDTrack *track;
600 unsigned char newch[16];
601 if (inSequence == NULL)
602 return kMDNoError;
603 memset(newch, 0, 16);
604 for (n = 0; n < inSequence->num; n++) {
605 track = MDSequenceGetTrack(inSequence, n);
606 if (track == NULL)
607 continue;
608 if (MDTrackGetNumberOfChannelEvents(track, -1) == 0)
609 continue;
610 newch[0] = MDTrackGetTrackChannel(track) & 15;
611 MDTrackRemapChannel(track, newch);
612 MDTrackSetTrackChannel(track, 0);
613 }
614 inSequence->single = 0;
615 return kMDNoError;
616 }
617
618 /* --------------------------------------
619 ��� MDSequenceIsSingleChannelMode
620 -------------------------------------- */
621 int
622 MDSequenceIsSingleChannelMode(const MDSequence *inSequence)
623 {
624 if (inSequence != NULL)
625 return (inSequence->single != 0);
626 else return 0;
627 }
628
629 #pragma mark ====== MDSequence Lock/Unlock ======
630
631 MDStatus
632 MDSequenceCreateMutex(MDSequence *inSequence)
633 {
634 int n;
635 if (inSequence == NULL)
636 return kMDErrorInternalError;
637 else if (inSequence->mutex != NULL)
638 return kMDErrorOnSequenceMutex;
639 else {
640 inSequence->mutex = (pthread_mutex_t *)calloc(sizeof(pthread_mutex_t), 1);
641 if (inSequence->mutex == NULL)
642 return kMDErrorOutOfMemory;
643 n = pthread_mutex_init(inSequence->mutex, NULL);
644 if (n != 0)
645 return kMDErrorOnSequenceMutex;
646 }
647 return kMDNoError;
648 }
649
650 MDStatus
651 MDSequenceDisposeMutex(MDSequence *inSequence)
652 {
653 int n;
654 if (inSequence == NULL || inSequence->mutex == NULL)
655 return kMDErrorInternalError;
656 n = pthread_mutex_destroy(inSequence->mutex);
657 free(inSequence->mutex);
658 inSequence->mutex = NULL;
659 if (n != 0)
660 return kMDErrorOnSequenceMutex;
661 else return kMDNoError;
662 }
663
664 void
665 MDSequenceLock(MDSequence *inSequence)
666 {
667 int n;
668 if (inSequence == NULL || inSequence->mutex == NULL)
669 return;
670 n = pthread_mutex_lock(inSequence->mutex);
671 }
672
673 void
674 MDSequenceUnlock(MDSequence *inSequence)
675 {
676 int n;
677 if (inSequence == NULL || inSequence->mutex == NULL)
678 return;
679 n = pthread_mutex_unlock(inSequence->mutex);
680 }
681
682 int
683 MDSequenceTryLock(MDSequence *inSequence)
684 {
685 int n;
686 if (inSequence == NULL || inSequence->mutex == NULL)
687 return 0;
688 n = pthread_mutex_trylock(inSequence->mutex);
689 if (n == 0)
690 return 0;
691 else if (n == EBUSY)
692 return 1;
693 else return -1;
694 }
695
696 #ifdef __MWERKS__
697 #pragma mark ====== MDMerger manipulations ======
698 #endif
699
700 #if 0
701 static void
702 MDSequenceAttachMerger(const MDSequence *inSequence, MDMerger *inMerger)
703 {
704 if (inSequence == NULL || inMerger == NULL)
705 return;
706 inMerger->next = inSequence->merger;
707
708 /* merger is a 'mutable' member, so this cast is acceptable */
709 ((MDSequence *)inSequence)->merger = inMerger;
710 }
711
712 static void
713 MDSequenceDetachMerger(const MDSequence *inSequence, MDMerger *inMerger)
714 {
715 MDMerger *currRef, *prevRef;
716 if (inSequence == NULL || inMerger == NULL)
717 return;
718 currRef = inSequence->merger;
719 prevRef = NULL;
720 while (currRef != NULL) {
721 if (currRef == inMerger) {
722 if (prevRef == NULL) {
723 /* merger is a 'mutable' member, so this cast is acceptable */
724 ((MDSequence *)inSequence)->merger = currRef->next;
725 } else {
726 prevRef->next = currRef->next;
727 }
728 break;
729 }
730 prevRef = currRef;
731 currRef = currRef->next;
732 }
733 }
734
735 #ifdef __MWERKS__
736 #pragma mark -
737 #pragma mark ====== MDMerger functions ======
738 #endif
739
740 /* --------------------------------------
741 ��� MDMergerNew
742 -------------------------------------- */
743 MDMerger *
744 MDMergerNew(MDSequence *inSequence)
745 {
746 MDMerger *newMerger = (MDMerger *)malloc(sizeof(*newMerger));
747 if (newMerger == NULL)
748 return NULL; /* out of memory */
749 memset(newMerger, 0, sizeof(*newMerger));
750 newMerger->refCount = 1;
751 newMerger->sequence = NULL;
752 newMerger->next = NULL;
753 newMerger->currentTrack = 0;
754 newMerger->eptr = NULL;
755 newMerger->tick = -1;
756 newMerger->info = NULL;
757 if (inSequence != NULL)
758 MDMergerSetSequence(newMerger, inSequence);
759 return newMerger;
760 }
761
762 /* --------------------------------------
763 ��� MDMergerRetain
764 -------------------------------------- */
765 void
766 MDMergerRetain(MDMerger *inMerger)
767 {
768 inMerger->refCount++;
769 }
770
771 /* --------------------------------------
772 ��� MDMergerRelease
773 -------------------------------------- */
774 void
775 MDMergerRelease(MDMerger *inMerger)
776 {
777 int32_t i, num;
778 if (--inMerger->refCount == 0) {
779 if (inMerger->info != NULL) {
780 num = MDArrayCount(inMerger->info);
781 for (i = 0; i < num; i++) {
782 MDMergerInfo info;
783 if (MDArrayFetch(inMerger->info, i, 1, &info) == 1) {
784 if (info.ptr != NULL)
785 MDPointerRelease(info.ptr);
786 if (info.track != NULL)
787 MDTrackRelease(info.track);
788 }
789 }
790 MDArrayRelease(inMerger->info);
791 }
792 if (inMerger->sequence != NULL) {
793 MDSequenceDetachMerger(inMerger->sequence, inMerger);
794 MDSequenceRelease(inMerger->sequence);
795 }
796 free(inMerger);
797 }
798 }
799
800 /* --------------------------------------
801 ��� MDMergerDuplicate
802 -------------------------------------- */
803 MDMerger *
804 MDMergerDuplicate(const MDMerger *inSrc)
805 {
806 MDMergerInfo anInfo, aSrcInfo;
807 int32_t n;
808 MDMerger *dest = MDMergerNew(NULL);
809 if (dest != NULL) {
810 dest->info = MDArrayNew(sizeof(MDMergerInfo));
811 if (dest->info == NULL) {
812 MDMergerRelease(dest);
813 return NULL;
814 }
815 for (n = MDArrayCount(inSrc->info) - 1; n >= 0; n--) {
816 if (MDArrayFetch(inSrc->info, n, 1, &aSrcInfo) == 1) {
817 anInfo.track = aSrcInfo.track;
818 MDTrackRetain(anInfo.track);
819 anInfo.ptr = MDPointerNew(anInfo.track);
820 MDPointerSetAutoAdjust(anInfo.ptr, 1);
821 MDPointerCopy(anInfo.ptr, aSrcInfo.ptr);
822 anInfo.eptr = aSrcInfo.eptr;
823 anInfo.tick = aSrcInfo.tick;
824 anInfo.lastTick = aSrcInfo.lastTick;
825 } else {
826 anInfo.track = NULL;
827 anInfo.ptr = NULL;
828 anInfo.eptr = NULL;
829 anInfo.tick = kMDMaxTick;
830 anInfo.lastTick = kMDNegativeTick;
831 }
832 MDArrayReplace(dest->info, n, 1, &anInfo);
833 }
834 dest->currentTrack = inSrc->currentTrack;
835 dest->eptr = inSrc->eptr;
836 dest->tick = inSrc->tick;
837 dest->sequence = inSrc->sequence;
838 if (dest->sequence != NULL) {
839 MDSequenceRetain(dest->sequence);
840 MDSequenceAttachMerger(dest->sequence, dest);
841 }
842 }
843 return dest;
844 }
845
846 /* --------------------------------------
847 ��� MDMergerSetSequence
848 -------------------------------------- */
849 MDStatus
850 MDMergerSetSequence(MDMerger *inMerger, MDSequence *inSequence)
851 {
852 if (inMerger->sequence != inSequence) {
853 if (inMerger->sequence != NULL) {
854 MDSequenceDetachMerger(inMerger->sequence, inMerger);
855 MDSequenceRelease(inMerger->sequence);
856 }
857 inMerger->sequence = inSequence;
858 if (inSequence != NULL) {
859 MDSequenceRetain(inSequence);
860 MDSequenceAttachMerger(inSequence, inMerger);
861 }
862 MDMergerReset(inMerger);
863 }
864 return kMDNoError;
865 }
866
867 /* --------------------------------------
868 ��� MDMergerGetSequence
869 -------------------------------------- */
870 MDSequence *
871 MDMergerGetSequence(MDMerger *inMerger)
872 {
873 return inMerger->sequence;
874 }
875
876 /* --------------------------------------
877 ��� MDMergerReset
878 -------------------------------------- */
879 void
880 MDMergerReset(MDMerger *inMerger)
881 {
882 int32_t num;
883 MDMergerInfo info;
884 if (inMerger == NULL || inMerger->sequence == NULL)
885 return;
886 if (inMerger->info == NULL) {
887 inMerger->info = MDArrayNew(sizeof(MDMergerInfo));
888 if (inMerger->info == NULL)
889 return;
890 } else {
891 num = MDArrayCount(inMerger->info);
892 while (--num >= 0) {
893 if (MDArrayFetch(inMerger->info, num, 1, &info) == 1) {
894 if (info.track != NULL)
895 MDTrackRelease(info.track);
896 if (info.ptr != NULL)
897 MDPointerRelease(info.ptr);
898 }
899 }
900 }
901 num = MDSequenceGetNumberOfTracks(inMerger->sequence);
902 MDArraySetCount(inMerger->info, num);
903 while (--num >= 0) {
904 info.track = MDSequenceGetTrack(inMerger->sequence, num);
905 MDTrackRetain(info.track);
906 info.eptr = NULL;
907 if (info.track != NULL) {
908 info.ptr = MDPointerNew(info.track);
909 if (info.ptr != NULL) {
910 MDPointerSetAutoAdjust(info.ptr, 1);
911 info.eptr = MDPointerForward(info.ptr);
912 }
913 } else info.ptr = NULL;
914 info.tick = (info.eptr != NULL ? MDGetTick(info.eptr) : LONG_MAX);
915 info.lastTick = -1.0;
916 MDArrayReplace(inMerger->info, num, 1, &info);
917 }
918 inMerger->tick = -1.0;
919 inMerger->currentTrack = -1;
920 inMerger->eptr = NULL;
921 }
922
923 /* --------------------------------------
924 ��� MDMergerJumpToTick
925 -------------------------------------- */
926 int
927 MDMergerJumpToTick(MDMerger *inMerger, MDTickType inTick)
928 {
929 int32_t i, num, minIndex;
930 MDTickType minTick;
931 MDEvent *eptr;
932 if (inMerger == NULL || inMerger->info == NULL)
933 return 0;
934 num = MDArrayCount(inMerger->info);
935 minIndex = -1;
936 minTick = kMDMaxTick;
937 eptr = NULL;
938 for (i = 0; i < num; i++) {
939 MDMergerInfo info;
940 if (MDArrayFetch(inMerger->info, i, 1, &info) == 1) {
941 if (info.ptr != NULL) {
942 MDEvent *last_eptr;
943 MDPointerJumpToTick(info.ptr, inTick);
944 last_eptr = MDPointerBackward(info.ptr);
945 info.eptr = MDPointerForward(info.ptr);
946 info.tick = (info.eptr != NULL ? MDGetTick(info.eptr) : kMDMaxTick);
947 info.lastTick = (last_eptr != NULL ? MDGetTick(last_eptr) : kMDNegativeTick);
948 if (info.tick < minTick) {
949 minIndex = i;
950 minTick = info.tick;
951 eptr = info.eptr;
952 }
953 MDArrayReplace(inMerger->info, i, 1, &info);
954 }
955 }
956 }
957 inMerger->eptr = eptr;
958 inMerger->tick = minTick;
959 inMerger->currentTrack = minIndex;
960 return 1;
961 }
962
963 /* --------------------------------------
964 ��� MDMergerCurrent
965 -------------------------------------- */
966 MDEvent *
967 MDMergerCurrent(const MDMerger *inMerger)
968 {
969 if (inMerger != NULL)
970 return inMerger->eptr;
971 else return NULL;
972 }
973
974 /* --------------------------------------
975 ��� MDMergerForward
976 -------------------------------------- */
977 MDEvent *
978 MDMergerForward(MDMerger *inMerger)
979 {
980 MDMergerInfo info;
981 MDTickType minTick;
982 int32_t minIndex, i, num;
983 MDEvent *eptr;
984
985 if (inMerger == NULL || inMerger->tick == kMDMaxTick)
986 return NULL;
987
988 /* ������������������������������������������������������������������������ */
989 if (inMerger->info == NULL)
990 return NULL;
991 if (inMerger->currentTrack != -1) {
992 if (MDArrayFetch(inMerger->info, inMerger->currentTrack, 1, &info) != 1)
993 return NULL;
994 if (info.ptr != NULL) {
995 info.eptr = MDPointerForward(info.ptr);
996 info.lastTick = info.tick;
997 info.tick = (info.eptr != NULL ? MDGetTick(info.eptr) : kMDMaxTick);
998 }
999 MDArrayReplace(inMerger->info, inMerger->currentTrack, 1, &info);
1000 }
1001
1002 /* tick ��������������������������������� */
1003 minTick = kMDMaxTick;
1004 minIndex = -1;
1005 num = MDArrayCount(inMerger->info);
1006 for (i = 0; i < num; i++) {
1007 if (MDArrayFetch(inMerger->info, i, 1, &info) == 1) {
1008 if (info.tick < minTick) {
1009 minTick = info.tick;
1010 minIndex = i;
1011 eptr = info.eptr;
1012 }
1013 }
1014 }
1015 inMerger->currentTrack = minIndex;
1016 if (minTick != kMDMaxTick) {
1017 inMerger->eptr = eptr;
1018 inMerger->tick = minTick;
1019 } else {
1020 inMerger->currentTrack = -1;
1021 inMerger->eptr = NULL;
1022 inMerger->tick = kMDMaxTick;
1023 }
1024 return inMerger->eptr;
1025 }
1026
1027 /* --------------------------------------
1028 ��� MDMergerBackward
1029 -------------------------------------- */
1030 MDEvent *
1031 MDMergerBackward(MDMerger *inMerger)
1032 {
1033 MDMergerInfo info;
1034 MDTickType maxLastTick;
1035 int32_t maxIndex, i, num;
1036 MDEvent *eptr;
1037
1038 if (inMerger == NULL || inMerger->info == NULL || inMerger->tick == kMDNegativeTick)
1039 return NULL;
1040
1041 /* lastTick ��������������������������������� */
1042 maxLastTick = kMDNegativeTick;
1043 maxIndex = -1;
1044 num = MDArrayCount(inMerger->info);
1045 for (i = num - 1; i >= 0; i--) {
1046 if (MDArrayFetch(inMerger->info, i, 1, &info) == 1) {
1047 if (info.lastTick > maxLastTick) {
1048 maxLastTick = info.lastTick;
1049 maxIndex = i;
1050 eptr = info.eptr;
1051 }
1052 }
1053 }
1054
1055 if (maxIndex == -1) {
1056 /* ������������������������������������������������ */
1057 inMerger->tick = kMDNegativeTick;
1058 inMerger->eptr = NULL;
1059 inMerger->currentTrack = -1;
1060 return NULL; /* ��������������������������� */
1061 }
1062
1063 /* ��������������������������������������������� */
1064 if (MDArrayFetch(inMerger->info, maxIndex, 1, &info) != 1)
1065 return NULL;
1066 if (info.ptr != NULL) {
1067 info.eptr = MDPointerBackward(info.ptr);
1068 if (info.eptr != NULL) {
1069 info.tick = MDGetTick(info.eptr);
1070 eptr = MDPointerBackward(info.ptr);
1071 info.lastTick = (eptr != NULL ? MDGetTick(eptr) : kMDNegativeTick);
1072 MDPointerForward(info.ptr);
1073 }
1074 MDArrayReplace(inMerger->info, maxIndex, 1, &info);
1075 inMerger->currentTrack = maxIndex;
1076 inMerger->eptr = info.eptr;
1077 inMerger->tick = info.tick;
1078 }
1079 return inMerger->eptr;
1080 }
1081
1082 /* --------------------------------------
1083 ��� MDMergerGetCurrentTrack
1084 -------------------------------------- */
1085 int32_t
1086 MDMergerGetCurrentTrack(MDMerger *inMerger)
1087 {
1088 if (inMerger != NULL)
1089 return inMerger->currentTrack;
1090 else return -1;
1091 }
1092
1093 /* --------------------------------------
1094 ��� MDMergerGetCurrentPositionInTrack
1095 -------------------------------------- */
1096 int32_t
1097 MDMergerGetCurrentPositionInTrack(MDMerger *inMerger)
1098 {
1099 MDMergerInfo info;
1100 if (inMerger != NULL && inMerger->info != NULL
1101 && MDArrayFetch(inMerger->info, inMerger->currentTrack, 1, &info) == 1) {
1102 if (info.ptr != NULL)
1103 return MDPointerGetPosition(info.ptr);
1104 }
1105 return -1;
1106 }
1107
1108 /* --------------------------------------
1109 ��� MDMergerGetTick
1110 -------------------------------------- */
1111 MDTickType
1112 MDMergerGetTick(MDMerger *inMerger)
1113 {
1114 if (inMerger != NULL)
1115 return inMerger->tick;
1116 else return kMDNegativeTick;
1117 }
1118 #endif

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26