/src/libxaac/encoder/iusace_lpd_utils.c
Line | Count | Source (jump to first uncovered line) |
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_fd_qc_util.h" |
41 | | #include "iusace_tns_usac.h" |
42 | | #include "iusace_config.h" |
43 | | #include "iusace_arith_enc.h" |
44 | | #include "iusace_fd_quant.h" |
45 | | #include "iusace_block_switch_const.h" |
46 | | #include "iusace_block_switch_struct_def.h" |
47 | | #include "iusace_ms.h" |
48 | | #include "iusace_signal_classifier.h" |
49 | | #include "ixheaace_sbr_header.h" |
50 | | #include "ixheaace_config.h" |
51 | | #include "ixheaace_asc_write.h" |
52 | | #include "iusace_main.h" |
53 | | #include "iusace_func_prototypes.h" |
54 | | #include "iusace_lpd_rom.h" |
55 | | #include "ixheaace_common_utils.h" |
56 | | |
57 | 211k | WORD32 ia_get_sample_rate(WORD32 sample_rate) { |
58 | 211k | if (92017 <= sample_rate) { |
59 | 0 | return 11; |
60 | 0 | } |
61 | 211k | if (75132 <= sample_rate) { |
62 | 0 | return 10; |
63 | 0 | } |
64 | 211k | if (55426 <= sample_rate) { |
65 | 0 | return 9; |
66 | 0 | } |
67 | 211k | if (46009 <= sample_rate) { |
68 | 0 | return 8; |
69 | 0 | } |
70 | 211k | if (37566 <= sample_rate) { |
71 | 0 | return 7; |
72 | 0 | } |
73 | 211k | if (27713 <= sample_rate) { |
74 | 29.6k | return 6; |
75 | 29.6k | } |
76 | 181k | if (23004 <= sample_rate) { |
77 | 48.0k | return 5; |
78 | 48.0k | } |
79 | 133k | if (18783 <= sample_rate) { |
80 | 10.4k | return 4; |
81 | 10.4k | } |
82 | 123k | if (13856 <= sample_rate) { |
83 | 38.3k | return 3; |
84 | 38.3k | } |
85 | 84.8k | if (11502 <= sample_rate) { |
86 | 28.9k | return 2; |
87 | 28.9k | } |
88 | 55.9k | if (9391 <= sample_rate) { |
89 | 5.35k | return 1; |
90 | 5.35k | } |
91 | 50.6k | return 0; |
92 | 55.9k | } |
93 | | |
94 | 2.64M | VOID iusace_write_bits2buf(WORD32 value, WORD32 no_of_bits, WORD16 *bitstream) { |
95 | 2.64M | WORD16 *pt_bitstream; |
96 | 2.64M | WORD32 i; |
97 | 2.64M | pt_bitstream = bitstream + no_of_bits; |
98 | 16.4M | for (i = 0; i < no_of_bits; i++) { |
99 | 13.7M | *--pt_bitstream = (WORD16)(value & MASK); |
100 | 13.7M | value >>= 1; |
101 | 13.7M | } |
102 | 2.64M | return; |
103 | 2.64M | } |
104 | | |
105 | 1.29M | WORD32 iusace_get_num_params(WORD32 *qn) { |
106 | 1.29M | return 2 + ((qn[0] > 0) ? 9 : 0) + ((qn[1] > 0) ? 9 : 0); |
107 | 1.29M | } |
108 | | |
109 | 1.84M | FLOAT32 iusace_cal_segsnr(FLOAT32 *sig1, FLOAT32 *sig2, WORD16 len, WORD16 nseg) { |
110 | 1.84M | FLOAT32 snr = 0.0f; |
111 | 1.84M | FLOAT32 signal, noise, error, fac; |
112 | 1.84M | WORD16 i, j; |
113 | 12.6M | for (i = 0; i < len; i += nseg) { |
114 | 10.7M | signal = 1e-6f; |
115 | 10.7M | noise = 1e-6f; |
116 | 698M | for (j = 0; j < nseg; j++) { |
117 | 688M | signal += (*sig1) * (*sig1); |
118 | 688M | error = *sig1++ - *sig2++; |
119 | 688M | noise += error * error; |
120 | 688M | } |
121 | 10.7M | snr += (FLOAT32)log10((FLOAT64)(signal / noise)); |
122 | 10.7M | } |
123 | 1.84M | fac = ((FLOAT32)(10 * nseg)) / (FLOAT32)len; |
124 | 1.84M | snr = fac * snr; |
125 | 1.84M | if (snr < -99.0f) { |
126 | 36.9k | snr = -99.0f; |
127 | 36.9k | } |
128 | 1.84M | return (snr); |
129 | 1.84M | } |
130 | | |
131 | 211k | VOID iusace_highpass_50hz_12k8(FLOAT32 *signal, WORD32 lg, FLOAT32 *mem, WORD32 fscale) { |
132 | 211k | WORD32 i; |
133 | 211k | WORD32 sr_idx = 0; |
134 | 211k | FLOAT32 x0, x1, x2, y0, y1, y2; |
135 | 211k | const FLOAT32 *a = NULL, *b = NULL; |
136 | | |
137 | 211k | y1 = mem[0]; |
138 | 211k | y2 = mem[1]; |
139 | 211k | x0 = mem[2]; |
140 | 211k | x1 = mem[3]; |
141 | 211k | sr_idx = ia_get_sample_rate(fscale); |
142 | 211k | a = &iusace_hp20_filter_coeffs[sr_idx][0]; |
143 | 211k | b = &iusace_hp20_filter_coeffs[sr_idx][2]; |
144 | | |
145 | 193M | for (i = 0; i < lg; i++) { |
146 | 193M | x2 = x1; |
147 | 193M | x1 = x0; |
148 | 193M | x0 = signal[i]; |
149 | 193M | y0 = (y1 * a[0]) + (y2 * a[1]) + (x0 * b[1]) + (x1 * b[0]) + (x2 * b[1]); |
150 | 193M | signal[i] = y0; |
151 | 193M | y2 = y1; |
152 | 193M | y1 = y0; |
153 | 193M | } |
154 | | |
155 | 211k | mem[0] = ((y1 > 1e-10) | (y1 < -1e-10)) ? y1 : 0; |
156 | 211k | mem[1] = ((y2 > 1e-10) | (y2 < -1e-10)) ? y2 : 0; |
157 | 211k | mem[2] = ((x0 > 1e-10) | (x0 < -1e-10)) ? x0 : 0; |
158 | 211k | mem[3] = ((x1 > 1e-10) | (x1 < -1e-10)) ? x1 : 0; |
159 | 211k | } |
160 | | |
161 | 11.0M | VOID iusace_apply_preemph(FLOAT32 *signal, FLOAT32 factor, WORD32 length, FLOAT32 *mem) { |
162 | 11.0M | WORD32 i; |
163 | 11.0M | FLOAT32 temp; |
164 | 11.0M | temp = signal[length - 1]; |
165 | 1.23G | for (i = length - 1; i > 0; i--) { |
166 | 1.22G | signal[i] = signal[i] - factor * signal[i - 1]; |
167 | 1.22G | } |
168 | 11.0M | signal[0] -= factor * (*mem); |
169 | 11.0M | *mem = temp; |
170 | 11.0M | } |
171 | | |
172 | 20.5M | VOID iusace_apply_deemph(FLOAT32 *signal, FLOAT32 factor, WORD32 length, FLOAT32 *mem) { |
173 | 20.5M | WORD32 i; |
174 | 20.5M | signal[0] = signal[0] + factor * (*mem); |
175 | 2.95G | for (i = 1; i < length; i++) { |
176 | 2.93G | signal[i] = signal[i] + factor * signal[i - 1]; |
177 | 2.93G | } |
178 | 20.5M | *mem = signal[length - 1]; |
179 | 20.5M | if ((*mem < 1e-10) & (*mem > -1e-10)) { |
180 | 300k | *mem = 0; |
181 | 300k | } |
182 | 20.5M | } |
183 | | |
184 | | VOID iusace_synthesis_tool_float(FLOAT32 *a, FLOAT32 *x, FLOAT32 *y, WORD32 l, FLOAT32 *mem, |
185 | 15.7M | FLOAT32 *scratch_synth_tool) { |
186 | 15.7M | FLOAT32 s; |
187 | 15.7M | FLOAT32 *yy; |
188 | 15.7M | WORD32 i, j; |
189 | 15.7M | memcpy(scratch_synth_tool, mem, ORDER * sizeof(FLOAT32)); |
190 | 15.7M | yy = &scratch_synth_tool[ORDER]; |
191 | 1.19G | for (i = 0; i < l; i++) { |
192 | 1.17G | s = x[i]; |
193 | 5.87G | for (j = 1; j <= ORDER; j += 4) { |
194 | 4.70G | s -= a[j] * yy[i - j]; |
195 | 4.70G | s -= a[j + 1] * yy[i - (j + 1)]; |
196 | 4.70G | s -= a[j + 2] * yy[i - (j + 2)]; |
197 | 4.70G | s -= a[j + 3] * yy[i - (j + 3)]; |
198 | 4.70G | } |
199 | 1.17G | yy[i] = s; |
200 | 1.17G | y[i] = s; |
201 | 1.17G | } |
202 | 15.7M | } |
203 | | |
204 | 46.5M | VOID iusace_compute_lp_residual(FLOAT32 *a, FLOAT32 *x, FLOAT32 *y, WORD32 l) { |
205 | 46.5M | FLOAT32 s; |
206 | 46.5M | WORD32 i; |
207 | 3.04G | for (i = 0; i < l; i++) { |
208 | 2.99G | s = x[i]; |
209 | 2.99G | s += a[1] * x[i - 1]; |
210 | 2.99G | s += a[2] * x[i - 2]; |
211 | 2.99G | s += a[3] * x[i - 3]; |
212 | 2.99G | s += a[4] * x[i - 4]; |
213 | 2.99G | s += a[5] * x[i - 5]; |
214 | 2.99G | s += a[6] * x[i - 6]; |
215 | 2.99G | s += a[7] * x[i - 7]; |
216 | 2.99G | s += a[8] * x[i - 8]; |
217 | 2.99G | s += a[9] * x[i - 9]; |
218 | 2.99G | s += a[10] * x[i - 10]; |
219 | 2.99G | s += a[11] * x[i - 11]; |
220 | 2.99G | s += a[12] * x[i - 12]; |
221 | 2.99G | s += a[13] * x[i - 13]; |
222 | 2.99G | s += a[14] * x[i - 14]; |
223 | 2.99G | s += a[15] * x[i - 15]; |
224 | 2.99G | s += a[16] * x[i - 16]; |
225 | 2.99G | y[i] = s; |
226 | 2.99G | } |
227 | 46.5M | } |
228 | | |
229 | 8.84M | VOID iusace_convolve(FLOAT32 *signal, FLOAT32 *wsynth_filter_ir, FLOAT32 *conv_out) { |
230 | 8.84M | FLOAT32 temp; |
231 | 8.84M | WORD32 i, n; |
232 | 291M | for (n = 0; n < LEN_SUBFR; n += 2) { |
233 | 282M | temp = 0.0f; |
234 | 9.33G | for (i = 0; i <= n; i++) { |
235 | 9.05G | temp += signal[i] * wsynth_filter_ir[n - i]; |
236 | 9.05G | } |
237 | 282M | conv_out[n] = temp; |
238 | 282M | temp = 0.0f; |
239 | 4.95G | for (i = 0; i <= (n + 1); i += 2) { |
240 | 4.66G | temp += signal[i] * wsynth_filter_ir[(n + 1) - i]; |
241 | 4.66G | temp += signal[i + 1] * wsynth_filter_ir[n - i]; |
242 | 4.66G | } |
243 | 282M | conv_out[n + 1] = temp; |
244 | 282M | } |
245 | 8.84M | } |
246 | | |
247 | | VOID iusace_autocorr_plus(FLOAT32 *speech, FLOAT32 *auto_corr_vector, WORD32 window_len, |
248 | 811k | const FLOAT32 *lp_analysis_win, FLOAT32 *temp_aut_corr) { |
249 | 811k | FLOAT32 val; |
250 | 811k | WORD16 i, j; |
251 | 362M | for (i = 0; i < window_len; i++) { |
252 | 361M | temp_aut_corr[i] = speech[i] * lp_analysis_win[i]; |
253 | 361M | } |
254 | 14.5M | for (i = 0; i <= ORDER; i++) { |
255 | 13.7M | val = 0.0f; |
256 | 6.05G | for (j = 0; j < window_len - i; j++) { |
257 | 6.04G | val += temp_aut_corr[j] * temp_aut_corr[j + i]; |
258 | 6.04G | } |
259 | 13.7M | auto_corr_vector[i] = val; |
260 | 13.7M | } |
261 | 811k | if (auto_corr_vector[0] < 1.0) { |
262 | 35.3k | auto_corr_vector[0] = 1.0; |
263 | 35.3k | } |
264 | 811k | } |
265 | | |
266 | | static VOID iusace_get_norm_correlation(FLOAT32 *exc, FLOAT32 *xn, FLOAT32 *wsyn_filt_ir, |
267 | | WORD32 min_interval, WORD32 max_interval, |
268 | 2.94M | FLOAT32 *norm_corr) { |
269 | 2.94M | WORD32 i, j, k; |
270 | 2.94M | FLOAT32 filt_prev_exc[LEN_SUBFR]; |
271 | 2.94M | FLOAT32 energy_filt_exc, corr, norm; |
272 | 2.94M | k = -min_interval; |
273 | | |
274 | 2.94M | iusace_convolve(&exc[k], wsyn_filt_ir, filt_prev_exc); |
275 | | |
276 | 68.4M | for (i = min_interval; i <= max_interval; i++) { |
277 | 65.4M | corr = 0.0F; |
278 | 65.4M | energy_filt_exc = 0.01F; |
279 | 4.25G | for (j = 0; j < LEN_SUBFR; j++) { |
280 | 4.18G | corr += xn[j] * filt_prev_exc[j]; |
281 | 4.18G | energy_filt_exc += filt_prev_exc[j] * filt_prev_exc[j]; |
282 | 4.18G | } |
283 | | |
284 | 65.4M | norm = (FLOAT32)(1.0f / sqrt(energy_filt_exc)); |
285 | 65.4M | norm_corr[i - min_interval] = corr * norm; |
286 | | |
287 | 65.4M | if (i != max_interval) { |
288 | 62.5M | k--; |
289 | 4.00G | for (j = LEN_SUBFR - 1; j > 0; j--) { |
290 | 3.93G | filt_prev_exc[j] = filt_prev_exc[j - 1] + exc[k] * wsyn_filt_ir[j]; |
291 | 3.93G | } |
292 | 62.5M | filt_prev_exc[0] = exc[k]; |
293 | 62.5M | } |
294 | 65.4M | } |
295 | 2.94M | } |
296 | | |
297 | 16.0M | static FLOAT32 iusace_corr_interpolate(FLOAT32 *x, WORD32 fraction) { |
298 | 16.0M | FLOAT32 interpol_value, *x1, *x2; |
299 | 16.0M | const FLOAT32 *p1_interp4_1_table, *p2_interp4_1_table; |
300 | 16.0M | if (fraction < 0) { |
301 | 6.13M | fraction += 4; |
302 | 6.13M | x--; |
303 | 6.13M | } |
304 | 16.0M | x1 = &x[0]; |
305 | 16.0M | x2 = &x[1]; |
306 | 16.0M | p1_interp4_1_table = &iusace_interp4_1[fraction]; |
307 | 16.0M | p2_interp4_1_table = &iusace_interp4_1[4 - fraction]; |
308 | 16.0M | interpol_value = x1[0] * p1_interp4_1_table[0] + x2[0] * p2_interp4_1_table[0]; |
309 | 16.0M | interpol_value += x1[-1] * p1_interp4_1_table[4] + x2[1] * p2_interp4_1_table[4]; |
310 | 16.0M | interpol_value += x1[-2] * p1_interp4_1_table[8] + x2[2] * p2_interp4_1_table[8]; |
311 | 16.0M | interpol_value += x1[-3] * p1_interp4_1_table[12] + x2[3] * p2_interp4_1_table[12]; |
312 | | |
313 | 16.0M | return interpol_value; |
314 | 16.0M | } |
315 | | |
316 | | VOID iusace_open_loop_search(FLOAT32 *wsp, WORD32 min_pitch_lag, WORD32 max_pitch_lag, |
317 | | WORD32 num_frame, WORD32 *ol_pitch_lag, |
318 | 1.33M | ia_usac_td_encoder_struct *st) { |
319 | 1.33M | WORD32 i, j, k; |
320 | 1.33M | FLOAT32 r, corr, energy1, energy2, corr_max = -1.0e23f; |
321 | 1.33M | const FLOAT32 *p1_ol_cw_table, *p2_ol_cw_table; |
322 | 1.33M | FLOAT32 *data_a, *data_b, *hp_wsp, *p, *p1; |
323 | | |
324 | 1.33M | p1_ol_cw_table = &iusace_ol_corr_weight[453]; |
325 | 1.33M | p2_ol_cw_table = &iusace_ol_corr_weight[259 + max_pitch_lag - st->prev_pitch_med]; |
326 | 1.33M | *ol_pitch_lag = 0; |
327 | 191M | for (i = max_pitch_lag; i > min_pitch_lag; i--) { |
328 | 189M | p = &wsp[0]; |
329 | 189M | p1 = &wsp[-i]; |
330 | 189M | corr = 0.0; |
331 | 6.89G | for (j = 0; j < num_frame; j += 2) { |
332 | 6.70G | corr += p[j] * p1[j]; |
333 | 6.70G | corr += p[j + 1] * p1[j + 1]; |
334 | 6.70G | } |
335 | 189M | corr *= *p1_ol_cw_table--; |
336 | 189M | if ((st->prev_pitch_med > 0) && (st->ol_wght_flg == 1)) { |
337 | 68.0M | corr *= *p2_ol_cw_table--; |
338 | 68.0M | } |
339 | 189M | if (corr >= corr_max) { |
340 | 76.7M | corr_max = corr; |
341 | 76.7M | *ol_pitch_lag = i; |
342 | 76.7M | } |
343 | 189M | } |
344 | 1.33M | data_a = st->hp_ol_ltp_mem; |
345 | 1.33M | data_b = st->hp_ol_ltp_mem + HP_ORDER; |
346 | 1.33M | hp_wsp = st->prev_hp_wsp + max_pitch_lag; |
347 | 95.6M | for (k = 0; k < num_frame; k++) { |
348 | 94.3M | data_b[0] = data_b[1]; |
349 | 94.3M | data_b[1] = data_b[2]; |
350 | 94.3M | data_b[2] = data_b[3]; |
351 | 94.3M | data_b[HP_ORDER] = wsp[k]; |
352 | 94.3M | r = data_b[0] * 0.83787057505665F; |
353 | 94.3M | r += data_b[1] * -2.50975570071058F; |
354 | 94.3M | r += data_b[2] * 2.50975570071058F; |
355 | 94.3M | r += data_b[3] * -0.83787057505665F; |
356 | 94.3M | r -= data_a[0] * -2.64436711600664F; |
357 | 94.3M | r -= data_a[1] * 2.35087386625360F; |
358 | 94.3M | r -= data_a[2] * -0.70001156927424F; |
359 | 94.3M | data_a[2] = data_a[1]; |
360 | 94.3M | data_a[1] = data_a[0]; |
361 | 94.3M | data_a[0] = r; |
362 | 94.3M | hp_wsp[k] = r; |
363 | 94.3M | } |
364 | 1.33M | p = &hp_wsp[0]; |
365 | 1.33M | p1 = &hp_wsp[-(*ol_pitch_lag)]; |
366 | 1.33M | corr = 0.0F; |
367 | 1.33M | energy1 = 0.0F; |
368 | 1.33M | energy2 = 0.0F; |
369 | 95.6M | for (j = 0; j < num_frame; j++) { |
370 | 94.3M | energy1 += p1[j] * p1[j]; |
371 | 94.3M | energy2 += p[j] * p[j]; |
372 | 94.3M | corr += p[j] * p1[j]; |
373 | 94.3M | } |
374 | 1.33M | st->ol_gain = (FLOAT32)(corr / (sqrt(energy1 * energy2) + 1e-5)); |
375 | 1.33M | memmove(st->prev_hp_wsp, &st->prev_hp_wsp[num_frame], max_pitch_lag * sizeof(FLOAT32)); |
376 | 1.33M | } |
377 | | |
378 | 236k | WORD32 iusace_get_ol_lag_median(WORD32 prev_ol_lag, WORD32 *prev_ol_lags) { |
379 | 236k | WORD32 sorted_ol_lags_out[NUM_OPEN_LOOP_LAGS + 1] = {0}; |
380 | 236k | WORD32 i, j, idx, val; |
381 | 236k | WORD32 num_lags = NUM_OPEN_LOOP_LAGS; |
382 | 1.18M | for (i = NUM_OPEN_LOOP_LAGS - 1; i > 0; i--) { |
383 | 944k | prev_ol_lags[i] = prev_ol_lags[i - 1]; |
384 | 944k | } |
385 | 236k | prev_ol_lags[0] = prev_ol_lag; |
386 | 1.41M | for (i = 0; i < NUM_OPEN_LOOP_LAGS; i++) { |
387 | 1.18M | sorted_ol_lags_out[i + 1] = prev_ol_lags[i]; |
388 | 1.18M | } |
389 | | |
390 | 236k | idx = (NUM_OPEN_LOOP_LAGS >> 1) + 1; |
391 | 1.41M | for (;;) { |
392 | 1.41M | if (idx > 1) { |
393 | 472k | val = sorted_ol_lags_out[--idx]; |
394 | 944k | } else { |
395 | 944k | val = sorted_ol_lags_out[num_lags]; |
396 | 944k | sorted_ol_lags_out[num_lags] = sorted_ol_lags_out[1]; |
397 | 944k | if (--num_lags == 1) { |
398 | 236k | sorted_ol_lags_out[1] = val; |
399 | 236k | break; |
400 | 236k | } |
401 | 944k | } |
402 | 1.18M | i = idx; |
403 | 1.18M | j = idx << 1; |
404 | 2.55M | while (j <= num_lags) { |
405 | 1.37M | if (j < num_lags && sorted_ol_lags_out[j] < sorted_ol_lags_out[j + 1]) { |
406 | 169k | ++j; |
407 | 169k | } |
408 | 1.37M | if (val < sorted_ol_lags_out[j]) { |
409 | 516k | sorted_ol_lags_out[i] = sorted_ol_lags_out[j]; |
410 | 516k | i = j; |
411 | 516k | j *= 2; |
412 | 859k | } else { |
413 | 859k | j = num_lags + 1; |
414 | 859k | } |
415 | 1.37M | } |
416 | 1.18M | sorted_ol_lags_out[i] = val; |
417 | 1.18M | } |
418 | | |
419 | 236k | return sorted_ol_lags_out[OPEN_LOOP_LAG_MEDIAN]; |
420 | 236k | } |
421 | | |
422 | | VOID iusace_closed_loop_search(FLOAT32 *exc, FLOAT32 *xn, FLOAT32 *wsyn_filt_ir, |
423 | | WORD32 search_range_min, WORD32 search_range_max, WORD32 *pit_frac, |
424 | | WORD32 is_first_subfrm, WORD32 min_pitch_lag_res1_2, |
425 | 2.94M | WORD32 min_pitch_lag_res_1, WORD32 *pitch_lag_out) { |
426 | 2.94M | WORD32 i, fraction, step; |
427 | 2.94M | FLOAT32 corr_vector[15 + 2 * LEN_INTERPOL1 + 1] = {0}; |
428 | 2.94M | FLOAT32 corr_max, temp; |
429 | 2.94M | FLOAT32 *p_norm_corr_vector; |
430 | 2.94M | WORD32 min_interval, max_interval; |
431 | 2.94M | min_interval = search_range_min - LEN_INTERPOL1; |
432 | 2.94M | max_interval = search_range_max + LEN_INTERPOL1; |
433 | 2.94M | p_norm_corr_vector = &corr_vector[0]; |
434 | 2.94M | iusace_get_norm_correlation(exc, xn, wsyn_filt_ir, min_interval, max_interval, |
435 | 2.94M | p_norm_corr_vector); |
436 | | |
437 | 2.94M | corr_max = p_norm_corr_vector[LEN_INTERPOL1]; |
438 | 2.94M | *pitch_lag_out = search_range_min; |
439 | 41.8M | for (i = search_range_min + 1; i <= search_range_max; i++) { |
440 | 38.9M | if (p_norm_corr_vector[i - search_range_min + LEN_INTERPOL1] > corr_max) { |
441 | 10.6M | corr_max = p_norm_corr_vector[i - search_range_min + LEN_INTERPOL1]; |
442 | 10.6M | *pitch_lag_out = i; |
443 | 10.6M | } |
444 | 38.9M | } |
445 | 2.94M | if ((is_first_subfrm == 0) && (*pitch_lag_out >= min_pitch_lag_res_1)) { |
446 | 354k | *pit_frac = 0; |
447 | 2.59M | } else { |
448 | 2.59M | step = 1; |
449 | 2.59M | fraction = -3; |
450 | 2.59M | if (((is_first_subfrm == 0) && (*pitch_lag_out >= min_pitch_lag_res1_2)) || |
451 | 2.59M | (min_pitch_lag_res1_2 == TMIN)) { |
452 | 204k | step = 2; |
453 | 204k | fraction = -2; |
454 | 204k | } |
455 | 2.59M | if (*pitch_lag_out == search_range_min) { |
456 | 431k | fraction = 0; |
457 | 431k | } |
458 | 2.59M | corr_max = iusace_corr_interpolate( |
459 | 2.59M | &p_norm_corr_vector[(*pitch_lag_out) - search_range_min + LEN_INTERPOL1], fraction); |
460 | 16.0M | for (i = (fraction + step); i <= 3; i += step) { |
461 | 13.5M | temp = iusace_corr_interpolate( |
462 | 13.5M | &p_norm_corr_vector[(*pitch_lag_out) - search_range_min + LEN_INTERPOL1], i); |
463 | 13.5M | if (temp > corr_max) { |
464 | 6.62M | corr_max = temp; |
465 | 6.62M | fraction = i; |
466 | 6.62M | } |
467 | 13.5M | } |
468 | 2.59M | if (fraction < 0) { |
469 | 588k | fraction += 4; |
470 | 588k | (*pitch_lag_out) -= 1; |
471 | 588k | } |
472 | 2.59M | *pit_frac = fraction; |
473 | 2.59M | } |
474 | 2.94M | } |
475 | | |
476 | | VOID iusace_decim2_fir_filter(FLOAT32 *signal, WORD32 length, FLOAT32 *mem, |
477 | 815k | FLOAT32 *scratch_fir_sig_buf) { |
478 | 815k | FLOAT32 *sig_buf = scratch_fir_sig_buf; |
479 | 815k | FLOAT32 temp; |
480 | 815k | WORD32 i, j; |
481 | 815k | memcpy(sig_buf, mem, DECIM2_FIR_FILT_MEM_SIZE * sizeof(FLOAT32)); |
482 | 815k | memcpy(sig_buf + DECIM2_FIR_FILT_MEM_SIZE, signal, length * sizeof(FLOAT32)); |
483 | 3.26M | for (i = 0; i < DECIM2_FIR_FILT_MEM_SIZE; i++) { |
484 | 2.44M | mem[i] = ((signal[length - DECIM2_FIR_FILT_MEM_SIZE + i] > 1e-10) || |
485 | 2.44M | (signal[length - DECIM2_FIR_FILT_MEM_SIZE + i] < -1e-10)) |
486 | 2.44M | ? signal[length - DECIM2_FIR_FILT_MEM_SIZE + i] |
487 | 2.44M | : 0; |
488 | 2.44M | } |
489 | 96.2M | for (i = 0, j = 0; i < length; i += 2, j++) { |
490 | 95.4M | temp = sig_buf[i] * 0.13F; |
491 | 95.4M | temp += sig_buf[i + 1] * 0.23F; |
492 | 95.4M | temp += sig_buf[i + 2] * 0.28F; |
493 | | #ifdef _WIN32 |
494 | | #pragma warning(suppress : 6385) |
495 | | #endif |
496 | 95.4M | temp += sig_buf[i + 3] * 0.23F; |
497 | 95.4M | temp += sig_buf[i + 4] * 0.13F; |
498 | 95.4M | signal[j] = temp; |
499 | 95.4M | } |
500 | 815k | } |
501 | | |
502 | | FLOAT32 iusace_calc_sq_gain(FLOAT32 *x, WORD32 num_bits, WORD32 length, |
503 | 1.18M | FLOAT32 *scratch_sq_gain_en) { |
504 | 1.18M | WORD32 i, j, k; |
505 | 1.18M | FLOAT32 gain, ener, temp, target, factor, offset; |
506 | 1.18M | FLOAT32 *en = scratch_sq_gain_en; |
507 | | |
508 | 118M | for (i = 0; i < length; i += 4) { |
509 | 117M | ener = 0.01f; |
510 | 588M | for (j = i; j < i + 4; j++) { |
511 | 470M | ener += x[j] * x[j]; |
512 | 470M | } |
513 | | |
514 | 117M | temp = (FLOAT32)log10(ener); |
515 | 117M | en[i / 4] = 9.0f + 10.0f * temp; |
516 | 117M | } |
517 | | |
518 | 1.18M | target = (6.0f / 4.0f) * (FLOAT32)(num_bits - (length / 16)); |
519 | | |
520 | 1.18M | factor = 128.0f; |
521 | 1.18M | offset = factor; |
522 | | |
523 | 13.0M | for (k = 0; k < 10; k++) { |
524 | 11.8M | factor *= 0.5f; |
525 | 11.8M | offset -= factor; |
526 | 11.8M | ener = 0.0f; |
527 | 1.18G | for (i = 0; i < length / 4; i++) { |
528 | 1.17G | temp = en[i] - offset; |
529 | | |
530 | 1.17G | if (temp > 3.0f) { |
531 | 517M | ener += temp; |
532 | 517M | } |
533 | 1.17G | } |
534 | 11.8M | if (ener > target) { |
535 | 4.16M | offset += factor; |
536 | 4.16M | } |
537 | 11.8M | } |
538 | | |
539 | 1.18M | gain = (FLOAT32)pow(10.0f, offset / 20.0f); |
540 | | |
541 | 1.18M | return (gain); |
542 | 1.18M | } |
543 | | |
544 | | VOID iusace_lpc_coef_gen(FLOAT32 *lsf_old, FLOAT32 *lsf_new, FLOAT32 *a, WORD32 nb_subfr, |
545 | 1.17M | WORD32 m) { |
546 | 1.17M | FLOAT32 lsf[ORDER] = {0}, *ptr_a; |
547 | 1.17M | FLOAT32 inc, fnew, fold; |
548 | 1.17M | WORD32 i = 0; |
549 | | |
550 | 1.17M | ptr_a = a; |
551 | | |
552 | 1.17M | inc = 1.0f / (FLOAT32)nb_subfr; |
553 | 1.17M | fnew = 0.5f - (0.5f * inc); |
554 | 1.17M | fold = 1.0f - fnew; |
555 | 19.9M | for (i = 0; i < m; i++) { |
556 | 18.8M | lsf[i] = (lsf_old[i] * fold) + (lsf_new[i] * fnew); |
557 | 18.8M | } |
558 | 1.17M | iusace_lsp_to_lp_conversion(lsf, ptr_a); |
559 | 1.17M | ptr_a += (m + 1); |
560 | 1.17M | iusace_lsp_to_lp_conversion(lsf_old, ptr_a); |
561 | 1.17M | ptr_a += (m + 1); |
562 | 1.17M | iusace_lsp_to_lp_conversion(lsf_new, ptr_a); |
563 | | |
564 | 1.17M | return; |
565 | 1.17M | } |
566 | | |
567 | | VOID iusace_interpolation_lsp_params(FLOAT32 *lsp_old, FLOAT32 *lsp_new, FLOAT32 *lp_flt_coff_a, |
568 | 1.61M | WORD32 nb_subfr) { |
569 | 1.61M | FLOAT32 lsp[ORDER]; |
570 | 1.61M | FLOAT32 factor; |
571 | 1.61M | WORD32 i, k; |
572 | 1.61M | FLOAT32 x_plus_y, x_minus_y; |
573 | | |
574 | 1.61M | factor = 1.0f / (FLOAT32)nb_subfr; |
575 | | |
576 | 1.61M | x_plus_y = 0.5f * factor; |
577 | | |
578 | 7.50M | for (k = 0; k < nb_subfr; k++) { |
579 | 5.89M | x_minus_y = 1.0f - x_plus_y; |
580 | 100M | for (i = 0; i < ORDER; i++) { |
581 | 94.3M | lsp[i] = (lsp_old[i] * x_minus_y) + (lsp_new[i] * x_plus_y); |
582 | 94.3M | } |
583 | 5.89M | x_plus_y += factor; |
584 | | |
585 | 5.89M | iusace_lsp_to_lp_conversion(lsp, lp_flt_coff_a); |
586 | | |
587 | 5.89M | lp_flt_coff_a += (ORDER + 1); |
588 | 5.89M | } |
589 | | |
590 | 1.61M | iusace_lsp_to_lp_conversion(lsp_new, lp_flt_coff_a); |
591 | | |
592 | 1.61M | return; |
593 | 1.61M | } |