#include "main.h" #include "cvt.h" #pragma pack(push) #pragma pack(1) typedef struct { DWORD mthd,hdsize; MIDIHEADER mhd; } FILEHEADER; typedef struct { DWORD mtrk,size; } TRACKHEADER; #pragma pack(pop) struct XMI_cvt { public: grow_buf out; bool _end; DWORD tr_sz; DWORD cur_time,wr_time; // DWORD loopstart; bool hasevents; void q_add(BYTE ch,BYTE note,DWORD tm); void WriteDelta(DWORD _d); void DoQueue(); DWORD ProcessNote(const BYTE* e); DWORD ProcessDelta(const BYTE* d); DWORD WriteEvent(const BYTE* e); bool run(MIDI_file* mf,const BYTE*,DWORD); #pragma pack(push) #pragma pack(1) #define Q_MAX 512 struct { DWORD time; BYTE note; BYTE channel; } ch_q[Q_MAX]; #pragma pack(pop) }; #define WriteBuf(A,B) out.write(A,B) #define WriteBufB(A) out.write_byte(A) #define WriteBufD(A) out.write_dword(A) //WORD _fastcall rev16(WORD); DWORD _fastcall rev32(DWORD); #define FixHeader(H) {(H).fmt=rev16((H).fmt);(H).trax=rev16((H).trax);(H).dtx=rev16((H).dtx);} #define MThd 'dhTM' #define MTrk 'krTM' #define EVNT 'TNVE' void XMI_cvt::q_add(BYTE ch,BYTE note,DWORD tm) { UINT n,_n=-1; for(n=0;ntm) */ch_q[n].time=tm; // q_notes++; return; } else if (ch_q[n].time==-1) _n=n; } if (_n!=-1) { ch_q[_n].channel=ch; ch_q[_n].time=tm; ch_q[_n].note=note; // q_notes++; } } void XMI_cvt::WriteDelta(DWORD _d) { DWORD d=_d-wr_time; wr_time=_d; int st=out.get_size(); gb_write_delta(out,d); tr_sz+=out.get_size()-st; } DWORD _inline ReadDelta1(const BYTE* d,DWORD* _l) { DWORD r=d[0],l=0; while(!(d[l+1]&0x80)) { r+=d[++l]; } *_l=l+1; return r; } void XMI_cvt::DoQueue() { while(1) { DWORD _i=-1; DWORD _mt=-1; UINT i; for(i=0;isz+1) goto fail; ptr+=4; _end=0; { UINT n; for(n=0;n=sz) goto _e; if (*(DWORD*)(buf+ptr)==_rv('FORM') && *(DWORD*)(buf+ptr+8)==_rv('XMID')) { ptr+=12; _te: if (ptr&1) ptr++; if (*(DWORD*)(buf+ptr)==_rv('EVNT')) goto _track; else if (*(DWORD*)(buf+ptr)==_rv('TIMB')) { ptr+=8+rev32(*(DWORD*)(buf+ptr+4)); if (ptr1) w=0x200; out.write_ptr(&w,2,8); } mf->size = out.get_size(); mf->data = (BYTE*)out.finish(); if (!mf->data) return 0; // if (loopstart>0x10) mf->loopstart=loopstart; #ifdef MF_USE_DMCRAP if (sz>ptr+0x20 && *(DWORD*)(buf+ptr)==_rv('FORM') && *(DWORD*)(buf+ptr+8)==_rv('XDLS')) { DWORD rs=rev32(*(DWORD*)(buf+_sz+4)); if (rs+12+_sz>sz) goto _ret; if (*(DWORD*)(buf+ptr+0x14)!=_rv('DLS ')) goto _ret; mf->DLSsize=rs; mf->pDLSdata=(BYTE*)malloc(rs); memcpy(mf->pDLSdata,buf+_sz+12,rs); } #endif _ret: return 1; fail: return 0; } bool load_xmi(MIDI_file * mf,const BYTE* buf,size_t sz) { XMI_cvt c; return c.run(mf,buf,sz); }