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