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