XMidiFile.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2003  The Pentagram Team
00003 
00004 This program is free software; you can redistribute it and/or
00005 modify it under the terms of the GNU General Public License
00006 as published by the Free Software Foundation; either version 2
00007 of the License, or (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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 //#include "gamma.h"
00065 
00066 // This is used to correct incorrect patch, vol and pan changes in midi files
00067 // The bias is just a value to used to work out if a vol and pan belong with a 
00068 // patch change. This is to ensure that the default state of a midi file is with
00069 // the tracks centred, unless the first patch change says otherwise.
00070 #define PATCH_VOL_PAN_BIAS      5
00071 
00072 
00073 // This is a default set of patches to convert from MT32 to GM
00074 // The index is the MT32 Patch nubmer and the value is the GM Patch
00075 // This is only suitable for music that doesn'tdo timbre changes
00076 // XMidis that contain Timbre changes will not convert properly
00077 const char XMidiFile::mt32asgm[128] = {
00078         0,      // 0    Piano 1
00079         1,      // 1    Piano 2
00080         2,      // 2    Piano 3 (synth)
00081         4,      // 3    EPiano 1
00082         4,      // 4    EPiano 2
00083         5,      // 5    EPiano 3
00084         5,      // 6    EPiano 4
00085         3,      // 7    Honkytonk
00086         16,     // 8    Organ 1
00087         17,     // 9    Organ 2
00088         18,     // 10   Organ 3
00089         16,     // 11   Organ 4
00090         19,     // 12   Pipe Organ 1
00091         19,     // 13   Pipe Organ 2
00092         19,     // 14   Pipe Organ 3
00093         21,     // 15   Accordion
00094         6,      // 16   Harpsichord 1
00095         6,      // 17   Harpsichord 2
00096         6,      // 18   Harpsichord 3
00097         7,      // 19   Clavinet 1
00098         7,      // 20   Clavinet 2
00099         7,      // 21   Clavinet 3
00100         8,      // 22   Celesta 1
00101         8,      // 23   Celesta 2
00102         62,     // 24   Synthbrass 1 (62)
00103         63,     // 25   Synthbrass 2 (63)
00104         62,     // 26   Synthbrass 3 Bank 8
00105         63,     // 27   Synthbrass 4 Bank 8
00106         38,     // 28   Synthbass 1
00107         39,     // 29   Synthbass 2
00108         38,     // 30   Synthbass 3 Bank 8
00109         39,     // 31   Synthbass 4 Bank 8
00110         88,     // 32   Fantasy
00111         90,     // 33   Harmonic Pan - No equiv closest is polysynth(90) :(
00112         52,     // 34   Choral ?? Currently set to SynthVox(54). Should it be ChoirAhhs(52)???
00113         92,     // 35   Glass
00114         97,     // 36   Soundtrack
00115         99,     // 37   Atmosphere
00116         14,     // 38   Warmbell, sounds kind of like crystal(98) perhaps Tubular Bells(14) would be better. It is!
00117         54,     // 39   FunnyVox, sounds alot like Bagpipe(109) and Shania(111)
00118         98,     // 40   EchoBell, no real equiv, sounds like Crystal(98)
00119         96,     // 41   IceRain
00120         68,     // 42   Oboe 2001, no equiv, just patching it to normal oboe(68)
00121         95,     // 43   EchoPans, no equiv, setting to SweepPad
00122         81,     // 44   DoctorSolo Bank 8
00123         87,     // 45   SchoolDaze, no real equiv
00124         112,    // 46   Bell Singer
00125         80,     // 47   SquareWave
00126         48,     // 48   Strings 1
00127         48,     // 49   Strings 2 - should be 49
00128         44,     // 50   Strings 3 (Synth) - Experimental set to Tremollo Strings - should be 50
00129         45,     // 51   Pizzicato Strings
00130         40,     // 52   Violin 1
00131         40,     // 53   Violin 2 ? Viola
00132         42,     // 54   Cello 1
00133         42,     // 55   Cello 2
00134         43,     // 56   Contrabass
00135         46,     // 57   Harp 1
00136         46,     // 58   Harp 2
00137         24,     // 59   Guitar 1 (Nylon)
00138         25,     // 60   Guitar 2 (Steel)
00139         26,     // 61   Elec Guitar 1
00140         27,     // 62   Elec Guitar 2
00141         104,    // 63   Sitar
00142         32,     // 64   Acou Bass 1
00143         32,     // 65   Acou Bass 2
00144         33,     // 66   Elec Bass 1
00145         34,     // 67   Elec Bass 2
00146         36,     // 68   Slap Bass 1
00147         37,     // 69   Slap Bass 2
00148         35,     // 70   Fretless Bass 1
00149         35,     // 71   Fretless Bass 2
00150         73,     // 72   Flute 1
00151         73,     // 73   Flute 2
00152         72,     // 74   Piccolo 1
00153         72,     // 75   Piccolo 2
00154         74,     // 76   Recorder
00155         75,     // 77   Pan Pipes
00156         64,     // 78   Sax 1
00157         65,     // 79   Sax 2
00158         66,     // 80   Sax 3
00159         67,     // 81   Sax 4
00160         71,     // 82   Clarinet 1
00161         71,     // 83   Clarinet 2
00162         68,     // 84   Oboe
00163         69,     // 85   English Horn (Cor Anglais)
00164         70,     // 86   Bassoon
00165         22,     // 87   Harmonica
00166         56,     // 88   Trumpet 1
00167         56,     // 89   Trumpet 2
00168         57,     // 90   Trombone 1
00169         57,     // 91   Trombone 2
00170         60,     // 92   French Horn 1
00171         60,     // 93   French Horn 2
00172         58,     // 94   Tuba    
00173         61,     // 95   Brass Section 1
00174         61,     // 96   Brass Section 2
00175         11,     // 97   Vibes 1
00176         11,     // 98   Vibes 2
00177         99,     // 99   Syn Mallet Bank 1
00178         112,    // 100  WindBell no real equiv Set to TinkleBell(112)
00179         9,      // 101  Glockenspiel
00180         14,     // 102  Tubular Bells
00181         13,     // 103  Xylophone
00182         12,     // 104  Marimba
00183         107,    // 105  Koto
00184         111,    // 106  Sho?? set to Shanai(111)
00185         77,     // 107  Shakauhachi
00186         78,     // 108  Whistle 1
00187         78,     // 109  Whistle 2
00188         76,     // 110  Bottle Blow
00189         76,     // 111  Breathpipe no real equiv set to bottle blow(76)
00190         47,     // 112  Timpani
00191         117,    // 113  Melodic Tom
00192         116,    // 114  Deap Snare no equiv, set to Taiko(116)
00193         118,    // 115  Electric Perc 1
00194         118,    // 116  Electric Perc 2
00195         116,    // 117  Taiko
00196         115,    // 118  Taiko Rim, no real equiv, set to Woodblock(115)
00197         119,    // 119  Cymbal, no real equiv, set to reverse cymbal(119)
00198         115,    // 120  Castanets, no real equiv, in GM set to Woodblock(115)
00199         112,    // 121  Triangle, no real equiv, set to TinkleBell(112)
00200         55,     // 122  Orchestral Hit
00201         124,    // 123  Telephone
00202         123,    // 124  BirdTweet
00203         94,     // 125  Big Notes Pad no equiv, set to halo pad (94)
00204         98,     // 126  Water Bell set to Crystal Pad(98)
00205         121     // 127  Jungle Tune set to Breath Noise
00206 };
00207 
00208 // Same as above, except include patch changes
00209 // so GS instruments can be used
00210 const char XMidiFile::mt32asgs[256] = {
00211         0, 0,   // 0    Piano 1
00212         1, 0,   // 1    Piano 2
00213         2, 0,   // 2    Piano 3 (synth)
00214         4, 0,   // 3    EPiano 1
00215         4, 0,   // 4    EPiano 2
00216         5, 0,   // 5    EPiano 3
00217         5, 0,   // 6    EPiano 4
00218         3, 0,   // 7    Honkytonk
00219         16, 0,  // 8    Organ 1
00220         17, 0,  // 9    Organ 2
00221         18, 0,  // 10   Organ 3
00222         16, 0,  // 11   Organ 4
00223         19, 0,  // 12   Pipe Organ 1
00224         19, 0,  // 13   Pipe Organ 2
00225         19, 0,  // 14   Pipe Organ 3
00226         21, 0,  // 15   Accordion
00227         6, 0,   // 16   Harpsichord 1
00228         6, 0,   // 17   Harpsichord 2
00229         6, 0,   // 18   Harpsichord 3
00230         7, 0,   // 19   Clavinet 1
00231         7, 0,   // 20   Clavinet 2
00232         7, 0,   // 21   Clavinet 3
00233         8, 0,   // 22   Celesta 1
00234         8, 0,   // 23   Celesta 2
00235         62, 0,  // 24   Synthbrass 1 (62)
00236         63, 0,  // 25   Synthbrass 2 (63)
00237         62, 0,  // 26   Synthbrass 3 Bank 8
00238         63, 0,  // 27   Synthbrass 4 Bank 8
00239         38, 0,  // 28   Synthbass 1
00240         39, 0,  // 29   Synthbass 2
00241         38, 0,  // 30   Synthbass 3 Bank 8
00242         39, 0,  // 31   Synthbass 4 Bank 8
00243         88, 0,  // 32   Fantasy
00244         90, 0,  // 33   Harmonic Pan - No equiv closest is polysynth(90) :(
00245         52, 0,  // 34   Choral ?? Currently set to SynthVox(54). Should it be ChoirAhhs(52)???
00246         92, 0,  // 35   Glass
00247         97, 0,  // 36   Soundtrack
00248         99, 0,  // 37   Atmosphere
00249         14, 0,  // 38   Warmbell, sounds kind of like crystal(98) perhaps Tubular Bells(14) would be better. It is!
00250         54, 0,  // 39   FunnyVox, sounds alot like Bagpipe(109) and Shania(111)
00251         98, 0,  // 40   EchoBell, no real equiv, sounds like Crystal(98)
00252         96, 0,  // 41   IceRain
00253         68, 0,  // 42   Oboe 2001, no equiv, just patching it to normal oboe(68)
00254         95, 0,  // 43   EchoPans, no equiv, setting to SweepPad
00255         81, 0,  // 44   DoctorSolo Bank 8
00256         87, 0,  // 45   SchoolDaze, no real equiv
00257         112, 0, // 46   Bell Singer
00258         80, 0,  // 47   SquareWave
00259         48, 0,  // 48   Strings 1
00260         48, 0,  // 49   Strings 2 - should be 49
00261         44, 0,  // 50   Strings 3 (Synth) - Experimental set to Tremollo Strings - should be 50
00262         45, 0,  // 51   Pizzicato Strings
00263         40, 0,  // 52   Violin 1
00264         40, 0,  // 53   Violin 2 ? Viola
00265         42, 0,  // 54   Cello 1
00266         42, 0,  // 55   Cello 2
00267         43, 0,  // 56   Contrabass
00268         46, 0,  // 57   Harp 1
00269         46, 0,  // 58   Harp 2
00270         24, 0,  // 59   Guitar 1 (Nylon)
00271         25, 0,  // 60   Guitar 2 (Steel)
00272         26, 0,  // 61   Elec Guitar 1
00273         27, 0,  // 62   Elec Guitar 2
00274         104, 0, // 63   Sitar
00275         32, 0,  // 64   Acou Bass 1
00276         32, 0,  // 65   Acou Bass 2
00277         33, 0,  // 66   Elec Bass 1
00278         34, 0,  // 67   Elec Bass 2
00279         36, 0,  // 68   Slap Bass 1
00280         37, 0,  // 69   Slap Bass 2
00281         35, 0,  // 70   Fretless Bass 1
00282         35, 0,  // 71   Fretless Bass 2
00283         73, 0,  // 72   Flute 1
00284         73, 0,  // 73   Flute 2
00285         72, 0,  // 74   Piccolo 1
00286         72, 0,  // 75   Piccolo 2
00287         74, 0,  // 76   Recorder
00288         75, 0,  // 77   Pan Pipes
00289         64, 0,  // 78   Sax 1
00290         65, 0,  // 79   Sax 2
00291         66, 0,  // 80   Sax 3
00292         67, 0,  // 81   Sax 4
00293         71, 0,  // 82   Clarinet 1
00294         71, 0,  // 83   Clarinet 2
00295         68, 0,  // 84   Oboe
00296         69, 0,  // 85   English Horn (Cor Anglais)
00297         70, 0,  // 86   Bassoon
00298         22, 0,  // 87   Harmonica
00299         56, 0,  // 88   Trumpet 1
00300         56, 0,  // 89   Trumpet 2
00301         57, 0,  // 90   Trombone 1
00302         57, 0,  // 91   Trombone 2
00303         60, 0,  // 92   French Horn 1
00304         60, 0,  // 93   French Horn 2
00305         58, 0,  // 94   Tuba    
00306         61, 0,  // 95   Brass Section 1
00307         61, 0,  // 96   Brass Section 2
00308         11, 0,  // 97   Vibes 1
00309         11, 0,  // 98   Vibes 2
00310         99, 0,  // 99   Syn Mallet Bank 1
00311         112, 0, // 100  WindBell no real equiv Set to TinkleBell(112)
00312         9, 0,   // 101  Glockenspiel
00313         14, 0,  // 102  Tubular Bells
00314         13, 0,  // 103  Xylophone
00315         12, 0,  // 104  Marimba
00316         107, 0, // 105  Koto
00317         111, 0, // 106  Sho?? set to Shanai(111)
00318         77, 0,  // 107  Shakauhachi
00319         78, 0,  // 108  Whistle 1
00320         78, 0,  // 109  Whistle 2
00321         76, 0,  // 110  Bottle Blow
00322         76, 0,  // 111  Breathpipe no real equiv set to bottle blow(76)
00323         47, 0,  // 112  Timpani
00324         117, 0, // 113  Melodic Tom
00325         116, 0, // 114  Deap Snare no equiv, set to Taiko(116)
00326         118, 0, // 115  Electric Perc 1
00327         118, 0, // 116  Electric Perc 2
00328         116, 0, // 117  Taiko
00329         115, 0, // 118  Taiko Rim, no real equiv, set to Woodblock(115)
00330         119, 0, // 119  Cymbal, no real equiv, set to reverse cymbal(119)
00331         115, 0, // 120  Castanets, no real equiv, in GM set to Woodblock(115)
00332         112, 0, // 121  Triangle, no real equiv, set to TinkleBell(112)
00333         55, 0,  // 122  Orchestral Hit
00334         124, 0, // 123  Telephone
00335         123, 0, // 124  BirdTweet
00336         94, 0,  // 125  Big Notes Pad no equiv, set to halo pad (94)
00337         98, 0,  // 126  Water Bell set to Crystal Pad(98)
00338         121, 0  // 127  Jungle Tune set to Breath Noise
00339 };
00340 
00341 // Reverse mapping. GM Notes converted to MT-32 patches
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 // MT32 SysEx
00371 //
00372 static const uint32 sysex_data_start = 7;               // Data starts at byte 7
00373 static const uint32 sysex_max_data_size = 256;
00374 
00375 
00376 //
00377 // Percussion
00378 //
00379 
00380 static const uint32 rhythm_base = 0x030110;     // Note, these are 7 bit!
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 // Memory offset based on index in the table
00387 static inline uint32 rhythm_mem_offset(uint32 index_num) { 
00388         return index_num * 4; 
00389 }
00390 
00391 // Memory offset based on note key num
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;                                 // 0-94 (M1-M64,R1-30,OFF)
00398         uint8           output_level;                   // 0-100
00399         uint8           panpot;                                 // 0-14 (L-R)
00400         uint8           reverb_switch;                  // 0-1 (off,on)
00401 };
00402 
00403 
00404 //
00405 // Timbre Memory Consts
00406 //
00407 static const uint32 timbre_base = 0x080000;     // Note, these are 7 bit!
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 // Patch Memory Consts
00414 //
00415 static const uint32 patch_base = 0x050000;              // Note, these are 7 bit!
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;                   // 0-3  (group A, group B, Memory, Rhythm)
00421         uint8           timbre_num;                             // 0-63
00422         uint8           key_shift;                              // 0-48
00423         uint8           fine_tune;                              // 0-100 (-50 - +50)
00424         uint8           bender_range;                   // 0-24
00425         uint8           assign_mode;                    // 0-3 (POLY1, POLY2, POLY3, POLY4)
00426         uint8           reverb_switch;                  // 0-1 (off,on)
00427         uint8           dummy;
00428 };
00429 
00430 static const PatchMemData patch_template = {
00431         2,              // timbre_group
00432         0,              // timbre_num
00433         24,             // key_shift
00434         50,             // fine_tune
00435         24,             // bender_range
00436         0,              // assign_mode
00437         1,              // reverb_switch
00438         0               // dummy
00439 };
00440         
00441 
00442 //
00443 // System Area Consts
00444 //
00445 static const uint32 system_base = 0x100000;     // Note, these are 7 bit!
00446 static const uint32 system_mem_size = 0x17;     // Display is 20 ASCII characters (32-127)
00447 #define system_mem_offset(setting) ((uintptr)(&((systemArea*)0)->setting))
00448 
00449 struct systemArea {
00450         char masterTune;                                        // MASTER TUNE 0-127 432.1-457.6Hz
00451         char reverbMode;                                        // REVERB MODE 0-3 (room, hall, plate, tap delay)
00452         char reverbTime;                                        // REVERB TIME 0-7 (1-8)
00453         char reverbLevel;                                       // REVERB LEVEL 0-7 (1-8)
00454         char reserveSettings[9];                        // PARTIAL RESERVE (PART 1) 0-32
00455         char chanAssign[9];                                     // MIDI CHANNEL (PART1) 0-16 (1-16,OFF)
00456         char masterVol;                                         // MASTER VOLUME 0-100
00457 };
00458 
00459 static const char system_init_reverb[3] = { 0,3,2 };                            // reverb mode = 0, time = 3, level = 2
00460 static const char system_part_chans[9] =  { 1,2,3,4,5,6,7,8,9 };        // default (0-based) chans for each part
00461 static const char system_part_rsv[9] = { 3,4,3,4,3,4,3,4,4 };           // # of reserved AIL partials/channel
00462 
00463 //
00464 // Display  Consts
00465 //
00466 static const uint32 display_base = 0x200000;    // Note, these are 7 bit!
00467 static const uint32 display_mem_size = 0x14;    // Display is 20 ASCII characters (32-127)
00468 
00469 // Display messages                         0123456789ABCDEF0123
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 // All Dev Reset
00486 //
00487 static const uint32 all_dev_reset_base = 0x7f0000;
00488 
00489 
00490 //
00491 // U7 Percussion Table
00492 //
00493 // Why this crap wasn't in the flexes i will never know
00494 //
00495 
00496 // The key num that the data below belongs to (subtract 24 to get memory num)
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 // The RhythmSetup data 
00503 static RhythmSetupData U7PercussionData[] = {
00504         {       0,      0x5A,   0x07,   0       },      // 28
00505         {       6,      0x64,   0x07,   1       },      // 33
00506         {       1,      0x5A,   0x05,   0       },      // 74
00507         {       1,      0x5A,   0x06,   0       },      // 76
00508         {       1,      0x5A,   0x07,   0       },      // 77
00509         {       2,      0x64,   0x07,   1       },      // 78
00510         {       1,      0x5A,   0x08,   0       },      // 79
00511         {       5,      0x5A,   0x07,   1       },      // 80
00512         {       1,      0x5A,   0x09,   0       },      // 81
00513         {       3,      0x5F,   0x07,   1       },      // 82
00514         {       4,      0x64,   0x04,   1       },      // 83
00515         {       4,      0x64,   0x05,   1       },      // 84
00516         {       4,      0x64,   0x06,   1       },      // 85
00517         {       4,      0x64,   0x07,   1       },      // 86
00518         {       4,      0x64,   0x08,   1       }       // 87
00519 };
00520 
00521 //GammaTable<unsigned char> XMidiFile::VolumeCurve(128);
00522 
00523 // Constructor
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         // SysEx data
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                 //delete [] events;
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 // Sets current to the new event and updates list
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 // GetVLQ
00611 //
00612 // Get a Conventional Variable Length Quantity
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 // GetVLQ2
00638 //
00639 // Get a XMidiFile Variable Length Quantity
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 // MovePatchVolAndPan.
00662 //
00663 // Well, this is just a modified version of what that method used to do. This
00664 // is a massive optimization. Speed up should be quite impressive
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                 // Got no patch change, return and don't try fixing it
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                 // Copy Patch Change Event
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                 // Copy Volume
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 //                      if (convert_type) vol->data[1] = VolumeCurve[90];
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                 // Copy Bank
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                 // Copy Pan
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 // Unsigned 64 Bit Int emulation. Only supports SOME operations
00780 struct uint64 {
00781         uint32  low;            // Low is first so uint64 can be cast as uint32 to get low dword
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         // uint64 operations
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         // uint32 operations
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                 // High 16 bits
00839                 uint32 h1 =   i >> 16;
00840                 uint32 h2 = low >> 16;
00841                 //uint32 h3 = high >> 16;
00842 
00843                 // Low 16 Bits
00844                 uint32 l1 =   i & 0xFFFF;
00845                 uint32 l2 = low & 0xFFFF;
00846                 uint32 l3 = high & 0xFFFF;
00847 
00848                 // The accumulator
00849                 uint32 accum;
00850 
00851                 // 0 -> 32
00852                 low = l1*l2;
00853                 high = 0;
00854 
00855                 // 16 -> 48
00856                 accum = h1*l2;
00857                 addlow(accum<<16);
00858                 high += accum>>16;
00859 
00860                 // 16 -> 48
00861                 accum = l1*h2;
00862                 addlow(accum<<16);      
00863                 high += accum>>16;
00864 
00865                 // 32 -> 64
00866                 high += h1*h2;
00867 
00868                 // 32 -> 64
00869                 high += l1*l3;
00870 
00871                 // 48 -> 80
00872                 high += (h1*l3) << 16;
00873 
00874                 // 48 -> 80
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                 // If there isn't a high dword, we only need to work on the low dword
00888                 if (!high) {
00889                         low /= div;
00890                         return *this;
00891                 }
00892 
00893                 // modulus of last division
00894                 uint32 mod = high;
00895                 uint32 l = low;
00896 
00897                 // Low shift
00898                 uint32 shift = 32;
00899                 low = 0;
00900 
00901                 // Only High DWORD
00902                 // Can divide
00903                 if (mod >= div) {
00904                         high = mod / div;
00905                         mod %= div;
00906                 }
00907                 else high = 0;
00908 
00909                 // Only Both high and low
00910                 while (--shift) {
00911 
00912                         mod <<= 1;
00913                         mod |= (l>>shift) & 1;
00914 
00915                         // Can divide
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                 // Only Low DWORD
00926                 mod <<= 1;
00927                 mod |= l & 1;
00928 
00929                 // Can divide
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                 // If there isn't a high dword, we only need to work on the low dword
00947                 if (!high) {
00948                         low %= div;
00949                         return *this;
00950                 }
00951 
00952                 // Remainder of last division
00953                 uint32 mod = high;
00954 
00955                 // Low shift
00956                 uint32 shift = 32;
00957 
00958                 while (1) {
00959 
00960                         // Can divide
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 // AdjustTimings
00995 //
00996 // It converts the midi's to use 120 Hz timing, and also calcs the duration of
00997 // the notes. It also strips the tempo events, and adds it's own
00998 //
00999 // This is used by Midi's ONLY! It will do nothing with XMidiFile
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         // Virtual playing
01011         XMidiNoteStack notes;
01012 
01013         for (XMidiEvent *event = list; event; event = event->next) {
01014 
01015                         // Note 64 bit int is required because multiplication by tempo can
01016                         // require 52 bits in some circumstances
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                         // Note on and note off handling
01030                         if (event->status <= 0x9F) {
01031 
01032                                 // Add if it's a note on and remove if it's a note off
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         //std::cout << "Max Polyphony: " << notes.GetMaxPolyphony() << std::endl;
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 // Converts Events
01062 //
01063 // Source is at the first data byte
01064 // size 1 is single data byte (ConvertEvent Only)
01065 // size 2 is dual data byte
01066 // size 3 is XMI Note on (ConvertNote only)
01067 // Returns bytes converted
01068 //
01069 // ConvertNote is used for Note On's and Note offs
01070 // ConvertSystemMessage is used for SysEx events and Meta events
01071 // ConvertEvent is used for everything else
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         // Bank changes are handled here
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