sf_estim.c revision 956c553ab0ce72f8074ad0fda2ffd66a0305700c
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
30static const Word16 MAX_SCF_DELTA = 60;
31
32/*!
33constants 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**********************************************************************************/
94static void
95CalcFormFactorChannel(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**********************************************************************************/
144static 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**********************************************************************************/
233static 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**********************************************************************************/
251static 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**********************************************************************************/
278static 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
328static 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**********************************************************************************/
392static 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**********************************************************************************/
559static 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**********************************************************************************/
697static void
698EstimateScaleFactorsChannel(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**********************************************************************************/
843void
844CalcFormFactor(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**********************************************************************************/
863void
864EstimateScaleFactors(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