xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_sbr_code_envelope_lp.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2023 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 
21 #include <string.h>
22 
23 #include "ixheaac_type_def.h"
24 #include "ixheaac_constants.h"
25 #include "ixheaace_aac_constants.h"
26 #include "ixheaac_basic_ops32.h"
27 #include "ixheaac_basic_ops16.h"
28 #include "ixheaac_basic_ops40.h"
29 #include "ixheaac_basic_ops.h"
30 #include "ixheaac_error_standards.h"
31 
32 #include "ixheaace_sbr_header.h"
33 #include "ixheaace_sbr_def.h"
34 #include "ixheaace_resampler.h"
35 #include "ixheaace_sbr_rom.h"
36 #include "ixheaace_common_rom.h"
37 #include "ixheaace_sbr_main.h"
38 #include "ixheaace_sbr_frame_info_gen.h"
39 #include "ixheaace_sbr_hbe.h"
40 #include "ixheaace_sbr_code_envelope.h"
41 #include "ixheaace_sbr_qmf_enc.h"
42 #include "ixheaace_sbr_tran_det.h"
43 #include "ixheaace_sbr_env_est.h"
44 #include "ixheaace_sbr_missing_harmonics_det.h"
45 #include "ixheaace_sbr_inv_filtering_estimation.h"
46 #include "ixheaace_sbr_noise_floor_est.h"
47 
48 #include "ixheaace_sbr_ton_corr.h"
49 #include "iusace_esbr_pvc.h"
50 #include "iusace_esbr_inter_tes.h"
51 #include "ixheaace_sbr.h"
52 #include "ixheaace_common_utils.h"
53 
ixheaace_index_low2_high(WORD32 offset,WORD32 index,ixheaace_freq_res res)54 static WORD32 ixheaace_index_low2_high(WORD32 offset, WORD32 index, ixheaace_freq_res res) {
55   switch (res) {
56     case FREQ_RES_LOW:
57       if (offset >= 0) {
58         return (index < offset) ? (index) : (2 * index - offset);
59       } else {
60         offset = -offset;
61         return (index < offset) ? (3 * index) : (2 * index + offset);
62       }
63     default:
64       return (index);
65   }
66 }
67 
ixheaace_code_envelope(WORD32 * ptr_sfb_energy,const ixheaace_freq_res * freq_res,ixheaace_str_sbr_code_envelope * pstr_code_env,WORD32 * ptr_dir_vec,WORD32 coupling,WORD32 num_envelopes,WORD32 channel,WORD32 header_active,WORD32 usac_indep_flag,WORD32 is_ld_sbr)68 IA_ERRORCODE ixheaace_code_envelope(WORD32 *ptr_sfb_energy, const ixheaace_freq_res *freq_res,
69                                     ixheaace_str_sbr_code_envelope *pstr_code_env,
70                                     WORD32 *ptr_dir_vec, WORD32 coupling, WORD32 num_envelopes,
71                                     WORD32 channel, WORD32 header_active, WORD32 usac_indep_flag,
72                                     WORD32 is_ld_sbr) {
73   IA_ERRORCODE err_code = IA_NO_ERROR;
74   WORD32 i, no_of_bands, band, last_nrg, current_energy;
75   WORD32 *ptr_energy;
76 
77   WORD32 code_book_scf_lav_lvl_time;
78   WORD32 code_book_scf_lav_lvl_freq;
79   WORD32 code_book_scf_lav_bal_time;
80   WORD32 code_book_scf_lav_bal_freq;
81   const UWORD8 *ptr_huff_tab_lvl_time_l;
82   const UWORD8 *ptr_huff_tab_bal_time_l;
83   const UWORD8 *ptr_huff_tab_lvl_freq_l;
84   const UWORD8 *ptr_huff_tab_bal_freq_l;
85 
86   WORD32 offset = pstr_code_env->offset;
87   WORD32 env_data_tab_comp_factor;
88 
89   WORD32 delta_f_bits = 0, delta_t_bits = 0;
90 
91   WORD32 use_dt;
92 
93   WORD32 delta_f[MAXIMUM_FREQ_COEFFS];
94   WORD32 delta_t[MAXIMUM_FREQ_COEFFS];
95 
96   FLOAT32 df_edge_first_ennv;
97 
98   df_edge_first_ennv = pstr_code_env->df_edge_1st_env +
99                        pstr_code_env->df_edge_incr * pstr_code_env->df_edge_incr_fac;
100 
101   switch (coupling) {
102     case COUPLING_1:
103       code_book_scf_lav_lvl_time = pstr_code_env->code_book_scf_lav_lvl_time;
104       code_book_scf_lav_lvl_freq = pstr_code_env->code_book_scf_lav_lvl_freq;
105       code_book_scf_lav_bal_time = pstr_code_env->code_book_scf_lav_bal_time;
106       code_book_scf_lav_bal_freq = pstr_code_env->code_book_scf_lav_bal_freq;
107       ptr_huff_tab_lvl_time_l = pstr_code_env->ptr_huff_tab_lvl_time_l;
108       ptr_huff_tab_bal_time_l = pstr_code_env->ptr_huff_tab_bal_time_l;
109       ptr_huff_tab_lvl_freq_l = pstr_code_env->ptr_huff_tab_lvl_freq_l;
110       ptr_huff_tab_bal_freq_l = pstr_code_env->ptr_huff_tab_bal_freq_l;
111       break;
112     default:
113       code_book_scf_lav_lvl_time = pstr_code_env->code_book_scf_lav_time;
114       code_book_scf_lav_lvl_freq = pstr_code_env->code_book_scf_lav_freq;
115       code_book_scf_lav_bal_time = pstr_code_env->code_book_scf_lav_time;
116       code_book_scf_lav_bal_freq = pstr_code_env->code_book_scf_lav_freq;
117       ptr_huff_tab_lvl_time_l = pstr_code_env->ptr_huff_tab_time_l;
118       ptr_huff_tab_bal_time_l = pstr_code_env->ptr_huff_tab_time_l;
119       ptr_huff_tab_lvl_freq_l = pstr_code_env->ptr_huff_tab_freq_l;
120       ptr_huff_tab_bal_freq_l = pstr_code_env->ptr_huff_tab_freq_l;
121   }
122 
123   if (coupling == 1 && channel == 1) {
124     env_data_tab_comp_factor = 1;
125   } else {
126     env_data_tab_comp_factor = 0;
127   }
128 
129   if (pstr_code_env->delta_t_across_frames == 0 || header_active) {
130     pstr_code_env->update = 0;
131   }
132 
133   for (i = 0; i < num_envelopes; i++) {
134     if (freq_res[i] == FREQ_RES_HIGH)
135       no_of_bands = pstr_code_env->num_scf[FREQ_RES_HIGH];
136     else
137       no_of_bands = pstr_code_env->num_scf[FREQ_RES_LOW];
138 
139     ptr_energy = ptr_sfb_energy;
140     current_energy = *ptr_energy;
141     delta_f[0] = ixheaac_shr32(current_energy, env_data_tab_comp_factor);
142     if (coupling && channel == 1)
143       delta_f_bits = pstr_code_env->start_bits_balance;
144     else
145       delta_f_bits = pstr_code_env->start_bits;
146 
147     if (pstr_code_env->update != 0) {
148       delta_t[0] = ixheaac_shr32((current_energy - pstr_code_env->sfb_nrg_prev[0]),
149                                  env_data_tab_comp_factor);
150 
151       err_code = ixheaace_compute_bits(delta_t[0], code_book_scf_lav_lvl_time,
152                                        code_book_scf_lav_bal_time, ptr_huff_tab_lvl_time_l,
153                                        ptr_huff_tab_bal_time_l, coupling, channel, &delta_t_bits);
154       if (err_code) {
155         return err_code;
156       }
157     }
158 
159     ixheaace_map_low_res_energy_value(current_energy, pstr_code_env->sfb_nrg_prev, offset, 0,
160                                       freq_res[i]);
161 
162     band = no_of_bands - 1;
163     while (band > 0) {
164       if (ptr_energy[band] - ptr_energy[band - 1] > code_book_scf_lav_lvl_freq) {
165         ptr_energy[band - 1] = ptr_energy[band] - code_book_scf_lav_lvl_freq;
166       }
167       band--;
168     }
169 
170     band = 1;
171     while (band < no_of_bands) {
172       WORD32 index;
173       WORD32 delta_lcl_bits = 0;
174 
175       if (ixheaac_sub32_sat(ptr_energy[band - 1], ptr_energy[band]) >
176           code_book_scf_lav_lvl_freq) {
177         ptr_energy[band] = ptr_energy[band - 1] - code_book_scf_lav_lvl_freq;
178       }
179 
180       last_nrg = *ptr_energy++;
181       current_energy = *ptr_energy;
182       delta_f[band] = ixheaac_shr32((current_energy - last_nrg), env_data_tab_comp_factor);
183 
184       err_code = ixheaace_compute_bits(
185           delta_f[band], code_book_scf_lav_lvl_freq, code_book_scf_lav_bal_freq,
186           ptr_huff_tab_lvl_freq_l, ptr_huff_tab_bal_freq_l, coupling, channel, &delta_lcl_bits);
187       if (err_code) {
188         return err_code;
189       }
190       delta_f_bits += delta_lcl_bits;
191 
192       if (pstr_code_env->update != 0) {
193         delta_lcl_bits = 0;
194         index = ixheaace_index_low2_high(offset, band, freq_res[i]);
195         delta_t[band] = current_energy - pstr_code_env->sfb_nrg_prev[index];
196         delta_t[band] = ixheaac_shr32(delta_t[band], env_data_tab_comp_factor);
197 
198         ixheaace_map_low_res_energy_value(current_energy, pstr_code_env->sfb_nrg_prev, offset,
199                                           band, freq_res[i]);
200         if ((delta_t[band] > 31) || (delta_t[band] < -31)) {
201           delta_t[band] = 31;
202         }
203 
204         err_code = ixheaace_compute_bits(
205             delta_t[band], code_book_scf_lav_lvl_time, code_book_scf_lav_bal_time,
206             ptr_huff_tab_lvl_time_l, ptr_huff_tab_bal_time_l, coupling, channel, &delta_lcl_bits);
207         if (err_code) {
208           return err_code;
209         }
210         delta_t_bits += delta_lcl_bits;
211       } else {
212         ixheaace_map_low_res_energy_value(current_energy, pstr_code_env->sfb_nrg_prev, offset,
213                                           band, freq_res[i]);
214       }
215       band++;
216     }
217 
218     if (i == 0) {
219       use_dt = (pstr_code_env->update != 0 &&
220                 (delta_f_bits > delta_t_bits * (1 + df_edge_first_ennv)));
221     } else if (is_ld_sbr) {
222       use_dt = ((pstr_code_env->update != 0) && (delta_f_bits > delta_t_bits));
223     } else {
224       use_dt = (delta_f_bits > delta_t_bits);
225     }
226 
227     if (use_dt) {
228       ptr_dir_vec[i] = TIME;
229       memcpy(ptr_sfb_energy, delta_t, no_of_bands * sizeof(ptr_sfb_energy[0]));
230     } else {
231       ptr_dir_vec[i] = FREQ;
232       memcpy(ptr_sfb_energy, delta_f, no_of_bands * sizeof(ptr_sfb_energy[0]));
233     }
234     if (0 == i && 1 == usac_indep_flag) {
235       ptr_dir_vec[i] = FREQ;
236       memcpy(ptr_sfb_energy, delta_f, no_of_bands * sizeof(ptr_sfb_energy[0]));
237     }
238 
239     ptr_sfb_energy += no_of_bands;
240     pstr_code_env->update = 1;
241   }
242   return err_code;
243 }
244