Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

693 lines
18 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
  4. //
  5. // Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
  6. //
  7. // Other brand and product names used herein are trademarks of their respective owners.
  8. //
  9. // The entire program and user interface including the structure, sequence, selection,
  10. // and arrangement of the dialog, the exclusively "yes" and "no" choices represented
  11. // by "1" and "2," and each dialog message are protected by copyrights registered in
  12. // the United States and by international treaties.
  13. //
  14. // Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
  15. // 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
  16. //
  17. // Active Voice Corporation
  18. // Seattle, Washington
  19. // USA
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////////////
  22. ////
  23. // mulaw.c - mulaw file format functions
  24. ////
  25. #include "winlocal.h"
  26. #include <mmsystem.h>
  27. #include "mulaw.h"
  28. #include "mem.h"
  29. #include "sys.h"
  30. #include "trace.h"
  31. #include "wavfmt.h"
  32. ////
  33. // private definitions
  34. ////
  35. // mulaw engine control structure
  36. //
  37. typedef struct MULAW
  38. {
  39. DWORD dwVersion;
  40. HINSTANCE hInst;
  41. HTASK hTask;
  42. DWORD dwFlags;
  43. } MULAW, FAR *LPMULAW;
  44. // helper functions
  45. //
  46. static LPMULAW MulawGetPtr(HMULAW hMulaw);
  47. static HMULAW MulawGetHandle(LPMULAW lpMulaw);
  48. static unsigned char linear2ulaw(int sample);
  49. static int ulaw2linear(unsigned char ulawbyte);
  50. static LRESULT MulawIOOpen(LPMMIOINFO lpmmioinfo, LPTSTR lpszFileName);
  51. static LRESULT MulawIOClose(LPMMIOINFO lpmmioinfo, UINT uFlags);
  52. static LRESULT MulawIORead(LPMMIOINFO lpmmioinfo, HPSTR pch, LONG cch);
  53. static LRESULT MulawIOWrite(LPMMIOINFO lpmmioinfo, const HPSTR pch, LONG cch, BOOL fFlush);
  54. static LRESULT MulawIOSeek(LPMMIOINFO lpmmioinfo, LONG lOffset, int iOrigin);
  55. static LRESULT MulawIORename(LPMMIOINFO lpmmioinfo, LPCTSTR lpszFileName, LPCTSTR lpszNewFileName);
  56. ////
  57. // public functions
  58. ////
  59. // MulawInit - initialize mulaw engine
  60. // <dwVersion> (i) must be MULAW_VERSION
  61. // <hInst> (i) instance handle of calling module
  62. // <dwFlags> (i) reserved; must be 0
  63. // return handle (NULL if error)
  64. //
  65. HMULAW DLLEXPORT WINAPI MulawInit(DWORD dwVersion, HINSTANCE hInst, DWORD dwFlags)
  66. {
  67. BOOL fSuccess = TRUE;
  68. LPMULAW lpMulaw = NULL;
  69. if (dwVersion != MULAW_VERSION)
  70. fSuccess = TraceFALSE(NULL);
  71. else if (hInst == NULL)
  72. fSuccess = TraceFALSE(NULL);
  73. else if ((lpMulaw = (LPMULAW) MemAlloc(NULL, sizeof(MULAW), 0)) == NULL)
  74. fSuccess = TraceFALSE(NULL);
  75. else
  76. {
  77. // initialize engine structure
  78. //
  79. lpMulaw->dwVersion = dwVersion;
  80. lpMulaw->hInst = hInst;
  81. lpMulaw->hTask = GetCurrentTask();
  82. lpMulaw->dwFlags = dwFlags;
  83. if (MulawReset(MulawGetHandle(lpMulaw)) != 0)
  84. fSuccess = TraceFALSE(NULL);
  85. }
  86. if (!fSuccess)
  87. {
  88. MulawTerm(MulawGetHandle(lpMulaw));
  89. lpMulaw = NULL;
  90. }
  91. return fSuccess ? MulawGetHandle(lpMulaw) : NULL;
  92. }
  93. // MulawTerm - shut down mulaw engine
  94. // <hMulaw> (i) handle returned from MulawInit
  95. // return 0 if success
  96. //
  97. int DLLEXPORT WINAPI MulawTerm(HMULAW hMulaw)
  98. {
  99. BOOL fSuccess = TRUE;
  100. LPMULAW lpMulaw;
  101. if ((lpMulaw = MulawGetPtr(hMulaw)) == NULL)
  102. fSuccess = TraceFALSE(NULL);
  103. else if ((lpMulaw = MemFree(NULL, lpMulaw)) != NULL)
  104. fSuccess = TraceFALSE(NULL);
  105. return fSuccess ? 0 : -1;
  106. }
  107. // MulawReset - reset mulaw engine
  108. // <hMulaw> (i) handle returned from MulawInit
  109. // return 0 if success
  110. //
  111. int DLLEXPORT WINAPI MulawReset(HMULAW hMulaw)
  112. {
  113. BOOL fSuccess = TRUE;
  114. LPMULAW lpMulaw;
  115. if ((lpMulaw = MulawGetPtr(hMulaw)) == NULL)
  116. fSuccess = TraceFALSE(NULL);
  117. else
  118. {
  119. // currently nothing to do
  120. }
  121. return fSuccess ? 0 : -1;
  122. }
  123. // MulawDecode - decode mulaw samples
  124. // <hMulaw> (i) handle returned from MulawInit
  125. // <lpabMulaw> (i) array of encoded samples
  126. // <lpaiPcm> (o) array of decoded samples
  127. // <uSamples> (i) number of samples to decode
  128. // return 0 if success
  129. //
  130. // NOTE: each BYTE in <lpabMulaw> contains 1 8-bit encoded sample
  131. // in Mulaw format.
  132. // Each PCM16 in <lpaiPcm> contains 1 16-bit decoded sample
  133. // in standard PCM format.
  134. //
  135. int DLLEXPORT WINAPI MulawDecode(HMULAW hMulaw, LPBYTE lpabMulaw, LPPCM16 lpaiPcm, UINT uSamples)
  136. {
  137. BOOL fSuccess = TRUE;
  138. LPMULAW lpMulaw;
  139. if ((lpMulaw = MulawGetPtr(hMulaw)) == NULL)
  140. fSuccess = TraceFALSE(NULL);
  141. else if (lpaiPcm == NULL || lpabMulaw == NULL)
  142. fSuccess = TraceFALSE(NULL);
  143. // decode each sample
  144. //
  145. else while (uSamples-- > 0)
  146. *lpaiPcm++ = (PCM16) ulaw2linear((BYTE) *lpabMulaw++);
  147. return fSuccess ? 0 : -1;
  148. }
  149. // MulawEncode - encode mulaw samples
  150. // <hMulaw> (i) handle returned from MulawInit
  151. // <lpaiPcm> (i) array of decoded samples
  152. // <lpabMulaw> (o) array of encoded samples
  153. // <uSamples> (i) number of samples to encode
  154. // return 0 if success
  155. //
  156. // NOTE: each BYTE in <lpabMulaw> contains 1 8-bit encoded sample
  157. // in Mulaw format.
  158. // Each PCM16 in <lpaiPcm> contains 1 16-bit decoded sample
  159. // in standard PCM format.
  160. //
  161. int DLLEXPORT WINAPI MulawEncode(HMULAW hMulaw, LPPCM16 lpaiPcm, LPBYTE lpabMulaw, UINT uSamples)
  162. {
  163. BOOL fSuccess = TRUE;
  164. LPMULAW lpMulaw;
  165. if ((lpMulaw = MulawGetPtr(hMulaw)) == NULL)
  166. fSuccess = TraceFALSE(NULL);
  167. else if (lpaiPcm == NULL || lpabMulaw == NULL)
  168. fSuccess = TraceFALSE(NULL);
  169. // encode each sample
  170. //
  171. else while (uSamples-- > 0)
  172. *lpabMulaw++ = (BYTE) linear2ulaw((PCM16) *lpaiPcm++);
  173. return fSuccess ? 0 : -1;
  174. }
  175. // MulawIOProc - i/o procedure for mulaw format file data
  176. // <lpmmioinfo> (i/o) information about open file
  177. // <uMessage> (i) message indicating the requested I/O operation
  178. // <lParam1> (i) message specific parameter
  179. // <lParam2> (i) message specific parameter
  180. // returns 0 if message not recognized, otherwise message specific value
  181. //
  182. // NOTE: the address of this function should be passed to the WavOpen()
  183. // or mmioInstallIOProc() functions for accessing mulaw format file data.
  184. //
  185. LRESULT DLLEXPORT CALLBACK MulawIOProc(LPTSTR lpmmioinfo,
  186. UINT uMessage, LPARAM lParam1, LPARAM lParam2)
  187. {
  188. BOOL fSuccess = TRUE;
  189. LRESULT lResult = 0;
  190. if (lpmmioinfo == NULL)
  191. fSuccess = TraceFALSE(NULL);
  192. else switch (uMessage)
  193. {
  194. case MMIOM_OPEN:
  195. lResult = MulawIOOpen((LPMMIOINFO) lpmmioinfo,
  196. (LPTSTR) lParam1);
  197. break;
  198. case MMIOM_CLOSE:
  199. lResult = MulawIOClose((LPMMIOINFO) lpmmioinfo,
  200. (UINT) lParam1);
  201. break;
  202. case MMIOM_READ:
  203. lResult = MulawIORead((LPMMIOINFO) lpmmioinfo,
  204. (HPSTR) lParam1, (LONG) lParam2);
  205. break;
  206. case MMIOM_WRITE:
  207. lResult = MulawIOWrite((LPMMIOINFO) lpmmioinfo,
  208. (const HPSTR) lParam1, (LONG) lParam2, FALSE);
  209. break;
  210. case MMIOM_WRITEFLUSH:
  211. lResult = MulawIOWrite((LPMMIOINFO) lpmmioinfo,
  212. (const HPSTR) lParam1, (LONG) lParam2, TRUE);
  213. break;
  214. case MMIOM_SEEK:
  215. lResult = MulawIOSeek((LPMMIOINFO) lpmmioinfo,
  216. (LONG) lParam1, (int) lParam2);
  217. break;
  218. case MMIOM_RENAME:
  219. lResult = MulawIORename((LPMMIOINFO) lpmmioinfo,
  220. (LPCTSTR) lParam1, (LPCTSTR) lParam2);
  221. break;
  222. default:
  223. lResult = 0;
  224. break;
  225. }
  226. return lResult;
  227. }
  228. ////
  229. // private functions
  230. ////
  231. // MulawGetPtr - verify that mulaw handle is valid,
  232. // <hMulaw> (i) handle returned from MulawInit
  233. // return corresponding mulaw pointer (NULL if error)
  234. //
  235. static LPMULAW MulawGetPtr(HMULAW hMulaw)
  236. {
  237. BOOL fSuccess = TRUE;
  238. LPMULAW lpMulaw;
  239. if ((lpMulaw = (LPMULAW) hMulaw) == NULL)
  240. fSuccess = TraceFALSE(NULL);
  241. else if (IsBadWritePtr(lpMulaw, sizeof(MULAW)))
  242. fSuccess = TraceFALSE(NULL);
  243. #ifdef CHECKTASK
  244. // make sure current task owns the mulaw engine handle
  245. //
  246. else if (lpMulaw->hTask != GetCurrentTask())
  247. fSuccess = TraceFALSE(NULL);
  248. #endif
  249. return fSuccess ? lpMulaw : NULL;
  250. }
  251. // MulawGetHandle - verify that mulaw pointer is valid,
  252. // <lpMulaw> (i) pointer to MULAW structure
  253. // return corresponding mulaw handle (NULL if error)
  254. //
  255. static HMULAW MulawGetHandle(LPMULAW lpMulaw)
  256. {
  257. BOOL fSuccess = TRUE;
  258. HMULAW hMulaw;
  259. if ((hMulaw = (HMULAW) lpMulaw) == NULL)
  260. fSuccess = TraceFALSE(NULL);
  261. return fSuccess ? hMulaw : NULL;
  262. }
  263. ////
  264. // low-level mulaw stuff
  265. ////
  266. // source - http://www.speech.su.oz.au/comp.speech/Section2/Q2.7.html
  267. #define ZEROTRAP // turn on the trap as per the MIL-STD
  268. #define BIAS 0x84 // define the add-in bias for 16 bit samples
  269. #define CLIP 32635
  270. //// linear2ulaw - this routine converts from 16 bit linear to ulaw
  271. //
  272. // Craig Reese: IDA/Supercomputing Research Center
  273. // Joe Campbell, Department of Defense
  274. // 29 September 1989
  275. //
  276. // References:
  277. // 1) CCITT Recommendation G.711 (very difficult to follow)
  278. // 2) "A New Digital Technique for Implementation of Any
  279. // Continuous PCM Companding Law," Villeret, Michel,
  280. // et. al. 1973 IEEE Int. Conf. on Communications, Vol 1,
  281. // 1973, pg. 11.12-11.17
  282. // 3) MIL-STD-188-113, "Interoperability and Performance Standards
  283. // for Analog-to-Digital Conversion Techniques,"
  284. // 17 February 1987
  285. //
  286. // Input: Signed 16 bit linear sample
  287. // Output: 8 bit ulaw sample
  288. //
  289. static unsigned char linear2ulaw(int sample)
  290. {
  291. static int exp_lut[256] =
  292. {
  293. 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
  294. 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  295. 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  296. 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  297. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  298. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  299. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  300. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  301. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  302. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  303. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  304. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  305. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  306. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  307. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  308. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  309. };
  310. int sign;
  311. int exponent;
  312. int mantissa;
  313. unsigned char ulawbyte;
  314. //
  315. // get the sample into sign-magnitude
  316. //
  317. // set aside the sign
  318. //
  319. sign = (sample >> 8) & 0x80;
  320. // get magnitude
  321. //
  322. if (sign != 0)
  323. sample = -sample;
  324. // clip the magnitude
  325. //
  326. if (sample > CLIP)
  327. sample = CLIP;
  328. //
  329. // convert from 16 bit linear to ulaw
  330. //
  331. sample = sample + BIAS;
  332. exponent = exp_lut[(sample >> 7) & 0xFF];
  333. mantissa = (sample >> (exponent + 3)) & 0x0F;
  334. ulawbyte = ~(sign | (exponent << 4) | mantissa);
  335. #ifdef ZEROTRAP
  336. // optional CCITT trap
  337. //
  338. if (ulawbyte == 0)
  339. ulawbyte = 0x02;
  340. #endif
  341. return ulawbyte;
  342. }
  343. //// ulaw2linear - this routine converts from ulaw to 16 bit linear
  344. //
  345. // Craig Reese: IDA/Supercomputing Research Center
  346. // 29 September 1989
  347. //
  348. // References:
  349. // 1) CCITT Recommendation G.711 (very difficult to follow)
  350. // 2) MIL-STD-188-113, "Interoperability and Performance Standards
  351. // for Analog-to-Digital Conversion Techniques,"
  352. // 17 February 1987
  353. //
  354. // Input: 8 bit ulaw sample
  355. // Output: Signed 16 bit linear sample
  356. //
  357. static int ulaw2linear(unsigned char ulawbyte)
  358. {
  359. static int exp_lut[8] =
  360. {
  361. 0, 132, 396, 924, 1980, 4092, 8316, 16764
  362. };
  363. int sign;
  364. int exponent;
  365. int mantissa;
  366. int sample;
  367. ulawbyte = ~ulawbyte;
  368. sign = (ulawbyte & 0x80);
  369. exponent = (ulawbyte >> 4) & 0x07;
  370. mantissa = ulawbyte & 0x0F;
  371. sample = exp_lut[exponent] + (mantissa << (exponent + 3));
  372. if (sign != 0)
  373. sample = -sample;
  374. return sample;
  375. }
  376. ////
  377. // installable file i/o procedures
  378. ////
  379. static LRESULT MulawIOOpen(LPMMIOINFO lpmmioinfo, LPTSTR lpszFileName)
  380. {
  381. BOOL fSuccess = TRUE;
  382. HMMIO hmmio = NULL;
  383. MMIOINFO mmioinfo;
  384. HMULAW hMulaw = NULL;
  385. HINSTANCE hInst;
  386. TracePrintf_1(NULL, 5,
  387. TEXT("MulawIOOpen (%s)\n"),
  388. (LPTSTR) lpszFileName);
  389. MemSet(&mmioinfo, 0, sizeof(mmioinfo));
  390. // interpret first value passed as pointer to next i/o procedure in chain
  391. //
  392. mmioinfo.pIOProc = (LPMMIOPROC) lpmmioinfo->adwInfo[0];
  393. // pass along second and third values to next i/o procedure
  394. //
  395. mmioinfo.adwInfo[0] = lpmmioinfo->adwInfo[1];
  396. mmioinfo.adwInfo[1] = lpmmioinfo->adwInfo[2];
  397. mmioinfo.adwInfo[2] = 0L;
  398. // get instance handle of current task
  399. //
  400. if ((hInst = SysGetTaskInstance(NULL)) == NULL)
  401. fSuccess = TraceFALSE(NULL);
  402. else if ((hMulaw = MulawInit(MULAW_VERSION, hInst, 0)) == NULL)
  403. fSuccess = TraceFALSE(NULL);
  404. else if ((hmmio = mmioOpen(lpszFileName, &mmioinfo, lpmmioinfo->dwFlags)) == NULL)
  405. fSuccess = TraceFALSE(NULL);
  406. else
  407. {
  408. // save stuff for use in other i/o routines
  409. //
  410. lpmmioinfo->adwInfo[0] = (DWORD) (LPVOID) hmmio;
  411. lpmmioinfo->adwInfo[1] = (DWORD) (LPVOID) hMulaw;
  412. }
  413. // clean up after error
  414. //
  415. if (!fSuccess && hMulaw != NULL && MulawTerm(hMulaw) != 0)
  416. fSuccess = TraceFALSE(NULL);
  417. if (!fSuccess && hmmio != NULL && mmioClose(hmmio, 0) != 0)
  418. fSuccess = TraceFALSE(NULL);
  419. // return the same error code given by mmioOpen
  420. //
  421. return fSuccess ? lpmmioinfo->wErrorRet = mmioinfo.wErrorRet : MMIOERR_CANNOTOPEN;
  422. }
  423. static LRESULT MulawIOClose(LPMMIOINFO lpmmioinfo, UINT uFlags)
  424. {
  425. BOOL fSuccess = TRUE;
  426. HMMIO hmmio = (HMMIO) lpmmioinfo->adwInfo[0];
  427. HMULAW hMulaw = (HMULAW) lpmmioinfo->adwInfo[1];
  428. UINT uRet = MMIOERR_CANNOTCLOSE;
  429. TracePrintf_0(NULL, 5,
  430. TEXT("MulawIOClose\n"));
  431. if (MulawTerm(hMulaw) != 0)
  432. fSuccess = TraceFALSE(NULL);
  433. else if ((uRet = mmioClose(hmmio, uFlags)) != 0)
  434. fSuccess = TraceFALSE(NULL);
  435. else
  436. {
  437. lpmmioinfo->adwInfo[0] = (DWORD) NULL;
  438. lpmmioinfo->adwInfo[1] = (DWORD) NULL;
  439. }
  440. return fSuccess ? 0 : uRet;
  441. }
  442. static LRESULT MulawIORead(LPMMIOINFO lpmmioinfo, HPSTR pch, LONG cch)
  443. {
  444. BOOL fSuccess = TRUE;
  445. HMMIO hmmio = (HMMIO) lpmmioinfo->adwInfo[0];
  446. HMULAW hMulaw = (HMULAW) lpmmioinfo->adwInfo[1];
  447. HPSTR pchMulaw = NULL;
  448. LONG cchMulaw;
  449. LONG lBytesRead;
  450. TracePrintf_1(NULL, 5,
  451. TEXT("MulawIORead (%ld)\n"),
  452. (long) cch);
  453. // mulaw format files contain 8 bit samples,
  454. // but we must simulate access to 16 bit samples.
  455. //
  456. cchMulaw = cch / 2L;
  457. if (cchMulaw <= 0)
  458. lBytesRead = 0; // nothing to do
  459. // allocate temporary buffer to hold the mulaw format samples
  460. //
  461. else if ((pchMulaw = (HPSTR) MemAlloc(NULL, cchMulaw, 0)) == NULL)
  462. fSuccess = TraceFALSE(NULL);
  463. // read mulaw format samples
  464. //
  465. else if ((lBytesRead = mmioRead(hmmio, pchMulaw, cchMulaw)) == -1)
  466. fSuccess = TraceFALSE(NULL);
  467. // decode mulaw format samples into pcm format samples
  468. //
  469. else if (MulawDecode(hMulaw, (LPBYTE) pchMulaw, (LPPCM16) pch, (UINT) lBytesRead) != 0)
  470. fSuccess = TraceFALSE(NULL);
  471. // update simulated file position
  472. //
  473. else
  474. lpmmioinfo->lDiskOffset += lBytesRead * 2L;
  475. // clean up
  476. //
  477. if (pchMulaw != NULL &&
  478. (pchMulaw = MemFree(NULL, pchMulaw)) != NULL)
  479. fSuccess = TraceFALSE(NULL);
  480. TracePrintf_2(NULL, 5,
  481. TEXT("MulawIO: lpmmioinfo->lDiskOffset=%ld, lBytesRead=%ld\n"),
  482. (long) lpmmioinfo->lDiskOffset,
  483. (long) lBytesRead);
  484. // return number of bytes read/decoded into pch
  485. //
  486. return fSuccess ? lBytesRead * 4L : -1;
  487. }
  488. static LRESULT MulawIOWrite(LPMMIOINFO lpmmioinfo, const HPSTR pch, LONG cch, BOOL fFlush)
  489. {
  490. BOOL fSuccess = TRUE;
  491. HMMIO hmmio = (HMMIO) lpmmioinfo->adwInfo[0];
  492. HMULAW hMulaw = (HMULAW) lpmmioinfo->adwInfo[1];
  493. HPSTR pchMulaw = NULL;
  494. LONG cchMulaw;
  495. LONG lBytesWritten;
  496. TracePrintf_1(NULL, 5,
  497. TEXT("MulawIOWrite (%ld)\n"),
  498. (long) cch);
  499. // mulaw format files contain 8 bit samples,
  500. // but we must simulate access to 16 bit samples.
  501. //
  502. cchMulaw = cch / 2L;
  503. if (cchMulaw <= 0)
  504. lBytesWritten = 0; // nothing to do
  505. // allocate temporary buffer to hold the mulaw format samples
  506. //
  507. else if ((pchMulaw = (HPSTR) MemAlloc(NULL, cchMulaw, 0)) == NULL)
  508. fSuccess = TraceFALSE(NULL);
  509. // encode pcm format samples into mulaw format samples
  510. // (there are 2 bytes required for each pcm sample)
  511. //
  512. else if (MulawEncode(hMulaw, (LPPCM16) pch, (LPBYTE) pchMulaw, (UINT) (cch / 2L)) != 0)
  513. fSuccess = TraceFALSE(NULL);
  514. // write mulaw format samples
  515. //
  516. else if ((lBytesWritten = mmioWrite(hmmio, pchMulaw, cchMulaw)) == -1)
  517. fSuccess = TraceFALSE(NULL);
  518. // update simulated file position
  519. //
  520. else
  521. lpmmioinfo->lDiskOffset += lBytesWritten * 2L;
  522. // clean up
  523. //
  524. if (pchMulaw != NULL &&
  525. (pchMulaw = MemFree(NULL, pchMulaw)) != NULL)
  526. fSuccess = TraceFALSE(NULL);
  527. TracePrintf_2(NULL, 5,
  528. TEXT("MulawIO: lpmmioinfo->lDiskOffset=%ld, lBytesWritten=%ld\n"),
  529. (long) lpmmioinfo->lDiskOffset,
  530. (long) lBytesWritten);
  531. // return number of bytes encoded/written from pch
  532. //
  533. return fSuccess ? lBytesWritten * 2L : -1;
  534. }
  535. static LRESULT MulawIOSeek(LPMMIOINFO lpmmioinfo, LONG lOffset, int iOrigin)
  536. {
  537. BOOL fSuccess = TRUE;
  538. HMMIO hmmio = (HMMIO) lpmmioinfo->adwInfo[0];
  539. LONG lPosNew;
  540. TracePrintf_2(NULL, 5,
  541. TEXT("MulawIOSeek (%ld, %d)\n"),
  542. (long) lOffset,
  543. (int) iOrigin);
  544. // mulaw format files contain 8 bit samples,
  545. // but we must simulate access to 16 bit samples.
  546. //
  547. if ((lPosNew = mmioSeek(hmmio, lOffset / 2L, iOrigin)) == -1)
  548. fSuccess = TraceFALSE(NULL);
  549. // update simulated file position
  550. //
  551. else
  552. lpmmioinfo->lDiskOffset = lPosNew * 2L;
  553. TracePrintf_1(NULL, 5,
  554. TEXT("MulawIO: lpmmioinfo->lDiskOffset=%ld\n"),
  555. (long) lpmmioinfo->lDiskOffset);
  556. return fSuccess ? lpmmioinfo->lDiskOffset : -1;
  557. }
  558. static LRESULT MulawIORename(LPMMIOINFO lpmmioinfo, LPCTSTR lpszFileName, LPCTSTR lpszNewFileName)
  559. {
  560. BOOL fSuccess = TRUE;
  561. UINT uRet = MMIOERR_FILENOTFOUND;
  562. TracePrintf_2(NULL, 5,
  563. TEXT("MulawIORename (%s, %s)\n"),
  564. (LPTSTR) lpszFileName,
  565. (LPTSTR) lpszNewFileName);
  566. if ((uRet = mmioRename(lpszFileName, lpszNewFileName, lpmmioinfo, 0)) != 0)
  567. fSuccess = TraceFALSE(NULL);
  568. return fSuccess ? 0 : uRet;
  569. }