2
0

stproc.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Source last modified: $Id: stproc.c,v 1.3 2005/05/24 16:01:55 albertofloyd Exp $
  3. *
  4. * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.
  5. *
  6. * The contents of this file, and the files included with this file,
  7. * are subject to the current version of the RealNetworks Public
  8. * Source License (the "RPSL") available at
  9. * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10. * the file under the current version of the RealNetworks Community
  11. * Source License (the "RCSL") available at
  12. * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13. * will apply. You may also obtain the license terms directly from
  14. * RealNetworks. You may not use this file except in compliance with
  15. * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16. * to this file, the RCSL. Please see the applicable RPSL or RCSL for
  17. * the rights, obligations and limitations governing use of the
  18. * contents of the file.
  19. *
  20. * This file is part of the Helix DNA Technology. RealNetworks is the
  21. * developer of the Original Code and owns the copyrights in the
  22. * portions it created.
  23. *
  24. * This file, and the files included with this file, is distributed
  25. * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  26. * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  27. * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  28. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  29. * ENJOYMENT OR NON-INFRINGEMENT.
  30. *
  31. * Technology Compatibility Kit Test Suite(s) Location:
  32. * http://www.helixcommunity.org/content/tck
  33. *
  34. * Contributor(s):
  35. *
  36. * ***** END LICENSE BLOCK ***** */
  37. /**************************************************************************************
  38. * Fixed-point HE-AAC decoder
  39. * Jon Recker (jrecker@real.com)
  40. * February 2005
  41. *
  42. * stproc.c - mid-side and intensity stereo processing
  43. **************************************************************************************/
  44. #include "coder.h"
  45. #include "assembly.h"
  46. /* pow14[0][i] = -pow(2, i/4.0)
  47. * pow14[1][i] = +pow(2, i/4.0)
  48. *
  49. * i = [0,1,2,3]
  50. * format = Q30
  51. */
  52. /**************************************************************************************
  53. * Function: StereoProcessGroup
  54. *
  55. * Description: apply mid-side and intensity stereo to group of transform coefficients
  56. *
  57. * Inputs: dequantized transform coefficients for both channels
  58. * pointer to appropriate scalefactor band table
  59. * mid-side mask enabled flag
  60. * buffer with mid-side mask (one bit for each scalefactor band)
  61. * bit offset into mid-side mask buffer
  62. * max coded scalefactor band
  63. * buffer of codebook indices for right channel
  64. * buffer of scalefactors for right channel, range = [0, 256]
  65. *
  66. * Outputs: updated transform coefficients in Q(FBITS_OUT_DQ_OFF)
  67. * updated minimum guard bit count for both channels
  68. *
  69. * Return: none
  70. *
  71. * Notes: assume no guard bits in input
  72. * gains 0 int bits
  73. **************************************************************************************/
  74. static void StereoProcessGroup(int *coefL, int *coefR, const /*short*/ int *sfbTab,
  75. int msMaskPres, unsigned char *msMaskPtr, int msMaskOffset, int maxSFB,
  76. unsigned char *cbRight, short *sfRight, int *gbCurrent)
  77. {
  78. //fb
  79. #pragma GCC diagnostic push
  80. #pragma GCC diagnostic ignored "-Wnarrowing"
  81. static const int pow14[2][4] PROGMEM = {
  82. { 0xc0000000, 0xb3e407d7, 0xa57d8666, 0x945d819b },
  83. { 0x40000000, 0x4c1bf829, 0x5a82799a, 0x6ba27e65 }
  84. };
  85. #pragma GCC diagnostic pop
  86. int sfb, width, cbIdx, sf, cl, cr, scalef, scalei;
  87. int gbMaskL, gbMaskR;
  88. unsigned char msMask;
  89. msMask = (*msMaskPtr++) >> msMaskOffset;
  90. gbMaskL = 0;
  91. gbMaskR = 0;
  92. for (sfb = 0; sfb < maxSFB; sfb++) {
  93. width = sfbTab[sfb+1] - sfbTab[sfb]; /* assume >= 0 (see sfBandTabLong/sfBandTabShort) */
  94. cbIdx = cbRight[sfb];
  95. if (cbIdx == 14 || cbIdx == 15) {
  96. /* intensity stereo */
  97. if (msMaskPres == 1 && (msMask & 0x01))
  98. cbIdx ^= 0x01; /* invert_intensity(): 14 becomes 15, or 15 becomes 14 */
  99. sf = -sfRight[sfb]; /* negative since we use identity 0.5^(x) = 2^(-x) (see spec) */
  100. cbIdx &= 0x01; /* choose - or + scale factor */
  101. scalef = pow14[cbIdx][sf & 0x03];
  102. scalei = (sf >> 2) + 2; /* +2 to compensate for scalef = Q30 */
  103. if (scalei > 0) {
  104. if (scalei > 30)
  105. scalei = 30;
  106. do {
  107. cr = MULSHIFT32(*coefL++, scalef);
  108. CLIP_2N(cr, 31-scalei);
  109. cr <<= scalei;
  110. gbMaskR |= FASTABS(cr);
  111. *coefR++ = cr;
  112. } while (--width);
  113. } else {
  114. scalei = -scalei;
  115. if (scalei > 31)
  116. scalei = 31;
  117. do {
  118. cr = MULSHIFT32(*coefL++, scalef) >> scalei;
  119. gbMaskR |= FASTABS(cr);
  120. *coefR++ = cr;
  121. } while (--width);
  122. }
  123. } else if ( cbIdx != 13 && ((msMaskPres == 1 && (msMask & 0x01)) || msMaskPres == 2) ) {
  124. /* mid-side stereo (assumes no GB in inputs) */
  125. do {
  126. cl = *coefL;
  127. cr = *coefR;
  128. if ( (FASTABS(cl) | FASTABS(cr)) >> 30 ) {
  129. /* avoid overflow (rare) */
  130. cl >>= 1;
  131. sf = cl + (cr >> 1); CLIP_2N(sf, 30); sf <<= 1;
  132. cl = cl - (cr >> 1); CLIP_2N(cl, 30); cl <<= 1;
  133. } else {
  134. /* usual case */
  135. sf = cl + cr;
  136. cl -= cr;
  137. }
  138. *coefL++ = sf;
  139. gbMaskL |= FASTABS(sf);
  140. *coefR++ = cl;
  141. gbMaskR |= FASTABS(cl);
  142. } while (--width);
  143. } else {
  144. /* nothing to do */
  145. coefL += width;
  146. coefR += width;
  147. }
  148. /* get next mask bit (should be branchless on ARM) */
  149. msMask >>= 1;
  150. if (++msMaskOffset == 8) {
  151. msMask = *msMaskPtr++;
  152. msMaskOffset = 0;
  153. }
  154. }
  155. cl = CLZ(gbMaskL) - 1;
  156. if (gbCurrent[0] > cl)
  157. gbCurrent[0] = cl;
  158. cr = CLZ(gbMaskR) - 1;
  159. if (gbCurrent[1] > cr)
  160. gbCurrent[1] = cr;
  161. return;
  162. }
  163. /**************************************************************************************
  164. * Function: StereoProcess
  165. *
  166. * Description: apply mid-side and intensity stereo, if enabled
  167. *
  168. * Inputs: valid AACDecInfo struct (including dequantized transform coefficients)
  169. *
  170. * Outputs: updated transform coefficients in Q(FBITS_OUT_DQ_OFF)
  171. * updated minimum guard bit count for both channels
  172. *
  173. * Return: 0 if successful, -1 if error
  174. **************************************************************************************/
  175. int StereoProcess(AACDecInfo *aacDecInfo)
  176. {
  177. PSInfoBase *psi;
  178. ICSInfo *icsInfo;
  179. int gp, win, nSamps, msMaskOffset;
  180. int *coefL, *coefR;
  181. unsigned char *msMaskPtr;
  182. const /*short*/ int *sfbTab;
  183. /* validate pointers */
  184. if (!aacDecInfo || !aacDecInfo->psInfoBase)
  185. return -1;
  186. psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
  187. /* mid-side and intensity stereo require common_window == 1 (see MPEG4 spec, Correction 2, 2004) */
  188. if (psi->commonWin != 1 || aacDecInfo->currBlockID != AAC_ID_CPE)
  189. return 0;
  190. /* nothing to do */
  191. if (!psi->msMaskPresent && !psi->intensityUsed[1])
  192. return 0;
  193. icsInfo = &(psi->icsInfo[0]);
  194. if (icsInfo->winSequence == 2) {
  195. sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx];
  196. nSamps = NSAMPS_SHORT;
  197. } else {
  198. sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx];
  199. nSamps = NSAMPS_LONG;
  200. }
  201. coefL = psi->coef[0];
  202. coefR = psi->coef[1];
  203. /* do fused mid-side/intensity processing for each block (one long or eight short) */
  204. msMaskOffset = 0;
  205. msMaskPtr = psi->msMaskBits;
  206. for (gp = 0; gp < icsInfo->numWinGroup; gp++) {
  207. for (win = 0; win < icsInfo->winGroupLen[gp]; win++) {
  208. StereoProcessGroup(coefL, coefR, sfbTab, psi->msMaskPresent,
  209. msMaskPtr, msMaskOffset, icsInfo->maxSFB, psi->sfbCodeBook[1] + gp*icsInfo->maxSFB,
  210. psi->scaleFactors[1] + gp*icsInfo->maxSFB, psi->gbCurrent);
  211. coefL += nSamps;
  212. coefR += nSamps;
  213. }
  214. /* we use one bit per sfb, so there are maxSFB bits for each window group */
  215. msMaskPtr += (msMaskOffset + icsInfo->maxSFB) >> 3;
  216. msMaskOffset = (msMaskOffset + icsInfo->maxSFB) & 0x07;
  217. }
  218. ASSERT(coefL == psi->coef[0] + 1024);
  219. ASSERT(coefR == psi->coef[1] + 1024);
  220. return 0;
  221. }