Coverage Report

Created: 2026-05-30 06:09

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