stproc.cpp
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 /************************************************************************************** 37 * Fixed-point MP3 decoder 38 * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) 39 * June 2003 40 * 41 * stproc.c - mid-side and intensity (MPEG1 and MPEG2) stereo processing 42 **************************************************************************************/ 43 44 #include "coder.h" 45 #include "assembly.h" 46 47 /************************************************************************************** 48 * Function: MidSideProc 49 * 50 * Description: sum-difference stereo reconstruction 51 * 52 * Inputs: vector x with dequantized samples from left and right channels 53 * number of non-zero samples (MAX of left and right) 54 * assume 1 guard bit in input 55 * guard bit mask (left and right channels) 56 * 57 * Outputs: updated sample vector x 58 * updated guard bit mask 59 * 60 * Return: none 61 * 62 * Notes: assume at least 1 GB in input 63 **************************************************************************************/ 64 void MidSideProc(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, int mOut[2]) 65 { 66 int i, xr, xl, mOutL, mOutR; 67 68 /* L = (M+S)/sqrt(2), R = (M-S)/sqrt(2) 69 * NOTE: 1/sqrt(2) done in DequantChannel() - see comments there 70 */ 71 mOutL = mOutR = 0; 72 for(i = 0; i < nSamps; i++) { 73 xl = x[0][i]; 74 xr = x[1][i]; 75 x[0][i] = xl + xr; 76 x[1][i] = xl - xr; 77 mOutL |= FASTABS(x[0][i]); 78 mOutR |= FASTABS(x[1][i]); 79 } 80 mOut[0] |= mOutL; 81 mOut[1] |= mOutR; 82 } 83 84 /************************************************************************************** 85 * Function: IntensityProcMPEG1 86 * 87 * Description: intensity stereo processing for MPEG1 88 * 89 * Inputs: vector x with dequantized samples from left and right channels 90 * number of non-zero samples in left channel 91 * valid FrameHeader struct 92 * two each of ScaleFactorInfoSub, CriticalBandInfo structs (both channels) 93 * flags indicating midSide on/off, mixedBlock on/off 94 * guard bit mask (left and right channels) 95 * 96 * Outputs: updated sample vector x 97 * updated guard bit mask 98 * 99 * Return: none 100 * 101 * Notes: assume at least 1 GB in input 102 * 103 * TODO: combine MPEG1/2 into one function (maybe) 104 * make sure all the mixed-block and IIP logic is right 105 **************************************************************************************/ 106 void IntensityProcMPEG1(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis, 107 CriticalBandInfo *cbi, int midSideFlag, int mixFlag, int mOut[2]) 108 { 109 int i=0, j=0, n=0, cb=0, w=0; 110 int sampsLeft, isf, mOutL, mOutR, xl, xr; 111 int fl, fr, fls[3], frs[3]; 112 int cbStartL=0, cbStartS=0, cbEndL=0, cbEndS=0; 113 int *isfTab; 114 115 /* NOTE - this works fine for mixed blocks, as long as the switch point starts in the 116 * short block section (i.e. on or after sample 36 = sfBand->l[8] = 3*sfBand->s[3] 117 * is this a safe assumption? 118 * TODO - intensity + mixed not quite right (diff = 11 on he_mode) 119 * figure out correct implementation (spec ambiguous about when to do short block reorder) 120 */ 121 if (cbi[1].cbType == 0) { 122 /* long block */ 123 cbStartL = cbi[1].cbEndL + 1; 124 cbEndL = cbi[0].cbEndL + 1; 125 cbStartS = cbEndS = 0; 126 i = fh->sfBand->l[cbStartL]; 127 } else if (cbi[1].cbType == 1 || cbi[1].cbType == 2) { 128 /* short or mixed block */ 129 cbStartS = cbi[1].cbEndSMax + 1; 130 cbEndS = cbi[0].cbEndSMax + 1; 131 cbStartL = cbEndL = 0; 132 i = 3 * fh->sfBand->s[cbStartS]; 133 } 134 135 sampsLeft = nSamps - i; /* process to length of left */ 136 isfTab = (int *)ISFMpeg1[midSideFlag]; 137 mOutL = mOutR = 0; 138 139 /* long blocks */ 140 for (cb = cbStartL; cb < cbEndL && sampsLeft > 0; cb++) { 141 isf = sfis->l[cb]; 142 if (isf == 7) { 143 fl = ISFIIP[midSideFlag][0]; 144 fr = ISFIIP[midSideFlag][1]; 145 } else { 146 fl = isfTab[isf]; 147 fr = isfTab[6] - isfTab[isf]; 148 } 149 150 n = fh->sfBand->l[cb + 1] - fh->sfBand->l[cb]; 151 for (j = 0; j < n && sampsLeft > 0; j++, i++) { 152 xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr); 153 xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl); 154 sampsLeft--; 155 } 156 } 157 158 /* short blocks */ 159 for (cb = cbStartS; cb < cbEndS && sampsLeft >= 3; cb++) { 160 for (w = 0; w < 3; w++) { 161 isf = sfis->s[cb][w]; 162 if (isf == 7) { 163 fls[w] = ISFIIP[midSideFlag][0]; 164 frs[w] = ISFIIP[midSideFlag][1]; 165 } else { 166 fls[w] = isfTab[isf]; 167 frs[w] = isfTab[6] - isfTab[isf]; 168 } 169 } 170 171 n = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb]; 172 for (j = 0; j < n && sampsLeft >= 3; j++, i+=3) { 173 xr = MULSHIFT32(frs[0], x[0][i+0]) << 2; x[1][i+0] = xr; mOutR |= FASTABS(xr); 174 xl = MULSHIFT32(fls[0], x[0][i+0]) << 2; x[0][i+0] = xl; mOutL |= FASTABS(xl); 175 xr = MULSHIFT32(frs[1], x[0][i+1]) << 2; x[1][i+1] = xr; mOutR |= FASTABS(xr); 176 xl = MULSHIFT32(fls[1], x[0][i+1]) << 2; x[0][i+1] = xl; mOutL |= FASTABS(xl); 177 xr = MULSHIFT32(frs[2], x[0][i+2]) << 2; x[1][i+2] = xr; mOutR |= FASTABS(xr); 178 xl = MULSHIFT32(fls[2], x[0][i+2]) << 2; x[0][i+2] = xl; mOutL |= FASTABS(xl); 179 sampsLeft -= 3; 180 } 181 } 182 mOut[0] = mOutL; 183 mOut[1] = mOutR; 184 185 return; 186 } 187 188 /************************************************************************************** 189 * Function: IntensityProcMPEG2 190 * 191 * Description: intensity stereo processing for MPEG2 192 * 193 * Inputs: vector x with dequantized samples from left and right channels 194 * number of non-zero samples in left channel 195 * valid FrameHeader struct 196 * two each of ScaleFactorInfoSub, CriticalBandInfo structs (both channels) 197 * ScaleFactorJS struct with joint stereo info from UnpackSFMPEG2() 198 * flags indicating midSide on/off, mixedBlock on/off 199 * guard bit mask (left and right channels) 200 * 201 * Outputs: updated sample vector x 202 * updated guard bit mask 203 * 204 * Return: none 205 * 206 * Notes: assume at least 1 GB in input 207 * 208 * TODO: combine MPEG1/2 into one function (maybe) 209 * make sure all the mixed-block and IIP logic is right 210 * probably redo IIP logic to be simpler 211 **************************************************************************************/ 212 void IntensityProcMPEG2(int x[MAX_NCHAN][MAX_NSAMP], int nSamps, FrameHeader *fh, ScaleFactorInfoSub *sfis, 213 CriticalBandInfo *cbi, ScaleFactorJS *sfjs, int midSideFlag, int mixFlag, int mOut[2]) 214 { 215 int i, j, k, n, r, cb, w; 216 int fl, fr, mOutL, mOutR, xl, xr; 217 int sampsLeft; 218 int isf, sfIdx, tmp, il[23]; 219 int *isfTab; 220 int cbStartL, cbStartS, cbEndL, cbEndS; 221 222 isfTab = (int *)ISFMpeg2[sfjs->intensityScale][midSideFlag]; 223 mOutL = mOutR = 0; 224 225 /* fill buffer with illegal intensity positions (depending on slen) */ 226 for (k = r = 0; r < 4; r++) { 227 tmp = (1 << sfjs->slen[r]) - 1; 228 for (j = 0; j < sfjs->nr[r]; j++, k++) 229 il[k] = tmp; 230 } 231 232 if (cbi[1].cbType == 0) { 233 /* long blocks */ 234 il[21] = il[22] = 1; 235 cbStartL = cbi[1].cbEndL + 1; /* start at end of right */ 236 cbEndL = cbi[0].cbEndL + 1; /* process to end of left */ 237 i = fh->sfBand->l[cbStartL]; 238 sampsLeft = nSamps - i; 239 240 for(cb = cbStartL; cb < cbEndL; cb++) { 241 sfIdx = sfis->l[cb]; 242 if (sfIdx == il[cb]) { 243 fl = ISFIIP[midSideFlag][0]; 244 fr = ISFIIP[midSideFlag][1]; 245 } else { 246 isf = (sfis->l[cb] + 1) >> 1; 247 fl = isfTab[(sfIdx & 0x01 ? isf : 0)]; 248 fr = isfTab[(sfIdx & 0x01 ? 0 : isf)]; 249 } 250 n = MIN(fh->sfBand->l[cb + 1] - fh->sfBand->l[cb], sampsLeft); 251 252 for(j = 0; j < n; j++, i++) { 253 xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr); 254 xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl); 255 } 256 257 /* early exit once we've used all the non-zero samples */ 258 sampsLeft -= n; 259 if (sampsLeft == 0) 260 break; 261 } 262 } else { 263 /* short or mixed blocks */ 264 il[12] = 1; 265 266 for(w = 0; w < 3; w++) { 267 cbStartS = cbi[1].cbEndS[w] + 1; /* start at end of right */ 268 cbEndS = cbi[0].cbEndS[w] + 1; /* process to end of left */ 269 i = 3 * fh->sfBand->s[cbStartS] + w; 270 271 /* skip through sample array by 3, so early-exit logic would be more tricky */ 272 for(cb = cbStartS; cb < cbEndS; cb++) { 273 sfIdx = sfis->s[cb][w]; 274 if (sfIdx == il[cb]) { 275 fl = ISFIIP[midSideFlag][0]; 276 fr = ISFIIP[midSideFlag][1]; 277 } else { 278 isf = (sfis->s[cb][w] + 1) >> 1; 279 fl = isfTab[(sfIdx & 0x01 ? isf : 0)]; 280 fr = isfTab[(sfIdx & 0x01 ? 0 : isf)]; 281 } 282 n = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb]; 283 284 for(j = 0; j < n; j++, i+=3) { 285 xr = MULSHIFT32(fr, x[0][i]) << 2; x[1][i] = xr; mOutR |= FASTABS(xr); 286 xl = MULSHIFT32(fl, x[0][i]) << 2; x[0][i] = xl; mOutL |= FASTABS(xl); 287 } 288 } 289 } 290 } 291 mOut[0] = mOutL; 292 mOut[1] = mOutR; 293 294 return; 295 } 296