/src/libxaac/encoder/ixheaace_sbr_code_envelope_lp.c
Line | Count | Source |
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 | | |
54 | 9.34M | static WORD32 ixheaace_index_low2_high(WORD32 offset, WORD32 index, ixheaace_freq_res res) { |
55 | 9.34M | switch (res) { |
56 | 1.90M | case FREQ_RES_LOW: |
57 | 1.90M | if (offset >= 0) { |
58 | 1.90M | return (index < offset) ? (index) : (2 * index - offset); |
59 | 1.90M | } else { |
60 | 0 | offset = -offset; |
61 | 0 | return (index < offset) ? (3 * index) : (2 * index + offset); |
62 | 0 | } |
63 | 7.44M | default: |
64 | 7.44M | return (index); |
65 | 9.34M | } |
66 | 9.34M | } |
67 | | |
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 | 1.69M | WORD32 is_ld_sbr) { |
73 | 1.69M | IA_ERRORCODE err_code = IA_NO_ERROR; |
74 | 1.69M | WORD32 i, no_of_bands, band, last_nrg, current_energy; |
75 | 1.69M | WORD32 *ptr_energy; |
76 | | |
77 | 1.69M | WORD32 code_book_scf_lav_lvl_time; |
78 | 1.69M | WORD32 code_book_scf_lav_lvl_freq; |
79 | 1.69M | WORD32 code_book_scf_lav_bal_time; |
80 | 1.69M | WORD32 code_book_scf_lav_bal_freq; |
81 | 1.69M | const UWORD8 *ptr_huff_tab_lvl_time_l; |
82 | 1.69M | const UWORD8 *ptr_huff_tab_bal_time_l; |
83 | 1.69M | const UWORD8 *ptr_huff_tab_lvl_freq_l; |
84 | 1.69M | const UWORD8 *ptr_huff_tab_bal_freq_l; |
85 | | |
86 | 1.69M | WORD32 offset = pstr_code_env->offset; |
87 | 1.69M | WORD32 env_data_tab_comp_factor; |
88 | | |
89 | 1.69M | WORD32 delta_f_bits = 0, delta_t_bits = 0; |
90 | | |
91 | 1.69M | WORD32 use_dt; |
92 | | |
93 | 1.69M | WORD32 delta_f[MAXIMUM_FREQ_COEFFS]; |
94 | 1.69M | WORD32 delta_t[MAXIMUM_FREQ_COEFFS]; |
95 | | |
96 | 1.69M | FLOAT32 df_edge_first_ennv; |
97 | | |
98 | 1.69M | df_edge_first_ennv = pstr_code_env->df_edge_1st_env + |
99 | 1.69M | pstr_code_env->df_edge_incr * pstr_code_env->df_edge_incr_fac; |
100 | | |
101 | 1.69M | switch (coupling) { |
102 | 497k | case COUPLING_1: |
103 | 497k | code_book_scf_lav_lvl_time = pstr_code_env->code_book_scf_lav_lvl_time; |
104 | 497k | code_book_scf_lav_lvl_freq = pstr_code_env->code_book_scf_lav_lvl_freq; |
105 | 497k | code_book_scf_lav_bal_time = pstr_code_env->code_book_scf_lav_bal_time; |
106 | 497k | code_book_scf_lav_bal_freq = pstr_code_env->code_book_scf_lav_bal_freq; |
107 | 497k | ptr_huff_tab_lvl_time_l = pstr_code_env->ptr_huff_tab_lvl_time_l; |
108 | 497k | ptr_huff_tab_bal_time_l = pstr_code_env->ptr_huff_tab_bal_time_l; |
109 | 497k | ptr_huff_tab_lvl_freq_l = pstr_code_env->ptr_huff_tab_lvl_freq_l; |
110 | 497k | ptr_huff_tab_bal_freq_l = pstr_code_env->ptr_huff_tab_bal_freq_l; |
111 | 497k | break; |
112 | 1.20M | default: |
113 | 1.20M | code_book_scf_lav_lvl_time = pstr_code_env->code_book_scf_lav_time; |
114 | 1.20M | code_book_scf_lav_lvl_freq = pstr_code_env->code_book_scf_lav_freq; |
115 | 1.20M | code_book_scf_lav_bal_time = pstr_code_env->code_book_scf_lav_time; |
116 | 1.20M | code_book_scf_lav_bal_freq = pstr_code_env->code_book_scf_lav_freq; |
117 | 1.20M | ptr_huff_tab_lvl_time_l = pstr_code_env->ptr_huff_tab_time_l; |
118 | 1.20M | ptr_huff_tab_bal_time_l = pstr_code_env->ptr_huff_tab_time_l; |
119 | 1.20M | ptr_huff_tab_lvl_freq_l = pstr_code_env->ptr_huff_tab_freq_l; |
120 | 1.20M | ptr_huff_tab_bal_freq_l = pstr_code_env->ptr_huff_tab_freq_l; |
121 | 1.69M | } |
122 | | |
123 | 1.69M | if (coupling == 1 && channel == 1) { |
124 | 248k | env_data_tab_comp_factor = 1; |
125 | 1.44M | } else { |
126 | 1.44M | env_data_tab_comp_factor = 0; |
127 | 1.44M | } |
128 | | |
129 | 1.69M | if (pstr_code_env->delta_t_across_frames == 0 || header_active) { |
130 | 192k | pstr_code_env->update = 0; |
131 | 192k | } |
132 | | |
133 | 4.12M | for (i = 0; i < num_envelopes; i++) { |
134 | 2.42M | if (freq_res[i] == FREQ_RES_HIGH) |
135 | 1.92M | no_of_bands = pstr_code_env->num_scf[FREQ_RES_HIGH]; |
136 | 497k | else |
137 | 497k | no_of_bands = pstr_code_env->num_scf[FREQ_RES_LOW]; |
138 | | |
139 | 2.42M | ptr_energy = ptr_sfb_energy; |
140 | 2.42M | current_energy = *ptr_energy; |
141 | 2.42M | delta_f[0] = ixheaac_shr32(current_energy, env_data_tab_comp_factor); |
142 | 2.42M | if (coupling && channel == 1) |
143 | 357k | delta_f_bits = pstr_code_env->start_bits_balance; |
144 | 2.06M | else |
145 | 2.06M | delta_f_bits = pstr_code_env->start_bits; |
146 | | |
147 | 2.42M | if (pstr_code_env->update != 0) { |
148 | 1.68M | delta_t[0] = ixheaac_shr32((current_energy - pstr_code_env->sfb_nrg_prev[0]), |
149 | 1.68M | env_data_tab_comp_factor); |
150 | | |
151 | 1.68M | err_code = ixheaace_compute_bits(delta_t[0], code_book_scf_lav_lvl_time, |
152 | 1.68M | code_book_scf_lav_bal_time, ptr_huff_tab_lvl_time_l, |
153 | 1.68M | ptr_huff_tab_bal_time_l, coupling, channel, &delta_t_bits); |
154 | 1.68M | if (err_code) { |
155 | 1.42k | return err_code; |
156 | 1.42k | } |
157 | 1.68M | } |
158 | | |
159 | 2.42M | ixheaace_map_low_res_energy_value(current_energy, pstr_code_env->sfb_nrg_prev, offset, 0, |
160 | 2.42M | freq_res[i]); |
161 | | |
162 | 2.42M | band = no_of_bands - 1; |
163 | 15.6M | while (band > 0) { |
164 | 13.2M | if (ptr_energy[band] - ptr_energy[band - 1] > code_book_scf_lav_lvl_freq) { |
165 | 144 | ptr_energy[band - 1] = ptr_energy[band] - code_book_scf_lav_lvl_freq; |
166 | 144 | } |
167 | 13.2M | band--; |
168 | 13.2M | } |
169 | | |
170 | 2.42M | band = 1; |
171 | 15.6M | while (band < no_of_bands) { |
172 | 13.2M | WORD32 index; |
173 | 13.2M | WORD32 delta_lcl_bits = 0; |
174 | | |
175 | 13.2M | if (ixheaac_sub32_sat(ptr_energy[band - 1], ptr_energy[band]) > |
176 | 13.2M | code_book_scf_lav_lvl_freq) { |
177 | 1.38M | ptr_energy[band] = ptr_energy[band - 1] - code_book_scf_lav_lvl_freq; |
178 | 1.38M | } |
179 | | |
180 | 13.2M | last_nrg = *ptr_energy++; |
181 | 13.2M | current_energy = *ptr_energy; |
182 | 13.2M | delta_f[band] = ixheaac_shr32((current_energy - last_nrg), env_data_tab_comp_factor); |
183 | | |
184 | 13.2M | err_code = ixheaace_compute_bits( |
185 | 13.2M | delta_f[band], code_book_scf_lav_lvl_freq, code_book_scf_lav_bal_freq, |
186 | 13.2M | ptr_huff_tab_lvl_freq_l, ptr_huff_tab_bal_freq_l, coupling, channel, &delta_lcl_bits); |
187 | 13.2M | if (err_code) { |
188 | 1 | return err_code; |
189 | 1 | } |
190 | 13.2M | delta_f_bits += delta_lcl_bits; |
191 | | |
192 | 13.2M | if (pstr_code_env->update != 0) { |
193 | 9.34M | delta_lcl_bits = 0; |
194 | 9.34M | index = ixheaace_index_low2_high(offset, band, freq_res[i]); |
195 | 9.34M | delta_t[band] = current_energy - pstr_code_env->sfb_nrg_prev[index]; |
196 | 9.34M | delta_t[band] = ixheaac_shr32(delta_t[band], env_data_tab_comp_factor); |
197 | | |
198 | 9.34M | ixheaace_map_low_res_energy_value(current_energy, pstr_code_env->sfb_nrg_prev, offset, |
199 | 9.34M | band, freq_res[i]); |
200 | 9.34M | if ((delta_t[band] > 31) || (delta_t[band] < -31)) { |
201 | 2.73k | delta_t[band] = 31; |
202 | 2.73k | } |
203 | | |
204 | 9.34M | err_code = ixheaace_compute_bits( |
205 | 9.34M | delta_t[band], code_book_scf_lav_lvl_time, code_book_scf_lav_bal_time, |
206 | 9.34M | ptr_huff_tab_lvl_time_l, ptr_huff_tab_bal_time_l, coupling, channel, &delta_lcl_bits); |
207 | 9.34M | if (err_code) { |
208 | 98 | return err_code; |
209 | 98 | } |
210 | 9.34M | delta_t_bits += delta_lcl_bits; |
211 | 9.34M | } else { |
212 | 3.89M | ixheaace_map_low_res_energy_value(current_energy, pstr_code_env->sfb_nrg_prev, offset, |
213 | 3.89M | band, freq_res[i]); |
214 | 3.89M | } |
215 | 13.2M | band++; |
216 | 13.2M | } |
217 | | |
218 | 2.42M | if (i == 0) { |
219 | 1.69M | use_dt = (pstr_code_env->update != 0 && |
220 | 952k | (delta_f_bits > delta_t_bits * (1 + df_edge_first_ennv))); |
221 | 1.69M | } else if (is_ld_sbr) { |
222 | 196k | use_dt = ((pstr_code_env->update != 0) && (delta_f_bits > delta_t_bits)); |
223 | 532k | } else { |
224 | 532k | use_dt = (delta_f_bits > delta_t_bits); |
225 | 532k | } |
226 | | |
227 | 2.42M | if (use_dt) { |
228 | 844k | ptr_dir_vec[i] = TIME; |
229 | 844k | memcpy(ptr_sfb_energy, delta_t, no_of_bands * sizeof(ptr_sfb_energy[0])); |
230 | 1.58M | } else { |
231 | 1.58M | ptr_dir_vec[i] = FREQ; |
232 | 1.58M | memcpy(ptr_sfb_energy, delta_f, no_of_bands * sizeof(ptr_sfb_energy[0])); |
233 | 1.58M | } |
234 | 2.42M | if (0 == i && 1 == usac_indep_flag) { |
235 | 45.4k | ptr_dir_vec[i] = FREQ; |
236 | 45.4k | memcpy(ptr_sfb_energy, delta_f, no_of_bands * sizeof(ptr_sfb_energy[0])); |
237 | 45.4k | } |
238 | | |
239 | 2.42M | ptr_sfb_energy += no_of_bands; |
240 | 2.42M | pstr_code_env->update = 1; |
241 | 2.42M | } |
242 | 1.69M | return err_code; |
243 | 1.69M | } |