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