1*15dc779aSAndroid Build Coastguard Worker /******************************************************************************
2*15dc779aSAndroid Build Coastguard Worker * *
3*15dc779aSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project
4*15dc779aSAndroid Build Coastguard Worker *
5*15dc779aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*15dc779aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*15dc779aSAndroid Build Coastguard Worker * You may obtain a copy of the License at:
8*15dc779aSAndroid Build Coastguard Worker *
9*15dc779aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*15dc779aSAndroid Build Coastguard Worker *
11*15dc779aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*15dc779aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*15dc779aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*15dc779aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*15dc779aSAndroid Build Coastguard Worker * limitations under the License.
16*15dc779aSAndroid Build Coastguard Worker *
17*15dc779aSAndroid Build Coastguard Worker *****************************************************************************
18*15dc779aSAndroid Build Coastguard Worker * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*15dc779aSAndroid Build Coastguard Worker */
20*15dc779aSAndroid Build Coastguard Worker
21*15dc779aSAndroid Build Coastguard Worker #include <float.h>
22*15dc779aSAndroid Build Coastguard Worker #include <math.h>
23*15dc779aSAndroid Build Coastguard Worker #include <stdlib.h>
24*15dc779aSAndroid Build Coastguard Worker
25*15dc779aSAndroid Build Coastguard Worker #include <string.h>
26*15dc779aSAndroid Build Coastguard Worker
27*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
28*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_constants.h"
29*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_common_enc.h"
30*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_uni_drc.h"
31*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_tables.h"
32*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_api.h"
33*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_api.h"
34*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_aac_constants.h"
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_psy_const.h"
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_tns.h"
37*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_tns_params.h"
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_rom.h"
39*15dc779aSAndroid Build Coastguard Worker
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops32.h"
41*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops16.h"
42*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops40.h"
43*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops.h"
44*15dc779aSAndroid Build Coastguard Worker
45*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_common_rom.h"
46*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_bitbuffer.h"
47*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_adjust_threshold_data.h"
48*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_dynamic_bits.h"
49*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_qc_data.h"
50*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_block_switch.h"
51*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_psy_data.h"
52*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_interface.h"
53*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_adjust_threshold.h"
54*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_common_utils.h"
55*15dc779aSAndroid Build Coastguard Worker
iaace_adj_thr_init(ia_adj_thr_state_struct * pstr_adj_thr_state,const FLOAT32 mean_pe,WORD32 ch_bitrate,WORD32 aot)56*15dc779aSAndroid Build Coastguard Worker VOID iaace_adj_thr_init(ia_adj_thr_state_struct *pstr_adj_thr_state, const FLOAT32 mean_pe,
57*15dc779aSAndroid Build Coastguard Worker WORD32 ch_bitrate, WORD32 aot) {
58*15dc779aSAndroid Build Coastguard Worker ia_adj_thr_elem_struct *pstr_adj_thr_ele = &pstr_adj_thr_state->str_adj_thr_ele;
59*15dc779aSAndroid Build Coastguard Worker ia_min_snr_adapt_param_struct *pstr_min_snr_params =
60*15dc779aSAndroid Build Coastguard Worker &pstr_adj_thr_ele->str_min_snr_adapt_params;
61*15dc779aSAndroid Build Coastguard Worker
62*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_long.clip_save_low = CLIP_SAVE_LO_LONG;
63*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_long.clip_save_high = CLIP_SAVE_HI_LONG;
64*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_long.min_bit_save = MIN_BITS_SAVE_LONG;
65*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_long.max_bit_save = MAX_BITS_SAVE_LONG;
66*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_long.clip_spend_low = CLIP_SPEND_LO_LONG;
67*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_long.clip_spend_high = CLIP_SPEND_HI_LONG;
68*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_long.min_bits_spend = MIN_BITS_SPEND_LONG;
69*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_long.max_bits_spend = MAX_BITS_SPEND_LONG;
70*15dc779aSAndroid Build Coastguard Worker
71*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_short.clip_save_low = CLIP_SAVE_LO_SHORT;
72*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_short.clip_save_high = CLIP_SAVE_HI_SHORT;
73*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_short.min_bit_save = MIN_BITS_SAVE_SHORT;
74*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_short.max_bit_save = MAX_BITS_SAVE_SHORT;
75*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_short.clip_spend_low = CLIP_SPEND_LO_SHORT;
76*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_short.clip_spend_high = CLIP_SPEND_HI_SHORT;
77*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_short.min_bits_spend = MIN_BITS_SPEND_SHORT;
78*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_state->str_bitres_params_short.max_bits_spend = MAX_BITS_SPEND_SHORT;
79*15dc779aSAndroid Build Coastguard Worker
80*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->pe_min = (FLOAT32)0.8f * mean_pe;
81*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->pe_max = (FLOAT32)1.2f * mean_pe;
82*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->pe_offset = 0.0f;
83*15dc779aSAndroid Build Coastguard Worker switch (aot) {
84*15dc779aSAndroid Build Coastguard Worker case AOT_AAC_LC:
85*15dc779aSAndroid Build Coastguard Worker case AOT_SBR:
86*15dc779aSAndroid Build Coastguard Worker case AOT_PS:
87*15dc779aSAndroid Build Coastguard Worker if (ch_bitrate < 32000) {
88*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->pe_offset = MAX(
89*15dc779aSAndroid Build Coastguard Worker (FLOAT32)50.0f, (FLOAT32)(100.0f) - (FLOAT32)(100.0f / 32000) * (FLOAT32)ch_bitrate);
90*15dc779aSAndroid Build Coastguard Worker }
91*15dc779aSAndroid Build Coastguard Worker break;
92*15dc779aSAndroid Build Coastguard Worker
93*15dc779aSAndroid Build Coastguard Worker case AOT_AAC_LD:
94*15dc779aSAndroid Build Coastguard Worker case AOT_AAC_ELD:
95*15dc779aSAndroid Build Coastguard Worker
96*15dc779aSAndroid Build Coastguard Worker if (ch_bitrate <= 32000) {
97*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->pe_offset = MAX(
98*15dc779aSAndroid Build Coastguard Worker (FLOAT32)50.0f, (FLOAT32)(100.0f) - (FLOAT32)(100.0f / 32000) * (FLOAT32)ch_bitrate);
99*15dc779aSAndroid Build Coastguard Worker }
100*15dc779aSAndroid Build Coastguard Worker break;
101*15dc779aSAndroid Build Coastguard Worker }
102*15dc779aSAndroid Build Coastguard Worker
103*15dc779aSAndroid Build Coastguard Worker if (ch_bitrate > 20000) {
104*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->str_ah_param.modify_min_snr = TRUE;
105*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->str_ah_param.start_sfb_long = 15;
106*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->str_ah_param.start_sfb_short = 3;
107*15dc779aSAndroid Build Coastguard Worker } else {
108*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->str_ah_param.modify_min_snr = FALSE;
109*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->str_ah_param.start_sfb_long = 0;
110*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->str_ah_param.start_sfb_short = 0;
111*15dc779aSAndroid Build Coastguard Worker }
112*15dc779aSAndroid Build Coastguard Worker
113*15dc779aSAndroid Build Coastguard Worker pstr_min_snr_params->max_red = (FLOAT32)0.25f;
114*15dc779aSAndroid Build Coastguard Worker
115*15dc779aSAndroid Build Coastguard Worker pstr_min_snr_params->start_ratio = (FLOAT32)1.e1f;
116*15dc779aSAndroid Build Coastguard Worker
117*15dc779aSAndroid Build Coastguard Worker pstr_min_snr_params->max_ratio = (FLOAT32)1.e3f;
118*15dc779aSAndroid Build Coastguard Worker
119*15dc779aSAndroid Build Coastguard Worker pstr_min_snr_params->red_ratio_fac =
120*15dc779aSAndroid Build Coastguard Worker (1.0f - pstr_min_snr_params->max_red) /
121*15dc779aSAndroid Build Coastguard Worker (10.0f * (FLOAT32)log10(pstr_min_snr_params->start_ratio / pstr_min_snr_params->max_ratio));
122*15dc779aSAndroid Build Coastguard Worker
123*15dc779aSAndroid Build Coastguard Worker pstr_min_snr_params->red_offs = 1.0f - pstr_min_snr_params->red_ratio_fac * 10.0f *
124*15dc779aSAndroid Build Coastguard Worker (FLOAT32)log10(pstr_min_snr_params->start_ratio);
125*15dc779aSAndroid Build Coastguard Worker
126*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->pe_last = (FLOAT32)0.0f;
127*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->dyn_bits_last = 0;
128*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_ele->pe_correction_fac = (FLOAT32)1.0f;
129*15dc779aSAndroid Build Coastguard Worker }
iaace_bits_to_pe(const FLOAT32 bits)130*15dc779aSAndroid Build Coastguard Worker FLOAT32 iaace_bits_to_pe(const FLOAT32 bits) { return (bits * 1.18f); }
iaace_calc_sfb_pe_data(ia_qc_pe_data_struct * pstr_qc_pe_data,ixheaace_psy_out_channel ** pstr_psy_out,WORD32 num_channels,WORD32 chn)131*15dc779aSAndroid Build Coastguard Worker static VOID iaace_calc_sfb_pe_data(ia_qc_pe_data_struct *pstr_qc_pe_data,
132*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel **pstr_psy_out, WORD32 num_channels,
133*15dc779aSAndroid Build Coastguard Worker WORD32 chn) {
134*15dc779aSAndroid Build Coastguard Worker WORD32 ch;
135*15dc779aSAndroid Build Coastguard Worker WORD32 scf_band_grp;
136*15dc779aSAndroid Build Coastguard Worker FLOAT32 num_lines;
137*15dc779aSAndroid Build Coastguard Worker FLOAT32 ld_thr, ld_ratio;
138*15dc779aSAndroid Build Coastguard Worker WORD32 i = 0, scf;
139*15dc779aSAndroid Build Coastguard Worker WORD32 sfb_count;
140*15dc779aSAndroid Build Coastguard Worker WORD32 scf_band_per_grp;
141*15dc779aSAndroid Build Coastguard Worker WORD32 max_sfb_per_grp;
142*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_sfb_energy;
143*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_sfb_thr;
144*15dc779aSAndroid Build Coastguard Worker ia_qc_pe_chan_data_struct *pstr_qc_pe_chan_data;
145*15dc779aSAndroid Build Coastguard Worker
146*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_data->pe = pstr_qc_pe_data->offset;
147*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_data->const_part = 0.0f;
148*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_data->num_active_lines = 0.0f;
149*15dc779aSAndroid Build Coastguard Worker
150*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_channels; ch++) {
151*15dc779aSAndroid Build Coastguard Worker sfb_count = pstr_psy_out[ch]->sfb_count;
152*15dc779aSAndroid Build Coastguard Worker scf_band_per_grp = pstr_psy_out[ch]->sfb_per_group;
153*15dc779aSAndroid Build Coastguard Worker max_sfb_per_grp = pstr_psy_out[ch]->max_sfb_per_grp;
154*15dc779aSAndroid Build Coastguard Worker ptr_sfb_energy = pstr_psy_out[ch]->ptr_sfb_energy;
155*15dc779aSAndroid Build Coastguard Worker ptr_sfb_thr = pstr_psy_out[ch]->ptr_sfb_thr;
156*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data = &pstr_qc_pe_data->pe_ch_data[ch];
157*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->pe = 0;
158*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->num_active_lines = 0;
159*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->const_part = 0;
160*15dc779aSAndroid Build Coastguard Worker
161*15dc779aSAndroid Build Coastguard Worker for (scf_band_grp = 0; scf_band_grp < sfb_count; scf_band_grp += scf_band_per_grp) {
162*15dc779aSAndroid Build Coastguard Worker i = scf_band_grp;
163*15dc779aSAndroid Build Coastguard Worker for (scf = max_sfb_per_grp - 1; scf >= 0; scf--, i++) {
164*15dc779aSAndroid Build Coastguard Worker if (ptr_sfb_energy[i] > ptr_sfb_thr[i]) {
165*15dc779aSAndroid Build Coastguard Worker ld_thr = (FLOAT32)log(ptr_sfb_thr[i]) * LOG2_1;
166*15dc779aSAndroid Build Coastguard Worker ld_ratio = pstr_qc_pe_chan_data->sfb_ld_energy[i] - ld_thr;
167*15dc779aSAndroid Build Coastguard Worker num_lines = pstr_qc_pe_chan_data->sfb_lines[i];
168*15dc779aSAndroid Build Coastguard Worker if (ld_ratio >= PE_C1) {
169*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->sfb_pe[i] = num_lines * ld_ratio;
170*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->sfb_const_part[i] =
171*15dc779aSAndroid Build Coastguard Worker num_lines * pstr_qc_pe_chan_data->sfb_ld_energy[i];
172*15dc779aSAndroid Build Coastguard Worker } else {
173*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->sfb_pe[i] = num_lines * (PE_C2 + PE_C3 * ld_ratio);
174*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->sfb_const_part[i] =
175*15dc779aSAndroid Build Coastguard Worker num_lines * (PE_C2 + PE_C3 * pstr_qc_pe_chan_data->sfb_ld_energy[i]);
176*15dc779aSAndroid Build Coastguard Worker num_lines = num_lines * PE_C3;
177*15dc779aSAndroid Build Coastguard Worker }
178*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->num_sfb_active_lines[i] = num_lines;
179*15dc779aSAndroid Build Coastguard Worker } else {
180*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->sfb_pe[i] = 0.0f;
181*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->sfb_const_part[i] = 0.0f;
182*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->num_sfb_active_lines[i] = 0.0;
183*15dc779aSAndroid Build Coastguard Worker }
184*15dc779aSAndroid Build Coastguard Worker
185*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->pe += pstr_qc_pe_chan_data->sfb_pe[i];
186*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->const_part += pstr_qc_pe_chan_data->sfb_const_part[i];
187*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_chan_data->num_active_lines += pstr_qc_pe_chan_data->num_sfb_active_lines[i];
188*15dc779aSAndroid Build Coastguard Worker }
189*15dc779aSAndroid Build Coastguard Worker }
190*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_data->pe += pstr_qc_pe_chan_data->pe;
191*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_data->const_part += pstr_qc_pe_chan_data->const_part;
192*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_data->num_active_lines += pstr_qc_pe_chan_data->num_active_lines;
193*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch]->pe = pstr_qc_pe_data->pe;
194*15dc779aSAndroid Build Coastguard Worker }
195*15dc779aSAndroid Build Coastguard Worker }
iaace_calc_bit_save(ia_bitres_param_struct * pstr_bitres_params,FLOAT32 fill_lvl)196*15dc779aSAndroid Build Coastguard Worker static FLOAT32 iaace_calc_bit_save(ia_bitres_param_struct *pstr_bitres_params, FLOAT32 fill_lvl) {
197*15dc779aSAndroid Build Coastguard Worker FLOAT32 bit_save;
198*15dc779aSAndroid Build Coastguard Worker const FLOAT32 clip_low = pstr_bitres_params->clip_save_low;
199*15dc779aSAndroid Build Coastguard Worker const FLOAT32 clip_high = pstr_bitres_params->clip_save_high;
200*15dc779aSAndroid Build Coastguard Worker const FLOAT32 min_bit_save = pstr_bitres_params->min_bit_save;
201*15dc779aSAndroid Build Coastguard Worker const FLOAT32 max_bit_save = pstr_bitres_params->max_bit_save;
202*15dc779aSAndroid Build Coastguard Worker
203*15dc779aSAndroid Build Coastguard Worker fill_lvl = MAX(fill_lvl, clip_low);
204*15dc779aSAndroid Build Coastguard Worker fill_lvl = MIN(fill_lvl, clip_high);
205*15dc779aSAndroid Build Coastguard Worker bit_save = max_bit_save -
206*15dc779aSAndroid Build Coastguard Worker ((max_bit_save - min_bit_save) / (clip_high - clip_low)) * (fill_lvl - clip_low);
207*15dc779aSAndroid Build Coastguard Worker
208*15dc779aSAndroid Build Coastguard Worker return bit_save;
209*15dc779aSAndroid Build Coastguard Worker }
210*15dc779aSAndroid Build Coastguard Worker
iaace_calc_bit_spend(ia_bitres_param_struct * pstr_bitres_params,FLOAT32 fill_lvl)211*15dc779aSAndroid Build Coastguard Worker static FLOAT32 iaace_calc_bit_spend(ia_bitres_param_struct *pstr_bitres_params,
212*15dc779aSAndroid Build Coastguard Worker FLOAT32 fill_lvl) {
213*15dc779aSAndroid Build Coastguard Worker FLOAT32 bit_spend;
214*15dc779aSAndroid Build Coastguard Worker const FLOAT32 clip_low = pstr_bitres_params->clip_spend_low;
215*15dc779aSAndroid Build Coastguard Worker const FLOAT32 clip_high = pstr_bitres_params->clip_spend_high;
216*15dc779aSAndroid Build Coastguard Worker const FLOAT32 min_bits_spend = pstr_bitres_params->min_bits_spend;
217*15dc779aSAndroid Build Coastguard Worker const FLOAT32 max_bits_spend = pstr_bitres_params->max_bits_spend;
218*15dc779aSAndroid Build Coastguard Worker
219*15dc779aSAndroid Build Coastguard Worker fill_lvl = MAX(fill_lvl, clip_low);
220*15dc779aSAndroid Build Coastguard Worker fill_lvl = MIN(fill_lvl, clip_high);
221*15dc779aSAndroid Build Coastguard Worker bit_spend = min_bits_spend + ((max_bits_spend - min_bits_spend) / (clip_high - clip_low)) *
222*15dc779aSAndroid Build Coastguard Worker (fill_lvl - clip_low);
223*15dc779aSAndroid Build Coastguard Worker
224*15dc779aSAndroid Build Coastguard Worker return bit_spend;
225*15dc779aSAndroid Build Coastguard Worker }
226*15dc779aSAndroid Build Coastguard Worker
iaace_adjust_pe_minmax(const FLOAT32 curr_pe,FLOAT32 * ptr_pe_min,FLOAT32 * ptr_pe_max)227*15dc779aSAndroid Build Coastguard Worker static VOID iaace_adjust_pe_minmax(const FLOAT32 curr_pe, FLOAT32 *ptr_pe_min,
228*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_pe_max) {
229*15dc779aSAndroid Build Coastguard Worker FLOAT32 min_hi_fac = 0.3f, max_hi_fac = 1.0f, min_low_fac = 0.14f, max_low_fac = 0.07f;
230*15dc779aSAndroid Build Coastguard Worker FLOAT32 diff;
231*15dc779aSAndroid Build Coastguard Worker FLOAT32 min_diff = curr_pe * (FLOAT32)0.1666666667f;
232*15dc779aSAndroid Build Coastguard Worker
233*15dc779aSAndroid Build Coastguard Worker if (curr_pe > *ptr_pe_max) {
234*15dc779aSAndroid Build Coastguard Worker diff = (curr_pe - *ptr_pe_max);
235*15dc779aSAndroid Build Coastguard Worker *ptr_pe_min += diff * min_hi_fac;
236*15dc779aSAndroid Build Coastguard Worker *ptr_pe_max += diff * max_hi_fac;
237*15dc779aSAndroid Build Coastguard Worker } else {
238*15dc779aSAndroid Build Coastguard Worker if (curr_pe < *ptr_pe_min) {
239*15dc779aSAndroid Build Coastguard Worker diff = (*ptr_pe_min - curr_pe);
240*15dc779aSAndroid Build Coastguard Worker *ptr_pe_min -= diff * min_low_fac;
241*15dc779aSAndroid Build Coastguard Worker *ptr_pe_max -= diff * max_low_fac;
242*15dc779aSAndroid Build Coastguard Worker } else {
243*15dc779aSAndroid Build Coastguard Worker *ptr_pe_min += (curr_pe - *ptr_pe_min) * min_hi_fac;
244*15dc779aSAndroid Build Coastguard Worker *ptr_pe_max -= (*ptr_pe_max - curr_pe) * max_low_fac;
245*15dc779aSAndroid Build Coastguard Worker }
246*15dc779aSAndroid Build Coastguard Worker }
247*15dc779aSAndroid Build Coastguard Worker
248*15dc779aSAndroid Build Coastguard Worker if ((*ptr_pe_max - *ptr_pe_min) < min_diff) {
249*15dc779aSAndroid Build Coastguard Worker FLOAT32 low_part, high_part;
250*15dc779aSAndroid Build Coastguard Worker low_part = MAX((FLOAT32)0.0f, curr_pe - *ptr_pe_min);
251*15dc779aSAndroid Build Coastguard Worker high_part = MAX((FLOAT32)0.0f, *ptr_pe_max - curr_pe);
252*15dc779aSAndroid Build Coastguard Worker *ptr_pe_max = curr_pe + high_part / (low_part + high_part) * min_diff;
253*15dc779aSAndroid Build Coastguard Worker *ptr_pe_min = curr_pe - low_part / (low_part + high_part) * min_diff;
254*15dc779aSAndroid Build Coastguard Worker *ptr_pe_min = MAX((FLOAT32)0.0f, *ptr_pe_min);
255*15dc779aSAndroid Build Coastguard Worker }
256*15dc779aSAndroid Build Coastguard Worker }
257*15dc779aSAndroid Build Coastguard Worker
iaace_bitres_calc_bitfac(const WORD32 bitres_bits,const WORD32 max_bitres_bits,const FLOAT32 pe,const WORD32 win_seq,const WORD32 avg_bits,const FLOAT32 max_bit_fac,ia_adj_thr_state_struct * pstr_adj_thr_state,ia_adj_thr_elem_struct * pstr_adj_the_elem)258*15dc779aSAndroid Build Coastguard Worker static FLOAT32 iaace_bitres_calc_bitfac(const WORD32 bitres_bits, const WORD32 max_bitres_bits,
259*15dc779aSAndroid Build Coastguard Worker const FLOAT32 pe, const WORD32 win_seq,
260*15dc779aSAndroid Build Coastguard Worker const WORD32 avg_bits, const FLOAT32 max_bit_fac,
261*15dc779aSAndroid Build Coastguard Worker ia_adj_thr_state_struct *pstr_adj_thr_state,
262*15dc779aSAndroid Build Coastguard Worker ia_adj_thr_elem_struct *pstr_adj_the_elem) {
263*15dc779aSAndroid Build Coastguard Worker ia_bitres_param_struct *pstr_bitres_params;
264*15dc779aSAndroid Build Coastguard Worker FLOAT32 pex;
265*15dc779aSAndroid Build Coastguard Worker FLOAT32 fill_lvl = 0.0f;
266*15dc779aSAndroid Build Coastguard Worker FLOAT32 bit_save, bit_spend, bitres_factor;
267*15dc779aSAndroid Build Coastguard Worker
268*15dc779aSAndroid Build Coastguard Worker if (max_bitres_bits) {
269*15dc779aSAndroid Build Coastguard Worker fill_lvl = (FLOAT32)bitres_bits / max_bitres_bits;
270*15dc779aSAndroid Build Coastguard Worker }
271*15dc779aSAndroid Build Coastguard Worker
272*15dc779aSAndroid Build Coastguard Worker if (win_seq != SHORT_WINDOW) {
273*15dc779aSAndroid Build Coastguard Worker pstr_bitres_params = &(pstr_adj_thr_state->str_bitres_params_long);
274*15dc779aSAndroid Build Coastguard Worker } else {
275*15dc779aSAndroid Build Coastguard Worker pstr_bitres_params = &(pstr_adj_thr_state->str_bitres_params_short);
276*15dc779aSAndroid Build Coastguard Worker }
277*15dc779aSAndroid Build Coastguard Worker
278*15dc779aSAndroid Build Coastguard Worker pex = MAX(pe, pstr_adj_the_elem->pe_min);
279*15dc779aSAndroid Build Coastguard Worker pex = MIN(pex, pstr_adj_the_elem->pe_max);
280*15dc779aSAndroid Build Coastguard Worker
281*15dc779aSAndroid Build Coastguard Worker bit_save = iaace_calc_bit_save(pstr_bitres_params, fill_lvl);
282*15dc779aSAndroid Build Coastguard Worker bit_spend = iaace_calc_bit_spend(pstr_bitres_params, fill_lvl);
283*15dc779aSAndroid Build Coastguard Worker
284*15dc779aSAndroid Build Coastguard Worker bitres_factor =
285*15dc779aSAndroid Build Coastguard Worker (FLOAT32)1.0f - bit_save +
286*15dc779aSAndroid Build Coastguard Worker ((bit_spend + bit_save) / (pstr_adj_the_elem->pe_max - pstr_adj_the_elem->pe_min)) *
287*15dc779aSAndroid Build Coastguard Worker (pex - pstr_adj_the_elem->pe_min);
288*15dc779aSAndroid Build Coastguard Worker if (avg_bits)
289*15dc779aSAndroid Build Coastguard Worker {
290*15dc779aSAndroid Build Coastguard Worker bitres_factor = MIN(bitres_factor,
291*15dc779aSAndroid Build Coastguard Worker (FLOAT32)1.0f - (FLOAT32)0.3f + (FLOAT32)bitres_bits / (FLOAT32)avg_bits);
292*15dc779aSAndroid Build Coastguard Worker }
293*15dc779aSAndroid Build Coastguard Worker
294*15dc779aSAndroid Build Coastguard Worker bitres_factor = MIN(bitres_factor, max_bit_fac);
295*15dc779aSAndroid Build Coastguard Worker
296*15dc779aSAndroid Build Coastguard Worker iaace_adjust_pe_minmax(pe, &pstr_adj_the_elem->pe_min, &pstr_adj_the_elem->pe_max);
297*15dc779aSAndroid Build Coastguard Worker
298*15dc779aSAndroid Build Coastguard Worker return bitres_factor;
299*15dc779aSAndroid Build Coastguard Worker }
300*15dc779aSAndroid Build Coastguard Worker
iaace_calc_pe_correction(FLOAT32 * ptr_correction_fac,const FLOAT32 pe_act,const FLOAT32 pe_last,const WORD32 bits_prev)301*15dc779aSAndroid Build Coastguard Worker static VOID iaace_calc_pe_correction(FLOAT32 *ptr_correction_fac, const FLOAT32 pe_act,
302*15dc779aSAndroid Build Coastguard Worker const FLOAT32 pe_last, const WORD32 bits_prev) {
303*15dc779aSAndroid Build Coastguard Worker if ((bits_prev > 0) && (pe_act < (FLOAT32)1.5f * pe_last) &&
304*15dc779aSAndroid Build Coastguard Worker (pe_act > (FLOAT32)0.7f * pe_last) &&
305*15dc779aSAndroid Build Coastguard Worker ((FLOAT32)1.2f * iaace_bits_to_pe((FLOAT32)bits_prev) > pe_last) &&
306*15dc779aSAndroid Build Coastguard Worker ((FLOAT32)0.65f * iaace_bits_to_pe((FLOAT32)bits_prev) < pe_last)) {
307*15dc779aSAndroid Build Coastguard Worker FLOAT32 new_fac = pe_last / iaace_bits_to_pe((FLOAT32)bits_prev);
308*15dc779aSAndroid Build Coastguard Worker
309*15dc779aSAndroid Build Coastguard Worker if (new_fac < (FLOAT32)1.0f) {
310*15dc779aSAndroid Build Coastguard Worker new_fac = MIN((FLOAT32)1.1f * new_fac, (FLOAT32)1.0f);
311*15dc779aSAndroid Build Coastguard Worker new_fac = MAX(new_fac, (FLOAT32)0.85f);
312*15dc779aSAndroid Build Coastguard Worker } else {
313*15dc779aSAndroid Build Coastguard Worker new_fac = MAX((FLOAT32)0.9f * new_fac, (FLOAT32)1.0f);
314*15dc779aSAndroid Build Coastguard Worker new_fac = MIN(new_fac, (FLOAT32)1.15f);
315*15dc779aSAndroid Build Coastguard Worker }
316*15dc779aSAndroid Build Coastguard Worker if (((new_fac > (FLOAT32)1.0f) && (*ptr_correction_fac < (FLOAT32)1.0f)) ||
317*15dc779aSAndroid Build Coastguard Worker ((new_fac < (FLOAT32)1.0f) && (*ptr_correction_fac > (FLOAT32)1.0f))) {
318*15dc779aSAndroid Build Coastguard Worker *ptr_correction_fac = (FLOAT32)1.0f;
319*15dc779aSAndroid Build Coastguard Worker }
320*15dc779aSAndroid Build Coastguard Worker
321*15dc779aSAndroid Build Coastguard Worker if ((*ptr_correction_fac < (FLOAT32)1.0f && new_fac < *ptr_correction_fac) ||
322*15dc779aSAndroid Build Coastguard Worker (*ptr_correction_fac > (FLOAT32)1.0f && new_fac > *ptr_correction_fac)) {
323*15dc779aSAndroid Build Coastguard Worker *ptr_correction_fac = (FLOAT32)0.85f * (*ptr_correction_fac) + (FLOAT32)0.15f * new_fac;
324*15dc779aSAndroid Build Coastguard Worker } else {
325*15dc779aSAndroid Build Coastguard Worker *ptr_correction_fac = (FLOAT32)0.7f * (*ptr_correction_fac) + (FLOAT32)0.3f * new_fac;
326*15dc779aSAndroid Build Coastguard Worker }
327*15dc779aSAndroid Build Coastguard Worker
328*15dc779aSAndroid Build Coastguard Worker *ptr_correction_fac = MIN(*ptr_correction_fac, (FLOAT32)1.15f);
329*15dc779aSAndroid Build Coastguard Worker *ptr_correction_fac = MAX(*ptr_correction_fac, (FLOAT32)0.85f);
330*15dc779aSAndroid Build Coastguard Worker } else {
331*15dc779aSAndroid Build Coastguard Worker *ptr_correction_fac = (FLOAT32)1.0f;
332*15dc779aSAndroid Build Coastguard Worker }
333*15dc779aSAndroid Build Coastguard Worker }
334*15dc779aSAndroid Build Coastguard Worker
iaace_calc_thr_exp(FLOAT32 thr_exp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],ixheaace_psy_out_channel ** pstr_psy_out,WORD32 num_chans,WORD32 chn)335*15dc779aSAndroid Build Coastguard Worker static VOID iaace_calc_thr_exp(
336*15dc779aSAndroid Build Coastguard Worker FLOAT32 thr_exp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
337*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel **pstr_psy_out, WORD32 num_chans, WORD32 chn) {
338*15dc779aSAndroid Build Coastguard Worker WORD32 sfb, ch, scf_band_grp;
339*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_chan_out;
340*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_scf_band_thr;
341*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_thr_exp;
342*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_chans; ch++) {
343*15dc779aSAndroid Build Coastguard Worker pstr_psy_chan_out = pstr_psy_out[ch];
344*15dc779aSAndroid Build Coastguard Worker ptr_thr_exp = thr_exp[ch];
345*15dc779aSAndroid Build Coastguard Worker for (scf_band_grp = 0; scf_band_grp < pstr_psy_chan_out->sfb_count;
346*15dc779aSAndroid Build Coastguard Worker scf_band_grp += pstr_psy_chan_out->sfb_per_group) {
347*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_thr_exp1 = &ptr_thr_exp[scf_band_grp];
348*15dc779aSAndroid Build Coastguard Worker ptr_scf_band_thr = &pstr_psy_chan_out->ptr_sfb_thr[scf_band_grp];
349*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < pstr_psy_chan_out->max_sfb_per_grp; sfb++) {
350*15dc779aSAndroid Build Coastguard Worker ptr_thr_exp1[sfb] = (FLOAT32)pow(*ptr_scf_band_thr++, RED_EXP_VAL);
351*15dc779aSAndroid Build Coastguard Worker }
352*15dc779aSAndroid Build Coastguard Worker }
353*15dc779aSAndroid Build Coastguard Worker }
354*15dc779aSAndroid Build Coastguard Worker }
355*15dc779aSAndroid Build Coastguard Worker
iaace_adapt_min_snr(ixheaace_psy_out_channel ** pstr_psy_out,ia_min_snr_adapt_param_struct * pstr_min_snr_params,WORD32 num_chans,WORD32 chn)356*15dc779aSAndroid Build Coastguard Worker static VOID iaace_adapt_min_snr(ixheaace_psy_out_channel **pstr_psy_out,
357*15dc779aSAndroid Build Coastguard Worker ia_min_snr_adapt_param_struct *pstr_min_snr_params,
358*15dc779aSAndroid Build Coastguard Worker WORD32 num_chans, WORD32 chn) {
359*15dc779aSAndroid Build Coastguard Worker WORD32 num_scf_band = 0, ch, scf_band_cnt, scf_band_offs, sfb;
360*15dc779aSAndroid Build Coastguard Worker FLOAT32 avg_energy = 0.0f, db_ratio, min_snr_red;
361*15dc779aSAndroid Build Coastguard Worker WORD32 i;
362*15dc779aSAndroid Build Coastguard Worker
363*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_chans; ch++) {
364*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_chan_out = pstr_psy_out[ch];
365*15dc779aSAndroid Build Coastguard Worker num_scf_band = 0;
366*15dc779aSAndroid Build Coastguard Worker avg_energy = 0;
367*15dc779aSAndroid Build Coastguard Worker scf_band_cnt = pstr_psy_chan_out->max_sfb_per_grp;
368*15dc779aSAndroid Build Coastguard Worker
369*15dc779aSAndroid Build Coastguard Worker for (scf_band_offs = 0; scf_band_offs < pstr_psy_chan_out->sfb_count;
370*15dc779aSAndroid Build Coastguard Worker scf_band_offs += pstr_psy_chan_out->sfb_per_group) {
371*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_sfb_energy = &pstr_psy_chan_out->ptr_sfb_energy[scf_band_offs];
372*15dc779aSAndroid Build Coastguard Worker for (sfb = scf_band_cnt - 1; sfb >= 0; sfb--) {
373*15dc779aSAndroid Build Coastguard Worker avg_energy += ptr_sfb_energy[sfb];
374*15dc779aSAndroid Build Coastguard Worker }
375*15dc779aSAndroid Build Coastguard Worker num_scf_band += scf_band_cnt;
376*15dc779aSAndroid Build Coastguard Worker }
377*15dc779aSAndroid Build Coastguard Worker
378*15dc779aSAndroid Build Coastguard Worker if (num_scf_band > 0) {
379*15dc779aSAndroid Build Coastguard Worker avg_energy /= num_scf_band;
380*15dc779aSAndroid Build Coastguard Worker }
381*15dc779aSAndroid Build Coastguard Worker
382*15dc779aSAndroid Build Coastguard Worker for (scf_band_offs = 0; scf_band_offs < pstr_psy_chan_out->sfb_count;
383*15dc779aSAndroid Build Coastguard Worker scf_band_offs += pstr_psy_chan_out->sfb_per_group) {
384*15dc779aSAndroid Build Coastguard Worker i = scf_band_offs;
385*15dc779aSAndroid Build Coastguard Worker for (sfb = scf_band_cnt - 1; sfb >= 0; sfb--, i++) {
386*15dc779aSAndroid Build Coastguard Worker if (pstr_min_snr_params->start_ratio * pstr_psy_chan_out->ptr_sfb_energy[i] <
387*15dc779aSAndroid Build Coastguard Worker avg_energy) {
388*15dc779aSAndroid Build Coastguard Worker db_ratio =
389*15dc779aSAndroid Build Coastguard Worker (FLOAT32)(10.0f * log10((MIN_FLT_VAL + avg_energy) /
390*15dc779aSAndroid Build Coastguard Worker (MIN_FLT_VAL + pstr_psy_chan_out->ptr_sfb_energy[i])));
391*15dc779aSAndroid Build Coastguard Worker min_snr_red =
392*15dc779aSAndroid Build Coastguard Worker pstr_min_snr_params->red_offs + pstr_min_snr_params->red_ratio_fac * db_ratio;
393*15dc779aSAndroid Build Coastguard Worker min_snr_red = MAX(min_snr_red, pstr_min_snr_params->max_red);
394*15dc779aSAndroid Build Coastguard Worker pstr_psy_chan_out->sfb_min_snr[i] =
395*15dc779aSAndroid Build Coastguard Worker (FLOAT32)pow(pstr_psy_out[ch]->sfb_min_snr[i], min_snr_red);
396*15dc779aSAndroid Build Coastguard Worker pstr_psy_chan_out->sfb_min_snr[i] =
397*15dc779aSAndroid Build Coastguard Worker MIN(MIN_SNR_LIMIT, pstr_psy_out[ch]->sfb_min_snr[i]);
398*15dc779aSAndroid Build Coastguard Worker }
399*15dc779aSAndroid Build Coastguard Worker }
400*15dc779aSAndroid Build Coastguard Worker }
401*15dc779aSAndroid Build Coastguard Worker }
402*15dc779aSAndroid Build Coastguard Worker }
403*15dc779aSAndroid Build Coastguard Worker
iaace_init_avoid_hole_flag(WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],ixheaace_psy_out_channel ** pstr_psy_out,ia_ah_param_struct * pstr_ah_param,WORD32 num_chans,WORD32 chn,WORD32 aot)404*15dc779aSAndroid Build Coastguard Worker static VOID iaace_init_avoid_hole_flag(
405*15dc779aSAndroid Build Coastguard Worker WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
406*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel **pstr_psy_out, ia_ah_param_struct *pstr_ah_param, WORD32 num_chans,
407*15dc779aSAndroid Build Coastguard Worker WORD32 chn, WORD32 aot) {
408*15dc779aSAndroid Build Coastguard Worker WORD32 ch;
409*15dc779aSAndroid Build Coastguard Worker FLOAT32 sfb_energy;
410*15dc779aSAndroid Build Coastguard Worker FLOAT32 scale_spread_energy = 0.0f;
411*15dc779aSAndroid Build Coastguard Worker WORD32 scf_band_grp, scf_band_cnt, scf_band;
412*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_scf_band_spread_energy, *ptr_scf_band_energy, *ptr_scf_band_min_snr;
413*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_chans; ch++) {
414*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_chan_out = pstr_psy_out[ch];
415*15dc779aSAndroid Build Coastguard Worker
416*15dc779aSAndroid Build Coastguard Worker if (pstr_psy_chan_out->window_sequence != SHORT_WINDOW) {
417*15dc779aSAndroid Build Coastguard Worker switch (aot) {
418*15dc779aSAndroid Build Coastguard Worker case AOT_AAC_LC:
419*15dc779aSAndroid Build Coastguard Worker case AOT_SBR:
420*15dc779aSAndroid Build Coastguard Worker case AOT_PS:
421*15dc779aSAndroid Build Coastguard Worker scale_spread_energy = 0.5f;
422*15dc779aSAndroid Build Coastguard Worker break;
423*15dc779aSAndroid Build Coastguard Worker
424*15dc779aSAndroid Build Coastguard Worker case AOT_AAC_LD:
425*15dc779aSAndroid Build Coastguard Worker case AOT_AAC_ELD:
426*15dc779aSAndroid Build Coastguard Worker scale_spread_energy = 0.56f;
427*15dc779aSAndroid Build Coastguard Worker break;
428*15dc779aSAndroid Build Coastguard Worker }
429*15dc779aSAndroid Build Coastguard Worker } else {
430*15dc779aSAndroid Build Coastguard Worker scale_spread_energy = 0.63f;
431*15dc779aSAndroid Build Coastguard Worker }
432*15dc779aSAndroid Build Coastguard Worker
433*15dc779aSAndroid Build Coastguard Worker for (scf_band_grp = 0; scf_band_grp < pstr_psy_chan_out->sfb_count;
434*15dc779aSAndroid Build Coastguard Worker scf_band_grp += pstr_psy_chan_out->sfb_per_group) {
435*15dc779aSAndroid Build Coastguard Worker ptr_scf_band_spread_energy = &pstr_psy_chan_out->ptr_sfb_spread_energy[scf_band_grp];
436*15dc779aSAndroid Build Coastguard Worker scf_band_cnt = pstr_psy_chan_out->max_sfb_per_grp;
437*15dc779aSAndroid Build Coastguard Worker for (scf_band = scf_band_cnt - 1; scf_band >= 0; scf_band--) {
438*15dc779aSAndroid Build Coastguard Worker *ptr_scf_band_spread_energy = *ptr_scf_band_spread_energy * scale_spread_energy;
439*15dc779aSAndroid Build Coastguard Worker ptr_scf_band_spread_energy++;
440*15dc779aSAndroid Build Coastguard Worker }
441*15dc779aSAndroid Build Coastguard Worker }
442*15dc779aSAndroid Build Coastguard Worker }
443*15dc779aSAndroid Build Coastguard Worker
444*15dc779aSAndroid Build Coastguard Worker if (pstr_ah_param->modify_min_snr) {
445*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_chans; ch++) {
446*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_chan_out = pstr_psy_out[ch];
447*15dc779aSAndroid Build Coastguard Worker ptr_scf_band_energy = pstr_psy_chan_out->ptr_sfb_energy;
448*15dc779aSAndroid Build Coastguard Worker
449*15dc779aSAndroid Build Coastguard Worker ptr_scf_band_min_snr = pstr_psy_chan_out->sfb_min_snr;
450*15dc779aSAndroid Build Coastguard Worker
451*15dc779aSAndroid Build Coastguard Worker for (scf_band_grp = 0; scf_band_grp < pstr_psy_chan_out->sfb_count;
452*15dc779aSAndroid Build Coastguard Worker scf_band_grp += pstr_psy_chan_out->sfb_per_group) {
453*15dc779aSAndroid Build Coastguard Worker for (scf_band = 0; scf_band < pstr_psy_chan_out->max_sfb_per_grp; scf_band++) {
454*15dc779aSAndroid Build Coastguard Worker FLOAT32 sfb_en_m1, sfb_en_p1, avg_energy;
455*15dc779aSAndroid Build Coastguard Worker if (scf_band > 0) {
456*15dc779aSAndroid Build Coastguard Worker sfb_en_m1 = ptr_scf_band_energy[scf_band_grp + scf_band - 1];
457*15dc779aSAndroid Build Coastguard Worker } else {
458*15dc779aSAndroid Build Coastguard Worker sfb_en_m1 = ptr_scf_band_energy[scf_band_grp];
459*15dc779aSAndroid Build Coastguard Worker }
460*15dc779aSAndroid Build Coastguard Worker if (scf_band < pstr_psy_chan_out->max_sfb_per_grp - 1) {
461*15dc779aSAndroid Build Coastguard Worker sfb_en_p1 = ptr_scf_band_energy[scf_band_grp + scf_band + 1];
462*15dc779aSAndroid Build Coastguard Worker } else {
463*15dc779aSAndroid Build Coastguard Worker sfb_en_p1 = ptr_scf_band_energy[scf_band_grp + scf_band];
464*15dc779aSAndroid Build Coastguard Worker }
465*15dc779aSAndroid Build Coastguard Worker
466*15dc779aSAndroid Build Coastguard Worker avg_energy = (sfb_en_m1 + sfb_en_p1) / (FLOAT32)2.0f;
467*15dc779aSAndroid Build Coastguard Worker sfb_energy = ptr_scf_band_energy[scf_band_grp + scf_band];
468*15dc779aSAndroid Build Coastguard Worker FLOAT32 temp_min_snr = 0.0f;
469*15dc779aSAndroid Build Coastguard Worker if (sfb_energy > avg_energy) {
470*15dc779aSAndroid Build Coastguard Worker switch (aot) {
471*15dc779aSAndroid Build Coastguard Worker case AOT_AAC_LC:
472*15dc779aSAndroid Build Coastguard Worker case AOT_SBR:
473*15dc779aSAndroid Build Coastguard Worker case AOT_PS:
474*15dc779aSAndroid Build Coastguard Worker temp_min_snr = MAX((FLOAT32)0.8f * avg_energy / sfb_energy, (FLOAT32)0.316f);
475*15dc779aSAndroid Build Coastguard Worker break;
476*15dc779aSAndroid Build Coastguard Worker
477*15dc779aSAndroid Build Coastguard Worker case AOT_AAC_LD:
478*15dc779aSAndroid Build Coastguard Worker case AOT_AAC_ELD:
479*15dc779aSAndroid Build Coastguard Worker temp_min_snr = MAX((FLOAT32)0.8f * avg_energy / sfb_energy, (FLOAT32)0.408f);
480*15dc779aSAndroid Build Coastguard Worker break;
481*15dc779aSAndroid Build Coastguard Worker }
482*15dc779aSAndroid Build Coastguard Worker if (pstr_psy_chan_out->window_sequence != SHORT_WINDOW) {
483*15dc779aSAndroid Build Coastguard Worker switch (aot) {
484*15dc779aSAndroid Build Coastguard Worker case AOT_AAC_LC:
485*15dc779aSAndroid Build Coastguard Worker case AOT_PS:
486*15dc779aSAndroid Build Coastguard Worker temp_min_snr = MAX(temp_min_snr, (FLOAT32)0.316f);
487*15dc779aSAndroid Build Coastguard Worker break;
488*15dc779aSAndroid Build Coastguard Worker
489*15dc779aSAndroid Build Coastguard Worker case AOT_AAC_LD:
490*15dc779aSAndroid Build Coastguard Worker temp_min_snr = MAX(temp_min_snr, (FLOAT32)0.408f);
491*15dc779aSAndroid Build Coastguard Worker break;
492*15dc779aSAndroid Build Coastguard Worker }
493*15dc779aSAndroid Build Coastguard Worker } else {
494*15dc779aSAndroid Build Coastguard Worker temp_min_snr = MAX(temp_min_snr, (FLOAT32)0.5f);
495*15dc779aSAndroid Build Coastguard Worker }
496*15dc779aSAndroid Build Coastguard Worker ptr_scf_band_min_snr[scf_band_grp + scf_band] =
497*15dc779aSAndroid Build Coastguard Worker MIN(ptr_scf_band_min_snr[scf_band_grp + scf_band], temp_min_snr);
498*15dc779aSAndroid Build Coastguard Worker }
499*15dc779aSAndroid Build Coastguard Worker
500*15dc779aSAndroid Build Coastguard Worker if (((FLOAT32)2.0f * sfb_energy < avg_energy) && (sfb_energy > (FLOAT32)0.0f)) {
501*15dc779aSAndroid Build Coastguard Worker temp_min_snr = avg_energy / ((FLOAT32)2.0f * sfb_energy) *
502*15dc779aSAndroid Build Coastguard Worker ptr_scf_band_min_snr[scf_band_grp + scf_band];
503*15dc779aSAndroid Build Coastguard Worker temp_min_snr = MIN((FLOAT32)0.8f, temp_min_snr);
504*15dc779aSAndroid Build Coastguard Worker ptr_scf_band_min_snr[scf_band_grp + scf_band] =
505*15dc779aSAndroid Build Coastguard Worker MIN(temp_min_snr, ptr_scf_band_min_snr[scf_band_grp + scf_band] * (FLOAT32)3.16f);
506*15dc779aSAndroid Build Coastguard Worker }
507*15dc779aSAndroid Build Coastguard Worker }
508*15dc779aSAndroid Build Coastguard Worker }
509*15dc779aSAndroid Build Coastguard Worker }
510*15dc779aSAndroid Build Coastguard Worker }
511*15dc779aSAndroid Build Coastguard Worker
512*15dc779aSAndroid Build Coastguard Worker if (num_chans == 2) {
513*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_out_mid = pstr_psy_out[chn];
514*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_out_side = pstr_psy_out[chn + 1];
515*15dc779aSAndroid Build Coastguard Worker WORD32 sfb;
516*15dc779aSAndroid Build Coastguard Worker
517*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < pstr_psy_out_mid->sfb_count; sfb++) {
518*15dc779aSAndroid Build Coastguard Worker if (pstr_psy_out[chn]->ms_used[sfb]) {
519*15dc779aSAndroid Build Coastguard Worker FLOAT32 sfb_en_mid = pstr_psy_out_mid->ptr_sfb_energy[sfb];
520*15dc779aSAndroid Build Coastguard Worker FLOAT32 sfb_en_side = pstr_psy_out_side->ptr_sfb_energy[sfb];
521*15dc779aSAndroid Build Coastguard Worker FLOAT32 max_sfb_en = MAX(sfb_en_mid, sfb_en_side);
522*15dc779aSAndroid Build Coastguard Worker FLOAT32 max_thr = 0.25f * pstr_psy_out_mid->sfb_min_snr[sfb] * max_sfb_en;
523*15dc779aSAndroid Build Coastguard Worker
524*15dc779aSAndroid Build Coastguard Worker pstr_psy_out_mid->sfb_min_snr[sfb] = (FLOAT32)MAX(
525*15dc779aSAndroid Build Coastguard Worker pstr_psy_out_mid->sfb_min_snr[sfb],
526*15dc779aSAndroid Build Coastguard Worker MIN(MAX_FLT_VAL, ((FLOAT32)max_thr / (MIN_FLT_VAL + (FLOAT32)sfb_en_mid))));
527*15dc779aSAndroid Build Coastguard Worker
528*15dc779aSAndroid Build Coastguard Worker if (pstr_psy_out_mid->ptr_sfb_energy[sfb] <= 1.0f) {
529*15dc779aSAndroid Build Coastguard Worker pstr_psy_out_mid->ptr_sfb_energy[sfb] =
530*15dc779aSAndroid Build Coastguard Worker MIN(pstr_psy_out_mid->ptr_sfb_energy[sfb], 0.8f);
531*15dc779aSAndroid Build Coastguard Worker }
532*15dc779aSAndroid Build Coastguard Worker
533*15dc779aSAndroid Build Coastguard Worker pstr_psy_out_side->sfb_min_snr[sfb] = (FLOAT32)MAX(
534*15dc779aSAndroid Build Coastguard Worker pstr_psy_out_side->sfb_min_snr[sfb],
535*15dc779aSAndroid Build Coastguard Worker MIN(MAX_FLT_VAL, ((FLOAT32)max_thr / (MIN_FLT_VAL + (FLOAT32)sfb_en_side))));
536*15dc779aSAndroid Build Coastguard Worker
537*15dc779aSAndroid Build Coastguard Worker if (pstr_psy_out_side->sfb_min_snr[sfb] <= 1.0f) {
538*15dc779aSAndroid Build Coastguard Worker pstr_psy_out_side->sfb_min_snr[sfb] = MIN(pstr_psy_out_side->sfb_min_snr[sfb], 0.8f);
539*15dc779aSAndroid Build Coastguard Worker }
540*15dc779aSAndroid Build Coastguard Worker }
541*15dc779aSAndroid Build Coastguard Worker }
542*15dc779aSAndroid Build Coastguard Worker }
543*15dc779aSAndroid Build Coastguard Worker
544*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_chans; ch++) {
545*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_chan_out = pstr_psy_out[ch];
546*15dc779aSAndroid Build Coastguard Worker for (scf_band_grp = 0; scf_band_grp < pstr_psy_chan_out->sfb_count;
547*15dc779aSAndroid Build Coastguard Worker scf_band_grp += pstr_psy_chan_out->sfb_per_group) {
548*15dc779aSAndroid Build Coastguard Worker for (scf_band = 0; scf_band < pstr_psy_chan_out->max_sfb_per_grp; scf_band++) {
549*15dc779aSAndroid Build Coastguard Worker if (pstr_psy_chan_out->ptr_sfb_spread_energy[scf_band_grp + scf_band] >
550*15dc779aSAndroid Build Coastguard Worker pstr_psy_chan_out->ptr_sfb_energy[scf_band_grp + scf_band] ||
551*15dc779aSAndroid Build Coastguard Worker pstr_psy_chan_out->sfb_min_snr[scf_band_grp + scf_band] > 1.0f) {
552*15dc779aSAndroid Build Coastguard Worker ah_flag[ch][scf_band_grp + scf_band] = NO_AH;
553*15dc779aSAndroid Build Coastguard Worker } else {
554*15dc779aSAndroid Build Coastguard Worker ah_flag[ch][scf_band_grp + scf_band] = AH_INACTIVE;
555*15dc779aSAndroid Build Coastguard Worker }
556*15dc779aSAndroid Build Coastguard Worker }
557*15dc779aSAndroid Build Coastguard Worker
558*15dc779aSAndroid Build Coastguard Worker for (scf_band = pstr_psy_chan_out->max_sfb_per_grp;
559*15dc779aSAndroid Build Coastguard Worker scf_band < pstr_psy_chan_out->sfb_per_group; scf_band++) {
560*15dc779aSAndroid Build Coastguard Worker ah_flag[ch][scf_band_grp + scf_band] = NO_AH;
561*15dc779aSAndroid Build Coastguard Worker }
562*15dc779aSAndroid Build Coastguard Worker }
563*15dc779aSAndroid Build Coastguard Worker }
564*15dc779aSAndroid Build Coastguard Worker }
565*15dc779aSAndroid Build Coastguard Worker
iaace_reduce_thr(ixheaace_psy_out_channel ** pstr_psy_out,WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],FLOAT32 thr_exp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],const FLOAT32 red_value,WORD32 num_channels,WORD32 chn)566*15dc779aSAndroid Build Coastguard Worker static VOID iaace_reduce_thr(
567*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel **pstr_psy_out,
568*15dc779aSAndroid Build Coastguard Worker WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
569*15dc779aSAndroid Build Coastguard Worker FLOAT32 thr_exp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
570*15dc779aSAndroid Build Coastguard Worker const FLOAT32 red_value, WORD32 num_channels, WORD32 chn) {
571*15dc779aSAndroid Build Coastguard Worker WORD32 ch, sfb_group, sfb;
572*15dc779aSAndroid Build Coastguard Worker FLOAT32 sfb_energy, sfb_threshold, sfb_thr_reduced;
573*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_sfb_energy_fix, *ptr_sfb_threshold_fix, *ptr_sfb_min_snr_fix, *ptr_thr_exp_fix;
574*15dc779aSAndroid Build Coastguard Worker
575*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_channels; ch++) {
576*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_chan_out = pstr_psy_out[ch];
577*15dc779aSAndroid Build Coastguard Worker ptr_sfb_energy_fix = pstr_psy_chan_out->ptr_sfb_energy;
578*15dc779aSAndroid Build Coastguard Worker ptr_sfb_threshold_fix = pstr_psy_chan_out->ptr_sfb_thr;
579*15dc779aSAndroid Build Coastguard Worker ptr_sfb_min_snr_fix = pstr_psy_chan_out->sfb_min_snr;
580*15dc779aSAndroid Build Coastguard Worker ptr_thr_exp_fix = &thr_exp[ch][0];
581*15dc779aSAndroid Build Coastguard Worker for (sfb_group = 0; sfb_group < pstr_psy_chan_out->sfb_count;
582*15dc779aSAndroid Build Coastguard Worker sfb_group += pstr_psy_chan_out->sfb_per_group) {
583*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < pstr_psy_chan_out->max_sfb_per_grp; sfb++) {
584*15dc779aSAndroid Build Coastguard Worker sfb_energy = ptr_sfb_energy_fix[sfb_group + sfb];
585*15dc779aSAndroid Build Coastguard Worker sfb_threshold = ptr_sfb_threshold_fix[sfb_group + sfb];
586*15dc779aSAndroid Build Coastguard Worker if (sfb_energy > sfb_threshold) {
587*15dc779aSAndroid Build Coastguard Worker sfb_thr_reduced =
588*15dc779aSAndroid Build Coastguard Worker (FLOAT32)pow((ptr_thr_exp_fix[sfb_group + sfb] + red_value), INV_RED_EXP_VAL);
589*15dc779aSAndroid Build Coastguard Worker
590*15dc779aSAndroid Build Coastguard Worker if ((sfb_thr_reduced > ptr_sfb_min_snr_fix[sfb_group + sfb] * sfb_energy) &&
591*15dc779aSAndroid Build Coastguard Worker (ah_flag[ch][sfb_group + sfb] != NO_AH)) {
592*15dc779aSAndroid Build Coastguard Worker sfb_thr_reduced =
593*15dc779aSAndroid Build Coastguard Worker MAX(ptr_sfb_min_snr_fix[sfb_group + sfb] * sfb_energy, sfb_threshold);
594*15dc779aSAndroid Build Coastguard Worker ah_flag[ch][sfb_group + sfb] = AH_ACTIVE;
595*15dc779aSAndroid Build Coastguard Worker }
596*15dc779aSAndroid Build Coastguard Worker ptr_sfb_threshold_fix[sfb_group + sfb] = sfb_thr_reduced;
597*15dc779aSAndroid Build Coastguard Worker }
598*15dc779aSAndroid Build Coastguard Worker }
599*15dc779aSAndroid Build Coastguard Worker }
600*15dc779aSAndroid Build Coastguard Worker }
601*15dc779aSAndroid Build Coastguard Worker }
602*15dc779aSAndroid Build Coastguard Worker
iaace_calc_pe_no_active_holes(FLOAT32 * ptr_pe,FLOAT32 * ptr_const_part,FLOAT32 * ptr_num_active_lines,ia_qc_pe_data_struct * pstr_qs_pe_data,WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],ixheaace_psy_out_channel ** pstr_psy_out,WORD32 num_channels,WORD32 chn)603*15dc779aSAndroid Build Coastguard Worker static VOID iaace_calc_pe_no_active_holes(
604*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_pe, FLOAT32 *ptr_const_part, FLOAT32 *ptr_num_active_lines,
605*15dc779aSAndroid Build Coastguard Worker ia_qc_pe_data_struct *pstr_qs_pe_data,
606*15dc779aSAndroid Build Coastguard Worker WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
607*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel **pstr_psy_out, WORD32 num_channels, WORD32 chn) {
608*15dc779aSAndroid Build Coastguard Worker WORD32 ch, sfb_group, sfb;
609*15dc779aSAndroid Build Coastguard Worker *ptr_pe = 0.0f;
610*15dc779aSAndroid Build Coastguard Worker *ptr_const_part = 0.0f;
611*15dc779aSAndroid Build Coastguard Worker *ptr_num_active_lines = 0;
612*15dc779aSAndroid Build Coastguard Worker
613*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_channels; ch++) {
614*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_chan_out = pstr_psy_out[ch];
615*15dc779aSAndroid Build Coastguard Worker ia_qc_pe_chan_data_struct *ptr_pe_chan_data = &pstr_qs_pe_data->pe_ch_data[ch];
616*15dc779aSAndroid Build Coastguard Worker
617*15dc779aSAndroid Build Coastguard Worker for (sfb_group = 0; sfb_group < pstr_psy_chan_out->sfb_count;
618*15dc779aSAndroid Build Coastguard Worker sfb_group += pstr_psy_chan_out->sfb_per_group) {
619*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < pstr_psy_chan_out->max_sfb_per_grp; sfb++) {
620*15dc779aSAndroid Build Coastguard Worker if (ah_flag[ch][sfb_group + sfb] < AH_ACTIVE) {
621*15dc779aSAndroid Build Coastguard Worker *ptr_pe += ptr_pe_chan_data->sfb_pe[sfb_group + sfb];
622*15dc779aSAndroid Build Coastguard Worker *ptr_const_part += ptr_pe_chan_data->sfb_const_part[sfb_group + sfb];
623*15dc779aSAndroid Build Coastguard Worker *ptr_num_active_lines += ptr_pe_chan_data->num_sfb_active_lines[sfb_group + sfb];
624*15dc779aSAndroid Build Coastguard Worker }
625*15dc779aSAndroid Build Coastguard Worker }
626*15dc779aSAndroid Build Coastguard Worker }
627*15dc779aSAndroid Build Coastguard Worker }
628*15dc779aSAndroid Build Coastguard Worker }
629*15dc779aSAndroid Build Coastguard Worker
iaace_correct_thr(ixheaace_psy_out_channel ** pstr_psy_out,WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],ia_qc_pe_data_struct * pstr_qs_pe_data,FLOAT32 thr_exp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],const FLOAT32 red_value,const FLOAT32 delta_pe,WORD32 num_channels,WORD32 chn)630*15dc779aSAndroid Build Coastguard Worker static VOID iaace_correct_thr(
631*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel **pstr_psy_out,
632*15dc779aSAndroid Build Coastguard Worker WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
633*15dc779aSAndroid Build Coastguard Worker ia_qc_pe_data_struct *pstr_qs_pe_data,
634*15dc779aSAndroid Build Coastguard Worker FLOAT32 thr_exp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
635*15dc779aSAndroid Build Coastguard Worker const FLOAT32 red_value, const FLOAT32 delta_pe, WORD32 num_channels, WORD32 chn) {
636*15dc779aSAndroid Build Coastguard Worker WORD32 i, ch, sfb_group, sfb;
637*15dc779aSAndroid Build Coastguard Worker FLOAT32 delta_sfb_pe;
638*15dc779aSAndroid Build Coastguard Worker FLOAT32 thr_factor;
639*15dc779aSAndroid Build Coastguard Worker FLOAT32 sfb_pe_factors[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
640*15dc779aSAndroid Build Coastguard Worker norm_factor[IXHEAACE_MAX_CH_IN_BS_ELE] = {MIN_FLT_VAL};
641*15dc779aSAndroid Build Coastguard Worker FLOAT32 sfb_en, sfb_thr, sfb_thr_reduced;
642*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_thr_exp;
643*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_sfb_energy, *ptr_sfb_thr, *ptr_sfb_min_snr;
644*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_chan_out = NULL;
645*15dc779aSAndroid Build Coastguard Worker ia_qc_pe_chan_data_struct *pstr_pe_chan_data = NULL;
646*15dc779aSAndroid Build Coastguard Worker
647*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_channels; ch++) {
648*15dc779aSAndroid Build Coastguard Worker pstr_psy_chan_out = pstr_psy_out[ch];
649*15dc779aSAndroid Build Coastguard Worker pstr_pe_chan_data = &pstr_qs_pe_data->pe_ch_data[ch];
650*15dc779aSAndroid Build Coastguard Worker norm_factor[ch] = MIN_FLT_VAL;
651*15dc779aSAndroid Build Coastguard Worker ptr_thr_exp = thr_exp[ch];
652*15dc779aSAndroid Build Coastguard Worker
653*15dc779aSAndroid Build Coastguard Worker for (sfb_group = 0; sfb_group < pstr_psy_chan_out->sfb_count;
654*15dc779aSAndroid Build Coastguard Worker sfb_group += pstr_psy_chan_out->sfb_per_group) {
655*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < pstr_psy_chan_out->max_sfb_per_grp; sfb++) {
656*15dc779aSAndroid Build Coastguard Worker if ((ah_flag[ch][sfb_group + sfb] < AH_ACTIVE) || (delta_pe > 0)) {
657*15dc779aSAndroid Build Coastguard Worker sfb_pe_factors[ch][sfb_group + sfb] =
658*15dc779aSAndroid Build Coastguard Worker pstr_pe_chan_data->num_sfb_active_lines[sfb_group + sfb] /
659*15dc779aSAndroid Build Coastguard Worker (ptr_thr_exp[sfb_group + sfb] + red_value);
660*15dc779aSAndroid Build Coastguard Worker norm_factor[ch] += sfb_pe_factors[ch][sfb_group + sfb];
661*15dc779aSAndroid Build Coastguard Worker } else {
662*15dc779aSAndroid Build Coastguard Worker sfb_pe_factors[ch][sfb_group + sfb] = 0.0f;
663*15dc779aSAndroid Build Coastguard Worker }
664*15dc779aSAndroid Build Coastguard Worker }
665*15dc779aSAndroid Build Coastguard Worker }
666*15dc779aSAndroid Build Coastguard Worker }
667*15dc779aSAndroid Build Coastguard Worker if (num_channels > 1) {
668*15dc779aSAndroid Build Coastguard Worker norm_factor[chn] = norm_factor[chn] + norm_factor[chn + 1];
669*15dc779aSAndroid Build Coastguard Worker }
670*15dc779aSAndroid Build Coastguard Worker norm_factor[chn] = 1.0f / norm_factor[chn];
671*15dc779aSAndroid Build Coastguard Worker
672*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_channels; ch++) {
673*15dc779aSAndroid Build Coastguard Worker pstr_psy_chan_out = pstr_psy_out[ch];
674*15dc779aSAndroid Build Coastguard Worker pstr_pe_chan_data = &pstr_qs_pe_data->pe_ch_data[ch];
675*15dc779aSAndroid Build Coastguard Worker ptr_sfb_energy = pstr_psy_chan_out->ptr_sfb_energy;
676*15dc779aSAndroid Build Coastguard Worker ptr_sfb_thr = pstr_psy_chan_out->ptr_sfb_thr;
677*15dc779aSAndroid Build Coastguard Worker ptr_sfb_min_snr = pstr_psy_chan_out->sfb_min_snr;
678*15dc779aSAndroid Build Coastguard Worker
679*15dc779aSAndroid Build Coastguard Worker for (sfb_group = 0; sfb_group < pstr_psy_chan_out->sfb_count;
680*15dc779aSAndroid Build Coastguard Worker sfb_group += pstr_psy_chan_out->sfb_per_group) {
681*15dc779aSAndroid Build Coastguard Worker i = sfb_group;
682*15dc779aSAndroid Build Coastguard Worker for (sfb = pstr_psy_chan_out->max_sfb_per_grp - 1; sfb >= 0; sfb--, i++) {
683*15dc779aSAndroid Build Coastguard Worker delta_sfb_pe = sfb_pe_factors[ch][i] * norm_factor[chn] * delta_pe;
684*15dc779aSAndroid Build Coastguard Worker if (pstr_pe_chan_data->num_sfb_active_lines[i] > (FLOAT32)0.5f) {
685*15dc779aSAndroid Build Coastguard Worker sfb_en = ptr_sfb_energy[i];
686*15dc779aSAndroid Build Coastguard Worker sfb_thr = ptr_sfb_thr[i];
687*15dc779aSAndroid Build Coastguard Worker thr_factor = MIN(-delta_sfb_pe / pstr_pe_chan_data->num_sfb_active_lines[i], 20.f);
688*15dc779aSAndroid Build Coastguard Worker thr_factor = (FLOAT32)pow(2.0f, thr_factor);
689*15dc779aSAndroid Build Coastguard Worker sfb_thr_reduced = sfb_thr * thr_factor;
690*15dc779aSAndroid Build Coastguard Worker
691*15dc779aSAndroid Build Coastguard Worker if ((sfb_thr_reduced > ptr_sfb_min_snr[i] * sfb_en) &&
692*15dc779aSAndroid Build Coastguard Worker (ah_flag[ch][i] == AH_INACTIVE)) {
693*15dc779aSAndroid Build Coastguard Worker sfb_thr_reduced = MAX(ptr_sfb_min_snr[i] * sfb_en, sfb_thr);
694*15dc779aSAndroid Build Coastguard Worker ah_flag[ch][i] = AH_ACTIVE;
695*15dc779aSAndroid Build Coastguard Worker }
696*15dc779aSAndroid Build Coastguard Worker ptr_sfb_thr[i] = sfb_thr_reduced;
697*15dc779aSAndroid Build Coastguard Worker }
698*15dc779aSAndroid Build Coastguard Worker }
699*15dc779aSAndroid Build Coastguard Worker }
700*15dc779aSAndroid Build Coastguard Worker }
701*15dc779aSAndroid Build Coastguard Worker }
702*15dc779aSAndroid Build Coastguard Worker
iaace_reduce_min_snr(ixheaace_psy_out_channel ** pstr_psy_out,ia_qc_pe_data_struct * pstr_qs_pe_data,WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],const FLOAT32 desired_pe,WORD32 num_channels,WORD32 chn)703*15dc779aSAndroid Build Coastguard Worker static VOID iaace_reduce_min_snr(
704*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel **pstr_psy_out, ia_qc_pe_data_struct *pstr_qs_pe_data,
705*15dc779aSAndroid Build Coastguard Worker WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
706*15dc779aSAndroid Build Coastguard Worker const FLOAT32 desired_pe, WORD32 num_channels, WORD32 chn) {
707*15dc779aSAndroid Build Coastguard Worker WORD32 sfb, sfb_sub_win, ch;
708*15dc779aSAndroid Build Coastguard Worker FLOAT32 delta_pe;
709*15dc779aSAndroid Build Coastguard Worker
710*15dc779aSAndroid Build Coastguard Worker sfb_sub_win = pstr_psy_out[chn]->max_sfb_per_grp;
711*15dc779aSAndroid Build Coastguard Worker
712*15dc779aSAndroid Build Coastguard Worker while (pstr_qs_pe_data->pe > desired_pe && sfb_sub_win > 0) {
713*15dc779aSAndroid Build Coastguard Worker sfb_sub_win--;
714*15dc779aSAndroid Build Coastguard Worker for (sfb = sfb_sub_win; sfb < pstr_psy_out[chn]->sfb_count;
715*15dc779aSAndroid Build Coastguard Worker sfb += pstr_psy_out[chn]->sfb_per_group) {
716*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_channels; ch++) {
717*15dc779aSAndroid Build Coastguard Worker if (ah_flag[ch][sfb] != NO_AH && pstr_psy_out[ch]->sfb_min_snr[sfb] < MIN_SNR_LIMIT) {
718*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch]->sfb_min_snr[sfb] = MIN_SNR_LIMIT;
719*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch]->ptr_sfb_thr[sfb] =
720*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[ch]->ptr_sfb_energy[sfb] * pstr_psy_out[ch]->sfb_min_snr[sfb];
721*15dc779aSAndroid Build Coastguard Worker delta_pe = pstr_qs_pe_data->pe_ch_data[ch].sfb_lines[sfb] * 1.5f -
722*15dc779aSAndroid Build Coastguard Worker pstr_qs_pe_data->pe_ch_data[ch].sfb_pe[sfb];
723*15dc779aSAndroid Build Coastguard Worker pstr_qs_pe_data->pe += delta_pe;
724*15dc779aSAndroid Build Coastguard Worker pstr_qs_pe_data->pe_ch_data[ch].pe += delta_pe;
725*15dc779aSAndroid Build Coastguard Worker }
726*15dc779aSAndroid Build Coastguard Worker }
727*15dc779aSAndroid Build Coastguard Worker if (pstr_qs_pe_data->pe <= desired_pe) {
728*15dc779aSAndroid Build Coastguard Worker break;
729*15dc779aSAndroid Build Coastguard Worker }
730*15dc779aSAndroid Build Coastguard Worker }
731*15dc779aSAndroid Build Coastguard Worker }
732*15dc779aSAndroid Build Coastguard Worker }
733*15dc779aSAndroid Build Coastguard Worker
iaace_allow_more_holes(ixheaace_psy_out_channel ** pstr_psy_out,ia_qc_pe_data_struct * pstr_qs_pe_data,WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],const ia_ah_param_struct * pstr_str_ah_param,const FLOAT32 desired_pe,WORD32 num_channels,WORD32 chn)734*15dc779aSAndroid Build Coastguard Worker static VOID iaace_allow_more_holes(
735*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel **pstr_psy_out, ia_qc_pe_data_struct *pstr_qs_pe_data,
736*15dc779aSAndroid Build Coastguard Worker WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
737*15dc779aSAndroid Build Coastguard Worker const ia_ah_param_struct *pstr_str_ah_param, const FLOAT32 desired_pe, WORD32 num_channels,
738*15dc779aSAndroid Build Coastguard Worker WORD32 chn) {
739*15dc779aSAndroid Build Coastguard Worker WORD32 sfb, ch;
740*15dc779aSAndroid Build Coastguard Worker FLOAT32 act_pe = pstr_qs_pe_data->pe;
741*15dc779aSAndroid Build Coastguard Worker
742*15dc779aSAndroid Build Coastguard Worker if (num_channels == 2 &&
743*15dc779aSAndroid Build Coastguard Worker pstr_psy_out[chn]->window_sequence == pstr_psy_out[chn + 1]->window_sequence) {
744*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_out_left = pstr_psy_out[chn];
745*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_out_right = pstr_psy_out[chn + 1];
746*15dc779aSAndroid Build Coastguard Worker
747*15dc779aSAndroid Build Coastguard Worker for (sfb = 0; sfb < pstr_psy_out_left->sfb_count; sfb++) {
748*15dc779aSAndroid Build Coastguard Worker if (pstr_psy_out[chn]->ms_used[sfb]) {
749*15dc779aSAndroid Build Coastguard Worker if (ah_flag[chn + 1][sfb] != NO_AH &&
750*15dc779aSAndroid Build Coastguard Worker 0.4f * pstr_psy_out_left->sfb_min_snr[sfb] * pstr_psy_out_left->ptr_sfb_energy[sfb] >
751*15dc779aSAndroid Build Coastguard Worker pstr_psy_out_right->ptr_sfb_energy[sfb]) {
752*15dc779aSAndroid Build Coastguard Worker ah_flag[chn + 1][sfb] = NO_AH;
753*15dc779aSAndroid Build Coastguard Worker
754*15dc779aSAndroid Build Coastguard Worker pstr_psy_out_right->ptr_sfb_thr[sfb] = 2.0f * pstr_psy_out_right->ptr_sfb_energy[sfb];
755*15dc779aSAndroid Build Coastguard Worker
756*15dc779aSAndroid Build Coastguard Worker act_pe -= pstr_qs_pe_data->pe_ch_data[chn + 1].sfb_pe[sfb];
757*15dc779aSAndroid Build Coastguard Worker } else {
758*15dc779aSAndroid Build Coastguard Worker if (ah_flag[chn][sfb] != NO_AH && 0.4f * pstr_psy_out_right->sfb_min_snr[sfb] *
759*15dc779aSAndroid Build Coastguard Worker pstr_psy_out_right->ptr_sfb_energy[sfb] >
760*15dc779aSAndroid Build Coastguard Worker pstr_psy_out_left->ptr_sfb_energy[sfb]) {
761*15dc779aSAndroid Build Coastguard Worker ah_flag[chn][sfb] = NO_AH;
762*15dc779aSAndroid Build Coastguard Worker
763*15dc779aSAndroid Build Coastguard Worker pstr_psy_out_left->ptr_sfb_thr[sfb] = 2.0f * pstr_psy_out_left->ptr_sfb_energy[sfb];
764*15dc779aSAndroid Build Coastguard Worker
765*15dc779aSAndroid Build Coastguard Worker act_pe -= pstr_qs_pe_data->pe_ch_data[chn].sfb_pe[sfb];
766*15dc779aSAndroid Build Coastguard Worker }
767*15dc779aSAndroid Build Coastguard Worker }
768*15dc779aSAndroid Build Coastguard Worker if (act_pe < desired_pe) {
769*15dc779aSAndroid Build Coastguard Worker break;
770*15dc779aSAndroid Build Coastguard Worker }
771*15dc779aSAndroid Build Coastguard Worker }
772*15dc779aSAndroid Build Coastguard Worker }
773*15dc779aSAndroid Build Coastguard Worker }
774*15dc779aSAndroid Build Coastguard Worker if (act_pe > desired_pe) {
775*15dc779aSAndroid Build Coastguard Worker WORD32 start_sfb[IXHEAACE_MAX_CH_IN_BS_ELE] = {0};
776*15dc779aSAndroid Build Coastguard Worker FLOAT32 average_energy, min_energy;
777*15dc779aSAndroid Build Coastguard Worker WORD32 ah_cnt;
778*15dc779aSAndroid Build Coastguard Worker WORD32 en_idx;
779*15dc779aSAndroid Build Coastguard Worker FLOAT32 energy[4];
780*15dc779aSAndroid Build Coastguard Worker WORD32 min_sfb, max_sfb;
781*15dc779aSAndroid Build Coastguard Worker WORD32 done;
782*15dc779aSAndroid Build Coastguard Worker
783*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_channels; ch++) {
784*15dc779aSAndroid Build Coastguard Worker if (pstr_psy_out[ch]->window_sequence != SHORT_WINDOW) {
785*15dc779aSAndroid Build Coastguard Worker start_sfb[ch] = pstr_str_ah_param->start_sfb_long;
786*15dc779aSAndroid Build Coastguard Worker } else {
787*15dc779aSAndroid Build Coastguard Worker start_sfb[ch] = pstr_str_ah_param->start_sfb_short;
788*15dc779aSAndroid Build Coastguard Worker }
789*15dc779aSAndroid Build Coastguard Worker }
790*15dc779aSAndroid Build Coastguard Worker
791*15dc779aSAndroid Build Coastguard Worker average_energy = 0.0f;
792*15dc779aSAndroid Build Coastguard Worker min_energy = MAX_FLT_VAL;
793*15dc779aSAndroid Build Coastguard Worker ah_cnt = 0;
794*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_channels; ch++) {
795*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_chan_out = pstr_psy_out[ch];
796*15dc779aSAndroid Build Coastguard Worker for (sfb = start_sfb[ch]; sfb < pstr_psy_chan_out->sfb_count; sfb++) {
797*15dc779aSAndroid Build Coastguard Worker if ((ah_flag[ch][sfb] != NO_AH) &&
798*15dc779aSAndroid Build Coastguard Worker (pstr_psy_chan_out->ptr_sfb_energy[sfb] > pstr_psy_chan_out->ptr_sfb_thr[sfb])) {
799*15dc779aSAndroid Build Coastguard Worker min_energy = MIN(min_energy, pstr_psy_chan_out->ptr_sfb_energy[sfb]);
800*15dc779aSAndroid Build Coastguard Worker average_energy += pstr_psy_chan_out->ptr_sfb_energy[sfb];
801*15dc779aSAndroid Build Coastguard Worker ah_cnt++;
802*15dc779aSAndroid Build Coastguard Worker }
803*15dc779aSAndroid Build Coastguard Worker }
804*15dc779aSAndroid Build Coastguard Worker }
805*15dc779aSAndroid Build Coastguard Worker
806*15dc779aSAndroid Build Coastguard Worker average_energy = MIN(MAX_FLT_VAL, average_energy / (ah_cnt + MIN_FLT_VAL));
807*15dc779aSAndroid Build Coastguard Worker
808*15dc779aSAndroid Build Coastguard Worker for (en_idx = 0; en_idx < 4; en_idx++) {
809*15dc779aSAndroid Build Coastguard Worker energy[en_idx] = min_energy * (FLOAT32)pow(average_energy / (min_energy + MIN_FLT_VAL),
810*15dc779aSAndroid Build Coastguard Worker (2 * en_idx + 1) / 7.0f);
811*15dc779aSAndroid Build Coastguard Worker }
812*15dc779aSAndroid Build Coastguard Worker max_sfb = pstr_psy_out[chn]->sfb_count - 1;
813*15dc779aSAndroid Build Coastguard Worker min_sfb = start_sfb[chn];
814*15dc779aSAndroid Build Coastguard Worker
815*15dc779aSAndroid Build Coastguard Worker if (num_channels == 2) {
816*15dc779aSAndroid Build Coastguard Worker max_sfb = MAX(max_sfb, pstr_psy_out[chn + 1]->sfb_count - 1);
817*15dc779aSAndroid Build Coastguard Worker
818*15dc779aSAndroid Build Coastguard Worker min_sfb = MIN(min_sfb, start_sfb[chn + 1]);
819*15dc779aSAndroid Build Coastguard Worker }
820*15dc779aSAndroid Build Coastguard Worker
821*15dc779aSAndroid Build Coastguard Worker sfb = max_sfb;
822*15dc779aSAndroid Build Coastguard Worker en_idx = 0;
823*15dc779aSAndroid Build Coastguard Worker done = 0;
824*15dc779aSAndroid Build Coastguard Worker while (!done) {
825*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_channels; ch++) {
826*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel *pstr_psy_chan_out = pstr_psy_out[ch];
827*15dc779aSAndroid Build Coastguard Worker if (sfb >= start_sfb[ch] && sfb < pstr_psy_chan_out->sfb_count) {
828*15dc779aSAndroid Build Coastguard Worker if (ah_flag[ch][sfb] != NO_AH &&
829*15dc779aSAndroid Build Coastguard Worker pstr_psy_chan_out->ptr_sfb_energy[sfb] < energy[en_idx]) {
830*15dc779aSAndroid Build Coastguard Worker ah_flag[ch][sfb] = NO_AH;
831*15dc779aSAndroid Build Coastguard Worker pstr_psy_chan_out->ptr_sfb_thr[sfb] = 2.0f * pstr_psy_chan_out->ptr_sfb_energy[sfb];
832*15dc779aSAndroid Build Coastguard Worker act_pe -= pstr_qs_pe_data->pe_ch_data[ch].sfb_pe[sfb];
833*15dc779aSAndroid Build Coastguard Worker }
834*15dc779aSAndroid Build Coastguard Worker
835*15dc779aSAndroid Build Coastguard Worker if (act_pe < desired_pe) {
836*15dc779aSAndroid Build Coastguard Worker done = 1;
837*15dc779aSAndroid Build Coastguard Worker break;
838*15dc779aSAndroid Build Coastguard Worker }
839*15dc779aSAndroid Build Coastguard Worker }
840*15dc779aSAndroid Build Coastguard Worker }
841*15dc779aSAndroid Build Coastguard Worker sfb--;
842*15dc779aSAndroid Build Coastguard Worker if (sfb < min_sfb) {
843*15dc779aSAndroid Build Coastguard Worker sfb = max_sfb;
844*15dc779aSAndroid Build Coastguard Worker en_idx++;
845*15dc779aSAndroid Build Coastguard Worker if (en_idx >= 4) {
846*15dc779aSAndroid Build Coastguard Worker done = 1;
847*15dc779aSAndroid Build Coastguard Worker }
848*15dc779aSAndroid Build Coastguard Worker }
849*15dc779aSAndroid Build Coastguard Worker }
850*15dc779aSAndroid Build Coastguard Worker }
851*15dc779aSAndroid Build Coastguard Worker }
852*15dc779aSAndroid Build Coastguard Worker
iaace_adapt_thr_to_pe(ixheaace_psy_out_channel ** pstr_psy_out,ia_qc_pe_data_struct * pstr_qs_pe_data,const FLOAT32 desired_pe,ia_ah_param_struct * pstr_ah_param,ia_min_snr_adapt_param_struct * pstr_msa_param,WORD32 num_channels,WORD32 chn,WORD32 aot)853*15dc779aSAndroid Build Coastguard Worker static VOID iaace_adapt_thr_to_pe(
854*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel **pstr_psy_out,
855*15dc779aSAndroid Build Coastguard Worker ia_qc_pe_data_struct *pstr_qs_pe_data, const FLOAT32 desired_pe,
856*15dc779aSAndroid Build Coastguard Worker ia_ah_param_struct *pstr_ah_param, ia_min_snr_adapt_param_struct *pstr_msa_param,
857*15dc779aSAndroid Build Coastguard Worker WORD32 num_channels, WORD32 chn, WORD32 aot) {
858*15dc779aSAndroid Build Coastguard Worker FLOAT32 no_red_pe, red_pe, red_pe_no_ah;
859*15dc779aSAndroid Build Coastguard Worker FLOAT32 const_part, const_part_no_ah;
860*15dc779aSAndroid Build Coastguard Worker FLOAT32 num_active_lines, num_active_lines_no_ah;
861*15dc779aSAndroid Build Coastguard Worker FLOAT32 desired_pe_no_ah;
862*15dc779aSAndroid Build Coastguard Worker FLOAT32 redval = 0.0f;
863*15dc779aSAndroid Build Coastguard Worker WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
864*15dc779aSAndroid Build Coastguard Worker FLOAT32 thr_exp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
865*15dc779aSAndroid Build Coastguard Worker WORD32 iteration;
866*15dc779aSAndroid Build Coastguard Worker
867*15dc779aSAndroid Build Coastguard Worker iaace_calc_thr_exp(thr_exp, pstr_psy_out, num_channels, chn);
868*15dc779aSAndroid Build Coastguard Worker iaace_adapt_min_snr(pstr_psy_out, pstr_msa_param, num_channels, chn);
869*15dc779aSAndroid Build Coastguard Worker iaace_init_avoid_hole_flag(ah_flag, pstr_psy_out, pstr_ah_param, num_channels, chn, aot);
870*15dc779aSAndroid Build Coastguard Worker
871*15dc779aSAndroid Build Coastguard Worker no_red_pe = pstr_qs_pe_data->pe;
872*15dc779aSAndroid Build Coastguard Worker const_part = pstr_qs_pe_data->const_part;
873*15dc779aSAndroid Build Coastguard Worker num_active_lines = pstr_qs_pe_data->num_active_lines;
874*15dc779aSAndroid Build Coastguard Worker if (num_active_lines > FLT_EPSILON) {
875*15dc779aSAndroid Build Coastguard Worker FLOAT32 avg_thr_exp =
876*15dc779aSAndroid Build Coastguard Worker (FLOAT32)pow(2.0f, (const_part - no_red_pe) / (INV_RED_EXP_VAL * num_active_lines));
877*15dc779aSAndroid Build Coastguard Worker redval = (FLOAT32)pow(2.0f, (const_part - desired_pe) / (INV_RED_EXP_VAL * num_active_lines))
878*15dc779aSAndroid Build Coastguard Worker - avg_thr_exp;
879*15dc779aSAndroid Build Coastguard Worker redval = MAX(0.0f, redval);
880*15dc779aSAndroid Build Coastguard Worker iaace_reduce_thr(pstr_psy_out, ah_flag, thr_exp, redval, num_channels, chn);
881*15dc779aSAndroid Build Coastguard Worker }
882*15dc779aSAndroid Build Coastguard Worker
883*15dc779aSAndroid Build Coastguard Worker iaace_calc_sfb_pe_data(pstr_qs_pe_data, pstr_psy_out, num_channels, chn);
884*15dc779aSAndroid Build Coastguard Worker red_pe = pstr_qs_pe_data->pe;
885*15dc779aSAndroid Build Coastguard Worker
886*15dc779aSAndroid Build Coastguard Worker iteration = 0;
887*15dc779aSAndroid Build Coastguard Worker do {
888*15dc779aSAndroid Build Coastguard Worker iaace_calc_pe_no_active_holes(&red_pe_no_ah, &const_part_no_ah, &num_active_lines_no_ah,
889*15dc779aSAndroid Build Coastguard Worker pstr_qs_pe_data, ah_flag, pstr_psy_out, num_channels, chn);
890*15dc779aSAndroid Build Coastguard Worker
891*15dc779aSAndroid Build Coastguard Worker desired_pe_no_ah = MAX(desired_pe - (red_pe - red_pe_no_ah), 0);
892*15dc779aSAndroid Build Coastguard Worker
893*15dc779aSAndroid Build Coastguard Worker if (num_active_lines_no_ah > FLT_EPSILON) {
894*15dc779aSAndroid Build Coastguard Worker FLOAT32 avg_thr_exp = (FLOAT32)pow(
895*15dc779aSAndroid Build Coastguard Worker 2.0f, (const_part_no_ah - red_pe_no_ah) / (INV_RED_EXP_VAL * num_active_lines_no_ah));
896*15dc779aSAndroid Build Coastguard Worker redval += (FLOAT32)pow(2.0f, (const_part_no_ah - desired_pe_no_ah) /
897*15dc779aSAndroid Build Coastguard Worker (INV_RED_EXP_VAL * num_active_lines_no_ah)) -
898*15dc779aSAndroid Build Coastguard Worker avg_thr_exp;
899*15dc779aSAndroid Build Coastguard Worker redval = MAX(0.0f, redval);
900*15dc779aSAndroid Build Coastguard Worker iaace_reduce_thr(pstr_psy_out, ah_flag, thr_exp, redval, num_channels, chn);
901*15dc779aSAndroid Build Coastguard Worker }
902*15dc779aSAndroid Build Coastguard Worker
903*15dc779aSAndroid Build Coastguard Worker iaace_calc_sfb_pe_data(pstr_qs_pe_data, pstr_psy_out, num_channels, chn);
904*15dc779aSAndroid Build Coastguard Worker
905*15dc779aSAndroid Build Coastguard Worker red_pe = pstr_qs_pe_data->pe;
906*15dc779aSAndroid Build Coastguard Worker iteration++;
907*15dc779aSAndroid Build Coastguard Worker } while ((fabs(red_pe - desired_pe) > (0.05f) * desired_pe) && (iteration < 2));
908*15dc779aSAndroid Build Coastguard Worker
909*15dc779aSAndroid Build Coastguard Worker if (red_pe < 1.15f * desired_pe) {
910*15dc779aSAndroid Build Coastguard Worker iaace_correct_thr(pstr_psy_out, ah_flag, pstr_qs_pe_data, thr_exp, redval,
911*15dc779aSAndroid Build Coastguard Worker desired_pe - red_pe, num_channels, chn);
912*15dc779aSAndroid Build Coastguard Worker } else {
913*15dc779aSAndroid Build Coastguard Worker iaace_reduce_min_snr(pstr_psy_out, pstr_qs_pe_data, ah_flag, 1.05f * desired_pe, num_channels,
914*15dc779aSAndroid Build Coastguard Worker chn);
915*15dc779aSAndroid Build Coastguard Worker iaace_allow_more_holes(pstr_psy_out, pstr_qs_pe_data, ah_flag, pstr_ah_param,
916*15dc779aSAndroid Build Coastguard Worker 1.05f * desired_pe, num_channels, chn);
917*15dc779aSAndroid Build Coastguard Worker }
918*15dc779aSAndroid Build Coastguard Worker }
919*15dc779aSAndroid Build Coastguard Worker
iaace_adjust_threshold(ia_adj_thr_state_struct * pstr_adj_thr_state,ia_adj_thr_elem_struct * pstr_adj_thr_elem,ixheaace_psy_out_channel ** pstr_psy_out,FLOAT32 * ptr_ch_bit_dist,ixheaace_qc_out_element * pstr_qc_out_el,const WORD32 avg_bits,const WORD32 bitres_bits,const WORD32 max_bitres_bits,const WORD32 side_info_bits,FLOAT32 * max_bit_fac,FLOAT32 * ptr_sfb_n_relevant_lines,FLOAT32 * ptr_sfb_ld_energy,WORD32 num_channels,WORD32 chn,WORD32 aot,WORD8 * ptr_scratch)920*15dc779aSAndroid Build Coastguard Worker VOID iaace_adjust_threshold(ia_adj_thr_state_struct *pstr_adj_thr_state,
921*15dc779aSAndroid Build Coastguard Worker ia_adj_thr_elem_struct *pstr_adj_thr_elem,
922*15dc779aSAndroid Build Coastguard Worker ixheaace_psy_out_channel **pstr_psy_out,
923*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_ch_bit_dist, ixheaace_qc_out_element *pstr_qc_out_el,
924*15dc779aSAndroid Build Coastguard Worker const WORD32 avg_bits, const WORD32 bitres_bits,
925*15dc779aSAndroid Build Coastguard Worker const WORD32 max_bitres_bits, const WORD32 side_info_bits,
926*15dc779aSAndroid Build Coastguard Worker FLOAT32 *max_bit_fac, FLOAT32 *ptr_sfb_n_relevant_lines,
927*15dc779aSAndroid Build Coastguard Worker FLOAT32 *ptr_sfb_ld_energy, WORD32 num_channels, WORD32 chn,
928*15dc779aSAndroid Build Coastguard Worker WORD32 aot, WORD8 *ptr_scratch) {
929*15dc779aSAndroid Build Coastguard Worker FLOAT32 no_red_pe, granted_pe, granted_pe_corr;
930*15dc779aSAndroid Build Coastguard Worker WORD32 curr_win_sequence;
931*15dc779aSAndroid Build Coastguard Worker ia_qc_pe_data_struct *pstr_qc_pe_data = (ia_qc_pe_data_struct *)ptr_scratch;
932*15dc779aSAndroid Build Coastguard Worker FLOAT32 bit_factor;
933*15dc779aSAndroid Build Coastguard Worker WORD32 ch;
934*15dc779aSAndroid Build Coastguard Worker
935*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_channels; ch++) {
936*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_data->pe_ch_data[ch].sfb_lines =
937*15dc779aSAndroid Build Coastguard Worker ptr_sfb_n_relevant_lines + MAXIMUM_GROUPED_SCALE_FACTOR_BAND * ch;
938*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_data->pe_ch_data[ch].sfb_ld_energy =
939*15dc779aSAndroid Build Coastguard Worker ptr_sfb_ld_energy + MAXIMUM_GROUPED_SCALE_FACTOR_BAND * ch;
940*15dc779aSAndroid Build Coastguard Worker }
941*15dc779aSAndroid Build Coastguard Worker pstr_qc_pe_data->offset = pstr_adj_thr_elem->pe_offset;
942*15dc779aSAndroid Build Coastguard Worker
943*15dc779aSAndroid Build Coastguard Worker iaace_calc_sfb_pe_data(pstr_qc_pe_data, pstr_psy_out, num_channels, chn);
944*15dc779aSAndroid Build Coastguard Worker
945*15dc779aSAndroid Build Coastguard Worker no_red_pe = pstr_qc_pe_data->pe;
946*15dc779aSAndroid Build Coastguard Worker
947*15dc779aSAndroid Build Coastguard Worker curr_win_sequence = LONG_WINDOW;
948*15dc779aSAndroid Build Coastguard Worker if (num_channels == 2) {
949*15dc779aSAndroid Build Coastguard Worker if ((pstr_psy_out[chn]->window_sequence == SHORT_WINDOW) ||
950*15dc779aSAndroid Build Coastguard Worker (pstr_psy_out[chn + 1]->window_sequence == SHORT_WINDOW)) {
951*15dc779aSAndroid Build Coastguard Worker curr_win_sequence = SHORT_WINDOW;
952*15dc779aSAndroid Build Coastguard Worker }
953*15dc779aSAndroid Build Coastguard Worker } else {
954*15dc779aSAndroid Build Coastguard Worker curr_win_sequence = pstr_psy_out[chn]->window_sequence;
955*15dc779aSAndroid Build Coastguard Worker }
956*15dc779aSAndroid Build Coastguard Worker
957*15dc779aSAndroid Build Coastguard Worker bit_factor = iaace_bitres_calc_bitfac(
958*15dc779aSAndroid Build Coastguard Worker bitres_bits, max_bitres_bits, no_red_pe + 5.0f * side_info_bits, curr_win_sequence,
959*15dc779aSAndroid Build Coastguard Worker avg_bits, *max_bit_fac, pstr_adj_thr_state, pstr_adj_thr_elem);
960*15dc779aSAndroid Build Coastguard Worker
961*15dc779aSAndroid Build Coastguard Worker granted_pe = bit_factor * iaace_bits_to_pe((FLOAT32)avg_bits);
962*15dc779aSAndroid Build Coastguard Worker
963*15dc779aSAndroid Build Coastguard Worker iaace_calc_pe_correction(&(pstr_adj_thr_elem->pe_correction_fac), MIN(granted_pe, no_red_pe),
964*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_elem->pe_last, pstr_adj_thr_elem->dyn_bits_last);
965*15dc779aSAndroid Build Coastguard Worker
966*15dc779aSAndroid Build Coastguard Worker granted_pe_corr = granted_pe * pstr_adj_thr_elem->pe_correction_fac;
967*15dc779aSAndroid Build Coastguard Worker
968*15dc779aSAndroid Build Coastguard Worker if (granted_pe_corr < no_red_pe) {
969*15dc779aSAndroid Build Coastguard Worker iaace_adapt_thr_to_pe(pstr_psy_out, pstr_qc_pe_data, granted_pe_corr,
970*15dc779aSAndroid Build Coastguard Worker &pstr_adj_thr_elem->str_ah_param,
971*15dc779aSAndroid Build Coastguard Worker &pstr_adj_thr_elem->str_min_snr_adapt_params, num_channels, chn, aot);
972*15dc779aSAndroid Build Coastguard Worker }
973*15dc779aSAndroid Build Coastguard Worker
974*15dc779aSAndroid Build Coastguard Worker for (ch = chn; ch < chn + num_channels; ch++) {
975*15dc779aSAndroid Build Coastguard Worker FLOAT32 tmp_var, temp1;
976*15dc779aSAndroid Build Coastguard Worker if (pstr_qc_pe_data->pe) {
977*15dc779aSAndroid Build Coastguard Worker tmp_var = 1.0f - num_channels * 0.2f;
978*15dc779aSAndroid Build Coastguard Worker temp1 = pstr_qc_pe_data->pe_ch_data[ch].pe / pstr_qc_pe_data->pe;
979*15dc779aSAndroid Build Coastguard Worker temp1 = temp1 * tmp_var;
980*15dc779aSAndroid Build Coastguard Worker ptr_ch_bit_dist[ch] = temp1 + 0.2f;
981*15dc779aSAndroid Build Coastguard Worker if (ptr_ch_bit_dist[ch] < 0.2f) {
982*15dc779aSAndroid Build Coastguard Worker ptr_ch_bit_dist[ch] = 0.2f;
983*15dc779aSAndroid Build Coastguard Worker }
984*15dc779aSAndroid Build Coastguard Worker } else {
985*15dc779aSAndroid Build Coastguard Worker ptr_ch_bit_dist[ch] = 0.2f;
986*15dc779aSAndroid Build Coastguard Worker }
987*15dc779aSAndroid Build Coastguard Worker }
988*15dc779aSAndroid Build Coastguard Worker
989*15dc779aSAndroid Build Coastguard Worker pstr_qc_out_el->pe = no_red_pe;
990*15dc779aSAndroid Build Coastguard Worker pstr_adj_thr_elem->pe_last = granted_pe;
991*15dc779aSAndroid Build Coastguard Worker }
992