Coverage Report

Created: 2026-06-10 06:27

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
144k
                      int windowSequence, const UINT flags) {
123
144k
  int group, band;
124
125
144k
  pJointStereoData->MsMaskPresent = (UCHAR)FDKreadBits(bs, 2);
126
127
144k
  FDKmemclear(pJointStereoData->MsUsed,
128
144k
              scaleFactorBandsTransmitted * sizeof(UCHAR));
129
130
144k
  pJointStereoData->cplx_pred_flag = 0;
131
144k
  if (cplxPredictionActiv) {
132
36.2k
    cplxPredictionData->pred_dir = 0;
133
36.2k
    cplxPredictionData->complex_coef = 0;
134
36.2k
    cplxPredictionData->use_prev_frame = 0;
135
36.2k
    cplxPredictionData->igf_pred_dir = 0;
136
36.2k
  }
137
138
144k
  switch (pJointStereoData->MsMaskPresent) {
139
64.1k
    case 0: /* no M/S */
140
      /* all flags are already cleared */
141
64.1k
      break;
142
143
15.4k
    case 1: /* read ms_used */
144
35.8k
      for (group = 0; group < windowGroups; group++) {
145
76.6k
        for (band = 0; band < scaleFactorBandsTransmitted; band++) {
146
56.2k
          pJointStereoData->MsUsed[band] |= (FDKreadBits(bs, 1) << group);
147
56.2k
        }
148
20.4k
      }
149
15.4k
      break;
150
151
25.5k
    case 2: /* full spectrum M/S */
152
90.2k
      for (band = 0; band < scaleFactorBandsTransmitted; band++) {
153
64.7k
        pJointStereoData->MsUsed[band] = 255; /* set all flags to 1 */
154
64.7k
      }
155
25.5k
      break;
156
157
38.9k
    case 3:
158
      /* M/S coding is disabled, complex stereo prediction is enabled */
159
38.9k
      if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
160
33.1k
        if (cplxPredictionActiv) { /* 'if (stereoConfigIndex == 0)' */
161
162
33.1k
          pJointStereoData->cplx_pred_flag = 1;
163
164
          /* cplx_pred_data()  cp. ISO/IEC FDIS 23003-3:2011(E)  Table 26 */
165
33.1k
          int cplx_pred_all = 0; /* local use only */
166
33.1k
          cplx_pred_all = FDKreadBits(bs, 1);
167
168
33.1k
          if (cplx_pred_all) {
169
125k
            for (group = 0; group < windowGroups; group++) {
170
108k
              UCHAR groupmask = ((UCHAR)1 << group);
171
149k
              for (band = 0; band < scaleFactorBandsTransmitted; band++) {
172
40.4k
                pJointStereoData->MsUsed[band] |= groupmask;
173
40.4k
              }
174
108k
            }
175
16.6k
          } else {
176
41.9k
            for (group = 0; group < windowGroups; group++) {
177
77.1k
              for (band = 0; band < scaleFactorBandsTransmitted;
178
51.8k
                   band += SFB_PER_PRED_BAND) {
179
51.8k
                pJointStereoData->MsUsed[band] |= (FDKreadBits(bs, 1) << group);
180
51.8k
                if ((band + 1) < scaleFactorBandsTotal) {
181
51.2k
                  pJointStereoData->MsUsed[band + 1] |=
182
51.2k
                      (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group));
183
51.2k
                }
184
51.8k
              }
185
25.3k
            }
186
16.6k
          }
187
33.1k
        } else {
188
3
          return -1;
189
3
        }
190
33.1k
      }
191
38.9k
      break;
192
144k
  }
