📄 imaalgorith.c
字号:
DWORD cSrcSamples;
UINT cBlockSamples;
int nSample;
int nStepSize;
int nEncSample1;
int nEncSample2;
int nPredSample;
int nStepIndex;
pbDstStart = pbDst;
cSrcSamples = pcmM16BytesToSamples(cbSrcLength);
//
// Restore the Step Index to that of the final convert of the previous
// buffer. Remember to restore this value to psi->nStepIndexL.
//
nStepIndex = (*pnStepIndexL);
//
//
//
//
while (0 != cSrcSamples)
{
cBlockSamples = (UINT)min(cSrcSamples, cSamplesPerBlock);
cSrcSamples -= cBlockSamples;
//
// block header
//
nPredSample = *(short HUGE_T *)pbSrc;
pbSrc += sizeof(short);
cBlockSamples--;
*(LONG HUGE_T *)pbDst = MAKELONG(nPredSample, nStepIndex);
pbDst += sizeof(LONG);
//
// We have written the header for this block--now write the data
// chunk (which consists of a bunch of encoded nibbles). Note
// that if we don't have enough data to fill a complete byte, then
// we add a 0 nibble on the end.
//
while( cBlockSamples>0 )
{
//
// sample 1
//
nSample = *(short HUGE_T *)pbSrc;
pbSrc += sizeof(short);
cBlockSamples--;
nStepSize = step[nStepIndex];
IMAAlgorithFastEncode(nEncSample1,nPredSample,nSample,nStepSize);
nStepIndex = IMAAlgorithNextStepIndex(nEncSample1, nStepIndex);
//
// sample 2
//
nEncSample2 = 0;
if( cBlockSamples>0 ) {
nSample = *(short HUGE_T *)pbSrc;
pbSrc += sizeof(short);
cBlockSamples--;
nStepSize = step[nStepIndex];
IMAAlgorithFastEncode(nEncSample2,nPredSample,nSample,nStepSize);
nStepIndex = IMAAlgorithNextStepIndex(nEncSample2, nStepIndex);
}
//
// Write out encoded byte.
//
*pbDst++ = (BYTE)(nEncSample1 | (nEncSample2 << 4));
}
}
//
// Restore the value of the Step Index, to be used on the next buffer.
//
(*pnStepIndexL) = nStepIndex;
//
// 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);
} // IMAAlgorithEncode4Bit_M16()
//--------------------------------------------------------------------------;
//--------------------------------------------------------------------------;
DWORD FNGLOBAL IMAAlgorithEncode4Bit_S08
(
HPBYTE pbSrc,
DWORD cbSrcLength,
HPBYTE pbDst,
UINT nBlockAlignment,
UINT cSamplesPerBlock,
int * pnStepIndexL,
int * pnStepIndexR
)
{
HPBYTE pbDstStart;
DWORD cSrcSamples;
UINT cBlockSamples;
int nSample;
int nStepSize;
DWORD dwLeft;
DWORD dwRight;
int i;
int nEncSampleL;
int nPredSampleL;
int nStepIndexL;
int nEncSampleR;
int nPredSampleR;
int nStepIndexR;
pbDstStart = pbDst;
cSrcSamples = pcmS08BytesToSamples(cbSrcLength);
//
// Restore the Step Index to that of the final convert of the previous
// buffer. Remember to restore this value to psi->nStepIndexL,R.
//
nStepIndexL = (*pnStepIndexL);
nStepIndexR = (*pnStepIndexR);
//
//
//
//
while( 0 != cSrcSamples )
{
//
// The samples should always be block aligned.
//
ASSERT( cSrcSamples >= cSamplesPerBlock );
cBlockSamples = cSamplesPerBlock;
cSrcSamples -= cBlockSamples;
//
// LEFT channel block header
//
nPredSampleL = ((short)*pbSrc++ - 128) << 8;
*(LONG HUGE_T *)pbDst = MAKELONG(nPredSampleL, nStepIndexL);
pbDst += sizeof(LONG);
//
// RIGHT channel block header
//
nPredSampleR = ((short)*pbSrc++ - 128) << 8;
*(LONG HUGE_T *)pbDst = MAKELONG(nPredSampleR, nStepIndexR);
pbDst += sizeof(LONG);
cBlockSamples--; // One sample is in the header.
//
// We have written the header for this block--now write the data
// chunk. This consists of 8 left samples (one DWORD of output)
// followed by 8 right samples (also one DWORD). Since the input
// samples are interleaved, we create the left and right DWORDs
// sample by sample, and then write them both out.
//
ASSERT( 0 == cBlockSamples%8 );
while( 0 != cBlockSamples )
{
cBlockSamples -= 8;
dwLeft = 0;
dwRight = 0;
for( i=0; i<8; i++ )
{
//
// LEFT channel
//
nSample = ((short)*pbSrc++ - 128) << 8;
nStepSize = step[nStepIndexL];
IMAAlgorithFastEncode(nEncSampleL,nPredSampleL,nSample,nStepSize);
nStepIndexL = IMAAlgorithNextStepIndex(nEncSampleL, nStepIndexL);
dwLeft |= ((DWORD)nEncSampleL) << 4*i;
//
// RIGHT channel
//
nSample = ((short)*pbSrc++ - 128) << 8;
nStepSize = step[nStepIndexR];
IMAAlgorithFastEncode(nEncSampleR,nPredSampleR,nSample,nStepSize);
nStepIndexR = IMAAlgorithNextStepIndex(nEncSampleR, nStepIndexR);
dwRight |= ((DWORD)nEncSampleR) << 4*i;
}
//
// Write out encoded DWORDs.
//
*(DWORD HUGE_T *)pbDst = dwLeft;
pbDst += sizeof(DWORD);
*(DWORD HUGE_T *)pbDst = dwRight;
pbDst += sizeof(DWORD);
}
}
//
// Restore the value of the Step Index, to be used on the next buffer.
//
(*pnStepIndexL) = nStepIndexL;
(*pnStepIndexR) = nStepIndexR;
//
// 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);
} // IMAAlgorithEncode4Bit_S08()
//--------------------------------------------------------------------------;
//--------------------------------------------------------------------------;
DWORD FNGLOBAL IMAAlgorithEncode4Bit_S16
(
HPBYTE pbSrc,
DWORD cbSrcLength,
HPBYTE pbDst,
UINT nBlockAlignment,
UINT cSamplesPerBlock,
int * pnStepIndexL,
int * pnStepIndexR
)
{
HPBYTE pbDstStart;
DWORD cSrcSamples;
UINT cBlockSamples;
int nSample;
int nStepSize;
DWORD dwLeft;
DWORD dwRight;
int i;
int nEncSampleL;
int nPredSampleL;
int nStepIndexL;
int nEncSampleR;
int nPredSampleR;
int nStepIndexR;
pbDstStart = pbDst;
cSrcSamples = pcmS16BytesToSamples(cbSrcLength);
//
// Restore the Step Index to that of the final convert of the previous
// buffer. Remember to restore this value to psi->nStepIndexL,R.
//
nStepIndexL = (*pnStepIndexL);
nStepIndexR = (*pnStepIndexR);
//
//
//
//
while( 0 != cSrcSamples )
{
//
// The samples should always be block aligned.
//
ASSERT( cSrcSamples >= cSamplesPerBlock );
cBlockSamples = cSamplesPerBlock;
cSrcSamples -= cBlockSamples;
//
// LEFT channel block header
//
nPredSampleL = *(short HUGE_T *)pbSrc;
pbSrc += sizeof(short);
*(LONG HUGE_T *)pbDst = MAKELONG(nPredSampleL, nStepIndexL);
pbDst += sizeof(LONG);
//
// RIGHT channel block header
//
nPredSampleR = *(short HUGE_T *)pbSrc;
pbSrc += sizeof(short);
*(LONG HUGE_T *)pbDst = MAKELONG(nPredSampleR, nStepIndexR);
pbDst += sizeof(LONG);
cBlockSamples--; // One sample is in the header.
//
// We have written the header for this block--now write the data
// chunk. This consists of 8 left samples (one DWORD of output)
// followed by 8 right samples (also one DWORD). Since the input
// samples are interleaved, we create the left and right DWORDs
// sample by sample, and then write them both out.
//
ASSERT( 0 == cBlockSamples%8 );
while( 0 != cBlockSamples )
{
cBlockSamples -= 8;
dwLeft = 0;
dwRight = 0;
for( i=0; i<8; i++ )
{
//
// LEFT channel
//
nSample = *(short HUGE_T *)pbSrc;
pbSrc += sizeof(short);
nStepSize = step[nStepIndexL];
IMAAlgorithFastEncode(nEncSampleL,nPredSampleL,nSample,nStepSize);
nStepIndexL = IMAAlgorithNextStepIndex(nEncSampleL, nStepIndexL);
dwLeft |= ((DWORD)nEncSampleL) << 4*i;
//
// RIGHT channel
//
nSample = *(short HUGE_T *)pbSrc;
pbSrc += sizeof(short);
nStepSize = step[nStepIndexR];
IMAAlgorithFastEncode(nEncSampleR,nPredSampleR,nSample,nStepSize);
nStepIndexR = IMAAlgorithNextStepIndex(nEncSampleR, nStepIndexR);
dwRight |= ((DWORD)nEncSampleR) << 4*i;
}
//
// Write out encoded DWORDs.
//
*(DWORD HUGE_T *)pbDst = dwLeft;
pbDst += sizeof(DWORD);
*(DWORD HUGE_T *)pbDst = dwRight;
pbDst += sizeof(DWORD);
}
}
//
// Restore the value of the Step Index, to be used on the next buffer.
//
(*pnStepIndexL) = nStepIndexL;
(*pnStepIndexR) = nStepIndexR;
//
// 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);
} // IMAAlgorithEncode4Bit_S16()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -