mirror of https://gitlab.com/ecodis/exhale.git
fix upsampler
This commit is contained in:
parent
12bb57155a
commit
74518caef4
|
@ -33,6 +33,7 @@
|
|||
<li><h3>exhaleApp: support for Unicode text on Windows™, 44100 Hz with CVBR mode 1</h3></li>
|
||||
<li><h3>exhaleApp: automatic upsampling of low-sample-rate input, better WAVE reading</h3></li>
|
||||
<li><h3>exhaleLib: optimized noise filling tool for slightly lower bit-rates at CVBR mode <4</h3></li>
|
||||
<li><h3>compilation: exhaleApp.exe -> exhale.exe (issue 8), support for Arm™, C header</h3></li>
|
||||
</ul>
|
||||
<h3> Version <b>1.0.4 <span class="gray"> May 2020</span></b></h3>
|
||||
<ul>
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
|
||||
#if ENABLE_RESAMPLING
|
||||
static const int16_t usfc2x[32] = { // 2x upsampling filter coefficients
|
||||
0, -13785, 8142, -5681, 4281, -3367, 2716, -2225, 1840, -1530, 1275, -1062, 883, -732,
|
||||
8913, -13785, 8142, -5681, 4281, -3367, 2716, -2225, 1840, -1530, 1275, -1062, 883, -732,
|
||||
604, -495, 402, -325, 260, -205, 160, -124, 94, -70, 51, -36, 25, -16, 11, -6, 3, -1
|
||||
};
|
||||
|
||||
|
@ -89,7 +89,7 @@ static void eaApplyUpsampler2x (int32_t* const pcmBuffer, int32_t* const upsampl
|
|||
{
|
||||
int32_t* chPcmBuf = &pcmBuffer[ch];
|
||||
int32_t* chUpsBuf = &upsampleBuffer[chLength * ch];
|
||||
# if 0
|
||||
# if 1
|
||||
if (firstFrame) // construct leading sample values via extrapolation
|
||||
{
|
||||
for (int8_t i = 0; i < 32; i++) chUpsBuf[i] = (*chPcmBuf * i + (32 >> 1)) >> 5;
|
||||
|
@ -112,7 +112,7 @@ static void eaApplyUpsampler2x (int32_t* const pcmBuffer, int32_t* const upsampl
|
|||
|
||||
for (uint16_t i = (frameSize >> 1); i > 0; i--, chPcmBuf += numChannels, chUpsBuf++)
|
||||
{
|
||||
int64_t r = (chUpsBuf[0] + (int64_t) chUpsBuf[1]) * 41681;
|
||||
int64_t r = (chUpsBuf[0] + (int64_t) chUpsBuf[1]) * (usfc2x[0] - SHRT_MIN);
|
||||
|
||||
for (int16_t c = 32 - 1; c > 0; c--) r += (chUpsBuf[-c] + (int64_t) chUpsBuf[c + 1]) * usfc2x[c];
|
||||
*chPcmBuf = *chUpsBuf; chPcmBuf += numChannels; // 1-to-1 mapping
|
||||
|
@ -510,7 +510,7 @@ int main (const int argc, char* argv[])
|
|||
#if ENABLE_RESAMPLING
|
||||
const bool enableUpsampler = eaInitUpsampler2x (&inPcmRsmp, variableCoreBitRateMode, i, frameLength, numChannels);
|
||||
const uint16_t firstLength = uint16_t (enableUpsampler ? (frameLength >> 1) + 32 : frameLength); // upsampler look-ahead
|
||||
const int64_t expectLength = wavReader.getDataBytesLeft () / int64_t ((numChannels * inSampDepth) >> (enableUpsampler ? 4 : 3));
|
||||
const int64_t expectLength = (wavReader.getDataBytesLeft () << (enableUpsampler ? 1 : 0)) / int64_t ((numChannels * inSampDepth) >> 3);
|
||||
#else
|
||||
const int64_t expectLength = wavReader.getDataBytesLeft () / int64_t ((numChannels * inSampDepth) >> 3);
|
||||
#endif
|
||||
|
@ -703,7 +703,7 @@ int main (const int argc, char* argv[])
|
|||
byteCount += bw;
|
||||
|
||||
#if ENABLE_RESAMPLING
|
||||
const int64_t actualLength = wavReader.getDataBytesRead () / int64_t ((numChannels * inSampDepth) >> (enableUpsampler ? 4 : 3));
|
||||
const int64_t actualLength = (wavReader.getDataBytesRead () << (enableUpsampler ? 1 : 0)) / int64_t ((numChannels * inSampDepth) >> 3);
|
||||
#else
|
||||
const int64_t actualLength = wavReader.getDataBytesRead () / int64_t ((numChannels * inSampDepth) >> 3);
|
||||
#endif
|
||||
|
|
|
@ -293,6 +293,41 @@ static inline uint8_t brModeAndFsToMaxSfbShort(const unsigned bitRateMode, const
|
|||
return (samplingRate > 51200 ? 11 : 13) - 2 + (bitRateMode >> 2);
|
||||
}
|
||||
|
||||
static inline void findActualBandwidthShort (uint8_t* const maxSfbShort, const uint16_t* sfbOffsets,
|
||||
const int32_t* mdctSignals, const int32_t* mdstSignals, const unsigned nSamplesInShort)
|
||||
{
|
||||
const uint16_t b = sfbOffsets[1]; // beginning of search region
|
||||
uint8_t maxSfb = __max (1, *maxSfbShort);
|
||||
uint16_t sfbOffs = sfbOffsets[maxSfb - 1];
|
||||
|
||||
for (uint16_t e = sfbOffsets[maxSfb] - 1; e >= b; e--) // search
|
||||
{
|
||||
int32_t maxAbs = abs (mdctSignals[e]);
|
||||
|
||||
if (mdstSignals != nullptr)
|
||||
{
|
||||
maxAbs = __max (maxAbs, abs (mdstSignals[e]));
|
||||
for (uint16_t w = 7; w > 0; w--)
|
||||
{
|
||||
maxAbs = __max (maxAbs, abs (mdctSignals[e + w * nSamplesInShort]));
|
||||
maxAbs = __max (maxAbs, abs (mdstSignals[e + w * nSamplesInShort]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint16_t w = 7; w > 0; w--)
|
||||
{
|
||||
maxAbs = __max (maxAbs, abs (mdctSignals[e + w * nSamplesInShort]));
|
||||
}
|
||||
}
|
||||
if (maxAbs > maxSfb * (SA_EPS >> 1)) break;
|
||||
|
||||
if (e == sfbOffs) sfbOffs = sfbOffsets[(--maxSfb) - 1];
|
||||
}
|
||||
|
||||
if (*maxSfbShort > maxSfb) *maxSfbShort = maxSfb;
|
||||
}
|
||||
|
||||
static inline uint32_t squareMeanRoot (const uint32_t value1, const uint32_t value2)
|
||||
{
|
||||
const double meanRoot = (sqrt ((double) value1) + sqrt ((double) value2)) * 0.5;
|
||||
|
@ -986,8 +1021,9 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
|
|||
#if !RESTRICT_TO_AAC
|
||||
if ((maxSfbCh > 0) && m_noiseFilling[el] && (m_bitRateMode <= 3 || !eightShorts))
|
||||
{
|
||||
const uint8_t numSwbFrame = __min (numSwbCh, (eightShorts ? maxSfbCh : maxSfbLong) +
|
||||
(m_bitRateMode < 2 || m_bitRateMode > 3 || samplingRate < 37566 ? 0 : 1));
|
||||
const uint32_t maxSfbCurr = (eightShorts ? (samplingRate < 37566 ? 14 : brModeAndFsToMaxSfbShort (m_bitRateMode, samplingRate)) : maxSfbLong);
|
||||
const uint8_t numSwbFrame = __min ((numSwbCh * ((maxSfbCh == maxSfbCurr) || (m_bitRateMode <= 2) ? 4u : 3u)) >> 2,
|
||||
(eightShorts ? maxSfbCh : maxSfbLong) + (m_bitRateMode < 2 || m_bitRateMode > 3 || samplingRate < 37566 ? 0 : 1));
|
||||
#ifndef NO_DTX_MODE
|
||||
const bool prvEightShorts = (coreConfig.icsInfoPrev[ch].windowSequence == EIGHT_SHORT);
|
||||
|
||||
|
@ -1033,7 +1069,17 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
|
|||
}
|
||||
grpData.sfbsPerGroup = coreConfig.icsInfoCurr[ch].maxSfb = numSwbFrame;
|
||||
}
|
||||
if (ch > 0) coreConfig.commonMaxSfb = (coreConfig.icsInfoCurr[0].maxSfb == coreConfig.icsInfoCurr[1].maxSfb);
|
||||
if (ch > 0 && coreConfig.commonWindow) // resynchronize the two max_sfb for stereo
|
||||
{
|
||||
uint8_t& maxSfb0 = coreConfig.icsInfoCurr[0].maxSfb;
|
||||
uint8_t& maxSfb1 = coreConfig.icsInfoCurr[1].maxSfb;
|
||||
|
||||
if (coreConfig.stereoMode > 0)
|
||||
{
|
||||
maxSfb0 = maxSfb1 = coreConfig.groupingData[0].sfbsPerGroup = grpData.sfbsPerGroup = __max (maxSfb0, maxSfb1);
|
||||
}
|
||||
coreConfig.commonMaxSfb = (maxSfb0 == maxSfb1);
|
||||
}
|
||||
}
|
||||
#ifndef NO_DTX_MODE
|
||||
else if (m_noiseFilling[el] && (m_bitRateMode < 1) && (m_numElements == 1) && (samplingRate <= 24000))
|
||||
|
@ -1447,7 +1493,7 @@ unsigned ExhaleEncoder::spectralProcessing () // complete ics_info(), calc TNS
|
|||
}
|
||||
memcpy (grpData.windowGroupLength, windowGroupingTable[icsCurr.windowGrouping], NUM_WINDOW_GROUPS * sizeof (uint8_t));
|
||||
#endif
|
||||
while (grpSO[icsCurr.maxSfb] > __max (m_bandwidCurr[ci], m_bandwidPrev[ci])) icsCurr.maxSfb--; // not a bug!!
|
||||
findActualBandwidthShort (&icsCurr.maxSfb, grpSO, m_mdctSignals[ci], nChannels < 2 ? nullptr : m_mdstSignals[ci], nSamplesInShort);
|
||||
|
||||
errorValue |= eightShortGrouping (grpData, grpSO, m_mdctSignals[ci], nChannels < 2 ? nullptr : m_mdstSignals[ci]);
|
||||
} // if EIGHT_SHORT
|
||||
|
|
Loading…
Reference in New Issue