00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020 #include "XMidiFile.h"
00021 #include "XMidiEvent.h"
00022 #include "XMidiEventList.h"
00023 #include "XMidiNoteStack.h"
00024
00025 #ifdef PENTAGRAM_IN_EXULT
00026 #include "game.h"
00027 #include "databuf.h"
00028 #else
00029 #include "IDataSource.h"
00030 #include "ODataSource.h"
00031 #endif
00032
00033 #ifndef UNDER_CE
00034 using std::atof;
00035 using std::atoi;
00036 using std::memcmp;
00037 using std::memcpy;
00038 using std::memset;
00039 using std::size_t;
00040 #endif
00041 using std::string;
00042 using std::endl;
00043
00044 #ifndef UNDER_CE
00045 #define XMidiEvent__Malloc XMidiEvent::Malloc
00046 #define XMidiEvent__Calloc XMidiEvent::Calloc
00047 #else
00048
00049 template<class T>
00050 static inline T* XMidiEvent__Malloc(size_t num=1)
00051 {
00052 return static_cast<T*>(std::malloc(num));
00053 }
00054
00055 template<class T>
00056 static inline T* XMidiEvent__Calloc(size_t num=1,size_t sz=0)
00057 {
00058 if(!sz) sz=sizeof(T);
00059 return static_cast<T*>(std::calloc(num,sz));
00060 }
00061
00062 #endif
00063
00064
00065
00066
00067
00068
00069
00070 #define PATCH_VOL_PAN_BIAS 5
00071
00072
00073
00074
00075
00076
00077 const char XMidiFile::mt32asgm[128] = {
00078 0,
00079 1,
00080 2,
00081 4,
00082 4,
00083 5,
00084 5,
00085 3,
00086 16,
00087 17,
00088 18,
00089 16,
00090 19,
00091 19,
00092 19,
00093 21,
00094 6,
00095 6,
00096 6,
00097 7,
00098 7,
00099 7,
00100 8,
00101 8,
00102 62,
00103 63,
00104 62,
00105 63,
00106 38,
00107 39,
00108 38,
00109 39,
00110 88,
00111 90,
00112 52,
00113 92,
00114 97,
00115 99,
00116 14,
00117 54,
00118 98,
00119 96,
00120 68,
00121 95,
00122 81,
00123 87,
00124 112,
00125 80,
00126 48,
00127 48,
00128 44,
00129 45,
00130 40,
00131 40,
00132 42,
00133 42,
00134 43,
00135 46,
00136 46,
00137 24,
00138 25,
00139 26,
00140 27,
00141 104,
00142 32,
00143 32,
00144 33,
00145 34,
00146 36,
00147 37,
00148 35,
00149 35,
00150 73,
00151 73,
00152 72,
00153 72,
00154 74,
00155 75,
00156 64,
00157 65,
00158 66,
00159 67,
00160 71,
00161 71,
00162 68,
00163 69,
00164 70,
00165 22,
00166 56,
00167 56,
00168 57,
00169 57,
00170 60,
00171 60,
00172 58,
00173 61,
00174 61,
00175 11,
00176 11,
00177 99,
00178 112,
00179 9,
00180 14,
00181 13,
00182 12,
00183 107,
00184 111,
00185 77,
00186 78,
00187 78,
00188 76,
00189 76,
00190 47,
00191 117,
00192 116,
00193 118,
00194 118,
00195 116,
00196 115,
00197 119,
00198 115,
00199 112,
00200 55,
00201 124,
00202 123,
00203 94,
00204 98,
00205 121
00206 };
00207
00208
00209
00210 const char XMidiFile::mt32asgs[256] = {
00211 0, 0,
00212 1, 0,
00213 2, 0,
00214 4, 0,
00215 4, 0,
00216 5, 0,
00217 5, 0,
00218 3, 0,
00219 16, 0,
00220 17, 0,
00221 18, 0,
00222 16, 0,
00223 19, 0,
00224 19, 0,
00225 19, 0,
00226 21, 0,
00227 6, 0,
00228 6, 0,
00229 6, 0,
00230 7, 0,
00231 7, 0,
00232 7, 0,
00233 8, 0,
00234 8, 0,
00235 62, 0,
00236 63, 0,
00237 62, 0,
00238 63, 0,
00239 38, 0,
00240 39, 0,
00241 38, 0,
00242 39, 0,
00243 88, 0,
00244 90, 0,
00245 52, 0,
00246 92, 0,
00247 97, 0,
00248 99, 0,
00249 14, 0,
00250 54, 0,
00251 98, 0,
00252 96, 0,
00253 68, 0,
00254 95, 0,
00255 81, 0,
00256 87, 0,
00257 112, 0,
00258 80, 0,
00259 48, 0,
00260 48, 0,
00261 44, 0,
00262 45, 0,
00263 40, 0,
00264 40, 0,
00265 42, 0,
00266 42, 0,
00267 43, 0,
00268 46, 0,
00269 46, 0,
00270 24, 0,
00271 25, 0,
00272 26, 0,
00273 27, 0,
00274 104, 0,
00275 32, 0,
00276 32, 0,
00277 33, 0,
00278 34, 0,
00279 36, 0,
00280 37, 0,
00281 35, 0,
00282 35, 0,
00283 73, 0,
00284 73, 0,
00285 72, 0,
00286 72, 0,
00287 74, 0,
00288 75, 0,
00289 64, 0,
00290 65, 0,
00291 66, 0,
00292 67, 0,
00293 71, 0,
00294 71, 0,
00295 68, 0,
00296 69, 0,
00297 70, 0,
00298 22, 0,
00299 56, 0,
00300 56, 0,
00301 57, 0,
00302 57, 0,
00303 60, 0,
00304 60, 0,
00305 58, 0,
00306 61, 0,
00307 61, 0,
00308 11, 0,
00309 11, 0,
00310 99, 0,
00311 112, 0,
00312 9, 0,
00313 14, 0,
00314 13, 0,
00315 12, 0,
00316 107, 0,
00317 111, 0,
00318 77, 0,
00319 78, 0,
00320 78, 0,
00321 76, 0,
00322 76, 0,
00323 47, 0,
00324 117, 0,
00325 116, 0,
00326 118, 0,
00327 118, 0,
00328 116, 0,
00329 115, 0,
00330 119, 0,
00331 115, 0,
00332 112, 0,
00333 55, 0,
00334 124, 0,
00335 123, 0,
00336 94, 0,
00337 98, 0,
00338 121, 0
00339 };
00340
00341
00342 const char XMidiFile::gmasmt32[128] =
00343 {
00344 0x00, 0x01, 0x03, 0x07, 0x05, 0x06, 0x11, 0x15,
00345 0x16, 0x65, 0x65, 0x62, 0x68, 0x67, 0x66, 0x69,
00346
00347 0x0C, 0x09, 0x0A, 0x0D, 0x0E, 0x0F, 0x57, 0x0F,
00348 0x3B, 0x3C, 0x3B, 0x3E, 0x3D, 0x3B, 0x3E, 0x3E,
00349
00350 0x40, 0x43, 0x42, 0x47, 0x44, 0x45, 0x42 , 0x46,
00351 0x35, 0x34, 0x36, 0x38, 0x35, 0x33, 0x39 , 0x70,
00352
00353 0X30, 0x32, 0x30, 0x32, 0x22, 0x2A, 0x21, 0x7A,
00354 0X58, 0x5A, 0x5E, 0x59, 0x5C, 0x5F, 0x59, 0x5B,
00355
00356 0x4E, 0x4F, 0x50, 0x51, 0x54, 0x55, 0x56, 0x53,
00357 0x4B, 0x49, 0x4C, 0x4D, 0x6E, 0x6B, 0x6C, 0x48,
00358
00359 0x2F, 0x43, 0x4B, 0x33, 0x3D, 0x48, 0x34, 0x43,
00360 0x20, 0x21, 0x43, 0x22, 0x20, 0x20, 0x21, 0x21,
00361
00362 0x29, 0x24, 0x23, 0x25, 0x2D, 0x21, 0x2B, 0x20,
00363 0x3F, 0x69, 0x69, 0x69, 0x33, 0x51, 0x34, 0x51,
00364
00365 0x17, 0x67, 0x67, 0x71, 0x75, 0x71, 0x74, 0x77,
00366 0x7C, 0x78, 0x77, 0x7C, 0x7B, 0x78, 0x77, 0x72
00367 };
00368
00369
00370
00371
00372 static const uint32 sysex_data_start = 7;
00373 static const uint32 sysex_max_data_size = 256;
00374
00375
00376
00377
00378
00379
00380 static const uint32 rhythm_base = 0x030110;
00381 static const uint32 rhythm_mem_size = 4;
00382
00383 static const uint32 rhythm_first_note = 24;
00384 static const uint32 rhythm_num_notes = 64;
00385
00386
00387 static inline uint32 rhythm_mem_offset(uint32 index_num) {
00388 return index_num * 4;
00389 }
00390
00391
00392 static inline uint32 rhythm_mem_offset_note(uint32 rhythm_note_num) {
00393 return (rhythm_note_num-rhythm_first_note) * 4;
00394 }
00395
00396 struct RhythmSetupData {
00397 uint8 timbre;
00398 uint8 output_level;
00399 uint8 panpot;
00400 uint8 reverb_switch;
00401 };
00402
00403
00404
00405
00406
00407 static const uint32 timbre_base = 0x080000;
00408 static const uint32 timbre_mem_size = 246;
00409 static inline uint32 timbre_mem_offset(uint32 timbre_num) { return timbre_num * 256; }
00410
00411
00412
00413
00414
00415 static const uint32 patch_base = 0x050000;
00416 static const uint32 patch_mem_size = 8;
00417 static inline uint32 patch_mem_offset(uint32 patch_num) { return patch_num * 8; }
00418
00419 struct PatchMemData {
00420 uint8 timbre_group;
00421 uint8 timbre_num;
00422 uint8 key_shift;
00423 uint8 fine_tune;
00424 uint8 bender_range;
00425 uint8 assign_mode;
00426 uint8 reverb_switch;
00427 uint8 dummy;
00428 };
00429
00430 static const PatchMemData patch_template = {
00431 2,
00432 0,
00433 24,
00434 50,
00435 24,
00436 0,
00437 1,
00438 0
00439 };
00440
00441
00442
00443
00444
00445 static const uint32 system_base = 0x100000;
00446 static const uint32 system_mem_size = 0x17;
00447 #define system_mem_offset(setting) ((uintptr)(&((systemArea*)0)->setting))
00448
00449 struct systemArea {
00450 char masterTune;
00451 char reverbMode;
00452 char reverbTime;
00453 char reverbLevel;
00454 char reserveSettings[9];
00455 char chanAssign[9];
00456 char masterVol;
00457 };
00458
00459 static const char system_init_reverb[3] = { 0,3,2 };
00460 static const char system_part_chans[9] = { 1,2,3,4,5,6,7,8,9 };
00461 static const char system_part_rsv[9] = { 3,4,3,4,3,4,3,4,4 };
00462
00463
00464
00465
00466 static const uint32 display_base = 0x200000;
00467 static const uint32 display_mem_size = 0x14;
00468
00469
00470 #ifdef PENTAGRAM_IN_EXULT
00471 static const char display[] = " Uploading Timbres! ";
00472 static const char display_black_gate[] = "BG Uploading Timbres";
00473 static const char display_serpent_isle[] = "SI Uploading Timbres";
00474
00475 static const char display_beginning[] = "--==| Exult! |==--";
00476 static const char display_beginning_bg[] = " U7: The Black Gate ";
00477 static const char display_beginning_si[] = "U7: The Serpent Isle";
00478 #else
00479
00480 static const char display[] = " Uploading Timbres! ";
00481 static const char display_beginning[] = "--=| Pentagram! |=--";
00482 #endif
00483
00484
00485
00486
00487 static const uint32 all_dev_reset_base = 0x7f0000;
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 static uint8 U7PercussionNotes[] = {
00498 28, 33, 74, 76, 77, 78, 79, 80,
00499 81, 82, 83, 84, 85, 86, 87, 0
00500 };
00501
00502
00503 static RhythmSetupData U7PercussionData[] = {
00504 { 0, 0x5A, 0x07, 0 },
00505 { 6, 0x64, 0x07, 1 },
00506 { 1, 0x5A, 0x05, 0 },
00507 { 1, 0x5A, 0x06, 0 },
00508 { 1, 0x5A, 0x07, 0 },
00509 { 2, 0x64, 0x07, 1 },
00510 { 1, 0x5A, 0x08, 0 },
00511 { 5, 0x5A, 0x07, 1 },
00512 { 1, 0x5A, 0x09, 0 },
00513 { 3, 0x5F, 0x07, 1 },
00514 { 4, 0x64, 0x04, 1 },
00515 { 4, 0x64, 0x05, 1 },
00516 { 4, 0x64, 0x06, 1 },
00517 { 4, 0x64, 0x07, 1 },
00518 { 4, 0x64, 0x08, 1 }
00519 };
00520
00521
00522
00523
00524 XMidiFile::XMidiFile(IDataSource *source, int pconvert) : num_tracks(0),
00525 events(NULL), convert_type(pconvert),
00526 do_reverb(false), do_chorus(false)
00527 {
00528 std::memset(bank127,0,sizeof(bank127));
00529
00530 ExtractTracks (source);
00531
00532
00533 if (pconvert >= XMIDIFILE_HINT_U7VOICE_MT_FILE) InsertDisplayEvents();
00534 }
00535
00536 XMidiFile::~XMidiFile()
00537 {
00538 if (events)
00539 {
00540 for (int i=0; i < num_tracks; i++) {
00541 events[i]->decerementCounter();
00542 events[i] = NULL;
00543 }
00544
00545 XMidiEvent::Free(events);
00546 }
00547 }
00548
00549 XMidiEventList *XMidiFile::GetEventList (uint32 track)
00550 {
00551 if (!events)
00552 {
00553 perr << "No midi data in loaded." << endl;
00554 return 0;
00555 }
00556
00557 if (track >= num_tracks)
00558 {
00559 perr << "Can't retrieve MIDI data, track out of range" << endl;
00560 return 0;
00561 }
00562
00563 return events[track];
00564 }
00565
00566
00567 void XMidiFile::CreateNewEvent (int time)
00568 {
00569 if (!list)
00570 {
00571 list = current = XMidiEvent__Calloc<XMidiEvent>();
00572 if (time > 0)
00573 current->time = time;
00574 return;
00575 }
00576
00577 if (time < 0 || list->time > time)
00578 {
00579 XMidiEvent *event = XMidiEvent__Calloc<XMidiEvent>();
00580 event->next = list;
00581 list = current = event;
00582 return;
00583 }
00584
00585 if (!current || current->time > time)
00586 current = list;
00587
00588 while (current->next)
00589 {
00590 if (current->next->time > time)
00591 {
00592 XMidiEvent *event = XMidiEvent__Calloc<XMidiEvent>();
00593
00594 event->next = current->next;
00595 current->next = event;
00596 current = event;
00597 current->time = time;
00598 return;
00599 }
00600
00601 current = current->next;
00602 }
00603
00604 current->next = XMidiEvent__Calloc<XMidiEvent>();
00605 current = current->next;
00606 current->time = time;
00607 }
00608
00609
00610
00611
00612
00613
00614 int XMidiFile::GetVLQ (IDataSource *source, uint32 &quant)
00615 {
00616 int i;
00617 quant = 0;
00618 unsigned int data;
00619
00620 for (i = 0; i < 4; i++)
00621 {
00622 data = source->read1();
00623 quant <<= 7;
00624 quant |= data & 0x7F;
00625
00626 if (!(data & 0x80))
00627 {
00628 i++;
00629 break;
00630 }
00631
00632 }
00633 return i;
00634 }
00635
00636
00637
00638
00639
00640
00641 int XMidiFile::GetVLQ2 (IDataSource *source, uint32 &quant)
00642 {
00643 int i;
00644 quant = 0;
00645 int data = 0;
00646
00647 for (i = 0; i < 4; i++)
00648 {
00649 data = source->read1();
00650 if (data & 0x80)
00651 {
00652 source->skip(-1);
00653 break;
00654 }
00655 quant += data;
00656 }
00657 return i;
00658 }
00659
00660
00661
00662
00663
00664
00665
00666 void XMidiFile::ApplyFirstState(first_state &fs, int chan_mask)
00667 {
00668 for (int channel = 0; channel < 16; channel++)
00669 {
00670 XMidiEvent *patch = fs.patch[channel];
00671 XMidiEvent *vol = fs.vol[channel];
00672 XMidiEvent *pan = fs.pan[channel];
00673 XMidiEvent *bank = fs.bank[channel];
00674 XMidiEvent *reverb = NULL;
00675 XMidiEvent *chorus = NULL;
00676 XMidiEvent *temp;
00677
00678
00679 if (!patch || !(chan_mask & 1 << channel)) continue;
00680 #if 0
00681 std::cout << "Channel: " << channel+1 << std::endl;
00682 std::cout << "Patch: " << (unsigned int) patch->data[0] << " @ " << patch->time << std::endl;
00683 if (bank) std::cout << " Bank: " << (unsigned int) bank->data[1] << " @ " << bank->time << std::endl;
00684 if (vol) std::cout << " Vol: " << (unsigned int) vol->data[1] << " @ " << vol->time << std::endl;
00685 if (pan) std::cout << " Pan: " << ((signed int) pan->data[1])-64 << " @ " << pan->time << std::endl;
00686 std::cout << std::endl;
00687 #endif
00688
00689
00690 temp = patch;
00691 patch = XMidiEvent__Calloc<XMidiEvent>();
00692 patch->time = temp->time;
00693 patch->status = channel|(MIDI_STATUS_PROG_CHANGE << 4);
00694 patch->data[0] = temp->data[0];
00695
00696
00697 if (vol && (vol->time > patch->time+PATCH_VOL_PAN_BIAS || vol->time < patch->time-PATCH_VOL_PAN_BIAS))
00698 vol = NULL;
00699
00700 temp = vol;
00701 vol = XMidiEvent__Calloc<XMidiEvent>();
00702 vol->status = channel|(MIDI_STATUS_CONTROLLER << 4);
00703 vol->data[0] = 7;
00704
00705 if (!temp)
00706 {
00707
00708 if (convert_type) vol->data[1] = 90;
00709 else vol->data[1] = 90;
00710 }
00711 else
00712 vol->data[1] = temp->data[1];
00713
00714
00715
00716 if (bank && (bank->time > patch->time+PATCH_VOL_PAN_BIAS || bank->time < patch->time-PATCH_VOL_PAN_BIAS))
00717 bank = NULL;
00718
00719 temp = bank;
00720
00721 bank = XMidiEvent__Calloc<XMidiEvent>();
00722 bank->status = channel|(MIDI_STATUS_CONTROLLER << 4);
00723
00724 if (!temp)
00725 bank->data[1] = 0;
00726 else
00727 bank->data[1] = temp->data[1];
00728
00729
00730 if (pan && (pan->time > patch->time+PATCH_VOL_PAN_BIAS || pan->time < patch->time-PATCH_VOL_PAN_BIAS))
00731 pan = NULL;
00732
00733 temp = pan;
00734 pan = XMidiEvent__Calloc<XMidiEvent>();
00735 pan->status = channel|(MIDI_STATUS_CONTROLLER << 4);
00736 pan->data[0] = 10;
00737
00738 if (!temp)
00739 pan->data[1] = 64;
00740 else
00741 pan->data[1] = temp->data[1];
00742
00743 if (do_reverb)
00744 {
00745 reverb = XMidiEvent__Calloc<XMidiEvent>();
00746 reverb->status = channel|(MIDI_STATUS_CONTROLLER << 4);
00747 reverb->data[0] = 91;
00748 reverb->data[1] = reverb_value;
00749 }
00750
00751 if (do_chorus)
00752 {
00753 chorus = XMidiEvent__Calloc<XMidiEvent>();
00754 chorus->status = channel|(MIDI_STATUS_CONTROLLER << 4);
00755 chorus->data[0] = 93;
00756 chorus->data[1] = chorus_value;
00757 }
00758
00759 vol->time = 0;
00760 pan->time = 0;
00761 patch->time = 0;
00762 bank->time = 0;
00763
00764 if (do_reverb && do_chorus) reverb->next = chorus;
00765 else if (do_reverb) reverb->next = bank;
00766 if (do_chorus) chorus->next = bank;
00767 bank->next = vol;
00768 vol->next = pan;
00769 pan->next = patch;
00770
00771 patch->next = list;
00772 if (do_reverb) list = reverb;
00773 else if (do_chorus) list = chorus;
00774 else list = bank;
00775 }
00776 }
00777
00778 #ifndef BEOS
00779
00780 struct uint64 {
00781 uint32 low;
00782 uint32 high;
00783
00784 uint64() : low(0), high(0) { }
00785 uint64(uint32 i) : low(i), high(0) { }
00786 uint64(uint32 h, uint32 l) : low(l), high(h) { }
00787 uint64(const uint64 &i) : low(i.low), high(i.high) { }
00788
00789 inline void addlow(uint32 l) {
00790 uint32 mid = (low >> 16);
00791 low = (low & 0xFFFF) + (l & 0xFFFF);
00792 mid += (low >> 16) + (l >> 16);
00793 low = (low&0xFFFF) + (mid << 16);
00794 high += mid >> 16;
00795 }
00796
00797
00798
00799 inline uint64 & operator = (uint64 &o) {
00800 low = o.low;
00801 high = o.high;
00802 return *this;
00803 }
00804
00805 inline uint64 & operator += (uint64 &o) {
00806 addlow(o.low);
00807 high += o.high;
00808 return *this;
00809 }
00810
00811 inline uint64 operator + (uint64 &o) {
00812 uint64 n(*this);
00813 n.addlow(o.low);
00814 n.high += o.high;
00815 return n;
00816 }
00817
00818
00819
00820 inline uint64 & operator = (uint32 i) {
00821 low = i;
00822 high = 0;
00823 return *this;
00824 }
00825
00826 inline uint64 & operator += (uint32 i) {
00827 addlow(i);
00828 return *this;
00829 }
00830
00831 inline uint64 operator + (uint32 i) {
00832 uint64 n(*this);
00833 n.addlow(i);
00834 return n;
00835 }
00836
00837 inline uint64 & operator *= (uint32 i) {
00838
00839 uint32 h1 = i >> 16;
00840 uint32 h2 = low >> 16;
00841
00842
00843
00844 uint32 l1 = i & 0xFFFF;
00845 uint32 l2 = low & 0xFFFF;
00846 uint32 l3 = high & 0xFFFF;
00847
00848
00849 uint32 accum;
00850
00851
00852 low = l1*l2;
00853 high = 0;
00854
00855
00856 accum = h1*l2;
00857 addlow(accum<<16);
00858 high += accum>>16;
00859
00860
00861 accum = l1*h2;
00862 addlow(accum<<16);
00863 high += accum>>16;
00864
00865
00866 high += h1*h2;
00867
00868
00869 high += l1*l3;
00870
00871
00872 high += (h1*l3) << 16;
00873
00874
00875 high += (l1*l3) << 16;
00876
00877 return *this;
00878 }
00879
00880 inline uint64 operator * (uint32 i) {
00881 uint64 n(*this);
00882 return n*=i;
00883 }
00884
00885 inline uint64 & operator /= (uint32 div) {
00886
00887
00888 if (!high) {
00889 low /= div;
00890 return *this;
00891 }
00892
00893
00894 uint32 mod = high;
00895 uint32 l = low;
00896
00897
00898 uint32 shift = 32;
00899 low = 0;
00900
00901
00902
00903 if (mod >= div) {
00904 high = mod / div;
00905 mod %= div;
00906 }
00907 else high = 0;
00908
00909
00910 while (--shift) {
00911
00912 mod <<= 1;
00913 mod |= (l>>shift) & 1;
00914
00915
00916 if (mod >= div) {
00917 uint32 v = mod / div;
00918 mod %= div;
00919 addlow(v << shift);
00920 high += v >> (32 - shift);
00921 }
00922 }
00923
00924
00925
00926 mod <<= 1;
00927 mod |= l & 1;
00928
00929
00930 if (mod >= div) {
00931 uint32 v = mod / div;
00932 mod %= div;
00933 addlow(v << shift);
00934 }
00935
00936 return *this;
00937 }
00938
00939 inline uint64 operator / (uint32 i) {
00940 uint64 n(*this);
00941 return n/=i;
00942 }
00943
00944 inline uint64 & operator %= (uint32 div) {
00945
00946
00947 if (!high) {
00948 low %= div;
00949 return *this;
00950 }
00951
00952
00953 uint32 mod = high;
00954
00955
00956 uint32 shift = 32;
00957
00958 while (1) {
00959
00960
00961 if (mod >= div) mod %= div;
00962
00963 if (shift == 0) break;
00964
00965 mod <<= 1;
00966 shift--;
00967 mod |= (low>>shift) & 1;
00968 }
00969
00970 high = 0;
00971 low = mod;
00972
00973 return *this;
00974 }
00975
00976 inline uint64 operator % (uint32 i) {
00977 uint64 n(*this);
00978 return n%=i;
00979 }
00980
00981 inline operator uint32 ()
00982 {
00983 return low;
00984 }
00985
00986 void printx() {
00987 if (high) std::printf ("%X%08X", high, low);
00988 else printf ("%X", low);
00989 }
00990 };
00991 #endif
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001 void XMidiFile::AdjustTimings(uint32 ppqn)
01002 {
01003 uint32 tempo = 500000;
01004 uint32 time_prev = 0;
01005 uint32 hs_rem = 0;
01006 uint32 hs = 0;
01007
01008 ppqn *= 10000;
01009
01010
01011 XMidiNoteStack notes;
01012
01013 for (XMidiEvent *event = list; event; event = event->next) {
01014
01015
01016
01017
01018 uint64 aim = event->time - time_prev;
01019 aim *= tempo;
01020
01021 hs_rem += aim%ppqn;
01022 hs += aim/ppqn;
01023 hs += hs_rem/ppqn;
01024 hs_rem %= ppqn;
01025
01026 time_prev = event->time;
01027 event->time = (hs*6)/5 + (6*hs_rem)/(5*ppqn);
01028
01029
01030 if (event->status <= 0x9F) {
01031
01032
01033 if ((event->status>>4) == MIDI_STATUS_NOTE_ON && event->data[1])
01034 notes.Push(event);
01035 else {
01036 XMidiEvent *prev = notes.FindAndPop(event);
01037 if (prev) prev->ex.note_on.duration = event->time - prev->time;
01038 }
01039
01040 }
01041 else if (event->status == 0xFF && event->data[0] == 0x51) {
01042
01043 tempo = (event->ex.sysex_data.buffer[0] << 16) +
01044 (event->ex.sysex_data.buffer[1] << 8) +
01045 event->ex.sysex_data.buffer[2];
01046
01047 event->ex.sysex_data.buffer[0] = 0x07;
01048 event->ex.sysex_data.buffer[1] = 0xA1;
01049 event->ex.sysex_data.buffer[2] = 0x20;
01050 }
01051 }
01052
01053
01054 static const unsigned char tempo_buf[5] = { 0x51, 0x03, 0x07, 0xA1, 0x20 };
01055 IBufferDataSource ds(tempo_buf, 5);
01056 current = list;
01057 ConvertSystemMessage (0, 0xFF,&ds);
01058 }
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 int XMidiFile::ConvertEvent (const int time, const unsigned char status, IDataSource *source, const int size, first_state &fs)
01074 {
01075 int data;
01076
01077 data = source->read1();
01078
01079
01080
01081 if ((status >> 4) == 0xB && data == 0)
01082 {
01083 data = source->read1();
01084
01085 bank127[status&0xF] = false;
01086
01087 if (convert_type == XMIDIFILE_CONVERT_MT32_TO_GM
01088 || convert_type == XMIDIFILE