1*15dc779aSAndroid Build Coastguard Worker /******************************************************************************
2*15dc779aSAndroid Build Coastguard Worker * *
3*15dc779aSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project
4*15dc779aSAndroid Build Coastguard Worker *
5*15dc779aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*15dc779aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*15dc779aSAndroid Build Coastguard Worker * You may obtain a copy of the License at:
8*15dc779aSAndroid Build Coastguard Worker *
9*15dc779aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*15dc779aSAndroid Build Coastguard Worker *
11*15dc779aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*15dc779aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*15dc779aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*15dc779aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*15dc779aSAndroid Build Coastguard Worker * limitations under the License.
16*15dc779aSAndroid Build Coastguard Worker *
17*15dc779aSAndroid Build Coastguard Worker *****************************************************************************
18*15dc779aSAndroid Build Coastguard Worker * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*15dc779aSAndroid Build Coastguard Worker */
20*15dc779aSAndroid Build Coastguard Worker #include <string.h>
21*15dc779aSAndroid Build Coastguard Worker #include <ixheaac_type_def.h>
22*15dc779aSAndroid Build Coastguard Worker #include <ixheaac_constants.h>
23*15dc779aSAndroid Build Coastguard Worker #include <ixheaac_basic_ops32.h>
24*15dc779aSAndroid Build Coastguard Worker #include <ixheaac_basic_ops16.h>
25*15dc779aSAndroid Build Coastguard Worker #include <ixheaac_basic_ops40.h>
26*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_common.h"
27*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_intrinsics.h"
28*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_common_rom.h"
29*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecsettings.h"
30*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_bitbuffer.h"
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_defines.h"
32*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_pns.h"
33*15dc779aSAndroid Build Coastguard Worker #include <ixheaacd_aac_rom.h>
34*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_pulsedata.h"
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_lt_predict.h"
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_cnst.h"
37*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_data_struct.h"
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_defines.h"
39*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_rom.h"
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_struct_def.h"
41*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_channelinfo.h"
42*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_interface.h"
43*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_acelp_info.h"
44*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_tns_usac.h"
45*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_info.h"
46*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_dec.h"
47*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecoder.h"
48*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_mps_polyphase.h"
49*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_sbr_const.h"
50*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_defines.h"
51*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_struct_def.h"
52*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_main.h"
53*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_acelp_com.h"
54*15dc779aSAndroid Build Coastguard Worker
ixheaacd_usac_ec_get_win_seq(WORD32 prev_win_seq)55*15dc779aSAndroid Build Coastguard Worker static WORD32 ixheaacd_usac_ec_get_win_seq(WORD32 prev_win_seq) {
56*15dc779aSAndroid Build Coastguard Worker if (prev_win_seq == LONG_START_SEQUENCE || prev_win_seq == EIGHT_SHORT_SEQUENCE) {
57*15dc779aSAndroid Build Coastguard Worker return LONG_STOP_SEQUENCE;
58*15dc779aSAndroid Build Coastguard Worker } else {
59*15dc779aSAndroid Build Coastguard Worker return ONLY_LONG_SEQUENCE;
60*15dc779aSAndroid Build Coastguard Worker }
61*15dc779aSAndroid Build Coastguard Worker }
62*15dc779aSAndroid Build Coastguard Worker
ixheaacd_usac_flip_spec_sign(WORD32 * ptr_spec_coeff,WORD32 samples_per_frame,UWORD32 * seed_value)63*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_usac_flip_spec_sign(WORD32 *ptr_spec_coeff, WORD32 samples_per_frame,
64*15dc779aSAndroid Build Coastguard Worker UWORD32 *seed_value) {
65*15dc779aSAndroid Build Coastguard Worker WORD32 i;
66*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < samples_per_frame; i++) {
67*15dc779aSAndroid Build Coastguard Worker ptr_spec_coeff[i] = ixheaac_mult32x16in32_sat(ptr_spec_coeff[i],
68*15dc779aSAndroid Build Coastguard Worker (WORD16)ixheaacd_randomsign(seed_value));
69*15dc779aSAndroid Build Coastguard Worker }
70*15dc779aSAndroid Build Coastguard Worker }
71*15dc779aSAndroid Build Coastguard Worker
iexheaace_ec_sfb_nrg_q(WORD32 * ptr_spectrum,ia_ec_sfb_str * pstr_ec_sfb,WORD32 win_seq,WORD32 win_trans,WORD32 * ptr_sfb_enrg)72*15dc779aSAndroid Build Coastguard Worker static VOID iexheaace_ec_sfb_nrg_q(WORD32 *ptr_spectrum, ia_ec_sfb_str *pstr_ec_sfb,
73*15dc779aSAndroid Build Coastguard Worker WORD32 win_seq, WORD32 win_trans, WORD32 *ptr_sfb_enrg) {
74*15dc779aSAndroid Build Coastguard Worker WORD16 *ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_long;
75*15dc779aSAndroid Build Coastguard Worker WORD32 l = 0, sfb, num_sfb = pstr_ec_sfb->num_sfb_long;
76*15dc779aSAndroid Build Coastguard Worker switch (win_seq) {
77*15dc779aSAndroid Build Coastguard Worker case EIGHT_SHORT_SEQUENCE:
78*15dc779aSAndroid Build Coastguard Worker if (win_trans == NO_TRANSITION) {
79*15dc779aSAndroid Build Coastguard Worker num_sfb = pstr_ec_sfb->num_sfb_short;
80*15dc779aSAndroid Build Coastguard Worker ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_short;
81*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < num_sfb; sfb++) {
82*15dc779aSAndroid Build Coastguard Worker WORD64 accu = (WORD64)1;
83*15dc779aSAndroid Build Coastguard Worker WORD32 q_nrg = (sizeof(accu) << 3) -
84*15dc779aSAndroid Build Coastguard Worker ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
85*15dc779aSAndroid Build Coastguard Worker for (; l < ptr_sfb_offset[sfb + 1]; l++) {
86*15dc779aSAndroid Build Coastguard Worker accu += ixheaac_mul32_sh(ptr_spectrum[l], ptr_spectrum[l], q_nrg);
87*15dc779aSAndroid Build Coastguard Worker }
88*15dc779aSAndroid Build Coastguard Worker ptr_sfb_enrg[sfb] = ixheaac_norm32((WORD32)accu);
89*15dc779aSAndroid Build Coastguard Worker }
90*15dc779aSAndroid Build Coastguard Worker } else {
91*15dc779aSAndroid Build Coastguard Worker num_sfb = pstr_ec_sfb->num_sfb_long;
92*15dc779aSAndroid Build Coastguard Worker ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_long;
93*15dc779aSAndroid Build Coastguard Worker
94*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < num_sfb; sfb++) {
95*15dc779aSAndroid Build Coastguard Worker WORD64 accu = (WORD64)1;
96*15dc779aSAndroid Build Coastguard Worker WORD32 q_nrg = (sizeof(accu) << 3) -
97*15dc779aSAndroid Build Coastguard Worker ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
98*15dc779aSAndroid Build Coastguard Worker for (; l < ptr_sfb_offset[sfb + 1]; l++) {
99*15dc779aSAndroid Build Coastguard Worker accu += ixheaac_mul32_sh(ptr_spectrum[(l >> 3)], ptr_spectrum[(l >> 3)], q_nrg);
100*15dc779aSAndroid Build Coastguard Worker }
101*15dc779aSAndroid Build Coastguard Worker ptr_sfb_enrg[sfb] = ixheaac_norm32((WORD32)accu);
102*15dc779aSAndroid Build Coastguard Worker }
103*15dc779aSAndroid Build Coastguard Worker }
104*15dc779aSAndroid Build Coastguard Worker break;
105*15dc779aSAndroid Build Coastguard Worker case ONLY_LONG_SEQUENCE:
106*15dc779aSAndroid Build Coastguard Worker case LONG_START_SEQUENCE:
107*15dc779aSAndroid Build Coastguard Worker case LONG_STOP_SEQUENCE:
108*15dc779aSAndroid Build Coastguard Worker if (win_trans == NO_TRANSITION) {
109*15dc779aSAndroid Build Coastguard Worker num_sfb = pstr_ec_sfb->num_sfb_long;
110*15dc779aSAndroid Build Coastguard Worker ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_long;
111*15dc779aSAndroid Build Coastguard Worker
112*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < num_sfb; sfb++) {
113*15dc779aSAndroid Build Coastguard Worker WORD64 accu = (WORD64)1;
114*15dc779aSAndroid Build Coastguard Worker WORD32 q_nrg = (sizeof(accu) << 3) -
115*15dc779aSAndroid Build Coastguard Worker ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
116*15dc779aSAndroid Build Coastguard Worker for (; l < ptr_sfb_offset[sfb + 1]; l++) {
117*15dc779aSAndroid Build Coastguard Worker accu += ixheaac_mul32_sh(ptr_spectrum[l], ptr_spectrum[l], q_nrg);
118*15dc779aSAndroid Build Coastguard Worker }
119*15dc779aSAndroid Build Coastguard Worker ptr_sfb_enrg[sfb] = ixheaac_norm32((WORD32)accu);
120*15dc779aSAndroid Build Coastguard Worker }
121*15dc779aSAndroid Build Coastguard Worker } else {
122*15dc779aSAndroid Build Coastguard Worker num_sfb = pstr_ec_sfb->num_sfb_short;
123*15dc779aSAndroid Build Coastguard Worker ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_short;
124*15dc779aSAndroid Build Coastguard Worker
125*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < num_sfb; sfb++) {
126*15dc779aSAndroid Build Coastguard Worker WORD64 accu = (WORD64)1;
127*15dc779aSAndroid Build Coastguard Worker WORD32 q_nrg = (sizeof(accu) << 3) -
128*15dc779aSAndroid Build Coastguard Worker ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
129*15dc779aSAndroid Build Coastguard Worker for (; l < ptr_sfb_offset[sfb + 1] << 3; l++) {
130*15dc779aSAndroid Build Coastguard Worker accu += (accu + (ixheaac_mul32_sh(ptr_spectrum[l], ptr_spectrum[l], q_nrg))) >> 3;
131*15dc779aSAndroid Build Coastguard Worker }
132*15dc779aSAndroid Build Coastguard Worker ptr_sfb_enrg[sfb] = ixheaac_norm32((WORD32)accu);
133*15dc779aSAndroid Build Coastguard Worker }
134*15dc779aSAndroid Build Coastguard Worker }
135*15dc779aSAndroid Build Coastguard Worker break;
136*15dc779aSAndroid Build Coastguard Worker }
137*15dc779aSAndroid Build Coastguard Worker }
138*15dc779aSAndroid Build Coastguard Worker
ixheaacd_usac_ec_interpolate(WORD32 * ptr_spectrum,WORD16 * pq_spec_coeff_prev,WORD16 * pq_spec_coeff_act,WORD16 * pq_spec_coeff_out,WORD32 * ptr_nrg_prev,WORD32 * ptr_nrg_act,WORD32 num_sfb,WORD16 * ptr_sfb_offset)139*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_usac_ec_interpolate(WORD32 *ptr_spectrum, WORD16 *pq_spec_coeff_prev,
140*15dc779aSAndroid Build Coastguard Worker WORD16 *pq_spec_coeff_act, WORD16 *pq_spec_coeff_out,
141*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_nrg_prev, WORD32 *ptr_nrg_act,
142*15dc779aSAndroid Build Coastguard Worker WORD32 num_sfb, WORD16 *ptr_sfb_offset) {
143*15dc779aSAndroid Build Coastguard Worker WORD32 sfb, l = 0;
144*15dc779aSAndroid Build Coastguard Worker WORD32 fac_shift;
145*15dc779aSAndroid Build Coastguard Worker WORD32 fac_mod;
146*15dc779aSAndroid Build Coastguard Worker
147*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < num_sfb; sfb++) {
148*15dc779aSAndroid Build Coastguard Worker fac_shift =
149*15dc779aSAndroid Build Coastguard Worker ptr_nrg_prev[sfb] - ptr_nrg_act[sfb] + ((*pq_spec_coeff_act - *pq_spec_coeff_prev) << 1);
150*15dc779aSAndroid Build Coastguard Worker fac_mod = fac_shift & 3;
151*15dc779aSAndroid Build Coastguard Worker fac_shift = (fac_shift >> 2) + 1;
152*15dc779aSAndroid Build Coastguard Worker fac_shift += *pq_spec_coeff_prev - ixheaac_max16(*pq_spec_coeff_prev, *pq_spec_coeff_act);
153*15dc779aSAndroid Build Coastguard Worker fac_shift = ixheaac_max32(ixheaac_min32(fac_shift, INT_BITS - 1), -(INT_BITS - 1));
154*15dc779aSAndroid Build Coastguard Worker
155*15dc779aSAndroid Build Coastguard Worker for (; l < ptr_sfb_offset[sfb + 1]; l++) {
156*15dc779aSAndroid Build Coastguard Worker WORD32 accu = ixheaac_shl32_sat(
157*15dc779aSAndroid Build Coastguard Worker ixheaac_mult32x32in32(ptr_spectrum[l], (WORD32)(ia_ec_interpolation_fac[fac_mod])), 1);
158*15dc779aSAndroid Build Coastguard Worker ptr_spectrum[l] = ixheaac_shl32_dir_sat((WORD32)accu, fac_shift);
159*15dc779aSAndroid Build Coastguard Worker }
160*15dc779aSAndroid Build Coastguard Worker }
161*15dc779aSAndroid Build Coastguard Worker *pq_spec_coeff_out = ixheaac_max16(*pq_spec_coeff_prev, *pq_spec_coeff_act);
162*15dc779aSAndroid Build Coastguard Worker }
163*15dc779aSAndroid Build Coastguard Worker
ixheaacd_usac_ec_interpolate_frame(ia_usac_data_struct * pstr_usac_data,ia_ec_state_str * pstr_ec_state,const ia_usac_samp_rate_info * pstr_samp_rate_info,WORD32 frame_ok,WORD32 chn)164*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_usac_ec_interpolate_frame(ia_usac_data_struct *pstr_usac_data,
165*15dc779aSAndroid Build Coastguard Worker ia_ec_state_str *pstr_ec_state,
166*15dc779aSAndroid Build Coastguard Worker const ia_usac_samp_rate_info *pstr_samp_rate_info,
167*15dc779aSAndroid Build Coastguard Worker WORD32 frame_ok, WORD32 chn) {
168*15dc779aSAndroid Build Coastguard Worker WORD32 frame_length = pstr_usac_data->ccfl;
169*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_spec_coeff = pstr_usac_data->coef_fix[chn];
170*15dc779aSAndroid Build Coastguard Worker WORD16 *ptr_spec_sf = pstr_usac_data->spec_scale[chn];
171*15dc779aSAndroid Build Coastguard Worker
172*15dc779aSAndroid Build Coastguard Worker WORD32 i;
173*15dc779aSAndroid Build Coastguard Worker ia_ec_scratch_str *pstr_ec_scratch = pstr_ec_state->pstr_ec_scratch;
174*15dc779aSAndroid Build Coastguard Worker WORD16 num_sfb_long;
175*15dc779aSAndroid Build Coastguard Worker WORD16 *ptr_sfb_long = NULL;
176*15dc779aSAndroid Build Coastguard Worker WORD16 num_sfb_short;
177*15dc779aSAndroid Build Coastguard Worker WORD16 *ptr_sfb_short = NULL;
178*15dc779aSAndroid Build Coastguard Worker
179*15dc779aSAndroid Build Coastguard Worker if (pstr_usac_data->core_mode == CORE_MODE_FD) {
180*15dc779aSAndroid Build Coastguard Worker num_sfb_long = pstr_samp_rate_info->num_sfb_1024;
181*15dc779aSAndroid Build Coastguard Worker ptr_sfb_long = (WORD16 *)pstr_samp_rate_info->ptr_sfb_1024;
182*15dc779aSAndroid Build Coastguard Worker num_sfb_short = pstr_samp_rate_info->num_sfb_128;
183*15dc779aSAndroid Build Coastguard Worker ptr_sfb_short = (WORD16 *)pstr_samp_rate_info->ptr_sfb_128;
184*15dc779aSAndroid Build Coastguard Worker if (pstr_usac_data->ccfl == WIN_LEN_768) {
185*15dc779aSAndroid Build Coastguard Worker num_sfb_long = pstr_samp_rate_info->num_sfb_768;
186*15dc779aSAndroid Build Coastguard Worker ptr_sfb_long = (WORD16 *)pstr_samp_rate_info->ptr_sfb_768;
187*15dc779aSAndroid Build Coastguard Worker num_sfb_short = pstr_samp_rate_info->num_sfb_96;
188*15dc779aSAndroid Build Coastguard Worker ptr_sfb_short = (WORD16 *)pstr_samp_rate_info->ptr_sfb_96;
189*15dc779aSAndroid Build Coastguard Worker }
190*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->str_ec_sfb.num_sfb_long = num_sfb_long;
191*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->str_ec_sfb.num_sfb_long = num_sfb_long;
192*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->str_ec_sfb.ptr_sfb_long = ptr_sfb_long;
193*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->str_ec_sfb.ptr_sfb_long = ptr_sfb_long;
194*15dc779aSAndroid Build Coastguard Worker
195*15dc779aSAndroid Build Coastguard Worker memset(pstr_ec_scratch->prev_sfb_nrg, 0, sizeof(pstr_ec_scratch->prev_sfb_nrg));
196*15dc779aSAndroid Build Coastguard Worker memset(pstr_ec_scratch->pres_sfb_nrg, 0, sizeof(pstr_ec_scratch->pres_sfb_nrg));
197*15dc779aSAndroid Build Coastguard Worker
198*15dc779aSAndroid Build Coastguard Worker if (!frame_ok) {
199*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_shape[chn] = pstr_ec_state->win_shape;
200*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_sequence[chn] = pstr_ec_state->win_seq;
201*15dc779aSAndroid Build Coastguard Worker memcpy(ptr_spec_coeff, pstr_ec_state->spectral_coeff,
202*15dc779aSAndroid Build Coastguard Worker sizeof(*ptr_spec_coeff) * frame_length);
203*15dc779aSAndroid Build Coastguard Worker memcpy(ptr_spec_sf, pstr_ec_state->q_spec_coeff, sizeof(pstr_ec_state->q_spec_coeff));
204*15dc779aSAndroid Build Coastguard Worker }
205*15dc779aSAndroid Build Coastguard Worker }
206*15dc779aSAndroid Build Coastguard Worker
207*15dc779aSAndroid Build Coastguard Worker if (!pstr_ec_state->prev_frame_ok[1]) {
208*15dc779aSAndroid Build Coastguard Worker if (frame_ok && pstr_ec_state->prev_frame_ok[0] &&
209*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->core_mode == CORE_MODE_FD) {
210*15dc779aSAndroid Build Coastguard Worker if (pstr_usac_data->window_sequence[chn] == EIGHT_SHORT_SEQUENCE) {
211*15dc779aSAndroid Build Coastguard Worker WORD32 wnd;
212*15dc779aSAndroid Build Coastguard Worker
213*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->win_seq == EIGHT_SHORT_SEQUENCE) {
214*15dc779aSAndroid Build Coastguard Worker WORD32 num_sfb = num_sfb_short;
215*15dc779aSAndroid Build Coastguard Worker WORD16 *ptr_sfb_offset = ptr_sfb_short;
216*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_shape[chn] = 1;
217*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_sequence[chn] = EIGHT_SHORT_SEQUENCE;
218*15dc779aSAndroid Build Coastguard Worker
219*15dc779aSAndroid Build Coastguard Worker for (wnd = 0; wnd < 8; wnd++) {
220*15dc779aSAndroid Build Coastguard Worker iexheaace_ec_sfb_nrg_q(&ptr_spec_coeff[wnd * (frame_length >> 3)],
221*15dc779aSAndroid Build Coastguard Worker &pstr_ec_state->str_ec_sfb, EIGHT_SHORT_SEQUENCE,
222*15dc779aSAndroid Build Coastguard Worker NO_TRANSITION, pstr_ec_scratch->prev_sfb_nrg);
223*15dc779aSAndroid Build Coastguard Worker
224*15dc779aSAndroid Build Coastguard Worker iexheaace_ec_sfb_nrg_q(&pstr_ec_state->spectral_coeff[wnd * (frame_length >> 3)],
225*15dc779aSAndroid Build Coastguard Worker &pstr_ec_state->str_ec_sfb, EIGHT_SHORT_SEQUENCE,
226*15dc779aSAndroid Build Coastguard Worker NO_TRANSITION, pstr_ec_scratch->pres_sfb_nrg);
227*15dc779aSAndroid Build Coastguard Worker
228*15dc779aSAndroid Build Coastguard Worker ixheaacd_usac_ec_interpolate(&ptr_spec_coeff[wnd * (frame_length / 8)],
229*15dc779aSAndroid Build Coastguard Worker &ptr_spec_sf[wnd], &pstr_ec_state->q_spec_coeff[wnd],
230*15dc779aSAndroid Build Coastguard Worker &ptr_spec_sf[wnd], pstr_ec_scratch->prev_sfb_nrg,
231*15dc779aSAndroid Build Coastguard Worker pstr_ec_scratch->pres_sfb_nrg, num_sfb, ptr_sfb_offset);
232*15dc779aSAndroid Build Coastguard Worker }
233*15dc779aSAndroid Build Coastguard Worker } else {
234*15dc779aSAndroid Build Coastguard Worker WORD32 num_sfb = num_sfb_long;
235*15dc779aSAndroid Build Coastguard Worker WORD16 *ptr_sfb_offset = ptr_sfb_long;
236*15dc779aSAndroid Build Coastguard Worker WORD16 q_spec_coeff_out;
237*15dc779aSAndroid Build Coastguard Worker
238*15dc779aSAndroid Build Coastguard Worker iexheaace_ec_sfb_nrg_q(&ptr_spec_coeff[frame_length - (frame_length >> 3)],
239*15dc779aSAndroid Build Coastguard Worker &pstr_ec_state->str_ec_sfb, EIGHT_SHORT_SEQUENCE,
240*15dc779aSAndroid Build Coastguard Worker TRANS_SHORT_LONG, pstr_ec_scratch->pres_sfb_nrg);
241*15dc779aSAndroid Build Coastguard Worker
242*15dc779aSAndroid Build Coastguard Worker iexheaace_ec_sfb_nrg_q(pstr_ec_state->spectral_coeff, &pstr_ec_state->str_ec_sfb,
243*15dc779aSAndroid Build Coastguard Worker ONLY_LONG_SEQUENCE, NO_TRANSITION,
244*15dc779aSAndroid Build Coastguard Worker pstr_ec_scratch->prev_sfb_nrg);
245*15dc779aSAndroid Build Coastguard Worker
246*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_shape[chn] = 0;
247*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_sequence[chn] = LONG_STOP_SEQUENCE;
248*15dc779aSAndroid Build Coastguard Worker memcpy(&ptr_spec_coeff[0], pstr_ec_state->spectral_coeff,
249*15dc779aSAndroid Build Coastguard Worker frame_length * sizeof(ptr_spec_coeff[0]));
250*15dc779aSAndroid Build Coastguard Worker
251*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < 8; i++) {
252*15dc779aSAndroid Build Coastguard Worker if (ptr_spec_sf[i] > ptr_spec_sf[0]) {
253*15dc779aSAndroid Build Coastguard Worker ptr_spec_sf[0] = ptr_spec_sf[i];
254*15dc779aSAndroid Build Coastguard Worker }
255*15dc779aSAndroid Build Coastguard Worker }
256*15dc779aSAndroid Build Coastguard Worker
257*15dc779aSAndroid Build Coastguard Worker ixheaacd_usac_ec_interpolate(ptr_spec_coeff, &pstr_ec_state->q_spec_coeff[0],
258*15dc779aSAndroid Build Coastguard Worker &ptr_spec_sf[0], &q_spec_coeff_out,
259*15dc779aSAndroid Build Coastguard Worker pstr_ec_scratch->prev_sfb_nrg,
260*15dc779aSAndroid Build Coastguard Worker pstr_ec_scratch->pres_sfb_nrg, num_sfb, ptr_sfb_offset);
261*15dc779aSAndroid Build Coastguard Worker
262*15dc779aSAndroid Build Coastguard Worker ptr_spec_sf[0] = q_spec_coeff_out;
263*15dc779aSAndroid Build Coastguard Worker }
264*15dc779aSAndroid Build Coastguard Worker } else {
265*15dc779aSAndroid Build Coastguard Worker WORD32 num_sfb = num_sfb_long;
266*15dc779aSAndroid Build Coastguard Worker WORD16 *ptr_sfb_offset = ptr_sfb_long;
267*15dc779aSAndroid Build Coastguard Worker WORD16 q_spec_coeff_act = pstr_ec_state->q_spec_coeff[0];
268*15dc779aSAndroid Build Coastguard Worker
269*15dc779aSAndroid Build Coastguard Worker iexheaace_ec_sfb_nrg_q(ptr_spec_coeff, &pstr_ec_state->str_ec_sfb, ONLY_LONG_SEQUENCE,
270*15dc779aSAndroid Build Coastguard Worker NO_TRANSITION, pstr_ec_scratch->prev_sfb_nrg);
271*15dc779aSAndroid Build Coastguard Worker
272*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->win_seq == EIGHT_SHORT_SEQUENCE) {
273*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_shape[chn] = 1;
274*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_sequence[chn] = LONG_START_SEQUENCE;
275*15dc779aSAndroid Build Coastguard Worker
276*15dc779aSAndroid Build Coastguard Worker for (i = 1; i < 8; i++) {
277*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->q_spec_coeff[i] > q_spec_coeff_act) {
278*15dc779aSAndroid Build Coastguard Worker q_spec_coeff_act = pstr_ec_state->q_spec_coeff[i];
279*15dc779aSAndroid Build Coastguard Worker }
280*15dc779aSAndroid Build Coastguard Worker }
281*15dc779aSAndroid Build Coastguard Worker
282*15dc779aSAndroid Build Coastguard Worker iexheaace_ec_sfb_nrg_q(pstr_ec_state->spectral_coeff, &pstr_ec_state->str_ec_sfb,
283*15dc779aSAndroid Build Coastguard Worker EIGHT_SHORT_SEQUENCE, TRANS_SHORT_LONG,
284*15dc779aSAndroid Build Coastguard Worker pstr_ec_scratch->pres_sfb_nrg);
285*15dc779aSAndroid Build Coastguard Worker } else {
286*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_shape[chn] = 0;
287*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_sequence[chn] = ONLY_LONG_SEQUENCE;
288*15dc779aSAndroid Build Coastguard Worker iexheaace_ec_sfb_nrg_q(pstr_ec_state->spectral_coeff, &pstr_ec_state->str_ec_sfb,
289*15dc779aSAndroid Build Coastguard Worker ONLY_LONG_SEQUENCE, NO_TRANSITION,
290*15dc779aSAndroid Build Coastguard Worker pstr_ec_scratch->pres_sfb_nrg);
291*15dc779aSAndroid Build Coastguard Worker }
292*15dc779aSAndroid Build Coastguard Worker ixheaacd_usac_ec_interpolate(ptr_spec_coeff, &ptr_spec_sf[0], &q_spec_coeff_act,
293*15dc779aSAndroid Build Coastguard Worker &ptr_spec_sf[0], pstr_ec_scratch->prev_sfb_nrg,
294*15dc779aSAndroid Build Coastguard Worker pstr_ec_scratch->pres_sfb_nrg, num_sfb, ptr_sfb_offset);
295*15dc779aSAndroid Build Coastguard Worker }
296*15dc779aSAndroid Build Coastguard Worker }
297*15dc779aSAndroid Build Coastguard Worker ixheaacd_usac_flip_spec_sign(ptr_spec_coeff, frame_length, &pstr_usac_data->seed_value[chn]);
298*15dc779aSAndroid Build Coastguard Worker }
299*15dc779aSAndroid Build Coastguard Worker
300*15dc779aSAndroid Build Coastguard Worker if (FRAME_MUTE == pstr_ec_state->conceal_state) {
301*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_shape[chn] = pstr_ec_state->win_shape;
302*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_sequence[chn] = ixheaacd_usac_ec_get_win_seq(pstr_ec_state->win_seq);
303*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->win_seq = pstr_usac_data->window_sequence[chn];
304*15dc779aSAndroid Build Coastguard Worker memset(ptr_spec_coeff, 0, frame_length * sizeof(ptr_spec_coeff[0]));
305*15dc779aSAndroid Build Coastguard Worker }
306*15dc779aSAndroid Build Coastguard Worker
307*15dc779aSAndroid Build Coastguard Worker return;
308*15dc779aSAndroid Build Coastguard Worker }
309*15dc779aSAndroid Build Coastguard Worker
ixheaacd_usac_lpc_ec_state(ia_ec_state_str * pstr_ec_state,WORD32 frame_ok)310*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_usac_lpc_ec_state(ia_ec_state_str *pstr_ec_state, WORD32 frame_ok) {
311*15dc779aSAndroid Build Coastguard Worker if (frame_ok == 0) {
312*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->fade_idx < MAX_FADE_FRAMES) {
313*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->fade_idx++;
314*15dc779aSAndroid Build Coastguard Worker }
315*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->conceal_state = FRAME_CONCEAL_SINGLE;
316*15dc779aSAndroid Build Coastguard Worker } else {
317*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->fade_idx > 0) {
318*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->fade_idx--;
319*15dc779aSAndroid Build Coastguard Worker }
320*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->conceal_state = FRAME_OKAY;
321*15dc779aSAndroid Build Coastguard Worker }
322*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->fade_idx >= MAX_FADE_FRAMES) {
323*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->fade_idx = MAX_FADE_FRAMES;
324*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->conceal_state = FRAME_MUTE;
325*15dc779aSAndroid Build Coastguard Worker }
326*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->fade_idx < 0) {
327*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->fade_idx = 0;
328*15dc779aSAndroid Build Coastguard Worker }
329*15dc779aSAndroid Build Coastguard Worker return;
330*15dc779aSAndroid Build Coastguard Worker }
331*15dc779aSAndroid Build Coastguard Worker
ixheaacd_usac_ec_state(ia_ec_state_str * pstr_ec_state,WORD32 frame_ok)332*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_usac_ec_state(ia_ec_state_str *pstr_ec_state, WORD32 frame_ok) {
333*15dc779aSAndroid Build Coastguard Worker WORD32 ec_state_val = (pstr_ec_state->prev_frame_ok[0] << 2) +
334*15dc779aSAndroid Build Coastguard Worker (pstr_ec_state->prev_frame_ok[1] << 1) + (frame_ok);
335*15dc779aSAndroid Build Coastguard Worker
336*15dc779aSAndroid Build Coastguard Worker switch (ec_state_val) {
337*15dc779aSAndroid Build Coastguard Worker case 0:
338*15dc779aSAndroid Build Coastguard Worker case 4:
339*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->fade_idx < MAX_FADE_FRAMES) {
340*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->fade_idx++;
341*15dc779aSAndroid Build Coastguard Worker }
342*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->conceal_state = FRAME_CONCEAL_SINGLE;
343*15dc779aSAndroid Build Coastguard Worker break;
344*15dc779aSAndroid Build Coastguard Worker case 1:
345*15dc779aSAndroid Build Coastguard Worker case 2:
346*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->fade_idx > 0) {
347*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->fade_idx--;
348*15dc779aSAndroid Build Coastguard Worker }
349*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->conceal_state = FRAME_FADE;
350*15dc779aSAndroid Build Coastguard Worker break;
351*15dc779aSAndroid Build Coastguard Worker case 5:
352*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->fade_idx > 0) {
353*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->fade_idx--;
354*15dc779aSAndroid Build Coastguard Worker }
355*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->conceal_state = FRAME_OKAY;
356*15dc779aSAndroid Build Coastguard Worker break;
357*15dc779aSAndroid Build Coastguard Worker break;
358*15dc779aSAndroid Build Coastguard Worker case 3:
359*15dc779aSAndroid Build Coastguard Worker case 6:
360*15dc779aSAndroid Build Coastguard Worker case 7:
361*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->fade_idx > 0) {
362*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->fade_idx--;
363*15dc779aSAndroid Build Coastguard Worker }
364*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->conceal_state = FRAME_OKAY;
365*15dc779aSAndroid Build Coastguard Worker break;
366*15dc779aSAndroid Build Coastguard Worker default:
367*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->conceal_state = FRAME_OKAY;
368*15dc779aSAndroid Build Coastguard Worker }
369*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->fade_idx > MAX_FADE_FRAMES) {
370*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->fade_idx = MAX_FADE_FRAMES;
371*15dc779aSAndroid Build Coastguard Worker }
372*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->fade_idx == MAX_FADE_FRAMES) {
373*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->conceal_state = FRAME_MUTE;
374*15dc779aSAndroid Build Coastguard Worker }
375*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->fade_idx < 0) {
376*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->fade_idx = 0;
377*15dc779aSAndroid Build Coastguard Worker }
378*15dc779aSAndroid Build Coastguard Worker }
379*15dc779aSAndroid Build Coastguard Worker
ixheaacd_usac_ec_init(ia_ec_state_str * pstr_ec_state,WORD32 core_coder_mode)380*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_usac_ec_init(ia_ec_state_str *pstr_ec_state, WORD32 core_coder_mode) {
381*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->win_shape = 1;
382*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->win_seq = ONLY_LONG_SEQUENCE;
383*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->prev_win_group_len = 1;
384*15dc779aSAndroid Build Coastguard Worker
385*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->conceal_state = FRAME_OKAY;
386*15dc779aSAndroid Build Coastguard Worker
387*15dc779aSAndroid Build Coastguard Worker memset(pstr_ec_state->spectral_coeff, 0, sizeof(pstr_ec_state->spectral_coeff));
388*15dc779aSAndroid Build Coastguard Worker memset(pstr_ec_state->q_spec_coeff, 0, sizeof(pstr_ec_state->q_spec_coeff));
389*15dc779aSAndroid Build Coastguard Worker
390*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->prev_frame_ok[0] = 1;
391*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->prev_frame_ok[1] = 1;
392*15dc779aSAndroid Build Coastguard Worker
393*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->fade_idx = 0;
394*15dc779aSAndroid Build Coastguard Worker
395*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->prev_core_mode = core_coder_mode;
396*15dc779aSAndroid Build Coastguard Worker }
397*15dc779aSAndroid Build Coastguard Worker
ixheaacd_usac_lpc_ec(FLOAT32 lsp[][ORDER],FLOAT32 * lpc4_lsf,FLOAT32 * lsf_adaptive_mean,const WORD32 first_lpd_flag)398*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_usac_lpc_ec(FLOAT32 lsp[][ORDER], FLOAT32 *lpc4_lsf, FLOAT32 *lsf_adaptive_mean,
399*15dc779aSAndroid Build Coastguard Worker const WORD32 first_lpd_flag) {
400*15dc779aSAndroid Build Coastguard Worker WORD32 i, j;
401*15dc779aSAndroid Build Coastguard Worker
402*15dc779aSAndroid Build Coastguard Worker if (first_lpd_flag) {
403*15dc779aSAndroid Build Coastguard Worker memcpy(lsp[0], lsf_init, sizeof(lsf_init));
404*15dc779aSAndroid Build Coastguard Worker memcpy(lpc4_lsf, lsf_init, sizeof(lsf_init));
405*15dc779aSAndroid Build Coastguard Worker } else {
406*15dc779aSAndroid Build Coastguard Worker memcpy(lsp[0], lpc4_lsf, ORDER * sizeof(lpc4_lsf[0]));
407*15dc779aSAndroid Build Coastguard Worker }
408*15dc779aSAndroid Build Coastguard Worker
409*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < ORDER; i++) {
410*15dc779aSAndroid Build Coastguard Worker FLOAT32 lsf_mean = (BETA * lsf_init[i]) + (ONE_BETA * lsf_adaptive_mean[i]);
411*15dc779aSAndroid Build Coastguard Worker lsp[1][i] = (BFI_FAC * lpc4_lsf[i]) + (ONE_BFI_FAC * lsf_mean);
412*15dc779aSAndroid Build Coastguard Worker }
413*15dc779aSAndroid Build Coastguard Worker
414*15dc779aSAndroid Build Coastguard Worker for (j = 2; j <= 4; j++) {
415*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < ORDER; i++) {
416*15dc779aSAndroid Build Coastguard Worker FLOAT32 lsf_mean = ((BETA + (j * ONE_BFI_FAC)) * lsf_init[i]) +
417*15dc779aSAndroid Build Coastguard Worker ((ONE_BETA - (j * ONE_BFI_FAC)) * lsf_adaptive_mean[i]);
418*15dc779aSAndroid Build Coastguard Worker lsp[j][i] = (BFI_FAC * lsp[j - 1][i]) + (ONE_BFI_FAC * lsf_mean);
419*15dc779aSAndroid Build Coastguard Worker }
420*15dc779aSAndroid Build Coastguard Worker }
421*15dc779aSAndroid Build Coastguard Worker
422*15dc779aSAndroid Build Coastguard Worker memcpy(lpc4_lsf, lsp[4], ORDER * sizeof(lpc4_lsf[0]));
423*15dc779aSAndroid Build Coastguard Worker }
424*15dc779aSAndroid Build Coastguard Worker
ixheaacd_usac_ec_save_states(ia_ec_state_str * pstr_ec_state,ia_usac_data_struct * pstr_usac_data,WORD32 ch)425*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_usac_ec_save_states(ia_ec_state_str *pstr_ec_state,
426*15dc779aSAndroid Build Coastguard Worker ia_usac_data_struct *pstr_usac_data, WORD32 ch) {
427*15dc779aSAndroid Build Coastguard Worker if (pstr_usac_data->core_mode == CORE_MODE_FD &&
428*15dc779aSAndroid Build Coastguard Worker (pstr_usac_data->frame_ok == 1 && pstr_ec_state->prev_frame_ok[1] == 1)) {
429*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_spec_coeff = pstr_usac_data->coef_fix[ch];
430*15dc779aSAndroid Build Coastguard Worker WORD16 *ptr_spec_scale = pstr_usac_data->spec_scale[ch];
431*15dc779aSAndroid Build Coastguard Worker WORD16 q_spec_coeff[MAX_SPEC_SCALE_LEN_EC];
432*15dc779aSAndroid Build Coastguard Worker UWORD8 win_shape = pstr_ec_state->win_shape;
433*15dc779aSAndroid Build Coastguard Worker UWORD8 win_shape_prev = pstr_ec_state->win_shape_prev;
434*15dc779aSAndroid Build Coastguard Worker WORD32 win_seq = pstr_ec_state->win_seq;
435*15dc779aSAndroid Build Coastguard Worker WORD32 td_frame_prev = pstr_ec_state->td_frame_prev;
436*15dc779aSAndroid Build Coastguard Worker WORD32 fac_data_present = pstr_ec_state->fac_data_present;
437*15dc779aSAndroid Build Coastguard Worker
438*15dc779aSAndroid Build Coastguard Worker ia_sfb_info_struct *sfb_info =
439*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->pstr_usac_winmap[pstr_usac_data->window_sequence[ch]];
440*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_scratch_buf = &pstr_ec_state->pstr_ec_scratch->spec_coeff[0];
441*15dc779aSAndroid Build Coastguard Worker
442*15dc779aSAndroid Build Coastguard Worker memcpy(q_spec_coeff, pstr_ec_state->q_spec_coeff, sizeof(q_spec_coeff));
443*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->win_seq = pstr_usac_data->window_sequence[ch];
444*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->win_shape = pstr_usac_data->window_shape[ch];
445*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->td_frame_prev = pstr_usac_data->td_frame_prev[ch];
446*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->fac_data_present = pstr_usac_data->fac_data_present[ch];
447*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->win_shape_prev = pstr_usac_data->window_shape_prev[ch];
448*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->prev_win_group_len = (WORD32)sfb_info->group_len[sfb_info->num_groups - 1];
449*15dc779aSAndroid Build Coastguard Worker
450*15dc779aSAndroid Build Coastguard Worker memcpy(pstr_ec_state->q_spec_coeff, ptr_spec_scale, sizeof(pstr_ec_state->q_spec_coeff));
451*15dc779aSAndroid Build Coastguard Worker
452*15dc779aSAndroid Build Coastguard Worker memcpy(ptr_scratch_buf, ptr_spec_coeff, pstr_usac_data->ccfl * sizeof(ptr_scratch_buf[0]));
453*15dc779aSAndroid Build Coastguard Worker memcpy(ptr_spec_coeff, &pstr_ec_state->spectral_coeff[0],
454*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->ccfl * sizeof(ptr_spec_coeff[0]));
455*15dc779aSAndroid Build Coastguard Worker memcpy(&pstr_ec_state->spectral_coeff[0], ptr_scratch_buf,
456*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->ccfl * sizeof(ptr_spec_coeff[0]));
457*15dc779aSAndroid Build Coastguard Worker
458*15dc779aSAndroid Build Coastguard Worker if (!pstr_usac_data->first_frame) {
459*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_sequence[ch] = win_seq;
460*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_shape[ch] = win_shape;
461*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->td_frame_prev_ec[ch] = td_frame_prev;
462*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->fac_data_present[ch] = fac_data_present;
463*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_shape_prev[ch] = win_shape_prev;
464*15dc779aSAndroid Build Coastguard Worker }
465*15dc779aSAndroid Build Coastguard Worker
466*15dc779aSAndroid Build Coastguard Worker memcpy(ptr_spec_scale, q_spec_coeff, sizeof(q_spec_coeff));
467*15dc779aSAndroid Build Coastguard Worker }
468*15dc779aSAndroid Build Coastguard Worker }
469*15dc779aSAndroid Build Coastguard Worker
ixheaacd_usac_apply_ec(ia_usac_data_struct * pstr_usac_data,const ia_usac_samp_rate_info * pstr_samp_rate_info,WORD32 ch)470*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_usac_apply_ec(ia_usac_data_struct *pstr_usac_data,
471*15dc779aSAndroid Build Coastguard Worker const ia_usac_samp_rate_info *pstr_samp_rate_info, WORD32 ch) {
472*15dc779aSAndroid Build Coastguard Worker WORD32 frame_ok = pstr_usac_data->frame_ok;
473*15dc779aSAndroid Build Coastguard Worker ia_ec_state_str *pstr_ec_state = &pstr_usac_data->str_error_concealment[ch];
474*15dc779aSAndroid Build Coastguard Worker
475*15dc779aSAndroid Build Coastguard Worker if (pstr_usac_data->core_mode == CORE_MODE_FD) {
476*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->win_shape == (UWORD8)-1) {
477*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->win_shape = pstr_usac_data->window_shape[ch];
478*15dc779aSAndroid Build Coastguard Worker }
479*15dc779aSAndroid Build Coastguard Worker
480*15dc779aSAndroid Build Coastguard Worker ixheaacd_usac_ec_state(pstr_ec_state, frame_ok);
481*15dc779aSAndroid Build Coastguard Worker
482*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->conceal_state == FRAME_OKAY) {
483*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->prev_core_mode = pstr_usac_data->core_mode;
484*15dc779aSAndroid Build Coastguard Worker ixheaacd_usac_ec_save_states(pstr_ec_state, pstr_usac_data, ch);
485*15dc779aSAndroid Build Coastguard Worker } else if (pstr_ec_state->conceal_state == FRAME_CONCEAL_SINGLE) {
486*15dc779aSAndroid Build Coastguard Worker ixheaacd_usac_ec_interpolate_frame(pstr_usac_data, pstr_ec_state, pstr_samp_rate_info,
487*15dc779aSAndroid Build Coastguard Worker frame_ok, ch);
488*15dc779aSAndroid Build Coastguard Worker } else {
489*15dc779aSAndroid Build Coastguard Worker }
490*15dc779aSAndroid Build Coastguard Worker if (!frame_ok) {
491*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_spec_coeff = pstr_usac_data->coef_fix[ch];
492*15dc779aSAndroid Build Coastguard Worker WORD16 *ptr_spec_scale = pstr_usac_data->spec_scale[ch];
493*15dc779aSAndroid Build Coastguard Worker
494*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_sequence[ch] = pstr_ec_state->win_seq;
495*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->window_shape[ch] = pstr_ec_state->win_shape;
496*15dc779aSAndroid Build Coastguard Worker
497*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->conceal_state != FRAME_MUTE) {
498*15dc779aSAndroid Build Coastguard Worker memcpy(ptr_spec_scale, pstr_ec_state->q_spec_coeff, sizeof(pstr_ec_state->q_spec_coeff));
499*15dc779aSAndroid Build Coastguard Worker memcpy(ptr_spec_coeff, pstr_ec_state->spectral_coeff,
500*15dc779aSAndroid Build Coastguard Worker sizeof(pstr_ec_state->spectral_coeff));
501*15dc779aSAndroid Build Coastguard Worker } else {
502*15dc779aSAndroid Build Coastguard Worker memset(ptr_spec_scale, 0, MAX_SPEC_SCALE_LEN * sizeof(ptr_spec_scale[0]));
503*15dc779aSAndroid Build Coastguard Worker memset(ptr_spec_coeff, 0, pstr_usac_data->ccfl * sizeof(ptr_spec_coeff[0]));
504*15dc779aSAndroid Build Coastguard Worker }
505*15dc779aSAndroid Build Coastguard Worker }
506*15dc779aSAndroid Build Coastguard Worker } else {
507*15dc779aSAndroid Build Coastguard Worker ixheaacd_usac_lpc_ec_state(pstr_ec_state, frame_ok);
508*15dc779aSAndroid Build Coastguard Worker
509*15dc779aSAndroid Build Coastguard Worker if (pstr_ec_state->conceal_state == FRAME_OKAY) {
510*15dc779aSAndroid Build Coastguard Worker memcpy(pstr_ec_state->lsf4, pstr_usac_data->lpc4_lsf, sizeof(pstr_ec_state->lsf4));
511*15dc779aSAndroid Build Coastguard Worker } else if (pstr_ec_state->conceal_state == FRAME_CONCEAL_SINGLE) {
512*15dc779aSAndroid Build Coastguard Worker WORD32 frame_length = pstr_usac_data->ccfl;
513*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_spec_coeff = pstr_usac_data->tcx_spec_coeffs[ch];
514*15dc779aSAndroid Build Coastguard Worker
515*15dc779aSAndroid Build Coastguard Worker ixheaacd_usac_flip_spec_sign(ptr_spec_coeff, frame_length,
516*15dc779aSAndroid Build Coastguard Worker &pstr_usac_data->seed_value[ch]);
517*15dc779aSAndroid Build Coastguard Worker } else {
518*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_spec_coeff = pstr_usac_data->tcx_spec_coeffs[ch];
519*15dc779aSAndroid Build Coastguard Worker memset(ptr_spec_coeff, 0, pstr_usac_data->ccfl * sizeof(ptr_spec_coeff[0]));
520*15dc779aSAndroid Build Coastguard Worker }
521*15dc779aSAndroid Build Coastguard Worker if (!frame_ok) {
522*15dc779aSAndroid Build Coastguard Worker memcpy(pstr_usac_data->lpc4_lsf, pstr_ec_state->lsf4, sizeof(pstr_usac_data->lpc4_lsf));
523*15dc779aSAndroid Build Coastguard Worker }
524*15dc779aSAndroid Build Coastguard Worker }
525*15dc779aSAndroid Build Coastguard Worker
526*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->prev_frame_ok[0] = pstr_ec_state->prev_frame_ok[1];
527*15dc779aSAndroid Build Coastguard Worker pstr_ec_state->prev_frame_ok[1] = frame_ok;
528*15dc779aSAndroid Build Coastguard Worker
529*15dc779aSAndroid Build Coastguard Worker return;
530*15dc779aSAndroid Build Coastguard Worker }
531*15dc779aSAndroid Build Coastguard Worker
ixheaacd_lpc_wt_tool(FLOAT32 a[],WORD32 l)532*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_lpc_wt_tool(FLOAT32 a[], WORD32 l) {
533*15dc779aSAndroid Build Coastguard Worker WORD32 i;
534*15dc779aSAndroid Build Coastguard Worker
535*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < l; i++) {
536*15dc779aSAndroid Build Coastguard Worker a[i] = a[i] * ixheaacd_gamma_table[i];
537*15dc779aSAndroid Build Coastguard Worker }
538*15dc779aSAndroid Build Coastguard Worker
539*15dc779aSAndroid Build Coastguard Worker return;
540*15dc779aSAndroid Build Coastguard Worker }
ixheaacd_lpc_coef_gen_ec(FLOAT32 lsf_old[],FLOAT32 lsf_new[],FLOAT32 a[],WORD32 m)541*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_lpc_coef_gen_ec(FLOAT32 lsf_old[], FLOAT32 lsf_new[], FLOAT32 a[],
542*15dc779aSAndroid Build Coastguard Worker WORD32 m) {
543*15dc779aSAndroid Build Coastguard Worker FLOAT32 lsf[ORDER], *ptr_a;
544*15dc779aSAndroid Build Coastguard Worker FLOAT32 inc, fnew, fold;
545*15dc779aSAndroid Build Coastguard Worker WORD32 i;
546*15dc779aSAndroid Build Coastguard Worker
547*15dc779aSAndroid Build Coastguard Worker ptr_a = a;
548*15dc779aSAndroid Build Coastguard Worker
549*15dc779aSAndroid Build Coastguard Worker inc = 1.0f / (FLOAT32)m;
550*15dc779aSAndroid Build Coastguard Worker fnew = 0.5f - (0.5f * inc);
551*15dc779aSAndroid Build Coastguard Worker fold = 1.0f - fnew;
552*15dc779aSAndroid Build Coastguard Worker
553*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < ORDER; i++) {
554*15dc779aSAndroid Build Coastguard Worker lsf[i] = (lsf_old[i] * fold) + (lsf_new[i] * fnew);
555*15dc779aSAndroid Build Coastguard Worker }
556*15dc779aSAndroid Build Coastguard Worker ixheaacd_lsp_to_lp_conversion(lsf, ptr_a);
557*15dc779aSAndroid Build Coastguard Worker
558*15dc779aSAndroid Build Coastguard Worker return;
559*15dc779aSAndroid Build Coastguard Worker }
560*15dc779aSAndroid Build Coastguard Worker
ixheaacd_usac_tcx_ec(ia_usac_data_struct * pstr_usac_data,ia_usac_lpd_decoder_handle st,FLOAT32 * ptr_lsp_curr,WORD32 frame_idx,FLOAT32 * lp_flt_coff_a)561*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_usac_tcx_ec(ia_usac_data_struct *pstr_usac_data, ia_usac_lpd_decoder_handle st,
562*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_lsp_curr, WORD32 frame_idx, FLOAT32 *lp_flt_coff_a) {
563*15dc779aSAndroid Build Coastguard Worker WORD32 ch = pstr_usac_data->present_chan;
564*15dc779aSAndroid Build Coastguard Worker FLOAT32 synth_buf[ORDER + LEN_FRAME], temp;
565*15dc779aSAndroid Build Coastguard Worker FLOAT32 exc_buf[MAX_PITCH + ORDER + 1 + LEN_FRAME];
566*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_syn = synth_buf + ORDER;
567*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_exc = exc_buf + MAX_PITCH + ORDER + 1;
568*15dc779aSAndroid Build Coastguard Worker FLOAT32 est_fac_est = 0.1f;
569*15dc779aSAndroid Build Coastguard Worker WORD32 i, sf_idx;
570*15dc779aSAndroid Build Coastguard Worker FLOAT32 synth_sig_buf[LEN_SUBFR + 1];
571*15dc779aSAndroid Build Coastguard Worker FLOAT32 *synth_signal = synth_sig_buf + 1;
572*15dc779aSAndroid Build Coastguard Worker WORD32 num_lost_frames = pstr_usac_data->num_lost_lpd_frames[ch];
573*15dc779aSAndroid Build Coastguard Worker WORD32 len_subfrm = pstr_usac_data->len_subfrm;
574*15dc779aSAndroid Build Coastguard Worker FLOAT32 past_tcx_gain = pstr_usac_data->past_gain_tcx[ch];
575*15dc779aSAndroid Build Coastguard Worker WORD32 l_div_part = MAX_PITCH + ORDER + 1 - len_subfrm;
576*15dc779aSAndroid Build Coastguard Worker FLOAT32 *synth = pstr_usac_data->synth_buf + MAX_PITCH - LEN_SUBFR;
577*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_synth = &synth[512 + frame_idx * len_subfrm];
578*15dc779aSAndroid Build Coastguard Worker FLOAT32 syn_buf[MAX_PITCH + ORDER + 1];
579*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_syn_buf = &syn_buf[ORDER];
580*15dc779aSAndroid Build Coastguard Worker
581*15dc779aSAndroid Build Coastguard Worker memcpy(syn_buf, &ptr_synth[-(MAX_PITCH + ORDER + 1)],
582*15dc779aSAndroid Build Coastguard Worker sizeof(syn_buf));
583*15dc779aSAndroid Build Coastguard Worker memcpy(st->synth_prev_ec, &syn_buf[MAX_PITCH + 1], sizeof(st->synth_prev_ec));
584*15dc779aSAndroid Build Coastguard Worker ixheaacd_residual_tool_float(pstr_usac_data->lp_flt_coff_a_ec, ptr_syn_buf, st->xcitation_prev,
585*15dc779aSAndroid Build Coastguard Worker pstr_usac_data->len_subfrm, 1);
586*15dc779aSAndroid Build Coastguard Worker ixheaacd_residual_tool_float(lp_flt_coff_a, &syn_buf[l_div_part],
587*15dc779aSAndroid Build Coastguard Worker st->xcitation_prev + l_div_part, pstr_usac_data->len_subfrm, 1);
588*15dc779aSAndroid Build Coastguard Worker if (st->last_tcx_pitch > MAX_PITCH) {
589*15dc779aSAndroid Build Coastguard Worker st->last_tcx_pitch = MAX_PITCH;
590*15dc779aSAndroid Build Coastguard Worker }
591*15dc779aSAndroid Build Coastguard Worker
592*15dc779aSAndroid Build Coastguard Worker memcpy(synth_buf, st->synth_prev_ec, ORDER * sizeof(FLOAT32));
593*15dc779aSAndroid Build Coastguard Worker memcpy(exc_buf, st->xcitation_prev, (MAX_PITCH + ORDER + 1) * sizeof(FLOAT32));
594*15dc779aSAndroid Build Coastguard Worker
595*15dc779aSAndroid Build Coastguard Worker if (num_lost_frames <= 8) {
596*15dc779aSAndroid Build Coastguard Worker est_fac_est = ixheaacd_exc_fade_fac[num_lost_frames - 1];
597*15dc779aSAndroid Build Coastguard Worker }
598*15dc779aSAndroid Build Coastguard Worker
599*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < len_subfrm; i++) {
600*15dc779aSAndroid Build Coastguard Worker ptr_exc[i] = est_fac_est * ptr_exc[i - st->last_tcx_pitch];
601*15dc779aSAndroid Build Coastguard Worker }
602*15dc779aSAndroid Build Coastguard Worker synth_signal[-1] = ptr_exc[-1];
603*15dc779aSAndroid Build Coastguard Worker
604*15dc779aSAndroid Build Coastguard Worker for (sf_idx = 0; sf_idx < len_subfrm; sf_idx += LEN_SUBFR) {
605*15dc779aSAndroid Build Coastguard Worker FLOAT32 lp_coef[ORDER + 1];
606*15dc779aSAndroid Build Coastguard Worker
607*15dc779aSAndroid Build Coastguard Worker ixheaacd_lpc_coef_gen_ec(st->lspold, ptr_lsp_curr, lp_coef, len_subfrm / LEN_SUBFR);
608*15dc779aSAndroid Build Coastguard Worker
609*15dc779aSAndroid Build Coastguard Worker ixheaacd_synthesis_tool_float(lp_coef, &ptr_exc[sf_idx], &ptr_syn[sf_idx], LEN_SUBFR,
610*15dc779aSAndroid Build Coastguard Worker synth_buf);
611*15dc779aSAndroid Build Coastguard Worker
612*15dc779aSAndroid Build Coastguard Worker ixheaacd_lpc_wt_tool(lp_coef, ORDER);
613*15dc779aSAndroid Build Coastguard Worker
614*15dc779aSAndroid Build Coastguard Worker ixheaacd_residual_tool_float(lp_coef, &ptr_syn[sf_idx], synth_signal, LEN_SUBFR, 1);
615*15dc779aSAndroid Build Coastguard Worker
616*15dc779aSAndroid Build Coastguard Worker ixheaacd_deemphsis_tool(synth_signal, LEN_SUBFR, synth_signal[-1]);
617*15dc779aSAndroid Build Coastguard Worker
618*15dc779aSAndroid Build Coastguard Worker temp = (est_fac_est * past_tcx_gain);
619*15dc779aSAndroid Build Coastguard Worker
620*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < LEN_SUBFR; i++) {
621*15dc779aSAndroid Build Coastguard Worker if (synth_signal[i] > temp) {
622*15dc779aSAndroid Build Coastguard Worker synth_signal[i] = temp;
623*15dc779aSAndroid Build Coastguard Worker } else {
624*15dc779aSAndroid Build Coastguard Worker if (synth_signal[i] < -temp) {
625*15dc779aSAndroid Build Coastguard Worker synth_signal[i] = -temp;
626*15dc779aSAndroid Build Coastguard Worker }
627*15dc779aSAndroid Build Coastguard Worker }
628*15dc779aSAndroid Build Coastguard Worker }
629*15dc779aSAndroid Build Coastguard Worker
630*15dc779aSAndroid Build Coastguard Worker for (i = LEN_SUBFR - 1; i >= 0; i--) {
631*15dc779aSAndroid Build Coastguard Worker synth_signal[i] = (synth_signal[i] - (PREEMPH_FILT_FAC * synth_signal[i - 1]));
632*15dc779aSAndroid Build Coastguard Worker }
633*15dc779aSAndroid Build Coastguard Worker ixheaacd_synthesis_tool_float(lp_coef, synth_signal, &ptr_syn[sf_idx], LEN_SUBFR, synth_buf);
634*15dc779aSAndroid Build Coastguard Worker
635*15dc779aSAndroid Build Coastguard Worker memmove(&ptr_synth[sf_idx], &ptr_syn[sf_idx], LEN_SUBFR * sizeof(FLOAT32));
636*15dc779aSAndroid Build Coastguard Worker }
637*15dc779aSAndroid Build Coastguard Worker
638*15dc779aSAndroid Build Coastguard Worker memcpy(st->xcitation_prev, ptr_exc + len_subfrm - (MAX_PITCH + ORDER + 1),
639*15dc779aSAndroid Build Coastguard Worker sizeof(FLOAT32) * (MAX_PITCH + ORDER + 1));
640*15dc779aSAndroid Build Coastguard Worker memcpy(st->synth_prev_ec, synth_buf + len_subfrm, sizeof(FLOAT32) * ORDER);
641*15dc779aSAndroid Build Coastguard Worker return;
642*15dc779aSAndroid Build Coastguard Worker }
643