Coverage Report

Created: 2025-10-10 06:12

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.44M
#define P_PI 3.1415926535897932
45
67.3k
#define PI_IN_Q28 843314880
46
1.47M
#define MULT(a, b) (a * b)
47
67.3k
#define Q28_FLOAT_VAL ((FLOAT32)(1 << 28))
48
67.3k
#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
67.3k
static WORD32 ixheaacd_mps_phase_wraping(WORD32 phase) {
64
67.3k
  const WORD32 pi_2 = 2 * PI_IN_Q28;
65
66
91.0k
  while (phase < 0) phase += pi_2;
67
67.3k
  while (phase >= pi_2) phase -= pi_2;
68
67.3k
  assert((phase >= 0) && (phase < pi_2));
69
70
67.3k
  return phase;
71
67.3k
}
72
73
static VOID ixheaacd_mps_buffer_pre_and_mix_matrix(
74
108k
    ia_mps_dec_state_struct *self) {
75
108k
  WORD32 pb, row, col;
76
77
1.36M
  for (pb = 0; pb < self->bs_param_bands; pb++) {
78
3.77M
    for (row = 0; row < MAX_M_INPUT; row++) {
79
7.55M
      for (col = 0; col < MAX_M_OUTPUT; col++) {
80
5.03M
        self->m1_param_re_prev[pb][row][col] =
81
5.03M
            self->m1_param_re[self->num_parameter_sets_prev - 1][pb][row][col];
82
5.03M
        self->m1_param_im_prev[pb][row][col] =
83
5.03M
            self->m1_param_im[self->num_parameter_sets_prev - 1][pb][row][col];
84
5.03M
        self->m2_decor_re_prev[pb][row][col] =
85
5.03M
            self->m2_decor_re[self->num_parameter_sets_prev - 1][pb][row][col];
86
5.03M
        self->m2_decor_im_prev[pb][row][col] =
87
5.03M
            self->m2_decor_im[self->num_parameter_sets_prev - 1][pb][row][col];
88
5.03M
        self->m2_resid_re_prev[pb][row][col] =
89
5.03M
            self->m2_resid_re[self->num_parameter_sets_prev - 1][pb][row][col];
90
5.03M
        self->m2_resid_im_prev[pb][row][col] =
91
5.03M
            self->m2_resid_im[self->num_parameter_sets_prev - 1][pb][row][col];
92
5.03M
      }
93
2.51M
    }
94
1.25M
  }
95
96
1.36M
  for (pb = 0; pb < self->bs_param_bands; pb++) {
97
1.25M
    self->phase_l_prev[pb] =
98
1.25M
        self->phase_l[self->num_parameter_sets_prev - 1][pb];
99
1.25M
    self->phase_r_prev[pb] =
100
1.25M
        self->phase_r[self->num_parameter_sets_prev - 1][pb];
101
1.25M
  }
102
108k
}
103
104
108k
VOID ixheaacd_pre_and_mix_matrix_calculation(ia_mps_dec_state_struct *self) {
105
108k
  WORD32 ps, pb;
106
108k
  ia_mps_bs_frame *curr_bit_stream = &(self->bs_frame);
107
108k
  FLOAT32 h_imag[2 * MAX_PARAMETER_BANDS];
108
108k
  FLOAT32 h_real[6 * MAX_PARAMETER_BANDS];
109
110
108k
  ixheaacd_mps_buffer_pre_and_mix_matrix(self);
111
112
239k
  for (ps = 0; ps < self->num_parameter_sets; ps++) {
113
130k
    FLOAT32 *h_im = &h_imag[0];
114
130k
    FLOAT32 *h_re = &h_real[0];
115
116
130k
    memset(h_real, 0, 6 * MAX_PARAMETER_BANDS * sizeof(FLOAT32));
117
130k
    memset(h_imag, 0, 2 * MAX_PARAMETER_BANDS * sizeof(FLOAT32));
118
119
130k
    switch (self->config->bs_phase_coding) {
120
30.0k
      case 0:
121
30.0k
        if (self->residual_coding) {
122
26.8k
          ixheaacd_mps_par2umx_pred(self, curr_bit_stream, h_imag, h_real, ps,
123
26.8k
                                    self->res_bands);
124
26.8k
        } else {
125
3.23k
          ixheaacd_mps_par2umx_ps(self, curr_bit_stream, h_real, ps);
126
3.23k
        }
127
128
30.0k
        break;
129
35.0k
      case 1:
130
35.0k
        ixheaacd_mps_par2umx_ps_ipd_opd(self, curr_bit_stream, h_real, ps);
131
35.0k
        break;
132
65.3k
      case 2:
133
65.3k
        ixheaacd_mps_par2umx_pred(self, curr_bit_stream, h_imag, h_real, ps,
134
65.3k
                                  self->res_bands);
135
65.3k
        break;
136
130k
    }
137
138
1.63M
    for (pb = 0; pb < self->bs_param_bands; pb++) {
139
1.50M
      self->m1_param_re[ps][pb][0][0] = 1.0f;
140
1.50M
      self->m1_param_re[ps][pb][1][0] = 1.0f;
141
142
1.50M
      self->m1_param_im[ps][pb][0][0] = 0;
143
1.50M
      self->m1_param_im[ps][pb][1][0] = 0;
144
145
1.50M
      self->m2_resid_re[ps][pb][0][0] = *h_re++;
146
1.50M
      self->m2_resid_im[ps][pb][0][0] = *h_im++;
147
1.50M
      self->m2_resid_im[ps][pb][0][1] = 0;
148
149
1.50M
      self->m2_resid_re[ps][pb][1][0] = *h_re++;
150
1.50M
      self->m2_resid_im[ps][pb][1][0] = *h_im++;
151
1.50M
      self->m2_resid_im[ps][pb][1][1] = 0;
152
153
1.50M
      self->m2_decor_re[ps][pb][0][0] = 0;
154
1.50M
      self->m2_decor_im[ps][pb][0][0] = 0;
155
1.50M
      self->m2_decor_re[ps][pb][0][1] = *h_re++;
156
1.50M
      self->m2_decor_im[ps][pb][0][1] = 0;
157
158
1.50M
      self->m2_decor_re[ps][pb][1][0] = 0;
159
1.50M
      self->m2_decor_im[ps][pb][1][0] = 0;
160
1.50M
      self->m2_decor_re[ps][pb][1][1] = *h_re++;
161
1.50M
      self->m2_decor_im[ps][pb][1][1] = 0;
162
163
1.50M
      self->m2_resid_re[ps][pb][0][1] = *h_re++;
164
1.50M
      self->m2_resid_re[ps][pb][1][1] = *h_re++;
165
1.50M
    }
166
130k
  }
167
108k
  ixheaacd_mps_smoothing_opd(self);
168
108k
}
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
38.2k
                                         FLOAT32 *h_real) {
174
38.2k
  WORD32 band;
175
38.2k
  FLOAT32 c_l_temp, c_r_temp, temp;
176
38.2k
  WORD32 cld_idx, icc_idx;
177
178
408k
  for (band = 0; band < ott_band_count; band++) {
179
369k
    cld_idx = *cld++ + 15;
180
369k
    icc_idx = *icc++;
181
182
369k
    icc_idx = icc_idx & 7;
183
184
369k
    c_l_temp = (ixheaacd_c_l_table[cld_idx]);
185
369k
    c_r_temp = (ixheaacd_c_l_table[30 - cld_idx]);
186
187
369k
    temp = ixheaacd_cos_table[icc_idx][cld_idx];
188
369k
    *h_real++ = MULT(temp, c_l_temp);
189
190
369k
    temp = ixheaacd_cos_table[icc_idx][30 - cld_idx];
191
369k
    *h_real++ = MULT(temp, c_r_temp);
192
193
369k
    temp = ixheaacd_sin_table[icc_idx][cld_idx];
194
369k
    *h_real++ = MULT(temp, c_l_temp);
195
196
369k
    temp = -ixheaacd_sin_table[icc_idx][30 - cld_idx];
197
369k
    *h_real++ = MULT(temp, c_r_temp);
198
199
369k
    h_real += 2;
200
369k
  }
201
38.2k
}
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
3.23k
                             WORD32 param_set_idx) {
206
3.23k
  ixheaacd_mps_par2umx_ps_core(curr_bit_stream->cld_idx[param_set_idx],
207
3.23k
                               curr_bit_stream->icc_idx[param_set_idx],
208
3.23k
                               self->bs_param_bands, h_real);
209
3.23k
}
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.09k
                                  WORD32 opd[MAX_PARAMETER_BANDS]) {
215
3.09k
  WORD32 band;
216
217
36.7k
  for (band = 0; band < self->num_bands_ipd; band++) {
218
33.6k
    WORD32 cld_idx = curr_bit_stream->cld_idx[param_set_idx][band] + 15;
219
33.6k
    WORD32 ipd_idx = (curr_bit_stream->ipd_idx[param_set_idx][band]) & 15;
220
33.6k
    WORD32 icc_idx = curr_bit_stream->icc_idx[param_set_idx][band];
221
222
33.6k
    if ((cld_idx == 15) && (ipd_idx == 8))
223
731
      opd[band] = 0;
224
32.9k
    else
225
32.9k
      opd[band] = ixheaacd_atan_table_Q28[ipd_idx][icc_idx][cld_idx];
226
33.6k
  }
227
3.09k
}
228
229
VOID ixheaacd_mps_par2umx_ps_ipd_opd(ia_mps_dec_state_struct *self,
230
                                     ia_mps_bs_frame *curr_bit_stream,
231
35.0k
                                     FLOAT32 *h_real, WORD32 param_set_idx) {
232
35.0k
  WORD32 opd[MAX_PARAMETER_BANDS];
233
35.0k
  WORD32 ott_band_count = self->bs_param_bands;
234
35.0k
  WORD32 num_bands_ipd = self->num_bands_ipd;
235
35.0k
  WORD32 band;
236
237
35.0k
  ixheaacd_mps_par2umx_ps_core(curr_bit_stream->cld_idx[param_set_idx],
238
35.0k
                               curr_bit_stream->icc_idx[param_set_idx],
239
35.0k
                               ott_band_count, h_real);
240
241
35.0k
  if (self->bs_phase_mode) {
242
3.09k
    ixheaacd_mps_opd_calc(self, curr_bit_stream, param_set_idx, opd);
243
244
36.7k
    for (band = 0; band < num_bands_ipd; band++) {
245
33.6k
      WORD32 ipd_idx = curr_bit_stream->ipd_idx[param_set_idx][band] & 15;
246
33.6k
      WORD32 ipd = ixheaacd_ipd_de_quant_table_q28[ipd_idx];
247
248
33.6k
      self->phase_l[param_set_idx][band] =
249
33.6k
          ixheaacd_mps_phase_wraping(opd[band]) * ONE_BY_Q28_FLOAT_VAL;
250
33.6k
      self->phase_r[param_set_idx][band] =
251
33.6k
          ixheaacd_mps_phase_wraping(opd[band] - ipd) * ONE_BY_Q28_FLOAT_VAL;
252
33.6k
    }
253
31.9k
  } else {
254
31.9k
    num_bands_ipd = 0;
255
31.9k
  }
256
257
363k
  for (band = num_bands_ipd; band < ott_band_count; band++) {
258
328k
    self->phase_l[param_set_idx][band] = 0;
259
328k
    self->phase_r[param_set_idx][band] = 0;
260
328k
  }
261
35.0k
}
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.1k
                               WORD32 param_set_idx, WORD32 res_bands) {
267
92.1k
  WORD32 band;
268
269
1.22M
  for (band = 0; band < self->bs_param_bands; band++) {
270
1.13M
    WORD32 cld_idx = curr_bit_stream->cld_idx[param_set_idx][band] + 15;
271
1.13M
    WORD32 icc_idx = curr_bit_stream->icc_idx[param_set_idx][band];
272
1.13M
    WORD32 ipd_idx = curr_bit_stream->ipd_idx[param_set_idx][band] & 15;
273
274
1.13M
    if ((band < self->num_bands_ipd) && (cld_idx == 15) && (icc_idx == 0) &&
275
582k
        (ipd_idx == 8)) {
276
2.43k
      FLOAT32 gain = 0.416666667f;
277
2.43k
      *h_imag++ = 0;
278
2.43k
      *h_imag++ = 0;
279
280
2.43k
      if (band < res_bands) {
281
371
        *h_real++ = gain;
282
371
        *h_real++ = gain;
283
371
        h_real += 2;
284
285
371
        *h_real++ = gain;
286
371
        *h_real++ = -gain;
287
2.06k
      } else {
288
2.06k
        *h_real++ = gain;
289
2.06k
        *h_real++ = -gain;
290
291
2.06k
        h_real += 4;
292
2.06k
      }
293
1.13M
    } else {
294
1.13M
      FLOAT32 weight, re_weight, im_weight;
295
296
1.13M
      weight = ixheaacd_weight[ipd_idx][icc_idx][cld_idx];
297
1.13M
      re_weight = ixheaacd_re_weight[ipd_idx][icc_idx][cld_idx];
298
1.13M
      im_weight = ixheaacd_im_weight[ipd_idx][icc_idx][cld_idx];
299
300
1.13M
      if (band < self->num_bands_ipd) {
301
735k
        weight = ixheaacd_weight[ipd_idx][icc_idx][cld_idx];
302
735k
        re_weight = ixheaacd_re_weight[ipd_idx][icc_idx][cld_idx];
303
735k
        im_weight = ixheaacd_im_weight[ipd_idx][icc_idx][cld_idx];
304
735k
      } else {
305
400k
        weight = ixheaacd_weight[0][icc_idx][cld_idx];
306
400k
        re_weight = ixheaacd_re_weight[0][icc_idx][cld_idx];
307
400k
        im_weight = ixheaacd_im_weight[0][icc_idx][cld_idx];
308
400k
      }
309
310
1.13M
      *h_real++ = weight - re_weight;
311
1.13M
      *h_imag++ = -im_weight;
312
1.13M
      *h_real++ = weight + re_weight;
313
1.13M
      *h_imag++ = im_weight;
314
315
1.13M
      if (band < res_bands) {
316
610k
        h_real += 2;
317
318
610k
        *h_real++ = weight;
319
610k
        *h_real++ = -weight;
320
610k
      } else {
321
524k
        FLOAT32 beta = ixheaacd_beta[ipd_idx][icc_idx][cld_idx];
322
323
524k
        *h_real++ = beta;
324
524k
        *h_real++ = -beta;
325
524k
        h_real += 2;
326
524k
      }
327
1.13M
    }
328
1.13M
  }
329
92.1k
}
330
331
18.8k
VOID ixheaacd_mps_apply_pre_matrix(ia_mps_dec_state_struct *self) {
332
18.8k
  WORD32 ts, qs, row;
333
18.8k
  if (self->pre_mix_req) {
334
8.12k
    ixheaacd_mps_upmix_interp_type1(
335
8.12k
        self->m1_param_re, self->r_out_re_in_m1, self->m1_param_re_prev,
336
8.12k
        (self->dir_sig_count + self->decor_sig_count), 1, self, self->bs_high_rate_mode);
337
338
298k
    for (ts = 0; ts < self->time_slots; ts++) {
339
871k
      for (qs = 0; qs < 2; qs++) {
340
580k
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
341
342
580k
        FLOAT32 real =
343
580k
            self->hyb_in[0][qs][ts].re * self->r_out_re_in_m1[ts][indx][0][0];
344
580k
        FLOAT32 imag =
345
580k
            self->hyb_in[0][qs][ts].im * self->r_out_re_in_m1[ts][indx][0][0];
346
1.74M
        for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
347
1.16M
             row++) {
348
1.16M
          self->v[row][ts][qs].re = real;
349
1.16M
          self->v[row][ts][qs].im = imag;
350
1.16M
        }
351
580k
      }
352
14.5M
      for (qs = 2; qs < self->hyb_band_count[0]; qs++) {
353
14.2M
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
354
14.2M
        FLOAT32 real =
355
14.2M
            self->hyb_in[0][qs][ts].re * self->r_out_re_in_m1[ts][indx][0][0];
356
14.2M
        FLOAT32 imag =
357
14.2M
            self->hyb_in[0][qs][ts].im * self->r_out_re_in_m1[ts][indx][0][0];
358
42.8M
        for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
359
28.5M
             row++) {
360
28.5M
          self->v[row][ts][qs].re = real;
361
28.5M
          self->v[row][ts][qs].im = imag;
362
28.5M
        }
363
14.2M
      }
364
290k
    }
