stproc.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:11k
源码类别:

Symbian

开发平台:

C/C++

  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, j, n, cb, w;
  105. int sampsLeft, isf, mOutL, mOutR, xl, xr;
  106. int fl, fr, fls[3], frs[3];
  107. int cbStartL, cbStartS, cbEndL, cbEndS;
  108. int *isfTab;
  109. /* NOTE - this works fine for mixed blocks, as long as the switch point starts in the
  110.  *  short block section (i.e. on or after sample 36 = sfBand->l[8] = 3*sfBand->s[3]
  111.  * is this a safe assumption?
  112.  * TODO - intensity + mixed not quite right (diff = 11 on he_mode)
  113.  *  figure out correct implementation (spec ambiguous about when to do short block reorder)
  114.  */
  115. if (cbi[1].cbType == 0) {
  116. /* long block */
  117. cbStartL = cbi[1].cbEndL + 1;
  118. cbEndL =   cbi[0].cbEndL + 1;
  119. cbStartS = cbEndS = 0;
  120. i = fh->sfBand->l[cbStartL];
  121. } else if (cbi[1].cbType == 1 || cbi[1].cbType == 2) {
  122. /* short or mixed block */
  123. cbStartS = cbi[1].cbEndSMax + 1;
  124. cbEndS =   cbi[0].cbEndSMax + 1;
  125. cbStartL = cbEndL = 0;
  126. i = 3 * fh->sfBand->s[cbStartS];
  127. }
  128. sampsLeft = nSamps - i; /* process to length of left */
  129. isfTab = (int *)ISFMpeg1[midSideFlag];
  130. mOutL = mOutR = 0;
  131. /* long blocks */
  132. for (cb = cbStartL; cb < cbEndL && sampsLeft > 0; cb++) {
  133. isf = sfis->l[cb];
  134. if (isf == 7) {
  135. fl = ISFIIP[midSideFlag][0];
  136. fr = ISFIIP[midSideFlag][1];
  137. } else {
  138. fl = isfTab[isf];
  139. fr = isfTab[6] - isfTab[isf];
  140. }
  141. n = fh->sfBand->l[cb + 1] - fh->sfBand->l[cb];
  142. for (j = 0; j < n && sampsLeft > 0; j++, i++) {
  143. xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr);
  144. xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl);
  145. sampsLeft--;
  146. }
  147. }
  148. /* short blocks */
  149. for (cb = cbStartS; cb < cbEndS && sampsLeft >= 3; cb++) {
  150. for (w = 0; w < 3; w++) {
  151. isf = sfis->s[cb][w];
  152. if (isf == 7) {
  153. fls[w] = ISFIIP[midSideFlag][0];
  154. frs[w] = ISFIIP[midSideFlag][1];
  155. } else {
  156. fls[w] = isfTab[isf];
  157. frs[w] = isfTab[6] - isfTab[isf];
  158. }
  159. }
  160. n = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb];
  161. for (j = 0; j < n && sampsLeft >= 3; j++, i+=3) {
  162. xr = MULSHIFT32(frs[0], x[0][i+0]) << 2; x[1][i+0] = xr; mOutR |= FASTABS(xr);
  163. xl = MULSHIFT32(fls[0], x[0][i+0]) << 2; x[0][i+0] = xl; mOutL |= FASTABS(xl);
  164. xr = MULSHIFT32(frs[1], x[0][i+1]) << 2; x[1][i+1] = xr; mOutR |= FASTABS(xr);
  165. xl = MULSHIFT32(fls[1], x[0][i+1]) << 2; x[0][i+1] = xl; mOutL |= FASTABS(xl);
  166. xr = MULSHIFT32(frs[2], x[0][i+2]) << 2; x[1][i+2] = xr; mOutR |= FASTABS(xr);
  167. xl = MULSHIFT32(fls[2], x[0][i+2]) << 2; x[0][i+2] = xl; mOutL |= FASTABS(xl);
  168. sampsLeft -= 3;
  169. }
  170. }
  171. mOut[0] = mOutL;
  172. mOut[1] = mOutR;
  173. return;
  174. }
  175. /**************************************************************************************
  176.  * Function:    IntensityProcMPEG2
  177.  *
  178.  * Description: intensity stereo processing for MPEG2
  179.  *
  180.  * Inputs:      vector x with dequantized samples from left and right channels
  181.  *              number of non-zero samples in left channel
  182.  *              valid FrameHeader struct
  183.  *              two each of ScaleFactorInfoSub, CriticalBandInfo structs (both channels)
  184.  *              ScaleFactorJS struct with joint stereo info from UnpackSFMPEG2()
  185.  *              flags indicating midSide on/off, mixedBlock on/off
  186.  *              guard bit mask (left and right channels)
  187.  *
  188.  * Outputs:     updated sample vector x
  189.  *              updated guard bit mask
  190.  *
  191.  * Return:      none
  192.  *
  193.  * Notes:       assume at least 1 GB in input
  194.  *
  195.  * TODO:        combine MPEG1/2 into one function (maybe)
  196.  *              make sure all the mixed-block and IIP logic is right
  197.  *                probably redo IIP logic to be simpler
  198.  **************************************************************************************/
  199. void IntensityProcMPEG2(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis, 
  200. CriticalBandInfo *cbi, ScaleFactorJS *sfjs, int midSideFlag, int mixFlag, int mOut[2])
  201. {
  202. int i, j, k, n, r, cb, w;
  203. int fl, fr, mOutL, mOutR, xl, xr;
  204. int sampsLeft;
  205. int isf, sfIdx, tmp, il[23];
  206. int *isfTab;
  207. int cbStartL, cbStartS, cbEndL, cbEndS;
  208. isfTab = (int *)ISFMpeg2[sfjs->intensityScale][midSideFlag];
  209. mOutL = mOutR = 0;
  210. /* fill buffer with illegal intensity positions (depending on slen) */
  211. for (k = r = 0; r < 4; r++) {
  212. tmp = (1 << sfjs->slen[r]) - 1;
  213. for (j = 0; j < sfjs->nr[r]; j++, k++) 
  214. il[k] = tmp;
  215. }
  216. if (cbi[1].cbType == 0) {
  217. /* long blocks */
  218. il[21] = il[22] = 1;
  219. cbStartL = cbi[1].cbEndL + 1; /* start at end of right */
  220. cbEndL =   cbi[0].cbEndL + 1; /* process to end of left */
  221. i = fh->sfBand->l[cbStartL];
  222. sampsLeft = nSamps - i;
  223. for(cb = cbStartL; cb < cbEndL; cb++) {
  224. sfIdx = sfis->l[cb];
  225. if (sfIdx == il[cb]) {
  226. fl = ISFIIP[midSideFlag][0];
  227. fr = ISFIIP[midSideFlag][1];
  228. } else {
  229. isf = (sfis->l[cb] + 1) >> 1;
  230. fl = isfTab[(sfIdx & 0x01 ? isf : 0)];
  231. fr = isfTab[(sfIdx & 0x01 ? 0 : isf)];
  232. }
  233. n = MIN(fh->sfBand->l[cb + 1] - fh->sfBand->l[cb], sampsLeft);
  234. for(j = 0; j < n; j++, i++) {
  235. xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr);
  236. xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl);
  237. }
  238. /* early exit once we've used all the non-zero samples */
  239. sampsLeft -= n;
  240. if (sampsLeft == 0)
  241. break;
  242. }
  243. } else {
  244. /* short or mixed blocks */
  245. il[12] = 1;
  246. for(w = 0; w < 3; w++) {
  247. cbStartS = cbi[1].cbEndS[w] + 1; /* start at end of right */
  248. cbEndS =   cbi[0].cbEndS[w] + 1; /* process to end of left */
  249. i = 3 * fh->sfBand->s[cbStartS] + w;
  250. /* skip through sample array by 3, so early-exit logic would be more tricky */
  251. for(cb = cbStartS; cb < cbEndS; cb++) {
  252. sfIdx = sfis->s[cb][w];
  253. if (sfIdx == il[cb]) {
  254. fl = ISFIIP[midSideFlag][0];
  255. fr = ISFIIP[midSideFlag][1];
  256. } else {
  257. isf = (sfis->s[cb][w] + 1) >> 1;
  258. fl = isfTab[(sfIdx & 0x01 ? isf : 0)];
  259. fr = isfTab[(sfIdx & 0x01 ? 0 : isf)];
  260. }
  261. n = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb];
  262. for(j = 0; j < n; j++, i+=3) {
  263. xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr);
  264. xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl);
  265. }
  266. }
  267. }
  268. }
  269. mOut[0] = mOutL;
  270. mOut[1] = mOutR;
  271. return;
  272. }