diff --git a/src/lib/bitAllocation.cpp b/src/lib/bitAllocation.cpp index 0499549..d21bd14 100644 --- a/src/lib/bitAllocation.cpp +++ b/src/lib/bitAllocation.cpp @@ -165,7 +165,7 @@ unsigned BitAllocator::initSfbStepSizes (const SfbGroupData* const groupData[USA const uint32_t* rms = grpData.sfbRmsValues; uint32_t* stepSizes = &sfbStepSizes[ch * numSwbShort * NUM_WINDOW_GROUPS]; // --- apply INTRA-channel simultaneous masking, equal-loudness weighting, and thresholding to SFB RMS data - uint32_t maskingSlope = 0, b, elw = 58254; // 8/9 + uint32_t maskingSlope = 0, gr, b, elw = 58254; // 8/9 uint32_t rmsEqualLoud = 0; uint32_t sumStepSizes = 0; @@ -185,7 +185,7 @@ unsigned BitAllocator::initSfbStepSizes (const SfbGroupData* const groupData[USA } if ((ch == lfeChannelIndex) || (grpData.numWindowGroups != 1)) // LFE, SHORT windows: no masking or ELW { - for (unsigned gr = 0; gr < grpData.numWindowGroups; gr++) + for (gr = 0; gr < grpData.numWindowGroups; gr++) { const uint32_t* gRms = &rms[numSwbShort * gr]; uint32_t* gStepSizes = &stepSizes[numSwbShort * gr]; @@ -207,11 +207,43 @@ unsigned BitAllocator::initSfbStepSizes (const SfbGroupData* const groupData[USA { // --- SHORT windows: apply perceptual just noticeable difference (JND) model and local band-peak smoothing nMeans++; + + for (b = maxSfbInCh - 1; b > 0; b--) // gentle temporal band-peak smoothing; a spectral one follows + { + uint32_t maxGrpStep = stepSizes[b], stepSizeM1 = BA_EPS; + + for (gr = 1; gr < grpData.numWindowGroups; gr++) + { + const uint32_t curGrpStep = stepSizes[b + numSwbShort * gr]; + + if (curGrpStep > maxGrpStep) maxGrpStep = curGrpStep; + } + for (gr = 0; gr + 1 < grpData.numWindowGroups; gr++) + { + const uint32_t newGrpStep = __max (stepSizeM1, stepSizes[b + numSwbShort * (gr + 1)]); + + stepSizeM1 = stepSizes[b + numSwbShort * gr]; + + if ((stepSizeM1 == maxGrpStep) && (maxGrpStep > newGrpStep)) + { + sumStepSizes -= unsigned (0.5 + sqrt ((double) maxGrpStep)); + stepSizes[b + numSwbShort * gr] = newGrpStep; + sumStepSizes += unsigned (0.5 + sqrt ((double) newGrpStep)); + } + } + if ((stepSizes[b + numSwbShort * gr] == maxGrpStep) && (maxGrpStep > stepSizeM1)) + { + sumStepSizes -= unsigned (0.5 + sqrt ((double) maxGrpStep)); + stepSizes[b + numSwbShort * gr] = stepSizeM1; + sumStepSizes += unsigned (0.5 + sqrt ((double) stepSizeM1)); + } + } // for b + m_avgStepSize[ch] = __min (USHRT_MAX, uint32_t ((sumStepSizes + (nBandsInCh >> 1)) / nBandsInCh)); sumMeans += m_avgStepSize[ch]; m_avgStepSize[ch] *= m_avgStepSize[ch]; - for (unsigned gr = 0; gr < grpData.numWindowGroups; gr++) // separate peak smoothing for each group + for (gr = 0; gr < grpData.numWindowGroups; gr++) // separate spectral peak smoothing for each group { jndPowerLawAndPeakSmoothing (&stepSizes[numSwbShort * gr], maxSfbInCh, m_avgStepSize[ch], m_avgSpecFlat[ch], 0); } diff --git a/src/lib/exhaleEnc.cpp b/src/lib/exhaleEnc.cpp index cc211d1..0a1eaff 100644 --- a/src/lib/exhaleEnc.cpp +++ b/src/lib/exhaleEnc.cpp @@ -1024,7 +1024,7 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en const uint8_t maxSfbShort = (samplingRate < 37566 ? 14 /*32 kHz*/ : brModeAndFsToMaxSfbShort(m_bitRateMode, samplingRate)); const uint16_t peakIndex = (shortWinCurr ? 0 : (m_specAnaCurr[ci] >> 5) & 2047); const unsigned sfmBasedSfbStart = (shortWinCurr ? maxSfbShort : maxSfbLong) - 5 + (m_bitRateMode >> 1) + (meanSpecFlat[ci] >> 5); - const unsigned targetBitCountX2 = ((54000 + 18000 * m_bitRateMode) * nSamplesInFrame) / (samplingRate * grpData.numWindowGroups); + const unsigned targetBitCount25 = ((60000 + 20000 * m_bitRateMode) * nSamplesInFrame) / (samplingRate * ((grpData.numWindowGroups + 1) >> 1)); unsigned b = grpData.sfbsPerGroup - 1; if ((grpRms[b] >> 16) > 0) lastSfb = b; @@ -1033,7 +1033,7 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en #if EC_TRELLIS_OPT_CODING if (grpLength == 1) // finalize bit count estimate, RDOC { - estimBitCount = m_sfbQuantizer.quantizeSpecRDOC (entrCoder, grpScaleFacs, __min (estimBitCount + 2, targetBitCountX2), + estimBitCount = m_sfbQuantizer.quantizeSpecRDOC (entrCoder, grpScaleFacs, __min (estimBitCount + 2, targetBitCount25), grpOff, grpRms, grpData.sfbsPerGroup, m_mdctQuantMag[ci]); for (b = 1; b < grpData.sfbsPerGroup; b++) { @@ -1056,7 +1056,7 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en #endif b = lastSfb; while ((b >= sfmBasedSfbStart) && (grpOff[b] > peakIndex) && ((grpRms[b] >> 16) <= 1) /*coarse quantization*/ && - ((estimBitCount * 9 > targetBitCountX2 * 4) || (grpLength > 1 /*no accurate bit count est. available*/))) + ((estimBitCount * 5 > targetBitCount25 * 2) || (grpLength > 1 /*no accurate bit count est. available*/))) { b--; // search first coarsely quantized high-freq. SFB } @@ -1087,7 +1087,7 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en } } - if (estimBitCount > targetBitCountX2) // too many bits!! + if (estimBitCount > targetBitCount25) // too many bits!! { for (b = lastSOff; b > 0; b--) { @@ -1108,7 +1108,7 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en grpRms[b] += 3 + entrCoder.indexGetBitCount ((int) grpScaleFacs[b] - grpScaleFacs[b - 1]); estimBitCount += grpRms[b] & USHRT_MAX; } - if (estimBitCount <= targetBitCountX2) break; + if (estimBitCount <= targetBitCount25) break; } for (b++; b <= lastSfb; b++) // re-repeat scale factor @@ -1118,7 +1118,7 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en grpScaleFacs[b] = grpScaleFacs[b - 1]; } } - } // if estimBitCount > targetBitCountX2 + } // if estimBitCount > targetBitCount25 for (b = lastSfb + 1; b < grpData.sfbsPerGroup; b++) {