Coverage Report

Created: 2026-02-26 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aac/libAACdec/src/stereo.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4
© Copyright  1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
5
Forschung e.V. All rights reserved.
6
7
 1.    INTRODUCTION
8
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10
scheme for digital audio. This FDK AAC Codec software is intended to be used on
11
a wide variety of Android devices.
12
13
AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14
general perceptual audio codecs. AAC-ELD is considered the best-performing
15
full-bandwidth communications codec by independent studies and is widely
16
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17
specifications.
18
19
Patent licenses for necessary patent claims for the FDK AAC Codec (including
20
those of Fraunhofer) may be obtained through Via Licensing
21
(www.vialicensing.com) or through the respective patent owners individually for
22
the purpose of encoding or decoding bit streams in products that are compliant
23
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24
Android devices already license these patent claims through Via Licensing or
25
directly from the patent owners, and therefore FDK AAC Codec software may
26
already be covered under those patent licenses when it is used for those
27
licensed purposes only.
28
29
Commercially-licensed AAC software libraries, including floating-point versions
30
with enhanced sound quality, are also available from Fraunhofer. Users are
31
encouraged to check the Fraunhofer website for additional applications
32
information and documentation.
33
34
2.    COPYRIGHT LICENSE
35
36
Redistribution and use in source and binary forms, with or without modification,
37
are permitted without payment of copyright license fees provided that you
38
satisfy the following conditions:
39
40
You must retain the complete text of this software license in redistributions of
41
the FDK AAC Codec or your modifications thereto in source code form.
42
43
You must retain the complete text of this software license in the documentation
44
and/or other materials provided with redistributions of the FDK AAC Codec or
45
your modifications thereto in binary form. You must make available free of
46
charge copies of the complete source code of the FDK AAC Codec and your
47
modifications thereto to recipients of copies in binary form.
48
49
The name of Fraunhofer may not be used to endorse or promote products derived
50
from this library without prior written permission.
51
52
You may not charge copyright license fees for anyone to use, copy or distribute
53
the FDK AAC Codec software or your modifications thereto.
54
55
Your modified versions of the FDK AAC Codec must carry prominent notices stating
56
that you changed the software and the date of any change. For modified versions
57
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59
AAC Codec Library for Android."
60
61
3.    NO PATENT LICENSE
62
63
NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65
Fraunhofer provides no warranty of patent non-infringement with respect to this
66
software.
67
68
You may use this FDK AAC Codec software or modifications thereto only for
69
purposes that are authorized by appropriate patent licenses.
70
71
4.    DISCLAIMER
72
73
This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75
including but not limited to the implied warranties of merchantability and
76
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78
or consequential damages, including but not limited to procurement of substitute
79
goods or services; loss of use, data, or profits, or business interruption,
80
however caused and on any theory of liability, whether in contract, strict
81
liability, or tort (including negligence), arising in any way out of the use of
82
this software, even if advised of the possibility of such damage.
83
84
5.    CONTACT INFORMATION
85
86
Fraunhofer Institute for Integrated Circuits IIS
87
Attention: Audio and Multimedia Departments - FDK AAC LL
88
Am Wolfsmantel 33
89
91058 Erlangen, Germany
90
91
www.iis.fraunhofer.de/amm
92
amm-info@iis.fraunhofer.de
93
----------------------------------------------------------------------------- */
94
95
/**************************** AAC decoder library ******************************
96
97
   Author(s):   Josef Hoepfl
98
99
   Description: joint stereo processing
100
101
*******************************************************************************/
102
103
#include "stereo.h"
104
105
#include "aac_rom.h"
106
#include "FDK_bitstream.h"
107
#include "channelinfo.h"
108
#include "FDK_audio.h"
109
110
enum { L = 0, R = 1 };
111
112
#include "block.h"
113
114
int CJointStereo_Read(HANDLE_FDK_BITSTREAM bs,
115
                      CJointStereoData *pJointStereoData,
116
                      const int windowGroups,
117
                      const int scaleFactorBandsTransmitted,
118
                      const int max_sfb_ste_clear,
119
                      CJointStereoPersistentData *pJointStereoPersistentData,
120
                      CCplxPredictionData *cplxPredictionData,
121
                      int cplxPredictionActiv, int scaleFactorBandsTotal,
122
127k
                      int windowSequence, const UINT flags) {
123
127k
  int group, band;
124
125
127k
  pJointStereoData->MsMaskPresent = (UCHAR)FDKreadBits(bs, 2);
126
127
127k
  FDKmemclear(pJointStereoData->MsUsed,
128
127k
              scaleFactorBandsTransmitted * sizeof(UCHAR));
129
130
127k
  pJointStereoData->cplx_pred_flag = 0;
131
127k
  if (cplxPredictionActiv) {
132
39.8k
    cplxPredictionData->pred_dir = 0;
133
39.8k
    cplxPredictionData->complex_coef = 0;
134
39.8k
    cplxPredictionData->use_prev_frame = 0;
135
39.8k
    cplxPredictionData->igf_pred_dir = 0;
136
39.8k
  }
137
138
127k
  switch (pJointStereoData->MsMaskPresent) {
139
52.2k
    case 0: /* no M/S */
140
      /* all flags are already cleared */
141
52.2k
      break;
142
143
14.2k
    case 1: /* read ms_used */
144
32.8k
      for (group = 0; group < windowGroups; group++) {
145
73.7k
        for (band = 0; band < scaleFactorBandsTransmitted; band++) {
146
55.1k
          pJointStereoData->MsUsed[band] |= (FDKreadBits(bs, 1) << group);
147
55.1k
        }
148
18.6k
      }
149
14.2k
      break;
150
151
19.4k
    case 2: /* full spectrum M/S */
152
68.0k
      for (band = 0; band < scaleFactorBandsTransmitted; band++) {
153
48.6k
        pJointStereoData->MsUsed[band] = 255; /* set all flags to 1 */
154
48.6k
      }
155
19.4k
      break;
156
157
41.2k
    case 3:
158
      /* M/S coding is disabled, complex stereo prediction is enabled */
159
41.2k
      if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
160
36.6k
        if (cplxPredictionActiv) { /* 'if (stereoConfigIndex == 0)' */
161
162
36.6k
          pJointStereoData->cplx_pred_flag = 1;
163
164
          /* cplx_pred_data()  cp. ISO/IEC FDIS 23003-3:2011(E)  Table 26 */
165
36.6k
          int cplx_pred_all = 0; /* local use only */
166
36.6k
          cplx_pred_all = FDKreadBits(bs, 1);
167
168
36.6k
          if (cplx_pred_all) {
169
146k
            for (group = 0; group < windowGroups; group++) {
170
127k
              UCHAR groupmask = ((UCHAR)1 << group);
171
162k
              for (band = 0; band < scaleFactorBandsTransmitted; band++) {
172
35.1k
                pJointStereoData->MsUsed[band] |= groupmask;
173
35.1k
              }
174
127k
            }
175
19.2k
          } else {
176
44.9k
            for (group = 0; group < windowGroups; group++) {
177
85.0k
              for (band = 0; band < scaleFactorBandsTransmitted;
178
57.4k
                   band += SFB_PER_PRED_BAND) {
179
57.4k
                pJointStereoData->MsUsed[band] |= (FDKreadBits(bs, 1) << group);
180
57.4k
                if ((band + 1) < scaleFactorBandsTotal) {
181
57.2k
                  pJointStereoData->MsUsed[band + 1] |=
182
57.2k
                      (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group));
183
57.2k
                }
184
57.4k
              }
185
27.5k
            }
186
17.3k
          }
187
36.6k
        } else {
188
5
          return -1;
189
5
        }
190
36.6k
      }
191
41.2k
      break;
192
127k
  }
