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
153 lines
5.0 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
/*************************************************************************** |
|
* |
|
* Copyright (C) 2001 Microsoft Corporation. All Rights Reserved. |
|
* |
|
* File: imaadpcm.h |
|
* Content: IMA ADPCM CODEC. |
|
* History: |
|
* Date By Reason |
|
* ==== == ====== |
|
* 04/29/01 dereks Created. |
|
* |
|
****************************************************************************/ |
|
|
|
#ifndef __IMAADPCM_H__ |
|
#define __IMAADPCM_H__ |
|
|
|
#include <windows.h> |
|
#include <windowsx.h> |
|
#include <mmsystem.h> |
|
#include <ctype.h> |
|
#include <mmreg.h> |
|
#include <msacm.h> |
|
|
|
#define XBOX_ADPCM_SAMPLES_PER_BLOCK 64 |
|
|
|
#define WAVE_FORMAT_XBOX_ADPCM 0x0069 |
|
|
|
#define IMAADPCM_BITS_PER_SAMPLE 4 |
|
#define IMAADPCM_HEADER_LENGTH 4 |
|
|
|
#define IMAADPCM_MAX_CHANNELS 2 |
|
#define IMAADPCM_PCM_BITS_PER_SAMPLE 16 |
|
|
|
#define NUMELMS(a) (sizeof(a) / sizeof(a[0])) |
|
|
|
typedef const WAVEFORMATEX *LPCWAVEFORMATEX; |
|
typedef const IMAADPCMWAVEFORMAT *LPCIMAADPCMWAVEFORMAT; |
|
|
|
#ifdef __cplusplus |
|
|
|
// |
|
// IMA ADPCM encoder function prototype |
|
// |
|
|
|
typedef BOOL (*LPFNIMAADPCMCONVERT)(LPBYTE pbSrc, LPBYTE pbDst, UINT cBlocks, UINT nBlockAlignment, UINT cSamplesPerBlock, LPINT pnStepIndexL, LPINT pnStepIndexR); |
|
|
|
// |
|
// Codec mode |
|
// |
|
|
|
enum CODEC_MODE |
|
{ |
|
CODEC_MODE_DECODE, |
|
CODEC_MODE_ENCODE_NORMAL, |
|
CODEC_MODE_ENCODE_OPTIMIZE_WHOLE_FILE, |
|
CODEC_MODE_ENCODE_OPTIMIZE_EACH_BLOCK, |
|
}; |
|
|
|
// |
|
// IMA ADPCM CODEC |
|
// |
|
|
|
class CImaAdpcmCodec |
|
{ |
|
private: |
|
static const short m_asNextStep[16]; // Step increment array |
|
static const short m_asStep[89]; // Step value array |
|
IMAADPCMWAVEFORMAT m_wfxEncode; // Encoded format description |
|
CODEC_MODE m_cmCodecMode; // Codec mode |
|
int m_nStepIndexL; // Left-channel stepping index |
|
int m_nStepIndexR; // Right-channel stepping index |
|
LPFNIMAADPCMCONVERT m_pfnConvert; // Conversion function |
|
|
|
public: |
|
CImaAdpcmCodec(void); |
|
~CImaAdpcmCodec(void); |
|
|
|
public: |
|
// Initialization |
|
BOOL Initialize(LPCIMAADPCMWAVEFORMAT pwfxEncode, CODEC_MODE cmCodecMode); |
|
|
|
// Size conversions |
|
WORD GetEncodeAlignment(void); |
|
WORD GetDecodeAlignment(void); |
|
WORD GetSourceAlignment(void); |
|
WORD GetDestinationAlignment(void); |
|
|
|
// Data conversions |
|
BOOL Convert(LPCVOID pvSrc, LPVOID pvDst, UINT cBlocks); |
|
void Reset(void); |
|
|
|
// Format descriptions |
|
static void CreatePcmFormat(WORD nChannels, DWORD nSamplesPerSec, LPWAVEFORMATEX pwfxFormat); |
|
static void CreateImaAdpcmFormat(WORD nChannels, DWORD nSamplesPerSec, WORD nSamplesPerBlock, LPIMAADPCMWAVEFORMAT pwfxFormat); |
|
|
|
static BOOL IsValidPcmFormat(LPCWAVEFORMATEX pwfxFormat); |
|
static BOOL IsValidImaAdpcmFormat(LPCIMAADPCMWAVEFORMAT pwfxFormat); |
|
|
|
private: |
|
// En/decoded data alignment |
|
static WORD CalculateEncodeAlignment(WORD nSamplesPerBlock, WORD nChannels); |
|
|
|
// Data conversion functions |
|
static BOOL EncodeM16(LPBYTE pbSrc, LPBYTE pbDst, UINT cBlocks, UINT nBlockAlignment, UINT cSamplesPerBlock, LPINT pnStepIndexL, LPINT pnStepIndexR); |
|
static BOOL EncodeS16(LPBYTE pbSrc, LPBYTE pbDst, UINT cBlocks, UINT nBlockAlignment, UINT cSamplesPerBlock, LPINT pnStepIndexL, LPINT pnStepIndexR); |
|
static BOOL DecodeM16(LPBYTE pbSrc, LPBYTE pbDst, UINT cBlocks, UINT nBlockAlignment, UINT cSamplesPerBlock, LPINT pnStepIndexL, LPINT pnStepIndexR); |
|
static BOOL DecodeS16(LPBYTE pbSrc, LPBYTE pbDst, UINT cBlocks, UINT nBlockAlignment, UINT cSamplesPerBlock, LPINT pnStepIndexL, LPINT pnStepIndexR); |
|
|
|
static int EncodeSample(int nInputSample, int *nPredictedSample, int nStepSize); |
|
static int DecodeSample(int nInputSample, int nPredictedSample, int nStepSize); |
|
|
|
static int NextStepIndex(int nEncodedSample, int nStepIndex); |
|
static BOOL ValidStepIndex(int nStepIndex); |
|
|
|
/*static ULONGLONG CalcDifference(LPDWORD pvBuffer1, LPDWORD pvBuffer2, DWORD dwLength);*/ |
|
ULONGLONG CalcDifference(LPBYTE pvBuffer1, LPBYTE pvBuffer2, UINT cBlocks, UINT cTotalBlocks, DWORD dwBlockSize); |
|
}; |
|
|
|
__inline WORD CImaAdpcmCodec::GetSourceAlignment(void) |
|
{ |
|
return ( m_cmCodecMode == CODEC_MODE_DECODE ) ? GetEncodeAlignment() : GetDecodeAlignment(); |
|
} |
|
|
|
__inline WORD CImaAdpcmCodec::GetDestinationAlignment(void) |
|
{ |
|
return ( m_cmCodecMode == CODEC_MODE_DECODE ) ? GetDecodeAlignment() : GetEncodeAlignment(); |
|
} |
|
|
|
__inline int CImaAdpcmCodec::NextStepIndex(int nEncodedSample, int nStepIndex) |
|
{ |
|
nStepIndex += m_asNextStep[nEncodedSample]; |
|
|
|
if(nStepIndex < 0) |
|
{ |
|
nStepIndex = 0; |
|
} |
|
else if(nStepIndex >= NUMELMS(m_asStep)) |
|
{ |
|
nStepIndex = NUMELMS(m_asStep) - 1; |
|
} |
|
|
|
return nStepIndex; |
|
} |
|
|
|
__inline BOOL CImaAdpcmCodec::ValidStepIndex(int nStepIndex) |
|
{ |
|
return (nStepIndex >= 0) && (nStepIndex < NUMELMS(m_asStep)); |
|
} |
|
|
|
#endif // __cplusplus |
|
|
|
#endif // __IMAADPCM_H__
|
|
|