Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/MD_package/MDEvent.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: 37977 byte(s)
Keyswitch will be sent while prerolling
1 /*
2 MDEvent.c
3 Created by Toshi Nagata, 2000.11.23.
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 <string.h> /* for memset() */
20 #include <stdlib.h> /* for malloc(), realloc(), free() */
21 #include <stdio.h> /* for sprintf() */
22 #include <ctype.h> /* for isspace(), tolower() */
23
24 #ifdef __MWERKS__
25 #pragma mark ====== Private definitions ======
26 #endif
27
28 struct MDMessage {
29 int32_t refCount;
30 int32_t length;
31 unsigned char msg[4]; /* variable length */
32 };
33
34 /* -------------------------------------------------------------------
35 MDEvent macros --- for private use only
36 ------------------------------------------------------------------- */
37 #define MDPrivateGetMessage(eventPtr) ((eventPtr)->u.message)
38 #define MDPrivateSetMessage(eventPtr, theMsg) ((eventPtr)->u.message = (theMsg))
39 #define MDPrivateGetDataPtr(eventPtr) ((eventPtr)->u.dataptr)
40 #define MDPrivateSetDataPtr(eventPtr, theData) ((eventPtr)->u.dataptr = (theData))
41 /*
42 #define MDPrivateGetObject(eventPtr) ((eventPtr)->u.objptr)
43 #define MDPrivateSetObject(eventPtr, theObj) ((eventPtr)->u.objptr = (theObj))
44 */
45
46 static unsigned char sIsNote60C4 = 0;
47
48 /* --------------------------------------
49 ��� MDMessageRetain
50 -------------------------------------- */
51 static void
52 MDMessageRetain(MDMessage *msgRef)
53 {
54 msgRef->refCount++;
55 }
56
57 /* --------------------------------------
58 ��� MDMessageRelease
59 -------------------------------------- */
60 static void
61 MDMessageRelease(MDMessage *msgRef)
62 {
63 msgRef->refCount--;
64 if (msgRef->refCount <= 0)
65 free(msgRef);
66 }
67
68 /* --------------------------------------
69 ��� MDMessageReallocate
70 -------------------------------------- */
71 static MDMessage *
72 MDMessageReallocate(MDMessage *msgRef, int32_t length)
73 {
74 MDMessage *newMsg;
75 int32_t newLength;
76
77 if (length < 4)
78 newLength = sizeof(*newMsg);
79 else
80 newLength = sizeof(*newMsg) - 4 + 1 + length; /* One extra byte for terminating null */
81
82 if (msgRef == NULL)
83 newMsg = (MDMessage *)malloc(newLength);
84 else if (msgRef->refCount == 1)
85 newMsg = (MDMessage *)realloc(msgRef, newLength);
86 else {
87 newMsg = (MDMessage *)malloc(newLength);
88 if (newMsg != NULL) {
89 int32_t minLength = (msgRef->length > length ? length : msgRef->length);
90 msgRef->refCount--;
91 memmove(newMsg->msg, msgRef->msg, minLength + 1);
92 }
93 }
94 if (newMsg != NULL) {
95 newMsg->length = length;
96 newMsg->msg[length] = 0; /* Null-terminate transparently */
97 newMsg->refCount = 1;
98 return newMsg;
99 } else return NULL;
100 }
101
102 #ifdef __MWERKS__
103 #pragma mark ====== Initialization ======
104 #endif
105
106 /* --------------------------------------
107 ��� MDEventInit
108 -------------------------------------- */
109 void
110 MDEventInit(MDEvent *eventRef)
111 {
112 memset(eventRef, 0, sizeof(*eventRef));
113 }
114
115 /* --------------------------------------
116 ��� MDEventClear
117 -------------------------------------- */
118 void
119 MDEventClear(MDEvent *eventRef)
120 {
121 if (MDHasEventMessage(eventRef)) {
122 if (MDPrivateGetMessage(eventRef) != NULL)
123 MDMessageRelease(MDPrivateGetMessage(eventRef));
124 } else if (MDHasEventData(eventRef)) {
125 if (MDPrivateGetDataPtr(eventRef) != NULL)
126 free(MDPrivateGetDataPtr(eventRef));
127 /* } else if (MDHasEventObject(eventRef)) {
128 if (MDPrivateGetObject(eventRef) != NULL)
129 MDReleaseObject(MDPrivateGetObject(eventRef));
130 */
131 }
132 MDEventInit(eventRef);
133 }
134
135 /* --------------------------------------
136 ��� MDEventClear
137 -------------------------------------- */
138 void
139 MDEventDefault(MDEvent *eventRef, int kind)
140 {
141 int n;
142 unsigned char *ucp;
143 MDEventInit(eventRef);
144 MDSetKind(eventRef, kind);
145 switch (kind) {
146 case kMDEventTempo:
147 MDSetTempo(eventRef, 120.0f); break;
148 case kMDEventTimeSignature:
149 ucp = MDGetMetaDataPtr(eventRef);
150 ucp[0] = 4; ucp[1] = 2; ucp[2] = 24; ucp[3] = 8; break;
151 case kMDEventSysex:
152 case kMDEventSysexCont:
153 n = (kind == kMDEventSysex ? 1 : 0);
154 if (MDSetMessageLength(eventRef, n) < 0)
155 return; /* Out of memory */
156 if (n == 1) {
157 static const unsigned char sF0 = 0xf0;
158 MDSetMessage(eventRef, &sF0);
159 }
160 break;
161 case kMDEventMetaMessage:
162 case kMDEventMetaText:
163 if (MDSetMessageLength(eventRef, 1) < 0)
164 return; /* Out of memory */
165 MDSetMessage(eventRef, (const unsigned char *)""); /* null C-string */
166 break;
167 case kMDEventNote:
168 MDSetData1(eventRef, 0x7f00);
169 MDSetDuration(eventRef, 1);
170 break;
171 }
172 }
173
174 #ifdef __MWERKS__
175 #pragma mark ====== Move/Copy ======
176 #endif
177
178 /* --------------------------------------
179 ��� MDEventCopy
180 -------------------------------------- */
181 void
182 MDEventCopy(MDEvent *destRef, const MDEvent *sourceRef, int32_t count)
183 {
184 if (destRef == sourceRef || count == 0)
185 return;
186 if (destRef < sourceRef) {
187 while (count-- > 0) {
188 *destRef = *sourceRef;
189 if (MDHasEventMessage(destRef))
190 MDMessageRetain(MDPrivateGetMessage(destRef));
191 destRef++;
192 sourceRef++;
193 }
194 } else {
195 destRef += count;
196 sourceRef += count;
197 while (count-- > 0) {
198 destRef--;
199 sourceRef--;
200 *destRef = *sourceRef;
201 if (MDHasEventMessage(destRef))
202 MDMessageRetain(MDPrivateGetMessage(destRef));
203 }
204 }
205 }
206
207 /* --------------------------------------
208 ��� MDEventMove
209 -------------------------------------- */
210 void
211 MDEventMove(MDEvent *destRef, MDEvent *sourceRef, int32_t count)
212 {
213 if (destRef == sourceRef || count == 0)
214 return;
215 if (destRef < sourceRef) {
216 while (count-- > 0) {
217 *destRef = *sourceRef;
218 MDEventInit(sourceRef);
219 destRef++;
220 sourceRef++;
221 }
222 } else {
223 destRef += count;
224 sourceRef += count;
225 while (count-- > 0) {
226 destRef--;
227 sourceRef--;
228 *destRef = *sourceRef;
229 MDEventInit(sourceRef);
230 }
231 }
232 }
233
234 #ifdef __MWERKS__
235 #pragma mark ====== Message-type event manipulation ======
236 #endif
237
238 /* --------------------------------------
239 ��� MDGetMessageLength
240 -------------------------------------- */
241 int32_t
242 MDGetMessageLength(const MDEvent *eventRef)
243 {
244 if (MDHasEventMessage(eventRef)) {
245 if (MDPrivateGetMessage(eventRef) == NULL)
246 return 0;
247 else return (MDPrivateGetMessage(eventRef)->length);
248 } else return -1;
249 }
250
251 /* --------------------------------------
252 ��� MDGetMessage
253 -------------------------------------- */
254 int32_t
255 MDGetMessage(const MDEvent *eventRef, unsigned char *outBuffer)
256 {
257 if (MDHasEventMessage(eventRef)) {
258 MDMessage *message = MDPrivateGetMessage(eventRef);
259 if (message == NULL)
260 return 0;
261 memmove(outBuffer, message->msg, message->length);
262 return message->length;
263 } else return -1;
264 }
265
266 /* --------------------------------------
267 ��� MDGetMessagePartial
268 -------------------------------------- */
269 int32_t
270 MDGetMessagePartial(const MDEvent *eventRef, unsigned char *outBuffer, int32_t inOffset, int32_t inLength)
271 {
272 if (MDHasEventMessage(eventRef)) {
273 MDMessage *message = MDPrivateGetMessage(eventRef);
274 if (message == NULL)
275 return 0;
276 if (inOffset + inLength > message->length)
277 inLength = message->length - inOffset;
278 memmove(outBuffer, message->msg + inOffset, inLength);
279 return inLength;
280 } else return -1;
281 }
282
283 /* --------------------------------------
284 ��� MDGetMessageConstPtr
285 -------------------------------------- */
286 const unsigned char *
287 MDGetMessageConstPtr(const MDEvent *eventRef, int32_t *outLength)
288 {
289 if (MDHasEventMessage(eventRef)) {
290 MDMessage *message = MDPrivateGetMessage(eventRef);
291 if (outLength != NULL)
292 *outLength = message->length;
293 return message->msg;
294 } else return NULL;
295 }
296
297 /* --------------------------------------
298 ��� MDGetMessagePtr
299 -------------------------------------- */
300 unsigned char *
301 MDGetMessagePtr(MDEvent *eventRef, int32_t *outLength)
302 {
303 if (MDHasEventMessage(eventRef)) {
304 MDMessage *message = MDPrivateGetMessage(eventRef);
305 if (outLength != NULL)
306 *outLength = message->length;
307 if (message->refCount > 1) {
308 /* This is a copy message, so we need to allocate new memory */
309 message = MDMessageReallocate(message, message->length);
310 if (message == NULL)
311 return NULL; /* out of memory */
312 MDPrivateSetMessage(eventRef, message);
313 }
314 return message->msg;
315 } else return NULL;
316 }
317
318 /* --------------------------------------
319 ��� MDSetMessageLength
320 -------------------------------------- */
321 int32_t
322 MDSetMessageLength(MDEvent *eventRef, int32_t inLength)
323 {
324 if (MDHasEventMessage(eventRef)) {
325 MDMessage *message;
326 message = MDMessageReallocate(MDPrivateGetMessage(eventRef), inLength);
327 if (message != NULL) {
328 MDPrivateSetMessage(eventRef, message);
329 return inLength;
330 } else return -1; /* out of memory */
331 }
332 return 0;
333 }
334
335 /* --------------------------------------
336 ��� MDCopyMessage
337 -------------------------------------- */
338 void
339 MDCopyMessage(MDEvent *destRef, MDEvent *srcRef)
340 {
341 if (MDHasEventMessage(destRef) && MDHasEventMessage(srcRef)) {
342 MDMessage *message = MDPrivateGetMessage(srcRef);
343 MDMessageRetain(message);
344 MDMessageRelease(MDPrivateGetMessage(destRef));
345 MDPrivateSetMessage(destRef, message);
346 }
347 }
348
349 /* --------------------------------------
350 ��� MDSetMessage
351 -------------------------------------- */
352 int32_t
353 MDSetMessage(MDEvent *eventRef, const unsigned char *inBuffer)
354 {
355 if (MDHasEventMessage(eventRef)) {
356 MDMessage *message = MDPrivateGetMessage(eventRef);
357 if (message != NULL) {
358 if (message->refCount > 1) {
359 /* This is a copy message, so we need to allocate new memory */
360 message = MDMessageReallocate(message, message->length);
361 if (message == NULL)
362 return -1; /* out of memory */
363 MDPrivateSetMessage(eventRef, message);
364 }
365 memmove(message->msg, inBuffer, message->length);
366 return message->length;
367 }
368 }
369 return 0;
370 }
371
372 /* --------------------------------------
373 ��� MDSetMessagePartial
374 -------------------------------------- */
375 int32_t
376 MDSetMessagePartial(MDEvent *eventRef, const unsigned char *inBuffer, int32_t inOffset, int32_t inLength)
377 {
378 if (MDHasEventMessage(eventRef)) {
379 MDMessage *message = MDPrivateGetMessage(eventRef);
380 if (message == NULL)
381 return 0;
382 if (inOffset < 0)
383 inOffset = 0;
384 if (inOffset + inLength > message->length)
385 inLength = message->length - inOffset;
386 if (message->refCount > 1) {
387 /* This is a copy message, so we need to allocate new memory */
388 message = MDMessageReallocate(message, message->length);
389 if (message == NULL)
390 return -1; /* out of memory */
391 MDPrivateSetMessage(eventRef, message);
392 }
393 memmove(message->msg + inOffset, inBuffer, inLength);
394 return message->length;
395 }
396 return 0;
397 }
398
399 #ifdef __MWERKS__
400 #pragma mark ====== Display data ======
401 #endif
402
403 /* --------------------------------------
404 ��� MDEventNoteNumberToNoteName
405 -------------------------------------- */
406 void
407 MDEventNoteNumberToNoteName(unsigned char inNumber, char *outName)
408 {
409 static char *note_name[] =
410 {"C", "C#", "D", "D#", "E", "F",
411 "F#", "G", "G#", "A", "A#", "B"};
412 snprintf(outName, 5, "%s%d", note_name[inNumber % 12],
413 (inNumber / 12) - 1 - (sIsNote60C4 ? 0 : 1));
414 }
415
416 int
417 MDEventNoteNameToNoteNumber(const char *p)
418 {
419 int n, code;
420 if (isdigit(*p)) {
421 /* Note number */
422 code = atoi(p);
423 } else {
424 static unsigned char table[] = { 9, 11, 0, 2, 4, 5, 7 };
425 if (*p >= 'A' && *p <= 'G')
426 code = table[*p++ - 'A'];
427 else if (*p >= 'a' && *p <= 'g')
428 code = table[*p++ - 'a'];
429 else return -1;
430 if (*p == '#') {
431 code++;
432 p++;
433 } else if (*p == 'b') {
434 code--;
435 p++;
436 }
437 n = atoi(p);
438 code += (n + (sIsNote60C4 ? 0 : 1) + 1) * 12;
439 }
440 return code;
441 }
442
443 /* --------------------------------------
444 ��� MDEventStaffToNote
445 -------------------------------------- */
446 int
447 MDEventStaffIndexToNoteNumber(int staff)
448 {
449 static signed char sOffset[] = {0, 4, 7, 11, 14, 17, 21, 24};
450 if (staff >= 0) {
451 return 60 + (staff / 7) * 24 + sOffset[staff % 7];
452 } else {
453 staff = -staff;
454 return 60 - ((staff / 7 + 1) * 24 - sOffset[7 - staff % 7]);
455 }
456 }
457
458 typedef struct DictRecord {
459 signed char kind;
460 signed char code;
461 const char *text;
462 const char *abbtext;
463 } DictRecord;
464
465 #define ArraySize(array) (sizeof(array) / sizeof(array[0]))
466
467 static const DictRecord sEventKindTable[] = {
468 { kMDEventTempo, -1, "@Tempo", "@t" },
469 { kMDEventTimeSignature, -1, "@Meter", "@m" },
470 { kMDEventKey, -1, "@Key", "@k" },
471 { kMDEventSMPTE, -1, "@SMPTE", "@sm" },
472 { kMDEventPortNumber, -1, "@Port", "@p" },
473 { kMDEventProgram, -1, "+Program", "+p" },
474 { kMDEventPitchBend, -1, "+Pitchbend", "+b" },
475 { kMDEventChanPres, -1, "+ChanPres", "+c" },
476 /* { kMDEventKeyPres, -1, "+KeyPres", "+k" }, */
477 { kMDEventSysex, -1, "#Sysex", "#" },
478 { kMDEventSysexCont, -1, "#Sysex", "#" },
479 { kMDEventMetaText, 2, "@Copyright", "@c" },
480 { kMDEventMetaText, 3, "@Sequence", "@s" },
481 { kMDEventMetaText, 4, "@Instrument", "@i" },
482 { kMDEventMetaText, 5, "@Lyric", "@l" },
483 { kMDEventMetaText, 6, "@Marker", "@mk" },
484 { kMDEventMetaText, 7, "@Cue", "@cu" },
485 { kMDEventMetaText, 8, "@Program", "@pr" },
486 { kMDEventMetaText, 9, "@Device", "@dv" },
487 { kMDEventMetaText, 1, "@Text", "@tx" },
488 { kMDEventControl, 0, "*BankSelMSB", "*b" },
489 { kMDEventControl, 1, "*Modulation", "*m" },
490 { kMDEventControl, 5, "*PortaTime", "*pt" },
491 { kMDEventControl, 6, "*DataEntryMSB", "*d" },
492 { kMDEventControl, 7, "*Volume", "*v" },
493 { kMDEventControl, 10, "*Pan", "*p" },
494 { kMDEventControl, 11, "*Expression", "*e" },
495 { kMDEventControl, 32, "*BankSelLSB", "*bl" },
496 { kMDEventControl, 38, "*DataEntryLSB", "*dl" },
497 { kMDEventControl, 64, "*Hold", "*h" },
498 { kMDEventControl, 65, "*Portamento", "*pp" },
499 { kMDEventControl, 66, "*Sostenuto", "*sp" },
500 { kMDEventControl, 67, "*Soft", "*sf" },
501 { kMDEventControl, 71, "*Resonance", "*r" },
502 { kMDEventControl, 72, "*Release", "*rl" },
503 { kMDEventControl, 73, "*Attack", "*at" },
504 { kMDEventControl, 74, "*Cutoff", "*ct" },
505 { kMDEventControl, 84, "*PortaCont", "*pc" },
506 { kMDEventControl, 91, "*Reverb", "*rv" },
507 { kMDEventControl, 93, "*Chorus", "*ch" },
508 { kMDEventControl, 94, "*VariEffect", "*ve" },
509 { kMDEventControl, 96, "*DataInc", "*+" },
510 { kMDEventControl, 97, "*DataDec", "*-" },
511 { kMDEventControl, 98, "*NRPNLSB", "*nl" },
512 { kMDEventControl, 99, "*NRPNMSB", "*nm" },
513 { kMDEventControl, 100, "*RPNLSB", "*rp" },
514 { kMDEventControl, 101, "*RPNMSB", "*rm" },
515 { kMDEventControl, 120, "*AllSoundsOff", "*ao" },
516 { kMDEventControl, 121, "*ResetAllConts", "*rs" },
517 { kMDEventControl, 123, "*AllNotesOff", "*an" },
518 { kMDEventControl, 124, "*OmniOff", "*oo" },
519 { kMDEventControl, 125, "*OmniOn", "*on" },
520 { kMDEventControl, 126, "*Mono", "*mo" },
521 { kMDEventControl, 127, "*Poly", "*po" }
522 };
523
524 static const char *sMeta = "@Meta";
525 static const char *sText = "@Text";
526 static const char *sControl = "*Control";
527
528 static const char *sKeyTable[] = {
529 "Cb", "Ab", "Gb", "Eb", "Db", "Bb", "Ab", "F", "Eb", "C", "Bb", "G", "F", "D",
530 "C", "A",
531 "G", "E", "D", "B", "A", "F#", "E", "C#", "B", "G#", "F#", "D#", "C#", "A#"
532 };
533 static const char *sMajorMinor[] = { "major", "minor" };
534
535 static const char *sUnknown = "<Unknown>";
536
537 /* --------------------------------------
538 ��� MDEventToKindString
539 -------------------------------------- */
540 int32_t
541 MDEventToKindString(const MDEvent *eref, char *buf, int32_t length)
542 {
543 int kind = MDGetKind(eref);
544 int code = MDGetCode(eref);
545 int n;
546 char temp[24];
547 for (n = ArraySize(sEventKindTable) - 1; n >= 0; n--) {
548 if (sEventKindTable[n].kind == kind
549 && (sEventKindTable[n].code == -1 || sEventKindTable[n].code == code)) {
550 if (kind == kMDEventControl) {
551 snprintf(buf, length, "%s(%d)", sEventKindTable[n].text, code);
552 } else {
553 strncpy(buf, sEventKindTable[n].text, length - 1);
554 buf[length - 1] = 0;
555 }
556 break;
557 }
558 }
559 if (n < 0) {
560 switch (kind) {
561 case kMDEventMetaText:
562 snprintf(buf, length, "%s(%d)", sText, code);
563 break;
564 case kMDEventMetaMessage:
565 snprintf(buf, length, "%s(%d)", sMeta, (int)MDGetCode(eref));
566 break;
567 case kMDEventNote:
568 case kMDEventInternalNoteOn:
569 case kMDEventInternalNoteOff:
570 MDEventNoteNumberToNoteName(MDGetCode(eref), temp);
571 snprintf(buf, length, "%-3s(%d)", temp, (int)MDGetCode(eref));
572 if (kind != kMDEventNote) {
573 size_t len = strlen(buf);
574 if (len < length) {
575 buf[len++] = (kind == kMDEventInternalNoteOn ? '*' : '!');
576 buf[len] = 0;
577 }
578 }
579 break;
580 case kMDEventKeyPres:
581 MDEventNoteNumberToNoteName(MDGetCode(eref), temp);
582 snprintf(buf, length, ">%-3s(%d)", temp, (int)MDGetCode(eref));
583 break;
584 case kMDEventControl:
585 snprintf(buf, length, "%s(%d)", sControl, code);
586 break;
587 case kMDEventNull:
588 buf[0] = 0;
589 break;
590 default:
591 snprintf(buf, length, "%s(%d)", sUnknown, (int)kind);
592 break;
593 }
594 }
595 return (int)strlen(buf);
596 }
597
598 static char *sMetronomeBeatModifier[] = { "", ".", "t", "*" };
599
600 /* --------------------------------------
601 ��� MDEventToDataString
602 -------------------------------------- */
603 int32_t
604 MDEventToDataString(const MDEvent *eref, char *buf, int32_t length)
605 {
606 const unsigned char *ptr;
607 const MDSMPTERecord *smp;
608 int32_t n, n1;
609 int d1, d2;
610
611 switch (MDGetKind(eref)) {
612 case kMDEventTempo:
613 n = sprintf(buf, "%.2f", MDGetTempo(eref));
614 break;
615 case kMDEventTimeSignature:
616 ptr = MDGetMetaDataPtr(eref);
617 d1 = (1 << (int)ptr[1]);
618 d2 = 96 / d1;
619 if (ptr[2] == d2) {
620 n = sprintf(buf, "%d/%d", (int)ptr[0], d1);
621 } else {
622 int d3, dot;
623 switch (ptr[2]) {
624 case 96: case 48: case 24: case 12: case 6: case 3:
625 d3 = 96 / ptr[2]; /* normal notes */
626 dot = 0;
627 break;
628 case 144: case 72: case 36: case 18: case 9:
629 d3 = 144 / ptr[2]; /* dotted notes */
630 dot = 1;
631 break;
632 case 64: case 32: case 16: case 8: case 4: case 2: case 1:
633 d3 = 64 / ptr[2]; /* triplets */
634 dot = 2;
635 break;
636 default:
637 d3 = ptr[2];
638 dot = 3;
639 break;
640 }
641 n = sprintf(buf, "%d/%d (%d%s)", (int)ptr[0], d1, d3, sMetronomeBeatModifier[dot]);
642 }
643 break;
644 case kMDEventKey:
645 ptr = MDGetMetaDataPtr(eref);
646 d2 = (ptr[1] & 1);
647 d1 = ((signed char)ptr[0] + 7) * 2 + d2;
648 if (d1 >= 0 && d1 < ArraySize(sKeyTable))
649 n = sprintf(buf, "%s %s", sKeyTable[d1], sMajorMinor[d2]);
650 else
651 n = sprintf(buf, "%s", sUnknown);
652 break;
653 case kMDEventSMPTE:
654 smp = MDGetSMPTERecordPtr(eref);
655 n = sprintf(buf, "%02d:%02d:%02d:%02d.%02d",
656 (int)smp->hour, (int)smp->min, (int)smp->sec, (int)smp->frame, (int)smp->subframe);
657 break;
658 case kMDEventPortNumber:
659 case kMDEventProgram:
660 case kMDEventPitchBend:
661 case kMDEventChanPres:
662 case kMDEventControl:
663 case kMDEventKeyPres:
664 n = sprintf(buf, "%6d", (int)MDGetData1(eref));
665 break;
666 case kMDEventMetaText:
667 ptr = MDGetMessageConstPtr(eref, &n);
668 if (n >= length)
669 n = length - 1;
670 strncpy(buf, (const char *)ptr, n);
671 buf[n] = 0;
672 break;
673 case kMDEventMetaMessage:
674 case kMDEventSysex:
675 case kMDEventSysexCont:
676 ptr = MDGetMessageConstPtr(eref, &n1);
677 if (MDGetKind(eref) == kMDEventSysex && n1 >= 8 && ptr[1] == 0x41) {
678 /* Does have Roland check-sum? */
679 d1 = 0;
680 for (n = 5; n < n1 - 1; n++)
681 d1 += ptr[n];
682 d1 = ((d1 & 0x7f) == 0);
683 } else d1 = 0;
684 n = 0;
685 while (n < length - 3 && n1 > 0) {
686 if (d1 && n1 == 2)
687 n += sprintf(buf + n, "cs ");
688 else
689 n += sprintf(buf + n, "%02X ", (int)(*ptr));
690 ptr++;
691 n1--;
692 }
693 if (n >= 1)
694 n--;
695 buf[n] = 0;
696 break;
697 case kMDEventNote:
698 d1 = MDGetNoteOnVelocity(eref);
699 d2 = MDGetNoteOffVelocity(eref);
700 /* d1 = ((MDGetData1(eref) >> 8) & 0xff);
701 d2 = (MDGetData1(eref) & 0xff); */
702 if (d2 != 0)
703 n = sprintf(buf, "%6d /%3d", d1, d2);
704 else
705 n = sprintf(buf, "%6d", d1);
706 break;
707 case kMDEventNull:
708 buf[0] = 0;
709 n = 0;
710 break;
711 default:
712 n = sprintf(buf, "%s", sUnknown);
713 break;
714 }
715 return n;
716 }
717
718 /* --------------------------------------
719 ��� MDEventToGTString
720 -------------------------------------- */
721 int32_t
722 MDEventToGTString(const MDEvent *eref, char *buf, int32_t length)
723 {
724 int32_t n;
725 /* char temp1[24]; */
726 MDTickType duration;
727
728 switch (MDGetKind(eref)) {
729 case kMDEventNote:
730 duration = MDGetDuration(eref);
731 n = sprintf(buf, "%6d", (int32_t)(duration));
732 break;
733 default:
734 buf[0] = 0;
735 n = 0;
736 break;
737 }
738 return n;
739 }
740
741 /* --------------------------------------
742 ��� MDEventMatchTable
743 -------------------------------------- */
744 static int
745 MDEventMatchTable(const char *buf, const DictRecord *dp, int max)
746 {
747 /* Match the string with the table */
748 const char *p, *q;
749 int n;
750
751 /* Look up the full name table first */
752 for (n = 0; n < max; n++) {
753 p = buf;
754 q = dp[n].text;
755 while (*p != 0 && *q != 0) {
756 if (tolower(*p) != tolower(*q))
757 break;
758 p++;
759 q++;
760 }
761 if (*p == 0 || *q == 0)
762 return n; /* Found */
763 }
764
765 /* Then the abbreviation table */
766 for (n = 0; n < max; n++) {
767 p = buf;
768 q = dp[n].abbtext;
769 while (*p != 0 && *q != 0) {
770 if (tolower(*p) != tolower(*q))
771 break;
772 p++;
773 q++;
774 }
775 if (*p == 0 || *q == 0)
776 return n; /* Found */
777 }
778
779 return -1; /* not found */
780 }
781
782 /* --------------------------------------
783 ��� MDEventKindStringToEvent
784 -------------------------------------- */
785 MDEventFieldCode
786 MDEventKindStringToEvent(const char *buf, MDEventFieldData *epout)
787 {
788 char temp[64], *p;
789 int n, kind, code;
790
791 /* Return value */
792 kind = -1;
793 code = -1;
794
795 /* Copy the string with conversion to lower characters */
796 for (n = 0, p = temp; n < 63 && buf[n] != 0; n++) {
797 if (!isspace(buf[n]))
798 *p++ = tolower(buf[n]);
799 }
800 *p = 0;
801
802 if (temp[0] == 0) {
803 kind = kMDEventNull;
804 code = 0;
805 } else if (temp[0] == '@') {
806 /* Meta event */
807 n = MDEventMatchTable(temp, sEventKindTable, ArraySize(sEventKindTable));
808 if (n >= 0) {
809 kind = sEventKindTable[n].kind;
810 code = sEventKindTable[n].code;
811 } else {
812 if (sscanf(temp, "@text(%d)", &n) == 1) {
813 code = n;
814 } else if (sscanf(temp, "@meta(%d)", &n) == 1) {
815 code = n;
816 } else if (sscanf(temp, "@%d", &n) == 1) {
817 code = n;
818 } else return kMDEventFieldNone;
819 if (code >= 1 && code <= 16) {
820 kind = kMDEventMetaText;
821 } else kind = kMDEventMetaMessage;
822 }
823 if (kind == kMDMetaEndOfTrack)
824 return kMDEventFieldNone; /* invalid */
825 } else if (temp[0] == '#') {
826 /* Sysex */
827 kind = kMDEventSysex;
828 } else if (temp[0] == '*') {
829 /* Control change */
830 kind = kMDEventControl;
831 n = MDEventMatchTable(temp, sEventKindTable, ArraySize(sEventKindTable));
832 if (n >= 0) {
833 code = sEventKindTable[n].code;
834 } else {
835 if (sscanf(temp, "*%d", &code) != 1)
836 return kMDEventFieldNone;
837 }
838 epout->ucValue[0] = kind;
839 epout->ucValue[1] = code;
840 return kMDEventFieldKindAndCode;
841 } else if (temp[0] == '+') {
842 /* Other special controllers */
843 n = MDEventMatchTable(temp, sEventKindTable, ArraySize(sEventKindTable));
844 if (n >= 0) {
845 kind = sEventKindTable[n].kind;
846 }
847 } else {
848 /* Notes */
849 kind = kMDEventNote;
850 p = temp;
851 if (*p == '>') {
852 /* Key pressure */
853 kind = kMDEventKeyPres;
854 p++;
855 }
856 code = MDEventNoteNameToNoteNumber(p);
857 if (code < 0)
858 return kMDEventFieldNone;
859 }
860 if (kind >= 0) {
861 epout->ucValue[0] = kind;
862 epout->ucValue[1] = (code >= 0 ? code : 0);
863 return kMDEventFieldKindAndCode;
864 }
865 return kMDEventFieldNone;
866 }
867
868 /* --------------------------------------
869 ��� MDEventGTStringToEvent
870 -------------------------------------- */
871 MDEventFieldCode
872 MDEventGTStringToEvent(const MDEvent *epin, const char *buf, MDEventFieldData *epout)
873 {
874 return kMDEventFieldNone;
875 }
876
877 /* --------------------------------------
878 ��� MDEventDataStringToEvent
879 -------------------------------------- */
880 MDEventFieldCode
881 MDEventDataStringToEvent(const MDEvent *epin, const char *buf, MDEventFieldData *epout)
882 {
883 unsigned char *ptr;
884 int32_t n;
885 int d0, d1, d2, d3, d4;
886 double dbl;
887 char temp[64];
888
889 epout->whole = 0;
890 switch (MDGetKind(epin)) {
891 case kMDEventTempo:
892 dbl = atof(buf);
893 if (dbl == 0.0)
894 return kMDEventFieldNone;
895 epout->floatValue = (float)dbl;
896 return kMDEventFieldTempo;
897 case kMDEventTimeSignature:
898 if (sscanf(buf, "%d/%d%n", &d1, &d2, &d3) == 2) {
899 if (32 % d2 != 0)
900 break; /* Invalid note name */
901 switch (d2) {
902 case 1: d4 = 0; break;
903 case 2: d4 = 1; break;
904 case 4: d4 = 2; break;
905 case 8: d4 = 3; break;
906 case 16: d4 = 4; break;
907 case 32: d4 = 5; break;
908 }
909 d1 = (d1 & 0x7f);
910 if (d1 != 0) {
911 char cc;
912 epout->ucValue[0] = d1;
913 epout->ucValue[1] = d4;
914 if (sscanf(buf + d3, " (%d%c", &d1, &cc) == 2) {
915 if (d1 == 0)
916 break; /* Invalid */
917 if (cc == ')') {
918 /* Normal note */
919 if (32 % d1 != 0)
920 break; /* Invalid note name */
921 d1 = 96 / d1;
922 } else if (cc == sMetronomeBeatModifier[1][0]) {
923 if (16 % d1 != 0)
924 break; /* Invalid note name */
925 d1 = 144 / d1;
926 } else if (cc == sMetronomeBeatModifier[2][0]) {
927 if (64 % d1 != 0)
928 break; /* Invalid note name */
929 d1 = 64 / d1;
930 } else if (cc != sMetronomeBeatModifier[3][0])
931 break; /* Invalid format */
932 } else d1 = 96 / d2;
933 if (d1 == 0)
934 d1 = 1;
935 epout->ucValue[2] = d1;
936 epout->ucValue[3] = 8;
937 return kMDEventFieldMetaData;
938 }
939 }
940 break;
941 case kMDEventKey:
942 if (sscanf(buf, "%2s %3s", temp, temp + 4) == 2) {
943 temp[0] = toupper(temp[0]);
944 for (d2 = 0; d2 < 2; d2++) {
945 if (strncmp(temp + 4, sMajorMinor[d2], 3) == 0)
946 break;
947 }
948 if (d2 >= 2)
949 d2 = 0; /* Assume it is major */
950 for (d1 = 0; d1 < ArraySize(sKeyTable) / 2; d1++) {
951 if (strcmp(temp, sKeyTable[d1 * 2 + d2]) == 0) {
952 /* found */
953 epout->ucValue[0] = d1 - 7;
954 epout->ucValue[1] = d2;
955 return kMDEventFieldMetaData;
956 }
957 }
958 }
959 break;
960 case kMDEventSMPTE:
961 if (sscanf(buf, "%d:%d:%d:%d.%d", &d0, &d1, &d2, &d3, &d4) == 5) {
962 epout->smpte.hour = d0;
963 epout->smpte.min = d1;
964 epout->smpte.sec = d2;
965 epout->smpte.frame = d3;
966 epout->smpte.subframe = d4;
967 return kMDEventFieldSMPTE;
968 }
969 break;
970 case kMDEventPortNumber:
971 case kMDEventProgram:
972 case kMDEventPitchBend:
973 case kMDEventChanPres:
974 case kMDEventKeyPres:
975 case kMDEventControl:
976 if (sscanf(buf, "%d", &d1) == 1) {
977 epout->intValue = d1;
978 return kMDEventFieldData;
979 }
980 break;
981 case kMDEventMetaText:
982 n = (int)strlen(buf) + 1;
983 ptr = (unsigned char *)malloc(n + sizeof(int32_t));
984 if (ptr != NULL) {
985 *((int32_t *)ptr) = n;
986 strcpy((char *)(ptr + sizeof(int32_t)), buf);
987 epout->binaryData = ptr;
988 return kMDEventFieldBinaryData;
989 }
990 break;
991 case kMDEventMetaMessage:
992 case kMDEventSysex:
993 case kMDEventSysexCont:
994 d0 = 16;
995 epout->binaryData = (unsigned char *)malloc(d0);
996 ptr = (unsigned char *)buf; /* Save the initial pointer */
997 d1 = sizeof(int32_t);
998 while (*buf != 0) {
999 while (*buf != 0 && isspace(*buf))
1000 buf++;
1001 if (*buf == 0)
1002 break;
1003 if (*buf == 'c' && buf[1] == 's') {
1004 /* Roland check-sum */
1005 d2 = 0;
1006 for (d3 = 5 + sizeof(int32_t); d3 < d1; d3++)
1007 d2 += epout->binaryData[d3];
1008 d2 = (0x80 - (d2 & 0x7f)) & 0x7f;
1009 buf += 2;
1010 } else if (sscanf(buf, "%2x%n", &d2, &d3) == 1) {
1011 buf += d3; /* Next position */
1012 } else if (*buf == '#') {
1013 buf++;
1014 if (sscanf(buf, "%d%n", &d2, &d3) == 1) {
1015 buf += d3;
1016 } else goto bad_sysex;
1017 } else goto bad_sysex;
1018 epout->binaryData[d1] = d2;
1019 d1++;
1020 if (d1 == d0) {
1021 d0 *= 2;
1022 epout->binaryData = (unsigned char *)realloc(epout->binaryData, d0);
1023 }
1024 }
1025 *((int32_t *)(epout->binaryData)) = d1 - sizeof(int32_t);
1026 return kMDEventFieldBinaryData;
1027 bad_sysex:
1028 free(epout->binaryData);
1029 epout->intValue = (int32_t)(buf - (char *)ptr);
1030 return kMDEventFieldInvalid;
1031
1032 case kMDEventNote:
1033 d0 = sscanf(buf, "%d / %d", &d1, &d2);
1034 if (d0 >= 1) {
1035 if (d0 == 1)
1036 d2 = 0;
1037 epout->ucValue[0] = d1;
1038 epout->ucValue[1] = d2;
1039 return kMDEventFieldVelocities;
1040 }
1041 break;
1042 }
1043 return kMDEventFieldNone;
1044 }
1045
1046 /* --------------------------------------
1047 ��� MDEventToMIDIMessage
1048 -------------------------------------- */
1049 int
1050 MDEventToMIDIMessage(const MDEvent *eventRef, unsigned char *buf)
1051 {
1052 switch (MDGetKind(eventRef)) {
1053 case kMDEventProgram:
1054 buf[0] = kMDEventSMFProgram + MDGetChannel(eventRef);
1055 buf[1] = MDGetData1(eventRef);
1056 return 2;
1057 case kMDEventNote:
1058 buf[0] = kMDEventSMFNoteOn + MDGetChannel(eventRef);
1059 buf[1] = MDGetCode(eventRef);
1060 buf[2] = MDGetNoteOnVelocity(eventRef);
1061 return 3;
1062 case kMDEventInternalNoteOff:
1063 buf[0] = kMDEventSMFNoteOff + MDGetChannel(eventRef);
1064 buf[1] = MDGetCode(eventRef);
1065 buf[2] = MDGetNoteOffVelocity(eventRef);
1066 return 3;
1067 case kMDEventControl:
1068 buf[0] = kMDEventSMFControl + MDGetChannel(eventRef);
1069 buf[1] = MDGetCode(eventRef);
1070 buf[2] = MDGetData1(eventRef);
1071 return 3;
1072 /*
1073 case kMDEventRPNControl:
1074 buf[0] = 0xb0 + MDGetChannel(eventRef);
1075 buf[1] = 6;
1076 buf[2] = MDGetData2(eventRef);
1077 return 3;
1078 case kMDEventRPNFine:
1079 buf[0] = 0xb0 + MDGetChannel(eventRef);
1080 buf[1] = 38;
1081 buf[2] = MDGetData2(eventRef);
1082 return 3;
1083 case kMDEventRPNInc:
1084 return 0;
1085 */
1086 case kMDEventPitchBend:
1087 buf[0] = kMDEventSMFPitchBend + MDGetChannel(eventRef);
1088 buf[1] = MDGetData1(eventRef) & 0x7f;
1089 buf[2] = ((MDGetData1(eventRef) + 8192) >> 7) & 0x7f;
1090 return 3;
1091 case kMDEventChanPres:
1092 buf[0] = kMDEventSMFChannelPressure + MDGetChannel(eventRef);
1093 buf[1] = MDGetData1(eventRef);
1094 return 2;
1095 case kMDEventKeyPres:
1096 buf[0] = kMDEventSMFKeyPressure + MDGetChannel(eventRef);
1097 buf[1] = MDGetCode(eventRef);
1098 buf[2] = MDGetData1(eventRef);
1099 return 3;
1100 default:
1101 return 0;
1102 }
1103 }
1104
1105 /* --------------------------------------
1106 ��� MDEventFromMIDIMessage
1107 -------------------------------------- */
1108 MDStatus
1109 MDEventFromMIDIMessage(MDEvent *eventRef, unsigned char firstByte, unsigned char lastStatusByte, int (*getCharFunc)(void *), void *funcArgument, unsigned char *outStatusByte)
1110 {
1111 MDStatus result = kMDNoError;
1112 int data1, data2;
1113 unsigned char ch; /* MIDI channel */
1114
1115 /* Get the status byte */
1116 if (firstByte < 0x80) {
1117 /* running status */
1118 data1 = firstByte;
1119 firstByte = lastStatusByte;
1120 } else {
1121 data1 = (*getCharFunc)(funcArgument);
1122 if (data1 < 0)
1123 return kMDErrorUnexpectedEOF;
1124 }
1125
1126 /* Get the MD track number */
1127 ch = (firstByte & 0x0f); /* MIDI channel */
1128 MDSetChannel(eventRef, ch);
1129
1130 switch (firstByte & 0xf0) {
1131 case kMDEventSMFNoteOff:
1132 case kMDEventSMFNoteOn:
1133 data2 = (*getCharFunc)(funcArgument);
1134 if (data2 < 0) {
1135 result = kMDErrorUnexpectedEOF;
1136 break;
1137 }
1138 data2 &= 0xff;
1139 if ((firstByte & 0xf0) == kMDEventSMFNoteOn && data2 != 0) {
1140 /* Note on */
1141 MDSetKind(eventRef, kMDEventInternalNoteOn);
1142 MDSetCode(eventRef, data1);
1143 MDSetNoteOnVelocity(eventRef, data2);
1144 MDSetNoteOffVelocity(eventRef, 0);
1145 MDSetDuration(eventRef, 0);
1146 } else {
1147 /* Note off */
1148 MDSetKind(eventRef, kMDEventInternalNoteOff);
1149 MDSetCode(eventRef, data1);
1150 MDSetNoteOnVelocity(eventRef, 0);
1151 MDSetNoteOffVelocity(eventRef, data2);
1152 }
1153 break;
1154 case kMDEventSMFKeyPressure:
1155 data2 = (*getCharFunc)(funcArgument);
1156 if (data2 < 0) {
1157 result = kMDErrorUnexpectedEOF;
1158 break;
1159 }
1160 MDSetKind(eventRef, kMDEventKeyPres);
1161 MDSetCode(eventRef, data1);
1162 MDSetData1(eventRef, data2);
1163 break;
1164 case kMDEventSMFControl:
1165 data2 = (*getCharFunc)(funcArgument);
1166 if (data2 < 0) {
1167 result = kMDErrorUnexpectedEOF;
1168 break;
1169 }
1170 MDSetKind(eventRef, kMDEventControl);
1171 MDSetCode(eventRef, data1);
1172 MDSetData1(eventRef, data2);
1173 break;
1174 case kMDEventSMFProgram:
1175 MDSetKind(eventRef, kMDEventProgram);
1176 MDSetData1(eventRef, data1);
1177 break;
1178 case kMDEventSMFChannelPressure:
1179 MDSetKind(eventRef, kMDEventChanPres);
1180 MDSetData1(eventRef, data1);
1181 break;
1182 case kMDEventSMFPitchBend:
1183 data2 = (*getCharFunc)(funcArgument);
1184 if (data2 < 0) {
1185 result = kMDErrorUnexpectedEOF;
1186 break;
1187 }
1188 MDSetKind(eventRef, kMDEventPitchBend);
1189 MDSetData1(eventRef, ((data1 & 0x7f) + ((data2 & 0x7f) << 7)) - 8192);
1190 break;
1191 default:
1192 result = kMDErrorUnknownChannelEvent;
1193 break;
1194 } /* end switch */
1195
1196 if (outStatusByte != NULL)
1197 *outStatusByte = firstByte;
1198
1199 return result;
1200
1201 }
1202
1203 /* --------------------------------------
1204 ��� MDEventParseTimeSignature
1205 -------------------------------------- */
1206 int
1207 MDEventParseTimeSignature(const MDEvent *eptr, int32_t timebase, int32_t *outTickPerBeat, int32_t *outBeatPerMeasure)
1208 {
1209 const unsigned char *p;
1210 if (eptr != NULL && MDGetKind(eptr) == kMDEventTimeSignature) {
1211 p = MDGetMetaDataPtr(eptr);
1212 if (p[1] >= 31)
1213 *outTickPerBeat = timebase; // ���������������������
1214 else
1215 *outTickPerBeat = (int32_t)(timebase * 4 / (1L << p[1]));
1216 *outBeatPerMeasure = p[0];
1217 return 1;
1218 } else {
1219 *outBeatPerMeasure = 4;
1220 *outTickPerBeat = timebase;
1221 return 0;
1222 }
1223 }
1224
1225 /* ------------------------------------------
1226 ��� MDEventCalculateMetronomeBarAndBeat
1227 ------------------------------------------ */
1228 int
1229 MDEventCalculateMetronomeBarAndBeat(const MDEvent *eptr, int32_t timebase, int32_t *outTickPerMeasure, int32_t *outTickPerMetronomeBeat)
1230 {
1231 if (eptr != NULL && MDGetKind(eptr) == kMDEventTimeSignature) {
1232 const unsigned char *p = MDGetMetaDataPtr(eptr);
1233 *outTickPerMetronomeBeat = timebase * p[2] / 24;
1234 if (p[1] < 31)
1235 *outTickPerMeasure = (timebase * 4 / (1 << p[1])) * p[0];
1236 else *outTickPerMeasure = timebase;
1237 return 1;
1238 } else {
1239 *outTickPerMetronomeBeat = timebase;
1240 *outTickPerMeasure = timebase * 4;
1241 return 0;
1242 }
1243 }
1244
1245 /* --------------------------------------
1246 ��� MDEventToString
1247 -------------------------------------- */
1248 char *
1249 MDEventToString(const MDEvent *eptr, char *buf, int32_t bufsize)
1250 {
1251 char *p;
1252 int32_t n = 0;
1253 p = buf;
1254 n = snprintf(buf, bufsize, "%d", (int32_t)MDGetTick(eptr));
1255 if (n > bufsize - 5)
1256 return buf;
1257 buf[n++] = '\t';
1258 n += MDEventToKindString(eptr, buf + n, bufsize - n);
1259 if (n > bufsize - 5)
1260 return buf;
1261 buf[n++] = '\t';
1262 n += MDEventToDataString(eptr, buf + n, bufsize - n);
1263 if (n > bufsize - 5)
1264 return buf;
1265 buf[n++] = '\t';
1266 n += MDEventToGTString(eptr, buf + n, bufsize - n);
1267 return buf;
1268 }
1269
1270 /* --------------------------------------
1271 ��� MDEventParseTickString
1272 -------------------------------------- */
1273 int
1274 MDEventParseTickString(const char *s, int32_t *bar, int32_t *beat, int32_t *tick)
1275 {
1276 int n;
1277 int d1, d2, d3;
1278 n = sscanf(s, "%d%*[^-0-9]%d%*[^-0-9]%d", &d1, &d2, &d3);
1279 switch (n) {
1280 case 1: d2 = 1; d3 = 0; break;
1281 case 2: d3 = 0; break;
1282 case 3: break;
1283 default: return 0;
1284 }
1285 if (bar != NULL)
1286 *bar = d1;
1287 if (beat != NULL)
1288 *beat = d2;
1289 if (tick != NULL)
1290 *tick = d3;
1291 return 3;
1292 }
1293
1294 int
1295 MDEventSMFMetaNumberToEventKind(int smfMetaNumber)
1296 {
1297 int kind;
1298 if (smfMetaNumber > 0 && smfMetaNumber < 16) {
1299 kind = kMDEventMetaText;
1300 } else {
1301 switch (smfMetaNumber) {
1302 case kMDMetaPortNumber:
1303 kind = kMDEventPortNumber; break;
1304 case kMDMetaTempo:
1305 kind = kMDEventTempo; break;
1306 case kMDMetaSMPTE:
1307 kind = kMDEventSMPTE; break;
1308 case kMDMetaTimeSignature:
1309 kind = kMDEventTimeSignature; break;
1310 case kMDMetaKey:
1311 kind = kMDEventKey; break;
1312 default:
1313 kind = kMDEventMetaMessage; break;
1314 }
1315 }
1316 return kind;
1317 }
1318
1319 int
1320 MDEventMetaKindCodeToSMFMetaNumber(int kind, int code)
1321 {
1322 switch (kind) {
1323 case kMDEventPortNumber: return kMDMetaPortNumber;
1324 case kMDEventTempo: return kMDMetaTempo;
1325 case kMDEventSMPTE: return kMDMetaSMPTE;
1326 case kMDEventTimeSignature: return kMDMetaTimeSignature;
1327 case kMDEventKey: return kMDMetaKey;
1328 case kMDEventMeta: return code;
1329 case kMDEventMetaMessage: return code;
1330 case kMDEventMetaText: return code;
1331 default: return -1;
1332 }
1333 }
1334
1335 int
1336 MDEventIsEventAllowableInConductorTrack(const MDEvent *eptr)
1337 {
1338 return MDIsMetaEvent(eptr);
1339 }
1340
1341 int
1342 MDEventIsEventAllowableInNonConductorTrack(const MDEvent *eptr)
1343 {
1344 return (eptr->kind != kMDEventTempo && eptr->kind != kMDEventTimeSignature);
1345 }

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