wavfile.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. #include "precompile.h"
  2. #ifdef _WIN32
  3. /*this header is used by windows multi-media*/
  4. #include <mmreg.h>
  5. #endif
  6. #include "wavfile.h"
  7. #include "memutil.h"
  8. static const unsigned char pcm8toalaw[] = {
  9. 42,
  10. 42,42,42,43,43,43,43,40,40,40,40,41,41,41,41,46,
  11. 46,46,46,47,47,47,47,44,44,44,44,45,45,45,45,34,
  12. 34,34,34,35,35,35,35,32,32,32,32,33,33,33,33,38,
  13. 38,38,38,39,39,39,39,36,36,36,36,37,37,37,37,58,
  14. 58,59,59,56,56,57,57,62,62,63,63,60,60,61,61,50,
  15. 50,51,51,48,48,49,49,54,54,55,55,52,52,53,53,10,
  16. 11,8,9,14,15,12,13,2,3,0,1,6,7,4,5,26,
  17. 24,30,28,18,16,22,20,106,110,98,102,122,114,74,90,213,
  18. 197,245,253,229,225,237,233,149,151,145,147,157,159,153,155,133,
  19. 132,135,134,129,128,131,130,141,140,143,142,137,136,139,138,181,
  20. 181,180,180,183,183,182,182,177,177,176,176,179,179,178,178,189,
  21. 189,188,188,191,191,190,190,185,185,184,184,187,187,186,186,165,
  22. 165,165,165,164,164,164,164,167,167,167,167,166,166,166,166,161,
  23. 161,161,161,160,160,160,160,163,163,163,163,162,162,162,162,173,
  24. 173,173,173,172,172,172,172,175,175,175,175,174,174,174,174,169,
  25. 169,169,169,168,168,168,168,171,171,171,171,170,170,170,170,};
  26. static const unsigned char pcm8tomulaw[] = {
  27. 0,
  28. 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,
  29. 4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,
  30. 8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,
  31. 12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,
  32. 16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,
  33. 24,24,25,25,26,26,27,27,28,28,29,29,30,30,31,31,
  34. 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
  35. 48,50,52,54,56,58,60,62,65,69,73,77,83,91,103,255,
  36. 231,219,211,205,201,197,193,190,188,186,184,182,180,178,176,175,
  37. 174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,159,
  38. 159,158,158,157,157,156,156,155,155,154,154,153,153,152,152,151,
  39. 151,150,150,149,149,148,148,147,147,146,146,145,145,144,144,143,
  40. 143,143,143,142,142,142,142,141,141,141,141,140,140,140,140,139,
  41. 139,139,139,138,138,138,138,137,137,137,137,136,136,136,136,135,
  42. 135,135,135,134,134,134,134,133,133,133,133,132,132,132,132,131,
  43. 131,131,131,130,130,130,130,129,129,129,129,128,128,128,128,};
  44. static const unsigned char alawtopcm8[] = {
  45. 106,
  46. 107,104,105,110,111,108,109,98,99,96,97,102,103,100,101,117,
  47. 117,116,116,119,119,118,118,113,113,112,112,115,115,114,114,42,
  48. 46,34,38,58,62,50,54,10,14,2,6,26,30,18,22,85,
  49. 87,81,83,93,95,89,91,69,71,65,67,77,79,73,75,126,
  50. 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,127,
  51. 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,122,
  52. 122,122,122,123,123,123,123,120,120,120,120,121,121,121,121,125,
  53. 125,125,125,125,125,125,125,124,124,124,124,124,124,124,124,149,
  54. 148,151,150,145,144,147,146,157,156,159,158,153,152,155,154,138,
  55. 138,139,139,136,136,137,137,142,142,143,143,140,140,141,141,214,
  56. 210,222,218,198,194,206,202,246,242,254,250,230,226,238,234,171,
  57. 169,175,173,163,161,167,165,187,185,191,189,179,177,183,181,129,
  58. 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,128,
  59. 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,133,
  60. 133,133,133,132,132,132,132,135,135,135,135,134,134,134,134,130,
  61. 130,130,130,130,130,130,130,131,131,131,131,131,131,131,131,};
  62. static const unsigned char ulawtopcm8[] = {
  63. 2,6,10,14,18,22,26,30,34,38,42,46,50,
  64. 54,58,62,65,67,69,71,73,75,77,79,81,
  65. 83,85,87,89,91,93,95,97,98,99,100,101,
  66. 102,103,104,105,106,107,108,109,110,111,112,112,
  67. 113,113,114,114,115,115,116,116,117,117,118,118,
  68. 119,119,120,120,120,121,121,121,121,122,122,122,
  69. 122,123,123,123,123,124,124,124,124,124,124,125,
  70. 125,125,125,125,125,125,125,126,126,126,126,126,
  71. 126,126,126,126,126,126,126,127,127,127,127,127,
  72. 127,127,127,127,127,127,127,127,127,127,127,127,
  73. 127,127,127,127,127,127,128,253,249,245,241,237,
  74. 233,229,225,221,217,213,209,205,201,197,193,190,
  75. 188,186,184,182,180,178,176,174,172,170,168,166,
  76. 164,162,160,158,157,156,155,154,153,152,151,150,
  77. 149,148,147,146,145,144,143,143,142,142,141,141,
  78. 140,140,139,139,138,138,137,137,136,136,135,135,
  79. 135,134,134,134,134,133,133,133,133,132,132,132,
  80. 132,131,131,131,131,131,131,130,130,130,130,130,
  81. 130,130,130,129,129,129,129,129,129,129,129,129,
  82. 129,129,129,128,128,128,128,128,128,128,128,128,
  83. 128,128,128,128,128,128,128,128,128,128,128,128,
  84. 128,128,128,};
  85. /* Copied from the CCITT G.711 specification */
  86. static const uint8_t ulaw_to_alaw_table[256] =
  87. {
  88. 42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37,
  89. 58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53,
  90. 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 26,
  91. 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, 106,
  92. 104, 105, 110, 111, 108, 109, 98, 99, 96, 97, 102, 103, 100, 101, 122, 120,
  93. 126, 127, 124, 125, 114, 115, 112, 113, 118, 119, 116, 117, 75, 73, 79, 77,
  94. 66, 67, 64, 65, 70, 71, 68, 69, 90, 91, 88, 89, 94, 95, 92, 93,
  95. 82, 82, 83, 83, 80, 80, 81, 81, 86, 86, 87, 87, 84, 84, 85, 85,
  96. 170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
  97. 186, 187, 184, 185, 190, 191, 188, 189, 178, 179, 176, 177, 182, 183, 180, 181,
  98. 138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154,
  99. 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234,
  100. 232, 233, 238, 239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248,
  101. 254, 255, 252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205,
  102. 194, 195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221,
  103. 210, 210, 211, 211, 208, 208, 209, 209, 214, 214, 215, 215, 212, 212, 213, 213
  104. };
  105. /* These transcoding tables are copied from the CCITT G.711 specification. To achieve
  106. optimal results, do not change them. */
  107. static const uint8_t alaw_to_ulaw_table[256] =
  108. {
  109. 42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37,
  110. 57, 58, 55, 56, 61, 62, 59, 60, 49, 50, 47, 48, 53, 54, 51, 52,
  111. 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 5,
  112. 26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21,
  113. 98, 99, 96, 97, 102, 103, 100, 101, 93, 93, 92, 92, 95, 95, 94, 94,
  114. 116, 118, 112, 114, 124, 126, 120, 122, 106, 107, 104, 105, 110, 111, 108, 109,
  115. 72, 73, 70, 71, 76, 77, 74, 75, 64, 65, 63, 63, 68, 69, 66, 67,
  116. 86, 87, 84, 85, 90, 91, 88, 89, 79, 79, 78, 78, 82, 83, 80, 81,
  117. 170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
  118. 185, 186, 183, 184, 189, 190, 187, 188, 177, 178, 175, 176, 181, 182, 179, 180,
  119. 138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133,
  120. 154, 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149,
  121. 226, 227, 224, 225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222,
  122. 244, 246, 240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237,
  123. 200, 201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195,
  124. 214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208, 209
  125. };
  126. static __inline uint8_t alaw_to_ulaw(uint8_t alaw)
  127. {
  128. return alaw_to_ulaw_table[alaw];
  129. }
  130. /*- End of function --------------------------------------------------------*/
  131. static __inline uint8_t ulaw_to_alaw(uint8_t ulaw)
  132. {
  133. return ulaw_to_alaw_table[ulaw];
  134. }
  135. /*- End of function --------------------------------------------------------*/
  136. static __inline int top_bit(unsigned int bits)
  137. {
  138. #if defined(SPANDSP_USE_86_ASM)
  139. int res;
  140. __asm__ (" xorl %[res],%[res];\n"
  141. " decl %[res];\n"
  142. " bsrl %[bits],%[res]\n"
  143. : [res] "=&r" (res)
  144. : [bits] "rm" (bits));
  145. return res;
  146. #elif defined(__ppc__) || defined(__powerpc__)
  147. int res;
  148. __asm__ ("cntlzw %[res],%[bits];\n"
  149. : [res] "=&r" (res)
  150. : [bits] "r" (bits));
  151. return 31 - res;
  152. #elif defined(_M_IX86)
  153. /* Visual Studio i386 */
  154. __asm
  155. {
  156. xor eax, eax
  157. dec eax
  158. bsr eax, bits
  159. }
  160. #elif defined(_M_X64)
  161. /* Visual Studio x86_64 */
  162. /* TODO: Need the appropriate x86_64 code */
  163. int res;
  164. if (bits == 0)
  165. return -1;
  166. res = 0;
  167. if (bits & 0xFFFF0000)
  168. {
  169. bits &= 0xFFFF0000;
  170. res += 16;
  171. }
  172. if (bits & 0xFF00FF00)
  173. {
  174. bits &= 0xFF00FF00;
  175. res += 8;
  176. }
  177. if (bits & 0xF0F0F0F0)
  178. {
  179. bits &= 0xF0F0F0F0;
  180. res += 4;
  181. }
  182. if (bits & 0xCCCCCCCC)
  183. {
  184. bits &= 0xCCCCCCCC;
  185. res += 2;
  186. }
  187. if (bits & 0xAAAAAAAA)
  188. {
  189. bits &= 0xAAAAAAAA;
  190. res += 1;
  191. }
  192. return res;
  193. #else
  194. int res;
  195. if (bits == 0)
  196. return -1;
  197. res = 0;
  198. if (bits & 0xFFFF0000)
  199. {
  200. bits &= 0xFFFF0000;
  201. res += 16;
  202. }
  203. if (bits & 0xFF00FF00)
  204. {
  205. bits &= 0xFF00FF00;
  206. res += 8;
  207. }
  208. if (bits & 0xF0F0F0F0)
  209. {
  210. bits &= 0xF0F0F0F0;
  211. res += 4;
  212. }
  213. if (bits & 0xCCCCCCCC)
  214. {
  215. bits &= 0xCCCCCCCC;
  216. res += 2;
  217. }
  218. if (bits & 0xAAAAAAAA)
  219. {
  220. bits &= 0xAAAAAAAA;
  221. res += 1;
  222. }
  223. return res;
  224. #endif
  225. }
  226. /*- End of function --------------------------------------------------------*/
  227. /*! \brief Find the bit position of the lowest set bit in a word
  228. \param bits The word to be searched
  229. \return The bit number of the lowest set bit, or -1 if the word is zero. */
  230. static __inline int bottom_bit(unsigned int bits)
  231. {
  232. int res;
  233. #if defined(SPANDSP_USE_86_ASM)
  234. __asm__ (" xorl %[res],%[res];\n"
  235. " decl %[res];\n"
  236. " bsfl %[bits],%[res]\n"
  237. : [res] "=&r" (res)
  238. : [bits] "rm" (bits));
  239. return res;
  240. #else
  241. if (bits == 0)
  242. return -1;
  243. res = 31;
  244. if (bits & 0x0000FFFF)
  245. {
  246. bits &= 0x0000FFFF;
  247. res -= 16;
  248. }
  249. if (bits & 0x00FF00FF)
  250. {
  251. bits &= 0x00FF00FF;
  252. res -= 8;
  253. }
  254. if (bits & 0x0F0F0F0F)
  255. {
  256. bits &= 0x0F0F0F0F;
  257. res -= 4;
  258. }
  259. if (bits & 0x33333333)
  260. {
  261. bits &= 0x33333333;
  262. res -= 2;
  263. }
  264. if (bits & 0x55555555)
  265. {
  266. bits &= 0x55555555;
  267. res -= 1;
  268. }
  269. return res;
  270. #endif
  271. }
  272. #define ULAW_BIAS 0x84
  273. /*! \brief Encode a linear sample to u-law
  274. \param linear The sample to encode.
  275. \return The u-law value.
  276. */
  277. static __inline uint8_t linear_to_ulaw(int linear)
  278. {
  279. uint8_t u_val;
  280. int mask;
  281. int seg;
  282. /* Get the sign and the magnitude of the value. */
  283. if (linear >= 0)
  284. {
  285. linear = ULAW_BIAS + linear;
  286. mask = 0xFF;
  287. }
  288. else
  289. {
  290. linear = ULAW_BIAS - linear;
  291. mask = 0x7F;
  292. }
  293. seg = top_bit(linear | 0xFF) - 7;
  294. /*
  295. * Combine the sign, segment, quantization bits,
  296. * and complement the code word.
  297. */
  298. if (seg >= 8)
  299. u_val = (uint8_t) (0x7F ^ mask);
  300. else
  301. u_val = (uint8_t) (((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask);
  302. #ifdef ULAW_ZEROTRAP
  303. /* Optional ITU trap */
  304. if (u_val == 0)
  305. u_val = 0x02;
  306. #endif
  307. return u_val;
  308. }
  309. /*! The A-law alternate mark inversion mask */
  310. #define ALAW_AMI_MASK 0x55
  311. /*! \brief Encode a linear sample to A-law
  312. \param linear The sample to encode.
  313. \return The A-law value.
  314. */
  315. static __inline uint8_t linear_to_alaw(int linear)
  316. {
  317. int mask;
  318. int seg;
  319. if (linear >= 0)
  320. {
  321. /* Sign (bit 7) bit = 1 */
  322. mask = ALAW_AMI_MASK | 0x80;
  323. }
  324. else
  325. {
  326. /* Sign (bit 7) bit = 0 */
  327. mask = ALAW_AMI_MASK;
  328. linear = -linear - 1;
  329. }
  330. /* Convert the scaled magnitude to segment number. */
  331. seg = top_bit(linear | 0xFF) - 7;
  332. if (seg >= 8)
  333. {
  334. if (linear >= 0)
  335. {
  336. /* Out of range. Return maximum value. */
  337. return (uint8_t) (0x7F ^ mask);
  338. }
  339. /* We must be just a tiny step below zero */
  340. return (uint8_t) (0x00 ^ mask);
  341. }
  342. /* Combine the sign, segment, and quantization bits. */
  343. return (uint8_t) (((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask);
  344. }
  345. /*- End of function --------------------------------------------------------*/
  346. struct wavfile_t
  347. {
  348. HANDLE hFile;
  349. int isread;
  350. int clock; // 8k or 16k
  351. int samplebit; // 8 or 16
  352. int format_tag;
  353. int file_format_tag;
  354. int file_samplebit;
  355. int file_clock;
  356. };
  357. static int read_wav_header(HANDLE hFile, int *clock, int *samplebit, int *format_tag)
  358. {
  359. DWORD dw;
  360. DWORD dwByteRead;
  361. DWORD dwFileLen;
  362. DWORD dwFormatLen;
  363. WAVEFORMATEX fmt;
  364. SetFilePointer(hFile, 0, NULL, FILE_END);
  365. dwFileLen = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
  366. SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  367. ReadFile(hFile, &dw, sizeof(dw), &dwByteRead, NULL);
  368. if (dw != 'FFIR')
  369. return -1;
  370. ReadFile(hFile, &dw, sizeof(dw), &dwByteRead, NULL);
  371. if (dw != dwFileLen-8)
  372. return -1;
  373. ReadFile(hFile, &dw, sizeof(dw), &dwByteRead, NULL);
  374. if (dw != 'EVAW')
  375. return -1;
  376. ReadFile(hFile, &dw, sizeof(dw), &dwByteRead, NULL);
  377. if (dw != ' tmf')
  378. return -1;
  379. ReadFile(hFile, &dwFormatLen, sizeof(dwFormatLen), &dwByteRead, NULL);
  380. if (dwFormatLen < 16)
  381. return -1;
  382. ReadFile(hFile, &fmt, dwFormatLen, &dwByteRead, NULL);
  383. *format_tag = (int)fmt.wFormatTag;
  384. if (fmt.nChannels != 1)
  385. return -1;
  386. if (fmt.nSamplesPerSec == 8000)
  387. *clock = 8000;
  388. else if (fmt.nSamplesPerSec == 16000)
  389. *clock = 16000;
  390. else
  391. return -1; // not supported
  392. *samplebit = (int)fmt.wBitsPerSample;
  393. ReadFile(hFile, &dw, sizeof(dw), &dwByteRead, NULL);
  394. while (dw != 'atad') { // is not data chunk
  395. DWORD tmp;
  396. ReadFile(hFile, &tmp, sizeof(tmp), &dwByteRead, NULL);
  397. SetFilePointer(hFile, tmp, NULL, FILE_CURRENT);
  398. ReadFile(hFile, &dw, sizeof(dw), &dwByteRead, NULL);
  399. }
  400. ReadFile(hFile, &dw, sizeof(dw), &dwByteRead, NULL);
  401. return 0;
  402. }
  403. static int write_wav_header(HANDLE hFile, int clock, int samplebit, int format_tag)
  404. {
  405. WORD wFormat;
  406. WORD wBitsPerSample;
  407. DWORD dw;
  408. DWORD dwByteWritten;
  409. WAVEFORMATEX fmt;
  410. DWORD dwFmtSize = sizeof(fmt);
  411. wFormat = (WORD)format_tag;
  412. wBitsPerSample = (WORD)samplebit;
  413. if (wFormat == WAVE_FORMAT_PCM) {
  414. dwFmtSize -= 2;
  415. }
  416. dw = 'FFIR'; // riff chunk
  417. WriteFile(hFile, &dw, sizeof(dw), &dwByteWritten, NULL);
  418. dw = 0x7fffffff; // riff chunk size
  419. WriteFile(hFile, &dw, sizeof(dw), &dwByteWritten, NULL);
  420. dw = 'EVAW'; // format
  421. WriteFile(hFile, &dw, sizeof(dw), &dwByteWritten, NULL);
  422. dw = ' tmf'; // fmt subchunk
  423. WriteFile(hFile, &dw, sizeof(dw), &dwByteWritten, NULL);
  424. dw = dwFmtSize;
  425. WriteFile(hFile, &dw, sizeof(dw), &dwByteWritten, NULL);
  426. fmt.wFormatTag = wFormat;
  427. fmt.nChannels = 1;
  428. fmt.nSamplesPerSec = (DWORD)clock;
  429. fmt.nBlockAlign = 2;
  430. fmt.wBitsPerSample = wBitsPerSample;
  431. fmt.cbSize = 0;
  432. fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * wBitsPerSample / 8;
  433. WriteFile(hFile, &fmt, dwFmtSize, &dwByteWritten, NULL);
  434. dw = 'atad'; // data chunk
  435. WriteFile(hFile, &dw, sizeof(dw), &dwByteWritten, NULL);
  436. dw = 0x7fffffff; // data chunk size
  437. WriteFile(hFile, &dw, sizeof(dw), &dwByteWritten, NULL);
  438. return 0;
  439. }
  440. static int write_wav_header_end(HANDLE hFile, int ispcm16)
  441. {
  442. DWORD dwByteWritten;
  443. DWORD dw;
  444. DWORD dwFileLen;
  445. DWORD dwDataChunkOffset;
  446. if (hFile == INVALID_HANDLE_VALUE)
  447. return -1;
  448. dwDataChunkOffset = (ispcm16 ? 44 : 46);
  449. SetFilePointer(hFile, 0, NULL, FILE_END);
  450. dwFileLen = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
  451. dw = dwFileLen - 8; // riff chunk size
  452. SetFilePointer(hFile, 4, NULL, FILE_BEGIN);
  453. WriteFile(hFile, &dw, sizeof(dw), &dwByteWritten, NULL);
  454. dw = dwFileLen - dwDataChunkOffset; // data chunk size
  455. SetFilePointer(hFile, dwDataChunkOffset-4, NULL, FILE_BEGIN);
  456. WriteFile(hFile, &dw, sizeof(dw), &dwByteWritten, NULL);
  457. SetFilePointer(hFile, 0, NULL, FILE_END);
  458. return 0;
  459. }
  460. static int read_wav_frame(HANDLE hFile, DWORD dwFrameSize, unsigned char *buf)
  461. {
  462. DWORD dwByteRead;
  463. BOOL bRet;
  464. bRet = ReadFile(hFile, buf, dwFrameSize, &dwByteRead, NULL);
  465. if (!bRet || dwByteRead == 0) {
  466. return -1;
  467. }
  468. if (dwByteRead < dwFrameSize) {
  469. memset(buf+dwByteRead, 0, dwFrameSize-dwByteRead);
  470. }
  471. return 0;
  472. }
  473. static int write_wav_frame(HANDLE hFile, const char *buf, DWORD size)
  474. {
  475. DWORD dwByteWritten;
  476. BOOL bRet = WriteFile(hFile, buf, size, &dwByteWritten, NULL);
  477. return bRet ? 0 : -1;
  478. }
  479. TOOLKIT_API int wavfile_probe_format(const char *file, int *p_clock, int *p_samplebit, int *format_tag)
  480. {
  481. HANDLE hFile;
  482. int clock;
  483. int tag;
  484. int samplebit;
  485. if (!file)
  486. return -1;
  487. hFile = CreateFileA(file,
  488. GENERIC_READ,
  489. FILE_SHARE_READ,
  490. NULL,
  491. OPEN_EXISTING,
  492. FILE_ATTRIBUTE_NORMAL,
  493. NULL);
  494. if (hFile == INVALID_HANDLE_VALUE)
  495. return -1;
  496. if (read_wav_header(hFile, &clock, &samplebit, &tag) != 0) {
  497. CloseHandle(hFile);
  498. return -1;
  499. }
  500. CloseHandle(hFile);
  501. if (p_clock)
  502. *p_clock = clock;
  503. if (format_tag)
  504. *format_tag = tag;
  505. if (p_samplebit)
  506. *p_samplebit = samplebit;
  507. return 0;
  508. }
  509. TOOLKIT_API int wavfile_open(const char *file,
  510. int isread,
  511. int clock,
  512. int samplebit,
  513. int format_tag,
  514. wavfile_t **p_wavfile)
  515. {
  516. wavfile_t *wavfile;
  517. wavfile = ZALLOC_T(wavfile_t);
  518. wavfile->clock = clock;
  519. wavfile->format_tag = format_tag;
  520. wavfile->samplebit = samplebit;
  521. wavfile->isread = !!isread;
  522. wavfile->hFile = CreateFileA(file,
  523. isread ? GENERIC_READ : GENERIC_WRITE, FILE_SHARE_READ,
  524. NULL,
  525. isread ? OPEN_EXISTING : OPEN_ALWAYS,
  526. FILE_ATTRIBUTE_NORMAL,
  527. NULL);
  528. if (wavfile->hFile == INVALID_HANDLE_VALUE)
  529. return -1;
  530. if (isread) {
  531. int read_clock;
  532. int read_format_tag;
  533. int read_samplebit;
  534. if (read_wav_header(wavfile->hFile, &read_clock, &read_samplebit, &read_format_tag) != 0) {
  535. CloseHandle(wavfile->hFile);
  536. return -1;
  537. }
  538. wavfile->file_clock = read_clock;
  539. wavfile->file_format_tag = read_format_tag;
  540. wavfile->file_samplebit = read_samplebit;
  541. } else {
  542. if (write_wav_header(wavfile->hFile, clock, samplebit, format_tag) != 0) {
  543. CloseHandle(wavfile->hFile);
  544. return -1;
  545. }
  546. }
  547. *p_wavfile = wavfile;
  548. return 0;
  549. }
  550. TOOLKIT_API int wavfile_close(wavfile_t *wavfile)
  551. {
  552. if (!wavfile->isread)
  553. write_wav_header_end(wavfile->hFile, wavfile->samplebit == 16);
  554. CloseHandle(wavfile->hFile);
  555. wavfile->hFile = INVALID_HANDLE_VALUE;
  556. free(wavfile);
  557. return 0;
  558. }
  559. TOOLKIT_API int wavfile_get_native_handle(wavfile_t *wavfile, HANDLE *p_handle)
  560. {
  561. *p_handle = wavfile->hFile;
  562. return 0;
  563. }
  564. TOOLKIT_API int wavfile_write(wavfile_t *wavfile, const void *buf, int size)
  565. {
  566. if (write_wav_frame(wavfile->hFile, buf, size) != 0)
  567. return -1;
  568. return 0;
  569. }
  570. TOOLKIT_API int wavfile_read(wavfile_t *wavfile, void *buf, int size)
  571. {
  572. int i;
  573. if (wavfile->file_format_tag == wavfile->format_tag) {
  574. if (wavfile->file_samplebit == wavfile->samplebit) {
  575. if (read_wav_frame(wavfile->hFile, size, buf) != 0)
  576. return -1;
  577. } else if (wavfile->file_samplebit == 16) {
  578. short tmp[256];
  579. if (read_wav_frame(wavfile->hFile, 2*size, (unsigned char*)&tmp[0]) != 0)
  580. return -1;
  581. if (wavfile->format_tag == WAVE_FORMAT_PCM) {
  582. for (i = 0; i < size; ++i)
  583. *((unsigned char*)buf + i) = (tmp[i] >> 8) + 128;
  584. } else if (wavfile->format_tag == WAVE_FORMAT_ALAW) {
  585. for (i = 0; i < size; ++i)
  586. *((unsigned char*)buf + i) = linear_to_alaw(tmp[i]);
  587. } else if (wavfile->format_tag == WAVE_FORMAT_MULAW) {
  588. for (i = 0; i < size; ++i)
  589. *((unsigned char*)buf + i) = linear_to_alaw(tmp[i]);
  590. } else {
  591. return -1;
  592. }
  593. } else {
  594. return -1;
  595. }
  596. } else if (wavfile->file_samplebit == wavfile->samplebit && wavfile->samplebit == 8) {
  597. if (read_wav_frame(wavfile->hFile, size, buf) != 0)
  598. return -1;
  599. if (wavfile->file_format_tag == WAVE_FORMAT_PCM) {
  600. if (wavfile->format_tag == WAVE_FORMAT_ALAW) {
  601. for (i = 0; i < size; ++i)
  602. *((unsigned char*)buf + i) = pcm8toalaw[*((unsigned char*)buf+i)];
  603. } else if (wavfile->format_tag == WAVE_FORMAT_MULAW) {
  604. for (i = 0; i < size; ++i)
  605. *((unsigned char*)buf + i) = pcm8tomulaw[*((unsigned char*)buf+i)];
  606. } else {
  607. return -1;
  608. }
  609. } else if (wavfile->file_format_tag == WAVE_FORMAT_ALAW) {
  610. if (wavfile->format_tag == WAVE_FORMAT_MULAW) {
  611. for (i = 0; i < size; ++i)
  612. *((unsigned char*)buf + i) = alaw_to_ulaw(*((unsigned char*)buf+i));
  613. } else if (wavfile->format_tag == WAVE_FORMAT_PCM) {
  614. for (i = 0; i < size; ++i)
  615. *((unsigned char*)buf + i) = alawtopcm8[*((unsigned char*)buf+i)];
  616. } else {
  617. return -1;
  618. }
  619. } else if (wavfile->file_format_tag == WAVE_FORMAT_MULAW) {
  620. if (wavfile->format_tag == WAVE_FORMAT_ALAW) {
  621. for (i = 0; i < size; ++i)
  622. *((unsigned char*)buf + i) = ulaw_to_alaw(*((unsigned char*)buf+i));
  623. } else if (wavfile->format_tag == WAVE_FORMAT_PCM) {
  624. for (i = 0; i < size; ++i)
  625. *((unsigned char*)buf + i) = ulawtopcm8[*((unsigned char*)buf+i)];
  626. } else {
  627. return -1;
  628. }
  629. } else {
  630. return -1;
  631. }
  632. } else {
  633. return -1;
  634. }
  635. return 0;
  636. }
  637. // PCM16, PCMA, PCMU, PCM8