1
0

hmp.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include "main.h"
  2. #include "cvt.h"
  3. #include <intsafe.h>
  4. #define _MThd 'dhTM'
  5. #define _MTrk 'krTM'
  6. static DWORD ProcessTrack(const BYTE* track,grow_buf & out,int size)
  7. {
  8. UINT s_sz=out.get_size();
  9. const BYTE *pt = track;
  10. BYTE lc1 = 0,lastcom = 0;
  11. DWORD t=0,d;
  12. bool run = 0;
  13. int n1,n2;
  14. while(track < pt + size)
  15. {
  16. if (track[0]&0x80)
  17. {
  18. BYTE b=track[0]&0x7F;
  19. out.write_byte(b);
  20. t+=b;
  21. }
  22. else
  23. {
  24. d = (track[0])&0x7F;
  25. n1 = 0;
  26. while((track[n1]&0x80)==0)
  27. {
  28. n1++;
  29. d+=(track[n1]&0x7F)<<(n1*7);
  30. }
  31. t+=d;
  32. n1 = 1;
  33. while((track[n1]&0x80)==0)
  34. {
  35. n1++;
  36. if (n1==4) return 0;
  37. }
  38. for(n2=0;n2<=n1;n2++)
  39. {
  40. BYTE b=track[n1-n2]&0x7F;
  41. if (n2!=n1) b|=0x80;
  42. out.write_byte(b);
  43. }
  44. track+=n1;
  45. }
  46. track++;
  47. if (*track == 0xFF)//meta
  48. {
  49. unsigned int _d;
  50. UINT s=DecodeDelta(track+2,&_d);
  51. UINT result;
  52. if (UIntAdd(2, s, &result) || UIntAdd(result, _d, &result) == S_OK || !out.write(track,result))
  53. return 0;
  54. if (track[1]==0x2F) break;
  55. }
  56. else
  57. {
  58. lc1=track[0];
  59. if ((lc1&0x80) == 0) return 0;
  60. switch(lc1&0xF0)
  61. {
  62. case 0x80:
  63. case 0x90:
  64. case 0xA0:
  65. case 0xB0:
  66. case 0xE0:
  67. if (lc1!=lastcom)
  68. {
  69. out.write_byte(lc1);
  70. }
  71. out.write(track+1,2);
  72. track+=3;
  73. break;
  74. case 0xC0:
  75. case 0xD0:
  76. if (lc1!=lastcom)
  77. {
  78. out.write_byte(lc1);
  79. }
  80. out.write_byte(track[1]);
  81. track+=2;
  82. break;
  83. default:
  84. return 0;
  85. }
  86. lastcom=lc1;
  87. }
  88. }
  89. return out.get_size()-s_sz;
  90. }
  91. #define FixHeader(H) {(H).fmt=rev16((H).fmt);(H).trax=rev16((H).trax);(H).dtx=rev16((H).dtx);}
  92. BYTE hmp_track0[19]={'M','T','r','k',0,0,0,11,0,0xFF,0x51,0x03,0x18,0x80,0x00,0,0xFF,0x2F,0};
  93. bool load_hmp(MIDI_file* mf,const BYTE* buf, size_t br)
  94. {
  95. MIDIHEADER mhd = {1,0,0xC0};
  96. const BYTE * max = buf+br;
  97. const BYTE* ptr = buf;
  98. BOOL funky=0;
  99. if (!memcmp(buf,"HMIMIDIR",8)) funky=1;
  100. grow_buf dst;
  101. DWORD n1,n2;
  102. dst.write_dword(_rv('MThd'));
  103. dst.write_dword(_rv(6));
  104. dst.write(0,sizeof(mhd));
  105. ptr = buf+(funky ? 0x1a: 0x30);
  106. mhd.trax = *ptr;
  107. if (funky) mhd.dtx=rev16(*(WORD*)(buf+0x4c))/6;
  108. dst.write(hmp_track0,sizeof(hmp_track0));
  109. while(*(WORD*)ptr != 0x2FFF && ptr < max - 4-7) ptr++;
  110. ptr+=funky ? 5 : 7;
  111. if (ptr == max-4) return 0;
  112. UINT n;
  113. for(n=1;n<mhd.trax;n++)
  114. {
  115. n1 = funky ? *(WORD*)ptr : *(DWORD*)ptr - 12;
  116. if (ptr + n1 > max)
  117. {
  118. mhd.trax=n;
  119. break;
  120. }
  121. dst.write_dword(_rv('MTrk'));
  122. if (!funky) ptr += 8;
  123. UINT ts_ofs=dst.get_size();
  124. dst.write_dword(0);
  125. if (!(n2=ProcessTrack(funky ? ptr+4 : ptr,dst,n1))) return 0;
  126. dst.write_dword_ptr(rev32(n2),ts_ofs);
  127. if (funky) ptr+=n1;
  128. else ptr += n1 + 4;
  129. }
  130. FixHeader(mhd);
  131. dst.write_ptr(&mhd,sizeof(mhd),8);
  132. mf->size = dst.get_size();
  133. mf->data = (BYTE*)dst.finish();
  134. return !!mf->data;
  135. }