aboutsummaryrefslogtreecommitdiff
path: root/decoder/ixheaacd_tcx_fwd_alcnx.c
diff options
context:
space:
mode:
Diffstat (limited to 'decoder/ixheaacd_tcx_fwd_alcnx.c')
-rw-r--r--decoder/ixheaacd_tcx_fwd_alcnx.c105
1 files changed, 84 insertions, 21 deletions
diff --git a/decoder/ixheaacd_tcx_fwd_alcnx.c b/decoder/ixheaacd_tcx_fwd_alcnx.c
index 411bf35..e0dd052 100644
--- a/decoder/ixheaacd_tcx_fwd_alcnx.c
+++ b/decoder/ixheaacd_tcx_fwd_alcnx.c
@@ -43,6 +43,8 @@
#include "ixheaacd_mps_polyphase.h"
#include "ixheaacd_sbr_const.h"
+#include "ixheaacd_ec_defines.h"
+#include "ixheaacd_ec_struct_def.h"
#include "ixheaacd_main.h"
#include "ixheaacd_arith_dec.h"
#include "ixheaacd_func_def.h"
@@ -53,7 +55,6 @@
#include "ixheaacd_basic_ops32.h"
#include "ixheaacd_basic_ops40.h"
-static FLOAT32 ixheaacd_randomsign(UWORD32 *seed);
#define ABS(A) ((A) < 0 ? (-A) : (A))
VOID ixheaacd_lpc_coeff_wt_apply(FLOAT32 *a, FLOAT32 *ap) {
@@ -135,17 +136,48 @@ static VOID ixheaacd_low_fq_deemphasis(FLOAT32 x[], WORD32 lg,
return;
}
+static WORD32 ixheaacd_calc_max_pitch(FLOAT32 x[LEN_SUPERFRAME], WORD32 n) {
+ FLOAT32 max_m;
+ FLOAT32 t_est;
+ WORD32 i, i_max, pitch_tcx;
+
+ max_m = 0;
+ i_max = 1;
+
+ for (i = 1; i < n; i++) {
+ FLOAT32 mag = (x[2 * i] * x[2 * i]) + (x[2 * i + 1] * x[2 * i + 1]);
+ if (mag > max_m) {
+ max_m = mag;
+ i_max = i;
+ }
+ }
+
+ t_est = (n / (FLOAT32)i_max);
+
+ if (t_est >= 256) {
+ pitch_tcx = 256;
+ } else {
+ FLOAT32 tmp_est = t_est;
+ while (tmp_est < 256) {
+ tmp_est += t_est;
+ }
+ pitch_tcx = (WORD32)(tmp_est - t_est);
+ }
+
+ return (pitch_tcx);
+}
+
WORD32 ixheaacd_tcx_mdct(ia_usac_data_struct *usac_data,
ia_td_frame_data_struct *pstr_td_frame_data,
WORD32 frame_index, FLOAT32 lp_flt_coff_a[], WORD32 lg,
ia_usac_lpd_decoder_handle st) {
WORD32 i, mode;
WORD32 *ptr_tcx_quant;
- FLOAT32 tmp, gain_tcx, noise_level, energy, temp;
+ FLOAT32 tmp, gain_tcx = 0.0f, noise_level, energy, temp;
FLOAT32 *ptr_a, i_ap[ORDER + 1];
const FLOAT32 *sine_window_prev, *sine_window;
WORD32 fac_length_prev;
- FLOAT32 alfd_gains[LEN_SUPERFRAME / (4 * 8)];
+ FLOAT32 alfd_gains[LEN_SUPERFRAME / (4 * 8)] = {0};
FLOAT32 x[LEN_SUPERFRAME], buf[ORDER + LEN_SUPERFRAME];
WORD32 int_x[LEN_SUPERFRAME + (2 * FAC_LENGTH)];
WORD32 int_xn1[LEN_SUPERFRAME + (2 * FAC_LENGTH)];
@@ -154,7 +186,7 @@ WORD32 ixheaacd_tcx_mdct(ia_usac_data_struct *usac_data,
FLOAT32 *xn;
FLOAT32 xn1[2 * FAC_LENGTH], facwindow[2 * FAC_LENGTH];
WORD32 TTT;
- WORD8 shiftp;
+ WORD8 shiftp = 0;
WORD32 preshift = 0;
WORD32 loop_count = 0;
FLOAT32 *exc = &usac_data->exc_buf[usac_data->len_subfrm * frame_index +
@@ -208,10 +240,8 @@ WORD32 ixheaacd_tcx_mdct(ia_usac_data_struct *usac_data,
st->exc_prev[i + fac_length + fac_length_prev + 1] = 0.0f;
}
}
-
- noise_level =
- 0.0625f *
- (8.0f - ((FLOAT32)pstr_td_frame_data->noise_factor[frame_index]));
+ if (usac_data->frame_ok == 1) {
+ noise_level = 0.0625f * (8.0f - ((FLOAT32)pstr_td_frame_data->noise_factor[frame_index]));
ptr_tcx_quant = pstr_td_frame_data->x_tcx_invquant;
for (i = 0; i < frame_index; i++)
@@ -219,6 +249,10 @@ WORD32 ixheaacd_tcx_mdct(ia_usac_data_struct *usac_data,
for (i = 0; i < lg; i++) x[i] = (FLOAT32)ptr_tcx_quant[i];
+ if (usac_data->ec_flag) {
+ st->last_tcx_pitch = ixheaacd_calc_max_pitch(x, (lg >> 5));
+ }
+
for (i = lg / 6; i < lg; i += 8) {
WORD32 k, max_k = min(lg, i + 8);
FLOAT32 tmp = 0.0f;
@@ -235,12 +269,10 @@ WORD32 ixheaacd_tcx_mdct(ia_usac_data_struct *usac_data,
ixheaacd_low_fq_deemphasis(x, lg, alfd_gains);
ixheaacd_lpc_coeff_wt_apply(lp_flt_coff_a + (ORDER + 1), i_ap);
- err = ixheaacd_lpc_to_td(i_ap, ORDER, gain1, usac_data->len_subfrm / 4);
- if (err) return err;
+ ixheaacd_lpc_to_td(i_ap, ORDER, gain1, usac_data->len_subfrm / 4);
ixheaacd_lpc_coeff_wt_apply(lp_flt_coff_a + (2 * (ORDER + 1)), i_ap);
- err = ixheaacd_lpc_to_td(i_ap, ORDER, gain2, usac_data->len_subfrm / 4);
- if (err) return err;
+ ixheaacd_lpc_to_td(i_ap, ORDER, gain2, usac_data->len_subfrm / 4);
energy = 0.01f;
for (i = 0; i < lg; i++) energy += x[i] * x[i];
@@ -252,14 +284,38 @@ WORD32 ixheaacd_tcx_mdct(ia_usac_data_struct *usac_data,
10.0f,
((FLOAT32)pstr_td_frame_data->global_gain[frame_index]) / 28.0f) /
(temp * 2.0f);
-
+ }
+ if (usac_data->ec_flag) {
+ if (usac_data->frame_ok == 1) {
+ usac_data->past_gain_tcx[usac_data->present_chan] = gain_tcx;
+ } else {
+ gain_tcx = usac_data->past_gain_tcx[usac_data->present_chan];
+ }
+ }
+ if (usac_data->frame_ok == 1) {
ixheaacd_noise_shaping(x, lg, (usac_data->len_subfrm) / 4, gain1, gain2);
-
shiftp = ixheaacd_float2fix(x, int_x, lg);
+ }
+ if (usac_data->ec_flag == 1) {
+ if (st->mode_prev != 0) {
+ if (usac_data->frame_ok == 1) {
+ memcpy(usac_data->tcx_spec_coeffs[usac_data->present_chan], int_x, lg * sizeof(int_x[0]));
+ usac_data->last_shiftp = shiftp;
+ } else {
+ memcpy(int_x, usac_data->tcx_spec_coeffs[usac_data->present_chan], lg * sizeof(int_x[0]));
+ shiftp = usac_data->last_shiftp;
+ }
+ }
+ } else {
+ if (lg & (lg - 1)) {
+ if ((lg != 48) && (lg != 96) && (lg != 192) && (lg != 384) && (lg != 768)) {
+ return -1;
+ }
+ }
+ }
- err = ixheaacd_acelp_mdct_main(usac_data, int_x, int_xn1, (2 * fac_length),
- lg - (2 * fac_length), &preshift);
- if (err == -1) return err;
+ ixheaacd_acelp_mdct_main(usac_data, int_x, int_xn1, (2 * fac_length), lg - (2 * fac_length),
+ &preshift);
ixheaacd_fix2float(int_xn1, xn_buf, (lg + (2 * fac_length)), &shiftp,
&preshift);
@@ -298,9 +354,16 @@ WORD32 ixheaacd_tcx_mdct(ia_usac_data_struct *usac_data,
preshift = 0;
shiftp = ixheaacd_float2fix(x, int_x, fac_length);
- err =
- ixheaacd_acelp_mdct(int_x, int_xn1, &preshift, fac_length, ptr_scratch);
- if (err == -1) return err;
+ if (usac_data->ec_flag == 0) {
+ if (fac_length & (fac_length - 1)) {
+ if ((fac_length != 48) && (fac_length != 96) && (fac_length != 192) &&
+ (fac_length != 384) && (fac_length != 768)) {
+ return -1;
+ }
+ }
+ }
+
+ ixheaacd_acelp_mdct(int_x, int_xn1, &preshift, fac_length, ptr_scratch);
ixheaacd_fix2float(int_xn1, xn1, fac_length, &shiftp, &preshift);
@@ -377,7 +440,7 @@ WORD32 ixheaacd_tcx_mdct(ia_usac_data_struct *usac_data,
return err;
}
-static FLOAT32 ixheaacd_randomsign(UWORD32 *seed) {
+FLOAT32 ixheaacd_randomsign(UWORD32 *seed) {
FLOAT32 sign = 0.0f;
*seed = (UWORD32)(((UWORD64)(*seed) * (UWORD64)69069) + 5);