mirror of
https://gitlab.com/ecodis/exhale.git
synced 2025-01-04 19:20:32 +01:00
realign and clean
This commit is contained in:
parent
5bfcbaca3e
commit
ab91fd8f9c
@ -316,16 +316,9 @@ int BasicMP4Writer::finishFile (const unsigned avgBitrate, const unsigned maxBit
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
int BasicMP4Writer::initHeader (const uint32_t audioLength) // reserve bytes for header in file
|
||||
int BasicMP4Writer::initHeader (const uint32_t audioLength, const unsigned extraDelay)
|
||||
{
|
||||
/* NOTE: the following condition is, as far as I can tell, correct, but some decoders with DRC processing
|
||||
may decode too few samples with it. Hence, I disabled it. See also corresponding NOTE in exhaleApp.cpp */
|
||||
const bool flushFrameUsed = true; // ((audioLength + m_pregapLength) % m_frameLength) > 0;
|
||||
#ifdef NO_PREROLL_DATA
|
||||
const unsigned frameCount = ((audioLength + m_frameLength - 1) / m_frameLength) + (flushFrameUsed ? 2 : 1);
|
||||
#else
|
||||
const unsigned frameCount = ((audioLength + m_frameLength - 1) / m_frameLength) + (flushFrameUsed ? 1 : 0);
|
||||
#endif
|
||||
const unsigned frameCount = (audioLength + m_pregapLength - extraDelay + m_sampleRate / 200u + m_frameLength - 1u) / m_frameLength;
|
||||
const unsigned chunkCount = ((frameCount + m_rndAccPeriod - 1) / m_rndAccPeriod);
|
||||
const unsigned numFramesFirstPeriod = __min (frameCount, m_rndAccPeriod);
|
||||
const unsigned numFramesFinalPeriod = (frameCount <= m_rndAccPeriod ? 0 : frameCount % m_rndAccPeriod);
|
||||
@ -366,7 +359,7 @@ unsigned BasicMP4Writer::open (const int mp4FileHandle, const unsigned sampleRat
|
||||
}
|
||||
|
||||
m_fileHandle = mp4FileHandle;
|
||||
reset (frameLength, pregapLength, __min (USHRT_MAX, raPeriod));
|
||||
reset (frameLength, pregapLength, __min (USHRT_MAX, raPeriod), sampleRate);
|
||||
|
||||
// create fixed-length 576-byte part of MPEG-4 file header
|
||||
memcpy (m_staticHeader, staticHeaderTemplate, STAT_HEADER_SIZE * sizeof (uint8_t));
|
||||
@ -427,7 +420,7 @@ unsigned BasicMP4Writer::open (const int mp4FileHandle, const unsigned sampleRat
|
||||
return 0; // correct operation
|
||||
}
|
||||
|
||||
void BasicMP4Writer::reset (const unsigned frameLength /*= 0*/, const unsigned pregapLength /*= 0*/, const unsigned raPeriod /*= 0*/)
|
||||
void BasicMP4Writer::reset (const unsigned frameLength, const unsigned pregapLength, const unsigned raPeriod, const unsigned sampleRate)
|
||||
{
|
||||
m_ascSizeM5 = 0;
|
||||
m_frameCount = 0;
|
||||
@ -436,7 +429,7 @@ void BasicMP4Writer::reset (const unsigned frameLength /*= 0*/, const unsigned p
|
||||
m_mediaSize = 0; // total length of 'mdat' (access unit) payload in file
|
||||
m_pregapLength = pregapLength;
|
||||
m_rndAccPeriod = raPeriod;
|
||||
m_sampleRate = 0;
|
||||
m_sampleRate = sampleRate;
|
||||
m_dynamicHeader.clear ();
|
||||
m_rndAccOffsets.clear ();
|
||||
#ifndef NO_PREROLL_DATA
|
||||
|
@ -53,7 +53,7 @@ private:
|
||||
public:
|
||||
|
||||
// constructor
|
||||
BasicMP4Writer () { m_fileHandle = -1; reset (); }
|
||||
BasicMP4Writer () { m_fileHandle = -1; reset (0, 0, 0, 0); }
|
||||
// destructor
|
||||
#ifdef NO_PREROLL_DATA
|
||||
~BasicMP4Writer() { m_dynamicHeader.clear (); m_rndAccOffsets.clear (); }
|
||||
@ -65,12 +65,12 @@ public:
|
||||
int finishFile (const unsigned avgBitrate, const unsigned maxBitrate, const uint32_t audioLength,
|
||||
const uint32_t modifTime = 0, const uint8_t* ascBuf = nullptr);
|
||||
unsigned getFrameCount () const { return m_frameCount; }
|
||||
int initHeader (const uint32_t audioLength);
|
||||
int initHeader (const uint32_t audioLength, const unsigned extraDelay);
|
||||
unsigned open (const int mp4FileHandle, const unsigned sampleRate, const unsigned numChannels,
|
||||
const unsigned bitDepth, const unsigned frameLength, const unsigned pregapLength,
|
||||
const unsigned raPeriod, const uint8_t* ascBuf, const unsigned ascSize,
|
||||
const uint32_t creatTime = 0, const char vbrQuality = 0);
|
||||
void reset (const unsigned frameLength = 0, const unsigned pregapLength = 0, const unsigned raPeriod = 0);
|
||||
void reset (const unsigned frameLength, const unsigned pregapLength, const unsigned raPeriod, const unsigned sampleRate);
|
||||
#ifndef NO_PREROLL_DATA
|
||||
int updateIPFs (const uint8_t* ascUcBuf, const uint32_t ascUcLength, const uint32_t ucOffset);
|
||||
#endif
|
||||
|
@ -118,9 +118,10 @@ unsigned BasicWavReader::readDataFloat16 (const int fileHandle, int32_t* frameBu
|
||||
const unsigned chanCount, void* tempBuf)
|
||||
{
|
||||
#if BWR_BUFFERED_READ
|
||||
const unsigned rest = ((frameCount >> (BWR_READ_FRACT - 1)) << (BWR_READ_FRACT - 1)) < frameCount ? 1 : 0;
|
||||
unsigned framesRead = 0;
|
||||
|
||||
for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT); fract++)
|
||||
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;
|
||||
@ -168,9 +169,10 @@ unsigned BasicWavReader::readDataFloat32 (const int fileHandle, int32_t* frameBu
|
||||
const unsigned chanCount, void* tempBuf)
|
||||
{
|
||||
#if BWR_BUFFERED_READ
|
||||
const unsigned rest = ((frameCount >> (BWR_READ_FRACT - 1)) << (BWR_READ_FRACT - 1)) < frameCount ? 1 : 0;
|
||||
unsigned framesRead = 0;
|
||||
|
||||
for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT); fract++)
|
||||
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;
|
||||
@ -216,9 +218,10 @@ unsigned BasicWavReader::readDataLnPcm08 (const int fileHandle, int32_t* frameBu
|
||||
const unsigned chanCount, void* tempBuf)
|
||||
{
|
||||
#if BWR_BUFFERED_READ
|
||||
const unsigned rest = ((frameCount >> (BWR_READ_FRACT - 1)) << (BWR_READ_FRACT - 1)) < frameCount ? 1 : 0;
|
||||
unsigned framesRead = 0;
|
||||
|
||||
for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT); fract++)
|
||||
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;
|
||||
@ -254,9 +257,10 @@ unsigned BasicWavReader::readDataLnPcm16 (const int fileHandle, int32_t* frameBu
|
||||
const unsigned chanCount, void* tempBuf)
|
||||
{
|
||||
#if BWR_BUFFERED_READ
|
||||
const unsigned rest = ((frameCount >> (BWR_READ_FRACT - 1)) << (BWR_READ_FRACT - 1)) < frameCount ? 1 : 0;
|
||||
unsigned framesRead = 0;
|
||||
|
||||
for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT); fract++)
|
||||
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;
|
||||
@ -292,9 +296,10 @@ unsigned BasicWavReader::readDataLnPcm24 (const int fileHandle, int32_t* frameBu
|
||||
const unsigned chanCount, void* tempBuf)
|
||||
{
|
||||
#if BWR_BUFFERED_READ
|
||||
const unsigned rest = ((frameCount >> (BWR_READ_FRACT - 1)) << (BWR_READ_FRACT - 1)) < frameCount ? 1 : 0;
|
||||
unsigned framesRead = 0;
|
||||
|
||||
for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT); fract++)
|
||||
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;
|
||||
@ -332,9 +337,10 @@ unsigned BasicWavReader::readDataLnPcm32 (const int fileHandle, int32_t* frameBu
|
||||
const unsigned chanCount, void* tempBuf)
|
||||
{
|
||||
#if BWR_BUFFERED_READ
|
||||
const unsigned rest = ((frameCount >> (BWR_READ_FRACT - 1)) << (BWR_READ_FRACT - 1)) < frameCount ? 1 : 0;
|
||||
unsigned framesRead = 0;
|
||||
|
||||
for (unsigned fract = 0; fract < (1 << BWR_READ_FRACT); fract++)
|
||||
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;
|
||||
|
@ -54,11 +54,10 @@
|
||||
#define EA_PEAK_NORM -96.33f // 20 * log10(2^-16), 16-bit normalization
|
||||
#define EA_PEAK_MIN 0.262f // 20 * log10() + EA_PEAK_NORM = -108 dbFS
|
||||
#define ENABLE_RESAMPLING 1 // 1: automatic input up- and downsampling
|
||||
#define ENABLE_SIMPLE_SBR 1 // 1: basic 2:1 low-rate SBR functionality
|
||||
#define IGNORE_WAV_LENGTH 0 // 1: ignore input size indicators (nasty)
|
||||
#define XHE_AAC_LOW_DELAY 0 // 1: allow encoding with 768 frame length
|
||||
|
||||
#if ENABLE_RESAMPLING
|
||||
#define FULL_FRM_LOOKAHEAD // on: encoder delay = zero or frame length
|
||||
|
||||
static const int16_t usfc2x[32] = { // 2x upsampling filter coefficients
|
||||
(83359-65536), -27563, 16273, -11344, 8541, -6708, 5403, -4419, 3647, -3025, 2514, -2088, 1730,
|
||||
-1428, 1173, -957, 775, -622, 494, -388, 300, -230, 172, -127, 91, -63, 43, -27, 16, -9, 4, -1
|
||||
@ -382,14 +381,14 @@ int main (const int argc, char* argv[])
|
||||
fprintf_s (stdout, " preset\t= # (0-9) low-complexity standard compliant xHE-AAC at 16ú#+48 kbit/s\n");
|
||||
# if XHE_AAC_LOW_DELAY
|
||||
fprintf_s (stdout, " \t (A-J) 41ms low-delay compatible xHE-AAC with BE at 16ú#+48 kbit/s\n");
|
||||
# elif ENABLE_SIMPLE_SBR
|
||||
# else
|
||||
fprintf_s (stdout, " \t (a-g) low-complexity compliant xHE-AAC with SBR at 12ú#+36 kbit/s\n");
|
||||
# endif
|
||||
#else
|
||||
fprintf_s (stdout, " preset\t= # (0-9) low-complexity standard compliant xHE-AAC at 16*#+48 kbit/s\n");
|
||||
# if XHE_AAC_LOW_DELAY
|
||||
fprintf_s (stdout, " \t (A-J) 41ms low-delay compatible xHE-AAC with BE at 16*#+48 kbit/s\n");
|
||||
# elif ENABLE_SIMPLE_SBR
|
||||
# else
|
||||
fprintf_s (stdout, " \t (a-g) low-complexity compliant xHE-AAC with SBR at 12*#+36 kbit/s\n");
|
||||
# endif
|
||||
#endif
|
||||
@ -420,19 +419,13 @@ int main (const int argc, char* argv[])
|
||||
// check preset mode, derive coder config
|
||||
#if XHE_AAC_LOW_DELAY
|
||||
if ((*argv[1] >= '0' && *argv[1] <= '9') || (*argv[1] >= 'A' && *argv[1] <= 'J'))
|
||||
#elif ENABLE_SIMPLE_SBR
|
||||
if ((*argv[1] >= '0' && *argv[1] <= '9') || (*argv[1] >= 'a' && *argv[1] <= 'g'))
|
||||
#else
|
||||
if (*argv[1] >= '0' && *argv[1] <= '9')
|
||||
if ((*argv[1] >= '0' && *argv[1] <= '9') || (*argv[1] >= 'a' && *argv[1] <= 'g'))
|
||||
#endif
|
||||
{
|
||||
i = (uint16_t) argv[1][0];
|
||||
compatibleExtensionFlag = (i & 0x40) >> 6;
|
||||
#if ENABLE_SIMPLE_SBR
|
||||
coreSbrFrameLengthIndex = (i > 0x60 ? 5 : (i & 0x20) >> 5);
|
||||
#else
|
||||
coreSbrFrameLengthIndex = (i & 0x20) >> 5;
|
||||
#endif
|
||||
variableCoreBitRateMode = (i & 0x0F) - (i >> 6);
|
||||
}
|
||||
else if (*argv[1] == '#') // default mode
|
||||
@ -447,18 +440,12 @@ int main (const int argc, char* argv[])
|
||||
# else
|
||||
fprintf_s (stderr, " ERROR reading preset mode: character %s is not supported! Use 0-9 or A-J.\n\n", argv[1]);
|
||||
# endif
|
||||
#elif ENABLE_SIMPLE_SBR
|
||||
#else
|
||||
# ifdef EXHALE_APP_WCHAR
|
||||
fwprintf_s (stderr, L" ERROR reading preset mode: character %s is not supported! Use 0-9 or a-g.\n\n", argv[1]);
|
||||
# else
|
||||
fprintf_s (stderr, " ERROR reading preset mode: character %s is not supported! Use 0-9 or a-g.\n\n", argv[1]);
|
||||
# endif
|
||||
#else
|
||||
# ifdef EXHALE_APP_WCHAR
|
||||
fwprintf_s (stderr, L" ERROR reading preset mode: character %s is not supported! Please use 0-9.\n\n", argv[1]);
|
||||
# else
|
||||
fprintf_s (stderr, " ERROR reading preset mode: character %s is not supported! Please use 0-9.\n\n", argv[1]);
|
||||
# endif
|
||||
#endif
|
||||
return 16384; // preset isn't supported
|
||||
}
|
||||
@ -542,18 +529,14 @@ int main (const int argc, char* argv[])
|
||||
#else // Linux, MacOS, Unix
|
||||
if ((wavReader.open (inFileHandle, startLength, readStdin ? LLONG_MAX : lseek (inFileHandle, 0, 2 /*SEEK_END*/)) != 0) ||
|
||||
#endif
|
||||
#if ENABLE_SIMPLE_SBR
|
||||
(wavReader.getSampleRate () >= 1000 && wavReader.getSampleRate () < 24000 && coreSbrFrameLengthIndex >= 3) ||
|
||||
#endif
|
||||
(wavReader.getNumChannels () >= 7))
|
||||
(wavReader.getSampleRate () >= 1000 && wavReader.getSampleRate () < 24000 && coreSbrFrameLengthIndex >= 3) || (wavReader.getNumChannels () >= 7))
|
||||
{
|
||||
fprintf_s (stderr, " ERROR while trying to open WAVE file: invalid or unsupported audio format!\n\n");
|
||||
#if ENABLE_SIMPLE_SBR
|
||||
|
||||
if (wavReader.getSampleRate () >= 1000 && wavReader.getSampleRate () < 24000 && coreSbrFrameLengthIndex >= 3)
|
||||
{
|
||||
fprintf_s (stderr, " The sampling rate is %d kHz but xHE-AAC with SBR requires at least 24 kHz.\n\n", wavReader.getSampleRate () / 1000);
|
||||
}
|
||||
#endif
|
||||
i = 8192; // return value
|
||||
|
||||
goto mainFinish; // audio format invalid
|
||||
@ -582,14 +565,11 @@ int main (const int argc, char* argv[])
|
||||
goto mainFinish; // bad output string
|
||||
}
|
||||
|
||||
if (wavReader.getSampleRate () > 32100 + (unsigned) variableCoreBitRateMode * 12000 + (variableCoreBitRateMode >> 2) * 3900
|
||||
#if ENABLE_SIMPLE_SBR
|
||||
&& (coreSbrFrameLengthIndex < 3)
|
||||
#endif
|
||||
if ((wavReader.getSampleRate () > 32100 + (unsigned) variableCoreBitRateMode * 12000 + (variableCoreBitRateMode >> 2) * 3900) &&
|
||||
#if ENABLE_RESAMPLING
|
||||
&& (variableCoreBitRateMode > 1 || wavReader.getSampleRate () != 48000)
|
||||
(variableCoreBitRateMode > 1 || wavReader.getSampleRate () != 48000) &&
|
||||
#endif
|
||||
)
|
||||
(coreSbrFrameLengthIndex < 3))
|
||||
{
|
||||
i = (variableCoreBitRateMode > 4 ? 96 : __min (64, 32 + variableCoreBitRateMode * 12));
|
||||
fprintf_s (stderr, " ERROR during encoding! Input sample rate must be <=%d kHz for preset mode %d!\n\n", i, variableCoreBitRateMode);
|
||||
@ -597,11 +577,7 @@ int main (const int argc, char* argv[])
|
||||
|
||||
goto mainFinish; // ask for resampling
|
||||
}
|
||||
#if ENABLE_SIMPLE_SBR
|
||||
if (wavReader.getSampleRate () > 32000 && coreSbrFrameLengthIndex < 3 && variableCoreBitRateMode <= 1)
|
||||
#else
|
||||
if (wavReader.getSampleRate () > 32000 && variableCoreBitRateMode <= 1)
|
||||
#endif
|
||||
if ((wavReader.getSampleRate () > 32000) && (coreSbrFrameLengthIndex < 3) && (variableCoreBitRateMode <= 1))
|
||||
{
|
||||
#if ENABLE_RESAMPLING
|
||||
if (wavReader.getSampleRate () == 48000)
|
||||
@ -658,18 +634,19 @@ int main (const int argc, char* argv[])
|
||||
{
|
||||
const unsigned numChannels = wavReader.getNumChannels ();
|
||||
const unsigned inSampDepth = wavReader.getBitDepth ();
|
||||
const unsigned sbrEncDelay = (coreSbrFrameLengthIndex >= 3 ? 962 : 0);
|
||||
#if ENABLE_RESAMPLING
|
||||
const bool enableUpsampler = eaInitUpsampler2x (&inPcmRsmp, variableCoreBitRateMode, i, frameLength, numChannels);
|
||||
# if ENABLE_SIMPLE_SBR
|
||||
const bool enableResampler = (coreSbrFrameLengthIndex >= 3 ? false : // no 3:2 downsampling needed when using SBR
|
||||
eaInitDownsampler (&inPcmRsmp, variableCoreBitRateMode, i, frameLength, numChannels));
|
||||
# else
|
||||
const bool enableResampler = eaInitDownsampler (&inPcmRsmp, variableCoreBitRateMode, i, frameLength, numChannels);
|
||||
# endif
|
||||
const uint16_t firstLength = uint16_t (enableUpsampler ? (frameLength >> 1) + 32 : (enableResampler ? startLength : frameLength));
|
||||
const unsigned inFrameSize = (enableResampler ? startLength : frameLength) * sizeof (int32_t); // max buffer size
|
||||
const unsigned resampRatio = (enableResampler ? 3 : 1); // for resampling ratio
|
||||
const unsigned resampShift = (enableResampler || enableUpsampler ? 1 : 0);
|
||||
# ifdef FULL_FRM_LOOKAHEAD
|
||||
const uint16_t inPadLength = uint16_t ((((frameLength << 1) - startLength) * resampRatio) >> resampShift)
|
||||
+ (coreSbrFrameLengthIndex >= 3 ? firstLength - (sbrEncDelay >> resampShift) : 0);
|
||||
# endif
|
||||
const int64_t expectLength = (wavReader.getDataBytesLeft () << resampShift) / int64_t ((numChannels * inSampDepth * resampRatio) >> 3);
|
||||
|
||||
if (enableUpsampler) // notify by printf
|
||||
@ -696,7 +673,13 @@ int main (const int argc, char* argv[])
|
||||
}
|
||||
|
||||
#if ENABLE_RESAMPLING
|
||||
# ifdef FULL_FRM_LOOKAHEAD
|
||||
memset (inPcmData, 0, inPadLength * numChannels * sizeof (int32_t)); // padding
|
||||
|
||||
if (inPadLength + wavReader.read (inPcmData + inPadLength * numChannels, firstLength - inPadLength) != firstLength)
|
||||
# else
|
||||
if (wavReader.read (inPcmData, firstLength) != firstLength) // full first frame
|
||||
# endif
|
||||
#else
|
||||
if (wavReader.read (inPcmData, frameLength) != frameLength) // full first frame
|
||||
#endif
|
||||
@ -737,11 +720,16 @@ int main (const int argc, char* argv[])
|
||||
|
||||
// init encoder, generate UsacConfig()
|
||||
memset (outAuData, 0, 108 * sizeof (uint8_t)); // max. allowed ASC + UC size
|
||||
#ifdef FULL_FRM_LOOKAHEAD
|
||||
outAuData[0] = 1; // to skip 1st frame
|
||||
#endif
|
||||
i = exhaleEnc.initEncoder (outAuData, &bw); // bw stores actual ASC + UC size
|
||||
|
||||
if ((i |= mp4Writer.open (outFileHandle, sampleRate, numChannels, inSampDepth, frameLength, startLength
|
||||
#if ENABLE_SIMPLE_SBR
|
||||
+ (coreSbrFrameLengthIndex >= 3 ? 962 : 0)
|
||||
if ((i |= mp4Writer.open (outFileHandle, sampleRate, numChannels, inSampDepth, frameLength,
|
||||
#ifdef FULL_FRM_LOOKAHEAD
|
||||
(frameLength << (coreSbrFrameLengthIndex >= 3 ? 1 : 0))
|
||||
#else
|
||||
startLength + sbrEncDelay
|
||||
#endif
|
||||
#ifndef NO_PREROLL_DATA
|
||||
- frameLength
|
||||
@ -759,12 +747,8 @@ int main (const int argc, char* argv[])
|
||||
if (*argv[1] != '#') // user-def. mode
|
||||
{
|
||||
fprintf_s (stdout, " Encoding %d-kHz %d-channel %d-bit WAVE to low-complexity xHE-AAC at %d kbit/s\n\n",
|
||||
#if ENABLE_SIMPLE_SBR
|
||||
sampleRate / 1000, numChannels, inSampDepth, __min (5, numChannels) * (((24 + variableCoreBitRateMode * 8) *
|
||||
(coreSbrFrameLengthIndex >= 3 ? 3 : 4)) >> 2));
|
||||
#else
|
||||
sampleRate / 1000, numChannels, inSampDepth, __min (5, numChannels) * (24 + variableCoreBitRateMode * 8));
|
||||
#endif
|
||||
}
|
||||
if (!readStdin && (mod3Percent > 0))
|
||||
{
|
||||
@ -777,20 +761,20 @@ int main (const int argc, char* argv[])
|
||||
fprintf_s (stdout, EXHALE_TEXT_BLUE " Progress: " EXHALE_TEXT_INIT "-"); fflush (stdout);
|
||||
#endif
|
||||
}
|
||||
#if !IGNORE_WAV_LENGTH
|
||||
|
||||
if (!readStdin) // reserve space for MP4 file header. TODO: nasty, avoid this
|
||||
{
|
||||
if ((headerRes = (uint32_t) mp4Writer.initHeader (uint32_t (__min (UINT_MAX - startLength, expectLength)))) < 666)
|
||||
if ((headerRes = (uint32_t) mp4Writer.initHeader (uint32_t (__min (UINT_MAX - startLength, expectLength)), sbrEncDelay)) < 666)
|
||||
{
|
||||
fprintf_s (stderr, "\n ERROR while trying to write MPEG-4 bit-stream header: stopped after %d bytes!\n\n", headerRes);
|
||||
i = 3; // return value
|
||||
# if USE_EXHALELIB_DLL
|
||||
#if USE_EXHALELIB_DLL
|
||||
exhaleDelete (&exhaleEnc);
|
||||
# endif
|
||||
#endif
|
||||
goto mainFinish; // writeout error
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
i = 1; // for progress bar
|
||||
|
||||
#if ENABLE_RESAMPLING
|
||||
@ -809,6 +793,25 @@ int main (const int argc, char* argv[])
|
||||
#endif
|
||||
goto mainFinish; // coder-time error
|
||||
}
|
||||
#ifdef FULL_FRM_LOOKAHEAD
|
||||
wavReader.read (inPcmData, (frameLength * resampRatio) >> resampShift); // discard the initial look-ahead AU
|
||||
|
||||
// resample leading frame if necessary
|
||||
if (enableUpsampler) eaApplyUpsampler2x (inPcmData, inPcmRsmp, frameLength, numChannels);
|
||||
else
|
||||
if (enableResampler) eaApplyDownsampler (inPcmData, inPcmRsmp, frameLength, numChannels);
|
||||
|
||||
// leading frame, actual look-ahead AU
|
||||
if ((bw = exhaleEnc.encodeFrame ()) < 3)
|
||||
{
|
||||
fprintf_s (stderr, "\n ERROR while trying to create first xHE-AAC frame: error value %d was returned!\n\n", bw);
|
||||
i = 2; // return value
|
||||
# if USE_EXHALELIB_DLL
|
||||
exhaleDelete (&exhaleEnc);
|
||||
# endif
|
||||
goto mainFinish; // coder-time error
|
||||
}
|
||||
#endif
|
||||
#ifdef NO_PREROLL_DATA
|
||||
if (bwMax < bw) bwMax = bw;
|
||||
// write first AU, add frame to header
|
||||
@ -864,11 +867,7 @@ int main (const int argc, char* argv[])
|
||||
|
||||
if (!readStdin && (mod3Percent > 0) && !(mp4Writer.getFrameCount () % mod3Percent))
|
||||
{
|
||||
#if ENABLE_SIMPLE_SBR
|
||||
if ((i++) < (coreSbrFrameLengthIndex >= 3 ? 17 : 34)) // with short files
|
||||
#else
|
||||
if ((i++) < 34) // for short files
|
||||
#endif
|
||||
{
|
||||
fprintf_s (stdout, "-"); fflush (stdout);
|
||||
}
|
||||
@ -904,13 +903,22 @@ int main (const int argc, char* argv[])
|
||||
|
||||
#if ENABLE_RESAMPLING
|
||||
const int64_t actualLength = (wavReader.getDataBytesRead () << resampShift) / int64_t ((numChannels * inSampDepth * resampRatio) >> 3);
|
||||
const int64_t inFileLength = wavReader.getDataBytesRead () / int64_t ((numChannels * inSampDepth) >> 3);
|
||||
const unsigned inFrmLength = (frameLength * resampRatio) >> resampShift;
|
||||
# ifdef FULL_FRM_LOOKAHEAD
|
||||
const unsigned flushLength = (inFileLength - (enableUpsampler ? 32 : 0) + inPadLength) % inFrmLength;
|
||||
# else
|
||||
const unsigned flushLength = (inFileLength - (enableUpsampler ? 32 : 0)) % inFrmLength;
|
||||
# endif
|
||||
if ((flushLength == 0) || (flushLength + ((startLength * resampRatio) >> resampShift) - inFrmLength // flush
|
||||
+ (enableUpsampler ? 32 : 0) + wavReader.getSampleRate () / 200 > inFrmLength))
|
||||
#else
|
||||
const int64_t actualLength = wavReader.getDataBytesRead () / int64_t ((numChannels * inSampDepth) >> 3);
|
||||
const unsigned flushLength = actualLength % frameLength;
|
||||
|
||||
if ((flushLength == 0) || (flushLength + startLength - frameLength + sampleRate/200 > frameLength)) // flush
|
||||
#endif
|
||||
/* NOTE: the following "if" is, as far as I can tell, correct, but some decoders
|
||||
with DRC processing may decode too few samples with it. Hence, I disabled it.
|
||||
if (((actualLength + startLength) % frameLength) > 0) // flush trailing audio
|
||||
*/ {
|
||||
{
|
||||
memset (inPcmData, 0, inFrameSize * numChannels);
|
||||
#if ENABLE_RESAMPLING
|
||||
// resample flush frame if necessary
|
||||
@ -940,13 +948,11 @@ int main (const int argc, char* argv[])
|
||||
byteCount += bw;
|
||||
} // trailing frame
|
||||
|
||||
#if !IGNORE_WAV_LENGTH
|
||||
if (readStdin) // reserve space for MP4 file header (is there an easier way?)
|
||||
#endif
|
||||
{
|
||||
int64_t pos = _SEEK (outFileHandle, 0, 1 /*SEEK_CUR*/);
|
||||
|
||||
if ((headerRes = (uint32_t) mp4Writer.initHeader (uint32_t (__min (UINT_MAX - startLength, actualLength)))) < 666)
|
||||
if ((headerRes = (uint32_t) mp4Writer.initHeader (uint32_t (__min (UINT_MAX - startLength, actualLength)), sbrEncDelay)) < 666)
|
||||
{
|
||||
fprintf_s (stderr, "\n ERROR while trying to write MPEG-4 bit-stream header: stopped after %d bytes!\n\n", headerRes);
|
||||
i = 3; // return value
|
||||
@ -990,7 +996,7 @@ int main (const int argc, char* argv[])
|
||||
if (i == 0)
|
||||
{
|
||||
i = __min (USHRT_MAX, wavReader.getSampleRate ());
|
||||
i = (uint16_t) mp4Writer.updateIPFs (outAuData, bw, (i == 57600 || i == 38400 || i == 19200 /*BL USAC*/ ? 6 : 3));
|
||||
i = (uint16_t) mp4Writer.updateIPFs (outAuData, bw, (i == 57600 || i == 38400 || i == 28800 || i == 19200 /*BL USAC*/ ? 6 : 3));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1000,14 +1006,14 @@ int main (const int argc, char* argv[])
|
||||
bw = mp4Writer.finishFile (br, bw, uint32_t (__min (UINT_MAX - startLength, actualLength)), (time (nullptr) + 2082844800) & UINT_MAX,
|
||||
(i == 0) && (numChannels < 7) ? outAuData : nullptr);
|
||||
// print out collected file statistics
|
||||
#if ENABLE_SIMPLE_SBR
|
||||
if (coreSbrFrameLengthIndex >= 3)
|
||||
{
|
||||
fprintf_s (stdout, " Done, actual average incl. SBR data %.2f kbit/s\n\n", (float) br * 0.001f);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
fprintf_s (stdout, " Done, actual average %.1f kbit/s\n\n", (float) br * 0.001f);
|
||||
{
|
||||
fprintf_s (stdout, " Done, actual average %.1f kbit/s\n\n", (float) br * 0.001f);
|
||||
}
|
||||
if (numChannels < 7)
|
||||
{
|
||||
fprintf_s (stdout, " Input statistics: File loudness %.2f LUFS,\tsample peak level %.2f dBFS\n\n",
|
||||
|
@ -1691,7 +1691,6 @@ unsigned ExhaleEncoder::temporalProcessing () // determine time-domain aspects o
|
||||
tsCurr[ch] = (m_tempAnaCurr[ci] /*R*/) & UCHAR_MAX;
|
||||
tsNext[ch] = (m_tempAnaNext[ci] >> 8) & UCHAR_MAX;
|
||||
// save maximum spectral flatness of current and neighboring frames for quantization
|
||||
// m_specFlatPrev[ci] = __max (m_specFlatPrev[ci], (m_specAnaCurr[ci] >> 16) & UCHAR_MAX);
|
||||
m_tempAnaCurr [ci] = (m_tempAnaCurr[ci] & 0xFFFFFF) | (__max (sfCurr, __max (m_specFlatPrev[ci], sfNext)) << 24);
|
||||
m_specFlatPrev[ci] = (uint8_t) sfCurr;
|
||||
|
||||
@ -2155,7 +2154,9 @@ unsigned ExhaleEncoder::initEncoder (unsigned char* const audioConfigBuffer, uin
|
||||
if ((errorValue == 0) && (audioConfigBuffer != nullptr)) // save UsacConfig() for writeout
|
||||
{
|
||||
const uint32_t loudnessInfo = (audioConfigBytes ? *audioConfigBytes : 0);
|
||||
|
||||
#if 1 //FULL_FRM_LOOKAHEAD
|
||||
if (*audioConfigBuffer > 0) m_frameCount--; // to skip 1 frame
|
||||
#endif
|
||||
errorValue = m_outStream.createAudioConfig (m_frequencyIdx, m_frameLength != CCFL_1024, chConf, m_numElements,
|
||||
elementTypeConfig[chConf], loudnessInfo,
|
||||
#if !RESTRICT_TO_AAC
|
||||
|
Loading…
Reference in New Issue
Block a user