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

📄 mpc_decoder.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 4 页
字号:
        mpc_decoder_read_bitstream_sv7(d);
        break;
    default:
        return (mpc_uint32_t)(-1);
    }
    d->FrameWasValid = mpc_decoder_bits_read(d) - FrameBitCnt == d->FwdJumpInfo;

    // synthesize signal
    mpc_decoder_requantisierung(d, d->Max_Band);

    //if ( d->EQ_activated && PluginSettings.EQbyMPC )
    //    perform_EQ ();

    mpc_decoder_synthese_filter_float(d, buffer);

    d->DecodedFrames++;

    // cut off first MPC_DECODER_SYNTH_DELAY zero-samples
    if (d->DecodedFrames == d->OverallFrames  && d->StreamVersion >= 6) {        
        // reconstruct exact filelength
        mpc_int32_t  mod_block   = mpc_decoder_bitstream_read(d,  11);
        mpc_int32_t  FilterDecay;

        if (mod_block == 0) {
            // Encoder bugfix
            mod_block = 1152;                    
        }
        FilterDecay = (mod_block + MPC_DECODER_SYNTH_DELAY) % MPC_FRAME_LENGTH;

        // additional FilterDecay samples are needed for decay of synthesis filter
        if (MPC_DECODER_SYNTH_DELAY + mod_block >= MPC_FRAME_LENGTH) {

            // **********************************************************************
            // Rhoades 4/16/2002
            // Commented out are blocks of code which cause gapless playback to fail.
            // Temporary fix...
            // **********************************************************************

            if (!d->TrueGaplessPresent) {
                mpc_decoder_reset_y(d);
            } 
            else {
                //if ( MPC_FRAME_LENGTH != d->LastValidSamples ) {
                mpc_decoder_bitstream_read(d, 20);
                mpc_decoder_read_bitstream_sv7(d);
                mpc_decoder_requantisierung(d, d->Max_Band);
                //FilterDecay = d->LastValidSamples;
                //}
                //else {
                //FilterDecay = 0;
                //}
            }

            mpc_decoder_synthese_filter_float(d, buffer + 2304);

            output_frame_length = MPC_FRAME_LENGTH + FilterDecay;
        }
        else {                              // there are only FilterDecay samples needed for this frame
            output_frame_length = FilterDecay;
        }
    }

    if (d->samples_to_skip) {
        if (output_frame_length < d->samples_to_skip) {
            d->samples_to_skip -= output_frame_length;
            output_frame_length = 0;
        }
        else {
            output_frame_length -= d->samples_to_skip;
            memmove(
                buffer, 
                buffer + d->samples_to_skip * 2, 
                output_frame_length * 2 * sizeof (MPC_SAMPLE_FORMAT));
            d->samples_to_skip = 0;
        }
    }

    return output_frame_length;
}

mpc_uint32_t mpc_decoder_decode(
    mpc_decoder *d,
    MPC_SAMPLE_FORMAT *buffer, 
    mpc_uint32_t *vbr_update_acc, 
    mpc_uint32_t *vbr_update_bits)
{
    for(;;)
    {
        //const mpc_int32_t MaxBrokenFrames = 0; // PluginSettings.MaxBrokenFrames

        mpc_uint32_t RING = d->Zaehler;
        mpc_int32_t vbr_ring = (RING << 5) + d->pos;

        mpc_uint32_t valid_samples = mpc_decoder_decode_internal(d, buffer);

        if (valid_samples == (mpc_uint32_t)(-1) ) {
            return 0;
        }

        /**************** ERROR CONCEALMENT *****************/
        if (d->FrameWasValid == 0 ) {
            // error occurred in bitstream
            return (mpc_uint32_t)(-1);
        } 
        else {
            if (vbr_update_acc && vbr_update_bits) {
                (*vbr_update_acc) ++;
                vbr_ring = (d->Zaehler << 5) + d->pos - vbr_ring;
                if (vbr_ring < 0) {
                    vbr_ring += 524288;
                }
                (*vbr_update_bits) += vbr_ring;
            }

        }
        mpc_decoder_update_buffer(d, RING);

        if (valid_samples > 0) {
            return valid_samples;
        }
    }
}

