xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_sbr_ton_corr_hp.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 <math.h>
22 #include <string.h>
23 
24 #include "ixheaac_type_def.h"
25 #include "ixheaac_constants.h"
26 #include "ixheaace_aac_constants.h"
27 #include "ixheaac_basic_ops32.h"
28 #include "ixheaac_basic_ops16.h"
29 #include "ixheaac_basic_ops40.h"
30 #include "ixheaac_basic_ops.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_hbe.h"
38 #include "ixheaace_sbr_qmf_enc.h"
39 #include "ixheaace_sbr_tran_det.h"
40 #include "ixheaace_sbr_frame_info_gen.h"
41 #include "ixheaace_sbr_env_est.h"
42 #include "ixheaace_sbr_code_envelope.h"
43 #include "ixheaace_sbr_main.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 #include "ixheaace_sbr_ton_corr.h"
48 #include "iusace_esbr_pvc.h"
49 #include "iusace_esbr_inter_tes.h"
50 #include "ixheaace_sbr.h"
51 
52 #include "ixheaace_sbr_misc.h"
53 #include "ixheaace_common_utils.h"
54 
ixheaace_calc_auto_corr_second_order(ixheaace_acorr_coeffs * pstr_ac,FLOAT32 ** ptr_real,FLOAT32 ** ptr_imag,WORD32 bd,WORD32 len)55 static VOID ixheaace_calc_auto_corr_second_order(ixheaace_acorr_coeffs *pstr_ac,
56                                                  FLOAT32 **ptr_real, FLOAT32 **ptr_imag,
57                                                  WORD32 bd, WORD32 len) {
58   WORD32 j, jminus1, jminus2;
59   float rel = 1.0f / (1.0f + RELAXATION);
60 
61   memset(pstr_ac, 0, sizeof(ixheaace_acorr_coeffs));
62 
63   for (j = 0; j < (len - 2 - 1); j++) {
64     jminus1 = j - 1;
65     jminus2 = jminus1 - 1;
66 
67     pstr_ac->r00r += ptr_real[j][bd] * ptr_real[j][bd] + ptr_imag[j][bd] * ptr_imag[j][bd];
68 
69     pstr_ac->r11r += ptr_real[jminus1][bd] * ptr_real[jminus1][bd] +
70                      ptr_imag[jminus1][bd] * ptr_imag[jminus1][bd];
71 
72     pstr_ac->r01r +=
73         ptr_real[j][bd] * ptr_real[jminus1][bd] + ptr_imag[j][bd] * ptr_imag[jminus1][bd];
74 
75     pstr_ac->r01i +=
76         ptr_imag[j][bd] * ptr_real[jminus1][bd] - ptr_real[j][bd] * ptr_imag[jminus1][bd];
77 
78     pstr_ac->r02r +=
79         ptr_real[j][bd] * ptr_real[jminus2][bd] + ptr_imag[j][bd] * ptr_imag[jminus2][bd];
80 
81     pstr_ac->r02i +=
82         ptr_imag[j][bd] * ptr_real[jminus2][bd] - ptr_real[j][bd] * ptr_imag[jminus2][bd];
83   }
84 
85   pstr_ac->r22r =
86       pstr_ac->r11r + ptr_real[-2][bd] * ptr_real[-2][bd] + ptr_imag[-2][bd] * ptr_imag[-2][bd];
87 
88   pstr_ac->r12r =
89       pstr_ac->r01r + ptr_real[-1][bd] * ptr_real[-2][bd] + ptr_imag[-1][bd] * ptr_imag[-2][bd];
90 
91   pstr_ac->r12i =
92       pstr_ac->r01i + ptr_imag[-1][bd] * ptr_real[-2][bd] - ptr_real[-1][bd] * ptr_imag[-2][bd];
93 
94   jminus1 = j - 1;
95   jminus2 = jminus1 - 1;
96 
97   pstr_ac->r00r += ptr_real[j][bd] * ptr_real[j][bd] + ptr_imag[j][bd] * ptr_imag[j][bd];
98 
99   pstr_ac->r11r += ptr_real[jminus1][bd] * ptr_real[jminus1][bd] +
100                    ptr_imag[jminus1][bd] * ptr_imag[jminus1][bd];
101 
102   pstr_ac->r01r +=
103       ptr_real[j][bd] * ptr_real[jminus1][bd] + ptr_imag[j][bd] * ptr_imag[jminus1][bd];
104 
105   pstr_ac->r01i +=
106       ptr_imag[j][bd] * ptr_real[jminus1][bd] - ptr_real[j][bd] * ptr_imag[jminus1][bd];
107 
108   pstr_ac->r02r +=
109       ptr_real[j][bd] * ptr_real[jminus2][bd] + ptr_imag[j][bd] * ptr_imag[jminus2][bd];
110 
111   pstr_ac->r02i +=
112       ptr_imag[j][bd] * ptr_real[jminus2][bd] - ptr_real[j][bd] * ptr_imag[jminus2][bd];
113 
114   pstr_ac->det = pstr_ac->r11r * pstr_ac->r22r -
115                  rel * (pstr_ac->r12r * pstr_ac->r12r + pstr_ac->r12i * pstr_ac->r12i);
116 }
117 
ixheaace_calculate_tonality_quotas(ixheaace_pstr_sbr_ton_corr_est pstr_ton_corr,FLOAT32 ** ptr_real,FLOAT32 ** ptr_imag,WORD32 usb,WORD32 num_time_slots,WORD32 is_ld_sbr)118 VOID ixheaace_calculate_tonality_quotas(ixheaace_pstr_sbr_ton_corr_est pstr_ton_corr,
119                                         FLOAT32 **ptr_real, FLOAT32 **ptr_imag, WORD32 usb,
120                                         WORD32 num_time_slots, WORD32 is_ld_sbr) {
121   WORD32 i, k, r, time_index;
122   FLOAT32 alphar[2], alphai[2], r01r, r02r, r11r, r12r, r01i, r02i, r12i, det, r00r;
123   ixheaace_acorr_coeffs ac;
124   FLOAT32 *ptr_energy_vec = pstr_ton_corr->energy_vec;
125   FLOAT32 **ptr_quota_mtx = pstr_ton_corr->ptr_quota_mtx;
126 
127   WORD32 start_index_matrix = pstr_ton_corr->start_index_matrix;
128   WORD32 tot_no_est = pstr_ton_corr->est_cnt;
129   WORD32 no_est_per_frame = pstr_ton_corr->est_cnt_per_frame;
130   WORD32 move = pstr_ton_corr->move;
131   WORD32 num_qmf_ch = pstr_ton_corr->num_qmf_ch;
132   WORD32 len = num_time_slots;
133   WORD32 qm_len;
134   for (i = 0; i < move; i++) {
135     memcpy(ptr_quota_mtx[i], ptr_quota_mtx[i + no_est_per_frame],
136            num_qmf_ch * sizeof(ptr_quota_mtx[i][0]));
137   }
138 
139   memmove(ptr_energy_vec, ptr_energy_vec + no_est_per_frame, move * sizeof(ptr_energy_vec[0]));
140   memset(ptr_energy_vec + start_index_matrix, 0,
141          (tot_no_est - start_index_matrix) * sizeof(ptr_energy_vec[0]));
142   if (is_ld_sbr) {
143     len = num_time_slots / 2;
144     qm_len = 2 + len;
145   } else {
146     qm_len = 18;
147   }
148 
149   for (r = 0; r < usb; r++) {
150     k = 2;
151     time_index = start_index_matrix;
152 
153     while (k <= qm_len) {
154       ixheaace_calc_auto_corr_second_order(&ac, &ptr_real[k], &ptr_imag[k], r, len);
155 
156       r00r = ac.r00r;
157       r11r = ac.r11r;
158       r12r = ac.r12r;
159       r12i = ac.r12i;
160       r01r = ac.r01r;
161       r01i = ac.r01i;
162       r02r = ac.r02r;
163       r02i = ac.r02i;
164       det = ac.det;
165 
166       if (det == 0) {
167         alphar[1] = alphai[1] = 0;
168       } else {
169         alphar[1] = (r01r * r12r - r01i * r12i - r02r * r11r) / det;
170         alphai[1] = (r01i * r12r + r01r * r12i - r02i * r11r) / det;
171       }
172 
173       if (r11r == 0) {
174         alphar[0] = alphai[0] = 0;
175       } else {
176         alphar[0] = -(r01r + alphar[1] * r12r + alphai[1] * r12i) / r11r;
177         alphai[0] = -(r01i + alphai[1] * r12r - alphar[1] * r12i) / r11r;
178       }
179       if (r00r) {
180         FLOAT32 tmp =
181             -(alphar[0] * r01r + alphai[0] * r01i + alphar[1] * r02r + alphai[1] * r02i) / (r00r);
182         ptr_quota_mtx[time_index][r] = (FLOAT32)ixheaace_div32(tmp, 1.0f - tmp);
183       } else {
184         ptr_quota_mtx[time_index][r] = 0;
185       }
186       ptr_energy_vec[time_index] += r00r;
187 
188       k += is_ld_sbr ? len : 16;
189 
190       time_index++;
191     }
192   }
193 }
194