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