📄 ps_dec.c
字号:
y[3] = f2 - f8;
y[0] = f2 + f8;
y[2] = f1 - f7;
y[1] = f1 + f7;
}
/* complex filter, size 8 */
static void channel_filter8(hyb_info *hyb, uint8_t frame_len, const real_t *filter,
qmf_t *buffer, qmf_t **X_hybrid)
{
uint8_t i, n;
real_t input_re1[4], input_re2[4], input_im1[4], input_im2[4];
real_t x[4];
for (i = 0; i < frame_len; i++)
{
input_re1[0] = MUL_F(filter[6],QMF_RE(buffer[6+i]));
input_re1[1] = MUL_F(filter[5],(QMF_RE(buffer[5+i]) + QMF_RE(buffer[7+i])));
input_re1[2] = -MUL_F(filter[0],(QMF_RE(buffer[0+i]) + QMF_RE(buffer[12+i]))) + MUL_F(filter[4],(QMF_RE(buffer[4+i]) + QMF_RE(buffer[8+i])));
input_re1[3] = -MUL_F(filter[1],(QMF_RE(buffer[1+i]) + QMF_RE(buffer[11+i]))) + MUL_F(filter[3],(QMF_RE(buffer[3+i]) + QMF_RE(buffer[9+i])));
input_im1[0] = MUL_F(filter[5],(QMF_IM(buffer[7+i]) - QMF_IM(buffer[5+i])));
input_im1[1] = MUL_F(filter[0],(QMF_IM(buffer[12+i]) - QMF_IM(buffer[0+i]))) + MUL_F(filter[4],(QMF_IM(buffer[8+i]) - QMF_IM(buffer[4+i])));
input_im1[2] = MUL_F(filter[1],(QMF_IM(buffer[11+i]) - QMF_IM(buffer[1+i]))) + MUL_F(filter[3],(QMF_IM(buffer[9+i]) - QMF_IM(buffer[3+i])));
input_im1[3] = MUL_F(filter[2],(QMF_IM(buffer[10+i]) - QMF_IM(buffer[2+i])));
for (n = 0; n < 4; n++)
{
x[n] = input_re1[n] - input_im1[3-n];
}
DCT3_4_unscaled(x, x);
QMF_RE(X_hybrid[i][7]) = x[0];
QMF_RE(X_hybrid[i][5]) = x[2];
QMF_RE(X_hybrid[i][3]) = x[3];
QMF_RE(X_hybrid[i][1]) = x[1];
for (n = 0; n < 4; n++)
{
x[n] = input_re1[n] + input_im1[3-n];
}
DCT3_4_unscaled(x, x);
QMF_RE(X_hybrid[i][6]) = x[1];
QMF_RE(X_hybrid[i][4]) = x[3];
QMF_RE(X_hybrid[i][2]) = x[2];
QMF_RE(X_hybrid[i][0]) = x[0];
input_im2[0] = MUL_F(filter[6],QMF_IM(buffer[6+i]));
input_im2[1] = MUL_F(filter[5],(QMF_IM(buffer[5+i]) + QMF_IM(buffer[7+i])));
input_im2[2] = -MUL_F(filter[0],(QMF_IM(buffer[0+i]) + QMF_IM(buffer[12+i]))) + MUL_F(filter[4],(QMF_IM(buffer[4+i]) + QMF_IM(buffer[8+i])));
input_im2[3] = -MUL_F(filter[1],(QMF_IM(buffer[1+i]) + QMF_IM(buffer[11+i]))) + MUL_F(filter[3],(QMF_IM(buffer[3+i]) + QMF_IM(buffer[9+i])));
input_re2[0] = MUL_F(filter[5],(QMF_RE(buffer[7+i]) - QMF_RE(buffer[5+i])));
input_re2[1] = MUL_F(filter[0],(QMF_RE(buffer[12+i]) - QMF_RE(buffer[0+i]))) + MUL_F(filter[4],(QMF_RE(buffer[8+i]) - QMF_RE(buffer[4+i])));
input_re2[2] = MUL_F(filter[1],(QMF_RE(buffer[11+i]) - QMF_RE(buffer[1+i]))) + MUL_F(filter[3],(QMF_RE(buffer[9+i]) - QMF_RE(buffer[3+i])));
input_re2[3] = MUL_F(filter[2],(QMF_RE(buffer[10+i]) - QMF_RE(buffer[2+i])));
for (n = 0; n < 4; n++)
{
x[n] = input_im2[n] + input_re2[3-n];
}
DCT3_4_unscaled(x, x);
QMF_IM(X_hybrid[i][7]) = x[0];
QMF_IM(X_hybrid[i][5]) = x[2];
QMF_IM(X_hybrid[i][3]) = x[3];
QMF_IM(X_hybrid[i][1]) = x[1];
for (n = 0; n < 4; n++)
{
x[n] = input_im2[n] - input_re2[3-n];
}
DCT3_4_unscaled(x, x);
QMF_IM(X_hybrid[i][6]) = x[1];
QMF_IM(X_hybrid[i][4]) = x[3];
QMF_IM(X_hybrid[i][2]) = x[2];
QMF_IM(X_hybrid[i][0]) = x[0];
}
}
static void INLINE DCT3_6_unscaled(real_t *y, real_t *x)
{
real_t f0, f1, f2, f3, f4, f5, f6, f7;
f0 = MUL_F(x[3], FRAC_CONST(0.70710678118655));
f1 = x[0] + f0;
f2 = x[0] - f0;
f3 = MUL_F((x[1] - x[5]), FRAC_CONST(0.70710678118655));
f4 = MUL_F(x[2], FRAC_CONST(0.86602540378444)) + MUL_F(x[4], FRAC_CONST(0.5));
f5 = f4 - x[4];
f6 = MUL_F(x[1], FRAC_CONST(0.96592582628907)) + MUL_F(x[5], FRAC_CONST(0.25881904510252));
f7 = f6 - f3;
y[0] = f1 + f6 + f4;
y[1] = f2 + f3 - x[4];
y[2] = f7 + f2 - f5;
y[3] = f1 - f7 - f5;
y[4] = f1 - f3 - x[4];
y[5] = f2 - f6 + f4;
}
/* complex filter, size 12 */
static void channel_filter12(hyb_info *hyb, uint8_t frame_len, const real_t *filter,
qmf_t *buffer, qmf_t **X_hybrid)
{
uint8_t i, n;
real_t input_re1[6], input_re2[6], input_im1[6], input_im2[6];
real_t out_re1[6], out_re2[6], out_im1[6], out_im2[6];
for (i = 0; i < frame_len; i++)
{
for (n = 0; n < 6; n++)
{
if (n == 0)
{
input_re1[0] = MUL_F(QMF_RE(buffer[6+i]), filter[6]);
input_re2[0] = MUL_F(QMF_IM(buffer[6+i]), filter[6]);
} else {
input_re1[6-n] = MUL_F((QMF_RE(buffer[n+i]) + QMF_RE(buffer[12-n+i])), filter[n]);
input_re2[6-n] = MUL_F((QMF_IM(buffer[n+i]) + QMF_IM(buffer[12-n+i])), filter[n]);
}
input_im2[n] = MUL_F((QMF_RE(buffer[n+i]) - QMF_RE(buffer[12-n+i])), filter[n]);
input_im1[n] = MUL_F((QMF_IM(buffer[n+i]) - QMF_IM(buffer[12-n+i])), filter[n]);
}
DCT3_6_unscaled(out_re1, input_re1);
DCT3_6_unscaled(out_re2, input_re2);
DCT3_6_unscaled(out_im1, input_im1);
DCT3_6_unscaled(out_im2, input_im2);
for (n = 0; n < 6; n += 2)
{
QMF_RE(X_hybrid[i][n]) = out_re1[n] - out_im1[n];
QMF_IM(X_hybrid[i][n]) = out_re2[n] + out_im2[n];
QMF_RE(X_hybrid[i][n+1]) = out_re1[n+1] + out_im1[n+1];
QMF_IM(X_hybrid[i][n+1]) = out_re2[n+1] - out_im2[n+1];
QMF_RE(X_hybrid[i][10-n]) = out_re1[n+1] - out_im1[n+1];
QMF_IM(X_hybrid[i][10-n]) = out_re2[n+1] + out_im2[n+1];
QMF_RE(X_hybrid[i][11-n]) = out_re1[n] + out_im1[n];
QMF_IM(X_hybrid[i][11-n]) = out_re2[n] - out_im2[n];
}
}
}
/* Hybrid analysis: further split up QMF subbands
* to improve frequency resolution
*/
static void hybrid_analysis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32],
uint8_t use34)
{
uint8_t k, n, band;
uint8_t offset = 0;
uint8_t qmf_bands = (use34) ? 5 : 3;
uint8_t *resolution = (use34) ? hyb->resolution34 : hyb->resolution20;
for (band = 0; band < qmf_bands; band++)
{
/* build working buffer */
memcpy(hyb->work, hyb->buffer[band], 12 * sizeof(qmf_t));
/* add new samples */
for (n = 0; n < hyb->frame_len; n++)
{
QMF_RE(hyb->work[12 + n]) = QMF_RE(X[n + 6 /*delay*/][band]);
QMF_IM(hyb->work[12 + n]) = QMF_IM(X[n + 6 /*delay*/][band]);
}
/* store samples */
memcpy(hyb->buffer[band], hyb->work + hyb->frame_len, 12 * sizeof(qmf_t));
switch(resolution[band])
{
case 2:
/* Type B real filter, Q[p] = 2 */
channel_filter2(hyb, hyb->frame_len, p2_13_20, hyb->work, hyb->temp);
break;
case 4:
/* Type A complex filter, Q[p] = 4 */
channel_filter4(hyb, hyb->frame_len, p4_13_34, hyb->work, hyb->temp);
break;
case 8:
/* Type A complex filter, Q[p] = 8 */
channel_filter8(hyb, hyb->frame_len, (use34) ? p8_13_34 : p8_13_20,
hyb->work, hyb->temp);
break;
case 12:
/* Type A complex filter, Q[p] = 12 */
channel_filter12(hyb, hyb->frame_len, p12_13_34, hyb->work, hyb->temp);
break;
}
for (n = 0; n < hyb->frame_len; n++)
{
for (k = 0; k < resolution[band]; k++)
{
QMF_RE(X_hybrid[n][offset + k]) = QMF_RE(hyb->temp[n][k]);
QMF_IM(X_hybrid[n][offset + k]) = QMF_IM(hyb->temp[n][k]);
}
}
offset += resolution[band];
}
/* group hybrid channels */
if (!use34)
{
for (n = 0; n < 32 /*30?*/; n++)
{
QMF_RE(X_hybrid[n][3]) += QMF_RE(X_hybrid[n][4]);
QMF_IM(X_hybrid[n][3]) += QMF_IM(X_hybrid[n][4]);
QMF_RE(X_hybrid[n][4]) = 0;
QMF_IM(X_hybrid[n][4]) = 0;
QMF_RE(X_hybrid[n][2]) += QMF_RE(X_hybrid[n][5]);
QMF_IM(X_hybrid[n][2]) += QMF_IM(X_hybrid[n][5]);
QMF_RE(X_hybrid[n][5]) = 0;
QMF_IM(X_hybrid[n][5]) = 0;
}
}
}
static void hybrid_synthesis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32],
uint8_t use34)
{
uint8_t k, n, band;
uint8_t offset = 0;
uint8_t qmf_bands = (use34) ? 5 : 3;
uint8_t *resolution = (use34) ? hyb->resolution34 : hyb->resolution20;
for(band = 0; band < qmf_bands; band++)
{
for (n = 0; n < hyb->frame_len; n++)
{
QMF_RE(X[n][band]) = 0;
QMF_IM(X[n][band]) = 0;
for (k = 0; k < resolution[band]; k++)
{
QMF_RE(X[n][band]) += QMF_RE(X_hybrid[n][offset + k]);
QMF_IM(X[n][band]) += QMF_IM(X_hybrid[n][offset + k]);
}
}
offset += resolution[band];
}
}
/* limits the value i to the range [min,max] */
static int8_t delta_clip(int8_t i, int8_t min, int8_t max)
{
if (i < min)
return min;
else if (i > max)
return max;
else
return i;
}
//int iid = 0;
/* delta decode array */
static void delta_decode(uint8_t enable, int8_t *index, int8_t *index_prev,
uint8_t dt_flag, uint8_t nr_par, uint8_t stride,
int8_t min_index, int8_t max_index)
{
int8_t i;
if (enable == 1)
{
if (dt_flag == 0)
{
/* delta coded in frequency direction */
index[0] = 0 + index[0];
index[0] = delta_clip(index[0], min_index, max_index);
for (i = 1; i < nr_par; i++)
{
index[i] = index[i-1] + index[i];
index[i] = delta_clip(index[i], min_index, max_index);
}
} else {
/* delta coded in time direction */
for (i = 0; i < nr_par; i++)
{
//int8_t tmp2;
//int8_t tmp = index[i];
//printf("%d %d\n", index_prev[i*stride], index[i]);
//printf("%d\n", index[i]);
index[i] = index_prev[i*stride] + index[i];
//tmp2 = index[i];
index[i] = delta_clip(index[i], min_index, max_index);
//if (iid)
//{
// if (index[i] == 7)
// {
// printf("%d %d %d\n", index_prev[i*stride], tmp, tmp2);
// }
//}
}
}
} else {
/* set indices to zero */
for (i = 0; i < nr_par; i++)
{
index[i] = 0;
}
}
/* coarse */
if (stride == 2)
{
for (i = (nr_par<<1)-1; i > 0; i--)
{
index[i] = index[i>>1];
}
}
}
/* delta modulo decode array */
/* in: log2 value of the modulo value to allow using AND instead of MOD */
static void delta_modulo_decode(uint8_t enable, int8_t *index, int8_t *index_prev,
uint8_t dt_flag, uint8_t nr_par, uint8_t stride,
int8_t log2modulo)
{
int8_t i;
if (enable == 1)
{
if (dt_flag == 0)
{
/* delta coded in frequency direction */
index[0] = 0 + index[0];
index[0] &= log2modulo;
for (i = 1; i < nr_par; i++)
{
index[i] = index[i-1] + index[i];
index[i] &= log2modulo;
}
} else {
/* delta coded in time direction */
for (i = 0; i < nr_par; i++)
{
index[i] = index_prev[i*stride] + index[i];
index[i] &= log2modulo;
}
}
} else {
/* set indices to zero */
for (i = 0; i < nr_par; i++)
{
index[i] = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -