aacquant.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:18k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * FAAC - Freeware Advanced Audio Coder
  3.  * Copyright (C) 2001 Menno Bakker
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2.1 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  * You should have received a copy of the GNU Lesser General Public
  15.  * License along with this library; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  *
  18.  * $Id: aacquant.c,v 1.3 2001/06/04 23:02:24 wmay Exp $
  19.  */
  20. #include <math.h>
  21. #include <stdlib.h>
  22. #include "aacquant.h"
  23. #include "coder.h"
  24. #include "huffman.h"
  25. #include "psych.h"
  26. #include "util.h"
  27. #define XRPOW_FTOI(src,dest) ((dest) = (int)(src))
  28. #define QUANTFAC(rx)  adj43[rx]
  29. #define ROUNDFAC 0.4054
  30. double *pow43;
  31. double *adj43;
  32. double *adj43asm;
  33. void AACQuantizeInit(CoderInfo *coderInfo, unsigned int numChannels)
  34. {
  35. unsigned int channel, i;
  36. pow43 = (double*)AllocMemory(PRECALC_SIZE*sizeof(double));
  37. adj43 = (double*)AllocMemory(PRECALC_SIZE*sizeof(double));
  38. adj43asm = (double*)AllocMemory(PRECALC_SIZE*sizeof(double));
  39. pow43[0] = 0.0;
  40. for(i=1;i<PRECALC_SIZE;i++)
  41. pow43[i] = pow((double)i, 4.0/3.0);
  42. adj43asm[0] = 0.0;
  43. for (i = 1; i < PRECALC_SIZE; i++)
  44. adj43asm[i] = i - 0.5 - pow(0.5 * (pow43[i - 1] + pow43[i]),0.75);
  45. for (i = 0; i < PRECALC_SIZE-1; i++)
  46. adj43[i] = (i + 1) - pow(0.5 * (pow43[i] + pow43[i + 1]), 0.75);
  47. adj43[i] = 0.5;
  48. for (channel = 0; channel < numChannels; channel++) {
  49. coderInfo[channel].old_value = 0;
  50. coderInfo[channel].CurrentStep = 4;
  51. coderInfo[channel].requantFreq = (double*)AllocMemory(BLOCK_LEN_LONG*sizeof(double));
  52. }
  53. }
  54. void AACQuantizeEnd(CoderInfo *coderInfo, unsigned int numChannels)
  55. {
  56. unsigned int channel;
  57. if (pow43) FreeMemory(pow43);
  58. if (adj43) FreeMemory(adj43);
  59. if (adj43asm) FreeMemory(adj43asm);
  60. for (channel = 0; channel < numChannels; channel++) {
  61. if (coderInfo[channel].requantFreq) FreeMemory(coderInfo[channel].requantFreq);
  62. }
  63. }
  64. int AACQuantize(CoderInfo *coderInfo,
  65. PsyInfo *psyInfo,
  66. ChannelInfo *channelInfo,
  67. int *cb_width,
  68. int num_cb,
  69. double *xr,
  70. int desired_rate)
  71. {
  72. int sb, i, do_q = 0;
  73. int bits, sign;
  74. double *xr_pow, *xmin;
  75. int *xi;
  76. /* Use local copy's */
  77. int *scale_factor = coderInfo->scale_factor;
  78. xr_pow = (double*)AllocMemory(FRAME_LEN*sizeof(double));
  79. xmin = (double*)AllocMemory(MAX_SCFAC_BANDS*sizeof(double));
  80. xi = (int*)AllocMemory(FRAME_LEN*sizeof(int));
  81. if (coderInfo->block_type == ONLY_SHORT_WINDOW) {
  82. SortForGrouping(coderInfo, psyInfo, channelInfo, cb_width, xr);
  83. } else {
  84. for (sb = 0; sb < coderInfo->nr_of_sfb; sb++) {
  85. if (channelInfo->msInfo.is_present && channelInfo->msInfo.ms_used[sb]) {
  86. psyInfo->maskThr[sb] = psyInfo->maskThrMS[sb];
  87. psyInfo->maskEn[sb] = psyInfo->maskEnMS[sb];
  88. }
  89. }
  90. }
  91. /* Set all scalefactors to 0 */
  92. coderInfo->global_gain = 0;
  93. for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
  94. scale_factor[sb] = 0;
  95. /* Compute xr_pow */
  96. for (i = 0; i < FRAME_LEN; i++) {
  97.         double temp = fabs(xr[i]);
  98.         xr_pow[i] = sqrt(temp * sqrt(temp));
  99.         do_q += (temp > 1E-20);
  100.     }
  101. if (do_q) {
  102. bits = SearchStepSize(coderInfo, desired_rate, xr_pow, xi);
  103. coderInfo->old_value = coderInfo->global_gain;
  104. CalcAllowedDist(psyInfo, cb_width, num_cb, xr, xmin);
  105. OuterLoop(coderInfo, xr, xr_pow, xi, xmin, desired_rate);
  106. for ( i = 0; i < FRAME_LEN; i++ )  {
  107. sign = (xr[i] < 0) ? -1 : 1;
  108. xi[i] *= sign;
  109. }
  110. } else {
  111. coderInfo->global_gain = 0;
  112. SetMemory(xi, 0, FRAME_LEN*sizeof(int));
  113. }
  114. CountBitsLong(coderInfo, xi);
  115. /* offset the difference of common_scalefac and scalefactors by SF_OFFSET  */
  116. for (i = 0; i < coderInfo->nr_of_sfb; i++) {
  117. if ((coderInfo->book_vector[i]!=INTENSITY_HCB)&&(coderInfo->book_vector[i]!=INTENSITY_HCB2)) {
  118. scale_factor[i] = coderInfo->global_gain - scale_factor[i] + SF_OFFSET;
  119. }
  120. }
  121. coderInfo->global_gain = scale_factor[0];
  122. /* place the codewords and their respective lengths in arrays data[] and len[] respectively */
  123. /* there are 'counter' elements in each array, and these are variable length arrays depending on the input */
  124. coderInfo->spectral_count = 0;
  125. for(i = 0; i < coderInfo->nr_of_sfb; i++) {
  126. OutputBits(
  127. coderInfo,
  128. coderInfo->book_vector[i],
  129. xi,
  130. coderInfo->sfb_offset[i],
  131. coderInfo->sfb_offset[i+1]-coderInfo->sfb_offset[i]);
  132. }
  133. if (xmin) FreeMemory(xmin);
  134. if (xr_pow) FreeMemory(xr_pow);
  135. if (xi) FreeMemory(xi);
  136. return bits;
  137. }
  138. static int SearchStepSize(CoderInfo *coderInfo,
  139.   const int desired_rate,
  140.   const double *xr,
  141.   int *xi)
  142. {
  143. int flag_GoneOver = 0;
  144. int CurrentStep = coderInfo->CurrentStep;
  145. int nBits;
  146. int StepSize = coderInfo->old_value;
  147. int Direction = 0;
  148. do
  149. {
  150. coderInfo->global_gain = StepSize;
  151. nBits = CountBits(coderInfo, xi, xr);
  152. if (CurrentStep == 1 ) {
  153. break; /* nothing to adjust anymore */
  154. }
  155. if (flag_GoneOver) {
  156. CurrentStep /= 2;
  157. }
  158. if (nBits > desired_rate) { /* increase Quantize_StepSize */
  159. if (Direction == -1 && !flag_GoneOver) {
  160. flag_GoneOver = 1;
  161. CurrentStep /= 2; /* late adjust */
  162. }
  163. Direction = 1;
  164. StepSize += CurrentStep;
  165. } else if (nBits < desired_rate) {
  166. if (Direction == 1 && !flag_GoneOver) {
  167. flag_GoneOver = 1;
  168. CurrentStep /= 2; /* late adjust */
  169. }
  170. Direction = -1;
  171. StepSize -= CurrentStep;
  172. } else break;
  173. } while (1);
  174. CurrentStep = coderInfo->old_value - StepSize;
  175. coderInfo->CurrentStep = CurrentStep/4 != 0 ? 4 : 2;
  176. coderInfo->old_value = coderInfo->global_gain;
  177. return nBits;
  178. }
  179. #if 1 /* TAKEHIRO_IEEE754_HACK */
  180. #pragma warning( disable : 4244 4307 )
  181. typedef union {
  182.     float f;
  183.     int i;
  184. } fi_union;
  185. #define MAGIC_FLOAT (65536*(128))
  186. #define MAGIC_INT 0x4b000000
  187. static void Quantize(const double *xp, int *pi, double istep)
  188. {
  189. int j;
  190. fi_union *fi;
  191. fi = (fi_union *)pi;
  192. for (j = FRAME_LEN/4 - 1; j >= 0; --j) {
  193. double x0 = istep * xp[0];
  194. double x1 = istep * xp[1];
  195. double x2 = istep * xp[2];
  196. double x3 = istep * xp[3];
  197. x0 += MAGIC_FLOAT; fi[0].f = x0;
  198. x1 += MAGIC_FLOAT; fi[1].f = x1;
  199. x2 += MAGIC_FLOAT; fi[2].f = x2;
  200. x3 += MAGIC_FLOAT; fi[3].f = x3;
  201. fi[0].f = x0 + (adj43asm - MAGIC_INT)[fi[0].i];
  202. fi[1].f = x1 + (adj43asm - MAGIC_INT)[fi[1].i];
  203. fi[2].f = x2 + (adj43asm - MAGIC_INT)[fi[2].i];
  204. fi[3].f = x3 + (adj43asm - MAGIC_INT)[fi[3].i];
  205. fi[0].i -= MAGIC_INT;
  206. fi[1].i -= MAGIC_INT;
  207. fi[2].i -= MAGIC_INT;
  208. fi[3].i -= MAGIC_INT;
  209. fi += 4;
  210. xp += 4;
  211. }
  212. }
  213. #else
  214. static void Quantize(const double *xr, int *ix, double istep)
  215. {
  216. int j;
  217.     for (j = FRAME_LEN/8; j > 0; --j) {
  218. double x1, x2, x3, x4, x5, x6, x7, x8;
  219. int rx1, rx2, rx3, rx4, rx5, rx6, rx7, rx8;
  220. x1 = *xr++ * istep;
  221. x2 = *xr++ * istep;
  222. XRPOW_FTOI(x1, rx1);
  223. x3 = *xr++ * istep;
  224. XRPOW_FTOI(x2, rx2);
  225. x4 = *xr++ * istep;
  226. XRPOW_FTOI(x3, rx3);
  227. x5 = *xr++ * istep;
  228. XRPOW_FTOI(x4, rx4);
  229. x6 = *xr++ * istep;
  230. XRPOW_FTOI(x5, rx5);
  231. x7 = *xr++ * istep;
  232. XRPOW_FTOI(x6, rx6);
  233. x8 = *xr++ * istep;
  234. XRPOW_FTOI(x7, rx7);
  235. x1 += QUANTFAC(rx1);
  236. XRPOW_FTOI(x8, rx8);
  237. x2 += QUANTFAC(rx2);
  238. XRPOW_FTOI(x1,*ix++);
  239. x3 += QUANTFAC(rx3);
  240. XRPOW_FTOI(x2,*ix++);
  241. x4 += QUANTFAC(rx4);
  242. XRPOW_FTOI(x3,*ix++);
  243. x5 += QUANTFAC(rx5);
  244. XRPOW_FTOI(x4,*ix++);
  245. x6 += QUANTFAC(rx6);
  246. XRPOW_FTOI(x5,*ix++);
  247. x7 += QUANTFAC(rx7);
  248. XRPOW_FTOI(x6,*ix++);
  249. x8 += QUANTFAC(rx8);
  250. XRPOW_FTOI(x7,*ix++);
  251. XRPOW_FTOI(x8,*ix++);
  252.     }
  253. }
  254. #endif
  255. static int CountBitsLong(CoderInfo *coderInfo, int *xi)
  256. {
  257. int i, bits = 0;
  258. /* find a good method to section the scalefactor bands into huffman codebook sections */
  259. BitSearch(coderInfo, xi);
  260. /* calculate the amount of bits needed for encoding the huffman codebook numbers */
  261. bits += SortBookNumbers(coderInfo, NULL, 0);
  262. /* calculate the amount of bits needed for the spectral values */
  263. coderInfo->spectral_count = 0;
  264. for(i = 0; i < coderInfo->nr_of_sfb; i++) {  
  265. bits += CalcBits(coderInfo,
  266. coderInfo->book_vector[i],
  267. xi,
  268. coderInfo->sfb_offset[i], 
  269. coderInfo->sfb_offset[i+1] - coderInfo->sfb_offset[i]);
  270. }
  271. /* the number of bits for the scalefactors */
  272. bits += WriteScalefactors(coderInfo, NULL, 0);
  273. /* the total amount of bits required */
  274. return bits;
  275. }
  276. static int CountBits(CoderInfo *coderInfo, int *ix, const double *xr)
  277. {
  278. int bits = 0, i;
  279. /* since quantize uses table lookup, we need to check this first: */
  280. double w = (IXMAX_VAL) / IPOW20(coderInfo->global_gain);
  281. for ( i = 0; i < FRAME_LEN; i++ )  {
  282. if (xr[i] > w)
  283. return LARGE_BITS;
  284. }
  285. Quantize(xr, ix, IPOW20(coderInfo->global_gain));
  286. bits = CountBitsLong(coderInfo, ix);
  287. return bits;
  288. }
  289. static int InnerLoop(CoderInfo *coderInfo,
  290.  double *xr_pow,
  291.  int *xi,
  292.  int max_bits)
  293. {
  294. int bits;
  295. /*  count bits */
  296. bits = CountBits(coderInfo, xi, xr_pow);
  297. /*  increase quantizer stepsize until needed bits are below maximum */
  298. while (bits > max_bits) {
  299. coderInfo->global_gain += 1;
  300. bits = CountBits(coderInfo, xi, xr_pow);
  301. }
  302. return bits;
  303. }
  304. static void CalcAllowedDist(PsyInfo *psyInfo, int *cb_width, int num_cb,
  305. double *xr, double *xmin)
  306. {
  307. int sfb, start, end, i;
  308. double en0, xmin0;
  309. end = 0;
  310. for (sfb = 0; sfb < num_cb; sfb++)
  311. {
  312. start = end;
  313. end += cb_width[sfb];
  314. for (en0 = 0.0, i = start; i < end; i++)
  315. {
  316. en0 += xr[i] * xr[i];
  317. }
  318. en0 /= cb_width[sfb];
  319. xmin0 = psyInfo->maskEn[sfb];
  320. if (xmin0 > 0.0)
  321. xmin0 = en0 * psyInfo->maskThr[sfb] / xmin0;
  322. xmin[sfb] = xmin0;
  323. }
  324. }
  325. static int OuterLoop(CoderInfo *coderInfo,
  326.  double *xr,
  327.  double *xr_pow,
  328.  int *xi,
  329.  double *xmin,
  330.  int target_bits)
  331. {
  332. int sb;
  333. int notdone, over, better;
  334. int store_global_gain, outer_loop_count;
  335. int best_global_gain, age;
  336.     calcNoiseResult noiseInfo;
  337.     calcNoiseResult bestNoiseInfo;
  338. double sfQuantFac = pow(2.0, 0.1875);
  339. int *scale_factor = coderInfo->scale_factor;
  340. int *best_scale_factor;
  341. int *save_xi;
  342. double *distort;
  343. distort = (double*)AllocMemory(MAX_SCFAC_BANDS*sizeof(double));
  344. best_scale_factor = (int*)AllocMemory(MAX_SCFAC_BANDS*sizeof(int));
  345. save_xi = (int*)AllocMemory(FRAME_LEN*sizeof(int));
  346. notdone = 1;
  347. outer_loop_count = 0;
  348. do { /* outer iteration loop */
  349. over = 0;
  350. outer_loop_count++;
  351. InnerLoop(coderInfo, xr_pow, xi, target_bits);
  352. store_global_gain = coderInfo->global_gain;
  353. over = CalcNoise(coderInfo, xr, xi, coderInfo->requantFreq, distort, xmin, &noiseInfo);
  354. if (outer_loop_count == 1)
  355. better = 1;
  356. else
  357. better = QuantCompare(&bestNoiseInfo, &noiseInfo);
  358. if (better) {
  359. bestNoiseInfo = noiseInfo;
  360. best_global_gain = store_global_gain;
  361. for (sb = 0; sb < coderInfo->nr_of_sfb; sb++) {
  362. best_scale_factor[sb] = scale_factor[sb];
  363. }
  364. memcpy(save_xi, xi, sizeof(int)*BLOCK_LEN_LONG);
  365. age = 0;
  366. } else
  367. age++;
  368.         if (age > 3 && bestNoiseInfo.over_count == 0)
  369.             break;
  370.         notdone = BalanceNoise(coderInfo, distort, xr_pow);
  371. for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
  372. if (scale_factor[sb] > 30)
  373. notdone = 0;
  374. if (notdone == 0) 
  375.             break;
  376. } while (1);
  377. coderInfo->global_gain = best_global_gain;
  378. for (sb = 0; sb < coderInfo->nr_of_sfb; sb++) {
  379. scale_factor[sb] = best_scale_factor[sb];
  380. }
  381. memcpy(xi, save_xi, sizeof(int)*BLOCK_LEN_LONG);
  382. if (best_scale_factor) FreeMemory(best_scale_factor);
  383. if (save_xi) FreeMemory(save_xi);
  384. if (distort) FreeMemory(distort);
  385. return 0;
  386. }
  387. static int CalcNoise(CoderInfo *coderInfo,
  388.  double *xr,
  389.  int *xi,
  390.  double *requant_xr,
  391.  double *error_energy,
  392.  double *xmin,
  393.  calcNoiseResult *res
  394.  )
  395. {
  396. int i, sb, sbw;
  397. int over = 0, count = 0;
  398. double invQuantFac;
  399. double linediff, noise;
  400. double over_noise = 1;
  401. double tot_noise = 1;
  402. double max_noise = 1E-20;
  403. for (sb = 0; sb < coderInfo->nr_of_sfb; sb++) {
  404. sbw = coderInfo->sfb_offset[sb+1] - coderInfo->sfb_offset[sb];
  405. invQuantFac = pow(2.0, -0.25*(coderInfo->scale_factor[sb] - coderInfo->global_gain));
  406. error_energy[sb] = 0.0;
  407. for (i = coderInfo->sfb_offset[sb]; i < coderInfo->sfb_offset[sb+1]; i++){
  408. requant_xr[i] = pow43[xi[i]] * invQuantFac; 
  409. /* measure the distortion in each scalefactor band */
  410. linediff = fabs(xr[i]) - requant_xr[i];
  411. error_energy[sb] += linediff * linediff;
  412. }
  413. error_energy[sb] = error_energy[sb] / sbw;
  414. noise = error_energy[sb] / xmin[sb];
  415. /* multiplying here is adding in dB */
  416. tot_noise *= max(noise, 1E-20);
  417. if (noise>1) {
  418. over++;
  419. /* multiplying here is adding in dB */
  420. over_noise *= noise;
  421. }
  422. max_noise = max(max_noise,noise);
  423. error_energy[sb] = noise;
  424. count++;
  425.    }
  426. res->tot_count  = count;
  427. res->over_count = over;
  428. res->tot_noise   = 10.*log10(max(1e-20,tot_noise )); 
  429. res->over_noise  = 10.*log10(max(1e+00,over_noise)); 
  430. res->max_noise   = 10.*log10(max(1e-20,max_noise ));
  431. return over;
  432. }
  433. static int QuantCompare(calcNoiseResult *best,
  434. calcNoiseResult *calc)
  435. {
  436. int better;
  437. better = calc->over_count  < best->over_count
  438. ||  ( calc->over_count == best->over_count  &&
  439. calc->over_noise  < best->over_noise )
  440. ||  ( calc->over_count == best->over_count  &&
  441. calc->over_noise == best->over_noise  &&
  442. calc->tot_noise   < best->tot_noise  ); 
  443. return better;
  444. }
  445. static int BalanceNoise(CoderInfo *coderInfo,
  446. double *distort,
  447. double *xrpow)
  448. {
  449. int status = 0, sb;
  450. AmpScalefacBands(coderInfo, distort, xrpow);
  451. for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
  452. if (coderInfo->scale_factor[sb] == 0)
  453. status = 1;
  454. return status;
  455. }
  456. static void AmpScalefacBands(CoderInfo *coderInfo,
  457.  double *distort,
  458.  double *xr_pow)
  459. {
  460. int start, end, l, sfb;
  461. double ifqstep, distort_thresh;
  462. ifqstep = pow(2.0, 0.1875);
  463. distort_thresh = -900;
  464. for (sfb = 0; sfb < coderInfo->nr_of_sfb; sfb++) {
  465. distort_thresh = max(distort[sfb], distort_thresh);
  466. }
  467. if (distort_thresh>1.0)
  468. distort_thresh=1.0;
  469. else
  470. distort_thresh *= .95;
  471.     for ( sfb = 0; sfb < coderInfo->nr_of_sfb; sfb++ ) {
  472. if (distort[sfb] > distort_thresh) {
  473. coderInfo->scale_factor[sfb]++;
  474. start = coderInfo->sfb_offset[sfb];
  475. end   = coderInfo->sfb_offset[sfb+1];
  476. for ( l = start; l < end; l++ ) {
  477. xr_pow[l] *= ifqstep;
  478. }
  479. }
  480.     }
  481. }
  482. static int SortForGrouping(CoderInfo* coderInfo,
  483.    PsyInfo *psyInfo,
  484.    ChannelInfo *channelInfo,
  485.    int *sfb_width_table,
  486.    double *xr)
  487. {
  488. int i,j,ii;
  489. int index = 0;
  490. double xr_tmp[1024];
  491. double thr_tmp[150];
  492. double en_tmp[150];
  493. int book=1;
  494. int group_offset=0;
  495. int k=0;
  496. int windowOffset = 0;
  497. /* set up local variables for used quantInfo elements */
  498. int* sfb_offset = coderInfo->sfb_offset;
  499. int* nr_of_sfb = &(coderInfo->nr_of_sfb);
  500. int* window_group_length;
  501. int num_window_groups;
  502. *nr_of_sfb = coderInfo->max_sfb;              /* Init to max_sfb */
  503. window_group_length = coderInfo->window_group_length;
  504. num_window_groups = coderInfo->num_window_groups;
  505. /* calc org sfb_offset just for shortblock */
  506. sfb_offset[k]=0;
  507. for (k=1 ; k <*nr_of_sfb+1; k++) {
  508. sfb_offset[k] = sfb_offset[k-1] + sfb_width_table[k-1];
  509. }
  510. /* sort the input spectral coefficients */
  511. index = 0;
  512. group_offset=0;
  513. for (i=0; i< num_window_groups; i++) {
  514. for (k=0; k<*nr_of_sfb; k++) {
  515. for (j=0; j < window_group_length[i]; j++) {
  516. for (ii=0;ii< sfb_width_table[k];ii++)
  517. xr_tmp[index++] = xr[ii+ sfb_offset[k] + 128*j +group_offset];
  518. }
  519. }
  520. group_offset +=  128*window_group_length[i];     
  521. }
  522. for (k=0; k<1024; k++){
  523. xr[k] = xr_tmp[k];
  524. }
  525. /* now calc the new sfb_offset table for the whole p_spectrum vector*/
  526. index = 0;
  527. sfb_offset[index++] = 0;
  528. windowOffset = 0;
  529. for (i=0; i < num_window_groups; i++) {
  530. for (k=0 ; k <*nr_of_sfb; k++) {
  531. int w;
  532. double worstTHR;
  533. double worstEN;
  534. /* for this window group and this band, find worst case inverse sig-mask-ratio */
  535. if (channelInfo->msInfo.is_present && channelInfo->msInfo.ms_usedS[windowOffset][k]) {
  536. worstTHR = psyInfo->maskThrSMS[windowOffset][k];
  537. worstEN = psyInfo->maskEnSMS[windowOffset][k];
  538. } else {
  539. worstTHR = psyInfo->maskThrS[windowOffset][k];
  540. worstEN = psyInfo->maskEnS[windowOffset][k];
  541. }
  542. for (w=1;w<window_group_length[i];w++) {
  543. if (channelInfo->msInfo.is_present && channelInfo->msInfo.ms_usedS[w+windowOffset][k]) {
  544. if (psyInfo->maskThrSMS[w+windowOffset][k] < worstTHR) {
  545. worstTHR = psyInfo->maskThrSMS[w+windowOffset][k];
  546. worstEN = psyInfo->maskEnSMS[w+windowOffset][k];
  547. }
  548. } else {
  549. if (psyInfo->maskThrS[w+windowOffset][k] < worstTHR) {
  550. worstTHR = psyInfo->maskThrS[w+windowOffset][k];
  551. worstEN = psyInfo->maskEnS[w+windowOffset][k];
  552. }
  553. }
  554. }
  555. thr_tmp[k+ i* *nr_of_sfb] = worstTHR;
  556. en_tmp[k+ i* *nr_of_sfb] = worstEN;
  557. sfb_offset[index] = sfb_offset[index-1] + sfb_width_table[k]*window_group_length[i] ;
  558. index++;
  559. }
  560. windowOffset += window_group_length[i];
  561. }
  562. *nr_of_sfb = *nr_of_sfb * num_window_groups;  /* Number interleaved bands. */
  563. for (k = 0; k < *nr_of_sfb; k++){
  564. psyInfo->maskThr[k] = thr_tmp[k];
  565. psyInfo->maskEn[k] = en_tmp[k];
  566. }
  567. return 0;
  568. }