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 "ixheaacd_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 "ixheaacd_constants.h"
39 #include "ixheaacd_mps_dec.h"
40 #include "ixheaacd_mps_decor.h"
41 #include "ixheaacd_mps_hybfilter.h"
42 #include "ixheaacd_error_standards.h"
43 #include "ixheaacd_basic_ops32.h"
44 #include "ixheaacd_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] = ixheaacd_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] = ixheaacd_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 + PARAMETER_BANDSX2;
627
628 p_input_real = input_real;
629 p_input_imag = input_imag;
630
631 p_output_real = output_real;
632 p_output_imag = output_imag;
633
634 for (ts = 0; ts < time_slots; ts++) {
635 memset(direct_nrg, 0, sizeof(direct_nrg));
636 memset(reverb_nrg, 0, sizeof(reverb_nrg));
637
638 for (qs = 0; qs < 55; qs++) {
639 v1 = p_input_real[qs];
640 v2 = p_input_imag[qs];
641 v3 = p_output_real[qs];
642 v4 = p_output_imag[qs];
643
644 pb = hybrid_2_param_28[qs];
645 direct_nrg[pb] +=
646 (WORD64)((WORD64)v1 * (WORD64)v1) + (WORD64)((WORD64)v2 * (WORD64)v2);
647 reverb_nrg[pb] +=
648 (WORD64)((WORD64)v3 * (WORD64)v3) + (WORD64)((WORD64)v4 * (WORD64)v4);
649 }
650
651 for (; qs < num_bands_2; qs++) {
652 v1 = p_input_real[qs];
653 v2 = p_input_imag[qs];
654 v3 = p_output_real[qs];
655 v4 = p_output_imag[qs];
656
657 direct_nrg[27] +=
658 (WORD64)((WORD64)v1 * (WORD64)v1) + (WORD64)((WORD64)v2 * (WORD64)v2);
659 reverb_nrg[27] +=
660 (WORD64)((WORD64)v3 * (WORD64)v3) + (WORD64)((WORD64)v4 * (WORD64)v4);
661 }
662
663 for (pb = 0; pb < parameter_bands; pb++) {
664 WORD16 qtemp, qtemp_1;
665 temp_1 = ixheaacd_mps_narrow(direct_nrg[pb], &qtemp);
666
667 temp_2 = smooth_direct_nrg[pb] << 2;
668 temp3 =
669 ixheaacd_mps_add32(temp_2, temp_1, &(q_smooth_direct_nrg[pb]), qtemp);
670 smooth_direct_nrg[pb] = ixheaacd_mps_mult32x16_shr_16(temp3, one_by_5);
671
672 temp_1 = ixheaacd_mps_narrow(reverb_nrg[pb], &qtemp);
673 temp_2 = smooth_reverb_nrg[pb] << 2;
674
675 temp3 =
676 ixheaacd_mps_add32(temp_2, temp_1, &(q_smooth_reverb_nrg[pb]), qtemp);
677 smooth_reverb_nrg[pb] = ixheaacd_mps_mult32x16_shr_16(temp3, one_by_5);
678
679 qtemp1 = q_smooth_reverb_nrg[pb] - 1;
680 temp_1 = (smooth_reverb_nrg[pb] >> 2) * 3;
681 qtemp = q_smooth_direct_nrg[pb];
682 temp3 = smooth_direct_nrg[pb];
683
684 if (ixheaacd_mps_comp(temp3, temp_1, &qtemp, qtemp1)) {
685 temp_2 = ixheaacd_mps_div_32(temp3, temp_1, &qtemp2);
686 qtemp2 = qtemp2 + qtemp - qtemp1;
687 temp3 = (qtemp2) > 28 ? MAX_32 : 4 << qtemp2;
688
689 if (temp_2 > temp3) {
690 *duck_gain = (ONE_IN_Q15 - 1);
691 *q_duck_gain++ = 14;
692 } else {
693 *duck_gain = ixheaacd_mps_sqrt(temp_2, &qtemp2, sqrt_tab);
694 *q_duck_gain++ = qtemp2;
695 }
696 duck_gain++;
697 continue;
698 }
699
700 *duck_gain = ONE_IN_Q14 - 1;
701
702 qtemp = q_smooth_direct_nrg[pb] - 1;
703 temp_1 = (smooth_direct_nrg[pb] >> 2) * 3;
704
705 qtemp_1 = q_smooth_reverb_nrg[pb];
706 temp_2 = smooth_reverb_nrg[pb];
707 if (ixheaacd_mps_comp(temp_2, temp_1, &(qtemp_1), qtemp)) {
708 temp3 = ixheaacd_mps_div_32(temp_1, temp_2, &qtemp3);
709 qtemp3 = qtemp3 + qtemp - qtemp_1;
710
711 *duck_gain = ixheaacd_mps_sqrt(temp3, &qtemp3, sqrt_tab);
712 *q_duck_gain = qtemp3;
713 }
714
715 duck_gain++;
716 q_duck_gain++;
717 }
718 duck_gain -= parameter_bands;
719 q_duck_gain -= parameter_bands;
720
721 for (qs = 0; qs < 55; qs++) {
722 pb = hybrid_2_param_28[qs];
723 gain = duck_gain[pb];
724 if (gain == 16383) {
725 continue;
726 }
727 qgain = q_duck_gain[pb];
728 p_output_real[qs] =
729 ixheaacd_mps_mult32_shr_n(p_output_real[qs], gain, qgain);
730 p_output_imag[qs] =
731 ixheaacd_mps_mult32_shr_n(p_output_imag[qs], gain, qgain);
732 }
733
734 gain = duck_gain[27];
735
736 if (gain != 16383) {
737 qgain = q_duck_gain[27];
738 for (; qs < num_bands_2; qs++) {
739 p_output_real[qs] =
740 ixheaacd_mps_mult32_shr_n(p_output_real[qs], gain, qgain);
741 p_output_imag[qs] =
742 ixheaacd_mps_mult32_shr_n(p_output_imag[qs], gain, qgain);
743 }
744 }
745
746 p_input_real += MAX_HYBRID_BANDS;
747 p_input_imag += MAX_HYBRID_BANDS;
748
749 p_output_real += MAX_HYBRID_BANDS;
750 p_output_imag += MAX_HYBRID_BANDS;
751 }
752 }
753
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)754 static VOID ixheaacd_ducker_apply(
755 ia_mps_dec_ducker_interface *const face, WORD32 const time_slots,
756 WORD32 const *input_real, WORD32 const *input_imag, WORD32 *output_real,
757 WORD32 *output_imag, ia_mps_dec_mps_tables_struct *ia_mps_dec_mps_table_ptr,
758 VOID *scratch) {
759 ia_mps_dec_duck_instance_struct *self =
760 (ia_mps_dec_duck_instance_struct *)&face[1];
761 WORD32 *duck_gain;
762 WORD32 gain;
763 WORD16 qgain;
764 WORD64 direct_nrg[28];
765 WORD64 reverb_nrg[28];
766 WORD16 *q_duck_gain;
767 WORD32 ts;
768 WORD32 qs;
769 WORD32 pb;
770 WORD16 qtemp1, qtemp2, qtemp3;
771 WORD32 temp_1, temp_2, temp3;
772 const WORD32 *p_input_real;
773 const WORD32 *p_input_imag;
774 const WORD32 *hybrid_2_param_28 =
775 ia_mps_dec_mps_table_ptr->m1_m2_table_ptr->hybrid_2_param_28;
776 const WORD32 *sqrt_tab = ia_mps_dec_mps_table_ptr->common_table_ptr->sqrt_tab;
777 WORD32 *smooth_direct_nrg = self->smooth_direct_nrg;
778 WORD16 *q_smooth_direct_nrg = self->q_smooth_direct_nrg;
779
780 WORD32 *smooth_reverb_nrg = self->smooth_reverb_nrg;
781 WORD16 *q_smooth_reverb_nrg = self->q_smooth_reverb_nrg;
782
783 WORD32 parameter_bands = self->parameter_bands;
784
785 WORD32 *p_output_real, *p_output_imag;
786
787 WORD32 num_bands_2 = self->hybrid_bands;
788 WORD32 v1, v2, v3, v4;
789 WORD16 one_by_5 = ONE_BY_FIVE_Q16;
790
791 duck_gain = scratch;
792 q_duck_gain = (WORD16 *)scratch + PARAMETER_BANDSX2;
793
794 p_input_real = input_real;
795 p_input_imag = input_imag;
796
797 p_output_real = output_real;
798 p_output_imag = output_imag;
799
800 for (ts = 0; ts < time_slots; ts++) {
801 memset(direct_nrg, 0, sizeof(direct_nrg));
802 memset(reverb_nrg, 0, sizeof(reverb_nrg));
803
804 for (qs = 0; qs < num_bands_2; qs++) {
805 v1 = p_input_real[qs];
806 v2 = p_input_imag[qs];
807 v3 = p_output_real[qs];
808 v4 = p_output_imag[qs];
809
810 pb = hybrid_2_param_28[qs];
811 direct_nrg[pb] +=
812 (WORD64)((WORD64)v1 * (WORD64)v1) + (WORD64)((WORD64)v2 * (WORD64)v2);
813 reverb_nrg[pb] +=
814 (WORD64)((WORD64)v3 * (WORD64)v3) + (WORD64)((WORD64)v4 * (WORD64)v4);
815 }
816
817 for (pb = 0; pb < parameter_bands; pb++) {
818 WORD16 qtemp, qtemp_1;
819 temp_1 = ixheaacd_mps_narrow(direct_nrg[pb], &qtemp);
820 temp_2 = smooth_direct_nrg[pb] << 2;
821 temp3 =
822 ixheaacd_mps_add32(temp_2, temp_1, &(q_smooth_direct_nrg[pb]), qtemp);
823 smooth_direct_nrg[pb] = ixheaacd_mps_mult32x16_shr_16(temp3, one_by_5);
824
825 temp_1 = ixheaacd_mps_narrow(reverb_nrg[pb], &qtemp);
826 temp_2 = smooth_reverb_nrg[pb] << 2;
827
828 temp3 =
829 ixheaacd_mps_add32(temp_2, temp_1, &(q_smooth_reverb_nrg[pb]), qtemp);
830 smooth_reverb_nrg[pb] = ixheaacd_mps_mult32x16_shr_16(temp3, one_by_5);
831
832 qtemp1 = q_smooth_reverb_nrg[pb] - 1;
833 temp_1 = (smooth_reverb_nrg[pb] >> 2) * 3;
834 qtemp = q_smooth_direct_nrg[pb];
835 temp3 = smooth_direct_nrg[pb];
836
837 if (ixheaacd_mps_comp(temp3, temp_1, &qtemp, qtemp1)) {
838 temp_2 = ixheaacd_mps_div_32(temp3, temp_1, &qtemp2);
839 qtemp2 = qtemp2 + qtemp - qtemp1;
840 temp3 = qtemp2 > 28 ? MAX_32 : 4 << qtemp2;
841
842 if (temp_2 > temp3) {
843 *duck_gain = 32767;
844 *q_duck_gain++ = 14;
845 } else {
846 *duck_gain = ixheaacd_mps_sqrt(temp_2, &qtemp2, sqrt_tab);
847 *q_duck_gain++ = qtemp2;
848 }
849 duck_gain++;
850 continue;
851 }
852
853 *duck_gain = 16383;
854
855 qtemp = q_smooth_direct_nrg[pb] - 1;
856 temp_1 = (smooth_direct_nrg[pb] >> 2) * 3;
857
858 qtemp_1 = q_smooth_reverb_nrg[pb];
859 temp_2 = smooth_reverb_nrg[pb];
860 if (ixheaacd_mps_comp(temp_2, temp_1, &(qtemp_1), qtemp)) {
861 temp3 = ixheaacd_mps_div_32(temp_1, temp_2, &qtemp3);
862 qtemp3 = qtemp3 + qtemp - qtemp_1;
863
864 *duck_gain = ixheaacd_mps_sqrt(temp3, &qtemp3, sqrt_tab);
865 *q_duck_gain = qtemp3;
866 }
867
868 duck_gain++;
869 q_duck_gain++;
870 }
871
872 duck_gain -= parameter_bands;
873 q_duck_gain -= parameter_bands;
874
875 for (qs = 0; qs < num_bands_2; qs++) {
876 pb = hybrid_2_param_28[qs];
877 gain = duck_gain[pb];
878 if (gain == 16383) {
879 continue;
880 }
881 qgain = q_duck_gain[pb];
882 p_output_real[qs] =
883 ixheaacd_mps_mult32_shr_n(p_output_real[qs], gain, qgain);
884 p_output_imag[qs] =
885 ixheaacd_mps_mult32_shr_n(p_output_imag[qs], gain, qgain);
886 }
887
888 p_input_real += MAX_HYBRID_BANDS;
889 p_input_imag += MAX_HYBRID_BANDS;
890
891 p_output_real += MAX_HYBRID_BANDS;
892 p_output_imag += MAX_HYBRID_BANDS;
893 }
894 }
895
ixheaacd_ducker_create(ia_mps_dec_ducker_interface * const face,WORD32 const hybrid_bands)896 static IA_ERRORCODE ixheaacd_ducker_create(
897 ia_mps_dec_ducker_interface *const face, WORD32 const hybrid_bands) {
898 ia_mps_dec_duck_instance_struct *self = NULL;
899 IA_ERRORCODE error_code = IA_NO_ERROR;
900 WORD32 i;
901
902 if (face == NULL) {
903 error_code = IA_FATAL_ERROR;
904 }
905
906 if (error_code == IA_NO_ERROR) {
907 self = (ia_mps_dec_duck_instance_struct *)&face[1];
908
909 self->hybrid_bands = hybrid_bands;
910 self->parameter_bands = MAX_PARAMETER_BANDS;
911
912 self->alpha = DUCK_ALPHA;
913 self->one_minus_alpha = DUCK_ONEMINUSALPHA;
914 self->gamma = DUCK_GAMMA;
915 self->abs_thr = ABS_THR_FIX;
916 self->hybrid_bands = hybrid_bands;
917 self->parameter_bands = MAX_PARAMETER_BANDS;
918
919 self->qalpha = 15;
920 self->qgamma = 14;
921
922 if (hybrid_bands == 71)
923 face->apply = ixheaacd_ducker_apply_71;
924 else
925 face->apply = ixheaacd_ducker_apply;
926
927 for (i = 0; i < MAX_PARAMETER_BANDS; i++) {
928 self->q_smooth_direct_nrg[i] = 31;
929 self->q_smooth_reverb_nrg[i] = 31;
930 }
931 }
932
933 return error_code;
934 }
935
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)936 IA_ERRORCODE ixheaacd_decorr_create(
937 ia_mps_dec_decorr_dec_handle self, WORD32 subbands, WORD32 seed,
938 WORD32 dec_type, WORD32 decorr_config,
939 ia_mps_dec_mps_tables_struct *ia_mps_dec_mps_table_ptr) {
940 IA_ERRORCODE error_code = IA_NO_ERROR;
941 WORD32 i, reverb_band;
942
943 const WORD32 *rev_split_freq;
944
945 switch (decorr_config) {
946 case DECOR_CONFIG_0:
947 rev_split_freq =
948 ia_mps_dec_mps_table_ptr->decor_table_ptr->rev_table.rev_split_freq_0;
949 break;
950 case DECOR_CONFIG_1:
951 rev_split_freq =
952 ia_mps_dec_mps_table_ptr->decor_table_ptr->rev_table.rev_split_freq_1;
953 break;
954 case DECOR_CONFIG_2:
955 rev_split_freq =
956 ia_mps_dec_mps_table_ptr->decor_table_ptr->rev_table.rev_split_freq_2;
957 break;
958 default:
959 return IA_FATAL_ERROR;
960 break;
961 }
962
963 if (error_code == IA_NO_ERROR) {
964 self->decorr_seed = seed;
965 self->numbins = subbands;
966
967 for (i = 0; i < self->numbins; i++) {
968 reverb_band = 0;
969 while ((reverb_band < 3) &&
970 (ixheaacd_get_qmf_sb(
971 i, ia_mps_dec_mps_table_ptr->mdct2qmf_table_ptr) >=
972 (rev_split_freq[reverb_band] - 1)))
973 reverb_band++;
974
975 {
976 self->no_sample_delay[i] =
977 ia_mps_dec_mps_table_ptr->decor_table_ptr->rev_table
978 .rev_delay[reverb_band][self->decorr_seed];
979
980 error_code = ixheaacd_decorr_filt_create(
981 self->filter[i], self->decorr_seed,
982 ixheaacd_get_qmf_sb(i,
983 ia_mps_dec_mps_table_ptr->mdct2qmf_table_ptr),
984 reverb_band, dec_type, ia_mps_dec_mps_table_ptr);
985 }
986 }
987
988 if (error_code == IA_NO_ERROR) {
989 error_code = ixheaacd_ducker_create(self->ducker, self->numbins);
990 }
991 }
992 return (error_code);
993 }
994
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)995 VOID ixheaacd_decorr_apply(ia_heaac_mps_state_struct *pstr_mps_state, WORD32 length,
996 WORD32 *input_real, WORD32 *input_imag,
997 WORD32 *output_real, WORD32 *output_imag,
998 WORD32 index) {
999 WORD32 l = index - pstr_mps_state->num_direct_signals;
1000 ia_mps_dec_decorr_dec_handle decorr_ptr = pstr_mps_state->ap_decor[l];
1001 WORD32 idx, sb_sample;
1002
1003 WORD32 *p_input_real, *p_input_re, *p_input_imag, *p_input_im;
1004 WORD32 *p_output_real, *p_output_imag, *p_output_re, *p_output_im;
1005 WORD32 *delay_buffer_real, *delay_buffer_imag;
1006 WORD32 length1;
1007 VOID *free_scratch;
1008
1009 free_scratch = (WORD32 *)pstr_mps_state->mps_scratch_mem_v + MAX_TIMESLOTSX2;
1010
1011 if (decorr_ptr != NULL) {
1012 p_input_real = input_real;
1013 p_input_imag = input_imag;
1014
1015 p_output_real = output_real;
1016 p_output_imag = output_imag;
1017 for (idx = 0; idx < decorr_ptr->numbins; idx++) {
1018 p_input_re = p_input_real;
1019 p_input_im = p_input_imag;
1020
1021 p_output_re = p_output_real;
1022 p_output_im = p_output_imag;
1023
1024 length1 = length - decorr_ptr->no_sample_delay[idx];
1025 delay_buffer_real =
1026 &decorr_ptr->delay_buffer_real[idx][decorr_ptr->no_sample_delay[idx]];
1027 delay_buffer_imag =
1028 &decorr_ptr->delay_buffer_imag[idx][decorr_ptr->no_sample_delay[idx]];
1029 for (sb_sample = 0; sb_sample < length1; sb_sample++) {
1030 delay_buffer_real[sb_sample] = *p_input_re;
1031 *delay_buffer_imag++ = *p_input_im;
1032 p_input_re += MAX_HYBRID_BANDS;
1033 p_input_im += MAX_HYBRID_BANDS;
1034 }
1035 {
1036 ixheaacd_decorr_filt_apply(
1037 decorr_ptr->filter[idx], length, decorr_ptr->delay_buffer_real[idx],
1038 decorr_ptr->delay_buffer_imag[idx], p_output_re++, p_output_im++);
1039 }
1040
1041 length1 = decorr_ptr->no_sample_delay[idx];
1042 delay_buffer_real = &decorr_ptr->delay_buffer_real[idx][0];
1043 delay_buffer_imag = &decorr_ptr->delay_buffer_imag[idx][0];
1044 for (sb_sample = 0; sb_sample < length1; sb_sample++) {
1045 delay_buffer_real[sb_sample] = *p_input_re;
1046 p_input_re += MAX_HYBRID_BANDS;
1047 *delay_buffer_imag++ = *p_input_im;
1048 p_input_im += MAX_HYBRID_BANDS;
1049 }
1050
1051 p_input_real++;
1052 p_input_imag++;
1053
1054 p_output_real++;
1055 p_output_imag++;
1056 }
1057 decorr_ptr->ducker->apply(decorr_ptr->ducker, length, input_real,
1058 input_imag, output_real, output_imag,
1059 &(pstr_mps_state->ia_mps_dec_mps_table), free_scratch);
1060 }
1061 }
1062