mus.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include "main.h"
  2. #include "cvt.h"
  3. bool is_mus(const BYTE* buf,size_t s)
  4. {
  5. if (s>0x20 && *(DWORD*)buf == '\x1ASUM')
  6. {
  7. int ofs = ((WORD*)buf)[3];
  8. int n_ins = ((WORD*)buf)[6];
  9. if (ofs>=16+(n_ins<<1) && ofs<16+(n_ins<<2) && ofs<s)
  10. {
  11. return 1;
  12. }
  13. }
  14. return 0;
  15. }
  16. static BYTE tempodat[] = {0x00,0xFF,0x51,0x03,0x09,0xA3,0x1A};
  17. static BYTE controllers[15] = {0,0,1,7,10,11,91,93,64,67,120,123,126,127,121};
  18. #define abort _abort_
  19. struct MUS_cvt
  20. {
  21. public:
  22. bool abort;
  23. DWORD ct;
  24. DWORD lt;
  25. grow_buf out;
  26. void AddEvent(DWORD ev,int l);
  27. bool run(MIDI_file* mf,const BYTE* ptr,DWORD sz);
  28. };
  29. void MUS_cvt::AddEvent(DWORD ev,int l)
  30. {
  31. DWORD dt = ct - lt;
  32. int tl=3;
  33. gb_write_delta(out,dt);
  34. lt = ct;
  35. BYTE ec=(BYTE)(ev&0xF0);
  36. out.write(&ev,l);
  37. }
  38. bool MUS_cvt::run(MIDI_file* mf,const BYTE* ptr,DWORD sz)
  39. {
  40. #pragma pack(push)
  41. #pragma pack(1)
  42. struct
  43. {
  44. char id[4];
  45. WORD len;
  46. WORD ofs;
  47. WORD ch1,ch2;
  48. WORD n_ins;
  49. WORD dummy;
  50. } hdr;
  51. #pragma pack(pop)
  52. DWORD _pt=0;
  53. memcpy(&hdr,ptr,sizeof(hdr));
  54. const BYTE* score = ptr+sizeof(hdr)+2*hdr.n_ins;
  55. long x;
  56. static BYTE _hd_[]={'M','T','h','d',0,0,0,6, 0,0,0,1,0,0x59,'M','T','r','k'};
  57. out.write(_hd_,sizeof(_hd_));
  58. DWORD ts_ofs=out.get_size();
  59. out.write_dword(0);
  60. lt=0;
  61. abort = 0;
  62. ct = 0;
  63. out.write(tempodat,sizeof(tempodat));
  64. x=0;
  65. bool t;
  66. BYTE ch;
  67. BYTE vols[16];
  68. ZeroMemory(vols,sizeof(vols));
  69. union
  70. {
  71. BYTE b[4];
  72. DWORD dw;
  73. } ev;
  74. while(x<hdr.len && score[x]!=0x60)
  75. {
  76. ev.dw = 0;
  77. t=(score[x]&0x80)?1:0;
  78. ch = score[x]&0xF;
  79. if (ch == 0xF) ch = 9;//hdr.ch1+1;
  80. else if (ch>=9) ch++;
  81. switch(score[x]&0x70)
  82. {
  83. case 0: //release note
  84. ev.b[0]=0x80|ch;
  85. ev.b[1]=score[x+1];
  86. ev.b[2]=0;//vols[ch];
  87. AddEvent(ev.dw,3);
  88. x+=2;
  89. break;
  90. case 0x10: //play note
  91. ev.b[0]=0x90|ch;
  92. ev.b[1]=score[x+1]&0x7F;
  93. if (score[x+1]&0x80)
  94. {
  95. vols[ch]=score[x+2];
  96. x+=3;
  97. }
  98. else
  99. {
  100. x+=2;
  101. }
  102. ev.b[2]=vols[ch];
  103. AddEvent(ev.dw,3);
  104. break;
  105. case 0x20: //pitch wheel
  106. ev.b[0]=0xE0|ch;
  107. ev.b[1]=0;
  108. ev.b[2]=score[x+1]>>1;
  109. AddEvent(ev.dw,3);
  110. x+=2;
  111. break;
  112. case 0x30: //system event
  113. if (score[x+1]>=10 && score[x+1]<=14)
  114. {
  115. ev.b[0]=0xB0|ch;
  116. ev.b[1]=controllers[score[x+1]];
  117. ev.b[2]=1;
  118. AddEvent(ev.dw,3);
  119. x+=2;
  120. break;
  121. }
  122. else return 0;
  123. case 0x40: //change controller
  124. if (score[x+1])
  125. {
  126. if (score[x+1]<10)
  127. {
  128. ev.b[0]=0xB0|ch;
  129. ev.b[1]=controllers[score[x+1]];
  130. ev.b[2]=score[x+2];
  131. AddEvent(ev.dw,3);
  132. x+=3;
  133. }
  134. else return 0;
  135. }
  136. else
  137. {
  138. ev.b[0]=0xC0|ch;
  139. ev.b[1]=score[x+2];
  140. AddEvent(ev.dw,2);
  141. x+=3;
  142. };
  143. break;
  144. case 0x50:
  145. case 0x70:
  146. case 0x60:
  147. return 0;
  148. }
  149. if (abort) return 0;
  150. if (t)
  151. {
  152. DWORD dt=0;
  153. do
  154. {
  155. dt = (dt<<7) + (score[x]&0x7F);
  156. } while(score[x++]&0x80);
  157. ct+=dt;
  158. }
  159. }
  160. out.write_dword(0x002FFF00);
  161. out.write_dword_ptr(rev32(out.get_size()-(ts_ofs+4)),ts_ofs);
  162. mf->size = out.get_size();
  163. mf->data = (BYTE*)out.finish();
  164. return !!mf->data;
  165. }
  166. bool load_mus(MIDI_file* mf,const BYTE* ptr,size_t sz)
  167. {
  168. MUS_cvt c;
  169. return c.run(mf,ptr,sz);
  170. }