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

📄 drm_dec.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 4 页
字号:

static void drm_ps_pan_element(drm_ps_info *ps, bitfile *ld)
{
    drm_ps_huff_tab huff;
    uint8_t band;

    ps->bs_pan_dt_flag = faad_get1bit(ld);
    if (ps->bs_pan_dt_flag)
    {
        huff = t_huffman_pan;
    } else {
        huff = f_huffman_pan;
    }

    for (band = 0; band < DRM_NUM_PAN_BANDS; band++)
    {
        ps->bs_pan_data[band] = huff_dec(ld, huff);
    }
}

/* binary search huffman decoding */
static int8_t huff_dec(bitfile *ld, drm_ps_huff_tab huff)
{
    uint8_t bit;
    int16_t index = 0;

    while (index >= 0)
    {
        bit = (uint8_t)faad_get1bit(ld);
        index = huff[index][bit];
    }

    return index + 15;
}


static int8_t sa_delta_clip(drm_ps_info *ps, int8_t i)
{
    if (i < 0) {
      /*  printf(" SAminclip %d", i); */
        ps->sa_decode_error = 1;
        return 0;
    } else if (i > 7) {
     /*   printf(" SAmaxclip %d", i); */
        ps->sa_decode_error = 1;
        return 7;
    } else
        return i;
}

static int8_t pan_delta_clip(drm_ps_info *ps, int8_t i)
{   
    if (i < -7) {
        /* printf(" PANminclip %d", i); */
        ps->pan_decode_error = 1;
        return -7;
    } else if (i > 7) {
       /* printf(" PANmaxclip %d", i);  */
        ps->pan_decode_error = 1;
        return 7;
    } else
        return i;
}

static void drm_ps_delta_decode(drm_ps_info *ps) 
{
    uint8_t band;    

    if (ps->bs_enable_sa) 
    {    
        if (ps->bs_sa_dt_flag && !ps->g_last_had_sa) 
        {        
            for (band = 0; band < DRM_NUM_SA_BANDS; band++)
            {   
                ps->g_prev_sa_index[band] = 0;
            }           
        }       
        if (ps->bs_sa_dt_flag)
        {
            ps->g_sa_index[0] = sa_delta_clip(ps, ps->g_prev_sa_index[0]+ps->bs_sa_data[0]);            

        } else {
            ps->g_sa_index[0] = sa_delta_clip(ps,ps->bs_sa_data[0]);          
        }
        
        for (band = 1; band < DRM_NUM_SA_BANDS; band++)
        {   
            if (ps->bs_sa_dt_flag)
            {
                ps->g_sa_index[band] = sa_delta_clip(ps, ps->g_prev_sa_index[band] + ps->bs_sa_data[band]);
            } else {
                ps->g_sa_index[band] = sa_delta_clip(ps, ps->g_sa_index[band-1] + ps->bs_sa_data[band]);                
            }
        }
    }

    /* An error during SA decoding implies PAN data will be undecodable, too */
    /* Also, we don't like on/off switching in PS, so we force to last settings */
    if (ps->sa_decode_error) {
        ps->pan_decode_error = 1;
        ps->bs_enable_pan = ps->g_last_had_pan;
        ps->bs_enable_sa = ps->g_last_had_sa;
    }
    
       
    if (ps->bs_enable_sa) 
    {    
        if (ps->sa_decode_error) {
            for (band = 0; band < DRM_NUM_SA_BANDS; band++)
            {   
                ps->g_sa_index[band] = ps->g_last_good_sa_index[band];
            }
        } else {
            for (band = 0; band < DRM_NUM_SA_BANDS; band++)
            {   
                ps->g_last_good_sa_index[band] = ps->g_sa_index[band];
            }
        }
    }
    
    if (ps->bs_enable_pan) 
    {
        if (ps->bs_pan_dt_flag && !ps->g_last_had_pan) 
        {
/* The DRM PS spec doesn't say anything about this case. (deltacoded in time without a previous frame)
   AAC PS spec you must tread previous frame as 0, so that's what we try. 
*/
            for (band = 0; band < DRM_NUM_PAN_BANDS; band++)
            {   
                ps->g_prev_pan_index[band] = 0;
            }
        } 

        if (ps->bs_pan_dt_flag)
        {   
             ps->g_pan_index[0] = pan_delta_clip(ps,  ps->g_prev_pan_index[0]+ps->bs_pan_data[0]);
        } else {
             ps->g_pan_index[0] = pan_delta_clip(ps, ps->bs_pan_data[0]);
        }
    
        for (band = 1; band < DRM_NUM_PAN_BANDS; band++)
        {   
            if (ps->bs_pan_dt_flag)
            {
                ps->g_pan_index[band] = pan_delta_clip(ps, ps->g_prev_pan_index[band] + ps->bs_pan_data[band]);
            } else {
                ps->g_pan_index[band] = pan_delta_clip(ps, ps->g_pan_index[band-1] + ps->bs_pan_data[band]);
            }
        }
 
        if (ps->pan_decode_error) {
            for (band = 0; band < DRM_NUM_PAN_BANDS; band++)
            {   
                ps->g_pan_index[band] = ps->g_last_good_pan_index[band];
            }
        } else {
            for (band = 0; band < DRM_NUM_PAN_BANDS; band++)
            {   
                ps->g_last_good_pan_index[band] = ps->g_pan_index[band];
            }
        }
    }
}

