From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/Plugins/Input/in_midi/xmi.cpp | 310 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 Src/Plugins/Input/in_midi/xmi.cpp (limited to 'Src/Plugins/Input/in_midi/xmi.cpp') diff --git a/Src/Plugins/Input/in_midi/xmi.cpp b/Src/Plugins/Input/in_midi/xmi.cpp new file mode 100644 index 00000000..6f18ec87 --- /dev/null +++ b/Src/Plugins/Input/in_midi/xmi.cpp @@ -0,0 +1,310 @@ +#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); +} \ No newline at end of file -- cgit