Coverage Report

Created: 2026-08-13 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/decoder/ixheaacd_mps_pre_mix.c
Line
Count
Source
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
23
#include <assert.h>
24
#include "ixheaac_type_def.h"
25
#include "ixheaacd_bitbuffer.h"
26
#include "ixheaacd_common_rom.h"
27
#include "ixheaacd_sbrdecsettings.h"
28
#include "ixheaacd_sbr_scale.h"
29
#include "ixheaacd_env_extr_part.h"
30
#include "ixheaacd_sbr_rom.h"
31
#include "ixheaacd_hybrid.h"
32
#include "ixheaacd_ps_dec.h"
33
#include "ixheaacd_config.h"
34
#include "ixheaacd_qmf_dec.h"
35
#include "ixheaacd_mps_polyphase.h"
36
#include "ixheaac_constants.h"
37
#include "ixheaacd_mps_struct_def.h"
38
#include "ixheaacd_mps_res_rom.h"
39
#include "ixheaacd_mps_aac_struct.h"
40
#include "ixheaacd_mps_dec.h"
41
42
#define ONE_IN_Q28 (268435456)
43
#define PI_BY_8_Q28 (105414352)
44
1.24M
#define P_PI 3.1415926535897932
45
53.8k
#define PI_IN_Q28 843314880
46
1.34M
#define MULT(a, b) (a * b)
47
53.8k
#define Q28_FLOAT_VAL ((FLOAT32)(1 << 28))
48
53.8k
#define ONE_BY_Q28_FLOAT_VAL (1.0f / Q28_FLOAT_VAL)
49
50
extern const WORD32 ixheaacd_atan_table_Q28[16][8][31];
51
extern const WORD32 ixheaacd_ipd_de_quant_table_q28[16];
52
53
extern const FLOAT32 ixheaacd_im_weight[16][8][31];
54
extern const FLOAT32 ixheaacd_re_weight[16][8][31];
55
extern const FLOAT32 ixheaacd_beta[16][8][31];
56
extern const FLOAT32 ixheaacd_weight[16][8][31];
57
extern const FLOAT32 ixheaacd_c_l_table[31];
58
extern const FLOAT32 ixheaacd_sin_table[8][31];
59
extern const FLOAT32 ixheaacd_cos_table[8][31];
60
61
extern const WORD32 ixheaacd_mps_gain_set_indx[29];
62
63
53.8k
static WORD32 ixheaacd_mps_phase_wraping(WORD32 phase) {
64
53.8k
  const WORD32 pi_2 = 2 * PI_IN_Q28;
65
66
73.7k
  while (phase < 0) phase += pi_2;
67
53.8k
  while (phase >= pi_2) phase -= pi_2;
68
53.8k
  assert((phase >= 0) && (phase < pi_2));
69
70
53.8k
  return phase;
71
53.8k
}
72
73
static VOID ixheaacd_mps_buffer_pre_and_mix_matrix(
74
101k
    ia_mps_dec_state_struct *self) {
75
101k
  WORD32 pb, row, col;
76
77
1.53M
  for (pb = 0; pb < self->bs_param_bands; pb++) {
78
4.29M
    for (row = 0; row < MAX_M_INPUT; row++) {
79
8.59M
      for (col = 0; col < MAX_M_OUTPUT; col++) {
80
5.73M
        self->m1_param_re_prev[pb][row][col] =
81
5.73M
            self->m1_param_re[self->num_parameter_sets_prev - 1][pb][row][col];
82
5.73M
        self->m1_param_im_prev[pb][row][col] =
83
5.73M
            self->m1_param_im[self->num_parameter_sets_prev - 1][pb][row][col];
84
5.73M
        self->m2_decor_re_prev[pb][row][col] =
85
5.73M
            self->m2_decor_re[self->num_parameter_sets_prev - 1][pb][row][col];
86
5.73M
        self->m2_decor_im_prev[pb][row][col] =
87
5.73M
            self->m2_decor_im[self->num_parameter_sets_prev - 1][pb][row][col];
88
5.73M
        self->m2_resid_re_prev[pb][row][col] =
89
5.73M
            self->m2_resid_re[self->num_parameter_sets_prev - 1][pb][row][col];
90
5.73M
        self->m2_resid_im_prev[pb][row][col] =
91
5.73M
            self->m2_resid_im[self->num_parameter_sets_prev - 1][pb][row][col];
92
5.73M
      }
93
2.86M
    }
94
1.43M
  }
95
96
1.53M
  for (pb = 0; pb < self->bs_param_bands; pb++) {
97
1.43M
    self->phase_l_prev[pb] =
98
1.43M
        self->phase_l[self->num_parameter_sets_prev - 1][pb];
99
1.43M
    self->phase_r_prev[pb] =
100
1.43M
        self->phase_r[self->num_parameter_sets_prev - 1][pb];
101
1.43M
  }
102
101k
}
103
104
101k
VOID ixheaacd_pre_and_mix_matrix_calculation(ia_mps_dec_state_struct *self) {
105
101k
  WORD32 ps, pb;
106
101k
  ia_mps_bs_frame *curr_bit_stream = &(self->bs_frame);
107
101k
  FLOAT32 h_imag[2 * MAX_PARAMETER_BANDS];
108
101k
  FLOAT32 h_real[6 * MAX_PARAMETER_BANDS];
109
110
101k
  ixheaacd_mps_buffer_pre_and_mix_matrix(self);
111
112
226k
  for (ps = 0; ps < self->num_parameter_sets; ps++) {
113
125k
    FLOAT32 *h_im = &h_imag[0];
114
125k
    FLOAT32 *h_re = &h_real[0];
115
116
125k
    memset(h_real, 0, 6 * MAX_PARAMETER_BANDS * sizeof(FLOAT32));
117
125k
    memset(h_imag, 0, 2 * MAX_PARAMETER_BANDS * sizeof(FLOAT32));
118
119
125k
    switch (self->config->bs_phase_coding) {
120
26.7k
      case 0:
121
26.7k
        if (self->residual_coding) {
122
22.5k
          ixheaacd_mps_par2umx_pred(self, curr_bit_stream, h_imag, h_real, ps,
123
22.5k
                                    self->res_bands);
124
22.5k
        } else {
125
4.17k
          ixheaacd_mps_par2umx_ps(self, curr_bit_stream, h_real, ps);
126
4.17k
        }
127
128
26.7k
        break;
129
28.4k
      case 1:
130
28.4k
        ixheaacd_mps_par2umx_ps_ipd_opd(self, curr_bit_stream, h_real, ps);
131
28.4k
        break;
132
70.0k
      case 2:
133
70.0k
        ixheaacd_mps_par2umx_pred(self, curr_bit_stream, h_imag, h_real, ps,
134
70.0k
                                  self->res_bands);
135
70.0k
        break;
136
125k
    }
137
138
1.79M
    for (pb = 0; pb < self->bs_param_bands; pb++) {
139
1.67M
      self->m1_param_re[ps][pb][0][0] = 1.0f;
140
1.67M
      self->m1_param_re[ps][pb][1][0] = 1.0f;
141
142
1.67M
      self->m1_param_im[ps][pb][0][0] = 0;
143
1.67M
      self->m1_param_im[ps][pb][1][0] = 0;
144
145
1.67M
      self->m2_resid_re[ps][pb][0][0] = *h_re++;
146
1.67M
      self->m2_resid_im[ps][pb][0][0] = *h_im++;
147
1.67M
      self->m2_resid_im[ps][pb][0][1] = 0;
148
149
1.67M
      self->m2_resid_re[ps][pb][1][0] = *h_re++;
150
1.67M
      self->m2_resid_im[ps][pb][1][0] = *h_im++;
151
1.67M
      self->m2_resid_im[ps][pb][1][1] = 0;
152
153
1.67M
      self->m2_decor_re[ps][pb][0][0] = 0;
154
1.67M
      self->m2_decor_im[ps][pb][0][0] = 0;
155
1.67M
      self->m2_decor_re[ps][pb][0][1] = *h_re++;
156
1.67M
      self->m2_decor_im[ps][pb][0][1] = 0;
157
158
1.67M
      self->m2_decor_re[ps][pb][1][0] = 0;
159
1.67M
      self->m2_decor_im[ps][pb][1][0] = 0;
160
1.67M
      self->m2_decor_re[ps][pb][1][1] = *h_re++;
161
1.67M
      self->m2_decor_im[ps][pb][1][1] = 0;
162
163
1.67M
      self->m2_resid_re[ps][pb][0][1] = *h_re++;
164
1.67M
      self->m2_resid_re[ps][pb][1][1] = *h_re++;
165
1.67M
    }
166
125k
  }
167
101k
  ixheaacd_mps_smoothing_opd(self);
168
101k
}
169
170
static VOID ixheaacd_mps_par2umx_ps_core(WORD32 cld[MAX_PARAMETER_BANDS],
171
                                         WORD32 icc[MAX_PARAMETER_BANDS],
172
                                         WORD32 ott_band_count,
173
32.5k
                                         FLOAT32 *h_real) {
174
32.5k
  WORD32 band;
175
32.5k
  FLOAT32 c_l_temp, c_r_temp, temp;
176
32.5k
  WORD32 cld_idx, icc_idx;
177
178
369k
  for (band = 0; band < ott_band_count; band++) {
179
336k
    cld_idx = *cld++ + 15;
180
336k
    icc_idx = *icc++;
181
182
336k
    icc_idx = icc_idx & 7;
183
184
336k
    c_l_temp = (ixheaacd_c_l_table[cld_idx]);
185
336k
    c_r_temp = (ixheaacd_c_l_table[30 - cld_idx]);
186
187
336k
    temp = ixheaacd_cos_table[icc_idx][cld_idx];
188
336k
    *h_real++ = MULT(temp, c_l_temp);
189
190
336k
    temp = ixheaacd_cos_table[icc_idx][30 - cld_idx];
191
336k
    *h_real++ = MULT(temp, c_r_temp);
192
193
336k
    temp = ixheaacd_sin_table[icc_idx][cld_idx];
194
336k
    *h_real++ = MULT(temp, c_l_temp);
195
196
336k
    temp = -ixheaacd_sin_table[icc_idx][30 - cld_idx];
197
336k
    *h_real++ = MULT(temp, c_r_temp);
198
199
336k
    h_real += 2;
200
336k
  }
201
32.5k
}
202
203
VOID ixheaacd_mps_par2umx_ps(ia_mps_dec_state_struct *self,
204
                             ia_mps_bs_frame *curr_bit_stream, FLOAT32 *h_real,
205
4.17k
                             WORD32 param_set_idx) {
206
4.17k
  ixheaacd_mps_par2umx_ps_core(curr_bit_stream->cld_idx[param_set_idx],
207
4.17k
                               curr_bit_stream->icc_idx[param_set_idx],
208
4.17k
                               self->bs_param_bands, h_real);
209
4.17k
}
210
211
static VOID ixheaacd_mps_opd_calc(ia_mps_dec_state_struct *self,
212
                                  ia_mps_bs_frame *curr_bit_stream,
213
                                  WORD32 param_set_idx,
214
3.45k
                                  WORD32 opd[MAX_PARAMETER_BANDS]) {
215
3.45k
  WORD32 band;
216
217
30.3k
  for (band = 0; band < self->num_bands_ipd; band++) {
218
26.9k
    WORD32 cld_idx = curr_bit_stream->cld_idx[param_set_idx][band] + 15;
219
26.9k
    WORD32 ipd_idx = (curr_bit_stream->ipd_idx[param_set_idx][band]) & 15;
220
26.9k
    WORD32 icc_idx = curr_bit_stream->icc_idx[param_set_idx][band];
221
222
26.9k
    if ((cld_idx == 15) && (ipd_idx == 8))
223
683
      opd[band] = 0;
224
26.2k
    else
225
26.2k
      opd[band] = ixheaacd_atan_table_Q28[ipd_idx][icc_idx][cld_idx];
226
26.9k
  }
227
3.45k
}
228
229
VOID ixheaacd_mps_par2umx_ps_ipd_opd(ia_mps_dec_state_struct *self,
230
                                     ia_mps_bs_frame *curr_bit_stream,
231
28.4k
                                     FLOAT32 *h_real, WORD32 param_set_idx) {
232
28.4k
  WORD32 opd[MAX_PARAMETER_BANDS];
233
28.4k
  WORD32 ott_band_count = self->bs_param_bands;
234
28.4k
  WORD32 num_bands_ipd = self->num_bands_ipd;
235
28.4k
  WORD32 band;
236
237
28.4k
  ixheaacd_mps_par2umx_ps_core(curr_bit_stream->cld_idx[param_set_idx],
238
28.4k
                               curr_bit_stream->icc_idx[param_set_idx],
239
28.4k
                               ott_band_count, h_real);
240
241
28.4k
  if (self->bs_phase_mode) {
242
3.45k
    ixheaacd_mps_opd_calc(self, curr_bit_stream, param_set_idx, opd);
243
244
30.3k
    for (band = 0; band < num_bands_ipd; band++) {
245
26.9k
      WORD32 ipd_idx = curr_bit_stream->ipd_idx[param_set_idx][band] & 15;
246
26.9k
      WORD32 ipd = ixheaacd_ipd_de_quant_table_q28[ipd_idx];
247
248
26.9k
      self->phase_l[param_set_idx][band] =
249
26.9k
          ixheaacd_mps_phase_wraping(opd[band]) * ONE_BY_Q28_FLOAT_VAL;
250
26.9k
      self->phase_r[param_set_idx][band] =
251
26.9k
          ixheaacd_mps_phase_wraping(opd[band] - ipd) * ONE_BY_Q28_FLOAT_VAL;
252
26.9k
    }
253
24.9k
  } else {
254
24.9k
    num_bands_ipd = 0;
255
24.9k
  }
256
257
313k
  for (band = num_bands_ipd; band < ott_band_count; band++) {
258
285k
    self->phase_l[param_set_idx][band] = 0;
259
285k
    self->phase_r[param_set_idx][band] = 0;
260
285k
  }
261
28.4k
}
262
263
VOID ixheaacd_mps_par2umx_pred(ia_mps_dec_state_struct *self,
264
                               ia_mps_bs_frame *curr_bit_stream,
265
                               FLOAT32 *h_imag, FLOAT32 *h_real,
266
92.5k
                               WORD32 param_set_idx, WORD32 res_bands) {
267
92.5k
  WORD32 band;
268
269
1.42M
  for (band = 0; band < self->bs_param_bands; band++) {
270
1.33M
    WORD32 cld_idx = curr_bit_stream->cld_idx[param_set_idx][band] + 15;
271
1.33M
    WORD32 icc_idx = curr_bit_stream->icc_idx[param_set_idx][band];
272
1.33M
    WORD32 ipd_idx = curr_bit_stream->ipd_idx[param_set_idx][band] & 15;
273
274
1.33M
    if ((band < self->num_bands_ipd) && (cld_idx == 15) && (icc_idx == 0) &&
275
644k
        (ipd_idx == 8)) {
276
2.03k
      FLOAT32 gain = 0.416666667f;
277
2.03k
      *h_imag++ = 0;
278
2.03k
      *h_imag++ = 0;
279
280
2.03k
      if (band < res_bands) {
281
453
        *h_real++ = gain;
282
453
        *h_real++ = gain;
283
453
        h_real += 2;
284
285
453
        *h_real++ = gain;
286
453
        *h_real++ = -gain;
287
1.58k
      } else {
288
1.58k
        *h_real++ = gain;
289
1.58k
        *h_real++ = -gain;
290
291
1.58k
        h_real += 4;
292
1.58k
      }
293
1.33M
    } else {
294
1.33M
      FLOAT32 weight, re_weight, im_weight;
295
296
1.33M
      weight = ixheaacd_weight[ipd_idx][icc_idx][cld_idx];
297
1.33M
      re_weight = ixheaacd_re_weight[ipd_idx][icc_idx][cld_idx];
298
1.33M
      im_weight = ixheaacd_im_weight[ipd_idx][icc_idx][cld_idx];
299
300
1.33M
      if (band < self->num_bands_ipd) {
301
807k
        weight = ixheaacd_weight[ipd_idx][icc_idx][cld_idx];
302
807k
        re_weight = ixheaacd_re_weight[ipd_idx][icc_idx][cld_idx];
303
807k
        im_weight = ixheaacd_im_weight[ipd_idx][icc_idx][cld_idx];
304
807k
      } else {
305
527k
        weight = ixheaacd_weight[0][icc_idx][cld_idx];
306
527k
        re_weight = ixheaacd_re_weight[0][icc_idx][cld_idx];
307
527k
        im_weight = ixheaacd_im_weight[0][icc_idx][cld_idx];
308
527k
      }
309
310
1.33M
      *h_real++ = weight - re_weight;
311
1.33M
      *h_imag++ = -im_weight;
312
1.33M
      *h_real++ = weight + re_weight;
313
1.33M
      *h_imag++ = im_weight;
314
315
1.33M
      if (band < res_bands) {
316
675k
        h_real += 2;
317
318
675k
        *h_real++ = weight;
319
675k
        *h_real++ = -weight;
320
675k
      } else {
321
659k
        FLOAT32 beta = ixheaacd_beta[ipd_idx][icc_idx][cld_idx];
322
323
659k
        *h_real++ = beta;
324
659k
        *h_real++ = -beta;
325
659k
        h_real += 2;
326
659k
      }
327
1.33M
    }
328
1.33M
  }
329
92.5k
}
330
331
22.2k
VOID ixheaacd_mps_apply_pre_matrix(ia_mps_dec_state_struct *self) {
332
22.2k
  WORD32 ts, qs, row;
333
22.2k
  if (self->pre_mix_req) {
334
8.82k
    ixheaacd_mps_upmix_interp_type1(
335
8.82k
        self->m1_param_re, self->r_out_re_in_m1, self->m1_param_re_prev,
336
8.82k
        (self->dir_sig_count + self->decor_sig_count), 1, self, self->bs_high_rate_mode);
337
338
352k
    for (ts = 0; ts < self->time_slots; ts++) {
339
1.03M
      for (qs = 0; qs < 2; qs++) {
340
687k
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
341
342
687k
        FLOAT32 real =
343
687k
            self->hyb_in[0][qs][ts].re * self->r_out_re_in_m1[ts][indx][0][0];
344
687k
        FLOAT32 imag =
345
687k
            self->hyb_in[0][qs][ts].im * self->r_out_re_in_m1[ts][indx][0][0];
346
2.06M
        for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
347
1.37M
             row++) {
348
1.37M
          self->v[row][ts][qs].re = real;
349
1.37M
          self->v[row][ts][qs].im = imag;
350
1.37M
        }
351
687k
      }
352
14.9M
      for (qs = 2; qs < self->hyb_band_count[0]; qs++) {
353
14.6M
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
354
14.6M
        FLOAT32 real =
355
14.6M
            self->hyb_in[0][qs][ts].re * self->r_out_re_in_m1[ts][indx][0][0];
356
14.6M
        FLOAT32 imag =
357
14.6M
            self->hyb_in[0][qs][ts].im * self->r_out_re_in_m1[ts][indx][0][0];
358
43.8M
        for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
359
29.2M
             row++) {
360
29.2M
          self->v[row][ts][qs].re = real;
361
29.2M
          self->v[row][ts][qs].im = imag;
362
29.2M
        }
363
14.6M
      }
364
343k
    }