193
194
127k
  if (cplxPredictionActiv) {
195
    /* If all sfb are MS-ed then no complex prediction */
196
39.8k
    if (pJointStereoData->MsMaskPresent == 3) {
197
36.6k
      if (pJointStereoData->cplx_pred_flag) {
198
36.6k
        int delta_code_time = 0;
199
200
        /* set pointer to Huffman codebooks */
201
36.6k
        const CodeBookDescription *hcb = &AACcodeBookDescriptionTable[BOOKSCL];
202
        /* set predictors to zero in case of a transition from long to short
203
         * window sequences and vice versa */
204
36.6k
        if (((windowSequence == BLOCK_SHORT) &&
205
20.4k
             (pJointStereoPersistentData->winSeqPrev != BLOCK_SHORT)) ||
206
35.6k
            ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) &&
207
20.0k
             (windowSequence != BLOCK_SHORT))) {
208
1.81k
          FDKmemclear(pJointStereoPersistentData->alpha_q_re_prev,
209
1.81k
                      JointStereoMaximumGroups * JointStereoMaximumBands *
210
1.81k
                          sizeof(SHORT));
211
1.81k
          FDKmemclear(pJointStereoPersistentData->alpha_q_im_prev,
212
1.81k
                      JointStereoMaximumGroups * JointStereoMaximumBands *
213
1.81k
                          sizeof(SHORT));
214
1.81k
        }
215
36.6k
        {
216
36.6k
          FDKmemclear(cplxPredictionData->alpha_q_re,
217
36.6k
                      JointStereoMaximumGroups * JointStereoMaximumBands *
218
36.6k
                          sizeof(SHORT));
219
36.6k
          FDKmemclear(cplxPredictionData->alpha_q_im,
220
36.6k
                      JointStereoMaximumGroups * JointStereoMaximumBands *
221
36.6k
                          sizeof(SHORT));
222
36.6k
        }
223
224
        /* 0 = mid->side prediction, 1 = side->mid prediction */
225
36.6k
        cplxPredictionData->pred_dir = FDKreadBits(bs, 1);
226
36.6k
        cplxPredictionData->complex_coef = FDKreadBits(bs, 1);
227
228
36.6k
        if (cplxPredictionData->complex_coef) {
229
30.4k
          if (flags & AC_INDEP) {
230
29.5k
            cplxPredictionData->use_prev_frame = 0;
231
29.5k
          } else {
232
951
            cplxPredictionData->use_prev_frame = FDKreadBits(bs, 1);
233
951
          }
234
30.4k
        }
235
236
36.6k
        if (flags & AC_INDEP) {
237
35.6k
          delta_code_time = 0;
238
35.6k
        } else {
239
1.06k
          delta_code_time = FDKreadBits(bs, 1);
240
1.06k
        }
241
242
36.6k
        {
243
36.6k
          int last_alpha_q_re = 0, last_alpha_q_im = 0;
244
245
191k
          for (group = 0; group < windowGroups; group++) {
246
230k
            for (band = 0; band < scaleFactorBandsTransmitted;
247
155k
                 band += SFB_PER_PRED_BAND) {
248
75.5k
              if (delta_code_time == 1) {
249
7.47k
                if (group > 0) {
250
5.74k
                  last_alpha_q_re =
251
5.74k
                      cplxPredictionData->alpha_q_re[group - 1][band];
252
5.74k
                  last_alpha_q_im =
253
5.74k
                      cplxPredictionData->alpha_q_im[group - 1][band];
254
5.74k
                } else if ((windowSequence == BLOCK_SHORT) &&
255
1.13k
                           (pJointStereoPersistentData->winSeqPrev ==
256
1.13k
                            BLOCK_SHORT)) {
257
                  /* Included for error-robustness */
258
373
                  if (pJointStereoPersistentData->winGroupsPrev == 0) return -1;
259
260
372
                  last_alpha_q_re =
261
372
                      pJointStereoPersistentData->alpha_q_re_prev
262
372
                          [pJointStereoPersistentData->winGroupsPrev - 1][band];
263
372
                  last_alpha_q_im =
264
372
                      pJointStereoPersistentData->alpha_q_im_prev
265
372
                          [pJointStereoPersistentData->winGroupsPrev - 1][band];
266
1.36k
                } else {
267
1.36k
                  last_alpha_q_re =
268
1.36k
                      pJointStereoPersistentData->alpha_q_re_prev[group][band];
269
1.36k
                  last_alpha_q_im =
270
1.36k
                      pJointStereoPersistentData->alpha_q_im_prev[group][band];
271
1.36k
                }
272
273
68.0k
              } else {
274
68.0k
                if (band > 0) {
275
39.0k
                  last_alpha_q_re =
276
39.0k
                      cplxPredictionData->alpha_q_re[group][band - 1];
277
39.0k
                  last_alpha_q_im =
278
39.0k
                      cplxPredictionData->alpha_q_im[group][band - 1];
279
39.0k
                } else {
280
28.9k
                  last_alpha_q_re = 0;
281
28.9k
                  last_alpha_q_im = 0;
282
28.9k
                }
283
284
68.0k
              } /* if (delta_code_time == 1) */
285
286
75.5k
              if (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)) {
287
42.8k
                int dpcm_alpha_re, dpcm_alpha_im;
288
289
42.8k
                dpcm_alpha_re = CBlock_DecodeHuffmanWord(bs, hcb);
290
42.8k
                dpcm_alpha_re -= 60;
291
42.8k
                dpcm_alpha_re *= -1;
292
293
42.8k
                cplxPredictionData->alpha_q_re[group][band] =
294
42.8k
                    dpcm_alpha_re + last_alpha_q_re;
295
296
42.8k
                if (cplxPredictionData->complex_coef) {
297
32.5k
                  dpcm_alpha_im = CBlock_DecodeHuffmanWord(bs, hcb);
298
32.5k
                  dpcm_alpha_im -= 60;
299
32.5k
                  dpcm_alpha_im *= -1;
300
301
32.5k
                  cplxPredictionData->alpha_q_im[group][band] =
302
32.5k
                      dpcm_alpha_im + last_alpha_q_im;
303
32.5k
                } else {
304
10.2k
                  cplxPredictionData->alpha_q_im[group][band] = 0;
305
10.2k
                }
306
307
42.8k
              } else {
308
32.6k
                cplxPredictionData->alpha_q_re[group][band] = 0;
309
32.6k
                cplxPredictionData->alpha_q_im[group][band] = 0;
310
32.6k
              } /* if (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)) */
311
312
75.5k
              if ((band + 1) <
313
75.5k
                  scaleFactorBandsTransmitted) { /* <= this should be the
314
                                                    correct way (cp.
315
                                                    ISO_IEC_FDIS_23003-0(E) */
316
                /*    7.7.2.3.2 Decoding of prediction coefficients) */
317
49.3k
                cplxPredictionData->alpha_q_re[group][band + 1] =
318
49.3k
                    cplxPredictionData->alpha_q_re[group][band];
319
49.3k
                cplxPredictionData->alpha_q_im[group][band + 1] =
320
49.3k
                    cplxPredictionData->alpha_q_im[group][band];
321
49.3k
              } /* if ((band+1)<scaleFactorBandsTotal) */
322
323
75.5k
              pJointStereoPersistentData->alpha_q_re_prev[group][band] =
324
75.5k
                  cplxPredictionData->alpha_q_re[group][band];
325
75.5k
              pJointStereoPersistentData->alpha_q_im_prev[group][band] =
326
75.5k
                  cplxPredictionData->alpha_q_im[group][band];
327
75.5k
            }
328
329
9.96M
            for (band = scaleFactorBandsTransmitted; band < max_sfb_ste_clear;
330
9.80M
                 band++) {
331
9.80M
              cplxPredictionData->alpha_q_re[group][band] = 0;
332
9.80M
              cplxPredictionData->alpha_q_im[group][band] = 0;
333
9.80M
              pJointStereoPersistentData->alpha_q_re_prev[group][band] = 0;
334
9.80M
              pJointStereoPersistentData->alpha_q_im_prev[group][band] = 0;
335
9.80M
            }
336
155k
          }
337
36.6k
        }
338
36.6k
      }
