• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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                           fMin(DFRACT_BITS - 1, srLeftChan + 1)) +
811                          (staticSpectralCoeffsR[index_offset + i] >>
812                           fMin(DFRACT_BITS - 1, srRightChan + 1)));
813                   }
814                 } else {
815                   for (int i = 0; i < windowLen; i++) {
816                     dmx_re_prev[i] =
817                         ((staticSpectralCoeffsL[index_offset + i] >>
818                           fMin(DFRACT_BITS - 1, srLeftChan + 1)) -
819                          (staticSpectralCoeffsR[index_offset + i] >>
820                           fMin(DFRACT_BITS - 1, srRightChan + 1)));
821                   }
822                 }
823               }
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               FDKmemcpy(store_dmx_re_prev, &dmx_re_prev[0],
829                         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               *store_dmx_re_prev_e = dmx_re_prev_e;
834 
835             } /* if ( (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence !=
836                  BLOCK_SHORT) || (window == 0) ) */
837 
838           } /* if ( pJointStereoData->use_prev_frame == 1 ) */
839 
840         } /* 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         SHORT *leftScale = &SFBleftScale[window * 16];
846         SHORT *rightScale = &SFBrightScale[window * 16];
847 
848         specScaleL[window] = specScaleR[window] = frameMaxScale;
849 
850         /* adapt scaling-factors to previous frame */
851         if (cplxPredictionData->use_prev_frame == 1) {
852           if (window == 0) {
853             if (dmx_re_prev_e < frameMaxScale) {
854               if (mainband_flag == 0) {
855                 scaleValues(
856                     dmx_re_prev, store_dmx_re_prev, windowLen,
857                     -fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e)));
858               } else {
859                 scaleValues(
860                     dmx_re_prev, windowLen,
861                     -fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e)));
862               }
863             } else {
864               if (mainband_flag == 0) {
865                 FDKmemcpy(dmx_re_prev, store_dmx_re_prev,
866                           windowLen * sizeof(FIXP_DBL));
867               }
868               specScaleL[0] = dmx_re_prev_e;
869               specScaleR[0] = dmx_re_prev_e;
870             }
871           } else { /* window != 0 */
872             FDK_ASSERT(pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
873                        BLOCK_SHORT);
874             if (specScaleL[window - 1] < frameMaxScale) {
875               scaleValues(&dmx_re[windowLen * (window - 1)], windowLen,
876                           -fMin(DFRACT_BITS - 1,
877                                 (frameMaxScale - specScaleL[window - 1])));
878             } else {
879               specScaleL[window] = specScaleL[window - 1];
880               specScaleR[window] = specScaleR[window - 1];
881             }
882           }
883         } /* if ( pJointStereoData->use_prev_frame == 1 ) */
884 
885         /* scaling factors of both channels ought to be equal now */
886         FDK_ASSERT(specScaleL[window] == specScaleR[window]);
887 
888         /* rescale signal and calculate downmix MDCT */
889         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           int lScale = leftScale[band];
893           int rScale = rightScale[band];
894 
895           lScale = fMin(DFRACT_BITS - 1, specScaleL[window] - lScale);
896           rScale = fMin(DFRACT_BITS - 1,
897                         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           leftScale[band] = rightScale[band] = specScaleL[window];
906 
907           for (int i = pScaleFactorBandOffsets[band];
908                i < pScaleFactorBandOffsets[band + 1]; i++) {
909             spectrumL[windowLen * window + i] >>= lScale;
910             spectrumR[windowLen * window + i] >>= rScale;
911           }
912 
913           /* now calculate downmix MDCT */
914           if (pJointStereoData->MsUsed[band] & groupMask) {
915             for (int i = pScaleFactorBandOffsets[band];
916                  i < pScaleFactorBandOffsets[band + 1]; i++) {
917               dmx_re[windowLen * window + i] =
918                   spectrumL[windowLen * window + i];
919             }
920           } else {
921             if (cplxPredictionData->pred_dir == 0) {
922               for (int i = pScaleFactorBandOffsets[band];
923                    i < pScaleFactorBandOffsets[band + 1]; i++) {
924                 dmx_re[windowLen * window + i] =
925                     (spectrumL[windowLen * window + i] +
926                      spectrumR[windowLen * window + i]) >>
927                     1;
928               }
929             } else {
930               for (int i = pScaleFactorBandOffsets[band];
931                    i < pScaleFactorBandOffsets[band + 1]; i++) {
932                 dmx_re[windowLen * window + i] =
933                     (spectrumL[windowLen * window + i] -
934                      spectrumR[windowLen * window + i]) >>
935                     1;
936               }
937             }
938           }
939 
940         } /* for ( band=0; band<max_sfb_ste; band++ ) */
941         /* Clean until the end */
942         for (int i = pScaleFactorBandOffsets[max_sfb_ste_outside];
943              i < windowLen; i++) {
944           dmx_re[windowLen * window + i] = (FIXP_DBL)0;
945         }
946 
947         /* 3. calculate MDST-portion corresponding to the current frame. */
948         if (cplxPredictionData->complex_coef == 1) {
949           {
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             if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
955                  BLOCK_SHORT) &&
956                 (window != 0)) {
957               pCoeff = mdst_filt_coef_curr[currentShape];
958               pCoeffPrev = mdst_filt_coef_prev[currentShape];
959             }
960 
961             /* The length of the filter processing must be extended because of
962              * filter boundary problems */
963             int extended_band = fMin(
964                 pScaleFactorBandOffsets[max_sfb_ste_outside] + 7, windowLen);
965 
966             /* 3.2. estimate downmix MDST from current frame downmix MDCT */
967             if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
968                  BLOCK_SHORT) &&
969                 (window != 0)) {
970               CJointStereo_filterAndAdd(&dmx_re[windowLen * window],
971                                         extended_band, windowLen, pCoeff,
972                                         &dmx_im[windowLen * window], 1);
973 
974               CJointStereo_filterAndAdd(&dmx_re[windowLen * (window - 1)],
975                                         extended_band, windowLen, pCoeffPrev,
976                                         &dmx_im[windowLen * window], 0);
977             } else {
978               CJointStereo_filterAndAdd(dmx_re, extended_band, windowLen,
979                                         pCoeff, dmx_im, 1);
980 
981               if (cplxPredictionData->use_prev_frame == 1) {
982                 CJointStereo_filterAndAdd(dmx_re_prev, extended_band, windowLen,
983                                           pCoeffPrev,
984                                           &dmx_im[windowLen * window], 0);
985               }
986             }
987 
988           } /* if(pAacDecoderChannelInfo[L]->transform_splitting_active) */
989         }   /* if ( pJointStereoData->complex_coef == 1 ) */
990 
991         /* 4. upmix process */
992         LONG pred_dir = cplxPredictionData->pred_dir ? -1 : 1;
993         /* 0.1 in Q-3.34 */
994         const FIXP_DBL pointOne = 0x66666666; /* 0.8 */
995         /* Shift value for the downmix */
996         const INT shift_dmx = SF_FNA_COEFFS + 1;
997 
998         for (band = 0; band < max_sfb_ste_outside; band++) {
999           if (pJointStereoData->MsUsed[band] & groupMask) {
1000             FIXP_SGL tempRe =
1001                 (FIXP_SGL)cplxPredictionData->alpha_q_re[group][band];
1002             FIXP_SGL tempIm =
1003                 (FIXP_SGL)cplxPredictionData->alpha_q_im[group][band];
1004 
1005             /* Find the minimum common headroom for alpha_re and alpha_im */
1006             int alpha_re_headroom = CountLeadingBits((INT)tempRe) - 16;
1007             if (tempRe == (FIXP_SGL)0) alpha_re_headroom = 15;
1008             int alpha_im_headroom = CountLeadingBits((INT)tempIm) - 16;
1009             if (tempIm == (FIXP_SGL)0) alpha_im_headroom = 15;
1010             int val = fMin(alpha_re_headroom, alpha_im_headroom);
1011 
1012             /* Multiply alpha by 0.1 with maximum precision */
1013             FDK_ASSERT(val >= 0);
1014             FIXP_DBL alpha_re_tmp = fMult((FIXP_SGL)(tempRe << val), pointOne);
1015             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             int alpha_re_exp = -3 + 15 - val;
1020 
1021             int help3_shift = alpha_re_exp + 1;
1022 
1023             FIXP_DBL *p2CoeffL = &(
1024                 spectrumL[windowLen * window + pScaleFactorBandOffsets[band]]);
1025             FIXP_DBL *p2CoeffR = &(
1026                 spectrumR[windowLen * window + pScaleFactorBandOffsets[band]]);
1027             FIXP_DBL *p2dmxIm =
1028                 &(dmx_im[windowLen * window + pScaleFactorBandOffsets[band]]);
1029             FIXP_DBL *p2dmxRe =
1030                 &(dmx_re[windowLen * window + pScaleFactorBandOffsets[band]]);
1031 
1032             for (int i = pScaleFactorBandOffsets[band];
1033                  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               FIXP_DBL side, left, right;
1047 
1048               side = fMultAddDiv2(fMultDiv2(alpha_re_tmp, *p2dmxRe++),
1049                                   alpha_im_tmp, (*p2dmxIm++) << shift_dmx);
1050               side = ((*p2CoeffR) >> 2) -
1051                      (FIXP_DBL)SATURATE_SHIFT(side, -(help3_shift - 2),
1052                                               DFRACT_BITS - 2);
1053 
1054               left = ((*p2CoeffL) >> 2) + side;
1055               right = ((*p2CoeffL) >> 2) - side;
1056               right = (FIXP_DBL)((LONG)right * pred_dir);
1057 
1058               *p2CoeffL++ = SATURATE_LEFT_SHIFT_ALT(left, 2, DFRACT_BITS);
1059               *p2CoeffR++ = SATURATE_LEFT_SHIFT_ALT(right, 2, DFRACT_BITS);
1060             }
1061           }
1062 
1063         } /* for ( band=0; band < max_sfb_ste; band++ ) */
1064       }   /* for ( groupwin=0; groupwin<pWindowGroupLength[group]; groupwin++,
1065              window++ ) */
1066 
1067     } /* for ( window = 0, group = 0; group < windowGroups; group++ ) */
1068 
1069     /* free scratch buffer */
1070     C_AALLOC_SCRATCH_END(dmx_im, FIXP_DBL, 1024);
1071 
1072   } else {
1073     /* MS stereo */
1074 
1075     for (window = 0, group = 0; group < windowGroups; group++) {
1076       groupMask = 1 << group;
1077 
1078       for (int groupwin = 0; groupwin < pWindowGroupLength[group];
1079            groupwin++, window++) {
1080         FIXP_DBL *leftSpectrum, *rightSpectrum;
1081         SHORT *leftScale = &SFBleftScale[window * 16];
1082         SHORT *rightScale = &SFBrightScale[window * 16];
1083 
1084         leftSpectrum =
1085             SPEC(spectrumL, window, pAacDecoderChannelInfo[L]->granuleLength);
1086         rightSpectrum =
1087             SPEC(spectrumR, window, pAacDecoderChannelInfo[R]->granuleLength);
1088 
1089         for (band = 0; band < max_sfb_ste_outside; band++) {
1090           if (pJointStereoData->MsUsed[band] & groupMask) {
1091             int lScale = leftScale[band];
1092             int rScale = rightScale[band];
1093             int commonScale = lScale > rScale ? lScale : rScale;
1094             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             FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) ==
1100                        GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo));
1101             FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) ==
1102                        GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo));
1103 
1104             commonScale++;
1105             leftScale[band] = commonScale;
1106             rightScale[band] = commonScale;
1107 
1108             lScale = fMin(DFRACT_BITS - 1, commonScale - lScale);
1109             rScale = fMin(DFRACT_BITS - 1, commonScale - rScale);
1110 
1111             FDK_ASSERT(lScale >= 0 && rScale >= 0);
1112 
1113             offsetCurrBand = pScaleFactorBandOffsets[band];
1114             offsetNextBand = pScaleFactorBandOffsets[band + 1];
1115 
1116             CJointStereo_GenerateMSOutput(&(leftSpectrum[offsetCurrBand]),
1117                                           &(rightSpectrum[offsetCurrBand]),
1118                                           lScale, rScale,
1119                                           offsetNextBand - offsetCurrBand);
1120           }
1121         }
1122         if (scaleFactorBandsTransmittedL > scaleFactorBandsTransmitted) {
1123           for (; band < scaleFactorBandsTransmittedL; band++) {
1124             if (pJointStereoData->MsUsed[band] & groupMask) {
1125               rightScale[band] = leftScale[band];
1126 
1127               for (int index = pScaleFactorBandOffsets[band];
1128                    index < pScaleFactorBandOffsets[band + 1]; index++) {
1129                 FIXP_DBL leftCoefficient = leftSpectrum[index];
1130                 /* FIXP_DBL rightCoefficient = (FIXP_DBL)0; */
1131                 rightSpectrum[index] = leftCoefficient;
1132               }
1133             }
1134           }
1135         } else if (scaleFactorBandsTransmittedR > scaleFactorBandsTransmitted) {
1136           for (; band < scaleFactorBandsTransmittedR; band++) {
1137             if (pJointStereoData->MsUsed[band] & groupMask) {
1138               leftScale[band] = rightScale[band];
1139 
1140               for (int index = pScaleFactorBandOffsets[band];
1141                    index < pScaleFactorBandOffsets[band + 1]; index++) {
1142                 /* FIXP_DBL leftCoefficient  = (FIXP_DBL)0; */
1143                 FIXP_DBL rightCoefficient = rightSpectrum[index];
1144 
1145                 leftSpectrum[index] = rightCoefficient;
1146                 rightSpectrum[index] = -rightCoefficient;
1147               }
1148             }
1149           }
1150         }
1151       }
1152     }
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     if (pJointStereoData->MsMaskPresent == 2) {
1158       FDKmemclear(pJointStereoData->MsUsed,
1159                   JointStereoMaximumBands * sizeof(UCHAR));
1160     }
1161   }
1162 }
1163 
CJointStereo_ApplyIS(CAacDecoderChannelInfo * pAacDecoderChannelInfo[2],const SHORT * pScaleFactorBandOffsets,const UCHAR * pWindowGroupLength,const int windowGroups,const int scaleFactorBandsTransmitted)1164 void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
1165                           const SHORT *pScaleFactorBandOffsets,
1166                           const UCHAR *pWindowGroupLength,
1167                           const int windowGroups,
1168                           const int scaleFactorBandsTransmitted) {
1169   CJointStereoData *pJointStereoData =
1170       &pAacDecoderChannelInfo[L]->pComData->jointStereoData;
1171 
1172   for (int window = 0, group = 0; group < windowGroups; group++) {
1173     UCHAR *CodeBook;
1174     SHORT *ScaleFactor;
1175     UCHAR groupMask = 1 << group;
1176 
1177     CodeBook = &pAacDecoderChannelInfo[R]->pDynData->aCodeBook[group * 16];
1178     ScaleFactor =
1179         &pAacDecoderChannelInfo[R]->pDynData->aScaleFactor[group * 16];
1180 
1181     for (int groupwin = 0; groupwin < pWindowGroupLength[group];
1182          groupwin++, window++) {
1183       FIXP_DBL *leftSpectrum, *rightSpectrum;
1184       SHORT *leftScale =
1185           &pAacDecoderChannelInfo[L]->pDynData->aSfbScale[window * 16];
1186       SHORT *rightScale =
1187           &pAacDecoderChannelInfo[R]->pDynData->aSfbScale[window * 16];
1188       int band;
1189 
1190       leftSpectrum = SPEC(pAacDecoderChannelInfo[L]->pSpectralCoefficient,
1191                           window, pAacDecoderChannelInfo[L]->granuleLength);
1192       rightSpectrum = SPEC(pAacDecoderChannelInfo[R]->pSpectralCoefficient,
1193                            window, pAacDecoderChannelInfo[R]->granuleLength);
1194 
1195       for (band = 0; band < scaleFactorBandsTransmitted; band++) {
1196         if ((CodeBook[band] == INTENSITY_HCB) ||
1197             (CodeBook[band] == INTENSITY_HCB2)) {
1198           int bandScale = -(ScaleFactor[band] + 100);
1199 
1200           int msb = bandScale >> 2;
1201           int lsb = bandScale & 0x03;
1202 
1203           /* exponent of MantissaTable[lsb][0] is 1, thus msb+1 below. */
1204           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           FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) ==
1212                      GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo));
1213           FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) ==
1214                      GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo));
1215 
1216           rightScale[band] = leftScale[band] + msb + 1;
1217 
1218           if (pJointStereoData->MsUsed[band] & groupMask) {
1219             if (CodeBook[band] == INTENSITY_HCB) /* _NOT_ in-phase */
1220             {
1221               scale = -scale;
1222             }
1223           } else {
1224             if (CodeBook[band] == INTENSITY_HCB2) /* out-of-phase */
1225             {
1226               scale = -scale;
1227             }
1228           }
1229 
1230           for (int index = pScaleFactorBandOffsets[band];
1231                index < pScaleFactorBandOffsets[band + 1]; index++) {
1232             rightSpectrum[index] = fMult(leftSpectrum[index], scale);
1233           }
1234         }
1235       }
1236     }
1237   }
1238 }
1239