stproc.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Version: RCSL 1.0/RPSL 1.0
  3. *
  4. * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
  5. *
  6. * The contents of this file, and the files included with this file, are
  7. * subject to the current version of the RealNetworks Public Source License
  8. * Version 1.0 (the "RPSL") available at
  9. * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10. * the file under the RealNetworks Community Source License Version 1.0
  11. * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
  12. * in which case the RCSL will apply. You may also obtain the license terms
  13. * directly from RealNetworks. You may not use this file except in
  14. * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
  15. * applicable to this file, the RCSL. Please see the applicable RPSL or
  16. * RCSL for the rights, obligations and limitations governing use of the
  17. * contents of the file.
  18. *
  19. * This file is part of the Helix DNA Technology. RealNetworks is the
  20. * developer of the Original Code and owns the copyrights in the portions
  21. * it created.
  22. *
  23. * This file, and the files included with this file, is distributed and made
  24. * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  25. * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  26. * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
  27. * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  28. *
  29. * Technology Compatibility Kit Test Suite(s) Location:
  30. * http://www.helixcommunity.org/content/tck
  31. *
  32. * Contributor(s):
  33. *
  34. * ***** END LICENSE BLOCK ***** */
  35. /**************************************************************************************
  36. * Fixed-point MP3 decoder
  37. * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com)
  38. * June 2003
  39. *
  40. * stproc.c - mid-side and intensity (MPEG1 and MPEG2) stereo processing
  41. **************************************************************************************/
  42. #include "coder.h"
  43. #include "assembly.h"
  44. /**************************************************************************************
  45. * Function: MidSideProc
  46. *
  47. * Description: sum-difference stereo reconstruction
  48. *
  49. * Inputs: vector x with dequantized samples from left and right channels
  50. * number of non-zero samples (MAX of left and right)
  51. * assume 1 guard bit in input
  52. * guard bit mask (left and right channels)
  53. *
  54. * Outputs: updated sample vector x
  55. * updated guard bit mask
  56. *
  57. * Return: none
  58. *
  59. * Notes: assume at least 1 GB in input
  60. **************************************************************************************/
  61. void MidSideProc(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, int mOut[2])
  62. {
  63. int i, xr, xl, mOutL, mOutR;
  64. /* L = (M+S)/sqrt(2), R = (M-S)/sqrt(2)
  65. * NOTE: 1/sqrt(2) done in DequantChannel() - see comments there
  66. */
  67. mOutL = mOutR = 0;
  68. for(i = 0; i < nSamps; i++) {
  69. xl = x[0][i];
  70. xr = x[1][i];
  71. x[0][i] = xl + xr;
  72. x[1][i] = xl - xr;
  73. mOutL |= FASTABS(x[0][i]);
  74. mOutR |= FASTABS(x[1][i]);
  75. }
  76. mOut[0] |= mOutL;
  77. mOut[1] |= mOutR;
  78. }
  79. /**************************************************************************************
  80. * Function: IntensityProcMPEG1
  81. *
  82. * Description: intensity stereo processing for MPEG1
  83. *
  84. * Inputs: vector x with dequantized samples from left and right channels
  85. * number of non-zero samples in left channel
  86. * valid FrameHeader struct
  87. * two each of ScaleFactorInfoSub, CriticalBandInfo structs (both channels)
  88. * flags indicating midSide on/off, mixedBlock on/off
  89. * guard bit mask (left and right channels)
  90. *
  91. * Outputs: updated sample vector x
  92. * updated guard bit mask
  93. *
  94. * Return: none
  95. *
  96. * Notes: assume at least 1 GB in input
  97. *
  98. * TODO: combine MPEG1/2 into one function (maybe)
  99. * make sure all the mixed-block and IIP logic is right
  100. **************************************************************************************/
  101. void IntensityProcMPEG1(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis,
  102. CriticalBandInfo *cbi, int midSideFlag, int mixFlag, int mOut[2])
  103. {
  104. int i=0, j=0, n=0, cb=0, w=0;
  105. int sampsLeft, isf, mOutL, mOutR, xl, xr;
  106. int fl, fr, fls[3], frs[3];
  107. int cbStartL=0, cbStartS=0, cbEndL=0, cbEndS=0;
  108. int *isfTab;
  109. (void)mixFlag;
  110. /* NOTE - this works fine for mixed blocks, as long as the switch point starts in the
  111. * short block section (i.e. on or after sample 36 = sfBand->l[8] = 3*sfBand->s[3]
  112. * is this a safe assumption?
  113. * TODO - intensity + mixed not quite right (diff = 11 on he_mode)
  114. * figure out correct implementation (spec ambiguous about when to do short block reorder)
  115. */
  116. if (cbi[1].cbType == 0) {
  117. /* long block */
  118. cbStartL = cbi[1].cbEndL + 1;
  119. cbEndL = cbi[0].cbEndL + 1;
  120. cbStartS = cbEndS = 0;
  121. i = fh->sfBand->l[cbStartL];
  122. } else if (cbi[1].cbType == 1 || cbi[1].cbType == 2) {
  123. /* short or mixed block */
  124. cbStartS = cbi[1].cbEndSMax + 1;
  125. cbEndS = cbi[0].cbEndSMax + 1;
  126. cbStartL = cbEndL = 0;
  127. i = 3 * fh->sfBand->s[cbStartS];
  128. }
  129. sampsLeft = nSamps - i; /* process to length of left */
  130. isfTab = (int *)ISFMpeg1[midSideFlag];
  131. mOutL = mOutR = 0;
  132. /* long blocks */
  133. for (cb = cbStartL; cb < cbEndL && sampsLeft > 0; cb++) {
  134. isf = sfis->l[cb];
  135. if (isf == 7) {
  136. fl = ISFIIP[midSideFlag][0];
  137. fr = ISFIIP[midSideFlag][1];
  138. } else {
  139. fl = isfTab[isf];
  140. fr = isfTab[6] - isfTab[isf];
  141. }
  142. n = fh->sfBand->l[cb + 1] - fh->sfBand->l[cb];
  143. for (j = 0; j < n && sampsLeft > 0; j++, i++) {
  144. xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr);
  145. xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl);
  146. sampsLeft--;
  147. }
  148. }
  149. /* short blocks */
  150. for (cb = cbStartS; cb < cbEndS && sampsLeft >= 3; cb++) {
  151. for (w = 0; w < 3; w++) {
  152. isf = sfis->s[cb][w];
  153. if (isf == 7) {
  154. fls[w] = ISFIIP[midSideFlag][0];
  155. frs[w] = ISFIIP[midSideFlag][1];
  156. } else {
  157. fls[w] = isfTab[isf];
  158. frs[w] = isfTab[6] - isfTab[isf];
  159. }
  160. }
  161. n = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb];
  162. for (j = 0; j < n && sampsLeft >= 3; j++, i+=3) {
  163. xr = MULSHIFT32(frs[0], x[0][i+0]) << 2; x[1][i+0] = xr; mOutR |= FASTABS(xr);
  164. xl = MULSHIFT32(fls[0], x[0][i+0]) << 2; x[0][i+0] = xl; mOutL |= FASTABS(xl);
  165. xr = MULSHIFT32(frs[1], x[0][i+1]) << 2; x[1][i+1] = xr; mOutR |= FASTABS(xr);
  166. xl = MULSHIFT32(fls[1], x[0][i+1]) << 2; x[0][i+1] = xl; mOutL |= FASTABS(xl);
  167. xr = MULSHIFT32(frs[2], x[0][i+2]) << 2; x[1][i+2] = xr; mOutR |= FASTABS(xr);
  168. xl = MULSHIFT32(fls[2], x[0][i+2]) << 2; x[0][i+2] = xl; mOutL |= FASTABS(xl);
  169. sampsLeft -= 3;
  170. }
  171. }
  172. mOut[0] = mOutL;
  173. mOut[1] = mOutR;
  174. return;
  175. }
  176. /**************************************************************************************
  177. * Function: IntensityProcMPEG2
  178. *
  179. * Description: intensity stereo processing for MPEG2
  180. *
  181. * Inputs: vector x with dequantized samples from left and right channels
  182. * number of non-zero samples in left channel
  183. * valid FrameHeader struct
  184. * two each of ScaleFactorInfoSub, CriticalBandInfo structs (both channels)
  185. * ScaleFactorJS struct with joint stereo info from UnpackSFMPEG2()
  186. * flags indicating midSide on/off, mixedBlock on/off
  187. * guard bit mask (left and right channels)
  188. *
  189. * Outputs: updated sample vector x
  190. * updated guard bit mask
  191. *
  192. * Return: none
  193. *
  194. * Notes: assume at least 1 GB in input
  195. *
  196. * TODO: combine MPEG1/2 into one function (maybe)
  197. * make sure all the mixed-block and IIP logic is right
  198. * probably redo IIP logic to be simpler
  199. **************************************************************************************/
  200. void IntensityProcMPEG2(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis,
  201. CriticalBandInfo *cbi, ScaleFactorJS *sfjs, int midSideFlag, int mixFlag, int mOut[2])
  202. {
  203. int i, j, k, n, r, cb, w;
  204. int fl, fr, mOutL, mOutR, xl, xr;
  205. int sampsLeft;
  206. int isf, sfIdx, tmp, il[23];
  207. int *isfTab;
  208. int cbStartL, cbStartS, cbEndL, cbEndS;
  209. (void)mixFlag;
  210. isfTab = (int *)ISFMpeg2[sfjs->intensityScale][midSideFlag];
  211. mOutL = mOutR = 0;
  212. /* fill buffer with illegal intensity positions (depending on slen) */
  213. for (k = r = 0; r < 4; r++) {
  214. tmp = (1 << sfjs->slen[r]) - 1;
  215. for (j = 0; j < sfjs->nr[r]; j++, k++)
  216. il[k] = tmp;
  217. }
  218. if (cbi[1].cbType == 0) {
  219. /* long blocks */
  220. il[21] = il[22] = 1;
  221. cbStartL = cbi[1].cbEndL + 1; /* start at end of right */
  222. cbEndL = cbi[0].cbEndL + 1; /* process to end of left */
  223. i = fh->sfBand->l[cbStartL];
  224. sampsLeft = nSamps - i;
  225. for(cb = cbStartL; cb < cbEndL; cb++) {
  226. sfIdx = sfis->l[cb];
  227. if (sfIdx == il[cb]) {
  228. fl = ISFIIP[midSideFlag][0];
  229. fr = ISFIIP[midSideFlag][1];
  230. } else {
  231. isf = (sfis->l[cb] + 1) >> 1;
  232. fl = isfTab[(sfIdx & 0x01 ? isf : 0)];
  233. fr = isfTab[(sfIdx & 0x01 ? 0 : isf)];
  234. }
  235. n = MIN(fh->sfBand->l[cb + 1] - fh->sfBand->l[cb], sampsLeft);
  236. for(j = 0; j < n; j++, i++) {
  237. xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr);
  238. xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl);
  239. }
  240. /* early exit once we've used all the non-zero samples */
  241. sampsLeft -= n;
  242. if (sampsLeft == 0)
  243. break;
  244. }
  245. } else {
  246. /* short or mixed blocks */
  247. il[12] = 1;
  248. for(w = 0; w < 3; w++) {
  249. cbStartS = cbi[1].cbEndS[w] + 1; /* start at end of right */
  250. cbEndS = cbi[0].cbEndS[w] + 1; /* process to end of left */
  251. i = 3 * fh->sfBand->s[cbStartS] + w;
  252. /* skip through sample array by 3, so early-exit logic would be more tricky */
  253. for(cb = cbStartS; cb < cbEndS; cb++) {
  254. sfIdx = sfis->s[cb][w];
  255. if (sfIdx == il[cb]) {
  256. fl = ISFIIP[midSideFlag][0];
  257. fr = ISFIIP[midSideFlag][1];
  258. } else {
  259. isf = (sfis->s[cb][w] + 1) >> 1;
  260. fl = isfTab[(sfIdx & 0x01 ? isf : 0)];
  261. fr = isfTab[(sfIdx & 0x01 ? 0 : isf)];
  262. }
  263. n = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb];
  264. for(j = 0; j < n; j++, i+=3) {
  265. xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr);
  266. xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl);
  267. }
  268. }
  269. }
  270. }
  271. mOut[0] = mOutL;
  272. mOut[1] = mOutR;
  273. return;
  274. }