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

📄 drm_dec.c

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

                RE(tmp0) = RE(ps->d2_buff[k][temp_delay_ser[k]][b]);
                IM(tmp0) = IM(ps->d2_buff[k][temp_delay_ser[k]][b]);

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

                RE(tmp) += -MUL_F(new_delay_slopes[k], RE(R0));
                IM(tmp) += -MUL_F(new_delay_slopes[k], IM(R0));

                RE(ps->d2_buff[k][temp_delay_ser[k]][b]) = RE(R0) + MUL_F(new_delay_slopes[k], RE(tmp));
                IM(ps->d2_buff[k][temp_delay_ser[k]][b]) = IM(R0) + MUL_F(new_delay_slopes[k], IM(tmp));

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

            QMF_RE(ps->SA[s][b]) = MUL_R(RE(R0), transratio);
            QMF_IM(ps->SA[s][b]) = MUL_R(IM(R0), transratio);

            for (k = 0; k < NUM_OF_LINKS; k++)
            {
                if (++temp_delay_ser[k] >= delay_length[k][rateselect])
                    temp_delay_ser[k] = 0;
            }
        }       
    }

    for (k = 0; k < NUM_OF_LINKS; k++)
        ps->delay_buf_index_ser[k] = temp_delay_ser[k];
}

static void drm_add_ambiance(drm_ps_info *ps, uint8_t rateselect, qmf_t X_left[38][64], qmf_t X_right[38][64]) 
{
    uint8_t s, b, ifreq, qclass;    
    real_t sa_map[MAX_SA_BAND], sa_dir_map[MAX_SA_BAND], k_sa_map[MAX_SA_BAND], k_sa_dir_map[MAX_SA_BAND];
    real_t new_dir_map, new_sa_map;
    
    if (ps->bs_enable_sa)
    {
        /* Instead of dequantization and mapping, we use an inverse mapping
           to look up all the values we need */
        for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS][rateselect]; b++)
        {
            const real_t inv_f_num_of_subsamples = FRAC_CONST(0.03333333333);

            ifreq = sa_inv_freq[b];
            qclass = (b != 0);

            sa_map[b]  = sa_quant[ps->g_prev_sa_index[ifreq]][qclass];
            new_sa_map = sa_quant[ps->g_sa_index[ifreq]][qclass];

            k_sa_map[b] = MUL_F(inv_f_num_of_subsamples, (new_sa_map - sa_map[b]));    
            
            sa_dir_map[b] = sa_sqrt_1_minus[ps->g_prev_sa_index[ifreq]][qclass];                        
            new_dir_map   = sa_sqrt_1_minus[ps->g_sa_index[ifreq]][qclass];
                                                   
            k_sa_dir_map[b] = MUL_F(inv_f_num_of_subsamples, (new_dir_map - sa_dir_map[b]));

        }

        for (s = 0; s < NUM_OF_SUBSAMPLES; s++)
        {
            for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS][rateselect]; b++)
            {                
                QMF_RE(X_right[s][b]) = MUL_F(QMF_RE(X_left[s][b]), sa_dir_map[b]) - MUL_F(QMF_RE(ps->SA[s][b]), sa_map[b]);
                QMF_IM(X_right[s][b]) = MUL_F(QMF_IM(X_left[s][b]), sa_dir_map[b]) - MUL_F(QMF_IM(ps->SA[s][b]), sa_map[b]);
                QMF_RE(X_left[s][b]) = MUL_F(QMF_RE(X_left[s][b]), sa_dir_map[b]) + MUL_F(QMF_RE(ps->SA[s][b]), sa_map[b]);
                QMF_IM(X_left[s][b]) = MUL_F(QMF_IM(X_left[s][b]), sa_dir_map[b]) + MUL_F(QMF_IM(ps->SA[s][b]), sa_map[b]);
      
                sa_map[b]     += k_sa_map[b];
                sa_dir_map[b] += k_sa_dir_map[b];
            }
            for (b = sa_freq_scale[DRM_NUM_SA_BANDS][rateselect]; b < NUM_OF_QMF_CHANNELS; b++)
            {                
                QMF_RE(X_right[s][b]) = QMF_RE(X_left[s][b]);
                QMF_IM(X_right[s][b]) = QMF_IM(X_left[s][b]);
            }
        }
    } 
    else {
        for (s = 0; s < NUM_OF_SUBSAMPLES; s++)
        {
            for (b = 0; b < NUM_OF_QMF_CHANNELS; b++)
            {
                QMF_RE(X_right[s][b]) = QMF_RE(X_left[s][b]);
                QMF_IM(X_right[s][b]) = QMF_IM(X_left[s][b]);                
            }
        }
    }
}