193
194
144k
  if (cplxPredictionActiv) {
195
    /* If all sfb are MS-ed then no complex prediction */
196
36.2k
    if (pJointStereoData->MsMaskPresent == 3) {
197
33.1k
      if (pJointStereoData->cplx_pred_flag) {
198
33.1k
        int delta_code_time = 0;
199
200
        /* set pointer to Huffman codebooks */
201
33.1k
        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
33.1k
        if (((windowSequence == BLOCK_SHORT) &&
205
17.4k
             (pJointStereoPersistentData->winSeqPrev != BLOCK_SHORT)) ||
206
31.8k
            ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) &&
207
16.8k
             (windowSequence != BLOCK_SHORT))) {
208
2.12k
          FDKmemclear(pJointStereoPersistentData->alpha_q_re_prev,
209
2.12k
                      JointStereoMaximumGroups * JointStereoMaximumBands *
210
2.12k
                          sizeof(SHORT));
211
2.12k
          FDKmemclear(pJointStereoPersistentData->alpha_q_im_prev,
212
2.12k
                      JointStereoMaximumGroups * JointStereoMaximumBands *
213
2.12k
                          sizeof(SHORT));
214
2.12k
        }
215
33.1k
        {
216
33.1k
          FDKmemclear(cplxPredictionData->alpha_q_re,
217
33.1k
                      JointStereoMaximumGroups * JointStereoMaximumBands *
218
33.1k
                          sizeof(SHORT));
219
33.1k
          FDKmemclear(cplxPredictionData->alpha_q_im,
220
33.1k
                      JointStereoMaximumGroups * JointStereoMaximumBands *
221
33.1k
                          sizeof(SHORT));
222
33.1k
        }
223
224
        /* 0 = mid->side prediction, 1 = side->mid prediction */
225
33.1k
        cplxPredictionData->pred_dir = FDKreadBits(bs, 1);
226
33.1k
        cplxPredictionData->complex_coef = FDKreadBits(bs, 1);
227
228
33.1k
        if (cplxPredictionData->complex_coef) {
229
27.9k
          if (flags & AC_INDEP) {
230
27.0k
            cplxPredictionData->use_prev_frame = 0;
231
27.0k
          } else {
232
896
            cplxPredictionData->use_prev_frame = FDKreadBits(bs, 1);
233
896
          }
234
27.9k
        }
235
236
33.1k
        if (flags & AC_INDEP) {
237
32.1k
          delta_code_time = 0;
238
32.1k
        } else {
239
1.04k
          delta_code_time = FDKreadBits(bs, 1);
240
1.04k
        }
241
242
33.1k
        {
243
33.1k
          int last_alpha_q_re = 0, last_alpha_q_im = 0;
244
245
167k
          for (group = 0; group < windowGroups; group++) {
246
206k
            for (band = 0; band < scaleFactorBandsTransmitted;
247
134k
                 band += SFB_PER_PRED_BAND) {
248
72.4k
              if (delta_code_time == 1) {
249
6.51k
                if (group > 0) {
250
5.02k
                  last_alpha_q_re =
251
5.02k
                      cplxPredictionData->alpha_q_re[group - 1][band];
252
5.02k
                  last_alpha_q_im =
253
5.02k
                      cplxPredictionData->alpha_q_im[group - 1][band];
254
5.02k
                } else if ((windowSequence == BLOCK_SHORT) &&
255
980
                           (pJointStereoPersistentData->winSeqPrev ==
256
980
                            BLOCK_SHORT)) {
257
                  /* Included for error-robustness */
258
425
                  if (pJointStereoPersistentData->winGroupsPrev == 0) return -1;
259
260
424
                  last_alpha_q_re =
261
424
                      pJointStereoPersistentData->alpha_q_re_prev
262
424
                          [pJointStereoPersistentData->winGroupsPrev - 1][band];
263
424
                  last_alpha_q_im =
264
424
                      pJointStereoPersistentData->alpha_q_im_prev
265
424
                          [pJointStereoPersistentData->winGroupsPrev - 1][band];
266
1.06k
                } else {
267
1.06k
                  last_alpha_q_re =
268
1.06k
                      pJointStereoPersistentData->alpha_q_re_prev[group][band];
269
1.06k
                  last_alpha_q_im =
270
1.06k
                      pJointStereoPersistentData->alpha_q_im_prev[group][band];
271
1.06k
                }
272
273
65.9k
              } else {
274
65.9k
                if (band > 0) {
275
38.7k
                  last_alpha_q_re =
276
38.7k
                      cplxPredictionData->alpha_q_re[group][band - 1];
277
38.7k
                  last_alpha_q_im =
278
38.7k
                      cplxPredictionData->alpha_q_im[group][band - 1];
279
38.7k
                } else {
280
27.2k
                  last_alpha_q_re = 0;
281
27.2k
                  last_alpha_q_im = 0;
282
27.2k
                }
283
284
65.9k
              } /* if (delta_code_time == 1) */
285
286
72.4k
              if (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)) {
287
41.7k
                int dpcm_alpha_re, dpcm_alpha_im;
288
289
41.7k
                dpcm_alpha_re = CBlock_DecodeHuffmanWord(bs, hcb);
290
41.7k
                dpcm_alpha_re -= 60;
291
41.7k
                dpcm_alpha_re *= -1;
292
293
41.7k
                cplxPredictionData->alpha_q_re[group][band] =
294
41.7k
                    dpcm_alpha_re + last_alpha_q_re;
295
296
41.7k
                if (cplxPredictionData->complex_coef) {
297
32.6k
                  dpcm_alpha_im = CBlock_DecodeHuffmanWord(bs, hcb);
298
32.6k
                  dpcm_alpha_im -= 60;
299
32.6k
                  dpcm_alpha_im *= -1;
300
301
32.6k
                  cplxPredictionData->alpha_q_im[group][band] =
302
32.6k
                      dpcm_alpha_im + last_alpha_q_im;
303
32.6k
                } else {
304
9.09k
                  cplxPredictionData->alpha_q_im[group][band] = 0;
305
9.09k
                }
306
307
41.7k
              } else {
308
30.7k
                cplxPredictionData->alpha_q_re[group][band] = 0;
309
30.7k
                cplxPredictionData->alpha_q_im[group][band] = 0;
310
30.7k
              } /* if (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)) */
311
312
72.4k
              if ((band + 1) <
313
72.4k
                  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
48.2k
                cplxPredictionData->alpha_q_re[group][band + 1] =
318
48.2k
                    cplxPredictionData->alpha_q_re[group][band];
319
48.2k
                cplxPredictionData->alpha_q_im[group][band + 1] =
320
48.2k
                    cplxPredictionData->alpha_q_im[group][band];
321
48.2k
              } /* if ((band+1)<scaleFactorBandsTotal) */
322
323
72.4k
              pJointStereoPersistentData->alpha_q_re_prev[group][band] =
324
72.4k
                  cplxPredictionData->alpha_q_re[group][band];
325
72.4k
              pJointStereoPersistentData->alpha_q_im_prev[group][band] =
326
72.4k
                  cplxPredictionData->alpha_q_im[group][band];
327
72.4k
            }
328
329
8.60M
            for (band = scaleFactorBandsTransmitted; band < max_sfb_ste_clear;
330
8.46M
                 band++) {
331
8.46M
              cplxPredictionData->alpha_q_re[group][band] = 0;
332
8.46M
              cplxPredictionData->alpha_q_im[group][band] = 0;
333
8.46M
              pJointStereoPersistentData->alpha_q_re_prev[group][band] = 0;
334
8.46M
              pJointStereoPersistentData->alpha_q_im_prev[group][band] = 0;
335
8.46M
            }
336
134k
          }
337
33.1k
        }
338
33.1k
      }
339
33.1k
    } else {
340
16.8k
      for (group = 0; group < windowGroups; group++) {
341
900k
        for (band = 0; band < max_sfb_ste_clear; band++) {
342
886k
          pJointStereoPersistentData->alpha_q_re_prev[group][band] = 0;
343
886k
          pJointStereoPersistentData->alpha_q_im_prev[group][band] = 0;
344
886k
        }
345
13.8k
      }
346
3.01k
    }
347
348
36.2k
    pJointStereoPersistentData->winGroupsPrev = windowGroups;
349
36.2k
  }
350
351
144k
  return 0;
352
144k
}
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
262k
) {
360
262k
  int i, j;
361
362
262k
  int indices_1[] = {2, 1, 0, 1, 2, 3};
363
262k
  int indices_2[] = {1, 0, 0, 2, 3, 4};
364
262k
  int indices_3[] = {0, 0, 1, 3, 4, 5};
365
366
262k
  int subtr_1[] = {6, 5, 4, 2, 1, 1};
367
262k
  int subtr_2[] = {5, 4, 3, 1, 1, 2};
368
262k
  int subtr_3[] = {4, 3, 2, 1, 2, 3};
369
370
262k
  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
578k
    for (i = 0; i < 3; i++) {
378
433k
      out[0] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[i]]) >> SR_FNA_OUT;
379
433k
      out[0] +=
380
433k
          (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[5 - i]]) >> SR_FNA_OUT;
381
433k
    }
382
383
578k
    for (i = 0; i < 3; i++) {
384
433k
      out[1] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[i]]) >> SR_FNA_OUT;
385
433k
      out[1] +=
386
433k
          (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[5 - i]]) >> SR_FNA_OUT;
387
433k
    }
388
389
578k
    for (i = 0; i < 3; i++) {
390
433k
      out[2] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[i]]) >> SR_FNA_OUT;
391
433k
      out[2] +=
392
433k
          (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[5 - i]]) >> SR_FNA_OUT;
393
433k
    }
394
395
1.01M
    for (j = 3; j < (len - 3); j++) {
396
3.46M
      for (i = 0; i < 3; i++) {
397
2.59M
        out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i]) >> SR_FNA_OUT;
398
2.59M
        out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i]) >> SR_FNA_OUT;
399
2.59M
      }
400
866k
    }
401
402
578k
    for (i = 0; i < 3; i++) {
403
433k
      out[len - 3] -=
404
433k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[i]]) >> SR_FNA_OUT;
405
433k
      out[len - 3] +=
406
433k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[5 - i]]) >> SR_FNA_OUT;
407
433k
    }
408
409
578k
    for (i = 0; i < 3; i++) {
410
433k
      out[len - 2] -=
411
433k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[i]]) >> SR_FNA_OUT;
412
433k
      out[len - 2] +=
413
433k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[5 - i]]) >> SR_FNA_OUT;
414
433k
    }
415
416
578k
    for (i = 0; i < 3; i++) {
417
433k
      out[len - 1] -=
418
433k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[i]]) >> SR_FNA_OUT;
419
433k
      out[len - 1] +=
420
433k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[5 - i]]) >> SR_FNA_OUT;
421
433k
    }
422
423
144k
  } 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
470k
    for (i = 0; i < 3; i++) {
430
352k
      out[0] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[i]] >> SR_FNA_OUT);
431
352k
      out[0] -=
432
352k
          (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[5 - i]] >> SR_FNA_OUT);
433
352k
    }
434
117k
    out[0] -= (FIXP_DBL)fMultDiv2(coeff[3], in[0] >> SR_FNA_OUT);
435
436
470k
    for (i = 0; i < 3; i++) {
437
352k
      out[1] += (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[i]] >> SR_FNA_OUT);
438
352k
      out[1] +=
439
352k
          (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[5 - i]] >> SR_FNA_OUT);
440
352k
    }
441
117k
    out[1] += (FIXP_DBL)fMultDiv2(coeff[3], in[1] >> SR_FNA_OUT);
442
443
470k
    for (i = 0; i < 3; i++) {
444
352k
      out[2] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[i]] >> SR_FNA_OUT);
445
352k
      out[2] -=
446
352k
          (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[5 - i]] >> SR_FNA_OUT);
447
352k
    }
448
117k
    out[2] -= (FIXP_DBL)fMultDiv2(coeff[3], in[2] >> SR_FNA_OUT);
449
450
255k
    for (j = 3; j < (len - 4); j++) {
451
553k
      for (i = 0; i < 3; i++) {
452
415k
        out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i] >> SR_FNA_OUT);
453
415k
        out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i] >> SR_FNA_OUT);
454
415k
      }
455
138k
      out[j] += (FIXP_DBL)fMultDiv2(coeff[3], in[j] >> SR_FNA_OUT);
456
457
138k
      j++;
458
459
553k
      for (i = 0; i < 3; i++) {
460
415k
        out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i] >> SR_FNA_OUT);
461
415k
        out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i] >> SR_FNA_OUT);
462
415k
      }
463
138k
      out[j] -= (FIXP_DBL)fMultDiv2(coeff[3], in[j] >> SR_FNA_OUT);
464
138k
    }
465
466
470k
    for (i = 0; i < 3; i++) {
467
352k
      out[len - 3] +=
468
352k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[i]] >> SR_FNA_OUT);
469
352k
      out[len - 3] +=
470
352k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[5 - i]] >> SR_FNA_OUT);
471
352k
    }
472
117k
    out[len - 3] += (FIXP_DBL)fMultDiv2(coeff[3], in[len - 3] >> SR_FNA_OUT);
473
474
470k
    for (i = 0; i < 3; i++) {
475
352k
      out[len - 2] -=
476
352k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[i]] >> SR_FNA_OUT);
477
352k
      out[len - 2] -=
478
352k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[5 - i]] >> SR_FNA_OUT);
479
352k
    }
480
117k
    out[len - 2] -= (FIXP_DBL)fMultDiv2(coeff[3], in[len - 2] >> SR_FNA_OUT);
481
482
470k
    for (i = 0; i < 3; i++) {
483
352k
      out[len - 1] +=
484
352k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[i]] >> SR_FNA_OUT);
485
352k
      out[len - 1] +=
486
352k
          (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[5 - i]] >> SR_FNA_OUT);
487
352k
    }
488
117k
    out[len - 1] += (FIXP_DBL)fMultDiv2(coeff[3], in[len - 1] >> SR_FNA_OUT);
489
117k
  }
490
262k
}
491
492
static inline void CJointStereo_GenerateMSOutput(FIXP_DBL *pSpecLCurrBand,
493
                                                 FIXP_DBL *pSpecRCurrBand,
494
                                                 UINT leftScale,
495
                                                 UINT rightScale,
496
124k
                                                 UINT nSfbBands) {
497
124k
  unsigned int i;
498
499
124k
  FIXP_DBL leftCoefficient0;
500
124k
  FIXP_DBL leftCoefficient1;
501
124k
  FIXP_DBL leftCoefficient2;
502
124k
  FIXP_DBL leftCoefficient3;
503
504
124k
  FIXP_DBL rightCoefficient0;
505
124k
  FIXP_DBL rightCoefficient1;
506
124k
  FIXP_DBL rightCoefficient2;
507
124k
  FIXP_DBL rightCoefficient3;
508
509
304k
  for (i = nSfbBands; i > 0; i -= 4) {
510
180k
    leftCoefficient0 = pSpecLCurrBand[i - 4];
511
180k
    leftCoefficient1 = pSpecLCurrBand[i - 3];
512
180k
    leftCoefficient2 = pSpecLCurrBand[i - 2];
513
180k
    leftCoefficient3 = pSpecLCurrBand[i - 1];
514
515
180k
    rightCoefficient0 = pSpecRCurrBand[i - 4];
516
180k
    rightCoefficient1 = pSpecRCurrBand[i - 3];
517
180k
    rightCoefficient2 = pSpecRCurrBand[i - 2];
518
180k
    rightCoefficient3 = pSpecRCurrBand[i - 1];
519
520
    /* MS output generation */
521
180k
    leftCoefficient0 >>= leftScale;
522
180k
    leftCoefficient1 >>= leftScale;
523
180k
    leftCoefficient2 >>= leftScale;
524
180k
    leftCoefficient3 >>= leftScale;
525
526
180k
    rightCoefficient0 >>= rightScale;
527
180k
    rightCoefficient1 >>= rightScale;
528
180k
    rightCoefficient2 >>= rightScale;
529
180k
    rightCoefficient3 >>= rightScale;
530
531
180k
    pSpecLCurrBand[i - 4] = leftCoefficient0 + rightCoefficient0;
532
180k
    pSpecLCurrBand[i - 3] = leftCoefficient1 + rightCoefficient1;
533
180k
    pSpecLCurrBand[i - 2] = leftCoefficient2 + rightCoefficient2;
534
180k
    pSpecLCurrBand[i - 1] = leftCoefficient3 + rightCoefficient3;
535
536
180k
    pSpecRCurrBand[i - 4] = leftCoefficient0 - rightCoefficient0;
537
180k
    pSpecRCurrBand[i - 3] = leftCoefficient1 - rightCoefficient1;
538
180k
    pSpecRCurrBand[i - 2] = leftCoefficient2 - rightCoefficient2;
539
180k
    pSpecRCurrBand[i - 1] = leftCoefficient3 - rightCoefficient3;
540
180k
  }
541
124k
}
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
141k
    SHORT *store_dmx_re_prev_e, const int mainband_flag) {
553
141k
  int window, group, band;
554
141k
  UCHAR groupMask;
555
141k
  CJointStereoData *pJointStereoData =
556
141k
      &pAacDecoderChannelInfo[L]->pComData->jointStereoData;
557
141k
  CCplxPredictionData *cplxPredictionData =
558
141k
      pAacDecoderChannelInfo[L]->pComStaticData->cplxPredictionData;
559
560
141k
  int max_sfb_ste =
561
141k
      fMax(scaleFactorBandsTransmittedL, scaleFactorBandsTransmittedR);
562
141k
  int min_sfb_ste =
563
141k
      fMin(scaleFactorBandsTransmittedL, scaleFactorBandsTransmittedR);
564
141k
  int scaleFactorBandsTransmitted = min_sfb_ste;
565
566
141k
  if (pJointStereoData->cplx_pred_flag) {
567
33.0k
    int windowLen, groupwin, frameMaxScale;
568
33.0k
    CJointStereoPersistentData *pJointStereoPersistentData =
569
33.0k
        &pAacDecoderStaticChannelInfo[L]
570
33.0k
             ->pCpeStaticData->jointStereoPersistentData;
571
33.0k
    FIXP_DBL *const staticSpectralCoeffsL =
572
33.0k
        pAacDecoderStaticChannelInfo[L]
573
33.0k
            ->pCpeStaticData->jointStereoPersistentData.spectralCoeffs[L];
574
33.0k
    FIXP_DBL *const staticSpectralCoeffsR =
575
33.0k
        pAacDecoderStaticChannelInfo[L]
576
33.0k
            ->pCpeStaticData->jointStereoPersistentData.spectralCoeffs[R];
577
33.0k
    SHORT *const staticSpecScaleL =
578
33.0k
        pAacDecoderStaticChannelInfo[L]
579
33.0k
            ->pCpeStaticData->jointStereoPersistentData.specScale[L];
580
33.0k
    SHORT *const staticSpecScaleR =
581
33.0k
        pAacDecoderStaticChannelInfo[L]
582
33.0k
            ->pCpeStaticData->jointStereoPersistentData.specScale[R];
583
584
33.0k
    FIXP_DBL *dmx_re =
585
33.0k
        pAacDecoderStaticChannelInfo[L]
586
33.0k
            ->pCpeStaticData->jointStereoPersistentData.scratchBuffer;
587
33.0k
    FIXP_DBL *dmx_re_prev =
588
33.0k
        pAacDecoderStaticChannelInfo[L]
589
33.0k
            ->pCpeStaticData->jointStereoPersistentData.scratchBuffer +
590
33.0k
        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
33.0k
    SHORT dmx_re_prev_e = *store_dmx_re_prev_e;
595
596
33.0k
    const FIXP_FILT *pCoeff;
597
33.0k
    const FIXP_FILT *pCoeffPrev;
598
33.0k
    int coeffPointerOffset;
599
600
33.0k
    int previousShape = (int)pJointStereoPersistentData->winShapePrev;
601
33.0k
    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
33.0k
    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
33.0k
    windowLen =
614
33.0k
        pAacDecoderChannelInfo[L]->granuleLength; /* framelength 768 => 96,
615
                                                     framelength 1024 => 128 */
616
617
    /* if this is no short-block set length for long-block */
618
33.0k
    if (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence != BLOCK_SHORT) {
619
15.6k
      windowLen *= 8;
620
15.6k
    }
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
33.0k
    pCoeffPrev = mdst_filt_coef_prev[previousShape];
628
629
33.0k
    if (cplxPredictionData->complex_coef == 1) {
630
27.8k
      switch (pAacDecoderChannelInfo[L]
631
27.8k
                  ->icsInfo.WindowSequence) { /* current window sequence */
632
16.6k
        case BLOCK_SHORT:
633
24.1k
        case BLOCK_LONG:
634
24.1k
          pCoeffPrev = mdst_filt_coef_prev[previousShape];
635
24.1k
          break;
636
637
2.91k
        case BLOCK_START:
638
2.91k
          if ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) ||
639
2.80k
              (pJointStereoPersistentData->winSeqPrev == BLOCK_START)) {
640
            /* a stop-start-sequence can only follow on an eight-short-sequence
641
             * or a start-sequence */
642
2.08k
            pCoeffPrev = mdst_filt_coef_prev[2 + previousShape];
643
2.08k
          } else {
644
823
            pCoeffPrev = mdst_filt_coef_prev[previousShape];
645
823
          }
646
2.91k
          break;
647
648
803
        case BLOCK_STOP:
649
803
          pCoeffPrev = mdst_filt_coef_prev[2 + previousShape];
650
803
          break;
651
652
0
        default:
653
0
          pCoeffPrev = mdst_filt_coef_prev[previousShape];
654
0
          break;
655
27.8k
      }
656
27.8k
    }
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
33.0k
    if ((previousShape == SHAPE_SINE) && (currentShape == SHAPE_SINE)) {
663
27.8k
      coeffPointerOffset = 0;
664
27.8k
    } else if ((previousShape == SHAPE_SINE) && (currentShape == SHAPE_KBD)) {
665
1.44k
      coeffPointerOffset = 2;
666
3.78k
    } else if ((previousShape == SHAPE_KBD) && (currentShape == SHAPE_KBD)) {
667
424
      coeffPointerOffset = 1;
668
424
    } else /* if ( (previousShape == SHAPE_KBD) && (currentShape == SHAPE_SINE)
669
              ) */
