mirror of
https://gitlab.com/ecodis/exhale.git
synced 2025-03-11 16:50:09 +01:00
SBR bit allocation
This commit is contained in:
parent
6fe06fa78b
commit
5373500b9c
@ -25,9 +25,16 @@
|
||||
<td valign="top">
|
||||
|
||||
<h1><br><span class="pink">exhale</span> - <span class="pink">e</span>codis e<span class="pink">x</span>tended <span class="pink">h</span>igh-efficiency <span class="pink">a</span>nd <span class="pink">l</span>ow-complexity <span class="pink">e</span>ncoder<br><span class="gray"><sup><br>Software Release Notes, Version History, Known Issues, Upcoming Feature Roadmap</sup></span><br><br></h1>
|
||||
<h3> The version of this distribution of the «exhale» software release is <b>1.0.8</b> (official pub­lic minor release) from October 2020. Please check <a href="http://www.ecodis.de/audio.htm#mpeg">www.ecodis.de</a> regularly for new versions of this software. A summary of each version up to this release, a list of known issues with this release, and a roadmap of additional functionality are provided below.</h3>
|
||||
<h3> The version of this distribution of the «exhale» software release is <b>1.1RC</b> (preliminary pub­lic major release) from Nov. 2020. Please check <a href="http://www.ecodis.de/audio.htm#mpeg">www.ecodis.de</a> regularly for new versions of this software. A summary of each version up to this release, a list of known issues with this release, and a roadmap of additional functionality are provided below.</h3>
|
||||
<h3><br><b>Chronological Version History</b></h3>
|
||||
<h3> Version <b>1.0.8 <span class="gray"> Oct. 2020, this release</span></b></h3>
|
||||
<h3> Version <b>1.1RC <span class="gray">Nov. 2020, this release</span></b></h3>
|
||||
<ul>
|
||||
<li><h3>addition of basic SBR functionality for lower-rate coding down to 18 kbps/channel</h3></li>
|
||||
<li><h3>exhaleApp: add support for CVBR modes a—g for encoding with SBR functionality</h3></li>
|
||||
<li><h3>exhaleApp: show «ARM» in header and '-v' command on corresponding platforms</h3></li>
|
||||
<li><h3>exhaleLib: basic 2:1 SBR encoding with ccfl = 2048, minor fixes and code cleanup</h3></li>
|
||||
</ul>
|
||||
<h3> Version <b>1.0.8 <span class="gray"> Oct. 2020</span></b></h3>
|
||||
<ul>
|
||||
<li><h3>minor quality improvements at low and high rates, some license text clarifications</h3></li>
|
||||
<li><h3>exhaleApp: slightly improved loudness calculation for low and high sampling rates</h3></li>
|
||||
@ -111,7 +118,7 @@
|
||||
<li><h3>exhaleLib: speed-ups and further quality tuning for difficult signals, as necessary.</h3></li>
|
||||
</ul>
|
||||
<h3><br></h3>
|
||||
<h4><span class="gray">Written by C. R. Helmrich for exhale 1.0.8, Oct. 2020. Available at www.ecodis.de/exhale/release.htm.</span><br><br></h4>
|
||||
<h4><span class="gray">Written by C. R. Helmrich for exhale 1.1RC, Nov. 2020. Available at www.ecodis.de/exhale/release.htm.</span><br><br></h4>
|
||||
|
||||
</td>
|
||||
<td valign="top" colspan="2">
|
||||
|
@ -287,7 +287,9 @@ int main (const int argc, char* argv[])
|
||||
if ((argc > 1) && (strcmp (argv[1], "-V") == 0 || strcmp (argv[1], "-v") == 0))
|
||||
#endif
|
||||
{
|
||||
#if defined (_WIN64) || defined (WIN64) || defined (_LP64) || defined (__LP64__) || defined (__x86_64) || defined (__x86_64__)
|
||||
#if defined (__arm__) || defined (__aarch64__) || defined (__arm64__)
|
||||
fprintf_s (stdout, "exhale %s.%s%s (ARM",
|
||||
#elif defined (_WIN64) || defined (WIN64) || defined (_LP64) || defined (__LP64__) || defined (__x86_64) || defined (__x86_64__)
|
||||
fprintf_s (stdout, "exhale %s.%s%s (x64",
|
||||
#else // 32-bit OS
|
||||
fprintf_s (stdout, "exhale %s.%s%s (x86",
|
||||
@ -347,7 +349,9 @@ int main (const int argc, char* argv[])
|
||||
fprintf_s (stdout, EXHALE_TEXT_INIT "ncoder |\n");
|
||||
#endif
|
||||
fprintf_s (stdout, " | |\n");
|
||||
#if defined (_WIN64) || defined (WIN64) || defined (_LP64) || defined (__LP64__) || defined (__x86_64) || defined (__x86_64__)
|
||||
#if defined (__arm__) || defined (__aarch64__) || defined (__arm64__)
|
||||
fprintf_s (stdout, " | version %s.%s%s (ARM, built on %s) - written by C.R.Helmrich |\n",
|
||||
#elif defined (_WIN64) || defined (WIN64) || defined (_LP64) || defined (__LP64__) || defined (__x86_64) || defined (__x86_64__)
|
||||
fprintf_s (stdout, " | version %s.%s%s (x64, built on %s) - written by C.R.Helmrich |\n",
|
||||
#else // 32-bit OS
|
||||
fprintf_s (stdout, " | version %s.%s%s (x86, built on %s) - written by C.R.Helmrich |\n",
|
||||
|
@ -418,7 +418,7 @@ unsigned BitAllocator::imprSfbStepSizes (const SfbGroupData* const groupData[USA
|
||||
const unsigned firstChannelIndex, const uint8_t* const sfm, const bool commonWindow,
|
||||
const uint8_t* const sfbStereoData /*= nullptr*/, const uint8_t stereoConfig /*= 0*/)
|
||||
{
|
||||
const uint8_t maxSfbL16k = 16 + __min (35, (9 << 17) / __max (1, samplingRate)); // SFB index at 15.8 kHz
|
||||
const uint8_t maxSfbL16k = 16 + __min (4 + (samplingRate >> 10), (9 << 17) / __max (1, samplingRate)); // SFB index at 15.8 kHz
|
||||
const uint32_t redFactor = __max ((samplingRate < 27713 ? 2 : 1), __min (3, m_rateIndex)) - (stereoConfig >> 3);
|
||||
const uint32_t redWeight = __min (4, 9 - __min (9, m_rateIndex));
|
||||
short* const tempCoeffs = (short* const) m_tempSfbValue;
|
||||
|
@ -768,7 +768,7 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
|
||||
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 uint32_t maxSfbLong = (useMaxBandwidth ? m_numSwbLong : brModeAndFsToMaxSfbLong (m_bitRateMode, samplingRate));
|
||||
const uint32_t scaleSBR = (m_shiftValSBR > 0 ? 8 : 0); // reduces core rate by 25 %
|
||||
const uint32_t scaleSBR = (m_shiftValSBR > 0 || m_nonMpegExt ? (samplingRate < 23004 || m_bitRateMode == 0 ? 8 : 6 + ((m_bitRateMode + 1) >> 2)) : 0); // -25% rate
|
||||
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);
|
||||
const uint64_t scaleBr = (m_bitRateMode == 0 ? __min (32, 3 + (samplingRate >> 10) + (samplingRate >> 13) - (nChannels >> 1))
|
||||
@ -926,8 +926,8 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
|
||||
}
|
||||
else memset (coreConfig.stereoDataCurr, 0, (MAX_NUM_SWB_SHORT * NUM_WINDOW_GROUPS) * sizeof (uint8_t));
|
||||
|
||||
errorValue |= m_bitAllocator.imprSfbStepSizes (m_scaleFacData, m_numSwbShort, m_mdctSignals, nSamplesInFrame,
|
||||
nrChannels, samplingRate, sfbStepSizes, ci, meanSpecFlat,
|
||||
errorValue |= m_bitAllocator.imprSfbStepSizes (m_scaleFacData, m_numSwbShort, m_mdctSignals, nSamplesInFrame, nrChannels,
|
||||
((32 + 5 * m_shiftValSBR) * samplingRate) >> 5, sfbStepSizes, ci, meanSpecFlat,
|
||||
coreConfig.commonWindow, coreConfig.stereoDataCurr, coreConfig.stereoConfig);
|
||||
|
||||
for (unsigned ch = 0; ch < nrChannels; ch++) // channel loop
|
||||
@ -1301,9 +1301,13 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en
|
||||
// NOTE: gap-filling SFB bit count might be inaccurate now since scale factors changed
|
||||
if (coreConfig.specFillData[ch] == 1) errorValue |= 1;
|
||||
#endif
|
||||
s = ci + nrChannels - 1 - 2 * ch; // other channel in stereo
|
||||
if ((coreConfig.elementType < ID_USAC_LFE) && (m_shiftValSBR > 0)) // collect SBR data
|
||||
{
|
||||
const uint8_t msfVal = (shortWinPrev ? 31 : __max (2, __max (m_meanFlatPrev[ci], meanSpecFlat[ci]) >> 3));
|
||||
const uint8_t msfVal = (shortWinPrev ? 31 : __max (2, __max (m_meanSpecPrev[ci], meanSpecFlat[ci]) >> 3));
|
||||
const uint8_t msfSte = (coreConfig.stereoMode == 0 ? 0 : (coreConfig.icsInfoPrev[s + ch - ci].windowSequence ==
|
||||
EIGHT_SHORT ? 31 : __max (2, __max (m_meanSpecPrev[s ], meanSpecFlat[s ]) >> 3)));
|
||||
int32_t tmpValSynch = 0;
|
||||
|
||||
memset (m_coreSignals[ci], 0, 10 * sizeof (int32_t));
|
||||
#if ENABLE_INTERTES
|
||||
@ -1312,86 +1316,21 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en
|
||||
m_coreSignals[ci][0] = (shortWinPrev ? 0 : 1) << 20; // bs_freq_res = low resp. high
|
||||
#endif
|
||||
m_coreSignals[ci][0] |= 4 - int32_t (sqrt (0.75 * msfVal)); // filter mode, 0 = none
|
||||
#if 1
|
||||
// TODO: start putting into function
|
||||
int32_t* const sbrLevel = &m_coreSignals[ci][nSamplesTempAna - 64 + nSamplesInFrame];
|
||||
uint64_t enValues[8] = {(uint64_t) sbrLevel[22] * (uint64_t) sbrLevel[22], (uint64_t) sbrLevel[23] * (uint64_t) sbrLevel[23],
|
||||
(uint64_t) sbrLevel[24] * (uint64_t) sbrLevel[24], (uint64_t) sbrLevel[25] * (uint64_t) sbrLevel[25],
|
||||
(uint64_t) sbrLevel[26] * (uint64_t) sbrLevel[26], (uint64_t) sbrLevel[27] * (uint64_t) sbrLevel[27],
|
||||
(uint64_t) sbrLevel[28] * (uint64_t) sbrLevel[28], (uint64_t) sbrLevel[11] * (uint64_t) sbrLevel[11]};
|
||||
uint64_t envTmp0[1] = { enValues[0] + enValues[1] + enValues[2] + enValues[3] +
|
||||
enValues[4] + enValues[5] + enValues[6] + enValues[7]};
|
||||
uint64_t envTmp1[2] = {(enValues[0] + enValues[1] + enValues[2] + enValues[3]) << 1,
|
||||
(enValues[4] + enValues[5] + enValues[6] + enValues[7]) << 1};
|
||||
uint64_t envTmp2[4] = {(enValues[0] + enValues[1]) << 2, (enValues[2] + enValues[3]) << 2,
|
||||
(enValues[4] + enValues[5]) << 2, (enValues[6] + enValues[7]) << 2};
|
||||
uint64_t envTmp3[8] = { enValues[0] << 3, enValues[1] << 3, enValues[2] << 3, enValues[3] << 3,
|
||||
enValues[4] << 3, enValues[5] << 3, enValues[6] << 3, enValues[7] << 3};
|
||||
uint64_t errTmp[4] = {0, 0, 0, 0};
|
||||
uint64_t errBest;
|
||||
int32_t tmpBest;
|
||||
|
||||
for (int unit = 0; unit < 8; unit++)
|
||||
if (ch > 0 && coreConfig.stereoMode > 0) // synch. sbr_grid(), sbr_invf() for stereo
|
||||
{
|
||||
const int64_t ref = enValues[unit] << 3;
|
||||
|
||||
errTmp[0] += abs ((int64_t) envTmp0[unit >> 3] - ref); // abs() since
|
||||
errTmp[1] += abs ((int64_t) envTmp1[unit >> 2] - ref); // both values
|
||||
errTmp[2] += abs ((int64_t) envTmp2[unit >> 1] - ref); // are already
|
||||
errTmp[3] += abs ((int64_t) envTmp3[unit >> 0] - ref); // squares
|
||||
tmpValSynch = (m_coreSignals[ci - 1][0] >> 21) & 3; // nEnv, bits 23-22
|
||||
m_coreSignals[ci][0] |= m_coreSignals[ci - 1][0] & 0x10000F; // bits 21
|
||||
m_coreSignals[ci - 1][0] |= m_coreSignals[ci][0] & 0x10000F; // and 4-1
|
||||
}
|
||||
|
||||
errBest = errTmp[0]; // find tmp value providing minimal weighted error
|
||||
tmpBest = 0;
|
||||
for (uint8_t t = 1; t < 3; t++)
|
||||
m_coreSignals[ci][0] |= getSbrEnvelopeAndNoise (&m_coreSignals[ci][nSamplesTempAna - 64 + nSamplesInFrame], msfVal,
|
||||
__max (m_meanTempPrev[ci], meanTempFlat[ci]) >> 3, m_bitRateMode == 0,
|
||||
msfSte, tmpValSynch, nSamplesInFrame, &m_coreSignals[ci][1]) << 21;
|
||||
if (ch + 1 == nrChannels) // update the flatness histories
|
||||
{
|
||||
if ((errTmp[t] << t) < errBest)
|
||||
{
|
||||
errBest = errTmp[t] << t;
|
||||
tmpBest = t;
|
||||
}
|
||||
m_meanSpecPrev[ci] = meanSpecFlat[ci]; m_meanSpecPrev[s] = meanSpecFlat[s];
|
||||
m_meanTempPrev[ci] = meanTempFlat[ci]; m_meanTempPrev[s] = meanTempFlat[s];
|
||||
}
|
||||
if ((errBest >> 3) > envTmp0[0]) tmpBest = (m_bitRateMode == 0 ? 2 : 3);
|
||||
|
||||
/*quant.*/ if (tmpBest == 0)
|
||||
{
|
||||
m_coreSignals[ci][1] = quantizeSbrEnvelopeLevel (envTmp0[0], nSamplesInFrame, msfVal);
|
||||
}
|
||||
else if (tmpBest == 1)
|
||||
{
|
||||
m_coreSignals[ci][1] = quantizeSbrEnvelopeLevel (envTmp1[0], nSamplesInFrame, msfVal);
|
||||
m_coreSignals[ci][2] = quantizeSbrEnvelopeLevel (envTmp1[1], nSamplesInFrame, msfVal);
|
||||
}
|
||||
else if (tmpBest == 2)
|
||||
{
|
||||
m_coreSignals[ci][1] = quantizeSbrEnvelopeLevel (envTmp2[0], nSamplesInFrame, msfVal);
|
||||
m_coreSignals[ci][2] = quantizeSbrEnvelopeLevel (envTmp2[1], nSamplesInFrame, msfVal);
|
||||
m_coreSignals[ci][3] = quantizeSbrEnvelopeLevel (envTmp2[2], nSamplesInFrame, msfVal);
|
||||
m_coreSignals[ci][4] = quantizeSbrEnvelopeLevel (envTmp2[3], nSamplesInFrame, msfVal);
|
||||
}
|
||||
else // (tmpBest == 3)
|
||||
{
|
||||
m_coreSignals[ci][1] = quantizeSbrEnvelopeLevel (envTmp3[0], nSamplesInFrame, msfVal);
|
||||
m_coreSignals[ci][2] = quantizeSbrEnvelopeLevel (envTmp3[1], nSamplesInFrame, msfVal);
|
||||
m_coreSignals[ci][3] = quantizeSbrEnvelopeLevel (envTmp3[2], nSamplesInFrame, msfVal);
|
||||
m_coreSignals[ci][4] = quantizeSbrEnvelopeLevel (envTmp3[3], nSamplesInFrame, msfVal);
|
||||
m_coreSignals[ci][5] = quantizeSbrEnvelopeLevel (envTmp3[4], nSamplesInFrame, msfVal);
|
||||
m_coreSignals[ci][6] = quantizeSbrEnvelopeLevel (envTmp3[5], nSamplesInFrame, msfVal);
|
||||
m_coreSignals[ci][7] = quantizeSbrEnvelopeLevel (envTmp3[6], nSamplesInFrame, msfVal);
|
||||
m_coreSignals[ci][8] = quantizeSbrEnvelopeLevel (envTmp3[7], nSamplesInFrame, msfVal);
|
||||
}
|
||||
|
||||
m_coreSignals[ci][9] = ((int32_t) msfVal << 13) | ((int32_t) msfVal << 26); // noise level(s), 31 = none
|
||||
# if ENABLE_INTERTES
|
||||
// m_auBitStream.write ((m_coreSignals[ci][9] >> (i=0..(1 << tmpBest)-1)) & 1, 1); // bs_temp_shape[ch][env=i]
|
||||
# endif
|
||||
memcpy (&sbrLevel[20], &sbrLevel[10] /*last*/, 10 * sizeof (int32_t));
|
||||
memcpy (&sbrLevel[10], sbrLevel /*& current*/, 10 * sizeof (int32_t)); // delay line
|
||||
// TODO: end putting into function
|
||||
#endif
|
||||
m_coreSignals[ci][0] |= tmpBest /* TODO: call function here, returning tmpBest */ << 21;
|
||||
|
||||
m_meanFlatPrev[ci] = meanSpecFlat[ci];
|
||||
}
|
||||
ci++;
|
||||
}
|
||||
@ -1937,7 +1876,8 @@ ExhaleEncoder::ExhaleEncoder (int32_t* const inputPcmData, unsigned ch
|
||||
m_mdctQuantMag[ch] = nullptr;
|
||||
m_mdctSignals[ch] = nullptr;
|
||||
m_mdstSignals[ch] = nullptr;
|
||||
m_meanFlatPrev[ch] = 0;
|
||||
m_meanSpecPrev[ch] = 0;
|
||||
m_meanTempPrev[ch] = 0;
|
||||
m_scaleFacData[ch] = nullptr;
|
||||
m_specAnaCurr[ch] = 0;
|
||||
m_specFlatPrev[ch] = 0;
|
||||
|
@ -79,7 +79,8 @@ private:
|
||||
uint8_t* m_mdctQuantMag[USAC_MAX_NUM_CHANNELS];
|
||||
int32_t* m_mdctSignals[USAC_MAX_NUM_CHANNELS];
|
||||
int32_t* m_mdstSignals[USAC_MAX_NUM_CHANNELS];
|
||||
uint8_t m_meanFlatPrev[USAC_MAX_NUM_CHANNELS];
|
||||
uint8_t m_meanSpecPrev[USAC_MAX_NUM_CHANNELS]; // for
|
||||
uint8_t m_meanTempPrev[USAC_MAX_NUM_CHANNELS]; // SBR
|
||||
#if !RESTRICT_TO_AAC
|
||||
bool m_noiseFilling[USAC_MAX_NUM_ELEMENTS];
|
||||
bool m_nonMpegExt;
|
||||
|
@ -52,14 +52,105 @@ static const unsigned allowedSamplingRates[USAC_NUM_SAMPLE_RATES] = {
|
||||
57600, 51200, 40000, 38400, 34150, 28800, 25600, 20000, 19200, 17075, 14400, 12800, 9600 // USAC
|
||||
};
|
||||
|
||||
// public SBR related functions
|
||||
int8_t quantizeSbrEnvelopeLevel (const uint64_t energy, const unsigned divisor, const uint8_t noiseLevel)
|
||||
static int8_t quantizeSbrEnvelopeLevel (const uint64_t energy, const uint32_t divisor, const uint8_t noiseLevel)
|
||||
{
|
||||
const double ener = (double) energy / (double) divisor;
|
||||
|
||||
return (ener > 8192.0 ? int8_t (1.375 - 0.03125 * noiseLevel + 6.64385619 * log10 (ener)) - 26 : 0);
|
||||
}
|
||||
|
||||
// public SBR related functions
|
||||
int32_t getSbrEnvelopeAndNoise (int32_t* const sbrLevels, const uint8_t specFlat5b, const uint8_t tempFlat5b, const bool lowBitRateMode,
|
||||
const uint8_t specFlatSte, const int32_t tmpValSte, const uint32_t frameSize, int32_t* sbrArray)
|
||||
{
|
||||
const uint64_t enValue[8] = {(uint64_t) sbrLevels[22] * (uint64_t) sbrLevels[22],
|
||||
(uint64_t) sbrLevels[23] * (uint64_t) sbrLevels[23],
|
||||
(uint64_t) sbrLevels[24] * (uint64_t) sbrLevels[24],
|
||||
(uint64_t) sbrLevels[25] * (uint64_t) sbrLevels[25],
|
||||
(uint64_t) sbrLevels[26] * (uint64_t) sbrLevels[26],
|
||||
(uint64_t) sbrLevels[27] * (uint64_t) sbrLevels[27],
|
||||
(uint64_t) sbrLevels[28] * (uint64_t) sbrLevels[28],
|
||||
(uint64_t) sbrLevels[11] * (uint64_t) sbrLevels[11]};
|
||||
const uint64_t envTmp0[1] = { enValue[0] + enValue[1] + enValue[2] + enValue[3] +
|
||||
enValue[4] + enValue[5] + enValue[6] + enValue[7]};
|
||||
const uint64_t envTmp1[2] = {(enValue[0] + enValue[1] + enValue[2] + enValue[3]) << 1,
|
||||
(enValue[4] + enValue[5] + enValue[6] + enValue[7]) << 1};
|
||||
const uint64_t envTmp2[4] = {(enValue[0] + enValue[1]) << 2, (enValue[2] + enValue[3]) << 2,
|
||||
(enValue[4] + enValue[5]) << 2, (enValue[6] + enValue[7]) << 2};
|
||||
const uint64_t envTmp3[8] = { enValue[0] << 3, enValue[1] << 3, enValue[2] << 3, enValue[3] << 3,
|
||||
enValue[4] << 3, enValue[5] << 3, enValue[6] << 3, enValue[7] << 3};
|
||||
uint64_t errTmp[4] = {0, 0, 0, 0};
|
||||
uint64_t errBest;
|
||||
int32_t tmpBest;
|
||||
uint8_t t;
|
||||
|
||||
for (t = 0; t < 8; t++) // get energy errors due to temporal merging
|
||||
{
|
||||
const int64_t ref = enValue[t] << 3;
|
||||
|
||||
errTmp[0] += abs ((int64_t) envTmp0[t >> 3] - ref); // abs() since
|
||||
errTmp[1] += abs ((int64_t) envTmp1[t >> 2] - ref); // both values
|
||||
errTmp[2] += abs ((int64_t) envTmp2[t >> 1] - ref); // are already
|
||||
errTmp[3] += abs ((int64_t) envTmp3[t >> 0] - ref); // squares
|
||||
}
|
||||
errBest = errTmp[0];
|
||||
tmpBest = 0;
|
||||
|
||||
for (t = 1; t < 3; t++) // find tmp value for minimal weighted error
|
||||
{
|
||||
if ((errTmp[t] << t) < errBest)
|
||||
{
|
||||
errBest = errTmp[t] << t;
|
||||
tmpBest = t;
|
||||
}
|
||||
}
|
||||
if ((errBest >> 3) > envTmp0[0]) tmpBest = (lowBitRateMode ? 2 : 3);
|
||||
|
||||
if (tmpBest < tmpValSte) tmpBest = tmpValSte;
|
||||
|
||||
/*Q*/if (tmpBest == 0) // quantized envelopes for optimal tmp value
|
||||
{
|
||||
sbrArray[0] = quantizeSbrEnvelopeLevel (envTmp0[0], frameSize, specFlat5b);
|
||||
}
|
||||
else if (tmpBest == 1)
|
||||
{
|
||||
sbrArray[0] = quantizeSbrEnvelopeLevel (envTmp1[0], frameSize, specFlat5b);
|
||||
sbrArray[1] = quantizeSbrEnvelopeLevel (envTmp1[1], frameSize, specFlat5b);
|
||||
}
|
||||
else if (tmpBest == 2)
|
||||
{
|
||||
sbrArray[0] = quantizeSbrEnvelopeLevel (envTmp2[0], frameSize, specFlat5b);
|
||||
sbrArray[1] = quantizeSbrEnvelopeLevel (envTmp2[1], frameSize, specFlat5b);
|
||||
sbrArray[2] = quantizeSbrEnvelopeLevel (envTmp2[2], frameSize, specFlat5b);
|
||||
sbrArray[3] = quantizeSbrEnvelopeLevel (envTmp2[3], frameSize, specFlat5b);
|
||||
}
|
||||
else // (tmpBest == 3)
|
||||
{
|
||||
sbrArray[0] = quantizeSbrEnvelopeLevel (envTmp3[0], frameSize, specFlat5b);
|
||||
sbrArray[1] = quantizeSbrEnvelopeLevel (envTmp3[1], frameSize, specFlat5b);
|
||||
sbrArray[2] = quantizeSbrEnvelopeLevel (envTmp3[2], frameSize, specFlat5b);
|
||||
sbrArray[3] = quantizeSbrEnvelopeLevel (envTmp3[3], frameSize, specFlat5b);
|
||||
sbrArray[4] = quantizeSbrEnvelopeLevel (envTmp3[4], frameSize, specFlat5b);
|
||||
sbrArray[5] = quantizeSbrEnvelopeLevel (envTmp3[5], frameSize, specFlat5b);
|
||||
sbrArray[6] = quantizeSbrEnvelopeLevel (envTmp3[6], frameSize, specFlat5b);
|
||||
sbrArray[7] = quantizeSbrEnvelopeLevel (envTmp3[7], frameSize, specFlat5b);
|
||||
}
|
||||
|
||||
// quantized noise level for up to two temporal units, 31 = no noise
|
||||
t = __max (specFlat5b, specFlatSte);
|
||||
sbrArray[8] = ((int32_t) t << 13) | ((int32_t) t << 26);
|
||||
#if ENABLE_INTERTES
|
||||
if ((t < 12) && (tempFlat5b > (lowBitRateMode ? 15 : 26)) && (tmpBest < 3))
|
||||
{
|
||||
sbrArray[8] |= (1 << (1 << tmpBest)) - 1; // TODO: inter-TES mode = inv. filter mode
|
||||
}
|
||||
#endif
|
||||
memcpy (&sbrLevels[20], &sbrLevels[10] /*last*/, 10 * sizeof (int32_t)); // update the
|
||||
memcpy (&sbrLevels[10], sbrLevels /*& current*/, 10 * sizeof (int32_t)); // delay line
|
||||
|
||||
return tmpBest;
|
||||
}
|
||||
|
||||
// public sampling rate functions
|
||||
int8_t toSamplingFrequencyIndex (const unsigned samplingRate)
|
||||
{
|
||||
|
@ -178,27 +178,27 @@ const uint8_t eightTimesSqrt256Minus[256] = {
|
||||
static const uint8_t elementCountConfig[USAC_MAX_NUM_ELCONFIGS] = {0, 1, 1, 2, 3, 3, 4, 5, 2, 2, 2, 5, 5};
|
||||
|
||||
static const ELEM_TYPE elementTypeConfig[USAC_MAX_NUM_ELCONFIGS][USAC_MAX_NUM_ELEMENTS] = {
|
||||
{ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF}, // CCI_UNDEF
|
||||
{ID_USAC_SCE, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF}, // CCI_1_CH
|
||||
{ID_USAC_CPE, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF}, // CCI_2_CH
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF}, // CCI_3_CH
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_USAC_SCE, ID_EL_UNDEF, ID_EL_UNDEF}, // CCI_4_CH
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_USAC_CPE, ID_EL_UNDEF, ID_EL_UNDEF}, // CCI_5_CH
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_USAC_CPE, ID_USAC_LFE, ID_EL_UNDEF}, // CCI_6_CH
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_USAC_CPE, ID_USAC_CPE, ID_USAC_LFE}, // CCI_8_CH
|
||||
{ID_USAC_SCE, ID_USAC_SCE, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF}, // CCI_2_CHM
|
||||
{ID_USAC_CPE, ID_USAC_SCE, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF}, // CCI_3_CHR
|
||||
{ID_USAC_CPE, ID_USAC_CPE, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF}, // CCI_4_CHR
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_USAC_CPE, ID_USAC_SCE, ID_USAC_LFE}, // CCI_7_CH
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_USAC_CPE, ID_USAC_CPE, ID_USAC_LFE} // CCI_8_CHM
|
||||
{ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF},
|
||||
{ID_USAC_SCE, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF},
|
||||
{ID_USAC_CPE, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF},
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF},
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_USAC_SCE, ID_EL_UNDEF, ID_EL_UNDEF},
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_USAC_CPE, ID_EL_UNDEF, ID_EL_UNDEF},
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_USAC_CPE, ID_USAC_LFE, ID_EL_UNDEF},
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_USAC_CPE, ID_USAC_CPE, ID_USAC_LFE},
|
||||
{ID_USAC_SCE, ID_USAC_SCE, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF},
|
||||
{ID_USAC_CPE, ID_USAC_SCE, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF},
|
||||
{ID_USAC_CPE, ID_USAC_CPE, ID_EL_UNDEF, ID_EL_UNDEF, ID_EL_UNDEF},
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_USAC_CPE, ID_USAC_SCE, ID_USAC_LFE},
|
||||
{ID_USAC_SCE, ID_USAC_CPE, ID_USAC_CPE, ID_USAC_CPE, ID_USAC_LFE}
|
||||
};
|
||||
|
||||
// fast calculation of x / den: (x * oneTwentyEightOver[den]) >> 7, accurate for 0 <= x <= 162
|
||||
const uint8_t oneTwentyEightOver[14] = {0, 128, 64, 43, 32, 26, 22, 19, 16, 15, 13, 12, 11, 10};
|
||||
|
||||
// public SBR related functions
|
||||
int8_t quantizeSbrEnvelopeLevel (const uint64_t energy, const unsigned divisor, const uint8_t noiseLevel);
|
||||
|
||||
int32_t getSbrEnvelopeAndNoise (int32_t* const sbrLevels, const uint8_t specFlat5b, const uint8_t tempFlat5b, const bool lowBitRateMode,
|
||||
const uint8_t specFlatSte, const int32_t tmpValSte, const uint32_t frameSize, int32_t* sbrArray);
|
||||
// public sampling rate functions
|
||||
int8_t toSamplingFrequencyIndex (const unsigned samplingRate);
|
||||
unsigned toSamplingRate (const int8_t samplingFrequencyIndex);
|
||||
|
@ -344,7 +344,7 @@ unsigned TempAnalyzer::temporalAnalysis (const int32_t* const timeSignals[USAC_M
|
||||
m_tempAnaStats[ch] = packAvgTempAnalysisStats (sumAbsHpL, sumAbsHpR, m_avgAbsHpPrev[ch],
|
||||
sumAbsPpL + sumAbsPpR, maxAbsValL + maxAbsValR);
|
||||
u = maxAbsValR;
|
||||
if ((m_maxHfLevPrev[ch] < (maxHfrLevL >> 3)) || (maxHfrLevL < (maxHfrLevR >> 3))) // transient
|
||||
if ((m_maxHfLevPrev[ch] < (maxHfrLevL >> 4)) || (maxHfrLevL < (maxHfrLevR >> 4))) // transient
|
||||
{
|
||||
maxAbsValL = maxHfrLevL;
|
||||
maxAbsValR = maxHfrLevR;
|
||||
|
Loading…
x
Reference in New Issue
Block a user