339
36.6k
    } else {
340
18.7k
      for (group = 0; group < windowGroups; group++) {
341
1.00M
        for (band = 0; band < max_sfb_ste_clear; band++) {
342
994k
          pJointStereoPersistentData->alpha_q_re_prev[group][band] = 0;
343
994k
          pJointStereoPersistentData->alpha_q_im_prev[group][band] = 0;
344
994k
        }
345
15.5k
      }
346
3.16k
    }
347
348
39.8k
    pJointStereoPersistentData->winGroupsPrev = windowGroups;
349
39.8k
  }
350
351
127k
  return 0;
352
127k
}
353
354
static void CJointStereo_filterAndAdd(
355
    FIXP_DBL *in, int len, int windowLen, const FIXP_FILT *coeff, FIXP_DBL *out,
356
    UCHAR isCurrent /* output values with even index get a
357
                       positve addon (=1) or a negative addon
358
                       (=0) */
359
302k
) {
360
302k
  int i, j;
361
362
302k
  int indices_1[] = {2, 1, 0, 1, 2, 3};
363
302k
  int indices_2[] = {1, 0, 0, 2, 3, 4};
364
302k
  int indices_3[] = {0, 0, 1, 3, 4, 5};
365
366
302k
  int subtr_1[] = {6, 5, 4, 2, 1, 1};
367
302k
  int subtr_2[] = {5, 4, 3, 1, 1, 2};
368
302k
  int subtr_3[] = {4, 3, 2, 1, 2, 3};
369
370
302k
  if (isCurrent == 1) {
371
    /* exploit the symmetry of the table: coeff[6] = - coeff[0],
372
                                          coeff[5] = - coeff[1],
373
                                          coeff[4] = - coeff[2],
374
                                          coeff[3] = 0
375
    */
376
377
663k
    for (i = 0; i < 3; i++) {
378
497k
      out[0] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[i]]) >> SR_FNA_OUT;
379
497k
      out[0] +=
380
497k
          (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[5 - i]]) >> SR_FNA_OUT;
381
497k
    }
382
383
663k
    for (i = 0; i < 3; i++) {
384
497k
      out[1] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[i]]) >> SR_FNA_OUT;
385
497k
      out[1] +=
386
497k
          (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[5 - i]]) >> SR_FNA_OUT;
387
497k
    }
388
389
663k
    for (i = 0; i < 3; i++) {
390
497k
      out[2] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[i]]) >> SR_FNA_OUT;
391
497k
      out[2] +=
392
497k
          (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[5 - i]]) >> SR_FNA_OUT;
393
497k
    }
394
395
1.05M
    for (j = 3; j < (len - 3); j++) {
396
3.55M
      for (i = 0; i < 3; i++) {
397
2.66M
        out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i]) >> SR_FNA_OUT;
398
2.66M
        out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i]) >> SR_FNA_OUT;
399
2.66M
      }
400
888k
    }
401
402
663k
    for (i = 0; i < 3; i++) {
403
497k
      out[len - 3] -=
404
497k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[i]]) >> SR_FNA_OUT;
405
497k
      out[len - 3] +=
406
497k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[5 - i]]) >> SR_FNA_OUT;
407
497k
    }
408
409
663k
    for (i = 0; i < 3; i++) {
410
497k
      out[len - 2] -=
411
497k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[i]]) >> SR_FNA_OUT;
412
497k
      out[len - 2] +=
413
497k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[5 - i]]) >> SR_FNA_OUT;
414
497k
    }
415
416
663k
    for (i = 0; i < 3; i++) {
417
497k
      out[len - 1] -=
418
497k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[i]]) >> SR_FNA_OUT;
419
497k
      out[len - 1] +=
420
497k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[5 - i]]) >> SR_FNA_OUT;
421
497k
    }
422
423
165k
  } else {
424
    /* exploit the symmetry of the table: coeff[6] = coeff[0],
425
                                          coeff[5] = coeff[1],
426
                                          coeff[4] = coeff[2]
427
    */
428
429
545k
    for (i = 0; i < 3; i++) {
430
409k
      out[0] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[i]] >> SR_FNA_OUT);
431
409k
      out[0] -=
432
409k
          (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[5 - i]] >> SR_FNA_OUT);
433
409k
    }
434
136k
    out[0] -= (FIXP_DBL)fMultDiv2(coeff[3], in[0] >> SR_FNA_OUT);
435
436
545k
    for (i = 0; i < 3; i++) {
437
409k
      out[1] += (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[i]] >> SR_FNA_OUT);
438
409k
      out[1] +=
439
409k
          (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[5 - i]] >> SR_FNA_OUT);
440
409k
    }
441
136k
    out[1] += (FIXP_DBL)fMultDiv2(coeff[3], in[1] >> SR_FNA_OUT);
442
443
545k
    for (i = 0; i < 3; i++) {
444
409k
      out[2] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[i]] >> SR_FNA_OUT);
445
409k
      out[2] -=
446
409k
          (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[5 - i]] >> SR_FNA_OUT);
447
409k
    }
448
136k
    out[2] -= (FIXP_DBL)fMultDiv2(coeff[3], in[2] >> SR_FNA_OUT);
449
450
283k
    for (j = 3; j < (len - 4); j++) {
451
588k
      for (i = 0; i < 3; i++) {
452
441k
        out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i] >> SR_FNA_OUT);
453
441k
        out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i] >> SR_FNA_OUT);
454
441k
      }
455
147k
      out[j] += (FIXP_DBL)fMultDiv2(coeff[3], in[j] >> SR_FNA_OUT);
456
457
147k
      j++;
458
459
588k
      for (i = 0; i < 3; i++) {
460
441k
        out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i] >> SR_FNA_OUT);
461
441k
        out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i] >> SR_FNA_OUT);
462
441k
      }
463
147k
      out[j] -= (FIXP_DBL)fMultDiv2(coeff[3], in[j] >> SR_FNA_OUT);
464
147k
    }
465
466
545k
    for (i = 0; i < 3; i++) {
467
409k
      out[len - 3] +=
468
409k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[i]] >> SR_FNA_OUT);
469
409k
      out[len - 3] +=
470
409k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[5 - i]] >> SR_FNA_OUT);
471
409k
    }
472
136k
    out[len - 3] += (FIXP_DBL)fMultDiv2(coeff[3], in[len - 3] >> SR_FNA_OUT);
473
474
545k
    for (i = 0; i < 3; i++) {
475
409k
      out[len - 2] -=
476
409k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[i]] >> SR_FNA_OUT);
477
409k
      out[len - 2] -=
478
409k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[5 - i]] >> SR_FNA_OUT);
479
409k
    }
480
136k
    out[len - 2] -= (FIXP_DBL)fMultDiv2(coeff[3], in[len - 2] >> SR_FNA_OUT);
481
482
545k
    for (i = 0; i < 3; i++) {
483
409k
      out[len - 1] +=
484
409k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[i]] >> SR_FNA_OUT);
485
409k
      out[len - 1] +=
486
409k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[5 - i]] >> SR_FNA_OUT);
487
409k
    }
488
136k
    out[len - 1] += (FIXP_DBL)fMultDiv2(coeff[3], in[len - 1] >> SR_FNA_OUT);
489
136k
  }
