⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imaalgorith.c

📁 书中的主要程序文件。在打开例题的.dsw文件后,请读者在 tools菜单下的 Options 的 Directories 标签中选择 Executable files
💻 C
📖 第 1 页 / 共 4 页
字号:



//--------------------------------------------------------------------------;
//  
//  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 + -