xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_sbr_inv_filtering_estimation.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 #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