void
mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band) 
{
    mpc_int32_t     Band;
    mpc_int32_t     n;
    MPC_SAMPLE_FORMAT facL;
    MPC_SAMPLE_FORMAT facR;
    MPC_SAMPLE_FORMAT templ;
    MPC_SAMPLE_FORMAT tempr;
    MPC_SAMPLE_FORMAT* YL;
    MPC_SAMPLE_FORMAT* YR;
    mpc_int32_t*    L;
    mpc_int32_t*    R;

#ifdef MPC_FIXED_POINT
#if MPC_FIXED_POINT_FRACTPART == 14
#define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \
    MPC_MULTIPLY_EX(CcVal, d->SCF[SCF_idx], d->SCF_shift[SCF_idx])
#else

#error FIXME, Cc table is in 18.14 format

#endif
#else
#define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \
    MPC_MULTIPLY(CcVal, d->SCF[SCF_idx])
#endif
    // requantization and scaling of subband-samples
    for ( Band = 0; Band <= Last_Band; Band++ ) {   // setting pointers
        YL = d->Y_L[0] + Band;
        YR = d->Y_R[0] + Band;
        L  = d->Q[Band].L;
        R  = d->Q[Band].R;
        /************************** MS-coded **************************/
        if ( d->MS_Flag [Band] ) {
            if ( d->Res_L [Band] ) {
                if ( d->Res_R [Band] ) {    // M!=0, S!=0
                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]);
                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]);
                    for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) {
                        *YL   = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++));
                        *YR   = templ - tempr;
                    }
                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]);
                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]);
                    for ( ; n < 24; n++, YL += 32, YR += 32 ) {
                        *YL   = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++));
                        *YR   = templ - tempr;
                    }
                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]);
                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]);
                    for ( ; n < 36; n++, YL += 32, YR += 32 ) {
                        *YL   = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++));
                        *YR   = templ - tempr;
                    }
                } else {    // M!=0, S==0
                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]);
                    for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) {
                        *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
                    }
                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]);
                    for ( ; n < 24; n++, YL += 32, YR += 32 ) {
                        *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
                    }
                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]);
                    for ( ; n < 36; n++, YL += 32, YR += 32 ) {
                        *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
                    }
                }
            } else {
                if (d->Res_R[Band])    // M==0, S!=0
                {
                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]);
                    for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) {
                        *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++)));
                    }
                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]);
                    for ( ; n < 24; n++, YL += 32, YR += 32 ) {
                        *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++)));
                    }
                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]);
                    for ( ; n < 36; n++, YL += 32, YR += 32 ) {
                        *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++)));
                    }
                } else {    // M==0, S==0
                    for ( n = 0; n < 36; n++, YL += 32, YR += 32 ) {
                        *YR = *YL = 0;
                    }
                }
            }
        }
        /************************** LR-coded **************************/
        else {
            if ( d->Res_L [Band] ) {
                if ( d->Res_R [Band] ) {    // L!=0, R!=0
                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]);
                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]);
                    for (n = 0; n < 12; n++, YL += 32, YR += 32 ) {
                        *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
                        *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
                    }
                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]);
                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]);
                    for (; n < 24; n++, YL += 32, YR += 32 ) {
                        *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
                        *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
                    }
                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]);
                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]);
                    for (; n < 36; n++, YL += 32, YR += 32 ) {
                        *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
                        *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
                    }
                } else {     // L!=0, R==0
                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]);
                    for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) {
                        *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
                        *YR = 0;
                    }
                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]);
                    for ( ; n < 24; n++, YL += 32, YR += 32 ) {
                        *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
                        *YR = 0;
                    }
                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]);
                    for ( ; n < 36; n++, YL += 32, YR += 32 ) {
                        *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
                        *YR = 0;
                    }
                }
            }
            else {
                if ( d->Res_R [Band] ) {    // L==0, R!=0
                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]);
                    for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) {
                        *YL = 0;
                        *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
                    }
                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]);
                    for ( ; n < 24; n++, YL += 32, YR += 32 ) {
                        *YL = 0;
                        *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
                    }
                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]);
                    for ( ; n < 36; n++, YL += 32, YR += 32 ) {
                        *YL = 0;
                        *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
                    }
                } else {    // L==0, R==0
                    for ( n = 0; n < 36; n++, YL += 32, YR += 32 ) {
                        *YR = *YL = 0;
                    }
                }
            }
        }
    }
}

/****************************************** SV 6 ******************************************/
void
mpc_decoder_read_bitstream_sv6(mpc_decoder *d) 
{
    mpc_int32_t n,k;
    mpc_int32_t Max_used_Band=0;
    HuffmanTyp *Table;
    const HuffmanTyp *x1;
    const HuffmanTyp *x2;
    mpc_int32_t *L;
    mpc_int32_t *R;
    mpc_int32_t *ResL = d->Res_L;
    mpc_int32_t *ResR = d->Res_R;

    /************************ HEADER **************************/
    ResL = d->Res_L;
    ResR = d->Res_R;
    for (n=0; n <= d->Max_Band; ++n, ++ResL, ++ResR)
    {
        if      (n<11)           Table = d->Region_A;
        else if (n>=11 && n<=22) Table = d->Region_B;
        else /*if (n>=23)*/      Table = d->Region_C;

        *ResL = d->Q_res[n][mpc_decoder_huffman_decode(d, Table)];
        if (d->MS_used) {
            d->MS_Flag[n] = mpc_decoder_bitstream_read(d,  1);
        }
        *ResR = d->Q_res[n][mpc_decoder_huffman_decode(d, Table)];

        // only perform the following procedure up to the maximum non-zero subband
        if (*ResL || *ResR) Max_used_Band = n;
    }

    /************************* SCFI-Bundle *****************************/
    ResL = d->Res_L;
    ResR = d->Res_R;
    for (n=0; n<=Max_used_Band; ++n, ++ResL, ++ResR) {
        if (*ResL) mpc_decoder_scfi_bundle_read(d, d->SCFI_Bundle, &(d->SCFI_L[n]), &(d->DSCF_Flag_L[n]));
        if (*ResR) mpc_decoder_scfi_bundle_read(d, d->SCFI_Bundle, &(d->SCFI_R[n]), &(d->DSCF_Flag_R[n]));
    }

    /***************************** SCFI ********************************/
    ResL = d->Res_L;
    ResR = d->Res_R;
    L    = d->SCF_Index_L[0];
    R    = d->SCF_Index_R[0];
    for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR, L+=3, R+=3)
    {
        if (*ResL)
        {
            /*********** DSCF ************/
            if (d->DSCF_Flag_L[n]==1)
            {
                L[2] = d->DSCF_Reference_L[n];
                switch (d->SCFI_L[n])
                {
                case 3:
                    L[0] = L[2] + mpc_decoder_huffman_decode_fast(d,  d->DSCF_Entropie);
                    L[1] = L[0];
                    L[2] = L[1];
                    break;
                case 1:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -