1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*
2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc.
3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License");
5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License.
6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at
7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **     http://www.apache.org/licenses/LICENSE-2.0
9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software
11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS,
12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and
14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License.
15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */
16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*******************************************************************************
17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	File:		sf_estim.c
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Content:	Scale factor estimation functions
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
21956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*******************************************************************************/
22956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h"
24956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "oper_32b.h"
25956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "sf_estim.h"
26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "quantize.h"
27956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "bit_cnt.h"
28956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "aac_rom.h"
29956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word16 MAX_SCF_DELTA = 60;
31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*!
33b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgardconstants reference in comments
34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong C0 = 6.75f;
36b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard C1 = -69.33295f;   -16/3*log(MAX_QUANT+0.5-logCon)/log(2)
37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong C2 = 4.0f;
38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong C3 = 2.66666666f;
39b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
40b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  PE_C1 = 3.0f;        log(8.0)/log(2)
41b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  PE_C2 = 1.3219281f;  log(2.5)/log(2)
42b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  PE_C3 = 0.5593573f;  1-C2/C1
43b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*/
45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#define FF_SQRT_BITS                    7
47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#define FF_SQRT_TABLE_SIZE              (1<<FF_SQRT_BITS - 1<<(FF_SQRT_BITS-2))
48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define COEF08_31		0x66666666		/* 0.8*(1 << 31) */
49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define PE_C1_8			24				/* PE_C1*8 */
50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define PE_C2_16		21				/* PE_C2*8/PE_C3 */
51e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define PE_SCALE		0x059a			/* 0.7 * (1 << (15 - 1 - 3))*/
52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define SCALE_ESTIMATE_COEF	0x5555		/* (8.8585/(4*log2(10))) * (1 << 15)*/
54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: formfac_sqrt
58b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* description:  calculates sqrt(x)/256
59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong__inline Word32 formfac_sqrt(Word32 x)
62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 y;
64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 preshift, postshift;
65b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
66b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	if (x==0) return 0;
68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	preshift  = norm_l(x) - (INT_BITS-1-FF_SQRT_BITS);
69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	postshift = preshift >> 1;
70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	preshift  = postshift << 1;
71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	postshift = postshift + 8;	  /* sqrt/256 */
72e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if(preshift >= 0)
73e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		y = x << preshift;        /* now 1/4 <= y < 1 */
74e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	else
75e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		y = x >> (-preshift);
76e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	y = formfac_sqrttable[y-32];
77b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
78e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if(postshift >= 0)
79e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		y = y >> postshift;
80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	else
81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		y = y << (-postshift);
82b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	return y;
84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: CalcFormFactorChannel
90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  calculate the form factor one channel
91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*				ffac(n) = sqrt(abs(X(k)) + sqrt(abs(X(k+1)) + ....
92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void
95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongCalcFormFactorChannel(Word16 *logSfbFormFactor,
96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                      Word16 *sfbNRelevantLines,
97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                      Word16 *logSfbEnergy,
98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                      PSY_OUT_CHANNEL *psyOutChan)
99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
100e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 sfbw, sfbw1;
101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 i, j;
102b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe	Word32 sfbOffs, sfb;
103b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
104e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	sfbw = sfbw1 = 0;
105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	for (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup){
106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
107b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			i = sfbOffs+sfb;
108b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			if (psyOutChan->sfbEnergy[i] > psyOutChan->sfbThreshold[i]) {
110e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				Word32 accu, avgFormFactor,iSfbWidth;
111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				Word32 *mdctSpec;
112e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				sfbw = psyOutChan->sfbOffsets[i+1] - psyOutChan->sfbOffsets[i];
113e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				iSfbWidth = invSBF[(sfbw >> 2) - 1];
114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				mdctSpec = psyOutChan->mdctSpectrum + psyOutChan->sfbOffsets[i];
115b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				accu = 0;
116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				/* calc sum of sqrt(spec) */
117e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				for (j=sfbw; j; j--) {
118e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard					accu += formfac_sqrt(L_abs(*mdctSpec)); mdctSpec++;
119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				}
120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				logSfbFormFactor[i] = iLog4(accu);
121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				logSfbEnergy[i] = iLog4(psyOutChan->sfbEnergy[i]);
122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				avgFormFactor = fixmul(rsqrt(psyOutChan->sfbEnergy[i],INT_BITS), iSfbWidth);
123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				avgFormFactor = rsqrt((Word32)avgFormFactor,INT_BITS) >> 10;
124956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				/* result is multiplied by 4 */
125956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				if(avgFormFactor)
126956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					sfbNRelevantLines[i] = accu / avgFormFactor;
127956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				else
128956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					sfbNRelevantLines[i] = 0x7fff;
129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
130956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			else {
131956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				/* set number of lines to zero */
132b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				sfbNRelevantLines[i] = 0;
133956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
137956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
138956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
139956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
140956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: improveScf
141956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  find better scalefactor with analysis by synthesis
142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
144b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgardstatic Word16 improveScf(Word32 *spec,
145b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                         Word16  sfbWidth,
146b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                         Word32  thresh,
147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         Word16  scf,
148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         Word16  minScf,
149b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                         Word32 *dist,
150956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         Word16 *minScfCalculated)
151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 cnt;
153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 sfbDist;
154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 scfBest;
155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 thresh125 = L_add(thresh, (thresh >> 2));
156b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
157b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	scfBest = scf;
158b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* calc real distortion */
160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	sfbDist = calcSfbDist(spec, sfbWidth, scf);
161b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	*minScfCalculated = scf;
162e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if(!sfbDist)
163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  return scfBest;
164b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	if (sfbDist > thresh125) {
166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		Word32 scfEstimated;
167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		Word32 sfbDistBest;
168b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		scfEstimated = scf;
169b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		sfbDistBest = sfbDist;
170b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
171b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		cnt = 0;
172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		while (sfbDist > thresh125 && (cnt < 3)) {
173b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scf = scf + 1;
175956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			sfbDist = calcSfbDist(spec, sfbWidth, scf);
176b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
177956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			if (sfbDist < sfbDistBest) {
178b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				scfBest = scf;
179b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				sfbDistBest = sfbDist;
180956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			cnt = cnt + 1;
182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
183b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		cnt = 0;
184b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		scf = scfEstimated;
185b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		sfbDist = sfbDistBest;
186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		while ((sfbDist > thresh125) && (cnt < 1) && (scf > minScf)) {
187b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scf = scf - 1;
189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			sfbDist = calcSfbDist(spec, sfbWidth, scf);
190b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			if (sfbDist < sfbDistBest) {
192b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				scfBest = scf;
193b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				sfbDistBest = sfbDist;
194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
195b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			*minScfCalculated = scf;
196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			cnt = cnt + 1;
197e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
198b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*dist = sfbDistBest;
199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	else {
201b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		Word32 sfbDistBest;
202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		Word32 sfbDistAllowed;
203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		Word32 thresh08 = fixmul(COEF08_31, thresh);
204b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		sfbDistBest = sfbDist;
205b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		if (sfbDist < thresh08)
207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			sfbDistAllowed = sfbDist;
208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		else
209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			sfbDistAllowed = thresh08;
210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		for (cnt=0; cnt<3; cnt++) {
211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scf = scf + 1;
212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			sfbDist = calcSfbDist(spec, sfbWidth, scf);
213b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			if (fixmul(COEF08_31,sfbDist) < sfbDistAllowed) {
215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				*minScfCalculated = scfBest + 1;
216b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				scfBest = scf;
217b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				sfbDistBest = sfbDist;
218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
220b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*dist = sfbDistBest;
221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
222b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
223956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* return best scalefactor */
224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	return scfBest;
225956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
226956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
228956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: countSingleScfBits
230956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  count single scf bits in huffum
231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 countSingleScfBits(Word16 scf, Word16 scfLeft, Word16 scfRight)
234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word16 scfBits;
236b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	scfBits = bitCountScalefactorDelta(scfLeft - scf) +
238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		bitCountScalefactorDelta(scf - scfRight);
239b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	return scfBits;
241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
244956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: calcSingleSpecPe
246956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  ldRatio = log2(en(n)) - 0,375*scfGain(n)
247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*				nbits = 0.7*nLines*ldRation for ldRation >= c1
248b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard*				nbits = 0.7*nLines*(c2 + c3*ldRatio) for ldRation < c1
249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
251956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcSingleSpecPe(Word16 scf, Word16 sfbConstPePart, Word16 nLines)
252956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 specPe;
254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 ldRatio;
255956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 scf3;
256b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	ldRatio = sfbConstPePart << 3; /*  (sfbConstPePart -0.375*scf)*8 */
258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	scf3 = scf + scf + scf;
259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	ldRatio = ldRatio - scf3;
260b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	if (ldRatio < PE_C1_8) {
262b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		ldRatio = (ldRatio + PE_C2_16) >> 1;
264956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
265956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	specPe = nLines * ldRatio;
266956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	specPe = (specPe * PE_SCALE) >> 14;
267b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
268956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	return saturate(specPe);
269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
272956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
274956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: countScfBitsDiff
275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  count different scf bits used
276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
278b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgardstatic Word16 countScfBitsDiff(Word16 *scfOld, Word16 *scfNew,
279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               Word16 sfbCnt, Word16 startSfb, Word16 stopSfb)
280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 scfBitsDiff;
282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 sfb, sfbLast;
283956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 sfbPrev, sfbNext;
284b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
285b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	scfBitsDiff = 0;
286b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	sfb = 0;
287b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* search for first relevant sfb */
289b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	sfbLast = startSfb;
290956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	while (sfbLast < stopSfb && scfOld[sfbLast] == VOAAC_SHRT_MIN) {
291b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
292956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		sfbLast = sfbLast + 1;
293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* search for previous relevant sfb and count diff */
295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	sfbPrev = startSfb - 1;
296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	while ((sfbPrev>=0) && scfOld[sfbPrev] == VOAAC_SHRT_MIN) {
297b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		sfbPrev = sfbPrev - 1;
299956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
300b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	if (sfbPrev>=0) {
302956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		scfBitsDiff += bitCountScalefactorDelta(scfNew[sfbPrev] - scfNew[sfbLast]) -
303956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			bitCountScalefactorDelta(scfOld[sfbPrev] - scfOld[sfbLast]);
304956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* now loop through all sfbs and count diffs of relevant sfbs */
306956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	for (sfb=sfbLast+1; sfb<stopSfb; sfb++) {
307b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
308956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		if (scfOld[sfb] != VOAAC_SHRT_MIN) {
309956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scfBitsDiff += bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfb]) -
310956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfb]);
311b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			sfbLast = sfb;
312956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
313956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
314956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* search for next relevant sfb and count diff */
315b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	sfbNext = stopSfb;
316956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	while (sfbNext < sfbCnt && scfOld[sfbNext] == VOAAC_SHRT_MIN) {
317b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
318956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		sfbNext = sfbNext + 1;
319956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
320b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
321956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	if (sfbNext < sfbCnt)
322956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		scfBitsDiff += bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfbNext]) -
323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfbNext]);
324b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
325956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	return saturate(scfBitsDiff);
326956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
327956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
328956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcSpecPeDiff(Word16 *scfOld,
329956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 *scfNew,
330956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 *sfbConstPePart,
331956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 *logSfbEnergy,
332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 *logSfbFormFactor,
333956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 *sfbNRelevantLines,
334b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                             Word16 startSfb,
335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 stopSfb)
336956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 specPeDiff;
338956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 sfb;
339b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
340b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	specPeDiff = 0;
341b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
342956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* loop through all sfbs and count pe difference */
343956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	for (sfb=startSfb; sfb<stopSfb; sfb++) {
344b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
345b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		if (scfOld[sfb] != VOAAC_SHRT_MIN) {
347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			Word32 ldRatioOld, ldRatioNew;
348956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			Word32 scf3;
349b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
350b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
351956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			if (sfbConstPePart[sfb] == MIN_16) {
352956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				sfbConstPePart[sfb] = ((logSfbEnergy[sfb] -
353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					logSfbFormFactor[sfb]) + 11-8*4+3) >> 2;
354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
355b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
356b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			ldRatioOld = sfbConstPePart[sfb] << 3;
358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scf3 = scfOld[sfb] + scfOld[sfb] + scfOld[sfb];
359956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			ldRatioOld = ldRatioOld - scf3;
360956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			ldRatioNew = sfbConstPePart[sfb] << 3;
361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scf3 = scfNew[sfb] + scfNew[sfb] + scfNew[sfb];
362956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			ldRatioNew = ldRatioNew - scf3;
363b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
364956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			if (ldRatioOld < PE_C1_8) {
365956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
366956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				ldRatioOld = (ldRatioOld + PE_C2_16) >> 1;
367956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
368b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
369956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			if (ldRatioNew < PE_C1_8) {
370956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/
371956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				ldRatioNew = (ldRatioNew + PE_C2_16) >> 1;
372956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
373b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
374956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			specPeDiff +=  sfbNRelevantLines[sfb] * (ldRatioNew - ldRatioOld);
375956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
376956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
377b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
378956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	specPeDiff = (specPeDiff * PE_SCALE) >> 14;
379b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
380956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	return saturate(specPeDiff);
381956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
382956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
383956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
384956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
385956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
386956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: assimilateSingleScf
387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  searched for single scalefactor bands, where the number of bits gained
388956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*				by using a smaller scfgain(n) is greater than the estimated increased
389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*				bit demand
390956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
391956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
392956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
393b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                                Word16 *scf,
394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 *minScf,
395b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                                Word32 *sfbDist,
396956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 *sfbConstPePart,
397956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 *logSfbEnergy,
398956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 *logSfbFormFactor,
399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 *sfbNRelevantLines,
400956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 *minScfCalculated,
401956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Flag    restartOnSuccess)
402956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
4032f0fb8c1ec139d385feb6990111ed6dc93422eacMartin Storsjo	Word16 sfbLast, sfbAct, sfbNext, scfAct, scfMin;
404956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word16 *scfLast, *scfNext;
405956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 sfbPeOld, sfbPeNew;
406956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 sfbDistNew;
407956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 j;
408956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Flag   success;
409956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word16 deltaPe, deltaPeNew, deltaPeTmp;
410956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word16 *prevScfLast = psyOutChan->prevScfLast;
411956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word16 *prevScfNext = psyOutChan->prevScfNext;
412956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word16 *deltaPeLast = psyOutChan->deltaPeLast;
413956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Flag   updateMinScfCalculated;
414b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
415b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	success = 0;
416b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	deltaPe = 0;
417b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
418956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	for(j=0;j<psyOutChan->sfbCnt;j++){
419b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		prevScfLast[j] = MAX_16;
420b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		prevScfNext[j] = MAX_16;
421b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		deltaPeLast[j] = MAX_16;
422e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
423b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
424b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	sfbLast = -1;
425b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	sfbAct = -1;
426b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	sfbNext = -1;
427956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	scfLast = 0;
428956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	scfNext = 0;
429b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	scfMin = MAX_16;
430956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	do {
431956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		/* search for new relevant sfb */
432956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		sfbNext = sfbNext + 1;
433956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		while (sfbNext < psyOutChan->sfbCnt && scf[sfbNext] == MIN_16) {
434b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
435956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			sfbNext = sfbNext + 1;
436956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
437b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
438956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		if ((sfbLast>=0) && (sfbAct>=0) && sfbNext < psyOutChan->sfbCnt) {
439956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			/* relevant scfs to the left and to the right */
440b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			scfAct  = scf[sfbAct];
441956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scfLast = scf + sfbLast;
442956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scfNext = scf + sfbNext;
443956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scfMin  = min(*scfLast, *scfNext);
444956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
445956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		else {
446b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
447956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			if (sfbLast == -1 && (sfbAct>=0) && sfbNext < psyOutChan->sfbCnt) {
448956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				/* first relevant scf */
449b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				scfAct  = scf[sfbAct];
450956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				scfLast = &scfAct;
451956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				scfNext = scf + sfbNext;
452b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				scfMin  = *scfNext;
453956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
454956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			else {
455b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
456956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				if ((sfbLast>=0) && (sfbAct>=0) && sfbNext == psyOutChan->sfbCnt) {
457956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					/* last relevant scf */
458b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					scfAct  = scf[sfbAct];
459956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					scfLast = scf + sfbLast;
460956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					scfNext = &scfAct;
461b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					scfMin  = *scfLast;
462956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				}
463956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
464956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
465b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
466956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		if (sfbAct>=0)
467956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scfMin = max(scfMin, minScf[sfbAct]);
468b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
469b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		if ((sfbAct >= 0) &&
470b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			(sfbLast>=0 || sfbNext < psyOutChan->sfbCnt) &&
471b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			scfAct > scfMin &&
472b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			(*scfLast != prevScfLast[sfbAct] ||
473b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			*scfNext != prevScfNext[sfbAct] ||
474956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			deltaPe < deltaPeLast[sfbAct])) {
475b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			success = 0;
476b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
477b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			/* estimate required bits for actual scf */
478956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			if (sfbConstPePart[sfbAct] == MIN_16) {
479956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				sfbConstPePart[sfbAct] = logSfbEnergy[sfbAct] -
480956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					logSfbFormFactor[sfbAct] + 11-8*4; /* 4*log2(6.75) - 32 */
481b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
482956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				if (sfbConstPePart[sfbAct] < 0)
483956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					sfbConstPePart[sfbAct] = sfbConstPePart[sfbAct] + 3;
484956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				sfbConstPePart[sfbAct] = sfbConstPePart[sfbAct] >> 2;
485956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
486b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
487956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			sfbPeOld = calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], sfbNRelevantLines[sfbAct]) +
488956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				countSingleScfBits(scfAct, *scfLast, *scfNext);
489b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			deltaPeNew = deltaPe;
490b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			updateMinScfCalculated = 1;
491956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			do {
492956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				scfAct = scfAct - 1;
493956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				/* check only if the same check was not done before */
494b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
495956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				if (scfAct < minScfCalculated[sfbAct]) {
496956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					sfbPeNew = calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], sfbNRelevantLines[sfbAct]) +
497956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						countSingleScfBits(scfAct, *scfLast, *scfNext);
498b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					/* use new scf if no increase in pe and
499956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					quantization error is smaller */
500956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					deltaPeTmp = deltaPe + sfbPeNew - sfbPeOld;
501b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
502956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					if (deltaPeTmp < 10) {
503956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						sfbDistNew = calcSfbDist(psyOutChan->mdctSpectrum+
504956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong							psyOutChan->sfbOffsets[sfbAct],
505956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong							(psyOutChan->sfbOffsets[sfbAct+1] - psyOutChan->sfbOffsets[sfbAct]),
506956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong							scfAct);
507956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						if (sfbDistNew < sfbDist[sfbAct]) {
508956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong							/* success, replace scf by new one */
509b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard							scf[sfbAct] = scfAct;
510b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard							sfbDist[sfbAct] = sfbDistNew;
511b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard							deltaPeNew = deltaPeTmp;
512b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard							success = 1;
513956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						}
514956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						/* mark as already checked */
515b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
516956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						if (updateMinScfCalculated) {
517b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard							minScfCalculated[sfbAct] = scfAct;
518956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						}
519956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					}
520956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					else {
521b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard						updateMinScfCalculated = 0;
522956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					}
523956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				}
524b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
525956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			} while (scfAct > scfMin);
526b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			deltaPe = deltaPeNew;
527956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			/* save parameters to avoid multiple computations of the same sfb */
528b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			prevScfLast[sfbAct] = *scfLast;
529b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			prevScfNext[sfbAct] = *scfNext;
530b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			deltaPeLast[sfbAct] = deltaPe;
531956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
532b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
533956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		if (success && restartOnSuccess) {
534956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			/* start again at first sfb */
535b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			sfbLast = -1;
536b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			sfbAct  = -1;
537b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			sfbNext = -1;
538956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scfLast = 0;
539956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scfNext = 0;
540b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			scfMin  = MAX_16;
541b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			success = 0;
542956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
543956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		else {
544956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			/* shift sfbs for next band */
545b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			sfbLast = sfbAct;
546b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			sfbAct  = sfbNext;
547956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
548b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
549956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  } while (sfbNext < psyOutChan->sfbCnt);
550956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
551956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
552956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
553956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
554956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
555956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: assimilateMultipleScf
556956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  scalefactor difference reduction
557956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
558956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
559956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,
560b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                                  Word16 *scf,
561956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  Word16 *minScf,
562b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                                  Word32 *sfbDist,
563956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  Word16 *sfbConstPePart,
564956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  Word16 *logSfbEnergy,
565956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  Word16 *logSfbFormFactor,
566956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  Word16 *sfbNRelevantLines)
567956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
568956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 sfb, startSfb, stopSfb, scfMin, scfMax, scfAct;
569956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Flag   possibleRegionFound;
570956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 deltaScfBits;
571956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 deltaSpecPe;
572956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 deltaPe, deltaPeNew;
573956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 sfbCnt;
574956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 *sfbDistNew = psyOutChan->sfbDistNew;
575956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word16 *scfTmp = psyOutChan->prevScfLast;
576956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
577b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	deltaPe = 0;
578b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	sfbCnt = psyOutChan->sfbCnt;
579b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
580956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* calc min and max scalfactors */
581b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	scfMin = MAX_16;
582b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	scfMax = MIN_16;
583956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	for (sfb=0; sfb<sfbCnt; sfb++) {
584b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
585956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		if (scf[sfb] != MIN_16) {
586956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scfMin = min(scfMin, scf[sfb]);
587956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scfMax = max(scfMax, scf[sfb]);
588956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
589956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
590b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
591956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	if (scfMax !=  MIN_16) {
592b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
593b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		scfAct = scfMax;
594b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
595956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		do {
596956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scfAct = scfAct - 1;
597956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			for (sfb=0; sfb<sfbCnt; sfb++) {
598b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				scfTmp[sfb] = scf[sfb];
599956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
600b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			stopSfb = 0;
601956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			do {
602b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				sfb = stopSfb;
603b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
604956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				while (sfb < sfbCnt && (scf[sfb] == MIN_16 || scf[sfb] <= scfAct)) {
605956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					sfb = sfb + 1;
606956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				}
607b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				startSfb = sfb;
608956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				sfb = sfb + 1;
609b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
610956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				while (sfb < sfbCnt && (scf[sfb] == MIN_16 || scf[sfb] > scfAct)) {
611956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					sfb = sfb + 1;
612956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				}
613b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				stopSfb = sfb;
614b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
615b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				possibleRegionFound = 0;
616b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
617956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				if (startSfb < sfbCnt) {
618b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					possibleRegionFound = 1;
619956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					for (sfb=startSfb; sfb<stopSfb; sfb++) {
620b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
621956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						if (scf[sfb]!=MIN_16) {
622b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
623956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong							if (scfAct < minScf[sfb]) {
624b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard								possibleRegionFound = 0;
625956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong								break;
626956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong							}
627956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						}
628956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					}
629956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				}
630b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
631b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
632956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				if (possibleRegionFound) { /* region found */
633b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
634956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					/* replace scfs in region by scfAct */
635956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					for (sfb=startSfb; sfb<stopSfb; sfb++) {
636b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
637956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						if (scfTmp[sfb]!=MIN_16)
638b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard							scfTmp[sfb] = scfAct;
639956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					}
640b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
641956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					/* estimate change in bit demand for new scfs */
642956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					deltaScfBits = countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);
643956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					deltaSpecPe = calcSpecPeDiff(scf, scfTmp, sfbConstPePart,
644b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard						logSfbEnergy, logSfbFormFactor, sfbNRelevantLines,
645956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						startSfb, stopSfb);
646956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					deltaPeNew = deltaPe + deltaScfBits + deltaSpecPe;
647b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
648b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
649956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					if (deltaPeNew < 10) {
650956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						Word32 distOldSum, distNewSum;
651b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
652956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						/* quantize and calc sum of new distortion */
653b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard						distOldSum = 0;
654b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard						distNewSum = 0;
655956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						for (sfb=startSfb; sfb<stopSfb; sfb++) {
656b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
657956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong							if (scfTmp[sfb] != MIN_16) {
658956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong								distOldSum = L_add(distOldSum, sfbDist[sfb]);
659b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
660956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong								sfbDistNew[sfb] = calcSfbDist(psyOutChan->mdctSpectrum +
661b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard									psyOutChan->sfbOffsets[sfb],
662956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong									(psyOutChan->sfbOffsets[sfb+1] - psyOutChan->sfbOffsets[sfb]),
663956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong									scfAct);
664b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
665b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
666956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong								if (sfbDistNew[sfb] > psyOutChan->sfbThreshold[sfb]) {
667956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong									distNewSum = distOldSum << 1;
668956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong									break;
669956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong								}
670956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong								distNewSum = L_add(distNewSum, sfbDistNew[sfb]);
671956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong							}
672956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						}
673b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
674956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						if (distNewSum < distOldSum) {
675b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard							deltaPe = deltaPeNew;
676956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong							for (sfb=startSfb; sfb<stopSfb; sfb++) {
677b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
678956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong								if (scf[sfb]!=MIN_16) {
679b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard									scf[sfb] = scfAct;
680b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard									sfbDist[sfb] = sfbDistNew[sfb];
681956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong								}
682956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong							}
683956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong						}
684956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					}
685b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				}
686b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			} while (stopSfb <= sfbCnt);
687956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		} while (scfAct > scfMin);
688956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
689956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
690956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
691956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
692956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
693956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: EstimateScaleFactorsChannel
694956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  estimate scale factors for one channel
695956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
696956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
697956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void
698956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongEstimateScaleFactorsChannel(PSY_OUT_CHANNEL *psyOutChan,
699956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            Word16          *scf,
700956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            Word16          *globalGain,
701956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            Word16          *logSfbEnergy,
702956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            Word16          *logSfbFormFactor,
703956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            Word16          *sfbNRelevantLines)
704956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
705956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 i, j;
706956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 thresh, energy;
707956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 energyPart, thresholdPart;
708956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 scfInt, minScf, maxScf, maxAllowedScf, lastSf;
709956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 maxSpec;
710956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word32 *sfbDist = psyOutChan->sfbDist;
711956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word16 *minSfMaxQuant = psyOutChan->minSfMaxQuant;
712956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word16 *minScfCalculated = psyOutChan->minScfCalculated;
713b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
714b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
715956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	for (i=0; i<psyOutChan->sfbCnt; i++) {
716e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word32 sbfwith, sbfStart;
717956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		Word32 *mdctSpec;
718b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		thresh = psyOutChan->sfbThreshold[i];
719b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		energy = psyOutChan->sfbEnergy[i];
720b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
721e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		sbfStart = psyOutChan->sfbOffsets[i];
722e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		sbfwith = psyOutChan->sfbOffsets[i+1] - sbfStart;
723e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		mdctSpec = psyOutChan->mdctSpectrum+sbfStart;
724b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
725b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		maxSpec = 0;
726956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		/* maximum of spectrum */
727e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (j=sbfwith; j; j-- ) {
728e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			Word32 absSpec = L_abs(*mdctSpec); mdctSpec++;
729b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			maxSpec |= absSpec;
730956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
731b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
732956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		/* scfs without energy or with thresh>energy are marked with MIN_16 */
733b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		scf[i] = MIN_16;
734b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		minSfMaxQuant[i] = MIN_16;
735b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
736956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		if ((maxSpec > 0) && (energy > thresh)) {
737b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
738b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			energyPart = logSfbFormFactor[i];
739b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			thresholdPart = iLog4(thresh);
740e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			/* -20 = 4*log2(6.75) - 32 */
741956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			scfInt = ((thresholdPart - energyPart - 20) * SCALE_ESTIMATE_COEF) >> 15;
742b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
743956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			minSfMaxQuant[i] = iLog4(maxSpec) - 68; /* 68  -16/3*log(MAX_QUANT+0.5-logCon)/log(2) + 1 */
744b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
745b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
746956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			if (minSfMaxQuant[i] > scfInt) {
747b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				scfInt = minSfMaxQuant[i];
748956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
749b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
750956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			/* find better scalefactor with analysis by synthesis */
751e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			scfInt = improveScf(psyOutChan->mdctSpectrum+sbfStart,
752e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				sbfwith,
753b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				thresh, scfInt, minSfMaxQuant[i],
754956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				&sfbDist[i], &minScfCalculated[i]);
755b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
756b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			scf[i] = scfInt;
757956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
758956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
759b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
760b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
761956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* scalefactor differece reduction  */
762956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	{
763956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		Word16 sfbConstPePart[MAX_GROUPED_SFB];
764956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		for(i=0;i<psyOutChan->sfbCnt;i++) {
765b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			sfbConstPePart[i] = MIN_16;
766956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
767b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
768b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		assimilateSingleScf(psyOutChan, scf,
769956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			minSfMaxQuant, sfbDist, sfbConstPePart, logSfbEnergy,
770956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			logSfbFormFactor, sfbNRelevantLines, minScfCalculated, 1);
771b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
772b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		assimilateMultipleScf(psyOutChan, scf,
773956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			minSfMaxQuant, sfbDist, sfbConstPePart, logSfbEnergy,
774956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			logSfbFormFactor, sfbNRelevantLines);
775956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
776956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
777956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* get max scalefac for global gain */
778b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	maxScf = MIN_16;
779b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	minScf = MAX_16;
780956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	for (i=0; i<psyOutChan->sfbCnt; i++) {
781b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
782956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		if (maxScf < scf[i]) {
783b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			maxScf = scf[i];
784956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
785b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
786956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		if ((scf[i] != MIN_16) && (minScf > scf[i])) {
787b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			minScf = scf[i];
788956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
789956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
790956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* limit scf delta */
791956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	maxAllowedScf = minScf + MAX_SCF_DELTA;
792956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	for(i=0; i<psyOutChan->sfbCnt; i++) {
793b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
794956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		if ((scf[i] != MIN_16) && (maxAllowedScf < scf[i])) {
795b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			scf[i] = maxAllowedScf;
796956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
797956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
798956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* new maxScf if any scf has been limited */
799b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
800956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	if (maxAllowedScf < maxScf) {
801b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		maxScf = maxAllowedScf;
802956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
803b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
804956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/* calc loop scalefactors */
805b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
806956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	if (maxScf > MIN_16) {
807b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*globalGain = maxScf;
808b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		lastSf = 0;
809b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
810956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		for(i=0; i<psyOutChan->sfbCnt; i++) {
811b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
812956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			if (scf[i] == MIN_16) {
813b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				scf[i] = lastSf;
814956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				/* set band explicitely to zero */
815956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				for (j=psyOutChan->sfbOffsets[i]; j<psyOutChan->sfbOffsets[i+1]; j++) {
816b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					psyOutChan->mdctSpectrum[j] = 0;
817956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				}
818956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
819956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			else {
820956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				scf[i] = maxScf - scf[i];
821b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				lastSf = scf[i];
822956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
823956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
824956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
825956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	else{
826b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*globalGain = 0;
827956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		/* set spectrum explicitely to zero */
828956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		for(i=0; i<psyOutChan->sfbCnt; i++) {
829b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			scf[i] = 0;
830956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			for (j=psyOutChan->sfbOffsets[i]; j<psyOutChan->sfbOffsets[i+1]; j++) {
831b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				psyOutChan->mdctSpectrum[j] = 0;
832956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			}
833956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		}
834956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
835956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
836956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
837956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
838956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
839956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: CalcFormFactor
840956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  estimate Form factors for all channel
841956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
842956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
843956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid
844956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongCalcFormFactor(Word16 logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],
845956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
846956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
847956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
848956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               const Word16 nChannels)
849956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
850956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word16 j;
851b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
852956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	for (j=0; j<nChannels; j++) {
853956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		CalcFormFactorChannel(logSfbFormFactor[j], sfbNRelevantLines[j], logSfbEnergy[j], &psyOutChannel[j]);
854956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
855956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
856956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
857956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
858956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
859956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: EstimateScaleFactors
860956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  estimate scale factors for all channel
861956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
862956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
863956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid
864956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongEstimateScaleFactors(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
865956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     QC_OUT_CHANNEL  qcOutChannel[MAX_CHANNELS],
866956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     Word16          logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
867956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     Word16          logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],
868956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     Word16          sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
869956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     const Word16    nChannels)
870956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
871956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	Word16 j;
872b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
873956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	for (j=0; j<nChannels; j++) {
874956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		EstimateScaleFactorsChannel(&psyOutChannel[j],
875956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			qcOutChannel[j].scf,
876956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			&(qcOutChannel[j].globalGain),
877956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			logSfbEnergy[j],
878956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			logSfbFormFactor[j],
879956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			sfbNRelevantLines[j]);
880956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	}
881956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
882956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
883