1*15dc779aSAndroid Build Coastguard Worker /******************************************************************************
2*15dc779aSAndroid Build Coastguard Worker * *
3*15dc779aSAndroid Build Coastguard Worker * Copyright (C) 2018 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 <assert.h>
21*15dc779aSAndroid Build Coastguard Worker #include <float.h>
22*15dc779aSAndroid Build Coastguard Worker #include <stdlib.h>
23*15dc779aSAndroid Build Coastguard Worker #include <stdio.h>
24*15dc779aSAndroid Build Coastguard Worker #include <math.h>
25*15dc779aSAndroid Build Coastguard Worker #include <string.h>
26*15dc779aSAndroid Build Coastguard Worker
27*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
28*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_bitbuffer.h"
29*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_interface.h"
30*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_defines.h"
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_aac_rom.h"
32*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_tns_usac.h"
33*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_cnst.h"
34*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_acelp_info.h"
35*15dc779aSAndroid Build Coastguard Worker
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecsettings.h"
37*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_info.h"
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_common.h"
39*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_data_struct.h"
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_dec.h"
41*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecoder.h"
42*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_mps_polyphase.h"
43*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_sbr_const.h"
44*15dc779aSAndroid Build Coastguard Worker
45*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_pulsedata.h"
46*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_pns.h"
47*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_lt_predict.h"
48*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_defines.h"
49*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_struct_def.h"
50*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_main.h"
51*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_channelinfo.h"
52*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec.h"
53*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_arith_dec.h"
54*15dc779aSAndroid Build Coastguard Worker
55*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_func_def.h"
56*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_windows.h"
57*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_acelp_com.h"
58*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_constants.h"
59*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops32.h"
60*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops40.h"
61*15dc779aSAndroid Build Coastguard Worker
62*15dc779aSAndroid Build Coastguard Worker #define LSF_GAP_F 50.0f
63*15dc779aSAndroid Build Coastguard Worker #define FREQ_MAX_F 6400.0f
64*15dc779aSAndroid Build Coastguard Worker #define FREQ_DIV_F 400.0f
65*15dc779aSAndroid Build Coastguard Worker
66*15dc779aSAndroid Build Coastguard Worker extern const FLOAT32 ixheaacd_fir_lp_filt[1 + FILTER_DELAY];
67*15dc779aSAndroid Build Coastguard Worker
68*15dc779aSAndroid Build Coastguard Worker const WORD32 ixheaacd_pow_10_i_by_128[128] = {
69*15dc779aSAndroid Build Coastguard Worker 16384, 17788, 19312, 20968, 22765, 24716, 26835,
70*15dc779aSAndroid Build Coastguard Worker 29135, 31632, 34343, 37287, 40483, 43953, 47720,
71*15dc779aSAndroid Build Coastguard Worker 51810, 56251, 61072, 66307, 71990, 78161, 84860,
72*15dc779aSAndroid Build Coastguard Worker 92134, 100030, 108604, 117913, 128019, 138992, 150905,
73*15dc779aSAndroid Build Coastguard Worker 163840, 177882, 193129, 209682, 227654, 247167, 268352,
74*15dc779aSAndroid Build Coastguard Worker 291353, 316325, 343438, 372874, 404834, 439532, 477205,
75*15dc779aSAndroid Build Coastguard Worker 518107, 562515, 610728, 663075, 719908, 781612, 848605,
76*15dc779aSAndroid Build Coastguard Worker 921340, 1000309, 1086046, 1179133, 1280197, 1389925, 1509057,
77*15dc779aSAndroid Build Coastguard Worker 1638400, 1778829, 1931294, 2096827, 2276549, 2471675, 2683525,
78*15dc779aSAndroid Build Coastguard Worker 2913532, 3163255, 3434381, 3728745, 4048340, 4395328, 4772057,
79*15dc779aSAndroid Build Coastguard Worker 5181075, 5625151, 6107289, 6630752, 7199081, 7816122, 8486051,
80*15dc779aSAndroid Build Coastguard Worker 9213400, 10003091, 10860467, 11791330, 12801978, 13899250, 15090570,
81*15dc779aSAndroid Build Coastguard Worker 16384000, 17788290, 19312945, 20968279, 22765494, 24716750, 26835250,
82*15dc779aSAndroid Build Coastguard Worker 29135329, 31632551, 34343813, 37287459, 40483409, 43953287, 47720573,
83*15dc779aSAndroid Build Coastguard Worker 51810757, 56251515, 61072895, 66307521, 71990813, 78161226, 84860513,
84*15dc779aSAndroid Build Coastguard Worker 92134002, 100030911, 108604672, 117913300, 128019781, 138992500, 150905703,
85*15dc779aSAndroid Build Coastguard Worker 163840000, 177882909, 193129453, 209682794, 227654941, 247167501, 268352504,
86*15dc779aSAndroid Build Coastguard Worker 291353298, 316325515, 343438130, 372874596, 404834095, 439532879, 477205734,
87*15dc779aSAndroid Build Coastguard Worker 518107571, 562515151};
88*15dc779aSAndroid Build Coastguard Worker
89*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_lsf_weight_2st_flt(float *lsfq, float *w, WORD32 mode);
90*15dc779aSAndroid Build Coastguard Worker
ixheaacd_mult32_m(WORD32 a,WORD32 b)91*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaacd_mult32_m(WORD32 a, WORD32 b) {
92*15dc779aSAndroid Build Coastguard Worker WORD32 result;
93*15dc779aSAndroid Build Coastguard Worker WORD64 temp_result;
94*15dc779aSAndroid Build Coastguard Worker
95*15dc779aSAndroid Build Coastguard Worker temp_result = (WORD64)a * (WORD64)b;
96*15dc779aSAndroid Build Coastguard Worker result = (WORD32)(temp_result >> 31);
97*15dc779aSAndroid Build Coastguard Worker
98*15dc779aSAndroid Build Coastguard Worker return (result);
99*15dc779aSAndroid Build Coastguard Worker }
100*15dc779aSAndroid Build Coastguard Worker
ixheaacd_reset_acelp_data_fix(ia_usac_data_struct * usac_data,ia_usac_lpd_decoder_handle st,WORD32 * ptr_overlap_buf,WORD32 was_last_short,WORD32 tw_mdct)101*15dc779aSAndroid Build Coastguard Worker void ixheaacd_reset_acelp_data_fix(ia_usac_data_struct *usac_data,
102*15dc779aSAndroid Build Coastguard Worker ia_usac_lpd_decoder_handle st,
103*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_overlap_buf,
104*15dc779aSAndroid Build Coastguard Worker WORD32 was_last_short, WORD32 tw_mdct) {
105*15dc779aSAndroid Build Coastguard Worker WORD32 i;
106*15dc779aSAndroid Build Coastguard Worker
107*15dc779aSAndroid Build Coastguard Worker if (was_last_short == 1) {
108*15dc779aSAndroid Build Coastguard Worker st->mode_prev = -2;
109*15dc779aSAndroid Build Coastguard Worker } else {
110*15dc779aSAndroid Build Coastguard Worker st->mode_prev = -1;
111*15dc779aSAndroid Build Coastguard Worker }
112*15dc779aSAndroid Build Coastguard Worker
113*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < NUM_SUBFR_SUPERFRAME_BY2 - 1; i++) {
114*15dc779aSAndroid Build Coastguard Worker st->pitch_prev[i] = 64;
115*15dc779aSAndroid Build Coastguard Worker st->gain_prev[i] = 0;
116*15dc779aSAndroid Build Coastguard Worker }
117*15dc779aSAndroid Build Coastguard Worker
118*15dc779aSAndroid Build Coastguard Worker st->bpf_active_prev = 0;
119*15dc779aSAndroid Build Coastguard Worker
120*15dc779aSAndroid Build Coastguard Worker if (ptr_overlap_buf != NULL && !tw_mdct) {
121*15dc779aSAndroid Build Coastguard Worker const WORD32 *ptr_window_coeff;
122*15dc779aSAndroid Build Coastguard Worker WORD32 fac_length;
123*15dc779aSAndroid Build Coastguard Worker if (was_last_short) {
124*15dc779aSAndroid Build Coastguard Worker fac_length = (usac_data->ccfl) / 16;
125*15dc779aSAndroid Build Coastguard Worker } else {
126*15dc779aSAndroid Build Coastguard Worker fac_length = (usac_data->len_subfrm) / 2;
127*15dc779aSAndroid Build Coastguard Worker }
128*15dc779aSAndroid Build Coastguard Worker
129*15dc779aSAndroid Build Coastguard Worker if (fac_length == 48) {
130*15dc779aSAndroid Build Coastguard Worker ptr_window_coeff = ixheaacd_sine_win_96;
131*15dc779aSAndroid Build Coastguard Worker } else if (fac_length == 64) {
132*15dc779aSAndroid Build Coastguard Worker ptr_window_coeff = ixheaacd_sine_win_128;
133*15dc779aSAndroid Build Coastguard Worker } else if (fac_length == 96) {
134*15dc779aSAndroid Build Coastguard Worker ptr_window_coeff = ixheaacd_sine_win_192;
135*15dc779aSAndroid Build Coastguard Worker } else {
136*15dc779aSAndroid Build Coastguard Worker ptr_window_coeff = ixheaacd_sine_win_256;
137*15dc779aSAndroid Build Coastguard Worker }
138*15dc779aSAndroid Build Coastguard Worker
139*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < 2 * fac_length; i++) {
140*15dc779aSAndroid Build Coastguard Worker ptr_overlap_buf[(usac_data->ccfl) / 2 - fac_length + i] =
141*15dc779aSAndroid Build Coastguard Worker ixheaacd_mult32_m(
142*15dc779aSAndroid Build Coastguard Worker ptr_overlap_buf[(usac_data->ccfl) / 2 - fac_length + i],
143*15dc779aSAndroid Build Coastguard Worker ptr_window_coeff[2 * fac_length - 1 - i]);
144*15dc779aSAndroid Build Coastguard Worker }
145*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < (usac_data->ccfl) / 2 - fac_length; i++) {
146*15dc779aSAndroid Build Coastguard Worker ptr_overlap_buf[(usac_data->ccfl) / 2 + fac_length + i] = 0;
147*15dc779aSAndroid Build Coastguard Worker }
148*15dc779aSAndroid Build Coastguard Worker
149*15dc779aSAndroid Build Coastguard Worker if (ptr_overlap_buf != NULL) {
150*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < (usac_data->len_subfrm) / 2 - fac_length; i++) {
151*15dc779aSAndroid Build Coastguard Worker st->exc_prev[i] = 0.0f;
152*15dc779aSAndroid Build Coastguard Worker }
153*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < 2 * fac_length + 1; i++) {
154*15dc779aSAndroid Build Coastguard Worker st->exc_prev[(usac_data->len_subfrm) / 2 - fac_length + i] =
155*15dc779aSAndroid Build Coastguard Worker ptr_overlap_buf[i + usac_data->ccfl / 2 - fac_length - 1] /
156*15dc779aSAndroid Build Coastguard Worker (float)(16384);
157*15dc779aSAndroid Build Coastguard Worker }
158*15dc779aSAndroid Build Coastguard Worker } else {
159*15dc779aSAndroid Build Coastguard Worker ixheaacd_memset(st->exc_prev, 1 + (2 * FAC_LENGTH));
160*15dc779aSAndroid Build Coastguard Worker }
161*15dc779aSAndroid Build Coastguard Worker }
162*15dc779aSAndroid Build Coastguard Worker
163*15dc779aSAndroid Build Coastguard Worker return;
164*15dc779aSAndroid Build Coastguard Worker }
165*15dc779aSAndroid Build Coastguard Worker
ixheaacd_fix2flt_data(ia_usac_data_struct * usac_data,ia_usac_lpd_decoder_handle st,WORD32 k)166*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_fix2flt_data(ia_usac_data_struct *usac_data,
167*15dc779aSAndroid Build Coastguard Worker ia_usac_lpd_decoder_handle st, WORD32 k) {
168*15dc779aSAndroid Build Coastguard Worker WORD32 i;
169*15dc779aSAndroid Build Coastguard Worker WORD32 fac_length;
170*15dc779aSAndroid Build Coastguard Worker WORD32 window_sequence_last = usac_data->window_sequence_last[k];
171*15dc779aSAndroid Build Coastguard Worker WORD32 *p_ola_buffer = usac_data->overlap_data_ptr[k];
172*15dc779aSAndroid Build Coastguard Worker if (window_sequence_last == EIGHT_SHORT_SEQUENCE) {
173*15dc779aSAndroid Build Coastguard Worker fac_length = (usac_data->ccfl) / 16;
174*15dc779aSAndroid Build Coastguard Worker } else {
175*15dc779aSAndroid Build Coastguard Worker fac_length = (usac_data->len_subfrm) / 2;
176*15dc779aSAndroid Build Coastguard Worker }
177*15dc779aSAndroid Build Coastguard Worker
178*15dc779aSAndroid Build Coastguard Worker ixheaacd_memset(st->lp_flt_coeff_a_prev, 2 * (ORDER + 1));
179*15dc779aSAndroid Build Coastguard Worker ixheaacd_memset(st->xcitation_prev, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
180*15dc779aSAndroid Build Coastguard Worker ixheaacd_memset(st->synth_prev, MAX_PITCH + SYNTH_DELAY_LMAX);
181*15dc779aSAndroid Build Coastguard Worker ixheaacd_memset(st->bpf_prev, FILTER_DELAY + LEN_SUBFR);
182*15dc779aSAndroid Build Coastguard Worker
183*15dc779aSAndroid Build Coastguard Worker st->gain_threshold = 0.0f;
184*15dc779aSAndroid Build Coastguard Worker
185*15dc779aSAndroid Build Coastguard Worker if (p_ola_buffer != NULL) {
186*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < (usac_data->len_subfrm) / 2 - fac_length; i++) {
187*15dc779aSAndroid Build Coastguard Worker st->exc_prev[i] = 0;
188*15dc779aSAndroid Build Coastguard Worker }
189*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < 2 * fac_length + 1; i++) {
190*15dc779aSAndroid Build Coastguard Worker st->exc_prev[(usac_data->len_subfrm) / 2 - fac_length + i] = (FLOAT32)(
191*15dc779aSAndroid Build Coastguard Worker p_ola_buffer[i + usac_data->ccfl / 2 - fac_length - 1] / 16384.0);
192*15dc779aSAndroid Build Coastguard Worker }
193*15dc779aSAndroid Build Coastguard Worker } else {
194*15dc779aSAndroid Build Coastguard Worker ixheaacd_memset(st->exc_prev, 1 + (2 * FAC_LENGTH));
195*15dc779aSAndroid Build Coastguard Worker }
196*15dc779aSAndroid Build Coastguard Worker
197*15dc779aSAndroid Build Coastguard Worker return;
198*15dc779aSAndroid Build Coastguard Worker }
199*15dc779aSAndroid Build Coastguard Worker
ixheaacd_init_acelp_data(ia_usac_data_struct * usac_data,ia_usac_lpd_decoder_handle st)200*15dc779aSAndroid Build Coastguard Worker void ixheaacd_init_acelp_data(ia_usac_data_struct *usac_data,
201*15dc779aSAndroid Build Coastguard Worker ia_usac_lpd_decoder_handle st) {
202*15dc779aSAndroid Build Coastguard Worker ixheaacd_reset_acelp_data_fix(usac_data, st, NULL, 0, 0);
203*15dc779aSAndroid Build Coastguard Worker }
204*15dc779aSAndroid Build Coastguard Worker
205*15dc779aSAndroid Build Coastguard Worker #define PI_BY_6400 (PI / 6400.0)
206*15dc779aSAndroid Build Coastguard Worker #define SCALE1 (6400.0 / PI)
207*15dc779aSAndroid Build Coastguard Worker
ixheaacd_lsp_2_lsf_conversion(float lsp[],float lsf[],WORD32 m)208*15dc779aSAndroid Build Coastguard Worker void ixheaacd_lsp_2_lsf_conversion(float lsp[], float lsf[], WORD32 m) {
209*15dc779aSAndroid Build Coastguard Worker short i;
210*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < m; i++) {
211*15dc779aSAndroid Build Coastguard Worker lsf[i] = (float)(acos(lsp[i]) * SCALE1);
212*15dc779aSAndroid Build Coastguard Worker }
213*15dc779aSAndroid Build Coastguard Worker return;
214*15dc779aSAndroid Build Coastguard Worker }
215*15dc779aSAndroid Build Coastguard Worker
ixheaacd_lsf_2_lsp_conversion_float(FLOAT32 lsf[],FLOAT32 lsp[],WORD32 m)216*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_lsf_2_lsp_conversion_float(FLOAT32 lsf[], FLOAT32 lsp[],
217*15dc779aSAndroid Build Coastguard Worker WORD32 m) {
218*15dc779aSAndroid Build Coastguard Worker WORD32 i;
219*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < m; i++)
220*15dc779aSAndroid Build Coastguard Worker lsp[i] = (FLOAT32)cos((double)lsf[i] * (double)PI_BY_6400);
221*15dc779aSAndroid Build Coastguard Worker
222*15dc779aSAndroid Build Coastguard Worker return;
223*15dc779aSAndroid Build Coastguard Worker }
224*15dc779aSAndroid Build Coastguard Worker
ixheaacd_bass_post_filter(FLOAT32 * synth_sig,WORD32 * pitch,FLOAT32 * pitch_gain,FLOAT32 * synth_out,WORD32 len_fr,WORD32 len2,FLOAT32 bpf_prev[],WORD32 ec_flag)225*15dc779aSAndroid Build Coastguard Worker static WORD32 ixheaacd_bass_post_filter(FLOAT32 *synth_sig, WORD32 *pitch, FLOAT32 *pitch_gain,
226*15dc779aSAndroid Build Coastguard Worker FLOAT32 *synth_out, WORD32 len_fr, WORD32 len2,
227*15dc779aSAndroid Build Coastguard Worker FLOAT32 bpf_prev[], WORD32 ec_flag) {
228*15dc779aSAndroid Build Coastguard Worker WORD32 i, j, sf, num_subfr, pitch_lag, lg;
229*15dc779aSAndroid Build Coastguard Worker FLOAT32 x_energy, xy_corr, y_energy, norm_corr, energy, gain, tmp, alpha;
230*15dc779aSAndroid Build Coastguard Worker FLOAT32 noise_buf[FILTER_DELAY + (2 * LEN_SUBFR)], *noise_tmp1, *noise_tmp2,
231*15dc779aSAndroid Build Coastguard Worker *x, *y;
232*15dc779aSAndroid Build Coastguard Worker
233*15dc779aSAndroid Build Coastguard Worker noise_tmp1 = noise_buf + FILTER_DELAY;
234*15dc779aSAndroid Build Coastguard Worker noise_tmp2 = noise_buf + FILTER_DELAY + LEN_SUBFR;
235*15dc779aSAndroid Build Coastguard Worker
236*15dc779aSAndroid Build Coastguard Worker memcpy(synth_out, synth_sig - LEN_SUBFR, len_fr * sizeof(FLOAT32));
237*15dc779aSAndroid Build Coastguard Worker
238*15dc779aSAndroid Build Coastguard Worker if (len_fr % 64)
239*15dc779aSAndroid Build Coastguard Worker memset(synth_out + len_fr, 0, (LEN_SUBFR - len_fr % 64) * sizeof(FLOAT32));
240*15dc779aSAndroid Build Coastguard Worker
241*15dc779aSAndroid Build Coastguard Worker sf = 0;
242*15dc779aSAndroid Build Coastguard Worker for (num_subfr = 0; num_subfr < len_fr; num_subfr += LEN_SUBFR, sf++) {
243*15dc779aSAndroid Build Coastguard Worker pitch_lag = pitch[sf];
244*15dc779aSAndroid Build Coastguard Worker gain = pitch_gain[sf];
245*15dc779aSAndroid Build Coastguard Worker if (((pitch_lag >> 1) + 96 - num_subfr) > MAX_PITCH) {
246*15dc779aSAndroid Build Coastguard Worker if (ec_flag) {
247*15dc779aSAndroid Build Coastguard Worker pitch_lag = (MAX_PITCH + num_subfr - 96) << 1;
248*15dc779aSAndroid Build Coastguard Worker } else {
249*15dc779aSAndroid Build Coastguard Worker return -1;
250*15dc779aSAndroid Build Coastguard Worker }
251*15dc779aSAndroid Build Coastguard Worker }
252*15dc779aSAndroid Build Coastguard Worker if (gain > 1.0f) gain = 1.0f;
253*15dc779aSAndroid Build Coastguard Worker if (gain < 0.0f) gain = 0.0f;
254*15dc779aSAndroid Build Coastguard Worker
255*15dc779aSAndroid Build Coastguard Worker x = &synth_sig[num_subfr - 96];
256*15dc779aSAndroid Build Coastguard Worker y = &synth_sig[num_subfr - pitch_lag / 2 - 96];
257*15dc779aSAndroid Build Coastguard Worker
258*15dc779aSAndroid Build Coastguard Worker x_energy = 0.01f;
259*15dc779aSAndroid Build Coastguard Worker xy_corr = 0.01f;
260*15dc779aSAndroid Build Coastguard Worker y_energy = 0.01f;
261*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < LEN_SUBFR + 96; i++) {
262*15dc779aSAndroid Build Coastguard Worker x_energy += x[i] * x[i];
263*15dc779aSAndroid Build Coastguard Worker xy_corr += x[i] * y[i];
264*15dc779aSAndroid Build Coastguard Worker y_energy += y[i] * y[i];
265*15dc779aSAndroid Build Coastguard Worker }
266*15dc779aSAndroid Build Coastguard Worker
267*15dc779aSAndroid Build Coastguard Worker norm_corr = xy_corr / (FLOAT32)sqrt(x_energy * y_energy);
268*15dc779aSAndroid Build Coastguard Worker
269*15dc779aSAndroid Build Coastguard Worker if (norm_corr > 0.95f) pitch_lag >>= 1;
270*15dc779aSAndroid Build Coastguard Worker
271*15dc779aSAndroid Build Coastguard Worker lg = len_fr + len2 - pitch_lag - num_subfr;
272*15dc779aSAndroid Build Coastguard Worker if (lg < 0) lg = 0;
273*15dc779aSAndroid Build Coastguard Worker if (lg > LEN_SUBFR) lg = LEN_SUBFR;
274*15dc779aSAndroid Build Coastguard Worker
275*15dc779aSAndroid Build Coastguard Worker if (pitch_lag > MAX_PITCH) {
276*15dc779aSAndroid Build Coastguard Worker if (ec_flag) {
277*15dc779aSAndroid Build Coastguard Worker pitch_lag = MAX_PITCH;
278*15dc779aSAndroid Build Coastguard Worker } else {
279*15dc779aSAndroid Build Coastguard Worker return -1;
280*15dc779aSAndroid Build Coastguard Worker }
281*15dc779aSAndroid Build Coastguard Worker }
282*15dc779aSAndroid Build Coastguard Worker
283*15dc779aSAndroid Build Coastguard Worker if (gain > 0) {
284*15dc779aSAndroid Build Coastguard Worker if (lg > 0) {
285*15dc779aSAndroid Build Coastguard Worker tmp = 0.01f;
286*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < lg; i++) {
287*15dc779aSAndroid Build Coastguard Worker tmp += synth_sig[i + num_subfr] * synth_sig[i + num_subfr];
288*15dc779aSAndroid Build Coastguard Worker }
289*15dc779aSAndroid Build Coastguard Worker energy = 0.01f;
290*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < lg; i++) {
291*15dc779aSAndroid Build Coastguard Worker energy += synth_sig[i + num_subfr + pitch_lag] *
292*15dc779aSAndroid Build Coastguard Worker synth_sig[i + num_subfr + pitch_lag];
293*15dc779aSAndroid Build Coastguard Worker }
294*15dc779aSAndroid Build Coastguard Worker tmp = (FLOAT32)sqrt(tmp / energy);
295*15dc779aSAndroid Build Coastguard Worker if (tmp < gain) gain = tmp;
296*15dc779aSAndroid Build Coastguard Worker }
297*15dc779aSAndroid Build Coastguard Worker
298*15dc779aSAndroid Build Coastguard Worker alpha = 0.5f * gain;
299*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < lg; i++) {
300*15dc779aSAndroid Build Coastguard Worker noise_tmp2[i] = alpha * (synth_sig[i + num_subfr] -
301*15dc779aSAndroid Build Coastguard Worker 0.5f * synth_sig[i + num_subfr - pitch_lag] -
302*15dc779aSAndroid Build Coastguard Worker 0.5f * synth_sig[i + num_subfr + pitch_lag]);
303*15dc779aSAndroid Build Coastguard Worker }
304*15dc779aSAndroid Build Coastguard Worker for (i = lg; i < LEN_SUBFR; i++) {
305*15dc779aSAndroid Build Coastguard Worker noise_tmp2[i] = alpha * (synth_sig[i + num_subfr] -
306*15dc779aSAndroid Build Coastguard Worker synth_sig[i + num_subfr - pitch_lag]);
307*15dc779aSAndroid Build Coastguard Worker }
308*15dc779aSAndroid Build Coastguard Worker } else {
309*15dc779aSAndroid Build Coastguard Worker memset(noise_tmp2, 0, LEN_SUBFR * sizeof(FLOAT32));
310*15dc779aSAndroid Build Coastguard Worker }
311*15dc779aSAndroid Build Coastguard Worker
312*15dc779aSAndroid Build Coastguard Worker memcpy(noise_buf, bpf_prev, (FILTER_DELAY + LEN_SUBFR) * sizeof(FLOAT32));
313*15dc779aSAndroid Build Coastguard Worker memcpy(bpf_prev, noise_buf + LEN_SUBFR,
314*15dc779aSAndroid Build Coastguard Worker (FILTER_DELAY + LEN_SUBFR) * sizeof(FLOAT32));
315*15dc779aSAndroid Build Coastguard Worker
316*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < LEN_SUBFR; i++) {
317*15dc779aSAndroid Build Coastguard Worker tmp = ixheaacd_fir_lp_filt[0] * noise_tmp1[i];
318*15dc779aSAndroid Build Coastguard Worker for (j = 1; j <= FILTER_DELAY; j++) {
319*15dc779aSAndroid Build Coastguard Worker tmp +=
320*15dc779aSAndroid Build Coastguard Worker ixheaacd_fir_lp_filt[j] * (noise_tmp1[i - j] + noise_tmp1[i + j]);
321*15dc779aSAndroid Build Coastguard Worker }
322*15dc779aSAndroid Build Coastguard Worker synth_out[i + num_subfr] -= tmp;
323*15dc779aSAndroid Build Coastguard Worker }
324*15dc779aSAndroid Build Coastguard Worker }
325*15dc779aSAndroid Build Coastguard Worker
326*15dc779aSAndroid Build Coastguard Worker return 0;
327*15dc779aSAndroid Build Coastguard Worker }
328*15dc779aSAndroid Build Coastguard Worker
ixheaacd_reorder_lsf(float * lsf,float min_dist,int n)329*15dc779aSAndroid Build Coastguard Worker void ixheaacd_reorder_lsf(float *lsf, float min_dist, int n) {
330*15dc779aSAndroid Build Coastguard Worker int i;
331*15dc779aSAndroid Build Coastguard Worker float lsf_min;
332*15dc779aSAndroid Build Coastguard Worker
333*15dc779aSAndroid Build Coastguard Worker lsf_min = min_dist;
334*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < n; i++) {
335*15dc779aSAndroid Build Coastguard Worker if (lsf[i] < lsf_min) lsf[i] = lsf_min;
336*15dc779aSAndroid Build Coastguard Worker
337*15dc779aSAndroid Build Coastguard Worker lsf_min = lsf[i] + min_dist;
338*15dc779aSAndroid Build Coastguard Worker }
339*15dc779aSAndroid Build Coastguard Worker
340*15dc779aSAndroid Build Coastguard Worker lsf_min = FREQ_MAX_F - min_dist;
341*15dc779aSAndroid Build Coastguard Worker for (i = n - 1; i >= 0; i--) {
342*15dc779aSAndroid Build Coastguard Worker if (lsf[i] > lsf_min) lsf[i] = lsf_min;
343*15dc779aSAndroid Build Coastguard Worker
344*15dc779aSAndroid Build Coastguard Worker lsf_min = lsf[i] - min_dist;
345*15dc779aSAndroid Build Coastguard Worker }
346*15dc779aSAndroid Build Coastguard Worker
347*15dc779aSAndroid Build Coastguard Worker return;
348*15dc779aSAndroid Build Coastguard Worker }
349*15dc779aSAndroid Build Coastguard Worker
ixheaacd_lpd_dec(ia_usac_data_struct * usac_data,ia_usac_lpd_decoder_handle st,ia_td_frame_data_struct * pstr_td_frame_data,FLOAT32 fsynth[],WORD32 first_lpd_flag,WORD32 short_fac_flag,WORD32 bpf_control_info)350*15dc779aSAndroid Build Coastguard Worker WORD32 ixheaacd_lpd_dec(ia_usac_data_struct *usac_data,
351*15dc779aSAndroid Build Coastguard Worker ia_usac_lpd_decoder_handle st,
352*15dc779aSAndroid Build Coastguard Worker ia_td_frame_data_struct *pstr_td_frame_data,
353*15dc779aSAndroid Build Coastguard Worker FLOAT32 fsynth[], WORD32 first_lpd_flag,
354*15dc779aSAndroid Build Coastguard Worker WORD32 short_fac_flag, WORD32 bpf_control_info) {
355*15dc779aSAndroid Build Coastguard Worker FLOAT32 *synth_buf = usac_data->synth_buf;
356*15dc779aSAndroid Build Coastguard Worker FLOAT32 *xcitation_buff = usac_data->exc_buf;
357*15dc779aSAndroid Build Coastguard Worker FLOAT32 lsp_curr[ORDER];
358*15dc779aSAndroid Build Coastguard Worker FLOAT32 lsf_curr[ORDER];
359*15dc779aSAndroid Build Coastguard Worker FLOAT32 *lp_flt_coff_a = usac_data->lp_flt_coff;
360*15dc779aSAndroid Build Coastguard Worker FLOAT32 *synth, *xcitation_curr;
361*15dc779aSAndroid Build Coastguard Worker WORD32 *pitch = usac_data->pitch;
362*15dc779aSAndroid Build Coastguard Worker FLOAT32 *pitch_gain = usac_data->pitch_gain;
363*15dc779aSAndroid Build Coastguard Worker FLOAT32 lsf_flt[(2 * NUM_FRAMES + 1) * ORDER];
364*15dc779aSAndroid Build Coastguard Worker
365*15dc779aSAndroid Build Coastguard Worker WORD32 i, k, tp, mode;
366*15dc779aSAndroid Build Coastguard Worker WORD32 *mod;
367*15dc779aSAndroid Build Coastguard Worker FLOAT32 gain, stability_factor = 0.0f;
368*15dc779aSAndroid Build Coastguard Worker FLOAT32 tmp, synth_corr, synth_energy;
369*15dc779aSAndroid Build Coastguard Worker
370*15dc779aSAndroid Build Coastguard Worker WORD32 len_fr;
371*15dc779aSAndroid Build Coastguard Worker WORD32 len_subfrm;
372*15dc779aSAndroid Build Coastguard Worker WORD32 num_subfr;
373*15dc779aSAndroid Build Coastguard Worker WORD32 num_subfr_in_superfr;
374*15dc779aSAndroid Build Coastguard Worker WORD32 num_subfr_by2;
375*15dc779aSAndroid Build Coastguard Worker WORD32 synth_delay;
376*15dc779aSAndroid Build Coastguard Worker WORD32 num_samples = 0;
377*15dc779aSAndroid Build Coastguard Worker
378*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_scratch = &usac_data->scratch_buffer[0];
379*15dc779aSAndroid Build Coastguard Worker
380*15dc779aSAndroid Build Coastguard Worker WORD32 subfr_len = 0, n_subfr = 0;
381*15dc779aSAndroid Build Coastguard Worker WORD32 err = 0;
382*15dc779aSAndroid Build Coastguard Worker WORD32 ch = usac_data->present_chan;
383*15dc779aSAndroid Build Coastguard Worker
384*15dc779aSAndroid Build Coastguard Worker len_fr = usac_data->ccfl;
385*15dc779aSAndroid Build Coastguard Worker len_subfrm = usac_data->len_subfrm;
386*15dc779aSAndroid Build Coastguard Worker num_subfr = usac_data->num_subfrm;
387*15dc779aSAndroid Build Coastguard Worker num_subfr_in_superfr = NUM_FRAMES * num_subfr;
388*15dc779aSAndroid Build Coastguard Worker num_subfr_by2 = (num_subfr_in_superfr / 2) - 1;
389*15dc779aSAndroid Build Coastguard Worker synth_delay = num_subfr_by2 * LEN_SUBFR;
390*15dc779aSAndroid Build Coastguard Worker
391*15dc779aSAndroid Build Coastguard Worker synth = synth_buf + MAX_PITCH + synth_delay;
392*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(st->synth_prev, synth_buf, MAX_PITCH + synth_delay);
393*15dc779aSAndroid Build Coastguard Worker ixheaacd_memset(synth, SYNTH_DELAY_LMAX + LEN_SUPERFRAME - synth_delay);
394*15dc779aSAndroid Build Coastguard Worker
395*15dc779aSAndroid Build Coastguard Worker xcitation_curr = xcitation_buff + MAX_PITCH + INTER_LP_FIL_ORDER + 1;
396*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(st->xcitation_prev, xcitation_buff,
397*15dc779aSAndroid Build Coastguard Worker MAX_PITCH + INTER_LP_FIL_ORDER + 1);
398*15dc779aSAndroid Build Coastguard Worker memset(xcitation_curr, 0, sizeof(FLOAT32) * (LEN_SUPERFRAME + 1));
399*15dc779aSAndroid Build Coastguard Worker
400*15dc779aSAndroid Build Coastguard Worker mod = pstr_td_frame_data->mod;
401*15dc779aSAndroid Build Coastguard Worker if (usac_data->frame_ok == 1) {
402*15dc779aSAndroid Build Coastguard Worker usac_data->num_lost_lpd_frames[usac_data->present_chan] = 0;
403*15dc779aSAndroid Build Coastguard Worker }
404*15dc779aSAndroid Build Coastguard Worker
405*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag && usac_data->frame_ok == 0) {
406*15dc779aSAndroid Build Coastguard Worker ixheaacd_usac_lpc_ec(usac_data->lsp_coeff, usac_data->lpc4_lsf, usac_data->lsf_adaptive_mean,
407*15dc779aSAndroid Build Coastguard Worker first_lpd_flag);
408*15dc779aSAndroid Build Coastguard Worker }
409*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < num_subfr_by2; i++) {
410*15dc779aSAndroid Build Coastguard Worker pitch[i] = st->pitch_prev[i];
411*15dc779aSAndroid Build Coastguard Worker pitch_gain[i] = st->gain_prev[i];
412*15dc779aSAndroid Build Coastguard Worker }
413*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < num_subfr_in_superfr; i++) {
414*15dc779aSAndroid Build Coastguard Worker pitch[i + num_subfr_by2] = 64;
415*15dc779aSAndroid Build Coastguard Worker pitch_gain[i + num_subfr_by2] = 0.0f;
416*15dc779aSAndroid Build Coastguard Worker }
417*15dc779aSAndroid Build Coastguard Worker
418*15dc779aSAndroid Build Coastguard Worker if (usac_data->frame_ok) {
419*15dc779aSAndroid Build Coastguard Worker if (!first_lpd_flag) {
420*15dc779aSAndroid Build Coastguard Worker ixheaacd_lsp_2_lsf_conversion(st->lspold, lsf_flt, ORDER);
421*15dc779aSAndroid Build Coastguard Worker }
422*15dc779aSAndroid Build Coastguard Worker
423*15dc779aSAndroid Build Coastguard Worker ixheaacd_alg_vec_dequant(pstr_td_frame_data, first_lpd_flag, lsf_flt, pstr_td_frame_data->mod,
424*15dc779aSAndroid Build Coastguard Worker usac_data->ec_flag);
425*15dc779aSAndroid Build Coastguard Worker }
426*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag && !(usac_data->frame_ok)) {
427*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < 5; i++) {
428*15dc779aSAndroid Build Coastguard Worker memcpy(&lsf_flt[i * ORDER], &usac_data->lsp_coeff[i], ORDER * sizeof(lsf_flt[0]));
429*15dc779aSAndroid Build Coastguard Worker }
430*15dc779aSAndroid Build Coastguard Worker }
431*15dc779aSAndroid Build Coastguard Worker if (first_lpd_flag) {
432*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(&lsf_flt[0], st->lsf_prev, ORDER);
433*15dc779aSAndroid Build Coastguard Worker ixheaacd_lsf_2_lsp_conversion_float(st->lsf_prev, st->lspold, ORDER);
434*15dc779aSAndroid Build Coastguard Worker }
435*15dc779aSAndroid Build Coastguard Worker
436*15dc779aSAndroid Build Coastguard Worker if ((first_lpd_flag && mod[0] == 0) || (first_lpd_flag && mod[1] == 0) ||
437*15dc779aSAndroid Build Coastguard Worker ((first_lpd_flag && mod[2] == 0 && len_subfrm != LEN_FRAME))) {
438*15dc779aSAndroid Build Coastguard Worker FLOAT32 lp_flt_coeff_a[9 * (ORDER + 1)];
439*15dc779aSAndroid Build Coastguard Worker FLOAT32 tmp_buf[3 * LEN_FRAME + ORDER];
440*15dc779aSAndroid Build Coastguard Worker FLOAT32 tmp_res_buf[3 * LEN_FRAME];
441*15dc779aSAndroid Build Coastguard Worker FLOAT32 *tmp = &(tmp_buf[LEN_FRAME]);
442*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_tmp = &(tmp_res_buf[LEN_FRAME]);
443*15dc779aSAndroid Build Coastguard Worker WORD32 tmp_start;
444*15dc779aSAndroid Build Coastguard Worker FLOAT32 mem = 0;
445*15dc779aSAndroid Build Coastguard Worker WORD32 gain;
446*15dc779aSAndroid Build Coastguard Worker WORD32 length;
447*15dc779aSAndroid Build Coastguard Worker
448*15dc779aSAndroid Build Coastguard Worker ixheaacd_interpolation_lsp_params(st->lspold, st->lspold, lp_flt_coeff_a,
449*15dc779aSAndroid Build Coastguard Worker 8);
450*15dc779aSAndroid Build Coastguard Worker
451*15dc779aSAndroid Build Coastguard Worker memcpy(st->lp_flt_coeff_a_prev, lp_flt_coeff_a,
452*15dc779aSAndroid Build Coastguard Worker (ORDER + 1) * sizeof(FLOAT32));
453*15dc779aSAndroid Build Coastguard Worker memcpy(st->lp_flt_coeff_a_prev + ORDER + 1, lp_flt_coeff_a,
454*15dc779aSAndroid Build Coastguard Worker (ORDER + 1) * sizeof(FLOAT32));
455*15dc779aSAndroid Build Coastguard Worker
456*15dc779aSAndroid Build Coastguard Worker if (mod[0] == 0) {
457*15dc779aSAndroid Build Coastguard Worker WORD32 fac_length;
458*15dc779aSAndroid Build Coastguard Worker if (short_fac_flag) {
459*15dc779aSAndroid Build Coastguard Worker fac_length = (len_subfrm * NUM_FRAMES) / 16;
460*15dc779aSAndroid Build Coastguard Worker } else {
461*15dc779aSAndroid Build Coastguard Worker fac_length = len_subfrm / 2;
462*15dc779aSAndroid Build Coastguard Worker }
463*15dc779aSAndroid Build Coastguard Worker
464*15dc779aSAndroid Build Coastguard Worker if (usac_data->frame_ok == 0) {
465*15dc779aSAndroid Build Coastguard Worker memset(&pstr_td_frame_data->fac_data[0], 0, sizeof(pstr_td_frame_data->fac_data));
466*15dc779aSAndroid Build Coastguard Worker }
467*15dc779aSAndroid Build Coastguard Worker gain = ixheaacd_pow_10_i_by_128[pstr_td_frame_data->fac_data[0]];
468*15dc779aSAndroid Build Coastguard Worker
469*15dc779aSAndroid Build Coastguard Worker memcpy(ptr_scratch, &pstr_td_frame_data->fac_data[0],
470*15dc779aSAndroid Build Coastguard Worker 129 * sizeof(WORD32));
471*15dc779aSAndroid Build Coastguard Worker
472*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < fac_length / 2; i++) {
473*15dc779aSAndroid Build Coastguard Worker pstr_td_frame_data->fac_data[i] = ptr_scratch[2 * i + 1] << 16;
474*15dc779aSAndroid Build Coastguard Worker pstr_td_frame_data->fac_data[fac_length / 2 + i] =
475*15dc779aSAndroid Build Coastguard Worker ptr_scratch[fac_length - 2 * i] << 16;
476*15dc779aSAndroid Build Coastguard Worker }
477*15dc779aSAndroid Build Coastguard Worker
478*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag == 0) {
479*15dc779aSAndroid Build Coastguard Worker if (fac_length & (fac_length - 1)) {
480*15dc779aSAndroid Build Coastguard Worker if ((fac_length != 48) && (fac_length != 96) && (fac_length != 192) &&
481*15dc779aSAndroid Build Coastguard Worker (fac_length != 384) && (fac_length != 768)) {
482*15dc779aSAndroid Build Coastguard Worker return -1;
483*15dc779aSAndroid Build Coastguard Worker }
484*15dc779aSAndroid Build Coastguard Worker }
485*15dc779aSAndroid Build Coastguard Worker }
486*15dc779aSAndroid Build Coastguard Worker
487*15dc779aSAndroid Build Coastguard Worker ixheaacd_fwd_alias_cancel_tool(usac_data, pstr_td_frame_data, fac_length, lp_flt_coeff_a,
488*15dc779aSAndroid Build Coastguard Worker gain);
489*15dc779aSAndroid Build Coastguard Worker
490*15dc779aSAndroid Build Coastguard Worker memset(&usac_data->overlap_data_ptr[usac_data->present_chan][(len_fr / 2)], 0,
491*15dc779aSAndroid Build Coastguard Worker fac_length * sizeof(WORD32));
492*15dc779aSAndroid Build Coastguard Worker }
493*15dc779aSAndroid Build Coastguard Worker
494*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < 2 * len_subfrm; i++)
495*15dc779aSAndroid Build Coastguard Worker st->fd_synth[ORDER + i] = (FLOAT32)(
496*15dc779aSAndroid Build Coastguard Worker (FLOAT32)usac_data->overlap_data_ptr[usac_data->present_chan][i] /
497*15dc779aSAndroid Build Coastguard Worker 16384.0);
498*15dc779aSAndroid Build Coastguard Worker num_samples = min(2 * len_subfrm, MAX_PITCH + synth_delay);
499*15dc779aSAndroid Build Coastguard Worker
500*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(st->fd_synth + ORDER, synth - 2 * len_subfrm,
501*15dc779aSAndroid Build Coastguard Worker 2 * len_subfrm);
502*15dc779aSAndroid Build Coastguard Worker
503*15dc779aSAndroid Build Coastguard Worker ixheaacd_preemphsis_tool_float(st->fd_synth + ORDER, PREEMPH_FILT_FAC,
504*15dc779aSAndroid Build Coastguard Worker 2 * len_subfrm, mem);
505*15dc779aSAndroid Build Coastguard Worker
506*15dc779aSAndroid Build Coastguard Worker ixheaacd_memset(tmp, ORDER);
507*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(st->fd_synth + ORDER, tmp + ORDER, 2 * len_subfrm);
508*15dc779aSAndroid Build Coastguard Worker tmp_start = 0;
509*15dc779aSAndroid Build Coastguard Worker
510*15dc779aSAndroid Build Coastguard Worker ixheaacd_memset(ptr_tmp - len_subfrm, 3 * len_subfrm);
511*15dc779aSAndroid Build Coastguard Worker memset(st->fd_synth, 0, ORDER * sizeof(WORD32));
512*15dc779aSAndroid Build Coastguard Worker length = (2 * len_subfrm - tmp_start) / LEN_SUBFR;
513*15dc779aSAndroid Build Coastguard Worker
514*15dc779aSAndroid Build Coastguard Worker ixheaacd_residual_tool_float1(lp_flt_coeff_a,
515*15dc779aSAndroid Build Coastguard Worker &st->fd_synth[ORDER + tmp_start],
516*15dc779aSAndroid Build Coastguard Worker &ptr_tmp[tmp_start], LEN_SUBFR, length);
517*15dc779aSAndroid Build Coastguard Worker
518*15dc779aSAndroid Build Coastguard Worker if (mod[0] != 0 && (len_subfrm == LEN_FRAME || mod[1] != 0)) {
519*15dc779aSAndroid Build Coastguard Worker num_samples = min(len_subfrm, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
520*15dc779aSAndroid Build Coastguard Worker } else {
521*15dc779aSAndroid Build Coastguard Worker num_samples = min(2 * len_subfrm, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
522*15dc779aSAndroid Build Coastguard Worker }
523*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(ptr_tmp + 2 * len_subfrm - num_samples,
524*15dc779aSAndroid Build Coastguard Worker xcitation_curr - num_samples, num_samples);
525*15dc779aSAndroid Build Coastguard Worker }
526*15dc779aSAndroid Build Coastguard Worker
527*15dc779aSAndroid Build Coastguard Worker k = 0;
528*15dc779aSAndroid Build Coastguard Worker
529*15dc779aSAndroid Build Coastguard Worker while (k < 4) {
530*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag && usac_data->frame_ok == 0) {
531*15dc779aSAndroid Build Coastguard Worker if (mod[k] != 0 && usac_data->frame_ok == 0 &&
532*15dc779aSAndroid Build Coastguard Worker usac_data->str_error_concealment[ch].prev_frame_ok[0] == 0 && k == 0) {
533*15dc779aSAndroid Build Coastguard Worker memcpy(st->lspold, usac_data->lspold_ec, sizeof(st->lspold));
534*15dc779aSAndroid Build Coastguard Worker }
535*15dc779aSAndroid Build Coastguard Worker usac_data->num_lost_lpd_frames[usac_data->present_chan]++;
536*15dc779aSAndroid Build Coastguard Worker }
537*15dc779aSAndroid Build Coastguard Worker
538*15dc779aSAndroid Build Coastguard Worker mode = mod[k];
539*15dc779aSAndroid Build Coastguard Worker if ((st->mode_prev == 0) && (mode > 0) &&
540*15dc779aSAndroid Build Coastguard Worker (k != 0 || st->bpf_active_prev == 1)) {
541*15dc779aSAndroid Build Coastguard Worker i = (k * num_subfr) + num_subfr_by2;
542*15dc779aSAndroid Build Coastguard Worker pitch[i + 1] = pitch[i] = pitch[i - 1];
543*15dc779aSAndroid Build Coastguard Worker pitch_gain[i + 1] = pitch_gain[i] = pitch_gain[i - 1];
544*15dc779aSAndroid Build Coastguard Worker }
545*15dc779aSAndroid Build Coastguard Worker if (usac_data->frame_ok == 0) {
546*15dc779aSAndroid Build Coastguard Worker memcpy(lsf_curr, &lsf_flt[(k + 1) * ORDER], ORDER * sizeof(FLOAT32));
547*15dc779aSAndroid Build Coastguard Worker } else {
548*15dc779aSAndroid Build Coastguard Worker if ((mode == 0) || (mode == 1))
549*15dc779aSAndroid Build Coastguard Worker memcpy(lsf_curr, &lsf_flt[(k + 1) * ORDER], ORDER * sizeof(FLOAT32));
550*15dc779aSAndroid Build Coastguard Worker else if (mode == 2)
551*15dc779aSAndroid Build Coastguard Worker memcpy(lsf_curr, &lsf_flt[(k + 2) * ORDER], ORDER * sizeof(FLOAT32));
552*15dc779aSAndroid Build Coastguard Worker else
553*15dc779aSAndroid Build Coastguard Worker memcpy(lsf_curr, &lsf_flt[(k + 4) * ORDER], ORDER * sizeof(FLOAT32));
554*15dc779aSAndroid Build Coastguard Worker }
555*15dc779aSAndroid Build Coastguard Worker
556*15dc779aSAndroid Build Coastguard Worker ixheaacd_lsf_2_lsp_conversion_float(lsf_curr, lsp_curr, ORDER);
557*15dc779aSAndroid Build Coastguard Worker if (usac_data->frame_ok) {
558*15dc779aSAndroid Build Coastguard Worker tmp = 0.0f;
559*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < ORDER; i++) {
560*15dc779aSAndroid Build Coastguard Worker tmp += (lsf_curr[i] - st->lsf_prev[i]) * (lsf_curr[i] - st->lsf_prev[i]);
561*15dc779aSAndroid Build Coastguard Worker }
562*15dc779aSAndroid Build Coastguard Worker stability_factor = (FLOAT32)(1.25f - (tmp / 400000.0f));
563*15dc779aSAndroid Build Coastguard Worker if (stability_factor > 1.0f) {
564*15dc779aSAndroid Build Coastguard Worker stability_factor = 1.0f;
565*15dc779aSAndroid Build Coastguard Worker }
566*15dc779aSAndroid Build Coastguard Worker if (stability_factor < 0.0f) {
567*15dc779aSAndroid Build Coastguard Worker stability_factor = 0.0f;
568*15dc779aSAndroid Build Coastguard Worker }
569*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag) {
570*15dc779aSAndroid Build Coastguard Worker usac_data->stability_factor_old = stability_factor;
571*15dc779aSAndroid Build Coastguard Worker }
572*15dc779aSAndroid Build Coastguard Worker }
573*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag && !(usac_data->frame_ok)) {
574*15dc779aSAndroid Build Coastguard Worker stability_factor = usac_data->stability_factor_old;
575*15dc779aSAndroid Build Coastguard Worker }
576*15dc779aSAndroid Build Coastguard Worker if (usac_data->frame_ok == 0) {
577*15dc779aSAndroid Build Coastguard Worker mode = st->mode_prev;
578*15dc779aSAndroid Build Coastguard Worker }
579*15dc779aSAndroid Build Coastguard Worker if ((usac_data->frame_ok == 1 && mode == 0) ||
580*15dc779aSAndroid Build Coastguard Worker (usac_data->frame_ok == 0 && (st->mode_prev == 0 || st->mode_prev == 1))) {
581*15dc779aSAndroid Build Coastguard Worker ixheaacd_interpolation_lsp_params(st->lspold, lsp_curr, lp_flt_coff_a, num_subfr);
582*15dc779aSAndroid Build Coastguard Worker
583*15dc779aSAndroid Build Coastguard Worker if (usac_data->frame_ok == 1 || (usac_data->frame_ok == 0 && st->mode_prev == 0)) {
584*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_alias_cnx(usac_data, pstr_td_frame_data, k, lp_flt_coff_a,
585*15dc779aSAndroid Build Coastguard Worker stability_factor, st);
586*15dc779aSAndroid Build Coastguard Worker }
587*15dc779aSAndroid Build Coastguard Worker
588*15dc779aSAndroid Build Coastguard Worker if (usac_data->frame_ok == 0 && st->mode_prev == 1) {
589*15dc779aSAndroid Build Coastguard Worker ixheaacd_usac_tcx_ec(usac_data, st, lsp_curr, k, lp_flt_coff_a);
590*15dc779aSAndroid Build Coastguard Worker }
591*15dc779aSAndroid Build Coastguard Worker
592*15dc779aSAndroid Build Coastguard Worker if ((st->mode_prev != 0) && bpf_control_info) {
593*15dc779aSAndroid Build Coastguard Worker i = (k * num_subfr) + num_subfr_by2;
594*15dc779aSAndroid Build Coastguard Worker pitch[i - 1] = pitch[i];
595*15dc779aSAndroid Build Coastguard Worker pitch_gain[i - 1] = pitch_gain[i];
596*15dc779aSAndroid Build Coastguard Worker if (st->mode_prev != -2) {
597*15dc779aSAndroid Build Coastguard Worker pitch[i - 2] = pitch[i];
598*15dc779aSAndroid Build Coastguard Worker pitch_gain[i - 2] = pitch_gain[i];
599*15dc779aSAndroid Build Coastguard Worker }
600*15dc779aSAndroid Build Coastguard Worker }
601*15dc779aSAndroid Build Coastguard Worker k++;
602*15dc779aSAndroid Build Coastguard Worker } else {
603*15dc779aSAndroid Build Coastguard Worker if (mode == 1) {
604*15dc779aSAndroid Build Coastguard Worker subfr_len = len_subfrm;
605*15dc779aSAndroid Build Coastguard Worker n_subfr = num_subfr;
606*15dc779aSAndroid Build Coastguard Worker } else if (mode == 2) {
607*15dc779aSAndroid Build Coastguard Worker subfr_len = len_subfrm << 1;
608*15dc779aSAndroid Build Coastguard Worker n_subfr = num_subfr_in_superfr / 2;
609*15dc779aSAndroid Build Coastguard Worker } else if (mode == 3) {
610*15dc779aSAndroid Build Coastguard Worker subfr_len = len_subfrm << 2;
611*15dc779aSAndroid Build Coastguard Worker n_subfr = num_subfr_in_superfr;
612*15dc779aSAndroid Build Coastguard Worker } else {
613*15dc779aSAndroid Build Coastguard Worker if (usac_data->frame_ok == 0) {
614*15dc779aSAndroid Build Coastguard Worker mode = 3;
615*15dc779aSAndroid Build Coastguard Worker subfr_len = len_subfrm << 2;
616*15dc779aSAndroid Build Coastguard Worker n_subfr = num_subfr_in_superfr;
617*15dc779aSAndroid Build Coastguard Worker }
618*15dc779aSAndroid Build Coastguard Worker }
619*15dc779aSAndroid Build Coastguard Worker
620*15dc779aSAndroid Build Coastguard Worker ixheaacd_lpc_coef_gen(st->lspold, lsp_curr, lp_flt_coff_a, n_subfr,
621*15dc779aSAndroid Build Coastguard Worker ORDER);
622*15dc779aSAndroid Build Coastguard Worker
623*15dc779aSAndroid Build Coastguard Worker err = ixheaacd_tcx_mdct(usac_data, pstr_td_frame_data, k, lp_flt_coff_a,
624*15dc779aSAndroid Build Coastguard Worker subfr_len, st);
625*15dc779aSAndroid Build Coastguard Worker if (err) return err;
626*15dc779aSAndroid Build Coastguard Worker if (usac_data->frame_ok == 1 && k == 2) {
627*15dc779aSAndroid Build Coastguard Worker memcpy(usac_data->lp_flt_coff_a_ec, &lp_flt_coff_a[k * (ORDER + 1)],
628*15dc779aSAndroid Build Coastguard Worker sizeof(usac_data->lp_flt_coff_a_ec));
629*15dc779aSAndroid Build Coastguard Worker }
630*15dc779aSAndroid Build Coastguard Worker k += (1 << (mode - 1));
631*15dc779aSAndroid Build Coastguard Worker }
632*15dc779aSAndroid Build Coastguard Worker
633*15dc779aSAndroid Build Coastguard Worker st->mode_prev = mode;
634*15dc779aSAndroid Build Coastguard Worker if (usac_data->frame_ok == 0) {
635*15dc779aSAndroid Build Coastguard Worker memcpy(usac_data->lspold_ec, st->lspold, sizeof(st->lspold));
636*15dc779aSAndroid Build Coastguard Worker }
637*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(lsp_curr, st->lspold, ORDER);
638*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(lsf_curr, st->lsf_prev, ORDER);
639*15dc779aSAndroid Build Coastguard Worker }
640*15dc779aSAndroid Build Coastguard Worker
641*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(xcitation_buff + len_fr, st->xcitation_prev,
642*15dc779aSAndroid Build Coastguard Worker MAX_PITCH + INTER_LP_FIL_ORDER + 1);
643*15dc779aSAndroid Build Coastguard Worker
644*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(synth_buf + len_fr, st->synth_prev, MAX_PITCH + synth_delay);
645*15dc779aSAndroid Build Coastguard Worker
646*15dc779aSAndroid Build Coastguard Worker if (!bpf_control_info) {
647*15dc779aSAndroid Build Coastguard Worker if (mod[0] != 0 && st->bpf_active_prev) {
648*15dc779aSAndroid Build Coastguard Worker for (i = 2; i < num_subfr_in_superfr; i++)
649*15dc779aSAndroid Build Coastguard Worker pitch_gain[num_subfr_by2 + i] = 0.0;
650*15dc779aSAndroid Build Coastguard Worker } else {
651*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < num_subfr_in_superfr; i++)
652*15dc779aSAndroid Build Coastguard Worker pitch_gain[num_subfr_by2 + i] = 0.0;
653*15dc779aSAndroid Build Coastguard Worker }
654*15dc779aSAndroid Build Coastguard Worker }
655*15dc779aSAndroid Build Coastguard Worker st->bpf_active_prev = bpf_control_info;
656*15dc779aSAndroid Build Coastguard Worker
657*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < num_subfr_by2; i++) {
658*15dc779aSAndroid Build Coastguard Worker st->pitch_prev[i] = pitch[num_subfr_in_superfr + i];
659*15dc779aSAndroid Build Coastguard Worker st->gain_prev[i] = pitch_gain[num_subfr_in_superfr + i];
660*15dc779aSAndroid Build Coastguard Worker }
661*15dc779aSAndroid Build Coastguard Worker
662*15dc779aSAndroid Build Coastguard Worker synth = synth_buf + MAX_PITCH;
663*15dc779aSAndroid Build Coastguard Worker
664*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < num_subfr_in_superfr; i++) {
665*15dc779aSAndroid Build Coastguard Worker tp = pitch[i];
666*15dc779aSAndroid Build Coastguard Worker gain = pitch_gain[i];
667*15dc779aSAndroid Build Coastguard Worker if (gain > 0.0f) {
668*15dc779aSAndroid Build Coastguard Worker synth_corr = 0.0f, synth_energy = 1e-6f;
669*15dc779aSAndroid Build Coastguard Worker if ((((i * LEN_SUBFR) + LEN_SUBFR) > LEN_SUPERFRAME) ||
670*15dc779aSAndroid Build Coastguard Worker ((((i * LEN_SUBFR) + LEN_SUBFR) - tp) > LEN_SUPERFRAME)) {
671*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag) {
672*15dc779aSAndroid Build Coastguard Worker tp = LEN_SUPERFRAME - LEN_SUBFR - (i * LEN_SUBFR);
673*15dc779aSAndroid Build Coastguard Worker } else
674*15dc779aSAndroid Build Coastguard Worker return -1;
675*15dc779aSAndroid Build Coastguard Worker }
676*15dc779aSAndroid Build Coastguard Worker for (k = 0; k < LEN_SUBFR; k++) {
677*15dc779aSAndroid Build Coastguard Worker synth_corr +=
678*15dc779aSAndroid Build Coastguard Worker synth[i * LEN_SUBFR + k] * synth[(i * LEN_SUBFR) - tp + k];
679*15dc779aSAndroid Build Coastguard Worker synth_energy +=
680*15dc779aSAndroid Build Coastguard Worker synth[(i * LEN_SUBFR) - tp + k] * synth[(i * LEN_SUBFR) - tp + k];
681*15dc779aSAndroid Build Coastguard Worker }
682*15dc779aSAndroid Build Coastguard Worker pitch_gain[i] = synth_corr / synth_energy;
683*15dc779aSAndroid Build Coastguard Worker }
684*15dc779aSAndroid Build Coastguard Worker }
685*15dc779aSAndroid Build Coastguard Worker
686*15dc779aSAndroid Build Coastguard Worker if (mod[3] == 0) {
687*15dc779aSAndroid Build Coastguard Worker err = ixheaacd_bass_post_filter(synth, pitch, pitch_gain, fsynth, len_fr, synth_delay,
688*15dc779aSAndroid Build Coastguard Worker st->bpf_prev, usac_data->ec_flag);
689*15dc779aSAndroid Build Coastguard Worker } else {
690*15dc779aSAndroid Build Coastguard Worker err = ixheaacd_bass_post_filter(synth, pitch, pitch_gain, fsynth, len_fr,
691*15dc779aSAndroid Build Coastguard Worker synth_delay - (len_subfrm / 2), st->bpf_prev,
692*15dc779aSAndroid Build Coastguard Worker usac_data->ec_flag);
693*15dc779aSAndroid Build Coastguard Worker }
694*15dc779aSAndroid Build Coastguard Worker if (err) return err;
695*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag && usac_data->frame_ok) {
696*15dc779aSAndroid Build Coastguard Worker memcpy(usac_data->lpc4_lsf, pstr_td_frame_data->lpc4_lsf, sizeof(usac_data->lpc4_lsf));
697*15dc779aSAndroid Build Coastguard Worker memcpy(usac_data->str_error_concealment[ch].lsf4, usac_data->lpc4_lsf,
698*15dc779aSAndroid Build Coastguard Worker sizeof(usac_data->lpc4_lsf));
699*15dc779aSAndroid Build Coastguard Worker memcpy(usac_data->lsf_adaptive_mean, pstr_td_frame_data->lsf_adaptive_mean_cand,
700*15dc779aSAndroid Build Coastguard Worker sizeof(usac_data->lsf_adaptive_mean));
701*15dc779aSAndroid Build Coastguard Worker }
702*15dc779aSAndroid Build Coastguard Worker return err;
703*15dc779aSAndroid Build Coastguard Worker }
704*15dc779aSAndroid Build Coastguard Worker
ixheaacd_lpd_dec_update(ia_usac_lpd_decoder_handle tddec,ia_usac_data_struct * usac_data,WORD32 i_ch)705*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_lpd_dec_update(ia_usac_lpd_decoder_handle tddec,
706*15dc779aSAndroid Build Coastguard Worker ia_usac_data_struct *usac_data, WORD32 i_ch) {
707*15dc779aSAndroid Build Coastguard Worker WORD32 i, k;
708*15dc779aSAndroid Build Coastguard Worker
709*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_overlap = &usac_data->overlap_data_ptr[i_ch][0];
710*15dc779aSAndroid Build Coastguard Worker WORD32 len_fr, lpd_sbf_len, lpd_delay, num_subfr_by2, synth_delay, fac_length;
711*15dc779aSAndroid Build Coastguard Worker
712*15dc779aSAndroid Build Coastguard Worker if (usac_data->tw_mdct[0])
713*15dc779aSAndroid Build Coastguard Worker ptr_overlap = &usac_data->overlap_data_ptr[i_ch][usac_data->ccfl / 2];
714*15dc779aSAndroid Build Coastguard Worker
715*15dc779aSAndroid Build Coastguard Worker len_fr = usac_data->ccfl;
716*15dc779aSAndroid Build Coastguard Worker lpd_sbf_len = (NUM_FRAMES * usac_data->num_subfrm) / 2;
717*15dc779aSAndroid Build Coastguard Worker lpd_delay = lpd_sbf_len * LEN_SUBFR;
718*15dc779aSAndroid Build Coastguard Worker num_subfr_by2 = lpd_sbf_len - 1;
719*15dc779aSAndroid Build Coastguard Worker synth_delay = num_subfr_by2 * LEN_SUBFR;
720*15dc779aSAndroid Build Coastguard Worker fac_length = (usac_data->len_subfrm) / 2;
721*15dc779aSAndroid Build Coastguard Worker
722*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < LEN_SUBFR + synth_delay; i++)
723*15dc779aSAndroid Build Coastguard Worker ptr_overlap[i] = (WORD32)(
724*15dc779aSAndroid Build Coastguard Worker (FLOAT32)tddec->synth_prev[MAX_PITCH - (LEN_SUBFR) + i] * 16384.0);
725*15dc779aSAndroid Build Coastguard Worker
726*15dc779aSAndroid Build Coastguard Worker ptr_overlap += LEN_SUBFR + synth_delay - fac_length;
727*15dc779aSAndroid Build Coastguard Worker
728*15dc779aSAndroid Build Coastguard Worker for (k = 0; k < 2 * fac_length; k++)
729*15dc779aSAndroid Build Coastguard Worker ptr_overlap[k] = (WORD32)((FLOAT32)tddec->exc_prev[k + 1] * 16384.0);
730*15dc779aSAndroid Build Coastguard Worker
731*15dc779aSAndroid Build Coastguard Worker ptr_overlap = &usac_data->overlap_data_ptr[i_ch][lpd_delay + fac_length];
732*15dc779aSAndroid Build Coastguard Worker
733*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < len_fr - lpd_delay - fac_length; i++) ptr_overlap[i] = 0;
734*15dc779aSAndroid Build Coastguard Worker
735*15dc779aSAndroid Build Coastguard Worker usac_data->window_shape[i_ch] = WIN_SEL_0;
736*15dc779aSAndroid Build Coastguard Worker usac_data->window_sequence_last[i_ch] = EIGHT_SHORT_SEQUENCE;
737*15dc779aSAndroid Build Coastguard Worker usac_data->td_frame_prev[i_ch] = 1;
738*15dc779aSAndroid Build Coastguard Worker
739*15dc779aSAndroid Build Coastguard Worker if (tddec->mode_prev == 0) {
740*15dc779aSAndroid Build Coastguard Worker memmove(usac_data->lpc_prev[i_ch], &tddec->lp_flt_coeff_a_prev[ORDER + 1],
741*15dc779aSAndroid Build Coastguard Worker (ORDER + 1) * sizeof(FLOAT32));
742*15dc779aSAndroid Build Coastguard Worker memmove(usac_data->acelp_in[i_ch], tddec->exc_prev,
743*15dc779aSAndroid Build Coastguard Worker (1 + (2 * FAC_LENGTH)) * sizeof(FLOAT32));
744*15dc779aSAndroid Build Coastguard Worker }
745*15dc779aSAndroid Build Coastguard Worker
746*15dc779aSAndroid Build Coastguard Worker return;
747*15dc779aSAndroid Build Coastguard Worker }
748*15dc779aSAndroid Build Coastguard Worker
ixheaacd_lpd_bpf_fix(ia_usac_data_struct * usac_data,WORD32 is_short_flag,FLOAT32 out_buffer[],ia_usac_lpd_decoder_handle st)749*15dc779aSAndroid Build Coastguard Worker WORD32 ixheaacd_lpd_bpf_fix(ia_usac_data_struct *usac_data,
750*15dc779aSAndroid Build Coastguard Worker WORD32 is_short_flag, FLOAT32 out_buffer[],
751*15dc779aSAndroid Build Coastguard Worker ia_usac_lpd_decoder_handle st) {
752*15dc779aSAndroid Build Coastguard Worker WORD32 i, tp, k;
753*15dc779aSAndroid Build Coastguard Worker float synth_buf[MAX_PITCH + SYNTH_DELAY_LMAX + LEN_SUPERFRAME];
754*15dc779aSAndroid Build Coastguard Worker float signal_out[LEN_SUPERFRAME];
755*15dc779aSAndroid Build Coastguard Worker float *synth, synth_corr, synth_energy;
756*15dc779aSAndroid Build Coastguard Worker WORD32 pitch[NUM_SUBFR_SUPERFRAME_BY2 + 3];
757*15dc779aSAndroid Build Coastguard Worker float pitch_gain[NUM_SUBFR_SUPERFRAME_BY2 + 3];
758*15dc779aSAndroid Build Coastguard Worker WORD32 len_fr, lpd_sbf_len, num_subfr_by2, synth_delay;
759*15dc779aSAndroid Build Coastguard Worker WORD32 err = 0;
760*15dc779aSAndroid Build Coastguard Worker
761*15dc779aSAndroid Build Coastguard Worker len_fr = usac_data->ccfl;
762*15dc779aSAndroid Build Coastguard Worker lpd_sbf_len = (NUM_FRAMES * usac_data->num_subfrm) / 2;
763*15dc779aSAndroid Build Coastguard Worker num_subfr_by2 = lpd_sbf_len - 1;
764*15dc779aSAndroid Build Coastguard Worker synth_delay = num_subfr_by2 * LEN_SUBFR;
765*15dc779aSAndroid Build Coastguard Worker
766*15dc779aSAndroid Build Coastguard Worker ixheaacd_memset(synth_buf, MAX_PITCH + synth_delay + len_fr);
767*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(st->synth_prev, synth_buf, MAX_PITCH + synth_delay);
768*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(out_buffer, synth_buf + MAX_PITCH - (LEN_SUBFR),
769*15dc779aSAndroid Build Coastguard Worker synth_delay + len_fr + (LEN_SUBFR));
770*15dc779aSAndroid Build Coastguard Worker
771*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < num_subfr_by2; i++) {
772*15dc779aSAndroid Build Coastguard Worker pitch[i] = st->pitch_prev[i];
773*15dc779aSAndroid Build Coastguard Worker pitch_gain[i] = st->gain_prev[i];
774*15dc779aSAndroid Build Coastguard Worker }
775*15dc779aSAndroid Build Coastguard Worker for (i = num_subfr_by2; i < lpd_sbf_len + 3; i++) {
776*15dc779aSAndroid Build Coastguard Worker pitch[i] = 64;
777*15dc779aSAndroid Build Coastguard Worker pitch_gain[i] = 0.0f;
778*15dc779aSAndroid Build Coastguard Worker }
779*15dc779aSAndroid Build Coastguard Worker if (st->mode_prev == 0) {
780*15dc779aSAndroid Build Coastguard Worker pitch[num_subfr_by2] = pitch[num_subfr_by2 - 1];
781*15dc779aSAndroid Build Coastguard Worker pitch_gain[num_subfr_by2] = pitch_gain[num_subfr_by2 - 1];
782*15dc779aSAndroid Build Coastguard Worker if (!is_short_flag) {
783*15dc779aSAndroid Build Coastguard Worker pitch[num_subfr_by2 + 1] = pitch[num_subfr_by2];
784*15dc779aSAndroid Build Coastguard Worker pitch_gain[num_subfr_by2 + 1] = pitch_gain[num_subfr_by2];
785*15dc779aSAndroid Build Coastguard Worker }
786*15dc779aSAndroid Build Coastguard Worker }
787*15dc779aSAndroid Build Coastguard Worker
788*15dc779aSAndroid Build Coastguard Worker synth = synth_buf + MAX_PITCH;
789*15dc779aSAndroid Build Coastguard Worker
790*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < num_subfr_by2 + 2; i++) {
791*15dc779aSAndroid Build Coastguard Worker tp = pitch[i];
792*15dc779aSAndroid Build Coastguard Worker if ((i * LEN_SUBFR + MAX_PITCH) < tp) {
793*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag == 0)
794*15dc779aSAndroid Build Coastguard Worker return -1;
795*15dc779aSAndroid Build Coastguard Worker else {
796*15dc779aSAndroid Build Coastguard Worker tp = MAX_PITCH - (i * LEN_SUBFR);
797*15dc779aSAndroid Build Coastguard Worker }
798*15dc779aSAndroid Build Coastguard Worker } else if (((i * LEN_SUBFR + MAX_PITCH - tp) >= 1883) ||
799*15dc779aSAndroid Build Coastguard Worker (((i * LEN_SUBFR) + LEN_SUBFR) > LEN_SUPERFRAME) ||
800*15dc779aSAndroid Build Coastguard Worker ((((i * LEN_SUBFR) + LEN_SUBFR) - tp) > LEN_SUPERFRAME)) {
801*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag == 0)
802*15dc779aSAndroid Build Coastguard Worker return -1;
803*15dc779aSAndroid Build Coastguard Worker else {
804*15dc779aSAndroid Build Coastguard Worker tp = (i * LEN_SUBFR + MAX_PITCH - 1882);
805*15dc779aSAndroid Build Coastguard Worker }
806*15dc779aSAndroid Build Coastguard Worker }
807*15dc779aSAndroid Build Coastguard Worker
808*15dc779aSAndroid Build Coastguard Worker if (pitch_gain[i] > 0.0f) {
809*15dc779aSAndroid Build Coastguard Worker synth_corr = 0.0f, synth_energy = 1e-6f;
810*15dc779aSAndroid Build Coastguard Worker for (k = 0; k < LEN_SUBFR; k++) {
811*15dc779aSAndroid Build Coastguard Worker synth_corr +=
812*15dc779aSAndroid Build Coastguard Worker synth[i * LEN_SUBFR + k] * synth[(i * LEN_SUBFR) - tp + k];
813*15dc779aSAndroid Build Coastguard Worker synth_energy +=
814*15dc779aSAndroid Build Coastguard Worker synth[(i * LEN_SUBFR) - tp + k] * synth[(i * LEN_SUBFR) - tp + k];
815*15dc779aSAndroid Build Coastguard Worker }
816*15dc779aSAndroid Build Coastguard Worker pitch_gain[i] = synth_corr / synth_energy;
817*15dc779aSAndroid Build Coastguard Worker }
818*15dc779aSAndroid Build Coastguard Worker }
819*15dc779aSAndroid Build Coastguard Worker
820*15dc779aSAndroid Build Coastguard Worker err = ixheaacd_bass_post_filter(
821*15dc779aSAndroid Build Coastguard Worker synth, pitch, pitch_gain, signal_out, (lpd_sbf_len + 2) * LEN_SUBFR + LEN_SUBFR,
822*15dc779aSAndroid Build Coastguard Worker len_fr - (lpd_sbf_len + 4) * LEN_SUBFR, st->bpf_prev, usac_data->ec_flag);
823*15dc779aSAndroid Build Coastguard Worker if (err != 0) return err;
824*15dc779aSAndroid Build Coastguard Worker
825*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(signal_out, out_buffer,
826*15dc779aSAndroid Build Coastguard Worker (lpd_sbf_len + 2) * LEN_SUBFR + LEN_SUBFR);
827*15dc779aSAndroid Build Coastguard Worker return err;
828*15dc779aSAndroid Build Coastguard Worker }
829