Home | History | Annotate | Download | only in src
      1 /*
      2  ** Copyright 2003-2010, VisualOn, Inc.
      3  **
      4  ** Licensed under the Apache License, Version 2.0 (the "License");
      5  ** you may not use this file except in compliance with the License.
      6  ** You may obtain a copy of the License at
      7  **
      8  **     http://www.apache.org/licenses/LICENSE-2.0
      9  **
     10  ** Unless required by applicable law or agreed to in writing, software
     11  ** distributed under the License is distributed on an "AS IS" BASIS,
     12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  ** See the License for the specific language governing permissions and
     14  ** limitations under the License.
     15  */
     16 /*******************************************************************************
     17 	File:		sf_estim.c
     18 
     19 	Content:	Scale factor estimation functions
     20 
     21 *******************************************************************************/
     22 
     23 #include "basic_op.h"
     24 #include "oper_32b.h"
     25 #include "sf_estim.h"
     26 #include "quantize.h"
     27 #include "bit_cnt.h"
     28 #include "aac_rom.h"
     29 
     30 static const Word16 MAX_SCF_DELTA = 60;
     31 
     32 /*!
     33 constants reference in comments
     34 
     35  C0 = 6.75f;
     36  C1 = -69.33295f;   -16/3*log(MAX_QUANT+0.5-logCon)/log(2)
     37  C2 = 4.0f;
     38  C3 = 2.66666666f;
     39 
     40   PE_C1 = 3.0f;        log(8.0)/log(2)
     41   PE_C2 = 1.3219281f;  log(2.5)/log(2)
     42   PE_C3 = 0.5593573f;  1-C2/C1
     43 
     44 */
     45 
     46 #define FF_SQRT_BITS                    7
     47 #define FF_SQRT_TABLE_SIZE              (1<<FF_SQRT_BITS - 1<<(FF_SQRT_BITS-2))
     48 #define COEF08_31		0x66666666		/* 0.8*(1 << 31) */
     49 #define PE_C1_8			24				/* PE_C1*8 */
     50 #define PE_C2_16		21				/* PE_C2*8/PE_C3 */
     51 #define PE_SCALE		0x059a			/* 0.7 * (1 << (15 - 1 - 3))*/
     52 
     53 #define SCALE_ESTIMATE_COEF	0x5555		/* (8.8585/(4*log2(10))) * (1 << 15)*/
     54 
     55 /*********************************************************************************
     56 *
     57 * function name: formfac_sqrt
     58 * description:  calculates sqrt(x)/256
     59 *
     60 **********************************************************************************/
     61 __inline Word32 formfac_sqrt(Word32 x)
     62 {
     63 	Word32 y;
     64 	Word32 preshift, postshift;
     65 
     66 
     67 	if (x==0) return 0;
     68 	preshift  = norm_l(x) - (INT_BITS-1-FF_SQRT_BITS);
     69 	postshift = preshift >> 1;
     70 	preshift  = postshift << 1;
     71 	postshift = postshift + 8;	  /* sqrt/256 */
     72 	if(preshift >= 0)
     73 		y = x << preshift;        /* now 1/4 <= y < 1 */
     74 	else
     75 		y = x >> (-preshift);
     76 	y = formfac_sqrttable[y-32];
     77 
     78 	if(postshift >= 0)
     79 		y = y >> postshift;
     80 	else
     81 		y = y << (-postshift);
     82 
     83 	return y;
     84 }
     85 
     86 
     87 /*********************************************************************************
     88 *
     89 * function name: CalcFormFactorChannel
     90 * description:  calculate the form factor one channel
     91 *				ffac(n) = sqrt(abs(X(k)) + sqrt(abs(X(k+1)) + ....
     92 *
     93 **********************************************************************************/
     94 static void
     95 CalcFormFactorChannel(Word16 *logSfbFormFactor,
     96                       Word16 *sfbNRelevantLines,
     97                       Word16 *logSfbEnergy,
     98                       PSY_OUT_CHANNEL *psyOutChan)
     99 {
    100 	Word32 sfbw, sfbw1;
    101 	Word32 i, j;
    102 	Word32 sfbOffs, sfb, shift;
    103 
    104 	sfbw = sfbw1 = 0;
    105 	for (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup){
    106 		for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
    107 			i = sfbOffs+sfb;
    108 
    109 			if (psyOutChan->sfbEnergy[i] > psyOutChan->sfbThreshold[i]) {
    110 				Word32 accu, avgFormFactor,iSfbWidth;
    111 				Word32 *mdctSpec;
    112 				sfbw = psyOutChan->sfbOffsets[i+1] - psyOutChan->sfbOffsets[i];
    113 				iSfbWidth = invSBF[(sfbw >> 2) - 1];
    114 				mdctSpec = psyOutChan->mdctSpectrum + psyOutChan->sfbOffsets[i];
    115 				accu = 0;
    116 				/* calc sum of sqrt(spec) */
    117 				for (j=sfbw; j; j--) {
    118 					accu += formfac_sqrt(L_abs(*mdctSpec)); mdctSpec++;
    119 				}
    120 				logSfbFormFactor[i] = iLog4(accu);
    121 				logSfbEnergy[i] = iLog4(psyOutChan->sfbEnergy[i]);
    122 				avgFormFactor = fixmul(rsqrt(psyOutChan->sfbEnergy[i],INT_BITS), iSfbWidth);
    123 				avgFormFactor = rsqrt((Word32)avgFormFactor,INT_BITS) >> 10;
    124 				/* result is multiplied by 4 */
    125 				if(avgFormFactor)
    126 					sfbNRelevantLines[i] = accu / avgFormFactor;
    127 				else
    128 					sfbNRelevantLines[i] = 0x7fff;
    129 			}
    130 			else {
    131 				/* set number of lines to zero */
    132 				sfbNRelevantLines[i] = 0;
    133 			}
    134 		}
    135 	}
    136 }
    137 
    138 /*********************************************************************************
    139 *
    140 * function name: improveScf
    141 * description:  find better scalefactor with analysis by synthesis
    142 *
    143 **********************************************************************************/
    144 static Word16 improveScf(Word32 *spec,
    145                          Word16  sfbWidth,
    146                          Word32  thresh,
    147                          Word16  scf,
    148                          Word16  minScf,
    149                          Word32 *dist,
    150                          Word16 *minScfCalculated)
    151 {
    152 	Word32 cnt;
    153 	Word32 sfbDist;
    154 	Word32 scfBest;
    155 	Word32 thresh125 = L_add(thresh, (thresh >> 2));
    156 
    157 	scfBest = scf;
    158 
    159 	/* calc real distortion */
    160 	sfbDist = calcSfbDist(spec, sfbWidth, scf);
    161 	*minScfCalculated = scf;
    162 	if(!sfbDist)
    163 	  return scfBest;
    164 
    165 	if (sfbDist > thresh125) {
    166 		Word32 scfEstimated;
    167 		Word32 sfbDistBest;
    168 		scfEstimated = scf;
    169 		sfbDistBest = sfbDist;
    170 
    171 		cnt = 0;
    172 		while (sfbDist > thresh125 && (cnt < 3)) {
    173 
    174 			scf = scf + 1;
    175 			sfbDist = calcSfbDist(spec, sfbWidth, scf);
    176 
    177 			if (sfbDist < sfbDistBest) {
    178 				scfBest = scf;
    179 				sfbDistBest = sfbDist;
    180 			}
    181 			cnt = cnt + 1;
    182 		}
    183 		cnt = 0;
    184 		scf = scfEstimated;
    185 		sfbDist = sfbDistBest;
    186 		while ((sfbDist > thresh125) && (cnt < 1) && (scf > minScf)) {
    187 
    188 			scf = scf - 1;
    189 			sfbDist = calcSfbDist(spec, sfbWidth, scf);
    190 
    191 			if (sfbDist < sfbDistBest) {
    192 				scfBest = scf;
    193 				sfbDistBest = sfbDist;
    194 			}
    195 			*minScfCalculated = scf;
    196 			cnt = cnt + 1;
    197 		}
    198 		*dist = sfbDistBest;
    199 	}
    200 	else {
    201 		Word32 sfbDistBest;
    202 		Word32 sfbDistAllowed;
    203 		Word32 thresh08 = fixmul(COEF08_31, thresh);
    204 		sfbDistBest = sfbDist;
    205 
    206 		if (sfbDist < thresh08)
    207 			sfbDistAllowed = sfbDist;
    208 		else
    209 			sfbDistAllowed = thresh08;
    210 		for (cnt=0; cnt<3; cnt++) {
    211 			scf = scf + 1;
    212 			sfbDist = calcSfbDist(spec, sfbWidth, scf);
    213 
    214 			if (fixmul(COEF08_31,sfbDist) < sfbDistAllowed) {
    215 				*minScfCalculated = scfBest + 1;
    216 				scfBest = scf;
    217 				sfbDistBest = sfbDist;
    218 			}
    219 		}
    220 		*dist = sfbDistBest;
    221 	}
    222 
    223 	/* return best scalefactor */
    224 	return scfBest;
    225 }
    226 
    227 /*********************************************************************************
    228 *
    229 * function name: countSingleScfBits
    230 * description:  count single scf bits in huffum
    231 *
    232 **********************************************************************************/
    233 static Word16 countSingleScfBits(Word16 scf, Word16 scfLeft, Word16 scfRight)
    234 {
    235 	Word16 scfBits;
    236 
    237 	scfBits = bitCountScalefactorDelta(scfLeft - scf) +
    238 		bitCountScalefactorDelta(scf - scfRight);
    239 
    240 	return scfBits;
    241 }
    242 
    243 /*********************************************************************************
    244 *
    245 * function name: calcSingleSpecPe
    246 * description:  ldRatio = log2(en(n)) - 0,375*scfGain(n)
    247 *				nbits = 0.7*nLines*ldRation for ldRation >= c1
    248 *				nbits = 0.7*nLines*(c2 + c3*ldRatio) for ldRation < c1
    249 *
    250 **********************************************************************************/
    251 static Word16 calcSingleSpecPe(Word16 scf, Word16 sfbConstPePart, Word16 nLines)
    252 {
    253 	Word32 specPe;
    254 	Word32 ldRatio;
    255 	Word32 scf3;
    256 
    257 	ldRatio = sfbConstPePart << 3; /*  (sfbConstPePart -0.375*scf)*8 */
    258 	scf3 = scf + scf + scf;
    259 	ldRatio = ldRatio - scf3;
    260 
    261 	if (ldRatio < PE_C1_8) {
    262 		/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
    263 		ldRatio = (ldRatio + PE_C2_16) >> 1;
    264 	}
    265 	specPe = nLines * ldRatio;
    266 	specPe = (specPe * PE_SCALE) >> 14;
    267 
    268 	return saturate(specPe);
    269 }
    270 
    271 
    272 /*********************************************************************************
    273 *
    274 * function name: countScfBitsDiff
    275 * description:  count different scf bits used
    276 *
    277 **********************************************************************************/
    278 static Word16 countScfBitsDiff(Word16 *scfOld, Word16 *scfNew,
    279                                Word16 sfbCnt, Word16 startSfb, Word16 stopSfb)
    280 {
    281 	Word32 scfBitsDiff;
    282 	Word32 sfb, sfbLast;
    283 	Word32 sfbPrev, sfbNext;
    284 
    285 	scfBitsDiff = 0;
    286 	sfb = 0;
    287 
    288 	/* search for first relevant sfb */
    289 	sfbLast = startSfb;
    290 	while (sfbLast < stopSfb && scfOld[sfbLast] == VOAAC_SHRT_MIN) {
    291 
    292 		sfbLast = sfbLast + 1;
    293 	}
    294 	/* search for previous relevant sfb and count diff */
    295 	sfbPrev = startSfb - 1;
    296 	while ((sfbPrev>=0) && scfOld[sfbPrev] == VOAAC_SHRT_MIN) {
    297 
    298 		sfbPrev = sfbPrev - 1;
    299 	}
    300 
    301 	if (sfbPrev>=0) {
    302 		scfBitsDiff += bitCountScalefactorDelta(scfNew[sfbPrev] - scfNew[sfbLast]) -
    303 			bitCountScalefactorDelta(scfOld[sfbPrev] - scfOld[sfbLast]);
    304 	}
    305 	/* now loop through all sfbs and count diffs of relevant sfbs */
    306 	for (sfb=sfbLast+1; sfb<stopSfb; sfb++) {
    307 
    308 		if (scfOld[sfb] != VOAAC_SHRT_MIN) {
    309 			scfBitsDiff += bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfb]) -
    310 				bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfb]);
    311 			sfbLast = sfb;
    312 		}
    313 	}
    314 	/* search for next relevant sfb and count diff */
    315 	sfbNext = stopSfb;
    316 	while (sfbNext < sfbCnt && scfOld[sfbNext] == VOAAC_SHRT_MIN) {
    317 
    318 		sfbNext = sfbNext + 1;
    319 	}
    320 
    321 	if (sfbNext < sfbCnt)
    322 		scfBitsDiff += bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfbNext]) -
    323 		bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfbNext]);
    324 
    325 	return saturate(scfBitsDiff);
    326 }
    327 
    328 static Word16 calcSpecPeDiff(Word16 *scfOld,
    329                              Word16 *scfNew,
    330                              Word16 *sfbConstPePart,
    331                              Word16 *logSfbEnergy,
    332                              Word16 *logSfbFormFactor,
    333                              Word16 *sfbNRelevantLines,
    334                              Word16 startSfb,
    335                              Word16 stopSfb)
    336 {
    337 	Word32 specPeDiff;
    338 	Word32 sfb;
    339 
    340 	specPeDiff = 0;
    341 
    342 	/* loop through all sfbs and count pe difference */
    343 	for (sfb=startSfb; sfb<stopSfb; sfb++) {
    344 
    345 
    346 		if (scfOld[sfb] != VOAAC_SHRT_MIN) {
    347 			Word32 ldRatioOld, ldRatioNew;
    348 			Word32 scf3;
    349 
    350 
    351 			if (sfbConstPePart[sfb] == MIN_16) {
    352 				sfbConstPePart[sfb] = ((logSfbEnergy[sfb] -
    353 					logSfbFormFactor[sfb]) + 11-8*4+3) >> 2;
    354 			}
    355 
    356 
    357 			ldRatioOld = sfbConstPePart[sfb] << 3;
    358 			scf3 = scfOld[sfb] + scfOld[sfb] + scfOld[sfb];
    359 			ldRatioOld = ldRatioOld - scf3;
    360 			ldRatioNew = sfbConstPePart[sfb] << 3;
    361 			scf3 = scfNew[sfb] + scfNew[sfb] + scfNew[sfb];
    362 			ldRatioNew = ldRatioNew - scf3;
    363 
    364 			if (ldRatioOld < PE_C1_8) {
    365 				/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
    366 				ldRatioOld = (ldRatioOld + PE_C2_16) >> 1;
    367 			}
    368 
    369 			if (ldRatioNew < PE_C1_8) {
    370 				/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
    371 				ldRatioNew = (ldRatioNew + PE_C2_16) >> 1;
    372 			}
    373 
    374 			specPeDiff +=  sfbNRelevantLines[sfb] * (ldRatioNew - ldRatioOld);
    375 		}
    376 	}
    377 
    378 	specPeDiff = (specPeDiff * PE_SCALE) >> 14;
    379 
    380 	return saturate(specPeDiff);
    381 }
    382 
    383 
    384 /*********************************************************************************
    385 *
    386 * function name: assimilateSingleScf
    387 * description:  searched for single scalefactor bands, where the number of bits gained
    388 *				by using a smaller scfgain(n) is greater than the estimated increased
    389 *				bit demand
    390 *
    391 **********************************************************************************/
    392 static void assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
    393                                 Word16 *scf,
    394                                 Word16 *minScf,
    395                                 Word32 *sfbDist,
    396                                 Word16 *sfbConstPePart,
    397                                 Word16 *logSfbEnergy,
    398                                 Word16 *logSfbFormFactor,
    399                                 Word16 *sfbNRelevantLines,
    400                                 Word16 *minScfCalculated,
    401                                 Flag    restartOnSuccess)
    402 {
    403 	Word32 sfbLast, sfbAct, sfbNext, scfAct, scfMin;
    404 	Word16 *scfLast, *scfNext;
    405 	Word32 sfbPeOld, sfbPeNew;
    406 	Word32 sfbDistNew;
    407 	Word32 j;
    408 	Flag   success;
    409 	Word16 deltaPe, deltaPeNew, deltaPeTmp;
    410 	Word16 *prevScfLast = psyOutChan->prevScfLast;
    411 	Word16 *prevScfNext = psyOutChan->prevScfNext;
    412 	Word16 *deltaPeLast = psyOutChan->deltaPeLast;
    413 	Flag   updateMinScfCalculated;
    414 
    415 	success = 0;
    416 	deltaPe = 0;
    417 
    418 	for(j=0;j<psyOutChan->sfbCnt;j++){
    419 		prevScfLast[j] = MAX_16;
    420 		prevScfNext[j] = MAX_16;
    421 		deltaPeLast[j] = MAX_16;
    422 	}
    423 
    424 	sfbLast = -1;
    425 	sfbAct = -1;
    426 	sfbNext = -1;
    427 	scfLast = 0;
    428 	scfNext = 0;
    429 	scfMin = MAX_16;
    430 	do {
    431 		/* search for new relevant sfb */
    432 		sfbNext = sfbNext + 1;
    433 		while (sfbNext < psyOutChan->sfbCnt && scf[sfbNext] == MIN_16) {
    434 
    435 			sfbNext = sfbNext + 1;
    436 		}
    437 
    438 		if ((sfbLast>=0) && (sfbAct>=0) && sfbNext < psyOutChan->sfbCnt) {
    439 			/* relevant scfs to the left and to the right */
    440 			scfAct  = scf[sfbAct];
    441 			scfLast = scf + sfbLast;
    442 			scfNext = scf + sfbNext;
    443 			scfMin  = min(*scfLast, *scfNext);
    444 		}
    445 		else {
    446 
    447 			if (sfbLast == -1 && (sfbAct>=0) && sfbNext < psyOutChan->sfbCnt) {
    448 				/* first relevant scf */
    449 				scfAct  = scf[sfbAct];
    450 				scfLast = &scfAct;
    451 				scfNext = scf + sfbNext;
    452 				scfMin  = *scfNext;
    453 			}
    454 			else {
    455 
    456 				if ((sfbLast>=0) && (sfbAct>=0) && sfbNext == psyOutChan->sfbCnt) {
    457 					/* last relevant scf */
    458 					scfAct  = scf[sfbAct];
    459 					scfLast = scf + sfbLast;
    460 					scfNext = &scfAct;
    461 					scfMin  = *scfLast;
    462 				}
    463 			}
    464 		}
    465 
    466 		if (sfbAct>=0)
    467 			scfMin = max(scfMin, minScf[sfbAct]);
    468 
    469 		if ((sfbAct >= 0) &&
    470 			(sfbLast>=0 || sfbNext < psyOutChan->sfbCnt) &&
    471 			scfAct > scfMin &&
    472 			(*scfLast != prevScfLast[sfbAct] ||
    473 			*scfNext != prevScfNext[sfbAct] ||
    474 			deltaPe < deltaPeLast[sfbAct])) {
    475 			success = 0;
    476 
    477 			/* estimate required bits for actual scf */
    478 			if (sfbConstPePart[sfbAct] == MIN_16) {
    479 				sfbConstPePart[sfbAct] = logSfbEnergy[sfbAct] -
    480 					logSfbFormFactor[sfbAct] + 11-8*4; /* 4*log2(6.75) - 32 */
    481 
    482 				if (sfbConstPePart[sfbAct] < 0)
    483 					sfbConstPePart[sfbAct] = sfbConstPePart[sfbAct] + 3;
    484 				sfbConstPePart[sfbAct] = sfbConstPePart[sfbAct] >> 2;
    485 			}
    486 
    487 			sfbPeOld = calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], sfbNRelevantLines[sfbAct]) +
    488 				countSingleScfBits(scfAct, *scfLast, *scfNext);
    489 			deltaPeNew = deltaPe;
    490 			updateMinScfCalculated = 1;
    491 			do {
    492 				scfAct = scfAct - 1;
    493 				/* check only if the same check was not done before */
    494 
    495 				if (scfAct < minScfCalculated[sfbAct]) {
    496 					sfbPeNew = calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], sfbNRelevantLines[sfbAct]) +
    497 						countSingleScfBits(scfAct, *scfLast, *scfNext);
    498 					/* use new scf if no increase in pe and
    499 					quantization error is smaller */
    500 					deltaPeTmp = deltaPe + sfbPeNew - sfbPeOld;
    501 
    502 					if (deltaPeTmp < 10) {
    503 						sfbDistNew = calcSfbDist(psyOutChan->mdctSpectrum+
    504 							psyOutChan->sfbOffsets[sfbAct],
    505 							(psyOutChan->sfbOffsets[sfbAct+1] - psyOutChan->sfbOffsets[sfbAct]),
    506 							scfAct);
    507 						if (sfbDistNew < sfbDist[sfbAct]) {
    508 							/* success, replace scf by new one */
    509 							scf[sfbAct] = scfAct;
    510 							sfbDist[sfbAct] = sfbDistNew;
    511 							deltaPeNew = deltaPeTmp;
    512 							success = 1;
    513 						}
    514 						/* mark as already checked */
    515 
    516 						if (updateMinScfCalculated) {
    517 							minScfCalculated[sfbAct] = scfAct;
    518 						}
    519 					}
    520 					else {
    521 						updateMinScfCalculated = 0;
    522 					}
    523 				}
    524 
    525 			} while (scfAct > scfMin);
    526 			deltaPe = deltaPeNew;
    527 			/* save parameters to avoid multiple computations of the same sfb */
    528 			prevScfLast[sfbAct] = *scfLast;
    529 			prevScfNext[sfbAct] = *scfNext;
    530 			deltaPeLast[sfbAct] = deltaPe;
    531 		}
    532 
    533 		if (success && restartOnSuccess) {
    534 			/* start again at first sfb */
    535 			sfbLast = -1;
    536 			sfbAct  = -1;
    537 			sfbNext = -1;
    538 			scfLast = 0;
    539 			scfNext = 0;
    540 			scfMin  = MAX_16;
    541 			success = 0;
    542 		}
    543 		else {
    544 			/* shift sfbs for next band */
    545 			sfbLast = sfbAct;
    546 			sfbAct  = sfbNext;
    547 		}
    548 
    549   } while (sfbNext < psyOutChan->sfbCnt);
    550 }
    551 
    552 
    553 /*********************************************************************************
    554 *
    555 * function name: assimilateMultipleScf
    556 * description:  scalefactor difference reduction
    557 *
    558 **********************************************************************************/
    559 static void assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,
    560                                   Word16 *scf,
    561                                   Word16 *minScf,
    562                                   Word32 *sfbDist,
    563                                   Word16 *sfbConstPePart,
    564                                   Word16 *logSfbEnergy,
    565                                   Word16 *logSfbFormFactor,
    566                                   Word16 *sfbNRelevantLines)
    567 {
    568 	Word32 sfb, startSfb, stopSfb, scfMin, scfMax, scfAct;
    569 	Flag   possibleRegionFound;
    570 	Word32 deltaScfBits;
    571 	Word32 deltaSpecPe;
    572 	Word32 deltaPe, deltaPeNew;
    573 	Word32 sfbCnt;
    574 	Word32 *sfbDistNew = psyOutChan->sfbDistNew;
    575 	Word16 *scfTmp = psyOutChan->prevScfLast;
    576 
    577 	deltaPe = 0;
    578 	sfbCnt = psyOutChan->sfbCnt;
    579 
    580 	/* calc min and max scalfactors */
    581 	scfMin = MAX_16;
    582 	scfMax = MIN_16;
    583 	for (sfb=0; sfb<sfbCnt; sfb++) {
    584 
    585 		if (scf[sfb] != MIN_16) {
    586 			scfMin = min(scfMin, scf[sfb]);
    587 			scfMax = max(scfMax, scf[sfb]);
    588 		}
    589 	}
    590 
    591 	if (scfMax !=  MIN_16) {
    592 
    593 		scfAct = scfMax;
    594 
    595 		do {
    596 			scfAct = scfAct - 1;
    597 			for (sfb=0; sfb<sfbCnt; sfb++) {
    598 				scfTmp[sfb] = scf[sfb];
    599 			}
    600 			stopSfb = 0;
    601 			do {
    602 				sfb = stopSfb;
    603 
    604 				while (sfb < sfbCnt && (scf[sfb] == MIN_16 || scf[sfb] <= scfAct)) {
    605 					sfb = sfb + 1;
    606 				}
    607 				startSfb = sfb;
    608 				sfb = sfb + 1;
    609 
    610 				while (sfb < sfbCnt && (scf[sfb] == MIN_16 || scf[sfb] > scfAct)) {
    611 					sfb = sfb + 1;
    612 				}
    613 				stopSfb = sfb;
    614 
    615 				possibleRegionFound = 0;
    616 
    617 				if (startSfb < sfbCnt) {
    618 					possibleRegionFound = 1;
    619 					for (sfb=startSfb; sfb<stopSfb; sfb++) {
    620 
    621 						if (scf[sfb]!=MIN_16) {
    622 
    623 							if (scfAct < minScf[sfb]) {
    624 								possibleRegionFound = 0;
    625 								break;
    626 							}
    627 						}
    628 					}
    629 				}
    630 
    631 
    632 				if (possibleRegionFound) { /* region found */
    633 
    634 					/* replace scfs in region by scfAct */
    635 					for (sfb=startSfb; sfb<stopSfb; sfb++) {
    636 
    637 						if (scfTmp[sfb]!=MIN_16)
    638 							scfTmp[sfb] = scfAct;
    639 					}
    640 
    641 					/* estimate change in bit demand for new scfs */
    642 					deltaScfBits = countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);
    643 					deltaSpecPe = calcSpecPeDiff(scf, scfTmp, sfbConstPePart,
    644 						logSfbEnergy, logSfbFormFactor, sfbNRelevantLines,
    645 						startSfb, stopSfb);
    646 					deltaPeNew = deltaPe + deltaScfBits + deltaSpecPe;
    647 
    648 
    649 					if (deltaPeNew < 10) {
    650 						Word32 distOldSum, distNewSum;
    651 
    652 						/* quantize and calc sum of new distortion */
    653 						distOldSum = 0;
    654 						distNewSum = 0;
    655 						for (sfb=startSfb; sfb<stopSfb; sfb++) {
    656 
    657 							if (scfTmp[sfb] != MIN_16) {
    658 								distOldSum = L_add(distOldSum, sfbDist[sfb]);
    659 
    660 								sfbDistNew[sfb] = calcSfbDist(psyOutChan->mdctSpectrum +
    661 									psyOutChan->sfbOffsets[sfb],
    662 									(psyOutChan->sfbOffsets[sfb+1] - psyOutChan->sfbOffsets[sfb]),
    663 									scfAct);
    664 
    665 
    666 								if (sfbDistNew[sfb] > psyOutChan->sfbThreshold[sfb]) {
    667 									distNewSum = distOldSum << 1;
    668 									break;
    669 								}
    670 								distNewSum = L_add(distNewSum, sfbDistNew[sfb]);
    671 							}
    672 						}
    673 
    674 						if (distNewSum < distOldSum) {
    675 							deltaPe = deltaPeNew;
    676 							for (sfb=startSfb; sfb<stopSfb; sfb++) {
    677 
    678 								if (scf[sfb]!=MIN_16) {
    679 									scf[sfb] = scfAct;
    680 									sfbDist[sfb] = sfbDistNew[sfb];
    681 								}
    682 							}
    683 						}
    684 					}
    685 				}
    686 			} while (stopSfb <= sfbCnt);
    687 		} while (scfAct > scfMin);
    688 	}
    689 }
    690 
    691 /*********************************************************************************
    692 *
    693 * function name: EstimateScaleFactorsChannel
    694 * description:  estimate scale factors for one channel
    695 *
    696 **********************************************************************************/
    697 static void
    698 EstimateScaleFactorsChannel(PSY_OUT_CHANNEL *psyOutChan,
    699                             Word16          *scf,
    700                             Word16          *globalGain,
    701                             Word16          *logSfbEnergy,
    702                             Word16          *logSfbFormFactor,
    703                             Word16          *sfbNRelevantLines)
    704 {
    705 	Word32 i, j;
    706 	Word32 thresh, energy;
    707 	Word32 energyPart, thresholdPart;
    708 	Word32 scfInt, minScf, maxScf, maxAllowedScf, lastSf;
    709 	Word32 maxSpec;
    710 	Word32 *sfbDist = psyOutChan->sfbDist;
    711 	Word16 *minSfMaxQuant = psyOutChan->minSfMaxQuant;
    712 	Word16 *minScfCalculated = psyOutChan->minScfCalculated;
    713 
    714 
    715 	for (i=0; i<psyOutChan->sfbCnt; i++) {
    716 		Word32 sbfwith, sbfStart;
    717 		Word32 *mdctSpec;
    718 		thresh = psyOutChan->sfbThreshold[i];
    719 		energy = psyOutChan->sfbEnergy[i];
    720 
    721 		sbfStart = psyOutChan->sfbOffsets[i];
    722 		sbfwith = psyOutChan->sfbOffsets[i+1] - sbfStart;
    723 		mdctSpec = psyOutChan->mdctSpectrum+sbfStart;
    724 
    725 		maxSpec = 0;
    726 		/* maximum of spectrum */
    727 		for (j=sbfwith; j; j-- ) {
    728 			Word32 absSpec = L_abs(*mdctSpec); mdctSpec++;
    729 			maxSpec |= absSpec;
    730 		}
    731 
    732 		/* scfs without energy or with thresh>energy are marked with MIN_16 */
    733 		scf[i] = MIN_16;
    734 		minSfMaxQuant[i] = MIN_16;
    735 
    736 		if ((maxSpec > 0) && (energy > thresh)) {
    737 
    738 			energyPart = logSfbFormFactor[i];
    739 			thresholdPart = iLog4(thresh);
    740 			/* -20 = 4*log2(6.75) - 32 */
    741 			scfInt = ((thresholdPart - energyPart - 20) * SCALE_ESTIMATE_COEF) >> 15;
    742 
    743 			minSfMaxQuant[i] = iLog4(maxSpec) - 68; /* 68  -16/3*log(MAX_QUANT+0.5-logCon)/log(2) + 1 */
    744 
    745 
    746 			if (minSfMaxQuant[i] > scfInt) {
    747 				scfInt = minSfMaxQuant[i];
    748 			}
    749 
    750 			/* find better scalefactor with analysis by synthesis */
    751 			scfInt = improveScf(psyOutChan->mdctSpectrum+sbfStart,
    752 				sbfwith,
    753 				thresh, scfInt, minSfMaxQuant[i],
    754 				&sfbDist[i], &minScfCalculated[i]);
    755 
    756 			scf[i] = scfInt;
    757 		}
    758 	}
    759 
    760 
    761 	/* scalefactor differece reduction  */
    762 	{
    763 		Word16 sfbConstPePart[MAX_GROUPED_SFB];
    764 		for(i=0;i<psyOutChan->sfbCnt;i++) {
    765 			sfbConstPePart[i] = MIN_16;
    766 		}
    767 
    768 		assimilateSingleScf(psyOutChan, scf,
    769 			minSfMaxQuant, sfbDist, sfbConstPePart, logSfbEnergy,
    770 			logSfbFormFactor, sfbNRelevantLines, minScfCalculated, 1);
    771 
    772 		assimilateMultipleScf(psyOutChan, scf,
    773 			minSfMaxQuant, sfbDist, sfbConstPePart, logSfbEnergy,
    774 			logSfbFormFactor, sfbNRelevantLines);
    775 	}
    776 
    777 	/* get max scalefac for global gain */
    778 	maxScf = MIN_16;
    779 	minScf = MAX_16;
    780 	for (i=0; i<psyOutChan->sfbCnt; i++) {
    781 
    782 		if (maxScf < scf[i]) {
    783 			maxScf = scf[i];
    784 		}
    785 
    786 		if ((scf[i] != MIN_16) && (minScf > scf[i])) {
    787 			minScf = scf[i];
    788 		}
    789 	}
    790 	/* limit scf delta */
    791 	maxAllowedScf = minScf + MAX_SCF_DELTA;
    792 	for(i=0; i<psyOutChan->sfbCnt; i++) {
    793 
    794 		if ((scf[i] != MIN_16) && (maxAllowedScf < scf[i])) {
    795 			scf[i] = maxAllowedScf;
    796 		}
    797 	}
    798 	/* new maxScf if any scf has been limited */
    799 
    800 	if (maxAllowedScf < maxScf) {
    801 		maxScf = maxAllowedScf;
    802 	}
    803 
    804 	/* calc loop scalefactors */
    805 
    806 	if (maxScf > MIN_16) {
    807 		*globalGain = maxScf;
    808 		lastSf = 0;
    809 
    810 		for(i=0; i<psyOutChan->sfbCnt; i++) {
    811 
    812 			if (scf[i] == MIN_16) {
    813 				scf[i] = lastSf;
    814 				/* set band explicitely to zero */
    815 				for (j=psyOutChan->sfbOffsets[i]; j<psyOutChan->sfbOffsets[i+1]; j++) {
    816 					psyOutChan->mdctSpectrum[j] = 0;
    817 				}
    818 			}
    819 			else {
    820 				scf[i] = maxScf - scf[i];
    821 				lastSf = scf[i];
    822 			}
    823 		}
    824 	}
    825 	else{
    826 		*globalGain = 0;
    827 		/* set spectrum explicitely to zero */
    828 		for(i=0; i<psyOutChan->sfbCnt; i++) {
    829 			scf[i] = 0;
    830 			for (j=psyOutChan->sfbOffsets[i]; j<psyOutChan->sfbOffsets[i+1]; j++) {
    831 				psyOutChan->mdctSpectrum[j] = 0;
    832 			}
    833 		}
    834 	}
    835 }
    836 
    837 /*********************************************************************************
    838 *
    839 * function name: CalcFormFactor
    840 * description:  estimate Form factors for all channel
    841 *
    842 **********************************************************************************/
    843 void
    844 CalcFormFactor(Word16 logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],
    845                Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
    846                Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
    847                PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
    848                const Word16 nChannels)
    849 {
    850 	Word16 j;
    851 
    852 	for (j=0; j<nChannels; j++) {
    853 		CalcFormFactorChannel(logSfbFormFactor[j], sfbNRelevantLines[j], logSfbEnergy[j], &psyOutChannel[j]);
    854 	}
    855 }
    856 
    857 /*********************************************************************************
    858 *
    859 * function name: EstimateScaleFactors
    860 * description:  estimate scale factors for all channel
    861 *
    862 **********************************************************************************/
    863 void
    864 EstimateScaleFactors(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
    865                      QC_OUT_CHANNEL  qcOutChannel[MAX_CHANNELS],
    866                      Word16          logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
    867                      Word16          logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],
    868                      Word16          sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
    869                      const Word16    nChannels)
    870 {
    871 	Word16 j;
    872 
    873 	for (j=0; j<nChannels; j++) {
    874 		EstimateScaleFactorsChannel(&psyOutChannel[j],
    875 			qcOutChannel[j].scf,
    876 			&(qcOutChannel[j].globalGain),
    877 			logSfbEnergy[j],
    878 			logSfbFormFactor[j],
    879 			sfbNRelevantLines[j]);
    880 	}
    881 }
    882 
    883