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