490
302k
}
491
492
static inline void CJointStereo_GenerateMSOutput(FIXP_DBL *pSpecLCurrBand,
493
                                                 FIXP_DBL *pSpecRCurrBand,
494
                                                 UINT leftScale,
495
                                                 UINT rightScale,
496
107k
                                                 UINT nSfbBands) {
497
107k
  unsigned int i;
498
499
107k
  FIXP_DBL leftCoefficient0;
500
107k
  FIXP_DBL leftCoefficient1;
501
107k
  FIXP_DBL leftCoefficient2;
502
107k
  FIXP_DBL leftCoefficient3;
503
504
107k
  FIXP_DBL rightCoefficient0;
505
107k
  FIXP_DBL rightCoefficient1;
506
107k
  FIXP_DBL rightCoefficient2;
507
107k
  FIXP_DBL rightCoefficient3;
508
509
260k
  for (i = nSfbBands; i > 0; i -= 4) {
510
152k
    leftCoefficient0 = pSpecLCurrBand[i - 4];
511
152k
    leftCoefficient1 = pSpecLCurrBand[i - 3];
512
152k
    leftCoefficient2 = pSpecLCurrBand[i - 2];
513
152k
    leftCoefficient3 = pSpecLCurrBand[i - 1];
514
515
152k
    rightCoefficient0 = pSpecRCurrBand[i - 4];
516
152k
    rightCoefficient1 = pSpecRCurrBand[i - 3];
517
152k
    rightCoefficient2 = pSpecRCurrBand[i - 2];
518
152k
    rightCoefficient3 = pSpecRCurrBand[i - 1];
519
520
    /* MS output generation */
521
152k
    leftCoefficient0 >>= leftScale;
522
152k
    leftCoefficient1 >>= leftScale;
523
152k
    leftCoefficient2 >>= leftScale;
524
152k
    leftCoefficient3 >>= leftScale;
525
526
152k
    rightCoefficient0 >>= rightScale;
527
152k
    rightCoefficient1 >>= rightScale;
528
152k
    rightCoefficient2 >>= rightScale;
529
152k
    rightCoefficient3 >>= rightScale;
530
531
152k
    pSpecLCurrBand[i - 4] = leftCoefficient0 + rightCoefficient0;
532
152k
    pSpecLCurrBand[i - 3] = leftCoefficient1 + rightCoefficient1;
533
152k
    pSpecLCurrBand[i - 2] = leftCoefficient2 + rightCoefficient2;
534
152k
    pSpecLCurrBand[i - 1] = leftCoefficient3 + rightCoefficient3;
535
536
152k
    pSpecRCurrBand[i - 4] = leftCoefficient0 - rightCoefficient0;
537
152k
    pSpecRCurrBand[i - 3] = leftCoefficient1 - rightCoefficient1;
538
152k
    pSpecRCurrBand[i - 2] = leftCoefficient2 - rightCoefficient2;
539
152k
    pSpecRCurrBand[i - 1] = leftCoefficient3 - rightCoefficient3;
540
152k
  }
541
107k
}
542
543
void CJointStereo_ApplyMS(
544
    CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
545
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2],
546
    FIXP_DBL *spectrumL, FIXP_DBL *spectrumR, SHORT *SFBleftScale,
547
    SHORT *SFBrightScale, SHORT *specScaleL, SHORT *specScaleR,
548
    const SHORT *pScaleFactorBandOffsets, const UCHAR *pWindowGroupLength,
549
    const int windowGroups, const int max_sfb_ste_outside,
550
    const int scaleFactorBandsTransmittedL,
551
    const int scaleFactorBandsTransmittedR, FIXP_DBL *store_dmx_re_prev,
552
124k
    SHORT *store_dmx_re_prev_e, const int mainband_flag) {
553
124k
  int window, group, band;
554
124k
  UCHAR groupMask;
555
124k
  CJointStereoData *pJointStereoData =
556
124k
      &pAacDecoderChannelInfo[L]->pComData->jointStereoData;
557
124k
  CCplxPredictionData *cplxPredictionData =
558
124k
      pAacDecoderChannelInfo[L]->pComStaticData->cplxPredictionData;
559
560
124k
  int max_sfb_ste =
561
124k
      fMax(scaleFactorBandsTransmittedL, scaleFactorBandsTransmittedR);
562
124k
  int min_sfb_ste =
563
124k
      fMin(scaleFactorBandsTransmittedL, scaleFactorBandsTransmittedR);
564
124k
  int scaleFactorBandsTransmitted = min_sfb_ste;
565
566
124k
  if (pJointStereoData->cplx_pred_flag) {
567
36.5k
    int windowLen, groupwin, frameMaxScale;
568
36.5k
    CJointStereoPersistentData *pJointStereoPersistentData =
569
36.5k
        &pAacDecoderStaticChannelInfo[L]
570
36.5k
             ->pCpeStaticData->jointStereoPersistentData;
571
36.5k
    FIXP_DBL *const staticSpectralCoeffsL =
572
36.5k
        pAacDecoderStaticChannelInfo[L]
573
36.5k
            ->pCpeStaticData->jointStereoPersistentData.spectralCoeffs[L];
574
36.5k
    FIXP_DBL *const staticSpectralCoeffsR =
575
36.5k
        pAacDecoderStaticChannelInfo[L]
576
36.5k
            ->pCpeStaticData->jointStereoPersistentData.spectralCoeffs[R];
577
36.5k
    SHORT *const staticSpecScaleL =
578
36.5k
        pAacDecoderStaticChannelInfo[L]
579
36.5k
            ->pCpeStaticData->jointStereoPersistentData.specScale[L];
580
36.5k
    SHORT *const staticSpecScaleR =
581
36.5k
        pAacDecoderStaticChannelInfo[L]
582
36.5k
            ->pCpeStaticData->jointStereoPersistentData.specScale[R];
583
584
36.5k
    FIXP_DBL *dmx_re =
585
36.5k
        pAacDecoderStaticChannelInfo[L]
586
36.5k
            ->pCpeStaticData->jointStereoPersistentData.scratchBuffer;
587
36.5k
    FIXP_DBL *dmx_re_prev =
588
36.5k
        pAacDecoderStaticChannelInfo[L]
589
36.5k
            ->pCpeStaticData->jointStereoPersistentData.scratchBuffer +
590
36.5k
        1024;
591
592
    /* When MS is applied over the main band this value gets computed. Otherwise
593
     * (for the tiles) it uses the assigned value */
594
36.5k
    SHORT dmx_re_prev_e = *store_dmx_re_prev_e;
595
596
36.5k
    const FIXP_FILT *pCoeff;
597
36.5k
    const FIXP_FILT *pCoeffPrev;
598
36.5k
    int coeffPointerOffset;
599
600
36.5k
    int previousShape = (int)pJointStereoPersistentData->winShapePrev;
601
36.5k
    int currentShape = (int)pAacDecoderChannelInfo[L]->icsInfo.WindowShape;
602
603
    /* complex stereo prediction */
604
605
    /* 0. preparations */
606
607
    /* 0.0. get scratch buffer for downmix MDST */
608
36.5k
    C_AALLOC_SCRATCH_START(dmx_im, FIXP_DBL, 1024);
609
610
    /* 0.1. window lengths */
611
612
    /* get length of short window for current configuration */
613
36.5k
    windowLen =
614
36.5k
        pAacDecoderChannelInfo[L]->granuleLength; /* framelength 768 => 96,
615
                                                     framelength 1024 => 128 */
616
617
    /* if this is no short-block set length for long-block */
618
36.5k
    if (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence != BLOCK_SHORT) {
619
16.2k
      windowLen *= 8;
620
16.2k
    }
621
622
    /* 0.2. set pointer to filter-coefficients for MDST excitation including
623
     * previous frame portions */
624
    /*      cp. ISO/IEC FDIS 23003-3:2011(E) table 125 */
625
626
    /* set pointer to default-position */
627
36.5k
    pCoeffPrev = mdst_filt_coef_prev[previousShape];
628
629
36.5k
    if (cplxPredictionData->complex_coef == 1) {
630
30.4k
      switch (pAacDecoderChannelInfo[L]
631
30.4k
                  ->icsInfo.WindowSequence) { /* current window sequence */
632
19.3k
        case BLOCK_SHORT:
633
27.6k
        case BLOCK_LONG:
634
27.6k
          pCoeffPrev = mdst_filt_coef_prev[previousShape];
635
27.6k
          break;
636
637
2.35k
        case BLOCK_START:
638
2.35k
          if ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) ||
639
2.23k
              (pJointStereoPersistentData->winSeqPrev == BLOCK_START)) {
640
            /* a stop-start-sequence can only follow on an eight-short-sequence
641
             * or a start-sequence */
642
1.80k
            pCoeffPrev = mdst_filt_coef_prev[2 + previousShape];
643
1.80k
          } else {
644
545
            pCoeffPrev = mdst_filt_coef_prev[previousShape];
645
545
          }
646
2.35k
          break;
647
648
384
        case BLOCK_STOP:
649
384
          pCoeffPrev = mdst_filt_coef_prev[2 + previousShape];
650
384
          break;
651
652
0
        default:
653
0
          pCoeffPrev = mdst_filt_coef_prev[previousShape];
654
0
          break;
655
30.4k
      }
656
30.4k
    }
657
658
    /* 0.3. set pointer to filter-coefficients for MDST excitation */
659
660
    /* define offset of pointer to filter-coefficients for MDST exitation
661
     * employing only the current frame */
662
36.5k
    if ((previousShape == SHAPE_SINE) && (currentShape == SHAPE_SINE)) {
663
31.3k
      coeffPointerOffset = 0;
664
31.3k
    } else if ((previousShape == SHAPE_SINE) && (currentShape == SHAPE_KBD)) {
665
1.09k
      coeffPointerOffset = 2;
666
4.13k
    } else if ((previousShape == SHAPE_KBD) && (currentShape == SHAPE_KBD)) {
667
592
      coeffPointerOffset = 1;
668
592
    } else /* if ( (previousShape == SHAPE_KBD) && (currentShape == SHAPE_SINE)
669
              ) */
670
3.53k
    {
671
3.53k
      coeffPointerOffset = 3;
672
3.53k
    }
673
674
    /* set pointer to filter-coefficient table cp. ISO/IEC FDIS 23003-3:2011(E)
675
     * table 124 */
676
36.5k
    switch (pAacDecoderChannelInfo[L]
677
36.5k
                ->icsInfo.WindowSequence) { /* current window sequence */
678
20.3k
      case BLOCK_SHORT:
679
31.6k
      case BLOCK_LONG:
680
31.6k
        pCoeff = mdst_filt_coef_curr[coeffPointerOffset];
681
31.6k
        break;
682
683
4.48k
      case BLOCK_START:
684
4.48k
        if ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) ||
685
4.31k
            (pJointStereoPersistentData->winSeqPrev == BLOCK_START)) {
686
          /* a stop-start-sequence can only follow on an eight-short-sequence or
687
           * a start-sequence */
688
2.89k
          pCoeff = mdst_filt_coef_curr[12 + coeffPointerOffset];
689
2.89k
        } else {
690
1.58k
          pCoeff = mdst_filt_coef_curr[4 + coeffPointerOffset];
691
1.58k
        }
692
4.48k
        break;
693
694
416
      case BLOCK_STOP:
695
416
        pCoeff = mdst_filt_coef_curr[8 + coeffPointerOffset];
696
416
        break;
697
698
0
      default:
699
0
        pCoeff = mdst_filt_coef_curr[coeffPointerOffset];
700
36.5k
    }
701
702
    /* 0.4. find maximum common (l/r) band-scaling-factor for whole sequence
703
     * (all windows) */
704
36.5k
    frameMaxScale = 0;
705
191k
    for (window = 0, group = 0; group < windowGroups; group++) {
706
333k
      for (groupwin = 0; groupwin < pWindowGroupLength[group];
707
178k
           groupwin++, window++) {
708
178k
        SHORT *leftScale = &SFBleftScale[window * 16];
709
178k
        SHORT *rightScale = &SFBrightScale[window * 16];
710
178k
        int windowMaxScale = 0;
711
712
        /* find maximum scaling factor of all bands in this window */
713
196k
        for (band = 0; band < min_sfb_ste; band++) {
714
17.8k
          int lScale = leftScale[band];
715
17.8k
          int rScale = rightScale[band];
716
17.8k
          int commonScale = ((lScale > rScale) ? lScale : rScale);
717
17.8k
          windowMaxScale =
718
17.8k
              (windowMaxScale < commonScale) ? commonScale : windowMaxScale;
719
17.8k
        }
720
178k
        if (scaleFactorBandsTransmittedL >
721
178k
            min_sfb_ste) { /* i.e. scaleFactorBandsTransmittedL == max_sfb_ste
722
                            */
723
7.52k
          for (; band < max_sfb_ste; band++) {
724
6.77k
            int lScale = leftScale[band];
725
6.77k
            windowMaxScale =
726
6.77k
                (windowMaxScale < lScale) ? lScale : windowMaxScale;
727
6.77k
          }
728
178k
        } else {
729
178k
          if (scaleFactorBandsTransmittedR >
730
178k
              min_sfb_ste) { /* i.e. scaleFactorBandsTransmittedR == max_sfb_ste
731
                              */
732
133k
            for (; band < max_sfb_ste; band++) {
733
112k
              int rScale = rightScale[band];
734
112k
              windowMaxScale =
735
112k
                  (windowMaxScale < rScale) ? rScale : windowMaxScale;
736
112k
            }
737
21.1k
          }
738
178k
        }
739
740
        /* find maximum common SF of all windows */
741
178k
        frameMaxScale =
742
178k
            (frameMaxScale < windowMaxScale) ? windowMaxScale : frameMaxScale;
743
178k
      }
744
154k
    }
745
746
    /* add some headroom for overflow protection during filter and add operation
747
     */
748
36.5k
    frameMaxScale += 2;
749
750
    /* process on window-basis (i.e. iterate over all groups and corresponding
751
     * windows) */
752
191k
    for (window = 0, group = 0; group < windowGroups; group++) {
753
154k
      groupMask = 1 << group;
754
755
333k
      for (groupwin = 0; groupwin < pWindowGroupLength[group];
756
178k
           groupwin++, window++) {
757
        /* initialize the MDST with zeros */
758
178k
        FDKmemclear(&dmx_im[windowLen * window], windowLen * sizeof(FIXP_DBL));
759
760
        /* 1. calculate the previous downmix MDCT. We do this once just for the
761
         * Main band. */
762
178k
        if (cplxPredictionData->complex_coef == 1) {
763
165k
          if ((cplxPredictionData->use_prev_frame == 1) && (mainband_flag)) {
764
            /* if this is a long-block or the first window of a short-block
765
               calculate the downmix MDCT of the previous frame.
766
               use_prev_frame is assumed not to change during a frame!
767
            */
768
769
            /* first determine shiftfactors to scale left and right channel */
770
5.49k
            if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence !=
771
5.49k
                 BLOCK_SHORT) ||
772
5.25k
                (window == 0)) {
773
899
              int index_offset = 0;
774
899
              int srLeftChan = 0;
775
899
              int srRightChan = 0;
776
899
              if (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
777
899
                  BLOCK_SHORT) {
778
                /* use the last window of the previous frame for MDCT
779
                 * calculation if this is a short-block. */
780
657
                index_offset = windowLen * 7;
781
657
                if (staticSpecScaleL[7] > staticSpecScaleR[7]) {
782
47
                  srRightChan = staticSpecScaleL[7] - staticSpecScaleR[7];
783
47
                  dmx_re_prev_e = staticSpecScaleL[7];
784
610
                } else {
785
610
                  srLeftChan = staticSpecScaleR[7] - staticSpecScaleL[7];
786
610
                  dmx_re_prev_e = staticSpecScaleR[7];
787
610
                }
788
657
              } else {
789
242
                if (staticSpecScaleL[0] > staticSpecScaleR[0]) {
790
59
                  srRightChan = staticSpecScaleL[0] - staticSpecScaleR[0];
791
59
                  dmx_re_prev_e = staticSpecScaleL[0];
792
183
                } else {
793
183
                  srLeftChan = staticSpecScaleR[0] - staticSpecScaleL[0];
794
183
                  dmx_re_prev_e = staticSpecScaleR[0];
795
183
                }
796
242
              }
797
798
              /* now scale channels and determine downmix MDCT of previous frame
799
               */
800
899
              if (pAacDecoderStaticChannelInfo[L]
801
899
                      ->pCpeStaticData->jointStereoPersistentData
802
899
                      .clearSpectralCoeffs == 1) {
803
0
                FDKmemclear(dmx_re_prev, windowLen * sizeof(FIXP_DBL));
804
0
                dmx_re_prev_e = 0;
805
899
              } else {
806
899
                if (cplxPredictionData->pred_dir == 0) {
807
137k
                  for (int i = 0; i < windowLen; i++) {
808
136k
                    dmx_re_prev[i] =
809
136k
                        ((staticSpectralCoeffsL[index_offset + i] >>
810
136k
                          fMin(DFRACT_BITS - 1, srLeftChan + 1)) +
811
136k
                         (staticSpectralCoeffsR[index_offset + i] >>
812
136k
                          fMin(DFRACT_BITS - 1, srRightChan + 1)));
813
136k
                  }
814
571
                } else {
815
130k
                  for (int i = 0; i < windowLen; i++) {
816
130k
                    dmx_re_prev[i] =
817
130k
                        ((staticSpectralCoeffsL[index_offset + i] >>
818
130k
                          fMin(DFRACT_BITS - 1, srLeftChan + 1)) -
819
130k
                         (staticSpectralCoeffsR[index_offset + i] >>
820
130k
                          fMin(DFRACT_BITS - 1, srRightChan + 1)));
821
130k
                  }
822
328
                }
823
899
              }
824
825
              /* In case that we use INF we have to preserve the state of the
826
              "dmx_re_prev" (original or computed). This is necessary because we
827
              have to apply MS over the separate IGF tiles. */
828
899
              FDKmemcpy(store_dmx_re_prev, &dmx_re_prev[0],
829
899
                        windowLen * sizeof(FIXP_DBL));
830
831
              /* Particular exponent of the computed/original "dmx_re_prev" must
832
               * be kept for the tile MS calculations if necessary.*/
833
899
              *store_dmx_re_prev_e = dmx_re_prev_e;
834
835
899
            } /* if ( (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence !=
836
                 BLOCK_SHORT) || (window == 0) ) */
837
838
5.49k
          } /* if ( pJointStereoData->use_prev_frame == 1 ) */
839
840
165k
        } /* if ( pJointStereoData->complex_coef == 1 ) */
