/src/libxaac/encoder/iusace_lpd_utils.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_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 | 153k | WORD32 ia_get_sample_rate(WORD32 sample_rate) { |
58 | 153k | if (92017 <= sample_rate) { |
59 | 0 | return 11; |
60 | 0 | } |
61 | 153k | if (75132 <= sample_rate) { |
62 | 0 | return 10; |
63 | 0 | } |
64 | 153k | if (55426 <= sample_rate) { |
65 | 0 | return 9; |
66 | 0 | } |
67 | 153k | if (46009 <= sample_rate) { |
68 | 0 | return 8; |
69 | 0 | } |
70 | 153k | if (37566 <= sample_rate) { |
71 | 0 | return 7; |
72 | 0 | } |
73 | 153k | if (27713 <= sample_rate) { |
74 | 19.2k | return 6; |
75 | 19.2k | } |
76 | 134k | if (23004 <= sample_rate) { |
77 | 26.5k | return 5; |
78 | 26.5k | } |
79 | 108k | if (18783 <= sample_rate) { |
80 | 6.99k | return 4; |
81 | 6.99k | } |
82 | 101k | if (13856 <= sample_rate) { |
83 | 33.5k | return 3; |
84 | 33.5k | } |
85 | 67.5k | if (11502 <= sample_rate) { |
86 | 39.6k | return 2; |
87 | 39.6k | } |
88 | 27.9k | if (9391 <= sample_rate) { |
89 | 3.60k | return 1; |
90 | 3.60k | } |
91 | 24.2k | return 0; |
92 | 27.9k | } |
93 | | |
94 | 2.14M | VOID iusace_write_bits2buf(WORD32 value, WORD32 no_of_bits, WORD16 *bitstream) { |
95 | 2.14M | WORD16 *pt_bitstream; |
96 | 2.14M | WORD32 i; |
97 | 2.14M | pt_bitstream = bitstream + no_of_bits; |
98 | 13.7M | for (i = 0; i < no_of_bits; i++) { |
99 | 11.5M | *--pt_bitstream = (WORD16)(value & MASK); |
100 | 11.5M | value >>= 1; |
101 | 11.5M | } |
102 | 2.14M | return; |
103 | 2.14M | } |
104 | | |
105 | 934k | WORD32 iusace_get_num_params(WORD32 *qn) { |
106 | 934k | return 2 + ((qn[0] > 0) ? 9 : 0) + ((qn[1] > 0) ? 9 : 0); |
107 | 934k | } |
108 | | |
109 | 1.48M | FLOAT32 iusace_cal_segsnr(FLOAT32 *sig1, FLOAT32 *sig2, WORD16 len, WORD16 nseg) { |
110 | 1.48M | FLOAT32 snr = 0.0f; |
111 | 1.48M | FLOAT32 signal, noise, error, fac; |
112 | 1.48M | WORD16 i, j; |
113 | 9.40M | for (i = 0; i < len; i += nseg) { |
114 | 7.92M | signal = 1e-6f; |
115 | 7.92M | noise = 1e-6f; |
116 | 515M | for (j = 0; j < nseg; j++) { |
117 | 507M | signal += (*sig1) * (*sig1); |
118 | 507M | error = *sig1++ - *sig2++; |
119 | 507M | noise += error * error; |
120 | 507M | } |
121 | 7.92M | snr += (FLOAT32)log10((FLOAT64)(signal / noise)); |
122 | 7.92M | } |
123 | 1.48M | fac = ((FLOAT32)(10 * nseg)) / (FLOAT32)len; |
124 | 1.48M | snr = fac * snr; |
125 | 1.48M | if (snr < -99.0f) { |
126 | 2.02k | snr = -99.0f; |
127 | 2.02k | } |
128 | 1.48M | return (snr); |
129 | 1.48M | } |
130 | | |
131 | 153k | VOID iusace_highpass_50hz_12k8(FLOAT32 *signal, WORD32 lg, FLOAT32 *mem, WORD32 fscale) { |
132 | 153k | WORD32 i; |
133 | 153k | WORD32 sr_idx = 0; |
134 | 153k | FLOAT32 x0, x1, x2, y0, y1, y2; |
135 | 153k | const FLOAT32 *a = NULL, *b = NULL; |
136 | | |
137 | 153k | y1 = mem[0]; |
138 | 153k | y2 = mem[1]; |
139 | 153k | x0 = mem[2]; |
140 | 153k | x1 = mem[3]; |
141 | 153k | sr_idx = ia_get_sample_rate(fscale); |
142 | 153k | a = &iusace_hp20_filter_coeffs[sr_idx][0]; |
143 | 153k | b = &iusace_hp20_filter_coeffs[sr_idx][2]; |
144 | | |
145 | 141M | for (i = 0; i < lg; i++) { |
146 | 141M | x2 = x1; |
147 | 141M | x1 = x0; |
148 | 141M | x0 = signal[i]; |
149 | 141M | y0 = (y1 * a[0]) + (y2 * a[1]) + (x0 * b[1]) + (x1 * b[0]) + (x2 * b[1]); |
150 | 141M | signal[i] = y0; |
151 | 141M | y2 = y1; |
152 | 141M | y1 = y0; |
153 | 141M | } |
154 | | |
155 | 153k | mem[0] = ((y1 > 1e-10) | (y1 < -1e-10)) ? y1 : 0; |
156 | 153k | mem[1] = ((y2 > 1e-10) | (y2 < -1e-10)) ? y2 : 0; |
157 | 153k | mem[2] = ((x0 > 1e-10) | (x0 < -1e-10)) ? x0 : 0; |
158 | 153k | mem[3] = ((x1 > 1e-10) | (x1 < -1e-10)) ? x1 : 0; |
159 | 153k | } |
160 | | |
161 | 8.14M | VOID iusace_apply_preemph(FLOAT32 *signal, FLOAT32 factor, WORD32 length, FLOAT32 *mem) { |
162 | 8.14M | WORD32 i; |
163 | 8.14M | FLOAT32 temp; |
164 | 8.14M | temp = signal[length - 1]; |
165 | 938M | for (i = length - 1; i > 0; i--) { |
166 | 930M | signal[i] = signal[i] - factor * signal[i - 1]; |
167 | 930M | } |
168 | 8.14M | signal[0] -= factor * (*mem); |
169 | 8.14M | *mem = temp; |
170 | 8.14M | } |
171 | | |
172 | 15.3M | VOID iusace_apply_deemph(FLOAT32 *signal, FLOAT32 factor, WORD32 length, FLOAT32 *mem) { |
173 | 15.3M | WORD32 i; |
174 | 15.3M | signal[0] = signal[0] + factor * (*mem); |
175 | 2.22G | for (i = 1; i < length; i++) { |
176 | 2.21G | signal[i] = signal[i] + factor * signal[i - 1]; |
177 | 2.21G | } |
178 | 15.3M | *mem = signal[length - 1]; |
179 | 15.3M | if ((*mem < 1e-10) & (*mem > -1e-10)) { |
180 | 243k | *mem = 0; |
181 | 243k | } |
182 | 15.3M | } |
183 | | |
184 | | VOID iusace_synthesis_tool_float(FLOAT32 *a, FLOAT32 *x, FLOAT32 *y, WORD32 l, FLOAT32 *mem, |
185 | 11.6M | FLOAT32 *scratch_synth_tool) { |
186 | 11.6M | FLOAT32 s; |
187 | 11.6M | FLOAT32 *yy; |
188 | 11.6M | WORD32 i, j; |
189 | 11.6M | memcpy(scratch_synth_tool, mem, ORDER * sizeof(FLOAT32)); |
190 | 11.6M | yy = &scratch_synth_tool[ORDER]; |
191 | 901M | for (i = 0; i < l; i++) { |
192 | 889M | s = x[i]; |
193 | 4.44G | for (j = 1; j <= ORDER; j += 4) { |
194 | 3.55G | s -= a[j] * yy[i - j]; |
195 | 3.55G | s -= a[j + 1] * yy[i - (j + 1)]; |
196 | 3.55G | s -= a[j + 2] * yy[i - (j + 2)]; |
197 | 3.55G | s -= a[j + 3] * yy[i - (j + 3)]; |
198 | 3.55G | } |
199 | 889M | yy[i] = s; |
200 | 889M | y[i] = s; |
201 | 889M | } |
202 | 11.6M | } |
203 | | |
204 | 35.0M | VOID iusace_compute_lp_residual(FLOAT32 *a, FLOAT32 *x, FLOAT32 *y, WORD32 l) { |
205 | 35.0M | FLOAT32 s; |
206 | 35.0M | WORD32 i; |
207 | 2.30G | for (i = 0; i < l; i++) { |
208 | 2.27G | s = x[i]; |
209 | 2.27G | s += a[1] * x[i - 1]; |
210 | 2.27G | s += a[2] * x[i - 2]; |
211 | 2.27G | s += a[3] * x[i - 3]; |
212 | 2.27G | s += a[4] * x[i - 4]; |
213 | 2.27G | s += a[5] * x[i - 5]; |
214 | 2.27G | s += a[6] * x[i - 6]; |
215 | 2.27G | s += a[7] * x[i - 7]; |
216 | 2.27G | s += a[8] * x[i - 8]; |
217 | 2.27G | s += a[9] * x[i - 9]; |
218 | 2.27G | s += a[10] * x[i - 10]; |
219 | 2.27G | s += a[11] * x[i - 11]; |
220 | 2.27G | s += a[12] * x[i - 12]; |
221 | 2.27G | s += a[13] * x[i - 13]; |
222 | 2.27G | s += a[14] * x[i - 14]; |
223 | 2.27G | s += a[15] * x[i - 15]; |
224 | 2.27G | s += a[16] * x[i - 16]; |
225 | 2.27G | y[i] = s; |
226 | 2.27G | } |
227 | 35.0M | } |
228 | | |
229 | 6.44M | VOID iusace_convolve(FLOAT32 *signal, FLOAT32 *wsynth_filter_ir, FLOAT32 *conv_out) { |
230 | 6.44M | FLOAT32 temp; |
231 | 6.44M | WORD32 i, n; |
232 | 212M | for (n = 0; n < LEN_SUBFR; n += 2) { |
233 | 206M | temp = 0.0f; |
234 | 6.81G | for (i = 0; i <= n; i++) { |
235 | 6.60G | temp += signal[i] * wsynth_filter_ir[n - i]; |
236 | 6.60G | } |
237 | 206M | conv_out[n] = temp; |
238 | 206M | temp = 0.0f; |
239 | 3.61G | for (i = 0; i <= (n + 1); i += 2) { |
240 | 3.40G | temp += signal[i] * wsynth_filter_ir[(n + 1) - i]; |
241 | 3.40G | temp += signal[i + 1] * wsynth_filter_ir[n - i]; |
242 | 3.40G | } |
243 | 206M | conv_out[n + 1] = temp; |
244 | 206M | } |
245 | 6.44M | } |
246 | | |
247 | | VOID iusace_autocorr_plus(FLOAT32 *speech, FLOAT32 *auto_corr_vector, WORD32 window_len, |
248 | 586k | const FLOAT32 *lp_analysis_win, FLOAT32 *temp_aut_corr) { |
249 | 586k | FLOAT32 val; |
250 | 586k | WORD16 i, j; |
251 | 263M | for (i = 0; i < window_len; i++) { |
252 | 263M | temp_aut_corr[i] = speech[i] * lp_analysis_win[i]; |
253 | 263M | } |
254 | 10.5M | for (i = 0; i <= ORDER; i++) { |
255 | 9.97M | val = 0.0f; |
256 | 4.40G | for (j = 0; j < window_len - i; j++) { |
257 | 4.39G | val += temp_aut_corr[j] * temp_aut_corr[j + i]; |
258 | 4.39G | } |
259 | 9.97M | auto_corr_vector[i] = val; |
260 | 9.97M | } |
261 | 586k | if (auto_corr_vector[0] < 1.0) { |
262 | 38.0k | auto_corr_vector[0] = 1.0; |
263 | 38.0k | } |
264 | 586k | } |
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.14M | FLOAT32 *norm_corr) { |
269 | 2.14M | WORD32 i, j, k; |
270 | 2.14M | FLOAT32 filt_prev_exc[LEN_SUBFR]; |
271 | 2.14M | FLOAT32 energy_filt_exc, corr, norm; |
272 | 2.14M | k = -min_interval; |
273 | | |
274 | 2.14M | iusace_convolve(&exc[k], wsyn_filt_ir, filt_prev_exc); |
275 | | |
276 | 50.1M | for (i = min_interval; i <= max_interval; i++) { |
277 | 47.9M | corr = 0.0F; |
278 | 47.9M | energy_filt_exc = 0.01F; |
279 | 3.11G | for (j = 0; j < LEN_SUBFR; j++) { |
280 | 3.07G | corr += xn[j] * filt_prev_exc[j]; |
281 | 3.07G | energy_filt_exc += filt_prev_exc[j] * filt_prev_exc[j]; |
282 | 3.07G | } |
283 | | |
284 | 47.9M | norm = (FLOAT32)(1.0f / sqrt(energy_filt_exc)); |
285 | 47.9M | norm_corr[i - min_interval] = corr * norm; |
286 | | |
287 | 47.9M | if (i != max_interval) { |
288 | 45.8M | k--; |
289 | 2.93G | for (j = LEN_SUBFR - 1; j > 0; j--) { |
290 | 2.88G | filt_prev_exc[j] = filt_prev_exc[j - 1] + exc[k] * wsyn_filt_ir[j]; |
291 | 2.88G | } |
292 | 45.8M | filt_prev_exc[0] = exc[k]; |
293 | 45.8M | } |
294 | 47.9M | } |
295 | 2.14M | } |
296 | | |
297 | 11.7M | static FLOAT32 iusace_corr_interpolate(FLOAT32 *x, WORD32 fraction) { |
298 | 11.7M | FLOAT32 interpol_value, *x1, *x2; |
299 | 11.7M | const FLOAT32 *p1_interp4_1_table, *p2_interp4_1_table; |
300 | 11.7M | if (fraction < 0) { |
301 | 4.46M | fraction += 4; |
302 | 4.46M | x--; |
303 | 4.46M | } |
304 | 11.7M | x1 = &x[0]; |
305 | 11.7M | x2 = &x[1]; |
306 | 11.7M | p1_interp4_1_table = &iusace_interp4_1[fraction]; |
307 | 11.7M | p2_interp4_1_table = &iusace_interp4_1[4 - fraction]; |
308 | 11.7M | interpol_value = x1[0] * p1_interp4_1_table[0] + x2[0] * p2_interp4_1_table[0]; |
309 | 11.7M | interpol_value += x1[-1] * p1_interp4_1_table[4] + x2[1] * p2_interp4_1_table[4]; |
310 | 11.7M | interpol_value += x1[-2] * p1_interp4_1_table[8] + x2[2] * p2_interp4_1_table[8]; |
311 | 11.7M | interpol_value += x1[-3] * p1_interp4_1_table[12] + x2[3] * p2_interp4_1_table[12]; |
312 | | |
313 | 11.7M | return interpol_value; |
314 | 11.7M | } |
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 | 985k | ia_usac_td_encoder_struct *st) { |
319 | 985k | WORD32 i, j, k; |
320 | 985k | FLOAT32 r, corr, energy1, energy2, corr_max = -1.0e23f; |
321 | 985k | const FLOAT32 *p1_ol_cw_table, *p2_ol_cw_table; |
322 | 985k | FLOAT32 *data_a, *data_b, *hp_wsp, *p, *p1; |
323 | | |
324 | 985k | p1_ol_cw_table = &iusace_ol_corr_weight[453]; |
325 | 985k | p2_ol_cw_table = &iusace_ol_corr_weight[259 + max_pitch_lag - st->prev_pitch_med]; |
326 | 985k | *ol_pitch_lag = 0; |
327 | 135M | for (i = max_pitch_lag; i > min_pitch_lag; i--) { |
328 | 134M | p = &wsp[0]; |
329 | 134M | p1 = &wsp[-i]; |
330 | 134M | corr = 0.0; |
331 | 4.86G | for (j = 0; j < num_frame; j += 2) { |
332 | 4.72G | corr += p[j] * p1[j]; |
333 | 4.72G | corr += p[j + 1] * p1[j + 1]; |
334 | 4.72G | } |
335 | 134M | corr *= *p1_ol_cw_table--; |
336 | 134M | if ((st->prev_pitch_med > 0) && (st->ol_wght_flg == 1)) { |
337 | 44.8M | corr *= *p2_ol_cw_table--; |
338 | 44.8M | } |
339 | 134M | if (corr >= corr_max) { |
340 | 52.5M | corr_max = corr; |
341 | 52.5M | *ol_pitch_lag = i; |
342 | 52.5M | } |
343 | 134M | } |
344 | 985k | data_a = st->hp_ol_ltp_mem; |
345 | 985k | data_b = st->hp_ol_ltp_mem + HP_ORDER; |
346 | 985k | hp_wsp = st->prev_hp_wsp + max_pitch_lag; |
347 | 69.7M | for (k = 0; k < num_frame; k++) { |
348 | 68.7M | data_b[0] = data_b[1]; |
349 | 68.7M | data_b[1] = data_b[2]; |
350 | 68.7M | data_b[2] = data_b[3]; |
351 | 68.7M | data_b[HP_ORDER] = wsp[k]; |
352 | 68.7M | r = data_b[0] * 0.83787057505665F; |
353 | 68.7M | r += data_b[1] * -2.50975570071058F; |
354 | 68.7M | r += data_b[2] * 2.50975570071058F; |
355 | 68.7M | r += data_b[3] * -0.83787057505665F; |
356 | 68.7M | r -= data_a[0] * -2.64436711600664F; |
357 | 68.7M | r -= data_a[1] * 2.35087386625360F; |
358 | 68.7M | r -= data_a[2] * -0.70001156927424F; |
359 | 68.7M | data_a[2] = data_a[1]; |
360 | 68.7M | data_a[1] = data_a[0]; |
361 | 68.7M | data_a[0] = r; |
362 | 68.7M | hp_wsp[k] = r; |
363 | 68.7M | } |
364 | 985k | p = &hp_wsp[0]; |
365 | 985k | p1 = &hp_wsp[-(*ol_pitch_lag)]; |
366 | 985k | corr = 0.0F; |
367 | 985k | energy1 = 0.0F; |
368 | 985k | energy2 = 0.0F; |
369 | 69.7M | for (j = 0; j < num_frame; j++) { |
370 | 68.7M | energy1 += p1[j] * p1[j]; |
371 | 68.7M | energy2 += p[j] * p[j]; |
372 | 68.7M | corr += p[j] * p1[j]; |
373 | 68.7M | } |
374 | 985k | st->ol_gain = (FLOAT32)(corr / (sqrt(energy1 * energy2) + 1e-5)); |
375 | 985k | memmove(st->prev_hp_wsp, &st->prev_hp_wsp[num_frame], max_pitch_lag * sizeof(FLOAT32)); |
376 | 985k | } |
377 | | |
378 | 157k | WORD32 iusace_get_ol_lag_median(WORD32 prev_ol_lag, WORD32 *prev_ol_lags) { |
379 | 157k | WORD32 sorted_ol_lags_out[NUM_OPEN_LOOP_LAGS + 1] = {0}; |
380 | 157k | WORD32 i, j, idx, val; |
381 | 157k | WORD32 num_lags = NUM_OPEN_LOOP_LAGS; |
382 | 789k | for (i = NUM_OPEN_LOOP_LAGS - 1; i > 0; i--) { |
383 | 631k | prev_ol_lags[i] = prev_ol_lags[i - 1]; |
384 | 631k | } |
385 | 157k | prev_ol_lags[0] = prev_ol_lag; |
386 | 946k | for (i = 0; i < NUM_OPEN_LOOP_LAGS; i++) { |
387 | 789k | sorted_ol_lags_out[i + 1] = prev_ol_lags[i]; |
388 | 789k | } |
389 | | |
390 | 157k | idx = (NUM_OPEN_LOOP_LAGS >> 1) + 1; |
391 | 946k | for (;;) { |
392 | 946k | if (idx > 1) { |
393 | 315k | val = sorted_ol_lags_out[--idx]; |
394 | 631k | } else { |
395 | 631k | val = sorted_ol_lags_out[num_lags]; |
396 | 631k | sorted_ol_lags_out[num_lags] = sorted_ol_lags_out[1]; |
397 | 631k | if (--num_lags == 1) { |
398 | 157k | sorted_ol_lags_out[1] = val; |
399 | 157k | break; |
400 | 157k | } |
401 | 631k | } |
402 | 789k | i = idx; |
403 | 789k | j = idx << 1; |
404 | 1.71M | while (j <= num_lags) { |
405 | 925k | if (j < num_lags && sorted_ol_lags_out[j] < sorted_ol_lags_out[j + 1]) { |
406 | 120k | ++j; |
407 | 120k | } |
408 | 925k | if (val < sorted_ol_lags_out[j]) { |
409 | 367k | sorted_ol_lags_out[i] = sorted_ol_lags_out[j]; |
410 | 367k | i = j; |
411 | 367k | j *= 2; |
412 | 557k | } else { |
413 | 557k | j = num_lags + 1; |
414 | 557k | } |
415 | 925k | } |
416 | 789k | sorted_ol_lags_out[i] = val; |
417 | 789k | } |
418 | | |
419 | 157k | return sorted_ol_lags_out[OPEN_LOOP_LAG_MEDIAN]; |
420 | 157k | } |
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.14M | WORD32 min_pitch_lag_res_1, WORD32 *pitch_lag_out) { |
426 | 2.14M | WORD32 i, fraction, step; |
427 | 2.14M | FLOAT32 corr_vector[15 + 2 * LEN_INTERPOL1 + 1] = {0}; |
428 | 2.14M | FLOAT32 corr_max, temp; |
429 | 2.14M | FLOAT32 *p_norm_corr_vector; |
430 | 2.14M | WORD32 min_interval, max_interval; |
431 | 2.14M | min_interval = search_range_min - LEN_INTERPOL1; |
432 | 2.14M | max_interval = search_range_max + LEN_INTERPOL1; |
433 | 2.14M | p_norm_corr_vector = &corr_vector[0]; |
434 | 2.14M | iusace_get_norm_correlation(exc, xn, wsyn_filt_ir, min_interval, max_interval, |
435 | 2.14M | p_norm_corr_vector); |
436 | | |
437 | 2.14M | corr_max = p_norm_corr_vector[LEN_INTERPOL1]; |
438 | 2.14M | *pitch_lag_out = search_range_min; |
439 | 30.7M | for (i = search_range_min + 1; i <= search_range_max; i++) { |
440 | 28.6M | if (p_norm_corr_vector[i - search_range_min + LEN_INTERPOL1] > corr_max) { |
441 | 7.86M | corr_max = p_norm_corr_vector[i - search_range_min + LEN_INTERPOL1]; |
442 | 7.86M | *pitch_lag_out = i; |
443 | 7.86M | } |
444 | 28.6M | } |
445 | 2.14M | if ((is_first_subfrm == 0) && (*pitch_lag_out >= min_pitch_lag_res_1)) { |
446 | 256k | *pit_frac = 0; |
447 | 1.89M | } else { |
448 | 1.89M | step = 1; |
449 | 1.89M | fraction = -3; |
450 | 1.89M | if (((is_first_subfrm == 0) && (*pitch_lag_out >= min_pitch_lag_res1_2)) || |
451 | 1.74M | (min_pitch_lag_res1_2 == TMIN)) { |
452 | 153k | step = 2; |
453 | 153k | fraction = -2; |
454 | 153k | } |
455 | 1.89M | if (*pitch_lag_out == search_range_min) { |
456 | 317k | fraction = 0; |
457 | 317k | } |
458 | 1.89M | corr_max = iusace_corr_interpolate( |
459 | 1.89M | &p_norm_corr_vector[(*pitch_lag_out) - search_range_min + LEN_INTERPOL1], fraction); |
460 | 11.7M | for (i = (fraction + step); i <= 3; i += step) { |
461 | 9.83M | temp = iusace_corr_interpolate( |
462 | 9.83M | &p_norm_corr_vector[(*pitch_lag_out) - search_range_min + LEN_INTERPOL1], i); |
463 | 9.83M | if (temp > corr_max) { |
464 | 4.82M | corr_max = temp; |
465 | 4.82M | fraction = i; |
466 | 4.82M | } |
467 | 9.83M | } |
468 | 1.89M | if (fraction < 0) { |
469 | 443k | fraction += 4; |
470 | 443k | (*pitch_lag_out) -= 1; |
471 | 443k | } |
472 | 1.89M | *pit_frac = fraction; |
473 | 1.89M | } |
474 | 2.14M | } |
475 | | |
476 | | VOID iusace_decim2_fir_filter(FLOAT32 *signal, WORD32 length, FLOAT32 *mem, |
477 | 590k | FLOAT32 *scratch_fir_sig_buf) { |
478 | 590k | FLOAT32 *sig_buf = scratch_fir_sig_buf; |
479 | 590k | FLOAT32 temp; |
480 | 590k | WORD32 i, j; |
481 | 590k | memcpy(sig_buf, mem, DECIM2_FIR_FILT_MEM_SIZE * sizeof(FLOAT32)); |
482 | 590k | memcpy(sig_buf + DECIM2_FIR_FILT_MEM_SIZE, signal, length * sizeof(FLOAT32)); |
483 | 2.36M | for (i = 0; i < DECIM2_FIR_FILT_MEM_SIZE; i++) { |
484 | 1.77M | mem[i] = ((signal[length - DECIM2_FIR_FILT_MEM_SIZE + i] > 1e-10) || |
485 | 944k | (signal[length - DECIM2_FIR_FILT_MEM_SIZE + i] < -1e-10)) |
486 | 1.77M | ? signal[length - DECIM2_FIR_FILT_MEM_SIZE + i] |
487 | 1.77M | : 0; |
488 | 1.77M | } |
489 | 70.3M | for (i = 0, j = 0; i < length; i += 2, j++) { |
490 | 69.7M | temp = sig_buf[i] * 0.13F; |
491 | 69.7M | temp += sig_buf[i + 1] * 0.23F; |
492 | 69.7M | temp += sig_buf[i + 2] * 0.28F; |
493 | | #ifdef _WIN32 |
494 | | #pragma warning(suppress : 6385) |
495 | | #endif |
496 | 69.7M | temp += sig_buf[i + 3] * 0.23F; |
497 | 69.7M | temp += sig_buf[i + 4] * 0.13F; |
498 | 69.7M | signal[j] = temp; |
499 | 69.7M | } |
500 | 590k | } |
501 | | |
502 | | FLOAT32 iusace_calc_sq_gain(FLOAT32 *x, WORD32 num_bits, WORD32 length, |
503 | 949k | FLOAT32 *scratch_sq_gain_en) { |
504 | 949k | WORD32 i, j, k; |
505 | 949k | FLOAT32 gain, ener, temp, target, factor, offset; |
506 | 949k | FLOAT32 *en = scratch_sq_gain_en; |
507 | | |
508 | 96.2M | for (i = 0; i < length; i += 4) { |
509 | 95.2M | ener = 0.01f; |
510 | 476M | for (j = i; j < i + 4; j++) { |
511 | 381M | ener += x[j] * x[j]; |
512 | 381M | } |
513 | | |
514 | 95.2M | temp = (FLOAT32)log10(ener); |
515 | 95.2M | en[i / 4] = 9.0f + 10.0f * temp; |
516 | 95.2M | } |
517 | | |
518 | 949k | target = (6.0f / 4.0f) * (FLOAT32)(num_bits - (length / 16)); |
519 | | |
520 | 949k | factor = 128.0f; |
521 | 949k | offset = factor; |
522 | | |
523 | 10.4M | for (k = 0; k < 10; k++) { |
524 | 9.49M | factor *= 0.5f; |
525 | 9.49M | offset -= factor; |
526 | 9.49M | ener = 0.0f; |
527 | 962M | for (i = 0; i < length / 4; i++) { |
528 | 952M | temp = en[i] - offset; |
529 | | |
530 | 952M | if (temp > 3.0f) { |
531 | 420M | ener += temp; |
532 | 420M | } |
533 | 952M | } |
534 | 9.49M | if (ener > target) { |
535 | 3.35M | offset += factor; |
536 | 3.35M | } |
537 | 9.49M | } |
538 | | |
539 | 949k | gain = (FLOAT32)pow(10.0f, offset / 20.0f); |
540 | | |
541 | 949k | return (gain); |
542 | 949k | } |
543 | | |
544 | | VOID iusace_lpc_coef_gen(FLOAT32 *lsf_old, FLOAT32 *lsf_new, FLOAT32 *a, WORD32 nb_subfr, |
545 | 944k | WORD32 m) { |
546 | 944k | FLOAT32 lsf[ORDER] = {0}, *ptr_a; |
547 | 944k | FLOAT32 inc, fnew, fold; |
548 | 944k | WORD32 i = 0; |
549 | | |
550 | 944k | ptr_a = a; |
551 | | |
552 | 944k | inc = 1.0f / (FLOAT32)nb_subfr; |
553 | 944k | fnew = 0.5f - (0.5f * inc); |
554 | 944k | fold = 1.0f - fnew; |
555 | 16.0M | for (i = 0; i < m; i++) { |
556 | 15.1M | lsf[i] = (lsf_old[i] * fold) + (lsf_new[i] * fnew); |
557 | 15.1M | } |
558 | 944k | iusace_lsp_to_lp_conversion(lsf, ptr_a); |
559 | 944k | ptr_a += (m + 1); |
560 | 944k | iusace_lsp_to_lp_conversion(lsf_old, ptr_a); |
561 | 944k | ptr_a += (m + 1); |
562 | 944k | iusace_lsp_to_lp_conversion(lsf_new, ptr_a); |
563 | | |
564 | 944k | return; |
565 | 944k | } |
566 | | |
567 | | VOID iusace_interpolation_lsp_params(FLOAT32 *lsp_old, FLOAT32 *lsp_new, FLOAT32 *lp_flt_coff_a, |
568 | 1.16M | WORD32 nb_subfr) { |
569 | 1.16M | FLOAT32 lsp[ORDER]; |
570 | 1.16M | FLOAT32 factor; |
571 | 1.16M | WORD32 i, k; |
572 | 1.16M | FLOAT32 x_plus_y, x_minus_y; |
573 | | |
574 | 1.16M | factor = 1.0f / (FLOAT32)nb_subfr; |
575 | | |
576 | 1.16M | x_plus_y = 0.5f * factor; |
577 | | |
578 | 5.46M | for (k = 0; k < nb_subfr; k++) { |
579 | 4.29M | x_minus_y = 1.0f - x_plus_y; |
580 | 73.0M | for (i = 0; i < ORDER; i++) { |
581 | 68.7M | lsp[i] = (lsp_old[i] * x_minus_y) + (lsp_new[i] * x_plus_y); |
582 | 68.7M | } |
583 | 4.29M | x_plus_y += factor; |
584 | | |
585 | 4.29M | iusace_lsp_to_lp_conversion(lsp, lp_flt_coff_a); |
586 | | |
587 | 4.29M | lp_flt_coff_a += (ORDER + 1); |
588 | 4.29M | } |
589 | | |
590 | 1.16M | iusace_lsp_to_lp_conversion(lsp_new, lp_flt_coff_a); |
591 | | |
592 | 1.16M | return; |
593 | 1.16M | } |