670
3.36k
    {
671
3.36k
      coeffPointerOffset = 3;
672
3.36k
    }
673
674
    /* set pointer to filter-coefficient table cp. ISO/IEC FDIS 23003-3:2011(E)
675
     * table 124 */
676
33.0k
    switch (pAacDecoderChannelInfo[L]
677
33.0k
                ->icsInfo.WindowSequence) { /* current window sequence */
678
17.3k
      case BLOCK_SHORT:
679
27.2k
      case BLOCK_LONG:
680
27.2k
        pCoeff = mdst_filt_coef_curr[coeffPointerOffset];
681
27.2k
        break;
682
683
5.01k
      case BLOCK_START:
684
5.01k
        if ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) ||
685
4.86k
            (pJointStereoPersistentData->winSeqPrev == BLOCK_START)) {
686
          /* a stop-start-sequence can only follow on an eight-short-sequence or
687
           * a start-sequence */
688
3.70k
          pCoeff = mdst_filt_coef_curr[12 + coeffPointerOffset];
689
3.70k
        } else {
690
1.30k
          pCoeff = mdst_filt_coef_curr[4 + coeffPointerOffset];
691
1.30k
        }
692
5.01k
        break;
693
694
826
      case BLOCK_STOP:
695
826
        pCoeff = mdst_filt_coef_curr[8 + coeffPointerOffset];
696
826
        break;
697
698
0
      default:
699
0
        pCoeff = mdst_filt_coef_curr[coeffPointerOffset];
700
33.0k
    }
701
702
    /* 0.4. find maximum common (l/r) band-scaling-factor for whole sequence
703
     * (all windows) */
704
33.0k
    frameMaxScale = 0;
705
166k
    for (window = 0, group = 0; group < windowGroups; group++) {
706
288k
      for (groupwin = 0; groupwin < pWindowGroupLength[group];
707
154k
           groupwin++, window++) {
708
154k
        SHORT *leftScale = &SFBleftScale[window * 16];
709
154k
        SHORT *rightScale = &SFBrightScale[window * 16];
710
154k
        int windowMaxScale = 0;
711
712
        /* find maximum scaling factor of all bands in this window */
713
171k
        for (band = 0; band < min_sfb_ste; band++) {
714
16.4k
          int lScale = leftScale[band];
715
16.4k
          int rScale = rightScale[band];
716
16.4k
          int commonScale = ((lScale > rScale) ? lScale : rScale);
717
16.4k
          windowMaxScale =
718
16.4k
              (windowMaxScale < commonScale) ? commonScale : windowMaxScale;
719
16.4k
        }
720
154k
        if (scaleFactorBandsTransmittedL >
721
154k
            min_sfb_ste) { /* i.e. scaleFactorBandsTransmittedL == max_sfb_ste
722
                            */
723
7.72k
          for (; band < max_sfb_ste; band++) {
724
6.80k
            int lScale = leftScale[band];
725
6.80k
            windowMaxScale =
726
6.80k
                (windowMaxScale < lScale) ? lScale : windowMaxScale;
727
6.80k
          }
728
153k
        } else {
729
153k
          if (scaleFactorBandsTransmittedR >
730
153k
              min_sfb_ste) { /* i.e. scaleFactorBandsTransmittedR == max_sfb_ste
731
                              */
732
127k
            for (; band < max_sfb_ste; band++) {
733
107k
              int rScale = rightScale[band];
734
107k
              windowMaxScale =
735
107k
                  (windowMaxScale < rScale) ? rScale : windowMaxScale;
736
107k
            }
737
20.1k
          }
738
153k
        }
739
740
        /* find maximum common SF of all windows */
741
154k
        frameMaxScale =
742
154k
            (frameMaxScale < windowMaxScale) ? windowMaxScale : frameMaxScale;
743
154k
      }
744
133k
    }
745
746
    /* add some headroom for overflow protection during filter and add operation
747
     */
748
33.0k
    frameMaxScale += 2;
749
750
    /* process on window-basis (i.e. iterate over all groups and corresponding
751
     * windows) */
