1 /****************************************************************************** 2 * * 3 * Copyright (C) 2018 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 #include <float.h> 21 #include <stdlib.h> 22 #include <stdio.h> 23 #include <math.h> 24 #include <string.h> 25 26 #include <ixheaacd_type_def.h> 27 28 #include "ixheaacd_bitbuffer.h" 29 30 #include "ixheaacd_interface.h" 31 32 #include "ixheaacd_tns_usac.h" 33 #include "ixheaacd_cnst.h" 34 35 #include "ixheaacd_acelp_info.h" 36 37 #include "ixheaacd_td_mdct.h" 38 39 #include "ixheaacd_sbrdecsettings.h" 40 #include "ixheaacd_info.h" 41 #include "ixheaacd_sbr_common.h" 42 #include "ixheaacd_drc_data_struct.h" 43 #include "ixheaacd_drc_dec.h" 44 #include "ixheaacd_sbrdecoder.h" 45 #include "ixheaacd_mps_polyphase.h" 46 #include "ixheaacd_sbr_const.h" 47 #include "ixheaacd_main.h" 48 #include "ixheaacd_arith_dec.h" 49 #include "ixheaacd_func_def.h" 50 51 #include "ixheaacd_acelp_com.h" 52 53 #define F_PIT_SHARP 0.85F 54 #define MEAN_ENER 30 55 56 extern const FLOAT32 ixheaacd_interpol_filt[INTER_LP_FIL_LEN]; 57 58 VOID ixheaacd_acelp_pitch_sharpening(FLOAT32 *x, WORD32 pit_lag) { 59 WORD32 i; 60 for (i = pit_lag; i < LEN_SUBFR; i++) { 61 x[i] += x[i - pit_lag] * F_PIT_SHARP; 62 } 63 return; 64 } 65 66 static VOID ixheaacd_acelp_decode_1sp_per_track(WORD32 idx_1p, WORD32 M, 67 WORD32 ixheaacd_drc_offset, 68 WORD32 track, 69 FLOAT32 code_vec[]) { 70 WORD32 sign_index, mask, m; 71 WORD32 sp_pos; 72 mask = ((1 << M) - 1); 73 74 sp_pos = (idx_1p & mask) + ixheaacd_drc_offset; 75 sign_index = ((idx_1p >> M) & 1); 76 77 m = (sp_pos << 2) + track; 78 if (sign_index == 1) 79 code_vec[m] = (code_vec[m] - 1.0f); 80 else 81 code_vec[m] = (code_vec[m] + 1.0f); 82 83 return; 84 } 85 86 static VOID ixheaacd_acelp_decode_2sp_per_track(WORD32 idx_2p, WORD32 M, 87 WORD32 ixheaacd_drc_offset, 88 WORD32 track, 89 FLOAT32 code_vec[]) { 90 WORD32 sign_index; 91 WORD32 mask, m0, m1; 92 WORD32 sp_pos[2]; 93 mask = ((1 << M) - 1); 94 95 sp_pos[0] = (((idx_2p >> M) & mask) + ixheaacd_drc_offset); 96 sp_pos[1] = ((idx_2p & mask) + ixheaacd_drc_offset); 97 98 sign_index = (idx_2p >> 2 * M) & 1; 99 100 m0 = (sp_pos[0] << 2) + track; 101 m1 = (sp_pos[1] << 2) + track; 102 103 if ((sp_pos[1] - sp_pos[0]) < 0) { 104 if (sign_index == 1) { 105 code_vec[m0] = (code_vec[m0] - 1.0f); 106 code_vec[m1] = (code_vec[m1] + 1.0f); 107 } else { 108 code_vec[m0] = (code_vec[m0] + 1.0f); 109 code_vec[m1] = (code_vec[m1] - 1.0f); 110 } 111 } else { 112 if (sign_index == 1) { 113 code_vec[m0] = (code_vec[m0] - 1.0f); 114 code_vec[m1] = (code_vec[m1] - 1.0f); 115 } else { 116 code_vec[m0] = (code_vec[m0] + 1.0f); 117 code_vec[m1] = (code_vec[m1] + 1.0f); 118 } 119 } 120 return; 121 } 122 123 static VOID ixheaacd_acelp_decode_3sp_per_track(WORD32 idx_3p, WORD32 M, 124 WORD32 ixheaacd_drc_offset, 125 WORD32 track, 126 FLOAT32 code_vec[]) { 127 WORD32 j, mask, idx_2p, idx_1p; 128 129 mask = ((1 << (2 * M - 1)) - 1); 130 idx_2p = idx_3p & mask; 131 j = ixheaacd_drc_offset; 132 if (((idx_3p >> ((2 * M) - 1)) & 1) == 1) { 133 j += (1 << (M - 1)); 134 } 135 ixheaacd_acelp_decode_2sp_per_track(idx_2p, M - 1, j, track, code_vec); 136 mask = ((1 << (M + 1)) - 1); 137 idx_1p = (idx_3p >> 2 * M) & mask; 138 ixheaacd_acelp_decode_1sp_per_track(idx_1p, M, ixheaacd_drc_offset, track, 139 code_vec); 140 return; 141 } 142 143 static VOID ixheaacd_d_acelp_decode_4sp_per_track_section( 144 WORD32 index, WORD32 ixheaacd_drc_offset, WORD32 track, 145 FLOAT32 code_vec[]) { 146 WORD32 j, idx_2p; 147 148 idx_2p = index & 31; 149 j = ixheaacd_drc_offset; 150 if (((index >> 5) & 1) == 1) { 151 j += 4; 152 } 153 ixheaacd_acelp_decode_2sp_per_track(idx_2p, 2, j, track, code_vec); 154 idx_2p = (index >> 6) & 127; 155 ixheaacd_acelp_decode_2sp_per_track(idx_2p, 3, ixheaacd_drc_offset, track, 156 code_vec); 157 return; 158 } 159 160 static VOID ixheaacd_acelp_decode_4sp_per_track(WORD32 idx_4p, WORD32 track, 161 FLOAT32 code_vec[]) { 162 WORD32 idx_1p, idx_2p, idx_3p; 163 164 switch ((idx_4p >> 14) & 3) { 165 case 0: 166 if (((idx_4p >> 13) & 1) == 0) 167 ixheaacd_d_acelp_decode_4sp_per_track_section(idx_4p, 0, track, 168 code_vec); 169 else 170 ixheaacd_d_acelp_decode_4sp_per_track_section(idx_4p, 8, track, 171 code_vec); 172 break; 173 case 1: 174 idx_1p = idx_4p >> 10; 175 ixheaacd_acelp_decode_1sp_per_track(idx_1p, 3, 0, track, code_vec); 176 ixheaacd_acelp_decode_3sp_per_track(idx_4p, 3, 8, track, code_vec); 177 break; 178 case 2: 179 idx_2p = idx_4p >> 7; 180 ixheaacd_acelp_decode_2sp_per_track(idx_2p, 3, 0, track, code_vec); 181 ixheaacd_acelp_decode_2sp_per_track(idx_4p, 3, 8, track, code_vec); 182 break; 183 case 3: 184 idx_3p = idx_4p >> 4; 185 ixheaacd_acelp_decode_3sp_per_track(idx_3p, 3, 0, track, code_vec); 186 ixheaacd_acelp_decode_1sp_per_track(idx_4p, 3, 8, track, code_vec); 187 break; 188 } 189 return; 190 } 191 192 static VOID ixheaacd_d_acelp_add_pulse(WORD32 pos[], WORD32 nb_pulse, 193 WORD32 track, FLOAT32 code[]) { 194 WORD32 i, k; 195 for (k = 0; k < nb_pulse; k++) { 196 i = ((pos[k] & (16 - 1)) << 2) + track; 197 if ((pos[k] & 16) == 0) { 198 code[i] = (WORD16)(code[i] + 1.0f); 199 } else { 200 code[i] = (WORD16)(code[i] - 1.0f); 201 } 202 } 203 return; 204 } 205 206 static VOID ixheaacd_d_acelp_decode_1p_n1(WORD32 index, WORD32 N, 207 WORD32 ixheaacd_drc_offset, 208 WORD32 pos[]) { 209 WORD32 i, pos1, mask; 210 mask = ((1 << N) - 1); 211 212 pos1 = ((index & mask) + ixheaacd_drc_offset); 213 i = ((index >> N) & 1); 214 if (i == 1) { 215 pos1 += 16; 216 } 217 pos[0] = pos1; 218 return; 219 } 220 221 VOID ixheaacd_acelp_decode_pulses_per_track(WORD32 cb_index[], WORD16 code_bits, 222 FLOAT32 code_vec[]) { 223 WORD32 track_idx, index, ixheaacd_drc_offset, pos[6], i; 224 memset(code_vec, 0, 64 * sizeof(FLOAT32)); 225 226 if (code_bits == 12) { 227 for (track_idx = 0; track_idx < 4; track_idx += 2) { 228 ixheaacd_drc_offset = cb_index[2 * (track_idx / 2)]; 229 index = cb_index[2 * (track_idx / 2) + 1]; 230 ixheaacd_d_acelp_decode_1p_n1(index, 4, 0, pos); 231 ixheaacd_d_acelp_add_pulse( 232 pos, 1, 2 * ixheaacd_drc_offset + track_idx / 2, code_vec); 233 } 234 } else if (code_bits == 16) { 235 i = 0; 236 ixheaacd_drc_offset = cb_index[i++]; 237 ixheaacd_drc_offset = (ixheaacd_drc_offset == 0) ? 1 : 3; 238 for (track_idx = 0; track_idx < 4; track_idx++) { 239 if (track_idx != ixheaacd_drc_offset) { 240 index = cb_index[i++]; 241 ixheaacd_d_acelp_decode_1p_n1(index, 4, 0, pos); 242 ixheaacd_d_acelp_add_pulse(pos, 1, track_idx, code_vec); 243 } 244 } 245 } else if (code_bits == 20) { 246 for (track_idx = 0; track_idx < 4; track_idx++) { 247 index = cb_index[track_idx]; 248 ixheaacd_acelp_decode_1sp_per_track(index, 4, 0, track_idx, code_vec); 249 } 250 } else if (code_bits == 28) { 251 for (track_idx = 0; track_idx < 2; track_idx++) { 252 index = cb_index[track_idx]; 253 ixheaacd_acelp_decode_2sp_per_track(index, 4, 0, track_idx, code_vec); 254 } 255 for (track_idx = 2; track_idx < 4; track_idx++) { 256 index = cb_index[track_idx]; 257 ixheaacd_acelp_decode_1sp_per_track(index, 4, 0, track_idx, code_vec); 258 } 259 } else if (code_bits == 36) { 260 for (track_idx = 0; track_idx < 4; track_idx++) { 261 index = cb_index[track_idx]; 262 ixheaacd_acelp_decode_2sp_per_track(index, 4, 0, track_idx, code_vec); 263 } 264 } else if (code_bits == 44) { 265 for (track_idx = 0; track_idx < 2; track_idx++) { 266 index = cb_index[track_idx]; 267 ixheaacd_acelp_decode_3sp_per_track(index, 4, 0, track_idx, code_vec); 268 } 269 for (track_idx = 2; track_idx < 4; track_idx++) { 270 index = cb_index[track_idx]; 271 ixheaacd_acelp_decode_2sp_per_track(index, 4, 0, track_idx, code_vec); 272 } 273 } else if (code_bits == 52) { 274 for (track_idx = 0; track_idx < 4; track_idx++) { 275 index = cb_index[track_idx]; 276 ixheaacd_acelp_decode_3sp_per_track(index, 4, 0, track_idx, code_vec); 277 } 278 } else if (code_bits == 64) { 279 for (track_idx = 0; track_idx < 4; track_idx++) { 280 index = ((cb_index[track_idx] << 14) + cb_index[track_idx + 4]); 281 ixheaacd_acelp_decode_4sp_per_track(index, track_idx, code_vec); 282 } 283 } 284 return; 285 } 286 287 static void ixheaacd_acelp_decode_gains(WORD32 index, FLOAT32 code_vec[], 288 FLOAT32 *pitch_gain, 289 FLOAT32 *codebook_gain, 290 FLOAT32 mean_exc_energy, 291 FLOAT32 *energy) { 292 WORD32 i; 293 FLOAT32 avg_innov_energy, est_gain; 294 const FLOAT32 *gain_table = ixheaacd_int_leave_gain_table; 295 296 avg_innov_energy = 0.01f; 297 for (i = 0; i < LEN_SUBFR; i++) { 298 avg_innov_energy += code_vec[i] * code_vec[i]; 299 } 300 *energy = avg_innov_energy; 301 302 avg_innov_energy = 303 (FLOAT32)(10.0 * log10(avg_innov_energy / (FLOAT32)LEN_SUBFR)); 304 305 est_gain = mean_exc_energy - avg_innov_energy; 306 307 est_gain = (FLOAT32)pow(10.0, 0.05 * est_gain); 308 *pitch_gain = gain_table[index * 2]; 309 310 *codebook_gain = gain_table[index * 2 + 1] * est_gain; 311 312 return; 313 } 314 315 static VOID ixheaacd_cb_exc_calc(FLOAT32 xcitation_curr[], WORD32 pitch_lag, 316 WORD32 frac) { 317 WORD32 i, j; 318 FLOAT32 s, *x0, *x1, *x2; 319 const FLOAT32 *c1, *c2; 320 321 x0 = &xcitation_curr[-pitch_lag]; 322 frac = -frac; 323 if (frac < 0) { 324 frac += UP_SAMP; 325 x0--; 326 } 327 for (j = 0; j < LEN_SUBFR + 1; j++) { 328 x1 = x0++; 329 x2 = x1 + 1; 330 c1 = &ixheaacd_interpol_filt[frac]; 331 c2 = &ixheaacd_interpol_filt[UP_SAMP - frac]; 332 s = 0.0; 333 for (i = 0; i < INTER_LP_FIL_ORDER; i++, c1 += UP_SAMP, c2 += UP_SAMP) { 334 s += (*x1--) * (*c1) + (*x2++) * (*c2); 335 } 336 xcitation_curr[j] = s; 337 } 338 return; 339 } 340 341 WORD32 ixheaacd_acelp_alias_cnx(ia_usac_data_struct *usac_data, 342 ia_td_frame_data_struct *pstr_td_frame_data, 343 WORD32 k, FLOAT32 lp_filt_coeff[], 344 FLOAT32 stability_factor, 345 ia_usac_lpd_decoder_handle st) { 346 WORD32 i, subfr_idx; 347 WORD32 pitch_lag, pitch_lag_frac, index, pitch_flag, pitch_lag_max; 348 WORD32 pitch_lag_min = 0; 349 FLOAT32 tmp, pitch_gain, gain_code, voicing_factor, r_v, innov_energy, 350 pitch_energy, mean_ener_code; 351 FLOAT32 gain_smooth, gain_code0, cpe; 352 FLOAT32 code[LEN_SUBFR], synth_temp[128 + 16]; 353 FLOAT32 post_process_exc[LEN_SUBFR]; 354 FLOAT32 gain_smooth_factor; 355 FLOAT32 *ptr_lp_filt_coeff; 356 WORD32 pitch_min; 357 WORD32 pitch_fr2; 358 WORD32 pitch_fr1; 359 WORD32 pitch_max; 360 WORD32 subfr_nb = 0; 361 WORD16 num_codebits_table[8] = {20, 28, 36, 44, 52, 64, 12, 16}; 362 FLOAT32 x[FAC_LENGTH], xn2[2 * FAC_LENGTH + 16]; 363 WORD32 int_x[FAC_LENGTH]; 364 WORD32 TTT; 365 WORD32 len_subfr = usac_data->len_subfrm; 366 WORD32 fac_length; 367 WORD8 shiftp; 368 WORD32 preshift; 369 WORD32 *ptr_scratch = &usac_data->scratch_buffer[0]; 370 WORD32 *int_xn2 = &usac_data->x_ac_dec[0]; 371 WORD32 loop_count = 0; 372 WORD32 core_mode = pstr_td_frame_data->acelp_core_mode; 373 FLOAT32 *synth_signal = 374 &usac_data->synth_buf[len_subfr * k + MAX_PITCH + 375 (((NUM_FRAMES * usac_data->num_subfrm) / 2) - 1) * 376 LEN_SUBFR]; 377 FLOAT32 *xcitation_curr = 378 &usac_data->exc_buf[len_subfr * k + MAX_PITCH + (INTER_LP_FIL_ORDER + 1)]; 379 FLOAT32 *ptr_pitch_gain = 380 &usac_data->pitch_gain[k * usac_data->num_subfrm + 381 (((NUM_FRAMES * usac_data->num_subfrm) / 2) - 1)]; 382 WORD32 *ptr_pitch = 383 &usac_data->pitch[k * usac_data->num_subfrm + 384 (((NUM_FRAMES * usac_data->num_subfrm) / 2) - 1)]; 385 WORD32 err = 0; 386 fac_length = len_subfr / 2; 387 388 if (st->mode_prev > 0) { 389 for (i = 0; i < fac_length / 2; i++) { 390 x[i] = st->fac_gain * pstr_td_frame_data->fac[k * FAC_LENGTH + 2 * i]; 391 x[fac_length / 2 + i] = 392 st->fac_gain * 393 pstr_td_frame_data->fac[k * FAC_LENGTH + fac_length - 2 * i - 1]; 394 } 395 for (i = 0; i < fac_length / 8; i++) { 396 x[i] *= st->fac_fd_data[2 * i]; 397 x[fac_length - i - 1] *= st->fac_fd_data[2 * i + 1]; 398 } 399 400 preshift = 0; 401 shiftp = ixheaacd_float2fix(x, int_x, fac_length); 402 403 err = 404 ixheaacd_acelp_mdct(int_x, int_xn2, &preshift, fac_length, ptr_scratch); 405 if (err == -1) return err; 406 ixheaacd_fix2float(int_xn2, xn2 + fac_length, fac_length, &shiftp, 407 &preshift); 408 409 ixheaacd_vec_cnst_mul((2.0f / (FLOAT32)fac_length), xn2 + fac_length, 410 xn2 + fac_length, fac_length); 411 412 memset(xn2, 0, fac_length * sizeof(FLOAT32)); 413 414 ixheaacd_lpc_wt_synthesis_tool(st->lp_flt_coeff_a_prev, xn2 + fac_length, 415 fac_length); 416 417 for (i = 0; i < 2 * fac_length; i++) 418 xn2[i] += synth_signal[i - (2 * fac_length)]; 419 420 memcpy(synth_signal - fac_length, xn2 + fac_length, 421 fac_length * sizeof(FLOAT32)); 422 423 tmp = 0.0; 424 ixheaacd_preemphsis_tool_float(xn2, PREEMPH_FILT_FAC, 2 * fac_length, tmp); 425 426 ptr_lp_filt_coeff = st->lp_flt_coeff_a_prev; 427 TTT = fac_length % LEN_SUBFR; 428 if (TTT != 0) { 429 ixheaacd_residual_tool_float( 430 ptr_lp_filt_coeff, &xn2[fac_length], 431 &xcitation_curr[fac_length - (2 * fac_length)], TTT, 1); 432 ptr_lp_filt_coeff += (ORDER + 1); 433 } 434 435 loop_count = (fac_length + TTT) / LEN_SUBFR; 436 ixheaacd_residual_tool_float(ptr_lp_filt_coeff, &xn2[fac_length + TTT], 437 &xcitation_curr[TTT - fac_length], LEN_SUBFR, 438 loop_count); 439 } 440 441 for (i = 0; i < ORDER; i++) 442 synth_temp[i] = synth_signal[i - ORDER] - 443 (PREEMPH_FILT_FAC * synth_signal[i - ORDER - 1]); 444 445 i = (((st->fscale * TMIN) + (FSCALE_DENOM / 2)) / FSCALE_DENOM) - TMIN; 446 pitch_min = TMIN + i; 447 pitch_fr2 = TFR2 - i; 448 pitch_fr1 = TFR1; 449 pitch_max = TMAX + (6 * i); 450 451 ptr_lp_filt_coeff = lp_filt_coeff; 452 for (subfr_idx = 0; subfr_idx < len_subfr; subfr_idx += LEN_SUBFR) { 453 pitch_flag = subfr_idx; 454 if ((len_subfr == 256) && (subfr_idx == (2 * LEN_SUBFR))) { 455 pitch_flag = 0; 456 } 457 index = pstr_td_frame_data->acb_index[k * 4 + subfr_nb]; 458 459 if (pitch_flag == 0) { 460 if (index < (pitch_fr2 - pitch_min) * 4) { 461 pitch_lag = pitch_min + (index / 4); 462 pitch_lag_frac = index - (pitch_lag - pitch_min) * 4; 463 } else if (index < 464 ((pitch_fr2 - pitch_min) * 4 + (pitch_fr1 - pitch_fr2) * 2)) { 465 index -= (pitch_fr2 - pitch_min) * 4; 466 pitch_lag = pitch_fr2 + (index / 2); 467 pitch_lag_frac = index - (pitch_lag - pitch_fr2) * 2; 468 pitch_lag_frac *= 2; 469 } else { 470 pitch_lag = index + pitch_fr1 - ((pitch_fr2 - pitch_min) * 4) - 471 ((pitch_fr1 - pitch_fr2) * 2); 472 pitch_lag_frac = 0; 473 } 474 pitch_lag_min = pitch_lag - 8; 475 if (pitch_lag_min < pitch_min) pitch_lag_min = pitch_min; 476 477 pitch_lag_max = pitch_lag_min + 15; 478 if (pitch_lag_max > pitch_max) { 479 pitch_lag_max = pitch_max; 480 pitch_lag_min = pitch_lag_max - 15; 481 } 482 } else { 483 pitch_lag = pitch_lag_min + index / 4; 484 pitch_lag_frac = index - (pitch_lag - pitch_lag_min) * 4; 485 } 486 487 ixheaacd_cb_exc_calc(&xcitation_curr[subfr_idx], pitch_lag, pitch_lag_frac); 488 489 mean_ener_code = 490 (((FLOAT32)pstr_td_frame_data->mean_energy[k]) * 12.0f) + 18.0f; 491 492 if (pstr_td_frame_data->ltp_filtering_flag[k * 4 + subfr_nb] == 0) { 493 for (i = 0; i < LEN_SUBFR; i++) 494 code[i] = (FLOAT32)(0.18 * xcitation_curr[i - 1 + subfr_idx] + 495 0.64 * xcitation_curr[i + subfr_idx] + 496 0.18 * xcitation_curr[i + 1 + subfr_idx]); 497 498 ixheaacd_mem_cpy(code, &xcitation_curr[subfr_idx], LEN_SUBFR); 499 } 500 501 ixheaacd_acelp_decode_pulses_per_track( 502 &(pstr_td_frame_data->icb_index[k * 4 + subfr_nb][0]), 503 num_codebits_table[core_mode], code); 504 505 tmp = 0.0; 506 ixheaacd_preemphsis_tool_float(code, TILT_CODE, LEN_SUBFR, tmp); 507 i = pitch_lag; 508 if (pitch_lag_frac > 2) i++; 509 if (i >= 0) ixheaacd_acelp_pitch_sharpening(code, i); 510 511 index = pstr_td_frame_data->gains[k * 4 + subfr_nb]; 512 513 ixheaacd_acelp_decode_gains(index, code, &pitch_gain, &gain_code, 514 mean_ener_code, &innov_energy); 515 516 pitch_energy = 0.0; 517 for (i = 0; i < LEN_SUBFR; i++) 518 pitch_energy += 519 xcitation_curr[i + subfr_idx] * xcitation_curr[i + subfr_idx]; 520 521 pitch_energy *= (pitch_gain * pitch_gain); 522 523 innov_energy *= gain_code * gain_code; 524 525 r_v = (FLOAT32)((pitch_energy - innov_energy) / 526 (pitch_energy + innov_energy)); 527 528 for (i = 0; i < LEN_SUBFR; i++) 529 post_process_exc[i] = pitch_gain * xcitation_curr[i + subfr_idx]; 530 531 for (i = 0; i < LEN_SUBFR; i++) 532 xcitation_curr[i + subfr_idx] = 533 pitch_gain * xcitation_curr[i + subfr_idx] + gain_code * code[i]; 534 535 i = pitch_lag; 536 if (pitch_lag_frac > 2) i++; 537 538 if (i > pitch_max) i = pitch_max; 539 540 *ptr_pitch++ = i; 541 *ptr_pitch_gain++ = pitch_gain; 542 543 voicing_factor = (FLOAT32)(0.5 * (1.0 - r_v)); 544 gain_smooth_factor = stability_factor * voicing_factor; 545 gain_code0 = gain_code; 546 if (gain_code0 < st->gain_threshold) { 547 gain_code0 = (FLOAT32)(gain_code0 * 1.19); 548 if (gain_code0 > st->gain_threshold) gain_code0 = st->gain_threshold; 549 } else { 550 gain_code0 = (FLOAT32)(gain_code0 / 1.19); 551 if (gain_code0 < st->gain_threshold) gain_code0 = st->gain_threshold; 552 } 553 st->gain_threshold = gain_code0; 554 gain_smooth = (FLOAT32)((gain_smooth_factor * gain_code0) + 555 ((1.0 - gain_smooth_factor) * gain_code)); 556 for (i = 0; i < LEN_SUBFR; i++) code[i] *= gain_smooth; 557 558 cpe = (FLOAT32)(0.125 * (1.0 + r_v)); 559 560 post_process_exc[0] += code[0] - (cpe * code[1]); 561 562 for (i = 1; i < LEN_SUBFR - 1; i++) 563 post_process_exc[i] += code[i] - (cpe * (code[i - 1] + code[i + 1])); 564 565 post_process_exc[LEN_SUBFR - 1] += 566 code[LEN_SUBFR - 1] - (cpe * code[LEN_SUBFR - 2]); 567 568 ixheaacd_synthesis_tool_float(ptr_lp_filt_coeff, post_process_exc, 569 &synth_signal[subfr_idx], LEN_SUBFR, 570 synth_temp); 571 memcpy(synth_temp, &synth_signal[subfr_idx + LEN_SUBFR - ORDER], 572 ORDER * sizeof(FLOAT32)); 573 574 ptr_lp_filt_coeff += (ORDER + 1); 575 subfr_nb++; 576 } 577 578 ixheaacd_deemphsis_tool(synth_signal, len_subfr, synth_signal[-1]); 579 580 memset(synth_temp + 16, 0, 128 * sizeof(FLOAT32)); 581 ixheaacd_synthesis_tool_float1(ptr_lp_filt_coeff, synth_temp + 16, 128); 582 583 ptr_lp_filt_coeff -= (2 * (ORDER + 1)); 584 memcpy(st->lp_flt_coeff_a_prev, ptr_lp_filt_coeff, 585 (2 * (ORDER + 1)) * sizeof(FLOAT32)); 586 587 memcpy(st->exc_prev, synth_signal + len_subfr - (1 + fac_length), 588 (1 + fac_length) * sizeof(FLOAT32)); 589 590 memcpy(st->exc_prev + 1 + fac_length, synth_temp + 16, 591 fac_length * sizeof(FLOAT32)); 592 ixheaacd_deemphsis_tool(st->exc_prev + 1 + fac_length, fac_length, 593 synth_signal[len_subfr - 1]); 594 595 return err; 596 } 597