mids.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include "main.h"
  2. #include "cvt.h"
  3. bool is_mids(const BYTE* buf,size_t s)
  4. {
  5. return s>0x20 && *(DWORD*)buf==_rv('RIFF') && *(DWORD*)(buf+8)==_rv('MIDS') && *(DWORD*)(buf+12)==_rv('fmt ');
  6. }
  7. typedef struct
  8. {
  9. DWORD dwTimeFormat;
  10. DWORD cbMaxBuffer;
  11. DWORD dwFlags;
  12. } MIDSFMT;
  13. #define WRITE(X,Y) out.write(X,Y)
  14. #define WRITE_DELTA(X) gb_write_delta(out,X)
  15. #define D_WRITE {WRITE_DELTA(ct-tw);tw=ct;}
  16. bool load_mids(MIDI_file* mf,const BYTE* buf,size_t sz)
  17. {
  18. if (sz<*(long*)(buf+4)+8) return 0;
  19. MIDSFMT* fmt=(MIDSFMT*)(buf+0x14);
  20. DWORD ofs;
  21. ofs=*(DWORD*)(buf+0x10)+0x14;
  22. if (*(DWORD*)(buf+ofs)!=_rv('data')) return 0;
  23. //ofs+=8+*(DWORD*)(buf+ofs+4);
  24. ofs+=8;
  25. DWORD ss=*(DWORD*)(buf+ofs-4);
  26. DWORD nc=*(DWORD*)(buf+ofs);
  27. DWORD* ptr=(DWORD*)(buf+ofs);
  28. grow_buf out;
  29. ss>>=2;
  30. DWORD mhdr[2];
  31. mhdr[0]=_rv('MThd');
  32. mhdr[1]=_rv(6);
  33. WRITE(mhdr,8);
  34. WORD w=0;
  35. WRITE(&w,2);
  36. w=0x100;
  37. WRITE(&w,2);
  38. w=rev16((WORD)fmt->dwTimeFormat);
  39. WRITE(&w,2);
  40. mhdr[0]=_rv('MTrk');
  41. WRITE(mhdr,8);
  42. DWORD tw=0,ct=0;
  43. DWORD cc=0;
  44. DWORD cs;
  45. DWORD pos=1;
  46. while(cc<nc)
  47. {
  48. cs = (ptr[pos+1]>>2)+pos;
  49. if (cs>ss) break;
  50. pos+=2;
  51. while(pos<cs)
  52. {
  53. ct+=ptr[pos];
  54. pos+=2;
  55. DWORD e=ptr[pos];
  56. if (e&MEVT_F_LONG)
  57. {
  58. pos+=e&0xFFFFFF;
  59. }
  60. else
  61. {
  62. if (e>>24==MEVT_TEMPO)
  63. {
  64. D_WRITE;
  65. BYTE tmp[6]={0xFF,0x51,0x03,(BYTE)((e>>16)&0xFF),(BYTE)((e>>8)&0xFF),(BYTE)(e&0xFF)};
  66. WRITE(tmp,6);
  67. }
  68. else if (!(e>>24))
  69. {
  70. BYTE c=(BYTE)(e&0xF0);
  71. if (c!=0xF0)
  72. {
  73. D_WRITE;
  74. DWORD l=(c==0xC0 || c==0xD0) ? 2 : 3;
  75. WRITE(&e,l);
  76. }
  77. }
  78. pos++;
  79. }
  80. }
  81. }
  82. WRITE("\x00\xFF\x2F",4);
  83. out.write_dword_ptr(rev32(out.get_size()-(8+6+8)),8+6+4);
  84. mf->size = out.get_size();
  85. mf->data = (BYTE*)out.finish();
  86. return !!mf->data;
  87. }