Team Fortress 2 Source Code as on 22/4/2020
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.

153 lines
5.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. /***************************************************************************
  3. *
  4. * Copyright (C) 2001 Microsoft Corporation. All Rights Reserved.
  5. *
  6. * File: imaadpcm.h
  7. * Content: IMA ADPCM CODEC.
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 04/29/01 dereks Created.
  12. *
  13. ****************************************************************************/
  14. #ifndef __IMAADPCM_H__
  15. #define __IMAADPCM_H__
  16. #include <windows.h>
  17. #include <windowsx.h>
  18. #include <mmsystem.h>
  19. #include <ctype.h>
  20. #include <mmreg.h>
  21. #include <msacm.h>
  22. #define XBOX_ADPCM_SAMPLES_PER_BLOCK 64
  23. #define WAVE_FORMAT_XBOX_ADPCM 0x0069
  24. #define IMAADPCM_BITS_PER_SAMPLE 4
  25. #define IMAADPCM_HEADER_LENGTH 4
  26. #define IMAADPCM_MAX_CHANNELS 2
  27. #define IMAADPCM_PCM_BITS_PER_SAMPLE 16
  28. #define NUMELMS(a) (sizeof(a) / sizeof(a[0]))
  29. typedef const WAVEFORMATEX *LPCWAVEFORMATEX;
  30. typedef const IMAADPCMWAVEFORMAT *LPCIMAADPCMWAVEFORMAT;
  31. #ifdef __cplusplus
  32. //
  33. // IMA ADPCM encoder function prototype
  34. //
  35. typedef BOOL (*LPFNIMAADPCMCONVERT)(LPBYTE pbSrc, LPBYTE pbDst, UINT cBlocks, UINT nBlockAlignment, UINT cSamplesPerBlock, LPINT pnStepIndexL, LPINT pnStepIndexR);
  36. //
  37. // Codec mode
  38. //
  39. enum CODEC_MODE
  40. {
  41. CODEC_MODE_DECODE,
  42. CODEC_MODE_ENCODE_NORMAL,
  43. CODEC_MODE_ENCODE_OPTIMIZE_WHOLE_FILE,
  44. CODEC_MODE_ENCODE_OPTIMIZE_EACH_BLOCK,
  45. };
  46. //
  47. // IMA ADPCM CODEC
  48. //
  49. class CImaAdpcmCodec
  50. {
  51. private:
  52. static const short m_asNextStep[16]; // Step increment array
  53. static const short m_asStep[89]; // Step value array
  54. IMAADPCMWAVEFORMAT m_wfxEncode; // Encoded format description
  55. CODEC_MODE m_cmCodecMode; // Codec mode
  56. int m_nStepIndexL; // Left-channel stepping index
  57. int m_nStepIndexR; // Right-channel stepping index
  58. LPFNIMAADPCMCONVERT m_pfnConvert; // Conversion function
  59. public:
  60. CImaAdpcmCodec(void);
  61. ~CImaAdpcmCodec(void);
  62. public:
  63. // Initialization
  64. BOOL Initialize(LPCIMAADPCMWAVEFORMAT pwfxEncode, CODEC_MODE cmCodecMode);
  65. // Size conversions
  66. WORD GetEncodeAlignment(void);
  67. WORD GetDecodeAlignment(void);
  68. WORD GetSourceAlignment(void);
  69. WORD GetDestinationAlignment(void);
  70. // Data conversions
  71. BOOL Convert(LPCVOID pvSrc, LPVOID pvDst, UINT cBlocks);
  72. void Reset(void);
  73. // Format descriptions
  74. static void CreatePcmFormat(WORD nChannels, DWORD nSamplesPerSec, LPWAVEFORMATEX pwfxFormat);
  75. static void CreateImaAdpcmFormat(WORD nChannels, DWORD nSamplesPerSec, WORD nSamplesPerBlock, LPIMAADPCMWAVEFORMAT pwfxFormat);
  76. static BOOL IsValidPcmFormat(LPCWAVEFORMATEX pwfxFormat);
  77. static BOOL IsValidImaAdpcmFormat(LPCIMAADPCMWAVEFORMAT pwfxFormat);
  78. private:
  79. // En/decoded data alignment
  80. static WORD CalculateEncodeAlignment(WORD nSamplesPerBlock, WORD nChannels);
  81. // Data conversion functions
  82. static BOOL EncodeM16(LPBYTE pbSrc, LPBYTE pbDst, UINT cBlocks, UINT nBlockAlignment, UINT cSamplesPerBlock, LPINT pnStepIndexL, LPINT pnStepIndexR);
  83. static BOOL EncodeS16(LPBYTE pbSrc, LPBYTE pbDst, UINT cBlocks, UINT nBlockAlignment, UINT cSamplesPerBlock, LPINT pnStepIndexL, LPINT pnStepIndexR);
  84. static BOOL DecodeM16(LPBYTE pbSrc, LPBYTE pbDst, UINT cBlocks, UINT nBlockAlignment, UINT cSamplesPerBlock, LPINT pnStepIndexL, LPINT pnStepIndexR);
  85. static BOOL DecodeS16(LPBYTE pbSrc, LPBYTE pbDst, UINT cBlocks, UINT nBlockAlignment, UINT cSamplesPerBlock, LPINT pnStepIndexL, LPINT pnStepIndexR);
  86. static int EncodeSample(int nInputSample, int *nPredictedSample, int nStepSize);
  87. static int DecodeSample(int nInputSample, int nPredictedSample, int nStepSize);
  88. static int NextStepIndex(int nEncodedSample, int nStepIndex);
  89. static BOOL ValidStepIndex(int nStepIndex);
  90. /*static ULONGLONG CalcDifference(LPDWORD pvBuffer1, LPDWORD pvBuffer2, DWORD dwLength);*/
  91. ULONGLONG CalcDifference(LPBYTE pvBuffer1, LPBYTE pvBuffer2, UINT cBlocks, UINT cTotalBlocks, DWORD dwBlockSize);
  92. };
  93. __inline WORD CImaAdpcmCodec::GetSourceAlignment(void)
  94. {
  95. return ( m_cmCodecMode == CODEC_MODE_DECODE ) ? GetEncodeAlignment() : GetDecodeAlignment();
  96. }
  97. __inline WORD CImaAdpcmCodec::GetDestinationAlignment(void)
  98. {
  99. return ( m_cmCodecMode == CODEC_MODE_DECODE ) ? GetDecodeAlignment() : GetEncodeAlignment();
  100. }
  101. __inline int CImaAdpcmCodec::NextStepIndex(int nEncodedSample, int nStepIndex)
  102. {
  103. nStepIndex += m_asNextStep[nEncodedSample];
  104. if(nStepIndex < 0)
  105. {
  106. nStepIndex = 0;
  107. }
  108. else if(nStepIndex >= NUMELMS(m_asStep))
  109. {
  110. nStepIndex = NUMELMS(m_asStep) - 1;
  111. }
  112. return nStepIndex;
  113. }
  114. __inline BOOL CImaAdpcmCodec::ValidStepIndex(int nStepIndex)
  115. {
  116. return (nStepIndex >= 0) && (nStepIndex < NUMELMS(m_asStep));
  117. }
  118. #endif // __cplusplus
  119. #endif // __IMAADPCM_H__