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 <float.h>
21*15dc779aSAndroid Build Coastguard Worker #include <stdlib.h>
22*15dc779aSAndroid Build Coastguard Worker #include <stdio.h>
23*15dc779aSAndroid Build Coastguard Worker #include <math.h>
24*15dc779aSAndroid Build Coastguard Worker #include <string.h>
25*15dc779aSAndroid Build Coastguard Worker
26*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
27*15dc779aSAndroid Build Coastguard Worker
28*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_bitbuffer.h"
29*15dc779aSAndroid Build Coastguard Worker
30*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_interface.h"
31*15dc779aSAndroid Build Coastguard Worker
32*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_tns_usac.h"
33*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_cnst.h"
34*15dc779aSAndroid Build Coastguard Worker
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_acelp_info.h"
36*15dc779aSAndroid Build Coastguard Worker
37*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_td_mdct.h"
38*15dc779aSAndroid Build Coastguard Worker
39*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecsettings.h"
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_info.h"
41*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_common.h"
42*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_data_struct.h"
43*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_dec.h"
44*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecoder.h"
45*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_mps_polyphase.h"
46*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_sbr_const.h"
47*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_defines.h"
48*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_struct_def.h"
49*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_main.h"
50*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_arith_dec.h"
51*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_func_def.h"
52*15dc779aSAndroid Build Coastguard Worker
53*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_acelp_com.h"
54*15dc779aSAndroid Build Coastguard Worker
55*15dc779aSAndroid Build Coastguard Worker #define F_PIT_SHARP 0.85F
56*15dc779aSAndroid Build Coastguard Worker #define MEAN_ENER 30
57*15dc779aSAndroid Build Coastguard Worker
58*15dc779aSAndroid Build Coastguard Worker extern const FLOAT32 ixheaacd_interpol_filt[INTER_LP_FIL_LEN];
59*15dc779aSAndroid Build Coastguard Worker
ixheaacd_acelp_pitch_sharpening(FLOAT32 * x,WORD32 pit_lag)60*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_acelp_pitch_sharpening(FLOAT32 *x, WORD32 pit_lag) {
61*15dc779aSAndroid Build Coastguard Worker WORD32 i;
62*15dc779aSAndroid Build Coastguard Worker for (i = pit_lag; i < LEN_SUBFR; i++) {
63*15dc779aSAndroid Build Coastguard Worker x[i] += x[i - pit_lag] * F_PIT_SHARP;
64*15dc779aSAndroid Build Coastguard Worker }
65*15dc779aSAndroid Build Coastguard Worker return;
66*15dc779aSAndroid Build Coastguard Worker }
67*15dc779aSAndroid Build Coastguard Worker
ixheaacd_acelp_decode_1sp_per_track(WORD32 idx_1p,WORD32 M,WORD32 ixheaacd_drc_offset,WORD32 track,FLOAT32 code_vec[])68*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_acelp_decode_1sp_per_track(WORD32 idx_1p, WORD32 M,
69*15dc779aSAndroid Build Coastguard Worker WORD32 ixheaacd_drc_offset,
70*15dc779aSAndroid Build Coastguard Worker WORD32 track,
71*15dc779aSAndroid Build Coastguard Worker FLOAT32 code_vec[]) {
72*15dc779aSAndroid Build Coastguard Worker WORD32 sign_index, mask, m;
73*15dc779aSAndroid Build Coastguard Worker WORD32 sp_pos;
74*15dc779aSAndroid Build Coastguard Worker mask = ((1 << M) - 1);
75*15dc779aSAndroid Build Coastguard Worker
76*15dc779aSAndroid Build Coastguard Worker sp_pos = (idx_1p & mask) + ixheaacd_drc_offset;
77*15dc779aSAndroid Build Coastguard Worker sign_index = ((idx_1p >> M) & 1);
78*15dc779aSAndroid Build Coastguard Worker
79*15dc779aSAndroid Build Coastguard Worker m = (sp_pos << 2) + track;
80*15dc779aSAndroid Build Coastguard Worker if (sign_index == 1)
81*15dc779aSAndroid Build Coastguard Worker code_vec[m] = (code_vec[m] - 1.0f);
82*15dc779aSAndroid Build Coastguard Worker else
83*15dc779aSAndroid Build Coastguard Worker code_vec[m] = (code_vec[m] + 1.0f);
84*15dc779aSAndroid Build Coastguard Worker
85*15dc779aSAndroid Build Coastguard Worker return;
86*15dc779aSAndroid Build Coastguard Worker }
87*15dc779aSAndroid Build Coastguard Worker
ixheaacd_acelp_decode_2sp_per_track(WORD32 idx_2p,WORD32 M,WORD32 ixheaacd_drc_offset,WORD32 track,FLOAT32 code_vec[])88*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_acelp_decode_2sp_per_track(WORD32 idx_2p, WORD32 M,
89*15dc779aSAndroid Build Coastguard Worker WORD32 ixheaacd_drc_offset,
90*15dc779aSAndroid Build Coastguard Worker WORD32 track,
91*15dc779aSAndroid Build Coastguard Worker FLOAT32 code_vec[]) {
92*15dc779aSAndroid Build Coastguard Worker WORD32 sign_index;
93*15dc779aSAndroid Build Coastguard Worker WORD32 mask, m0, m1;
94*15dc779aSAndroid Build Coastguard Worker WORD32 sp_pos[2];
95*15dc779aSAndroid Build Coastguard Worker mask = ((1 << M) - 1);
96*15dc779aSAndroid Build Coastguard Worker
97*15dc779aSAndroid Build Coastguard Worker sp_pos[0] = (((idx_2p >> M) & mask) + ixheaacd_drc_offset);
98*15dc779aSAndroid Build Coastguard Worker sp_pos[1] = ((idx_2p & mask) + ixheaacd_drc_offset);
99*15dc779aSAndroid Build Coastguard Worker
100*15dc779aSAndroid Build Coastguard Worker sign_index = (idx_2p >> 2 * M) & 1;
101*15dc779aSAndroid Build Coastguard Worker
102*15dc779aSAndroid Build Coastguard Worker m0 = (sp_pos[0] << 2) + track;
103*15dc779aSAndroid Build Coastguard Worker m1 = (sp_pos[1] << 2) + track;
104*15dc779aSAndroid Build Coastguard Worker
105*15dc779aSAndroid Build Coastguard Worker if ((sp_pos[1] - sp_pos[0]) < 0) {
106*15dc779aSAndroid Build Coastguard Worker if (sign_index == 1) {
107*15dc779aSAndroid Build Coastguard Worker code_vec[m0] = (code_vec[m0] - 1.0f);
108*15dc779aSAndroid Build Coastguard Worker code_vec[m1] = (code_vec[m1] + 1.0f);
109*15dc779aSAndroid Build Coastguard Worker } else {
110*15dc779aSAndroid Build Coastguard Worker code_vec[m0] = (code_vec[m0] + 1.0f);
111*15dc779aSAndroid Build Coastguard Worker code_vec[m1] = (code_vec[m1] - 1.0f);
112*15dc779aSAndroid Build Coastguard Worker }
113*15dc779aSAndroid Build Coastguard Worker } else {
114*15dc779aSAndroid Build Coastguard Worker if (sign_index == 1) {
115*15dc779aSAndroid Build Coastguard Worker code_vec[m0] = (code_vec[m0] - 1.0f);
116*15dc779aSAndroid Build Coastguard Worker code_vec[m1] = (code_vec[m1] - 1.0f);
117*15dc779aSAndroid Build Coastguard Worker } else {
118*15dc779aSAndroid Build Coastguard Worker code_vec[m0] = (code_vec[m0] + 1.0f);
119*15dc779aSAndroid Build Coastguard Worker code_vec[m1] = (code_vec[m1] + 1.0f);
120*15dc779aSAndroid Build Coastguard Worker }
121*15dc779aSAndroid Build Coastguard Worker }
122*15dc779aSAndroid Build Coastguard Worker return;
123*15dc779aSAndroid Build Coastguard Worker }
124*15dc779aSAndroid Build Coastguard Worker
ixheaacd_acelp_decode_3sp_per_track(WORD32 idx_3p,WORD32 M,WORD32 ixheaacd_drc_offset,WORD32 track,FLOAT32 code_vec[])125*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_acelp_decode_3sp_per_track(WORD32 idx_3p, WORD32 M,
126*15dc779aSAndroid Build Coastguard Worker WORD32 ixheaacd_drc_offset,
127*15dc779aSAndroid Build Coastguard Worker WORD32 track,
128*15dc779aSAndroid Build Coastguard Worker FLOAT32 code_vec[]) {
129*15dc779aSAndroid Build Coastguard Worker WORD32 j, mask, idx_2p, idx_1p;
130*15dc779aSAndroid Build Coastguard Worker
131*15dc779aSAndroid Build Coastguard Worker mask = ((1 << (2 * M - 1)) - 1);
132*15dc779aSAndroid Build Coastguard Worker idx_2p = idx_3p & mask;
133*15dc779aSAndroid Build Coastguard Worker j = ixheaacd_drc_offset;
134*15dc779aSAndroid Build Coastguard Worker if (((idx_3p >> ((2 * M) - 1)) & 1) == 1) {
135*15dc779aSAndroid Build Coastguard Worker j += (1 << (M - 1));
136*15dc779aSAndroid Build Coastguard Worker }
137*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_2sp_per_track(idx_2p, M - 1, j, track, code_vec);
138*15dc779aSAndroid Build Coastguard Worker mask = ((1 << (M + 1)) - 1);
139*15dc779aSAndroid Build Coastguard Worker idx_1p = (idx_3p >> 2 * M) & mask;
140*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_1sp_per_track(idx_1p, M, ixheaacd_drc_offset, track,
141*15dc779aSAndroid Build Coastguard Worker code_vec);
142*15dc779aSAndroid Build Coastguard Worker return;
143*15dc779aSAndroid Build Coastguard Worker }
144*15dc779aSAndroid Build Coastguard Worker
ixheaacd_d_acelp_decode_4sp_per_track_section(WORD32 index,WORD32 ixheaacd_drc_offset,WORD32 track,FLOAT32 code_vec[])145*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_d_acelp_decode_4sp_per_track_section(
146*15dc779aSAndroid Build Coastguard Worker WORD32 index, WORD32 ixheaacd_drc_offset, WORD32 track,
147*15dc779aSAndroid Build Coastguard Worker FLOAT32 code_vec[]) {
148*15dc779aSAndroid Build Coastguard Worker WORD32 j, idx_2p;
149*15dc779aSAndroid Build Coastguard Worker
150*15dc779aSAndroid Build Coastguard Worker idx_2p = index & 31;
151*15dc779aSAndroid Build Coastguard Worker j = ixheaacd_drc_offset;
152*15dc779aSAndroid Build Coastguard Worker if (((index >> 5) & 1) == 1) {
153*15dc779aSAndroid Build Coastguard Worker j += 4;
154*15dc779aSAndroid Build Coastguard Worker }
155*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_2sp_per_track(idx_2p, 2, j, track, code_vec);
156*15dc779aSAndroid Build Coastguard Worker idx_2p = (index >> 6) & 127;
157*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_2sp_per_track(idx_2p, 3, ixheaacd_drc_offset, track,
158*15dc779aSAndroid Build Coastguard Worker code_vec);
159*15dc779aSAndroid Build Coastguard Worker return;
160*15dc779aSAndroid Build Coastguard Worker }
161*15dc779aSAndroid Build Coastguard Worker
ixheaacd_acelp_decode_4sp_per_track(WORD32 idx_4p,WORD32 track,FLOAT32 code_vec[])162*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_acelp_decode_4sp_per_track(WORD32 idx_4p, WORD32 track,
163*15dc779aSAndroid Build Coastguard Worker FLOAT32 code_vec[]) {
164*15dc779aSAndroid Build Coastguard Worker WORD32 idx_1p, idx_2p, idx_3p;
165*15dc779aSAndroid Build Coastguard Worker
166*15dc779aSAndroid Build Coastguard Worker switch ((idx_4p >> 14) & 3) {
167*15dc779aSAndroid Build Coastguard Worker case 0:
168*15dc779aSAndroid Build Coastguard Worker if (((idx_4p >> 13) & 1) == 0)
169*15dc779aSAndroid Build Coastguard Worker ixheaacd_d_acelp_decode_4sp_per_track_section(idx_4p, 0, track,
170*15dc779aSAndroid Build Coastguard Worker code_vec);
171*15dc779aSAndroid Build Coastguard Worker else
172*15dc779aSAndroid Build Coastguard Worker ixheaacd_d_acelp_decode_4sp_per_track_section(idx_4p, 8, track,
173*15dc779aSAndroid Build Coastguard Worker code_vec);
174*15dc779aSAndroid Build Coastguard Worker break;
175*15dc779aSAndroid Build Coastguard Worker case 1:
176*15dc779aSAndroid Build Coastguard Worker idx_1p = idx_4p >> 10;
177*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_1sp_per_track(idx_1p, 3, 0, track, code_vec);
178*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_3sp_per_track(idx_4p, 3, 8, track, code_vec);
179*15dc779aSAndroid Build Coastguard Worker break;
180*15dc779aSAndroid Build Coastguard Worker case 2:
181*15dc779aSAndroid Build Coastguard Worker idx_2p = idx_4p >> 7;
182*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_2sp_per_track(idx_2p, 3, 0, track, code_vec);
183*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_2sp_per_track(idx_4p, 3, 8, track, code_vec);
184*15dc779aSAndroid Build Coastguard Worker break;
185*15dc779aSAndroid Build Coastguard Worker case 3:
186*15dc779aSAndroid Build Coastguard Worker idx_3p = idx_4p >> 4;
187*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_3sp_per_track(idx_3p, 3, 0, track, code_vec);
188*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_1sp_per_track(idx_4p, 3, 8, track, code_vec);
189*15dc779aSAndroid Build Coastguard Worker break;
190*15dc779aSAndroid Build Coastguard Worker }
191*15dc779aSAndroid Build Coastguard Worker return;
192*15dc779aSAndroid Build Coastguard Worker }
193*15dc779aSAndroid Build Coastguard Worker
ixheaacd_d_acelp_add_pulse(WORD32 pos[],WORD32 nb_pulse,WORD32 track,FLOAT32 code[])194*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_d_acelp_add_pulse(WORD32 pos[], WORD32 nb_pulse,
195*15dc779aSAndroid Build Coastguard Worker WORD32 track, FLOAT32 code[]) {
196*15dc779aSAndroid Build Coastguard Worker WORD32 i, k;
197*15dc779aSAndroid Build Coastguard Worker for (k = 0; k < nb_pulse; k++) {
198*15dc779aSAndroid Build Coastguard Worker i = ((pos[k] & (16 - 1)) << 2) + track;
199*15dc779aSAndroid Build Coastguard Worker if ((pos[k] & 16) == 0) {
200*15dc779aSAndroid Build Coastguard Worker code[i] = (WORD16)(code[i] + 1.0f);
201*15dc779aSAndroid Build Coastguard Worker } else {
202*15dc779aSAndroid Build Coastguard Worker code[i] = (WORD16)(code[i] - 1.0f);
203*15dc779aSAndroid Build Coastguard Worker }
204*15dc779aSAndroid Build Coastguard Worker }
205*15dc779aSAndroid Build Coastguard Worker return;
206*15dc779aSAndroid Build Coastguard Worker }
207*15dc779aSAndroid Build Coastguard Worker
ixheaacd_d_acelp_decode_1p_n1(WORD32 index,WORD32 N,WORD32 ixheaacd_drc_offset,WORD32 pos[])208*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_d_acelp_decode_1p_n1(WORD32 index, WORD32 N,
209*15dc779aSAndroid Build Coastguard Worker WORD32 ixheaacd_drc_offset,
210*15dc779aSAndroid Build Coastguard Worker WORD32 pos[]) {
211*15dc779aSAndroid Build Coastguard Worker WORD32 i, pos1, mask;
212*15dc779aSAndroid Build Coastguard Worker mask = ((1 << N) - 1);
213*15dc779aSAndroid Build Coastguard Worker
214*15dc779aSAndroid Build Coastguard Worker pos1 = ((index & mask) + ixheaacd_drc_offset);
215*15dc779aSAndroid Build Coastguard Worker i = ((index >> N) & 1);
216*15dc779aSAndroid Build Coastguard Worker if (i == 1) {
217*15dc779aSAndroid Build Coastguard Worker pos1 += 16;
218*15dc779aSAndroid Build Coastguard Worker }
219*15dc779aSAndroid Build Coastguard Worker pos[0] = pos1;
220*15dc779aSAndroid Build Coastguard Worker return;
221*15dc779aSAndroid Build Coastguard Worker }
222*15dc779aSAndroid Build Coastguard Worker
ixheaacd_acelp_decode_pulses_per_track(WORD32 cb_index[],const WORD16 code_bits,FLOAT32 code_vec[])223*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_acelp_decode_pulses_per_track(WORD32 cb_index[],
224*15dc779aSAndroid Build Coastguard Worker const WORD16 code_bits,
225*15dc779aSAndroid Build Coastguard Worker FLOAT32 code_vec[]) {
226*15dc779aSAndroid Build Coastguard Worker WORD32 track_idx, index, ixheaacd_drc_offset, pos[6], i;
227*15dc779aSAndroid Build Coastguard Worker memset(code_vec, 0, 64 * sizeof(FLOAT32));
228*15dc779aSAndroid Build Coastguard Worker
229*15dc779aSAndroid Build Coastguard Worker if (code_bits == 12) {
230*15dc779aSAndroid Build Coastguard Worker for (track_idx = 0; track_idx < 4; track_idx += 2) {
231*15dc779aSAndroid Build Coastguard Worker ixheaacd_drc_offset = cb_index[2 * (track_idx / 2)];
232*15dc779aSAndroid Build Coastguard Worker index = cb_index[2 * (track_idx / 2) + 1];
233*15dc779aSAndroid Build Coastguard Worker ixheaacd_d_acelp_decode_1p_n1(index, 4, 0, pos);
234*15dc779aSAndroid Build Coastguard Worker ixheaacd_d_acelp_add_pulse(
235*15dc779aSAndroid Build Coastguard Worker pos, 1, 2 * ixheaacd_drc_offset + track_idx / 2, code_vec);
236*15dc779aSAndroid Build Coastguard Worker }
237*15dc779aSAndroid Build Coastguard Worker } else if (code_bits == 16) {
238*15dc779aSAndroid Build Coastguard Worker i = 0;
239*15dc779aSAndroid Build Coastguard Worker ixheaacd_drc_offset = cb_index[i++];
240*15dc779aSAndroid Build Coastguard Worker ixheaacd_drc_offset = (ixheaacd_drc_offset == 0) ? 1 : 3;
241*15dc779aSAndroid Build Coastguard Worker for (track_idx = 0; track_idx < 4; track_idx++) {
242*15dc779aSAndroid Build Coastguard Worker if (track_idx != ixheaacd_drc_offset) {
243*15dc779aSAndroid Build Coastguard Worker index = cb_index[i++];
244*15dc779aSAndroid Build Coastguard Worker ixheaacd_d_acelp_decode_1p_n1(index, 4, 0, pos);
245*15dc779aSAndroid Build Coastguard Worker ixheaacd_d_acelp_add_pulse(pos, 1, track_idx, code_vec);
246*15dc779aSAndroid Build Coastguard Worker }
247*15dc779aSAndroid Build Coastguard Worker }
248*15dc779aSAndroid Build Coastguard Worker } else if (code_bits == 20) {
249*15dc779aSAndroid Build Coastguard Worker for (track_idx = 0; track_idx < 4; track_idx++) {
250*15dc779aSAndroid Build Coastguard Worker index = cb_index[track_idx];
251*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_1sp_per_track(index, 4, 0, track_idx, code_vec);
252*15dc779aSAndroid Build Coastguard Worker }
253*15dc779aSAndroid Build Coastguard Worker } else if (code_bits == 28) {
254*15dc779aSAndroid Build Coastguard Worker for (track_idx = 0; track_idx < 2; track_idx++) {
255*15dc779aSAndroid Build Coastguard Worker index = cb_index[track_idx];
256*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_2sp_per_track(index, 4, 0, track_idx, code_vec);
257*15dc779aSAndroid Build Coastguard Worker }
258*15dc779aSAndroid Build Coastguard Worker for (track_idx = 2; track_idx < 4; track_idx++) {
259*15dc779aSAndroid Build Coastguard Worker index = cb_index[track_idx];
260*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_1sp_per_track(index, 4, 0, track_idx, code_vec);
261*15dc779aSAndroid Build Coastguard Worker }
262*15dc779aSAndroid Build Coastguard Worker } else if (code_bits == 36) {
263*15dc779aSAndroid Build Coastguard Worker for (track_idx = 0; track_idx < 4; track_idx++) {
264*15dc779aSAndroid Build Coastguard Worker index = cb_index[track_idx];
265*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_2sp_per_track(index, 4, 0, track_idx, code_vec);
266*15dc779aSAndroid Build Coastguard Worker }
267*15dc779aSAndroid Build Coastguard Worker } else if (code_bits == 44) {
268*15dc779aSAndroid Build Coastguard Worker for (track_idx = 0; track_idx < 2; track_idx++) {
269*15dc779aSAndroid Build Coastguard Worker index = cb_index[track_idx];
270*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_3sp_per_track(index, 4, 0, track_idx, code_vec);
271*15dc779aSAndroid Build Coastguard Worker }
272*15dc779aSAndroid Build Coastguard Worker for (track_idx = 2; track_idx < 4; track_idx++) {
273*15dc779aSAndroid Build Coastguard Worker index = cb_index[track_idx];
274*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_2sp_per_track(index, 4, 0, track_idx, code_vec);
275*15dc779aSAndroid Build Coastguard Worker }
276*15dc779aSAndroid Build Coastguard Worker } else if (code_bits == 52) {
277*15dc779aSAndroid Build Coastguard Worker for (track_idx = 0; track_idx < 4; track_idx++) {
278*15dc779aSAndroid Build Coastguard Worker index = cb_index[track_idx];
279*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_3sp_per_track(index, 4, 0, track_idx, code_vec);
280*15dc779aSAndroid Build Coastguard Worker }
281*15dc779aSAndroid Build Coastguard Worker } else if (code_bits == 64) {
282*15dc779aSAndroid Build Coastguard Worker for (track_idx = 0; track_idx < 4; track_idx++) {
283*15dc779aSAndroid Build Coastguard Worker index = ((cb_index[track_idx] << 14) + cb_index[track_idx + 4]);
284*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_4sp_per_track(index, track_idx, code_vec);
285*15dc779aSAndroid Build Coastguard Worker }
286*15dc779aSAndroid Build Coastguard Worker }
287*15dc779aSAndroid Build Coastguard Worker return;
288*15dc779aSAndroid Build Coastguard Worker }
289*15dc779aSAndroid Build Coastguard Worker
ixheaacd_acelp_decode_gains(WORD32 index,FLOAT32 code_vec[],FLOAT32 * pitch_gain,FLOAT32 * codebook_gain,FLOAT32 mean_exc_energy,FLOAT32 * energy)290*15dc779aSAndroid Build Coastguard Worker static void ixheaacd_acelp_decode_gains(WORD32 index, FLOAT32 code_vec[],
291*15dc779aSAndroid Build Coastguard Worker FLOAT32 *pitch_gain,
292*15dc779aSAndroid Build Coastguard Worker FLOAT32 *codebook_gain,
293*15dc779aSAndroid Build Coastguard Worker FLOAT32 mean_exc_energy,
294*15dc779aSAndroid Build Coastguard Worker FLOAT32 *energy) {
295*15dc779aSAndroid Build Coastguard Worker WORD32 i;
296*15dc779aSAndroid Build Coastguard Worker FLOAT32 avg_innov_energy, est_gain;
297*15dc779aSAndroid Build Coastguard Worker const FLOAT32 *gain_table = ixheaacd_int_leave_gain_table;
298*15dc779aSAndroid Build Coastguard Worker
299*15dc779aSAndroid Build Coastguard Worker avg_innov_energy = 0.01f;
300*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < LEN_SUBFR; i++) {
301*15dc779aSAndroid Build Coastguard Worker avg_innov_energy += code_vec[i] * code_vec[i];
302*15dc779aSAndroid Build Coastguard Worker }
303*15dc779aSAndroid Build Coastguard Worker *energy = avg_innov_energy;
304*15dc779aSAndroid Build Coastguard Worker
305*15dc779aSAndroid Build Coastguard Worker avg_innov_energy =
306*15dc779aSAndroid Build Coastguard Worker (FLOAT32)(10.0 * log10(avg_innov_energy / (FLOAT32)LEN_SUBFR));
307*15dc779aSAndroid Build Coastguard Worker
308*15dc779aSAndroid Build Coastguard Worker est_gain = mean_exc_energy - avg_innov_energy;
309*15dc779aSAndroid Build Coastguard Worker
310*15dc779aSAndroid Build Coastguard Worker est_gain = (FLOAT32)pow(10.0, 0.05 * est_gain);
311*15dc779aSAndroid Build Coastguard Worker *pitch_gain = gain_table[index * 2];
312*15dc779aSAndroid Build Coastguard Worker
313*15dc779aSAndroid Build Coastguard Worker *codebook_gain = gain_table[index * 2 + 1] * est_gain;
314*15dc779aSAndroid Build Coastguard Worker
315*15dc779aSAndroid Build Coastguard Worker return;
316*15dc779aSAndroid Build Coastguard Worker }
317*15dc779aSAndroid Build Coastguard Worker
ixheaacd_acelp_decode_gains_with_ec(WORD32 index,FLOAT32 code_vec[],FLOAT32 * pitch_gain,FLOAT32 * codebook_gain,FLOAT32 mean_exc_energy,FLOAT32 * energy,FLOAT32 * past_pitch_gain,FLOAT32 * past_gain_code,WORD32 bfi)318*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_acelp_decode_gains_with_ec(WORD32 index, FLOAT32 code_vec[],
319*15dc779aSAndroid Build Coastguard Worker FLOAT32 *pitch_gain, FLOAT32 *codebook_gain,
320*15dc779aSAndroid Build Coastguard Worker FLOAT32 mean_exc_energy, FLOAT32 *energy,
321*15dc779aSAndroid Build Coastguard Worker FLOAT32 *past_pitch_gain, FLOAT32 *past_gain_code,
322*15dc779aSAndroid Build Coastguard Worker WORD32 bfi) {
323*15dc779aSAndroid Build Coastguard Worker WORD32 i;
324*15dc779aSAndroid Build Coastguard Worker FLOAT32 avg_innov_energy, est_gain, gain_inov;
325*15dc779aSAndroid Build Coastguard Worker const FLOAT32 *gain_table = ixheaacd_int_leave_gain_table;
326*15dc779aSAndroid Build Coastguard Worker
327*15dc779aSAndroid Build Coastguard Worker avg_innov_energy = 0.01f;
328*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < LEN_SUBFR; i++) {
329*15dc779aSAndroid Build Coastguard Worker avg_innov_energy += code_vec[i] * code_vec[i];
330*15dc779aSAndroid Build Coastguard Worker }
331*15dc779aSAndroid Build Coastguard Worker *energy = avg_innov_energy;
332*15dc779aSAndroid Build Coastguard Worker gain_inov = (FLOAT32)(1 / sqrt(avg_innov_energy / LEN_SUBFR));
333*15dc779aSAndroid Build Coastguard Worker
334*15dc779aSAndroid Build Coastguard Worker if (bfi) {
335*15dc779aSAndroid Build Coastguard Worker FLOAT32 tgpit = (*past_pitch_gain);
336*15dc779aSAndroid Build Coastguard Worker
337*15dc779aSAndroid Build Coastguard Worker if (tgpit > 0.95f) {
338*15dc779aSAndroid Build Coastguard Worker tgpit = 0.95f;
339*15dc779aSAndroid Build Coastguard Worker } else if (tgpit < 0.5f) {
340*15dc779aSAndroid Build Coastguard Worker tgpit = 0.5f;
341*15dc779aSAndroid Build Coastguard Worker }
342*15dc779aSAndroid Build Coastguard Worker *pitch_gain = (FLOAT32)tgpit;
343*15dc779aSAndroid Build Coastguard Worker tgpit = tgpit * 0.95f;
344*15dc779aSAndroid Build Coastguard Worker *past_pitch_gain = (FLOAT32)tgpit;
345*15dc779aSAndroid Build Coastguard Worker
346*15dc779aSAndroid Build Coastguard Worker tgpit = 1.4f - tgpit;
347*15dc779aSAndroid Build Coastguard Worker tgpit = *past_gain_code * tgpit;
348*15dc779aSAndroid Build Coastguard Worker *codebook_gain = tgpit * gain_inov;
349*15dc779aSAndroid Build Coastguard Worker
350*15dc779aSAndroid Build Coastguard Worker *past_gain_code = tgpit;
351*15dc779aSAndroid Build Coastguard Worker return;
352*15dc779aSAndroid Build Coastguard Worker }
353*15dc779aSAndroid Build Coastguard Worker
354*15dc779aSAndroid Build Coastguard Worker avg_innov_energy = (FLOAT32)(10.0 * log10(avg_innov_energy / (FLOAT32)LEN_SUBFR));
355*15dc779aSAndroid Build Coastguard Worker est_gain = mean_exc_energy - avg_innov_energy;
356*15dc779aSAndroid Build Coastguard Worker
357*15dc779aSAndroid Build Coastguard Worker est_gain = (FLOAT32)pow(10.0, 0.05 * est_gain);
358*15dc779aSAndroid Build Coastguard Worker if (!bfi) {
359*15dc779aSAndroid Build Coastguard Worker *pitch_gain = gain_table[index * 2];
360*15dc779aSAndroid Build Coastguard Worker *past_pitch_gain = *pitch_gain;
361*15dc779aSAndroid Build Coastguard Worker }
362*15dc779aSAndroid Build Coastguard Worker
363*15dc779aSAndroid Build Coastguard Worker *codebook_gain = gain_table[index * 2 + 1] * est_gain;
364*15dc779aSAndroid Build Coastguard Worker *past_gain_code = (*codebook_gain) / gain_inov;
365*15dc779aSAndroid Build Coastguard Worker
366*15dc779aSAndroid Build Coastguard Worker return;
367*15dc779aSAndroid Build Coastguard Worker }
368*15dc779aSAndroid Build Coastguard Worker
ixheaacd_cb_exc_calc(FLOAT32 xcitation_curr[],WORD32 pitch_lag,WORD32 frac)369*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_cb_exc_calc(FLOAT32 xcitation_curr[], WORD32 pitch_lag,
370*15dc779aSAndroid Build Coastguard Worker WORD32 frac) {
371*15dc779aSAndroid Build Coastguard Worker WORD32 i, j;
372*15dc779aSAndroid Build Coastguard Worker FLOAT32 s, *x0, *x1, *x2;
373*15dc779aSAndroid Build Coastguard Worker const FLOAT32 *c1, *c2;
374*15dc779aSAndroid Build Coastguard Worker
375*15dc779aSAndroid Build Coastguard Worker x0 = &xcitation_curr[-pitch_lag];
376*15dc779aSAndroid Build Coastguard Worker frac = -frac;
377*15dc779aSAndroid Build Coastguard Worker if (frac < 0) {
378*15dc779aSAndroid Build Coastguard Worker frac += UP_SAMP;
379*15dc779aSAndroid Build Coastguard Worker x0--;
380*15dc779aSAndroid Build Coastguard Worker }
381*15dc779aSAndroid Build Coastguard Worker for (j = 0; j < LEN_SUBFR + 1; j++) {
382*15dc779aSAndroid Build Coastguard Worker x1 = x0++;
383*15dc779aSAndroid Build Coastguard Worker x2 = x1 + 1;
384*15dc779aSAndroid Build Coastguard Worker c1 = &ixheaacd_interpol_filt[frac];
385*15dc779aSAndroid Build Coastguard Worker c2 = &ixheaacd_interpol_filt[UP_SAMP - frac];
386*15dc779aSAndroid Build Coastguard Worker s = 0.0;
387*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < INTER_LP_FIL_ORDER; i++, c1 += UP_SAMP, c2 += UP_SAMP) {
388*15dc779aSAndroid Build Coastguard Worker s += (*x1--) * (*c1) + (*x2++) * (*c2);
389*15dc779aSAndroid Build Coastguard Worker }
390*15dc779aSAndroid Build Coastguard Worker xcitation_curr[j] = s;
391*15dc779aSAndroid Build Coastguard Worker }
392*15dc779aSAndroid Build Coastguard Worker return;
393*15dc779aSAndroid Build Coastguard Worker }
394*15dc779aSAndroid Build Coastguard Worker
ixheaacd_acelp_alias_cnx(ia_usac_data_struct * usac_data,ia_td_frame_data_struct * pstr_td_frame_data,WORD32 k,FLOAT32 lp_filt_coeff[],FLOAT32 stability_factor,ia_usac_lpd_decoder_handle st)395*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_acelp_alias_cnx(ia_usac_data_struct *usac_data,
396*15dc779aSAndroid Build Coastguard Worker ia_td_frame_data_struct *pstr_td_frame_data, WORD32 k,
397*15dc779aSAndroid Build Coastguard Worker FLOAT32 lp_filt_coeff[], FLOAT32 stability_factor,
398*15dc779aSAndroid Build Coastguard Worker ia_usac_lpd_decoder_handle st) {
399*15dc779aSAndroid Build Coastguard Worker WORD32 i, subfr_idx;
400*15dc779aSAndroid Build Coastguard Worker WORD32 pitch_lag = 0, pitch_lag_frac = 0, index, pitch_flag, pitch_lag_max;
401*15dc779aSAndroid Build Coastguard Worker WORD32 pitch_lag_min = 0;
402*15dc779aSAndroid Build Coastguard Worker FLOAT32 tmp, pitch_gain, gain_code, voicing_factor, r_v, innov_energy,
403*15dc779aSAndroid Build Coastguard Worker pitch_energy, mean_ener_code;
404*15dc779aSAndroid Build Coastguard Worker FLOAT32 gain_smooth, gain_code0, cpe;
405*15dc779aSAndroid Build Coastguard Worker FLOAT32 code[LEN_SUBFR] = {0}, synth_temp[128 + 16] = {0};
406*15dc779aSAndroid Build Coastguard Worker FLOAT32 post_process_exc[LEN_SUBFR] = {0};
407*15dc779aSAndroid Build Coastguard Worker FLOAT32 gain_smooth_factor;
408*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_lp_filt_coeff;
409*15dc779aSAndroid Build Coastguard Worker WORD32 pitch_min;
410*15dc779aSAndroid Build Coastguard Worker WORD32 pitch_fr2;
411*15dc779aSAndroid Build Coastguard Worker WORD32 pitch_fr1;
412*15dc779aSAndroid Build Coastguard Worker WORD32 pitch_max;
413*15dc779aSAndroid Build Coastguard Worker WORD32 subfr_nb = 0;
414*15dc779aSAndroid Build Coastguard Worker const WORD16 num_codebits_table[8] = {20, 28, 36, 44, 52, 64, 12, 16};
415*15dc779aSAndroid Build Coastguard Worker FLOAT32 x[FAC_LENGTH] = {0}, xn2[2 * FAC_LENGTH + 16] = {0};
416*15dc779aSAndroid Build Coastguard Worker WORD32 int_x[FAC_LENGTH] = {0};
417*15dc779aSAndroid Build Coastguard Worker WORD32 TTT;
418*15dc779aSAndroid Build Coastguard Worker WORD32 len_subfr = usac_data->len_subfrm;
419*15dc779aSAndroid Build Coastguard Worker WORD32 fac_length;
420*15dc779aSAndroid Build Coastguard Worker WORD8 shiftp;
421*15dc779aSAndroid Build Coastguard Worker WORD32 preshift;
422*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_scratch = &usac_data->scratch_buffer[0];
423*15dc779aSAndroid Build Coastguard Worker WORD32 *int_xn2 = &usac_data->x_ac_dec[0];
424*15dc779aSAndroid Build Coastguard Worker WORD32 loop_count = 0;
425*15dc779aSAndroid Build Coastguard Worker WORD32 core_mode = pstr_td_frame_data->acelp_core_mode;
426*15dc779aSAndroid Build Coastguard Worker FLOAT32 *synth_signal =
427*15dc779aSAndroid Build Coastguard Worker &usac_data->synth_buf[len_subfr * k + MAX_PITCH +
428*15dc779aSAndroid Build Coastguard Worker (((NUM_FRAMES * usac_data->num_subfrm) / 2) - 1) *
429*15dc779aSAndroid Build Coastguard Worker LEN_SUBFR];
430*15dc779aSAndroid Build Coastguard Worker FLOAT32 *xcitation_curr =
431*15dc779aSAndroid Build Coastguard Worker &usac_data->exc_buf[len_subfr * k + MAX_PITCH + (INTER_LP_FIL_ORDER + 1)];
432*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_pitch_gain =
433*15dc779aSAndroid Build Coastguard Worker &usac_data->pitch_gain[k * usac_data->num_subfrm +
434*15dc779aSAndroid Build Coastguard Worker (((NUM_FRAMES * usac_data->num_subfrm) / 2) - 1)];
435*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_pitch =
436*15dc779aSAndroid Build Coastguard Worker &usac_data->pitch[k * usac_data->num_subfrm +
437*15dc779aSAndroid Build Coastguard Worker (((NUM_FRAMES * usac_data->num_subfrm) / 2) - 1)];
438*15dc779aSAndroid Build Coastguard Worker fac_length = len_subfr / 2;
439*15dc779aSAndroid Build Coastguard Worker
440*15dc779aSAndroid Build Coastguard Worker WORD32 bfi = (usac_data->num_lost_lpd_frames[usac_data->present_chan] > 0) ? 1 : 0;
441*15dc779aSAndroid Build Coastguard Worker WORD32 i_offset =
442*15dc779aSAndroid Build Coastguard Worker (usac_data->str_tddec[usac_data->present_chan]->fscale * TMIN + (FSCALE_DENOM / 2)) /
443*15dc779aSAndroid Build Coastguard Worker FSCALE_DENOM -
444*15dc779aSAndroid Build Coastguard Worker TMIN;
445*15dc779aSAndroid Build Coastguard Worker const WORD32 pitch_max_val = TMAX + (6 * i_offset);
446*15dc779aSAndroid Build Coastguard Worker WORD16 code_t[LEN_SUBFR];
447*15dc779aSAndroid Build Coastguard Worker
448*15dc779aSAndroid Build Coastguard Worker if (st->mode_prev > 0) {
449*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < fac_length / 2; i++) {
450*15dc779aSAndroid Build Coastguard Worker x[i] = st->fac_gain * pstr_td_frame_data->fac[k * FAC_LENGTH + 2 * i];
451*15dc779aSAndroid Build Coastguard Worker x[fac_length / 2 + i] =
452*15dc779aSAndroid Build Coastguard Worker st->fac_gain *
453*15dc779aSAndroid Build Coastguard Worker pstr_td_frame_data->fac[k * FAC_LENGTH + fac_length - 2 * i - 1];
454*15dc779aSAndroid Build Coastguard Worker }
455*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < fac_length / 8; i++) {
456*15dc779aSAndroid Build Coastguard Worker x[i] *= st->fac_fd_data[2 * i];
457*15dc779aSAndroid Build Coastguard Worker x[fac_length - i - 1] *= st->fac_fd_data[2 * i + 1];
458*15dc779aSAndroid Build Coastguard Worker }
459*15dc779aSAndroid Build Coastguard Worker
460*15dc779aSAndroid Build Coastguard Worker preshift = 0;
461*15dc779aSAndroid Build Coastguard Worker shiftp = ixheaacd_float2fix(x, int_x, fac_length);
462*15dc779aSAndroid Build Coastguard Worker
463*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_mdct(int_x, int_xn2, &preshift, fac_length, ptr_scratch);
464*15dc779aSAndroid Build Coastguard Worker
465*15dc779aSAndroid Build Coastguard Worker ixheaacd_fix2float(int_xn2, xn2 + fac_length, fac_length, &shiftp,
466*15dc779aSAndroid Build Coastguard Worker &preshift);
467*15dc779aSAndroid Build Coastguard Worker
468*15dc779aSAndroid Build Coastguard Worker ixheaacd_vec_cnst_mul((2.0f / (FLOAT32)fac_length), xn2 + fac_length,
469*15dc779aSAndroid Build Coastguard Worker xn2 + fac_length, fac_length);
470*15dc779aSAndroid Build Coastguard Worker
471*15dc779aSAndroid Build Coastguard Worker memset(xn2, 0, fac_length * sizeof(FLOAT32));
472*15dc779aSAndroid Build Coastguard Worker
473*15dc779aSAndroid Build Coastguard Worker ixheaacd_lpc_wt_synthesis_tool(st->lp_flt_coeff_a_prev, xn2 + fac_length,
474*15dc779aSAndroid Build Coastguard Worker fac_length);
475*15dc779aSAndroid Build Coastguard Worker
476*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < 2 * fac_length; i++)
477*15dc779aSAndroid Build Coastguard Worker xn2[i] += synth_signal[i - (2 * fac_length)];
478*15dc779aSAndroid Build Coastguard Worker
479*15dc779aSAndroid Build Coastguard Worker memcpy(synth_signal - fac_length, xn2 + fac_length,
480*15dc779aSAndroid Build Coastguard Worker fac_length * sizeof(FLOAT32));
481*15dc779aSAndroid Build Coastguard Worker
482*15dc779aSAndroid Build Coastguard Worker tmp = 0.0;
483*15dc779aSAndroid Build Coastguard Worker ixheaacd_preemphsis_tool_float(xn2, PREEMPH_FILT_FAC, 2 * fac_length, tmp);
484*15dc779aSAndroid Build Coastguard Worker
485*15dc779aSAndroid Build Coastguard Worker ptr_lp_filt_coeff = st->lp_flt_coeff_a_prev;
486*15dc779aSAndroid Build Coastguard Worker TTT = fac_length % LEN_SUBFR;
487*15dc779aSAndroid Build Coastguard Worker if (TTT != 0) {
488*15dc779aSAndroid Build Coastguard Worker ixheaacd_residual_tool_float(
489*15dc779aSAndroid Build Coastguard Worker ptr_lp_filt_coeff, &xn2[fac_length],
490*15dc779aSAndroid Build Coastguard Worker &xcitation_curr[fac_length - (2 * fac_length)], TTT, 1);
491*15dc779aSAndroid Build Coastguard Worker ptr_lp_filt_coeff += (ORDER + 1);
492*15dc779aSAndroid Build Coastguard Worker }
493*15dc779aSAndroid Build Coastguard Worker
494*15dc779aSAndroid Build Coastguard Worker loop_count = (fac_length + TTT) / LEN_SUBFR;
495*15dc779aSAndroid Build Coastguard Worker ixheaacd_residual_tool_float(ptr_lp_filt_coeff, &xn2[fac_length + TTT],
496*15dc779aSAndroid Build Coastguard Worker &xcitation_curr[TTT - fac_length], LEN_SUBFR,
497*15dc779aSAndroid Build Coastguard Worker loop_count);
498*15dc779aSAndroid Build Coastguard Worker }
499*15dc779aSAndroid Build Coastguard Worker
500*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < ORDER; i++)
501*15dc779aSAndroid Build Coastguard Worker synth_temp[i] = synth_signal[i - ORDER] -
502*15dc779aSAndroid Build Coastguard Worker (PREEMPH_FILT_FAC * synth_signal[i - ORDER - 1]);
503*15dc779aSAndroid Build Coastguard Worker
504*15dc779aSAndroid Build Coastguard Worker i = (((st->fscale * TMIN) + (FSCALE_DENOM / 2)) / FSCALE_DENOM) - TMIN;
505*15dc779aSAndroid Build Coastguard Worker pitch_min = TMIN + i;
506*15dc779aSAndroid Build Coastguard Worker pitch_fr2 = TFR2 - i;
507*15dc779aSAndroid Build Coastguard Worker pitch_fr1 = TFR1;
508*15dc779aSAndroid Build Coastguard Worker pitch_max = TMAX + (6 * i);
509*15dc779aSAndroid Build Coastguard Worker
510*15dc779aSAndroid Build Coastguard Worker ptr_lp_filt_coeff = lp_filt_coeff;
511*15dc779aSAndroid Build Coastguard Worker for (subfr_idx = 0; subfr_idx < len_subfr; subfr_idx += LEN_SUBFR) {
512*15dc779aSAndroid Build Coastguard Worker pitch_flag = subfr_idx;
513*15dc779aSAndroid Build Coastguard Worker if ((len_subfr == 256) && (subfr_idx == (2 * LEN_SUBFR))) {
514*15dc779aSAndroid Build Coastguard Worker pitch_flag = 0;
515*15dc779aSAndroid Build Coastguard Worker }
516*15dc779aSAndroid Build Coastguard Worker index = pstr_td_frame_data->acb_index[k * 4 + subfr_nb];
517*15dc779aSAndroid Build Coastguard Worker
518*15dc779aSAndroid Build Coastguard Worker if (pitch_flag == 0) {
519*15dc779aSAndroid Build Coastguard Worker if (index < (pitch_fr2 - pitch_min) * 4) {
520*15dc779aSAndroid Build Coastguard Worker pitch_lag = pitch_min + (index / 4);
521*15dc779aSAndroid Build Coastguard Worker pitch_lag_frac = index - (pitch_lag - pitch_min) * 4;
522*15dc779aSAndroid Build Coastguard Worker } else if (index <
523*15dc779aSAndroid Build Coastguard Worker ((pitch_fr2 - pitch_min) * 4 + (pitch_fr1 - pitch_fr2) * 2)) {
524*15dc779aSAndroid Build Coastguard Worker index -= (pitch_fr2 - pitch_min) * 4;
525*15dc779aSAndroid Build Coastguard Worker pitch_lag = pitch_fr2 + (index / 2);
526*15dc779aSAndroid Build Coastguard Worker pitch_lag_frac = index - (pitch_lag - pitch_fr2) * 2;
527*15dc779aSAndroid Build Coastguard Worker pitch_lag_frac *= 2;
528*15dc779aSAndroid Build Coastguard Worker } else {
529*15dc779aSAndroid Build Coastguard Worker pitch_lag = index + pitch_fr1 - ((pitch_fr2 - pitch_min) * 4) -
530*15dc779aSAndroid Build Coastguard Worker ((pitch_fr1 - pitch_fr2) * 2);
531*15dc779aSAndroid Build Coastguard Worker pitch_lag_frac = 0;
532*15dc779aSAndroid Build Coastguard Worker }
533*15dc779aSAndroid Build Coastguard Worker pitch_lag_min = pitch_lag - 8;
534*15dc779aSAndroid Build Coastguard Worker if (pitch_lag_min < pitch_min) pitch_lag_min = pitch_min;
535*15dc779aSAndroid Build Coastguard Worker
536*15dc779aSAndroid Build Coastguard Worker pitch_lag_max = pitch_lag_min + 15;
537*15dc779aSAndroid Build Coastguard Worker if (pitch_lag_max > pitch_max) {
538*15dc779aSAndroid Build Coastguard Worker pitch_lag_max = pitch_max;
539*15dc779aSAndroid Build Coastguard Worker pitch_lag_min = pitch_lag_max - 15;
540*15dc779aSAndroid Build Coastguard Worker }
541*15dc779aSAndroid Build Coastguard Worker } else {
542*15dc779aSAndroid Build Coastguard Worker pitch_lag = pitch_lag_min + index / 4;
543*15dc779aSAndroid Build Coastguard Worker pitch_lag_frac = index - (pitch_lag - pitch_lag_min) * 4;
544*15dc779aSAndroid Build Coastguard Worker }
545*15dc779aSAndroid Build Coastguard Worker
546*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag) {
547*15dc779aSAndroid Build Coastguard Worker if (bfi) {
548*15dc779aSAndroid Build Coastguard Worker if (usac_data->pitch_lag_old >= pitch_max_val) {
549*15dc779aSAndroid Build Coastguard Worker usac_data->pitch_lag_old = (pitch_max_val - 5);
550*15dc779aSAndroid Build Coastguard Worker }
551*15dc779aSAndroid Build Coastguard Worker pitch_lag = usac_data->pitch_lag_old;
552*15dc779aSAndroid Build Coastguard Worker pitch_lag_frac = usac_data->pitch_lag_frac_old;
553*15dc779aSAndroid Build Coastguard Worker }
554*15dc779aSAndroid Build Coastguard Worker }
555*15dc779aSAndroid Build Coastguard Worker ixheaacd_cb_exc_calc(&xcitation_curr[subfr_idx], pitch_lag, pitch_lag_frac);
556*15dc779aSAndroid Build Coastguard Worker
557*15dc779aSAndroid Build Coastguard Worker mean_ener_code =
558*15dc779aSAndroid Build Coastguard Worker (((FLOAT32)pstr_td_frame_data->mean_energy[k]) * 12.0f) + 18.0f;
559*15dc779aSAndroid Build Coastguard Worker
560*15dc779aSAndroid Build Coastguard Worker if (pstr_td_frame_data->ltp_filtering_flag[k * 4 + subfr_nb] == 0) {
561*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < LEN_SUBFR; i++)
562*15dc779aSAndroid Build Coastguard Worker code[i] = (FLOAT32)(0.18 * xcitation_curr[i - 1 + subfr_idx] +
563*15dc779aSAndroid Build Coastguard Worker 0.64 * xcitation_curr[i + subfr_idx] +
564*15dc779aSAndroid Build Coastguard Worker 0.18 * xcitation_curr[i + 1 + subfr_idx]);
565*15dc779aSAndroid Build Coastguard Worker
566*15dc779aSAndroid Build Coastguard Worker ixheaacd_mem_cpy(code, &xcitation_curr[subfr_idx], LEN_SUBFR);
567*15dc779aSAndroid Build Coastguard Worker }
568*15dc779aSAndroid Build Coastguard Worker if (usac_data->frame_ok == 1) {
569*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_pulses_per_track(
570*15dc779aSAndroid Build Coastguard Worker &(pstr_td_frame_data->icb_index[k * 4 + subfr_nb][0]), num_codebits_table[core_mode],
571*15dc779aSAndroid Build Coastguard Worker code);
572*15dc779aSAndroid Build Coastguard Worker } else {
573*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag) {
574*15dc779aSAndroid Build Coastguard Worker WORD32 idx;
575*15dc779aSAndroid Build Coastguard Worker if (bfi) {
576*15dc779aSAndroid Build Coastguard Worker for (idx = 0; idx < LEN_SUBFR; idx++) {
577*15dc779aSAndroid Build Coastguard Worker usac_data->seed_ace = ((((WORD32)usac_data->seed_ace * 31821) >> 1) + 13849);
578*15dc779aSAndroid Build Coastguard Worker code_t[idx] = (WORD16)((usac_data->seed_ace) >> 4);
579*15dc779aSAndroid Build Coastguard Worker code[idx] = ((FLOAT32)code_t[idx] / 512);
580*15dc779aSAndroid Build Coastguard Worker }
581*15dc779aSAndroid Build Coastguard Worker }
582*15dc779aSAndroid Build Coastguard Worker }
583*15dc779aSAndroid Build Coastguard Worker }
584*15dc779aSAndroid Build Coastguard Worker
585*15dc779aSAndroid Build Coastguard Worker tmp = 0.0;
586*15dc779aSAndroid Build Coastguard Worker ixheaacd_preemphsis_tool_float(code, TILT_CODE, LEN_SUBFR, tmp);
587*15dc779aSAndroid Build Coastguard Worker i = pitch_lag;
588*15dc779aSAndroid Build Coastguard Worker if (pitch_lag_frac > 2) i++;
589*15dc779aSAndroid Build Coastguard Worker if (i >= 0) ixheaacd_acelp_pitch_sharpening(code, i);
590*15dc779aSAndroid Build Coastguard Worker
591*15dc779aSAndroid Build Coastguard Worker index = pstr_td_frame_data->gains[k * 4 + subfr_nb];
592*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag) {
593*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_gains_with_ec(index, code, &pitch_gain, &gain_code, mean_ener_code,
594*15dc779aSAndroid Build Coastguard Worker &innov_energy, &usac_data->past_pitch_gain,
595*15dc779aSAndroid Build Coastguard Worker &usac_data->past_gain_code, bfi);
596*15dc779aSAndroid Build Coastguard Worker } else {
597*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_decode_gains(index, code, &pitch_gain, &gain_code, mean_ener_code,
598*15dc779aSAndroid Build Coastguard Worker &innov_energy);
599*15dc779aSAndroid Build Coastguard Worker }
600*15dc779aSAndroid Build Coastguard Worker
601*15dc779aSAndroid Build Coastguard Worker pitch_energy = 0.0;
602*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < LEN_SUBFR; i++)
603*15dc779aSAndroid Build Coastguard Worker pitch_energy +=
604*15dc779aSAndroid Build Coastguard Worker xcitation_curr[i + subfr_idx] * xcitation_curr[i + subfr_idx];
605*15dc779aSAndroid Build Coastguard Worker
606*15dc779aSAndroid Build Coastguard Worker pitch_energy *= (pitch_gain * pitch_gain);
607*15dc779aSAndroid Build Coastguard Worker
608*15dc779aSAndroid Build Coastguard Worker innov_energy *= gain_code * gain_code;
609*15dc779aSAndroid Build Coastguard Worker
610*15dc779aSAndroid Build Coastguard Worker r_v = (FLOAT32)((pitch_energy - innov_energy) /
611*15dc779aSAndroid Build Coastguard Worker (pitch_energy + innov_energy));
612*15dc779aSAndroid Build Coastguard Worker
613*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < LEN_SUBFR; i++)
614*15dc779aSAndroid Build Coastguard Worker post_process_exc[i] = pitch_gain * xcitation_curr[i + subfr_idx];
615*15dc779aSAndroid Build Coastguard Worker
616*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < LEN_SUBFR; i++)
617*15dc779aSAndroid Build Coastguard Worker xcitation_curr[i + subfr_idx] =
618*15dc779aSAndroid Build Coastguard Worker pitch_gain * xcitation_curr[i + subfr_idx] + gain_code * code[i];
619*15dc779aSAndroid Build Coastguard Worker
620*15dc779aSAndroid Build Coastguard Worker i = pitch_lag;
621*15dc779aSAndroid Build Coastguard Worker if (pitch_lag_frac > 2) i++;
622*15dc779aSAndroid Build Coastguard Worker
623*15dc779aSAndroid Build Coastguard Worker if (i > pitch_max) i = pitch_max;
624*15dc779aSAndroid Build Coastguard Worker
625*15dc779aSAndroid Build Coastguard Worker *ptr_pitch++ = i;
626*15dc779aSAndroid Build Coastguard Worker *ptr_pitch_gain++ = pitch_gain;
627*15dc779aSAndroid Build Coastguard Worker
628*15dc779aSAndroid Build Coastguard Worker voicing_factor = (FLOAT32)(0.5 * (1.0 - r_v));
629*15dc779aSAndroid Build Coastguard Worker gain_smooth_factor = stability_factor * voicing_factor;
630*15dc779aSAndroid Build Coastguard Worker gain_code0 = gain_code;
631*15dc779aSAndroid Build Coastguard Worker if (gain_code0 < st->gain_threshold) {
632*15dc779aSAndroid Build Coastguard Worker gain_code0 = (FLOAT32)(gain_code0 * 1.19);
633*15dc779aSAndroid Build Coastguard Worker if (gain_code0 > st->gain_threshold) gain_code0 = st->gain_threshold;
634*15dc779aSAndroid Build Coastguard Worker } else {
635*15dc779aSAndroid Build Coastguard Worker gain_code0 = (FLOAT32)(gain_code0 / 1.19);
636*15dc779aSAndroid Build Coastguard Worker if (gain_code0 < st->gain_threshold) gain_code0 = st->gain_threshold;
637*15dc779aSAndroid Build Coastguard Worker }
638*15dc779aSAndroid Build Coastguard Worker st->gain_threshold = gain_code0;
639*15dc779aSAndroid Build Coastguard Worker gain_smooth = (FLOAT32)((gain_smooth_factor * gain_code0) +
640*15dc779aSAndroid Build Coastguard Worker ((1.0 - gain_smooth_factor) * gain_code));
641*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < LEN_SUBFR; i++) code[i] *= gain_smooth;
642*15dc779aSAndroid Build Coastguard Worker
643*15dc779aSAndroid Build Coastguard Worker cpe = (FLOAT32)(0.125 * (1.0 + r_v));
644*15dc779aSAndroid Build Coastguard Worker
645*15dc779aSAndroid Build Coastguard Worker post_process_exc[0] += code[0] - (cpe * code[1]);
646*15dc779aSAndroid Build Coastguard Worker
647*15dc779aSAndroid Build Coastguard Worker for (i = 1; i < LEN_SUBFR - 1; i++)
648*15dc779aSAndroid Build Coastguard Worker post_process_exc[i] += code[i] - (cpe * (code[i - 1] + code[i + 1]));
649*15dc779aSAndroid Build Coastguard Worker
650*15dc779aSAndroid Build Coastguard Worker post_process_exc[LEN_SUBFR - 1] +=
651*15dc779aSAndroid Build Coastguard Worker code[LEN_SUBFR - 1] - (cpe * code[LEN_SUBFR - 2]);
652*15dc779aSAndroid Build Coastguard Worker
653*15dc779aSAndroid Build Coastguard Worker ixheaacd_synthesis_tool_float(ptr_lp_filt_coeff, post_process_exc,
654*15dc779aSAndroid Build Coastguard Worker &synth_signal[subfr_idx], LEN_SUBFR,
655*15dc779aSAndroid Build Coastguard Worker synth_temp);
656*15dc779aSAndroid Build Coastguard Worker memcpy(synth_temp, &synth_signal[subfr_idx + LEN_SUBFR - ORDER],
657*15dc779aSAndroid Build Coastguard Worker ORDER * sizeof(FLOAT32));
658*15dc779aSAndroid Build Coastguard Worker
659*15dc779aSAndroid Build Coastguard Worker ptr_lp_filt_coeff += (ORDER + 1);
660*15dc779aSAndroid Build Coastguard Worker subfr_nb++;
661*15dc779aSAndroid Build Coastguard Worker }
662*15dc779aSAndroid Build Coastguard Worker
663*15dc779aSAndroid Build Coastguard Worker ixheaacd_deemphsis_tool(synth_signal, len_subfr, synth_signal[-1]);
664*15dc779aSAndroid Build Coastguard Worker
665*15dc779aSAndroid Build Coastguard Worker memset(synth_temp + 16, 0, 128 * sizeof(FLOAT32));
666*15dc779aSAndroid Build Coastguard Worker ixheaacd_synthesis_tool_float1(ptr_lp_filt_coeff, synth_temp + 16, 128);
667*15dc779aSAndroid Build Coastguard Worker
668*15dc779aSAndroid Build Coastguard Worker ptr_lp_filt_coeff -= (2 * (ORDER + 1));
669*15dc779aSAndroid Build Coastguard Worker memcpy(st->lp_flt_coeff_a_prev, ptr_lp_filt_coeff,
670*15dc779aSAndroid Build Coastguard Worker (2 * (ORDER + 1)) * sizeof(FLOAT32));
671*15dc779aSAndroid Build Coastguard Worker
672*15dc779aSAndroid Build Coastguard Worker memcpy(st->exc_prev, synth_signal + len_subfr - (1 + fac_length),
673*15dc779aSAndroid Build Coastguard Worker (1 + fac_length) * sizeof(FLOAT32));
674*15dc779aSAndroid Build Coastguard Worker
675*15dc779aSAndroid Build Coastguard Worker memcpy(st->exc_prev + 1 + fac_length, synth_temp + 16,
676*15dc779aSAndroid Build Coastguard Worker fac_length * sizeof(FLOAT32));
677*15dc779aSAndroid Build Coastguard Worker ixheaacd_deemphsis_tool(st->exc_prev + 1 + fac_length, fac_length,
678*15dc779aSAndroid Build Coastguard Worker synth_signal[len_subfr - 1]);
679*15dc779aSAndroid Build Coastguard Worker
680*15dc779aSAndroid Build Coastguard Worker if (usac_data->ec_flag) {
681*15dc779aSAndroid Build Coastguard Worker usac_data->pitch_lag_old = pitch_lag;
682*15dc779aSAndroid Build Coastguard Worker usac_data->pitch_lag_frac_old = pitch_lag_frac;
683*15dc779aSAndroid Build Coastguard Worker }
684*15dc779aSAndroid Build Coastguard Worker return;
685*15dc779aSAndroid Build Coastguard Worker }
686