diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Input/in_midi/mids.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Input/in_midi/mids.cpp')
-rw-r--r-- | Src/Plugins/Input/in_midi/mids.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_midi/mids.cpp b/Src/Plugins/Input/in_midi/mids.cpp new file mode 100644 index 00000000..456da30f --- /dev/null +++ b/Src/Plugins/Input/in_midi/mids.cpp @@ -0,0 +1,96 @@ +#include "main.h" +#include "cvt.h" + +bool is_mids(const BYTE* buf,size_t s) +{ + return s>0x20 && *(DWORD*)buf==_rv('RIFF') && *(DWORD*)(buf+8)==_rv('MIDS') && *(DWORD*)(buf+12)==_rv('fmt '); +} + +typedef struct +{ + DWORD dwTimeFormat; + DWORD cbMaxBuffer; + DWORD dwFlags; +} MIDSFMT; + + +#define WRITE(X,Y) out.write(X,Y) + +#define WRITE_DELTA(X) gb_write_delta(out,X) + +#define D_WRITE {WRITE_DELTA(ct-tw);tw=ct;} + +bool load_mids(MIDI_file* mf,const BYTE* buf,size_t sz) +{ + if (sz<*(long*)(buf+4)+8) return 0; + MIDSFMT* fmt=(MIDSFMT*)(buf+0x14); + DWORD ofs; + ofs=*(DWORD*)(buf+0x10)+0x14; + if (*(DWORD*)(buf+ofs)!=_rv('data')) return 0; + //ofs+=8+*(DWORD*)(buf+ofs+4); + ofs+=8; + DWORD ss=*(DWORD*)(buf+ofs-4); + DWORD nc=*(DWORD*)(buf+ofs); + DWORD* ptr=(DWORD*)(buf+ofs); + grow_buf out; + ss>>=2; + DWORD mhdr[2]; + mhdr[0]=_rv('MThd'); + mhdr[1]=_rv(6); + WRITE(mhdr,8); + WORD w=0; + WRITE(&w,2); + w=0x100; + WRITE(&w,2); + w=rev16((WORD)fmt->dwTimeFormat); + WRITE(&w,2); + mhdr[0]=_rv('MTrk'); + WRITE(mhdr,8); + DWORD tw=0,ct=0; + DWORD cc=0; + DWORD cs; + DWORD pos=1; + while(cc<nc) + { + cs = (ptr[pos+1]>>2)+pos; + if (cs>ss) break; + pos+=2; + while(pos<cs) + { + ct+=ptr[pos]; + pos+=2; + DWORD e=ptr[pos]; + if (e&MEVT_F_LONG) + { + pos+=e&0xFFFFFF; + } + else + { + if (e>>24==MEVT_TEMPO) + { + D_WRITE; + BYTE tmp[6]={0xFF,0x51,0x03,(BYTE)((e>>16)&0xFF),(BYTE)((e>>8)&0xFF),(BYTE)(e&0xFF)}; + WRITE(tmp,6); + } + else if (!(e>>24)) + { + BYTE c=(BYTE)(e&0xF0); + if (c!=0xF0) + { + D_WRITE; + DWORD l=(c==0xC0 || c==0xD0) ? 2 : 3; + WRITE(&e,l); + } + } + pos++; + } + } + } + WRITE("\x00\xFF\x2F",4); + + out.write_dword_ptr(rev32(out.get_size()-(8+6+8)),8+6+4); + + mf->size = out.get_size(); + mf->data = (BYTE*)out.finish(); + return !!mf->data; +}
\ No newline at end of file |