Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/MD_package/MDEvent.h

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-chdr
File size: 19809 byte(s)
Xcode project is updated so that ppc/i386 universal binary can be built (as before)
1 /*
2 * MDEvent.h
3 *
4 * Created by Toshi Nagata on Sun Jun 17 2001.
5
6 Copyright (c) 2000-2016 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 #ifndef __MDEvent__
19 #define __MDEvent__
20
21 #ifndef __MDCommon__
22 #include "MDCommon.h"
23 #endif
24
25 /* MD イベントの種類を表す定数 */
26 typedef unsigned char MDEventKind;
27 enum {
28 kMDEventNull = 0,
29 kMDEventMeta, /* code = meta code, data1/data2 = data */
30 kMDEventTempo, /* tempo = tempo (number of quarters per minutes) */
31 kMDEventTimeSignature, /* metadata[0] = numerator,
32 metadata[1] = denominator (negative power of 2 as in SMF),
33 metadata[2] = length of one metronome-click
34 (multiples of 1/24 of quarter note)
35 metadata[3] = the number of 32-nd notes per
36 24 MIDI clocks (usually 8) */
37 kMDEventKey, /* metadata[0] = key (-7 to 7), metadata[1] = major or minor */
38 kMDEventSMPTE, /* SMPTE record (hour, min, sec, frame, subframe) */
39 kMDEventPortNumber, /* data1 = port number */
40 kMDEventMetaText, /* code = meta code, message = message (text) */
41 kMDEventMetaMessage, /* code = meta code, message = message */
42 kMDEventProgram, /* data1 = program, data2 = bank select */
43 kMDEventNote, /* code = key code,
44 data1 = (on-velocity << 8) + off-velocity,
45 duration/m_duration = duration */
46 kMDEventInternalNoteOff, /* used only for temporary use; code = key code, vel[1] = off-velocity, ldata = track number */
47 kMDEventInternalNoteOn, /* used only for temporary use; code = key code, vel[0] = on-velocity, duration (optional) = expected duration */
48 kMDEventInternalDuration, /* used only for temporary use; duration = expected duration of the immediately following note-on */
49 kMDEventControl, /* code = control code, data1 = control data */
50 kMDEventPitchBend, /* data1 = pitch bend value */
51 kMDEventChanPres, /* data1 = channel pressure value */
52 kMDEventKeyPres, /* code = key code, data1 = key pressure value */
53 kMDEventSysex, /* message = sysex message (beginning from 'F0') */
54 kMDEventSysexCont, /* message = sysex message (not beginning from 'F0') */
55 kMDEventData, /* code = data identifier, dataptr = a pointer to
56 a memory block allocated by malloc() */
57 kMDEventObject, /* code = data identifier, objptr = a pointer to
58 a object that can be released by MDReleaseObject(objptr) call */
59 kMDEventSpecial, /* code = special code */
60 kMDEventStop
61 };
62
63 /* SMF イベントの種類 */
64 enum {
65 kMDEventSMFNoteOff = 0x80,
66 kMDEventSMFNoteOn = 0x90,
67 kMDEventSMFKeyPressure = 0xa0,
68 kMDEventSMFControl = 0xb0,
69 kMDEventSMFProgram = 0xc0,
70 kMDEventSMFChannelPressure = 0xd0,
71 kMDEventSMFPitchBend = 0xe0,
72 kMDEventSMFSysex = 0xf0,
73 kMDEventSMFSysexF7 = 0xf7,
74 kMDEventSMFMeta = 0xff
75 };
76
77 /* メタイベントの種類をあらわす定数 */
78 typedef unsigned char MDMetaKind;
79 enum {
80 kMDMetaSequenceNumber = 0,
81 kMDMetaText = 1,
82 kMDMetaCopyright = 2,
83 kMDMetaSequenceName = 3,
84 kMDMetaInstrumentName = 4,
85 kMDMetaLyric = 5,
86 kMDMetaMarker = 6,
87 kMDMetaCuePoint = 7,
88 kMDMetaProgramName = 8, /* New in RP-016 */
89 kMDMetaDeviceName = 9, /* New in RP-016 */
90 kMDMetaChannelPrefix = 0x20,
91 kMDMetaPortNumber = 0x21,
92 kMDMetaEndOfTrack = 0x2f,
93 kMDMetaTempo = 0x51,
94 kMDMetaSMPTE = 0x54,
95 kMDMetaTimeSignature = 0x58,
96 kMDMetaKey = 0x59,
97 kMDMetaSequencerSpecific = 0x7f,
98
99 /* Internally used to keep track of durations of overlapping notes */
100 /* It contains a BER-compressed integer and represents the duration of the preceding
101 note-on event. */
102 kMDMetaDuration = 0x7e
103 };
104
105 /* Type of special events */
106 enum {
107 kMDSpecialEndOfSequence = 0,
108 kMDSpecialStopPlaying
109 };
110
111 /* tick および絶対時間を扱う型。絶対時間の単位はマイクロ秒。 */
112 typedef int32_t MDTickType;
113 typedef int64_t MDTimeType;
114
115 #define kMDMaxTick ((MDTickType)0x7ffffff0)
116 #define kMDNegativeTick ((MDTickType)-1)
117 #define kMDMaxTime ((MDTimeType)10000000000000.0)
118 #define kMDNegativeTime ((MDTimeType)-1)
119
120 #define kMDMaxTempo 100000.0f /* Somewhat arbitrary (anything less than 60000000) */
121 #define kMDMinTempo 3.60f /* Quite strict */
122
123 #define kMDMaxData 80000000.0f
124 #define kMDMinData -80000000.0f
125
126 #define kMDMaxPosition 0x7ffffff0
127 #define kMDNegativePosition -1
128
129 /* メッセージデータ(Sysex やテキスト系メタイベント)を格納する構造体
130 本体は MDEvent.c で定義される */
131 typedef struct MDMessage MDMessage;
132
133 /* SMPTE データを格納するためのビットフィールド構造体 */
134 typedef struct MDSMPTERecord {
135 unsigned int reserved: 1;
136 unsigned int hour: 6; /* including SMPTE type (upper 2 bits) */
137 unsigned int min: 6;
138 unsigned int sec: 6;
139 unsigned int frame: 5;
140 unsigned int subframe: 8;
141 } MDSMPTERecord;
142
143 /* MIDI イベントそのものを格納する構造体。opaque ではなく、MDEvent 自体も使ってよい。
144 ただし、フィールドに直接アクセスすることは好ましくなく、アクセスマクロを使うこと。 */
145 typedef struct MDEvent MDEvent;
146 struct MDEvent {
147 MDEventKind kind; /* The kind of this event record */
148 unsigned char code; /* key code or meta-event code */
149 short channel; /* channel number; 0-15: MIDI channel 0-15, 16: sysex, 17: non-MIDI */
150 MDTickType tick; /* tick */
151 union {
152 unsigned char vel[2]; /* note events: note-on and note-off velocity */
153 short data1; /* other events: a 16-bit value */
154 } data1;
155 union {
156 MDTickType duration; /* for note events */
157 struct {
158 short data2; /* for other MIDI events */
159 short data3;
160 } d;
161 int32_t ldata; /* for internal note-off event */
162 unsigned char metadata[4]; /* meta events */
163 MDSMPTERecord smpte; /* SMPTE */
164 float tempo;
165 MDMessage * message;
166 void * dataptr;
167 } u;
168 };
169
170 /* MDEventGetDisplay などで使われるデータ構造。 */
171 typedef union MDEventDisplayValue {
172 const char * ccp;
173 char * cp;
174 int32_t l;
175 float f;
176 } MDEventDisplayValue;
177
178 /* あるティック位置でのテンポ・拍子・調号などを覚えておくためのキャッシュ。
179 キャッシュは MDSequence と連動しており、MDSequence およびそれに属するトラッ
180 クに何か変更を加えた時には更新する必要がある。これは自動的には行われないので、
181 変更を加えるたびに適当なタイミングで MDSequenceUpdateCache() を呼び出すこと。
182 MDCache 関連の関数定義は MDSequence.h に、関数本体は MDSequence.c にある。 */
183 /*typedef struct MDCache MDCache; */
184
185 /* -------------------------------------------------------------------
186 MDEvent macros
187 ------------------------------------------------------------------- */
188
189 /*#define MDTempoToMetronomeTempo(tp) (60000000.0 / (tp)) */
190 /*#define MDMetronomeTempoToTempo(mtp) (60000000.0 / (mtp)) */
191 #define MDGetKind(eventPtr) ((eventPtr)->kind)
192 #define MDSetKind(eventPtr, theKind) ((eventPtr)->kind = (theKind))
193 #define MDGetCode(eventPtr) ((eventPtr)->code)
194 #define MDSetCode(eventPtr, theCode) ((eventPtr)->code = (theCode))
195 #define MDGetChannel(eventPtr) ((eventPtr)->channel)
196 #define MDSetChannel(eventPtr, theChan) ((eventPtr)->channel = (theChan))
197 #define MDGetTick(eventPtr) ((eventPtr)->tick)
198 #define MDSetTick(eventPtr, theTick) ((eventPtr)->tick = (theTick))
199 #define MDGetData1(eventPtr) ((eventPtr)->data1.data1)
200 #define MDSetData1(eventPtr, theData) ((eventPtr)->data1.data1 = (theData))
201 #define MDGetNoteOnVelocity(eventPtr) ((eventPtr)->data1.vel[0])
202 #define MDSetNoteOnVelocity(eventPtr, theVel) ((eventPtr)->data1.vel[0] = (theVel))
203 #define MDGetNoteOffVelocity(eventPtr) ((eventPtr)->data1.vel[1])
204 #define MDSetNoteOffVelocity(eventPtr, theVel) ((eventPtr)->data1.vel[1] = (theVel))
205 #define MDGetData2(eventPtr) ((eventPtr)->u.d.data2)
206 #define MDSetData2(eventPtr, theData) ((eventPtr)->u.d.data2 = (theData))
207 #define MDGetLData(eventPtr) ((eventPtr)->u.ldata)
208 #define MDSetLData(eventPtr, theData) ((eventPtr)->u.ldata = (theData))
209 #define MDGetDuration(eventPtr) ((eventPtr)->u.duration)
210 #define MDSetDuration(eventPtr, theDuration) ((eventPtr)->u.duration = (theDuration))
211 #define MDGetTempo(eventPtr) ((eventPtr)->u.tempo)
212 #define MDSetTempo(eventPtr, theTempo) ((eventPtr)->u.tempo = (theTempo))
213 /*#define MDGetMetronomeTempo(eventPtr) (MDTempoToMetronomeTempo((eventPtr)->u.tempo)) */
214 #define MDGetData3(eventPtr) ((eventPtr)->u.d.data3)
215 #define MDSetData3(eventPtr, theData) ((eventPtr)->u.d.data3 = (theData))
216 #define MDGetMetaDataPtr(eventPtr) ((eventPtr)->u.metadata)
217 #define MDGetSMPTERecordPtr(eventPtr) (&((eventPtr)->u.smpte))
218
219 /* 各種判定用マクロ */
220 #define MDIsChannelEvent(eventRef) \
221 (MDGetKind(eventRef) >= kMDEventProgram && MDGetKind(eventRef) <= kMDEventKeyPres)
222 #define MDIsSysexEvent(eventRef) \
223 (MDGetKind(eventRef) == kMDEventSysex || MDGetKind(eventRef) == kMDEventSysexCont)
224 #define MDIsMetaEvent(eventRef) \
225 (MDGetKind(eventRef) >= kMDEventMeta && MDGetKind(eventRef) <= kMDEventMetaMessage)
226 #define MDIsTextMetaEvent(eventRef) \
227 (MDGetKind(eventRef) == kMDEventMetaText)
228 #define MDHasEventMessage(eventRef) \
229 (MDIsSysexEvent(eventRef) || MDGetKind(eventRef) == kMDEventMetaMessage || MDGetKind(eventRef) == kMDEventMetaText)
230 #define MDHasEventData(eventRef) \
231 (MDGetKind(eventRef) == kMDEventData)
232 #define MDHasEventObject(eventRef) \
233 (MDGetKind(eventRef) == kMDEventObject)
234 #define MDIsNoteEvent(eventRef) \
235 (MDGetKind(eventRef) == kMDEventNote)
236 #define MDHasDuration(eventRef) \
237 (MDGetKind(eventRef) == kMDEventNote)
238 #define MDHasCode(eventRef) \
239 (MDIsNoteEvent(eventRef) || MDGetKind(eventRef) == kMDEventInternalNoteOff \
240 || MDGetKind(eventRef) == kMDEventControl || MDGetKind(eventRef) == kMDEventKeyPres \
241 || MDGetKind(eventRef) == kMDEventMeta || MDGetKind(eventRef) == kMDEventMetaText \
242 || MDGetKind(eventRef) == kMDEventMetaMessage)
243 #define MDIsTickEqual(eref1, eref2) (MDGetTick(eref1) == MDGetTick(eref2))
244 #define MDIsTickGreater(eref1, eref2) (MDGetTick(eref1) > MDGetTick(eref2))
245 #define MDIsTickLess(eref1, eref2) (MDGetTick(eref1) < MDGetTick(eref2))
246 #define MDIsTickGreaterOrEqual(eref1, eref2) (MDGetTick(eref1) >= MDGetTick(eref2))
247 #define MDIsTickLessOrEqual(eref1, eref2) (MDGetTick(eref1) <= MDGetTick(eref2))
248
249 #ifdef __cplusplus
250 extern "C" {
251 #endif
252
253 /* -------------------------------------------------------------------
254 MDEvent functions
255 ------------------------------------------------------------------- */
256
257 /* イベントを0で初期化する。 */
258 void MDEventInit(MDEvent *eventRef);
259
260 /* イベントをクリアする。メッセージ・データ・オブジェクトを含んでいる場合はそれらを
261 解放する。 */
262 void MDEventClear(MDEvent *eventRef);
263
264 /* 指定された種類のデフォルトイベントを作る。 */
265 void MDEventDefault(MDEvent *eventRef, int kind);
266
267 /* イベントをコピーする。メッセージデータはポインタだけがコピーされ Retain される。 */
268 void MDEventCopy(MDEvent *destRef, const MDEvent *sourceRef, int32_t count);
269
270 /* イベントを移動させる。sourceRef は0で初期化される。 */
271 void MDEventMove(MDEvent *destRef, MDEvent *sourceRef, int32_t count);
272
273 /* メッセージの長さを得る。メッセージイベントでない場合は -1 を返す。 */
274 int32_t MDGetMessageLength(const MDEvent *eventRef);
275
276 /* srcRef から destRef にメッセージデータだけをコピーする。 */
277 void MDCopyMessage(MDEvent *destRef, MDEvent *srcRef);
278
279 /* 渡されたバッファアドレスにメッセージデータをコピーする。outBuffer はメッセージを
280 格納するのに十分な大きさがなければならない。
281 メッセージの長さを返す。メッセージイベントでない場合は -1 を返す。 */
282 int32_t MDGetMessage(const MDEvent *eventRef, unsigned char *outBuffer);
283
284 /* メッセージデータの inOffset 目のバイト(先頭が0)から inLength バイトを outBuffer
285 にコピーする。outBuffer は最大 inLength バイトのデータを格納できる大きさがなければ
286 ならない。実際にコピーしたバイト数を返す。メッセージイベントでない場合は -1 を返す。 */
287 int32_t MDGetMessagePartial(const MDEvent *eventRef, unsigned char *outBuffer, int32_t inOffset, int32_t inLength);
288
289 /* メッセージデータの長さとデータへのポインタを返す。この関数で得たポインタには
290 書き込みをしてはならない。 */
291 const unsigned char *
292 MDGetMessageConstPtr(const MDEvent *eventRef, int32_t *outLength);
293
294 /* 注意:MDGetMessagePtr, MDSetMessageLength, MDSetMessage, MDSetMessagePartial を
295 呼び出した時、一見必要がないように見えても内部的にメモリ確保が行われることがある。
296 これらの関数はメッセージの内容を書き換えるため、refCount を使ってコピーを保持している
297 メッセージの場合は新しいコピーがその時点で作成されるからである。 */
298
299 /* メッセージデータの長さとデータへのポインタを返す。データに書き込んでも構わないが、
300 決められた長さの外側に書き込まないよう注意すること。 */
301 unsigned char * MDGetMessagePtr(MDEvent *eventRef, int32_t *outLength);
302
303 /* メッセージの長さを変更する。メッセージイベントでない場合は何もしない。inLength と
304 同じ値が返されるが、メモリ不足の場合は負の値が返される。 */
305 int32_t MDSetMessageLength(MDEvent *eventRef, int32_t inLength);
306
307 /* 渡されたバッファのデータをメッセージデータにコピーする。
308 メッセージの長さはあらかじめセットされている値が使われる。
309 メッセージの長さが返される。メモリ不足が起こった場合は負の値が返される。
310 メッセージイベントでない場合は何もしない。 */
311 int32_t MDSetMessage(MDEvent *eventRef, const unsigned char *inBuffer);
312
313 /* メッセージデータの inOffset 目のバイト(先頭が0)から inLength バイトを inBuffer
314 のデータで置き換える。inOffset + inLength がメッセージの長さより長い場合は、メッ
315 セージの長さちょうどで打ち切られる。
316 メッセージの長さが返される。メモリ不足が起こった場合は負の値が返される。
317 メッセージイベントでない場合は何もしない。 */
318 int32_t MDSetMessagePartial(MDEvent *eventRef, const unsigned char *inBuffer, int32_t inOffset, int32_t inLength);
319
320 /* イベントデータと表示データの相互変換。 */
321
322 /* ノートナンバーをノート名に変換する。 */
323 void MDEventNoteNumberToNoteName(unsigned char inNumber, char *outName);
324
325 /* ノート名をノートナンバーに変換する。 */
326 int MDEventNoteNameToNoteNumber(const char *p);
327
328 /* 五線(加線)の番号をノートナンバーに変換する。五線番号は、中央のCが0で、上が正、下が負の整数。 */
329 int MDEventStaffIndexToNoteNumber(int staff);
330
331 /* イベントを表示用文字列に変換する。length は buf[] に格納できる最大の文字数(最後のヌル文字を含む) */
332 int32_t MDEventToKindString(const MDEvent *eref, char *buf, int32_t length);
333 int32_t MDEventToDataString(const MDEvent *eref, char *buf, int32_t length);
334 int32_t MDEventToGTString(const MDEvent *eref, char *buf, int32_t length);
335
336 /* 表示用文字列からイベントデータを得る。code はイベントのどの部分に対応するかをあらわす定数。 */
337 typedef short MDEventFieldCode;
338 enum {
339 kMDEventFieldNone = 0,
340 kMDEventFieldKindAndCode, /* Code は無意味な場合もある */
341 kMDEventFieldTick,
342 kMDEventFieldCode,
343 kMDEventFieldData, /* data1 */
344 kMDEventFieldVelocities, /* ucValue[0] が on-velocity, ucValue[1] が off-velocity */
345 kMDEventFieldSMPTE,
346 kMDEventFieldMetaData,
347 kMDEventFieldTempo,
348 kMDEventFieldBinaryData, /* Meta event/sysex data (including text) */
349 kMDEventFieldPointer,
350 kMDEventFieldInvalid
351 };
352
353 /* MDEventFieldData と少なくとも同じサイズの整数型 */
354 typedef intptr_t MDEventFieldDataWhole;
355 typedef union MDEventFieldData {
356 MDEventFieldDataWhole whole;
357 int32_t intValue; /* code, data1 */
358 float floatValue; /* tempo */
359 MDSMPTERecord smpte; /* SMPTE */
360 MDTickType tickValue; /* tick */
361 unsigned char ucValue[4]; /* metaData, KindAndCode ([0] が kind, [1] が code) */
362 unsigned char * binaryData; /* malloc() されたメモリへのポインタ。先頭の sizeof(int32_t) バイトはデータの長さで、そのあとにデータ本体が続く。 */
363 void * anyPointer; /* 任意のポインタ */
364 } MDEventFieldData;
365
366 MDEventFieldCode MDEventKindStringToEvent(const char *buf, MDEventFieldData *epout);
367 MDEventFieldCode MDEventGTStringToEvent(const MDEvent *epin, const char *buf, MDEventFieldData *epout);
368 MDEventFieldCode MDEventDataStringToEvent(const MDEvent *epin, const char *buf, MDEventFieldData *epout);
369
370 /* イベントを MIDI メッセージに変換する(チャンネルイベントのみ)。buf は4バイト必要。 */
371 int MDEventToMIDIMessage(const MDEvent *eventRef, unsigned char *buf);
372
373 /* MIDI メッセージをイベントに変換する(チャンネルイベントのみ)。firstByte は最初のデータバイト(ランニングステータス可)、lastStatusByte はランニングステータスの時に仮定されるステータスバイト、getCharFunc は1バイト読み込むための関数へのポインタ、funcArgument は getCharFunc に渡す引数、outStatusByte はこのイベントのステータスバイトを受け取るためのポインタ。 */
374 MDStatus MDEventFromMIDIMessage(MDEvent *eventRef, unsigned char firstByte, unsigned char lastStatusByte, int (*getCharFunc)(void *), void *funcArgument, unsigned char *outStatusByte);
375
376 /* 拍子記号イベントから、1小節の拍数、1拍の tick 数を求める */
377 int MDEventParseTimeSignature(const MDEvent *eptr, int32_t timebase, int32_t *outTickPerBeat, int32_t *outBeatPerMeasure);
378
379 char * MDEventToString(const MDEvent *eptr, char *buf, int32_t bufsize);
380
381 /* Parse "bar:beat:tick" string to three int32_t integers */
382 int MDEventParseTickString(const char *s, int32_t *bar, int32_t *beat, int32_t *tick);
383
384 int MDEventSMFMetaNumberToEventKind(int smfMetaNumber);
385 int MDEventMetaKindCodeToSMFMetaNumber(int kind, int code);
386
387 /* Check if the event is allowable in the conductor/non-conductor tracks */
388 int MDEventIsEventAllowableInConductorTrack(const MDEvent *eptr);
389 int MDEventIsEventAllowableInNonConductorTrack(const MDEvent *eptr);
390
391 /* Get metronome bar and beat length from timebase and kMDEventTimeSignature event */
392 int MDEventCalculateMetronomeBarAndBeat(const MDEvent *eptr, int32_t timebase, int32_t *outTickPerMeasure, int32_t *outTickPerMetronomeBeat);
393
394 #ifdef __cplusplus
395 }
396 #endif
397
398 #endif /* __MDEvent__ */

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