841
842
        /* 2. calculate downmix MDCT of current frame */
843
844
        /* set pointer to scale-factor-bands of current window */
845
178k
        SHORT *leftScale = &SFBleftScale[window * 16];
846
178k
        SHORT *rightScale = &SFBrightScale[window * 16];
847
848
178k
        specScaleL[window] = specScaleR[window] = frameMaxScale;
849
850
        /* adapt scaling-factors to previous frame */
851
178k
        if (cplxPredictionData->use_prev_frame == 1) {
852
5.49k
          if (window == 0) {
853
899
            if (dmx_re_prev_e < frameMaxScale) {
854
644
              if (mainband_flag == 0) {
855
0
                scaleValues(
856
0
                    dmx_re_prev, store_dmx_re_prev, windowLen,
857
0
                    -fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e)));
858
644
              } else {
859
644
                scaleValues(
860
644
                    dmx_re_prev, windowLen,
861
644
                    -fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e)));
862
644
              }
863
644
            } else {
864
255
              if (mainband_flag == 0) {
865
0
                FDKmemcpy(dmx_re_prev, store_dmx_re_prev,
866
0
                          windowLen * sizeof(FIXP_DBL));
867
0
              }
868
255
              specScaleL[0] = dmx_re_prev_e;
869
255
              specScaleR[0] = dmx_re_prev_e;
870
255
            }
871
4.59k
          } else { /* window != 0 */
872
4.59k
            FDK_ASSERT(pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
873
4.59k
                       BLOCK_SHORT);
874
4.59k
            if (specScaleL[window - 1] < frameMaxScale) {
875
0
              scaleValues(&dmx_re[windowLen * (window - 1)], windowLen,
876
0
                          -fMin(DFRACT_BITS - 1,
877
0
                                (frameMaxScale - specScaleL[window - 1])));
878
4.59k
            } else {
879
4.59k
              specScaleL[window] = specScaleL[window - 1];
880
4.59k
              specScaleR[window] = specScaleR[window - 1];
881
4.59k
            }
882
4.59k
          }
883
5.49k
        } /* if ( pJointStereoData->use_prev_frame == 1 ) */
884
885
        /* scaling factors of both channels ought to be equal now */
886
178k
        FDK_ASSERT(specScaleL[window] == specScaleR[window]);
887
888
        /* rescale signal and calculate downmix MDCT */
889
315k
        for (band = 0; band < max_sfb_ste; band++) {
890
          /* first adapt scaling of current band to scaling of current window =>
891
           * shift signal right */
892
137k
          int lScale = leftScale[band];
893
137k
          int rScale = rightScale[band];
894
895
137k
          lScale = fMin(DFRACT_BITS - 1, specScaleL[window] - lScale);
896
137k
          rScale = fMin(DFRACT_BITS - 1,
897
137k
                        specScaleL[window] - rScale); /* L or R doesn't
898
                                                         matter,
899
                                                         specScales are
900
                                                         equal at this
901
                                                         point */
902
903
          /* Write back to sfb scale to cover the case when max_sfb_ste <
904
           * max_sfb */
905
137k
          leftScale[band] = rightScale[band] = specScaleL[window];
906
907
137k
          for (int i = pScaleFactorBandOffsets[band];
908
1.41M
               i < pScaleFactorBandOffsets[band + 1]; i++) {
909
1.27M
            spectrumL[windowLen * window + i] >>= lScale;
910
1.27M
            spectrumR[windowLen * window + i] >>= rScale;
911
1.27M
          }
912
913
          /* now calculate downmix MDCT */
914
137k
          if (pJointStereoData->MsUsed[band] & groupMask) {
915
86.9k
            for (int i = pScaleFactorBandOffsets[band];
916
787k
                 i < pScaleFactorBandOffsets[band + 1]; i++) {
917
700k
              dmx_re[windowLen * window + i] =
918
700k
                  spectrumL[windowLen * window + i];
919
700k
            }
920
86.9k
          } else {
921
50.1k
            if (cplxPredictionData->pred_dir == 0) {
922
20.7k
              for (int i = pScaleFactorBandOffsets[band];
923
342k
                   i < pScaleFactorBandOffsets[band + 1]; i++) {
924
321k
                dmx_re[windowLen * window + i] =
925
321k
                    (spectrumL[windowLen * window + i] +
926
321k
                     spectrumR[windowLen * window + i]) >>
927
321k
                    1;
928
321k
              }
929
29.4k
            } else {
930
29.4k
              for (int i = pScaleFactorBandOffsets[band];
931
282k
                   i < pScaleFactorBandOffsets[band + 1]; i++) {
932
253k
                dmx_re[windowLen * window + i] =
933
253k
                    (spectrumL[windowLen * window + i] -
934
253k
                     spectrumR[windowLen * window + i]) >>
935
253k
                    1;
936
253k
              }
937
29.4k
            }
938
50.1k
          }
939
940
137k
        } /* for ( band=0; band<max_sfb_ste; band++ ) */
941
        /* Clean until the end */
942
178k
        for (int i = pScaleFactorBandOffsets[max_sfb_ste_outside];
943
27.4M
             i < windowLen; i++) {
944
27.3M
          dmx_re[windowLen * window + i] = (FIXP_DBL)0;
945
27.3M
        }
946
947
        /* 3. calculate MDST-portion corresponding to the current frame. */
948
178k
        if (cplxPredictionData->complex_coef == 1) {
949
165k
          {
950
            /* 3.1 move pointer in filter-coefficient table in case of short
951
             * window sequence */
952
            /*     (other coefficients are utilized for the last 7 short
953
             * windows)            */
954
165k
            if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
955
165k
                 BLOCK_SHORT) &&
956
154k
                (window != 0)) {
957
135k
              pCoeff = mdst_filt_coef_curr[currentShape];
958
135k
              pCoeffPrev = mdst_filt_coef_prev[currentShape];
959
135k
            }
