| /****************************************************************************** |
| * |
| * Copyright (C) 2023 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at: |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| ***************************************************************************** |
| * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
| */ |
| #include "ixheaac_type_def.h" |
| #include "ixheaac_constants.h" |
| #include "ixheaac_basic_ops32.h" |
| #include "ixheaac_basic_ops16.h" |
| #include "ixheaac_basic_ops40.h" |
| #include "ixheaac_basic_ops.h" |
| #include "ixheaacd_defines.h" |
| |
| VOID ixheaacd_res_tns_parcor_2_lpc_32x16(WORD16 *parcor, WORD16 *lpc, WORD16 *scale, WORD order) |
| |
| { |
| WORD i, j, status; |
| WORD32 z1; |
| WORD16 z[MAX_ORDER + 1]; |
| WORD16 w[MAX_ORDER + 1]; |
| WORD32 accu1, accu2; |
| |
| status = 1; |
| *scale = 0; |
| while (status) { |
| status = 0; |
| |
| for (i = MAX_ORDER; i >= 0; i--) { |
| z[i] = 0; |
| w[i] = 0; |
| } |
| |
| accu1 = (0x7fffffff >> *scale); |
| |
| for (i = 0; i <= order; i++) { |
| z1 = accu1; |
| |
| for (j = 0; j < order; j++) { |
| w[j] = ixheaac_round16(accu1); |
| |
| accu1 = ixheaac_mac16x16in32_shl_sat(accu1, parcor[j], z[j]); |
| if (ixheaac_abs32_sat(accu1) == 0x7fffffff) status = 1; |
| } |
| for (j = (order - 1); j >= 0; j--) { |
| accu2 = ixheaac_deposit16h_in32(z[j]); |
| accu2 = ixheaac_mac16x16in32_shl_sat(accu2, parcor[j], w[j]); |
| z[j + 1] = ixheaac_round16(accu2); |
| if (ixheaac_abs32_sat(accu2) == 0x7fffffff) status = 1; |
| } |
| |
| z[0] = ixheaac_round16(z1); |
| lpc[i] = ixheaac_round16(accu1); |
| accu1 = 0; |
| } |
| accu1 = (status - 1); |
| if (accu1 == 0) { |
| *scale = *scale + 1; |
| } |
| } |
| } |
| |
| VOID ixheaacd_res_tns_ar_filter_fixed_32x16(WORD32 *spectrum, WORD32 size, WORD32 inc, |
| WORD16 *lpc, WORD32 order, WORD32 shift_value, |
| WORD scale_spec) { |
| WORD32 i, j; |
| WORD32 y, state[MAX_ORDER + 1]; |
| |
| if ((order & 3) != 0) { |
| for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) { |
| lpc[i] = 0; |
| } |
| lpc[i] = 0; |
| order = ((order & 0xfffffffc) + 4); |
| order = order & 31; |
| } |
| |
| for (i = 0; i < order; i++) { |
| y = (*spectrum) << scale_spec; |
| for (j = i; j > 0; j--) { |
| y = ixheaac_sub32_sat(y, ixheaac_mult32x16in32_shl_sat(state[j - 1], lpc[j])); |
| state[j] = state[j - 1]; |
| } |
| |
| state[0] = ixheaac_shl32_dir_sat_limit(y, shift_value); |
| *spectrum = y >> scale_spec; |
| spectrum += inc; |
| } |
| |
| for (i = order; i < size; i++) { |
| y = (*spectrum) << scale_spec; |
| |
| for (j = order; j > 0; j--) { |
| y = ixheaac_sub32_sat(y, ixheaac_mult32x16in32_shl_sat(state[j - 1], lpc[j])); |
| state[j] = state[j - 1]; |
| } |
| |
| state[0] = ixheaac_shl32_dir_sat_limit(y, shift_value); |
| *spectrum = y >> scale_spec; |
| spectrum += inc; |
| } |
| } |
| |
| WORD32 ixheaacd_res_calc_max_spectral_line(WORD32 *p_tmp, WORD32 size) { |
| WORD32 max_spectral_line = 0, i; |
| WORD count, remaining, temp_1, temp_2, temp3, temp4; |
| |
| count = size >> 3; |
| for (i = count; i--;) { |
| temp_1 = *p_tmp++; |
| temp_2 = *p_tmp++; |
| temp3 = *p_tmp++; |
| temp4 = *p_tmp++; |
| |
| max_spectral_line = ixheaac_abs32_nrm(temp_1) | max_spectral_line; |
| max_spectral_line = ixheaac_abs32_nrm(temp_2) | max_spectral_line; |
| max_spectral_line = ixheaac_abs32_nrm(temp3) | max_spectral_line; |
| max_spectral_line = ixheaac_abs32_nrm(temp4) | max_spectral_line; |
| temp_1 = *p_tmp++; |
| temp_2 = *p_tmp++; |
| temp3 = *p_tmp++; |
| temp4 = *p_tmp++; |
| |
| max_spectral_line = ixheaac_abs32_nrm(temp_1) | max_spectral_line; |
| max_spectral_line = ixheaac_abs32_nrm(temp_2) | max_spectral_line; |
| max_spectral_line = ixheaac_abs32_nrm(temp3) | max_spectral_line; |
| max_spectral_line = ixheaac_abs32_nrm(temp4) | max_spectral_line; |
| } |
| |
| remaining = size - (count << 3); |
| if (remaining) { |
| for (i = remaining; i--;) { |
| max_spectral_line = ixheaac_abs32_nrm(*p_tmp) | max_spectral_line; |
| p_tmp++; |
| } |
| } |
| |
| return ixheaac_norm32(max_spectral_line); |
| } |