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 /* 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 * 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- * 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. * 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" #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 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 // private reader functions
bool BasicWavReader::readRiffHeader () 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++) for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT) + rest; fract++)
{ {
const int16_t* fBuf = (const int16_t*) tempBuf; // words 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 unsigned read = getFrames (fileHandle, tempBuf, frameCount, (fract & 1), chanCount * 2);
const int bytesRead = _READ (fileHandle, tempBuf, size * chanCount * 2);
const unsigned read = __max (0, bytesRead / (chanCount * 2));
for (unsigned i = read * chanCount; i > 0; i--) 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++) for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT) + rest; fract++)
{ {
const float* fBuf = (const float*) tempBuf; // 4 bytes 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 unsigned read = getFrames (fileHandle, tempBuf, frameCount, (fract & 1), chanCount * 4);
const int bytesRead = _READ (fileHandle, tempBuf, size * chanCount * 4);
const unsigned read = __max (0, bytesRead / (chanCount * 4));
for (unsigned i = read * chanCount; i > 0; i--) 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++) for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT) + rest; fract++)
{ {
const uint8_t* iBuf = (const uint8_t*) tempBuf; // 1b 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 unsigned read = getFrames (fileHandle, tempBuf, frameCount, (fract & 1), chanCount);
const int bytesRead = _READ (fileHandle, tempBuf, size * chanCount);
const unsigned read = __max (0, bytesRead / chanCount);
for (unsigned i = read * chanCount; i > 0; i--) 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++) for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT) + rest; fract++)
{ {
const int16_t* iBuf = (const int16_t*) tempBuf; // words 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 unsigned read = getFrames (fileHandle, tempBuf, frameCount, (fract & 1), chanCount * 2);
const int bytesRead = _READ (fileHandle, tempBuf, size * chanCount * 2);
const unsigned read = __max (0, bytesRead / (chanCount * 2));
for (unsigned i = read * chanCount; i > 0; i--) 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++) for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT) + rest; fract++)
{ {
const uint8_t* iBuf = (const uint8_t*) tempBuf; // 3b 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 unsigned read = getFrames (fileHandle, tempBuf, frameCount, (fract & 1), chanCount * 3);
const int bytesRead = _READ (fileHandle, tempBuf, size * chanCount * 3);
const unsigned read = __max (0, bytesRead / (chanCount * 3));
for (unsigned i = read * chanCount; i > 0; i--) 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++) for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT) + rest; fract++)
{ {
const int32_t* iBuf = (const int32_t*) tempBuf; // dword 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 unsigned read = getFrames (fileHandle, tempBuf, frameCount, (fract & 1), chanCount * 4);
const int bytesRead = _READ (fileHandle, tempBuf, size * chanCount * 4);
const unsigned read = __max (0, bytesRead / (chanCount * 4));
for (unsigned i = read * chanCount; i > 0; i--) 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 // get means of spectral and temporal flatness for every channel
m_bitAllocator.getChAverageSpecFlat (meanSpecFlat, nChannels); m_bitAllocator.getChAverageSpecFlat (meanSpecFlat, nChannels);
//m_bitAllocator.getChAverageTempFlat (meanTempFlat, nChannels);
for (unsigned el = 0; el < m_numElements; el++) // element loop 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 ] = (m_specAnaCurr[ci ] & (UINT_MAX - 65504)) | peakIndexSte;
m_specAnaCurr[ci + 1] = (m_specAnaCurr[ci + 1] & (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; 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 else memset (coreConfig.stereoDataCurr, 0, (eightShorts0 || !coreConfig.commonWindow
? MAX_NUM_SWB_SHORT * NUM_WINDOW_GROUPS : MAX_NUM_SWB_LONG) * sizeof (uint8_t)); ? 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 // 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)); 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]); grpScaleFacs[b] = m_bitAllocator.getScaleFac (grpStepSizes[b], &m_mdctSignals[ci][grpOff[b]], sfbWidth, grpRms[b]);
} }
} // for gr } // for gr

View File

@@ -1,11 +1,11 @@
/* exhaleLibPch.cpp - pre-compiled source file for classes of exhaleLib coding library /* 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 * 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- * 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. * 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" #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 SBR related functions
static int32_t getSbrDeltaBitCount (const int32_t delta, const bool dt) 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) 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}; (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, 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}; 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 rat3BandsL = sbrLevels[28] & USHRT_MAX;
const uint32_t rat3BandsM = sbrLevels[28] >> 16; const uint32_t rat3BandsM = sbrLevels[28] >> 16;
const uint32_t rat3BandsH = sbrLevels[29] & USHRT_MAX; const uint32_t rat3BandsH = sbrLevels[29] & USHRT_MAX;
uint64_t errTmp[4] = {0, 0, 0, 0}; uint64_t errTmp[4] = {0, 0, 0, 0};
uint64_t errBest; uint64_t errBest;
int32_t tmpBest, bitCount, diff; int32_t tmpBest = 0;
uint8_t t; uint8_t t;
for (t = 0; t < 8; t++) // get energy errors due to temporal merging 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 errTmp[3] += abs ((int64_t) envTmp3[t >> 0] - ref); // squares
} }
errBest = errTmp[0]; errBest = errTmp[0];
tmpBest = 0;
for (t = 1; t < 3; t++) // find tmp value for minimal weighted error 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 c[3] = {curr & SCHAR_MAX, (curr >> 8) & SCHAR_MAX, (curr >> 16) & SCHAR_MAX};
const int32_t prev = sbrLevels[30]; const int32_t prev = sbrLevels[30];
const int32_t p[3] = {prev & SCHAR_MAX, (prev >> 8) & SCHAR_MAX, (prev >> 16) & SCHAR_MAX}; 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) + if ((t > 0 || !ind) && (7/*PCM bits*/ + getSbrDeltaBitCount (df[1],false) + getSbrDeltaBitCount (df[2], false) >
getSbrDeltaBitCount (c[2] - p[2], true) < 13)) // approximate! getSbrDeltaBitCount (dt[0], true) + getSbrDeltaBitCount (dt[1], true) + getSbrDeltaBitCount (dt[2], true)))
{ {
tmpBest |= 1 << (12 + t); // delta-time coding flag for envelope tmpBest |= 1 << (12 + t); // delta-time coding flag for envelope
dp = dt;
useDTime = true;
diff = c[0] - p[0]; sbrData[t] = getSbrDeltaHuffCode (dt[0], true);
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 );
} }
else // delta-frequency coding else // delta-frequency
{ {
sbrData[t] = c[0]; bitCount = 8; // first envelope is PCM coded sbrData[t] = df[0];
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] |= 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 sbrData[t] |= 1 << bitCount; // MSB delimiter for bitstream writer
sbrLevels[30] = curr; sbrLevels[30] = curr;
} }