960
961
            /* The length of the filter processing must be extended because of
962
             * filter boundary problems */
963
165k
            int extended_band = fMin(
964
165k
                pScaleFactorBandOffsets[max_sfb_ste_outside] + 7, windowLen);
965
966
            /* 3.2. estimate downmix MDST from current frame downmix MDCT */
967
165k
            if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
968
165k
                 BLOCK_SHORT) &&
969
154k
                (window != 0)) {
970
135k
              CJointStereo_filterAndAdd(&dmx_re[windowLen * window],
971
135k
                                        extended_band, windowLen, pCoeff,
972
135k
                                        &dmx_im[windowLen * window], 1);
973
974
135k
              CJointStereo_filterAndAdd(&dmx_re[windowLen * (window - 1)],
975
135k
                                        extended_band, windowLen, pCoeffPrev,
976
135k
                                        &dmx_im[windowLen * window], 0);
977
135k
            } else {
978
30.4k
              CJointStereo_filterAndAdd(dmx_re, extended_band, windowLen,
979
30.4k
                                        pCoeff, dmx_im, 1);
980
981
30.4k
              if (cplxPredictionData->use_prev_frame == 1) {
982
899
                CJointStereo_filterAndAdd(dmx_re_prev, extended_band, windowLen,
983
899
                                          pCoeffPrev,
984
899
                                          &dmx_im[windowLen * window], 0);
985
899
              }
986
30.4k
            }
987
988
165k
          } /* if(pAacDecoderChannelInfo[L]->transform_splitting_active) */
989
165k
        }   /* if ( pJointStereoData->complex_coef == 1 ) */
990
991
        /* 4. upmix process */
992
178k
        LONG pred_dir = cplxPredictionData->pred_dir ? -1 : 1;
993
        /* 0.1 in Q-3.34 */
994
178k
        const FIXP_DBL pointOne = 0x66666666; /* 0.8 */
995
        /* Shift value for the downmix */
996
178k
        const INT shift_dmx = SF_FNA_COEFFS + 1;
997
998
315k
        for (band = 0; band < max_sfb_ste_outside; band++) {
999
137k
          if (pJointStereoData->MsUsed[band] & groupMask) {
1000
86.9k
            FIXP_SGL tempRe =
1001
86.9k
                (FIXP_SGL)cplxPredictionData->alpha_q_re[group][band];
1002
86.9k
            FIXP_SGL tempIm =
1003
86.9k
                (FIXP_SGL)cplxPredictionData->alpha_q_im[group][band];
1004
1005
            /* Find the minimum common headroom for alpha_re and alpha_im */
1006
86.9k
            int alpha_re_headroom = CountLeadingBits((INT)tempRe) - 16;
1007
86.9k
            if (tempRe == (FIXP_SGL)0) alpha_re_headroom = 15;
1008
86.9k
            int alpha_im_headroom = CountLeadingBits((INT)tempIm) - 16;
1009
86.9k
            if (tempIm == (FIXP_SGL)0) alpha_im_headroom = 15;
1010
86.9k
            int val = fMin(alpha_re_headroom, alpha_im_headroom);
1011
1012
            /* Multiply alpha by 0.1 with maximum precision */
1013
86.9k
            FDK_ASSERT(val >= 0);
1014
86.9k
            FIXP_DBL alpha_re_tmp = fMult((FIXP_SGL)(tempRe << val), pointOne);
1015
86.9k
            FIXP_DBL alpha_im_tmp = fMult((FIXP_SGL)(tempIm << val), pointOne);
1016
1017
            /* Calculate alpha exponent */
1018
            /* (Q-3.34 * Q15.0) shifted left by "val" */
1019
86.9k
            int alpha_re_exp = -3 + 15 - val;
1020
1021
86.9k
            int help3_shift = alpha_re_exp + 1;
1022
1023
86.9k
            FIXP_DBL *p2CoeffL = &(
1024
86.9k
                spectrumL[windowLen * window + pScaleFactorBandOffsets[band]]);
1025
86.9k
            FIXP_DBL *p2CoeffR = &(
1026
86.9k
                spectrumR[windowLen * window + pScaleFactorBandOffsets[band]]);
1027
86.9k
            FIXP_DBL *p2dmxIm =
1028
86.9k
                &(dmx_im[windowLen * window + pScaleFactorBandOffsets[band]]);
1029
86.9k
            FIXP_DBL *p2dmxRe =
1030
86.9k
                &(dmx_re[windowLen * window + pScaleFactorBandOffsets[band]]);
1031
1032
86.9k
            for (int i = pScaleFactorBandOffsets[band];
1033
787k
                 i < pScaleFactorBandOffsets[band + 1]; i++) {
1034
              /* Calculating helper term:
1035
                    side = specR[i] - alpha_re[i] * dmx_re[i] - alpha_im[i] *
1036
                dmx_im[i];
1037
1038
                Here "dmx_re" may be the same as "specL" or alternatively keep
1039
                the downmix. "dmx_re" and "specL" are two different pointers
1040
                pointing to separate arrays, which may or may not contain the
1041
                same data (with different scaling).
1042
1043
                specL[i] =   + (specL[i] + side);
1044
                specR[i] = -/+ (specL[i] - side);
1045
              */
1046
700k
              FIXP_DBL side, left, right;
1047
1048
700k
              side = fMultAddDiv2(fMultDiv2(alpha_re_tmp, *p2dmxRe++),
1049
700k
                                  alpha_im_tmp, (*p2dmxIm++) << shift_dmx);
1050
700k
              side = ((*p2CoeffR) >> 2) -
1051
700k
                     (FIXP_DBL)SATURATE_SHIFT(side, -(help3_shift - 2),
1052
700k
                                              DFRACT_BITS - 2);
1053
1054
700k
              left = ((*p2CoeffL) >> 2) + side;
1055
700k
              right = ((*p2CoeffL) >> 2) - side;
1056
700k
              right = (FIXP_DBL)((LONG)right * pred_dir);
1057
1058
700k
              *p2CoeffL++ = SATURATE_LEFT_SHIFT_ALT(left, 2, DFRACT_BITS);
1059
700k
              *p2CoeffR++ = SATURATE_LEFT_SHIFT_ALT(right, 2, DFRACT_BITS);
1060
700k
            }
1061
86.9k
          }
1062
1063
137k
        } /* for ( band=0; band < max_sfb_ste; band++ ) */
1064
178k
      }   /* for ( groupwin=0; groupwin<pWindowGroupLength[group]; groupwin++,
1065
             window++ ) */
1066
1067
154k
    } /* for ( window = 0, group = 0; group < windowGroups; group++ ) */
1068
1069
    /* free scratch buffer */
1070
36.5k
    C_AALLOC_SCRATCH_END(dmx_im, FIXP_DBL, 1024);
1071
1072
88.3k
  } else {
1073
    /* MS stereo */
1074
1075
278k
    for (window = 0, group = 0; group < windowGroups; group++) {
1076
190k
      groupMask = 1 << group;
1077
1078
441k
      for (int groupwin = 0; groupwin < pWindowGroupLength[group];
1079
251k
           groupwin++, window++) {
1080
251k
        FIXP_DBL *leftSpectrum, *rightSpectrum;
1081
251k
        SHORT *leftScale = &SFBleftScale[window * 16];
1082
251k
        SHORT *rightScale = &SFBrightScale[window * 16];
1083
1084
251k
        leftSpectrum =
1085
251k
            SPEC(spectrumL, window, pAacDecoderChannelInfo[L]->granuleLength);
1086
251k
        rightSpectrum =
1087
251k
            SPEC(spectrumR, window, pAacDecoderChannelInfo[R]->granuleLength);
1088
1089
728k
        for (band = 0; band < max_sfb_ste_outside; band++) {
1090
477k
          if (pJointStereoData->MsUsed[band] & groupMask) {
1091
107k
            int lScale = leftScale[band];
1092
107k
            int rScale = rightScale[band];
1093
107k
            int commonScale = lScale > rScale ? lScale : rScale;
1094
107k
            unsigned int offsetCurrBand, offsetNextBand;
1095
1096
            /* ISO/IEC 14496-3 Chapter 4.6.8.1.1 :
1097
               M/S joint channel coding can only be used if common_window is 1.
1098
             */
1099
107k
            FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) ==
1100
107k
                       GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo));
1101
107k
            FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) ==
1102
107k
                       GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo));
