xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_psy_configuration.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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 <stdlib.h>
22*15dc779aSAndroid Build Coastguard Worker #include <math.h>
23*15dc779aSAndroid Build Coastguard Worker 
24*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
25*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_constants.h"
26*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_common_enc.h"
27*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_uni_drc.h"
28*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_tables.h"
29*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_api.h"
30*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_api.h"
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_aac_constants.h"
32*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops32.h"
33*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops16.h"
34*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops40.h"
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops.h"
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_error_standards.h"
37*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_error_codes.h"
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_psy_const.h"
39*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_tns.h"
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_tns_params.h"
41*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_rom.h"
42*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_common_rom.h"
43*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_bitbuffer.h"
44*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_psy_configuration.h"
45*15dc779aSAndroid Build Coastguard Worker 
46*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_adjust_threshold_data.h"
47*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_tns_params.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 
ia_enhaacplus_enc_init_sfb_table(ixheaace_psycho_tables * pstr_psycho_tab,WORD32 sample_rate,WORD32 aot,WORD32 block_type,WORD32 * ptr_sfb_offset,WORD32 * sfb_cnt,WORD32 long_frame_len)56*15dc779aSAndroid Build Coastguard Worker static IA_ERRORCODE ia_enhaacplus_enc_init_sfb_table(ixheaace_psycho_tables *pstr_psycho_tab,
57*15dc779aSAndroid Build Coastguard Worker                                                      WORD32 sample_rate, WORD32 aot,
58*15dc779aSAndroid Build Coastguard Worker                                                      WORD32 block_type, WORD32 *ptr_sfb_offset,
59*15dc779aSAndroid Build Coastguard Worker                                                      WORD32 *sfb_cnt, WORD32 long_frame_len) {
60*15dc779aSAndroid Build Coastguard Worker   const UWORD8 *ptr_sfb_param = NULL;
61*15dc779aSAndroid Build Coastguard Worker   UWORD32 i;
62*15dc779aSAndroid Build Coastguard Worker   WORD32 spec_start_offset, spec_lines = 0;
63*15dc779aSAndroid Build Coastguard Worker 
64*15dc779aSAndroid Build Coastguard Worker   /* sfb_info_tab[] */
65*15dc779aSAndroid Build Coastguard Worker   for (i = 0; i < sizeof(pstr_psycho_tab->sfb_info_tab) / sizeof(ixheaace_sfb_info_tab); i++) {
66*15dc779aSAndroid Build Coastguard Worker     if (pstr_psycho_tab->sfb_info_tab[i].sample_rate == sample_rate) {
67*15dc779aSAndroid Build Coastguard Worker       switch (block_type) {
68*15dc779aSAndroid Build Coastguard Worker         case LONG_WINDOW:
69*15dc779aSAndroid Build Coastguard Worker         case START_WINDOW:
70*15dc779aSAndroid Build Coastguard Worker         case STOP_WINDOW:
71*15dc779aSAndroid Build Coastguard Worker           if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
72*15dc779aSAndroid Build Coastguard Worker             if (long_frame_len == FRAME_LEN_960) {
73*15dc779aSAndroid Build Coastguard Worker               ptr_sfb_param = pstr_psycho_tab->sfb_info_tab[i].param_long_960;
74*15dc779aSAndroid Build Coastguard Worker             } else {
75*15dc779aSAndroid Build Coastguard Worker               ptr_sfb_param = pstr_psycho_tab->sfb_info_tab[i].param_long;
76*15dc779aSAndroid Build Coastguard Worker             }
77*15dc779aSAndroid Build Coastguard Worker             spec_lines = long_frame_len;
78*15dc779aSAndroid Build Coastguard Worker             break;
79*15dc779aSAndroid Build Coastguard Worker           } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
80*15dc779aSAndroid Build Coastguard Worker             if (long_frame_len == FRAME_LEN_480)
81*15dc779aSAndroid Build Coastguard Worker               ptr_sfb_param = pstr_psycho_tab->sfb_info_tab[i].param_long_480_ld;
82*15dc779aSAndroid Build Coastguard Worker             else
83*15dc779aSAndroid Build Coastguard Worker               ptr_sfb_param = pstr_psycho_tab->sfb_info_tab[i].param_long_512_ld;
84*15dc779aSAndroid Build Coastguard Worker             spec_lines = long_frame_len;
85*15dc779aSAndroid Build Coastguard Worker             break;
86*15dc779aSAndroid Build Coastguard Worker           }
87*15dc779aSAndroid Build Coastguard Worker 
88*15dc779aSAndroid Build Coastguard Worker         case SHORT_WINDOW:
89*15dc779aSAndroid Build Coastguard Worker           if (long_frame_len == FRAME_LEN_SHORT_120) {
90*15dc779aSAndroid Build Coastguard Worker             ptr_sfb_param = pstr_psycho_tab->sfb_info_tab[i].param_short_120;
91*15dc779aSAndroid Build Coastguard Worker           } else {
92*15dc779aSAndroid Build Coastguard Worker             ptr_sfb_param = pstr_psycho_tab->sfb_info_tab[i].param_short;
93*15dc779aSAndroid Build Coastguard Worker           }
94*15dc779aSAndroid Build Coastguard Worker           spec_lines = long_frame_len;
95*15dc779aSAndroid Build Coastguard Worker           break;
96*15dc779aSAndroid Build Coastguard Worker       }
97*15dc779aSAndroid Build Coastguard Worker       break;
98*15dc779aSAndroid Build Coastguard Worker     }
99*15dc779aSAndroid Build Coastguard Worker   }
100*15dc779aSAndroid Build Coastguard Worker 
101*15dc779aSAndroid Build Coastguard Worker   if (ptr_sfb_param == NULL) {
102*15dc779aSAndroid Build Coastguard Worker     return IA_EXHEAACE_INIT_FATAL_SCALE_FACTOR_BAND_NOT_SUPPORTED;
103*15dc779aSAndroid Build Coastguard Worker   }
104*15dc779aSAndroid Build Coastguard Worker 
105*15dc779aSAndroid Build Coastguard Worker   *sfb_cnt = 0;
106*15dc779aSAndroid Build Coastguard Worker   spec_start_offset = 0;
107*15dc779aSAndroid Build Coastguard Worker 
108*15dc779aSAndroid Build Coastguard Worker   do {
109*15dc779aSAndroid Build Coastguard Worker     ptr_sfb_offset[*sfb_cnt] = spec_start_offset;
110*15dc779aSAndroid Build Coastguard Worker 
111*15dc779aSAndroid Build Coastguard Worker     spec_start_offset += ptr_sfb_param[*sfb_cnt];
112*15dc779aSAndroid Build Coastguard Worker 
113*15dc779aSAndroid Build Coastguard Worker     (*sfb_cnt)++;
114*15dc779aSAndroid Build Coastguard Worker   } while (spec_start_offset < spec_lines);
115*15dc779aSAndroid Build Coastguard Worker 
116*15dc779aSAndroid Build Coastguard Worker   if (spec_start_offset != spec_lines) {
117*15dc779aSAndroid Build Coastguard Worker     return IA_EXHEAACE_INIT_FATAL_SFB_TABLE_INIT_FAILED;
118*15dc779aSAndroid Build Coastguard Worker   }
119*15dc779aSAndroid Build Coastguard Worker 
120*15dc779aSAndroid Build Coastguard Worker   ptr_sfb_offset[*sfb_cnt] = spec_start_offset;
121*15dc779aSAndroid Build Coastguard Worker 
122*15dc779aSAndroid Build Coastguard Worker   return IA_NO_ERROR;
123*15dc779aSAndroid Build Coastguard Worker }
124*15dc779aSAndroid Build Coastguard Worker 
iaace_atan_approx(FLOAT32 val)125*15dc779aSAndroid Build Coastguard Worker FLOAT32 iaace_atan_approx(FLOAT32 val) {
126*15dc779aSAndroid Build Coastguard Worker   if (val < (FLOAT32)1.0f) {
127*15dc779aSAndroid Build Coastguard Worker     return (val / ((FLOAT32)1.0f + (FLOAT32)0.280872f * val * val));
128*15dc779aSAndroid Build Coastguard Worker   } else {
129*15dc779aSAndroid Build Coastguard Worker     return ((FLOAT32)1.57079633f - val / ((FLOAT32)0.280872f + val * val));
130*15dc779aSAndroid Build Coastguard Worker   }
131*15dc779aSAndroid Build Coastguard Worker }
132*15dc779aSAndroid Build Coastguard Worker 
iaace_calc_bark_line_value(WORD32 num_lines,WORD32 fft_line,WORD32 sample_rate)133*15dc779aSAndroid Build Coastguard Worker static FLOAT32 iaace_calc_bark_line_value(WORD32 num_lines, WORD32 fft_line, WORD32 sample_rate) {
134*15dc779aSAndroid Build Coastguard Worker   FLOAT32 center_freq, temp, b_value;
135*15dc779aSAndroid Build Coastguard Worker   center_freq = (FLOAT32)fft_line * ((FLOAT32)sample_rate * (FLOAT32)0.5f) / (FLOAT32)num_lines;
136*15dc779aSAndroid Build Coastguard Worker   temp = (FLOAT32)iaace_atan_approx((FLOAT32)1.3333333e-4f * center_freq);
137*15dc779aSAndroid Build Coastguard Worker   b_value = (FLOAT32)13.3f * iaace_atan_approx((FLOAT32)0.00076f * center_freq) +
138*15dc779aSAndroid Build Coastguard Worker             (FLOAT32)3.5f * temp * temp;
139*15dc779aSAndroid Build Coastguard Worker   return (b_value);
140*15dc779aSAndroid Build Coastguard Worker }
141*15dc779aSAndroid Build Coastguard Worker 
iaace_thr_quiet_init(WORD32 sfb_count,WORD32 * ptr_sfb_offset,FLOAT32 * ptr_bark_val,FLOAT32 * ptr_thr_quiet,const FLOAT32 * ptr_bark_quiet_thr_val,WORD32 aot)142*15dc779aSAndroid Build Coastguard Worker static VOID iaace_thr_quiet_init(WORD32 sfb_count, WORD32 *ptr_sfb_offset, FLOAT32 *ptr_bark_val,
143*15dc779aSAndroid Build Coastguard Worker                                  FLOAT32 *ptr_thr_quiet, const FLOAT32 *ptr_bark_quiet_thr_val,
144*15dc779aSAndroid Build Coastguard Worker                                  WORD32 aot) {
145*15dc779aSAndroid Build Coastguard Worker   WORD32 i;
146*15dc779aSAndroid Build Coastguard Worker   FLOAT32 bark_thr_quiet;
147*15dc779aSAndroid Build Coastguard Worker 
148*15dc779aSAndroid Build Coastguard Worker   for (i = 0; i < sfb_count; i++) {
149*15dc779aSAndroid Build Coastguard Worker     if (aot == AOT_AAC_ELD) {
150*15dc779aSAndroid Build Coastguard Worker       ptr_thr_quiet[i] = (FLOAT32)(ptr_sfb_offset[i + 1] - ptr_sfb_offset[i]) * 42;
151*15dc779aSAndroid Build Coastguard Worker     } else {
152*15dc779aSAndroid Build Coastguard Worker       WORD32 b_val1, b_val2;
153*15dc779aSAndroid Build Coastguard Worker 
154*15dc779aSAndroid Build Coastguard Worker       if (i > 0) {
155*15dc779aSAndroid Build Coastguard Worker         b_val1 = (WORD32)(ptr_bark_val[i] + ptr_bark_val[i - 1]) >> 1;
156*15dc779aSAndroid Build Coastguard Worker       } else {
157*15dc779aSAndroid Build Coastguard Worker         b_val1 = (WORD32)(ptr_bark_val[i]) >> 1;
158*15dc779aSAndroid Build Coastguard Worker       }
159*15dc779aSAndroid Build Coastguard Worker 
160*15dc779aSAndroid Build Coastguard Worker       if (i < sfb_count - 1) {
161*15dc779aSAndroid Build Coastguard Worker         b_val2 = (WORD32)(ptr_bark_val[i] + ptr_bark_val[i + 1]) >> 1;
162*15dc779aSAndroid Build Coastguard Worker       } else {
163*15dc779aSAndroid Build Coastguard Worker         b_val2 = (WORD32)(ptr_bark_val[i]);
164*15dc779aSAndroid Build Coastguard Worker       }
165*15dc779aSAndroid Build Coastguard Worker       b_val1 = MIN(b_val1, (WORD32)MAX_BARK_VALUE);
166*15dc779aSAndroid Build Coastguard Worker       b_val2 = MIN(b_val2, (WORD32)MAX_BARK_VALUE);
167*15dc779aSAndroid Build Coastguard Worker       bark_thr_quiet = MIN(ptr_bark_quiet_thr_val[b_val1], ptr_bark_quiet_thr_val[b_val2]);
168*15dc779aSAndroid Build Coastguard Worker 
169*15dc779aSAndroid Build Coastguard Worker       ptr_thr_quiet[i] = (FLOAT32)db_lin_scale(bark_thr_quiet - 20.0f) * 16887.8f *
170*15dc779aSAndroid Build Coastguard Worker                          (FLOAT32)(ptr_sfb_offset[i + 1] - ptr_sfb_offset[i]);
171*15dc779aSAndroid Build Coastguard Worker     }
172*15dc779aSAndroid Build Coastguard Worker   }
173*15dc779aSAndroid Build Coastguard Worker }
174*15dc779aSAndroid Build Coastguard Worker 
iaace_spreading_init(WORD32 sfb_count,FLOAT32 * ptr_bark_val,FLOAT32 * ptr_mask_low_fac,FLOAT32 * ptr_mask_high_fac,FLOAT32 * ptr_mask_low_fac_spr_energy,FLOAT32 * ptr_mask_high_fac_spr_energy,const WORD32 bit_rate,WORD32 block_type)175*15dc779aSAndroid Build Coastguard Worker static VOID iaace_spreading_init(WORD32 sfb_count, FLOAT32 *ptr_bark_val,
176*15dc779aSAndroid Build Coastguard Worker                                  FLOAT32 *ptr_mask_low_fac, FLOAT32 *ptr_mask_high_fac,
177*15dc779aSAndroid Build Coastguard Worker                                  FLOAT32 *ptr_mask_low_fac_spr_energy,
178*15dc779aSAndroid Build Coastguard Worker                                  FLOAT32 *ptr_mask_high_fac_spr_energy, const WORD32 bit_rate,
179*15dc779aSAndroid Build Coastguard Worker                                  WORD32 block_type) {
180*15dc779aSAndroid Build Coastguard Worker   WORD32 i;
181*15dc779aSAndroid Build Coastguard Worker   FLOAT32 mask_low_spr_energy, mask_high_spr_energy;
182*15dc779aSAndroid Build Coastguard Worker 
183*15dc779aSAndroid Build Coastguard Worker   if (block_type != SHORT_WINDOW) {
184*15dc779aSAndroid Build Coastguard Worker     mask_low_spr_energy = MASK_LOW_SP_ENERGY_L;
185*15dc779aSAndroid Build Coastguard Worker     mask_high_spr_energy = (bit_rate > MASK_HIGH_SP_BITRATE_THRESH) ? MASK_HIGH_SP_ENERGY_L
186*15dc779aSAndroid Build Coastguard Worker                                                                     : MASK_HIGH_SP_ENERGY_L_LBR;
187*15dc779aSAndroid Build Coastguard Worker   } else {
188*15dc779aSAndroid Build Coastguard Worker     mask_low_spr_energy = MASK_LOW_SP_ENERGY_S;
189*15dc779aSAndroid Build Coastguard Worker     mask_high_spr_energy = MASK_HIGH_SP_ENERGY_S;
190*15dc779aSAndroid Build Coastguard Worker   }
191*15dc779aSAndroid Build Coastguard Worker 
192*15dc779aSAndroid Build Coastguard Worker   for (i = 0; i < sfb_count; i++) {
193*15dc779aSAndroid Build Coastguard Worker     if (i > 0) {
194*15dc779aSAndroid Build Coastguard Worker       FLOAT32 db_val;
195*15dc779aSAndroid Build Coastguard Worker       FLOAT32 diff_val = (ptr_bark_val[i] - ptr_bark_val[i - 1]);
196*15dc779aSAndroid Build Coastguard Worker 
197*15dc779aSAndroid Build Coastguard Worker       db_val = MASK_HIGH_FAC * diff_val;
198*15dc779aSAndroid Build Coastguard Worker       ptr_mask_high_fac[i] = (FLOAT32)pow(10.0f, -db_val);
199*15dc779aSAndroid Build Coastguard Worker       db_val = MASK_LOW_FAC * diff_val;
200*15dc779aSAndroid Build Coastguard Worker       ptr_mask_low_fac[i - 1] = (FLOAT32)pow(10.0f, -db_val);
201*15dc779aSAndroid Build Coastguard Worker       db_val = mask_high_spr_energy * diff_val;
202*15dc779aSAndroid Build Coastguard Worker       ptr_mask_high_fac_spr_energy[i] = (FLOAT32)pow(10.0f, -db_val);
203*15dc779aSAndroid Build Coastguard Worker       db_val = mask_low_spr_energy * diff_val;
204*15dc779aSAndroid Build Coastguard Worker       ptr_mask_low_fac_spr_energy[i - 1] = (FLOAT32)pow(10.0f, -db_val);
205*15dc779aSAndroid Build Coastguard Worker     } else {
206*15dc779aSAndroid Build Coastguard Worker       ptr_mask_high_fac[i] = 0.0f;
207*15dc779aSAndroid Build Coastguard Worker       ptr_mask_low_fac[sfb_count - 1] = 0.0f;
208*15dc779aSAndroid Build Coastguard Worker       ptr_mask_high_fac_spr_energy[i] = 0.0f;
209*15dc779aSAndroid Build Coastguard Worker       ptr_mask_low_fac_spr_energy[sfb_count - 1] = 0.0f;
210*15dc779aSAndroid Build Coastguard Worker     }
211*15dc779aSAndroid Build Coastguard Worker   }
212*15dc779aSAndroid Build Coastguard Worker   return;
213*15dc779aSAndroid Build Coastguard Worker }
214*15dc779aSAndroid Build Coastguard Worker 
iaace_bark_values_init(WORD32 sfb_count,WORD32 * ptr_sfb_offset,WORD32 num_lines,WORD32 sample_rate,FLOAT32 * ptr_b_value,WORD32 aot)215*15dc779aSAndroid Build Coastguard Worker static VOID iaace_bark_values_init(WORD32 sfb_count, WORD32 *ptr_sfb_offset, WORD32 num_lines,
216*15dc779aSAndroid Build Coastguard Worker                                    WORD32 sample_rate, FLOAT32 *ptr_b_value, WORD32 aot) {
217*15dc779aSAndroid Build Coastguard Worker   WORD32 i;
218*15dc779aSAndroid Build Coastguard Worker   FLOAT32 b_val0, b_val1;
219*15dc779aSAndroid Build Coastguard Worker   b_val0 = 0.0f;
220*15dc779aSAndroid Build Coastguard Worker 
221*15dc779aSAndroid Build Coastguard Worker   for (i = 0; i < sfb_count; i++) {
222*15dc779aSAndroid Build Coastguard Worker     b_val1 = iaace_calc_bark_line_value(num_lines, ptr_sfb_offset[i + 1], sample_rate);
223*15dc779aSAndroid Build Coastguard Worker     ptr_b_value[i] = (b_val0 + b_val1) * (FLOAT32)0.5f;
224*15dc779aSAndroid Build Coastguard Worker     if (aot == AOT_AAC_ELD) {
225*15dc779aSAndroid Build Coastguard Worker       if (ptr_b_value[i] > MAX_BARK_VALUE) {
226*15dc779aSAndroid Build Coastguard Worker         ptr_b_value[i] = MAX_BARK_VALUE;
227*15dc779aSAndroid Build Coastguard Worker       }
228*15dc779aSAndroid Build Coastguard Worker     }
229*15dc779aSAndroid Build Coastguard Worker 
230*15dc779aSAndroid Build Coastguard Worker     b_val0 = b_val1;
231*15dc779aSAndroid Build Coastguard Worker   }
232*15dc779aSAndroid Build Coastguard Worker }
233*15dc779aSAndroid Build Coastguard Worker 
iaace_bits_to_pe(const FLOAT32 bits)234*15dc779aSAndroid Build Coastguard Worker static FLOAT32 iaace_bits_to_pe(const FLOAT32 bits) { return (bits * 1.18f); }
iaace_min_snr_init(const WORD32 bit_rate,const WORD32 sample_rate,const WORD32 num_lines,const WORD32 * ptr_sfb_offset,const FLOAT32 * ptr_bark_value,const WORD32 sfb_active,FLOAT32 * ptr_sfb_min_snr)235*15dc779aSAndroid Build Coastguard Worker static VOID iaace_min_snr_init(const WORD32 bit_rate, const WORD32 sample_rate,
236*15dc779aSAndroid Build Coastguard Worker                                const WORD32 num_lines, const WORD32 *ptr_sfb_offset,
237*15dc779aSAndroid Build Coastguard Worker                                const FLOAT32 *ptr_bark_value, const WORD32 sfb_active,
238*15dc779aSAndroid Build Coastguard Worker                                FLOAT32 *ptr_sfb_min_snr) {
239*15dc779aSAndroid Build Coastguard Worker   WORD32 sfb;
240*15dc779aSAndroid Build Coastguard Worker   FLOAT32 bark_fac;
241*15dc779aSAndroid Build Coastguard Worker   FLOAT32 bark_width;
242*15dc779aSAndroid Build Coastguard Worker   FLOAT32 pe_per_window, pe_part;
243*15dc779aSAndroid Build Coastguard Worker   FLOAT32 snr;
244*15dc779aSAndroid Build Coastguard Worker   FLOAT32 b_val0, b_val1;
245*15dc779aSAndroid Build Coastguard Worker 
246*15dc779aSAndroid Build Coastguard Worker   bark_fac = (FLOAT32)1.0 / MIN(ptr_bark_value[sfb_active - 1] / MAX_BARK_VALUE, (FLOAT32)1.0);
247*15dc779aSAndroid Build Coastguard Worker   pe_per_window = iaace_bits_to_pe((FLOAT32)bit_rate / (FLOAT32)sample_rate * (FLOAT32)num_lines);
248*15dc779aSAndroid Build Coastguard Worker   b_val0 = (FLOAT32)0.0f;
249*15dc779aSAndroid Build Coastguard Worker 
250*15dc779aSAndroid Build Coastguard Worker   for (sfb = 0; sfb < sfb_active; sfb++) {
251*15dc779aSAndroid Build Coastguard Worker     b_val1 = (FLOAT32)2.0 * ptr_bark_value[sfb] - b_val0;
252*15dc779aSAndroid Build Coastguard Worker     bark_width = b_val1 - b_val0;
253*15dc779aSAndroid Build Coastguard Worker     b_val0 = b_val1;
254*15dc779aSAndroid Build Coastguard Worker 
255*15dc779aSAndroid Build Coastguard Worker     pe_part = pe_per_window * (FLOAT32)0.024f * bark_fac;
256*15dc779aSAndroid Build Coastguard Worker     pe_part *= bark_width;
257*15dc779aSAndroid Build Coastguard Worker     pe_part /= (FLOAT32)(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]);
258*15dc779aSAndroid Build Coastguard Worker     snr = (FLOAT32)pow(2.0f, pe_part) - 1.5f;
259*15dc779aSAndroid Build Coastguard Worker     snr = 1.0f / MAX(snr, 1.0f);
260*15dc779aSAndroid Build Coastguard Worker     snr = MIN(snr, 0.8f);
261*15dc779aSAndroid Build Coastguard Worker     snr = MAX(snr, 0.003f);
262*15dc779aSAndroid Build Coastguard Worker     ptr_sfb_min_snr[sfb] = snr;
263*15dc779aSAndroid Build Coastguard Worker   }
264*15dc779aSAndroid Build Coastguard Worker }
265*15dc779aSAndroid Build Coastguard Worker 
ia_enhaacplus_enc_init_psy_configuration(WORD32 bit_rate,WORD32 sample_rate,WORD32 bandwidth,WORD32 aot,ixheaace_psy_configuration_long * pstr_psy_conf,ixheaace_aac_tables * pstr_aac_tables,WORD32 long_frame_len)266*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE ia_enhaacplus_enc_init_psy_configuration(
267*15dc779aSAndroid Build Coastguard Worker     WORD32 bit_rate, WORD32 sample_rate, WORD32 bandwidth, WORD32 aot,
268*15dc779aSAndroid Build Coastguard Worker     ixheaace_psy_configuration_long *pstr_psy_conf, ixheaace_aac_tables *pstr_aac_tables,
269*15dc779aSAndroid Build Coastguard Worker     WORD32 long_frame_len) {
270*15dc779aSAndroid Build Coastguard Worker   WORD32 sfb;
271*15dc779aSAndroid Build Coastguard Worker   FLOAT32 sfb_bark_val[MAXIMUM_SCALE_FACTOR_BAND_LONG];
272*15dc779aSAndroid Build Coastguard Worker   IA_ERRORCODE error;
273*15dc779aSAndroid Build Coastguard Worker   error = ia_enhaacplus_enc_init_sfb_table(pstr_aac_tables->pstr_psycho_tab, sample_rate, aot,
274*15dc779aSAndroid Build Coastguard Worker                                            LONG_WINDOW, pstr_psy_conf->sfb_offsets,
275*15dc779aSAndroid Build Coastguard Worker                                            &(pstr_psy_conf->sfb_cnt), long_frame_len);
276*15dc779aSAndroid Build Coastguard Worker   if (error != IA_NO_ERROR) {
277*15dc779aSAndroid Build Coastguard Worker     return error;
278*15dc779aSAndroid Build Coastguard Worker   }
279*15dc779aSAndroid Build Coastguard Worker 
280*15dc779aSAndroid Build Coastguard Worker   /*   calculate bark values for each pb */
281*15dc779aSAndroid Build Coastguard Worker   iaace_bark_values_init(pstr_psy_conf->sfb_cnt, pstr_psy_conf->sfb_offsets,
282*15dc779aSAndroid Build Coastguard Worker                          pstr_psy_conf->sfb_offsets[pstr_psy_conf->sfb_cnt], sample_rate,
283*15dc779aSAndroid Build Coastguard Worker                          sfb_bark_val, aot);
284*15dc779aSAndroid Build Coastguard Worker 
285*15dc779aSAndroid Build Coastguard Worker   /*init thresholds in quiet  */
286*15dc779aSAndroid Build Coastguard Worker 
287*15dc779aSAndroid Build Coastguard Worker   iaace_thr_quiet_init(pstr_psy_conf->sfb_cnt, pstr_psy_conf->sfb_offsets, sfb_bark_val,
288*15dc779aSAndroid Build Coastguard Worker                        pstr_psy_conf->sfb_threshold_quiet,
289*15dc779aSAndroid Build Coastguard Worker                        pstr_aac_tables->pstr_psycho_tab->ixheaace_bark_quiet_thr_val, aot);
290*15dc779aSAndroid Build Coastguard Worker 
291*15dc779aSAndroid Build Coastguard Worker   /*  calculate spreading function */
292*15dc779aSAndroid Build Coastguard Worker 
293*15dc779aSAndroid Build Coastguard Worker   iaace_spreading_init(pstr_psy_conf->sfb_cnt, sfb_bark_val, pstr_psy_conf->sfb_mask_low_factor,
294*15dc779aSAndroid Build Coastguard Worker                        pstr_psy_conf->sfb_mask_high_factor,
295*15dc779aSAndroid Build Coastguard Worker                        pstr_psy_conf->sfb_mask_low_factor_spread_nrg,
296*15dc779aSAndroid Build Coastguard Worker                        pstr_psy_conf->sfb_mask_high_factor_spread_nrg, bit_rate, LONG_WINDOW);
297*15dc779aSAndroid Build Coastguard Worker 
298*15dc779aSAndroid Build Coastguard Worker   /*
299*15dc779aSAndroid Build Coastguard Worker     init ratio
300*15dc779aSAndroid Build Coastguard Worker   */
301*15dc779aSAndroid Build Coastguard Worker 
302*15dc779aSAndroid Build Coastguard Worker   pstr_psy_conf->min_remaining_threshold_factor = MIN_THRESH_FAC;
303*15dc779aSAndroid Build Coastguard Worker 
304*15dc779aSAndroid Build Coastguard Worker   pstr_psy_conf->clip_energy = CLIP_ENERGY_VALUE_LONG;
305*15dc779aSAndroid Build Coastguard Worker   if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
306*15dc779aSAndroid Build Coastguard Worker     pstr_psy_conf->ratio_float = C_RATIO;
307*15dc779aSAndroid Build Coastguard Worker   } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
308*15dc779aSAndroid Build Coastguard Worker     if (aot == AOT_AAC_ELD) {
309*15dc779aSAndroid Build Coastguard Worker       pstr_psy_conf->ratio_float = C_RATIO;
310*15dc779aSAndroid Build Coastguard Worker     } else {
311*15dc779aSAndroid Build Coastguard Worker       pstr_psy_conf->ratio_float = SNR_FLOAT;
312*15dc779aSAndroid Build Coastguard Worker     }
313*15dc779aSAndroid Build Coastguard Worker   }
314*15dc779aSAndroid Build Coastguard Worker 
315*15dc779aSAndroid Build Coastguard Worker   pstr_psy_conf->lowpass_line = (WORD32)((2 * bandwidth * long_frame_len) / sample_rate);
316*15dc779aSAndroid Build Coastguard Worker 
317*15dc779aSAndroid Build Coastguard Worker   /* pstr_psy_conf->pstr_sfb_offset[] */
318*15dc779aSAndroid Build Coastguard Worker   for (sfb = 0; sfb < pstr_psy_conf->sfb_cnt; sfb++) {
319*15dc779aSAndroid Build Coastguard Worker     if (pstr_psy_conf->sfb_offsets[sfb] >= pstr_psy_conf->lowpass_line) break;
320*15dc779aSAndroid Build Coastguard Worker   }
321*15dc779aSAndroid Build Coastguard Worker   pstr_psy_conf->sfb_active = sfb;
322*15dc779aSAndroid Build Coastguard Worker 
323*15dc779aSAndroid Build Coastguard Worker   /*
324*15dc779aSAndroid Build Coastguard Worker     calculate minSnr
325*15dc779aSAndroid Build Coastguard Worker   */
326*15dc779aSAndroid Build Coastguard Worker   iaace_min_snr_init(bit_rate, sample_rate, pstr_psy_conf->sfb_offsets[pstr_psy_conf->sfb_cnt],
327*15dc779aSAndroid Build Coastguard Worker                      pstr_psy_conf->sfb_offsets, sfb_bark_val, pstr_psy_conf->sfb_active,
328*15dc779aSAndroid Build Coastguard Worker                      pstr_psy_conf->sfb_min_snr);
329*15dc779aSAndroid Build Coastguard Worker 
330*15dc779aSAndroid Build Coastguard Worker   return IA_NO_ERROR;
331*15dc779aSAndroid Build Coastguard Worker }
332*15dc779aSAndroid Build Coastguard Worker 
ia_enhaacplus_enc_init_psy_configuration_short(WORD32 bit_rate,WORD32 sample_rate,WORD32 bandwidth,WORD32 aot,ixheaace_psy_configuration_short * pstr_psy_conf,ixheaace_aac_tables * pstr_aac_tables,WORD32 long_frame_len)333*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE ia_enhaacplus_enc_init_psy_configuration_short(
334*15dc779aSAndroid Build Coastguard Worker     WORD32 bit_rate, WORD32 sample_rate, WORD32 bandwidth, WORD32 aot,
335*15dc779aSAndroid Build Coastguard Worker     ixheaace_psy_configuration_short *pstr_psy_conf, ixheaace_aac_tables *pstr_aac_tables,
336*15dc779aSAndroid Build Coastguard Worker     WORD32 long_frame_len) {
337*15dc779aSAndroid Build Coastguard Worker   WORD32 sfb;
338*15dc779aSAndroid Build Coastguard Worker   FLOAT32 sfb_bark_val[MAXIMUM_SCALE_FACTOR_BAND_SHORT] = {0};
339*15dc779aSAndroid Build Coastguard Worker   IA_ERRORCODE error;
340*15dc779aSAndroid Build Coastguard Worker   /*
341*15dc779aSAndroid Build Coastguard Worker     init sfb table
342*15dc779aSAndroid Build Coastguard Worker   */
343*15dc779aSAndroid Build Coastguard Worker   error = ia_enhaacplus_enc_init_sfb_table(pstr_aac_tables->pstr_psycho_tab, sample_rate, aot,
344*15dc779aSAndroid Build Coastguard Worker                                            SHORT_WINDOW, pstr_psy_conf->sfb_offsets,
345*15dc779aSAndroid Build Coastguard Worker                                            &(pstr_psy_conf->sfb_cnt), long_frame_len);
346*15dc779aSAndroid Build Coastguard Worker 
347*15dc779aSAndroid Build Coastguard Worker   if (error != IA_NO_ERROR) {
348*15dc779aSAndroid Build Coastguard Worker     return error;
349*15dc779aSAndroid Build Coastguard Worker   }
350*15dc779aSAndroid Build Coastguard Worker 
351*15dc779aSAndroid Build Coastguard Worker   iaace_bark_values_init(pstr_psy_conf->sfb_cnt, pstr_psy_conf->sfb_offsets,
352*15dc779aSAndroid Build Coastguard Worker                          pstr_psy_conf->sfb_offsets[pstr_psy_conf->sfb_cnt], sample_rate,
353*15dc779aSAndroid Build Coastguard Worker                          sfb_bark_val, aot);
354*15dc779aSAndroid Build Coastguard Worker 
355*15dc779aSAndroid Build Coastguard Worker   iaace_thr_quiet_init(pstr_psy_conf->sfb_cnt, pstr_psy_conf->sfb_offsets, sfb_bark_val,
356*15dc779aSAndroid Build Coastguard Worker                        pstr_psy_conf->sfb_threshold_quiet,
357*15dc779aSAndroid Build Coastguard Worker                        pstr_aac_tables->pstr_psycho_tab->ixheaace_bark_quiet_thr_val, aot);
358*15dc779aSAndroid Build Coastguard Worker 
359*15dc779aSAndroid Build Coastguard Worker   /*
360*15dc779aSAndroid Build Coastguard Worker     calculate spreading function
361*15dc779aSAndroid Build Coastguard Worker   */
362*15dc779aSAndroid Build Coastguard Worker   iaace_spreading_init(pstr_psy_conf->sfb_cnt, sfb_bark_val, pstr_psy_conf->sfb_mask_low_factor,
363*15dc779aSAndroid Build Coastguard Worker                        pstr_psy_conf->sfb_mask_high_factor,
364*15dc779aSAndroid Build Coastguard Worker                        pstr_psy_conf->sfb_mask_low_factor_spread_nrg,
365*15dc779aSAndroid Build Coastguard Worker                        pstr_psy_conf->sfb_mask_high_factor_spread_nrg, bit_rate, SHORT_WINDOW);
366*15dc779aSAndroid Build Coastguard Worker 
367*15dc779aSAndroid Build Coastguard Worker   /*
368*15dc779aSAndroid Build Coastguard Worker     init ratio
369*15dc779aSAndroid Build Coastguard Worker   */
370*15dc779aSAndroid Build Coastguard Worker 
371*15dc779aSAndroid Build Coastguard Worker   pstr_psy_conf->min_remaining_threshold_factor = 0.01f;
372*15dc779aSAndroid Build Coastguard Worker 
373*15dc779aSAndroid Build Coastguard Worker   pstr_psy_conf->clip_energy = CLIP_ENERGY_VALUE_LONG / (TRANS_FAC * TRANS_FAC);
374*15dc779aSAndroid Build Coastguard Worker   switch (aot) {
375*15dc779aSAndroid Build Coastguard Worker     case AOT_AAC_LC:
376*15dc779aSAndroid Build Coastguard Worker     case AOT_SBR:
377*15dc779aSAndroid Build Coastguard Worker     case AOT_PS:
378*15dc779aSAndroid Build Coastguard Worker       pstr_psy_conf->ratio_float = C_RATIO;
379*15dc779aSAndroid Build Coastguard Worker       break;
380*15dc779aSAndroid Build Coastguard Worker 
381*15dc779aSAndroid Build Coastguard Worker     case AOT_AAC_LD:
382*15dc779aSAndroid Build Coastguard Worker     case AOT_AAC_ELD:
383*15dc779aSAndroid Build Coastguard Worker       pstr_psy_conf->ratio_float = SNR_FLOAT;
384*15dc779aSAndroid Build Coastguard Worker       break;
385*15dc779aSAndroid Build Coastguard Worker   }
386*15dc779aSAndroid Build Coastguard Worker 
387*15dc779aSAndroid Build Coastguard Worker   pstr_psy_conf->lowpass_line = (WORD32)((2 * bandwidth * long_frame_len) / sample_rate);
388*15dc779aSAndroid Build Coastguard Worker   for (sfb = 0; sfb < pstr_psy_conf->sfb_cnt; sfb++) {
389*15dc779aSAndroid Build Coastguard Worker     if (pstr_psy_conf->sfb_offsets[sfb] >= pstr_psy_conf->lowpass_line) break;
390*15dc779aSAndroid Build Coastguard Worker   }
391*15dc779aSAndroid Build Coastguard Worker   pstr_psy_conf->sfb_active = sfb;
392*15dc779aSAndroid Build Coastguard Worker 
393*15dc779aSAndroid Build Coastguard Worker   iaace_min_snr_init(bit_rate, sample_rate, pstr_psy_conf->sfb_offsets[pstr_psy_conf->sfb_cnt],
394*15dc779aSAndroid Build Coastguard Worker                      pstr_psy_conf->sfb_offsets, sfb_bark_val, pstr_psy_conf->sfb_active,
395*15dc779aSAndroid Build Coastguard Worker                      pstr_psy_conf->sfb_min_snr);
396*15dc779aSAndroid Build Coastguard Worker 
397*15dc779aSAndroid Build Coastguard Worker   return IA_NO_ERROR;
398*15dc779aSAndroid Build Coastguard Worker }
399*15dc779aSAndroid Build Coastguard Worker 
ia_enhaacplus_enc_power2(WORD32 power,WORD q_power,WORD * q_result,const WORD32 * power_of_2_table_neg,const WORD32 * power_of_2_table_pos)400*15dc779aSAndroid Build Coastguard Worker WORD32 ia_enhaacplus_enc_power2(WORD32 power, WORD q_power, WORD *q_result,
401*15dc779aSAndroid Build Coastguard Worker                                 const WORD32 *power_of_2_table_neg,
402*15dc779aSAndroid Build Coastguard Worker                                 const WORD32 *power_of_2_table_pos) {
403*15dc779aSAndroid Build Coastguard Worker   WORD32 int_part, frac_part;
404*15dc779aSAndroid Build Coastguard Worker   WORD32 result;
405*15dc779aSAndroid Build Coastguard Worker   WORD16 sign = 0;
406*15dc779aSAndroid Build Coastguard Worker 
407*15dc779aSAndroid Build Coastguard Worker   if (power < 0) {
408*15dc779aSAndroid Build Coastguard Worker     sign = 1;
409*15dc779aSAndroid Build Coastguard Worker     power = ixheaac_negate32(power);
410*15dc779aSAndroid Build Coastguard Worker   }
411*15dc779aSAndroid Build Coastguard Worker 
412*15dc779aSAndroid Build Coastguard Worker   if (q_power < 32)
413*15dc779aSAndroid Build Coastguard Worker     int_part = ixheaac_shr32(power, q_power);
414*15dc779aSAndroid Build Coastguard Worker   else
415*15dc779aSAndroid Build Coastguard Worker     int_part = 0;
416*15dc779aSAndroid Build Coastguard Worker 
417*15dc779aSAndroid Build Coastguard Worker   if (q_power < 39) {
418*15dc779aSAndroid Build Coastguard Worker     power = ixheaac_shr32_dir(power, q_power - 8);
419*15dc779aSAndroid Build Coastguard Worker     frac_part = power & 0xFF;
420*15dc779aSAndroid Build Coastguard Worker   } else
421*15dc779aSAndroid Build Coastguard Worker     frac_part = 0;
422*15dc779aSAndroid Build Coastguard Worker 
423*15dc779aSAndroid Build Coastguard Worker   if (!sign) {
424*15dc779aSAndroid Build Coastguard Worker     result = power_of_2_table_pos[frac_part];
425*15dc779aSAndroid Build Coastguard Worker     *q_result = Q_POWER2_TABLE - int_part;
426*15dc779aSAndroid Build Coastguard Worker   } else {
427*15dc779aSAndroid Build Coastguard Worker     result = power_of_2_table_neg[frac_part];
428*15dc779aSAndroid Build Coastguard Worker     *q_result = Q_POWER2_TABLE + int_part;
429*15dc779aSAndroid Build Coastguard Worker   }
430*15dc779aSAndroid Build Coastguard Worker 
431*15dc779aSAndroid Build Coastguard Worker   return (result);
432*15dc779aSAndroid Build Coastguard Worker }
433