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
21*15dc779aSAndroid Build Coastguard Worker #include <math.h>
22*15dc779aSAndroid Build Coastguard Worker #include <stdlib.h>
23*15dc779aSAndroid Build Coastguard Worker #include <string.h>
24*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_common.h"
25*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
26*15dc779aSAndroid Build Coastguard Worker
27*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_constants.h"
28*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops32.h"
29*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops16.h"
30*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops40.h"
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops.h"
32*15dc779aSAndroid Build Coastguard Worker
33*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_op.h"
34*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_intrinsics.h"
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_common_rom.h"
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_basic_funcs.h"
37*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_bitbuffer.h"
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecsettings.h"
39*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_scale.h"
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_lpp_tran.h"
41*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_env_extr_part.h"
42*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_rom.h"
43*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_hybrid.h"
44*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ps_dec.h"
45*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_env_extr.h"
46*15dc779aSAndroid Build Coastguard Worker
47*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_sbr_const.h"
48*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_env_extr.h"
49*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_freq_sca.h"
50*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_intrinsics.h"
51*15dc779aSAndroid Build Coastguard Worker
52*15dc779aSAndroid Build Coastguard Worker const WORD32 ixheaacd_samp_rate_table[12] = {92017, 75132, 55426, 46009,
53*15dc779aSAndroid Build Coastguard Worker 37566, 27713, 23004, 18783,
54*15dc779aSAndroid Build Coastguard Worker 13856, 11502, 9391, 16428320};
55*15dc779aSAndroid Build Coastguard Worker
56*15dc779aSAndroid Build Coastguard Worker const WORD32 ixheaacd_v_offset_40[16] = {
57*15dc779aSAndroid Build Coastguard Worker 3 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1,
58*15dc779aSAndroid Build Coastguard Worker 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 1 + 1, 0};
59*15dc779aSAndroid Build Coastguard Worker
ixheaacd_int_div(WORD32 num,WORD32 den)60*15dc779aSAndroid Build Coastguard Worker static WORD32 ixheaacd_int_div(WORD32 num, WORD32 den) {
61*15dc779aSAndroid Build Coastguard Worker if (den != 0) {
62*15dc779aSAndroid Build Coastguard Worker WORD32 result = 0;
63*15dc779aSAndroid Build Coastguard Worker WORD32 temp = 0;
64*15dc779aSAndroid Build Coastguard Worker while (den <= num) {
65*15dc779aSAndroid Build Coastguard Worker temp = 0;
66*15dc779aSAndroid Build Coastguard Worker while (num >= (den << (temp + 1))) {
67*15dc779aSAndroid Build Coastguard Worker temp++;
68*15dc779aSAndroid Build Coastguard Worker }
69*15dc779aSAndroid Build Coastguard Worker result = result + (1 << temp);
70*15dc779aSAndroid Build Coastguard Worker num = num - (den * (1 << temp));
71*15dc779aSAndroid Build Coastguard Worker }
72*15dc779aSAndroid Build Coastguard Worker return result;
73*15dc779aSAndroid Build Coastguard Worker } else {
74*15dc779aSAndroid Build Coastguard Worker return 0;
75*15dc779aSAndroid Build Coastguard Worker }
76*15dc779aSAndroid Build Coastguard Worker }
77*15dc779aSAndroid Build Coastguard Worker
ixheaacd_aac_shellsort(WORD16 * in,WORD32 n)78*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_aac_shellsort(WORD16 *in, WORD32 n) {
79*15dc779aSAndroid Build Coastguard Worker WORD32 i, j;
80*15dc779aSAndroid Build Coastguard Worker WORD32 inc;
81*15dc779aSAndroid Build Coastguard Worker WORD32 v, w;
82*15dc779aSAndroid Build Coastguard Worker
83*15dc779aSAndroid Build Coastguard Worker inc = 1;
84*15dc779aSAndroid Build Coastguard Worker
85*15dc779aSAndroid Build Coastguard Worker do {
86*15dc779aSAndroid Build Coastguard Worker inc = (((inc << 1) + inc) + 1);
87*15dc779aSAndroid Build Coastguard Worker } while (inc <= n);
88*15dc779aSAndroid Build Coastguard Worker
89*15dc779aSAndroid Build Coastguard Worker do {
90*15dc779aSAndroid Build Coastguard Worker inc = (ixheaacd_int_div(inc, 3));
91*15dc779aSAndroid Build Coastguard Worker for (i = inc; i < n; i++) {
92*15dc779aSAndroid Build Coastguard Worker v = in[i];
93*15dc779aSAndroid Build Coastguard Worker j = i;
94*15dc779aSAndroid Build Coastguard Worker
95*15dc779aSAndroid Build Coastguard Worker while ((w = in[(j - inc)]) > v) {
96*15dc779aSAndroid Build Coastguard Worker in[j] = w;
97*15dc779aSAndroid Build Coastguard Worker j = (j - inc);
98*15dc779aSAndroid Build Coastguard Worker
99*15dc779aSAndroid Build Coastguard Worker if (j < inc) break;
100*15dc779aSAndroid Build Coastguard Worker }
101*15dc779aSAndroid Build Coastguard Worker in[j] = v;
102*15dc779aSAndroid Build Coastguard Worker }
103*15dc779aSAndroid Build Coastguard Worker
104*15dc779aSAndroid Build Coastguard Worker } while (inc > 1);
105*15dc779aSAndroid Build Coastguard Worker }
106*15dc779aSAndroid Build Coastguard Worker
107*15dc779aSAndroid Build Coastguard Worker WORD32
ixheaacd_calc_start_band(WORD32 fs_mapped,const WORD32 start_freq,FLOAT32 upsamp_fac)108*15dc779aSAndroid Build Coastguard Worker ixheaacd_calc_start_band(WORD32 fs_mapped, const WORD32 start_freq,
109*15dc779aSAndroid Build Coastguard Worker FLOAT32 upsamp_fac) {
110*15dc779aSAndroid Build Coastguard Worker WORD32 k0_min;
111*15dc779aSAndroid Build Coastguard Worker
112*15dc779aSAndroid Build Coastguard Worker if (upsamp_fac == 4) {
113*15dc779aSAndroid Build Coastguard Worker if (fs_mapped < 32000) {
114*15dc779aSAndroid Build Coastguard Worker k0_min = (WORD32)(((FLOAT32)(3000 * 2 * 32) / fs_mapped) + 0.5);
115*15dc779aSAndroid Build Coastguard Worker } else {
116*15dc779aSAndroid Build Coastguard Worker if (fs_mapped < 64000) {
117*15dc779aSAndroid Build Coastguard Worker k0_min = (WORD32)(((FLOAT32)(4000 * 2 * 32) / fs_mapped) + 0.5);
118*15dc779aSAndroid Build Coastguard Worker } else {
119*15dc779aSAndroid Build Coastguard Worker k0_min = (WORD32)(((FLOAT32)(5000 * 2 * 32) / fs_mapped) + 0.5);
120*15dc779aSAndroid Build Coastguard Worker }
121*15dc779aSAndroid Build Coastguard Worker }
122*15dc779aSAndroid Build Coastguard Worker } else {
123*15dc779aSAndroid Build Coastguard Worker if (fs_mapped < 32000) {
124*15dc779aSAndroid Build Coastguard Worker k0_min = (WORD32)(((FLOAT32)(3000 * 2 * 64) / fs_mapped) + 0.5);
125*15dc779aSAndroid Build Coastguard Worker } else {
126*15dc779aSAndroid Build Coastguard Worker if (fs_mapped < 64000) {
127*15dc779aSAndroid Build Coastguard Worker k0_min = (WORD32)(((FLOAT32)(4000 * 2 * 64) / fs_mapped) + 0.5);
128*15dc779aSAndroid Build Coastguard Worker } else {
129*15dc779aSAndroid Build Coastguard Worker k0_min = (WORD32)(((FLOAT32)(5000 * 2 * 64) / fs_mapped) + 0.5);
130*15dc779aSAndroid Build Coastguard Worker }
131*15dc779aSAndroid Build Coastguard Worker }
132*15dc779aSAndroid Build Coastguard Worker }
133*15dc779aSAndroid Build Coastguard Worker
134*15dc779aSAndroid Build Coastguard Worker switch (fs_mapped) {
135*15dc779aSAndroid Build Coastguard Worker case 16000: {
136*15dc779aSAndroid Build Coastguard Worker WORD32 v_offset[] = {-8, -7, -6, -5, -4, -3, -2, -1,
137*15dc779aSAndroid Build Coastguard Worker 0, 1, 2, 3, 4, 5, 6, 7};
138*15dc779aSAndroid Build Coastguard Worker return (k0_min + v_offset[start_freq]);
139*15dc779aSAndroid Build Coastguard Worker } break;
140*15dc779aSAndroid Build Coastguard Worker case 22050: {
141*15dc779aSAndroid Build Coastguard Worker WORD32 v_offset[] = {-5, -4, -3, -2, -1, 0, 1, 2,
142*15dc779aSAndroid Build Coastguard Worker 3, 4, 5, 6, 7, 9, 11, 13};
143*15dc779aSAndroid Build Coastguard Worker return (k0_min + v_offset[start_freq]);
144*15dc779aSAndroid Build Coastguard Worker } break;
145*15dc779aSAndroid Build Coastguard Worker case 24000: {
146*15dc779aSAndroid Build Coastguard Worker WORD32 v_offset[] = {-5, -3, -2, -1, 0, 1, 2, 3,
147*15dc779aSAndroid Build Coastguard Worker 4, 5, 6, 7, 9, 11, 13, 16};
148*15dc779aSAndroid Build Coastguard Worker return (k0_min + v_offset[start_freq]);
149*15dc779aSAndroid Build Coastguard Worker } break;
150*15dc779aSAndroid Build Coastguard Worker case 32000: {
151*15dc779aSAndroid Build Coastguard Worker WORD32 v_offset[] = {-6, -4, -2, -1, 0, 1, 2, 3,
152*15dc779aSAndroid Build Coastguard Worker 4, 5, 6, 7, 9, 11, 13, 16};
153*15dc779aSAndroid Build Coastguard Worker return (k0_min + v_offset[start_freq]);
154*15dc779aSAndroid Build Coastguard Worker } break;
155*15dc779aSAndroid Build Coastguard Worker case 40000: {
156*15dc779aSAndroid Build Coastguard Worker WORD32 v_offset[] = {-1, 0, 1, 2, 3, 4, 5, 6,
157*15dc779aSAndroid Build Coastguard Worker 7, 8, 9, 11, 13, 15, 17, 19};
158*15dc779aSAndroid Build Coastguard Worker return (k0_min + v_offset[start_freq]);
159*15dc779aSAndroid Build Coastguard Worker } break;
160*15dc779aSAndroid Build Coastguard Worker case 44100:
161*15dc779aSAndroid Build Coastguard Worker case 48000:
162*15dc779aSAndroid Build Coastguard Worker case 64000: {
163*15dc779aSAndroid Build Coastguard Worker WORD32 v_offset[] = {-4, -2, -1, 0, 1, 2, 3, 4,
164*15dc779aSAndroid Build Coastguard Worker 5, 6, 7, 9, 11, 13, 16, 20};
165*15dc779aSAndroid Build Coastguard Worker return (k0_min + v_offset[start_freq]);
166*15dc779aSAndroid Build Coastguard Worker } break;
167*15dc779aSAndroid Build Coastguard Worker case 88200:
168*15dc779aSAndroid Build Coastguard Worker case 96000: {
169*15dc779aSAndroid Build Coastguard Worker WORD32 v_offset[] = {-2, -1, 0, 1, 2, 3, 4, 5,
170*15dc779aSAndroid Build Coastguard Worker 6, 7, 9, 11, 13, 16, 20, 24};
171*15dc779aSAndroid Build Coastguard Worker return (k0_min + v_offset[start_freq]);
172*15dc779aSAndroid Build Coastguard Worker } break;
173*15dc779aSAndroid Build Coastguard Worker
174*15dc779aSAndroid Build Coastguard Worker default: {
175*15dc779aSAndroid Build Coastguard Worker WORD32 v_offset[] = {0, 1, 2, 3, 4, 5, 6, 7,
176*15dc779aSAndroid Build Coastguard Worker 9, 11, 13, 16, 20, 24, 28, 33};
177*15dc779aSAndroid Build Coastguard Worker return (k0_min + v_offset[start_freq]);
178*15dc779aSAndroid Build Coastguard Worker }
179*15dc779aSAndroid Build Coastguard Worker }
180*15dc779aSAndroid Build Coastguard Worker }
181*15dc779aSAndroid Build Coastguard Worker
182*15dc779aSAndroid Build Coastguard Worker WORD32
ixheaacd_calc_stop_band(WORD32 fs,const WORD32 stop_freq,FLOAT32 upsamp_fac)183*15dc779aSAndroid Build Coastguard Worker ixheaacd_calc_stop_band(WORD32 fs, const WORD32 stop_freq, FLOAT32 upsamp_fac) {
184*15dc779aSAndroid Build Coastguard Worker WORD32 result, i;
185*15dc779aSAndroid Build Coastguard Worker WORD16 arr_stop_freq[14];
186*15dc779aSAndroid Build Coastguard Worker WORD32 k1_min;
187*15dc779aSAndroid Build Coastguard Worker WORD16 arr_diff_stop_freq[13];
188*15dc779aSAndroid Build Coastguard Worker
189*15dc779aSAndroid Build Coastguard Worker if (upsamp_fac == 4) {
190*15dc779aSAndroid Build Coastguard Worker fs = fs / 2;
191*15dc779aSAndroid Build Coastguard Worker if (fs < 32000) {
192*15dc779aSAndroid Build Coastguard Worker k1_min = (WORD32)(((FLOAT32)(6000 * 2 * 32) / fs) + 0.5);
193*15dc779aSAndroid Build Coastguard Worker } else {
194*15dc779aSAndroid Build Coastguard Worker if (fs < 64000) {
195*15dc779aSAndroid Build Coastguard Worker k1_min = (WORD32)(((FLOAT32)(8000 * 2 * 32) / fs) + 0.5);
196*15dc779aSAndroid Build Coastguard Worker } else {
197*15dc779aSAndroid Build Coastguard Worker k1_min = (WORD32)(((FLOAT32)(10000 * 2 * 32) / fs) + 0.5);
198*15dc779aSAndroid Build Coastguard Worker }
199*15dc779aSAndroid Build Coastguard Worker }
200*15dc779aSAndroid Build Coastguard Worker } else {
201*15dc779aSAndroid Build Coastguard Worker if (fs < 32000) {
202*15dc779aSAndroid Build Coastguard Worker k1_min = (WORD32)(((FLOAT32)(6000 * 2 * 64) / fs) + 0.5);
203*15dc779aSAndroid Build Coastguard Worker } else {
204*15dc779aSAndroid Build Coastguard Worker if (fs < 64000) {
205*15dc779aSAndroid Build Coastguard Worker k1_min = (WORD32)(((FLOAT32)(8000 * 2 * 64) / fs) + 0.5);
206*15dc779aSAndroid Build Coastguard Worker } else {
207*15dc779aSAndroid Build Coastguard Worker k1_min = (WORD32)(((FLOAT32)(10000 * 2 * 64) / fs) + 0.5);
208*15dc779aSAndroid Build Coastguard Worker }
209*15dc779aSAndroid Build Coastguard Worker }
210*15dc779aSAndroid Build Coastguard Worker }
211*15dc779aSAndroid Build Coastguard Worker
212*15dc779aSAndroid Build Coastguard Worker /*Calculate stop frequency vector*/
213*15dc779aSAndroid Build Coastguard Worker for (i = 0; i <= 13; i++) {
214*15dc779aSAndroid Build Coastguard Worker arr_stop_freq[i] = (WORD32)(k1_min * pow(64.0 / k1_min, i / 13.0) + 0.5);
215*15dc779aSAndroid Build Coastguard Worker }
216*15dc779aSAndroid Build Coastguard Worker
217*15dc779aSAndroid Build Coastguard Worker /*Ensure increasing bandwidth */
218*15dc779aSAndroid Build Coastguard Worker for (i = 0; i <= 12; i++) {
219*15dc779aSAndroid Build Coastguard Worker arr_diff_stop_freq[i] = arr_stop_freq[i + 1] - arr_stop_freq[i];
220*15dc779aSAndroid Build Coastguard Worker }
221*15dc779aSAndroid Build Coastguard Worker
222*15dc779aSAndroid Build Coastguard Worker ixheaacd_aac_shellsort(&arr_diff_stop_freq[0],
223*15dc779aSAndroid Build Coastguard Worker 13); /*Sort bandwidth changes */
224*15dc779aSAndroid Build Coastguard Worker
225*15dc779aSAndroid Build Coastguard Worker result = k1_min;
226*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < stop_freq; i++) {
227*15dc779aSAndroid Build Coastguard Worker result = ixheaac_add32_sat(result, arr_diff_stop_freq[i]);
228*15dc779aSAndroid Build Coastguard Worker }
229*15dc779aSAndroid Build Coastguard Worker
230*15dc779aSAndroid Build Coastguard Worker return (result);
231*15dc779aSAndroid Build Coastguard Worker }
ixheaacd_calc_k0_k2_bands(const WORD32 samp_freq,const WORD32 start_freq,const WORD32 stop_freq,FLOAT32 upsamp_fac,WORD16 * ptr_k0,WORD16 * ptr_k2)232*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE ixheaacd_calc_k0_k2_bands(const WORD32 samp_freq,
233*15dc779aSAndroid Build Coastguard Worker const WORD32 start_freq,
234*15dc779aSAndroid Build Coastguard Worker const WORD32 stop_freq,
235*15dc779aSAndroid Build Coastguard Worker FLOAT32 upsamp_fac, WORD16 *ptr_k0,
236*15dc779aSAndroid Build Coastguard Worker WORD16 *ptr_k2) {
237*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE err_code = IA_NO_ERROR;
238*15dc779aSAndroid Build Coastguard Worker
239*15dc779aSAndroid Build Coastguard Worker WORD32 fs_mapped = 0;
240*15dc779aSAndroid Build Coastguard Worker WORD32 fs = samp_freq;
241*15dc779aSAndroid Build Coastguard Worker
242*15dc779aSAndroid Build Coastguard Worker if (upsamp_fac == 4) {
243*15dc779aSAndroid Build Coastguard Worker fs = fs / 2;
244*15dc779aSAndroid Build Coastguard Worker }
245*15dc779aSAndroid Build Coastguard Worker
246*15dc779aSAndroid Build Coastguard Worker if (fs >= 0 && fs < 18783) {
247*15dc779aSAndroid Build Coastguard Worker fs_mapped = 16000;
248*15dc779aSAndroid Build Coastguard Worker } else if (fs >= 18783 && fs < 23004) {
249*15dc779aSAndroid Build Coastguard Worker fs_mapped = 22050;
250*15dc779aSAndroid Build Coastguard Worker } else if (fs >= 23004 && fs < 27713) {
251*15dc779aSAndroid Build Coastguard Worker fs_mapped = 24000;
252*15dc779aSAndroid Build Coastguard Worker } else if (fs >= 27713 && fs < 35777) {
253*15dc779aSAndroid Build Coastguard Worker fs_mapped = 32000;
254*15dc779aSAndroid Build Coastguard Worker } else if (fs >= 35777 && fs < 42000) {
255*15dc779aSAndroid Build Coastguard Worker fs_mapped = 40000;
256*15dc779aSAndroid Build Coastguard Worker } else if (fs >= 42000 && fs < 46009) {
257*15dc779aSAndroid Build Coastguard Worker fs_mapped = 44100;
258*15dc779aSAndroid Build Coastguard Worker } else if (fs >= 46009 && fs < 55426) {
259*15dc779aSAndroid Build Coastguard Worker fs_mapped = 48000;
260*15dc779aSAndroid Build Coastguard Worker } else if (fs >= 55426 && fs < 75132) {
261*15dc779aSAndroid Build Coastguard Worker fs_mapped = 64000;
262*15dc779aSAndroid Build Coastguard Worker } else if (fs >= 75132 && fs < 92017) {
263*15dc779aSAndroid Build Coastguard Worker fs_mapped = 88200;
264*15dc779aSAndroid Build Coastguard Worker } else if (fs >= 92017) {
265*15dc779aSAndroid Build Coastguard Worker fs_mapped = 96000;
266*15dc779aSAndroid Build Coastguard Worker } else {
267*15dc779aSAndroid Build Coastguard Worker return -1;
268*15dc779aSAndroid Build Coastguard Worker }
269*15dc779aSAndroid Build Coastguard Worker
270*15dc779aSAndroid Build Coastguard Worker /* Update start_freq struct */
271*15dc779aSAndroid Build Coastguard Worker *ptr_k0 = ixheaacd_calc_start_band(fs_mapped, start_freq, upsamp_fac);
272*15dc779aSAndroid Build Coastguard Worker
273*15dc779aSAndroid Build Coastguard Worker /*Update stop_freq struct */
274*15dc779aSAndroid Build Coastguard Worker if (stop_freq < 14) {
275*15dc779aSAndroid Build Coastguard Worker *ptr_k2 = ixheaacd_calc_stop_band(samp_freq, stop_freq, upsamp_fac);
276*15dc779aSAndroid Build Coastguard Worker } else if (stop_freq == 14) {
277*15dc779aSAndroid Build Coastguard Worker *ptr_k2 = 2 * (*ptr_k0);
278*15dc779aSAndroid Build Coastguard Worker } else {
279*15dc779aSAndroid Build Coastguard Worker *ptr_k2 = 3 * (*ptr_k0);
280*15dc779aSAndroid Build Coastguard Worker }
281*15dc779aSAndroid Build Coastguard Worker
282*15dc779aSAndroid Build Coastguard Worker /* limit to Nyqvist */
283*15dc779aSAndroid Build Coastguard Worker if (*ptr_k2 > 64) {
284*15dc779aSAndroid Build Coastguard Worker *ptr_k2 = 64;
285*15dc779aSAndroid Build Coastguard Worker }
286*15dc779aSAndroid Build Coastguard Worker return err_code;
287*15dc779aSAndroid Build Coastguard Worker }
288*15dc779aSAndroid Build Coastguard Worker
ixheaacd_calc_master_frq_bnd_tbl(ia_freq_band_data_struct * pstr_freq_band_data,ia_sbr_header_data_struct * ptr_header_data,ixheaacd_misc_tables * pstr_common_tables)289*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE ixheaacd_calc_master_frq_bnd_tbl(
290*15dc779aSAndroid Build Coastguard Worker ia_freq_band_data_struct *pstr_freq_band_data,
291*15dc779aSAndroid Build Coastguard Worker ia_sbr_header_data_struct *ptr_header_data,
292*15dc779aSAndroid Build Coastguard Worker ixheaacd_misc_tables *pstr_common_tables) {
293*15dc779aSAndroid Build Coastguard Worker WORD32 k;
294*15dc779aSAndroid Build Coastguard Worker WORD32 fs = ptr_header_data->out_sampling_freq;
295*15dc779aSAndroid Build Coastguard Worker WORD16 bands;
296*15dc779aSAndroid Build Coastguard Worker WORD16 k0 = 0, k2 = 0, k1;
297*15dc779aSAndroid Build Coastguard Worker WORD32 k2_achived;
298*15dc779aSAndroid Build Coastguard Worker WORD32 k2_diff;
299*15dc779aSAndroid Build Coastguard Worker WORD32 incr;
300*15dc779aSAndroid Build Coastguard Worker WORD32 dk;
301*15dc779aSAndroid Build Coastguard Worker WORD16 vec_dk[MAX_OCTAVE + MAX_SECOND_REGION];
302*15dc779aSAndroid Build Coastguard Worker WORD16 *vec_dk0 = &vec_dk[0];
303*15dc779aSAndroid Build Coastguard Worker WORD16 *vec_dk1 = &vec_dk[MAX_OCTAVE];
304*15dc779aSAndroid Build Coastguard Worker WORD16 upsamp_fac = ptr_header_data->upsamp_fac;
305*15dc779aSAndroid Build Coastguard Worker WORD16 *f_master_tbl = pstr_freq_band_data->f_master_tbl;
306*15dc779aSAndroid Build Coastguard Worker WORD16 num_mf_bands;
307*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE err_code = IA_NO_ERROR;
308*15dc779aSAndroid Build Coastguard Worker
309*15dc779aSAndroid Build Coastguard Worker k1 = 0;
310*15dc779aSAndroid Build Coastguard Worker incr = 0;
311*15dc779aSAndroid Build Coastguard Worker dk = 0;
312*15dc779aSAndroid Build Coastguard Worker
313*15dc779aSAndroid Build Coastguard Worker err_code = ixheaacd_calc_k0_k2_bands(fs, ptr_header_data->start_freq,
314*15dc779aSAndroid Build Coastguard Worker ptr_header_data->stop_freq, upsamp_fac,
315*15dc779aSAndroid Build Coastguard Worker &k0, &k2);
316*15dc779aSAndroid Build Coastguard Worker if (err_code) return err_code;
317*15dc779aSAndroid Build Coastguard Worker
318*15dc779aSAndroid Build Coastguard Worker if (k2 > NO_SYNTHESIS_CHANNELS) {
319*15dc779aSAndroid Build Coastguard Worker k2 = NO_SYNTHESIS_CHANNELS;
320*15dc779aSAndroid Build Coastguard Worker }
321*15dc779aSAndroid Build Coastguard Worker if (upsamp_fac == 4) {
322*15dc779aSAndroid Build Coastguard Worker if ((sub_d(k2, k0) > MAX_FREQ_COEFFS) || (k2 <= k0)) {
323*15dc779aSAndroid Build Coastguard Worker return -1;
324*15dc779aSAndroid Build Coastguard Worker }
325*15dc779aSAndroid Build Coastguard Worker if ((2 * fs == 44100) && (sub_d(k2, k0) > MAX_FREQ_COEFFS)) {
326*15dc779aSAndroid Build Coastguard Worker return -1;
327*15dc779aSAndroid Build Coastguard Worker }
328*15dc779aSAndroid Build Coastguard Worker if ((2 * fs >= 48000) && (sub_d(k2, k0) > MAX_FREQ_COEFFS)) {
329*15dc779aSAndroid Build Coastguard Worker return -1;
330*15dc779aSAndroid Build Coastguard Worker }
331*15dc779aSAndroid Build Coastguard Worker } else {
332*15dc779aSAndroid Build Coastguard Worker if ((sub_d(k2, k0) > MAX_FREQ_COEFFS_SBR) || (k2 <= k0)) {
333*15dc779aSAndroid Build Coastguard Worker return -1;
334*15dc779aSAndroid Build Coastguard Worker }
335*15dc779aSAndroid Build Coastguard Worker if ((fs == 44100) && (sub_d(k2, k0) > MAX_FREQ_COEFFS_FS44100)) {
336*15dc779aSAndroid Build Coastguard Worker return -1;
337*15dc779aSAndroid Build Coastguard Worker }
338*15dc779aSAndroid Build Coastguard Worker if ((fs >= 48000) && (sub_d(k2, k0) > MAX_FREQ_COEFFS_FS48000)) {
339*15dc779aSAndroid Build Coastguard Worker return -1;
340*15dc779aSAndroid Build Coastguard Worker }
341*15dc779aSAndroid Build Coastguard Worker }
342*15dc779aSAndroid Build Coastguard Worker
343*15dc779aSAndroid Build Coastguard Worker if (ptr_header_data->freq_scale == 0) {
344*15dc779aSAndroid Build Coastguard Worker WORD16 num_bands;
345*15dc779aSAndroid Build Coastguard Worker if (ptr_header_data->alter_scale == 0) {
346*15dc779aSAndroid Build Coastguard Worker dk = 1;
347*15dc779aSAndroid Build Coastguard Worker num_bands = (WORD16)(k2 - k0);
348*15dc779aSAndroid Build Coastguard Worker num_bands = num_bands - (num_bands & 0x1);
349*15dc779aSAndroid Build Coastguard Worker } else {
350*15dc779aSAndroid Build Coastguard Worker dk = 2;
351*15dc779aSAndroid Build Coastguard Worker num_bands = (WORD16)((k2 - k0) + 2) >> 2;
352*15dc779aSAndroid Build Coastguard Worker num_bands = num_bands << 1;
353*15dc779aSAndroid Build Coastguard Worker }
354*15dc779aSAndroid Build Coastguard Worker if (num_bands < 1) {
355*15dc779aSAndroid Build Coastguard Worker return -1;
356*15dc779aSAndroid Build Coastguard Worker }
357*15dc779aSAndroid Build Coastguard Worker k2_achived = k0 + (num_bands << (dk - 1));
358*15dc779aSAndroid Build Coastguard Worker
359*15dc779aSAndroid Build Coastguard Worker k2_diff = k2 - k2_achived;
360*15dc779aSAndroid Build Coastguard Worker
361*15dc779aSAndroid Build Coastguard Worker for (k = 0; k < num_bands; k++) {
362*15dc779aSAndroid Build Coastguard Worker vec_dk[k] = dk;
363*15dc779aSAndroid Build Coastguard Worker }
364*15dc779aSAndroid Build Coastguard Worker
365*15dc779aSAndroid Build Coastguard Worker if (k2_diff < 0) {
366*15dc779aSAndroid Build Coastguard Worker incr = 1;
367*15dc779aSAndroid Build Coastguard Worker k = 0;
368*15dc779aSAndroid Build Coastguard Worker }
369*15dc779aSAndroid Build Coastguard Worker if (k2_diff > 0) {
370*15dc779aSAndroid Build Coastguard Worker incr = -1;
371*15dc779aSAndroid Build Coastguard Worker k = sub_d(num_bands, 1);
372*15dc779aSAndroid Build Coastguard Worker }
373*15dc779aSAndroid Build Coastguard Worker while (k2_diff != 0) {
374*15dc779aSAndroid Build Coastguard Worker vec_dk[k] = vec_dk[k] - incr;
375*15dc779aSAndroid Build Coastguard Worker k = (WORD16)(k + incr);
376*15dc779aSAndroid Build Coastguard Worker k2_diff = k2_diff + incr;
377*15dc779aSAndroid Build Coastguard Worker }
378*15dc779aSAndroid Build Coastguard Worker f_master_tbl[0] = k0;
379*15dc779aSAndroid Build Coastguard Worker for (k = 1; k <= num_bands; k++)
380*15dc779aSAndroid Build Coastguard Worker f_master_tbl[k] = f_master_tbl[k - 1] + vec_dk[k - 1];
381*15dc779aSAndroid Build Coastguard Worker num_mf_bands = num_bands;
382*15dc779aSAndroid Build Coastguard Worker } else {
383*15dc779aSAndroid Build Coastguard Worker WORD32 num_bands0;
384*15dc779aSAndroid Build Coastguard Worker WORD32 num_bands1;
385*15dc779aSAndroid Build Coastguard Worker
386*15dc779aSAndroid Build Coastguard Worker switch (ptr_header_data->freq_scale) {
387*15dc779aSAndroid Build Coastguard Worker case 1:
388*15dc779aSAndroid Build Coastguard Worker bands = 12;
389*15dc779aSAndroid Build Coastguard Worker break;
390*15dc779aSAndroid Build Coastguard Worker case 2:
391*15dc779aSAndroid Build Coastguard Worker bands = 10;
392*15dc779aSAndroid Build Coastguard Worker break;
393*15dc779aSAndroid Build Coastguard Worker case 3:
394*15dc779aSAndroid Build Coastguard Worker bands = 8;
395*15dc779aSAndroid Build Coastguard Worker break;
396*15dc779aSAndroid Build Coastguard Worker default:
397*15dc779aSAndroid Build Coastguard Worker bands = 8;
398*15dc779aSAndroid Build Coastguard Worker };
399*15dc779aSAndroid Build Coastguard Worker
400*15dc779aSAndroid Build Coastguard Worker if ((upsamp_fac == 4) && (k0 < bands)) {
401*15dc779aSAndroid Build Coastguard Worker bands = ((WORD32)(k0 - (k0 & 1)));
402*15dc779aSAndroid Build Coastguard Worker }
403*15dc779aSAndroid Build Coastguard Worker
404*15dc779aSAndroid Build Coastguard Worker if ((WORD32)(10000 * k2) > (WORD32)(22449 * k0)) {
405*15dc779aSAndroid Build Coastguard Worker k1 = k0 << 1;
406*15dc779aSAndroid Build Coastguard Worker
407*15dc779aSAndroid Build Coastguard Worker num_bands0 = bands;
408*15dc779aSAndroid Build Coastguard Worker
409*15dc779aSAndroid Build Coastguard Worker num_bands1 = pstr_common_tables->log_dual_is_table[k2] -
410*15dc779aSAndroid Build Coastguard Worker pstr_common_tables->log_dual_is_table[k1];
411*15dc779aSAndroid Build Coastguard Worker num_bands1 = bands * num_bands1;
412*15dc779aSAndroid Build Coastguard Worker
413*15dc779aSAndroid Build Coastguard Worker if (ptr_header_data->alter_scale) {
414*15dc779aSAndroid Build Coastguard Worker num_bands1 = (WORD32)(((WORD64)num_bands1 * (0x6276)) >> 15);
415*15dc779aSAndroid Build Coastguard Worker }
416*15dc779aSAndroid Build Coastguard Worker num_bands1 = num_bands1 + 0x1000;
417*15dc779aSAndroid Build Coastguard Worker
418*15dc779aSAndroid Build Coastguard Worker num_bands1 = num_bands1 >> 13;
419*15dc779aSAndroid Build Coastguard Worker num_bands1 = num_bands1 << 1;
420*15dc779aSAndroid Build Coastguard Worker
421*15dc779aSAndroid Build Coastguard Worker if (num_bands0 < 1) {
422*15dc779aSAndroid Build Coastguard Worker return -1;
423*15dc779aSAndroid Build Coastguard Worker }
424*15dc779aSAndroid Build Coastguard Worker
425*15dc779aSAndroid Build Coastguard Worker if (num_bands1 < 1) {
426*15dc779aSAndroid Build Coastguard Worker return -1;
427*15dc779aSAndroid Build Coastguard Worker }
428*15dc779aSAndroid Build Coastguard Worker
429*15dc779aSAndroid Build Coastguard Worker ixheaacd_calc_bands(vec_dk0, k0, k1, (WORD16)num_bands0);
430*15dc779aSAndroid Build Coastguard Worker
431*15dc779aSAndroid Build Coastguard Worker ixheaacd_aac_shellsort(vec_dk0, num_bands0);
432*15dc779aSAndroid Build Coastguard Worker
433*15dc779aSAndroid Build Coastguard Worker f_master_tbl[0] = k0;
434*15dc779aSAndroid Build Coastguard Worker
435*15dc779aSAndroid Build Coastguard Worker for (k = 1; k <= num_bands0; k++)
436*15dc779aSAndroid Build Coastguard Worker f_master_tbl[k] = f_master_tbl[k - 1] + vec_dk0[k - 1];
437*15dc779aSAndroid Build Coastguard Worker
438*15dc779aSAndroid Build Coastguard Worker ixheaacd_calc_bands(vec_dk1, k1, k2, (WORD16)num_bands1);
439*15dc779aSAndroid Build Coastguard Worker ixheaacd_aac_shellsort(vec_dk1, num_bands1);
440*15dc779aSAndroid Build Coastguard Worker
441*15dc779aSAndroid Build Coastguard Worker if (vec_dk1[0] < vec_dk0[num_bands0 - 1]) {
442*15dc779aSAndroid Build Coastguard Worker WORD16 change = vec_dk0[num_bands0 - 1] - vec_dk1[0];
443*15dc779aSAndroid Build Coastguard Worker WORD16 temp = vec_dk1[num_bands1 - 1] - vec_dk1[0];
444*15dc779aSAndroid Build Coastguard Worker temp = temp >> 1;
445*15dc779aSAndroid Build Coastguard Worker if (change > temp) {
446*15dc779aSAndroid Build Coastguard Worker change = temp;
447*15dc779aSAndroid Build Coastguard Worker }
448*15dc779aSAndroid Build Coastguard Worker vec_dk1[0] = vec_dk1[0] + change;
449*15dc779aSAndroid Build Coastguard Worker vec_dk1[num_bands1 - 1] = vec_dk1[num_bands1 - 1] - change;
450*15dc779aSAndroid Build Coastguard Worker ixheaacd_aac_shellsort(vec_dk1, num_bands1);
451*15dc779aSAndroid Build Coastguard Worker }
452*15dc779aSAndroid Build Coastguard Worker
453*15dc779aSAndroid Build Coastguard Worker f_master_tbl[num_bands0] = k1;
454*15dc779aSAndroid Build Coastguard Worker for (k = 1; k <= num_bands1; k++)
455*15dc779aSAndroid Build Coastguard Worker f_master_tbl[num_bands0 + k] =
456*15dc779aSAndroid Build Coastguard Worker f_master_tbl[num_bands0 + k - 1] + vec_dk1[k - 1];
457*15dc779aSAndroid Build Coastguard Worker num_mf_bands = add_d(num_bands0, num_bands1);
458*15dc779aSAndroid Build Coastguard Worker } else {
459*15dc779aSAndroid Build Coastguard Worker k1 = k2;
460*15dc779aSAndroid Build Coastguard Worker
461*15dc779aSAndroid Build Coastguard Worker num_bands0 = pstr_common_tables->log_dual_is_table[k1] -
462*15dc779aSAndroid Build Coastguard Worker pstr_common_tables->log_dual_is_table[k0];
463*15dc779aSAndroid Build Coastguard Worker
464*15dc779aSAndroid Build Coastguard Worker num_bands0 = bands * num_bands0;
465*15dc779aSAndroid Build Coastguard Worker
466*15dc779aSAndroid Build Coastguard Worker num_bands0 = num_bands0 + 0x1000;
467*15dc779aSAndroid Build Coastguard Worker
468*15dc779aSAndroid Build Coastguard Worker num_bands0 = num_bands0 >> 13;
469*15dc779aSAndroid Build Coastguard Worker num_bands0 = num_bands0 << 1;
470*15dc779aSAndroid Build Coastguard Worker
471*15dc779aSAndroid Build Coastguard Worker if (num_bands0 < 1) {
472*15dc779aSAndroid Build Coastguard Worker return -1;
473*15dc779aSAndroid Build Coastguard Worker }
474*15dc779aSAndroid Build Coastguard Worker ixheaacd_calc_bands(vec_dk0, k0, k1, (WORD16)num_bands0);
475*15dc779aSAndroid Build Coastguard Worker ixheaacd_aac_shellsort(vec_dk0, num_bands0);
476*15dc779aSAndroid Build Coastguard Worker
477*15dc779aSAndroid Build Coastguard Worker if (vec_dk0[0] == 0) {
478*15dc779aSAndroid Build Coastguard Worker return -1;
479*15dc779aSAndroid Build Coastguard Worker }
480*15dc779aSAndroid Build Coastguard Worker
481*15dc779aSAndroid Build Coastguard Worker f_master_tbl[0] = k0;
482*15dc779aSAndroid Build Coastguard Worker for (k = 1; k <= num_bands0; k++)
483*15dc779aSAndroid Build Coastguard Worker f_master_tbl[k] = f_master_tbl[k - 1] + vec_dk0[k - 1];
484*15dc779aSAndroid Build Coastguard Worker
485*15dc779aSAndroid Build Coastguard Worker num_mf_bands = num_bands0;
486*15dc779aSAndroid Build Coastguard Worker }
487*15dc779aSAndroid Build Coastguard Worker }
488*15dc779aSAndroid Build Coastguard Worker if (num_mf_bands < 1) {
489*15dc779aSAndroid Build Coastguard Worker return -1;
490*15dc779aSAndroid Build Coastguard Worker }
491*15dc779aSAndroid Build Coastguard Worker pstr_freq_band_data->num_mf_bands = num_mf_bands;
492*15dc779aSAndroid Build Coastguard Worker
493*15dc779aSAndroid Build Coastguard Worker if (upsamp_fac == 4) {
494*15dc779aSAndroid Build Coastguard Worker for (k = 1; k < num_mf_bands; k++) {
495*15dc779aSAndroid Build Coastguard Worker if (!(f_master_tbl[k] - f_master_tbl[k - 1] <= k0 - 2)) {
496*15dc779aSAndroid Build Coastguard Worker return -1;
497*15dc779aSAndroid Build Coastguard Worker }
498*15dc779aSAndroid Build Coastguard Worker }
499*15dc779aSAndroid Build Coastguard Worker }
500*15dc779aSAndroid Build Coastguard Worker
501*15dc779aSAndroid Build Coastguard Worker return 0;
502*15dc779aSAndroid Build Coastguard Worker }
503*15dc779aSAndroid Build Coastguard Worker
ixheaacd_calc_freq_ratio(WORD16 k_start,WORD16 k_stop,WORD16 num_bands)504*15dc779aSAndroid Build Coastguard Worker static WORD16 ixheaacd_calc_freq_ratio(WORD16 k_start, WORD16 k_stop,
505*15dc779aSAndroid Build Coastguard Worker WORD16 num_bands) {
506*15dc779aSAndroid Build Coastguard Worker WORD32 bandfactor;
507*15dc779aSAndroid Build Coastguard Worker WORD32 step;
508*15dc779aSAndroid Build Coastguard Worker WORD32 direction;
509*15dc779aSAndroid Build Coastguard Worker WORD32 start;
510*15dc779aSAndroid Build Coastguard Worker WORD32 stop;
511*15dc779aSAndroid Build Coastguard Worker WORD32 temp;
512*15dc779aSAndroid Build Coastguard Worker WORD32 j, i;
513*15dc779aSAndroid Build Coastguard Worker
514*15dc779aSAndroid Build Coastguard Worker bandfactor = 0x3f000000L;
515*15dc779aSAndroid Build Coastguard Worker step = 0x20000000L;
516*15dc779aSAndroid Build Coastguard Worker direction = 1;
517*15dc779aSAndroid Build Coastguard Worker start = ixheaac_shl32(ixheaac_deposit16l_in32(k_start), INT_BITS - 8);
518*15dc779aSAndroid Build Coastguard Worker stop = ixheaac_shl32(ixheaac_deposit16l_in32(k_stop), INT_BITS - 8);
519*15dc779aSAndroid Build Coastguard Worker
520*15dc779aSAndroid Build Coastguard Worker i = 0;
521*15dc779aSAndroid Build Coastguard Worker
522*15dc779aSAndroid Build Coastguard Worker do {
523*15dc779aSAndroid Build Coastguard Worker i = i + 1;
524*15dc779aSAndroid Build Coastguard Worker temp = stop;
525*15dc779aSAndroid Build Coastguard Worker
526*15dc779aSAndroid Build Coastguard Worker for (j = 0; j < num_bands; j++)
527*15dc779aSAndroid Build Coastguard Worker temp = ixheaac_mult16x16in32_shl(ixheaac_extract16h(temp),
528*15dc779aSAndroid Build Coastguard Worker ixheaac_extract16h(bandfactor));
529*15dc779aSAndroid Build Coastguard Worker
530*15dc779aSAndroid Build Coastguard Worker if (temp < start) {
531*15dc779aSAndroid Build Coastguard Worker if (direction == 0) step = ixheaac_shr32(step, 1);
532*15dc779aSAndroid Build Coastguard Worker direction = 1;
533*15dc779aSAndroid Build Coastguard Worker bandfactor = ixheaac_add32_sat(bandfactor, step);
534*15dc779aSAndroid Build Coastguard Worker } else {
535*15dc779aSAndroid Build Coastguard Worker if (direction == 1) step = ixheaac_shr32(step, 1);
536*15dc779aSAndroid Build Coastguard Worker direction = 0;
537*15dc779aSAndroid Build Coastguard Worker bandfactor = ixheaac_sub32_sat(bandfactor, step);
538*15dc779aSAndroid Build Coastguard Worker }
539*15dc779aSAndroid Build Coastguard Worker
540*15dc779aSAndroid Build Coastguard Worker if (i > 100) {
541*15dc779aSAndroid Build Coastguard Worker step = 0;
542*15dc779aSAndroid Build Coastguard Worker }
543*15dc779aSAndroid Build Coastguard Worker } while (step > 0);
544*15dc779aSAndroid Build Coastguard Worker
545*15dc779aSAndroid Build Coastguard Worker return ixheaac_extract16h(bandfactor);
546*15dc779aSAndroid Build Coastguard Worker }
547*15dc779aSAndroid Build Coastguard Worker
ixheaacd_calc_bands(WORD16 * diff,WORD16 start,WORD16 stop,WORD16 num_bands)548*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_calc_bands(WORD16 *diff, WORD16 start, WORD16 stop,
549*15dc779aSAndroid Build Coastguard Worker WORD16 num_bands) {
550*15dc779aSAndroid Build Coastguard Worker WORD32 i;
551*15dc779aSAndroid Build Coastguard Worker WORD32 previous;
552*15dc779aSAndroid Build Coastguard Worker WORD32 current;
553*15dc779aSAndroid Build Coastguard Worker WORD32 temp, exact;
554*15dc779aSAndroid Build Coastguard Worker WORD16 bandfactor = ixheaacd_calc_freq_ratio(start, stop, num_bands);
555*15dc779aSAndroid Build Coastguard Worker
556*15dc779aSAndroid Build Coastguard Worker previous = stop;
557*15dc779aSAndroid Build Coastguard Worker exact = ixheaac_shl32_sat(ixheaac_deposit16l_in32(stop), INT_BITS - 8);
558*15dc779aSAndroid Build Coastguard Worker
559*15dc779aSAndroid Build Coastguard Worker for (i = num_bands - 1; i >= 0; i--) {
560*15dc779aSAndroid Build Coastguard Worker exact = ixheaac_mult16x16in32(ixheaac_extract16h(exact), bandfactor);
561*15dc779aSAndroid Build Coastguard Worker
562*15dc779aSAndroid Build Coastguard Worker temp = ixheaac_add32_sat(exact, 0x00400000);
563*15dc779aSAndroid Build Coastguard Worker exact = exact << 1;
564*15dc779aSAndroid Build Coastguard Worker
565*15dc779aSAndroid Build Coastguard Worker current = ixheaac_extract16l(ixheaac_shr32(temp, (INT_BITS - 9)));
566*15dc779aSAndroid Build Coastguard Worker
567*15dc779aSAndroid Build Coastguard Worker diff[i] = sub_d(previous, current);
568*15dc779aSAndroid Build Coastguard Worker previous = current;
569*15dc779aSAndroid Build Coastguard Worker }
570*15dc779aSAndroid Build Coastguard Worker }
571*15dc779aSAndroid Build Coastguard Worker
ixheaacd_derive_hi_lo_freq_bnd_tbls(ia_freq_band_data_struct * pstr_freq_band_data,ia_sbr_header_data_struct * ptr_header_data)572*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_derive_hi_lo_freq_bnd_tbls(
573*15dc779aSAndroid Build Coastguard Worker ia_freq_band_data_struct *pstr_freq_band_data,
574*15dc779aSAndroid Build Coastguard Worker ia_sbr_header_data_struct *ptr_header_data) {
575*15dc779aSAndroid Build Coastguard Worker WORD16 k;
576*15dc779aSAndroid Build Coastguard Worker WORD16 xover_band = ptr_header_data->xover_band;
577*15dc779aSAndroid Build Coastguard Worker WORD16 *f_master_tbl = pstr_freq_band_data->f_master_tbl + xover_band;
578*15dc779aSAndroid Build Coastguard Worker WORD16 *f_low_tbl = pstr_freq_band_data->freq_band_table[LOW];
579*15dc779aSAndroid Build Coastguard Worker WORD16 *f_high_tbl = pstr_freq_band_data->freq_band_table[HIGH];
580*15dc779aSAndroid Build Coastguard Worker WORD16 num_mf_bands = pstr_freq_band_data->num_mf_bands;
581*15dc779aSAndroid Build Coastguard Worker WORD16 num_lf_bands, num_hf_bands;
582*15dc779aSAndroid Build Coastguard Worker num_hf_bands = num_mf_bands - xover_band;
583*15dc779aSAndroid Build Coastguard Worker k = 0;
584*15dc779aSAndroid Build Coastguard Worker *f_low_tbl = *f_high_tbl = *f_master_tbl;
585*15dc779aSAndroid Build Coastguard Worker f_low_tbl++;
586*15dc779aSAndroid Build Coastguard Worker f_high_tbl++;
587*15dc779aSAndroid Build Coastguard Worker f_master_tbl++;
588*15dc779aSAndroid Build Coastguard Worker k++;
589*15dc779aSAndroid Build Coastguard Worker if ((num_hf_bands & 1)) {
590*15dc779aSAndroid Build Coastguard Worker *f_low_tbl = *f_high_tbl = *f_master_tbl;
591*15dc779aSAndroid Build Coastguard Worker f_high_tbl++;
592*15dc779aSAndroid Build Coastguard Worker f_master_tbl++;
593*15dc779aSAndroid Build Coastguard Worker f_low_tbl++;
594*15dc779aSAndroid Build Coastguard Worker k++;
595*15dc779aSAndroid Build Coastguard Worker }
596*15dc779aSAndroid Build Coastguard Worker for (; k <= num_hf_bands; k++) {
597*15dc779aSAndroid Build Coastguard Worker *f_high_tbl = *f_master_tbl;
598*15dc779aSAndroid Build Coastguard Worker f_high_tbl++;
599*15dc779aSAndroid Build Coastguard Worker f_master_tbl++;
600*15dc779aSAndroid Build Coastguard Worker k++;
601*15dc779aSAndroid Build Coastguard Worker
602*15dc779aSAndroid Build Coastguard Worker *f_low_tbl = *f_high_tbl = *f_master_tbl;
603*15dc779aSAndroid Build Coastguard Worker f_high_tbl++;
604*15dc779aSAndroid Build Coastguard Worker f_master_tbl++;
605*15dc779aSAndroid Build Coastguard Worker f_low_tbl++;
606*15dc779aSAndroid Build Coastguard Worker }
607*15dc779aSAndroid Build Coastguard Worker num_lf_bands = ((num_hf_bands + 1) >> 1);
608*15dc779aSAndroid Build Coastguard Worker
609*15dc779aSAndroid Build Coastguard Worker pstr_freq_band_data->num_sf_bands[LOW] = num_lf_bands;
610*15dc779aSAndroid Build Coastguard Worker pstr_freq_band_data->num_sf_bands[HIGH] = num_hf_bands;
611*15dc779aSAndroid Build Coastguard Worker }
612*15dc779aSAndroid Build Coastguard Worker
ixheaacd_derive_noise_freq_bnd_tbl(ia_sbr_header_data_struct * ptr_header_data,ixheaacd_misc_tables * pstr_common_tables,ia_freq_band_data_struct * pstr_freq_band_data)613*15dc779aSAndroid Build Coastguard Worker WORD32 ixheaacd_derive_noise_freq_bnd_tbl(
614*15dc779aSAndroid Build Coastguard Worker ia_sbr_header_data_struct *ptr_header_data,
615*15dc779aSAndroid Build Coastguard Worker ixheaacd_misc_tables *pstr_common_tables,
616*15dc779aSAndroid Build Coastguard Worker ia_freq_band_data_struct *pstr_freq_band_data) {
617*15dc779aSAndroid Build Coastguard Worker WORD16 k2, kx;
618*15dc779aSAndroid Build Coastguard Worker WORD32 temp;
619*15dc779aSAndroid Build Coastguard Worker WORD32 num_lf_bands = pstr_freq_band_data->num_sf_bands[LOW];
620*15dc779aSAndroid Build Coastguard Worker WORD32 num_hf_bands = pstr_freq_band_data->num_sf_bands[HIGH];
621*15dc779aSAndroid Build Coastguard Worker k2 = pstr_freq_band_data->freq_band_table[HIGH][num_hf_bands];
622*15dc779aSAndroid Build Coastguard Worker kx = pstr_freq_band_data->freq_band_table[HIGH][0];
623*15dc779aSAndroid Build Coastguard Worker
624*15dc779aSAndroid Build Coastguard Worker if (ptr_header_data->noise_bands == 0) {
625*15dc779aSAndroid Build Coastguard Worker temp = 1;
626*15dc779aSAndroid Build Coastguard Worker } else {
627*15dc779aSAndroid Build Coastguard Worker temp = pstr_common_tables->log_dual_is_table[k2] -
628*15dc779aSAndroid Build Coastguard Worker pstr_common_tables->log_dual_is_table[kx];
629*15dc779aSAndroid Build Coastguard Worker temp = temp * ptr_header_data->noise_bands;
630*15dc779aSAndroid Build Coastguard Worker temp = temp + 0x800;
631*15dc779aSAndroid Build Coastguard Worker temp = temp >> 12;
632*15dc779aSAndroid Build Coastguard Worker if (temp == 0) {
633*15dc779aSAndroid Build Coastguard Worker temp = 1;
634*15dc779aSAndroid Build Coastguard Worker }
635*15dc779aSAndroid Build Coastguard Worker }
636*15dc779aSAndroid Build Coastguard Worker if (temp > MAX_NOISE_COEFFS) {
637*15dc779aSAndroid Build Coastguard Worker return -1;
638*15dc779aSAndroid Build Coastguard Worker }
639*15dc779aSAndroid Build Coastguard Worker pstr_freq_band_data->num_nf_bands = temp;
640*15dc779aSAndroid Build Coastguard Worker pstr_freq_band_data->num_if_bands = pstr_freq_band_data->num_nf_bands;
641*15dc779aSAndroid Build Coastguard Worker {
642*15dc779aSAndroid Build Coastguard Worker WORD16 i_k, k;
643*15dc779aSAndroid Build Coastguard Worker WORD16 num, den;
644*15dc779aSAndroid Build Coastguard Worker WORD16 *f_noise_tbl = pstr_freq_band_data->freq_band_tbl_noise;
645*15dc779aSAndroid Build Coastguard Worker WORD16 *f_low_tbl = pstr_freq_band_data->freq_band_table[LOW];
646*15dc779aSAndroid Build Coastguard Worker WORD32 num_nf_bands = pstr_freq_band_data->num_nf_bands;
647*15dc779aSAndroid Build Coastguard Worker
648*15dc779aSAndroid Build Coastguard Worker num = num_lf_bands;
649*15dc779aSAndroid Build Coastguard Worker den = num_nf_bands;
650*15dc779aSAndroid Build Coastguard Worker
651*15dc779aSAndroid Build Coastguard Worker k = 0;
652*15dc779aSAndroid Build Coastguard Worker *f_noise_tbl = f_low_tbl[0];
653*15dc779aSAndroid Build Coastguard Worker f_noise_tbl++;
654*15dc779aSAndroid Build Coastguard Worker k++;
655*15dc779aSAndroid Build Coastguard Worker i_k = 0;
656*15dc779aSAndroid Build Coastguard Worker
657*15dc779aSAndroid Build Coastguard Worker for (; k <= num_nf_bands; k++) {
658*15dc779aSAndroid Build Coastguard Worker i_k = i_k + (WORD16)ixheaacd_int_div(num, den);
659*15dc779aSAndroid Build Coastguard Worker *f_noise_tbl = f_low_tbl[i_k];
660*15dc779aSAndroid Build Coastguard Worker num = num_lf_bands - i_k;
661*15dc779aSAndroid Build Coastguard Worker den = den - 1;
662*15dc779aSAndroid Build Coastguard Worker f_noise_tbl++;
663*15dc779aSAndroid Build Coastguard Worker }
664*15dc779aSAndroid Build Coastguard Worker }
665*15dc779aSAndroid Build Coastguard Worker return 0;
666*15dc779aSAndroid Build Coastguard Worker }
667*15dc779aSAndroid Build Coastguard Worker
ixheaacd_calc_frq_bnd_tbls(ia_sbr_header_data_struct * ptr_header_data,ixheaacd_misc_tables * pstr_common_tables)668*15dc779aSAndroid Build Coastguard Worker WORD32 ixheaacd_calc_frq_bnd_tbls(ia_sbr_header_data_struct *ptr_header_data,
669*15dc779aSAndroid Build Coastguard Worker ixheaacd_misc_tables *pstr_common_tables) {
670*15dc779aSAndroid Build Coastguard Worker WORD32 err;
671*15dc779aSAndroid Build Coastguard Worker WORD16 num_lf_bands, lsb, usb;
672*15dc779aSAndroid Build Coastguard Worker ia_freq_band_data_struct *pstr_freq_band_data =
673*15dc779aSAndroid Build Coastguard Worker ptr_header_data->pstr_freq_band_data;
674*15dc779aSAndroid Build Coastguard Worker
675*15dc779aSAndroid Build Coastguard Worker err = ixheaacd_calc_master_frq_bnd_tbl(pstr_freq_band_data, ptr_header_data,
676*15dc779aSAndroid Build Coastguard Worker pstr_common_tables);
677*15dc779aSAndroid Build Coastguard Worker
678*15dc779aSAndroid Build Coastguard Worker if (err ||
679*15dc779aSAndroid Build Coastguard Worker (ptr_header_data->xover_band > pstr_freq_band_data->num_mf_bands)) {
680*15dc779aSAndroid Build Coastguard Worker return -1;
681*15dc779aSAndroid Build Coastguard Worker }
682*15dc779aSAndroid Build Coastguard Worker
683*15dc779aSAndroid Build Coastguard Worker ixheaacd_derive_hi_lo_freq_bnd_tbls(pstr_freq_band_data, ptr_header_data);
684*15dc779aSAndroid Build Coastguard Worker
685*15dc779aSAndroid Build Coastguard Worker num_lf_bands = pstr_freq_band_data->num_sf_bands[LOW];
686*15dc779aSAndroid Build Coastguard Worker
687*15dc779aSAndroid Build Coastguard Worker if ((num_lf_bands <= 0) ||
688*15dc779aSAndroid Build Coastguard Worker (num_lf_bands > ixheaac_shr16(MAX_FREQ_COEFFS, 1))) {
689*15dc779aSAndroid Build Coastguard Worker return -1;
690*15dc779aSAndroid Build Coastguard Worker }
691*15dc779aSAndroid Build Coastguard Worker
692*15dc779aSAndroid Build Coastguard Worker lsb = pstr_freq_band_data->freq_band_table[LOW][0];
693*15dc779aSAndroid Build Coastguard Worker usb = pstr_freq_band_data->freq_band_table[LOW][num_lf_bands];
694*15dc779aSAndroid Build Coastguard Worker
695*15dc779aSAndroid Build Coastguard Worker pstr_freq_band_data->sub_band_start = lsb;
696*15dc779aSAndroid Build Coastguard Worker
697*15dc779aSAndroid Build Coastguard Worker ptr_header_data->status = 1;
698*15dc779aSAndroid Build Coastguard Worker
699*15dc779aSAndroid Build Coastguard Worker if ((lsb > NO_ANALYSIS_CHANNELS) || (lsb >= usb)) {
700*15dc779aSAndroid Build Coastguard Worker return -1;
701*15dc779aSAndroid Build Coastguard Worker }
702*15dc779aSAndroid Build Coastguard Worker
703*15dc779aSAndroid Build Coastguard Worker if (ixheaacd_derive_noise_freq_bnd_tbl(ptr_header_data, pstr_common_tables,
704*15dc779aSAndroid Build Coastguard Worker pstr_freq_band_data)) {
705*15dc779aSAndroid Build Coastguard Worker return -1;
706*15dc779aSAndroid Build Coastguard Worker }
707*15dc779aSAndroid Build Coastguard Worker
708*15dc779aSAndroid Build Coastguard Worker pstr_freq_band_data->sub_band_start = lsb;
709*15dc779aSAndroid Build Coastguard Worker pstr_freq_band_data->sub_band_end = usb;
710*15dc779aSAndroid Build Coastguard Worker
711*15dc779aSAndroid Build Coastguard Worker return 0;
712*15dc779aSAndroid Build Coastguard Worker }
713