📄 imaalgorith.c
字号:
//--------------------------------------------------------------------------;
//
// BOOL IMAAlgorithValidStepIndex
//
// Description:
// This routine checks the step index value to make sure that it is
// within the legal range.
//
// Arguments:
//
// int nStepIndex: The step index value.
//
// Return (BOOL): TRUE if the step index is valid; FALSE otherwise.
//
//--------------------------------------------------------------------------;
INLINE BOOL IMAAlgorithValidStepIndex
(
int nStepIndex
)
{
if( nStepIndex >= 0 && nStepIndex <= 88 )
return TRUE;
else
return FALSE;
}
//==========================================================================;
//
// DECODE ROUTINES
//
//==========================================================================;
//--------------------------------------------------------------------------;
//
// DWORD IMAAlgorithDecode4Bit_M08
// DWORD IMAAlgorithDecode4Bit_M16
// DWORD IMAAlgorithDecode4Bit_S08
// DWORD IMAAlgorithDecode4Bit_S16
//
// Description:
// These functions decode a buffer of data from ADPCM to PCM in the
// specified format. The appropriate function is called once for each
// ACMDM_STREAM_CONVERT message received. Note that since these
// functions must share the same prototype as the encoding functions
// (see acmdStreamOpen() and acmdStreamConvert() in ACM.c for more
// details), not all the parameters are used by these routines.
//
// Arguments:
// HPBYTE pbSrc: Pointer to the source buffer (ADPCM data).
// DWORD cbSrcLength: The length of the source buffer (in bytes).
// HPBYTE pbDst: Pointer to the destination buffer (PCM data). Note
// that it is assumed that the destination buffer is
// large enough to hold all the encoded data; see
// acmdStreamSize() in ACM.c for more details.
// UINT nBlockAlignment: The block alignment of the ADPCM data (in
// bytes).
// UINT cSamplesPerBlock: The number of samples in each ADPCM block;
// not used for decoding.
// int *pnStepIndexL: Pointer to the step index value (left channel)
// in the STREAMINSTANCE structure; not used for
// decoding.
// int *pnStepIndexR: Pointer to the step index value (right channel)
// in the STREAMINSTANCE structure; not used for
// decoding.
//
// Return (DWORD): The number of bytes used in the destination buffer.
//
//--------------------------------------------------------------------------;
DWORD FNGLOBAL IMAAlgorithDecode4Bit_M08
(
HPBYTE pbSrc,
DWORD cbSrcLength,
HPBYTE pbDst,
UINT nBlockAlignment,
UINT cSamplesPerBlock,
int * pnStepIndexL,
int * pnStepIndexR
)
{
HPBYTE pbDstStart;
UINT cbHeader;
UINT cbBlockLength;
BYTE bSample;
int nStepSize;
int nEncSample;
int nPredSample;
int nStepIndex;
pbDstStart = pbDst;
cbHeader = IMAALGORITH_HEADER_LENGTH * 1; // 1 = number of channels.
DPF(3,"Starting IMAAlgorithDecode4Bit_M08().");
//
//
//
while (cbSrcLength >= cbHeader)
{
DWORD dwHeader;
cbBlockLength = (UINT)min(cbSrcLength, nBlockAlignment);
cbSrcLength -= cbBlockLength;
cbBlockLength -= cbHeader;
//
// block header
//
dwHeader = *(DWORD HUGE_T *)pbSrc;
pbSrc += sizeof(DWORD);
nPredSample = (int)(short)LOWORD(dwHeader);
nStepIndex = (int)(BYTE)HIWORD(dwHeader);
if( !IMAAlgorithValidStepIndex(nStepIndex) ) {
//
// The step index is out of range - this is considered a fatal
// error as the input stream is corrupted. We fail by returning
// zero bytes converted.
//
DPF(1,"IMAAlgorithDecode4Bit_M08: invalid step index.");
return 0;
}
//
// write out first sample
//
*pbDst++ = (BYTE)((nPredSample >> 8) + 128);
//
//
//
while (cbBlockLength--)
{
bSample = *pbSrc++;
//
// sample 1
//
nEncSample = (bSample & (BYTE)0x0F);
nStepSize = step[nStepIndex];
nPredSample = IMAAlgorithSampleDecode(nEncSample, nPredSample, nStepSize);
nStepIndex = IMAAlgorithNextStepIndex(nEncSample, nStepIndex);
//
// write out sample
//
*pbDst++ = (BYTE)((nPredSample >> 8) + 128);
//
// sample 2
//
nEncSample = (bSample >> 4);
nStepSize = step[nStepIndex];
nPredSample = IMAAlgorithSampleDecode(nEncSample, nPredSample, nStepSize);
nStepIndex = IMAAlgorithNextStepIndex(nEncSample, nStepIndex);
//
// write out sample
//
*pbDst++ = (BYTE)((nPredSample >> 8) + 128);
}
}
//
// We return the number of bytes used in the destination. This is
// simply the difference in bytes from where we started.
//
return (DWORD)(pbDst - pbDstStart);
} // IMAAlgorithDecode4Bit_M08()
//--------------------------------------------------------------------------;
//--------------------------------------------------------------------------;
DWORD FNGLOBAL IMAAlgorithDecode4Bit_M16
(
HPBYTE pbSrc,
DWORD cbSrcLength,
HPBYTE pbDst,
UINT nBlockAlignment,
UINT cSamplesPerBlock,
int * pnStepIndexL,
int * pnStepIndexR
)
{
HPBYTE pbDstStart;
UINT cbHeader;
UINT cbBlockLength;
BYTE bSample;
int nStepSize;
int nEncSample;
int nPredSample;
int nStepIndex;
pbDstStart = pbDst;
cbHeader = IMAALGORITH_HEADER_LENGTH * 1; // 1 = number of channels.
DPF(3,"Starting IMAAlgorithDecode4Bit_M16().");
//
//
//
while (cbSrcLength >= cbHeader)
{
DWORD dwHeader;
cbBlockLength = (UINT)min(cbSrcLength, nBlockAlignment);
cbSrcLength -= cbBlockLength;
cbBlockLength -= cbHeader;
//
// block header
//
dwHeader = *(DWORD HUGE_T *)pbSrc;
pbSrc += sizeof(DWORD);
nPredSample = (int)(short)LOWORD(dwHeader);
nStepIndex = (int)(BYTE)HIWORD(dwHeader);
if( !IMAAlgorithValidStepIndex(nStepIndex) ) {
//
// The step index is out of range - this is considered a fatal
// error as the input stream is corrupted. We fail by returning
// zero bytes converted.
//
DPF(1,"IMAAlgorithDecode4Bit_M16: invalid step index.");
return 0;
}
//
// write out first sample
//
*(short HUGE_T *)pbDst = (short)nPredSample;
pbDst += sizeof(short);
//
//
//
while (cbBlockLength--)
{
bSample = *pbSrc++;
//
// sample 1
//
nEncSample = (bSample & (BYTE)0x0F);
nStepSize = step[nStepIndex];
nPredSample = IMAAlgorithSampleDecode(nEncSample, nPredSample, nStepSize);
nStepIndex = IMAAlgorithNextStepIndex(nEncSample, nStepIndex);
//
// write out sample
//
*(short HUGE_T *)pbDst = (short)nPredSample;
pbDst += sizeof(short);
//
// sample 2
//
nEncSample = (bSample >> 4);
nStepSize = step[nStepIndex];
nPredSample = IMAAlgorithSampleDecode(nEncSample, nPredSample, nStepSize);
nStepIndex = IMAAlgorithNextStepIndex(nEncSample, nStepIndex);
//
// write out sample
//
*(short HUGE_T *)pbDst = (short)nPredSample;
pbDst += sizeof(short);
}
}
//
// We return the number of bytes used in the destination. This is
// simply the difference in bytes from where we started.
//
return (DWORD)(pbDst - pbDstStart);
} // IMAAlgorithDecode4Bit_M16()
//--------------------------------------------------------------------------;
//--------------------------------------------------------------------------;
DWORD FNGLOBAL IMAAlgorithDecode4Bit_S08
(
HPBYTE pbSrc,
DWORD cbSrcLength,
HPBYTE pbDst,
UINT nBlockAlignment,
UINT cSamplesPerBlock,
int * pnStepIndexL,
int * pnStepIndexR
)
{
HPBYTE pbDstStart;
UINT cbHeader;
UINT cbBlockLength;
int nStepSize;
DWORD dwHeader;
DWORD dwLeft;
DWORD dwRight;
int i;
int nEncSampleL;
int nPredSampleL;
int nStepIndexL;
int nEncSampleR;
int nPredSampleR;
int nStepIndexR;
pbDstStart = pbDst;
cbHeader = IMAALGORITH_HEADER_LENGTH * 2; // 2 = number of channels.
DPF(3,"Starting IMAAlgorithDecode4Bit_S08().");
//
//
//
while( 0 != cbSrcLength )
{
//
// The data should always be block aligned.
//
ASSERT( cbSrcLength >= nBlockAlignment );
cbBlockLength = nBlockAlignment;
cbSrcLength -= cbBlockLength;
cbBlockLength -= cbHeader;
//
// LEFT channel header
//
dwHeader = *(DWORD HUGE_T *)pbSrc;
pbSrc += sizeof(DWORD);
nPredSampleL = (int)(short)LOWORD(dwHeader);
nStepIndexL = (int)(BYTE)HIWORD(dwHeader);
if( !IMAAlgorithValidStepIndex(nStepIndexL) ) {
//
// The step index is out of range - this is considered a fatal
// error as the input stream is corrupted. We fail by returning
// zero bytes converted.
//
DPF(1,"IMAAlgorithDecode4Bit_S08: invalid step index (L).");
return 0;
}
//
// RIGHT channel header
//
dwHeader = *(DWORD HUGE_T *)pbSrc;
pbSrc += sizeof(DWORD);
nPredSampleR = (int)(short)LOWORD(dwHeader);
nStepIndexR = (int)(BYTE)HIWORD(dwHeader);
if( !IMAAlgorithValidStepIndex(nStepIndexR) ) {
//
// The step index is out of range - this is considered a fatal
// error as the input stream is corrupted. We fail by returning
// zero bytes converted.
//
DPF(1,"IMAAlgorithDecode4Bit_S08: invalid step index (R).");
return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -