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 <math.h>
21 #include <string.h>
22 #include "ixheaac_type_def.h"
23 #include "ixheaacd_bitbuffer.h"
24 #include "ixheaacd_common_rom.h"
25 #include "ixheaacd_sbrdecsettings.h"
26 #include "ixheaacd_sbr_scale.h"
27 #include "ixheaacd_env_extr_part.h"
28 #include "ixheaacd_sbr_rom.h"
29 #include "ixheaacd_hybrid.h"
30 #include "ixheaacd_ps_dec.h"
31 #include "ixheaacd_config.h"
32 #include "ixheaacd_qmf_dec.h"
33 #include "ixheaacd_audioobjtypes.h"
34 #include "ixheaacd_mps_polyphase.h"
35 #include "ixheaacd_mps_struct_def.h"
36 #include "ixheaacd_mps_res_rom.h"
37 #include "ixheaacd_mps_aac_struct.h"
38 #include "ixheaac_constants.h"
39 #include "ixheaacd_mps_dec.h"
40 #include "ixheaacd_mps_decor.h"
41 #include "ixheaacd_mps_hybfilter.h"
42 #include "ixheaac_error_standards.h"
43 #include "ixheaac_basic_ops32.h"
44 #include "ixheaac_basic_ops40.h"
45 #include "ixheaacd_mps_macro_def.h"
46 #include "ixheaacd_mps_basic_op.h"
47
48 static const WORD32 ixheaacd_decorr_delay[] = {11, 10, 5, 2};
49 static const WORD32 ixheaacd_decorr_delay_ldmps[] = {8, 7, 2, 1};
50
51 static const WORD32 ixheaacd_qmf_split_freq_0[] = {3, 15, 24, 65};
52 static const WORD32 ixheaacd_qmf_split_freq_1[] = {3, 50, 65, 65};
53 static const WORD32 ixheaacd_qmf_split_freq_2[] = {0, 15, 65, 65};
54
55
56 static const WORD32 ixheaacd_qmf_split_freq_0_ldmps[] = {0, 15, 24, 65};
57 static const WORD32 ixheaacd_qmf_split_freq_1_ldmps[] = {0, 50, 65, 65};
58 static const WORD32 ixheaacd_qmf_split_freq_2_ldmps[] = {0, 15, 65, 65};
59
60 extern const WORD32 ixheaacd_mps_gain_set_indx[29];
61
62 static const FLOAT32
63 ixheaacd_lattice_coeff_0_filt_den_coeff[DECORR_FILT_0_ORD + 1] = {
64 1.000000f, -0.314818f, -0.256828f, -0.173641f, -0.115077f, 0.000599f,
65 0.033343f, 0.122672f, -0.356362f, 0.128058f, 0.089800f};
66 static const FLOAT32
67 ixheaacd_lattice_coeff_0_filt_num_coeff[DECORR_FILT_0_ORD + 1] = {
68 0.089800f, 0.128058f, -0.356362f, 0.122672f, 0.033343f, 0.000599f,
69 -0.115077f, -0.173641f, -0.256828f, -0.314818f, 1.000000f};
70
71 static const FLOAT32
72 ixheaacd_lattice_coeff_1_filt_den_coeff[DECORR_FILT_1_ORD + 1] = {
73 1.000000f, -0.287137f, -0.088940f, 0.123204f, -0.126111f,
74 0.064218f, 0.045768f, -0.016264f, -0.122100f};
75 static const FLOAT32
76 ixheaacd_lattice_coeff_1_filt_num_coeff[DECORR_FILT_1_ORD + 1] = {
77 -0.122100f, -0.016264f, 0.045768f, 0.064218f, -0.126111f,
78 0.123204f, -0.088940f, -0.287137f, 1.000000f};
79
80 static const FLOAT32
81 ixheaacd_lattice_coeff_2_filt_den_coeff[DECORR_FILT_2_ORD + 1] = {
82 1.000000f, 0.129403f, -0.032633f, 0.035700f};
83 static const FLOAT32
84 ixheaacd_lattice_coeff_2_filt_num_coeff[DECORR_FILT_2_ORD + 1] = {
85 0.035700f, -0.032633f, 0.129403f, 1.000000f};
86
87 static const FLOAT32
88 ixheaacd_lattice_coeff_3_filt_den_coeff[DECORR_FILT_3_ORD + 1] = {
89 1.000000f, 0.034742f, -0.013000f};
90 static const FLOAT32
91 ixheaacd_lattice_coeff_3_filt_num_coeff[DECORR_FILT_3_ORD + 1] = {
92 -0.013000f, 0.034742f, 1.000000f};
93
94 static const FLOAT32
95 ixheaacd_lattice_coeff_1_filt_num_ldmps[DECORR_FILTER_ORDER_BAND_1 + 1] = {
96 (0.3355999887f), (0.0024894588f), (-0.1572290659f), (0.2807503343f),
97 (-0.1942857355f), (0.3840600252f), (-0.4084388912f), (-0.1750483066f),
98 (0.5559588671f), (-0.4935829639f), (0.0567415841f), (-0.0658148378f),
99 (0.3378961682f), (0.2284426540f), (-0.7025330663f), (1.0000000000f)};
100
101 static const FLOAT32
102 ixheaacd_lattice_coeff_1_filt_den_ldmps[DECORR_FILTER_ORDER_BAND_1 + 1] = {
103 (1.0000000000f), (-0.7025330663f), (0.2284426540f), (0.3378961682f),
104 (-0.0658148378f), (0.0567415841f), (-0.4935829639f), (0.5559588671f),
105 (-0.1750483066f), (-0.4084388912f), (0.3840600252f), (-0.1942857355f),
106 (0.2807503343f), (-0.1572290659f), (0.0024894588f), (0.3355999887f)};
107
108 static const FLOAT32
109 ixheaacd_lattice_coeff_2_filt_num_ldmps[DECORR_FILTER_ORDER_BAND_2 + 1] = {
110 (-0.4623999894f), (0.2341193259f), (0.5163637400f), (-0.0253488291f),
111 (-0.2871030867f), (0.0153170601f), (1.0000000000f)};
112
113 static const FLOAT32
114 ixheaacd_lattice_coeff_2_filt_den_ldmps[DECORR_FILTER_ORDER_BAND_2 + 1] = {
115 (1.0000000000f), (0.0153170601f), (-0.2871030867f), (-0.0253488291f),
116 (0.5163637400f), (0.2341193259f), (-0.4623999894f)
117
118 };
119
120 static const FLOAT32
121 ixheaacd_lattice_coeff_3_filt_num_ldmps[DECORR_FILTER_ORDER_BAND_3 + 1] = {
122 (0.2468000054f), (0.0207958221f), (-0.3898491263f), (1.0000000000f)};
123
124 static const FLOAT32
125 ixheaacd_lattice_coeff_3_filt_den_ldmps[DECORR_FILTER_ORDER_BAND_3 + 1] = {
126 (1.0000000000f), (-0.3898491263f), (0.0207958221f), (0.2468000054f)};
127
128 extern WORD32
129 ixheaacd_hybrid_band_71_to_processing_band_28_map[MAX_HYBRID_BANDS_MPS];
130 extern WORD32
131 ixheaacd_hybrid_band_64_to_processing_band_23_map[MAX_HYBRID_BANDS_MPS];
132
133 static const WORD32 ixheaacd_hybrid_to_qmf_map[MAX_HYBRID_BANDS_MPS] = {
134 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10,
135 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
136 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
137 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63};
138
139 static const WORD32 ixheaacd_hybrid_to_qmf_map_ldmps[MAX_HYBRID_BANDS_MPS] = {
140 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
141 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
142 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
143 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70};
144
ixheaacd_mps_decor_filt_init(ia_mps_decor_filt_struct * self,WORD32 reverb_band,WORD32 object_type)145 static VOID ixheaacd_mps_decor_filt_init(ia_mps_decor_filt_struct *self,
146 WORD32 reverb_band,
147 WORD32 object_type) {
148 if (object_type == AOT_ER_AAC_ELD || object_type == AOT_ER_AAC_LD) {
149 switch (reverb_band) {
150 case 0:
151 self->num_len = self->den_len = DECORR_FILTER_ORDER_BAND_0 + 1;
152 self->num = NULL;
153 self->den = NULL;
154
155 break;
156 case 1:
157 self->num_len = self->den_len = DECORR_FILTER_ORDER_BAND_1 + 1;
158 self->num = ixheaacd_lattice_coeff_1_filt_num_ldmps;
159 self->den = ixheaacd_lattice_coeff_1_filt_den_ldmps;
160
161 break;
162 case 2:
163 self->num_len = self->den_len = DECORR_FILTER_ORDER_BAND_2 + 1;
164 self->num = ixheaacd_lattice_coeff_2_filt_num_ldmps;
165 self->den = ixheaacd_lattice_coeff_2_filt_den_ldmps;
166 break;
167 case 3:
168 self->num_len = self->den_len = DECORR_FILTER_ORDER_BAND_3 + 1;
169 self->num = ixheaacd_lattice_coeff_3_filt_num_ldmps;
170 self->den = ixheaacd_lattice_coeff_3_filt_den_ldmps;
171 break;
172 }
173 } else {
174 switch (reverb_band) {
175 case 0:
176 self->num_len = self->den_len = DECORR_FILT_0_ORD + 1;
177 self->num = ixheaacd_lattice_coeff_0_filt_num_coeff;
178 self->den = ixheaacd_lattice_coeff_0_filt_den_coeff;
179
180 break;
181 case 1:
182 self->num_len = self->den_len = DECORR_FILT_1_ORD + 1;
183 self->num = ixheaacd_lattice_coeff_1_filt_num_coeff;
184 self->den = ixheaacd_lattice_coeff_1_filt_den_coeff;
185
186 break;
187 case 2:
188 self->num_len = self->den_len = DECORR_FILT_2_ORD + 1;
189 self->num = ixheaacd_lattice_coeff_2_filt_num_coeff;
190 self->den = ixheaacd_lattice_coeff_2_filt_den_coeff;
191 break;
192 case 3:
193 self->num_len = self->den_len = DECORR_FILT_3_ORD + 1;
194 self->num = ixheaacd_lattice_coeff_3_filt_num_coeff;
195 self->den = ixheaacd_lattice_coeff_3_filt_den_coeff;
196 break;
197 }
198 }
199
200 self->state_len = self->num_len;
201 memset(self->state, 0,
202 sizeof(ia_cmplx_flt_struct) * (MAX_DECORR_FILTER_ORDER + 1));
203
204 return;
205 }
206
ixheaacd_mps_allpass_apply(ia_mps_decor_filt_struct * self,ia_cmplx_flt_struct * input,WORD32 len,ia_cmplx_flt_struct * output)207 static VOID ixheaacd_mps_allpass_apply(ia_mps_decor_filt_struct *self,
208 ia_cmplx_flt_struct *input, WORD32 len,
209 ia_cmplx_flt_struct *output) {
210 WORD32 i, j;
211
212 for (i = 0; i < len; i++) {
213 output[i].re = self->state[0].re + input[i].re * self->num[0];
214 output[i].im = self->state[0].im + input[i].im * self->num[0];
215
216 for (j = 1; j < self->num_len; j++) {
217 self->state[j - 1].re = self->state[j].re + self->num[j] * input[i].re -
218 self->den[j] * output[i].re;
219 self->state[j - 1].im = self->state[j].im + self->num[j] * input[i].im -
220 self->den[j] * output[i].im;
221 }
222 }
223 }
224
ixheaacd_mps_decor_energy_adjustment(ixheaacd_mps_decor_energy_adjust_filt_struct * handle,ia_cmplx_flt_struct in[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],ia_cmplx_flt_struct out[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],WORD32 time_slots,WORD32 res_bands,WORD32 ldmps_present)225 static VOID ixheaacd_mps_decor_energy_adjustment(
226 ixheaacd_mps_decor_energy_adjust_filt_struct *handle,
227 ia_cmplx_flt_struct in[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
228 ia_cmplx_flt_struct out[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
229 WORD32 time_slots, WORD32 res_bands, WORD32 ldmps_present) {
230 ixheaacd_mps_decor_energy_adjust_filt_struct *self =
231 (ixheaacd_mps_decor_energy_adjust_filt_struct *)handle;
232 FLOAT32 in_energy[MAX_PARAMETER_BANDS] = {0};
233 FLOAT32 out_energy[MAX_PARAMETER_BANDS] = {0};
234 FLOAT32 gain[MAX_PARAMETER_BANDS];
235 WORD32 i, j, k, loop_counter;
236 WORD32 *ptr_hybrid_band;
237
238 if (ldmps_present == 1)
239 ptr_hybrid_band = ixheaacd_hybrid_band_64_to_processing_band_23_map;
240 else
241 ptr_hybrid_band = ixheaacd_hybrid_band_71_to_processing_band_28_map;
242
243 WORD32 start_param_band = 0, start_bin = 0;
244
245 if (res_bands != NO_RES_BANDS) {
246 start_bin = ixheaacd_mps_gain_set_indx[res_bands];
247 start_param_band = res_bands;
248 }
249
250 for (i = 0; i < time_slots; i++) {
251 memset(in_energy, 0, sizeof(FLOAT32) * MAX_PARAMETER_BANDS);
252 memset(out_energy, 0, sizeof(FLOAT32) * MAX_PARAMETER_BANDS);
253
254 for (j = start_bin; j < self->num_bins; j++) {
255 k = ptr_hybrid_band[j];
256
257 in_energy[k] += in[i][j].re * in[i][j].re + in[i][j].im * in[i][j].im;
258 out_energy[k] +=
259 out[i][j].re * out[i][j].re + out[i][j].im * out[i][j].im;
260 }
261
262 loop_counter = MAX_PARAMETER_BANDS;
263
264 for (k = start_param_band; k < loop_counter; k++) {
265 self->smooth_in_energy[k] = self->smooth_in_energy[k] * DECOR_ALPHA +
266 in_energy[k] * ONE_MINUS_DECOR_ALPHA;
267 self->smooth_out_energy[k] = self->smooth_out_energy[k] * DECOR_ALPHA +
268 out_energy[k] * ONE_MINUS_DECOR_ALPHA;
269
270 gain[k] = 1.0f;
271
272 if (self->smooth_out_energy[k] >
273 self->smooth_in_energy[k] * DECOR_GAMMA) {
274 gain[k] = (FLOAT32)sqrt(self->smooth_in_energy[k] * DECOR_GAMMA /
275 (self->smooth_out_energy[k] + ABS_THR));
276 }
277
278 if (self->smooth_in_energy[k] >
279 self->smooth_out_energy[k] * DECOR_GAMMA) {
280 gain[k] =
281 min(2.0f, (FLOAT32)sqrt(self->smooth_in_energy[k] /
282 (DECOR_GAMMA * self->smooth_out_energy[k] +
283 ABS_THR)));
284 }
285 }
286
287 for (j = start_bin; j < self->num_bins; j++) {
288 k = ptr_hybrid_band[j];
289
290 out[i][j].re *= gain[k];
291 out[i][j].im *= gain[k];
292 }
293 }
294 }
295
ixheaacd_mps_decor_init(ia_mps_decor_struct * self,WORD32 subbands,WORD32 decor_config,WORD32 object_type)296 IA_ERRORCODE ixheaacd_mps_decor_init(ia_mps_decor_struct *self,
297 WORD32 subbands, WORD32 decor_config,
298 WORD32 object_type) {
299 WORD32 i, reverb_band;
300 const WORD32 *splitfreq;
301 const WORD32 *ptr_ixheaacd_hybrid_to_qmf_map;
302 const WORD32 *ptr_decorr_delay;
303 if (object_type == AOT_ER_AAC_ELD || object_type == AOT_ER_AAC_LD) {
304 ptr_ixheaacd_hybrid_to_qmf_map = ixheaacd_hybrid_to_qmf_map_ldmps;
305 ptr_decorr_delay = ixheaacd_decorr_delay_ldmps;
306 switch (decor_config) {
307 case 0:
308 splitfreq = ixheaacd_qmf_split_freq_0_ldmps;
309 break;
310 case 1:
311 splitfreq = ixheaacd_qmf_split_freq_1_ldmps;
312 break;
313 case 2:
314 splitfreq = ixheaacd_qmf_split_freq_2_ldmps;
315 break;
316 default:
317 return IA_FATAL_ERROR;
318 }
319 } else {
320 ptr_ixheaacd_hybrid_to_qmf_map = ixheaacd_hybrid_to_qmf_map;
321 ptr_decorr_delay = ixheaacd_decorr_delay;
322 switch (decor_config) {
323 case 0:
324 splitfreq = ixheaacd_qmf_split_freq_0;
325 break;
326 case 1:
327 splitfreq = ixheaacd_qmf_split_freq_1;
328 break;
329 case 2:
330 splitfreq = ixheaacd_qmf_split_freq_2;
331 break;
332 default:
333 return IA_FATAL_ERROR;
334 }
335 }
336
337 self->num_bins = subbands;
338 if (self->num_bins > MAX_HYBRID_BANDS_MPS) return IA_FATAL_ERROR;
339
340 for (i = 0; i < self->num_bins; i++) {
341 reverb_band = 0;
342 while ((reverb_band < 3) &&
343 (ptr_ixheaacd_hybrid_to_qmf_map[i] >= (splitfreq[reverb_band] - 1)))
344 reverb_band++;
345
346 self->delay_sample_count[i] = ptr_decorr_delay[reverb_band];
347 ixheaacd_mps_decor_filt_init(&self->filter[i], reverb_band, object_type);
348 }
349
350 self->decor_nrg_smooth.num_bins = self->num_bins;
351
352 return IA_NO_ERROR;
353 }
354
ixheaacd_mps_decor_apply(ia_mps_decor_struct * self,ia_cmplx_flt_struct in[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],ia_cmplx_flt_struct out[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],WORD32 length,WORD32 res_bands,WORD32 ldmps_present)355 VOID ixheaacd_mps_decor_apply(
356 ia_mps_decor_struct *self,
357 ia_cmplx_flt_struct in[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
358 ia_cmplx_flt_struct out[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
359 WORD32 length, WORD32 res_bands, WORD32 ldmps_present) {
360 WORD32 idx, sb_sample, index = 0;
361
362 ia_cmplx_flt_struct scratch[MAX_TIME_SLOTS];
363
364 if (res_bands != NO_RES_BANDS) index = ixheaacd_mps_gain_set_indx[res_bands];
365
366 for (idx = index; idx < self->num_bins; idx++) {
367 for (sb_sample = 0; sb_sample < length; sb_sample++) {
368 self->decor_delay_buffer[idx][self->delay_sample_count[idx] + sb_sample]
369 .re = in[sb_sample][idx].re;
370 self->decor_delay_buffer[idx][self->delay_sample_count[idx] + sb_sample]
371 .im = in[sb_sample][idx].im;
372 }
373 ixheaacd_mps_allpass_apply(&self->filter[idx],
374 self->decor_delay_buffer[idx], length, scratch);
375
376 for (sb_sample = 0; sb_sample < length; sb_sample++) {
377 out[sb_sample][idx].re = scratch[sb_sample].re;
378 out[sb_sample][idx].im = scratch[sb_sample].im;
379 }
380
381 for (sb_sample = 0; sb_sample < self->delay_sample_count[idx];
382 sb_sample++) {
383 self->decor_delay_buffer[idx][sb_sample].re =
384 self->decor_delay_buffer[idx][length + sb_sample].re;
385 self->decor_delay_buffer[idx][sb_sample].im =
386 self->decor_delay_buffer[idx][length + sb_sample].im;
387 }
388 }
389
390 ixheaacd_mps_decor_energy_adjustment(&self->decor_nrg_smooth, in, out, length,
391 res_bands,
392 ldmps_present);
393 }
394
ixheaacd_convert_lattice_coefs_complex(WORD32 const order,WORD32 const * const rfc_real,WORD32 const * const rfc_imag,WORD32 * const apar_real,WORD32 * const apar_imag)395 static VOID ixheaacd_convert_lattice_coefs_complex(WORD32 const order,
396 WORD32 const *const rfc_real,
397 WORD32 const *const rfc_imag,
398 WORD32 *const apar_real,
399 WORD32 *const apar_imag) {
400 WORD32 i, j;
401 WORD32 tmp_real[MAX_DECORR_FILTER_ORDER + 1];
402 WORD32 tmp_imag[MAX_DECORR_FILTER_ORDER + 1];
403 WORD64 temp;
404
405 apar_real[0] = 32768;
406 apar_imag[0] = 0;
407
408 for (i = 0; i < order; i++) {
409 apar_real[i + 1] = rfc_real[i];
410 apar_imag[i + 1] = rfc_imag[i];
411 for (j = 0; j < i; j++) {
412 temp = (WORD64)((WORD64)rfc_real[i] * (WORD64)tmp_real[i - j - 1] +
413 (WORD64)rfc_imag[i] * (WORD64)tmp_imag[i - j - 1]);
414 temp >>= 15;
415 apar_real[j + 1] = ixheaac_add32(tmp_real[j], (WORD32)temp);
416
417 temp = (WORD64)((WORD64)rfc_real[i] * (WORD64)tmp_imag[i - j - 1] +
418 (WORD64)rfc_imag[i] * (WORD64)tmp_real[i - j - 1]);
419 temp >>= 15;
420 apar_imag[j + 1] = ixheaac_sub32(tmp_imag[j], (WORD32)temp);
421 }
422 for (j = 0; j <= i; j++) {
423 tmp_real[j] = apar_real[j + 1];
424 tmp_imag[j] = apar_imag[j + 1];
425 }
426 }
427 }
428
ixheaacd_decorr_filt_create(ia_mps_dec_decorr_filter_instance_struct * self,WORD32 const decorr_seed,WORD32 const qmf_band,WORD32 const reverb_band,WORD32 const dec_type,ia_mps_dec_mps_tables_struct * ia_mps_dec_mps_table)429 static IA_ERRORCODE ixheaacd_decorr_filt_create(
430 ia_mps_dec_decorr_filter_instance_struct *self, WORD32 const decorr_seed,
431 WORD32 const qmf_band, WORD32 const reverb_band, WORD32 const dec_type,
432 ia_mps_dec_mps_tables_struct *ia_mps_dec_mps_table) {
433 IA_ERRORCODE error_code = IA_NO_ERROR;
434 WORD32 i;
435 const WORD32 *lattice_coeff = NULL;
436 WORD32 lattice_coeff_real[MAX_DECORR_FILTER_ORDER];
437 WORD32 lattice_coeff_imag[MAX_DECORR_FILTER_ORDER];
438 WORD32 temp_1;
439
440 if (self == NULL) {
441 error_code = IA_FATAL_ERROR;
442 }
443
444 if (error_code == IA_NO_ERROR) {
445 switch (reverb_band) {
446 case REVERB_BAND_0:
447 self->num_length = self->den_length = DECORR_FILTER_ORDER_BAND_0 + 1;
448 lattice_coeff = &(ia_mps_dec_mps_table->decor_table_ptr
449 ->lattice_coeff_0[decorr_seed][0]);
450 break;
451 case REVERB_BAND_1:
452 self->num_length = self->den_length = DECORR_FILTER_ORDER_BAND_1 + 1;
453 lattice_coeff = &(ia_mps_dec_mps_table->decor_table_ptr
454 ->lattice_coeff_1[decorr_seed][0]);
455 break;
456 case REVERB_BAND_2:
457 self->num_length = self->den_length = DECORR_FILTER_ORDER_BAND_2 + 1;
458 lattice_coeff = &(ia_mps_dec_mps_table->decor_table_ptr
459 ->lattice_coeff_2[decorr_seed][0]);
460 break;
461 case REVERB_BAND_3:
462 self->num_length = self->den_length = DECORR_FILTER_ORDER_BAND_3 + 1;
463 lattice_coeff = &(ia_mps_dec_mps_table->decor_table_ptr
464 ->lattice_coeff_3[decorr_seed][0]);
465 break;
466 default:
467 return IA_FATAL_ERROR;
468 }
469 self->state_length = (self->num_length > self->den_length)
470 ? self->num_length
471 : self->den_length;
472 }
473
474 if (error_code == IA_NO_ERROR) {
475 const WORD32 *cos_tab =
476 ia_mps_dec_mps_table->hybrid_table_ptr->cosine_array;
477 const WORD32 *sin_tab = ia_mps_dec_mps_table->hybrid_table_ptr->sine_array;
478
479 if (dec_type == 1) {
480 for (i = 0; i < self->num_length - 1; i++) {
481 temp_1 = (qmf_band * ia_mps_dec_mps_table->decor_table_ptr
482 ->lattice_delta_phi[decorr_seed][i]) >>
483 1;
484 lattice_coeff_real[i] = ixheaacd_mps_mult32_shr_15(
485 ixheaacd_mps_cos(temp_1, cos_tab), lattice_coeff[i]);
486 lattice_coeff_imag[i] = ixheaacd_mps_mult32_shr_15(
487 ixheaacd_mps_sin(temp_1, sin_tab), lattice_coeff[i]);
488 }
489
490 ixheaacd_convert_lattice_coefs_complex(
491 self->num_length - 1, lattice_coeff_real, lattice_coeff_imag,
492 self->denominator_real, self->denominator_imag);
493 for (i = 0; i < self->num_length; i++) {
494 self->numerator_real[i] =
495 self->denominator_real[self->num_length - 1 - i];
496 self->numerator_imag[i] =
497 -self->denominator_imag[self->num_length - 1 - i];
498 }
499
500 self->complex = 1;
501 } else {
502 switch (reverb_band) {
503 case REVERB_BAND_0:
504 self->denominator_real = &(ia_mps_dec_mps_table->decor_table_ptr
505 ->den_coef_0[decorr_seed][0]);
506 break;
507 case REVERB_BAND_1:
508 self->denominator_real = &(ia_mps_dec_mps_table->decor_table_ptr
509 ->den_coef_1[decorr_seed][0]);
510 break;
511 case REVERB_BAND_2:
512 self->denominator_real = &(ia_mps_dec_mps_table->decor_table_ptr
513 ->den_coef_2[decorr_seed][0]);
514 break;
515 case REVERB_BAND_3:
516 self->denominator_real = &(ia_mps_dec_mps_table->decor_table_ptr
517 ->den_coef_3[decorr_seed][0]);
518 break;
519 default:
520 return IA_FATAL_ERROR;
521 }
522
523 for (i = 0; i < self->num_length; i++) {
524 self->numerator_real[i] =
525 self->denominator_real[self->num_length - 1 - i];
526 }
527 self->complex = 0;
528 }
529 }
530 return error_code;
531 }
532
ixheaacd_decorr_filt_apply(ia_mps_dec_decorr_filter_instance_struct * const self,WORD32 const length,WORD32 const * const input_real,WORD32 const * const input_imag,WORD32 * const p_output_real,WORD32 * const p_output_imag)533 static VOID ixheaacd_decorr_filt_apply(
534 ia_mps_dec_decorr_filter_instance_struct *const self, WORD32 const length,
535 WORD32 const *const input_real, WORD32 const *const input_imag,
536 WORD32 *const p_output_real, WORD32 *const p_output_imag) {
537 WORD32 temp_1, temp_2, temp3, temp4;
538 WORD32 temp5, temp6, temp7, temp8;
539 WORD32 *state_real, *state_imag;
540 WORD32 *numerator_real, *denominator_real;
541 WORD32 *output_real = p_output_real;
542 WORD32 *output_imag = p_output_imag;
543
544 WORD32 common_part;
545 WORD32 i;
546 WORD32 j;
547
548 common_part = self->num_length;
549 state_real = self->state_real;
550 state_imag = self->state_imag;
551 numerator_real = self->numerator_real;
552 denominator_real = self->denominator_real;
553
554 {
555 for (i = 0; i < length; i++) {
556 {
557 temp5 = input_real[i];
558 temp6 = input_imag[i];
559
560 temp_1 = ixheaacd_mps_mult32_shr_14(temp5, numerator_real[0]);
561 temp_2 = ixheaacd_mps_mult32_shr_14(temp6, numerator_real[0]);
562
563 *output_real = temp_1 + state_real[0];
564 *output_imag = temp_2 + state_imag[0];
565
566 temp7 = *output_real;
567 temp8 = *output_imag;
568
569 output_real += MAX_HYBRID_BANDS;
570 output_imag += MAX_HYBRID_BANDS;
571 for (j = 1; j < common_part; j++) {
572 temp_1 = ixheaacd_mps_mult32x16_shr_16(temp5, numerator_real[j]);
573 temp3 = ixheaacd_mps_mult32x16_shr_16(temp6, numerator_real[j]);
574 temp_2 = ixheaacd_mps_mult32x16_shr_16(temp7, denominator_real[j]);
575 temp4 = ixheaacd_mps_mult32x16_shr_16(temp8, denominator_real[j]);
576 temp_1 -= temp_2;
577
578 state_real[j - 1] = state_real[j] + (temp_1 << 2);
579 temp3 -= temp4;
580
581 state_imag[j - 1] = state_imag[j] + (temp3 << 2);
582 }
583 }
584 }
585 }
586 }
587
ixheaacd_ducker_apply_71(ia_mps_dec_ducker_interface * const face,WORD32 const time_slots,WORD32 const * input_real,WORD32 const * input_imag,WORD32 * output_real,WORD32 * output_imag,ia_mps_dec_mps_tables_struct * ia_mps_dec_mps_table_ptr,VOID * scratch)588 static VOID ixheaacd_ducker_apply_71(
589 ia_mps_dec_ducker_interface *const face, WORD32 const time_slots,
590 WORD32 const *input_real, WORD32 const *input_imag, WORD32 *output_real,
591 WORD32 *output_imag, ia_mps_dec_mps_tables_struct *ia_mps_dec_mps_table_ptr,
592 VOID *scratch) {
593 ia_mps_dec_duck_instance_struct *self =
594 (ia_mps_dec_duck_instance_struct *)&face[1];
595 WORD32 *duck_gain;
596 WORD32 gain;
597 WORD16 qgain;
598 WORD64 direct_nrg[28];
599 WORD64 reverb_nrg[28];
600 WORD16 *q_duck_gain;
601 WORD32 ts;
602 WORD32 qs;
603 WORD32 pb;
604 WORD16 qtemp1, qtemp2, qtemp3;
605 WORD32 temp_1, temp_2, temp3;
606 const WORD32 *p_input_real;
607 const WORD32 *p_input_imag;
608 const WORD32 *hybrid_2_param_28 =
609 ia_mps_dec_mps_table_ptr->m1_m2_table_ptr->hybrid_2_param_28;
610 const WORD32 *sqrt_tab = ia_mps_dec_mps_table_ptr->common_table_ptr->sqrt_tab;
611 WORD32 *smooth_direct_nrg = self->smooth_direct_nrg;
612 WORD16 *q_smooth_direct_nrg = self->q_smooth_direct_nrg;
613
614 WORD32 *smooth_reverb_nrg = self->smooth_reverb_nrg;
615 WORD16 *q_smooth_reverb_nrg = self->q_smooth_reverb_nrg;
616
617 WORD32 parameter_bands = self->parameter_bands;
618
619 WORD32 *p_output_real, *p_output_imag;
620
621 WORD32 num_bands_2 = self->hybrid_bands;
622 WORD32 v1, v2, v3, v4;
623 WORD16 one_by_5 = ONE_BY_FIVE_Q16;
624
625 duck_gain = scratch;
626 q_duck_gain = (WORD16 *)scratch + IXHEAAC_GET_SIZE_ALIGNED_TYPE(
627 PARAMETER_BANDSX2, sizeof(*q_duck_gain), BYTE_ALIGN_8);
628
629 p_input_real = input_real;
630 p_input_imag = input_imag;
631
632 p_output_real = output_real;
633 p_output_imag = output_imag;
634
635 for (ts = 0; ts < time_slots; ts++) {
636 memset(direct_nrg, 0, sizeof(direct_nrg));
637 memset(reverb_nrg, 0, sizeof(reverb_nrg));
638
639 for (qs = 0; qs < 55; qs++) {
640 v1 = p_input_real[qs];
641 v2 = p_input_imag[qs];
642 v3 = p_output_real[qs];
643 v4 = p_output_imag[qs];
644
645 pb = hybrid_2_param_28[qs];
646 direct_nrg[pb] +=
647 (WORD64)((WORD64)v1 * (WORD64)v1) + (WORD64)((WORD64)v2 * (WORD64)v2);
648 reverb_nrg[pb] +=
649 (WORD64)((WORD64)v3 * (WORD64)v3) + (WORD64)((WORD64)v4 * (WORD64)v4);
650 }
651
652 for (; qs < num_bands_2; qs++) {
653 v1 = p_input_real[qs];
654 v2 = p_input_imag[qs];
655 v3 = p_output_real[qs];
656 v4 = p_output_imag[qs];
657
658 direct_nrg[27] +=
659 (WORD64)((WORD64)v1 * (WORD64)v1) + (WORD64)((WORD64)v2 * (WORD64)v2);
660 reverb_nrg[27] +=
661 (WORD64)((WORD64)v3 * (WORD64)v3) + (WORD64)((WORD64)v4 * (WORD64)v4);
662 }
663
664 for (pb = 0; pb < parameter_bands; pb++) {
665 WORD16 qtemp, qtemp_1;
666 temp_1 = ixheaacd_mps_narrow(direct_nrg[pb], &qtemp);
667
668 temp_2 = smooth_direct_nrg[pb] << 2;
669 temp3 =
670 ixheaacd_mps_add32(temp_2, temp_1, &(q_smooth_direct_nrg[pb]), qtemp);
671 smooth_direct_nrg[pb] = ixheaacd_mps_mult32x16_shr_16(temp3, one_by_5);
672
673 temp_1 = ixheaacd_mps_narrow(reverb_nrg[pb], &qtemp);
674 temp_2 = smooth_reverb_nrg[pb] << 2;
675
676 temp3 =
677 ixheaacd_mps_add32(temp_2, temp_1, &(q_smooth_reverb_nrg[pb]), qtemp);
678 smooth_reverb_nrg[pb] = ixheaacd_mps_mult32x16_shr_16(temp3, one_by_5);
679
680 qtemp1 = q_smooth_reverb_nrg[pb] - 1;
681 temp_1 = (smooth_reverb_nrg[pb] >> 2) * 3;
682 qtemp = q_smooth_direct_nrg[pb];
683 temp3 = smooth_direct_nrg[pb];
684
685 if (ixheaacd_mps_comp(temp3, temp_1, &qtemp, qtemp1)) {
686 temp_2 = ixheaacd_mps_div_32(temp3, temp_1, &qtemp2);
687 qtemp2 = qtemp2 + qtemp - qtemp1;
688 if (temp_1 == 0) {
689 qtemp2 = qtemp;
690 }
691 temp3 = (qtemp2) > 28 ? MAX_32 : 4 << qtemp2;
692
693 if (temp_2 > temp3) {
694 *duck_gain = (ONE_IN_Q15 - 1);
695 *q_duck_gain++ = 14;
696 } else {
697 *duck_gain = ixheaacd_mps_sqrt(temp_2, &qtemp2, sqrt_tab);
698 *q_duck_gain++ = qtemp2;
699 }
700 duck_gain++;
701 continue;
702 }
703
704 *duck_gain = ONE_IN_Q14 - 1;
705
706 qtemp = q_smooth_direct_nrg[pb] - 1;
707 temp_1 = (smooth_direct_nrg[pb] >> 2) * 3;
708
709 qtemp_1 = q_smooth_reverb_nrg[pb];
710 temp_2 = smooth_reverb_nrg[pb];
711 if (ixheaacd_mps_comp(temp_2, temp_1, &(qtemp_1), qtemp)) {
712 temp3 = ixheaacd_mps_div_32(temp_1, temp_2, &qtemp3);
713 qtemp3 = qtemp3 + qtemp - qtemp_1;
714
715 *duck_gain = ixheaacd_mps_sqrt(temp3, &qtemp3, sqrt_tab);
716 *q_duck_gain = qtemp3;
717 }
718
719 duck_gain++;
720 q_duck_gain++;
721 }
722 duck_gain -= parameter_bands;
723 q_duck_gain -= parameter_bands;
724
725 for (qs = 0; qs < 55; qs++) {
726 pb = hybrid_2_param_28[qs];
727 gain = duck_gain[pb];
728 if (gain == 16383) {
729 continue;
730 }
731 qgain = q_duck_gain[pb];
732 p_output_real[qs] =
733 ixheaacd_mps_mult32_shr_n(p_output_real[qs], gain, qgain);
734 p_output_imag[qs] =
735 ixheaacd_mps_mult32_shr_n(p_output_imag[qs], gain, qgain);
736 }
737
738 gain = duck_gain[27];
739
740 if (gain != 16383) {
741 qgain = q_duck_gain[27];
742 for (; qs < num_bands_2; qs++) {
743 p_output_real[qs] =
744 ixheaacd_mps_mult32_shr_n(p_output_real[qs], gain, qgain);
745 p_output_imag[qs] =
746 ixheaacd_mps_mult32_shr_n(p_output_imag[qs], gain, qgain);
747 }
748 }
749
750 p_input_real += MAX_HYBRID_BANDS;
751 p_input_imag += MAX_HYBRID_BANDS;
752
753 p_output_real += MAX_HYBRID_BANDS;
754 p_output_imag += MAX_HYBRID_BANDS;
755 }
756 }
757
ixheaacd_ducker_apply(ia_mps_dec_ducker_interface * const face,WORD32 const time_slots,WORD32 const * input_real,WORD32 const * input_imag,WORD32 * output_real,WORD32 * output_imag,ia_mps_dec_mps_tables_struct * ia_mps_dec_mps_table_ptr,VOID * scratch)758 static VOID ixheaacd_ducker_apply(
759 ia_mps_dec_ducker_interface *const face, WORD32 const time_slots,
760 WORD32 const *input_real, WORD32 const *input_imag, WORD32 *output_real,
761 WORD32 *output_imag, ia_mps_dec_mps_tables_struct *ia_mps_dec_mps_table_ptr,
762 VOID *scratch) {
763 ia_mps_dec_duck_instance_struct *self =
764 (ia_mps_dec_duck_instance_struct *)&face[1];
765 WORD32 *duck_gain;
766 WORD32 gain;
767 WORD16 qgain;
768 WORD64 direct_nrg[28];
769 WORD64 reverb_nrg[28];
770 WORD16 *q_duck_gain;
771 WORD32 ts;
772 WORD32 qs;
773 WORD32 pb;
774 WORD16 qtemp1, qtemp2, qtemp3;
775 WORD32 temp_1, temp_2, temp3;
776 const WORD32 *p_input_real;
777 const WORD32 *p_input_imag;
778 const WORD32 *hybrid_2_param_28 =
779 ia_mps_dec_mps_table_ptr->m1_m2_table_ptr->hybrid_2_param_28;
780 const WORD32 *sqrt_tab = ia_mps_dec_mps_table_ptr->common_table_ptr->sqrt_tab;
781 WORD32 *smooth_direct_nrg = self->smooth_direct_nrg;
782 WORD16 *q_smooth_direct_nrg = self->q_smooth_direct_nrg;
783
784 WORD32 *smooth_reverb_nrg = self->smooth_reverb_nrg;
785 WORD16 *q_smooth_reverb_nrg = self->q_smooth_reverb_nrg;
786
787 WORD32 parameter_bands = self->parameter_bands;
788
789 WORD32 *p_output_real, *p_output_imag;
790
791 WORD32 num_bands_2 = self->hybrid_bands;
792 WORD32 v1, v2, v3, v4;
793 WORD16 one_by_5 = ONE_BY_FIVE_Q16;
794
795 duck_gain = scratch;
796 q_duck_gain = (WORD16 *)scratch + IXHEAAC_GET_SIZE_ALIGNED_TYPE(
797 PARAMETER_BANDSX2, sizeof(*q_duck_gain), BYTE_ALIGN_8);
798
799 p_input_real = input_real;
800 p_input_imag = input_imag;
801
802 p_output_real = output_real;
803 p_output_imag = output_imag;
804
805 for (ts = 0; ts < time_slots; ts++) {
806 memset(direct_nrg, 0, sizeof(direct_nrg));
807 memset(reverb_nrg, 0, sizeof(reverb_nrg));
808
809 for (qs = 0; qs < num_bands_2; qs++) {
810 v1 = p_input_real[qs];
811 v2 = p_input_imag[qs];
812 v3 = p_output_real[qs];
813 v4 = p_output_imag[qs];
814
815 pb = hybrid_2_param_28[qs];
816 direct_nrg[pb] +=
817 (WORD64)((WORD64)v1 * (WORD64)v1) + (WORD64)((WORD64)v2 * (WORD64)v2);
818 reverb_nrg[pb] +=
819 (WORD64)((WORD64)v3 * (WORD64)v3) + (WORD64)((WORD64)v4 * (WORD64)v4);
820 }
821
822 for (pb = 0; pb < parameter_bands; pb++) {
823 WORD16 qtemp, qtemp_1;
824 temp_1 = ixheaacd_mps_narrow(direct_nrg[pb], &qtemp);
825 temp_2 = smooth_direct_nrg[pb] << 2;
826 temp3 =
827 ixheaacd_mps_add32(temp_2, temp_1, &(q_smooth_direct_nrg[pb]), qtemp);
828 smooth_direct_nrg[pb] = ixheaacd_mps_mult32x16_shr_16(temp3, one_by_5);
829
830 temp_1 = ixheaacd_mps_narrow(reverb_nrg[pb], &qtemp);
831 temp_2 = smooth_reverb_nrg[pb] << 2;
832
833 temp3 =
834 ixheaacd_mps_add32(temp_2, temp_1, &(q_smooth_reverb_nrg[pb]), qtemp);
835 smooth_reverb_nrg[pb] = ixheaacd_mps_mult32x16_shr_16(temp3, one_by_5);
836
837 qtemp1 = q_smooth_reverb_nrg[pb] - 1;
838 temp_1 = (smooth_reverb_nrg[pb] >> 2) * 3;
839 qtemp = q_smooth_direct_nrg[pb];
840 temp3 = smooth_direct_nrg[pb];
841
842 if (ixheaacd_mps_comp(temp3, temp_1, &qtemp, qtemp1)) {
843 temp_2 = ixheaacd_mps_div_32(temp3, temp_1, &qtemp2);
844 qtemp2 = qtemp2 + qtemp - qtemp1;
845 if (temp_1 == 0) {
846 qtemp2 = qtemp;
847 }
848 temp3 = qtemp2 > 28 ? MAX_32 : 4 << qtemp2;
849
850 if (temp_2 > temp3) {
851 *duck_gain = 32767;
852 *q_duck_gain++ = 14;
853 } else {
854 *duck_gain = ixheaacd_mps_sqrt(temp_2, &qtemp2, sqrt_tab);
855 *q_duck_gain++ = qtemp2;
856 }
857 duck_gain++;
858 continue;
859 }
860
861 *duck_gain = 16383;
862
863 qtemp = q_smooth_direct_nrg[pb] - 1;
864 temp_1 = (smooth_direct_nrg[pb] >> 2) * 3;
865
866 qtemp_1 = q_smooth_reverb_nrg[pb];
867 temp_2 = smooth_reverb_nrg[pb];
868 if (ixheaacd_mps_comp(temp_2, temp_1, &(qtemp_1), qtemp)) {
869 temp3 = ixheaacd_mps_div_32(temp_1, temp_2, &qtemp3);
870 qtemp3 = qtemp3 + qtemp - qtemp_1;
871
872 *duck_gain = ixheaacd_mps_sqrt(temp3, &qtemp3, sqrt_tab);
873 *q_duck_gain = qtemp3;
874 }
875
876 duck_gain++;
877 q_duck_gain++;
878 }
879
880 duck_gain -= parameter_bands;
881 q_duck_gain -= parameter_bands;
882
883 for (qs = 0; qs < num_bands_2; qs++) {
884 pb = hybrid_2_param_28[qs];
885 gain = duck_gain[pb];
886 if (gain == 16383) {
887 continue;
888 }
889 qgain = q_duck_gain[pb];
890 p_output_real[qs] =
891 ixheaacd_mps_mult32_shr_n(p_output_real[qs], gain, qgain);
892 p_output_imag[qs] =
893 ixheaacd_mps_mult32_shr_n(p_output_imag[qs], gain, qgain);
894 }
895
896 p_input_real += MAX_HYBRID_BANDS;
897 p_input_imag += MAX_HYBRID_BANDS;
898
899 p_output_real += MAX_HYBRID_BANDS;
900 p_output_imag += MAX_HYBRID_BANDS;
901 }
902 }
903
ixheaacd_ducker_create(ia_mps_dec_ducker_interface * const face,WORD32 const hybrid_bands)904 static IA_ERRORCODE ixheaacd_ducker_create(
905 ia_mps_dec_ducker_interface *const face, WORD32 const hybrid_bands) {
906 ia_mps_dec_duck_instance_struct *self = NULL;
907 IA_ERRORCODE error_code = IA_NO_ERROR;
908 WORD32 i;
909
910 if (face == NULL) {
911 error_code = IA_FATAL_ERROR;
912 }
913
914 if (error_code == IA_NO_ERROR) {
915 self = (ia_mps_dec_duck_instance_struct *)&face[1];
916
917 self->hybrid_bands = hybrid_bands;
918 self->parameter_bands = MAX_PARAMETER_BANDS;
919
920 self->alpha = DUCK_ALPHA;
921 self->one_minus_alpha = DUCK_ONEMINUSALPHA;
922 self->gamma = DUCK_GAMMA;
923 self->abs_thr = ABS_THR_FIX;
924 self->hybrid_bands = hybrid_bands;
925 self->parameter_bands = MAX_PARAMETER_BANDS;
926
927 self->qalpha = 15;
928 self->qgamma = 14;
929
930 if (hybrid_bands == 71)
931 face->apply = ixheaacd_ducker_apply_71;
932 else
933 face->apply = ixheaacd_ducker_apply;
934
935 for (i = 0; i < MAX_PARAMETER_BANDS; i++) {
936 self->q_smooth_direct_nrg[i] = 31;
937 self->q_smooth_reverb_nrg[i] = 31;
938 }
939 }
940
941 return error_code;
942 }
943
ixheaacd_decorr_create(ia_mps_dec_decorr_dec_handle self,WORD32 subbands,WORD32 seed,WORD32 dec_type,WORD32 decorr_config,ia_mps_dec_mps_tables_struct * ia_mps_dec_mps_table_ptr)944 IA_ERRORCODE ixheaacd_decorr_create(
945 ia_mps_dec_decorr_dec_handle self, WORD32 subbands, WORD32 seed,
946 WORD32 dec_type, WORD32 decorr_config,
947 ia_mps_dec_mps_tables_struct *ia_mps_dec_mps_table_ptr) {
948 IA_ERRORCODE error_code = IA_NO_ERROR;
949 WORD32 i, reverb_band;
950
951 const WORD32 *rev_split_freq;
952
953 switch (decorr_config) {
954 case DECOR_CONFIG_0:
955 rev_split_freq =
956 ia_mps_dec_mps_table_ptr->decor_table_ptr->rev_table.rev_split_freq_0;
957 break;
958 case DECOR_CONFIG_1:
959 rev_split_freq =
960 ia_mps_dec_mps_table_ptr->decor_table_ptr->rev_table.rev_split_freq_1;
961 break;
962 case DECOR_CONFIG_2:
963 rev_split_freq =
964 ia_mps_dec_mps_table_ptr->decor_table_ptr->rev_table.rev_split_freq_2;
965 break;
966 default:
967 return IA_FATAL_ERROR;
968 break;
969 }
970
971 if (error_code == IA_NO_ERROR) {
972 self->decorr_seed = seed;
973 self->numbins = subbands;
974
975 for (i = 0; i < self->numbins; i++) {
976 reverb_band = 0;
977 while ((reverb_band < 3) &&
978 (ixheaacd_get_qmf_sb(
979 i, ia_mps_dec_mps_table_ptr->mdct2qmf_table_ptr) >=
980 (rev_split_freq[reverb_band] - 1)))
981 reverb_band++;
982
983 {
984 self->no_sample_delay[i] =
985 ia_mps_dec_mps_table_ptr->decor_table_ptr->rev_table
986 .rev_delay[reverb_band][self->decorr_seed];
987
988 error_code = ixheaacd_decorr_filt_create(
989 self->filter[i], self->decorr_seed,
990 ixheaacd_get_qmf_sb(i,
991 ia_mps_dec_mps_table_ptr->mdct2qmf_table_ptr),
992 reverb_band, dec_type, ia_mps_dec_mps_table_ptr);
993 }
994 }
995
996 if (error_code == IA_NO_ERROR) {
997 error_code = ixheaacd_ducker_create(self->ducker, self->numbins);
998 }
999 }
1000 return (error_code);
1001 }
1002
ixheaacd_decorr_apply(ia_heaac_mps_state_struct * pstr_mps_state,WORD32 length,WORD32 * input_real,WORD32 * input_imag,WORD32 * output_real,WORD32 * output_imag,WORD32 index)1003 VOID ixheaacd_decorr_apply(ia_heaac_mps_state_struct *pstr_mps_state, WORD32 length,
1004 WORD32 *input_real, WORD32 *input_imag,
1005 WORD32 *output_real, WORD32 *output_imag,
1006 WORD32 index) {
1007 WORD32 l = index - pstr_mps_state->num_direct_signals;
1008 ia_mps_dec_decorr_dec_handle decorr_ptr = pstr_mps_state->ap_decor[l];
1009 WORD32 idx, sb_sample;
1010
1011 WORD32 *p_input_real, *p_input_re, *p_input_imag, *p_input_im;
1012 WORD32 *p_output_real, *p_output_imag, *p_output_re, *p_output_im;
1013 WORD32 *delay_buffer_real, *delay_buffer_imag;
1014 WORD32 length1;
1015 VOID *free_scratch;
1016
1017 free_scratch = (WORD32 *)pstr_mps_state->mps_scratch_mem_v +
1018 IXHEAAC_GET_SIZE_ALIGNED_TYPE(MAX_TIMESLOTSX2, sizeof(WORD32), BYTE_ALIGN_8);
1019
1020 if (decorr_ptr != NULL) {
1021 p_input_real = input_real;
1022 p_input_imag = input_imag;
1023
1024 p_output_real = output_real;
1025 p_output_imag = output_imag;
1026 for (idx = 0; idx < decorr_ptr->numbins; idx++) {
1027 p_input_re = p_input_real;
1028 p_input_im = p_input_imag;
1029
1030 p_output_re = p_output_real;
1031 p_output_im = p_output_imag;
1032
1033 length1 = length - decorr_ptr->no_sample_delay[idx];
1034 delay_buffer_real =
1035 &decorr_ptr->delay_buffer_real[idx][decorr_ptr->no_sample_delay[idx]];
1036 delay_buffer_imag =
1037 &decorr_ptr->delay_buffer_imag[idx][decorr_ptr->no_sample_delay[idx]];
1038 for (sb_sample = 0; sb_sample < length1; sb_sample++) {
1039 delay_buffer_real[sb_sample] = *p_input_re;
1040 *delay_buffer_imag++ = *p_input_im;
1041 p_input_re += MAX_HYBRID_BANDS;
1042 p_input_im += MAX_HYBRID_BANDS;
1043 }
1044 {
1045 ixheaacd_decorr_filt_apply(
1046 decorr_ptr->filter[idx], length, decorr_ptr->delay_buffer_real[idx],
1047 decorr_ptr->delay_buffer_imag[idx], p_output_re++, p_output_im++);
1048 }
1049
1050 length1 = decorr_ptr->no_sample_delay[idx];
1051 delay_buffer_real = &decorr_ptr->delay_buffer_real[idx][0];
1052 delay_buffer_imag = &decorr_ptr->delay_buffer_imag[idx][0];
1053 for (sb_sample = 0; sb_sample < length1; sb_sample++) {
1054 delay_buffer_real[sb_sample] = *p_input_re;
1055 p_input_re += MAX_HYBRID_BANDS;
1056 *delay_buffer_imag++ = *p_input_im;
1057 p_input_im += MAX_HYBRID_BANDS;
1058 }
1059
1060 p_input_real++;
1061 p_input_imag++;
1062
1063 p_output_real++;
1064 p_output_imag++;
1065 }
1066 decorr_ptr->ducker->apply(decorr_ptr->ducker, length, input_real,
1067 input_imag, output_real, output_imag,
1068 &(pstr_mps_state->ia_mps_dec_mps_table), free_scratch);
1069 }
1070 }
1071