2
0

sbrfreq.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Source last modified: $Id: sbrfreq.c,v 1.2 2005/05/20 18:05:41 jrecker Exp $
  3. *
  4. * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.
  5. *
  6. * The contents of this file, and the files included with this file,
  7. * are subject to the current version of the RealNetworks Public
  8. * Source License (the "RPSL") available at
  9. * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10. * the file under the current version of the RealNetworks Community
  11. * Source License (the "RCSL") available at
  12. * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13. * will apply. You may also obtain the license terms directly from
  14. * RealNetworks. You may not use this file except in compliance with
  15. * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16. * to this file, the RCSL. Please see the applicable RPSL or RCSL for
  17. * the rights, obligations and limitations governing use of the
  18. * contents of the file.
  19. *
  20. * This file is part of the Helix DNA Technology. RealNetworks is the
  21. * developer of the Original Code and owns the copyrights in the
  22. * portions it created.
  23. *
  24. * This file, and the files included with this file, is distributed
  25. * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  26. * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  27. * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  28. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  29. * ENJOYMENT OR NON-INFRINGEMENT.
  30. *
  31. * Technology Compatibility Kit Test Suite(s) Location:
  32. * http://www.helixcommunity.org/content/tck
  33. *
  34. * Contributor(s):
  35. *
  36. * ***** END LICENSE BLOCK ***** */
  37. /**************************************************************************************
  38. * Fixed-point HE-AAC decoder
  39. * Jon Recker (jrecker@real.com)
  40. * February 2005
  41. *
  42. * sbrfreq.c - frequency band table calculation for SBR
  43. **************************************************************************************/
  44. #include "sbr.h"
  45. #include "assembly.h"
  46. /**************************************************************************************
  47. * Function: BubbleSort
  48. *
  49. * Description: in-place sort of unsigned chars
  50. *
  51. * Inputs: buffer of elements to sort
  52. * number of elements to sort
  53. *
  54. * Outputs: sorted buffer
  55. *
  56. * Return: none
  57. **************************************************************************************/
  58. static void BubbleSort(unsigned char *v, int nItems)
  59. {
  60. int i;
  61. unsigned char t;
  62. while (nItems >= 2) {
  63. for (i = 0; i < nItems-1; i++) {
  64. if (v[i+1] < v[i]) {
  65. t = v[i+1];
  66. v[i+1] = v[i];
  67. v[i] = t;
  68. }
  69. }
  70. nItems--;
  71. }
  72. }
  73. /**************************************************************************************
  74. * Function: VMin
  75. *
  76. * Description: find smallest element in a buffer of unsigned chars
  77. *
  78. * Inputs: buffer of elements to search
  79. * number of elements to search
  80. *
  81. * Outputs: none
  82. *
  83. * Return: smallest element in buffer
  84. **************************************************************************************/
  85. static unsigned char VMin(unsigned char *v, int nItems)
  86. {
  87. int i;
  88. unsigned char vMin;
  89. vMin = v[0];
  90. for (i = 1; i < nItems; i++) {
  91. if (v[i] < vMin)
  92. vMin = v[i];
  93. }
  94. return vMin;
  95. }
  96. /**************************************************************************************
  97. * Function: VMax
  98. *
  99. * Description: find largest element in a buffer of unsigned chars
  100. *
  101. * Inputs: buffer of elements to search
  102. * number of elements to search
  103. *
  104. * Outputs: none
  105. *
  106. * Return: largest element in buffer
  107. **************************************************************************************/
  108. static unsigned char VMax(unsigned char *v, int nItems)
  109. {
  110. int i;
  111. unsigned char vMax;
  112. vMax = v[0];
  113. for (i = 1; i < nItems; i++) {
  114. if (v[i] > vMax)
  115. vMax = v[i];
  116. }
  117. return vMax;
  118. }
  119. /**************************************************************************************
  120. * Function: CalcFreqMasterScaleZero
  121. *
  122. * Description: calculate master frequency table when freqScale == 0
  123. * (4.6.18.3.2.1, figure 4.39)
  124. *
  125. * Inputs: alterScale flag
  126. * index of first QMF subband in master freq table (k0)
  127. * index of last QMF subband (k2)
  128. *
  129. * Outputs: master frequency table
  130. *
  131. * Return: number of bands in master frequency table
  132. *
  133. * Notes: assumes k2 - k0 <= 48 and k2 >= k0 (4.6.18.3.6)
  134. **************************************************************************************/
  135. static int CalcFreqMasterScaleZero(unsigned char *freqMaster, int alterScale, int k0, int k2)
  136. {
  137. int nMaster, k, nBands, k2Achieved, dk, vDk[64], k2Diff;
  138. if (alterScale) {
  139. dk = 2;
  140. nBands = 2 * ((k2 - k0 + 2) >> 2);
  141. } else {
  142. dk = 1;
  143. nBands = 2 * ((k2 - k0) >> 1);
  144. }
  145. if (nBands <= 0)
  146. return 0;
  147. k2Achieved = k0 + nBands * dk;
  148. k2Diff = k2 - k2Achieved;
  149. for (k = 0; k < nBands; k++)
  150. vDk[k] = dk;
  151. if (k2Diff > 0) {
  152. k = nBands - 1;
  153. while (k2Diff) {
  154. vDk[k]++;
  155. k--;
  156. k2Diff--;
  157. }
  158. } else if (k2Diff < 0) {
  159. k = 0;
  160. while (k2Diff) {
  161. vDk[k]--;
  162. k++;
  163. k2Diff++;
  164. }
  165. }
  166. nMaster = nBands;
  167. freqMaster[0] = k0;
  168. for (k = 1; k <= nBands; k++)
  169. freqMaster[k] = freqMaster[k-1] + vDk[k-1];
  170. return nMaster;
  171. }
  172. /* mBandTab[i] = temp1[i] / 2 */
  173. static const int mBandTab[3] PROGMEM = {6, 5, 4};
  174. /* invWarpTab[i] = 1.0 / temp2[i], Q30 (see 4.6.18.3.2.1) */
  175. static const int invWarpTab[2] PROGMEM = {0x40000000, 0x313b13b1};
  176. /**************************************************************************************
  177. * Function: CalcFreqMasterScale
  178. *
  179. * Description: calculate master frequency table when freqScale > 0
  180. * (4.6.18.3.2.1, figure 4.39)
  181. *
  182. * Inputs: alterScale flag
  183. * freqScale flag
  184. * index of first QMF subband in master freq table (k0)
  185. * index of last QMF subband (k2)
  186. *
  187. * Outputs: master frequency table
  188. *
  189. * Return: number of bands in master frequency table
  190. *
  191. * Notes: assumes k2 - k0 <= 48 and k2 >= k0 (4.6.18.3.6)
  192. **************************************************************************************/
  193. static int CalcFreqMaster(unsigned char *freqMaster, int freqScale, int alterScale, int k0, int k2)
  194. {
  195. int bands, twoRegions, k, k1, t, vLast, vCurr, pCurr;
  196. int invWarp, nBands0, nBands1, change;
  197. unsigned char vDk1Min, vDk0Max;
  198. unsigned char *vDelta;
  199. if (freqScale < 1 || freqScale > 3)
  200. return -1;
  201. bands = mBandTab[freqScale - 1];
  202. invWarp = invWarpTab[alterScale];
  203. /* tested for all k0 = [5, 64], k2 = [k0, 64] */
  204. if (k2*10000 > 22449*k0) {
  205. twoRegions = 1;
  206. k1 = 2*k0;
  207. } else {
  208. twoRegions = 0;
  209. k1 = k2;
  210. }
  211. /* tested for all k0 = [5, 64], k1 = [k0, 64], freqScale = [1,3] */
  212. t = (log2Tab[k1] - log2Tab[k0]) >> 3; /* log2(k1/k0), Q28 to Q25 */
  213. nBands0 = 2 * (((bands * t) + (1 << 24)) >> 25); /* multiply by bands/2, round to nearest int (mBandTab has factor of 1/2 rolled in) */
  214. /* tested for all valid combinations of k0, k1, nBands (from sampRate, freqScale, alterScale)
  215. * roundoff error can be a problem with fixpt (e.g. pCurr = 12.499999 instead of 12.50003)
  216. * because successive multiplication always undershoots a little bit, but this
  217. * doesn't occur in any of the ratios we encounter from the valid k0/k1 bands in the spec
  218. */
  219. t = RatioPowInv(k1, k0, nBands0);
  220. pCurr = k0 << 24;
  221. vLast = k0;
  222. vDelta = freqMaster + 1; /* operate in-place */
  223. for (k = 0; k < nBands0; k++) {
  224. pCurr = MULSHIFT32(pCurr, t) << 8; /* keep in Q24 */
  225. vCurr = (pCurr + (1 << 23)) >> 24;
  226. vDelta[k] = (vCurr - vLast);
  227. vLast = vCurr;
  228. }
  229. /* sort the deltas and find max delta for first region */
  230. BubbleSort(vDelta, nBands0);
  231. vDk0Max = VMax(vDelta, nBands0);
  232. /* fill master frequency table with bands from first region */
  233. freqMaster[0] = k0;
  234. for (k = 1; k <= nBands0; k++)
  235. freqMaster[k] += freqMaster[k-1];
  236. /* if only one region, then the table is complete */
  237. if (!twoRegions)
  238. return nBands0;
  239. /* tested for all k1 = [10, 64], k2 = [k0, 64], freqScale = [1,3] */
  240. t = (log2Tab[k2] - log2Tab[k1]) >> 3; /* log2(k1/k0), Q28 to Q25 */
  241. t = MULSHIFT32(bands * t, invWarp) << 2; /* multiply by bands/2, divide by warp factor, keep Q25 */
  242. nBands1 = 2 * ((t + (1 << 24)) >> 25); /* round to nearest int */
  243. /* see comments above for calculations in first region */
  244. t = RatioPowInv(k2, k1, nBands1);
  245. pCurr = k1 << 24;
  246. vLast = k1;
  247. vDelta = freqMaster + nBands0 + 1; /* operate in-place */
  248. for (k = 0; k < nBands1; k++) {
  249. pCurr = MULSHIFT32(pCurr, t) << 8; /* keep in Q24 */
  250. vCurr = (pCurr + (1 << 23)) >> 24;
  251. vDelta[k] = (vCurr - vLast);
  252. vLast = vCurr;
  253. }
  254. /* sort the deltas, adjusting first and last if the second region has smaller deltas than the first */
  255. vDk1Min = VMin(vDelta, nBands1);
  256. if (vDk1Min < vDk0Max) {
  257. BubbleSort(vDelta, nBands1);
  258. change = vDk0Max - vDelta[0];
  259. if (change > ((vDelta[nBands1 - 1] - vDelta[0]) >> 1))
  260. change = ((vDelta[nBands1 - 1] - vDelta[0]) >> 1);
  261. vDelta[0] += change;
  262. vDelta[nBands1-1] -= change;
  263. }
  264. BubbleSort(vDelta, nBands1);
  265. /* fill master frequency table with bands from second region
  266. * Note: freqMaster[nBands0] = k1
  267. */
  268. for (k = 1; k <= nBands1; k++)
  269. freqMaster[k + nBands0] += freqMaster[k + nBands0 - 1];
  270. return (nBands0 + nBands1);
  271. }
  272. /**************************************************************************************
  273. * Function: CalcFreqHigh
  274. *
  275. * Description: calculate high resolution frequency table (4.6.18.3.2.2)
  276. *
  277. * Inputs: master frequency table
  278. * number of bands in master frequency table
  279. * crossover band from header
  280. *
  281. * Outputs: high resolution frequency table
  282. *
  283. * Return: number of bands in high resolution frequency table
  284. **************************************************************************************/
  285. static int CalcFreqHigh(unsigned char *freqHigh, unsigned char *freqMaster, int nMaster, int crossOverBand)
  286. {
  287. int k, nHigh;
  288. nHigh = nMaster - crossOverBand;
  289. for (k = 0; k <= nHigh; k++)
  290. freqHigh[k] = freqMaster[k + crossOverBand];
  291. return nHigh;
  292. }
  293. /**************************************************************************************
  294. * Function: CalcFreqLow
  295. *
  296. * Description: calculate low resolution frequency table (4.6.18.3.2.2)
  297. *
  298. * Inputs: high resolution frequency table
  299. * number of bands in high resolution frequency table
  300. *
  301. * Outputs: low resolution frequency table
  302. *
  303. * Return: number of bands in low resolution frequency table
  304. **************************************************************************************/
  305. static int CalcFreqLow(unsigned char *freqLow, unsigned char *freqHigh, int nHigh)
  306. {
  307. int k, nLow, oddFlag;
  308. nLow = nHigh - (nHigh >> 1);
  309. freqLow[0] = freqHigh[0];
  310. oddFlag = nHigh & 0x01;
  311. for (k = 1; k <= nLow; k++)
  312. freqLow[k] = freqHigh[2*k - oddFlag];
  313. return nLow;
  314. }
  315. /**************************************************************************************
  316. * Function: CalcFreqNoise
  317. *
  318. * Description: calculate noise floor frequency table (4.6.18.3.2.2)
  319. *
  320. * Inputs: low resolution frequency table
  321. * number of bands in low resolution frequency table
  322. * index of starting QMF subband for SBR (kStart)
  323. * index of last QMF subband (k2)
  324. * number of noise bands
  325. *
  326. * Outputs: noise floor frequency table
  327. *
  328. * Return: number of bands in noise floor frequency table
  329. **************************************************************************************/
  330. static int CalcFreqNoise(unsigned char *freqNoise, unsigned char *freqLow, int nLow, int kStart, int k2, int noiseBands)
  331. {
  332. int i, iLast, k, nQ, lTop, lBottom;
  333. lTop = log2Tab[k2];
  334. lBottom = log2Tab[kStart];
  335. nQ = noiseBands*((lTop - lBottom) >> 2); /* Q28 to Q26, noiseBands = [0,3] */
  336. nQ = (nQ + (1 << 25)) >> 26;
  337. if (nQ < 1)
  338. nQ = 1;
  339. ASSERT(nQ <= MAX_NUM_NOISE_FLOOR_BANDS); /* required from 4.6.18.3.6 */
  340. iLast = 0;
  341. freqNoise[0] = freqLow[0];
  342. for (k = 1; k <= nQ; k++) {
  343. i = iLast + (nLow - iLast) / (nQ + 1 - k); /* truncating division */
  344. freqNoise[k] = freqLow[i];
  345. iLast = i;
  346. }
  347. return nQ;
  348. }
  349. /**************************************************************************************
  350. * Function: BuildPatches
  351. *
  352. * Description: build high frequency patches (4.6.18.6.3)
  353. *
  354. * Inputs: master frequency table
  355. * number of bands in low resolution frequency table
  356. * index of first QMF subband in master freq table (k0)
  357. * index of starting QMF subband for SBR (kStart)
  358. * number of QMF bands in high resolution frequency table
  359. * sample rate index
  360. *
  361. * Outputs: starting subband for each patch
  362. * number of subbands in each patch
  363. *
  364. * Return: number of patches
  365. **************************************************************************************/
  366. static int BuildPatches(unsigned char *patchNumSubbands, unsigned char *patchStartSubband, unsigned char *freqMaster,
  367. int nMaster, int k0, int kStart, int numQMFBands, int sampRateIdx)
  368. {
  369. int i, j, k;
  370. int msb, sb, usb, numPatches, goalSB, oddFlag;
  371. msb = k0;
  372. usb = kStart;
  373. numPatches = 0;
  374. goalSB = goalSBTab[sampRateIdx];
  375. if (nMaster == 0) {
  376. patchNumSubbands[0] = 0;
  377. patchStartSubband[0] = 0;
  378. return 0;
  379. }
  380. if (goalSB < kStart + numQMFBands) {
  381. k = 0;
  382. for (i = 0; freqMaster[i] < goalSB; i++)
  383. k = i+1;
  384. } else {
  385. k = nMaster;
  386. }
  387. do {
  388. j = k+1;
  389. do {
  390. j--;
  391. sb = freqMaster[j];
  392. oddFlag = (sb - 2 + k0) & 0x01;
  393. } while (sb > k0 - 1 + msb - oddFlag);
  394. patchNumSubbands[numPatches] = MAX(sb - usb, 0);
  395. patchStartSubband[numPatches] = k0 - oddFlag - patchNumSubbands[numPatches];
  396. /* from MPEG reference code - slightly different from spec */
  397. if ((patchNumSubbands[numPatches] < 3) && (numPatches > 0))
  398. break;
  399. if (patchNumSubbands[numPatches] > 0) {
  400. usb = sb;
  401. msb = sb;
  402. numPatches++;
  403. } else {
  404. msb = kStart;
  405. }
  406. if (freqMaster[k] - sb < 3)
  407. k = nMaster;
  408. } while (sb != (kStart + numQMFBands) && numPatches <= MAX_NUM_PATCHES);
  409. return numPatches;
  410. }
  411. /**************************************************************************************
  412. * Function: FindFreq
  413. *
  414. * Description: search buffer of unsigned chars for a specific value
  415. *
  416. * Inputs: buffer of elements to search
  417. * number of elements to search
  418. * value to search for
  419. *
  420. * Outputs: none
  421. *
  422. * Return: non-zero if the value is found anywhere in the buffer, zero otherwise
  423. **************************************************************************************/
  424. static int FindFreq(unsigned char *freq, int nFreq, unsigned char val)
  425. {
  426. int k;
  427. for (k = 0; k < nFreq; k++) {
  428. if (freq[k] == val)
  429. return 1;
  430. }
  431. return 0;
  432. }
  433. /**************************************************************************************
  434. * Function: RemoveFreq
  435. *
  436. * Description: remove one element from a buffer of unsigned chars
  437. *
  438. * Inputs: buffer of elements
  439. * number of elements
  440. * index of element to remove
  441. *
  442. * Outputs: new buffer of length nFreq-1
  443. *
  444. * Return: none
  445. **************************************************************************************/
  446. static void RemoveFreq(unsigned char *freq, int nFreq, int removeIdx)
  447. {
  448. int k;
  449. if (removeIdx >= nFreq)
  450. return;
  451. for (k = removeIdx; k < nFreq - 1; k++)
  452. freq[k] = freq[k+1];
  453. }
  454. /**************************************************************************************
  455. * Function: CalcFreqLimiter
  456. *
  457. * Description: calculate limiter frequency table (4.6.18.3.2.3)
  458. *
  459. * Inputs: number of subbands in each patch
  460. * low resolution frequency table
  461. * number of bands in low resolution frequency table
  462. * index of starting QMF subband for SBR (kStart)
  463. * number of limiter bands
  464. * number of patches
  465. *
  466. * Outputs: limiter frequency table
  467. *
  468. * Return: number of bands in limiter frequency table
  469. **************************************************************************************/
  470. static int CalcFreqLimiter(unsigned char *freqLimiter, unsigned char *patchNumSubbands, unsigned char *freqLow,
  471. int nLow, int kStart, int limiterBands, int numPatches)
  472. {
  473. int k, bands, nLimiter, nOctaves;
  474. int limBandsPerOctave[3] = {120, 200, 300}; /* [1.2, 2.0, 3.0] * 100 */
  475. unsigned char patchBorders[MAX_NUM_PATCHES + 1];
  476. /* simple case */
  477. if (limiterBands == 0) {
  478. freqLimiter[0] = freqLow[0] - kStart;
  479. freqLimiter[1] = freqLow[nLow] - kStart;
  480. return 1;
  481. }
  482. bands = limBandsPerOctave[limiterBands - 1];
  483. patchBorders[0] = kStart;
  484. /* from MPEG reference code - slightly different from spec (top border) */
  485. for (k = 1; k < numPatches; k++)
  486. patchBorders[k] = patchBorders[k-1] + patchNumSubbands[k-1];
  487. patchBorders[k] = freqLow[nLow];
  488. for (k = 0; k <= nLow; k++)
  489. freqLimiter[k] = freqLow[k];
  490. for (k = 1; k < numPatches; k++)
  491. freqLimiter[k+nLow] = patchBorders[k];
  492. k = 1;
  493. nLimiter = nLow + numPatches - 1;
  494. BubbleSort(freqLimiter, nLimiter + 1);
  495. while (k <= nLimiter) {
  496. nOctaves = log2Tab[freqLimiter[k]] - log2Tab[freqLimiter[k-1]]; /* Q28 */
  497. nOctaves = (nOctaves >> 9) * bands; /* Q19, max bands = 300 < 2^9 */
  498. if (nOctaves < (49 << 19)) { /* compare with 0.49*100, in Q19 */
  499. if (freqLimiter[k] == freqLimiter[k-1] || FindFreq(patchBorders, numPatches + 1, freqLimiter[k]) == 0) {
  500. RemoveFreq(freqLimiter, nLimiter + 1, k);
  501. nLimiter--;
  502. } else if (FindFreq(patchBorders, numPatches + 1, freqLimiter[k-1]) == 0) {
  503. RemoveFreq(freqLimiter, nLimiter + 1, k-1);
  504. nLimiter--;
  505. } else {
  506. k++;
  507. }
  508. } else {
  509. k++;
  510. }
  511. }
  512. /* store limiter boundaries as offsets from kStart */
  513. for (k = 0; k <= nLimiter; k++)
  514. freqLimiter[k] -= kStart;
  515. return nLimiter;
  516. }
  517. /**************************************************************************************
  518. * Function: CalcFreqTables
  519. *
  520. * Description: calulate master and derived frequency tables, and patches
  521. *
  522. * Inputs: initialized SBRHeader struct for this SCE/CPE block
  523. * initialized SBRFreq struct for this SCE/CPE block
  524. * sample rate index of output sample rate (after SBR)
  525. *
  526. * Outputs: master and derived frequency tables, and patches
  527. *
  528. * Return: non-zero if error, zero otherwise
  529. **************************************************************************************/
  530. int CalcFreqTables(SBRHeader *sbrHdr, SBRFreq *sbrFreq, int sampRateIdx)
  531. {
  532. int k0, k2;
  533. k0 = k0Tab[sampRateIdx][sbrHdr->startFreq];
  534. if (sbrHdr->stopFreq == 14)
  535. k2 = 2*k0;
  536. else if (sbrHdr->stopFreq == 15)
  537. k2 = 3*k0;
  538. else
  539. k2 = k2Tab[sampRateIdx][sbrHdr->stopFreq];
  540. if (k2 > 64)
  541. k2 = 64;
  542. /* calculate master frequency table */
  543. if (sbrHdr->freqScale == 0)
  544. sbrFreq->nMaster = CalcFreqMasterScaleZero(sbrFreq->freqMaster, sbrHdr->alterScale, k0, k2);
  545. else
  546. sbrFreq->nMaster = CalcFreqMaster(sbrFreq->freqMaster, sbrHdr->freqScale, sbrHdr->alterScale, k0, k2);
  547. /* calculate high frequency table and related parameters */
  548. sbrFreq->nHigh = CalcFreqHigh(sbrFreq->freqHigh, sbrFreq->freqMaster, sbrFreq->nMaster, sbrHdr->crossOverBand);
  549. sbrFreq->numQMFBands = sbrFreq->freqHigh[sbrFreq->nHigh] - sbrFreq->freqHigh[0];
  550. sbrFreq->kStart = sbrFreq->freqHigh[0];
  551. /* calculate low frequency table */
  552. sbrFreq->nLow = CalcFreqLow(sbrFreq->freqLow, sbrFreq->freqHigh, sbrFreq->nHigh);
  553. /* calculate noise floor frequency table */
  554. sbrFreq->numNoiseFloorBands = CalcFreqNoise(sbrFreq->freqNoise, sbrFreq->freqLow, sbrFreq->nLow, sbrFreq->kStart, k2, sbrHdr->noiseBands);
  555. /* calculate limiter table */
  556. sbrFreq->numPatches = BuildPatches(sbrFreq->patchNumSubbands, sbrFreq->patchStartSubband, sbrFreq->freqMaster,
  557. sbrFreq->nMaster, k0, sbrFreq->kStart, sbrFreq->numQMFBands, sampRateIdx);
  558. sbrFreq->nLimiter = CalcFreqLimiter(sbrFreq->freqLimiter, sbrFreq->patchNumSubbands, sbrFreq->freqLow, sbrFreq->nLow, sbrFreq->kStart,
  559. sbrHdr->limiterBands, sbrFreq->numPatches);
  560. return 0;
  561. }