752
166k
    for (window = 0, group = 0; group < windowGroups; group++) {
753
133k
      groupMask = 1 << group;
754
755
288k
      for (groupwin = 0; groupwin < pWindowGroupLength[group];
756
154k
           groupwin++, window++) {
757
        /* initialize the MDST with zeros */
758
154k
        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
154k
        if (cplxPredictionData->complex_coef == 1) {
763
144k
          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.18k
            if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence !=
771
5.18k
                 BLOCK_SHORT) ||
772
4.96k
                (window == 0)) {
773
836
              int index_offset = 0;
774
836
              int srLeftChan = 0;
775
836
              int srRightChan = 0;
776
836
              if (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
777
836
                  BLOCK_SHORT) {
778
                /* use the last window of the previous frame for MDCT
779
                 * calculation if this is a short-block. */
780
621
                index_offset = windowLen * 7;
781
621
                if (staticSpecScaleL[7] > staticSpecScaleR[7]) {
782
43
                  srRightChan = staticSpecScaleL[7] - staticSpecScaleR[7];
783
43
                  dmx_re_prev_e = staticSpecScaleL[7];
784
578
                } else {
785
578
                  srLeftChan = staticSpecScaleR[7] - staticSpecScaleL[7];
786
578
                  dmx_re_prev_e = staticSpecScaleR[7];
787
578
                }
788
621
              } else {
789
215
                if (staticSpecScaleL[0] > staticSpecScaleR[0]) {
790
29
                  srRightChan = staticSpecScaleL[0] - staticSpecScaleR[0];
791
29
                  dmx_re_prev_e = staticSpecScaleL[0];
792
186
                } else {
793
186
                  srLeftChan = staticSpecScaleR[0] - staticSpecScaleL[0];
794
186
                  dmx_re_prev_e = staticSpecScaleR[0];
795
186
                }
796
215
              }
797
798
              /* now scale channels and determine downmix MDCT of previous frame
799
               */
800
836
              if (pAacDecoderStaticChannelInfo[L]
801
836
                      ->pCpeStaticData->jointStereoPersistentData
802
836
                      .clearSpectralCoeffs == 1) {
803
0
                FDKmemclear(dmx_re_prev, windowLen * sizeof(FIXP_DBL));
804
0
                dmx_re_prev_e = 0;
805
836
              } else {
806
836
                if (cplxPredictionData->pred_dir == 0) {
807
147k
                  for (int i = 0; i < windowLen; i++) {
808
146k
                    dmx_re_prev[i] =
809
146k
                        ((staticSpectralCoeffsL[index_offset + i] >>
810
146k
                          fMin(DFRACT_BITS - 1, srLeftChan + 1)) +
811
146k
                         (staticSpectralCoeffsR[index_offset + i] >>
812
146k
                          fMin(DFRACT_BITS - 1, srRightChan + 1)));
813
146k
                  }
814
596
                } else {
815
95.4k
                  for (int i = 0; i < windowLen; i++) {
816
95.1k
                    dmx_re_prev[i] =
817
95.1k
                        ((staticSpectralCoeffsL[index_offset + i] >>
818
95.1k
                          fMin(DFRACT_BITS - 1, srLeftChan + 1)) -
819
95.1k
                         (staticSpectralCoeffsR[index_offset + i] >>
820
95.1k
                          fMin(DFRACT_BITS - 1, srRightChan + 1)));
821
95.1k
                  }
822
240
                }
823
836
              }
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
836
              FDKmemcpy(store_dmx_re_prev, &dmx_re_prev[0],
829
836
                        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
836
              *store_dmx_re_prev_e = dmx_re_prev_e;
834
835
836
            } /* if ( (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence !=
836
                 BLOCK_SHORT) || (window == 0) ) */
837
838
5.18k
          } /* if ( pJointStereoData->use_prev_frame == 1 ) */
839
840
144k
        } /* 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
154k
        SHORT *leftScale = &SFBleftScale[window * 16];
846
154k
        SHORT *rightScale = &SFBrightScale[window * 16];
847
848
154k
        specScaleL[window] = specScaleR[window] = frameMaxScale;
849
850
        /* adapt scaling-factors to previous frame */
851
154k
        if (cplxPredictionData->use_prev_frame == 1) {
852
5.18k
          if (window == 0) {
853
836
            if (dmx_re_prev_e < frameMaxScale) {
854
589
              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
589
              } else {
859
589
                scaleValues(
860
589
                    dmx_re_prev, windowLen,
861
589
                    -fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e)));
862
589
              }
863
589
            } else {
864
247
              if (mainband_flag == 0) {
865
0
                FDKmemcpy(dmx_re_prev, store_dmx_re_prev,
866
0
                          windowLen * sizeof(FIXP_DBL));
867
0
              }
868
247
              specScaleL[0] = dmx_re_prev_e;
869
247
              specScaleR[0] = dmx_re_prev_e;
870
247
            }
871
4.34k
          } else { /* window != 0 */
872
4.34k
            FDK_ASSERT(pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
873
4.34k
                       BLOCK_SHORT);
874
4.34k
            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.34k
            } else {
879
4.34k
              specScaleL[window] = specScaleL[window - 1];
880
4.34k
              specScaleR[window] = specScaleR[window - 1];
881
4.34k
            }
882
4.34k
          }
883
5.18k
        } /* if ( pJointStereoData->use_prev_frame == 1 ) */
884
885
        /* scaling factors of both channels ought to be equal now */
886
154k
        FDK_ASSERT(specScaleL[window] == specScaleR[window]);
887
888
        /* rescale signal and calculate downmix MDCT */
889
285k
        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
130k
          int lScale = leftScale[band];
893
130k
          int rScale = rightScale[band];
894
895
130k
          lScale = fMin(DFRACT_BITS - 1, specScaleL[window] - lScale);
896
130k
          rScale = fMin(DFRACT_BITS - 1,
897
130k
                        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
130k
          leftScale[band] = rightScale[band] = specScaleL[window];
906
907
130k
          for (int i = pScaleFactorBandOffsets[band];
908
1.43M
               i < pScaleFactorBandOffsets[band + 1]; i++) {
909
1.29M
            spectrumL[windowLen * window + i] >>= lScale;
910
1.29M
            spectrumR[windowLen * window + i] >>= rScale;
911
1.29M
          }
912
913
          /* now calculate downmix MDCT */
914
130k
          if (pJointStereoData->MsUsed[band] & groupMask) {
915
84.2k
            for (int i = pScaleFactorBandOffsets[band];
916
742k
                 i < pScaleFactorBandOffsets[band + 1]; i++) {
917
657k
              dmx_re[windowLen * window + i] =
918
657k
                  spectrumL[windowLen * window + i];
919
657k
            }
920
84.2k
          } else {
921
46.1k
            if (cplxPredictionData->pred_dir == 0) {
922
21.4k
              for (int i = pScaleFactorBandOffsets[band];
923
428k
                   i < pScaleFactorBandOffsets[band + 1]; i++) {
924
407k
                dmx_re[windowLen * window + i] =
925
407k
                    (spectrumL[windowLen * window + i] +
926
407k
                     spectrumR[windowLen * window + i]) >>
927
407k
                    1;
928
407k
              }
929
24.7k
            } else {
930
24.7k
              for (int i = pScaleFactorBandOffsets[band];
931
259k
                   i < pScaleFactorBandOffsets[band + 1]; i++) {
932
234k
                dmx_re[windowLen * window + i] =
933
234k
                    (spectrumL[windowLen * window + i] -
934
234k
                     spectrumR[windowLen * window + i]) >>
935
234k
                    1;
936
234k
              }
937
24.7k
            }
938
46.1k
          }
939
940
130k
        } /* for ( band=0; band<max_sfb_ste; band++ ) */
941
        /* Clean until the end */
942
154k
        for (int i = pScaleFactorBandOffsets[max_sfb_ste_outside];
943
24.6M
             i < windowLen; i++) {
944
24.5M
          dmx_re[windowLen * window + i] = (FIXP_DBL)0;
945
24.5M
        }
946
947
        /* 3. calculate MDST-portion corresponding to the current frame. */
