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 #include <math.h>
23
24 #include "ixheaac_type_def.h"
25 #include "ixheaac_constants.h"
26 #include "ixheaac_error_standards.h"
27 #include "ixheaace_aac_constants.h"
28 #include "ixheaac_basic_ops32.h"
29 #include "ixheaac_basic_ops16.h"
30 #include "ixheaac_basic_ops40.h"
31 #include "ixheaac_basic_ops.h"
32
33 #include "ixheaace_sbr_header.h"
34 #include "ixheaace_sbr_def.h"
35 #include "ixheaace_resampler.h"
36 #include "ixheaace_sbr_rom.h"
37 #include "ixheaace_common_rom.h"
38 #include "ixheaace_sbr_main.h"
39 #include "ixheaace_sbr_inv_filtering_estimation.h"
40 #include "ixheaace_sbr_misc.h"
41 #include "ixheaace_common_utils.h"
42
ixheaace_calculate_detector_values(FLOAT32 ** ptr_quota_mtx_org,WORD8 * ptr_idx_vx,FLOAT32 * ptr_energy_vec,ixheaace_str_detector_values * ptr_detector_values,WORD32 start_channel,WORD32 stop_channel,WORD32 start_index,WORD32 stop_index)43 static VOID ixheaace_calculate_detector_values(FLOAT32 **ptr_quota_mtx_org, WORD8 *ptr_idx_vx,
44 FLOAT32 *ptr_energy_vec,
45 ixheaace_str_detector_values *ptr_detector_values,
46 WORD32 start_channel, WORD32 stop_channel,
47 WORD32 start_index, WORD32 stop_index) {
48 WORD32 i, j;
49
50 FLOAT32 quota_vec_org[IXHEAACE_QMF_CHANNELS] = {0};
51 FLOAT32 quota_vec_sbr[IXHEAACE_QMF_CHANNELS] = {0};
52 FLOAT32 org_quota = 0.0f, sbr_quota = 0.0f;
53
54 ptr_detector_values->avg_energy = 0.0f;
55 for (j = start_index; j < stop_index; j++) {
56 for (i = start_channel; i < stop_channel; i++) {
57 quota_vec_org[i] += ptr_quota_mtx_org[j][i];
58 if (ptr_idx_vx[i] != -1) {
59 quota_vec_sbr[i] += ptr_quota_mtx_org[j][ptr_idx_vx[i]];
60 }
61 }
62 ptr_detector_values->avg_energy += ptr_energy_vec[j];
63 }
64 ptr_detector_values->avg_energy /= (stop_index - start_index);
65 org_quota = 0.0f;
66 sbr_quota = 0.0f;
67
68 for (i = start_channel; i < stop_channel; i++) {
69 quota_vec_org[i] /= (stop_index - start_index);
70 quota_vec_sbr[i] /= (stop_index - start_index);
71 org_quota += quota_vec_org[i];
72 sbr_quota += quota_vec_sbr[i];
73 }
74
75 org_quota /= (stop_channel - start_channel);
76 sbr_quota /= (stop_channel - start_channel);
77
78 memmove(ptr_detector_values->org_quota_mean, ptr_detector_values->org_quota_mean + 1,
79 IXHEAACE_INVF_SMOOTHING_LENGTH * sizeof(ptr_detector_values->org_quota_mean[0]));
80 memmove(ptr_detector_values->sbr_quota_mean, ptr_detector_values->sbr_quota_mean + 1,
81 IXHEAACE_INVF_SMOOTHING_LENGTH * sizeof(ptr_detector_values->org_quota_mean[0]));
82
83 ptr_detector_values->org_quota_mean[IXHEAACE_INVF_SMOOTHING_LENGTH] = org_quota;
84 ptr_detector_values->sbr_quota_mean[IXHEAACE_INVF_SMOOTHING_LENGTH] = sbr_quota;
85
86 ptr_detector_values->org_quota_mean_filt = 0.0f;
87 ptr_detector_values->sbr_quota_mean_filt = 0.0f;
88
89 for (i = 0; i < IXHEAACE_INVF_SMOOTHING_LENGTH + 1; i++) {
90 ptr_detector_values->org_quota_mean_filt +=
91 ptr_detector_values->org_quota_mean[i] * filter[i];
92 ptr_detector_values->sbr_quota_mean_filt +=
93 ptr_detector_values->sbr_quota_mean[i] * filter[i];
94 }
95 }
96
ixheaace_find_region(FLOAT32 curr_val,const FLOAT32 * ptr_borders,const WORD32 num_borders)97 static WORD32 ixheaace_find_region(FLOAT32 curr_val, const FLOAT32 *ptr_borders,
98 const WORD32 num_borders) {
99 WORD32 i;
100
101 if (curr_val < ptr_borders[0]) {
102 return 0;
103 }
104
105 for (i = 1; i < num_borders; i++) {
106 if (curr_val >= ptr_borders[i - 1] && curr_val < ptr_borders[i]) {
107 return i;
108 }
109 }
110
111 if (curr_val > ptr_borders[num_borders - 1]) {
112 return num_borders;
113 }
114
115 return 0;
116 }
117
ixheaace_decision_algorithm(const ixheaace_str_det_params * ptr_detector_params,ixheaace_str_detector_values ptr_detector_values,WORD32 transient_flag,WORD32 * ptr_prev_region_sbr,WORD32 * ptr_prev_region_orig,WORD32 is_ld_sbr)118 static ixheaace_invf_mode ixheaace_decision_algorithm(
119 const ixheaace_str_det_params *ptr_detector_params,
120 ixheaace_str_detector_values ptr_detector_values, WORD32 transient_flag,
121 WORD32 *ptr_prev_region_sbr, WORD32 *ptr_prev_region_orig, WORD32 is_ld_sbr) {
122 WORD32 inv_filt_level, region_sbr, region_orig, region_nrg;
123
124 const WORD32 hysteresis = 1;
125 const WORD32 num_regions_sbr = ptr_detector_params->num_regions_sbr;
126 const WORD32 num_regions_orig = ptr_detector_params->num_regions_orig;
127 const WORD32 num_regions_nrg = ptr_detector_params->num_regions_nrg;
128
129 FLOAT32 quant_steps_sbr_tmp[IXHEAACE_MAX_NUM_REGIONS];
130 FLOAT32 quant_steps_org_tmp[IXHEAACE_MAX_NUM_REGIONS];
131
132 FLOAT32 org_quota_mean_filt, sbr_quota_mean_filt, energy;
133 if (is_ld_sbr) {
134 org_quota_mean_filt =
135 (FLOAT32)(SBR_INV_LOG_2 * 3.0f * log(ptr_detector_values.org_quota_mean_filt + EPS));
136
137 sbr_quota_mean_filt =
138 (FLOAT32)(SBR_INV_LOG_2 * 3.0f * log(ptr_detector_values.sbr_quota_mean_filt + EPS));
139
140 energy = (FLOAT32)(SBR_INV_LOG_2 * 1.5f * log(ptr_detector_values.avg_energy + EPS));
141 } else {
142 org_quota_mean_filt =
143 (FLOAT32)(SBR_INV_LOG_2 * 3.0f * log(ptr_detector_values.org_quota_mean_filt * EPS));
144 sbr_quota_mean_filt =
145 (FLOAT32)(SBR_INV_LOG_2 * 3.0f * log(ptr_detector_values.sbr_quota_mean_filt * EPS));
146 energy = (FLOAT32)(SBR_INV_LOG_2 * 1.5f * log(ptr_detector_values.avg_energy * EPS));
147 }
148 memcpy(quant_steps_org_tmp, ptr_detector_params->quant_steps_org,
149 num_regions_orig * sizeof(quant_steps_org_tmp[0]));
150 memcpy(quant_steps_sbr_tmp, ptr_detector_params->quant_steps_sbr,
151 num_regions_sbr * sizeof(quant_steps_org_tmp[0]));
152
153 if (*ptr_prev_region_sbr < num_regions_sbr) {
154 quant_steps_sbr_tmp[*ptr_prev_region_sbr] =
155 ptr_detector_params->quant_steps_sbr[*ptr_prev_region_sbr] + (FLOAT32)hysteresis;
156 }
157
158 if (*ptr_prev_region_sbr > 0) {
159 quant_steps_sbr_tmp[*ptr_prev_region_sbr - 1] =
160 ptr_detector_params->quant_steps_sbr[*ptr_prev_region_sbr - 1] - (FLOAT32)hysteresis;
161 }
162
163 if (*ptr_prev_region_orig < num_regions_orig) {
164 quant_steps_org_tmp[*ptr_prev_region_orig] =
165 ptr_detector_params->quant_steps_org[*ptr_prev_region_orig] + (FLOAT32)hysteresis;
166 }
167
168 if (*ptr_prev_region_orig > 0) {
169 quant_steps_org_tmp[*ptr_prev_region_orig - 1] =
170 ptr_detector_params->quant_steps_org[*ptr_prev_region_orig - 1] - (FLOAT32)hysteresis;
171 }
172
173 region_sbr = ixheaace_find_region(sbr_quota_mean_filt, quant_steps_sbr_tmp, num_regions_sbr);
174
175 region_orig = ixheaace_find_region(org_quota_mean_filt, quant_steps_org_tmp, num_regions_orig);
176
177 region_nrg = ixheaace_find_region(energy, ptr_detector_params->energy_brdrs, num_regions_nrg);
178
179 *ptr_prev_region_sbr = region_sbr;
180 *ptr_prev_region_orig = region_orig;
181
182 inv_filt_level = (transient_flag == 1)
183 ? ptr_detector_params->region_space_transient[region_sbr][region_orig]
184 : ptr_detector_params->region_space[region_sbr][region_orig];
185
186 inv_filt_level =
187 ixheaac_max32(inv_filt_level + ptr_detector_params->energy_comp_factor[region_nrg], 0);
188
189 return (ixheaace_invf_mode)(inv_filt_level);
190 }
191
ixheaace_qmf_inverse_filtering_detector(ixheaace_pstr_sbr_inv_filt_est pstr_inv_filt,FLOAT32 ** ptr_quota_mtx,FLOAT32 * ptr_energy_vec,WORD8 * ptr_idx_vx,WORD32 start_index,WORD32 stop_index,WORD32 transient_flag,ixheaace_invf_mode * ptr_inf_vec,WORD32 is_ld_sbr)192 VOID ixheaace_qmf_inverse_filtering_detector(ixheaace_pstr_sbr_inv_filt_est pstr_inv_filt,
193 FLOAT32 **ptr_quota_mtx, FLOAT32 *ptr_energy_vec,
194 WORD8 *ptr_idx_vx, WORD32 start_index,
195 WORD32 stop_index, WORD32 transient_flag,
196 ixheaace_invf_mode *ptr_inf_vec, WORD32 is_ld_sbr) {
197 WORD32 band;
198
199 for (band = 0; band < pstr_inv_filt->no_detector_bands; band++) {
200 WORD32 start_channel = pstr_inv_filt->freq_band_tab_inv_filt[band];
201 WORD32 stop_channel = pstr_inv_filt->freq_band_tab_inv_filt[band + 1];
202
203 ixheaace_calculate_detector_values(ptr_quota_mtx, ptr_idx_vx, ptr_energy_vec,
204 &pstr_inv_filt->detector_values[band], start_channel,
205 stop_channel, start_index, stop_index);
206
207 ptr_inf_vec[band] = ixheaace_decision_algorithm(
208 pstr_inv_filt->ptr_detector_params, pstr_inv_filt->detector_values[band], transient_flag,
209 &pstr_inv_filt->prev_region_sbr[band], &pstr_inv_filt->prev_region_orig[band], is_ld_sbr);
210 }
211 }
212
ixheaace_reset_inv_filt_detector(ixheaace_pstr_sbr_inv_filt_est pstr_inv_filt,WORD32 * ptr_freq_band_tab_detector,WORD32 num_det_bands)213 static VOID ixheaace_reset_inv_filt_detector(ixheaace_pstr_sbr_inv_filt_est pstr_inv_filt,
214 WORD32 *ptr_freq_band_tab_detector,
215 WORD32 num_det_bands) {
216 memcpy(pstr_inv_filt->freq_band_tab_inv_filt, ptr_freq_band_tab_detector,
217 (num_det_bands + 1) * sizeof(pstr_inv_filt->freq_band_tab_inv_filt[0]));
218
219 pstr_inv_filt->no_detector_bands = num_det_bands;
220 }
221
ixheaace_create_inv_filt_detector(ixheaace_pstr_sbr_inv_filt_est pstr_inv_filt,WORD32 * ptr_freq_band_tab_detector,WORD32 num_det_bands,UWORD32 use_speech_config,ixheaace_str_qmf_tabs * ptr_qmf_tab)222 VOID ixheaace_create_inv_filt_detector(ixheaace_pstr_sbr_inv_filt_est pstr_inv_filt,
223 WORD32 *ptr_freq_band_tab_detector, WORD32 num_det_bands,
224 UWORD32 use_speech_config,
225 ixheaace_str_qmf_tabs *ptr_qmf_tab) {
226 WORD32 i;
227
228 memset(pstr_inv_filt, 0, sizeof(ixheaace_str_sbr_inv_filt_est));
229
230 if (use_speech_config) {
231 pstr_inv_filt->ptr_detector_params = &(ptr_qmf_tab->detector_params_aac_speech);
232 } else {
233 pstr_inv_filt->ptr_detector_params = &(ptr_qmf_tab->detector_params_aac);
234 }
235
236 pstr_inv_filt->no_detector_bands_max = num_det_bands;
237
238 for (i = 0; i < pstr_inv_filt->no_detector_bands_max; i++) {
239 memset(&pstr_inv_filt->detector_values[i], 0, sizeof(ixheaace_str_detector_values));
240
241 pstr_inv_filt->prev_invf_mode[i] = IXHEAACE_INVF_OFF;
242 pstr_inv_filt->prev_region_orig[i] = 0;
243 pstr_inv_filt->prev_region_sbr[i] = 0;
244 }
245
246 ixheaace_reset_inv_filt_detector(pstr_inv_filt, ptr_freq_band_tab_detector,
247 pstr_inv_filt->no_detector_bands_max);
248 }
249