xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_tns.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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 <math.h>
21*15dc779aSAndroid Build Coastguard Worker #include <stdio.h>
22*15dc779aSAndroid Build Coastguard Worker 
23*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
24*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_bitbuffer.h"
25*15dc779aSAndroid Build Coastguard Worker 
26*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_interface.h"
27*15dc779aSAndroid Build Coastguard Worker 
28*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_tns_usac.h"
29*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_cnst.h"
30*15dc779aSAndroid Build Coastguard Worker 
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_acelp_info.h"
32*15dc779aSAndroid Build Coastguard Worker 
33*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecsettings.h"
34*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_info.h"
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_common.h"
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_data_struct.h"
37*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_dec.h"
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecoder.h"
39*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_mps_polyphase.h"
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_sbr_const.h"
41*15dc779aSAndroid Build Coastguard Worker 
42*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_defines.h"
43*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_struct_def.h"
44*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_main.h"
45*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_arith_dec.h"
46*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_function_selector.h"
47*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_constants.h"
48*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops32.h"
49*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops40.h"
50*15dc779aSAndroid Build Coastguard Worker 
51*15dc779aSAndroid Build Coastguard Worker #define sfb_offset(x) (((x) > 0) ? sfb_top[(x)-1] : 0)
52*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_tns_dec_coef_usac(ia_usac_data_struct * usac_data,ia_tns_filter_struct * filter,WORD32 coef_res,WORD32 * par_coeff)53*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_tns_dec_coef_usac(ia_usac_data_struct *usac_data,
54*15dc779aSAndroid Build Coastguard Worker                                        ia_tns_filter_struct *filter,
55*15dc779aSAndroid Build Coastguard Worker                                        WORD32 coef_res, WORD32 *par_coeff) {
56*15dc779aSAndroid Build Coastguard Worker   WORD32 resolution;
57*15dc779aSAndroid Build Coastguard Worker   WORD32 *ptr_par_coeff = par_coeff;
58*15dc779aSAndroid Build Coastguard Worker   const WORD32 *tns_coeff_ptr;
59*15dc779aSAndroid Build Coastguard Worker   WORD32 ixheaacd_drc_offset = 4;
60*15dc779aSAndroid Build Coastguard Worker   WORD16 *ptr_coeff = filter->coef;
61*15dc779aSAndroid Build Coastguard Worker   WORD32 order;
62*15dc779aSAndroid Build Coastguard Worker 
63*15dc779aSAndroid Build Coastguard Worker   resolution = coef_res - 3;
64*15dc779aSAndroid Build Coastguard Worker   tns_coeff_ptr = usac_data->tns_coeff3_32;
65*15dc779aSAndroid Build Coastguard Worker   if (resolution) {
66*15dc779aSAndroid Build Coastguard Worker     tns_coeff_ptr = usac_data->tns_coeff4_32;
67*15dc779aSAndroid Build Coastguard Worker     ixheaacd_drc_offset = ixheaacd_drc_offset << 1;
68*15dc779aSAndroid Build Coastguard Worker   }
69*15dc779aSAndroid Build Coastguard Worker   order = filter->order;
70*15dc779aSAndroid Build Coastguard Worker 
71*15dc779aSAndroid Build Coastguard Worker   do {
72*15dc779aSAndroid Build Coastguard Worker     WORD16 temp = *ptr_coeff++;
73*15dc779aSAndroid Build Coastguard Worker     *ptr_par_coeff++ = tns_coeff_ptr[temp + ixheaacd_drc_offset];
74*15dc779aSAndroid Build Coastguard Worker     order--;
75*15dc779aSAndroid Build Coastguard Worker   } while (order != 0);
76*15dc779aSAndroid Build Coastguard Worker }
77*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_tns_parcor_lpc_convert_usac(WORD32 * parcor,WORD32 * lpc_coeff,WORD32 * scale,WORD order)78*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_tns_parcor_lpc_convert_usac(WORD32 *parcor,
79*15dc779aSAndroid Build Coastguard Worker                                                  WORD32 *lpc_coeff,
80*15dc779aSAndroid Build Coastguard Worker                                                  WORD32 *scale, WORD order)
81*15dc779aSAndroid Build Coastguard Worker 
82*15dc779aSAndroid Build Coastguard Worker {
83*15dc779aSAndroid Build Coastguard Worker   WORD i, j, status;
84*15dc779aSAndroid Build Coastguard Worker   WORD32 accu;
85*15dc779aSAndroid Build Coastguard Worker   WORD32 temp_buf1[TNS_MAX_ORDER + 1];
86*15dc779aSAndroid Build Coastguard Worker   WORD32 temp_buf2[TNS_MAX_ORDER + 1];
87*15dc779aSAndroid Build Coastguard Worker   WORD32 accu1, accu2;
88*15dc779aSAndroid Build Coastguard Worker 
89*15dc779aSAndroid Build Coastguard Worker   status = 1;
90*15dc779aSAndroid Build Coastguard Worker   *scale = 1;
91*15dc779aSAndroid Build Coastguard Worker 
92*15dc779aSAndroid Build Coastguard Worker   while (status) {
93*15dc779aSAndroid Build Coastguard Worker     status = 0;
94*15dc779aSAndroid Build Coastguard Worker 
95*15dc779aSAndroid Build Coastguard Worker     for (i = TNS_MAX_ORDER; i >= 0; i--) {
96*15dc779aSAndroid Build Coastguard Worker       temp_buf1[i] = 0;
97*15dc779aSAndroid Build Coastguard Worker       temp_buf2[i] = 0;
98*15dc779aSAndroid Build Coastguard Worker     }
99*15dc779aSAndroid Build Coastguard Worker 
100*15dc779aSAndroid Build Coastguard Worker     accu1 = (0x40000000 >> (*scale - 1));
101*15dc779aSAndroid Build Coastguard Worker 
102*15dc779aSAndroid Build Coastguard Worker     for (i = 0; i <= order; i++) {
103*15dc779aSAndroid Build Coastguard Worker       accu = accu1;
104*15dc779aSAndroid Build Coastguard Worker 
105*15dc779aSAndroid Build Coastguard Worker       for (j = 0; j < order; j++) {
106*15dc779aSAndroid Build Coastguard Worker         temp_buf2[j] = (accu1);
107*15dc779aSAndroid Build Coastguard Worker 
108*15dc779aSAndroid Build Coastguard Worker         accu1 = ixheaac_add32_sat(
109*15dc779aSAndroid Build Coastguard Worker             accu1, ixheaac_mult32_shl_sat(parcor[j], temp_buf1[j]));
110*15dc779aSAndroid Build Coastguard Worker         if (ixheaac_abs32_sat(accu1) == 0x7fffffff) status = 1;
111*15dc779aSAndroid Build Coastguard Worker       }
112*15dc779aSAndroid Build Coastguard Worker 
113*15dc779aSAndroid Build Coastguard Worker       for (j = (order - 1); j >= 0; j--) {
114*15dc779aSAndroid Build Coastguard Worker         accu2 = (temp_buf1[j]);
115*15dc779aSAndroid Build Coastguard Worker         accu2 = ixheaac_add32_sat(
116*15dc779aSAndroid Build Coastguard Worker             accu2, ixheaac_mult32_shl_sat(parcor[j], temp_buf2[j]));
117*15dc779aSAndroid Build Coastguard Worker         temp_buf1[j + 1] = (accu2);
118*15dc779aSAndroid Build Coastguard Worker 
119*15dc779aSAndroid Build Coastguard Worker         if (ixheaac_abs32_sat(accu2) == 0x7fffffff) status = 1;
120*15dc779aSAndroid Build Coastguard Worker       }
121*15dc779aSAndroid Build Coastguard Worker 
122*15dc779aSAndroid Build Coastguard Worker       temp_buf1[0] = (accu);
123*15dc779aSAndroid Build Coastguard Worker       lpc_coeff[i] = (accu1);
124*15dc779aSAndroid Build Coastguard Worker       accu1 = 0;
125*15dc779aSAndroid Build Coastguard Worker     }
126*15dc779aSAndroid Build Coastguard Worker 
127*15dc779aSAndroid Build Coastguard Worker     accu1 = (status - 1);
128*15dc779aSAndroid Build Coastguard Worker 
129*15dc779aSAndroid Build Coastguard Worker     if (accu1 == 0) {
130*15dc779aSAndroid Build Coastguard Worker       *scale = *scale + 1;
131*15dc779aSAndroid Build Coastguard Worker     }
132*15dc779aSAndroid Build Coastguard Worker   }
133*15dc779aSAndroid Build Coastguard Worker }
134*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_tns_ar_filter_usac(WORD32 * spectrum,WORD32 size,WORD32 inc,WORD32 * lpc_coeff,WORD32 order,WORD32 shift_value,WORD32 * ptr_filter_state)135*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_tns_ar_filter_usac(WORD32 *spectrum, WORD32 size,
136*15dc779aSAndroid Build Coastguard Worker                                         WORD32 inc, WORD32 *lpc_coeff,
137*15dc779aSAndroid Build Coastguard Worker                                         WORD32 order, WORD32 shift_value,
138*15dc779aSAndroid Build Coastguard Worker                                         WORD32 *ptr_filter_state) {
139*15dc779aSAndroid Build Coastguard Worker   WORD32 i, j;
140*15dc779aSAndroid Build Coastguard Worker   WORD32 y;
141*15dc779aSAndroid Build Coastguard Worker   WORD64 acc;
142*15dc779aSAndroid Build Coastguard Worker 
143*15dc779aSAndroid Build Coastguard Worker   if ((order & 3) != 0) {
144*15dc779aSAndroid Build Coastguard Worker     for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) {
145*15dc779aSAndroid Build Coastguard Worker       lpc_coeff[i] = 0;
146*15dc779aSAndroid Build Coastguard Worker     }
147*15dc779aSAndroid Build Coastguard Worker     lpc_coeff[i] = 0;
148*15dc779aSAndroid Build Coastguard Worker     order = ((order & 0xfffffffc) + 4);
149*15dc779aSAndroid Build Coastguard Worker   }
150*15dc779aSAndroid Build Coastguard Worker 
151*15dc779aSAndroid Build Coastguard Worker   for (i = 0; i < order; i++) {
152*15dc779aSAndroid Build Coastguard Worker     y = *spectrum;
153*15dc779aSAndroid Build Coastguard Worker     acc = 0;
154*15dc779aSAndroid Build Coastguard Worker 
155*15dc779aSAndroid Build Coastguard Worker     for (j = i; j > 0; j--) {
156*15dc779aSAndroid Build Coastguard Worker       acc = ixheaac_add64_sat(
157*15dc779aSAndroid Build Coastguard Worker           acc, ixheaac_mult64(ptr_filter_state[j - 1], lpc_coeff[j]));
158*15dc779aSAndroid Build Coastguard Worker       ptr_filter_state[j] = ptr_filter_state[j - 1];
159*15dc779aSAndroid Build Coastguard Worker     }
160*15dc779aSAndroid Build Coastguard Worker 
161*15dc779aSAndroid Build Coastguard Worker     y = ixheaac_sub32_sat(y, (WORD32)(acc >> 31));
162*15dc779aSAndroid Build Coastguard Worker     ptr_filter_state[0] = ixheaac_shl32(y, shift_value);
163*15dc779aSAndroid Build Coastguard Worker     *spectrum = y;
164*15dc779aSAndroid Build Coastguard Worker     spectrum += inc;
165*15dc779aSAndroid Build Coastguard Worker   }
166*15dc779aSAndroid Build Coastguard Worker 
167*15dc779aSAndroid Build Coastguard Worker   for (i = order; i < size; i++) {
168*15dc779aSAndroid Build Coastguard Worker     y = *spectrum;
169*15dc779aSAndroid Build Coastguard Worker     acc = 0;
170*15dc779aSAndroid Build Coastguard Worker     for (j = order; j > 0; j--) {
171*15dc779aSAndroid Build Coastguard Worker       acc = ixheaac_add64_sat(
172*15dc779aSAndroid Build Coastguard Worker           acc, ixheaac_mult64(ptr_filter_state[j - 1], lpc_coeff[j]));
173*15dc779aSAndroid Build Coastguard Worker       ;
174*15dc779aSAndroid Build Coastguard Worker       ptr_filter_state[j] = ptr_filter_state[j - 1];
175*15dc779aSAndroid Build Coastguard Worker     }
176*15dc779aSAndroid Build Coastguard Worker     y = ixheaac_sub32_sat(y, (WORD32)(acc >> 31));
177*15dc779aSAndroid Build Coastguard Worker     ptr_filter_state[0] = ixheaac_shl32(y, shift_value);
178*15dc779aSAndroid Build Coastguard Worker     *spectrum = y;
179*15dc779aSAndroid Build Coastguard Worker     spectrum += inc;
180*15dc779aSAndroid Build Coastguard Worker   }
181*15dc779aSAndroid Build Coastguard Worker }
182*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_tns_apply(ia_usac_data_struct * usac_data,WORD32 * spec,WORD32 nbands,ia_sfb_info_struct * pstr_sfb_info,ia_tns_frame_info_struct * pstr_tns)183*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE ixheaacd_tns_apply(ia_usac_data_struct *usac_data, WORD32 *spec,
184*15dc779aSAndroid Build Coastguard Worker                                 WORD32 nbands,
185*15dc779aSAndroid Build Coastguard Worker                                 ia_sfb_info_struct *pstr_sfb_info,
186*15dc779aSAndroid Build Coastguard Worker                                 ia_tns_frame_info_struct *pstr_tns) {
187*15dc779aSAndroid Build Coastguard Worker   WORD32 f, start, stop, size, inc;
188*15dc779aSAndroid Build Coastguard Worker   WORD32 n_filt, coef_res, order, direction;
189*15dc779aSAndroid Build Coastguard Worker   WORD32 *ptr_spec;
190*15dc779aSAndroid Build Coastguard Worker   WORD32 scale_spec;
191*15dc779aSAndroid Build Coastguard Worker   WORD32 scale_lpc;
192*15dc779aSAndroid Build Coastguard Worker   WORD32 guard_band;
193*15dc779aSAndroid Build Coastguard Worker   WORD32 shift;
194*15dc779aSAndroid Build Coastguard Worker   WORD32 lpc_coeff[TNS_MAX_ORDER + 1];
195*15dc779aSAndroid Build Coastguard Worker   WORD32 par_coeff[TNS_MAX_ORDER + 1];
196*15dc779aSAndroid Build Coastguard Worker   ia_tns_filter_struct *filt;
197*15dc779aSAndroid Build Coastguard Worker 
198*15dc779aSAndroid Build Coastguard Worker   const WORD16 *sfb_top;
199*15dc779aSAndroid Build Coastguard Worker 
200*15dc779aSAndroid Build Coastguard Worker   WORD32 nbins = (pstr_sfb_info->islong) ? 1024 : 128;
201*15dc779aSAndroid Build Coastguard Worker   WORD32 i, j, idx;
202*15dc779aSAndroid Build Coastguard Worker 
203*15dc779aSAndroid Build Coastguard Worker   idx = (pstr_sfb_info->islong) ? 0 : 1;
204*15dc779aSAndroid Build Coastguard Worker 
205*15dc779aSAndroid Build Coastguard Worker   ptr_spec = &usac_data->scratch_buffer[0];
206*15dc779aSAndroid Build Coastguard Worker 
207*15dc779aSAndroid Build Coastguard Worker   for (j = 0; j < pstr_tns->n_subblocks; j++) {
208*15dc779aSAndroid Build Coastguard Worker     sfb_top = pstr_sfb_info->ptr_sfb_tbl;
209*15dc779aSAndroid Build Coastguard Worker 
210*15dc779aSAndroid Build Coastguard Worker     for (i = 0; i < nbins; i++) {
211*15dc779aSAndroid Build Coastguard Worker       ptr_spec[i] = spec[i];
212*15dc779aSAndroid Build Coastguard Worker     }
213*15dc779aSAndroid Build Coastguard Worker 
214*15dc779aSAndroid Build Coastguard Worker     if (pstr_tns->str_tns_info[j].n_filt) {
215*15dc779aSAndroid Build Coastguard Worker       n_filt = pstr_tns->str_tns_info[j].n_filt;
216*15dc779aSAndroid Build Coastguard Worker 
217*15dc779aSAndroid Build Coastguard Worker       for (f = 0; f < n_filt; f++) {
218*15dc779aSAndroid Build Coastguard Worker         WORD32 tmp;
219*15dc779aSAndroid Build Coastguard Worker 
220*15dc779aSAndroid Build Coastguard Worker         coef_res = pstr_tns->str_tns_info[j].coef_res;
221*15dc779aSAndroid Build Coastguard Worker         filt = &pstr_tns->str_tns_info[j].str_filter[f];
222*15dc779aSAndroid Build Coastguard Worker         order = filt->order;
223*15dc779aSAndroid Build Coastguard Worker         direction = filt->direction;
224*15dc779aSAndroid Build Coastguard Worker         start = filt->start_band;
225*15dc779aSAndroid Build Coastguard Worker         stop = filt->stop_band;
226*15dc779aSAndroid Build Coastguard Worker 
227*15dc779aSAndroid Build Coastguard Worker         if (!order) continue;
228*15dc779aSAndroid Build Coastguard Worker 
229*15dc779aSAndroid Build Coastguard Worker         ixheaacd_tns_dec_coef_usac(usac_data, filt, coef_res,
230*15dc779aSAndroid Build Coastguard Worker                                    (WORD32 *)par_coeff);
231*15dc779aSAndroid Build Coastguard Worker 
232*15dc779aSAndroid Build Coastguard Worker         ixheaacd_tns_parcor_lpc_convert_usac(par_coeff, lpc_coeff, &scale_lpc,
233*15dc779aSAndroid Build Coastguard Worker                                              filt->order);
234*15dc779aSAndroid Build Coastguard Worker 
235*15dc779aSAndroid Build Coastguard Worker         tmp = (*usac_data->tns_max_bands_tbl_usac)[usac_data->sampling_rate_idx]
236*15dc779aSAndroid Build Coastguard Worker                                                   [idx];
237*15dc779aSAndroid Build Coastguard Worker 
238*15dc779aSAndroid Build Coastguard Worker         start = ixheaac_min32(start, tmp);
239*15dc779aSAndroid Build Coastguard Worker 
240*15dc779aSAndroid Build Coastguard Worker         start = ixheaac_min32(start, nbands);
241*15dc779aSAndroid Build Coastguard Worker         if (start > pstr_sfb_info->sfb_per_sbk) return -1;
242*15dc779aSAndroid Build Coastguard Worker         start = sfb_offset(start);
243*15dc779aSAndroid Build Coastguard Worker 
244*15dc779aSAndroid Build Coastguard Worker         stop = ixheaac_min32(stop, tmp);
245*15dc779aSAndroid Build Coastguard Worker         stop = ixheaac_min32(stop, nbands);
246*15dc779aSAndroid Build Coastguard Worker         if (stop > pstr_sfb_info->sfb_per_sbk) return -1;
247*15dc779aSAndroid Build Coastguard Worker         stop = sfb_offset(stop);
248*15dc779aSAndroid Build Coastguard Worker 
249*15dc779aSAndroid Build Coastguard Worker         guard_band = 31 - ixheaac_norm32(filt->order);
250*15dc779aSAndroid Build Coastguard Worker 
251*15dc779aSAndroid Build Coastguard Worker         if ((size = stop - start) <= 0) continue;
252*15dc779aSAndroid Build Coastguard Worker 
253*15dc779aSAndroid Build Coastguard Worker         if (direction) {
254*15dc779aSAndroid Build Coastguard Worker           inc = -1;
255*15dc779aSAndroid Build Coastguard Worker           shift = stop - 1;
256*15dc779aSAndroid Build Coastguard Worker         }
257*15dc779aSAndroid Build Coastguard Worker 
258*15dc779aSAndroid Build Coastguard Worker         else {
259*15dc779aSAndroid Build Coastguard Worker           inc = 1;
260*15dc779aSAndroid Build Coastguard Worker           shift = start;
261*15dc779aSAndroid Build Coastguard Worker         }
262*15dc779aSAndroid Build Coastguard Worker 
263*15dc779aSAndroid Build Coastguard Worker         {
264*15dc779aSAndroid Build Coastguard Worker           WORD32 *ptr_temp = ptr_spec + start;
265*15dc779aSAndroid Build Coastguard Worker           scale_spec = (*ixheaacd_calc_max_spectral_line)(ptr_temp, size);
266*15dc779aSAndroid Build Coastguard Worker         }
267*15dc779aSAndroid Build Coastguard Worker 
268*15dc779aSAndroid Build Coastguard Worker         scale_spec = ((scale_spec - guard_band) - scale_lpc);
269*15dc779aSAndroid Build Coastguard Worker 
270*15dc779aSAndroid Build Coastguard Worker         if (scale_spec > 0) {
271*15dc779aSAndroid Build Coastguard Worker           ixheaacd_tns_ar_filter_usac(&ptr_spec[shift], size, inc, lpc_coeff,
272*15dc779aSAndroid Build Coastguard Worker                                       filt->order, scale_lpc,
273*15dc779aSAndroid Build Coastguard Worker                                       usac_data->x_ac_dec);
274*15dc779aSAndroid Build Coastguard Worker         }
275*15dc779aSAndroid Build Coastguard Worker 
276*15dc779aSAndroid Build Coastguard Worker         else {
277*15dc779aSAndroid Build Coastguard Worker           WORD32 *ptr_temp = ptr_spec + start;
278*15dc779aSAndroid Build Coastguard Worker 
279*15dc779aSAndroid Build Coastguard Worker           scale_spec = -scale_spec;
280*15dc779aSAndroid Build Coastguard Worker           scale_spec = ixheaac_min32(scale_spec, 31);
281*15dc779aSAndroid Build Coastguard Worker 
282*15dc779aSAndroid Build Coastguard Worker           for (i = size; i != 0; i--) {
283*15dc779aSAndroid Build Coastguard Worker             *ptr_temp = *ptr_temp >> scale_spec;
284*15dc779aSAndroid Build Coastguard Worker             ptr_temp++;
285*15dc779aSAndroid Build Coastguard Worker           }
286*15dc779aSAndroid Build Coastguard Worker 
287*15dc779aSAndroid Build Coastguard Worker           {
288*15dc779aSAndroid Build Coastguard Worker             ixheaacd_tns_ar_filter_usac(&ptr_spec[shift], size, inc, lpc_coeff,
289*15dc779aSAndroid Build Coastguard Worker                                         filt->order, scale_lpc,
290*15dc779aSAndroid Build Coastguard Worker                                         usac_data->x_ac_dec);
291*15dc779aSAndroid Build Coastguard Worker           }
292*15dc779aSAndroid Build Coastguard Worker 
293*15dc779aSAndroid Build Coastguard Worker           {
294*15dc779aSAndroid Build Coastguard Worker             ptr_temp = ptr_spec + start;
295*15dc779aSAndroid Build Coastguard Worker             i = size;
296*15dc779aSAndroid Build Coastguard Worker 
297*15dc779aSAndroid Build Coastguard Worker             do {
298*15dc779aSAndroid Build Coastguard Worker               *ptr_temp = *ptr_temp << scale_spec;
299*15dc779aSAndroid Build Coastguard Worker               ptr_temp++;
300*15dc779aSAndroid Build Coastguard Worker               i--;
301*15dc779aSAndroid Build Coastguard Worker             } while (i != 0);
302*15dc779aSAndroid Build Coastguard Worker           }
303*15dc779aSAndroid Build Coastguard Worker         }
304*15dc779aSAndroid Build Coastguard Worker 
305*15dc779aSAndroid Build Coastguard Worker         for (i = start; i <= stop - 1; i++) {
306*15dc779aSAndroid Build Coastguard Worker           spec[i] = ptr_spec[i];
307*15dc779aSAndroid Build Coastguard Worker         }
308*15dc779aSAndroid Build Coastguard Worker       }
309*15dc779aSAndroid Build Coastguard Worker     }
310*15dc779aSAndroid Build Coastguard Worker 
311*15dc779aSAndroid Build Coastguard Worker     spec += pstr_sfb_info->bins_per_sbk;
312*15dc779aSAndroid Build Coastguard Worker   }
313*15dc779aSAndroid Build Coastguard Worker   return 0;
314*15dc779aSAndroid Build Coastguard Worker }
315