📄 drm_dec.c
字号:
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 + -