header_wav.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #include "header_wav.h"
  2. #include <windows.h>
  3. #include "header_avi.h"
  4. #include <mmsystem.h>
  5. #include <bfc/platform/types.h>
  6. #pragma pack(1)
  7. struct WAVEfmt
  8. {
  9. unsigned __int16 encoding;
  10. unsigned __int16 numChannels;
  11. unsigned __int32 sampleRate;
  12. unsigned __int32 avgBytesPerSec;
  13. unsigned __int16 blockAlign;
  14. unsigned __int16 bitsPerSample;
  15. };
  16. #pragma pack()
  17. #ifndef mmioFOURCC
  18. #define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
  19. ( (long)(unsigned char)(ch0) | ( (long)(unsigned char)(ch1) << 8 ) | \
  20. ( (long)(unsigned char)(ch2) << 16 ) | ( (long)(unsigned char)(ch3) << 24 ) )
  21. #endif /* mmioFOURCC */
  22. HeaderWav::HeaderWav(bool bAllowHttpConnection /* = false */)
  23. : bAllowHttp(bAllowHttpConnection), fh(INVALID_HANDLE_VALUE)
  24. {}
  25. int HeaderWav::getInfos(const wchar_t *filename, bool checkMetadata)
  26. {
  27. unsigned __int32 bytesPerSecond=0;
  28. {
  29. fh = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  30. if (fh == INVALID_HANDLE_VALUE) return 0;
  31. }
  32. int riffid = read_dword();
  33. if (riffid != mmioFOURCC('R', 'I', 'F', 'F'))
  34. {
  35. myfclose();
  36. return 0;
  37. }
  38. unsigned __int32 filesize = read_dword();
  39. int aviid = read_dword();
  40. if (aviid != mmioFOURCC('W', 'A', 'V', 'E'))
  41. {
  42. myfclose();
  43. return 0;
  44. }
  45. while (1)
  46. {
  47. int id = read_dword();
  48. if (!id) break;
  49. if (id == mmioFOURCC('L', 'I', 'S', 'T'))
  50. {
  51. unsigned __int32 len = read_dword() - 4;
  52. id = read_dword();
  53. switch (id)
  54. {
  55. case mmioFOURCC('I', 'N', 'F', 'O'):
  56. {
  57. if (!checkMetadata)
  58. {
  59. if (len)
  60. myfseek(len, FILE_CURRENT);
  61. break;
  62. }
  63. while (len)
  64. {
  65. int infoId = read_dword();
  66. unsigned __int32 infoSize = read_dword();
  67. unsigned __int32 chunksize = (infoSize + 1) & (~1);
  68. len -= (chunksize + 8);
  69. switch (infoId)
  70. {
  71. // TODO: IYER for year, but is it string or number?
  72. // TODO: ITRK for track, but is it string or number?
  73. case mmioFOURCC('I', 'C', 'O', 'M'):
  74. {
  75. composer = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
  76. composer[infoSize] = 0;
  77. myfread(composer, infoSize, 1);
  78. chunksize -= infoSize;
  79. }
  80. break;
  81. case mmioFOURCC('I', 'P', 'U', 'B'):
  82. {
  83. publisher = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
  84. publisher[infoSize] = 0;
  85. myfread(publisher, infoSize, 1);
  86. chunksize -= infoSize;
  87. }
  88. break;
  89. case mmioFOURCC('I', 'A', 'L', 'B'):
  90. {
  91. album = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
  92. album[infoSize] = 0;
  93. myfread(album, infoSize, 1);
  94. chunksize -= infoSize;
  95. }
  96. break;
  97. case mmioFOURCC('I', 'G', 'N', 'R'):
  98. {
  99. genre = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
  100. genre[infoSize] = 0;
  101. myfread(genre, infoSize, 1);
  102. chunksize -= infoSize;
  103. }
  104. break;
  105. case mmioFOURCC('I', 'C', 'M', 'T'):
  106. {
  107. comment = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
  108. comment[infoSize] = 0;
  109. myfread(comment, infoSize, 1);
  110. chunksize -= infoSize;
  111. }
  112. break;
  113. case mmioFOURCC('I', 'A', 'R', 'T'):
  114. {
  115. artist = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
  116. artist[infoSize] = 0;
  117. myfread(artist, infoSize, 1);
  118. chunksize -= infoSize;
  119. }
  120. break;
  121. case mmioFOURCC('I', 'N', 'A', 'M'):
  122. {
  123. title = (wchar_t*)calloc(infoSize + 1, sizeof(wchar_t));
  124. title[infoSize] = 0;
  125. myfread(title, infoSize, 1);
  126. chunksize -= infoSize;
  127. }
  128. break;
  129. }
  130. if (chunksize > 0) myfseek(chunksize, FILE_CURRENT);
  131. }
  132. }
  133. break;
  134. }
  135. continue;
  136. }
  137. unsigned __int32 size2 = read_dword();
  138. unsigned __int32 chunksize = (size2 + 1) & (~1);
  139. switch (id)
  140. {
  141. case mmioFOURCC('f', 'm', 't', ' '):
  142. {
  143. WAVEfmt fmt;
  144. size_t l = min(size2, sizeof(fmt));
  145. myfread(&fmt, l, 1);
  146. chunksize -= (unsigned __int32)l;
  147. has_audio=true;
  148. audio_nch=fmt.numChannels;
  149. audio_bps=fmt.bitsPerSample;
  150. audio_srate=fmt.sampleRate;
  151. bytesPerSecond=fmt.avgBytesPerSec;
  152. }
  153. break;
  154. case mmioFOURCC('d','a','t','a'):
  155. {
  156. if (bytesPerSecond)
  157. length = MulDiv(1000, chunksize, bytesPerSecond);
  158. }
  159. break;
  160. }
  161. if (chunksize > 0) myfseek(chunksize, FILE_CURRENT);
  162. }
  163. myfclose();
  164. return 1;
  165. }
  166. size_t HeaderWav::myfread(void *buffer, size_t size, size_t count)
  167. {
  168. DWORD bytesRead = 0;
  169. ReadFile(fh, buffer,(DWORD)(size*count), &bytesRead, NULL);
  170. return bytesRead;
  171. }
  172. int HeaderWav::myfclose()
  173. {
  174. return CloseHandle(fh);
  175. }
  176. // Note; Only supports SEEK_CUR for http (which is what is used)
  177. int HeaderWav::myfseek(long offset, DWORD origin)
  178. {
  179. return SetFilePointer(fh, offset, 0, origin);
  180. }
  181. /* TODO:
  182. __int64 myFileSeek (HANDLE hf, __int64 distance, DWORD MoveMethod)
  183. {
  184. LARGE_INTEGER li;
  185. li.QuadPart = distance;
  186. li.LowPart = SetFilePointer (hf, li.LowPart, &li.HighPart, MoveMethod);
  187. if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
  188. {
  189. li.QuadPart = -1;
  190. }
  191. return li.QuadPart;
  192. }
  193. */