948
154k
        if (cplxPredictionData->complex_coef == 1) {
949
144k
          {
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
144k
            if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
955
144k
                 BLOCK_SHORT) &&
956
133k
                (window != 0)) {
957
116k
              pCoeff = mdst_filt_coef_curr[currentShape];
958
116k
              pCoeffPrev = mdst_filt_coef_prev[currentShape];
959
116k
            }
960
961
            /* The length of the filter processing must be extended because of
962
             * filter boundary problems */
963
144k
            int extended_band = fMin(
964
144k
                pScaleFactorBandOffsets[max_sfb_ste_outside] + 7, windowLen);
965
966
            /* 3.2. estimate downmix MDST from current frame downmix MDCT */
967
144k
            if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
968
144k
                 BLOCK_SHORT) &&
969
133k
                (window != 0)) {
970
116k
              CJointStereo_filterAndAdd(&dmx_re[windowLen * window],
971
116k
                                        extended_band, windowLen, pCoeff,
972
116k
                                        &dmx_im[windowLen * window], 1);
973
974
116k
              CJointStereo_filterAndAdd(&dmx_re[windowLen * (window - 1)],
975
116k
                                        extended_band, windowLen, pCoeffPrev,
976
116k
                                        &dmx_im[windowLen * window], 0);
977
116k
            } else {
978
27.8k
              CJointStereo_filterAndAdd(dmx_re, extended_band, windowLen,
979
27.8k
                                        pCoeff, dmx_im, 1);
980
981
27.8k
              if (cplxPredictionData->use_prev_frame == 1) {
982
836
                CJointStereo_filterAndAdd(dmx_re_prev, extended_band, windowLen,
983
836
                                          pCoeffPrev,
984
836
                                          &dmx_im[windowLen * window], 0);
985
836
              }
986
27.8k
            }
987
988
144k
          } /* if(pAacDecoderChannelInfo[L]->transform_splitting_active) */
989
144k
        }   /* if ( pJointStereoData->complex_coef == 1 ) */
990
991
        /* 4. upmix process */
992
154k
        LONG pred_dir = cplxPredictionData->pred_dir ? -1 : 1;
993
        /* 0.1 in Q-3.34 */
994
154k
        const FIXP_DBL pointOne = 0x66666666; /* 0.8 */
995
        /* Shift value for the downmix */
996
154k
        const INT shift_dmx = SF_FNA_COEFFS + 1;
997
998
285k
        for (band = 0; band < max_sfb_ste_outside; band++) {
999
130k
          if (pJointStereoData->MsUsed[band] & groupMask) {
1000
84.2k
            FIXP_SGL tempRe =
1001
84.2k
                (FIXP_SGL)cplxPredictionData->alpha_q_re[group][band];
1002
84.2k
            FIXP_SGL tempIm =
1003
84.2k
                (FIXP_SGL)cplxPredictionData->alpha_q_im[group][band];
1004
1005
            /* Find the minimum common headroom for alpha_re and alpha_im */
1006
84.2k
            int alpha_re_headroom = CountLeadingBits((INT)tempRe) - 16;
1007
84.2k
            if (tempRe == (FIXP_SGL)0) alpha_re_headroom = 15;
1008
84.2k
            int alpha_im_headroom = CountLeadingBits((INT)tempIm) - 16;
1009
84.2k
            if (tempIm == (FIXP_SGL)0) alpha_im_headroom = 15;
1010
84.2k
            int val = fMin(alpha_re_headroom, alpha_im_headroom);
1011
1012
            /* Multiply alpha by 0.1 with maximum precision */
1013
84.2k
            FDK_ASSERT(val >= 0);
1014
84.2k
            FIXP_DBL alpha_re_tmp = fMult((FIXP_SGL)(tempRe << val), pointOne);
1015
84.2k
            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
84.2k
            int alpha_re_exp = -3 + 15 - val;
1020
1021
84.2k
            int help3_shift = alpha_re_exp + 1;
1022
1023
84.2k
            FIXP_DBL *p2CoeffL = &(
1024
84.2k
                spectrumL[windowLen * window + pScaleFactorBandOffsets[band]]);
1025
84.2k
            FIXP_DBL *p2CoeffR = &(
1026
84.2k
                spectrumR[windowLen * window + pScaleFactorBandOffsets[band]]);
1027
84.2k
            FIXP_DBL *p2dmxIm =
1028
84.2k
                &(dmx_im[windowLen * window + pScaleFactorBandOffsets[band]]);
1029
84.2k
            FIXP_DBL *p2dmxRe =
1030
84.2k
                &(dmx_re[windowLen * window + pScaleFactorBandOffsets[band]]);
1031
1032
84.2k
            for (int i = pScaleFactorBandOffsets[band];
1033
742k
                 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
657k
              FIXP_DBL side, left, right;
1047
1048
657k
              side = fMultAddDiv2(fMultDiv2(alpha_re_tmp, *p2dmxRe++),
1049
657k
                                  alpha_im_tmp, (*p2dmxIm++) << shift_dmx);
1050
657k
              side = ((*p2CoeffR) >> 2) -
1051
657k
                     (FIXP_DBL)SATURATE_SHIFT(side, -(help3_shift - 2),
1052
657k
                                              DFRACT_BITS - 2);
1053
1054
657k
              left = ((*p2CoeffL) >> 2) + side;
1055
657k
              right = ((*p2CoeffL) >> 2) - side;
1056
657k
              right = (FIXP_DBL)((LONG)right * pred_dir);
1057
1058
657k
              *p2CoeffL++ = SATURATE_LEFT_SHIFT_ALT(left, 2, DFRACT_BITS);
1059
657k
              *p2CoeffR++ = SATURATE_LEFT_SHIFT_ALT(right, 2, DFRACT_BITS);
1060
657k
            }
1061
84.2k
          }
1062
1063
130k
        } /* for ( band=0; band < max_sfb_ste; band++ ) */
1064
154k
      }   /* for ( groupwin=0; groupwin<pWindowGroupLength[group]; groupwin++,
1065
             window++ ) */
1066
1067
133k
    } /* for ( window = 0, group = 0; group < windowGroups; group++ ) */
1068
1069
    /* free scratch buffer */
1070
33.0k
    C_AALLOC_SCRATCH_END(dmx_im, FIXP_DBL, 1024);
