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