📄 sbrhfadj.c
字号:
if (sbrHdr->limiterGains != 3) { q = MULSHIFT32(sumEOrigMapped, gainMax); /* Q(fbitsDQ - ACC_SCALE - 2), gainMax = Q30 */ z = CLZ(sumECurr) - 1; r = InvRNormalized(sumECurr << z); /* in = Q(z - eCurrExpMax), out = Q(29 + 31 - z + eCurrExpMax) */ gainMax = MULSHIFT32(q, r); /* Q(29 + 31 - z + eCurrExpMax + fbitsDQ - ACC_SCALE - 2 - 32) */ psi->gainMaxFBits = 26 - z + eCurrExpMax + fbitsDQ - ACC_SCALE; } } psi->sumEOrigMapped = sumEOrigMapped; psi->gainMax = gainMax;}/************************************************************************************** * Function: CalcNoiseDivFactors * * Description: calculate 1/(1+Q) and Q/(1+Q) (4.6.18.7.4; 4.6.18.7.5) * * Inputs: dequantized noise floor scalefactor * * Outputs: 1/(1+Q) and Q/(1+Q), format = Q31 * * Return: none **************************************************************************************/static void CalcNoiseDivFactors(int q, int *qp1Inv, int *qqp1Inv){ int z, qp1, t, s; /* 1 + Q_orig */ qp1 = (q >> 1); qp1 += (1 << (FBITS_OUT_DQ_NOISE - 1)); /* >> 1 to avoid overflow when adding 1.0 */ z = CLZ(qp1) - 1; /* z <= 31 - FBITS_OUT_DQ_NOISE */ qp1 <<= z; /* Q(FBITS_OUT_DQ_NOISE + z) = Q31 * 2^-(31 - (FBITS_OUT_DQ_NOISE + z)) */ t = InvRNormalized(qp1) << 1; /* Q30 * 2^(31 - (FBITS_OUT_DQ_NOISE + z)), guaranteed not to overflow */ /* normalize to Q31 */ s = (31 - (FBITS_OUT_DQ_NOISE - 1) - z - 1); /* clearly z >= 0, z <= (30 - (FBITS_OUT_DQ_NOISE - 1)) */ *qp1Inv = (t >> s); /* s = [0, 31 - FBITS_OUT_DQ_NOISE] */ *qqp1Inv = MULSHIFT32(t, q) << (32 - FBITS_OUT_DQ_NOISE - s);}/************************************************************************************** * Function: CalcComponentGains * * Description: calculate gain of envelope, sinusoids, and noise in one limiter band * (4.6.18.7.5) * * Inputs: initialized PSInfoSBR struct * initialized SBRHeader struct for this SCE/CPE block * initialized SBRGrid struct for this channel * initialized SBRFreq struct for this SCE/CPE block * initialized SBRChan struct for this channel * index of current channel (0 for SCE, 0 or 1 for CPE) * index of current envelope * index of current limiter band * number of fraction bits in dequantized envelope * * Outputs: gains for envelope, sinusoids and noise * number of fraction bits for envelope gain * sum of the total gain for each component in this band * other updated state variables * * Return: none **************************************************************************************/static void CalcComponentGains(PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch, int env, int lim, int fbitsDQ){ int d, m, mStart, mEnd, q, qm, noiseFloor, sIndexMapped; int shift, eCurr, maxFlag, gainMax, gainMaxFBits; int gain, sm, z, r, fbitsGain, gainScale; unsigned char *freqBandTab; mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */ mEnd = sbrFreq->freqLimiter[lim + 1]; gainMax = psi->gainMax; gainMaxFBits = psi->gainMaxFBits; d = (env == psi->la || env == sbrChan->laPrev ? 0 : 1); freqBandTab = (sbrGrid->freqRes[env] ? sbrFreq->freqHigh : sbrFreq->freqLow); /* figure out which noise floor this envelope is in (only 1 or 2 noise floors allowed) */ noiseFloor = 0; if (sbrGrid->numNoiseFloors == 2 && sbrGrid->noiseTimeBorder[1] <= sbrGrid->envTimeBorder[env]) noiseFloor++; psi->sumECurrGLim = 0; psi->sumSM = 0; psi->sumQM = 0; /* calculate energy of noise to add in this limiter band */ for (m = mStart; m < mEnd; m++) { if (m == sbrFreq->freqNoise[psi->noiseFloorBand + 1] - sbrFreq->kStart) { /* map current QMF band to appropriate noise floor band (NOTE: freqLimiter[0] == freqLow[0] = freqHigh[0]) */ psi->noiseFloorBand++; CalcNoiseDivFactors(psi->noiseDataDequant[ch][noiseFloor][psi->noiseFloorBand], &(psi->qp1Inv), &(psi->qqp1Inv)); } if (m == sbrFreq->freqHigh[psi->highBand + 1] - sbrFreq->kStart) psi->highBand++; if (m == freqBandTab[psi->sBand + 1] - sbrFreq->kStart) { psi->sBand++; psi->sMapped = GetSMapped(sbrGrid, sbrFreq, sbrChan, env, psi->sBand, psi->la); } /* get sIndexMapped for this QMF subband */ sIndexMapped = 0; r = ((sbrFreq->freqHigh[psi->highBand+1] + sbrFreq->freqHigh[psi->highBand]) >> 1); if (m + sbrFreq->kStart == r) { /* r = center frequency, deltaStep = (env >= la || sIndexMapped'(r, numEnv'-1) == 1) */ if (env >= psi->la || sbrChan->addHarmonic[0][r] == 1) sIndexMapped = sbrChan->addHarmonic[1][psi->highBand]; } /* save sine flags from last envelope in this frame: * addHarmonic[0][0...63] = saved sine present flag from previous frame, for each QMF subband * addHarmonic[1][0...nHigh-1] = addHarmonic bit from current frame, for each high-res frequency band * from MPEG reference code - slightly different from spec * (sIndexMapped'(m,LE'-1) can still be 0 when numEnv == psi->la) */ if (env == sbrGrid->numEnv - 1) { if (m + sbrFreq->kStart == r) sbrChan->addHarmonic[0][m + sbrFreq->kStart] = sbrChan->addHarmonic[1][psi->highBand]; else sbrChan->addHarmonic[0][m + sbrFreq->kStart] = 0; } gain = psi->envDataDequant[ch][env][psi->sBand]; qm = MULSHIFT32(gain, psi->qqp1Inv) << 1; sm = (sIndexMapped ? MULSHIFT32(gain, psi->qp1Inv) << 1 : 0); /* three cases: (sMapped == 0 && delta == 1), (sMapped == 0 && delta == 0), (sMapped == 1) */ if (d == 1 && psi->sMapped == 0) gain = MULSHIFT32(psi->qp1Inv, gain) << 1; else if (psi->sMapped != 0) gain = MULSHIFT32(psi->qqp1Inv, gain) << 1; /* gain, qm, sm = Q(fbitsDQ), gainMax = Q(fbitsGainMax) */ eCurr = psi->eCurr[m]; if (eCurr) { z = CLZ(eCurr) - 1; r = InvRNormalized(eCurr << z); /* in = Q(z - eCurrExp), out = Q(29 + 31 - z + eCurrExp) */ gainScale = MULSHIFT32(gain, r); /* out = Q(29 + 31 - z + eCurrExp + fbitsDQ - 32) */ fbitsGain = 29 + 31 - z + psi->eCurrExp[m] + fbitsDQ - 32; } else { /* if eCurr == 0, then gain is unchanged (divide by EPS = 1) */ gainScale = gain; fbitsGain = fbitsDQ; } /* see if gain for this band exceeds max gain */ maxFlag = 0; if (gainMax != (int)0x80000000) { if (fbitsGain >= gainMaxFBits) { shift = MIN(fbitsGain - gainMaxFBits, 31); maxFlag = ((gainScale >> shift) > gainMax ? 1 : 0); } else { shift = MIN(gainMaxFBits - fbitsGain, 31); maxFlag = (gainScale > (gainMax >> shift) ? 1 : 0); } } if (maxFlag) { /* gainScale > gainMax, calculate ratio with 32/16 division */ q = 0; r = gainScale; /* guaranteed > 0, else maxFlag could not have been set */ z = CLZ(r); if (z < 16) { q = 16 - z; r >>= q; /* out = Q(fbitsGain - q) */ } z = CLZ(gainMax) - 1; r = (gainMax << z) / r; /* out = Q((fbitsGainMax + z) - (fbitsGain - q)) */ q = (gainMaxFBits + z) - (fbitsGain - q); /* r = Q(q) */ if (q > 30) { r >>= MIN(q - 30, 31); } else { z = MIN(30 - q, 30); CLIP_2N_SHIFT30(r, z); /* let r = Q30 since range = [0.0, 1.0) (clip to 0x3fffffff = 0.99999) */ } qm = MULSHIFT32(qm, r) << 2; gain = MULSHIFT32(gain, r) << 2; psi->gLimBuf[m] = gainMax; psi->gLimFbits[m] = gainMaxFBits; } else { psi->gLimBuf[m] = gainScale; psi->gLimFbits[m] = fbitsGain; } /* sumSM, sumQM, sumECurrGLim = Q(fbitsDQ - ACC_SCALE) */ psi->smBuf[m] = sm; psi->sumSM += (sm >> ACC_SCALE); psi->qmLimBuf[m] = qm; if (env != psi->la && env != sbrChan->laPrev && sm == 0) psi->sumQM += (qm >> ACC_SCALE); /* eCurr * gain^2 same as gain^2, before division by eCurr * (but note that gain != 0 even if eCurr == 0, since it's divided by eps) */ if (eCurr) psi->sumECurrGLim += (gain >> ACC_SCALE); }}/************************************************************************************** * Function: ApplyBoost * * Description: calculate and apply boost factor for envelope, sinusoids, and noise * in this limiter band (4.6.18.7.5) * * Inputs: initialized PSInfoSBR struct * initialized SBRFreq struct for this SCE/CPE block * index of current limiter band * number of fraction bits in dequantized envelope * * Outputs: envelope gain, sinusoids and noise after scaling by gBoost * format = Q(FBITS_GLIM_BOOST) for envelope gain, * = Q(FBITS_QLIM_BOOST) for noise * = Q(FBITS_OUT_QMFA) for sinusoids * * Return: none * * Notes: after scaling, each component has at least 1 GB **************************************************************************************/static void ApplyBoost(PSInfoSBR *psi, SBRFreq *sbrFreq, int lim, int fbitsDQ){ int m, mStart, mEnd, q, z, r; int sumEOrigMapped, gBoost; mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */ mEnd = sbrFreq->freqLimiter[lim + 1]; sumEOrigMapped = psi->sumEOrigMapped >> 1; r = (psi->sumECurrGLim >> 1) + (psi->sumSM >> 1) + (psi->sumQM >> 1); /* 1 GB fine (sm and qm are mutually exclusive in acc) */ if (r < (1 << (31-28))) { /* any non-zero numerator * 1/EPS_0 is > GBOOST_MAX * round very small r to zero to avoid scaling problems */ gBoost = (sumEOrigMapped == 0 ? (1 << 28) : GBOOST_MAX); z = 0; } else if (sumEOrigMapped == 0) { /* 1/(any non-zero denominator) * EPS_0 is appx. 0 */ gBoost = 0; z = 0; } else { /* numerator (sumEOrigMapped) and denominator (r) have same Q format (before << z) */ z = CLZ(r) - 1; /* z = [0, 27] */ r = InvRNormalized(r << z); gBoost = MULSHIFT32(sumEOrigMapped, r); } /* gBoost = Q(28 - z) */ if (gBoost > (GBOOST_MAX >> z)) { gBoost = GBOOST_MAX; z = 0; } gBoost <<= z; /* gBoost = Q28, minimum 1 GB */ /* convert gain, noise, sinusoids to fixed Q format, clipping if necessary * (rare, usually only happens at very low bitrates, introduces slight * distortion into final HF mapping, but should be inaudible) */ for (m = mStart; m < mEnd; m++) { /* let gLimBoost = Q24, since in practice the max values are usually 16 to 20 * unless limiterGains == 3 (limiter off) and eCurr ~= 0 (i.e. huge gain, but only * because the envelope has 0 power anyway) */ q = MULSHIFT32(psi->gLimBuf[m], gBoost) << 2; /* Q(gLimFbits) * Q(28) --> Q(gLimFbits[m]-2) */ r = SqrtFix(q, psi->gLimFbits[m] - 2, &z); z -= FBITS_GLIM_BOOST; if (z >= 0) { psi->gLimBoost[m] = r >> MIN(z, 31); } else { z = MIN(30, -z); CLIP_2N_SHIFT30(r, z); psi->gLimBoost[m] = r; } q = MULSHIFT32(psi->qmLimBuf[m], gBoost) << 2; /* Q(fbitsDQ) * Q(28) --> Q(fbitsDQ-2) */ r = SqrtFix(q, fbitsDQ - 2, &z); z -= FBITS_QLIM_BOOST; /* << by 14, since integer sqrt of x < 2^16, and we want to leave 1 GB */ if (z >= 0) { psi->qmLimBoost[m] = r >> MIN(31, z); } else { z = MIN(30, -z); CLIP_2N_SHIFT30(r, z);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -