finish reader, SBR

This commit is contained in:
Christian R. Helmrich 2021-05-06 22:00:00 +02:00
parent accb67be08
commit aaf8b0aa5a
3 changed files with 50 additions and 43 deletions

View File

@ -1,11 +1,11 @@
/* basicWavReader.cpp - source file for class with basic WAVE file reading capability
* written by C. R. Helmrich, last modified in 2020 - see License.htm for legal notices
* written by C. R. Helmrich, last modified in 2021 - see License.htm for legal notices
*
* The copyright in this software is being made available under the exhale Copyright License
* and comes with ABSOLUTELY NO WARRANTY. This software may be subject to other third-
* party rights, including patent rights. No such rights are granted under this License.
*
* Copyright (c) 2018-2020 Christian R. Helmrich, project ecodis. All rights reserved.
* Copyright (c) 2018-2021 Christian R. Helmrich, project ecodis. All rights reserved.
*/
#include "exhaleAppPch.h"
@ -25,6 +25,22 @@ static int64_t fourBytesToLength (const uint8_t* b, const int64_t lengthLimit)
return __min (lengthLimit, chunkLength); // for security
}
#if BWR_BUFFERED_READ
static inline unsigned getFrames (const int fileHandle, void* dataBuf, const unsigned frameCount,
const bool roundSize, const unsigned bytesPerFrame)
{
const int size = ((frameCount + (roundSize ? 1 << (BWR_READ_FRACT - 1) : 0)) >> BWR_READ_FRACT) * bytesPerFrame;
int bytesRead = _READ (fileHandle, dataBuf, size); // 1
if ((bytesRead = __max (0, bytesRead)) < size)
{
const int br = _READ (fileHandle, (uint8_t*) dataBuf + bytesRead, size - bytesRead);
bytesRead += __max (0, br); // bytes of read attempt 2
}
return bytesRead / bytesPerFrame; // num of frames read
}
#endif
// private reader functions
bool BasicWavReader::readRiffHeader ()
@ -124,9 +140,7 @@ unsigned BasicWavReader::readDataFloat16 (const int fileHandle, int32_t* frameBu
for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT) + rest; fract++)
{
const int16_t* fBuf = (const int16_t*) tempBuf; // words
const unsigned size = (frameCount + ((fract & 1) > 0 ? 1 << (BWR_READ_FRACT - 1) : 0)) >> BWR_READ_FRACT;
const int bytesRead = _READ (fileHandle, tempBuf, size * chanCount * 2);
const unsigned read = __max (0, bytesRead / (chanCount * 2));
const unsigned read = getFrames (fileHandle, tempBuf, frameCount, (fract & 1), chanCount * 2);
for (unsigned i = read * chanCount; i > 0; i--)
{
@ -175,9 +189,7 @@ unsigned BasicWavReader::readDataFloat32 (const int fileHandle, int32_t* frameBu
for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT) + rest; fract++)
{
const float* fBuf = (const float*) tempBuf; // 4 bytes
const unsigned size = (frameCount + ((fract & 1) > 0 ? 1 << (BWR_READ_FRACT - 1) : 0)) >> BWR_READ_FRACT;
const int bytesRead = _READ (fileHandle, tempBuf, size * chanCount * 4);
const unsigned read = __max (0, bytesRead / (chanCount * 4));
const unsigned read = getFrames (fileHandle, tempBuf, frameCount, (fract & 1), chanCount * 4);
for (unsigned i = read * chanCount; i > 0; i--)
{
@ -224,9 +236,7 @@ unsigned BasicWavReader::readDataLnPcm08 (const int fileHandle, int32_t* frameBu
for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT) + rest; fract++)
{
const uint8_t* iBuf = (const uint8_t*) tempBuf; // 1b
const unsigned size = (frameCount + ((fract & 1) > 0 ? 1 << (BWR_READ_FRACT - 1) : 0)) >> BWR_READ_FRACT;
const int bytesRead = _READ (fileHandle, tempBuf, size * chanCount);
const unsigned read = __max (0, bytesRead / chanCount);
const unsigned read = getFrames (fileHandle, tempBuf, frameCount, (fract & 1), chanCount);
for (unsigned i = read * chanCount; i > 0; i--)
{
@ -263,9 +273,7 @@ unsigned BasicWavReader::readDataLnPcm16 (const int fileHandle, int32_t* frameBu
for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT) + rest; fract++)
{
const int16_t* iBuf = (const int16_t*) tempBuf; // words
const unsigned size = (frameCount + ((fract & 1) > 0 ? 1 << (BWR_READ_FRACT - 1) : 0)) >> BWR_READ_FRACT;
const int bytesRead = _READ (fileHandle, tempBuf, size * chanCount * 2);
const unsigned read = __max (0, bytesRead / (chanCount * 2));
const unsigned read = getFrames (fileHandle, tempBuf, frameCount, (fract & 1), chanCount * 2);
for (unsigned i = read * chanCount; i > 0; i--)
{
@ -302,9 +310,7 @@ unsigned BasicWavReader::readDataLnPcm24 (const int fileHandle, int32_t* frameBu
for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT) + rest; fract++)
{
const uint8_t* iBuf = (const uint8_t*) tempBuf; // 3b
const unsigned size = (frameCount + ((fract & 1) > 0 ? 1 << (BWR_READ_FRACT - 1) : 0)) >> BWR_READ_FRACT;
const int bytesRead = _READ (fileHandle, tempBuf, size * chanCount * 3);
const unsigned read = __max (0, bytesRead / (chanCount * 3));
const unsigned read = getFrames (fileHandle, tempBuf, frameCount, (fract & 1), chanCount * 3);
for (unsigned i = read * chanCount; i > 0; i--)
{
@ -343,9 +349,7 @@ unsigned BasicWavReader::readDataLnPcm32 (const int fileHandle, int32_t* frameBu
for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT) + rest; fract++)
{
const int32_t* iBuf = (const int32_t*) tempBuf; // dword
const unsigned size = (frameCount + ((fract & 1) > 0 ? 1 << (BWR_READ_FRACT - 1) : 0)) >> BWR_READ_FRACT;
const int bytesRead = _READ (fileHandle, tempBuf, size * chanCount * 4);
const unsigned read = __max (0, bytesRead / (chanCount * 4));
const unsigned read = getFrames (fileHandle, tempBuf, frameCount, (fract & 1), chanCount * 4);
for (unsigned i = read * chanCount; i > 0; i--)
{

View File

@ -783,7 +783,6 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
// get means of spectral and temporal flatness for every channel
m_bitAllocator.getChAverageSpecFlat (meanSpecFlat, nChannels);
//m_bitAllocator.getChAverageTempFlat (meanTempFlat, nChannels);
for (unsigned el = 0; el < m_numElements; el++) // element loop
{
@ -920,7 +919,6 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
m_specAnaCurr[ci ] = (m_specAnaCurr[ci ] & (UINT_MAX - 65504)) | peakIndexSte;
m_specAnaCurr[ci + 1] = (m_specAnaCurr[ci + 1] & (UINT_MAX - 65504)) | peakIndexSte;
meanSpecFlat[ci] = meanSpecFlat[ci + 1] = ((uint16_t) meanSpecFlat[ci] + (uint16_t) meanSpecFlat[ci + 1]) >> 1;
// meanTempFlat[ci] = meanTempFlat[ci + 1] = ((uint16_t) meanTempFlat[ci] + (uint16_t) meanTempFlat[ci + 1]) >> 1;
}
else memset (coreConfig.stereoDataCurr, 0, (eightShorts0 || !coreConfig.commonWindow
? MAX_NUM_SWB_SHORT * NUM_WINDOW_GROUPS : MAX_NUM_SWB_LONG) * sizeof (uint8_t));
@ -958,7 +956,10 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
// scale step-sizes according to VBR mode & derive scale factors from step-sizes
grpStepSizes[b] = uint32_t (__max (BA_EPS, ((1u << 17) + grpStepSizes[b] * scale) >> 18));
#if !RESTRICT_TO_AAC
if (!m_noiseFilling[el] || (m_bitRateMode > 0) || (m_shiftValSBR == 0) || (samplingRate < 23004) ||
(b + 3 - (meanSpecFlat[ci] >> 6) < m_numSwbLong)) // HF
#endif
grpScaleFacs[b] = m_bitAllocator.getScaleFac (grpStepSizes[b], &m_mdctSignals[ci][grpOff[b]], sfbWidth, grpRms[b]);
}
} // for gr

View File

@ -1,11 +1,11 @@
/* exhaleLibPch.cpp - pre-compiled source file for classes of exhaleLib coding library
* written by C. R. Helmrich, last modified in 2020 - see License.htm for legal notices
* written by C. R. Helmrich, last modified in 2021 - see License.htm for legal notices
*
* The copyright in this software is being made available under the exhale Copyright License
* and comes with ABSOLUTELY NO WARRANTY. This software may be subject to other third-
* party rights, including patent rights. No such rights are granted under this License.
*
* Copyright (c) 2018-2020 Christian R. Helmrich, project ecodis. All rights reserved.
* Copyright (c) 2018-2021 Christian R. Helmrich, project ecodis. All rights reserved.
*/
#include "exhaleLibPch.h"
@ -59,7 +59,9 @@ static const uint8_t deltaHuffSbrT[14] = {0xFD, 0x7D, 0x3D, 0x1D, 0x0D, 0x05, 0x
// static SBR related functions
static int32_t getSbrDeltaBitCount (const int32_t delta, const bool dt)
{
return (delta == 5 && !dt ? 8 : abs (delta) + 2 + (delta >> 31));
const int dLimit = __max (-7, __min (6, delta));
return (delta != dLimit ? 85 : (delta == 5 && !dt ? 8 : abs (delta) + 2 + (delta >> 31)));
}
static int32_t getSbrDeltaHuffCode (const int32_t delta, const bool dt)
@ -126,13 +128,14 @@ int32_t getSbrEnvelopeAndNoise (int32_t* const sbrLevels, const uint8_t specFlat
(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};
const uint8_t noiseLevel = __min (30, __max (specFlat5b, specFlatSte));
const uint8_t noiseLimit = uint8_t (envTmp0[0] < frameSize * 30 ? 30 - envTmp0[0] / frameSize : 1);
const uint8_t noiseLevel = __max (noiseLimit, __min (30, __max (specFlat5b, specFlatSte)));
const uint32_t rat3BandsL = sbrLevels[28] & USHRT_MAX;
const uint32_t rat3BandsM = sbrLevels[28] >> 16;
const uint32_t rat3BandsH = sbrLevels[29] & USHRT_MAX;
uint64_t errTmp[4] = {0, 0, 0, 0};
uint64_t errBest;
int32_t tmpBest, bitCount, diff;
int32_t tmpBest = 0;
uint8_t t;
for (t = 0; t < 8; t++) // get energy errors due to temporal merging
@ -145,7 +148,6 @@ int32_t getSbrEnvelopeAndNoise (int32_t* const sbrLevels, const uint8_t specFlat
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
{
@ -203,27 +205,27 @@ int32_t getSbrEnvelopeAndNoise (int32_t* const sbrLevels, const uint8_t specFlat
const int32_t c[3] = {curr & SCHAR_MAX, (curr >> 8) & SCHAR_MAX, (curr >> 16) & SCHAR_MAX};
const int32_t prev = sbrLevels[30];
const int32_t p[3] = {prev & SCHAR_MAX, (prev >> 8) & SCHAR_MAX, (prev >> 16) & SCHAR_MAX};
const int df[3] = {c[0]/*PCM*/, c[1] - c[0], c[2] - c[1]};
const int dt[3] = {c[0] - p[0], c[1] - p[1], c[2] - p[2]};
const int* dp = df;
bool useDTime = false;
int32_t bitCount = 8;
if ((t > 0 || !ind) && (getSbrDeltaBitCount (c[0] - p[0], true) + getSbrDeltaBitCount (c[1] - p[1], true) +
getSbrDeltaBitCount (c[2] - p[2], true) < 13)) // approximate!
if ((t > 0 || !ind) && (7/*PCM bits*/ + getSbrDeltaBitCount (df[1],false) + getSbrDeltaBitCount (df[2], false) >
getSbrDeltaBitCount (dt[0], true) + getSbrDeltaBitCount (dt[1], true) + getSbrDeltaBitCount (dt[2], true)))
{
tmpBest |= 1 << (12 + t); // delta-time coding flag for envelope
dp = dt;
useDTime = true;
diff = c[0] - p[0];
sbrData[t] = getSbrDeltaHuffCode (diff, true ); bitCount = 8; // see bitStreamWriter.cpp, lines 186 and 213
diff = c[2] - p[2];
sbrData[t] |= getSbrDeltaHuffCode (diff, true ) << bitCount; bitCount += getSbrDeltaBitCount (diff, true );
diff = c[1] - p[1];
sbrData[t] |= getSbrDeltaHuffCode (diff, true ) << bitCount; bitCount += getSbrDeltaBitCount (diff, true );
sbrData[t] = getSbrDeltaHuffCode (dt[0], true);
}
else // delta-frequency coding
else // delta-frequency
{
sbrData[t] = c[0]; bitCount = 8; // first envelope is PCM coded
diff = c[2] - c[1];
sbrData[t] |= getSbrDeltaHuffCode (diff, false) << bitCount; bitCount += getSbrDeltaBitCount (diff, false);
diff = c[1] - c[0];
sbrData[t] |= getSbrDeltaHuffCode (diff, false) << bitCount; bitCount += getSbrDeltaBitCount (diff, false);
sbrData[t] = df[0];
}
sbrData[t] |= getSbrDeltaHuffCode (dp[2], useDTime) << bitCount; bitCount += getSbrDeltaBitCount (dp[2], useDTime);
sbrData[t] |= getSbrDeltaHuffCode (dp[1], useDTime) << bitCount; bitCount += getSbrDeltaBitCount (dp[1], useDTime);
sbrData[t] |= 1 << bitCount; // MSB delimiter for bitstream writer
sbrLevels[30] = curr;
}