static void drm_add_pan(drm_ps_info *ps, uint8_t rateselect, qmf_t X_left[38][64], qmf_t X_right[38][64]) 
{
    uint8_t s, b, qclass, ifreq;
    real_t tmp, coeff1, coeff2;
    real_t pan_base[MAX_PAN_BAND];
    real_t pan_delta[MAX_PAN_BAND];
    qmf_t temp_l, temp_r;

    if (ps->bs_enable_pan)
    {
        for (b = 0; b < NUM_OF_QMF_CHANNELS; b++) 
        {
            /* Instead of dequantization, 20->64 mapping and 2^G(x,y) we do an
               inverse mapping 64->20 and look up the 2^G(x,y) values directly */
            ifreq = pan_inv_freq[b];
            qclass = pan_quant_class[ifreq];

            if (ps->g_prev_pan_index[ifreq] >= 0)
            {
                pan_base[b] = pan_pow_2_pos[ps->g_prev_pan_index[ifreq]][qclass]; 
            } else {
                pan_base[b] = pan_pow_2_neg[-ps->g_prev_pan_index[ifreq]][qclass];
            }

            /* 2^((a-b)/30) = 2^(a/30) * 1/(2^(b/30)) */
            /* a en b can be negative so we may need to inverse parts */
            if (ps->g_pan_index[ifreq] >= 0)
            {
                if (ps->g_prev_pan_index[ifreq] >= 0) 
                {
                    pan_delta[b] = MUL_C(pan_pow_2_30_pos[ps->g_pan_index[ifreq]][qclass],
                                         pan_pow_2_30_neg[ps->g_prev_pan_index[ifreq]][qclass]);
                } else {
                    pan_delta[b] = MUL_C(pan_pow_2_30_pos[ps->g_pan_index[ifreq]][qclass],
                                         pan_pow_2_30_pos[-ps->g_prev_pan_index[ifreq]][qclass]);
                }
            } else {
                if (ps->g_prev_pan_index[ifreq] >= 0) 
                {
                    pan_delta[b] = MUL_C(pan_pow_2_30_neg[-ps->g_pan_index[ifreq]][qclass],
                                         pan_pow_2_30_neg[ps->g_prev_pan_index[ifreq]][qclass]);
                } else {
                    pan_delta[b] = MUL_C(pan_pow_2_30_neg[-ps->g_pan_index[ifreq]][qclass],
                                         pan_pow_2_30_pos[-ps->g_prev_pan_index[ifreq]][qclass]);
                }
            }
        }

        for (s = 0; s < NUM_OF_SUBSAMPLES; s++)
        {
            /* PAN always uses all 64 channels */
            for (b = 0; b < NUM_OF_QMF_CHANNELS; b++)
            {
                tmp = pan_base[b];

                coeff2 = DIV_R(REAL_CONST(2.0), (REAL_CONST(1.0) + tmp));
                coeff1 = MUL_R(coeff2, tmp);                

                QMF_RE(temp_l) = QMF_RE(X_left[s][b]);
                QMF_IM(temp_l) = QMF_IM(X_left[s][b]);
                QMF_RE(temp_r) = QMF_RE(X_right[s][b]);
                QMF_IM(temp_r) = QMF_IM(X_right[s][b]);

                QMF_RE(X_left[s][b]) = MUL_R(QMF_RE(temp_l), coeff1);
                QMF_IM(X_left[s][b]) = MUL_R(QMF_IM(temp_l), coeff1);
                QMF_RE(X_right[s][b]) = MUL_R(QMF_RE(temp_r), coeff2);
                QMF_IM(X_right[s][b]) = MUL_R(QMF_IM(temp_r), coeff2);
                
                /* 2^(a+k*b) = 2^a * 2^b * ... * 2^b */
                /*                   ^^^^^^^^^^^^^^^ k times */
                pan_base[b] = MUL_C(pan_base[b], pan_delta[b]);
            }           
        }       
    }     
}

drm_ps_info *drm_ps_init(void)
{
    drm_ps_info *ps = (drm_ps_info*)faad_malloc(sizeof(drm_ps_info));

    memset(ps, 0, sizeof(drm_ps_info));     

    return ps;
}

void drm_ps_free(drm_ps_info *ps)
{
    faad_free(ps);
}

/* main DRM PS decoding function */
uint8_t drm_ps_decode(drm_ps_info *ps, uint8_t guess, uint32_t samplerate, qmf_t X_left[38][64], qmf_t X_right[38][64])
{
    uint8_t rateselect = (samplerate >= 24000);
    
    if (ps == NULL) 
    {
        memcpy(X_right, X_left, sizeof(qmf_t)*30*64);
        return 0;    
    }     

    if (!ps->drm_ps_data_available && !guess) 
    {
        memcpy(X_right, X_left, sizeof(qmf_t)*30*64);
        memset(ps->g_prev_sa_index, 0, sizeof(ps->g_prev_sa_index));
        memset(ps->g_prev_pan_index, 0, sizeof(ps->g_prev_pan_index));
        return 0;
    }

    /* if SBR CRC doesn't match out, we can assume decode errors to start with,
       and we'll guess what the parameters should be */
    if (!guess)
    {
        ps->sa_decode_error = 0;
        ps->pan_decode_error = 0;
        drm_ps_delta_decode(ps);
    } else 
    {
        ps->sa_decode_error = 1;
        ps->pan_decode_error = 1;
        /* don't even bother decoding */
    }
  
    ps->drm_ps_data_available = 0;

    drm_calc_sa_side_signal(ps, X_left, rateselect);
    drm_add_ambiance(ps, rateselect, X_left, X_right);

    if (ps->bs_enable_sa)
    {
        ps->g_last_had_sa = 1;        

        memcpy(ps->g_prev_sa_index, ps->g_sa_index, sizeof(int8_t) * DRM_NUM_SA_BANDS);       

    } else {
        ps->g_last_had_sa = 0;
    }
    
    if (ps->bs_enable_pan)
    {
        drm_add_pan(ps, rateselect, X_left, X_right);
    
        ps->g_last_had_pan = 1;        

        memcpy(ps->g_prev_pan_index, ps->g_pan_index, sizeof(int8_t) * DRM_NUM_PAN_BANDS);

    } else {
        ps->g_last_had_pan = 0;
    }


    return 0;
}

#endif

⌨️ 快捷键说明

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