Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/MD_package/MDCalibrator.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 146 - (show annotations) (download) (as text)
Sun Dec 17 04:05:28 2017 UTC (6 years, 3 months ago) by toshinagata1964
File MIME type: text/x-csrc
File size: 24939 byte(s)
Xcode project is updated so that ppc/i386 universal binary can be built (as before)
1 /*
2 * MDCalibrator.c
3 *
4 * Created by Toshi Nagata on Sun Jun 17 2001.
5
6 Copyright (c) 2000-2011 Toshi Nagata. All rights reserved.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation version 2 of the License.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 */
17
18 #include "MDHeaders.h"
19
20 #include <limits.h>
21 #include <stdlib.h>
22
23 /* Internal struct: data for individual meta-event */
24 typedef union MDCalibratorData {
25 MDTimeType time;
26 int32_t bar;
27 short key;
28 short data1;
29 } MDCalibratorData;
30
31 struct MDCalibrator {
32 int32_t refCount;
33 MDSequence * parent;
34 MDTrack * track;
35 MDCalibrator * next; /* List of individual MDCalibrators */
36 MDCalibrator * chain; /* An internal chain of MDCalibrators */
37 MDEventKind kind;
38 short code;
39 MDPointer * before;
40 MDPointer * after;
41 MDTickType tick_before;
42 MDTickType tick_after;
43 MDCalibratorData data_before;
44 MDCalibratorData data_after;
45 };
46
47 #pragma mark ====== Private functions ======
48
49 /* --------------------------------------
50 ��� MDCalibratorTickToMeasureWithoutJump
51 -------------------------------------- */
52 static void
53 MDCalibratorTickToMeasureWithoutJump(MDCalibrator *inCalib, MDTickType inTick,
54 int32_t *outMeasure, int32_t *outBeat, int32_t *outTick)
55 {
56 MDEvent *eptr;
57 int32_t tickPerBeat, beatPerMeasure, beat;
58 MDTickType theTickBefore;
59 int32_t theBarBefore;
60 int32_t timebase;
61
62 eptr = MDPointerCurrent(inCalib->before);
63 timebase = MDSequenceGetTimebase(inCalib->parent);
64 MDEventParseTimeSignature(eptr, timebase, &tickPerBeat, &beatPerMeasure);
65
66 if (tickPerBeat == 0 || beatPerMeasure == 0) {
67 if (outMeasure != NULL)
68 *outMeasure = 0;
69 if (outBeat != NULL)
70 *outBeat = 0;
71 if (outTick != NULL)
72 *outTick = 0;
73 } else {
74 if (eptr == NULL) {
75 /* eptr == NULL ������������data_before.bar = 1, tick_before = 0 ��������������������� */
76 theTickBefore = 0;
77 theBarBefore = 1;
78 } else {
79 theTickBefore = inCalib->tick_before;
80 theBarBefore = inCalib->data_before.bar;
81 }
82
83 beat = (inTick - theTickBefore) / tickPerBeat;
84 if (outTick != NULL)
85 *outTick = (int32_t)(inTick - theTickBefore) - beat * tickPerBeat;
86 if (outBeat != NULL)
87 *outBeat = beat % beatPerMeasure + 1;
88 if (outMeasure != NULL)
89 *outMeasure = theBarBefore + beat / beatPerMeasure;
90 }
91 }
92
93 /* --------------------------------------
94 ��� MDCalibratorCalculateTime
95 -------------------------------------- */
96 static MDTimeType
97 MDCalibratorCalculateTime(MDCalibrator *inCalib, MDTickType inTick)
98 {
99 MDTickType tick_before;
100 MDTimeType time_before;
101 int32_t timebase;
102 float tempo;
103 if (inCalib->tick_before >= 0) {
104 tick_before = inCalib->tick_before;
105 time_before = inCalib->data_before.time;
106 tempo = MDCalibratorGetTempo(inCalib);
107 } else {
108 tempo = 120.0f;
109 tick_before = 0;
110 time_before = 0;
111 }
112 timebase = MDSequenceGetTimebase(inCalib->parent);
113 return time_before + (MDTimeType)floor(0.5 + (inTick - tick_before) * 60000000.0 / (tempo * timebase));
114 }
115
116 static MDCalibrator *
117 MDCalibratorInitialize(MDCalibrator *inCalib, MDSequence *inSequence, MDTrack *inTrack, MDEventKind inKind, short inCode)
118 {
119 if (inCalib == NULL)
120 return NULL;
121
122 if (inKind == kMDEventTempo || inKind == kMDEventTimeSignature) {
123 if (inSequence != NULL)
124 inTrack = MDSequenceGetTrack(inSequence, 0); /* the conductor track */
125 }
126 inCalib->parent = inSequence;
127 inCalib->track = inTrack;
128 inCalib->next = NULL;
129 inCalib->chain = NULL;
130 inCalib->kind = inKind;
131
132 MDSequenceRetain(inCalib->parent);
133 MDTrackRetain(inCalib->track);
134
135 if (inKind == kMDEventMeta || inKind == kMDEventMetaText || inKind == kMDEventMetaMessage
136 || inKind == kMDEventNote
137 || inKind == kMDEventControl || inKind == kMDEventKeyPres || inKind == kMDEventData
138 || inKind == kMDEventObject) {
139 inCalib->code = inCode;
140 } else inCalib->code = -1;
141
142 inCalib->before = MDPointerNew(inTrack);
143 if (inCalib->before == NULL) {
144 return NULL;
145 }
146 MDPointerSetAutoAdjust(inCalib->before, 1);
147 inCalib->after = MDPointerNew(inTrack);
148 if (inCalib->after == NULL) {
149 MDPointerRelease(inCalib->before);
150 inCalib->before = NULL;
151 return NULL;
152 }
153 MDPointerSetAutoAdjust(inCalib->after, 1);
154 MDCalibratorReset(inCalib);
155 return inCalib;
156 }
157
158 static MDCalibrator *
159 MDCalibratorAllocate(MDSequence *inSequence, MDTrack *inTrack, MDEventKind inKind, short inCode)
160 {
161 MDCalibrator *theRef = (MDCalibrator *)malloc(sizeof(MDCalibrator));
162 if (theRef == NULL)
163 return NULL; /* out of memory */
164 if (MDCalibratorInitialize(theRef, inSequence, inTrack, inKind, inCode) == NULL) {
165 free(theRef);
166 return NULL;
167 } else return theRef;
168 }
169
170 static void
171 MDCalibratorDeallocateChain(MDCalibrator *inCalib)
172 {
173 if (inCalib->chain != NULL)
174 MDCalibratorDeallocateChain(inCalib->chain);
175 MDPointerRelease(inCalib->before);
176 MDPointerRelease(inCalib->after);
177 free(inCalib);
178 }
179
180 /* --------------------------------------
181 ��� MDCalibratorForward
182 -------------------------------------- */
183 static int
184 MDCalibratorForward(MDCalibrator *inCalib)
185 {
186 MDEvent *eref;
187 int32_t measure, beat, tick;
188
189 if (inCalib->track == NULL || inCalib->after == NULL)
190 return 0;
191
192 /* The 'after' position is at the end of track */
193 if (inCalib->tick_after == kMDMaxTick)
194 return 0;
195
196 MDPointerCopy(inCalib->before, inCalib->after);
197 inCalib->tick_before = inCalib->tick_after;
198 while ((eref = MDPointerForward(inCalib->after)) != NULL) {
199 if (MDGetKind(eref) == inCalib->kind && (inCalib->code == -1 || MDGetCode(eref) == inCalib->code))
200 break;
201 }
202 if (eref == NULL)
203 inCalib->tick_after = kMDMaxTick;
204 else
205 inCalib->tick_after = MDGetTick(eref);
206
207 inCalib->data_before = inCalib->data_after;
208
209 switch (inCalib->kind) {
210 case kMDEventTempo:
211 // inCalib->data_before.time = inCalib->data_after.time;
212 inCalib->data_after.time = MDCalibratorCalculateTime(inCalib, inCalib->tick_after);
213 break;
214 case kMDEventTimeSignature:
215 // inCalib->data_before.bar = inCalib->data_after.bar;
216 MDCalibratorTickToMeasureWithoutJump(inCalib, inCalib->tick_after, &measure, &beat, &tick);
217 if (measure != 0 && (beat > 1 || tick > 0)) {
218 /* ��������������������������������������� */
219 measure++;
220 }
221 inCalib->data_after.bar = measure;
222 break;
223 default:
224 if (eref != NULL)
225 inCalib->data_after.data1 = MDGetData1(eref);
226 break;
227 }
228
229 return 1;
230 }
231
232 /* --------------------------------------
233 ��� MDCalibratorBackward
234 -------------------------------------- */
235 static int
236 MDCalibratorBackward(MDCalibrator *inCalib)
237 {
238 MDEvent *eref;
239 int32_t measure, beat, tick;
240 MDTimeType time;
241
242 if (inCalib->track == NULL || inCalib->before == NULL)
243 return 0;
244
245 /* The 'before' position is at the beginning of track */
246 if (inCalib->tick_before == kMDNegativeTick)
247 return 0;
248
249 MDPointerCopy(inCalib->after, inCalib->before);
250 inCalib->tick_after = inCalib->tick_before;
251 while ((eref = MDPointerBackward(inCalib->before)) != NULL) {
252 if (MDGetKind(eref) == inCalib->kind && (inCalib->code == -1 || MDGetCode(eref) == inCalib->code))
253 break;
254 }
255 if (eref == NULL)
256 inCalib->tick_before = kMDNegativeTick;
257 else
258 inCalib->tick_before = MDGetTick(eref);
259
260 inCalib->data_after = inCalib->data_before;
261 switch (inCalib->kind) {
262 case kMDEventTempo:
263 // inCalib->data_after.time = inCalib->data_before.time;
264 /* ������ data_before.time = 0 ��������� after ��������������������������� */
265 inCalib->data_before.time = 0;
266 time = MDCalibratorCalculateTime(inCalib, inCalib->tick_after);
267 /* time == data_after.time ������������������ data_before.time ��������������� */
268 inCalib->data_before.time += inCalib->data_after.time - time;
269 break;
270 case kMDEventTimeSignature:
271 // inCalib->data_after.bar = inCalib->data_before.bar;
272 /* ������ data_before.bar = 1 ������������������ after ������������������������������ */
273 inCalib->data_before.bar = 1;
274 MDCalibratorTickToMeasureWithoutJump(inCalib, inCalib->tick_after, &measure, &beat, &tick);
275 if (measure != 0 && (beat > 1 || tick > 0)) {
276 /* ��������������������������������������� */
277 measure++;
278 }
279 /* after ��������������������� data_after.bar ��������������������������� data_before.bar ��������������� */
280 inCalib->data_before.bar += inCalib->data_after.bar - measure;
281 break;
282 default:
283 if (eref != NULL)
284 inCalib->data_before.data1 = MDGetData1(eref);
285 break;
286 }
287
288 return 1;
289 }
290
291 #pragma mark ====== New/Retain/Release ======
292
293 /* --------------------------------------
294 ��� MDCalibratorNew
295 -------------------------------------- */
296 MDCalibrator *
297 MDCalibratorNew(MDSequence *inSequence, MDTrack *inTrack, MDEventKind inKind, short inCode)
298 {
299 MDCalibrator *theRef = MDCalibratorAllocate(inSequence, inTrack, inKind, inCode);
300 if (theRef == NULL)
301 return NULL; /* out of memory */
302 theRef->refCount = 1;
303 MDSequenceAttachCalibrator(inSequence, theRef);
304 return theRef;
305 }
306
307 /* --------------------------------------
308 ��� MDCalibratorRetain
309 -------------------------------------- */
310 void
311 MDCalibratorRetain(MDCalibrator *inCalib)
312 {
313 if (inCalib != NULL)
314 inCalib->refCount++;
315 }
316
317 /* --------------------------------------
318 ��� MDCalibratorRelease
319 -------------------------------------- */
320 void
321 MDCalibratorRelease(MDCalibrator *inCalib)
322 {
323 if (inCalib != NULL && --inCalib->refCount == 0) {
324 if (inCalib->parent != NULL) {
325 MDSequenceDetachCalibrator(inCalib->parent, inCalib);
326 MDSequenceRelease(inCalib->parent);
327 }
328 if (inCalib->track != NULL)
329 MDTrackRelease(inCalib->track);
330 MDCalibratorDeallocateChain(inCalib);
331 }
332 }
333
334 #pragma mark ====== Calibrator list manipulations ======
335
336 /* --------------------------------------
337 ��� MDCalibratorAppend
338 -------------------------------------- */
339 int
340 MDCalibratorIsSupporting(MDCalibrator *inCalib, MDTrack *inTrack, MDEventKind inKind, short inCode)
341 {
342 MDCalibrator *calib;
343 for (calib = inCalib; calib != NULL; calib = calib->chain) {
344 if (calib->track == inTrack && calib->kind == inKind && calib->code == inCode)
345 return 1;
346 }
347 return 0;
348 }
349
350 /* --------------------------------------
351 ��� MDCalibratorAppend
352 -------------------------------------- */
353 MDStatus
354 MDCalibratorAppend(MDCalibrator *inCalib, MDTrack *inTrack, MDEventKind inKind, short inCode)
355 {
356 MDCalibrator *theRef;
357 if (inCalib == NULL)
358 return kMDErrorBadParameter;
359 if (MDCalibratorIsSupporting(inCalib, inTrack, inKind, inCode))
360 return kMDNoError; /* Already there */
361 if (inCalib->kind == kMDEventNull) {
362 /* In-place substitution */
363 MDCalibrator *next, *chain;
364 int32_t refCount;
365 next = inCalib->next;
366 chain = inCalib->chain;
367 refCount = inCalib->refCount;
368 if (MDCalibratorInitialize(inCalib, inCalib->parent, inTrack, inKind, inCode) == NULL)
369 return kMDErrorOutOfMemory;
370 inCalib->next = next;
371 inCalib->chain = chain;
372 inCalib->refCount = refCount;
373 return kMDNoError;
374 }
375 theRef = MDCalibratorAllocate(inCalib->parent, inTrack, inKind, inCode);
376 if (theRef == NULL)
377 return kMDErrorOutOfMemory;
378 theRef->refCount = 0;
379 while (inCalib->chain != NULL)
380 inCalib = inCalib->chain;
381 inCalib->chain = theRef;
382 return kMDNoError;
383 }
384
385 /* --------------------------------------
386 ��� MDCalibratorGetInfo
387 -------------------------------------- */
388 MDStatus
389 MDCalibratorGetInfo(MDCalibrator *inCalib, int index, MDTrack **outTrack, MDEventKind *outKind, short *outCode)
390 {
391 while (inCalib != NULL && --index >= 0)
392 inCalib = inCalib->chain;
393 if (inCalib != NULL) {
394 if (outTrack != NULL)
395 *outTrack = inCalib->track;
396 if (outKind != NULL)
397 *outKind = inCalib->kind;
398 if (outCode != NULL)
399 *outCode = inCalib->code;
400 return kMDNoError;
401 } else return kMDErrorBadParameter;
402 }
403
404 /* --------------------------------------
405 ��� MDCalibratorRemoveAtIndex
406 -------------------------------------- */
407 MDStatus
408 MDCalibratorRemoveAtIndex(MDCalibrator *inCalib, int index)
409 {
410 MDCalibrator *calib = NULL;
411 if (index == 0) {
412 /* The first record in this calibrator chain */
413 if (inCalib->before != NULL)
414 MDPointerRelease(inCalib->before);
415 if (inCalib->after != NULL)
416 MDPointerRelease(inCalib->after);
417 if (inCalib->chain != NULL) {
418 /* Copy the next record to this record */
419 calib = inCalib->chain;
420 inCalib->chain->next = inCalib->next;
421 *inCalib = *(inCalib->chain);
422 free(calib); /* and deallocate the next record */
423 } else {
424 /* Set this record to 'null' */
425 inCalib->before = inCalib->after = NULL;
426 inCalib->track = NULL;
427 inCalib->kind = kMDEventNull;
428 inCalib->code = -1;
429 inCalib->tick_before = kMDNegativeTick;
430 inCalib->tick_after = kMDNegativeTick;
431 }
432 return kMDNoError;
433 }
434 while (inCalib != NULL && --index >= 0) {
435 calib = inCalib;
436 inCalib = inCalib->chain;
437 }
438 if (inCalib != NULL) {
439 /* Deallocate this record */
440 if (inCalib->before != NULL)
441 MDPointerRelease(inCalib->before);
442 if (inCalib->after != NULL)
443 MDPointerRelease(inCalib->after);
444 calib->chain = inCalib->chain;
445 free(inCalib);
446 return kMDNoError;
447 } else return kMDErrorBadParameter;
448 }
449
450 /* --------------------------------------
451 ��� MDCalibratorNextInList
452 -------------------------------------- */
453 MDCalibrator *
454 MDCalibratorNextInList(MDCalibrator *inCalib)
455 {
456 if (inCalib != NULL)
457 return inCalib->next;
458 else return NULL;
459 }
460
461 /* --------------------------------------
462 ��� MDCalibratorSetNextInList
463 -------------------------------------- */
464 void
465 MDCalibratorSetNextInList(MDCalibrator *inCalib, MDCalibrator *inNextCalib)
466 {
467 if (inCalib != NULL)
468 inCalib->next = inNextCalib;
469 }
470
471 #pragma mark ====== Moving around ======
472
473 /* --------------------------------------
474 ��� MDCalibratorReset
475 -------------------------------------- */
476 void
477 MDCalibratorReset(MDCalibrator *inCalib)
478 {
479 if (inCalib == NULL)
480 return;
481 MDPointerSetTrack(inCalib->before, inCalib->track);
482 MDPointerSetPosition(inCalib->before, -1);
483 MDPointerSetTrack(inCalib->after, inCalib->track);
484 MDPointerSetPosition(inCalib->after, -1);
485 inCalib->tick_before = kMDNegativeTick;
486 inCalib->tick_after = kMDNegativeTick;
487 switch (inCalib->kind) {
488 case kMDEventTempo:
489 inCalib->data_before.time = inCalib->data_after.time = kMDNegativeTime;
490 break;
491 case kMDEventTimeSignature:
492 inCalib->data_before.bar = inCalib->data_after.bar = 0;
493 break;
494 case kMDEventKey:
495 inCalib->data_before.key = inCalib->data_after.key = 0;
496 break;
497 }
498 if (inCalib->chain != NULL)
499 MDCalibratorReset(inCalib->chain);
500 }
501
502 /* Do 'jump to tick' for a single calibrator unit */
503 static void
504 MDCalibratorJumpToTickSub(MDCalibrator *inCalib, MDTickType inTick)
505 {
506 if (inTick >= inCalib->tick_after) {
507 // ���������������������������
508 if (inTick == kMDMaxTick) {
509 do {
510 MDCalibratorForward(inCalib);
511 } while (inCalib->tick_after < kMDMaxTick);
512 } else {
513 do {
514 MDCalibratorForward(inCalib);
515 } while (inTick >= inCalib->tick_after);
516 }
517 } else if (inTick < inCalib->tick_before) {
518 // ���������������������������
519 if (inTick < 0) {
520 do {
521 MDCalibratorBackward(inCalib);
522 } while (inCalib->tick_before >= 0);
523 } else {
524 do {
525 MDCalibratorBackward(inCalib);
526 } while (inTick < inCalib->tick_before);
527 }
528 }
529 }
530
531 /* --------------------------------------
532 ��� MDCalibratorJumpToTick
533 -------------------------------------- */
534 void
535 MDCalibratorJumpToTick(MDCalibrator *inCalib, MDTickType inTick)
536 {
537 if (inCalib == NULL || inCalib->track == NULL || inCalib->before == NULL)
538 return;
539 MDCalibratorJumpToTickSub(inCalib, inTick);
540 if (inCalib->chain != NULL)
541 MDCalibratorJumpToTick(inCalib->chain, inTick);
542 }
543
544 /* Do 'jump to position in track' for a single calibrator unit */
545 static void
546 MDCalibratorJumpToPositionInTrackSub(MDCalibrator *inCalib, MDTickType inTick, int32_t inPosition, MDTrack *inTrack)
547 {
548 if (inCalib->track == NULL || inCalib->before == NULL)
549 return;
550 if (inCalib->track != inTrack) {
551 MDCalibratorJumpToTickSub(inCalib, inTick);
552 } else {
553 if (inPosition >= MDPointerGetPosition(inCalib->after)) {
554 // ���������������������������
555 if (inPosition >= MDTrackGetNumberOfEvents(inCalib->track)) {
556 do {
557 MDCalibratorForward(inCalib);
558 } while (inCalib->tick_after < kMDMaxTick);
559 } else {
560 do {
561 MDCalibratorForward(inCalib);
562 } while (inPosition >= MDPointerGetPosition(inCalib->after));
563 }
564 } else if (inPosition < MDPointerGetPosition(inCalib->before)) {
565 // ���������������������������
566 if (inPosition < 0) {
567 do {
568 MDCalibratorBackward(inCalib);
569 } while (inCalib->tick_before >= 0);
570 } else {
571 do {
572 MDCalibratorBackward(inCalib);
573 } while (inPosition < MDPointerGetPosition(inCalib->before));
574 }
575 }
576 }
577 if (inCalib->chain != NULL)
578 MDCalibratorJumpToPositionInTrackSub(inCalib->chain, inTick, inPosition, inTrack);
579 }
580
581 /* --------------------------------------
582 ��� MDCalibratorJumpToPositionInTrack
583 -------------------------------------- */
584 void
585 MDCalibratorJumpToPositionInTrack(MDCalibrator *inCalib, int32_t inPosition, MDTrack *inTrack)
586 {
587 MDTickType tick;
588 MDPointer *pt;
589 MDEvent *ep;
590
591 if (inCalib == NULL || inCalib->track == NULL || inCalib->before == NULL)
592 return;
593
594 if (inPosition < 0)
595 tick = kMDNegativeTick;
596 else {
597 pt = MDPointerNew(inTrack);
598 MDPointerSetPosition(pt, inPosition);
599 ep = MDPointerCurrent(pt);
600 if (ep == NULL)
601 tick = kMDMaxTick;
602 else tick = MDGetTick(ep);
603 MDPointerRelease(pt);
604 }
605 MDCalibratorJumpToPositionInTrackSub(inCalib, tick, inPosition, inTrack);
606 }
607
608 #pragma mark ====== Getting calibrated information ======
609
610 /* --------------------------------------
611 ��� MDCalibratorMeasureToTick
612 -------------------------------------- */
613 MDTickType
614 MDCalibratorMeasureToTick(MDCalibrator *inCalib, int32_t inMeasure, int32_t inBeat, int32_t inTick)
615 {
616 MDEvent *eptr;
617 int32_t tickPerBeat, beatPerMeasure, timebase, theBarBefore;
618 double theTick, theTickBefore;
619
620 while (inCalib != NULL) {
621 if (inCalib->kind == kMDEventTimeSignature)
622 break;
623 inCalib = inCalib->chain;
624 }
625 if (inCalib == NULL)
626 return 0;
627
628 /* ��������������������������� */
629 if (inMeasure < 1)
630 return kMDNegativeTick;
631 if (inMeasure >= INT32_MAX)
632 return kMDMaxTick;
633 if (inMeasure >= inCalib->data_after.bar) {
634 /* ��������������������������� */
635 do {
636 MDCalibratorForward(inCalib);
637 } while (inMeasure >= inCalib->data_after.bar);
638 } else if (inMeasure < inCalib->data_before.bar) {
639 /* ��������������������������� */
640 do {
641 MDCalibratorBackward(inCalib);
642 } while (inMeasure < inCalib->data_before.bar);
643 }
644
645 /* ��������� tick ��������������������������������� */
646 eptr = MDPointerCurrent(inCalib->before);
647 timebase = MDSequenceGetTimebase(inCalib->parent);
648 MDEventParseTimeSignature(eptr, timebase, &tickPerBeat, &beatPerMeasure);
649 if (eptr == NULL) {
650 theBarBefore = 1;
651 theTickBefore = 0;
652 } else {
653 theBarBefore = inCalib->data_before.bar;
654 theTickBefore = inCalib->tick_before;
655 }
656 theTick = theTickBefore + inTick +
657 ((inBeat - 1) + (inMeasure - theBarBefore) * beatPerMeasure) * tickPerBeat;
658 if (theTick > kMDMaxTick)
659 return kMDMaxTick;
660 else
661 return (MDTickType)theTick;
662 }
663
664 /* --------------------------------------
665 ��� MDCalibratorTickToMeasure
666 -------------------------------------- */
667 void
668 MDCalibratorTickToMeasure(MDCalibrator *inCalib, MDTickType inTick, int32_t *outMeasure, int32_t *outBeat, int32_t *outTick)
669 {
670 MDCalibratorJumpToTick(inCalib, inTick);
671 while (inCalib != NULL) {
672 if (inCalib->kind == kMDEventTimeSignature)
673 break;
674 inCalib = inCalib->chain;
675 }
676 if (inCalib == NULL)
677 return;
678 MDCalibratorTickToMeasureWithoutJump(inCalib, inTick, outMeasure, outBeat, outTick);
679 }
680
681 /* --------------------------------------
682 ��� MDCalibratorGetTempo
683 -------------------------------------- */
684 float
685 MDCalibratorGetTempo(MDCalibrator *inCalib)
686 {
687 MDEvent *ep;
688 while (inCalib != NULL) {
689 if (inCalib->kind == kMDEventTempo) {
690 ep = MDPointerCurrent(inCalib->before);
691 if (ep != NULL)
692 return MDGetTempo(ep);
693 else break;
694 }
695 inCalib = inCalib->chain;
696 }
697 return 120.0f;
698 }
699
700 /* --------------------------------------
701 ��� MDCalibratorTimeToTick
702 -------------------------------------- */
703 MDTickType
704 MDCalibratorTimeToTick(MDCalibrator *inCalib, MDTimeType inTime)
705 {
706 MDTickType tick_before;
707 MDTimeType time_before;
708 int32_t timebase;
709
710 while (inCalib != NULL) {
711 if (inCalib->kind == kMDEventTempo)
712 break;
713 inCalib = inCalib->chain;
714 }
715 if (inCalib == NULL)
716 return kMDNegativeTick;
717
718 if (inTime >= inCalib->data_after.time) {
719 /* Search forward */
720 while (MDCalibratorForward(inCalib) && inTime >= inCalib->data_after.time) { }
721 } else if (inTime < inCalib->data_before.time) {
722 /* Search backward */
723 while (MDCalibratorBackward(inCalib) && inTime < inCalib->data_before.time) { }
724 }
725 if (inCalib->tick_before >= 0) {
726 tick_before = inCalib->tick_before;
727 time_before = inCalib->data_before.time;
728 } else {
729 tick_before = 0;
730 time_before = 0;
731 }
732 timebase = MDSequenceGetTimebase(inCalib->parent);
733 return tick_before + (MDTickType)floor(0.5 + (double)(inTime - time_before) * ((double)timebase * MDCalibratorGetTempo(inCalib) / 60000000.0));
734 }
735
736 /* --------------------------------------
737 ��� MDCalibratorTickToTime
738 -------------------------------------- */
739 MDTimeType
740 MDCalibratorTickToTime(MDCalibrator *inCalib, MDTickType inTick)
741 {
742 while (inCalib != NULL) {
743 if (inCalib->kind == kMDEventTempo)
744 break;
745 inCalib = inCalib->chain;
746 }
747 if (inCalib == NULL)
748 return (MDTimeType)0;
749 MDCalibratorJumpToTick(inCalib, inTick);
750 return MDCalibratorCalculateTime(inCalib, inTick);
751 }
752
753 /* --------------------------------------
754 ��� MDCalibratorGetEvent
755 -------------------------------------- */
756 MDEvent *
757 MDCalibratorGetEvent(MDCalibrator *inCalib, MDTrack *inTrack, MDEventKind inKind, short inCode)
758 {
759 while (inCalib != NULL) {
760 if ((inTrack == NULL || inCalib->track == inTrack)
761 && inCalib->kind == inKind && (inCode == -1 || inCalib->code == inCode))
762 break;
763 inCalib = inCalib->chain;
764 }
765 if (inCalib == NULL)
766 return NULL;
767 else return MDPointerCurrent(inCalib->before);
768 }
769
770 /* --------------------------------------
771 ��� MDCalibratorGetEventPosition
772 -------------------------------------- */
773 int32_t
774 MDCalibratorGetEventPosition(MDCalibrator *inCalib, MDTrack *inTrack, MDEventKind inKind, short inCode)
775 {
776 while (inCalib != NULL) {
777 if ((inTrack == NULL || inCalib->track == inTrack)
778 && inCalib->kind == inKind && (inCode == -1 || inCalib->code == inCode))
779 break;
780 inCalib = inCalib->chain;
781 }
782 if (inCalib == NULL)
783 return -1;
784 else return MDPointerGetPosition(inCalib->before);
785 }
786
787 /* --------------------------------------
788 ��� MDCalibratorGetNextEvent
789 -------------------------------------- */
790 MDEvent *
791 MDCalibratorGetNextEvent(MDCalibrator *inCalib, MDTrack *inTrack, MDEventKind inKind, short inCode)
792 {
793 while (inCalib != NULL) {
794 if ((inTrack == NULL || inCalib->track == inTrack)
795 && inCalib->kind == inKind && (inCode == -1 || inCalib->code == inCode))
796 break;
797 inCalib = inCalib->chain;
798 }
799 if (inCalib == NULL)
800 return NULL;
801 else return MDPointerCurrent(inCalib->after);
802 }
803
804 /* --------------------------------------
805 ��� MDCalibratorCopyPointer
806 -------------------------------------- */
807 MDPointer *
808 MDCalibratorCopyPointer(MDCalibrator *inCalib, MDTrack *inTrack, MDEventKind inKind, short inCode)
809 {
810 while (inCalib != NULL) {
811 if ((inTrack == NULL || inCalib->track == inTrack)
812 && inCalib->kind == inKind && (inCode == -1 || inCalib->code == inCode))
813 break;
814 inCalib = inCalib->chain;
815 }
816 if (inCalib == NULL)
817 return NULL;
818 else {
819 MDPointer *pt = MDPointerNew(inCalib->track);
820 if (pt == NULL)
821 return NULL;
822 MDPointerCopy(pt, inCalib->before);
823 MDPointerSetAutoAdjust(pt, 1);
824 return pt;
825 }
826 }

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