/src/libxaac/encoder/iusace_block_switch.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 "iusace_type_def.h" |
22 | | #include "ixheaace_mps_common_define.h" |
23 | | #include "iusace_cnst.h" |
24 | | #include "iusace_block_switch_const.h" |
25 | | #include "iusace_block_switch_struct_def.h" |
26 | | #include "iusace_rom.h" |
27 | | |
28 | 1.91G | static FLOAT32 iusace_fmult(FLOAT32 a, FLOAT32 b) { return (a * b); } |
29 | | |
30 | 766M | static FLOAT32 iusace_fadd(FLOAT32 a, FLOAT32 b) { return (a + b); } |
31 | | |
32 | | VOID iusace_init_block_switching(ia_block_switch_ctrl *pstr_blk_switch_ctrl, |
33 | 5.99k | const WORD32 bit_rate, const WORD32 num_chans) { |
34 | 5.99k | WORD32 i, w; |
35 | | |
36 | 5.99k | if ((num_chans == 1 && bit_rate > 24000) || (num_chans > 1 && bit_rate / num_chans > 16000)) { |
37 | 5.97k | pstr_blk_switch_ctrl->inv_attack_ratio = INV_ATTACK_RATIO_HIGH_BR; |
38 | 5.97k | } else { |
39 | 20 | pstr_blk_switch_ctrl->inv_attack_ratio = INV_ATTACK_RATIO_LOW_BR; |
40 | 20 | } |
41 | | |
42 | 17.9k | for (i = 0; i < BLK_SWITCH_FILT_LEN; i++) { |
43 | 11.9k | pstr_blk_switch_ctrl->iir_states[i] = 0; |
44 | 11.9k | } |
45 | | |
46 | | /* Clear Filtered Window Energies */ |
47 | 53.9k | for (w = 0; w < MAX_SHORT_WINDOWS; w++) { |
48 | 47.9k | pstr_blk_switch_ctrl->win_energy_filt[0][w] = 0; |
49 | 47.9k | pstr_blk_switch_ctrl->win_energy_filt[1][w] = 0; |
50 | 47.9k | pstr_blk_switch_ctrl->win_energy[0][w] = 0; |
51 | 47.9k | pstr_blk_switch_ctrl->win_energy[1][w] = 0; |
52 | 47.9k | } |
53 | 5.99k | pstr_blk_switch_ctrl->acc_win_energy = 0; |
54 | | |
55 | 5.99k | pstr_blk_switch_ctrl->window_seq = ONLY_LONG_SEQUENCE; |
56 | 5.99k | pstr_blk_switch_ctrl->next_win_seq = ONLY_LONG_SEQUENCE; |
57 | | |
58 | 5.99k | pstr_blk_switch_ctrl->attack = 0; |
59 | 5.99k | pstr_blk_switch_ctrl->lastattack = 0; |
60 | 5.99k | pstr_blk_switch_ctrl->attack_idx = 0; |
61 | 5.99k | pstr_blk_switch_ctrl->last_attack_idx = 0; |
62 | | |
63 | 5.99k | return; |
64 | 5.99k | } |
65 | | |
66 | 408k | static FLOAT32 iusace_srch_max_with_idx(const FLOAT32 *ptr_in, WORD32 *index) { |
67 | 408k | FLOAT32 max; |
68 | 408k | WORD32 i, idx; |
69 | | |
70 | 408k | max = 0; |
71 | 408k | idx = 0; |
72 | | |
73 | 3.67M | for (i = 0; i < MAX_SHORT_WINDOWS; i++) { |
74 | 3.27M | if (ptr_in[i + 1] > max) { |
75 | 762k | max = ptr_in[i + 1]; |
76 | 762k | idx = i; |
77 | 762k | } |
78 | 3.27M | } |
79 | 408k | *index = idx; |
80 | | |
81 | 408k | return max; |
82 | 408k | } |
83 | | |
84 | | static VOID iusace_blk_switch_iir_filt(const FLOAT32 *ptr_in, const FLOAT32 *ptr_iir_coeff, |
85 | | const WORD32 w, FLOAT32 *ptr_iir_states, |
86 | 3.27M | FLOAT32 *energy_accu, WORD32 block_len) { |
87 | 3.27M | FLOAT32 accu1; |
88 | | |
89 | 3.27M | WORD32 i; |
90 | | |
91 | 3.27M | FLOAT32 accu_unfilt = 0.0f; |
92 | 3.27M | FLOAT32 accu_filt = 0.0f; |
93 | 3.27M | FLOAT32 accu2, temp2, temp1; |
94 | | |
95 | 3.27M | FLOAT32 state0 = ptr_iir_states[0]; |
96 | 3.27M | FLOAT32 state1 = ptr_iir_states[1]; |
97 | | |
98 | 3.27M | FLOAT32 coeff0 = ptr_iir_coeff[0]; |
99 | 3.27M | FLOAT32 coeff1 = ptr_iir_coeff[1]; |
100 | | |
101 | 3.27M | const FLOAT32 *p_time_signal = &ptr_in[(block_len * w)]; |
102 | | |
103 | 385M | for (i = 0; i < block_len; i++) { |
104 | 381M | accu2 = iusace_fmult(state0, coeff1); |
105 | 381M | accu1 = iusace_fmult(state1, coeff0); |
106 | 381M | accu1 += accu2; |
107 | | |
108 | 381M | state0 = p_time_signal[i]; |
109 | 381M | state1 = iusace_fmult(state0, coeff1); |
110 | 381M | state1 = (state1 - accu1); |
111 | | |
112 | 381M | temp1 = iusace_fmult(state0, state0); |
113 | 381M | temp2 = iusace_fmult(state1, state1); |
114 | | |
115 | 381M | accu_unfilt = iusace_fadd(accu_unfilt, temp1); |
116 | 381M | accu_filt = iusace_fadd(accu_filt, temp2); |
117 | 381M | } |
118 | | |
119 | 3.27M | energy_accu[0] = accu_unfilt; |
120 | 3.27M | energy_accu[1] = accu_filt; |
121 | | |
122 | 3.27M | ptr_iir_states[0] = state0; |
123 | 3.27M | ptr_iir_states[1] = state1; |
124 | | |
125 | 3.27M | return; |
126 | 3.27M | } |
127 | | |
128 | | static VOID iusace_calc_window_energy(ia_block_switch_ctrl *ptr_blk_switch_ctrl, |
129 | 408k | const FLOAT32 *ptr_in, FLOAT32 *max, WORD32 ccfl) { |
130 | 408k | WORD32 w; |
131 | | |
132 | 408k | FLOAT32 energy_accu[2]; |
133 | 408k | *max = 0.0f; |
134 | | |
135 | 3.67M | for (w = 0; w < MAX_SHORT_WINDOWS; w++) { |
136 | | // block length for calculating energy is corecoder frame length / MAX_SHORT_WINDOWS |
137 | 3.27M | iusace_blk_switch_iir_filt(ptr_in, iusace_iir_hipass_coeffs, w, |
138 | 3.27M | ptr_blk_switch_ctrl->iir_states, &energy_accu[0], ccfl >> 3); |
139 | | |
140 | 3.27M | ptr_blk_switch_ctrl->win_energy[1][w] = energy_accu[0]; |
141 | 3.27M | ptr_blk_switch_ctrl->win_energy_filt[1][w] = energy_accu[1]; |
142 | | |
143 | 3.27M | if (ptr_blk_switch_ctrl->win_energy_filt[1][w] > *max) |
144 | 756k | *max = ptr_blk_switch_ctrl->win_energy_filt[1][w]; |
145 | 3.27M | } |
146 | 408k | return; |
147 | 408k | } |
148 | | |
149 | | VOID iusace_block_switching(ia_block_switch_ctrl *ptr_blk_switch_ctrl, const FLOAT32 *ptr_in, |
150 | 408k | WORD32 ccfl) { |
151 | 408k | WORD32 i; |
152 | | |
153 | 408k | FLOAT32 temp1, temp2; |
154 | 408k | FLOAT32 max; |
155 | 408k | FLOAT32 energy, energy_max; |
156 | | |
157 | 3.67M | for (i = 0; i < MAX_SHORT_WINDOWS; i++) { |
158 | 3.27M | ptr_blk_switch_ctrl->group_len[i] = 0; |
159 | 3.27M | } |
160 | | |
161 | 408k | ptr_blk_switch_ctrl->max_win_energy = |
162 | 408k | iusace_srch_max_with_idx(&ptr_blk_switch_ctrl->win_energy[0][MAX_SHORT_WINDOWS - 1], |
163 | 408k | &ptr_blk_switch_ctrl->attack_idx); |
164 | | |
165 | 408k | ptr_blk_switch_ctrl->attack_idx = ptr_blk_switch_ctrl->last_attack_idx; |
166 | 408k | ptr_blk_switch_ctrl->tot_grps_cnt = MAXIMUM_NO_OF_GROUPS; |
167 | | |
168 | 2.04M | for (i = 0; i < MAXIMUM_NO_OF_GROUPS; i++) { |
169 | 1.63M | ptr_blk_switch_ctrl->group_len[i] = |
170 | 1.63M | iusace_suggested_grouping_table[ptr_blk_switch_ctrl->attack_idx][i]; |
171 | 1.63M | } |
172 | | |
173 | 3.67M | for (i = 0; i < MAX_SHORT_WINDOWS; i++) { |
174 | 3.27M | ptr_blk_switch_ctrl->win_energy[0][i] = ptr_blk_switch_ctrl->win_energy[1][i]; |
175 | 3.27M | ptr_blk_switch_ctrl->win_energy_filt[0][i] = ptr_blk_switch_ctrl->win_energy_filt[1][i]; |
176 | 3.27M | } |
177 | | |
178 | 408k | iusace_calc_window_energy(ptr_blk_switch_ctrl, ptr_in, &max, ccfl); |
179 | | |
180 | 408k | ptr_blk_switch_ctrl->attack = FALSE; |
181 | | |
182 | 408k | energy_max = 0.0f; |
183 | | |
184 | 408k | energy = ptr_blk_switch_ctrl->win_energy_filt[0][MAX_SHORT_WINDOWS - 1]; |
185 | | |
186 | 3.67M | for (i = 0; i < MAX_SHORT_WINDOWS; i++) { |
187 | 3.27M | temp1 = iusace_fmult(ONE_MINUS_ACC_WINDOW_NRG_FAC, ptr_blk_switch_ctrl->acc_win_energy); |
188 | 3.27M | temp2 = iusace_fmult(ACC_WINDOW_NRG_FAC, energy); |
189 | 3.27M | ptr_blk_switch_ctrl->acc_win_energy = iusace_fadd(temp1, temp2); |
190 | | |
191 | 3.27M | temp1 = iusace_fmult(ptr_blk_switch_ctrl->win_energy_filt[1][i], |
192 | 3.27M | ptr_blk_switch_ctrl->inv_attack_ratio); |
193 | 3.27M | if (temp1 > ptr_blk_switch_ctrl->acc_win_energy) { |
194 | 118k | ptr_blk_switch_ctrl->attack = TRUE; |
195 | 118k | ptr_blk_switch_ctrl->last_attack_idx = i; |
196 | 118k | } |
197 | | |
198 | 3.27M | energy = ptr_blk_switch_ctrl->win_energy_filt[1][i]; |
199 | 3.27M | if (energy_max < energy) energy_max = energy; |
200 | 3.27M | } |
201 | | |
202 | 408k | if (ccfl == LEN_SUPERFRAME_768) { |
203 | 143k | energy_max = (energy_max * 4) / 3.0f; |
204 | 143k | } |
205 | 408k | if (energy_max < USAC_MIN_ATTACK_NRG) { |
206 | 190k | ptr_blk_switch_ctrl->attack = FALSE; |
207 | 190k | } |
208 | | |
209 | 408k | if ((!ptr_blk_switch_ctrl->attack) && (ptr_blk_switch_ctrl->lastattack)) { |
210 | 66.5k | if (ptr_blk_switch_ctrl->attack_idx == MAX_SHORT_WINDOWS - 1) { |
211 | 1.80k | ptr_blk_switch_ctrl->attack = TRUE; |
212 | 1.80k | } |
213 | 66.5k | ptr_blk_switch_ctrl->lastattack = FALSE; |
214 | 342k | } else { |
215 | 342k | ptr_blk_switch_ctrl->lastattack = ptr_blk_switch_ctrl->attack; |
216 | 342k | } |
217 | 408k | ptr_blk_switch_ctrl->window_seq = ptr_blk_switch_ctrl->next_win_seq; |
218 | | |
219 | 408k | if (ptr_blk_switch_ctrl->attack) { |
220 | 112k | ptr_blk_switch_ctrl->next_win_seq = EIGHT_SHORT_SEQUENCE; |
221 | 296k | } else { |
222 | 296k | ptr_blk_switch_ctrl->next_win_seq = ONLY_LONG_SEQUENCE; |
223 | 296k | } |
224 | 408k | if (ptr_blk_switch_ctrl->next_win_seq == EIGHT_SHORT_SEQUENCE) { |
225 | 112k | if (ptr_blk_switch_ctrl->window_seq == ONLY_LONG_SEQUENCE) { |
226 | 47.6k | ptr_blk_switch_ctrl->window_seq = LONG_START_SEQUENCE; |
227 | 47.6k | } |
228 | | |
229 | 112k | if (ptr_blk_switch_ctrl->window_seq == LONG_STOP_SEQUENCE) { |
230 | 21.8k | ptr_blk_switch_ctrl->window_seq = EIGHT_SHORT_SEQUENCE; |
231 | 21.8k | ptr_blk_switch_ctrl->tot_grps_cnt = 3; |
232 | 21.8k | ptr_blk_switch_ctrl->group_len[0] = 3; |
233 | 21.8k | ptr_blk_switch_ctrl->group_len[1] = 3; |
234 | 21.8k | ptr_blk_switch_ctrl->group_len[2] = 2; |
235 | 21.8k | } |
236 | 112k | } |
237 | | |
238 | 408k | if (ptr_blk_switch_ctrl->next_win_seq == ONLY_LONG_SEQUENCE) { |
239 | 296k | if (ptr_blk_switch_ctrl->window_seq == EIGHT_SHORT_SEQUENCE) { |
240 | 65.9k | ptr_blk_switch_ctrl->next_win_seq = LONG_STOP_SEQUENCE; |
241 | 65.9k | } |
242 | 296k | } |
243 | 408k | return; |
244 | 408k | } |
245 | | |
246 | | VOID iusace_sync_block_switching(ia_block_switch_ctrl *ptr_blk_switch_left_ctrl, |
247 | 233k | ia_block_switch_ctrl *ptr_blk_switch_right_ctrl) { |
248 | 233k | WORD32 i; |
249 | 233k | WORD32 patch_type = ONLY_LONG_SEQUENCE; |
250 | | |
251 | 233k | patch_type = iusace_synchronized_block_types[patch_type][ptr_blk_switch_left_ctrl->window_seq]; |
252 | 233k | patch_type = iusace_synchronized_block_types[patch_type][ptr_blk_switch_right_ctrl->window_seq]; |
253 | | |
254 | 233k | ptr_blk_switch_left_ctrl->window_seq = patch_type; |
255 | 233k | ptr_blk_switch_right_ctrl->window_seq = patch_type; |
256 | | |
257 | 233k | if (patch_type != EIGHT_SHORT_SEQUENCE) { /* tns_data_long Blocks */ |
258 | 166k | ptr_blk_switch_left_ctrl->tot_grps_cnt = 1; |
259 | 166k | ptr_blk_switch_right_ctrl->tot_grps_cnt = 1; |
260 | 166k | ptr_blk_switch_left_ctrl->group_len[0] = 1; |
261 | 166k | ptr_blk_switch_right_ctrl->group_len[0] = 1; |
262 | | |
263 | 1.33M | for (i = 1; i < MAX_SHORT_WINDOWS; i++) { |
264 | 1.16M | ptr_blk_switch_left_ctrl->group_len[i] = 0; |
265 | 1.16M | ptr_blk_switch_right_ctrl->group_len[i] = 0; |
266 | 1.16M | } |
267 | 166k | } else { /* tns_data_short Blocks */ |
268 | 67.1k | if (ptr_blk_switch_left_ctrl->max_win_energy > ptr_blk_switch_right_ctrl->max_win_energy) { |
269 | 24.6k | ptr_blk_switch_right_ctrl->tot_grps_cnt = ptr_blk_switch_left_ctrl->tot_grps_cnt; |
270 | 119k | for (i = 0; i < ptr_blk_switch_right_ctrl->tot_grps_cnt; i++) { |
271 | 95.1k | ptr_blk_switch_right_ctrl->group_len[i] = ptr_blk_switch_left_ctrl->group_len[i]; |
272 | 95.1k | } |
273 | 42.4k | } else { |
274 | 42.4k | ptr_blk_switch_left_ctrl->tot_grps_cnt = ptr_blk_switch_right_ctrl->tot_grps_cnt; |
275 | 205k | for (i = 0; i < ptr_blk_switch_left_ctrl->tot_grps_cnt; i++) { |
276 | 163k | ptr_blk_switch_left_ctrl->group_len[i] = ptr_blk_switch_right_ctrl->group_len[i]; |
277 | 163k | } |
278 | 42.4k | } |
279 | 67.1k | } |
280 | | |
281 | 233k | return; |
282 | 233k | } |