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

📄 imaalgorith.c

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