Coverage Report

Created: 2026-09-04 07:02

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