static void drm_calc_sa_side_signal(drm_ps_info *ps, qmf_t X[38][64], uint8_t rateselect) 
{      
    uint8_t s, b, k;
    complex_t qfrac, tmp0, tmp, in, R0;
    real_t peakdiff;
    real_t nrg;
    real_t power;
    real_t transratio;
    real_t new_delay_slopes[NUM_OF_LINKS];
    uint8_t temp_delay_ser[NUM_OF_LINKS];
    complex_t Phi_Fract;
#ifdef FIXED_POINT
    uint32_t in_re, in_im;
#endif

    for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS][rateselect]; b++)
    {
        /* set delay indices */    
        for (k = 0; k < NUM_OF_LINKS; k++)
            temp_delay_ser[k] = ps->delay_buf_index_ser[k];

        RE(Phi_Fract) = RE(Phi_Fract_Qmf[b]);
        IM(Phi_Fract) = IM(Phi_Fract_Qmf[b]);

        for (s = 0; s < NUM_OF_SUBSAMPLES; s++)
        {            
            const real_t gamma = REAL_CONST(1.5);
            const real_t sigma = REAL_CONST(1.5625);

            RE(in) = QMF_RE(X[s][b]);
            IM(in) = QMF_IM(X[s][b]);

#ifdef FIXED_POINT
            /* NOTE: all input is scaled by 2^(-5) because of fixed point QMF
            * meaning that P will be scaled by 2^(-10) compared to floating point version
            */
            in_re = ((abs(RE(in))+(1<<(REAL_BITS-1)))>>REAL_BITS);
            in_im = ((abs(IM(in))+(1<<(REAL_BITS-1)))>>REAL_BITS);
            power = in_re*in_re + in_im*in_im;
#else
            power = MUL_R(RE(in),RE(in)) + MUL_R(IM(in),IM(in));
#endif

            ps->peakdecay_fast[b] = MUL_F(ps->peakdecay_fast[b], peak_decay[rateselect]);
            if (ps->peakdecay_fast[b] < power)
                ps->peakdecay_fast[b] = power;

            peakdiff = ps->prev_peakdiff[b];
            peakdiff += MUL_F((ps->peakdecay_fast[b] - power - ps->prev_peakdiff[b]), smooth_coeff[rateselect]);
            ps->prev_peakdiff[b] = peakdiff;

            nrg = ps->prev_nrg[b];
            nrg += MUL_F((power - ps->prev_nrg[b]), smooth_coeff[rateselect]);
            ps->prev_nrg[b] = nrg;

            if (MUL_R(peakdiff, gamma) <= nrg) {
                transratio = sigma;
            } else {
                transratio = MUL_R(DIV_R(nrg, MUL_R(peakdiff, gamma)), sigma);
            }
            
            for (k = 0; k < NUM_OF_LINKS; k++) 
            {
                new_delay_slopes[k] = MUL_F(g_decayslope[b], filter_coeff[k]);
            }

            RE(tmp0) = RE(ps->d_buff[0][b]);
            IM(tmp0) = IM(ps->d_buff[0][b]);

            RE(ps->d_buff[0][b]) = RE(ps->d_buff[1][b]);
            IM(ps->d_buff[0][b]) = IM(ps->d_buff[1][b]);

            RE(ps->d_buff[1][b]) = RE(in);
            IM(ps->d_buff[1][b]) = IM(in);               

            ComplexMult(&RE(tmp), &IM(tmp), RE(tmp0), IM(tmp0), RE(Phi_Fract), IM(Phi_Fract));

            RE(R0) = RE(tmp);
            IM(R0) = IM(tmp);

            for (k = 0; k < NUM_OF_LINKS; k++) 
            {
                RE(qfrac) = RE(Q_Fract_allpass_Qmf[b][k]);
                IM(qfrac) = IM(Q_Fract_allpass_Qmf[b][k]);

⌨️ 快捷键说明

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