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.
154 lines
5.0 KiB
154 lines
5.0 KiB
5 years ago
|
//========= 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__
|