1103
1104
107k
            commonScale++;
1105
107k
            leftScale[band] = commonScale;
1106
107k
            rightScale[band] = commonScale;
1107
1108
107k
            lScale = fMin(DFRACT_BITS - 1, commonScale - lScale);
1109
107k
            rScale = fMin(DFRACT_BITS - 1, commonScale - rScale);
1110
1111
107k
            FDK_ASSERT(lScale >= 0 && rScale >= 0);
1112
1113
107k
            offsetCurrBand = pScaleFactorBandOffsets[band];
1114
107k
            offsetNextBand = pScaleFactorBandOffsets[band + 1];
1115
1116
107k
            CJointStereo_GenerateMSOutput(&(leftSpectrum[offsetCurrBand]),
1117
107k
                                          &(rightSpectrum[offsetCurrBand]),
1118
107k
                                          lScale, rScale,
1119
107k
                                          offsetNextBand - offsetCurrBand);
1120
107k
          }
1121
477k
        }
1122
251k
        if (scaleFactorBandsTransmittedL > scaleFactorBandsTransmitted) {
1123
598
          for (; band < scaleFactorBandsTransmittedL; band++) {
1124
0
            if (pJointStereoData->MsUsed[band] & groupMask) {
1125
0
              rightScale[band] = leftScale[band];
1126
1127
0
              for (int index = pScaleFactorBandOffsets[band];
1128
0
                   index < pScaleFactorBandOffsets[band + 1]; index++) {
1129
0
                FIXP_DBL leftCoefficient = leftSpectrum[index];
1130
                /* FIXP_DBL rightCoefficient = (FIXP_DBL)0; */
1131
0
                rightSpectrum[index] = leftCoefficient;
1132
0
              }
1133
0
            }
1134
0
          }
1135
250k
        } else if (scaleFactorBandsTransmittedR > scaleFactorBandsTransmitted) {
1136
2.33k
          for (; band < scaleFactorBandsTransmittedR; band++) {
1137
0
            if (pJointStereoData->MsUsed[band] & groupMask) {
1138
0
              leftScale[band] = rightScale[band];
1139
1140
0
              for (int index = pScaleFactorBandOffsets[band];
1141
0
                   index < pScaleFactorBandOffsets[band + 1]; index++) {
1142
                /* FIXP_DBL leftCoefficient  = (FIXP_DBL)0; */
1143
0
                FIXP_DBL rightCoefficient = rightSpectrum[index];
1144
1145
0
                leftSpectrum[index] = rightCoefficient;
1146
0
                rightSpectrum[index] = -rightCoefficient;
1147
0
              }
1148
0
            }
1149
0
          }
1150
2.33k
        }
1151
251k
      }
1152
190k
    }
1153
1154
    /* Reset MsUsed flags if no explicit signalling was transmitted. Necessary
1155
       for intensity coding. PNS correlation signalling was mapped before
1156
       calling CJointStereo_ApplyMS(). */
1157
88.3k
    if (pJointStereoData->MsMaskPresent == 2) {
1158
19.1k
      FDKmemclear(pJointStereoData->MsUsed,
1159
19.1k
                  JointStereoMaximumBands * sizeof(UCHAR));
1160
19.1k
    }
1161
88.3k
  }
1162
124k
}
1163
1164
void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
1165
                          const SHORT *pScaleFactorBandOffsets,
1166
                          const UCHAR *pWindowGroupLength,
1167
                          const int windowGroups,
1168
80.8k
                          const int scaleFactorBandsTransmitted) {
1169
80.8k
  CJointStereoData *pJointStereoData =
1170
80.8k
      &pAacDecoderChannelInfo[L]->pComData->jointStereoData;
1171
1172
251k
  for (int window = 0, group = 0; group < windowGroups; group++) {
1173
170k
    UCHAR *CodeBook;
1174
170k
    SHORT *ScaleFactor;
1175
170k
    UCHAR groupMask = 1 << group;
1176
1177
170k
    CodeBook = &pAacDecoderChannelInfo[R]->pDynData->aCodeBook[group * 16];
1178
170k
    ScaleFactor =
1179
170k
        &pAacDecoderChannelInfo[R]->pDynData->aScaleFactor[group * 16];
1180
1181
399k
    for (int groupwin = 0; groupwin < pWindowGroupLength[group];
1182
229k
         groupwin++, window++) {
1183
229k
      FIXP_DBL *leftSpectrum, *rightSpectrum;
1184
229k
      SHORT *leftScale =
1185
229k
          &pAacDecoderChannelInfo[L]->pDynData->aSfbScale[window * 16];
1186
229k
      SHORT *rightScale =
1187
229k
          &pAacDecoderChannelInfo[R]->pDynData->aSfbScale[window * 16];
1188
229k
      int band;
1189
1190
229k
      leftSpectrum = SPEC(pAacDecoderChannelInfo[L]->pSpectralCoefficient,
1191
229k
                          window, pAacDecoderChannelInfo[L]->granuleLength);
1192
229k
      rightSpectrum = SPEC(pAacDecoderChannelInfo[R]->pSpectralCoefficient,
1193
229k
                           window, pAacDecoderChannelInfo[R]->granuleLength);
1194
1195
662k
      for (band = 0; band < scaleFactorBandsTransmitted; band++) {
1196
433k
        if ((CodeBook[band] == INTENSITY_HCB) ||
1197
400k
            (CodeBook[band] == INTENSITY_HCB2)) {
1198
64.4k
          int bandScale = -(ScaleFactor[band] + 100);
1199
1200
64.4k
          int msb = bandScale >> 2;
1201
64.4k
          int lsb = bandScale & 0x03;
1202
1203
          /* exponent of MantissaTable[lsb][0] is 1, thus msb+1 below. */
1204
64.4k
          FIXP_DBL scale = MantissaTable[lsb][0];
1205
1206
          /* ISO/IEC 14496-3 Chapter 4.6.8.2.3 :
1207
             The use of intensity stereo coding is signaled by the use of the
1208
             pseudo codebooks INTENSITY_HCB and INTENSITY_HCB2 (15 and 14) only
1209
             in the right channel of a channel_pair_element() having a common
1210
             ics_info() (common_window == 1). */
1211
64.4k
          FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) ==
1212
64.4k
                     GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo));
1213
64.4k
          FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) ==
1214
64.4k
                     GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo));
1215
1216
64.4k
          rightScale[band] = leftScale[band] + msb + 1;
1217
1218
64.4k
          if (pJointStereoData->MsUsed[band] & groupMask) {
1219
20.0k
            if (CodeBook[band] == INTENSITY_HCB) /* _NOT_ in-phase */
1220
5.88k
            {
1221
5.88k
              scale = -scale;
1222
5.88k
            }
1223
44.4k
          } else {
1224
44.4k
            if (CodeBook[band] == INTENSITY_HCB2) /* out-of-phase */
1225
17.2k
            {
1226
17.2k
              scale = -scale;
1227
17.2k
            }
1228
44.4k
          }
1229
1230
64.4k
          for (int index = pScaleFactorBandOffsets[band];
1231
376k
               index < pScaleFactorBandOffsets[band + 1]; index++) {
1232
312k
            rightSpectrum[index] = fMult(leftSpectrum[index], scale);
1233
312k
          }
1234
64.4k
        }
1235
433k
      }
1236
229k
    }
1237
170k
  }
1238
80.8k
}