1071
1072
108k
  } else {
1073
    /* MS stereo */
1074
1075
330k
    for (window = 0, group = 0; group < windowGroups; group++) {
1076
221k
      groupMask = 1 << group;
1077
1078
510k
      for (int groupwin = 0; groupwin < pWindowGroupLength[group];
1079
288k
           groupwin++, window++) {
1080
288k
        FIXP_DBL *leftSpectrum, *rightSpectrum;
1081
288k
        SHORT *leftScale = &SFBleftScale[window * 16];
1082
288k
        SHORT *rightScale = &SFBrightScale[window * 16];
1083
1084
288k
        leftSpectrum =
1085
288k
            SPEC(spectrumL, window, pAacDecoderChannelInfo[L]->granuleLength);
1086
288k
        rightSpectrum =
1087
288k
            SPEC(spectrumR, window, pAacDecoderChannelInfo[R]->granuleLength);
1088
1089
786k
        for (band = 0; band < max_sfb_ste_outside; band++) {
1090
497k
          if (pJointStereoData->MsUsed[band] & groupMask) {
1091
124k
            int lScale = leftScale[band];
1092
124k
            int rScale = rightScale[band];
1093
124k
            int commonScale = lScale > rScale ? lScale : rScale;
1094
124k
            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
124k
            FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) ==
1100
124k
                       GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo));
1101
124k
            FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) ==
1102
124k
                       GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo));
1103
1104
124k
            commonScale++;
1105
124k
            leftScale[band] = commonScale;
1106
124k
            rightScale[band] = commonScale;
1107
1108
124k
            lScale = fMin(DFRACT_BITS - 1, commonScale - lScale);
1109
124k
            rScale = fMin(DFRACT_BITS - 1, commonScale - rScale);
1110
1111
124k
            FDK_ASSERT(lScale >= 0 && rScale >= 0);
1112
1113
124k
            offsetCurrBand = pScaleFactorBandOffsets[band];
1114
124k
            offsetNextBand = pScaleFactorBandOffsets[band + 1];
1115
1116
124k
            CJointStereo_GenerateMSOutput(&(leftSpectrum[offsetCurrBand]),
1117
124k
                                          &(rightSpectrum[offsetCurrBand]),
1118
124k
                                          lScale, rScale,
1119
124k
                                          offsetNextBand - offsetCurrBand);
1120
124k
          }
1121
497k
        }
1122
288k
        if (scaleFactorBandsTransmittedL > scaleFactorBandsTransmitted) {
1123
802
          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
288k
        } else if (scaleFactorBandsTransmittedR > scaleFactorBandsTransmitted) {
1136
2.77k
          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.77k
        }
1151
288k
      }
1152
221k
    }
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
108k
    if (pJointStereoData->MsMaskPresent == 2) {
1158
25.2k
      FDKmemclear(pJointStereoData->MsUsed,
1159
25.2k
                  JointStereoMaximumBands * sizeof(UCHAR));
1160
25.2k
    }
1161
108k
  }
1162
141k
}
1163
1164
void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
1165
                          const SHORT *pScaleFactorBandOffsets,
1166
                          const UCHAR *pWindowGroupLength,
1167
                          const int windowGroups,
1168
100k
                          const int scaleFactorBandsTransmitted) {
1169
100k
  CJointStereoData *pJointStereoData =
1170
100k
      &pAacDecoderChannelInfo[L]->pComData->jointStereoData;
1171
1172
303k
  for (int window = 0, group = 0; group < windowGroups; group++) {
1173
203k
    UCHAR *CodeBook;
1174
203k
    SHORT *ScaleFactor;
1175
203k
    UCHAR groupMask = 1 << group;
1176
1177
203k
    CodeBook = &pAacDecoderChannelInfo[R]->pDynData->aCodeBook[group * 16];
1178
203k
    ScaleFactor =
1179
203k
        &pAacDecoderChannelInfo[R]->pDynData->aScaleFactor[group * 16];
1180
1181
470k
    for (int groupwin = 0; groupwin < pWindowGroupLength[group];
1182
267k
         groupwin++, window++) {
1183
267k
      FIXP_DBL *leftSpectrum, *rightSpectrum;
1184
267k
      SHORT *leftScale =
1185
267k
          &pAacDecoderChannelInfo[L]->pDynData->aSfbScale[window * 16];
1186
267k
      SHORT *rightScale =
1187
267k
          &pAacDecoderChannelInfo[R]->pDynData->aSfbScale[window * 16];
1188
267k
      int band;
1189
1190
267k
      leftSpectrum = SPEC(pAacDecoderChannelInfo[L]->pSpectralCoefficient,
1191
267k
                          window, pAacDecoderChannelInfo[L]->granuleLength);
1192
267k
      rightSpectrum = SPEC(pAacDecoderChannelInfo[R]->pSpectralCoefficient,
1193
267k
                           window, pAacDecoderChannelInfo[R]->granuleLength);
1194
1195
718k
      for (band = 0; band < scaleFactorBandsTransmitted; band++) {
1196
450k
        if ((CodeBook[band] == INTENSITY_HCB) ||
1197
419k
            (CodeBook[band] == INTENSITY_HCB2)) {
1198
63.1k
          int bandScale = -(ScaleFactor[band] + 100);
1199
1200
63.1k
          int msb = bandScale >> 2;
1201
63.1k
          int lsb = bandScale & 0x03;
1202
1203
          /* exponent of MantissaTable[lsb][0] is 1, thus msb+1 below. */
1204
63.1k
          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
63.1k
          FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) ==
1212
63.1k
                     GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo));
1213
63.1k
          FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) ==
1214
63.1k
                     GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo));
1215
1216
63.1k
          rightScale[band] = leftScale[band] + msb + 1;
1217
1218
63.1k
          if (pJointStereoData->MsUsed[band] & groupMask) {
1219
20.3k
            if (CodeBook[band] == INTENSITY_HCB) /* _NOT_ in-phase */
1220
6.86k
            {
1221
6.86k
              scale = -scale;
1222
6.86k
            }
1223
42.8k
          } else {
1224
42.8k
            if (CodeBook[band] == INTENSITY_HCB2) /* out-of-phase */
1225
18.0k
            {
1226
18.0k
              scale = -scale;
1227
18.0k
            }
1228
42.8k
          }
1229
1230
63.1k
          for (int index = pScaleFactorBandOffsets[band];
1231
377k
               index < pScaleFactorBandOffsets[band + 1]; index++) {
1232
314k
            rightSpectrum[index] = fMult(leftSpectrum[index], scale);
1233
314k
          }
1234
63.1k
        }
1235
450k
      }
1236
267k
    }
1237
203k
  }
1238
100k
}