365
13.3k
  } else {
366
552k
    for (ts = 0; ts < self->time_slots; ts++) {
367
18.8M
      for (qs = 0; qs < self->hyb_band_count[0]; qs++) {
368
18.2M
        FLOAT32 real = self->hyb_in[0][qs][ts].re;
369
18.2M
        FLOAT32 imag = self->hyb_in[0][qs][ts].im;
370
54.8M
        for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
371
36.5M
             row++) {
372
36.5M
          self->v[row][ts][qs].re = real;
373
36.5M
          self->v[row][ts][qs].im = imag;
374
36.5M
        }
375
18.2M
      }
376
539k
    }
377
13.3k
  }
378
22.2k
  return;
379
22.2k
}
380
381
0
VOID ixheaacd_mps_apply_mix_matrix(ia_mps_dec_state_struct *self) {
382
0
  WORD32 ts, qs, row, col;
383
0
  WORD32 complex_m2 = ((self->config->bs_phase_coding != 0));
384
0
  WORD32 phase_interpolation = (self->config->bs_phase_coding == 1);
385
0
  WORD32 num_col_iters = 0;
386
387
0
  ixheaacd_mps_upmix_interp(self->m2_decor_re, self->r_out_diff_re_in_m2, self->m2_decor_re_prev,
388
0
                            self->out_ch_count, (self->dir_sig_count + self->decor_sig_count),
389
0
                            self, 1);
390
391
0
  ixheaacd_mps_upmix_interp(self->m2_resid_re, self->r_out_re_in_m2, self->m2_resid_re_prev,
392
0
                            self->out_ch_count, (self->dir_sig_count + self->decor_sig_count),
393
0
                            self, 1);
394
395
0
  if (complex_m2 && !phase_interpolation) {
396
0
    ixheaacd_mps_upmix_interp(self->m2_decor_im, self->r_out_diff_im_in_m2,
397
0
                              self->m2_decor_im_prev, self->out_ch_count,
398
0
                              (self->dir_sig_count + self->decor_sig_count), self, 1);
399
0
    ixheaacd_mps_upmix_interp(self->m2_resid_im, self->r_out_im_in_m2, self->m2_resid_im_prev,
400
0
                              self->out_ch_count, (self->dir_sig_count + self->decor_sig_count),
401
0
                              self, 1);
402
0
  }
403
404
0
  if (phase_interpolation) {
405
0
    ixheaacd_mps_phase_interpolation(
406
0
        self->phase_l, self->phase_r, self->phase_l_prev, self->phase_r_prev,
407
0
        self->r_out_ph_re_in_m2, self->r_out_ph_im_in_m2, self);
408
409
0
    for (ts = 0; ts < self->time_slots; ts++) {
410
0
      WORD32 pb;
411
0
      for (pb = 0; pb < self->bs_param_bands; pb++) {
412
0
        self->r_out_im_in_m2[ts][pb][0][0] =
413
0
              self->r_out_re_in_m2[ts][pb][0][0] *
414
0
              self->r_out_ph_im_in_m2[ts][pb][0];
415
416
0
        self->r_out_im_in_m2[ts][pb][0][1] =
417
0
              self->r_out_re_in_m2[ts][pb][0][1] *
418
0
              self->r_out_ph_im_in_m2[ts][pb][0];
419
420
0
        self->r_out_im_in_m2[ts][pb][1][0] =
421
0
              self->r_out_re_in_m2[ts][pb][1][0] *
422
0
              self->r_out_ph_im_in_m2[ts][pb][1];
423
424
0
        self->r_out_im_in_m2[ts][pb][1][1] =
425
0
              self->r_out_re_in_m2[ts][pb][1][1] *
426
0
              self->r_out_ph_im_in_m2[ts][pb][1];
427
428
0
        self->r_out_re_in_m2[ts][pb][0][0] =
429
0
              self->r_out_re_in_m2[ts][pb][0][0] *
430
0
              self->r_out_ph_re_in_m2[ts][pb][0];
431
432
0
        self->r_out_re_in_m2[ts][pb][0][1] =
433
0
              self->r_out_re_in_m2[ts][pb][0][1] *
434
0
              self->r_out_ph_re_in_m2[ts][pb][0];
435
436
0
        self->r_out_re_in_m2[ts][pb][1][0] =
437
0
              self->r_out_re_in_m2[ts][pb][1][0] *
438
0
              self->r_out_ph_re_in_m2[ts][pb][1];
439
440
0
        self->r_out_re_in_m2[ts][pb][1][1] =
441
0
              self->r_out_re_in_m2[ts][pb][1][1] *
442
0
              self->r_out_ph_re_in_m2[ts][pb][1];
443
444
0
        self->r_out_diff_im_in_m2[ts][pb][0][0] = 0;
445
0
        self->r_out_diff_im_in_m2[ts][pb][0][1] =
446
0
              self->r_out_diff_re_in_m2[ts][pb][0][1] *
447
0
              self->r_out_ph_im_in_m2[ts][pb][0];
448
449
0
        self->r_out_diff_im_in_m2[ts][pb][1][0] = 0;
450
0
        self->r_out_diff_im_in_m2[ts][pb][1][1] =
451
0
              self->r_out_diff_re_in_m2[ts][pb][1][1] *
452
0
              self->r_out_ph_im_in_m2[ts][pb][1];
453
454
0
        self->r_out_diff_re_in_m2[ts][pb][0][0] = 0;
455
0
        self->r_out_diff_re_in_m2[ts][pb][0][1] =
456
0
              self->r_out_diff_re_in_m2[ts][pb][0][1] *
457
0
              self->r_out_ph_re_in_m2[ts][pb][0];
458
459
0
        self->r_out_diff_re_in_m2[ts][pb][1][0] = 0;
460
0
        self->r_out_diff_re_in_m2[ts][pb][1][1] =
461
0
              self->r_out_diff_re_in_m2[ts][pb][1][1] *
462
0
              self->r_out_ph_re_in_m2[ts][pb][1];
463
0
      }
464
0
    }
465
0
  }
466
0
  if (self->res_bands == 0) {
467
0
    num_col_iters = self->dir_sig_count;
468
0
  }
469
0
  else {
470
0
    num_col_iters = (self->dir_sig_count + self->decor_sig_count);
471
0
  }
472
473
0
  for (ts = 0; ts < self->time_slots; ts++) {
474
0
    for (qs = 0; qs < self->hyb_band_count_max; qs++) {
475
0
      WORD32 indx = self->hyb_band_to_processing_band_table[qs];
476
477
0
      for (row = 0; row < self->out_ch_count; row++) {
478
0
          FLOAT32 sum_re_dir = 0;
479
0
          FLOAT32 sum_im_dir = 0;
480
0
          for (col = 0; col < num_col_iters; col++) {
481
0
              sum_re_dir += self->w_dir[col][ts][qs].re *
482
0
                  self->r_out_re_in_m2[ts][indx][row][col];
483
0
              sum_im_dir += self->w_dir[col][ts][qs].im *
484
0
                  self->r_out_re_in_m2[ts][indx][row][col];
485
0
          }
486
0
          self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
487
0
          self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
488
489
0
          self->hyb_diff_out[row][ts][qs].re =
490
0
              self->w_diff[1][ts][qs].re *
491
0
              self->r_out_diff_re_in_m2[ts][indx][row][1];
492
0
          self->hyb_diff_out[row][ts][qs].im =
493
0
              self->w_diff[1][ts][qs].im *
494
0
              self->r_out_diff_re_in_m2[ts][indx][row][1];
495
0
      }
496
0
    }
497
0
  }
498
499
0
  if (complex_m2) {
500
0
    if (phase_interpolation) {
501
0
      for (ts = 0; ts < self->time_slots; ts++) {
502
0
        for (qs = 0; qs < 2; qs++) {
503
0
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
504
0
          for (row = 0; row < self->out_ch_count; row++) {
505
0
              FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
506
0
              FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
507
0
              for (col = 0; col < num_col_iters; col++) {
508
0
                  sum_re_dir += self->w_dir[col][ts][qs].im *
509
0
                      self->r_out_im_in_m2[ts][indx][row][col];
510
0
                  sum_im_dir -= self->w_dir[col][ts][qs].re *
511
0
                      self->r_out_im_in_m2[ts][indx][row][col];
512
0
              }
513
0
              self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
514
0
              self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
515
0
              self->hyb_diff_out[row][ts][qs].re +=
516
0
                  self->w_diff[1][ts][qs].im *
517
0
                  self->r_out_diff_im_in_m2[ts][indx][row][1];
518
0
              self->hyb_diff_out[row][ts][qs].im -=
519
0
                  self->w_diff[1][ts][qs].re *
520
0
                  self->r_out_diff_im_in_m2[ts][indx][row][1];
521
0
          }
522
0
        }
523
0
        for (qs = 2; qs < self->hyb_band_count_max; qs++) {
524
0
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
525
0
          for (row = 0; row < self->out_ch_count; row++) {
526
0
              FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
527
0
              FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
528
0
              for (col = 0; col < num_col_iters; col++) {
529
0
                  sum_re_dir -= self->w_dir[col][ts][qs].im *
530
0
                      self->r_out_im_in_m2[ts][indx][row][col];
531
0
                  sum_im_dir += self->w_dir[col][ts][qs].re *
532
0
                      self->r_out_im_in_m2[ts][indx][row][col];
533
0
              }
534
0
              self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
535
0
              self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
536
0
              self->hyb_diff_out[row][ts][qs].re -=
537
0
                  self->w_diff[1][ts][qs].im *
538
0
                  self->r_out_diff_im_in_m2[ts][indx][row][1];
539
0
              self->hyb_diff_out[row][ts][qs].im +=
540
0
                  self->w_diff[1][ts][qs].re *
541
0
                  self->r_out_diff_im_in_m2[ts][indx][row][1];
542
0
          }
543
0
        }
544
0
      }
545
0
    }
546
0
    else {
547
0
      WORD32 num_cols = (self->dir_sig_count + self->decor_sig_count) > 1
548
0
              ? 1
549
0
              : (self->dir_sig_count + self->decor_sig_count);
550
0
      for (ts = 0; ts < self->time_slots; ts++) {
551
0
        for (qs = 0; qs < 2; qs++) {
552
0
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
553
0
          for (row = 0; row < self->out_ch_count; row++) {
554
0
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
555
0
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
556
0
            if (num_cols > 0) {
557
0
              sum_re_dir += self->w_dir[0][ts][qs].im *
558
0
                  self->r_out_im_in_m2[ts][indx][row][0];
559
0
              sum_im_dir -= self->w_dir[0][ts][qs].re *
560
0
                  self->r_out_im_in_m2[ts][indx][row][0];
561
0
            }
562
0
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
563
0
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
564
0
          }
565
0
        }
566
0
        for (qs = 2; qs < self->hyb_band_count_max; qs++) {
567
0
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
568
0
          for (row = 0; row < self->out_ch_count; row++) {
569
0
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
570
0
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
571
0
            if (num_cols > 0) {
572
0
              sum_re_dir -= self->w_dir[0][ts][qs].im *
573
0
                              self->r_out_im_in_m2[ts][indx][row][0];
574
0
              sum_im_dir += self->w_dir[0][ts][qs].re *
575
0
                              self->r_out_im_in_m2[ts][indx][row][0];
576
0
            }
577
0
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
578
0
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
579
0
          }
580
0
        }
581
0
      }
582
0
    }
583
0
  }
584
0
  return;
585
0
}
586
587
15.3k
VOID ixheaacd_mps_apply_mix_matrix_type1(ia_mps_dec_state_struct *self) {
588
15.3k
  WORD32 ts, qs, row;
589
590
15.3k
  ixheaacd_mps_upmix_interp_type2(self->m2_decor_re, self->r_out_diff_re_in_m2,
591
15.3k
                                  self->m2_decor_re_prev, self->out_ch_count, self, 1);
592
593
15.3k
  ixheaacd_mps_upmix_interp_type2(self->m2_resid_re, self->r_out_re_in_m2, self->m2_resid_re_prev,
594
15.3k
                                  self->out_ch_count, self, 0);
595
596
748k
  for (qs = 0; qs < self->hyb_band_count[0]; qs++) {
597
732k
    WORD32 indx = self->hyb_band_to_processing_band_table[qs];
598
22.8M
    for (ts = 0; ts < self->time_slots; ts++) {
599
66.2M
      for (row = 0; row < self->out_ch_count; row++) {
600
44.1M
        self->hyb_dir_out[row][ts][qs].re =
601
44.1M
            self->w_dir[0][ts][qs].re * self->r_out_re_in_m2[ts][indx][row][0];
602
44.1M
        self->hyb_dir_out[row][ts][qs].im =
603
44.1M
            self->w_dir[0][ts][qs].im * self->r_out_re_in_m2[ts][indx][row][0];
604
44.1M
        self->hyb_diff_out[row][ts][qs].re =
605
44.1M
            self->w_diff[1][ts][qs].re *
606
44.1M
            self->r_out_diff_re_in_m2[ts][indx][row][1];
607
44.1M
        self->hyb_diff_out[row][ts][qs].im =
608
44.1M
            self->w_diff[1][ts][qs].im *
609
44.1M
            self->r_out_diff_re_in_m2[ts][indx][row][1];
610
44.1M
      }
611
22.0M
    }
612
732k
  }
613
15.3k
  return;
614
15.3k
}
615
616
8.82k
VOID ixheaacd_mps_apply_mix_matrix_type2(ia_mps_dec_state_struct *self) {
617
8.82k
  WORD32 ts, qs, row, col;
618
8.82k
  WORD32 complex_m2 = ((self->config->bs_phase_coding != 0));
619
8.82k
  WORD32 phase_interpolation = (self->config->bs_phase_coding == 1);
620
8.82k
  WORD32 num_col_iters = 0;
621
622
8.82k
  ixheaacd_mps_upmix_interp_type1(self->m2_decor_re, self->r_out_diff_re_in_m2,
623
8.82k
                                  self->m2_decor_re_prev, self->out_ch_count,
624
8.82k
                                  (self->dir_sig_count + self->decor_sig_count), self, 1);
625
8.82k
  ixheaacd_mps_upmix_interp_type1(self->m2_resid_re, self->r_out_re_in_m2, self->m2_resid_re_prev,
626
8.82k
                                  self->out_ch_count,
627
8.82k
                                  (self->dir_sig_count + self->decor_sig_count), self, 1);
628
629
8.82k
  if (complex_m2 && !phase_interpolation) {
630
3.70k
    ixheaacd_mps_upmix_interp_type1(self->m2_decor_im, self->r_out_diff_im_in_m2,
631
3.70k
                                    self->m2_decor_im_prev, self->out_ch_count,
632
3.70k
                                    (self->dir_sig_count + self->decor_sig_count), self, 1);
633
3.70k
    ixheaacd_mps_upmix_interp_type1(self->m2_resid_im, self->r_out_im_in_m2,
634
3.70k
                                    self->m2_resid_im_prev, self->out_ch_count,
635
3.70k
                                    (self->dir_sig_count + self->decor_sig_count), self, 1);
636
3.70k
  }
637
638
8.82k
  if (phase_interpolation) {
639
3.95k
    ixheaacd_mps_phase_interpolation(
640
3.95k
        self->phase_l, self->phase_r, self->phase_l_prev, self->phase_r_prev,
641
3.95k
        self->r_out_ph_re_in_m2, self->r_out_ph_im_in_m2, self);
642
643
131k
    for (ts = 0; ts < self->time_slots; ts++) {
644
127k
      WORD32 pb;
645
1.56M
      for (pb = 0; pb < self->bs_param_bands; pb++) {
646
1.43M
        self->r_out_im_in_m2[ts][pb][0][0] =
647
1.43M
            self->r_out_re_in_m2[ts][pb][0][0] *
648
1.43M
            self->r_out_ph_im_in_m2[ts][pb][0];
649
650
1.43M
        self->r_out_im_in_m2[ts][pb][0][1] =
651
1.43M
            self->r_out_re_in_m2[ts][pb][0][1] *
652
1.43M
            self->r_out_ph_im_in_m2[ts][pb][0];
653
1.43M
        self->r_out_im_in_m2[ts][pb][1][0] =
654
1.43M
            self->r_out_re_in_m2[ts][pb][1][0] *
655
1.43M
            self->r_out_ph_im_in_m2[ts][pb][1];
656
657
1.43M
        self->r_out_im_in_m2[ts][pb][1][1] =
658
1.43M
            self->r_out_re_in_m2[ts][pb][1][1] *
659
1.43M
            self->r_out_ph_im_in_m2[ts][pb][1];
660
661
1.43M
        self->r_out_re_in_m2[ts][pb][0][0] =
662
1.43M
            self->r_out_re_in_m2[ts][pb][0][0] *
663
1.43M
            self->r_out_ph_re_in_m2[ts][pb][0];
664
665
1.43M
        self->r_out_re_in_m2[ts][pb][0][1] =
666
1.43M
            self->r_out_re_in_m2[ts][pb][0][1] *
667
1.43M
            self->r_out_ph_re_in_m2[ts][pb][0];
668
669
1.43M
        self->r_out_re_in_m2[ts][pb][1][0] =
670
1.43M
            self->r_out_re_in_m2[ts][pb][1][0] *
671
1.43M
            self->r_out_ph_re_in_m2[ts][pb][1];
672
673
1.43M
        self->r_out_re_in_m2[ts][pb][1][1] =
674
1.43M
            self->r_out_re_in_m2[ts][pb][1][1] *
675
1.43M
            self->r_out_ph_re_in_m2[ts][pb][1];
676
677
1.43M
        self->r_out_diff_im_in_m2[ts][pb][0][0] = 0;
678
1.43M
        self->r_out_diff_im_in_m2[ts][pb][0][1] =
679
1.43M
            self->r_out_diff_re_in_m2[ts][pb][0][1] *
680
1.43M
            self->r_out_ph_im_in_m2[ts][pb][0];
681
682
1.43M
        self->r_out_diff_im_in_m2[ts][pb][1][0] = 0;
683
1.43M
        self->r_out_diff_im_in_m2[ts][pb][1][1] =
684
1.43M
            self->r_out_diff_re_in_m2[ts][pb][1][1] *
685
1.43M
            self->r_out_ph_im_in_m2[ts][pb][1];
686
687
1.43M
        self->r_out_diff_re_in_m2[ts][pb][0][0] = 0;
688
1.43M
        self->r_out_diff_re_in_m2[ts][pb][0][1] =
689
1.43M
            self->r_out_diff_re_in_m2[ts][pb][0][1] *
690
1.43M
            self->r_out_ph_re_in_m2[ts][pb][0];
691
692
1.43M
        self->r_out_diff_re_in_m2[ts][pb][1][0] = 0;
693
1.43M
        self->r_out_diff_re_in_m2[ts][pb][1][1] =
694
1.43M
            self->r_out_diff_re_in_m2[ts][pb][1][1] *
695
1.43M
            self->r_out_ph_re_in_m2[ts][pb][1];
696
1.43M
      }
697
127k
    }
698
3.95k
  }
699
8.82k
  if (self->res_bands == 0) {
700
4.93k
    num_col_iters = self->dir_sig_count;
701
4.93k
  } else {
702
3.89k
    num_col_iters = (self->dir_sig_count + self->decor_sig_count);
703
3.89k
  }
704
352k
  for (ts = 0; ts < self->time_slots; ts++) {
705
16.1M
    for (qs = 0; qs < self->hyb_band_count_max; qs++) {
706
15.8M
      WORD32 indx = self->hyb_band_to_processing_band_table[qs];
707
708
47.4M
      for (row = 0; row < self->out_ch_count; row++) {
709
31.6M
        FLOAT32 sum_re_dir = 0;
710
31.6M
        FLOAT32 sum_im_dir = 0;
711
75.3M
        for (col = 0; col < num_col_iters; col++) {
712
43.7M
          sum_re_dir += self->w_dir[col][ts][qs].re *
713
43.7M
                        self->r_out_re_in_m2[ts][indx][row][col];
714
43.7M
          sum_im_dir += self->w_dir[col][ts][qs].im *
715
43.7M
                        self->r_out_re_in_m2[ts][indx][row][col];
716
43.7M
        }
717
31.6M
        self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
718
31.6M
        self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
719
720
31.6M
        self->hyb_diff_out[row][ts][qs].re =
721
31.6M
            self->w_diff[1][ts][qs].re *
722
31.6M
            self->r_out_diff_re_in_m2[ts][indx][row][1];
723
31.6M
        self->hyb_diff_out[row][ts][qs].im =
724
31.6M
            self->w_diff[1][ts][qs].im *
725
31.6M
            self->r_out_diff_re_in_m2[ts][indx][row][1];
726
31.6M
      }
727
15.8M
    }
728
343k
  }
729
730
8.82k
  if (complex_m2) {
731
7.65k
    if (phase_interpolation) {
732
131k
      for (ts = 0; ts < self->time_slots; ts++) {
733
382k
        for (qs = 0; qs < 2; qs++) {
734
255k
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
735
765k
          for (row = 0; row < self->out_ch_count; row++) {
736
510k
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
737
510k
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
738
1.02M
            for (col = 0; col < num_col_iters; col++) {
739
510k
              sum_re_dir += self->w_dir[col][ts][qs].im *
740
510k
                            self->r_out_im_in_m2[ts][indx][row][col];
741
510k
              sum_im_dir -= self->w_dir[col][ts][qs].re *
742
510k
                            self->r_out_im_in_m2[ts][indx][row][col];
743
510k
            }
744
510k
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
745
510k
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
746
510k
            self->hyb_diff_out[row][ts][qs].re +=
747
510k
                self->w_diff[1][ts][qs].im *
748
510k
                self->r_out_diff_im_in_m2[ts][indx][row][1];
749
510k
            self->hyb_diff_out[row][ts][qs].im -=
750
510k
                self->w_diff[1][ts][qs].re *
751
510k
                self->r_out_diff_im_in_m2[ts][indx][row][1];
752
510k
          }
753
255k
        }
754
8.42M
        for (qs = 2; qs < self->hyb_band_count_max; qs++) {
755
8.29M
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
756
24.8M
          for (row = 0; row < self->out_ch_count; row++) {
757
16.5M
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
758
16.5M
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
759
33.1M
            for (col = 0; col < num_col_iters; col++) {
760
16.5M
              sum_re_dir -= self->w_dir[col][ts][qs].im *
761
16.5M
                            self->r_out_im_in_m2[ts][indx][row][col];
762
16.5M
              sum_im_dir += self->w_dir[col][ts][qs].re *
763
16.5M
                            self->r_out_im_in_m2[ts][indx][row][col];
764
16.5M
            }
765
16.5M
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
766
16.5M
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
767
16.5M
            self->hyb_diff_out[row][ts][qs].re -=
768
16.5M
                self->w_diff[1][ts][qs].im *
769
16.5M
                self->r_out_diff_im_in_m2[ts][indx][row][1];
770
16.5M
            self->hyb_diff_out[row][ts][qs].im +=
771
16.5M
                self->w_diff[1][ts][qs].re *
772
16.5M
                self->r_out_diff_im_in_m2[ts][indx][row][1];
773
16.5M
          }
774
8.29M
        }
775
127k
      }
776
3.95k
    } else {
777
3.70k
      WORD32 num_cols = (self->dir_sig_count + self->decor_sig_count) > 1
778
3.70k
                         ? 1
779
3.70k
                         : (self->dir_sig_count + self->decor_sig_count);
780
187k
      for (ts = 0; ts < self->time_slots; ts++) {
781
552k
        for (qs = 0; qs < 2; qs++) {
782
368k
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
783
1.10M
          for (row = 0; row < self->out_ch_count; row++) {
784
736k
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
785
736k
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
786
736k
            if (num_cols > 0) {
787
736k
              sum_re_dir += self->w_dir[0][ts][qs].im *
788
736k
                            self->r_out_im_in_m2[ts][indx][row][0];
789
736k
              sum_im_dir -= self->w_dir[0][ts][qs].re *
790
736k
                            self->r_out_im_in_m2[ts][indx][row][0];
791
736k
            }
792
736k
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
793
736k
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
794
736k
          }
795
368k
        }
796
5.59M
        for (qs = 2; qs < self->hyb_band_count_max; qs++) {
797
5.41M
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
798
16.2M
          for (row = 0; row < self->out_ch_count; row++) {
799
10.8M
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
800
10.8M
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
801
10.8M
            if (num_cols > 0) {
802
10.8M
              sum_re_dir -= self->w_dir[0][ts][qs].im *
803
10.8M
                            self->r_out_im_in_m2[ts][indx][row][0];
804
10.8M
              sum_im_dir += self->w_dir[0][ts][qs].re *
805
10.8M
                            self->r_out_im_in_m2[ts][indx][row][0];
806
10.8M
            }
807
10.8M
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
808
10.8M
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
809
10.8M
          }
810
5.41M
        }
811
184k
      }
812
3.70k
    }
813
7.65k
  }
814
8.82k
  return;
815
8.82k
}
816
817
80.2k
VOID ixheaacd_mps_apply_mix_matrix_type3(ia_mps_dec_state_struct *self) {
818
80.2k
  WORD32 ts, qs, row, col;
819
80.2k
  WORD32 complex_m2 = ((self->config->bs_phase_coding != 0));
820
80.2k
  WORD32 phase_interpolation = (self->config->bs_phase_coding == 1);
821
80.2k
  WORD32 num_col_iters = 0;
822
823
80.2k
  if (self->res_bands != 28) {
824
67.1k
    ixheaacd_mps_upmix_interp_type2(self->m2_decor_re, self->r_out_diff_re_in_m2,
825
67.1k
                                    self->m2_decor_re_prev, self->out_ch_count, self, 1);
826
67.1k
  }
827
80.2k
  if (self->res_bands == 0) {
828
23.3k
    num_col_iters = self->dir_sig_count;
829
23.3k
    ixheaacd_mps_upmix_interp_type2(self->m2_resid_re, self->r_out_re_in_m2,
830
23.3k
                                    self->m2_resid_re_prev, self->out_ch_count, self, 0);
831
56.8k
  } else {
832
56.8k
    num_col_iters = (self->dir_sig_count + self->decor_sig_count);
833
56.8k
    ixheaacd_mps_upmix_interp_type1(self->m2_resid_re, self->r_out_re_in_m2,
834
56.8k
                                    self->m2_resid_re_prev, self->out_ch_count,
835
56.8k
                                    (self->dir_sig_count + self->decor_sig_count), self, 1);
836
56.8k
  }
837
838
80.2k
  if (complex_m2 && !phase_interpolation) {
839
56.4k
    ixheaacd_mps_upmix_interp_type2(self->m2_resid_im, self->r_out_im_in_m2,
840
56.4k
                                    self->m2_resid_im_prev, self->out_ch_count, self, 0);
841
56.4k
  }
842
843
80.2k
  if (phase_interpolation) {
844
15.5k
    ixheaacd_mps_phase_interpolation(
845
15.5k
        self->phase_l, self->phase_r, self->phase_l_prev, self->phase_r_prev,
846
15.5k
        self->r_out_ph_re_in_m2, self->r_out_ph_im_in_m2, self);
847
848
15.5k
    if (self->res_bands == 0) {
849
528k
      for (ts = 0; ts < self->time_slots; ts++) {
850
512k
        WORD32 pb;
851
5.52M
        for (pb = 0; pb < self->bs_param_bands; pb++) {
852
5.01M
          self->r_out_im_in_m2[ts][pb][0][0] =
853
5.01M
              self->r_out_re_in_m2[ts][pb][0][0] *
854
5.01M
              self->r_out_ph_im_in_m2[ts][pb][0];
855
856
5.01M
          self->r_out_im_in_m2[ts][pb][1][0] =
857
5.01M
              self->r_out_re_in_m2[ts][pb][1][0] *
858
5.01M
              self->r_out_ph_im_in_m2[ts][pb][1];
859
860
5.01M
          self->r_out_re_in_m2[ts][pb][0][0] =
861
5.01M
              self->r_out_re_in_m2[ts][pb][0][0] *
862
5.01M
              self->r_out_ph_re_in_m2[ts][pb][0];
863
864
5.01M
          self->r_out_re_in_m2[ts][pb][1][0] =
865
5.01M
              self->r_out_re_in_m2[ts][pb][1][0] *
866
5.01M
              self->r_out_ph_re_in_m2[ts][pb][1];
867
868
5.01M
          self->r_out_diff_im_in_m2[ts][pb][0][1] =
869
5.01M
              self->r_out_diff_re_in_m2[ts][pb][0][1] *
870
5.01M
              self->r_out_ph_im_in_m2[ts][pb][0];
871
872
5.01M
          self->r_out_diff_im_in_m2[ts][pb][1][1] =
873
5.01M
              self->r_out_diff_re_in_m2[ts][pb][1][1] *
874
5.01M
              self->r_out_ph_im_in_m2[ts][pb][1];
875
876
5.01M
          self->r_out_diff_re_in_m2[ts][pb][0][1] =
877
5.01M
              self->r_out_diff_re_in_m2[ts][pb][0][1] *
878
5.01M
              self->r_out_ph_re_in_m2[ts][pb][0];
879
880
5.01M
          self->r_out_diff_re_in_m2[ts][pb][1][1] =
881
5.01M
              self->r_out_diff_re_in_m2[ts][pb][1][1] *
882
5.01M
              self->r_out_ph_re_in_m2[ts][pb][1];
883
5.01M
        }
884
512k
      }
885
15.5k
    } else if (self->res_bands == 28) {
886
0
      for (ts = 0; ts < self->time_slots; ts++) {
887
0
        WORD32 pb;
888
0
        for (pb = 0; pb < self->bs_param_bands; pb++) {
889
0
          self->r_out_im_in_m2[ts][pb][0][0] =
890
0
              self->r_out_re_in_m2[ts][pb][0][0] *
891
0
              self->r_out_ph_im_in_m2[ts][pb][0];
892
893
0
          self->r_out_im_in_m2[ts][pb][0][1] =
894
0
              self->r_out_re_in_m2[ts][pb][0][1] *
895
0
              self->r_out_ph_im_in_m2[ts][pb][0];
896
897
0
          self->r_out_im_in_m2[ts][pb][1][0] =
898
0
              self->r_out_re_in_m2[ts][pb][1][0] *
899
0
              self->r_out_ph_im_in_m2[ts][pb][1];
900
901
0
          self->r_out_im_in_m2[ts][pb][1][1] =
902
0
              self->r_out_re_in_m2[ts][pb][1][1] *
903
0
              self->r_out_ph_im_in_m2[ts][pb][1];
904
905
0
          self->r_out_re_in_m2[ts][pb][0][0] =
906
0
              self->r_out_re_in_m2[ts][pb][0][0] *
907
0
              self->r_out_ph_re_in_m2[ts][pb][0];
908
909
0
          self->r_out_re_in_m2[ts][pb][0][1] =
910
0
              self->r_out_re_in_m2[ts][pb][0][1] *
911
0
              self->r_out_ph_re_in_m2[ts][pb][0];
912
913
0
          self->r_out_re_in_m2[ts][pb][1][0] =
914
0
              self->r_out_re_in_m2[ts][pb][1][0] *
915
0
              self->r_out_ph_re_in_m2[ts][pb][1];
916
917
0
          self->r_out_re_in_m2[ts][pb][1][1] =
918
0
              self->r_out_re_in_m2[ts][pb][1][1] *
919
0
              self->r_out_ph_re_in_m2[ts][pb][1];
920
0
        }
921
0
      }
922
0
    } else {
923
0
      for (ts = 0; ts < self->time_slots; ts++) {
924
0
        WORD32 pb;
925
0
        for (pb = 0; pb < self->bs_param_bands; pb++) {
926
0
          self->r_out_im_in_m2[ts][pb][0][0] =
927
0
              self->r_out_re_in_m2[ts][pb][0][0] *
928
0
              self->r_out_ph_im_in_m2[ts][pb][0];
929
930
0
          self->r_out_im_in_m2[ts][pb][0][1] =
931
0
              self->r_out_re_in_m2[ts][pb][0][1] *
932
0
              self->r_out_ph_im_in_m2[ts][pb][0];
933
934
0
          self->r_out_im_in_m2[ts][pb][1][0] =
935
0
              self->r_out_re_in_m2[ts][pb][1][0] *
936
0
              self->r_out_ph_im_in_m2[ts][pb][1];
937
938
0
          self->r_out_im_in_m2[ts][pb][1][1] =
939
0
              self->r_out_re_in_m2[ts][pb][1][1] *
940
0
              self->r_out_ph_im_in_m2[ts][pb][1];
941
942
0
          self->r_out_re_in_m2[ts][pb][0][0] =
943
0
              self->r_out_re_in_m2[ts][pb][0][0] *
944
0
              self->r_out_ph_re_in_m2[ts][pb][0];
945
946
0
          self->r_out_re_in_m2[ts][pb][0][1] =
947
0
              self->r_out_re_in_m2[ts][pb][0][1] *
948
0
              self->r_out_ph_re_in_m2[ts][pb][0];
949
950
0
          self->r_out_re_in_m2[ts][pb][1][0] =
951
0
              self->r_out_re_in_m2[ts][pb][1][0] *
952
0
              self->r_out_ph_re_in_m2[ts][pb][1];
953
954
0
          self->r_out_re_in_m2[ts][pb][1][1] =
955
0
              self->r_out_re_in_m2[ts][pb][1][1] *
956
0
              self->r_out_ph_re_in_m2[ts][pb][1];
957
958
0
          self->r_out_diff_im_in_m2[ts][pb][0][1] =
959
0
              self->r_out_diff_re_in_m2[ts][pb][0][1] *
960
0
              self->r_out_ph_im_in_m2[ts][pb][0];
961
962
0
          self->r_out_diff_im_in_m2[ts][pb][1][1] =
963
0
              self->r_out_diff_re_in_m2[ts][pb][1][1] *
964
0
              self->r_out_ph_im_in_m2[ts][pb][1];
965
966
0
          self->r_out_diff_re_in_m2[ts][pb][0][1] =
967
0
              self->r_out_diff_re_in_m2[ts][pb][0][1] *
968
0
              self->r_out_ph_re_in_m2[ts][pb][0];
969
970
0
          self->r_out_diff_re_in_m2[ts][pb][1][1] =
971
0
              self->r_out_diff_re_in_m2[ts][pb][1][1] *
972
0
              self->r_out_ph_re_in_m2[ts][pb][1];
973
0
        }
974
0
      }
975
0
    }
976
15.5k
  }
977
80.2k
  if (self->res_bands == 0) {
978
799k
    for (ts = 0; ts < self->time_slots; ts++) {
979
34.8M
      for (qs = 0; qs < self->hyb_band_count[0]; qs++) {
980
34.0M
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
981
102M
        for (row = 0; row < self->out_ch_count; row++) {
982
68.1M
          self->hyb_dir_out[row][ts][qs].re =
983
68.1M
              self->w_dir[0][ts][qs].re *
984
68.1M
              self->r_out_re_in_m2[ts][indx][row][0];
985
68.1M
          self->hyb_dir_out[row][ts][qs].im =
986
68.1M
              self->w_dir[0][ts][qs].im *
987
68.1M
              self->r_out_re_in_m2[ts][indx][row][0];
988
68.1M
          self->hyb_diff_out[row][ts][qs].re =
989
68.1M
              self->w_diff[1][ts][qs].re *
990
68.1M
              self->r_out_diff_re_in_m2[ts][indx][row][1];
991
68.1M
          self->hyb_diff_out[row][ts][qs].im =
992
68.1M
              self->w_diff[1][ts][qs].im *
993
68.1M
              self->r_out_diff_re_in_m2[ts][indx][row][1];
994
68.1M
        }
995
34.0M
      }
996
775k
    }
997
56.8k
  } else if (self->res_bands == 28) {
998
431k
    for (ts = 0; ts < self->time_slots; ts++) {
999
16.7M
      for (qs = 0; qs < self->hyb_band_count[1]; qs++) {
1000
16.3M
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1001
48.9M
        for (row = 0; row < self->out_ch_count; row++) {
1002
32.6M
          FLOAT32 sum_re_dir = 0;
1003
32.6M
          FLOAT32 sum_im_dir = 0;
1004
97.8M
          for (col = 0; col < num_col_iters; col++) {
1005
65.2M
            sum_re_dir += self->w_dir[col][ts][qs].re *
1006
65.2M
                          self->r_out_re_in_m2[ts][indx][row][col];
1007
65.2M
            sum_im_dir += self->w_dir[col][ts][qs].im *
1008
65.2M
                          self->r_out_re_in_m2[ts][indx][row][col];
1009
65.2M
          }
1010
32.6M
          self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1011
32.6M
          self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1012
32.6M
        }
1013
16.3M
      }
1014
435k
      for (; qs < self->hyb_band_count[0]; qs++) {
1015
17.0k
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1016
51.2k
        for (row = 0; row < self->out_ch_count; row++) {
1017
34.1k
          self->hyb_dir_out[row][ts][qs].re =
1018
34.1k
              self->w_dir[0][ts][qs].re *
1019
34.1k
              self->r_out_re_in_m2[ts][indx][row][0];
1020
34.1k
          self->hyb_dir_out[row][ts][qs].im =
1021
34.1k
              self->w_dir[0][ts][qs].im *
1022
34.1k
              self->r_out_re_in_m2[ts][indx][row][0];
1023
34.1k
        }
1024
17.0k
      }
1025
418k
    }
1026
43.7k
  } else {
1027
43.7k
    WORD32 dif_s = ixheaacd_mps_gain_set_indx[self->res_bands];
1028
1.87M
    for (ts = 0; ts < self->time_slots; ts++) {
1029
29.6M
      for (qs = 0; qs < dif_s; qs++) {
1030
27.7M
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1031
83.3M
        for (row = 0; row < self->out_ch_count; row++) {
1032
55.5M
          FLOAT32 sum_re_dir = 0;
1033
55.5M
          FLOAT32 sum_im_dir = 0;
1034
166M
          for (col = 0; col < num_col_iters; col++) {
1035
111M
            sum_re_dir += self->w_dir[col][ts][qs].re *
1036
111M
                          self->r_out_re_in_m2[ts][indx][row][col];
1037
111M
            sum_im_dir += self->w_dir[col][ts][qs].im *
1038
111M
                          self->r_out_re_in_m2[ts][indx][row][col];
1039
111M
          }
1040
55.5M
          self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1041
55.5M
          self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1042
55.5M
        }
1043
27.7M
      }
1044
33.7M
      for (; qs < self->hyb_band_count[1]; qs++) {
1045
31.9M
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1046
95.8M
        for (row = 0; row < self->out_ch_count; row++) {
1047
63.8M
          FLOAT32 sum_re_dir = 0;
1048
63.8M
          FLOAT32 sum_im_dir = 0;
1049
191M
          for (col = 0; col < num_col_iters; col++) {
1050
127M
            sum_re_dir += self->w_dir[col][ts][qs].re *
1051
127M
                          self->r_out_re_in_m2[ts][indx][row][col];
1052
127M
            sum_im_dir += self->w_dir[col][ts][qs].im *
1053
127M
                          self->r_out_re_in_m2[ts][indx][row][col];
1054
127M
          }
1055
63.8M
          self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1056
63.8M
          self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1057
63.8M
          self->hyb_diff_out[row][ts][qs].re =
1058
63.8M
              self->w_diff[1][ts][qs].re *
1059
63.8M
              self->r_out_diff_re_in_m2[ts][indx][row][1];
1060
63.8M
          self->hyb_diff_out[row][ts][qs].im =
1061
63.8M
              self->w_diff[1][ts][qs].im *
1062
63.8M
              self->r_out_diff_re_in_m2[ts][indx][row][1];
1063
63.8M
        }
1064
31.9M
      }
1065
24.8M
      for (; qs < self->hyb_band_count[0]; qs++) {
1066
22.9M
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1067
68.9M
        for (row = 0; row < self->out_ch_count; row++) {
1068
45.9M
          self->hyb_dir_out[row][ts][qs].re =
1069
45.9M
              self->w_dir[0][ts][qs].re *
1070
45.9M
              self->r_out_re_in_m2[ts][indx][row][0];
1071
45.9M
          self->hyb_dir_out[row][ts][qs].im =
1072
45.9M
              self->w_dir[0][ts][qs].im *
1073
45.9M
              self->r_out_re_in_m2[ts][indx][row][0];
1074
45.9M
          self->hyb_diff_out[row][ts][qs].re =
1075
45.9M
              self->w_diff[1][ts][qs].re *
1076
45.9M
              self->r_out_diff_re_in_m2[ts][indx][row][1];
1077
45.9M
          self->hyb_diff_out[row][ts][qs].im =
1078
45.9M
              self->w_diff[1][ts][qs].im *
1079
45.9M
              self->r_out_diff_re_in_m2[ts][indx][row][1];
1080
45.9M
        }
1081
22.9M
      }
1082
1.83M
    }
1083
43.7k
  }
1084
1085
80.2k
  if (complex_m2) {
1086
71.9k
    if (phase_interpolation) {
1087
528k
      for (ts = 0; ts < self->time_slots; ts++) {
1088
1.53M
        for (qs = 0; qs < 2; qs++) {
1089
1.02M
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1090
3.07M
          for (row = 0; row < self->out_ch_count; row++) {
1091
2.05M
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
1092
2.05M
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
1093
4.10M
            for (col = 0; col < num_col_iters; col++) {
1094
2.05M
              sum_re_dir += self->w_dir[col][ts][qs].im *
1095
2.05M
                            self->r_out_im_in_m2[ts][indx][row][col];
1096
2.05M
              sum_im_dir -= self->w_dir[col][ts][qs].re *
1097
2.05M
                            self->r_out_im_in_m2[ts][indx][row][col];
1098
2.05M
            }
1099
2.05M
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1100
2.05M
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1101
2.05M
            self->hyb_diff_out[row][ts][qs].re +=
1102
2.05M
                self->w_diff[1][ts][qs].im *
1103
2.05M
                self->r_out_diff_im_in_m2[ts][indx][row][1];
1104
2.05M
            self->hyb_diff_out[row][ts][qs].im -=
1105
2.05M
                self->w_diff[1][ts][qs].re *
1106
2.05M
                self->r_out_diff_im_in_m2[ts][indx][row][1];
1107
2.05M
          }
1108
1.02M
        }
1109
29.2M
        for (qs = 2; qs < self->hyb_band_count_max; qs++) {
1110
28.7M
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1111
86.1M
          for (row = 0; row < self->out_ch_count; row++) {
1112
57.4M
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
1113
57.4M
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
1114
114M
            for (col = 0; col < num_col_iters; col++) {
1115
57.4M
              sum_re_dir -= self->w_dir[col][ts][qs].im *
1116
57.4M
                            self->r_out_im_in_m2[ts][indx][row][col];
1117
57.4M
              sum_im_dir += self->w_dir[col][ts][qs].re *
1118
57.4M
                            self->r_out_im_in_m2[ts][indx][row][col];
1119
57.4M
            }
1120
57.4M
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1121
57.4M
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1122
57.4M
            self->hyb_diff_out[row][ts][qs].re -=
1123
57.4M
                self->w_diff[1][ts][qs].im *
1124
57.4M
                self->r_out_diff_im_in_m2[ts][indx][row][1];
1125
57.4M
            self->hyb_diff_out[row][ts][qs].im +=
1126
57.4M
                self->w_diff[1][ts][qs].re *
1127
57.4M
                self->r_out_diff_im_in_m2[ts][indx][row][1];
1128
57.4M
          }
1129
28.7M
        }
1130
512k
      }
1131
56.4k
    } else {
1132
56.4k
      WORD32 num_cols = (self->dir_sig_count + self->decor_sig_count) > 1
1133
56.4k
                         ? 1
1134
56.4k
                         : (self->dir_sig_count + self->decor_sig_count);
1135
2.24M
      for (ts = 0; ts < self->time_slots; ts++) {
1136
6.55M
        for (qs = 0; qs < 2; qs++) {
1137
4.37M
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1138
13.1M
          for (row = 0; row < self->out_ch_count; row++) {
1139
8.74M
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
1140
8.74M
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
1141
8.74M
            if (num_cols > 0) {
1142
8.74M
              sum_re_dir += self->w_dir[0][ts][qs].im *
1143
8.74M
                            self->r_out_im_in_m2[ts][indx][row][0];
1144
8.74M
              sum_im_dir -= self->w_dir[0][ts][qs].re *
1145
8.74M
                            self->r_out_im_in_m2[ts][indx][row][0];
1146
8.74M
            }
1147
8.74M
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1148
8.74M
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1149
8.74M
          }
1150
4.37M
        }
1151
91.9M
        for (qs = 2; qs < self->hyb_band_count_max; qs++) {
1152
89.7M
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1153
269M
          for (row = 0; row < self->out_ch_count; row++) {
1154
179M
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
1155
179M
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
1156
179M
            if (num_cols > 0) {
1157
179M
              sum_re_dir -= self->w_dir[0][ts][qs].im *
1158
179M
                            self->r_out_im_in_m2[ts][indx][row][0];
1159
179M
              sum_im_dir += self->w_dir[0][ts][qs].re *
1160
179M
                            self->r_out_im_in_m2[ts][indx][row][0];
1161
179M
            }
1162
179M
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1163
179M
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1164
179M
          }
1165
89.7M
        }
1166
2.18M
      }
1167
56.4k
    }
1168
71.9k
  }
1169
80.2k
  return;
1170
80.2k
}
1171
1172
VOID ixheaacd_mps_upmix_interp(
1173
    FLOAT32 m_matrix[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT],
1174
    FLOAT32 r_matrix_float[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT],
1175
    FLOAT32 m_matrix_prev[MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT], WORD32 num_rows,
1176
0
    WORD32 num_cols, ia_mps_dec_state_struct *self, WORD32 bs_high_rate_mode) {
1177
0
  WORD32 ts, ps, pb, row, col, i;
1178
0
  FLOAT32 ks, ms, ls;
1179
0
  FLOAT32 fl_step, fl_base;
1180
1181
0
  for (pb = 0; pb < self->bs_param_bands; pb++) {
1182
0
    for (row = 0; row < num_rows; row++) {
1183
0
      for (col = 0; col < num_cols; col++) {
1184
0
        ts = 0;
1185
0
        ps = 0;
1186
0
        ks = self->inv_param_slot_diff[ps];
1187
0
        ms = m_matrix[ps][pb][row][col];
1188
0
        ls = m_matrix_prev[pb][row][col];
1189
0
        fl_step = ks * (ms - ls);
1190
0
        fl_base = ls + fl_step;
1191
1192
0
        for (i = 1; i <= (WORD32)self->param_slot_diff[0]; i++) {
1193
0
          r_matrix_float[ts][pb][row][col] = fl_base;
1194
0
          fl_base += fl_step;
1195
0
          ts++;
1196
0
        }
1197
0
        if (bs_high_rate_mode) {
1198
0
          for (ps = 1; ps < self->num_parameter_sets; ps++) {
1199
0
            ks = self->inv_param_slot_diff[ps];
1200
0
            ms = m_matrix[ps][pb][row][col];
1201
0
            ls = m_matrix[ps - 1][pb][row][col];
1202
0
            fl_step = ks * (ms - ls);
1203
0
            fl_base = ls + fl_step;
1204
1205
0
            for (i = 1; i <= (WORD32)self->param_slot_diff[ps]; i++) {
1206
0
              r_matrix_float[ts][pb][row][col] = fl_base;
1207
0
              fl_base += fl_step;
1208
0
              ts++;
1209
0
            }
1210
0
          }
1211
0
        }
1212
0
      }
1213
0
    }
1214
0
  }
1215
0
  return;
1216
0
}
1217
1218
VOID ixheaacd_mps_upmix_interp_type1(
1219
    FLOAT32 m_matrix[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT],
1220
    FLOAT32 r_matrix_float[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT],
1221
    FLOAT32 m_matrix_prev[MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT], WORD32 num_rows,
1222
90.7k
    WORD32 num_cols, ia_mps_dec_state_struct *self, WORD32 bs_high_rate_mode) {
1223
90.7k
  WORD32 ts, ps, pb, row, col, i;
1224
90.7k
  FLOAT32 ks, ms, ls;
1225
90.7k
  FLOAT32 fl_step, fl_base;
1226
1227
1.39M
  for (pb = 0; pb < self->bs_param_bands; pb++) {
1228
3.92M
    for (row = 0; row < num_rows; row++) {
1229
7.66M
      for (col = 0; col < num_cols; col++) {
1230
5.04M
        ts = 0;
1231
5.04M
        ps = 0;
1232
5.04M
        ks = self->inv_param_slot_diff[ps];
1233
5.04M
        ms = m_matrix[ps][pb][row][col];
1234
5.04M
        ls = m_matrix_prev[pb][row][col];
1235
5.04M
        fl_step = ks * (ms - ls);
1236
5.04M
        fl_base = ls + fl_step;
1237
1238
150M
        for (i = 1; i <= (WORD32)self->param_slot_diff[0]; i++) {
1239
145M
          r_matrix_float[ts][pb][row][col] = fl_base;
1240
145M
          fl_base += fl_step;
1241
145M
          ts++;
1242
145M
        }
1243
5.04M
        if (bs_high_rate_mode) {
1244
7.22M
          for (ps = 1; ps < self->num_parameter_sets; ps++) {
1245
2.20M
            ks = self->inv_param_slot_diff[ps];
1246
2.20M
            ms = m_matrix[ps][pb][row][col];
1247
2.20M
            ls = m_matrix[ps - 1][pb][row][col];
1248
2.20M
            fl_step = ks * (ms - ls);
1249
2.20M
            fl_base = ls + fl_step;
1250
1251
35.3M
            for (i = 1; i <= self->param_slot_diff[ps]; i++) {
1252
33.1M
              r_matrix_float[ts][pb][row][col] = fl_base;
1253
33.1M
              fl_base += fl_step;
1254
33.1M
              ts++;
1255
33.1M
            }
1256
2.20M
          }
1257
5.01M
        }
1258
5.04M
      }
1259
2.61M
    }
1260
1.30M
  }
1261
90.7k
  return;
1262
90.7k
}
1263
1264
VOID ixheaacd_mps_upmix_interp_type2(
1265
    FLOAT32 m_matrix[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT],
1266
    FLOAT32 r_matrix_float[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT],
1267
    FLOAT32 m_matrix_prev[MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT], WORD32 num_rows,
1268
177k
    ia_mps_dec_state_struct *self, WORD32 col) {
1269
177k
  WORD32 ts, ps, pb, row, i;
1270
177k
  FLOAT32 ks, ms, ls;
1271
177k
  FLOAT32 fl_step, fl_base;
1272
1273
2.68M
  for (pb = 0; pb < self->bs_param_bands; pb++) {
1274
7.52M
    for (row = 0; row < num_rows; row++) {
1275
5.01M
      ts = 0;
1276
5.01M
      ps = 0;
1277
5.01M
      ks = self->inv_param_slot_diff[ps];
1278
5.01M
      ms = m_matrix[ps][pb][row][col];
1279
5.01M
      ls = m_matrix_prev[pb][row][col];
1280
5.01M
      fl_step = ks * (ms - ls);
1281
5.01M
      fl_base = ls + fl_step;
1282
1283
165M
      for (i = 1; i <= (WORD32)self->param_slot_diff[0]; i++) {
1284
160M
        r_matrix_float[ts][pb][row][col] = fl_base;
1285
160M
        fl_base += fl_step;
1286
160M
        ts++;
1287
160M
      }
1288
5.51M
      for (ps = 1; ps < self->num_parameter_sets; ps++) {
1289
506k
        ks = self->inv_param_slot_diff[ps];
1290
506k
        ms = m_matrix[ps][pb][row][col];
1291
506k
        ls = m_matrix[ps - 1][pb][row][col];
1292
506k
        fl_step = ks * (ms - ls);
1293
506k
        fl_base = ls + fl_step;
1294
1295
8.10M
        for (i = 1; i <= (WORD32)self->param_slot_diff[ps]; i++) {
1296
7.60M
          r_matrix_float[ts][pb][row][col] = fl_base;
1297
7.60M
          fl_base += fl_step;
1298
7.60M
          ts++;
1299
7.60M
        }
1300
506k
      }
1301
5.01M
    }
1302
2.50M
  }
1303
177k
  return;
1304
177k
}
1305
1306
static FLOAT32 ixheaacd_mps_angle_interpolation(FLOAT32 angle1, FLOAT32 angle2,
1307
613k
                                                FLOAT32 alpha, FLOAT32 *step) {
1308
618k
  while (angle2 - angle1 > (FLOAT32)P_PI) {
1309
5.75k
    angle1 = angle1 + 2.0f * (FLOAT32)P_PI;
1310
5.75k
  }
1311
617k
  while (angle1 - angle2 > (FLOAT32)P_PI) {
1312
4.58k
    angle2 = angle2 + 2.0f * (FLOAT32)P_PI;
1313
4.58k
  }
1314
613k
  *step = angle2 - angle1;
1315
613k
  return (1 - alpha) * angle1 + alpha * angle2;
1316
613k
}
1317
1318
VOID ixheaacd_mps_phase_interpolation(
1319
    FLOAT32 pl[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS],
1320
    FLOAT32 pr[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS],
1321
    FLOAT32 pl_prev[MAX_PARAMETER_BANDS], FLOAT32 pr_prev[MAX_PARAMETER_BANDS],
1322
    FLOAT32 r_re[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][2],
1323
    FLOAT32 r_im[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][2],
1324
19.5k
    ia_mps_dec_state_struct *self) {
1325
19.5k
  WORD32 i, ts, ps, pb;
1326
19.5k
  FLOAT32 step_l, step_r, alpha, tl, tr;
1327
216k
  for (pb = 0; pb < self->bs_param_bands; pb++) {
1328
196k
    ps = 0;
1329
196k
    ts = 0;
1330
196k
    alpha = (FLOAT32)self->inv_param_slot_diff[ps];
1331
196k
    tl = ixheaacd_mps_angle_interpolation(pl_prev[pb], pl[ps][pb], alpha,
1332
196k
                                          &step_l);
1333
196k
    tr = ixheaacd_mps_angle_interpolation(pr_prev[pb], pr[ps][pb], alpha,
1334
196k
                                          &step_r);
1335
196k
    step_l *= alpha;
1336
196k
    step_r *= alpha;
1337
1338
5.47M
    for (i = 1; i <= self->param_slot_diff[ps]; i++) {
1339
5.28M
      r_re[ts][pb][0] = (FLOAT32)cos(tl);
1340
5.28M
      r_im[ts][pb][0] = (FLOAT32)sin(tl);
1341
5.28M
      tl += step_l;
1342
1343
5.28M
      r_re[ts][pb][1] = (FLOAT32)cos(tr);
1344
5.28M
      r_im[ts][pb][1] = (FLOAT32)sin(tr);
1345
5.28M
      tr += step_r;
1346
5.28M
      ts++;
1347
5.28M
    }
1348
1349
306k
    for (ps = 1; ps < self->num_parameter_sets; ps++) {
1350
109k
      FLOAT32 alpha = self->inv_param_slot_diff[ps];
1351
109k
      tl = ixheaacd_mps_angle_interpolation(pl[ps - 1][pb], pl[ps][pb], alpha,
1352
109k
                                            &step_l);
1353
109k
      tr = ixheaacd_mps_angle_interpolation(pr[ps - 1][pb], pr[ps][pb], alpha,
1354
109k
                                            &step_r);
1355
109k
      step_l *= alpha;
1356
109k
      step_r *= alpha;
1357
1.28M
      for (i = 1; i <= self->param_slot_diff[ps]; i++) {
1358
1.17M
        if (ts < 72 && pb < 28) {
1359
1.17M
          r_re[ts][pb][0] = (FLOAT32)cos(tl);
1360
1.17M
          r_im[ts][pb][0] = (FLOAT32)sin(tl);
1361
1.17M
          tl += step_l;
1362
1363
1.17M
          r_re[ts][pb][1] = (FLOAT32)cos(tr);
1364
1.17M
          r_im[ts][pb][1] = (FLOAT32)sin(tr);
1365
1.17M
          tr += step_r;
1366
1.17M
        }
1367
1.17M
        ts++;
1368
1369
1.17M
        if (ts > 71) {
1370
0
          ts = 0;
1371
0
          break;
1372
0
        }
1373
1.17M
        if (pb > 27) {
1374
0
          pb = 0;
1375
0
          break;
1376
0
        }
1377
1.17M
      }
1378
109k
    }
1379
196k
  }
1380
19.5k
}
1381
1382
3.41k
VOID ixheaacd_mps_init_pre_and_post_matrix(ia_mps_dec_state_struct *self) {
1383
3.41k
  memset(self->m1_param_re_prev, 0,
1384
3.41k
         MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
1385
3.41k
  memset(self->m1_param_im_prev, 0,
1386
3.41k
         MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
1387
3.41k
  memset(self->m1_param_re_prev, 0,
1388
3.41k
         MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
1389
3.41k
  memset(self->m2_decor_re_prev, 0,
1390
3.41k
         MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
1391
3.41k
  memset(self->m2_resid_re_prev, 0,
1392
3.41k
         MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
1393
3.41k
  memset(self->m2_resid_im_prev, 0,
1394
3.41k
         MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
1395
3.41k
}