Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/MD_package/MDTrack.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 180 - (show annotations) (download) (as text)
Mon Feb 24 13:58:31 2020 UTC (4 years, 3 months ago) by toshinagata1964
File MIME type: text/x-chdr
File size: 20984 byte(s)
Copy & paste of overlapping notes was not working correctly. Hopefully fixed.
1 /*
2 * MDTrack.h
3 *
4 * Created by Toshi Nagata on Sun Jun 17 2001.
5
6 Copyright (c) 2000-2017 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 __MDTrack__
19 #define __MDTrack__
20
21 /* MIDI イベントの列を格納する構造体 */
22 typedef struct MDTrack MDTrack;
23
24 /* MDTrack 中のイベントの位置を指定する構造体。MDTrack と
25 連動して働き、イベントの挿入・削除が行われると自動的に指す位置が変化する。
26 MDPointer は opaque ではなく、ポインタだけでなくそれ自体を使うことができる。
27 (ただし、フィールドにアクセスすることはできない) */
28 typedef struct MDPointer MDPointer;
29
30 /* シーケンス中の全トラック中の全イベントをティック順に取り出すための仕掛け。 */
31 /* MDSequence.h の MDMerger と違って、MDSequence には依存しない。 */
32 typedef struct MDTrackMerger MDTrackMerger;
33
34 typedef unsigned char MDTrackAttribute;
35 enum {
36 kMDTrackAttributeRecord = 1,
37 kMDTrackAttributeSolo = 2,
38 kMDTrackAttributeMute = 4,
39 kMDTrackAttributeMuteBySolo = 8, /* Solo トラックが1つ以上ある時、それ以外のトラックはすべてこのフラグが立つ */
40 kMDTrackAttributeHidden = 16,
41 kMDTrackAttributeEditable = 32
42 };
43
44 #ifndef __MDEvent__
45 #include "MDEvent.h"
46 #endif
47
48 #ifndef __IntGroup_h__
49 #include "IntGroup.h"
50 #endif
51
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55
56 /* MDPointerForwardWithSelector(), MDPointerBackwardWithSelector() などで使う
57 コールバック関数 */
58 typedef int (*MDEventSelector)(const MDEvent *ep, int32_t position, void *inUserData);
59
60 /* -------------------------------------------------------------------
61 MDTrack functions
62 ------------------------------------------------------------------- */
63
64 /* 新しい MDTrackRecord をアロケートする。メモリ不足の場合は NULL を返す。
65 MDTrackNew() に対応する dispose や delete 関数は無い。代わりに MDTrackRelease()
66 を使用すること。 */
67 MDTrack * MDTrackNew(void);
68
69 /* 新しい MDTrack を作成し、そこに inTrack の全イベントをコピーする。 */
70 MDTrack * MDTrackNewFromTrack(const MDTrack *inTrack);
71
72 /* MDTrack の retain/release。 */
73 void MDTrackRetain(MDTrack *inTrack);
74 void MDTrackRelease(MDTrack *inTrack);
75
76 /* MDTrack に含まれているイベントをすべてクリアする。 */
77 void MDTrackClear(MDTrack *inTrack);
78
79 void MDTrackExchange(MDTrack *inTrack1, MDTrack *inTrack2);
80
81 /* 含まれているイベントの数を返す。 */
82 int32_t MDTrackGetNumberOfEvents(const MDTrack *inTrack);
83
84 /* 含まれているチャンネルイベントの数を返す。channel が 0-15 の範囲でなければ
85 すべてのチャンネルイベントの数の合計を返す。 */
86 int32_t MDTrackGetNumberOfChannelEvents(const MDTrack *inTrack, short channel);
87
88 /* 含まれているシステムエクスクルーシブイベントの数を返す。 */
89 int32_t MDTrackGetNumberOfSysexEvents(const MDTrack *inTrack);
90
91 /* 含まれている non-MIDI イベント(メタイベント)の数を返す。 */
92 int32_t MDTrackGetNumberOfNonMIDIEvents(const MDTrack *inTrack);
93
94 /* シーケンスの長さを返す。 */
95 MDTickType MDTrackGetDuration(const MDTrack *inTrack);
96
97 /* シーケンスの長さを変更する。既存のイベントの tick との整合性はチェックしないので注意。 */
98 void MDTrackSetDuration(MDTrack *inTrack, MDTickType inDuration);
99
100 /* シーケンスの末尾にイベントを追加する。イベントの順序はチェックしないので注意。
101 実際に追加できたイベントの数を返す。 */
102 int32_t MDTrackAppendEvents(MDTrack *inTrack, const MDEvent *inEvent, int32_t count);
103
104 /* 2つのトラックをマージする(inTrack1 の中に inTrack2 のイベントを挿入する)。
105 ioSet は NULL ならば無視される。ioSet != NULL で *ioSet == NULL なら、新しく IntGroup を
106 アロケートして、マージ後のトラックで inTrack2 由来のイベントが存在する位置の集合を入れて返す。
107 ioSet != NULL で *ioSet != NULL なら、*ioSet がマージ後のトラックで inTrack2 由来のイ
108 ベントが存在する位置の集合になるものと見なして挿入位置を決める(実際には、同ティックのイベントの
109 順序をどちらにするか、という場合にのみ参照される)。処理終了後には、*ioSet == NULL の
110 場合と同じく新しくアロケートされた IntGroup が返される。もとの *ioSet は release されない。 */
111 MDStatus MDTrackMerge(MDTrack *inTrack1, const MDTrack *inTrack2, IntGroup **ioSet);
112
113 /* MDTrackMerge の逆操作。inTrack の中から、位置が inSet に含まれるイベントをすべて抜き出して
114 新しいトラックに入れ、*outTrack に入れて返す。outTrack が NULL なら抜き出されたイベントは捨てられる。 */
115 MDStatus MDTrackUnmerge(MDTrack *inTrack, MDTrack **outTrack, const IntGroup *inSet);
116
117 MDStatus MDTrackExtract(MDTrack *inTrack, MDTrack **outTrack, const IntGroup *inSet);
118
119 /* inTrack を MIDI チャンネルで分けて最大16個のトラックにする。最も若い番号の MIDI チャンネルイベントと、チャンネルイベント以外のイベント(Sysex とメタイベント)は inTrack に残る。outTracks は MDTrack * を 16 個格納できる配列であること。対応するチャンネルイベントがない outTracks の要素は NULL になる。NULL でない最初の要素は inTrack に等しい。NULL でない outTracks の要素数を返す。 */
120 int MDTrackSplitByMIDIChannel(MDTrack *inTrack, MDTrack **outTracks);
121
122 /* noteOffEvent に対応する inTrack 中の internal note-on を探し、duration をセットして正常な Note イベントにする。Internal note-on は inTrack の先頭から末尾に向かって検索される。もし internal note-on の duration がゼロでなければ、noteOffevent とそのイベントの tick 差が duration に等しいかどうかもチェックされる。これは重なったノートを正しく対応づけるための処理。 */
123 /* lastPendingNoteOn が NULL でなければ、これは inTrack の中を指すポインタと見なされ、internal note-on はこのポインタ以降のみ検索される。*/
124 MDStatus MDTrackMatchNoteOff(MDTrack *inTrack, const MDEvent *noteOffEvent, MDPointer *lastPendingNoteOn);
125
126 /* inTrack のノートイベントで、internal note-on に対応する internal note-off イベントを noteOffTrack から探し出して、duration をセットする。対応がとれた internal note-off イベントは null イベントに変換される(二度読みを防ぐため)。SMF の読み込み、および MIDI レコーディングの時に使う。 */
127 MDStatus MDTrackMatchNoteOffInTrack(MDTrack *inTrack, MDTrack *noteOffTrack);
128
129 /* inTrack 中の全イベントの tick を newTick[] 中の値に先頭から順に変更する。newTick[] < 0 なら、そのイベントの tick は変更されない。tick が昇順になっていなければエラーになる。必要に応じて inTrack->duration は変更される。 */
130 MDStatus MDTrackChangeTick(MDTrack *inTrack, MDTickType *newTick);
131
132 /* inTrack 中の全イベントの tick に offset を加える。tick + offset が負の場合は 0 になる。必要に応じて inTrack->duration は変更される。 */
133 MDStatus MDTrackOffsetTick(MDTrack *inTrack, MDTickType offset);
134
135 /* トラック中で最も大きな tick を返す。duration を持っているイベントがある時は、そのイベントの終了 tick も考慮される。 */
136 MDTickType MDTrackGetLargestTick(MDTrack *inTrack);
137
138 /* duration を持っているイベントで、tick < inTick かつ tick+duration >= inTick であるものを
139 探し、その position を IntGroup として返す。メモリ不足の場合は NULL、該当するイベントが
140 1つもないときは空の IntGroup を返す。 */
141 IntGroup *MDTrackSearchEventsWithDurationCrossingTick(MDTrack *inTrack, MDTickType inTick);
142
143 /* inSelector が non-zero を返すイベントを探し、その position を IntGroup として返す。
144 メモリ不足の場合は NULL、該当するイベントが1つもないときは空の IntGroup を返す。 */
145 IntGroup *MDTrackSearchEventsWithSelector(MDTrack *inTrack, MDEventSelector inSelector, void *inUserData);
146
147 /* MIDIチャンネルを置き換える。チャンネルchのイベントはチャンネルnewch[ch]に変更される。変更先のチャンネルが重複していてもチェックされず、そのまま置換が行われる。newch[ch]が15より大きい時は16で割った余りが新しいチャンネルになる。この関数は必ず成功するので、エラーを発生しない。 */
148 void MDTrackRemapChannel(MDTrack *inTrack, const unsigned char *newch);
149
150 /* デバイス番号をセットする。 */
151 void MDTrackSetDevice(MDTrack *inTrack, int32_t dev);
152
153 /* デバイス番号を得る。 */
154 int32_t MDTrackGetDevice(const MDTrack *inTrack);
155
156 /* トラックのチャンネルをセットする。この値は親シーケンスがシングルチャンネルモードの場合のみ使われる。 */
157 void MDTrackSetTrackChannel(MDTrack *inTrack, short ch);
158
159 /* トラックのチャンネルを得る。 */
160 short MDTrackGetTrackChannel(const MDTrack *inTrack);
161
162 /* トラックの名前をセットする。文字列 (inName) は malloc でコピーされる。 */
163 MDStatus MDTrackSetName(MDTrack *inTrack, const char *inName);
164
165 /* トラックの名前を得る。 */
166 void MDTrackGetName(const MDTrack *inTrack, char *outName, int32_t length);
167
168 /* 出力デバイスの名前をセットする。文字列 (inName) は malloc でコピーされる。 */
169 MDStatus MDTrackSetDeviceName(MDTrack *inTrack, const char *inName);
170
171 /* 出力デバイスの名前を得る。 */
172 void MDTrackGetDeviceName(const MDTrack *inTrack, char *outName, int32_t length);
173
174 /* メタイベントからトラック名を推測する。 */
175 void MDTrackGuessName(MDTrack *inTrack, char *outName, int32_t length);
176
177 /* メタイベントからデバイス名を推測する。 */
178 void MDTrackGuessDeviceName(MDTrack *inTrack, char *outName, int32_t length);
179
180 /* トラック属性 (Rec/Solo/Mute) の取得、セット */
181 MDTrackAttribute MDTrackGetAttribute(const MDTrack *inTrack);
182 void MDTrackSetAttribute(MDTrack *inTrack, MDTrackAttribute inAttribute);
183
184 /* トラックの内容を標準出力にダンプする */
185 void MDTrackDump(const MDTrack *inTrack);
186
187 /* トラックの内容をチェックする(デバッグ用)。メッセージは stderr に出される */
188 /* MDStatus MDTrackCheck(const MDTrack *inTrack); */
189
190 /* Track の内部情報を正しく更新する。check が non-zero ならば、内部情報が矛盾していれば stderr にメッセージを出力する。 */
191 int MDTrackRecache(MDTrack *inTrack, int check);
192
193 int32_t MDTrackCountExtraInfo(const MDTrack *inTrack);
194 int32_t MDTrackGetExtraInfo(const MDTrack *inTrack, const char *key, const char **outValue);
195 int32_t MDTrackSetExtraInfo(MDTrack *inTrack, const char *key, const char *value);
196 const char *MDTrackGetExtraInfoAtIndex(const MDTrack *inTrack, int32_t index, const char **outKey);
197
198 /* -------------------------------------------------------------------
199 MDPointer functions
200 ------------------------------------------------------------------- */
201
202 /* 新しい MDPointer をアロケートする。メモリ不足の場合は NULL を返す。
203 inTrack と関係づけられ、場所は -1 (先頭イベントの前)にセットされる。 */
204 MDPointer * MDPointerNew(MDTrack *inTrack);
205
206 /* すでにアロケートされた MDPointer を初期化する。これはローカル変数などで
207 確保した MDPointerRecord を利用する時に使う。 */
208 /* MDPointer * MDPointerInit(MDPointer *inPointer, const MDTrack *inTrack); */
209
210 /* Retain/release */
211 void MDPointerRetain(MDPointer *inPointer);
212 void MDPointerRelease(MDPointer *inPointer);
213
214 /* MDPointer をコピーする。parent が違う時は意味がないが、一応 SetPosition を行う。 */
215 void MDPointerCopy(MDPointer *inDest, const MDPointer *inSrc);
216
217 /* MDTrack との関係付けを変更する。 */
218 void MDPointerSetTrack(MDPointer *inPointer, MDTrack *inTrack);
219
220 /* 関係付けられた MDTrack を返す。 */
221 MDTrack * MDPointerGetTrack(const MDPointer *inPointer);
222
223 /* 現在位置の変更。存在しない位置に移動しようとした時は先頭以前か末尾以降に
224 移動し、0 (false) を返す。 */
225 int MDPointerSetPosition(MDPointer *inPointer, int32_t inPos);
226 int MDPointerSetRelativePosition(MDPointer *inPointer, int32_t inOffset);
227
228 /* 現在位置を読み出す */
229 int32_t MDPointerGetPosition(const MDPointer *inPointer);
230
231 /* 挿入・削除後に位置を自動調整する場合に 1 をセットする。デフォルトは 0 */
232 void MDPointerSetAutoAdjust(MDPointer *inPointer, char flag);
233
234 /* 自動調整フラグが立っていれば 1, 立っていなければ 0 を返す */
235 int MDPointerIsAutoAdjust(const MDPointer *inPointer);
236
237 /* 以前に指していたイベントが削除された結果現在位置を指している場合に 1 (true) を返す */
238 int MDPointerIsRemoved(const MDPointer *inPointer);
239
240 /* inTick より小さくない tick 値を持つ最初のイベントの位置に移動する。そのような
241 イベントが存在しなければ末尾以降に移動し、0 (false) を返す。 */
242 int MDPointerJumpToTick(MDPointer *inPointer, MDTickType inTick);
243
244 /* 最後のイベントの位置に移動する。1つもイベントがなければ 0 (false) を返す。 */
245 int MDPointerJumpToLast(MDPointer *inPointer);
246
247 /* イベントのポインタが inEvent に一致する位置に移動する。そのようなイベントが存在
248 しなければ指している位置は変化せず、 0 (false) を返す。 */
249 int MDPointerLookForEvent(MDPointer *inPointer, const MDEvent *inEvent);
250
251 /* 現在のイベントへのポインタを得る。存在しないイベントを指している場合は NULL を返す。 */
252 MDEvent * MDPointerCurrent(const MDPointer *inPointer);
253
254 /* 1つ先の位置に進み、そのイベントへのポインタを得る。最後のイベントを越えた場合は
255 NULL を返す。 */
256 MDEvent * MDPointerForward(MDPointer *inPointer);
257
258 /* 1つ前の位置に戻り、そのイベントへのポインタを得る。先頭のイベントを越えた場合は
259 NULL を返す。 */
260 MDEvent * MDPointerBackward(MDPointer *inPointer);
261
262 /* 現在位置より先で inSelector が non-zero を返す最初のイベントの位置に移動する */
263 MDEvent * MDPointerForwardWithSelector(MDPointer *inPointer, MDEventSelector inSelector, void *inUserData);
264
265 /* 現在位置より前で inSelector が non-zero を返す最初のイベントの位置に移動する */
266 MDEvent * MDPointerBackwardWithSelector(MDPointer *inPointer, MDEventSelector inSelector, void *inUserData);
267
268 /* inPointSet 中の offset 番目の点の位置に移動する */
269 int MDPointerSetPositionWithPointSet(MDPointer *inPointer, IntGroup *inPointSet, int32_t offset, int *outIndex);
270
271 /* 現在位置より1つ進み、その点が pointSet の *index 番目の区間の終端より先であれば、次の区間の始点に対応する位置に移動して (*index) を +1 する。index == NULL であるか、または *index < 0 であるなら、pointSet に含まれるところまで現在位置を進め、index != NULL ならば *index にその区間の番号を返す。もし対応する点がなければ、inPointer はトラック末尾+1 の位置になり、*index には -1 が返される。 */
272 MDEvent * MDPointerForwardWithPointSet(MDPointer *inPointer, IntGroup *inPointSet, int *index);
273
274 /* 現在位置から1つ戻り、その点が pointSet の *index 番目の区間の始点より前であれば、前の区間の終点-1に対応する位置に移動して (*index) を -1 する。index == NULL であるか、または *index < 0 であるなら、pointSet に含まれるところまで現在位置を戻し、index != NULL ならば *index にその区間の番号を返す。もし対応する点がなければ、inPointer はトラック先頭-1 の位置になり、*index には -1 が返される。 */
275 MDEvent * MDPointerBackwardWithPointSet(MDPointer *inPointer, IntGroup *inPointSet, int *index);
276
277 /* 現在位置にイベントを1つ挿入する。tick が現在位置と合わない場合には、合う位置を探す。 */
278 MDStatus MDPointerInsertAnEvent(MDPointer *inPointer, const MDEvent *inEvent);
279
280 /* 現在位置のイベントを削除する。outEvent が NULL でなければ、古いイベントが *outEvent に返される。*/
281 MDStatus MDPointerDeleteAnEvent(MDPointer *inPointer, MDEvent *outEvent);
282
283 /* 現在位置のイベントを置き換える。outEvent が NULL でなければ、古いイベントが *outEvent に返される。 */
284 MDStatus MDPointerReplaceAnEvent(MDPointer *inPointer, const MDEvent *inEvent, MDEvent *outEvent);
285
286 /* 現在位置のイベントの tick を変更する。inPosition に変更後の位置を指定することができる。inPosition に動かすと
287 tick 順に矛盾を生じる場合は、inTick の値に合わせて適当な位置を探す。inPointer は移動後のイベントの位置に移る。 */
288 MDStatus MDPointerChangeTick(MDPointer *inPointer, MDTickType inTick, int32_t inPosition);
289
290 /* Change the duration value, with clearing the largestTick cache in the MDBlock */
291 MDStatus MDPointerSetDuration(MDPointer *inPointer, MDTickType inDuration);
292
293 /* Sanity check */
294 MDStatus MDPointerCheck(const MDPointer *inPointer);
295
296 /* 新しい MDTrackMerger をアロケートする。メモリ不足の場合は NULL を返す。 */
297 MDTrackMerger * MDTrackMergerNew(void);
298
299 /* Retain/release */
300 void MDTrackMergerRetain(MDTrackMerger *inMerger);
301 void MDTrackMergerRelease(MDTrackMerger *inMerger);
302
303 /* MDTrack を登録する。成功すれば現在のトラック数、失敗すれば -1 を返す。 */
304 int MDTrackMergerAddTrack(MDTrackMerger *inMerger, MDTrack *inTrack);
305
306 /* MDTrack の登録をやめる。現在のトラック数を返す。inTrack が登録されていなければ -1 を返す。 */
307 int MDTrackMergerRemoveTrack(MDTrackMerger *inMerger, MDTrack *inTrack);
308
309 /* num 番目のトラックを返す。存在しなければ NULL を返す。 */
310 MDTrack * MDTrackMergerGetTrack(MDTrackMerger *inMerger, int num);
311
312 /* inTick より小さくない tick 値を持つ最初のイベントの位置に移動し、そのイベントへの
313 ポインタを返す。そのようなイベントが存在しなければ末尾以降に移動し、NULL を返す。 */
314 /* outTrack が NULL でなければ、現在のイベントが属するトラックを返す。 */
315 MDEvent * MDTrackMergerJumpToTick(MDTrackMerger *inMerger, MDTickType inTick, MDTrack **outTrack);
316
317 /* 現在のイベントへのポインタを得る。存在しないイベントを指している場合は NULL を返す。 */
318 /* outTrack が NULL でなければ、現在のイベントが属するトラックを返す。 */
319 /* (呼ばれるたびにすべてのトラックの tick を比較するので注意) */
320 MDEvent * MDTrackMergerCurrent(MDTrackMerger *inMerger, MDTrack **outTrack);
321
322 /* 1つ先の位置に進み、そのイベントへのポインタを得る。最後のイベントを越えた場合は
323 NULL を返す。 */
324 /* outTrack が NULL でなければ、現在のイベントが属するトラックを返す。 */
325 MDEvent * MDTrackMergerForward(MDTrackMerger *inMerger, MDTrack **outTrack);
326
327 /* 1つ前の位置に戻り、そのイベントへのポインタを得る。先頭のイベントを越えた場合は
328 NULL を返す。 */
329 /* outTrack が NULL でなければ、現在のイベントが属するトラックを返す。 */
330 MDEvent * MDTrackMergerBackward(MDTrackMerger *inMerger, MDTrack **outTrack);
331
332 #ifdef __cplusplus
333 }
334 #endif
335
336 #endif /* __MDTrack__ */

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