365
10.7k
  } else {
366
429k
    for (ts = 0; ts < self->time_slots; ts++) {
367
14.6M
      for (qs = 0; qs < self->hyb_band_count[0]; qs++) {
368
14.2M
        FLOAT32 real = self->hyb_in[0][qs][ts].re;
369
14.2M
        FLOAT32 imag = self->hyb_in[0][qs][ts].im;
370
42.6M
        for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
371
28.4M
             row++) {
372
28.4M
          self->v[row][ts][qs].re = real;
373
28.4M
          self->v[row][ts][qs].im = imag;
374
28.4M
        }
375
14.2M
      }
376
418k
    }
377
10.7k
  }
378
18.8k
  return;
379
18.8k
}
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
17.8k
VOID ixheaacd_mps_apply_mix_matrix_type1(ia_mps_dec_state_struct *self) {
588
17.8k
  WORD32 ts, qs, row;
589
590
17.8k
  ixheaacd_mps_upmix_interp_type2(self->m2_decor_re, self->r_out_diff_re_in_m2,
591
17.8k
                                  self->m2_decor_re_prev, self->out_ch_count, self, 1);
592
593
17.8k
  ixheaacd_mps_upmix_interp_type2(self->m2_resid_re, self->r_out_re_in_m2, self->m2_resid_re_prev,
594
17.8k
                                  self->out_ch_count, self, 0);
595
596
722k
  for (qs = 0; qs < self->hyb_band_count[0]; qs++) {
597
704k
    WORD32 indx = self->hyb_band_to_processing_band_table[qs];
598
22.8M
    for (ts = 0; ts < self->time_slots; ts++) {
599
66.3M
      for (row = 0; row < self->out_ch_count; row++) {
600
44.2M
        self->hyb_dir_out[row][ts][qs].re =
601
44.2M
            self->w_dir[0][ts][qs].re * self->r_out_re_in_m2[ts][indx][row][0];
602
44.2M
        self->hyb_dir_out[row][ts][qs].im =
603
44.2M
            self->w_dir[0][ts][qs].im * self->r_out_re_in_m2[ts][indx][row][0];
604
44.2M
        self->hyb_diff_out[row][ts][qs].re =
605
44.2M
            self->w_diff[1][ts][qs].re *
606
44.2M
            self->r_out_diff_re_in_m2[ts][indx][row][1];
607
44.2M
        self->hyb_diff_out[row][ts][qs].im =
608
44.2M
            self->w_diff[1][ts][qs].im *
609
44.2M
            self->r_out_diff_re_in_m2[ts][indx][row][1];
610
44.2M
      }
611
22.1M
    }
612
704k
  }
613
17.8k
  return;
614
17.8k
}
615
616
8.12k
VOID ixheaacd_mps_apply_mix_matrix_type2(ia_mps_dec_state_struct *self) {
617
8.12k
  WORD32 ts, qs, row, col;
618
8.12k
  WORD32 complex_m2 = ((self->config->bs_phase_coding != 0));
619
8.12k
  WORD32 phase_interpolation = (self->config->bs_phase_coding == 1);
620
8.12k
  WORD32 num_col_iters = 0;
621
622
8.12k
  ixheaacd_mps_upmix_interp_type1(self->m2_decor_re, self->r_out_diff_re_in_m2,
623
8.12k
                                  self->m2_decor_re_prev, self->out_ch_count,
624
8.12k
                                  (self->dir_sig_count + self->decor_sig_count), self, 1);
625
8.12k
  ixheaacd_mps_upmix_interp_type1(self->m2_resid_re, self->r_out_re_in_m2, self->m2_resid_re_prev,
626
8.12k
                                  self->out_ch_count,
627
8.12k
                                  (self->dir_sig_count + self->decor_sig_count), self, 1);
628
629
8.12k
  if (complex_m2 && !phase_interpolation) {
630
2.44k
    ixheaacd_mps_upmix_interp_type1(self->m2_decor_im, self->r_out_diff_im_in_m2,
631
2.44k
                                    self->m2_decor_im_prev, self->out_ch_count,
632
2.44k
                                    (self->dir_sig_count + self->decor_sig_count), self, 1);
633
2.44k
    ixheaacd_mps_upmix_interp_type1(self->m2_resid_im, self->r_out_im_in_m2,
634
2.44k
                                    self->m2_resid_im_prev, self->out_ch_count,
635
2.44k
                                    (self->dir_sig_count + self->decor_sig_count), self, 1);
636
2.44k
  }
637
638
8.12k
  if (phase_interpolation) {
639
4.49k
    ixheaacd_mps_phase_interpolation(
640
4.49k
        self->phase_l, self->phase_r, self->phase_l_prev, self->phase_r_prev,
641
4.49k
        self->r_out_ph_re_in_m2, self->r_out_ph_im_in_m2, self);
642
643
148k
    for (ts = 0; ts < self->time_slots; ts++) {
644
143k
      WORD32 pb;
645
1.91M
      for (pb = 0; pb < self->bs_param_bands; pb++) {
646
1.77M
        self->r_out_im_in_m2[ts][pb][0][0] =
647
1.77M
            self->r_out_re_in_m2[ts][pb][0][0] *
648
1.77M
            self->r_out_ph_im_in_m2[ts][pb][0];
649
650
1.77M
        self->r_out_im_in_m2[ts][pb][0][1] =
651
1.77M
            self->r_out_re_in_m2[ts][pb][0][1] *
652
1.77M
            self->r_out_ph_im_in_m2[ts][pb][0];
653
1.77M
        self->r_out_im_in_m2[ts][pb][1][0] =
654
1.77M
            self->r_out_re_in_m2[ts][pb][1][0] *
655
1.77M
            self->r_out_ph_im_in_m2[ts][pb][1];
656
657
1.77M
        self->r_out_im_in_m2[ts][pb][1][1] =
658
1.77M
            self->r_out_re_in_m2[ts][pb][1][1] *
659
1.77M
            self->r_out_ph_im_in_m2[ts][pb][1];
660
661
1.77M
        self->r_out_re_in_m2[ts][pb][0][0] =
662
1.77M
            self->r_out_re_in_m2[ts][pb][0][0] *
663
1.77M
            self->r_out_ph_re_in_m2[ts][pb][0];
664
665
1.77M
        self->r_out_re_in_m2[ts][pb][0][1] =
666
1.77M
            self->r_out_re_in_m2[ts][pb][0][1] *
667
1.77M
            self->r_out_ph_re_in_m2[ts][pb][0];
668
669
1.77M
        self->r_out_re_in_m2[ts][pb][1][0] =
670
1.77M
            self->r_out_re_in_m2[ts][pb][1][0] *
671
1.77M
            self->r_out_ph_re_in_m2[ts][pb][1];
672
673
1.77M
        self->r_out_re_in_m2[ts][pb][1][1] =
674
1.77M
            self->r_out_re_in_m2[ts][pb][1][1] *
675
1.77M
            self->r_out_ph_re_in_m2[ts][pb][1];
676
677
1.77M
        self->r_out_diff_im_in_m2[ts][pb][0][0] = 0;
678
1.77M
        self->r_out_diff_im_in_m2[ts][pb][0][1] =
679
1.77M
            self->r_out_diff_re_in_m2[ts][pb][0][1] *
680
1.77M
            self->r_out_ph_im_in_m2[ts][pb][0];
681
682
1.77M
        self->r_out_diff_im_in_m2[ts][pb][1][0] = 0;
683
1.77M
        self->r_out_diff_im_in_m2[ts][pb][1][1] =
684
1.77M
            self->r_out_diff_re_in_m2[ts][pb][1][1] *
685
1.77M
            self->r_out_ph_im_in_m2[ts][pb][1];
686
687
1.77M
        self->r_out_diff_re_in_m2[ts][pb][0][0] = 0;
688
1.77M
        self->r_out_diff_re_in_m2[ts][pb][0][1] =
689
1.77M
            self->r_out_diff_re_in_m2[ts][pb][0][1] *
690
1.77M
            self->r_out_ph_re_in_m2[ts][pb][0];
691
692
1.77M
        self->r_out_diff_re_in_m2[ts][pb][1][0] = 0;
693
1.77M
        self->r_out_diff_re_in_m2[ts][pb][1][1] =
694
1.77M
            self->r_out_diff_re_in_m2[ts][pb][1][1] *
695
1.77M
            self->r_out_ph_re_in_m2[ts][pb][1];
696
1.77M
      }
697
143k
    }
698
4.49k
  }
699
8.12k
  if (self->res_bands == 0) {
700
5.73k
    num_col_iters = self->dir_sig_count;
701
5.73k
  } else {
702
2.39k
    num_col_iters = (self->dir_sig_count + self->decor_sig_count);
703
2.39k
  }
704
298k
  for (ts = 0; ts < self->time_slots; ts++) {
705
15.6M
    for (qs = 0; qs < self->hyb_band_count_max; qs++) {
706
15.3M
      WORD32 indx = self->hyb_band_to_processing_band_table[qs];
707
708
46.1M
      for (row = 0; row < self->out_ch_count; row++) {
709
30.7M
        FLOAT32 sum_re_dir = 0;
710
30.7M
        FLOAT32 sum_im_dir = 0;
711
69.0M
        for (col = 0; col < num_col_iters; col++) {
712
38.3M
          sum_re_dir += self->w_dir[col][ts][qs].re *
713
38.3M
                        self->r_out_re_in_m2[ts][indx][row][col];
714
38.3M
          sum_im_dir += self->w_dir[col][ts][qs].im *
715
38.3M
                        self->r_out_re_in_m2[ts][indx][row][col];
716
38.3M
        }
717
30.7M
        self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
718
30.7M
        self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
719
720
30.7M
        self->hyb_diff_out[row][ts][qs].re =
721
30.7M
            self->w_diff[1][ts][qs].re *
722
30.7M
            self->r_out_diff_re_in_m2[ts][indx][row][1];
723
30.7M
        self->hyb_diff_out[row][ts][qs].im =
724
30.7M
            self->w_diff[1][ts][qs].im *
725
30.7M
            self->r_out_diff_re_in_m2[ts][indx][row][1];
726
30.7M
      }
727
15.3M
    }
728
290k
  }
729
730
8.12k
  if (complex_m2) {
731
6.94k
    if (phase_interpolation) {
732
148k
      for (ts = 0; ts < self->time_slots; ts++) {
733
431k
        for (qs = 0; qs < 2; qs++) {
734
287k
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
735
862k
          for (row = 0; row < self->out_ch_count; row++) {
736
575k
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
737
575k
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
738
1.15M
            for (col = 0; col < num_col_iters; col++) {
739
575k
              sum_re_dir += self->w_dir[col][ts][qs].im *
740
575k
                            self->r_out_im_in_m2[ts][indx][row][col];
741
575k
              sum_im_dir -= self->w_dir[col][ts][qs].re *
742
575k
                            self->r_out_im_in_m2[ts][indx][row][col];
743
575k
            }
744
575k
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
745
575k
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
746
575k
            self->hyb_diff_out[row][ts][qs].re +=
747
575k
                self->w_diff[1][ts][qs].im *
748
575k
                self->r_out_diff_im_in_m2[ts][indx][row][1];
749
575k
            self->hyb_diff_out[row][ts][qs].im -=
750
575k
                self->w_diff[1][ts][qs].re *
751
575k
                self->r_out_diff_im_in_m2[ts][indx][row][1];
752
575k
          }
753
287k
        }
754
9.78M
        for (qs = 2; qs < self->hyb_band_count_max; qs++) {
755
9.64M
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
756
28.9M
          for (row = 0; row < self->out_ch_count; row++) {
757
19.2M
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
758
19.2M
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
759
38.5M
            for (col = 0; col < num_col_iters; col++) {
760
19.2M
              sum_re_dir -= self->w_dir[col][ts][qs].im *
761
19.2M
                            self->r_out_im_in_m2[ts][indx][row][col];
762
19.2M
              sum_im_dir += self->w_dir[col][ts][qs].re *
763
19.2M
                            self->r_out_im_in_m2[ts][indx][row][col];
764
19.2M
            }
765
19.2M
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
766
19.2M
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
767
19.2M
            self->hyb_diff_out[row][ts][qs].re -=
768
19.2M
                self->w_diff[1][ts][qs].im *
769
19.2M
                self->r_out_diff_im_in_m2[ts][indx][row][1];
770
19.2M
            self->hyb_diff_out[row][ts][qs].im +=
771
19.2M
                self->w_diff[1][ts][qs].re *
772
19.2M
                self->r_out_diff_im_in_m2[ts][indx][row][1];
773
19.2M
          }
774
9.64M
        }
775
143k
      }
776
4.49k
    } else {
777
2.44k
      WORD32 num_cols = (self->dir_sig_count + self->decor_sig_count) > 1
778
2.44k
                         ? 1
779
2.44k
                         : (self->dir_sig_count + self->decor_sig_count);
780
115k
      for (ts = 0; ts < self->time_slots; ts++) {
781
338k
        for (qs = 0; qs < 2; qs++) {
782
225k
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
783
676k
          for (row = 0; row < self->out_ch_count; row++) {
784
450k
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
785
450k
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
786
450k
            if (num_cols > 0) {
787
450k
              sum_re_dir += self->w_dir[0][ts][qs].im *
788
450k
                            self->r_out_im_in_m2[ts][indx][row][0];
789
450k
              sum_im_dir -= self->w_dir[0][ts][qs].re *
790
450k
                            self->r_out_im_in_m2[ts][indx][row][0];
791
450k
            }
792
450k
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
793
450k
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
794
450k
          }
795
225k
        }
796
3.71M
        for (qs = 2; qs < self->hyb_band_count_max; qs++) {
797
3.60M
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
798
10.8M
          for (row = 0; row < self->out_ch_count; row++) {
799
7.20M
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
800
7.20M
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
801
7.20M
            if (num_cols > 0) {
802
7.20M
              sum_re_dir -= self->w_dir[0][ts][qs].im *
803
7.20M
                            self->r_out_im_in_m2[ts][indx][row][0];
804
7.20M
              sum_im_dir += self->w_dir[0][ts][qs].re *
805
7.20M
                            self->r_out_im_in_m2[ts][indx][row][0];
806
7.20M
            }
807
7.20M
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
808
7.20M
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
809
7.20M
          }
810
3.60M
        }
811
112k
      }
812
2.44k
    }
813
6.94k
  }
814
8.12k
  return;
815
8.12k
}
816
817
85.2k
VOID ixheaacd_mps_apply_mix_matrix_type3(ia_mps_dec_state_struct *self) {
818
85.2k
  WORD32 ts, qs, row, col;
819
85.2k
  WORD32 complex_m2 = ((self->config->bs_phase_coding != 0));
820
85.2k
  WORD32 phase_interpolation = (self->config->bs_phase_coding == 1);
821
85.2k
  WORD32 num_col_iters = 0;
822
823
85.2k
  if (self->res_bands != 28) {
824
67.6k
    ixheaacd_mps_upmix_interp_type2(self->m2_decor_re, self->r_out_diff_re_in_m2,
825
67.6k
                                    self->m2_decor_re_prev, self->out_ch_count, self, 1);
826
67.6k
  }
827
85.2k
  if (self->res_bands == 0) {
828
29.4k
    num_col_iters = self->dir_sig_count;
829
29.4k
    ixheaacd_mps_upmix_interp_type2(self->m2_resid_re, self->r_out_re_in_m2,
830
29.4k
                                    self->m2_resid_re_prev, self->out_ch_count, self, 0);
831
55.8k
  } else {
832
55.8k
    num_col_iters = (self->dir_sig_count + self->decor_sig_count);
833
55.8k
    ixheaacd_mps_upmix_interp_type1(self->m2_resid_re, self->r_out_re_in_m2,
834
55.8k
                                    self->m2_resid_re_prev, self->out_ch_count,
835
55.8k
                                    (self->dir_sig_count + self->decor_sig_count), self, 1);
836
55.8k
  }
837
838
85.2k
  if (complex_m2 && !phase_interpolation) {
839
55.4k
    ixheaacd_mps_upmix_interp_type2(self->m2_resid_im, self->r_out_im_in_m2,
840
55.4k
                                    self->m2_resid_im_prev, self->out_ch_count, self, 0);
841
55.4k
  }
842
843
85.2k
  if (phase_interpolation) {
844
20.3k
    ixheaacd_mps_phase_interpolation(
845
20.3k
        self->phase_l, self->phase_r, self->phase_l_prev, self->phase_r_prev,
846
20.3k
        self->r_out_ph_re_in_m2, self->r_out_ph_im_in_m2, self);
847
848
20.3k
    if (self->res_bands == 0) {
849
671k
      for (ts = 0; ts < self->time_slots; ts++) {
850
650k
        WORD32 pb;
851
5.69M
        for (pb = 0; pb < self->bs_param_bands; pb++) {
852
5.04M
          self->r_out_im_in_m2[ts][pb][0][0] =
853
5.04M
              self->r_out_re_in_m2[ts][pb][0][0] *
854
5.04M
              self->r_out_ph_im_in_m2[ts][pb][0];
855
856
5.04M
          self->r_out_im_in_m2[ts][pb][1][0] =
857
5.04M
              self->r_out_re_in_m2[ts][pb][1][0] *
858
5.04M
              self->r_out_ph_im_in_m2[ts][pb][1];
859
860
5.04M
          self->r_out_re_in_m2[ts][pb][0][0] =
861
5.04M
              self->r_out_re_in_m2[ts][pb][0][0] *
862
5.04M
              self->r_out_ph_re_in_m2[ts][pb][0];
863
864
5.04M
          self->r_out_re_in_m2[ts][pb][1][0] =
865
5.04M
              self->r_out_re_in_m2[ts][pb][1][0] *
866
5.04M
              self->r_out_ph_re_in_m2[ts][pb][1];
867
868
5.04M
          self->r_out_diff_im_in_m2[ts][pb][0][1] =
869
5.04M
              self->r_out_diff_re_in_m2[ts][pb][0][1] *
870
5.04M
              self->r_out_ph_im_in_m2[ts][pb][0];
871
872
5.04M
          self->r_out_diff_im_in_m2[ts][pb][1][1] =
873
5.04M
              self->r_out_diff_re_in_m2[ts][pb][1][1] *
874
5.04M
              self->r_out_ph_im_in_m2[ts][pb][1];
875
876
5.04M
          self->r_out_diff_re_in_m2[ts][pb][0][1] =
877
5.04M
              self->r_out_diff_re_in_m2[ts][pb][0][1] *
878
5.04M
              self->r_out_ph_re_in_m2[ts][pb][0];
879
880
5.04M
          self->r_out_diff_re_in_m2[ts][pb][1][1] =
881
5.04M
              self->r_out_diff_re_in_m2[ts][pb][1][1] *
882
5.04M
              self->r_out_ph_re_in_m2[ts][pb][1];
883
5.04M
        }
884
650k
      }
885
20.3k
    } 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
20.3k
  }
977
85.2k
  if (self->res_bands == 0) {
978
1.00M
    for (ts = 0; ts < self->time_slots; ts++) {
979
44.9M
      for (qs = 0; qs < self->hyb_band_count[0]; qs++) {
980
43.9M
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
981
131M
        for (row = 0; row < self->out_ch_count; row++) {
982
87.9M
          self->hyb_dir_out[row][ts][qs].re =
983
87.9M
              self->w_dir[0][ts][qs].re *
984
87.9M
              self->r_out_re_in_m2[ts][indx][row][0];
985
87.9M
          self->hyb_dir_out[row][ts][qs].im =
986
87.9M
              self->w_dir[0][ts][qs].im *
987
87.9M
              self->r_out_re_in_m2[ts][indx][row][0];
988
87.9M
          self->hyb_diff_out[row][ts][qs].re =
989
87.9M
              self->w_diff[1][ts][qs].re *
990
87.9M
              self->r_out_diff_re_in_m2[ts][indx][row][1];
991
87.9M
          self->hyb_diff_out[row][ts][qs].im =
992
87.9M
              self->w_diff[1][ts][qs].im *
993
87.9M
              self->r_out_diff_re_in_m2[ts][indx][row][1];
994
87.9M
        }
995
43.9M
      }
996
970k
    }
997
55.8k
  } else if (self->res_bands == 28) {
998
579k
    for (ts = 0; ts < self->time_slots; ts++) {
999
22.4M
      for (qs = 0; qs < self->hyb_band_count[1]; qs++) {
1000
21.9M
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1001
65.7M
        for (row = 0; row < self->out_ch_count; row++) {
1002
43.8M
          FLOAT32 sum_re_dir = 0;
1003
43.8M
          FLOAT32 sum_im_dir = 0;
1004
131M
          for (col = 0; col < num_col_iters; col++) {
1005
87.6M
            sum_re_dir += self->w_dir[col][ts][qs].re *
1006
87.6M
                          self->r_out_re_in_m2[ts][indx][row][col];
1007
87.6M
            sum_im_dir += self->w_dir[col][ts][qs].im *
1008
87.6M
                          self->r_out_re_in_m2[ts][indx][row][col];
1009
87.6M
          }
1010
43.8M
          self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1011
43.8M
          self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1012
43.8M
        }
1013
21.9M
      }
1014
566k
      for (; qs < self->hyb_band_count[0]; qs++) {
1015
4.19k
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1016
12.5k
        for (row = 0; row < self->out_ch_count; row++) {
1017
8.38k
          self->hyb_dir_out[row][ts][qs].re =
1018
8.38k
              self->w_dir[0][ts][qs].re *
1019
8.38k
              self->r_out_re_in_m2[ts][indx][row][0];
1020
8.38k
          self->hyb_dir_out[row][ts][qs].im =
1021
8.38k
              self->w_dir[0][ts][qs].im *
1022
8.38k
              self->r_out_re_in_m2[ts][indx][row][0];
1023
8.38k
        }
1024
4.19k
      }
1025
562k
    }
1026
38.2k
  } else {
1027
38.2k
    WORD32 dif_s = ixheaacd_mps_gain_set_indx[self->res_bands];
1028
1.66M
    for (ts = 0; ts < self->time_slots; ts++) {
1029
30.3M
      for (qs = 0; qs < dif_s; qs++) {
1030
28.6M
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1031
86.0M
        for (row = 0; row < self->out_ch_count; row++) {
1032
57.3M
          FLOAT32 sum_re_dir = 0;
1033
57.3M
          FLOAT32 sum_im_dir = 0;
1034
172M
          for (col = 0; col < num_col_iters; col++) {
1035
114M
            sum_re_dir += self->w_dir[col][ts][qs].re *
1036
114M
                          self->r_out_re_in_m2[ts][indx][row][col];
1037
114M
            sum_im_dir += self->w_dir[col][ts][qs].im *
1038
114M
                          self->r_out_re_in_m2[ts][indx][row][col];
1039
114M
          }
1040
57.3M
          self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1041
57.3M
          self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1042
57.3M
        }
1043
28.6M
      }
1044
27.1M
      for (; qs < self->hyb_band_count[1]; qs++) {
1045
25.5M
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1046
76.5M
        for (row = 0; row < self->out_ch_count; row++) {
1047
51.0M
          FLOAT32 sum_re_dir = 0;
1048
51.0M
          FLOAT32 sum_im_dir = 0;
1049
153M
          for (col = 0; col < num_col_iters; col++) {
1050
102M
            sum_re_dir += self->w_dir[col][ts][qs].re *
1051
102M
                          self->r_out_re_in_m2[ts][indx][row][col];
1052
102M
            sum_im_dir += self->w_dir[col][ts][qs].im *
1053
102M
                          self->r_out_re_in_m2[ts][indx][row][col];
1054
102M
          }
1055
51.0M
          self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1056
51.0M
          self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1057
51.0M
          self->hyb_diff_out[row][ts][qs].re =
1058
51.0M
              self->w_diff[1][ts][qs].re *
1059
51.0M
              self->r_out_diff_re_in_m2[ts][indx][row][1];
1060
51.0M
          self->hyb_diff_out[row][ts][qs].im =
1061
51.0M
              self->w_diff[1][ts][qs].im *
1062
51.0M
              self->r_out_diff_re_in_m2[ts][indx][row][1];
1063
51.0M
        }
1064
25.5M
      }
1065
17.8M
      for (; qs < self->hyb_band_count[0]; qs++) {
1066
16.2M
        WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1067
48.6M
        for (row = 0; row < self->out_ch_count; row++) {
1068
32.4M
          self->hyb_dir_out[row][ts][qs].re =
1069
32.4M
              self->w_dir[0][ts][qs].re *
1070
32.4M
              self->r_out_re_in_m2[ts][indx][row][0];
1071
32.4M
          self->hyb_dir_out[row][ts][qs].im =
1072
32.4M
              self->w_dir[0][ts][qs].im *
1073
32.4M
              self->r_out_re_in_m2[ts][indx][row][0];
1074
32.4M
          self->hyb_diff_out[row][ts][qs].re =
1075
32.4M
              self->w_diff[1][ts][qs].re *
1076
32.4M
              self->r_out_diff_re_in_m2[ts][indx][row][1];
1077
32.4M
          self->hyb_diff_out[row][ts][qs].im =
1078
32.4M
              self->w_diff[1][ts][qs].im *
1079
32.4M
              self->r_out_diff_re_in_m2[ts][indx][row][1];
1080
32.4M
        }
1081
16.2M
      }
1082
1.62M
    }
1083
38.2k
  }
1084
1085
85.2k
  if (complex_m2) {
1086
75.7k
    if (phase_interpolation) {
1087
671k
      for (ts = 0; ts < self->time_slots; ts++) {
1088
1.95M
        for (qs = 0; qs < 2; qs++) {
1089
1.30M
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1090
3.90M
          for (row = 0; row < self->out_ch_count; row++) {
1091
2.60M
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
1092
2.60M
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
1093
5.20M
            for (col = 0; col < num_col_iters; col++) {
1094
2.60M
              sum_re_dir += self->w_dir[col][ts][qs].im *
1095
2.60M
                            self->r_out_im_in_m2[ts][indx][row][col];
1096
2.60M
              sum_im_dir -= self->w_dir[col][ts][qs].re *
1097
2.60M
                            self->r_out_im_in_m2[ts][indx][row][col];
1098
2.60M
            }
1099
2.60M
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1100
2.60M
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1101
2.60M
            self->hyb_diff_out[row][ts][qs].re +=
1102
2.60M
                self->w_diff[1][ts][qs].im *
1103
2.60M
                self->r_out_diff_im_in_m2[ts][indx][row][1];
1104
2.60M
            self->hyb_diff_out[row][ts][qs].im -=
1105
2.60M
                self->w_diff[1][ts][qs].re *
1106
2.60M
                self->r_out_diff_im_in_m2[ts][indx][row][1];
1107
2.60M
          }
1108
1.30M
        }
1109
42.3M
        for (qs = 2; qs < self->hyb_band_count_max; qs++) {
1110
41.7M
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1111
125M
          for (row = 0; row < self->out_ch_count; row++) {
1112
83.4M
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
1113
83.4M
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
1114
166M
            for (col = 0; col < num_col_iters; col++) {
1115
83.4M
              sum_re_dir -= self->w_dir[col][ts][qs].im *
1116
83.4M
                            self->r_out_im_in_m2[ts][indx][row][col];
1117
83.4M
              sum_im_dir += self->w_dir[col][ts][qs].re *
1118
83.4M
                            self->r_out_im_in_m2[ts][indx][row][col];
1119
83.4M
            }
1120
83.4M
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1121
83.4M
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1122
83.4M
            self->hyb_diff_out[row][ts][qs].re -=
1123
83.4M
                self->w_diff[1][ts][qs].im *
1124
83.4M
                self->r_out_diff_im_in_m2[ts][indx][row][1];
1125
83.4M
            self->hyb_diff_out[row][ts][qs].im +=
1126
83.4M
                self->w_diff[1][ts][qs].re *
1127
83.4M
                self->r_out_diff_im_in_m2[ts][indx][row][1];
1128
83.4M
          }
1129
41.7M
        }
1130
650k
      }
1131
55.4k
    } else {
1132
55.4k
      WORD32 num_cols = (self->dir_sig_count + self->decor_sig_count) > 1
1133
55.4k
                         ? 1
1134
55.4k
                         : (self->dir_sig_count + self->decor_sig_count);
1135
2.14M
      for (ts = 0; ts < self->time_slots; ts++) {
1136
6.26M
        for (qs = 0; qs < 2; qs++) {
1137
4.17M
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1138
12.5M
          for (row = 0; row < self->out_ch_count; row++) {
1139
8.35M
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
1140
8.35M
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
1141
8.35M
            if (num_cols > 0) {
1142
8.35M
              sum_re_dir += self->w_dir[0][ts][qs].im *
1143
8.35M
                            self->r_out_im_in_m2[ts][indx][row][0];
1144
8.35M
              sum_im_dir -= self->w_dir[0][ts][qs].re *
1145
8.35M
                            self->r_out_im_in_m2[ts][indx][row][0];
1146
8.35M
            }
1147
8.35M
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1148
8.35M
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1149
8.35M
          }
1150
4.17M
        }
1151
82.2M
        for (qs = 2; qs < self->hyb_band_count_max; qs++) {
1152
80.1M
          WORD32 indx = self->hyb_band_to_processing_band_table[qs];
1153
240M
          for (row = 0; row < self->out_ch_count; row++) {
1154
160M
            FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
1155
160M
            FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
1156
160M
            if (num_cols > 0) {
1157
160M
              sum_re_dir -= self->w_dir[0][ts][qs].im *
1158
160M
                            self->r_out_im_in_m2[ts][indx][row][0];
1159
160M
              sum_im_dir += self->w_dir[0][ts][qs].re *
1160
160M
                            self->r_out_im_in_m2[ts][indx][row][0];
1161
160M
            }
1162
160M
            self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
1163
160M
            self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
1164
160M
          }
1165
80.1M
        }
1166
2.08M
      }
1167
55.4k
    }
1168
75.7k
  }
1169
85.2k
  return;
1170
85.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
85.0k
    WORD32 num_cols, ia_mps_dec_state_struct *self, WORD32 bs_high_rate_mode) {
1223
85.0k
  WORD32 ts, ps, pb, row, col, i;
1224
85.0k
  FLOAT32 ks, ms, ls;
1225
85.0k
  FLOAT32 fl_step, fl_base;
1226
1227
1.19M
  for (pb = 0; pb < self->bs_param_bands; pb++) {
1228
3.34M
    for (row = 0; row < num_rows; row++) {
1229
6.49M
      for (col = 0; col < num_cols; col++) {
1230
4.27M
        ts = 0;
1231
4.27M
        ps = 0;
1232
4.27M
        ks = self->inv_param_slot_diff[ps];
1233
4.27M
        ms = m_matrix[ps][pb][row][col];
1234
4.27M
        ls = m_matrix_prev[pb][row][col];
1235
4.27M
        fl_step = ks * (ms - ls);
1236
4.27M
        fl_base = ls + fl_step;
1237
1238
126M
        for (i = 1; i <= (WORD32)self->param_slot_diff[0]; i++) {
1239
122M
          r_matrix_float[ts][pb][row][col] = fl_base;
1240
122M
          fl_base += fl_step;
1241
122M
          ts++;
1242
122M
        }
1243
4.27M
        if (bs_high_rate_mode) {
1244
6.39M
          for (ps = 1; ps < self->num_parameter_sets; ps++) {
1245
2.15M
            ks = self->inv_param_slot_diff[ps];
1246
2.15M
            ms = m_matrix[ps][pb][row][col];
1247
2.15M
            ls = m_matrix[ps - 1][pb][row][col];
1248
2.15M
            fl_step = ks * (ms - ls);
1249
2.15M
            fl_base = ls + fl_step;
1250
1251
28.5M
            for (i = 1; i <= self->param_slot_diff[ps]; i++) {
1252
26.3M
              r_matrix_float[ts][pb][row][col] = fl_base;
1253
26.3M
              fl_base += fl_step;
1254
26.3M
              ts++;
1255
26.3M
            }
1256
2.15M
          }
1257
4.24M
        }
1258
4.27M
      }
1259
2.22M
    }
1260
1.11M
  }
1261
85.0k
  return;
1262
85.0k
}
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
188k
    ia_mps_dec_state_struct *self, WORD32 col) {
1269
188k
  WORD32 ts, ps, pb, row, i;
1270
188k
  FLOAT32 ks, ms, ls;
1271
188k
  FLOAT32 fl_step, fl_base;
1272
1273
2.37M
  for (pb = 0; pb < self->bs_param_bands; pb++) {
1274
6.57M
    for (row = 0; row < num_rows; row++) {
1275
4.38M
      ts = 0;
1276
4.38M
      ps = 0;
1277
4.38M
      ks = self->inv_param_slot_diff[ps];
1278
4.38M
      ms = m_matrix[ps][pb][row][col];
1279
4.38M
      ls = m_matrix_prev[pb][row][col];
1280
4.38M
      fl_step = ks * (ms - ls);
1281
4.38M
      fl_base = ls + fl_step;
1282
1283
144M
      for (i = 1; i <= (WORD32)self->param_slot_diff[0]; i++) {
1284
140M
        r_matrix_float[ts][pb][row][col] = fl_base;
1285
140M
        fl_base += fl_step;
1286
140M
        ts++;
1287
140M
      }
1288
4.90M
      for (ps = 1; ps < self->num_parameter_sets; ps++) {
1289
527k
        ks = self->inv_param_slot_diff[ps];
1290
527k
        ms = m_matrix[ps][pb][row][col];
1291
527k
        ls = m_matrix[ps - 1][pb][row][col];
1292
527k
        fl_step = ks * (ms - ls);
1293
527k
        fl_base = ls + fl_step;
1294
1295
8.14M
        for (i = 1; i <= (WORD32)self->param_slot_diff[ps]; i++) {
1296
7.61M
          r_matrix_float[ts][pb][row][col] = fl_base;
1297
7.61M
          fl_base += fl_step;
1298
7.61M
          ts++;
1299
7.61M
        }
1300
527k
      }
1301
4.38M
    }
1302
2.19M
  }
1303
188k
  return;
1304
188k
}
1305
1306
static FLOAT32 ixheaacd_mps_angle_interpolation(FLOAT32 angle1, FLOAT32 angle2,
1307
707k
                                                FLOAT32 alpha, FLOAT32 *step) {
1308
714k
  while (angle2 - angle1 > (FLOAT32)P_PI) {
1309
7.35k
    angle1 = angle1 + 2.0f * (FLOAT32)P_PI;
1310
7.35k
  }
1311
713k
  while (angle1 - angle2 > (FLOAT32)P_PI) {
1312
6.28k
    angle2 = angle2 + 2.0f * (FLOAT32)P_PI;
1313
6.28k
  }
1314
707k
  *step = angle2 - angle1;
1315
707k
  return (1 - alpha) * angle1 + alpha * angle2;
1316
707k
}
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
24.8k
    ia_mps_dec_state_struct *self) {
1325
24.8k
  WORD32 i, ts, ps, pb;
1326
24.8k
  FLOAT32 step_l, step_r, alpha, tl, tr;
1327
237k
  for (pb = 0; pb < self->bs_param_bands; pb++) {
1328
213k
    ps = 0;
1329
213k
    ts = 0;
1330
213k
    alpha = (FLOAT32)self->inv_param_slot_diff[ps];
1331
213k
    tl = ixheaacd_mps_angle_interpolation(pl_prev[pb], pl[ps][pb], alpha,
1332
213k
                                          &step_l);
1333
213k
    tr = ixheaacd_mps_angle_interpolation(pr_prev[pb], pr[ps][pb], alpha,
1334
213k
                                          &step_r);
1335
213k
    step_l *= alpha;
1336
213k
    step_r *= alpha;
1337
1338
5.48M
    for (i = 1; i <= self->param_slot_diff[ps]; i++) {
1339
5.27M
      r_re[ts][pb][0] = (FLOAT32)cos(tl);
1340
5.27M
      r_im[ts][pb][0] = (FLOAT32)sin(tl);
1341
5.27M
      tl += step_l;
1342
1343
5.27M
      r_re[ts][pb][1] = (FLOAT32)cos(tr);
1344
5.27M
      r_im[ts][pb][1] = (FLOAT32)sin(tr);
1345
5.27M
      tr += step_r;
1346
5.27M
      ts++;
1347
5.27M
    }
1348
1349
353k
    for (ps = 1; ps < self->num_parameter_sets; ps++) {
1350
140k
      FLOAT32 alpha = self->inv_param_slot_diff[ps];
1351
140k
      tl = ixheaacd_mps_angle_interpolation(pl[ps - 1][pb], pl[ps][pb], alpha,
1352
140k
                                            &step_l);
1353
140k
      tr = ixheaacd_mps_angle_interpolation(pr[ps - 1][pb], pr[ps][pb], alpha,
1354
140k
                                            &step_r);
1355
140k
      step_l *= alpha;
1356
140k
      step_r *= alpha;
1357
1.68M
      for (i = 1; i <= self->param_slot_diff[ps]; i++) {
1358
1.54M
        if (ts < 72 && pb < 28) {
1359
1.54M
          r_re[ts][pb][0] = (FLOAT32)cos(tl);
1360
1.54M
          r_im[ts][pb][0] = (FLOAT32)sin(tl);
1361
1.54M
          tl += step_l;
1362
1363
1.54M
          r_re[ts][pb][1] = (FLOAT32)cos(tr);
1364
1.54M
          r_im[ts][pb][1] = (FLOAT32)sin(tr);
1365
1.54M
          tr += step_r;
1366
1.54M
        }
1367
1.54M
        ts++;
1368
1369
1.54M
        if (ts > 71) {
1370
0
          ts = 0;
1371
0
          break;
1372
0
        }
1373
1.54M
        if (pb > 27) {
1374
0
          pb = 0;
1375
0
          break;
1376
0
        }
1377
1.54M
      }
1378
140k
    }
1379
213k
  }
1380
24.8k
}
1381
1382
3.66k
VOID ixheaacd_mps_init_pre_and_post_matrix(ia_mps_dec_state_struct *self) {
1383
3.66k
  memset(self->m1_param_re_prev, 0,
1384
3.66k
         MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
1385
3.66k
  memset(self->m1_param_im_prev, 0,
1386
3.66k
         MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
1387
3.66k
  memset(self->m1_param_re_prev, 0,
1388
3.66k
         MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
1389
3.66k
  memset(self->m2_decor_re_prev, 0,
1390
3.66k
         MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
1391
3.66k
  memset(self->m2_resid_re_prev, 0,
1392
3.66k
         MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
1393
3.66k
  memset(self->m2_resid_im_prev, 0,
1394
3.66k
         MAX_PARAMETER_BANDS * MAX_M_OUTPUT * MAX_M_INPUT * sizeof(WORD32));
1395
3.66k
}