Windows NT 4.0 source code leak
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.

1556 lines
48 KiB

4 years ago
  1. //==========================================================================;
  2. //
  3. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. // PURPOSE.
  7. //
  8. // Copyright (c) 1992 - 1994 Microsoft Corporation. All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11. //
  12. // imaadpcm.c
  13. //
  14. // Description:
  15. // This file contains encode and decode routines for the IMA's ADPCM
  16. // format. This format is the same format used in Intel's DVI standard.
  17. // Intel has made this algorithm public domain and the IMA has endorsed
  18. // this format as a standard for audio compression.
  19. //
  20. // Implementation notes:
  21. //
  22. // A previous distribution of this codec used a data format which did
  23. // not comply with the IMA standard. For stereo files, the interleaving
  24. // of left and right samples was incorrect: the IMA standard requires
  25. // that a DWORD of left-channel data be followed by a DWORD of right-
  26. // channel data, but the previous implementation of this codec
  27. // interleaved the data at the byte level, with the 4 LSBs being the
  28. // left channel data and the 4 MSBs being the right channel data.
  29. // For mono files, each pair of samples was reversed: the first sample
  30. // was stored in the 4 MSBs rather than the 4 LSBs. This problem is
  31. // fixed during the current release. Note: files compressed by the
  32. // old codec will sound terrible when played back with the new codec,
  33. // and vice versa. Please recompress these files with the new codec,
  34. // since they do not conform to the standard and will not be reproduced
  35. // correctly by hardware codecs, etc.
  36. //
  37. // A previous distribution of this codec had an implementation problem
  38. // which degraded the sound quality of the encoding. This was due to
  39. // the fact that the step index was not properly maintained between
  40. // conversions. This problem has been fixed in the current release.
  41. //
  42. // The codec has been speeded up considerably by breaking
  43. // the encode and decode routines into four separate routines each:
  44. // mono 8-bit, mono 16-bit, stereo 8-bit, and stereo 16-bit. This
  45. // approach is recommended for real-time conversion routines.
  46. //
  47. //==========================================================================;
  48. #include <windows.h>
  49. #include <windowsx.h>
  50. #include <mmsystem.h>
  51. #include <mmreg.h>
  52. #include <msacm.h>
  53. #include <msacmdrv.h>
  54. #include "codec.h"
  55. #include "imaadpcm.h"
  56. #include "debug.h"
  57. //
  58. // This array is used by imaadpcmNextStepIndex to determine the next step
  59. // index to use. The step index is an index to the step[] array, below.
  60. //
  61. const short next_step[16] =
  62. {
  63. -1, -1, -1, -1, 2, 4, 6, 8,
  64. -1, -1, -1, -1, 2, 4, 6, 8
  65. };
  66. //
  67. // This array contains the array of step sizes used to encode the ADPCM
  68. // samples. The step index in each ADPCM block is an index to this array.
  69. //
  70. const short step[89] =
  71. {
  72. 7, 8, 9, 10, 11, 12, 13,
  73. 14, 16, 17, 19, 21, 23, 25,
  74. 28, 31, 34, 37, 41, 45, 50,
  75. 55, 60, 66, 73, 80, 88, 97,
  76. 107, 118, 130, 143, 157, 173, 190,
  77. 209, 230, 253, 279, 307, 337, 371,
  78. 408, 449, 494, 544, 598, 658, 724,
  79. 796, 876, 963, 1060, 1166, 1282, 1411,
  80. 1552, 1707, 1878, 2066, 2272, 2499, 2749,
  81. 3024, 3327, 3660, 4026, 4428, 4871, 5358,
  82. 5894, 6484, 7132, 7845, 8630, 9493, 10442,
  83. 11487, 12635, 13899, 15289, 16818, 18500, 20350,
  84. 22385, 24623, 27086, 29794, 32767
  85. };
  86. #ifndef INLINE
  87. #define INLINE __inline
  88. #endif
  89. //--------------------------------------------------------------------------;
  90. //
  91. // DWORD pcmM08BytesToSamples
  92. // DWORD pcmM16BytesToSamples
  93. // DWORD pcmS08BytesToSamples
  94. // DWORD pcmS16BytesToSamples
  95. //
  96. // Description:
  97. // These functions return the number of samples in a buffer of PCM
  98. // of the specified format. For efficiency, it is declared INLINE.
  99. // Note that, depending on the optimization flags, it may not
  100. // actually be implemented as INLINE. Optimizing for speed (-Oxwt)
  101. // will generally obey the INLINE specification.
  102. //
  103. // Arguments:
  104. // DWORD cb: The length of the buffer, in bytes.
  105. //
  106. // Return (DWORD): The length of the buffer in samples.
  107. //
  108. //--------------------------------------------------------------------------;
  109. INLINE DWORD pcmM08BytesToSamples(
  110. DWORD cb
  111. )
  112. {
  113. return cb;
  114. }
  115. INLINE DWORD pcmM16BytesToSamples(
  116. DWORD cb
  117. )
  118. {
  119. return cb / ((DWORD)2);
  120. }
  121. INLINE DWORD pcmS08BytesToSamples(
  122. DWORD cb
  123. )
  124. {
  125. return cb / ((DWORD)2);
  126. }
  127. INLINE DWORD pcmS16BytesToSamples(
  128. DWORD cb
  129. )
  130. {
  131. return cb / ((DWORD)4);
  132. }
  133. #ifdef WIN32
  134. //
  135. // This code assumes that the integer nPredictedSample is 32-bits wide!!!
  136. //
  137. // The following define replaces the pair of calls to the inline functions
  138. // imaadpcmSampleEncode() and imaadpcmSampleDecode which are called in the
  139. // encode routines. There is some redundancy between them which is exploited
  140. // in this define. Because there are two returns (nEncodedSample and
  141. // nPredictedSample), it is more efficient to use a #define rather than an
  142. // inline function which would require a pointer to one of the returns.
  143. //
  144. // Basically, nPredictedSample is calculated based on the lDifference value
  145. // already there, rather than regenerating it through imaadpcmSampleDecode().
  146. //
  147. #define imaadpcmFastEncode(nEncodedSample,nPredictedSample,nInputSample,nStepSize) \
  148. { \
  149. LONG lDifference; \
  150. \
  151. lDifference = nInputSample - nPredictedSample; \
  152. nEncodedSample = 0; \
  153. if( lDifference<0 ) { \
  154. nEncodedSample = 8; \
  155. lDifference = -lDifference; \
  156. } \
  157. \
  158. if( lDifference >= nStepSize ) { \
  159. nEncodedSample |= 4; \
  160. lDifference -= nStepSize; \
  161. } \
  162. \
  163. nStepSize >>= 1; \
  164. if( lDifference >= nStepSize ) { \
  165. nEncodedSample |= 2; \
  166. lDifference -= nStepSize; \
  167. } \
  168. \
  169. nStepSize >>= 1; \
  170. if( lDifference >= nStepSize ) { \
  171. nEncodedSample |= 1; \
  172. lDifference -= nStepSize; \
  173. } \
  174. \
  175. if( nEncodedSample & 8 ) \
  176. nPredictedSample = nInputSample + lDifference - (nStepSize>>1); \
  177. else \
  178. nPredictedSample = nInputSample - lDifference + (nStepSize>>1); \
  179. \
  180. if( nPredictedSample > 32767 ) \
  181. nPredictedSample = 32767; \
  182. else if( nPredictedSample < -32768 ) \
  183. nPredictedSample = -32768; \
  184. }
  185. #else
  186. //--------------------------------------------------------------------------;
  187. //
  188. // int imaadpcmSampleEncode
  189. //
  190. // Description:
  191. // This routine encodes a single ADPCM sample. For efficiency, it is
  192. // declared INLINE. Note that, depending on the optimization flags,
  193. // it may not actually be implemented as INLINE. Optimizing for speed
  194. // (-Oxwt) will generally obey the INLINE specification.
  195. //
  196. // Arguments:
  197. // int nInputSample: The sample to be encoded.
  198. // int nPredictedSample: The predicted value of nInputSample.
  199. // int nStepSize: The quantization step size for the difference between
  200. // nInputSample and nPredictedSample.
  201. //
  202. // Return (int): The 4-bit ADPCM encoded sample, which corresponds to the
  203. // quantized difference value.
  204. //
  205. //--------------------------------------------------------------------------;
  206. INLINE int imaadpcmSampleEncode
  207. (
  208. int nInputSample,
  209. int nPredictedSample,
  210. int nStepSize
  211. )
  212. {
  213. LONG lDifference; // difference may require 17 bits!
  214. int nEncodedSample;
  215. //
  216. // set sign bit (bit 3 of the encoded sample) based on sign of the
  217. // difference (nInputSample-nPredictedSample). Note that we want the
  218. // absolute value of the difference for the subsequent quantization.
  219. //
  220. lDifference = nInputSample - nPredictedSample;
  221. nEncodedSample = 0;
  222. if( lDifference<0 ) {
  223. nEncodedSample = 8;
  224. lDifference = -lDifference;
  225. }
  226. //
  227. // quantize lDifference sample
  228. //
  229. if( lDifference >= nStepSize ) { // Bit 2.
  230. nEncodedSample |= 4;
  231. lDifference -= nStepSize;
  232. }
  233. nStepSize >>= 1;
  234. if( lDifference >= nStepSize ) { // Bit 1.
  235. nEncodedSample |= 2;
  236. lDifference -= nStepSize;
  237. }
  238. nStepSize >>= 1;
  239. if( lDifference >= nStepSize ) { // Bit 0.
  240. nEncodedSample |= 1;
  241. }
  242. return (nEncodedSample);
  243. }
  244. #endif
  245. //--------------------------------------------------------------------------;
  246. //
  247. // int imaadpcmSampleDecode
  248. //
  249. // Description:
  250. // This routine decodes a single ADPCM sample. For efficiency, it is
  251. // declared INLINE. Note that, depending on the optimization flags,
  252. // it may not actually be implemented as INLINE. Optimizing for speed
  253. // (-Oxwt) will generally obey the INLINE specification.
  254. //
  255. // Arguments:
  256. // int nEncodedSample: The sample to be decoded.
  257. // int nPredictedSample: The predicted value of the sample (in PCM).
  258. // int nStepSize: The quantization step size used to encode the sample.
  259. //
  260. // Return (int): The decoded PCM sample.
  261. //
  262. //--------------------------------------------------------------------------;
  263. INLINE int imaadpcmSampleDecode
  264. (
  265. int nEncodedSample,
  266. int nPredictedSample,
  267. int nStepSize
  268. )
  269. {
  270. LONG lDifference;
  271. LONG lNewSample;
  272. //
  273. // calculate difference:
  274. //
  275. // lDifference = (nEncodedSample + 1/2) * nStepSize / 4
  276. //
  277. lDifference = nStepSize>>3;
  278. if (nEncodedSample & 4)
  279. lDifference += nStepSize;
  280. if (nEncodedSample & 2)
  281. lDifference += nStepSize>>1;
  282. if (nEncodedSample & 1)
  283. lDifference += nStepSize>>2;
  284. //
  285. // If the 'sign bit' of the encoded nibble is set, then the
  286. // difference is negative...
  287. //
  288. if (nEncodedSample & 8)
  289. lDifference = -lDifference;
  290. //
  291. // adjust predicted sample based on calculated difference
  292. //
  293. lNewSample = nPredictedSample + lDifference;
  294. //
  295. // check for overflow and clamp if necessary to a 16 signed sample.
  296. // Note that this is optimized for the most common case, when we
  297. // don't have to clamp.
  298. //
  299. if( (long)(short)lNewSample == lNewSample )
  300. {
  301. return (int)lNewSample;
  302. }
  303. //
  304. // Clamp.
  305. //
  306. if( lNewSample < -32768 )
  307. return (int)-32768;
  308. else
  309. return (int)32767;
  310. }
  311. //--------------------------------------------------------------------------;
  312. //
  313. // int imaadpcmNextStepIndex
  314. //
  315. // Description:
  316. // This routine calculates the step index value to use for the next
  317. // encode, based on the current value of the step index and the current
  318. // encoded sample. For efficiency, it is declared INLINE. Note that,
  319. // depending on the optimization flags, it may not actually be
  320. // implemented as INLINE. Optimizing for speed (-Oxwt) will generally
  321. // obey the INLINE specification.
  322. //
  323. // Arguments:
  324. // int nEncodedSample: The current encoded ADPCM sample.
  325. // int nStepIndex: The step index value used to encode nEncodedSample.
  326. //
  327. // Return (int): The step index to use for the next sample.
  328. //
  329. //--------------------------------------------------------------------------;
  330. INLINE int imaadpcmNextStepIndex
  331. (
  332. int nEncodedSample,
  333. int nStepIndex
  334. )
  335. {
  336. //
  337. // compute new stepsize step
  338. //
  339. nStepIndex += next_step[nEncodedSample];
  340. if (nStepIndex < 0)
  341. nStepIndex = 0;
  342. else if (nStepIndex > 88)
  343. nStepIndex = 88;
  344. return (nStepIndex);
  345. }
  346. //--------------------------------------------------------------------------;
  347. //
  348. // BOOL imaadpcmValidStepIndex
  349. //
  350. // Description:
  351. // This routine checks the step index value to make sure that it is
  352. // within the legal range.
  353. //
  354. // Arguments:
  355. //
  356. // int nStepIndex: The step index value.
  357. //
  358. // Return (BOOL): TRUE if the step index is valid; FALSE otherwise.
  359. //
  360. //--------------------------------------------------------------------------;
  361. INLINE BOOL imaadpcmValidStepIndex
  362. (
  363. int nStepIndex
  364. )
  365. {
  366. if( nStepIndex >= 0 && nStepIndex <= 88 )
  367. return TRUE;
  368. else
  369. return FALSE;
  370. }
  371. //==========================================================================;
  372. //
  373. // DECODE ROUTINES
  374. //
  375. //==========================================================================;
  376. //--------------------------------------------------------------------------;
  377. //
  378. // DWORD imaadpcmDecode4Bit_M08
  379. // DWORD imaadpcmDecode4Bit_M16
  380. // DWORD imaadpcmDecode4Bit_S08
  381. // DWORD imaadpcmDecode4Bit_S16
  382. //
  383. // Description:
  384. // These functions decode a buffer of data from ADPCM to PCM in the
  385. // specified format. The appropriate function is called once for each
  386. // ACMDM_STREAM_CONVERT message received. Note that since these
  387. // functions must share the same prototype as the encoding functions
  388. // (see acmdStreamOpen() and acmdStreamConvert() in codec.c for more
  389. // details), not all the parameters are used by these routines.
  390. //
  391. // Arguments:
  392. // HPBYTE pbSrc: Pointer to the source buffer (ADPCM data).
  393. // DWORD cbSrcLength: The length of the source buffer (in bytes).
  394. // HPBYTE pbDst: Pointer to the destination buffer (PCM data). Note
  395. // that it is assumed that the destination buffer is
  396. // large enough to hold all the encoded data; see
  397. // acmdStreamSize() in codec.c for more details.
  398. // UINT nBlockAlignment: The block alignment of the ADPCM data (in
  399. // bytes).
  400. // UINT cSamplesPerBlock: The number of samples in each ADPCM block;
  401. // not used for decoding.
  402. // int *pnStepIndexL: Pointer to the step index value (left channel)
  403. // in the STREAMINSTANCE structure; not used for
  404. // decoding.
  405. // int *pnStepIndexR: Pointer to the step index value (right channel)
  406. // in the STREAMINSTANCE structure; not used for
  407. // decoding.
  408. //
  409. // Return (DWORD): The number of bytes used in the destination buffer.
  410. //
  411. //--------------------------------------------------------------------------;
  412. DWORD FNGLOBAL imaadpcmDecode4Bit_M08
  413. (
  414. HPBYTE pbSrc,
  415. DWORD cbSrcLength,
  416. HPBYTE pbDst,
  417. UINT nBlockAlignment,
  418. UINT cSamplesPerBlock,
  419. int * pnStepIndexL,
  420. int * pnStepIndexR
  421. )
  422. {
  423. HPBYTE pbDstStart;
  424. UINT cbHeader;
  425. UINT cbBlockLength;
  426. BYTE bSample;
  427. int nStepSize;
  428. int nEncSample;
  429. int nPredSample;
  430. int nStepIndex;
  431. pbDstStart = pbDst;
  432. cbHeader = IMAADPCM_HEADER_LENGTH * 1; // 1 = number of channels.
  433. DPF(3,"Starting imaadpcmDecode4Bit_M08().");
  434. //
  435. //
  436. //
  437. while (cbSrcLength >= cbHeader)
  438. {
  439. DWORD dwHeader;
  440. cbBlockLength = (UINT)min(cbSrcLength, nBlockAlignment);
  441. cbSrcLength -= cbBlockLength;
  442. cbBlockLength -= cbHeader;
  443. //
  444. // block header
  445. //
  446. dwHeader = *(DWORD HUGE_T *)pbSrc;
  447. pbSrc += sizeof(DWORD);
  448. nPredSample = (int)(short)LOWORD(dwHeader);
  449. nStepIndex = (int)(BYTE)HIWORD(dwHeader);
  450. if( !imaadpcmValidStepIndex(nStepIndex) ) {
  451. //
  452. // The step index is out of range - this is considered a fatal
  453. // error as the input stream is corrupted. We fail by returning
  454. // zero bytes converted.
  455. //
  456. DPF(1,"imaadpcmDecode4Bit_M08: invalid step index.");
  457. return 0;
  458. }
  459. //
  460. // write out first sample
  461. //
  462. *pbDst++ = (BYTE)((nPredSample >> 8) + 128);
  463. //
  464. //
  465. //
  466. while (cbBlockLength--)
  467. {
  468. bSample = *pbSrc++;
  469. //
  470. // sample 1
  471. //
  472. nEncSample = (bSample & (BYTE)0x0F);
  473. nStepSize = step[nStepIndex];
  474. nPredSample = imaadpcmSampleDecode(nEncSample, nPredSample, nStepSize);
  475. nStepIndex = imaadpcmNextStepIndex(nEncSample, nStepIndex);
  476. //
  477. // write out sample
  478. //
  479. *pbDst++ = (BYTE)((nPredSample >> 8) + 128);
  480. //
  481. // sample 2
  482. //
  483. nEncSample = (bSample >> 4);
  484. nStepSize = step[nStepIndex];
  485. nPredSample = imaadpcmSampleDecode(nEncSample, nPredSample, nStepSize);
  486. nStepIndex = imaadpcmNextStepIndex(nEncSample, nStepIndex);
  487. //
  488. // write out sample
  489. //
  490. *pbDst++ = (BYTE)((nPredSample >> 8) + 128);
  491. }
  492. }
  493. //
  494. // We return the number of bytes used in the destination. This is
  495. // simply the difference in bytes from where we started.
  496. //
  497. return (DWORD)(pbDst - pbDstStart);
  498. } // imaadpcmDecode4Bit_M08()
  499. //--------------------------------------------------------------------------;
  500. //--------------------------------------------------------------------------;
  501. DWORD FNGLOBAL imaadpcmDecode4Bit_M16
  502. (
  503. HPBYTE pbSrc,
  504. DWORD cbSrcLength,
  505. HPBYTE pbDst,
  506. UINT nBlockAlignment,
  507. UINT cSamplesPerBlock,
  508. int * pnStepIndexL,
  509. int * pnStepIndexR
  510. )
  511. {
  512. HPBYTE pbDstStart;
  513. UINT cbHeader;
  514. UINT cbBlockLength;
  515. BYTE bSample;
  516. int nStepSize;
  517. int nEncSample;
  518. int nPredSample;
  519. int nStepIndex;
  520. pbDstStart = pbDst;
  521. cbHeader = IMAADPCM_HEADER_LENGTH * 1; // 1 = number of channels.
  522. DPF(3,"Starting imaadpcmDecode4Bit_M16().");
  523. //
  524. //
  525. //
  526. while (cbSrcLength >= cbHeader)
  527. {
  528. DWORD dwHeader;
  529. cbBlockLength = (UINT)min(cbSrcLength, nBlockAlignment);
  530. cbSrcLength -= cbBlockLength;
  531. cbBlockLength -= cbHeader;
  532. //
  533. // block header
  534. //
  535. dwHeader = *(DWORD HUGE_T *)pbSrc;
  536. pbSrc += sizeof(DWORD);
  537. nPredSample = (int)(short)LOWORD(dwHeader);
  538. nStepIndex = (int)(BYTE)HIWORD(dwHeader);
  539. if( !imaadpcmValidStepIndex(nStepIndex) ) {
  540. //
  541. // The step index is out of range - this is considered a fatal
  542. // error as the input stream is corrupted. We fail by returning
  543. // zero bytes converted.
  544. //
  545. DPF(1,"imaadpcmDecode4Bit_M16: invalid step index.");
  546. return 0;
  547. }
  548. //
  549. // write out first sample
  550. //
  551. *(short HUGE_T *)pbDst = (short)nPredSample;
  552. pbDst += sizeof(short);
  553. //
  554. //
  555. //
  556. while (cbBlockLength--)
  557. {
  558. bSample = *pbSrc++;
  559. //
  560. // sample 1
  561. //
  562. nEncSample = (bSample & (BYTE)0x0F);
  563. nStepSize = step[nStepIndex];
  564. nPredSample = imaadpcmSampleDecode(nEncSample, nPredSample, nStepSize);
  565. nStepIndex = imaadpcmNextStepIndex(nEncSample, nStepIndex);
  566. //
  567. // write out sample
  568. //
  569. *(short HUGE_T *)pbDst = (short)nPredSample;
  570. pbDst += sizeof(short);
  571. //
  572. // sample 2
  573. //
  574. nEncSample = (bSample >> 4);
  575. nStepSize = step[nStepIndex];
  576. nPredSample = imaadpcmSampleDecode(nEncSample, nPredSample, nStepSize);
  577. nStepIndex = imaadpcmNextStepIndex(nEncSample, nStepIndex);
  578. //
  579. // write out sample
  580. //
  581. *(short HUGE_T *)pbDst = (short)nPredSample;
  582. pbDst += sizeof(short);
  583. }
  584. }
  585. //
  586. // We return the number of bytes used in the destination. This is
  587. // simply the difference in bytes from where we started.
  588. //
  589. return (DWORD)(pbDst - pbDstStart);
  590. } // imaadpcmDecode4Bit_M16()
  591. //--------------------------------------------------------------------------;
  592. //--------------------------------------------------------------------------;
  593. DWORD FNGLOBAL imaadpcmDecode4Bit_S08
  594. (
  595. HPBYTE pbSrc,
  596. DWORD cbSrcLength,
  597. HPBYTE pbDst,
  598. UINT nBlockAlignment,
  599. UINT cSamplesPerBlock,
  600. int * pnStepIndexL,
  601. int * pnStepIndexR
  602. )
  603. {
  604. HPBYTE pbDstStart;
  605. UINT cbHeader;
  606. UINT cbBlockLength;
  607. int nStepSize;
  608. DWORD dwHeader;
  609. DWORD dwLeft;
  610. DWORD dwRight;
  611. int i;
  612. int nEncSampleL;
  613. int nPredSampleL;
  614. int nStepIndexL;
  615. int nEncSampleR;
  616. int nPredSampleR;
  617. int nStepIndexR;
  618. pbDstStart = pbDst;
  619. cbHeader = IMAADPCM_HEADER_LENGTH * 2; // 2 = number of channels.
  620. DPF(3,"Starting imaadpcmDecode4Bit_S08().");
  621. //
  622. //
  623. //
  624. while( 0 != cbSrcLength )
  625. {
  626. //
  627. // The data should always be block aligned.
  628. //
  629. ASSERT( cbSrcLength >= nBlockAlignment );
  630. cbBlockLength = nBlockAlignment;
  631. cbSrcLength -= cbBlockLength;
  632. cbBlockLength -= cbHeader;
  633. //
  634. // LEFT channel header
  635. //
  636. dwHeader = *(DWORD HUGE_T *)pbSrc;
  637. pbSrc += sizeof(DWORD);
  638. nPredSampleL = (int)(short)LOWORD(dwHeader);
  639. nStepIndexL = (int)(BYTE)HIWORD(dwHeader);
  640. if( !imaadpcmValidStepIndex(nStepIndexL) ) {
  641. //
  642. // The step index is out of range - this is considered a fatal
  643. // error as the input stream is corrupted. We fail by returning
  644. // zero bytes converted.
  645. //
  646. DPF(1,"imaadpcmDecode4Bit_S08: invalid step index (L).");
  647. return 0;
  648. }
  649. //
  650. // RIGHT channel header
  651. //
  652. dwHeader = *(DWORD HUGE_T *)pbSrc;
  653. pbSrc += sizeof(DWORD);
  654. nPredSampleR = (int)(short)LOWORD(dwHeader);
  655. nStepIndexR = (int)(BYTE)HIWORD(dwHeader);
  656. if( !imaadpcmValidStepIndex(nStepIndexR) ) {
  657. //
  658. // The step index is out of range - this is considered a fatal
  659. // error as the input stream is corrupted. We fail by returning
  660. // zero bytes converted.
  661. //
  662. DPF(1,"imaadpcmDecode4Bit_S08: invalid step index (R).");
  663. return 0;
  664. }
  665. //
  666. // write out first sample
  667. //
  668. *pbDst++ = (BYTE)((nPredSampleL >> 8) + 128);
  669. *pbDst++ = (BYTE)((nPredSampleR >> 8) + 128);
  670. //
  671. // The first DWORD contains 4 left samples, the second DWORD
  672. // contains 4 right samples. We process the source in 8-byte
  673. // chunks to make it easy to interleave the output correctly.
  674. //
  675. ASSERT( 0 == cbBlockLength%8 );
  676. while( 0 != cbBlockLength )
  677. {
  678. cbBlockLength -= 8;
  679. dwLeft = *(DWORD HUGE_T *)pbSrc;
  680. pbSrc += sizeof(DWORD);
  681. dwRight = *(DWORD HUGE_T *)pbSrc;
  682. pbSrc += sizeof(DWORD);
  683. for( i=8; i>0; i-- )
  684. {
  685. //
  686. // LEFT channel
  687. //
  688. nEncSampleL = (dwLeft & 0x0F);
  689. nStepSize = step[nStepIndexL];
  690. nPredSampleL = imaadpcmSampleDecode(nEncSampleL, nPredSampleL, nStepSize);
  691. nStepIndexL = imaadpcmNextStepIndex(nEncSampleL, nStepIndexL);
  692. //
  693. // RIGHT channel
  694. //
  695. nEncSampleR = (dwRight & 0x0F);
  696. nStepSize = step[nStepIndexR];
  697. nPredSampleR = imaadpcmSampleDecode(nEncSampleR, nPredSampleR, nStepSize);
  698. nStepIndexR = imaadpcmNextStepIndex(nEncSampleR, nStepIndexR);
  699. //
  700. // write out sample
  701. //
  702. *pbDst++ = (BYTE)((nPredSampleL >> 8) + 128);
  703. *pbDst++ = (BYTE)((nPredSampleR >> 8) + 128);
  704. //
  705. // Shift the next input sample into the low-order 4 bits.
  706. //
  707. dwLeft >>= 4;
  708. dwRight >>= 4;
  709. }
  710. }
  711. }
  712. //
  713. // We return the number of bytes used in the destination. This is
  714. // simply the difference in bytes from where we started.
  715. //
  716. return (DWORD)(pbDst - pbDstStart);
  717. } // imaadpcmDecode4Bit_S08()
  718. //--------------------------------------------------------------------------;
  719. //--------------------------------------------------------------------------;
  720. DWORD FNGLOBAL imaadpcmDecode4Bit_S16
  721. (
  722. HPBYTE pbSrc,
  723. DWORD cbSrcLength,
  724. HPBYTE pbDst,
  725. UINT nBlockAlignment,
  726. UINT cSamplesPerBlock,
  727. int * pnStepIndexL,
  728. int * pnStepIndexR
  729. )
  730. {
  731. HPBYTE pbDstStart;
  732. UINT cbHeader;
  733. UINT cbBlockLength;
  734. int nStepSize;
  735. DWORD dwHeader;
  736. DWORD dwLeft;
  737. DWORD dwRight;
  738. int i;
  739. int nEncSampleL;
  740. int nPredSampleL;
  741. int nStepIndexL;
  742. int nEncSampleR;
  743. int nPredSampleR;
  744. int nStepIndexR;
  745. pbDstStart = pbDst;
  746. cbHeader = IMAADPCM_HEADER_LENGTH * 2; // 2 = number of channels.
  747. DPF(3,"Starting imaadpcmDecode4Bit_S16().");
  748. //
  749. //
  750. //
  751. while( 0 != cbSrcLength )
  752. {
  753. //
  754. // The data should always be block aligned.
  755. //
  756. ASSERT( cbSrcLength >= nBlockAlignment );
  757. cbBlockLength = nBlockAlignment;
  758. cbSrcLength -= cbBlockLength;
  759. cbBlockLength -= cbHeader;
  760. //
  761. // LEFT channel header
  762. //
  763. dwHeader = *(DWORD HUGE_T *)pbSrc;
  764. pbSrc += sizeof(DWORD);
  765. nPredSampleL = (int)(short)LOWORD(dwHeader);
  766. nStepIndexL = (int)(BYTE)HIWORD(dwHeader);
  767. if( !imaadpcmValidStepIndex(nStepIndexL) ) {
  768. //
  769. // The step index is out of range - this is considered a fatal
  770. // error as the input stream is corrupted. We fail by returning
  771. // zero bytes converted.
  772. //
  773. DPF(1,"imaadpcmDecode4Bit_S16: invalid step index %u (L).", nStepIndexL);
  774. return 0;
  775. }
  776. //
  777. // RIGHT channel header
  778. //
  779. dwHeader = *(DWORD HUGE_T *)pbSrc;
  780. pbSrc += sizeof(DWORD);
  781. nPredSampleR = (int)(short)LOWORD(dwHeader);
  782. nStepIndexR = (int)(BYTE)HIWORD(dwHeader);
  783. if( !imaadpcmValidStepIndex(nStepIndexR) ) {
  784. //
  785. // The step index is out of range - this is considered a fatal
  786. // error as the input stream is corrupted. We fail by returning
  787. // zero bytes converted.
  788. //
  789. DPF(1,"imaadpcmDecode4Bit_S16: invalid step index %u (R).",nStepIndexR);
  790. return 0;
  791. }
  792. //
  793. // write out first sample
  794. //
  795. *(DWORD HUGE_T *)pbDst = MAKELONG(nPredSampleL, nPredSampleR);
  796. pbDst += sizeof(DWORD);
  797. //
  798. // The first DWORD contains 4 left samples, the second DWORD
  799. // contains 4 right samples. We process the source in 8-byte
  800. // chunks to make it easy to interleave the output correctly.
  801. //
  802. ASSERT( 0 == cbBlockLength%8 );
  803. while( 0 != cbBlockLength )
  804. {
  805. cbBlockLength -= 8;
  806. dwLeft = *(DWORD HUGE_T *)pbSrc;
  807. pbSrc += sizeof(DWORD);
  808. dwRight = *(DWORD HUGE_T *)pbSrc;
  809. pbSrc += sizeof(DWORD);
  810. for( i=8; i>0; i-- )
  811. {
  812. //
  813. // LEFT channel
  814. //
  815. nEncSampleL = (dwLeft & 0x0F);
  816. nStepSize = step[nStepIndexL];
  817. nPredSampleL = imaadpcmSampleDecode(nEncSampleL, nPredSampleL, nStepSize);
  818. nStepIndexL = imaadpcmNextStepIndex(nEncSampleL, nStepIndexL);
  819. //
  820. // RIGHT channel
  821. //
  822. nEncSampleR = (dwRight & 0x0F);
  823. nStepSize = step[nStepIndexR];
  824. nPredSampleR = imaadpcmSampleDecode(nEncSampleR, nPredSampleR, nStepSize);
  825. nStepIndexR = imaadpcmNextStepIndex(nEncSampleR, nStepIndexR);
  826. //
  827. // write out sample
  828. //
  829. *(DWORD HUGE_T *)pbDst = MAKELONG(nPredSampleL, nPredSampleR);
  830. pbDst += sizeof(DWORD);
  831. //
  832. // Shift the next input sample into the low-order 4 bits.
  833. //
  834. dwLeft >>= 4;
  835. dwRight >>= 4;
  836. }
  837. }
  838. }
  839. //
  840. // We return the number of bytes used in the destination. This is
  841. // simply the difference in bytes from where we started.
  842. //
  843. return (DWORD)(pbDst - pbDstStart);
  844. } // imaadpcmDecode4Bit_S16()
  845. //==========================================================================;
  846. //
  847. // ENCODE ROUTINES
  848. //
  849. //==========================================================================;
  850. //--------------------------------------------------------------------------;
  851. //
  852. // DWORD imaadpcmEncode4Bit_M08
  853. // DWORD imaadpcmEncode4Bit_M16
  854. // DWORD imaadpcmEncode4Bit_S08
  855. // DWORD imaadpcmEncode4Bit_S16
  856. //
  857. // Description:
  858. // These functions encode a buffer of data from PCM to ADPCM in the
  859. // specified format. The appropriate function is called once for each
  860. // ACMDM_STREAM_CONVERT message received. Note that since these
  861. // functions must share the same prototype as the decoding functions
  862. // (see acmdStreamOpen() and acmdStreamConvert() in codec.c for more
  863. // details), not all the parameters are used by these routines.
  864. //
  865. // Arguments:
  866. // HPBYTE pbSrc: Pointer to the source buffer (PCM data).
  867. // DWORD cbSrcLength: The length of the source buffer (in bytes).
  868. // HPBYTE pbDst: Pointer to the destination buffer (ADPCM data). Note
  869. // that it is assumed that the destination buffer is
  870. // large enough to hold all the encoded data; see
  871. // acmdStreamSize() in codec.c for more details.
  872. // UINT nBlockAlignment: The block alignment of the ADPCM data (in
  873. // bytes); not used for encoding.
  874. // UINT cSamplesPerBlock: The number of samples in each ADPCM block.
  875. // int *pnStepIndexL: Pointer to the step index value (left channel)
  876. // in the STREAMINSTANCE structure; this is used to
  877. // maintain the step index across converts.
  878. // int *pnStepIndexR: Pointer to the step index value (right channel)
  879. // in the STREAMINSTANCE structure; this is used to
  880. // maintain the step index across converts. It is only
  881. // used for stereo converts.
  882. //
  883. // Return (DWORD): The number of bytes used in the destination buffer.
  884. //
  885. //--------------------------------------------------------------------------;
  886. DWORD FNGLOBAL imaadpcmEncode4Bit_M08
  887. (
  888. HPBYTE pbSrc,
  889. DWORD cbSrcLength,
  890. HPBYTE pbDst,
  891. UINT nBlockAlignment,
  892. UINT cSamplesPerBlock,
  893. int * pnStepIndexL,
  894. int * pnStepIndexR
  895. )
  896. {
  897. HPBYTE pbDstStart;
  898. DWORD cSrcSamples;
  899. UINT cBlockSamples;
  900. int nSample;
  901. int nStepSize;
  902. int nEncSample1;
  903. int nEncSample2;
  904. int nPredSample;
  905. int nStepIndex;
  906. pbDstStart = pbDst;
  907. cSrcSamples = pcmM08BytesToSamples(cbSrcLength);
  908. //
  909. // Restore the Step Index to that of the final convert of the previous
  910. // buffer. Remember to restore this value to psi->nStepIndexL.
  911. //
  912. nStepIndex = (*pnStepIndexL);
  913. //
  914. //
  915. //
  916. //
  917. while (0 != cSrcSamples)
  918. {
  919. cBlockSamples = (UINT)min(cSrcSamples, cSamplesPerBlock);
  920. cSrcSamples -= cBlockSamples;
  921. //
  922. // block header
  923. //
  924. nPredSample = ((short)*pbSrc++ - 128) << 8;
  925. cBlockSamples--;
  926. *(LONG HUGE_T *)pbDst = MAKELONG(nPredSample, nStepIndex);
  927. pbDst += sizeof(LONG);
  928. //
  929. // We have written the header for this block--now write the data
  930. // chunk (which consists of a bunch of encoded nibbles). Note
  931. // that if we don't have enough data to fill a complete byte, then
  932. // we add a 0 nibble on the end.
  933. //
  934. while( cBlockSamples>0 )
  935. {
  936. //
  937. // sample 1
  938. //
  939. nSample = ((short)*pbSrc++ - 128) << 8;
  940. cBlockSamples--;
  941. nStepSize = step[nStepIndex];
  942. imaadpcmFastEncode(nEncSample1,nPredSample,nSample,nStepSize);
  943. nStepIndex = imaadpcmNextStepIndex(nEncSample1, nStepIndex);
  944. //
  945. // sample 2
  946. //
  947. nEncSample2 = 0;
  948. if( cBlockSamples>0 ) {
  949. nSample = ((short)*pbSrc++ - 128) << 8;
  950. cBlockSamples--;
  951. nStepSize = step[nStepIndex];
  952. imaadpcmFastEncode(nEncSample2,nPredSample,nSample,nStepSize);
  953. nStepIndex = imaadpcmNextStepIndex(nEncSample2, nStepIndex);
  954. }
  955. //
  956. // Write out encoded byte.
  957. //
  958. *pbDst++ = (BYTE)(nEncSample1 | (nEncSample2 << 4));
  959. }
  960. }
  961. //
  962. // Restore the value of the Step Index, to be used on the next buffer.
  963. //
  964. (*pnStepIndexL) = nStepIndex;
  965. //
  966. // We return the number of bytes used in the destination. This is
  967. // simply the difference in bytes from where we started.
  968. //
  969. return (DWORD)(pbDst - pbDstStart);
  970. } // imaadpcmEncode4Bit_M08()
  971. //--------------------------------------------------------------------------;
  972. //--------------------------------------------------------------------------;
  973. DWORD FNGLOBAL imaadpcmEncode4Bit_M16
  974. (
  975. HPBYTE pbSrc,
  976. DWORD cbSrcLength,
  977. HPBYTE pbDst,
  978. UINT nBlockAlignment,
  979. UINT cSamplesPerBlock,
  980. int * pnStepIndexL,
  981. int * pnStepIndexR
  982. )
  983. {
  984. HPBYTE pbDstStart;
  985. DWORD cSrcSamples;
  986. UINT cBlockSamples;
  987. int nSample;
  988. int nStepSize;
  989. int nEncSample1;
  990. int nEncSample2;
  991. int nPredSample;
  992. int nStepIndex;
  993. pbDstStart = pbDst;
  994. cSrcSamples = pcmM16BytesToSamples(cbSrcLength);
  995. //
  996. // Restore the Step Index to that of the final convert of the previous
  997. // buffer. Remember to restore this value to psi->nStepIndexL.
  998. //
  999. nStepIndex = (*pnStepIndexL);
  1000. //
  1001. //
  1002. //
  1003. //
  1004. while (0 != cSrcSamples)
  1005. {
  1006. cBlockSamples = (UINT)min(cSrcSamples, cSamplesPerBlock);
  1007. cSrcSamples -= cBlockSamples;
  1008. //
  1009. // block header
  1010. //
  1011. nPredSample = *(short HUGE_T *)pbSrc;
  1012. pbSrc += sizeof(short);
  1013. cBlockSamples--;
  1014. *(LONG HUGE_T *)pbDst = MAKELONG(nPredSample, nStepIndex);
  1015. pbDst += sizeof(LONG);
  1016. //
  1017. // We have written the header for this block--now write the data
  1018. // chunk (which consists of a bunch of encoded nibbles). Note
  1019. // that if we don't have enough data to fill a complete byte, then
  1020. // we add a 0 nibble on the end.
  1021. //
  1022. while( cBlockSamples>0 )
  1023. {
  1024. //
  1025. // sample 1
  1026. //
  1027. nSample = *(short HUGE_T *)pbSrc;
  1028. pbSrc += sizeof(short);
  1029. cBlockSamples--;
  1030. nStepSize = step[nStepIndex];
  1031. imaadpcmFastEncode(nEncSample1,nPredSample,nSample,nStepSize);
  1032. nStepIndex = imaadpcmNextStepIndex(nEncSample1, nStepIndex);
  1033. //
  1034. // sample 2
  1035. //
  1036. nEncSample2 = 0;
  1037. if( cBlockSamples>0 ) {
  1038. nSample = *(short HUGE_T *)pbSrc;
  1039. pbSrc += sizeof(short);
  1040. cBlockSamples--;
  1041. nStepSize = step[nStepIndex];
  1042. imaadpcmFastEncode(nEncSample2,nPredSample,nSample,nStepSize);
  1043. nStepIndex = imaadpcmNextStepIndex(nEncSample2, nStepIndex);
  1044. }
  1045. //
  1046. // Write out encoded byte.
  1047. //
  1048. *pbDst++ = (BYTE)(nEncSample1 | (nEncSample2 << 4));
  1049. }
  1050. }
  1051. //
  1052. // Restore the value of the Step Index, to be used on the next buffer.
  1053. //
  1054. (*pnStepIndexL) = nStepIndex;
  1055. //
  1056. // We return the number of bytes used in the destination. This is
  1057. // simply the difference in bytes from where we started.
  1058. //
  1059. return (DWORD)(pbDst - pbDstStart);
  1060. } // imaadpcmEncode4Bit_M16()
  1061. //--------------------------------------------------------------------------;
  1062. //--------------------------------------------------------------------------;
  1063. DWORD FNGLOBAL imaadpcmEncode4Bit_S08
  1064. (
  1065. HPBYTE pbSrc,
  1066. DWORD cbSrcLength,
  1067. HPBYTE pbDst,
  1068. UINT nBlockAlignment,
  1069. UINT cSamplesPerBlock,
  1070. int * pnStepIndexL,
  1071. int * pnStepIndexR
  1072. )
  1073. {
  1074. HPBYTE pbDstStart;
  1075. DWORD cSrcSamples;
  1076. UINT cBlockSamples;
  1077. int nSample;
  1078. int nStepSize;
  1079. DWORD dwLeft;
  1080. DWORD dwRight;
  1081. int i;
  1082. int nEncSampleL;
  1083. int nPredSampleL;
  1084. int nStepIndexL;
  1085. int nEncSampleR;
  1086. int nPredSampleR;
  1087. int nStepIndexR;
  1088. pbDstStart = pbDst;
  1089. cSrcSamples = pcmS08BytesToSamples(cbSrcLength);
  1090. //
  1091. // Restore the Step Index to that of the final convert of the previous
  1092. // buffer. Remember to restore this value to psi->nStepIndexL,R.
  1093. //
  1094. nStepIndexL = (*pnStepIndexL);
  1095. nStepIndexR = (*pnStepIndexR);
  1096. //
  1097. //
  1098. //
  1099. //
  1100. while( 0 != cSrcSamples )
  1101. {
  1102. //
  1103. // The samples should always be block aligned.
  1104. //
  1105. ASSERT( cSrcSamples >= cSamplesPerBlock );
  1106. cBlockSamples = cSamplesPerBlock;
  1107. cSrcSamples -= cBlockSamples;
  1108. //
  1109. // LEFT channel block header
  1110. //
  1111. nPredSampleL = ((short)*pbSrc++ - 128) << 8;
  1112. *(LONG HUGE_T *)pbDst = MAKELONG(nPredSampleL, nStepIndexL);
  1113. pbDst += sizeof(LONG);
  1114. //
  1115. // RIGHT channel block header
  1116. //
  1117. nPredSampleR = ((short)*pbSrc++ - 128) << 8;
  1118. *(LONG HUGE_T *)pbDst = MAKELONG(nPredSampleR, nStepIndexR);
  1119. pbDst += sizeof(LONG);
  1120. cBlockSamples--; // One sample is in the header.
  1121. //
  1122. // We have written the header for this block--now write the data
  1123. // chunk. This consists of 8 left samples (one DWORD of output)
  1124. // followed by 8 right samples (also one DWORD). Since the input
  1125. // samples are interleaved, we create the left and right DWORDs
  1126. // sample by sample, and then write them both out.
  1127. //
  1128. ASSERT( 0 == cBlockSamples%8 );
  1129. while( 0 != cBlockSamples )
  1130. {
  1131. cBlockSamples -= 8;
  1132. dwLeft = 0;
  1133. dwRight = 0;
  1134. for( i=0; i<8; i++ )
  1135. {
  1136. //
  1137. // LEFT channel
  1138. //
  1139. nSample = ((short)*pbSrc++ - 128) << 8;
  1140. nStepSize = step[nStepIndexL];
  1141. imaadpcmFastEncode(nEncSampleL,nPredSampleL,nSample,nStepSize);
  1142. nStepIndexL = imaadpcmNextStepIndex(nEncSampleL, nStepIndexL);
  1143. dwLeft |= ((DWORD)nEncSampleL) << 4*i;
  1144. //
  1145. // RIGHT channel
  1146. //
  1147. nSample = ((short)*pbSrc++ - 128) << 8;
  1148. nStepSize = step[nStepIndexR];
  1149. imaadpcmFastEncode(nEncSampleR,nPredSampleR,nSample,nStepSize);
  1150. nStepIndexR = imaadpcmNextStepIndex(nEncSampleR, nStepIndexR);
  1151. dwRight |= ((DWORD)nEncSampleR) << 4*i;
  1152. }
  1153. //
  1154. // Write out encoded DWORDs.
  1155. //
  1156. *(DWORD HUGE_T *)pbDst = dwLeft;
  1157. pbDst += sizeof(DWORD);
  1158. *(DWORD HUGE_T *)pbDst = dwRight;
  1159. pbDst += sizeof(DWORD);
  1160. }
  1161. }
  1162. //
  1163. // Restore the value of the Step Index, to be used on the next buffer.
  1164. //
  1165. (*pnStepIndexL) = nStepIndexL;
  1166. (*pnStepIndexR) = nStepIndexR;
  1167. //
  1168. // We return the number of bytes used in the destination. This is
  1169. // simply the difference in bytes from where we started.
  1170. //
  1171. return (DWORD)(pbDst - pbDstStart);
  1172. } // imaadpcmEncode4Bit_S08()
  1173. //--------------------------------------------------------------------------;
  1174. //--------------------------------------------------------------------------;
  1175. DWORD FNGLOBAL imaadpcmEncode4Bit_S16
  1176. (
  1177. HPBYTE pbSrc,
  1178. DWORD cbSrcLength,
  1179. HPBYTE pbDst,
  1180. UINT nBlockAlignment,
  1181. UINT cSamplesPerBlock,
  1182. int * pnStepIndexL,
  1183. int * pnStepIndexR
  1184. )
  1185. {
  1186. HPBYTE pbDstStart;
  1187. DWORD cSrcSamples;
  1188. UINT cBlockSamples;
  1189. int nSample;
  1190. int nStepSize;
  1191. DWORD dwLeft;
  1192. DWORD dwRight;
  1193. int i;
  1194. int nEncSampleL;
  1195. int nPredSampleL;
  1196. int nStepIndexL;
  1197. int nEncSampleR;
  1198. int nPredSampleR;
  1199. int nStepIndexR;
  1200. pbDstStart = pbDst;
  1201. cSrcSamples = pcmS16BytesToSamples(cbSrcLength);
  1202. //
  1203. // Restore the Step Index to that of the final convert of the previous
  1204. // buffer. Remember to restore this value to psi->nStepIndexL,R.
  1205. //
  1206. nStepIndexL = (*pnStepIndexL);
  1207. nStepIndexR = (*pnStepIndexR);
  1208. //
  1209. //
  1210. //
  1211. //
  1212. while( 0 != cSrcSamples )
  1213. {
  1214. //
  1215. // The samples should always be block aligned.
  1216. //
  1217. ASSERT( cSrcSamples >= cSamplesPerBlock );
  1218. cBlockSamples = cSamplesPerBlock;
  1219. cSrcSamples -= cBlockSamples;
  1220. //
  1221. // LEFT channel block header
  1222. //
  1223. nPredSampleL = *(short HUGE_T *)pbSrc;
  1224. pbSrc += sizeof(short);
  1225. *(LONG HUGE_T *)pbDst = MAKELONG(nPredSampleL, nStepIndexL);
  1226. pbDst += sizeof(LONG);
  1227. //
  1228. // RIGHT channel block header
  1229. //
  1230. nPredSampleR = *(short HUGE_T *)pbSrc;
  1231. pbSrc += sizeof(short);
  1232. *(LONG HUGE_T *)pbDst = MAKELONG(nPredSampleR, nStepIndexR);
  1233. pbDst += sizeof(LONG);
  1234. cBlockSamples--; // One sample is in the header.
  1235. //
  1236. // We have written the header for this block--now write the data
  1237. // chunk. This consists of 8 left samples (one DWORD of output)
  1238. // followed by 8 right samples (also one DWORD). Since the input
  1239. // samples are interleaved, we create the left and right DWORDs
  1240. // sample by sample, and then write them both out.
  1241. //
  1242. ASSERT( 0 == cBlockSamples%8 );
  1243. while( 0 != cBlockSamples )
  1244. {
  1245. cBlockSamples -= 8;
  1246. dwLeft = 0;
  1247. dwRight = 0;
  1248. for( i=0; i<8; i++ )
  1249. {
  1250. //
  1251. // LEFT channel
  1252. //
  1253. nSample = *(short HUGE_T *)pbSrc;
  1254. pbSrc += sizeof(short);
  1255. nStepSize = step[nStepIndexL];
  1256. imaadpcmFastEncode(nEncSampleL,nPredSampleL,nSample,nStepSize);
  1257. nStepIndexL = imaadpcmNextStepIndex(nEncSampleL, nStepIndexL);
  1258. dwLeft |= ((DWORD)nEncSampleL) << 4*i;
  1259. //
  1260. // RIGHT channel
  1261. //
  1262. nSample = *(short HUGE_T *)pbSrc;
  1263. pbSrc += sizeof(short);
  1264. nStepSize = step[nStepIndexR];
  1265. imaadpcmFastEncode(nEncSampleR,nPredSampleR,nSample,nStepSize);
  1266. nStepIndexR = imaadpcmNextStepIndex(nEncSampleR, nStepIndexR);
  1267. dwRight |= ((DWORD)nEncSampleR) << 4*i;
  1268. }
  1269. //
  1270. // Write out encoded DWORDs.
  1271. //
  1272. *(DWORD HUGE_T *)pbDst = dwLeft;
  1273. pbDst += sizeof(DWORD);
  1274. *(DWORD HUGE_T *)pbDst = dwRight;
  1275. pbDst += sizeof(DWORD);
  1276. }
  1277. }
  1278. //
  1279. // Restore the value of the Step Index, to be used on the next buffer.
  1280. //
  1281. (*pnStepIndexL) = nStepIndexL;
  1282. (*pnStepIndexR) = nStepIndexR;
  1283. //
  1284. // We return the number of bytes used in the destination. This is
  1285. // simply the difference in bytes from where we started.
  1286. //
  1287. return (DWORD)(pbDst - pbDstStart);
  1288. } // imaadpcmEncode4Bit_S16()