diff --git a/CMakeLists.txt b/CMakeLists.txt
index c1b0793..a7612ee 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,7 +16,7 @@ if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
endif()
-project(exhale VERSION 1.1.5 LANGUAGES CXX)
+project(exhale VERSION 1.1.6 LANGUAGES CXX)
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE Release
diff --git a/README.md b/README.md
index 801d848..2acf35b 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ exhale is being made available under an open-source license which is
based on the 3-clause BSD license but modified to address particular
aspects dictated by the nature and the output of this application.
-The license text and release notes for the current version 1.1.5 can
+The license text and release notes for the current version 1.1.6 can
be found in the `include` subdirectory of the exhale distribution.
diff --git a/include/Release.htm b/include/Release.htm
index 4ef1b91..abc4a87 100644
--- a/include/Release.htm
+++ b/include/Release.htm
@@ -25,9 +25,16 @@
exhale - ecodis extended high-efficiency and low-complexity encoder
Software Release Notes, Version History, Known Issues, Upcoming Feature Roadmap
- The version of this distribution of the «exhale» software release is 1.1.5 (official public minor release) from April 2021. Please check www.ecodis.de 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.
+ The version of this distribution of the «exhale» software release is 1.1.6 (official public minor release) from May 30, 2021. Please check www.ecodis.de 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.
Chronological Version History
- Version 1.1.5 Apr. 2021, this release
+ Version 1.1.6 May 2021, this release
+
+ minor quality tuning and support for delayless operation (media time=0) with SBR
+ exhaleApp: fixed very rare output file corruption after finishing encoding with SBR
+ exhaleApp: fixed compilation error under Fedora (issue 20) and stdin hickup issue
+ exhaleLib: fixed some quality issues in SBR modes, no changes in non-SBR modes
+
+ Version 1.1.5 Apr. 2021
exhaleApp: correct print-out of Unicode file names and paths, minor code cleanup
exhaleLib: minor tuning of immediate playout frames, no changes to audio quality
@@ -146,7 +153,7 @@
exhaleLib: speed-ups and further quality tuning for difficult signals, as necessary.
-Written by C. R. Helmrich for exhale 1.1.5, Apr. 2021. Available at www.ecodis.de/exhale/release.htm.
+Written by C. R. Helmrich for exhale 1.1.6, May 2021. Available at www.ecodis.de/exhale/release.htm.
|
diff --git a/include/version.h b/include/version.h
index a4de981..d33d4d0 100644
--- a/include/version.h
+++ b/include/version.h
@@ -15,5 +15,5 @@
# define EXHALELIB_VERSION_MINOR "1"
#endif
#ifndef EXHALELIB_VERSION_BUGFIX
-# define EXHALELIB_VERSION_BUGFIX ".5" // "RC" or ".0", ".1", ...
+# define EXHALELIB_VERSION_BUGFIX ".6" // "RC" or ".0", ".1", ...
#endif
diff --git a/src/app/basicMP4Writer.cpp b/src/app/basicMP4Writer.cpp
index 4b7c7f1..f5c39c8 100644
--- a/src/app/basicMP4Writer.cpp
+++ b/src/app/basicMP4Writer.cpp
@@ -323,13 +323,13 @@ int BasicMP4Writer::initHeader (const uint32_t audioLength, const unsigned extra
const unsigned numFramesFirstPeriod = __min (frameCount, m_rndAccPeriod);
const unsigned numFramesFinalPeriod = (frameCount <= m_rndAccPeriod ? 0 : frameCount % m_rndAccPeriod);
const unsigned smpGrpSize = 10 /*sgpd*/ + (numFramesFirstPeriod > UINT8_MAX ? 10 : 9) + ((numFramesFirstPeriod + 1) >> 1) /*csgp*/;
- const int estimHeaderSize = STAT_HEADER_SIZE + m_ascSizeM5 + 6 + 4 + frameCount * 4 /*stsz*/ + STSX_BSIZE * 6 + smpGrpSize +
+ const int estimHeaderSize = STAT_HEADER_SIZE + m_ascSizeM5 + 6 + 4 + frameCount * 4 /*stsz*/ + STSX_BSIZE * 6 + smpGrpSize + chunkCount * 4 /*stco*/ +
#ifdef NO_PREROLL_DATA
4 /*minimum stss*/ +
#else
((chunkCount + 1) >> 1) * 4 /*stss*/ +
#endif
- (numFramesFinalPeriod == 0 ? 12 : 24) /*stsc*/ + chunkCount * 4 /*stco*/ + 8 /*mdat*/;
+ (numFramesFinalPeriod == 0 ? (frameCount > m_rndAccPeriod && m_frameLength == 2048 ? 20 : 12) : 24) /*stsc*/ + 8 /*mdat*/;
int bytesWritten = 0;
for (int i = estimHeaderSize; i > 0; i -= STAT_HEADER_SIZE)
diff --git a/src/app/exhaleApp.cpp b/src/app/exhaleApp.cpp
index 6a97219..7bc143c 100644
--- a/src/app/exhaleApp.cpp
+++ b/src/app/exhaleApp.cpp
@@ -257,7 +257,7 @@ int main (const int argc, char* argv[])
{
if (argc <= 0) return argc; // for safety
- const bool readStdin = (argc == 3);
+ const bool readStdin = (argc == 3 || argc == 5);
BasicWavReader wavReader;
int32_t* inPcmData = nullptr; // 24-bit WAVE audio input buffer
#if ENABLE_RESAMPLING
@@ -282,7 +282,7 @@ int main (const int argc, char* argv[])
uint16_t coreSbrFrameLengthIndex = 1; // 0: 768, 1: 1024 samples
uint16_t variableCoreBitRateMode = 3; // 0: lowest... 9: highest
#if ENABLE_RESAMPLING
- uint8_t zeroDelayForSbrEncoding = 0; // 0: 1 frame, 1: no delay
+ uint8_t zeroDelayForSbrEncoding = (argc >= 5 && (argv[2][0] == 's' || argv[2][0] == 'S') && argv[2][1] == 0 ? 1 : 0);
#endif
#ifdef EXHALE_APP_WIN
const HANDLE hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
@@ -391,7 +391,7 @@ int main (const int argc, char* argv[])
fprintf_s (stdout, " ---------------------------------------------------------------------\n\n");
// check arg. list, print usage if needed
- if ((argc < 3) || (argc > 4) || (argc > 1 && argv[1][1] != 0))
+ if ((argc < 3) || (argc > 6) || (argc > 1 && argv[1][1] != 0))
{
fprintf_s (stdout, " Copyright 2018-2021 C.R.Helmrich, project ecodis. See License.htm for details.\n\n");
@@ -522,7 +522,11 @@ int main (const int argc, char* argv[])
if (inPathEnd == 0) // name has no path
{
#if EA_USE_WORK_DIR
+# ifdef __linux__
+ if ((currPath == nullptr) && (currPath = _GETCWD (NULL, 0)) != nullptr)
+# else
if ((currPath == nullptr) && (currPath = _GETCWD (NULL, 1)) != nullptr)
+# endif
{
exePath = currPath;
exePathEnd = (uint16_t) __min (USHRT_MAX - 1, _STRLEN (currPath));
@@ -631,7 +635,11 @@ int main (const int argc, char* argv[])
if (outPathEnd == 0) // name has no path
{
#if EA_USE_WORK_DIR
+# ifdef __linux__
+ if ((currPath != exePath) && (currPath = _GETCWD (NULL, 0)) != nullptr)
+# else
if ((currPath != exePath) && (currPath = _GETCWD (NULL, 1)) != nullptr)
+# endif
{
exePath = currPath;
exePathEnd = (uint16_t) __min (USHRT_MAX - 1, _STRLEN (currPath));
@@ -746,7 +754,8 @@ int main (const int argc, char* argv[])
#else
const unsigned sampleRate = wavReader.getSampleRate ();
#endif
- const unsigned indepPeriod = (sampleRate < 48000 ? sampleRate - 320u : 50u << 10u) / frameLength;
+ const bool userIndepPeriod = (argc >= 5 && argv[3][0] > '0' && argv[3][0] <= '9' && argv[3][1] >= '0' && argv[3][1] <= '9' && argv[3][2] == 0);
+ const unsigned indepPeriod = (userIndepPeriod ? 10 * (argv[3][0] - 48) + (argv[3][1] - 48) : (sampleRate < 48000 ? sampleRate - 320u : 50u << 10u) / frameLength);
const unsigned mod3Percent = unsigned ((expectLength * (3 + (coreSbrFrameLengthIndex & 3))) >> 17);
uint32_t byteCount = 0, bw = (numChannels < 7 ? loudStats : 0);
uint32_t br, bwMax = 0; // br will be used to hold bytes read and/or bit-rate
diff --git a/src/app/exhaleApp.rc b/src/app/exhaleApp.rc
index 538e402..b2b649c 100644
--- a/src/app/exhaleApp.rc
+++ b/src/app/exhaleApp.rc
@@ -13,7 +13,7 @@
0 ICON "exhaleApp.ico"
VS_VERSION_INFO VERSIONINFO
-FILEVERSION 1,1,5
+FILEVERSION 1,1,6
BEGIN
BLOCK "StringFileInfo"
BEGIN
diff --git a/src/lib/exhaleEnc.cpp b/src/lib/exhaleEnc.cpp
index 8a3df76..f890fe9 100644
--- a/src/lib/exhaleEnc.cpp
+++ b/src/lib/exhaleEnc.cpp
@@ -1447,7 +1447,7 @@ unsigned ExhaleEncoder::spectralProcessing () // complete ics_info(), calc TNS
}
icsCurr.maxSfb = __min (icsCurr.maxSfb, brModeAndFsToMaxSfbLong (m_bitRateMode, samplingRate));
}
- while (grpSO[icsCurr.maxSfb] > __max (m_bandwidCurr[ci], m_bandwidPrev[ci])) icsCurr.maxSfb--; // BW detector
+ while (grpSO[icsCurr.maxSfb] > __max (m_bandwidCurr[ci], m_bandwidPrev[ci]) + (icsCurr.maxSfb >> 1)) icsCurr.maxSfb--; // detect BW
}
else // icsCurr.windowSequence == EIGHT_SHORT
{
@@ -2142,7 +2142,7 @@ unsigned ExhaleEncoder::initEncoder (unsigned char* const audioConfigBuffer, uin
const uint32_t loudnessInfo = (audioConfigBytes ? *audioConfigBytes : 0);
if (*audioConfigBuffer & 1) m_frameCount--; // to skip 1 frame
- m_priLength = (*audioConfigBuffer >> 1); // priming, see below
+ m_priLength = (*audioConfigBuffer >> 1);
errorValue = m_outStream.createAudioConfig (m_frequencyIdx, m_frameLength != CCFL_1024, chConf, m_numElements,
elementTypeConfig[chConf], loudnessInfo,
#if !RESTRICT_TO_AAC
|