2
0

sbrhfadj.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Source last modified: $Id: sbrhfadj.c,v 1.3 2005/05/24 16:01:55 albertofloyd 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. * sbrhfadj.c - high frequency adjustment for SBR
  43. **************************************************************************************/
  44. #include "sbr.h"
  45. #include "assembly.h"
  46. /* invBandTab[i] = 1.0 / (i + 1), Q31 */
  47. static const int invBandTab[64] PROGMEM = {
  48. 0x7fffffff, 0x40000000, 0x2aaaaaab, 0x20000000, 0x1999999a, 0x15555555, 0x12492492, 0x10000000,
  49. 0x0e38e38e, 0x0ccccccd, 0x0ba2e8ba, 0x0aaaaaab, 0x09d89d8a, 0x09249249, 0x08888889, 0x08000000,
  50. 0x07878788, 0x071c71c7, 0x06bca1af, 0x06666666, 0x06186186, 0x05d1745d, 0x0590b216, 0x05555555,
  51. 0x051eb852, 0x04ec4ec5, 0x04bda12f, 0x04924925, 0x0469ee58, 0x04444444, 0x04210842, 0x04000000,
  52. 0x03e0f83e, 0x03c3c3c4, 0x03a83a84, 0x038e38e4, 0x03759f23, 0x035e50d8, 0x03483483, 0x03333333,
  53. 0x031f3832, 0x030c30c3, 0x02fa0be8, 0x02e8ba2f, 0x02d82d83, 0x02c8590b, 0x02b93105, 0x02aaaaab,
  54. 0x029cbc15, 0x028f5c29, 0x02828283, 0x02762762, 0x026a439f, 0x025ed098, 0x0253c825, 0x02492492,
  55. 0x023ee090, 0x0234f72c, 0x022b63cc, 0x02222222, 0x02192e2a, 0x02108421, 0x02082082, 0x02000000,
  56. };
  57. /**************************************************************************************
  58. * Function: EstimateEnvelope
  59. *
  60. * Description: estimate power of generated HF QMF bands in one time-domain envelope
  61. * (4.6.18.7.3)
  62. *
  63. * Inputs: initialized PSInfoSBR struct
  64. * initialized SBRHeader struct for this SCE/CPE block
  65. * initialized SBRGrid struct for this channel
  66. * initialized SBRFreq struct for this SCE/CPE block
  67. * index of current envelope
  68. *
  69. * Outputs: power of each QMF subband, stored as integer (Q0) * 2^N, N >= 0
  70. *
  71. * Return: none
  72. **************************************************************************************/
  73. static void EstimateEnvelope(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, int env)
  74. {
  75. int i, m, iStart, iEnd, xre, xim, nScale, expMax;
  76. int p, n, mStart, mEnd, invFact, t;
  77. int *XBuf;
  78. U64 eCurr;
  79. unsigned char *freqBandTab;
  80. /* estimate current envelope */
  81. iStart = sbrGrid->envTimeBorder[env] + HF_ADJ;
  82. iEnd = sbrGrid->envTimeBorder[env+1] + HF_ADJ;
  83. if (sbrGrid->freqRes[env]) {
  84. n = sbrFreq->nHigh;
  85. freqBandTab = sbrFreq->freqHigh;
  86. } else {
  87. n = sbrFreq->nLow;
  88. freqBandTab = sbrFreq->freqLow;
  89. }
  90. /* ADS should inline MADD64 (smlal) properly, but check to make sure */
  91. expMax = 0;
  92. if (sbrHdr->interpFreq) {
  93. for (m = 0; m < sbrFreq->numQMFBands; m++) {
  94. eCurr.w64 = 0;
  95. XBuf = psi->XBuf[iStart][sbrFreq->kStart + m];
  96. for (i = iStart; i < iEnd; i++) {
  97. /* scale to int before calculating power (precision not critical, and avoids overflow) */
  98. xre = (*XBuf) >> FBITS_OUT_QMFA; XBuf += 1;
  99. xim = (*XBuf) >> FBITS_OUT_QMFA; XBuf += (2*64 - 1);
  100. eCurr.w64 = MADD64(eCurr.w64, xre, xre);
  101. eCurr.w64 = MADD64(eCurr.w64, xim, xim);
  102. }
  103. /* eCurr.w64 is now Q(64 - 2*FBITS_OUT_QMFA) (64-bit word)
  104. * if energy is too big to fit in 32-bit word (> 2^31) scale down by power of 2
  105. */
  106. nScale = 0;
  107. if (eCurr.r.hi32) {
  108. nScale = (32 - CLZ(eCurr.r.hi32)) + 1;
  109. t = (int)(eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */
  110. t |= eCurr.r.hi32 << (32 - nScale);
  111. } else if (eCurr.r.lo32 >> 31) {
  112. nScale = 1;
  113. t = (int)(eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */
  114. } else {
  115. t = (int)eCurr.r.lo32;
  116. }
  117. invFact = invBandTab[(iEnd - iStart)-1];
  118. psi->eCurr[m] = MULSHIFT32(t, invFact);
  119. psi->eCurrExp[m] = nScale + 1; /* +1 for invFact = Q31 */
  120. if (psi->eCurrExp[m] > expMax)
  121. expMax = psi->eCurrExp[m];
  122. }
  123. } else {
  124. for (p = 0; p < n; p++) {
  125. mStart = freqBandTab[p];
  126. mEnd = freqBandTab[p+1];
  127. eCurr.w64 = 0;
  128. for (i = iStart; i < iEnd; i++) {
  129. XBuf = psi->XBuf[i][mStart];
  130. for (m = mStart; m < mEnd; m++) {
  131. xre = (*XBuf++) >> FBITS_OUT_QMFA;
  132. xim = (*XBuf++) >> FBITS_OUT_QMFA;
  133. eCurr.w64 = MADD64(eCurr.w64, xre, xre);
  134. eCurr.w64 = MADD64(eCurr.w64, xim, xim);
  135. }
  136. }
  137. nScale = 0;
  138. if (eCurr.r.hi32) {
  139. nScale = (32 - CLZ(eCurr.r.hi32)) + 1;
  140. t = (int)(eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */
  141. t |= eCurr.r.hi32 << (32 - nScale);
  142. } else if (eCurr.r.lo32 >> 31) {
  143. nScale = 1;
  144. t = (int)(eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */
  145. } else {
  146. t = (int)eCurr.r.lo32;
  147. }
  148. invFact = invBandTab[(iEnd - iStart)-1];
  149. invFact = MULSHIFT32(invBandTab[(mEnd - mStart)-1], invFact) << 1;
  150. t = MULSHIFT32(t, invFact);
  151. for (m = mStart; m < mEnd; m++) {
  152. psi->eCurr[m - sbrFreq->kStart] = t;
  153. psi->eCurrExp[m - sbrFreq->kStart] = nScale + 1; /* +1 for invFact = Q31 */
  154. }
  155. if (psi->eCurrExp[mStart - sbrFreq->kStart] > expMax)
  156. expMax = psi->eCurrExp[mStart - sbrFreq->kStart];
  157. }
  158. }
  159. psi->eCurrExpMax = expMax;
  160. }
  161. /**************************************************************************************
  162. * Function: GetSMapped
  163. *
  164. * Description: calculate SMapped (4.6.18.7.2)
  165. *
  166. * Inputs: initialized PSInfoSBR struct
  167. * initialized SBRGrid struct for this channel
  168. * initialized SBRFreq struct for this SCE/CPE block
  169. * initialized SBRChan struct for this channel
  170. * index of current envelope
  171. * index of current QMF band
  172. * la flag for this envelope
  173. *
  174. * Outputs: none
  175. *
  176. * Return: 1 if a sinusoid is present in this band, 0 if not
  177. **************************************************************************************/
  178. static int GetSMapped(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int env, int band, int la)
  179. {
  180. int bandStart, bandEnd, oddFlag, r;
  181. if (sbrGrid->freqRes[env]) {
  182. /* high resolution */
  183. bandStart = band;
  184. bandEnd = band+1;
  185. } else {
  186. /* low resolution (see CalcFreqLow() for mapping) */
  187. oddFlag = sbrFreq->nHigh & 0x01;
  188. bandStart = (band > 0 ? 2*band - oddFlag : 0); /* starting index for freqLow[band] */
  189. bandEnd = 2*(band+1) - oddFlag; /* ending index for freqLow[band+1] */
  190. }
  191. /* sMapped = 1 if sIndexMapped == 1 for any frequency in this band */
  192. for (band = bandStart; band < bandEnd; band++) {
  193. if (sbrChan->addHarmonic[1][band]) {
  194. r = ((sbrFreq->freqHigh[band+1] + sbrFreq->freqHigh[band]) >> 1);
  195. if (env >= la || sbrChan->addHarmonic[0][r] == 1)
  196. return 1;
  197. }
  198. }
  199. return 0;
  200. }
  201. #define GBOOST_MAX 0x2830afd3 /* Q28, 1.584893192 squared */
  202. #define ACC_SCALE 6
  203. /* squared version of table in 4.6.18.7.5 */
  204. static const int limGainTab[4] PROGMEM = {0x20138ca7, 0x40000000, 0x7fb27dce, 0x80000000}; /* Q30 (0x80000000 = sentinel for GMAX) */
  205. /**************************************************************************************
  206. * Function: CalcMaxGain
  207. *
  208. * Description: calculate max gain in one limiter band (4.6.18.7.5)
  209. *
  210. * Inputs: initialized PSInfoSBR struct
  211. * initialized SBRHeader struct for this SCE/CPE block
  212. * initialized SBRGrid struct for this channel
  213. * initialized SBRFreq struct for this SCE/CPE block
  214. * index of current channel (0 for SCE, 0 or 1 for CPE)
  215. * index of current envelope
  216. * index of current limiter band
  217. * number of fraction bits in dequantized envelope
  218. * (max = Q(FBITS_OUT_DQ_ENV - 6) = Q23, can go negative)
  219. *
  220. * Outputs: updated gainMax, gainMaxFBits, and sumEOrigMapped in PSInfoSBR struct
  221. *
  222. * Return: none
  223. **************************************************************************************/
  224. static void CalcMaxGain(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, int ch, int env, int lim, int fbitsDQ)
  225. {
  226. int m, mStart, mEnd, q, z, r;
  227. int sumEOrigMapped, sumECurr, gainMax, eOMGainMax, envBand;
  228. unsigned char eCurrExpMax;
  229. unsigned char *freqBandTab;
  230. mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */
  231. mEnd = sbrFreq->freqLimiter[lim + 1];
  232. freqBandTab = (sbrGrid->freqRes[env] ? sbrFreq->freqHigh : sbrFreq->freqLow);
  233. /* calculate max gain to apply to signal in this limiter band */
  234. sumECurr = 0;
  235. sumEOrigMapped = 0;
  236. eCurrExpMax = psi->eCurrExpMax;
  237. eOMGainMax = psi->eOMGainMax;
  238. envBand = psi->envBand;
  239. for (m = mStart; m < mEnd; m++) {
  240. /* map current QMF band to appropriate envelope band */
  241. if (m == freqBandTab[envBand + 1] - sbrFreq->kStart) {
  242. envBand++;
  243. eOMGainMax = psi->envDataDequant[ch][env][envBand] >> ACC_SCALE; /* summing max 48 bands */
  244. }
  245. sumEOrigMapped += eOMGainMax;
  246. /* easy test for overflow on ARM */
  247. sumECurr += (psi->eCurr[m] >> (eCurrExpMax - psi->eCurrExp[m]));
  248. if (sumECurr >> 30) {
  249. sumECurr >>= 1;
  250. eCurrExpMax++;
  251. }
  252. }
  253. psi->eOMGainMax = eOMGainMax;
  254. psi->envBand = envBand;
  255. psi->gainMaxFBits = 30; /* Q30 tables */
  256. if (sumECurr == 0) {
  257. /* any non-zero numerator * 1/EPS_0 is > G_MAX */
  258. gainMax = (sumEOrigMapped == 0 ? (int)limGainTab[sbrHdr->limiterGains] : (int)0x80000000);
  259. } else if (sumEOrigMapped == 0) {
  260. /* 1/(any non-zero denominator) * EPS_0 * limGainTab[x] is appx. 0 */
  261. gainMax = 0;
  262. } else {
  263. /* sumEOrigMapped = Q(fbitsDQ - ACC_SCALE), sumECurr = Q(-eCurrExpMax) */
  264. gainMax = limGainTab[sbrHdr->limiterGains];
  265. if (sbrHdr->limiterGains != 3) {
  266. q = MULSHIFT32(sumEOrigMapped, gainMax); /* Q(fbitsDQ - ACC_SCALE - 2), gainMax = Q30 */
  267. z = CLZ(sumECurr) - 1;
  268. r = InvRNormalized(sumECurr << z); /* in = Q(z - eCurrExpMax), out = Q(29 + 31 - z + eCurrExpMax) */
  269. gainMax = MULSHIFT32(q, r); /* Q(29 + 31 - z + eCurrExpMax + fbitsDQ - ACC_SCALE - 2 - 32) */
  270. psi->gainMaxFBits = 26 - z + eCurrExpMax + fbitsDQ - ACC_SCALE;
  271. }
  272. }
  273. psi->sumEOrigMapped = sumEOrigMapped;
  274. psi->gainMax = gainMax;
  275. }
  276. /**************************************************************************************
  277. * Function: CalcNoiseDivFactors
  278. *
  279. * Description: calculate 1/(1+Q) and Q/(1+Q) (4.6.18.7.4; 4.6.18.7.5)
  280. *
  281. * Inputs: dequantized noise floor scalefactor
  282. *
  283. * Outputs: 1/(1+Q) and Q/(1+Q), format = Q31
  284. *
  285. * Return: none
  286. **************************************************************************************/
  287. static void CalcNoiseDivFactors(int q, int *qp1Inv, int *qqp1Inv)
  288. {
  289. int z, qp1, t, s;
  290. /* 1 + Q_orig */
  291. qp1 = (q >> 1);
  292. qp1 += (1 << (FBITS_OUT_DQ_NOISE - 1)); /* >> 1 to avoid overflow when adding 1.0 */
  293. z = CLZ(qp1) - 1; /* z <= 31 - FBITS_OUT_DQ_NOISE */
  294. qp1 <<= z; /* Q(FBITS_OUT_DQ_NOISE + z) = Q31 * 2^-(31 - (FBITS_OUT_DQ_NOISE + z)) */
  295. t = InvRNormalized(qp1) << 1; /* Q30 * 2^(31 - (FBITS_OUT_DQ_NOISE + z)), guaranteed not to overflow */
  296. /* normalize to Q31 */
  297. s = (31 - (FBITS_OUT_DQ_NOISE - 1) - z - 1); /* clearly z >= 0, z <= (30 - (FBITS_OUT_DQ_NOISE - 1)) */
  298. *qp1Inv = (t >> s); /* s = [0, 31 - FBITS_OUT_DQ_NOISE] */
  299. *qqp1Inv = MULSHIFT32(t, q) << (32 - FBITS_OUT_DQ_NOISE - s);
  300. }
  301. /**************************************************************************************
  302. * Function: CalcComponentGains
  303. *
  304. * Description: calculate gain of envelope, sinusoids, and noise in one limiter band
  305. * (4.6.18.7.5)
  306. *
  307. * Inputs: initialized PSInfoSBR struct
  308. * initialized SBRHeader struct for this SCE/CPE block
  309. * initialized SBRGrid struct for this channel
  310. * initialized SBRFreq struct for this SCE/CPE block
  311. * initialized SBRChan struct for this channel
  312. * index of current channel (0 for SCE, 0 or 1 for CPE)
  313. * index of current envelope
  314. * index of current limiter band
  315. * number of fraction bits in dequantized envelope
  316. *
  317. * Outputs: gains for envelope, sinusoids and noise
  318. * number of fraction bits for envelope gain
  319. * sum of the total gain for each component in this band
  320. * other updated state variables
  321. *
  322. * Return: none
  323. **************************************************************************************/
  324. static void CalcComponentGains(PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch, int env, int lim, int fbitsDQ)
  325. {
  326. int d, m, mStart, mEnd, q, qm, noiseFloor, sIndexMapped;
  327. int shift, eCurr, maxFlag, gainMax, gainMaxFBits;
  328. int gain, sm, z, r, fbitsGain, gainScale;
  329. unsigned char *freqBandTab;
  330. mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */
  331. mEnd = sbrFreq->freqLimiter[lim + 1];
  332. gainMax = psi->gainMax;
  333. gainMaxFBits = psi->gainMaxFBits;
  334. d = (env == psi->la || env == sbrChan->laPrev ? 0 : 1);
  335. freqBandTab = (sbrGrid->freqRes[env] ? sbrFreq->freqHigh : sbrFreq->freqLow);
  336. /* figure out which noise floor this envelope is in (only 1 or 2 noise floors allowed) */
  337. noiseFloor = 0;
  338. if (sbrGrid->numNoiseFloors == 2 && sbrGrid->noiseTimeBorder[1] <= sbrGrid->envTimeBorder[env])
  339. noiseFloor++;
  340. psi->sumECurrGLim = 0;
  341. psi->sumSM = 0;
  342. psi->sumQM = 0;
  343. /* calculate energy of noise to add in this limiter band */
  344. for (m = mStart; m < mEnd; m++) {
  345. if (m == sbrFreq->freqNoise[psi->noiseFloorBand + 1] - sbrFreq->kStart) {
  346. /* map current QMF band to appropriate noise floor band (NOTE: freqLimiter[0] == freqLow[0] = freqHigh[0]) */
  347. psi->noiseFloorBand++;
  348. CalcNoiseDivFactors(psi->noiseDataDequant[ch][noiseFloor][psi->noiseFloorBand], &(psi->qp1Inv), &(psi->qqp1Inv));
  349. }
  350. if (m == sbrFreq->freqHigh[psi->highBand + 1] - sbrFreq->kStart)
  351. psi->highBand++;
  352. if (m == freqBandTab[psi->sBand + 1] - sbrFreq->kStart) {
  353. psi->sBand++;
  354. psi->sMapped = GetSMapped(sbrGrid, sbrFreq, sbrChan, env, psi->sBand, psi->la);
  355. }
  356. /* get sIndexMapped for this QMF subband */
  357. sIndexMapped = 0;
  358. r = ((sbrFreq->freqHigh[psi->highBand+1] + sbrFreq->freqHigh[psi->highBand]) >> 1);
  359. if (m + sbrFreq->kStart == r) {
  360. /* r = center frequency, deltaStep = (env >= la || sIndexMapped'(r, numEnv'-1) == 1) */
  361. if (env >= psi->la || sbrChan->addHarmonic[0][r] == 1)
  362. sIndexMapped = sbrChan->addHarmonic[1][psi->highBand];
  363. }
  364. /* save sine flags from last envelope in this frame:
  365. * addHarmonic[0][0...63] = saved sine present flag from previous frame, for each QMF subband
  366. * addHarmonic[1][0...nHigh-1] = addHarmonic bit from current frame, for each high-res frequency band
  367. * from MPEG reference code - slightly different from spec
  368. * (sIndexMapped'(m,LE'-1) can still be 0 when numEnv == psi->la)
  369. */
  370. if (env == sbrGrid->numEnv - 1) {
  371. if (m + sbrFreq->kStart == r)
  372. sbrChan->addHarmonic[0][m + sbrFreq->kStart] = sbrChan->addHarmonic[1][psi->highBand];
  373. else
  374. sbrChan->addHarmonic[0][m + sbrFreq->kStart] = 0;
  375. }
  376. gain = psi->envDataDequant[ch][env][psi->sBand];
  377. qm = MULSHIFT32(gain, psi->qqp1Inv) << 1;
  378. sm = (sIndexMapped ? MULSHIFT32(gain, psi->qp1Inv) << 1 : 0);
  379. /* three cases: (sMapped == 0 && delta == 1), (sMapped == 0 && delta == 0), (sMapped == 1) */
  380. if (d == 1 && psi->sMapped == 0)
  381. gain = MULSHIFT32(psi->qp1Inv, gain) << 1;
  382. else if (psi->sMapped != 0)
  383. gain = MULSHIFT32(psi->qqp1Inv, gain) << 1;
  384. /* gain, qm, sm = Q(fbitsDQ), gainMax = Q(fbitsGainMax) */
  385. eCurr = psi->eCurr[m];
  386. if (eCurr) {
  387. z = CLZ(eCurr) - 1;
  388. r = InvRNormalized(eCurr << z); /* in = Q(z - eCurrExp), out = Q(29 + 31 - z + eCurrExp) */
  389. gainScale = MULSHIFT32(gain, r); /* out = Q(29 + 31 - z + eCurrExp + fbitsDQ - 32) */
  390. fbitsGain = 29 + 31 - z + psi->eCurrExp[m] + fbitsDQ - 32;
  391. } else {
  392. /* if eCurr == 0, then gain is unchanged (divide by EPS = 1) */
  393. gainScale = gain;
  394. fbitsGain = fbitsDQ;
  395. }
  396. /* see if gain for this band exceeds max gain */
  397. maxFlag = 0;
  398. if (gainMax != (int)0x80000000) {
  399. if (fbitsGain >= gainMaxFBits) {
  400. shift = MIN(fbitsGain - gainMaxFBits, 31);
  401. maxFlag = ((gainScale >> shift) > gainMax ? 1 : 0);
  402. } else {
  403. shift = MIN(gainMaxFBits - fbitsGain, 31);
  404. maxFlag = (gainScale > (gainMax >> shift) ? 1 : 0);
  405. }
  406. }
  407. if (maxFlag) {
  408. /* gainScale > gainMax, calculate ratio with 32/16 division */
  409. q = 0;
  410. r = gainScale; /* guaranteed > 0, else maxFlag could not have been set */
  411. z = CLZ(r);
  412. if (z < 16) {
  413. q = 16 - z;
  414. r >>= q; /* out = Q(fbitsGain - q) */
  415. }
  416. z = CLZ(gainMax) - 1;
  417. r = (gainMax << z) / r; /* out = Q((fbitsGainMax + z) - (fbitsGain - q)) */
  418. q = (gainMaxFBits + z) - (fbitsGain - q); /* r = Q(q) */
  419. if (q > 30) {
  420. r >>= MIN(q - 30, 31);
  421. } else {
  422. z = MIN(30 - q, 30);
  423. CLIP_2N_SHIFT30(r, z); /* let r = Q30 since range = [0.0, 1.0) (clip to 0x3fffffff = 0.99999) */
  424. }
  425. qm = MULSHIFT32(qm, r) << 2;
  426. gain = MULSHIFT32(gain, r) << 2;
  427. psi->gLimBuf[m] = gainMax;
  428. psi->gLimFbits[m] = gainMaxFBits;
  429. } else {
  430. psi->gLimBuf[m] = gainScale;
  431. psi->gLimFbits[m] = fbitsGain;
  432. }
  433. /* sumSM, sumQM, sumECurrGLim = Q(fbitsDQ - ACC_SCALE) */
  434. psi->smBuf[m] = sm;
  435. psi->sumSM += (sm >> ACC_SCALE);
  436. psi->qmLimBuf[m] = qm;
  437. if (env != psi->la && env != sbrChan->laPrev && sm == 0)
  438. psi->sumQM += (qm >> ACC_SCALE);
  439. /* eCurr * gain^2 same as gain^2, before division by eCurr
  440. * (but note that gain != 0 even if eCurr == 0, since it's divided by eps)
  441. */
  442. if (eCurr)
  443. psi->sumECurrGLim += (gain >> ACC_SCALE);
  444. }
  445. }
  446. /**************************************************************************************
  447. * Function: ApplyBoost
  448. *
  449. * Description: calculate and apply boost factor for envelope, sinusoids, and noise
  450. * in this limiter band (4.6.18.7.5)
  451. *
  452. * Inputs: initialized PSInfoSBR struct
  453. * initialized SBRFreq struct for this SCE/CPE block
  454. * index of current limiter band
  455. * number of fraction bits in dequantized envelope
  456. *
  457. * Outputs: envelope gain, sinusoids and noise after scaling by gBoost
  458. * format = Q(FBITS_GLIM_BOOST) for envelope gain,
  459. * = Q(FBITS_QLIM_BOOST) for noise
  460. * = Q(FBITS_OUT_QMFA) for sinusoids
  461. *
  462. * Return: none
  463. *
  464. * Notes: after scaling, each component has at least 1 GB
  465. **************************************************************************************/
  466. static void ApplyBoost(PSInfoSBR *psi, SBRFreq *sbrFreq, int lim, int fbitsDQ)
  467. {
  468. int m, mStart, mEnd, q, z, r;
  469. int sumEOrigMapped, gBoost;
  470. mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */
  471. mEnd = sbrFreq->freqLimiter[lim + 1];
  472. sumEOrigMapped = psi->sumEOrigMapped >> 1;
  473. r = (psi->sumECurrGLim >> 1) + (psi->sumSM >> 1) + (psi->sumQM >> 1); /* 1 GB fine (sm and qm are mutually exclusive in acc) */
  474. if (r < (1 << (31-28))) {
  475. /* any non-zero numerator * 1/EPS_0 is > GBOOST_MAX
  476. * round very small r to zero to avoid scaling problems
  477. */
  478. gBoost = (sumEOrigMapped == 0 ? (1 << 28) : GBOOST_MAX);
  479. z = 0;
  480. } else if (sumEOrigMapped == 0) {
  481. /* 1/(any non-zero denominator) * EPS_0 is appx. 0 */
  482. gBoost = 0;
  483. z = 0;
  484. } else {
  485. /* numerator (sumEOrigMapped) and denominator (r) have same Q format (before << z) */
  486. z = CLZ(r) - 1; /* z = [0, 27] */
  487. r = InvRNormalized(r << z);
  488. gBoost = MULSHIFT32(sumEOrigMapped, r);
  489. }
  490. /* gBoost = Q(28 - z) */
  491. if (gBoost > (GBOOST_MAX >> z)) {
  492. gBoost = GBOOST_MAX;
  493. z = 0;
  494. }
  495. gBoost <<= z; /* gBoost = Q28, minimum 1 GB */
  496. /* convert gain, noise, sinusoids to fixed Q format, clipping if necessary
  497. * (rare, usually only happens at very low bitrates, introduces slight
  498. * distortion into final HF mapping, but should be inaudible)
  499. */
  500. for (m = mStart; m < mEnd; m++) {
  501. /* let gLimBoost = Q24, since in practice the max values are usually 16 to 20
  502. * unless limiterGains == 3 (limiter off) and eCurr ~= 0 (i.e. huge gain, but only
  503. * because the envelope has 0 power anyway)
  504. */
  505. q = MULSHIFT32(psi->gLimBuf[m], gBoost) << 2; /* Q(gLimFbits) * Q(28) --> Q(gLimFbits[m]-2) */
  506. r = SqrtFix(q, psi->gLimFbits[m] - 2, &z);
  507. z -= FBITS_GLIM_BOOST;
  508. if (z >= 0) {
  509. psi->gLimBoost[m] = r >> MIN(z, 31);
  510. } else {
  511. z = MIN(30, -z);
  512. CLIP_2N_SHIFT30(r, z);
  513. psi->gLimBoost[m] = r;
  514. }
  515. q = MULSHIFT32(psi->qmLimBuf[m], gBoost) << 2; /* Q(fbitsDQ) * Q(28) --> Q(fbitsDQ-2) */
  516. r = SqrtFix(q, fbitsDQ - 2, &z);
  517. z -= FBITS_QLIM_BOOST; /* << by 14, since integer sqrt of x < 2^16, and we want to leave 1 GB */
  518. if (z >= 0) {
  519. psi->qmLimBoost[m] = r >> MIN(31, z);
  520. } else {
  521. z = MIN(30, -z);
  522. CLIP_2N_SHIFT30(r, z);
  523. psi->qmLimBoost[m] = r;
  524. }
  525. q = MULSHIFT32(psi->smBuf[m], gBoost) << 2; /* Q(fbitsDQ) * Q(28) --> Q(fbitsDQ-2) */
  526. r = SqrtFix(q, fbitsDQ - 2, &z);
  527. z -= FBITS_OUT_QMFA; /* justify for adding to signal (xBuf) later */
  528. if (z >= 0) {
  529. psi->smBoost[m] = r >> MIN(31, z);
  530. } else {
  531. z = MIN(30, -z);
  532. CLIP_2N_SHIFT30(r, z);
  533. psi->smBoost[m] = r;
  534. }
  535. }
  536. }
  537. /**************************************************************************************
  538. * Function: CalcGain
  539. *
  540. * Description: calculate and apply proper gain to HF components in one envelope
  541. * (4.6.18.7.5)
  542. *
  543. * Inputs: initialized PSInfoSBR struct
  544. * initialized SBRHeader struct for this SCE/CPE block
  545. * initialized SBRGrid struct for this channel
  546. * initialized SBRFreq struct for this SCE/CPE block
  547. * initialized SBRChan struct for this channel
  548. * index of current channel (0 for SCE, 0 or 1 for CPE)
  549. * index of current envelope
  550. *
  551. * Outputs: envelope gain, sinusoids and noise after scaling
  552. *
  553. * Return: none
  554. **************************************************************************************/
  555. static void CalcGain(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch, int env)
  556. {
  557. int lim, fbitsDQ;
  558. /* initialize to -1 so that mapping limiter bands to env/noise bands works right on first pass */
  559. psi->envBand = -1;
  560. psi->noiseFloorBand = -1;
  561. psi->sBand = -1;
  562. psi->highBand = -1;
  563. fbitsDQ = (FBITS_OUT_DQ_ENV - psi->envDataDequantScale[ch][env]); /* Q(29 - optional scalefactor) */
  564. for (lim = 0; lim < sbrFreq->nLimiter; lim++) {
  565. /* the QMF bands are divided into lim regions (consecutive, non-overlapping) */
  566. CalcMaxGain(psi, sbrHdr, sbrGrid, sbrFreq, ch, env, lim, fbitsDQ);
  567. CalcComponentGains(psi, sbrGrid, sbrFreq, sbrChan, ch, env, lim, fbitsDQ);
  568. ApplyBoost(psi, sbrFreq, lim, fbitsDQ);
  569. }
  570. }
  571. /* hSmooth table from 4.7.18.7.6, format = Q31 */
  572. static const int hSmoothCoef[MAX_NUM_SMOOTH_COEFS] PROGMEM = {
  573. 0x2aaaaaab, 0x2697a512, 0x1becfa68, 0x0ebdb043, 0x04130598,
  574. };
  575. /**************************************************************************************
  576. * Function: MapHF
  577. *
  578. * Description: map HF components to proper QMF bands, with optional gain smoothing
  579. * filter (4.6.18.7.6)
  580. *
  581. * Inputs: initialized PSInfoSBR struct
  582. * initialized SBRHeader struct for this SCE/CPE block
  583. * initialized SBRGrid struct for this channel
  584. * initialized SBRFreq struct for this SCE/CPE block
  585. * initialized SBRChan struct for this channel
  586. * index of current envelope
  587. * reset flag (can be non-zero for first envelope only)
  588. *
  589. * Outputs: complete reconstructed subband QMF samples for this envelope
  590. *
  591. * Return: none
  592. *
  593. * Notes: ensures that output has >= MIN_GBITS_IN_QMFS guard bits,
  594. * so it's not necessary to check anything in the synth QMF
  595. **************************************************************************************/
  596. static void MapHF(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int env, int hfReset)
  597. {
  598. int noiseTabIndex, sinIndex, gainNoiseIndex, hSL;
  599. int i, iStart, iEnd, m, idx, j, s, n, smre, smim;
  600. int gFilt, qFilt, xre, xim, gbMask, gbIdx;
  601. int *XBuf;
  602. noiseTabIndex = sbrChan->noiseTabIndex;
  603. sinIndex = sbrChan->sinIndex;
  604. gainNoiseIndex = sbrChan->gainNoiseIndex; /* oldest entries in filter delay buffer */
  605. if (hfReset)
  606. noiseTabIndex = 2; /* starts at 1, double since complex */
  607. hSL = (sbrHdr->smoothMode ? 0 : 4);
  608. if (hfReset) {
  609. for (i = 0; i < hSL; i++) {
  610. for (m = 0; m < sbrFreq->numQMFBands; m++) {
  611. sbrChan->gTemp[gainNoiseIndex][m] = psi->gLimBoost[m];
  612. sbrChan->qTemp[gainNoiseIndex][m] = psi->qmLimBoost[m];
  613. }
  614. gainNoiseIndex++;
  615. if (gainNoiseIndex == MAX_NUM_SMOOTH_COEFS)
  616. gainNoiseIndex = 0;
  617. }
  618. ASSERT(env == 0); /* should only be reset when env == 0 */
  619. }
  620. iStart = sbrGrid->envTimeBorder[env];
  621. iEnd = sbrGrid->envTimeBorder[env+1];
  622. for (i = iStart; i < iEnd; i++) {
  623. /* save new values in temp buffers (delay)
  624. * we only store MAX_NUM_SMOOTH_COEFS most recent values,
  625. * so don't keep storing the same value over and over
  626. */
  627. if (i - iStart < MAX_NUM_SMOOTH_COEFS) {
  628. for (m = 0; m < sbrFreq->numQMFBands; m++) {
  629. sbrChan->gTemp[gainNoiseIndex][m] = psi->gLimBoost[m];
  630. sbrChan->qTemp[gainNoiseIndex][m] = psi->qmLimBoost[m];
  631. }
  632. }
  633. /* see 4.6.18.7.6 */
  634. XBuf = psi->XBuf[i + HF_ADJ][sbrFreq->kStart];
  635. gbMask = 0;
  636. for (m = 0; m < sbrFreq->numQMFBands; m++) {
  637. if (env == psi->la || env == sbrChan->laPrev) {
  638. /* no smoothing filter for gain, and qFilt = 0 (only need to do once) */
  639. if (i == iStart) {
  640. psi->gFiltLast[m] = sbrChan->gTemp[gainNoiseIndex][m];
  641. psi->qFiltLast[m] = 0;
  642. }
  643. } else if (hSL == 0) {
  644. /* no smoothing filter for gain, (only need to do once) */
  645. if (i == iStart) {
  646. psi->gFiltLast[m] = sbrChan->gTemp[gainNoiseIndex][m];
  647. psi->qFiltLast[m] = sbrChan->qTemp[gainNoiseIndex][m];
  648. }
  649. } else {
  650. /* apply smoothing filter to gain and noise (after MAX_NUM_SMOOTH_COEFS, it's always the same) */
  651. if (i - iStart < MAX_NUM_SMOOTH_COEFS) {
  652. gFilt = 0;
  653. qFilt = 0;
  654. idx = gainNoiseIndex;
  655. for (j = 0; j < MAX_NUM_SMOOTH_COEFS; j++) {
  656. /* sum(abs(hSmoothCoef[j])) for all j < 1.0 */
  657. gFilt += MULSHIFT32(sbrChan->gTemp[idx][m], hSmoothCoef[j]);
  658. qFilt += MULSHIFT32(sbrChan->qTemp[idx][m], hSmoothCoef[j]);
  659. idx--;
  660. if (idx < 0)
  661. idx += MAX_NUM_SMOOTH_COEFS;
  662. }
  663. psi->gFiltLast[m] = gFilt << 1; /* restore to Q(FBITS_GLIM_BOOST) (gain of filter < 1.0, so no overflow) */
  664. psi->qFiltLast[m] = qFilt << 1; /* restore to Q(FBITS_QLIM_BOOST) */
  665. }
  666. }
  667. if (psi->smBoost[m] != 0) {
  668. /* add scaled signal and sinusoid, don't add noise (qFilt = 0) */
  669. smre = psi->smBoost[m];
  670. smim = smre;
  671. /* sinIndex: [0] xre += sm [1] xim += sm*s [2] xre -= sm [3] xim -= sm*s */
  672. s = (sinIndex >> 1); /* if 2 or 3, flip sign to subtract sm */
  673. s <<= 31;
  674. smre ^= (s >> 31);
  675. smre -= (s >> 31);
  676. s ^= ((m + sbrFreq->kStart) << 31);
  677. smim ^= (s >> 31);
  678. smim -= (s >> 31);
  679. /* if sinIndex == 0 or 2, smim = 0; if sinIndex == 1 or 3, smre = 0 */
  680. s = sinIndex << 31;
  681. smim &= (s >> 31);
  682. s ^= 0x80000000;
  683. smre &= (s >> 31);
  684. noiseTabIndex += 2; /* noise filtered by 0, but still need to bump index */
  685. } else {
  686. /* add scaled signal and scaled noise */
  687. qFilt = psi->qFiltLast[m];
  688. n = noiseTab[noiseTabIndex++];
  689. smre = MULSHIFT32(n, qFilt) >> (FBITS_QLIM_BOOST - 1 - FBITS_OUT_QMFA);
  690. n = noiseTab[noiseTabIndex++];
  691. smim = MULSHIFT32(n, qFilt) >> (FBITS_QLIM_BOOST - 1 - FBITS_OUT_QMFA);
  692. }
  693. noiseTabIndex &= 1023; /* 512 complex numbers */
  694. gFilt = psi->gFiltLast[m];
  695. xre = MULSHIFT32(gFilt, XBuf[0]);
  696. xim = MULSHIFT32(gFilt, XBuf[1]);
  697. CLIP_2N_SHIFT30(xre, 32 - FBITS_GLIM_BOOST);
  698. CLIP_2N_SHIFT30(xim, 32 - FBITS_GLIM_BOOST);
  699. xre += smre; *XBuf++ = xre;
  700. xim += smim; *XBuf++ = xim;
  701. gbMask |= FASTABS(xre);
  702. gbMask |= FASTABS(xim);
  703. }
  704. /* update circular buffer index */
  705. gainNoiseIndex++;
  706. if (gainNoiseIndex == MAX_NUM_SMOOTH_COEFS)
  707. gainNoiseIndex = 0;
  708. sinIndex++;
  709. sinIndex &= 3;
  710. /* ensure MIN_GBITS_IN_QMFS guard bits in output
  711. * almost never occurs in practice, but checking here makes synth QMF logic very simple
  712. */
  713. if (gbMask >> (31 - MIN_GBITS_IN_QMFS)) {
  714. XBuf = psi->XBuf[i + HF_ADJ][sbrFreq->kStart];
  715. for (m = 0; m < sbrFreq->numQMFBands; m++) {
  716. xre = XBuf[0]; xim = XBuf[1];
  717. CLIP_2N(xre, (31 - MIN_GBITS_IN_QMFS));
  718. CLIP_2N(xim, (31 - MIN_GBITS_IN_QMFS));
  719. *XBuf++ = xre; *XBuf++ = xim;
  720. }
  721. CLIP_2N(gbMask, (31 - MIN_GBITS_IN_QMFS));
  722. }
  723. gbIdx = ((i + HF_ADJ) >> 5) & 0x01;
  724. sbrChan->gbMask[gbIdx] |= gbMask;
  725. }
  726. sbrChan->noiseTabIndex = noiseTabIndex;
  727. sbrChan->sinIndex = sinIndex;
  728. sbrChan->gainNoiseIndex = gainNoiseIndex;
  729. }
  730. /**************************************************************************************
  731. * Function: AdjustHighFreq
  732. *
  733. * Description: adjust high frequencies and add noise and sinusoids (4.6.18.7)
  734. *
  735. * Inputs: initialized PSInfoSBR struct
  736. * initialized SBRHeader struct for this SCE/CPE block
  737. * initialized SBRGrid struct for this channel
  738. * initialized SBRFreq struct for this SCE/CPE block
  739. * initialized SBRChan struct for this channel
  740. * index of current channel (0 for SCE, 0 or 1 for CPE)
  741. *
  742. * Outputs: complete reconstructed subband QMF samples for this channel
  743. *
  744. * Return: none
  745. **************************************************************************************/
  746. void AdjustHighFreq(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch)
  747. {
  748. int i, env, hfReset;
  749. unsigned char frameClass, pointer;
  750. frameClass = sbrGrid->frameClass;
  751. pointer = sbrGrid->pointer;
  752. /* derive la from table 4.159 */
  753. if ((frameClass == SBR_GRID_FIXVAR || frameClass == SBR_GRID_VARVAR) && pointer > 0)
  754. psi->la = sbrGrid->numEnv + 1 - pointer;
  755. else if (frameClass == SBR_GRID_VARFIX && pointer > 1)
  756. psi->la = pointer - 1;
  757. else
  758. psi->la = -1;
  759. /* for each envelope, estimate gain and adjust SBR QMF bands */
  760. hfReset = sbrChan->reset;
  761. for (env = 0; env < sbrGrid->numEnv; env++) {
  762. EstimateEnvelope(psi, sbrHdr, sbrGrid, sbrFreq, env);
  763. CalcGain(psi, sbrHdr, sbrGrid, sbrFreq, sbrChan, ch, env);
  764. MapHF(psi, sbrHdr, sbrGrid, sbrFreq, sbrChan, env, hfReset);
  765. hfReset = 0; /* only set for first envelope after header reset */
  766. }
  767. /* set saved sine flags to 0 for QMF bands outside of current frequency range */
  768. for (i = 0; i < sbrFreq->freqLimiter[0] + sbrFreq->kStart; i++)
  769. sbrChan->addHarmonic[0][i] = 0;
  770. for (i = sbrFreq->freqLimiter[sbrFreq->nLimiter] + sbrFreq->kStart; i < 64; i++)
  771. sbrChan->addHarmonic[0][i] = 0;
  772. sbrChan->addHarmonicFlag[0] = sbrChan->addHarmonicFlag[1];
  773. /* save la for next frame */
  774. if (psi->la == sbrGrid->numEnv)
  775. sbrChan->laPrev = 0;
  776. else
  777. sbrChan->laPrev = -1;
  778. }