/src/libxaac/encoder/iusace_tcx_enc.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 | | #include <math.h> |
23 | | #include "ixheaac_type_def.h" |
24 | | #include "ixheaace_adjust_threshold_data.h" |
25 | | #include "iusace_bitbuffer.h" |
26 | | |
27 | | /* DRC */ |
28 | | #include "impd_drc_common_enc.h" |
29 | | #include "impd_drc_uni_drc.h" |
30 | | #include "impd_drc_tables.h" |
31 | | #include "impd_drc_api.h" |
32 | | #include "impd_drc_uni_drc_eq.h" |
33 | | #include "impd_drc_uni_drc_filter_bank.h" |
34 | | #include "impd_drc_gain_enc.h" |
35 | | #include "impd_drc_struct_def.h" |
36 | | |
37 | | #include "iusace_cnst.h" |
38 | | #include "iusace_tns_usac.h" |
39 | | #include "iusace_psy_mod.h" |
40 | | #include "iusace_tns_usac.h" |
41 | | #include "iusace_config.h" |
42 | | #include "iusace_fft.h" |
43 | | #include "iusace_tcx_mdct.h" |
44 | | #include "iusace_arith_enc.h" |
45 | | #include "iusace_fd_qc_util.h" |
46 | | #include "iusace_fd_quant.h" |
47 | | #include "iusace_block_switch_const.h" |
48 | | #include "iusace_block_switch_struct_def.h" |
49 | | #include "iusace_ms.h" |
50 | | #include "iusace_signal_classifier.h" |
51 | | #include "ixheaace_sbr_header.h" |
52 | | #include "ixheaace_config.h" |
53 | | #include "ixheaace_asc_write.h" |
54 | | #include "iusace_main.h" |
55 | | #include "iusace_lpd_rom.h" |
56 | | #include "iusace_lpd.h" |
57 | | #include "iusace_avq_enc.h" |
58 | | #include "ixheaace_common_utils.h" |
59 | | |
60 | | const UWORD32 iusace_pow10_gain_div28[128] = { |
61 | | 1024, 1112, 1207, 1311, 1423, 1545, 1677, 1821, 1977, |
62 | | 2146, 2330, 2530, 2747, 2983, 3238, 3516, 3817, 4144, |
63 | | 4499, 4885, 5304, 5758, 6252, 6788, 7370, 8001, 8687, |
64 | | 9432, 10240, 11118, 12071, 13105, 14228, 15448, 16772, 18210, |
65 | | 19770, 21465, 23305, 25302, 27471, 29825, 32382, 35157, 38171, |
66 | | 41442, 44994, 48851, 53038, 57584, 62519, 67878, 73696, 80012, |
67 | | 86870, 94316, 102400, 111177, 120706, 131052, 142284, 154480, 167720, |
68 | | 182096, 197703, 214649, 233047, 253021, 274708, 298254, 323817, 351572, |
69 | | 381706, 414422, 449943, 488508, 530378, 575838, 625193, 678779, 736958, |
70 | | 800124, 868703, 943161, 1024000, 1111768, 1207059, 1310517, 1422843, 1544797, |
71 | | 1677203, 1820958, 1977034, 2146488, 2330466, 2530213, 2747080, 2982536, 3238172, |
72 | | 3515720, 3817056, 4144220, 4499426, 4885077, 5303782, 5758375, 6251932, 6787792, |
73 | | 7369581, 8001236, 8687031, 9431606, 10240000, 11117682, 12070591, 13105175, 14228434, |
74 | | 15447969, 16772032, 18209581, 19770345, 21464883, 23304662, 25302131, 27470805, 29825358, |
75 | | 32381723, 35157197}; |
76 | | |
77 | | static const FLOAT64 iusace_lpc_pre_twid_cos[ORDER + 1] = {1.0, |
78 | | 0.99969881867944277, |
79 | | 0.99879545613814691, |
80 | | 0.99729045666498317, |
81 | | 0.99518472640441780, |
82 | | 0.99247953486470630, |
83 | | 0.98917650991010153, |
84 | | 0.98527764316379052, |
85 | | 0.98078527933727178, |
86 | | 0.97570212991605565, |
87 | | 0.97003125425052761, |
88 | | 0.96377606826277584, |
89 | | 0.95694033551585822, |
90 | | 0.94952817722361749, |
91 | | 0.94154406823678738, |
92 | | 0.93299279849944938, |
93 | | 0.92387952832938047}; |
94 | | |
95 | | static const FLOAT64 iusace_lpc_pre_twid_sin[ORDER + 1] = {0, |
96 | | 0.024541229205697054, |
97 | | 0.049067675691753569, |
98 | | 0.073564563785488826, |
99 | | 0.098017143048367339, |
100 | | 0.12241067304257494, |
101 | | 0.14673047482398086, |
102 | | 0.17096188429473480, |
103 | | 0.19509032737506427, |
104 | | 0.21910124070226658, |
105 | | 0.24298017568754085, |
106 | | 0.26671274855909161, |
107 | | 0.29028467796767482, |
108 | | 0.31368175059826858, |
109 | | 0.33688984485751389, |
110 | | 0.35989503740419343, |
111 | | 0.38268344246110436}; |
112 | | |
113 | | static VOID iusace_lpc_mdct(FLOAT32 *ptr_lpc_coeffs, FLOAT32 *mdct_gains, WORD32 length, |
114 | 1.56M | iusace_scratch_mem *pstr_scratch) { |
115 | 1.56M | FLOAT32 *in_out = pstr_scratch->p_in_out_tcx; |
116 | 1.56M | WORD32 i; |
117 | | |
118 | 28.1M | for (i = 0; i < ORDER + 1; i++) { |
119 | 26.5M | in_out[2 * i] = (FLOAT32)(ptr_lpc_coeffs[i] * iusace_lpc_pre_twid_cos[i]); |
120 | 26.5M | in_out[2 * i + 1] = (FLOAT32)(-ptr_lpc_coeffs[i] * iusace_lpc_pre_twid_sin[i]); |
121 | 26.5M | } |
122 | 159M | for (; i < length; i++) { |
123 | 158M | in_out[2 * i] = 0.f; |
124 | 158M | in_out[2 * i + 1] = 0.f; |
125 | 158M | } |
126 | | |
127 | 1.56M | iusace_complex_fft(in_out, length, pstr_scratch); |
128 | | |
129 | 93.8M | for (i = 0; i<length>> 1; i++) { |
130 | 92.3M | mdct_gains[i] = (FLOAT32)( |
131 | 92.3M | 1.0f / sqrt(in_out[2 * i] * in_out[2 * i] + in_out[2 * i + 1] * in_out[2 * i + 1])); |
132 | 92.3M | } |
133 | | |
134 | 1.56M | return; |
135 | 1.56M | } |
136 | | |
137 | 0 | UWORD32 iusace_rounded_sqrt(UWORD32 pos_num) { |
138 | 0 | UWORD32 num = pos_num; |
139 | 0 | UWORD32 value = 0; |
140 | 0 | UWORD32 bit_set = 1 << 30; |
141 | |
|
142 | 0 | while (bit_set > num) { |
143 | 0 | bit_set >>= 2; |
144 | 0 | } |
145 | 0 | while (bit_set) { |
146 | 0 | if (num >= value + bit_set) { |
147 | 0 | num -= value + bit_set; |
148 | 0 | value += bit_set << 1; |
149 | 0 | } |
150 | 0 | value >>= 1; |
151 | 0 | bit_set >>= 2; |
152 | 0 | } |
153 | 0 | num = value + 1; |
154 | 0 | if (num * num - pos_num < pos_num - value * value) { |
155 | 0 | return num; |
156 | 0 | } |
157 | 0 | return value; |
158 | 0 | } |
159 | | |
160 | | static VOID iusace_noise_shaping(FLOAT32 *rr, WORD32 lg, WORD32 M, FLOAT32 *gain1, |
161 | 781k | FLOAT32 *gain2) { |
162 | 781k | WORD32 i, k; |
163 | 781k | FLOAT32 r, r_prev, g1, g2, a = 0, b = 0; |
164 | | |
165 | 781k | k = lg/M; |
166 | | |
167 | 781k | r_prev = 0; |
168 | 317M | for (i = 0; i < lg; i++) { |
169 | 316M | if ((i % k) == 0) { |
170 | 46.1M | g1 = gain1[i / k]; |
171 | 46.1M | g2 = gain2[i / k]; |
172 | 46.1M | a = 2.0f * g1 * g2 / (g1 + g2); |
173 | 46.1M | b = (g2 - g1) / (g1 + g2); |
174 | 46.1M | } |
175 | | |
176 | 316M | r = a * rr[i] + b * r_prev; |
177 | | |
178 | 316M | rr[i] = r; |
179 | 316M | r_prev = r; |
180 | 316M | } |
181 | | |
182 | 781k | return; |
183 | 781k | } |
184 | | |
185 | 781k | static VOID iusace_pre_shaping(FLOAT32 *rr, WORD32 lg, WORD32 M, FLOAT32 *gain1, FLOAT32 *gain2) { |
186 | 781k | WORD32 i, k; |
187 | 781k | FLOAT32 r, r_prev, g1, g2, a = 0, b = 0; |
188 | | |
189 | 781k | k = lg / M; |
190 | | |
191 | 781k | r_prev = 0; |
192 | 317M | for (i = 0; i < lg; i++) { |
193 | 316M | if ((i % k) == 0) { |
194 | 46.1M | g1 = gain1[i / k]; |
195 | 46.1M | g2 = gain2[i / k]; |
196 | | |
197 | 46.1M | a = (g1 + g2) / (2.0f * g1 * g2); |
198 | 46.1M | b = (g1 - g2) / (2.0f * g1 * g2); |
199 | 46.1M | } |
200 | | |
201 | 316M | r = a * rr[i] + b * r_prev; |
202 | | |
203 | 316M | r_prev = rr[i]; |
204 | 316M | rr[i] = r; |
205 | 316M | } |
206 | | |
207 | 781k | return; |
208 | 781k | } |
209 | | |
210 | 781k | static VOID iusace_adapt_lo_freq_emph(FLOAT32 *signal, WORD32 length) { |
211 | 781k | WORD32 i, j, i_max; |
212 | 781k | FLOAT32 max_energy, factor, temp; |
213 | | |
214 | 781k | i_max = length >> 2; |
215 | | |
216 | 781k | max_energy = 0.01f; |
217 | 10.6M | for (i = 0; i < i_max; i += 8) { |
218 | 9.89M | temp = 0.01f; |
219 | 89.0M | for (j = i; j < i + 8; j++) { |
220 | 79.1M | temp += signal[j] * signal[j]; |
221 | 79.1M | } |
222 | 9.89M | if (temp > max_energy) { |
223 | 1.00M | max_energy = temp; |
224 | 1.00M | } |
225 | 9.89M | } |
226 | | |
227 | 781k | factor = 10.0f; |
228 | 10.6M | for (i = 0; i < i_max; i += 8) { |
229 | 9.89M | temp = 0.01f; |
230 | 89.0M | for (j = i; j < i + 8; j++) { |
231 | 79.1M | temp += signal[j] * signal[j]; |
232 | 79.1M | } |
233 | 9.89M | temp = (FLOAT32)sqrt(sqrt(max_energy / temp)); |
234 | 9.89M | if (temp < factor) { |
235 | 1.01M | factor = temp; |
236 | 1.01M | } |
237 | 89.0M | for (j = i; j < i + 8; j++) { |
238 | 79.1M | signal[j] *= factor; |
239 | 79.1M | } |
240 | 9.89M | } |
241 | 781k | return; |
242 | 781k | } |
243 | | |
244 | 781k | static VOID iusace_adapt_lo_freq_deemph(FLOAT32 *signal, WORD32 length, FLOAT32 *gains) { |
245 | 781k | WORD32 i, j, i_max; |
246 | 781k | FLOAT32 max_energy, factor, energy, rm; |
247 | | |
248 | 781k | i_max = length >> 2; |
249 | | |
250 | 781k | max_energy = 0.01f; |
251 | 10.6M | for (i = 0; i < i_max; i += 8) { |
252 | 9.89M | energy = 0.01f; |
253 | 89.0M | for (j = i; j < i + 8; j++) { |
254 | 79.1M | energy += signal[j] * signal[j]; |
255 | 79.1M | } |
256 | 9.89M | if (energy > max_energy) { |
257 | 927k | max_energy = energy; |
258 | 927k | } |
259 | 9.89M | } |
260 | | |
261 | 781k | factor = 0.1f; |
262 | 10.6M | for (i = 0; i < i_max; i += 8) { |
263 | 9.89M | energy = 0.01f; |
264 | 89.0M | for (j = i; j < i + 8; j++) { |
265 | 79.1M | energy += signal[j] * signal[j]; |
266 | 79.1M | } |
267 | | |
268 | 9.89M | rm = (FLOAT32)sqrt(energy / max_energy); |
269 | 9.89M | if (rm > factor) { |
270 | 954k | factor = rm; |
271 | 954k | } |
272 | 89.0M | for (j = i; j < i + 8; j++) { |
273 | 79.1M | signal[j] *= factor; |
274 | 79.1M | } |
275 | 9.89M | gains[i / 8] = factor; |
276 | 9.89M | } |
277 | | |
278 | 781k | return; |
279 | 781k | } |
280 | | |
281 | | VOID iusace_tcx_fac_encode(ia_usac_data_struct *usac_data, FLOAT32 *lpc_coeffs, |
282 | | FLOAT32 *lpc_coeffs_quant, FLOAT32 *speech, WORD32 frame_len, |
283 | | WORD32 num_bits_per_supfrm, ia_usac_lpd_state_struct *lpd_state, |
284 | 781k | WORD32 *params, WORD32 *n_param, WORD32 ch_idx, WORD32 k_idx) { |
285 | 781k | ia_usac_td_encoder_struct *st = usac_data->td_encoder[ch_idx]; |
286 | 781k | iusace_scratch_mem *pstr_scratch = &usac_data->str_scratch; |
287 | 781k | FLOAT32 *weighted_sig = &pstr_scratch->p_wsig_buf[k_idx * st->len_subfrm]; |
288 | 781k | FLOAT32 *wsynth = pstr_scratch->p_wsyn_tcx_buf; |
289 | 781k | FLOAT32 *synth = pstr_scratch->p_synth_tcx_buf; |
290 | 781k | WORD32 i, k, n, mode, i_subfr, lg, lext, index, target_bits; |
291 | 781k | FLOAT32 tmp, gain, fac_ns, energy, gain_tcx, nsfill_en_thres; |
292 | 781k | FLOAT32 *ptr_lp_flt_coeffs, lp_flt_coeffs[ORDER + 1]; |
293 | 781k | const FLOAT32 *sine_window_prev, *sine_window; |
294 | 781k | FLOAT32 mem_tcx_q; |
295 | 781k | FLOAT32 *xn; |
296 | 781k | FLOAT32 *xn1 = pstr_scratch->p_xn1_tcx; |
297 | 781k | FLOAT32 *xn_buf = pstr_scratch->p_xn_buf_tcx; |
298 | 781k | FLOAT32 *x = pstr_scratch->p_x_tcx; |
299 | 781k | FLOAT32 *x_tmp = pstr_scratch->p_x_tmp_tcx; |
300 | 781k | FLOAT32 *en = pstr_scratch->p_en_tcx; |
301 | 781k | FLOAT32 sq_gain; |
302 | 781k | FLOAT32 gain_prev, gain_next; |
303 | 781k | FLOAT32 *alfd_gains = pstr_scratch->p_alfd_gains_tcx; |
304 | 781k | FLOAT32 *sq_enc = pstr_scratch->p_sq_enc_tcx; |
305 | 781k | WORD32 *sq_quant = pstr_scratch->p_sq_quant_tcx; |
306 | 781k | FLOAT32 sq_err_energy; |
307 | 781k | WORD32 max_k; |
308 | 781k | FLOAT32 *gain1 = pstr_scratch->p_gain1_tcx; |
309 | 781k | FLOAT32 *gain2 = pstr_scratch->p_gain2_tcx; |
310 | 781k | FLOAT32 *facelp = pstr_scratch->p_facelp_tcx; |
311 | 781k | FLOAT32 *xn2 = pstr_scratch->p_xn2_tcx; |
312 | 781k | FLOAT32 *fac_window = pstr_scratch->p_fac_window_tcx; |
313 | 781k | FLOAT32 *x1 = pstr_scratch->p_x1_tcx; |
314 | 781k | FLOAT32 *x2 = pstr_scratch->p_x2_tcx; |
315 | 781k | WORD32 *y = pstr_scratch->p_y_tcx; |
316 | | |
317 | 781k | WORD32 TTT; |
318 | 781k | FLOAT32 corr = 0; |
319 | 781k | WORD32 len_subfrm = st->len_subfrm; |
320 | 781k | WORD32 fac_length = len_subfrm >> 1; |
321 | 781k | WORD32 fac_len_prev, fac_len; |
322 | | |
323 | 781k | if (frame_len == 4 * st->len_subfrm) { |
324 | 111k | if (st->last_was_short) { |
325 | 0 | fac_len_prev = (st->len_frame) / 16; |
326 | 111k | } else { |
327 | 111k | fac_len_prev = st->len_subfrm / 2; |
328 | 111k | } |
329 | 111k | if (st->next_is_short) { |
330 | 0 | fac_len = (st->len_frame) / 16; |
331 | 111k | } else { |
332 | 111k | fac_len = st->len_subfrm / 2; |
333 | 111k | } |
334 | 669k | } else if (frame_len == 2 * st->len_subfrm) { |
335 | 223k | if (k_idx == 0 && st->last_was_short) { |
336 | 0 | fac_len_prev = (st->len_frame) / 16; |
337 | 223k | } else { |
338 | 223k | fac_len_prev = st->len_subfrm / 2; |
339 | 223k | } |
340 | 223k | if (k_idx == 2 && st->next_is_short) { |
341 | 0 | fac_len = (st->len_frame) / 16; |
342 | 223k | } else { |
343 | 223k | fac_len = st->len_subfrm / 2; |
344 | 223k | } |
345 | 446k | } else { |
346 | 446k | if (k_idx == 0 && st->last_was_short) { |
347 | 0 | fac_len_prev = (st->len_frame) / 16; |
348 | 446k | } else { |
349 | 446k | fac_len_prev = st->len_subfrm / 2; |
350 | 446k | } |
351 | 446k | if (k_idx == 3 && st->next_is_short) { |
352 | 0 | fac_len = (st->len_frame) / 16; |
353 | 446k | } else { |
354 | 446k | fac_len = st->len_subfrm / 2; |
355 | 446k | } |
356 | 446k | } |
357 | | |
358 | 781k | memset(xn_buf, 0, (128 + frame_len + 128) * sizeof(FLOAT32)); |
359 | | |
360 | 781k | mode = frame_len / len_subfrm; |
361 | | |
362 | 781k | if (mode > 2) { |
363 | 111k | mode = 3; |
364 | 111k | } |
365 | | |
366 | 781k | if (lpd_state->mode == 0) { |
367 | 285k | params += fac_len_prev; |
368 | 285k | } |
369 | 781k | switch (fac_len_prev) { |
370 | 0 | case 64: |
371 | 0 | sine_window_prev = iusace_sin_window_128; |
372 | 0 | break; |
373 | 781k | default: |
374 | 781k | sine_window_prev = iusace_sin_window_256; |
375 | 781k | break; |
376 | 781k | } |
377 | 781k | switch (fac_len) { |
378 | 0 | case 64: |
379 | 0 | sine_window = iusace_sin_window_128; |
380 | 0 | break; |
381 | 781k | default: |
382 | 781k | sine_window = iusace_sin_window_256; |
383 | 781k | break; |
384 | 781k | } |
385 | | |
386 | 781k | lg = frame_len; |
387 | 781k | lext = fac_length; |
388 | 781k | xn = xn_buf + fac_length; |
389 | | |
390 | 781k | *n_param = lg; |
391 | | |
392 | 781k | target_bits = num_bits_per_supfrm - 10; |
393 | | |
394 | 93.0M | for (i = 0; i < fac_length; i++) { |
395 | 92.3M | xn_buf[i] = lpd_state->tcx_mem[i + 128 - fac_length]; |
396 | 92.3M | } |
397 | | |
398 | 781k | memcpy(xn, speech, (frame_len + fac_length) * sizeof(FLOAT32)); |
399 | | |
400 | 781k | tmp = xn[-1]; |
401 | | |
402 | 781k | iusace_apply_deemph(xn, TILT_FAC, frame_len, &tmp); |
403 | | |
404 | 781k | memcpy(lpd_state->tcx_mem, &xn[frame_len - 128], 128 * sizeof(FLOAT32)); |
405 | | |
406 | 781k | memcpy(&xn[frame_len], &speech[frame_len], lext * sizeof(FLOAT32)); |
407 | 781k | iusace_apply_deemph(&xn[frame_len], TILT_FAC, lext, &tmp); |
408 | | |
409 | 105M | for (i = 0; i < ORDER + fac_len_prev; i++) { |
410 | 104M | xn1[i] = xn_buf[fac_length - ORDER + i]; |
411 | 104M | } |
412 | 105M | for (i = 0; i < ORDER + fac_len; i++) { |
413 | 104M | xn2[i] = xn_buf[frame_len - ORDER + i]; |
414 | 104M | } |
415 | | |
416 | 781k | if (lpd_state->mode >= -1) { |
417 | 781k | for (i = 0; i < fac_length - fac_len_prev; i++) { |
418 | 0 | xn_buf[i] = 0.0f; |
419 | 0 | } |
420 | 185M | for (i = fac_length - fac_len_prev; i < (fac_length + fac_len_prev); i++) { |
421 | 184M | xn_buf[i] *= sine_window_prev[i - fac_length + fac_len_prev]; |
422 | 184M | } |
423 | 185M | for (i = 0; i < (2 * fac_len); i++) { |
424 | 184M | xn_buf[frame_len + fac_length - fac_len + i] *= sine_window[(2 * fac_len) - 1 - i]; |
425 | 184M | } |
426 | 781k | for (i = 0; i < fac_length - fac_len; i++) { |
427 | 0 | xn_buf[frame_len + fac_length + fac_len + i] = 0.0f; |
428 | 0 | } |
429 | 781k | } |
430 | | |
431 | 781k | iusace_tcx_mdct_main(xn_buf, x, (2 * fac_length), frame_len - (2 * fac_length), |
432 | 781k | (2 * fac_length), pstr_scratch); |
433 | | |
434 | 781k | iusace_get_weighted_lpc(lpc_coeffs_quant + (ORDER + 1), lp_flt_coeffs); |
435 | 781k | iusace_lpc_mdct(lp_flt_coeffs, gain1, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME) << 1, |
436 | 781k | pstr_scratch); |
437 | | |
438 | 781k | iusace_get_weighted_lpc(lpc_coeffs_quant + (2 * (ORDER + 1)), lp_flt_coeffs); |
439 | 781k | iusace_lpc_mdct(lp_flt_coeffs, gain2, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME) << 1, |
440 | 781k | pstr_scratch); |
441 | | |
442 | 781k | iusace_pre_shaping(x, lg, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME), gain1, gain2); |
443 | | |
444 | 317M | for (i = 0; i < lg; i++) { |
445 | 316M | x_tmp[i] = x[i]; |
446 | 316M | } |
447 | | |
448 | 781k | iusace_adapt_lo_freq_emph(x, lg); |
449 | | |
450 | 781k | sq_gain = iusace_calc_sq_gain(x, target_bits, lg, pstr_scratch->p_sq_gain_en); |
451 | | |
452 | 317M | for (i = 0; i < lg; i++) { |
453 | 316M | sq_enc[i] = x[i] / sq_gain; |
454 | | |
455 | 316M | if (sq_enc[i] > 0.f) |
456 | 156M | sq_quant[i] = ((WORD32)(0.5f + sq_enc[i])); |
457 | 159M | else |
458 | 159M | sq_quant[i] = ((WORD32)(-0.5f + sq_enc[i])); |
459 | 316M | } |
460 | | |
461 | 317M | for (i = 0; i < lg; i++) { |
462 | 316M | params[i + 2] = sq_quant[i]; |
463 | 316M | x[i] = (FLOAT32)sq_quant[i]; |
464 | 316M | } |
465 | | |
466 | 317M | for (i = 0; i < lg; i++) { |
467 | 316M | en[i] = x[i] * x[i]; |
468 | 316M | } |
469 | 781k | if (mode == 3) { |
470 | 111k | tmp = 0.9441f; |
471 | 669k | } else if (mode == 2) { |
472 | 223k | tmp = 0.8913f; |
473 | 446k | } else { |
474 | 446k | tmp = 0.7943f; |
475 | 446k | } |
476 | 781k | energy = 0.0f; |
477 | 317M | for (i = 0; i < lg; i++) { |
478 | 316M | if (en[i] > energy) { |
479 | 39.3M | energy = en[i]; |
480 | 39.3M | } |
481 | 316M | en[i] = energy; |
482 | 316M | energy *= tmp; |
483 | 316M | } |
484 | 781k | energy = 0.0f; |
485 | 317M | for (i = lg - 1; i >= 0; i--) { |
486 | 316M | if (en[i] > energy) { |
487 | 202M | energy = en[i]; |
488 | 202M | } |
489 | 316M | en[i] = energy; |
490 | 316M | energy *= tmp; |
491 | 316M | } |
492 | | |
493 | 781k | nsfill_en_thres = 0.707f; |
494 | | |
495 | 781k | tmp = 0.0625f; |
496 | 781k | k = 1; |
497 | 317M | for (i = 0; i < lg; i++) { |
498 | 316M | if (en[i] <= nsfill_en_thres) { |
499 | 175M | tmp += sq_enc[i] * sq_enc[i]; |
500 | 175M | k++; |
501 | 175M | } |
502 | 316M | } |
503 | | |
504 | 781k | iusace_adapt_lo_freq_deemph(x, lg, alfd_gains); |
505 | | |
506 | 781k | energy = 1e-6f; |
507 | 317M | for (i = 0; i < lg; i++) { |
508 | 316M | corr += x_tmp[i] * x[i]; |
509 | 316M | energy += x[i] * x[i]; |
510 | 316M | } |
511 | 781k | gain_tcx = (corr / energy); |
512 | | |
513 | 781k | if (gain_tcx == 0.0f) { |
514 | 25.1k | gain_tcx = sq_gain; |
515 | 25.1k | } |
516 | | |
517 | 781k | energy = 0.0001f; |
518 | 317M | for (i = 0; i < lg; i++) { |
519 | 316M | tmp = x_tmp[i] - gain_tcx * x[i]; |
520 | 316M | energy += tmp * tmp; |
521 | 316M | } |
522 | | |
523 | 781k | tmp = (FLOAT32)sqrt((energy * (2.0f / (FLOAT32)lg)) / (FLOAT32)lg); |
524 | | |
525 | 317M | for (i = 0; i < frame_len; i++) { |
526 | 316M | wsynth[i] = weighted_sig[i] + tmp; |
527 | 316M | } |
528 | | |
529 | 781k | energy = 0.01f; |
530 | 317M | for (i = 0; i < lg; i++) { |
531 | 316M | energy += x[i] * x[i]; |
532 | 316M | } |
533 | | |
534 | 781k | tmp = (FLOAT32)(2.0f * sqrt(energy) / (FLOAT32)lg); |
535 | 781k | gain = gain_tcx * tmp; |
536 | | |
537 | 781k | index = (WORD32)floor(0.5f + (28.0f * (FLOAT32)log10(gain))); |
538 | 781k | if (index < 0) { |
539 | 214k | index = 0; |
540 | 214k | } |
541 | 781k | if (index > 127) { |
542 | 14.4k | index = 127; |
543 | 14.4k | } |
544 | 781k | params[1] = index; |
545 | | |
546 | 781k | gain_tcx = (FLOAT32)pow(10.0f, ((FLOAT32)index) / 28.0f) / tmp; |
547 | 781k | st->gain_tcx = gain_tcx; |
548 | | |
549 | 781k | sq_err_energy = 0.f; |
550 | 781k | n = 0; |
551 | 20.5M | for (k = lg / 2; k < lg;) { |
552 | 19.7M | tmp = 0.f; |
553 | | |
554 | 19.7M | max_k = MIN(lg, k + 8); |
555 | 178M | for (i = k; i < max_k; i++) { |
556 | 158M | tmp += (FLOAT32)sq_quant[i] * sq_quant[i]; |
557 | 158M | } |
558 | 19.7M | if (tmp == 0.f) { |
559 | 13.6M | tmp = 0.f; |
560 | 123M | for (i = k; i < max_k; i++) { |
561 | 109M | tmp += sq_enc[i] * sq_enc[i]; |
562 | 109M | } |
563 | | |
564 | 13.6M | sq_err_energy += (FLOAT32)log10((tmp / (FLOAT64)8) + 0.000000001); |
565 | 13.6M | n += 1; |
566 | 13.6M | } |
567 | 19.7M | k = max_k; |
568 | 19.7M | } |
569 | 781k | if (n > 0) { |
570 | 764k | fac_ns = (FLOAT32)pow(10., sq_err_energy / (FLOAT64)(2 * n)); |
571 | 764k | } else { |
572 | 16.3k | fac_ns = 0.f; |
573 | 16.3k | } |
574 | | |
575 | 781k | tmp = 8.0f - (16.0f * fac_ns); |
576 | | |
577 | 781k | index = (WORD32)floor(tmp + 0.5); |
578 | 781k | if (index < 0) { |
579 | 0 | index = 0; |
580 | 0 | } |
581 | 781k | if (index > 7) { |
582 | 157k | index = 7; |
583 | 157k | } |
584 | | |
585 | 781k | params[0] = index; |
586 | | |
587 | 781k | iusace_noise_shaping(x, lg, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME), gain1, gain2); |
588 | | |
589 | 781k | iusace_tcx_imdct(x, xn_buf, (2 * fac_length), frame_len - (2 * fac_length), (2 * fac_length), |
590 | 781k | pstr_scratch); |
591 | 501M | for (i = 0; i < frame_len + (2 * fac_length); i++) { |
592 | 501M | xn_buf[i] = xn_buf[i] * (2.0f / lg); |
593 | 501M | } |
594 | | |
595 | 93.0M | for (i = 0; i < fac_len_prev; i++) { |
596 | 92.3M | fac_window[i] = sine_window_prev[i] * sine_window_prev[(2 * fac_len_prev) - 1 - i]; |
597 | 92.3M | fac_window[fac_len_prev + i] = |
598 | 92.3M | 1.0f - (sine_window_prev[fac_len_prev + i] * sine_window_prev[fac_len_prev + i]); |
599 | 92.3M | } |
600 | | |
601 | 93.0M | for (i = 0; i < fac_len_prev; i++) { |
602 | 92.3M | xn1[ORDER + i] -= sq_gain * xn_buf[fac_length + i] * sine_window_prev[fac_len_prev + i]; |
603 | 92.3M | } |
604 | 93.0M | for (i = 0; i < fac_len; i++) { |
605 | 92.3M | xn2[ORDER + i] -= sq_gain * xn_buf[i + frame_len] * sine_window[(2 * fac_len) - 1 - i]; |
606 | 92.3M | } |
607 | | |
608 | 13.2M | for (i = 0; i < ORDER; i++) { |
609 | 12.4M | xn1[i] -= lpd_state->tcx_quant[1 + 128 - ORDER + i]; |
610 | 12.4M | xn2[i] -= sq_gain * xn_buf[frame_len - ORDER + i]; |
611 | 12.4M | } |
612 | | |
613 | 93.0M | for (i = 0; i < fac_len_prev; i++) { |
614 | 92.3M | facelp[i] = lpd_state->tcx_quant[1 + 128 + i] * fac_window[fac_len_prev + i] + |
615 | 92.3M | lpd_state->tcx_quant[1 + 128 - 1 - i] * fac_window[fac_len_prev - 1 - i]; |
616 | 92.3M | } |
617 | | |
618 | 781k | energy = 0.0f; |
619 | 93.0M | for (i = 0; i < fac_len_prev; i++) energy += xn1[ORDER + i] * xn1[ORDER + i]; |
620 | 781k | energy *= 2.0f; |
621 | 781k | tmp = 0.0f; |
622 | 93.0M | for (i = 0; i < fac_len_prev; i++) tmp += facelp[i] * facelp[i]; |
623 | 781k | if (tmp > energy) |
624 | 166k | gain = (FLOAT32)sqrt(energy / tmp); |
625 | 614k | else |
626 | 614k | gain = 1.0f; |
627 | | |
628 | 93.0M | for (i = 0; i < fac_len_prev; i++) { |
629 | 92.3M | xn1[ORDER + i] -= gain * facelp[i]; |
630 | 92.3M | } |
631 | | |
632 | 781k | iusace_get_weighted_lpc(lpc_coeffs_quant + (ORDER + 1), lp_flt_coeffs); |
633 | 781k | iusace_compute_lp_residual(lp_flt_coeffs, xn1 + ORDER, x1, fac_len_prev); |
634 | | |
635 | 781k | iusace_get_weighted_lpc(lpc_coeffs_quant + (2 * (ORDER + 1)), lp_flt_coeffs); |
636 | 781k | iusace_compute_lp_residual(lp_flt_coeffs, xn2 + ORDER, x2, fac_len); |
637 | | |
638 | 781k | iusace_tcx_mdct(x1, x1, fac_len_prev, pstr_scratch); |
639 | 781k | iusace_tcx_mdct(x2, x2, fac_len, pstr_scratch); |
640 | | |
641 | 781k | gain_prev = (FLOAT32)(sq_gain * 0.5f * sqrt(((FLOAT32)fac_len_prev) / (FLOAT32)frame_len)); |
642 | 781k | gain_next = (FLOAT32)(sq_gain * 0.5f * sqrt(((FLOAT32)fac_len) / (FLOAT32)frame_len)); |
643 | | |
644 | 93.0M | for (i = 0; i < fac_len_prev; i++) { |
645 | 92.3M | x1[i] /= gain_prev; |
646 | 92.3M | } |
647 | 93.0M | for (i = 0; i < fac_len; i++) { |
648 | 92.3M | x2[i] /= gain_next; |
649 | 92.3M | } |
650 | 23.8M | for (i = 0; i < fac_len_prev / 4; i++) { |
651 | 23.0M | k = i * lg / (8 * fac_len_prev); |
652 | 23.0M | x1[i] /= alfd_gains[k]; |
653 | 23.0M | } |
654 | 23.8M | for (i = 0; i < fac_len / 4; i++) { |
655 | 23.0M | k = i * lg / (8 * fac_len); |
656 | 23.0M | x2[i] /= alfd_gains[k]; |
657 | 23.0M | } |
658 | | |
659 | 12.3M | for (i = 0; i < fac_len; i += 8) { |
660 | 11.5M | iusace_find_nearest_neighbor(&x2[i], &y[i]); |
661 | 11.5M | } |
662 | 93.0M | for (i = 0; i < fac_len; i++) { |
663 | 92.3M | lpd_state->avq_params[i] = y[i]; |
664 | 92.3M | x2[i] = (FLOAT32)y[i]; |
665 | 92.3M | } |
666 | | |
667 | 12.3M | for (i = 0; i < fac_len_prev; i += 8) { |
668 | 11.5M | iusace_find_nearest_neighbor(&x1[i], &y[i]); |
669 | 11.5M | } |
670 | | |
671 | 93.0M | for (i = 0; i < fac_len_prev; i++) { |
672 | 92.3M | x1[i] = (FLOAT32)y[i]; |
673 | 92.3M | } |
674 | | |
675 | 781k | gain_prev = (FLOAT32)(gain_tcx * 0.5f * sqrt(((FLOAT32)fac_len_prev) / (FLOAT32)frame_len)); |
676 | 781k | gain_next = (FLOAT32)(gain_tcx * 0.5f * sqrt(((FLOAT32)fac_len) / (FLOAT32)frame_len)); |
677 | | |
678 | 93.0M | for (i = 0; i < fac_len_prev; i++) { |
679 | 92.3M | x1[i] *= gain_prev; |
680 | 92.3M | } |
681 | 93.0M | for (i = 0; i < fac_len; i++) { |
682 | 92.3M | x2[i] *= gain_next; |
683 | 92.3M | } |
684 | 23.8M | for (i = 0; i<fac_len_prev>> 2; i++) { |
685 | 23.0M | k = i * lg / (fac_len_prev << 3); |
686 | 23.0M | x1[i] *= alfd_gains[k]; |
687 | 23.0M | } |
688 | 23.8M | for (i = 0; i<fac_len>> 2; i++) { |
689 | 23.0M | k = i * lg / (fac_len << 3); |
690 | 23.0M | x2[i] *= alfd_gains[k]; |
691 | 23.0M | } |
692 | 781k | iusace_tcx_mdct(x1, xn1, fac_len_prev, pstr_scratch); |
693 | 781k | iusace_tcx_mdct(x2, xn2, fac_len, pstr_scratch); |
694 | | |
695 | 781k | FLOAT32 coeff1 = (2.0f / (FLOAT32)fac_len_prev), coeff2 = (2.0f / (FLOAT32)fac_len); |
696 | | |
697 | 93.0M | for (i = 0; i < fac_len_prev; i++) { |
698 | 92.3M | xn1[i] = xn1[i] * coeff1; |
699 | 92.3M | } |
700 | | |
701 | 93.0M | for (i = 0; i < fac_len; i++) { |
702 | 92.3M | xn2[i] = xn2[i] * coeff2; |
703 | 92.3M | } |
704 | | |
705 | 781k | memset(xn1 + fac_len_prev, 0, fac_len_prev * sizeof(FLOAT32)); |
706 | 781k | memset(xn2 + fac_len, 0, fac_len * sizeof(FLOAT32)); |
707 | | |
708 | 781k | iusace_get_weighted_lpc(lpc_coeffs_quant + (ORDER + 1), lp_flt_coeffs); |
709 | 781k | iusace_synthesis_tool_float(lp_flt_coeffs, xn1, xn1, 2 * fac_len_prev, xn1 + fac_len_prev, |
710 | 781k | pstr_scratch->p_buf_synthesis_tool); |
711 | | |
712 | 781k | iusace_get_weighted_lpc(lpc_coeffs_quant + (2 * (ORDER + 1)), lp_flt_coeffs); |
713 | 781k | iusace_synthesis_tool_float(lp_flt_coeffs, xn2, xn2, fac_len, xn2 + fac_len, |
714 | 781k | pstr_scratch->p_buf_synthesis_tool); |
715 | | |
716 | 93.0M | for (i = 0; i < fac_len_prev; i++) { |
717 | 92.3M | xn1[i] += facelp[i]; |
718 | 92.3M | } |
719 | | |
720 | 501M | for (i = 0; i < frame_len + (fac_length << 1); i++) { |
721 | 501M | xn_buf[i] *= gain_tcx; |
722 | 501M | } |
723 | | |
724 | 781k | if (lpd_state->mode >= -1) { |
725 | 185M | for (i = 0; i < (2 * fac_len_prev); i++) { |
726 | 184M | xn_buf[i + fac_length - fac_len_prev] *= sine_window_prev[i]; |
727 | 184M | } |
728 | 781k | for (i = 0; i < fac_length - fac_len_prev; i++) { |
729 | 0 | xn_buf[i] = 0.0f; |
730 | 0 | } |
731 | 781k | } |
732 | 185M | for (i = 0; i < (2 * fac_len); i++) { |
733 | 184M | xn_buf[i + frame_len + fac_length - fac_len] *= sine_window[(2 * fac_len) - 1 - i]; |
734 | 184M | } |
735 | 781k | for (i = 0; i < fac_length - fac_len; i++) { |
736 | 0 | xn_buf[i + frame_len + fac_length + fac_len] = 0.0f; |
737 | 0 | } |
738 | | |
739 | 781k | if (lpd_state->mode != 0) { |
740 | 118M | for (i = 0; i < (2 * fac_length); i++) { |
741 | 118M | xn_buf[i] += lpd_state->tcx_quant[1 + 128 - fac_length + i]; |
742 | 118M | } |
743 | | |
744 | 495k | mem_tcx_q = lpd_state->tcx_quant[128 - fac_length]; |
745 | 495k | } else { |
746 | 33.4M | for (i = 0; i < fac_len_prev; i++) { |
747 | 33.1M | params[i - fac_len_prev] = y[i]; |
748 | 33.1M | } |
749 | | |
750 | 66.6M | for (i = 0; i < (2 * fac_len_prev); i++) { |
751 | 66.3M | xn_buf[i + fac_length] += xn1[i]; |
752 | 66.3M | } |
753 | 285k | mem_tcx_q = lpd_state->tcx_quant[128]; |
754 | 285k | } |
755 | | |
756 | 781k | memcpy(lpd_state->tcx_quant, xn_buf + frame_len + fac_length - 128 - 1, |
757 | 781k | (1 + 256) * sizeof(FLOAT32)); |
758 | | |
759 | 93.0M | for (i = 0; i < fac_len; i++) { |
760 | 92.3M | xn_buf[i + frame_len + (fac_length - fac_len)] += xn2[i]; |
761 | 92.3M | } |
762 | | |
763 | 781k | if (lpd_state->mode > 0) { |
764 | 485k | iusace_apply_preemph(xn_buf, TILT_FAC, fac_length, &mem_tcx_q); |
765 | | |
766 | 485k | ptr_lp_flt_coeffs = lpd_state->lpc_coeffs_quant; |
767 | | |
768 | 485k | TTT = fac_length % LEN_SUBFR; |
769 | 485k | if (TTT != 0) { |
770 | 133k | memcpy(&(lpd_state->synth[ORDER + 128 - fac_length]), &xn_buf[0], TTT * sizeof(FLOAT32)); |
771 | 133k | iusace_compute_lp_residual(ptr_lp_flt_coeffs, &(lpd_state->synth[ORDER + 128 - fac_length]), |
772 | 133k | &(lpd_state->acelp_exc[(2 * len_subfrm) - fac_length]), TTT); |
773 | | |
774 | 133k | ptr_lp_flt_coeffs += (ORDER + 1); |
775 | 133k | } |
776 | | |
777 | 1.32M | for (i_subfr = TTT; i_subfr < fac_length; i_subfr += LEN_SUBFR) { |
778 | 838k | memcpy(&(lpd_state->synth[ORDER + 128 - fac_length + i_subfr]), &xn_buf[i_subfr], |
779 | 838k | LEN_SUBFR * sizeof(FLOAT32)); |
780 | 838k | iusace_compute_lp_residual( |
781 | 838k | ptr_lp_flt_coeffs, &(lpd_state->synth[ORDER + 128 - fac_length + i_subfr]), |
782 | 838k | &(lpd_state->acelp_exc[(2 * len_subfrm) - fac_length + i_subfr]), LEN_SUBFR); |
783 | 838k | ptr_lp_flt_coeffs += (ORDER + 1); |
784 | 838k | } |
785 | | |
786 | 485k | ptr_lp_flt_coeffs = lpd_state->lpc_coeffs; |
787 | 1.45M | for (i_subfr = 0; i_subfr < fac_length; i_subfr += LEN_SUBFR) { |
788 | 971k | iusace_get_weighted_lpc(ptr_lp_flt_coeffs, lp_flt_coeffs); |
789 | 971k | iusace_compute_lp_residual(lp_flt_coeffs, |
790 | 971k | &(lpd_state->synth[ORDER + 128 - fac_length + i_subfr]), |
791 | 971k | &(lpd_state->wsynth[1 + 128 - fac_length + i_subfr]), LEN_SUBFR); |
792 | 971k | ptr_lp_flt_coeffs += (ORDER + 1); |
793 | 971k | } |
794 | 485k | tmp = lpd_state->wsynth[0 + 128 - fac_length]; |
795 | 485k | iusace_apply_deemph(&(lpd_state->wsynth[1 + 128 - fac_length]), TILT_FAC, fac_length, &tmp); |
796 | 485k | } |
797 | | |
798 | 781k | k = ((frame_len / LEN_SUBFR) - 2) * (ORDER + 1); |
799 | 781k | memcpy(lpd_state->lpc_coeffs, lpc_coeffs + k, 2 * (ORDER + 1) * sizeof(FLOAT32)); |
800 | | |
801 | 781k | memcpy(lpd_state->lpc_coeffs_quant, lpc_coeffs_quant + (2 * (ORDER + 1)), |
802 | 781k | (ORDER + 1) * sizeof(FLOAT32)); |
803 | 781k | memcpy(lpd_state->lpc_coeffs_quant + (ORDER + 1), lpd_state->lpc_coeffs_quant, |
804 | 781k | (ORDER + 1) * sizeof(FLOAT32)); |
805 | | |
806 | 781k | memcpy(synth - 128, &(lpd_state->synth[ORDER]), 128 * sizeof(FLOAT32)); |
807 | 781k | lpd_state->tcx_fac = xn[frame_len - 1]; |
808 | | |
809 | 781k | iusace_apply_preemph(xn, TILT_FAC, frame_len, &mem_tcx_q); |
810 | 5.72M | for (i_subfr = 0; i_subfr < frame_len; i_subfr += LEN_SUBFR) { |
811 | 4.94M | memcpy(&synth[i_subfr], &xn[i_subfr], LEN_SUBFR * sizeof(FLOAT32)); |
812 | 4.94M | iusace_compute_lp_residual(lpc_coeffs_quant + (2 * (ORDER + 1)), &synth[i_subfr], |
813 | 4.94M | &xn[i_subfr], LEN_SUBFR); |
814 | 4.94M | } |
815 | 781k | memcpy(lpd_state->synth, synth + frame_len - (ORDER + 128), (ORDER + 128) * sizeof(FLOAT32)); |
816 | | |
817 | 781k | if (frame_len == len_subfrm) { |
818 | 446k | memcpy(x, lpd_state->acelp_exc + len_subfrm, len_subfrm * sizeof(FLOAT32)); |
819 | 446k | memcpy(lpd_state->acelp_exc, x, len_subfrm * sizeof(FLOAT32)); |
820 | 446k | memcpy(lpd_state->acelp_exc + len_subfrm, xn, len_subfrm * sizeof(FLOAT32)); |
821 | 446k | } else { |
822 | 334k | memcpy(lpd_state->acelp_exc, xn + frame_len - (2 * len_subfrm), |
823 | 334k | 2 * len_subfrm * sizeof(FLOAT32)); |
824 | 334k | } |
825 | | |
826 | 781k | memcpy(wsynth - 128, &(lpd_state->wsynth[1]), 128 * sizeof(FLOAT32)); |
827 | | |
828 | 781k | ptr_lp_flt_coeffs = lpc_coeffs; |
829 | 5.72M | for (i_subfr = 0; i_subfr < frame_len; i_subfr += LEN_SUBFR) { |
830 | 4.94M | iusace_get_weighted_lpc(ptr_lp_flt_coeffs, lp_flt_coeffs); |
831 | 4.94M | iusace_compute_lp_residual(lp_flt_coeffs, &synth[i_subfr], &wsynth[i_subfr], LEN_SUBFR); |
832 | 4.94M | ptr_lp_flt_coeffs += (ORDER + 1); |
833 | 4.94M | } |
834 | 781k | tmp = wsynth[-1]; |
835 | 781k | iusace_apply_deemph(wsynth, TILT_FAC, frame_len, &tmp); |
836 | | |
837 | 781k | memcpy(lpd_state->wsynth, wsynth + frame_len - (1 + 128), (1 + 128) * sizeof(FLOAT32)); |
838 | | |
839 | 781k | lpd_state->mode = mode; |
840 | | |
841 | 781k | lpd_state->num_bits = 10 + target_bits; |
842 | | |
843 | 781k | return; |
844 | 781k | } |