00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if 1
00023
00024 #ifndef __XMIDI_h_
00025 #define __XMIDI_h_
00026
00027 #include <string>
00028 #include "common_types.h"
00029 #include "databuf.h"
00030
00031
00032
00033 #define XMIDI_CONVERT_NOCONVERSION 0
00034 #define XMIDI_CONVERT_MT32_TO_GM 1
00035 #define XMIDI_CONVERT_MT32_TO_GS 2
00036 #define XMIDI_CONVERT_MT32_TO_GS127 3
00037 #define XMIDI_CONVERT_GS127_TO_GS 4
00038
00039
00040 #define MIDI_STATUS_NOTE_OFF 0x8
00041 #define MIDI_STATUS_NOTE_ON 0x9
00042 #define MIDI_STATUS_AFTERTOUCH 0xA
00043 #define MIDI_STATUS_CONTROLLER 0xB
00044 #define MIDI_STATUS_PROG_CHANGE 0xC
00045 #define MIDI_STATUS_PRESSURE 0xD
00046 #define MIDI_STATUS_PITCH_WHEEL 0xE
00047 #define MIDI_STATUS_SYSEX 0xF
00048
00049
00050 #define XMIDI_CONTROLLER_CHAN_LOCK 0x6e // Channel Lock
00051 #define XMIDI_CONTROLLER_CHAN_LOCK_PROT 0x6f // Channel Lock Protect
00052 #define XMIDI_CONTROLLER_VOICE_PROT 0x70 // Voice Protect
00053 #define XMIDI_CONTROLLER_TIMBRE_PROT 0x71 // Timbre Protect
00054 #define XMIDI_CONTROLLER_BANK_CHANGE 0x72 // Bank Change
00055 #define XMIDI_CONTROLLER_IND_CTRL_PREFIX 0x73 // Indirect Controller Prefix
00056 #define XMIDI_CONTROLLER_FOR_LOOP 0x74 // For Loop
00057 #define XMIDI_CONTROLLER_NEXT_BREAK 0x75 // Next/Break
00058 #define XMIDI_CONTROLLER_CLEAR_BB_COUNT 0x76 // Clear Beat/Bar Count
00059 #define XMIDI_CONTROLLER_CALLBACK_TRIG 0x77 // Callback Trigger
00060 #define XMIDI_CONTROLLER_SEQ_BRANCH_INDEX 0x78 // Sequence Branch Index
00061
00062
00063
00064 #define XMIDI_MAX_FOR_LOOP_COUNT 4
00065
00066 template <class T> class GammaTable;
00067
00068 struct midi_event
00069 {
00070 int time;
00071 unsigned char status;
00072
00073 unsigned char data[2];
00074
00075 uint32 len;
00076 unsigned char *buffer;
00077 int duration;
00078 midi_event *next_note;
00079 uint32 note_time;
00080 midi_event *next;
00081 };
00082
00083 class NoteStack {
00084 midi_event *notes;
00085 int polyphony;
00086 int max_polyphony;
00087 public:
00088
00089 NoteStack() : notes(0), polyphony(0), max_polyphony(0) { }
00090
00091
00092 void clear() {
00093 notes=0;
00094 polyphony=0;
00095 max_polyphony=0;
00096 }
00097
00098
00099 inline midi_event *PopTime(uint32 time) {
00100 if (notes && notes->note_time <= time) {
00101 midi_event *note = notes;
00102 notes = note->next_note;
00103 note->next_note = 0;
00104 polyphony--;
00105 return note;
00106 }
00107
00108 return 0;
00109 }
00110
00111
00112 inline midi_event *Pop() {
00113 if (notes) {
00114 midi_event *note = notes;
00115 notes = note->next_note;
00116 note->next_note = 0;
00117 polyphony--;
00118 return note;
00119 }
00120
00121 return 0;
00122 }
00123
00124
00125 inline midi_event *Remove(midi_event *event) {
00126 midi_event *prev = 0;
00127 midi_event *note = notes;
00128 while (note) {
00129
00130 if (note == event) {
00131 if (prev) prev->next_note = note->next_note;
00132 else notes = note->next_note;
00133 note->next_note = 0;
00134 polyphony--;
00135 return note;
00136 }
00137 prev = note;
00138 note = note->next_note;
00139 }
00140 return 0;
00141 }
00142
00143
00144 inline midi_event *FindAndPop(midi_event *event) {
00145
00146 midi_event *prev = 0;
00147 midi_event *note = notes;
00148 while (note) {
00149
00150 if ((note->status & 0xF) == (event->status & 0xF) && note->data[0] == event->data[0]) {
00151 if (prev) prev->next_note = note->next_note;
00152 else notes = note->next_note;
00153 note->next_note = 0;
00154 polyphony--;
00155 return note;
00156 }
00157 prev = note;
00158 note = note->next_note;
00159 }
00160 return 0;
00161 }
00162
00163
00164 inline void Push(midi_event *event) {
00165 event->next_note = notes;
00166 notes = event;
00167 polyphony++;
00168 if (max_polyphony < polyphony) max_polyphony = polyphony;
00169 }
00170
00171
00172 inline void Push(midi_event *event, uint32 time) {
00173 event->note_time = time;
00174 event->next_note = 0;
00175
00176 polyphony++;
00177 if (max_polyphony < polyphony) max_polyphony = polyphony;
00178
00179 if (!notes || time <= notes->note_time) {
00180 event->next_note = notes;
00181 notes = event;
00182 }
00183 else {
00184 midi_event *prev = notes;
00185 while (prev) {
00186 midi_event *note = prev->next_note;
00187
00188 if (!note || time <= note->note_time) {
00189 event->next_note = note;
00190 prev->next_note = event;
00191 return;
00192 }
00193 prev = note;
00194 }
00195 }
00196 }
00197
00198 inline int GetPolyphony() {
00199 return polyphony;
00200 }
00201
00202 inline int GetMaxPolyphony() {
00203 return max_polyphony;
00204 }
00205 };
00206
00207 class XMIDIEventList
00208 {
00209 int counter;
00210
00211
00212 int PutVLQ(DataSource *dest, uint32 value);
00213 uint32 ConvertListToMTrk (DataSource *dest);
00214
00215 static void DeleteEventList (midi_event *list);
00216
00217 public:
00218 midi_event *events;
00219
00220
00221 int Write (const char *filename);
00222 int Write (DataSource *dest);
00223
00224
00225 void IncerementCounter () { counter++; }
00226
00227
00228 void DecerementCounter ();
00229 };
00230
00231 class XMIDI
00232 {
00233 protected:
00234 uint16 num_tracks;
00235
00236 private:
00237 XMIDIEventList **events;
00238
00239 midi_event *list;
00240 midi_event *current;
00241 midi_event *notes_on;
00242
00243 const static char mt32asgm[128];
00244 const static char mt32asgs[256];
00245 bool bank127[16];
00246 int convert_type;
00247
00248 bool do_reverb;
00249 bool do_chorus;
00250 int chorus_value;
00251 int reverb_value;
00252
00253
00254 static GammaTable<unsigned char> VolumeCurve;
00255
00256 public:
00257 XMIDI(DataSource *source, int pconvert);
00258 ~XMIDI();
00259
00260 int number_of_tracks() { return num_tracks; }
00261
00262
00263 XMIDIEventList *GetEventList (uint32 track);
00264
00265
00266
00267
00268 private:
00269 XMIDI();
00270
00271 struct first_state {
00272 midi_event *patch[16];
00273 midi_event *bank[16];
00274 midi_event *pan[16];
00275 midi_event *vol[16];
00276 };
00277
00278
00279 void CreateNewEvent (int time);
00280
00281
00282 int GetVLQ (DataSource *source, uint32 &quant);
00283 int GetVLQ2 (DataSource *source, uint32 &quant);
00284
00285 void AdjustTimings(uint32 ppqn);
00286 void ApplyFirstState(first_state &fs, int chan_mask);
00287
00288 int ConvertNote (const int time, const unsigned char status, DataSource *source, const int size);
00289 int ConvertEvent (const int time, const unsigned char status, DataSource *source, const int size, first_state& fs);
00290 int ConvertSystemMessage (const int time, const unsigned char status, DataSource *source);
00291
00292 int ConvertFiletoList (DataSource *source, const bool is_xmi, first_state& fs);
00293
00294 int ExtractTracksFromXmi (DataSource *source);
00295 int ExtractTracksFromMid (DataSource *source, const uint32 ppqn, const int num_tracks, const bool type1);
00296
00297 int ExtractTracks (DataSource *source);
00298 };
00299 #endif
00300
00301 #endif