bugfix, rate tuning

This commit is contained in:
Christian R. Helmrich
2020-11-25 01:00:00 +01:00
parent f1d66fb3e4
commit 7f47aaab53
5 changed files with 113 additions and 83 deletions

View File

@@ -116,62 +116,61 @@ unsigned BitStreamWriter::writeChannelWiseSbrData (const int32_t* const sbrDataC
const bool indepFlag /*= false*/) const bool indepFlag /*= false*/)
{ {
const unsigned nb = (sbrDataCh0 != nullptr ? 2 * ((sbrDataCh0[0] >> 23) & 1) + 2 : 0); // noise bits/ch = 2 or 4 const unsigned nb = (sbrDataCh0 != nullptr ? 2 * ((sbrDataCh0[0] >> 23) & 1) + 2 : 0); // noise bits/ch = 2 or 4
#if ENABLE_INTERTES const unsigned ob = (indepFlag ? 1 : 0); // indepFlag dependent bit offset
const bool issTes = (nb > 0 ? ((sbrDataCh0[0] >> 30) & 1) : false);
const int8_t res = (nb > 0 ? (sbrDataCh0[0] >> 29) & 1 : 0); // bs_amp_res
#else
const int16_t res = (nb > 0 ? sbrDataCh0[0] >> 29 : 0); // short bs_amp_res
#endif
const bool stereo = (sbrDataCh1 != nullptr); const bool stereo = (sbrDataCh1 != nullptr);
const bool couple = (stereo ? ((sbrDataCh1[0] >> 23) & 1) : false); const int32_t ch0 = (nb > 0 ? sbrDataCh0[0] : 0);
const int32_t ch1 = (stereo ? sbrDataCh1[0] : 0);
#if ENABLE_INTERTES
const bool issTes = (((ch0 >> 30) & 1) != 0);
const int8_t res = (ch0 >> 29) & 1; // bs_amp_res
#else
const int16_t res = ch0 >> 29; // short bs_amp_res
#endif
const bool couple = (((ch1 >> 23) & 1) != 0);
unsigned bitCount = (stereo ? (couple ? 2 : 7 + nb) : 0) + 6 + nb; unsigned bitCount = (stereo ? (couple ? 2 : 7 + nb) : 0) + 6 + nb;
unsigned i, envCh0, envCh1, resCh0, resCh1; // bs_num_env[], bs_freq_res[] unsigned i, envCh0, envCh1, resCh0, resCh1; // bs_num_env[], bs_freq_res[]
if (nb == 0) return 0; if (nb == 0) return 0;
envCh0 = 1 << ((sbrDataCh0[0] >> 21) & 3); envCh0 = 1 << ((ch0 >> 21) & 3);
resCh0 = (sbrDataCh0[0] >> 20) & 1; resCh0 = (ch0 >> 20) & 1;
envCh1 = 1 << (((stereo && !couple ? sbrDataCh1[0] : sbrDataCh0[0]) >> 21) & 3); envCh1 = 1 << (((stereo && !couple ? ch1 : ch0) >> 21) & 3);
resCh1 = ((stereo && !couple ? sbrDataCh1[0] : sbrDataCh0[0]) >> 20) & 1; resCh1 = ((stereo && !couple ? ch1 : ch0) >> 20) & 1;
if (stereo) m_auBitStream.write (couple ? 1 : 0, 1); // _coupling if (stereo) m_auBitStream.write (couple ? 1 : 0, 1); // _coupling
// sbr_grid(), assumes bs_frame_class[ch] == 0, i.e. class FIXFIX // sbr_grid(), assumes bs_frame_class[ch] == 0, i.e. class FIXFIX
m_auBitStream.write ((sbrDataCh0[0] >> 20) & 7, 5); // class data m_auBitStream.write ((ch0 >> 20) & 7, 5);
if (stereo && !couple) m_auBitStream.write ((sbrDataCh1[0] >> 20) & 7, 5); if (stereo && !couple) m_auBitStream.write ((ch1 >> 20) & 7, 5);
// sbr_dtdf(), assumes bs_pvc == 0, i.e. no PVC like rest of code // sbr_dtdf(), assumes bs_pvc == 0, i.e. no PVC like rest of code
i = envCh0 - (indepFlag ? 1 : 0); for (i = ob; i < envCh0; i++) m_auBitStream.write ((ch0 >> (12 + i)) & 1, 1);
if (i > 0) m_auBitStream.write ((sbrDataCh0[0] >> 12) & 255, i); // _df_env bitCount += i - ob;
bitCount += i; for (i = ob; i < __min (2, envCh0); i++) m_auBitStream.write ((ch0 >> (4 + i)) & 1, 1);
i = __min (2, envCh0) - (indepFlag ? 1 : 0); bitCount += i - ob;
if (i > 0) m_auBitStream.write ((sbrDataCh0[0] >> 4) & 255, i); // df_noise
bitCount += i;
if (stereo) if (stereo)
{ {
i = envCh1 - (indepFlag ? 1 : 0); for (i = ob; i < envCh1; i++) m_auBitStream.write ((ch1 >> (12 + i)) & 1, 1);
if (i > 0) m_auBitStream.write ((sbrDataCh1[0] >> 12) & 255, i); bitCount += i - ob;
bitCount += i; for (i = ob; i < __min (2, envCh1); i++) m_auBitStream.write ((ch1 >> (4 + i)) & 1, 1);
i = __min (2, envCh1) - (indepFlag ? 1 : 0); bitCount += i - ob;
if (i > 0) m_auBitStream.write ((sbrDataCh1[0] >> 4) & 255, i);
bitCount += i;
} }
// sbr_invf(), assumes dflt_noise_bands < 3, i.e. 1-2 noise bands // sbr_invf(), assumes dflt_noise_bands < 3, i.e. 1-2 noise bands
i = 6 * nb - 9; // bitmask = 3 or 15 i = 6 * nb - 9;
m_auBitStream.write (sbrDataCh0[0] & i, nb); // bs_invf_mode[0][] m_auBitStream.write (ch0 & i, nb); // 3 or 15-bit bs_invf_mode[0]
if (stereo && !couple) m_auBitStream.write (sbrDataCh1[0] & i, nb); if (stereo && !couple) m_auBitStream.write (ch1 & i, nb);
// sbr_envelope() for mono/left channel, assumes bs_df_env[] == 0 // sbr_envelope() for mono/left channel, assumes bs_df_env[] == 0
for (i = 1; i <= envCh0; i++) // dt loop for (i = 1; i <= envCh0; i++) // dt loop
{ {
const uint8_t bits = (res > 0 && envCh0 > 1 ? 6 : 7); // start const uint8_t bits = ((ch0 & (1 << (11 + i))) != 0 ? 2 : (res > 0 && envCh0 > 1 ? 6 : 7));
const uint8_t bitd = (2 + 3 * resCh0) * 2; // differential, <25 TODO: VLC words const uint8_t bitd = (2 + 3 * resCh0) * 2; // differential, <25 TODO: VLC words
m_auBitStream.write (sbrDataCh0[i] & 127, bits); // bs_data_env m_auBitStream.write (sbrDataCh0[i] & 127, bits); // bs_data_env
bitCount += bits; bitCount += bits;
m_auBitStream.write (sbrDataCh0[i] >> 7, bitd); m_auBitStream.write ((sbrDataCh0[i] >> 7) & ((1 << bitd) - 1), bitd);
bitCount += bitd; bitCount += bitd;
#if ENABLE_INTERTES #if ENABLE_INTERTES
if (issTes) if (issTes)
@@ -191,12 +190,12 @@ unsigned BitStreamWriter::writeChannelWiseSbrData (const int32_t* const sbrDataC
{ {
for (i = 1; i <= envCh1; i++) // decoup. sbr_envelope() dt loop for (i = 1; i <= envCh1; i++) // decoup. sbr_envelope() dt loop
{ {
const uint8_t bits = (res > 0 && envCh1 > 1 ? 6 : 7); const uint8_t bits = ((ch1 & (1 << (11 + i))) != 0 ? 2 : (res > 0 && envCh1 > 1 ? 6 : 7));
const uint8_t bitd = (2 + 3 * resCh1) * 2; // TODO: VLC words const uint8_t bitd = (2 + 3 * resCh1) * 2; // TODO: VLC words
m_auBitStream.write (sbrDataCh1[i] & 127, bits); m_auBitStream.write (sbrDataCh1[i] & 127, bits);
bitCount += bits; bitCount += bits;
m_auBitStream.write (sbrDataCh1[i] >> 7, bitd); m_auBitStream.write ((sbrDataCh1[i] >> 7) & ((1 << bitd) - 1), bitd);
bitCount += bitd; bitCount += bitd;
#if ENABLE_INTERTES #if ENABLE_INTERTES
if (issTes) if (issTes)
@@ -214,10 +213,12 @@ unsigned BitStreamWriter::writeChannelWiseSbrData (const int32_t* const sbrDataC
} }
// sbr_noise() for mono/left channel, assumes bs_df_noise[i] == 0 // sbr_noise() for mono/left channel, assumes bs_df_noise[i] == 0
for (i = __min (2, envCh0); i > 0; i--) // dt loop for (i = 1; i <= __min (2, envCh0); i++) // dt loop
{ {
m_auBitStream.write ((sbrDataCh0[9] >> (13 * i)) & 31, 5); // _data_noise const uint8_t bits = ((ch0 & (1 << (3 + i))) != 0 ? 1 : 5);
bitCount += 5;
m_auBitStream.write ((sbrDataCh0[9] >> (13 * i)) & 31, bits); // _noise[]
bitCount += bits;
if (nb == 4) if (nb == 4)
{ {
m_auBitStream.write ((sbrDataCh0[9] >> (13 * i - 5)) & 31, 1); // TODO: VLC word m_auBitStream.write ((sbrDataCh0[9] >> (13 * i - 5)) & 31, 1); // TODO: VLC word
@@ -231,12 +232,12 @@ unsigned BitStreamWriter::writeChannelWiseSbrData (const int32_t* const sbrDataC
{ {
for (i = 1; i <= envCh1; i++) // coup. sbr_envelope() dt loop for (i = 1; i <= envCh1; i++) // coup. sbr_envelope() dt loop
{ {
const uint8_t bits = (res > 0 && envCh1 > 1 ? 5 : 6); const uint8_t bits = ((ch1 & (1 << (11 + i))) != 0 ? 1 : (res > 0 && envCh1 > 1 ? 5 : 6));
const uint8_t bitd = (2 + 3 * resCh1) * 2; // TODO: VLC words const uint8_t bitd = (2 + 3 * resCh1) * 1; // TODO: VLC words
m_auBitStream.write (sbrDataCh1[i] & 63, bits); m_auBitStream.write (sbrDataCh1[i] & 63, bits);
bitCount += bits; bitCount += bits;
m_auBitStream.write (sbrDataCh1[i] >> 7, bitd); m_auBitStream.write ((sbrDataCh1[i] >> 7) & ((1 << bitd) - 1), bitd);
bitCount += bitd; bitCount += bitd;
#if ENABLE_INTERTES #if ENABLE_INTERTES
if (issTes) if (issTes)
@@ -253,10 +254,12 @@ unsigned BitStreamWriter::writeChannelWiseSbrData (const int32_t* const sbrDataC
} }
} }
for (i = __min (2, envCh1); i > 0; i--) // sbr_noise() dt loop for (i = 1; i <= __min (2, envCh1); i++) // sbr_noise() dt loop
{ {
m_auBitStream.write ((sbrDataCh1[9] >> (13 * i)) & 31, 5); const uint8_t bits = ((ch1 & (1 << (3 + i))) != 0 ? 1 : 5);
bitCount += 5;
m_auBitStream.write ((sbrDataCh1[9] >> (13 * i)) & 31, bits);
bitCount += bits;
if (nb == 4) if (nb == 4)
{ {
m_auBitStream.write ((sbrDataCh1[9] >> (13 * i - 5)) & 31, 1); // TODO: VLC word m_auBitStream.write ((sbrDataCh1[9] >> (13 * i - 5)) & 31, 1); // TODO: VLC word

View File

@@ -464,6 +464,8 @@ static const uint8_t tnsScaleFactorBandLimit[2 /*long/short*/][USAC_NUM_FREQ_TAB
#endif #endif
}; };
static const uint8_t sbrRateOffset[10] = {8, 6, 6, 8, 7, 8, 8, 8, 8, 8}; // used for scaleSBR
// scale_factor_grouping map // scale_factor_grouping map
// group lengths based on transient location: 1133, 1115, 2114, 3113, 4112, 5111, 3311, 1331 // group lengths based on transient location: 1133, 1115, 2114, 3113, 4112, 5111, 3311, 1331
static const uint8_t scaleFactorGrouping[8] = {0x1B, 0x0F, 0x47, 0x63, 0x71, 0x78, 0x6C, 0x36}; static const uint8_t scaleFactorGrouping[8] = {0x1B, 0x0F, 0x47, 0x63, 0x71, 0x78, 0x6C, 0x36};
@@ -767,8 +769,8 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
const unsigned samplingRate = toSamplingRate (m_frequencyIdx); const unsigned samplingRate = toSamplingRate (m_frequencyIdx);
const unsigned lfeChannelIndex = (m_channelConf >= CCI_6_CH ? __max (5, nChannels - 1) : USAC_MAX_NUM_CHANNELS); const unsigned lfeChannelIndex = (m_channelConf >= CCI_6_CH ? __max (5, nChannels - 1) : USAC_MAX_NUM_CHANNELS);
const bool useMaxBandwidth = (samplingRate < 37566 || m_shiftValSBR > 0); const bool useMaxBandwidth = (samplingRate < 37566 || m_shiftValSBR > 0);
const uint32_t maxSfbLong = (useMaxBandwidth ? m_numSwbLong : brModeAndFsToMaxSfbLong (m_bitRateMode, samplingRate)); const uint8_t maxSfbLong = (useMaxBandwidth ? m_numSwbLong : brModeAndFsToMaxSfbLong (m_bitRateMode, samplingRate));
const uint32_t scaleSBR = (m_shiftValSBR > 0 || m_nonMpegExt ? (m_bitRateMode == 0 ? 8 : 6 + ((m_bitRateMode + 2 - samplingRate/24000) >> 2)) : 0); // -25% rate const uint16_t scaleSBR = (m_shiftValSBR > 0 || m_nonMpegExt ? sbrRateOffset[m_bitRateMode] : 0); // -25% rate
const uint64_t scaleSr = (samplingRate < 27713 ? (samplingRate < 23004 ? 32 : 34) - __min (3 << m_shiftValSBR, m_bitRateMode) const uint64_t scaleSr = (samplingRate < 27713 ? (samplingRate < 23004 ? 32 : 34) - __min (3 << m_shiftValSBR, m_bitRateMode)
: (samplingRate < 37566 && m_bitRateMode != 3u ? 36 : 37)) - (nChannels >> 1); : (samplingRate < 37566 && m_bitRateMode != 3u ? 36 : 37)) - (nChannels >> 1);
const uint64_t scaleBr = (m_bitRateMode == 0 ? __min (32, 3 + (samplingRate >> 10) + (samplingRate >> 13) - (nChannels >> 1)) const uint64_t scaleBr = (m_bitRateMode == 0 ? __min (32, 3 + (samplingRate >> 10) + (samplingRate >> 13) - (nChannels >> 1))
@@ -972,7 +974,7 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
: brModeAndFsToMaxSfbShort (m_bitRateMode, samplingRate)) : maxSfbLong); : brModeAndFsToMaxSfbShort (m_bitRateMode, samplingRate)) : maxSfbLong);
const bool keepMaxSfbCurr = ((samplingRate < 37566) || (samplingRate >= 46009 && samplingRate < 55426 && eightShorts)); const bool keepMaxSfbCurr = ((samplingRate < 37566) || (samplingRate >= 46009 && samplingRate < 55426 && eightShorts));
const uint8_t numSwbFrame = __min ((numSwbCh * ((maxSfbCh == maxSfbCurr) || (m_bitRateMode <= 2) || (m_shiftValSBR > 0) ? 4u : 3u)) >> 2, const uint8_t numSwbFrame = __min ((numSwbCh * ((maxSfbCh == maxSfbCurr) || (m_bitRateMode <= 2) || (m_shiftValSBR > 0) ? 4u : 3u)) >> 2,
(eightShorts ? maxSfbCh : maxSfbLong) + (m_bitRateMode < 2 || m_bitRateMode > 3 || keepMaxSfbCurr ? 0 : 1)); (eightShorts ? maxSfbCh : maxSfbLong) + (m_bitRateMode < 2 || m_bitRateMode > 3 || keepMaxSfbCurr ? 0u : 1u));
#ifndef NO_DTX_MODE #ifndef NO_DTX_MODE
if ((m_bitRateMode < 1) && (m_numElements == 1) && (samplingRate < 27713) && eightShorts) if ((m_bitRateMode < 1) && (m_numElements == 1) && (samplingRate < 27713) && eightShorts)
{ {
@@ -1312,9 +1314,7 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en
memset (m_coreSignals[ci], 0, 10 * sizeof (int32_t)); memset (m_coreSignals[ci], 0, 10 * sizeof (int32_t));
#if ENABLE_INTERTES #if ENABLE_INTERTES
m_coreSignals[ci][0] = (shortWinPrev ? 0x40000000 : 0x40100000); // freq_res, interTes m_coreSignals[ci][0] = 0x40000000; // bs_interTes = 1 for all frames
#else
m_coreSignals[ci][0] = (shortWinPrev ? 0 : 1) << 20; // bs_freq_res = low resp. high
#endif #endif
m_coreSignals[ci][0] |= 4 - int32_t (sqrt (0.75 * msfVal)); // filter mode, 0 = none m_coreSignals[ci][0] |= 4 - int32_t (sqrt (0.75 * msfVal)); // filter mode, 0 = none
@@ -1326,11 +1326,12 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en
} }
m_coreSignals[ci][0] |= getSbrEnvelopeAndNoise (&m_coreSignals[ci][nSamplesTempAna - 64 + nSamplesInFrame], msfVal, m_coreSignals[ci][0] |= getSbrEnvelopeAndNoise (&m_coreSignals[ci][nSamplesTempAna - 64 + nSamplesInFrame], msfVal,
__max (m_meanTempPrev[ci], meanTempFlat[ci]) >> 3, m_bitRateMode == 0, __max (m_meanTempPrev[ci], meanTempFlat[ci]) >> 3, m_bitRateMode == 0,
msfSte, tmpValSynch, nSamplesInFrame, &m_coreSignals[ci][1]) << 21; m_indepFlag, msfSte, tmpValSynch, nSamplesInFrame, &m_coreSignals[ci][1]);
if (ch + 1 == nrChannels) // update the flatness histories if (ch + 1 == nrChannels) // update the flatness histories
{ {
m_meanSpecPrev[ci] = meanSpecFlat[ci]; m_meanSpecPrev[s] = meanSpecFlat[s]; m_meanSpecPrev[ci] = meanSpecFlat[ci]; m_meanSpecPrev[s] = meanSpecFlat[s];
m_meanTempPrev[ci] = meanTempFlat[ci]; m_meanTempPrev[s] = meanTempFlat[s]; m_meanTempPrev[ci] = meanTempFlat[ci]; m_meanTempPrev[s] = meanTempFlat[s];
// TODO: coupling (m_coreSignals[ci][0] |= 1 << 23;)
} }
} }
ci++; ci++;

View File

@@ -60,8 +60,8 @@ static int8_t quantizeSbrEnvelopeLevel (const uint64_t energy, const uint32_t di
} }
// public SBR related functions // public SBR related functions
int32_t getSbrEnvelopeAndNoise (int32_t* const sbrLevels, const uint8_t specFlat5b, const uint8_t tempFlat5b, const bool lowBitRateMode, int32_t getSbrEnvelopeAndNoise (int32_t* const sbrLevels, const uint8_t specFlat5b, const uint8_t tempFlat5b, const bool lr, const bool ind,
const uint8_t specFlatSte, const int32_t tmpValSte, const uint32_t frameSize, int32_t* sbrArray) const uint8_t specFlatSte, const int32_t tmpValSte, const uint32_t frameSize, int32_t* sbrData)
{ {
const uint64_t enValue[8] = {(uint64_t) sbrLevels[22] * (uint64_t) sbrLevels[22], const uint64_t enValue[8] = {(uint64_t) sbrLevels[22] * (uint64_t) sbrLevels[22],
(uint64_t) sbrLevels[23] * (uint64_t) sbrLevels[23], (uint64_t) sbrLevels[23] * (uint64_t) sbrLevels[23],
@@ -104,50 +104,76 @@ int32_t getSbrEnvelopeAndNoise (int32_t* const sbrLevels, const uint8_t specFlat
tmpBest = t; tmpBest = t;
} }
} }
if ((errBest >> 3) > envTmp0[0]) tmpBest = (lowBitRateMode ? 2 : 3); if ((errBest >> 3) > envTmp0[0]) tmpBest = (lr ? 2 : 3);
if (tmpBest < tmpValSte) tmpBest = tmpValSte; if (tmpBest < tmpValSte) tmpBest = tmpValSte;
/*Q*/if (tmpBest == 0) // quantized envelopes for optimal tmp value /*Q*/if (tmpBest == 0) // quantized envelopes for optimal tmp value
{ {
sbrArray[0] = quantizeSbrEnvelopeLevel (envTmp0[0], frameSize, specFlat5b); sbrData[0] = quantizeSbrEnvelopeLevel (envTmp0[0], frameSize, specFlat5b);
} }
else if (tmpBest == 1) else if (tmpBest == 1)
{ {
sbrArray[0] = quantizeSbrEnvelopeLevel (envTmp1[0], frameSize, specFlat5b); sbrData[0] = quantizeSbrEnvelopeLevel (envTmp1[0], frameSize, specFlat5b);
sbrArray[1] = quantizeSbrEnvelopeLevel (envTmp1[1], frameSize, specFlat5b); sbrData[1] = quantizeSbrEnvelopeLevel (envTmp1[1], frameSize, specFlat5b);
} }
else if (tmpBest == 2) else if (tmpBest == 2)
{ {
sbrArray[0] = quantizeSbrEnvelopeLevel (envTmp2[0], frameSize, specFlat5b); sbrData[0] = quantizeSbrEnvelopeLevel (envTmp2[0], frameSize, specFlat5b);
sbrArray[1] = quantizeSbrEnvelopeLevel (envTmp2[1], frameSize, specFlat5b); sbrData[1] = quantizeSbrEnvelopeLevel (envTmp2[1], frameSize, specFlat5b);
sbrArray[2] = quantizeSbrEnvelopeLevel (envTmp2[2], frameSize, specFlat5b); sbrData[2] = quantizeSbrEnvelopeLevel (envTmp2[2], frameSize, specFlat5b);
sbrArray[3] = quantizeSbrEnvelopeLevel (envTmp2[3], frameSize, specFlat5b); sbrData[3] = quantizeSbrEnvelopeLevel (envTmp2[3], frameSize, specFlat5b);
} }
else // (tmpBest == 3) else // (tmpBest == 3)
{ {
sbrArray[0] = quantizeSbrEnvelopeLevel (envTmp3[0], frameSize, specFlat5b); sbrData[0] = quantizeSbrEnvelopeLevel (envTmp3[0], frameSize, specFlat5b);
sbrArray[1] = quantizeSbrEnvelopeLevel (envTmp3[1], frameSize, specFlat5b); sbrData[1] = quantizeSbrEnvelopeLevel (envTmp3[1], frameSize, specFlat5b);
sbrArray[2] = quantizeSbrEnvelopeLevel (envTmp3[2], frameSize, specFlat5b); sbrData[2] = quantizeSbrEnvelopeLevel (envTmp3[2], frameSize, specFlat5b);
sbrArray[3] = quantizeSbrEnvelopeLevel (envTmp3[3], frameSize, specFlat5b); sbrData[3] = quantizeSbrEnvelopeLevel (envTmp3[3], frameSize, specFlat5b);
sbrArray[4] = quantizeSbrEnvelopeLevel (envTmp3[4], frameSize, specFlat5b); sbrData[4] = quantizeSbrEnvelopeLevel (envTmp3[4], frameSize, specFlat5b);
sbrArray[5] = quantizeSbrEnvelopeLevel (envTmp3[5], frameSize, specFlat5b); sbrData[5] = quantizeSbrEnvelopeLevel (envTmp3[5], frameSize, specFlat5b);
sbrArray[6] = quantizeSbrEnvelopeLevel (envTmp3[6], frameSize, specFlat5b); sbrData[6] = quantizeSbrEnvelopeLevel (envTmp3[6], frameSize, specFlat5b);
sbrArray[7] = quantizeSbrEnvelopeLevel (envTmp3[7], frameSize, specFlat5b); sbrData[7] = quantizeSbrEnvelopeLevel (envTmp3[7], frameSize, specFlat5b);
} }
// quantized noise level for up to two temporal units, 30 = no noise // quantized noise level for up to two temporal units, 30 = no noise
t = __min (30, __max (specFlat5b, specFlatSte)); t = __min (30, __max (specFlat5b, specFlatSte));
sbrArray[8] = ((int32_t) t << 13) | ((int32_t) t << 26); sbrData[8] = ((int32_t) t << 13) | ((int32_t) t << 26);
#if ENABLE_INTERTES #if ENABLE_INTERTES
if ((t < 12) && (tempFlat5b > (lowBitRateMode ? 15 : 26)) && (tmpBest < 3)) if ((t < 12) && (tempFlat5b > (lr ? 15 : 26)) && (tmpBest < 3))
{ {
sbrArray[8] |= (1 << (1 << tmpBest)) - 1; // TODO: inter-TES mode = inv. filter mode sbrData[8] |= (1 << (1 << tmpBest)) - 1; // TODO: inter-TES mode = inv. filter mode?
} }
#endif #endif
memcpy (&sbrLevels[20], &sbrLevels[10] /*last*/, 10 * sizeof (int32_t)); // update the memcpy (&sbrLevels[20], &sbrLevels[10] /*last*/, 10 * sizeof (int32_t)); // update the
memcpy (&sbrLevels[10], sbrLevels /*& current*/, 10 * sizeof (int32_t)); // delay line memcpy (&sbrLevels[10], sbrLevels /*& current*/, 10 * sizeof (int32_t)); // delay line
tmpBest <<= 21; // config bits
for (t = 0; t < (1 << (tmpBest >> 21)); t++)
{
const int32_t sbrEnvel = sbrData[t] & 127;
const int32_t d = sbrLevels[30] - sbrEnvel; // two length-2 words!
if ((t > 0 || !ind) && (d == 0 || d == 1))
{
tmpBest |= 1 << (12 + t); // delta-time coding flag for envelope
sbrData[t] -= sbrEnvel;
sbrData[t] |= d | (d << 7) | (d << 9) | (d << 11) | (d << 13) | (d << 15);
}
sbrLevels[30] = sbrEnvel;
}
for (t = 0; t < ((tmpBest >> 21) == 0 ? 1 : 2); t++)
{
const int32_t sbrNoise = (sbrData[8] >> (13 * (t + 1))) & 31;
if ((t > 0 || !ind) && (sbrNoise == sbrLevels[31]))
{
tmpBest |= 1 << (4 + t); // and delta-time coding flag for noise
sbrData[8] -= sbrNoise << (13 * (t + 1));
}
sbrLevels[31] = sbrNoise;
}
return tmpBest; return tmpBest;
} }

View File

@@ -197,8 +197,8 @@ static const ELEM_TYPE elementTypeConfig[USAC_MAX_NUM_ELCONFIGS][USAC_MAX_NUM_EL
const uint8_t oneTwentyEightOver[14] = {0, 128, 64, 43, 32, 26, 22, 19, 16, 15, 13, 12, 11, 10}; const uint8_t oneTwentyEightOver[14] = {0, 128, 64, 43, 32, 26, 22, 19, 16, 15, 13, 12, 11, 10};
// public SBR related functions // public SBR related functions
int32_t getSbrEnvelopeAndNoise (int32_t* const sbrLevels, const uint8_t specFlat5b, const uint8_t tempFlat5b, const bool lowBitRateMode, int32_t getSbrEnvelopeAndNoise (int32_t* const sbrLevels, const uint8_t specFlat5b, const uint8_t tempFlat5b, const bool lr, const bool ind,
const uint8_t specFlatSte, const int32_t tmpValSte, const uint32_t frameSize, int32_t* sbrArray); const uint8_t specFlatSte, const int32_t tmpValSte, const uint32_t frameSize, int32_t* sbrData);
// public sampling rate functions // public sampling rate functions
int8_t toSamplingFrequencyIndex (const unsigned samplingRate); int8_t toSamplingFrequencyIndex (const unsigned samplingRate);
unsigned toSamplingRate (const int8_t samplingFrequencyIndex); unsigned toSamplingRate (const int8_t samplingFrequencyIndex);

View File

@@ -31,10 +31,10 @@ static const int16_t lpfc34[128] = { // 25% low-pass filter coefficients
}; };
// static helper functions // static helper functions
static unsigned updateAbsStats (const int32_t* const chSig, const int nSamples, unsigned* const maxAbsVal, int16_t* const maxAbsIdx) static uint64_t updateAbsStats (const int32_t* const chSig, const int nSamples, unsigned* const maxAbsVal, int16_t* const maxAbsIdx)
{ {
const int32_t* const chSigM1 = chSig - 1; // for first-order high-pass const int32_t* const chSigM1 = chSig - 1; // for first-order high-pass
unsigned sumAbs = 0; uint64_t sumAbs = 0;
for (int s = nSamples - 1; s >= 0; s--) for (int s = nSamples - 1; s >= 0; s--)
{ {
@@ -51,12 +51,12 @@ static unsigned updateAbsStats (const int32_t* const chSig, const int nSamples,
return sumAbs; return sumAbs;
} }
static unsigned applyPitchPred (const int32_t* const chSig, const int nSamples, const int pitchLag, const int pitchSign = 1) static uint64_t applyPitchPred (const int32_t* const chSig, const int nSamples, const int pitchLag, const int pitchSign = 1)
{ {
const int32_t* const chSigM1 = chSig - 1; // for first-order high-pass const int32_t* const chSigM1 = chSig - 1; // for first-order high-pass
const int32_t* const plSig = chSig - pitchLag; // & pitch prediction const int32_t* const plSig = chSig - pitchLag; // & pitch prediction
const int32_t* const plSigM1 = plSig - 1; const int32_t* const plSigM1 = plSig - 1;
unsigned sumAbs = 0; uint64_t sumAbs = 0;
for (int s = nSamples - 1; s >= 0; s--) for (int s = nSamples - 1; s >= 0; s--)
{ {
@@ -66,8 +66,8 @@ static unsigned applyPitchPred (const int32_t* const chSig, const int nSamples,
return sumAbs; return sumAbs;
} }
static inline uint32_t packAvgTempAnalysisStats (const unsigned avgAbsHpL, const unsigned avgAbsHpR, const unsigned avgAbsHpP, static inline uint32_t packAvgTempAnalysisStats (const uint64_t avgAbsHpL, const uint64_t avgAbsHpR, const unsigned avgAbsHpP,
const unsigned avgAbsPpLR, const unsigned maxAbsHpLR) const uint64_t avgAbsPpLR, const unsigned maxAbsHpLR)
{ {
// spectral flatness, normalized for a value of 256 for noise-like, spectrally flat waveform // spectral flatness, normalized for a value of 256 for noise-like, spectrally flat waveform
const unsigned flatSpec = 256 - int ((int64_t (avgAbsPpLR/*L+R sum*/ + TA_EPS) * 256) / (int64_t (avgAbsHpL + avgAbsHpR + TA_EPS))); const unsigned flatSpec = 256 - int ((int64_t (avgAbsPpLR/*L+R sum*/ + TA_EPS) * 256) / (int64_t (avgAbsHpL + avgAbsHpR + TA_EPS)));
@@ -145,7 +145,7 @@ unsigned TempAnalyzer::temporalAnalysis (const int32_t* const timeSignals[USAC_M
const int32_t* const chSigM1 = chSig - 1; // for first-order high-pass const int32_t* const chSigM1 = chSig - 1; // for first-order high-pass
const int32_t* const chSigPH = chSig + halfFrameOffset; const int32_t* const chSigPH = chSig + halfFrameOffset;
// --- get L1 norm and pitch lag of both sides // --- get L1 norm and pitch lag of both sides
unsigned sumAbsValL = 0, sumAbsValR = 0; uint64_t sumAbsValL = 0, sumAbsValR = 0;
unsigned maxAbsValL = 0, maxAbsValR = 0; unsigned maxAbsValL = 0, maxAbsValR = 0;
int32_t maxHfrLevL = 0, maxHfrLevR = 0; int32_t maxHfrLevL = 0, maxHfrLevR = 0;
int16_t maxAbsIdxL = 0, maxAbsIdxR = 0; int16_t maxAbsIdxL = 0, maxAbsIdxR = 0;
@@ -193,7 +193,7 @@ unsigned TempAnalyzer::temporalAnalysis (const int32_t* const timeSignals[USAC_M
const unsigned numUnits = nSamplesInFrame >> (sbrShift + 7); const unsigned numUnits = nSamplesInFrame >> (sbrShift + 7);
int32_t* const hfrLevel = &lrCoreTimeSignals[ch][(resamplerOffset + nSamplesInFrame) >> sbrShift]; int32_t* const hfrLevel = &lrCoreTimeSignals[ch][(resamplerOffset + nSamplesInFrame) >> sbrShift];
for (u = numUnits; u > 0; /*u*/) for (u = numUnits; u > 0; )
{ {
ue[8] += ue[--u]; ue[8] += ue[--u];
hfrLevel[numUnits - u] = int32_t (0.5 + sqrt ((double) ue[u])); hfrLevel[numUnits - u] = int32_t (0.5 + sqrt ((double) ue[u]));
@@ -276,8 +276,8 @@ unsigned TempAnalyzer::temporalAnalysis (const int32_t* const timeSignals[USAC_M
else // nonzero signal in the current frame else // nonzero signal in the current frame
{ {
const int maxAbsIdxP = __max ((int) m_maxIdxHpPrev[ch] - nSamplesInFrame, 1 - (int) lookaheadOffset); const int maxAbsIdxP = __max ((int) m_maxIdxHpPrev[ch] - nSamplesInFrame, 1 - (int) lookaheadOffset);
unsigned sumAbsHpL = sumAbsValL, sumAbsHpR = sumAbsValR; // after high-pass filter uint64_t sumAbsHpL = sumAbsValL, sumAbsHpR = sumAbsValR; // after high-pass filter
unsigned sumAbsPpL = sumAbsValL, sumAbsPpR = sumAbsValR; // after pitch prediction uint64_t sumAbsPpL = sumAbsValL, sumAbsPpR = sumAbsValR; // after pitch prediction
int pLag, pLagBestR = 0, pSgn; int pLag, pLagBestR = 0, pSgn;
// test left-side pitch lag on this frame // test left-side pitch lag on this frame
@@ -344,7 +344,7 @@ unsigned TempAnalyzer::temporalAnalysis (const int32_t* const timeSignals[USAC_M
m_tempAnaStats[ch] = packAvgTempAnalysisStats (sumAbsHpL, sumAbsHpR, m_avgAbsHpPrev[ch], m_tempAnaStats[ch] = packAvgTempAnalysisStats (sumAbsHpL, sumAbsHpR, m_avgAbsHpPrev[ch],
sumAbsPpL + sumAbsPpR, maxAbsValL + maxAbsValR); sumAbsPpL + sumAbsPpR, maxAbsValL + maxAbsValR);
u = maxAbsValR; u = maxAbsValR;
if ((m_maxHfLevPrev[ch] < (maxHfrLevL >> 4)) || (maxHfrLevL < (maxHfrLevR >> 4))) // transient if ((m_maxHfLevPrev[ch] < (maxHfrLevL >> 4)) || (maxHfrLevL < (maxHfrLevR >> 4))) // HF
{ {
maxAbsValL = maxHfrLevL; maxAbsValL = maxHfrLevL;
maxAbsValR = maxHfrLevR; maxAbsValR = maxHfrLevR;
@@ -353,7 +353,7 @@ unsigned TempAnalyzer::temporalAnalysis (const int32_t* const timeSignals[USAC_M
m_transientLoc[ch] = packTransLocWithPitchLag (maxAbsValL, maxAbsValR, m_maxAbsHpPrev[ch], m_transientLoc[ch] = packTransLocWithPitchLag (maxAbsValL, maxAbsValR, m_maxAbsHpPrev[ch],
maxAbsIdxL, maxAbsIdxR, __max (1, pLagBestR)); maxAbsIdxL, maxAbsIdxR, __max (1, pLagBestR));
// update stats history for this channel // update stats history for this channel
m_avgAbsHpPrev[ch] = sumAbsHpR; m_avgAbsHpPrev[ch] = (unsigned) sumAbsHpR;
m_maxAbsHpPrev[ch] = u; m_maxAbsHpPrev[ch] = u;
m_maxIdxHpPrev[ch] = (unsigned) maxAbsIdxR; m_maxIdxHpPrev[ch] = (unsigned) maxAbsIdxR;
m_pitchLagPrev[ch] = (unsigned) pLagBestR; m_pitchLagPrev[ch] = (unsigned) pLagBestR;