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