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 #include "ixheaac_type_def.h"
21 #include "ixheaac_constants.h"
22 #include "ixheaac_basic_ops32.h"
23 #include "ixheaac_basic_ops16.h"
24 #include "ixheaac_basic_ops40.h"
25 #include "ixheaac_basic_ops.h"
26 #include "ixheaacd_defines.h"
27
ixheaacd_res_tns_parcor_2_lpc_32x16(WORD16 * parcor,WORD16 * lpc,WORD16 * scale,WORD order)28 VOID ixheaacd_res_tns_parcor_2_lpc_32x16(WORD16 *parcor, WORD16 *lpc, WORD16 *scale, WORD order)
29
30 {
31 WORD i, j, status;
32 WORD32 z1;
33 WORD16 z[MAX_ORDER + 1];
34 WORD16 w[MAX_ORDER + 1];
35 WORD32 accu1, accu2;
36
37 status = 1;
38 *scale = 0;
39 while (status) {
40 status = 0;
41
42 for (i = MAX_ORDER; i >= 0; i--) {
43 z[i] = 0;
44 w[i] = 0;
45 }
46
47 accu1 = (0x7fffffff >> *scale);
48
49 for (i = 0; i <= order; i++) {
50 z1 = accu1;
51
52 for (j = 0; j < order; j++) {
53 w[j] = ixheaac_round16(accu1);
54
55 accu1 = ixheaac_mac16x16in32_shl_sat(accu1, parcor[j], z[j]);
56 if (ixheaac_abs32_sat(accu1) == 0x7fffffff) status = 1;
57 }
58 for (j = (order - 1); j >= 0; j--) {
59 accu2 = ixheaac_deposit16h_in32(z[j]);
60 accu2 = ixheaac_mac16x16in32_shl_sat(accu2, parcor[j], w[j]);
61 z[j + 1] = ixheaac_round16(accu2);
62 if (ixheaac_abs32_sat(accu2) == 0x7fffffff) status = 1;
63 }
64
65 z[0] = ixheaac_round16(z1);
66 lpc[i] = ixheaac_round16(accu1);
67 accu1 = 0;
68 }
69 accu1 = (status - 1);
70 if (accu1 == 0) {
71 *scale = *scale + 1;
72 }
73 }
74 }
75
ixheaacd_res_tns_ar_filter_fixed_32x16(WORD32 * spectrum,WORD32 size,WORD32 inc,WORD16 * lpc,WORD32 order,WORD32 shift_value,WORD scale_spec)76 VOID ixheaacd_res_tns_ar_filter_fixed_32x16(WORD32 *spectrum, WORD32 size, WORD32 inc,
77 WORD16 *lpc, WORD32 order, WORD32 shift_value,
78 WORD scale_spec) {
79 WORD32 i, j;
80 WORD32 y, state[MAX_ORDER + 1];
81
82 if ((order & 3) != 0) {
83 for (i = order + 1; i < ((WORD32)(order & 0xfffffffc) + 4); i++) {
84 lpc[i] = 0;
85 }
86 lpc[i] = 0;
87 order = ((order & 0xfffffffc) + 4);
88 order = order & 31;
89 }
90
91 for (i = 0; i < order; i++) {
92 y = (*spectrum) << scale_spec;
93 for (j = i; j > 0; j--) {
94 y = ixheaac_sub32_sat(y, ixheaac_mult32x16in32_shl_sat(state[j - 1], lpc[j]));
95 state[j] = state[j - 1];
96 }
97
98 state[0] = ixheaac_shl32_dir_sat_limit(y, shift_value);
99 *spectrum = y >> scale_spec;
100 spectrum += inc;
101 }
102
103 for (i = order; i < size; i++) {
104 y = (*spectrum) << scale_spec;
105
106 for (j = order; j > 0; j--) {
107 y = ixheaac_sub32_sat(y, ixheaac_mult32x16in32_shl_sat(state[j - 1], lpc[j]));
108 state[j] = state[j - 1];
109 }
110
111 state[0] = ixheaac_shl32_dir_sat_limit(y, shift_value);
112 *spectrum = y >> scale_spec;
113 spectrum += inc;
114 }
115 }
116
ixheaacd_res_calc_max_spectral_line(WORD32 * p_tmp,WORD32 size)117 WORD32 ixheaacd_res_calc_max_spectral_line(WORD32 *p_tmp, WORD32 size) {
118 WORD32 max_spectral_line = 0, i;
119 WORD count, remaining, temp_1, temp_2, temp3, temp4;
120
121 count = size >> 3;
122 for (i = count; i--;) {
123 temp_1 = *p_tmp++;
124 temp_2 = *p_tmp++;
125 temp3 = *p_tmp++;
126 temp4 = *p_tmp++;
127
128 max_spectral_line = ixheaac_abs32_nrm(temp_1) | max_spectral_line;
129 max_spectral_line = ixheaac_abs32_nrm(temp_2) | max_spectral_line;
130 max_spectral_line = ixheaac_abs32_nrm(temp3) | max_spectral_line;
131 max_spectral_line = ixheaac_abs32_nrm(temp4) | max_spectral_line;
132 temp_1 = *p_tmp++;
133 temp_2 = *p_tmp++;
134 temp3 = *p_tmp++;
135 temp4 = *p_tmp++;
136
137 max_spectral_line = ixheaac_abs32_nrm(temp_1) | max_spectral_line;
138 max_spectral_line = ixheaac_abs32_nrm(temp_2) | max_spectral_line;
139 max_spectral_line = ixheaac_abs32_nrm(temp3) | max_spectral_line;
140 max_spectral_line = ixheaac_abs32_nrm(temp4) | max_spectral_line;
141 }
142
143 remaining = size - (count << 3);
144 if (remaining) {
145 for (i = remaining; i--;) {
146 max_spectral_line = ixheaac_abs32_nrm(*p_tmp) | max_spectral_line;
147 p_tmp++;
148 }
149 }
150
151 return ixheaac_norm32(max_spectral_line);
152 }
153