• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 **********************************************************************************/
formfac_sqrt(Word32 x)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
CalcFormFactorChannel(Word16 * logSfbFormFactor,Word16 * sfbNRelevantLines,Word16 * logSfbEnergy,PSY_OUT_CHANNEL * psyOutChan)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;
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 **********************************************************************************/
improveScf(Word32 * spec,Word16 sfbWidth,Word32 thresh,Word16 scf,Word16 minScf,Word32 * dist,Word16 * minScfCalculated)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 **********************************************************************************/
countSingleScfBits(Word16 scf,Word16 scfLeft,Word16 scfRight)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 **********************************************************************************/
calcSingleSpecPe(Word16 scf,Word16 sfbConstPePart,Word16 nLines)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 **********************************************************************************/
countScfBitsDiff(Word16 * scfOld,Word16 * scfNew,Word16 sfbCnt,Word16 startSfb,Word16 stopSfb)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 
calcSpecPeDiff(Word16 * scfOld,Word16 * scfNew,Word16 * sfbConstPePart,Word16 * logSfbEnergy,Word16 * logSfbFormFactor,Word16 * sfbNRelevantLines,Word16 startSfb,Word16 stopSfb)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 **********************************************************************************/
assimilateSingleScf(PSY_OUT_CHANNEL * psyOutChan,Word16 * scf,Word16 * minScf,Word32 * sfbDist,Word16 * sfbConstPePart,Word16 * logSfbEnergy,Word16 * logSfbFormFactor,Word16 * sfbNRelevantLines,Word16 * minScfCalculated,Flag restartOnSuccess)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 	Word16 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 **********************************************************************************/
assimilateMultipleScf(PSY_OUT_CHANNEL * psyOutChan,Word16 * scf,Word16 * minScf,Word32 * sfbDist,Word16 * sfbConstPePart,Word16 * logSfbEnergy,Word16 * logSfbFormFactor,Word16 * sfbNRelevantLines)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
EstimateScaleFactorsChannel(PSY_OUT_CHANNEL * psyOutChan,Word16 * scf,Word16 * globalGain,Word16 * logSfbEnergy,Word16 * logSfbFormFactor,Word16 * sfbNRelevantLines)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
CalcFormFactor(Word16 logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],const Word16 nChannels)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
EstimateScaleFactors(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],QC_OUT_CHANNEL qcOutChannel[MAX_CHANNELS],Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],Word16 logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],const Word16 nChannels)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