diff --git a/README.md b/README.md
index 55b6738..6e61997 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,10 @@ encode uncompressed WAVE-format audio files into MPEG-4-format files
complying with the ISO/IEC 23003-3 (MPEG-D) Unified Speech and Audio
Coding (USAC, also known as Extended High-Efficiency AAC) standard.
+In addition, exhale writes program peak-level and loudness data into
+the generated MPEG-4 files according to the ISO/IEC 23003-4, Dynamic
+Range Control (DRC) specification for use by decoders providing DRC.
+
exhale currently makes use of all frequency-domain (FD) coding tools
in the scalefactor based MDCT processing path, except for predictive
joint stereo, which is still being integrated. Its objective is high
diff --git a/include/Release.htm b/include/Release.htm
index e0f4852..9663a96 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.0.1 (official public minor release) from February 2020. 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.0.2 (official public minor release) from March 2020. 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.0.1 Feb. 2020, this release
+ Version 1.0.2 Mar. 2020, this release
+
+ added basic low/mid-rate joint-stereo coding functionality, bugfixes, and speedups
+ exhaleApp: support for input sampling rates of up to 48000 Hz with CVBR mode 2
+ exhaleLib: frame adaptive joint-stereo preprocessing and coding (CVBR mode <5)
+ exhaleLib: accelerated R/D opt. coding, stability and quality fixes (issues 2 and 3)
+
+ Version 1.0.1 Feb. 2020
improved low-bitrate coding efficiency and support for MPEG-D loudness metadata
exhaleApp: increased MP4 file versatility (issue 1) and calculation of loudness info
@@ -49,20 +56,20 @@
Known Issues with This Release
If you notice an issue with this release not mentioned below, please contact ecodis or a contributor with the details (configuration, input file) needed to reproduce the issue.
- exhaleLib: Coding of stereo or multichannel input yields suboptimal audio quality because the joint-channel coding functionality provided by the ISO/IEC 23003-3 standard has not been implemented so far. See the functionality roadmap below.
+ exhaleLib: Coding of stereo or multichannel input occasionally leads to suboptimal audio quality because the joint-channel coding functionality provided by ISO/IEC 23003-3 has not been fully implemented. See the functionality roadmap below.
exhaleApp: Only basic WAVE input file reading functionality has been implemented. Specifically, 8-bit WAVE input is assumed to contain an even number of audio samples, and the Broadcast and Extensible WAVE file formats are not supported.
Roadmap of Upcoming Features
If you are in need of an additional library or application feature not mentioned below, please contact ecodis or a contributor with a request, and we will see what we can do.
support for coding with a core coder frame length of 768 samples, no version plan
- exhaleLib: finalized integration of joint-channel coding functionality, version 1.0.2
+ exhaleLib: finalized integration of higher-rate joint-channel coding, version 1.0.3
exhaleLib: quality tuning and bug fixing for low-rate stereo coding, version 1.0.3
exhaleLib: finalization of support for 3.0 – 5.1 multichannel coding, version 1.0.4
exhaleLib: speed-ups and further quality tuning for critical signals, version 1.0.5.
-Written by C. R. Helmrich for exhale 1.0.1, Feb. 2020. Available at www.ecodis.de/exhale/release.htm.
+Written by C. R. Helmrich for exhale 1.0.2, Mar. 2020. Available at www.ecodis.de/exhale/release.htm.
|
diff --git a/src/lib/stereoProcessing.cpp b/src/lib/stereoProcessing.cpp
index a4a4fb3..1e6eaf4 100644
--- a/src/lib/stereoProcessing.cpp
+++ b/src/lib/stereoProcessing.cpp
@@ -11,10 +11,6 @@
#include "exhaleLibPch.h"
#include "stereoProcessing.h"
-// static helper functions
-
-// private helper function
-
// constructor
StereoProcessor::StereoProcessor ()
{
@@ -76,8 +72,8 @@ unsigned StereoProcessor::applyFullFrameMatrix (int32_t* const mdctSpectrum1, in
if (realOnlyCalc) // real data, only MDCTs are available
{
- int32_t* sfbNext1 = &sfbMdct1[1];
- int32_t* sfbNext2 = &sfbMdct2[1];
+ const int32_t* sfbNext1 = &sfbMdct1[1];
+ const int32_t* sfbNext2 = &sfbMdct2[1];
for (uint16_t s = sfbWidth - (sfb + 1 == numSwbFrame ? 1 : 0); s > 0; s--)
{
@@ -151,7 +147,7 @@ unsigned StereoProcessor::applyFullFrameMatrix (int32_t* const mdctSpectrum1, in
grpRms1[sfb] = uint32_t ((sumAbsValM + (sfbWidth >> 1)) / sfbWidth);
grpRms2[sfb] = uint32_t ((sumAbsValS + (sfbWidth >> 1)) / sfbWidth);
- sfbStereoData[sfb + numSwbFrame * gr] = 16; // alpha = 0
+ if (applyPredSte) sfbStereoData[sfb + numSwbFrame * gr] = 16; // initialize to alpha=0
if ((sfbIsOdd) || (sfb + 1 == maxSfbSte)) // finish pair
{
@@ -175,7 +171,36 @@ unsigned StereoProcessor::applyFullFrameMatrix (int32_t* const mdctSpectrum1, in
}
if (realOnlyCalc) // real data, only MDCTs available
{
- // TODO
+ const int32_t* nextA = (alterPredDir ? &mdctSpectrum2[offEv + 1] : &mdctSpectrum1[offEv + 1]);
+ const int32_t* nextB = (alterPredDir ? &mdctSpectrum1[offEv + 1] : &mdctSpectrum2[offEv + 1]);
+
+ if (sfbEv == 0) // exclude unavailable DC estimate
+ {
+ mdctA -= width; nextA++;
+ mdctB -= width; nextB++;
+ }
+ else
+ {
+ mdctA -= (width + 1); // point to pre-
+ mdctB -= (width + 1); // vious samples
+ }
+ for (uint16_t s = width - (sfbEv == 0 ? 2 : 1); s > 0; s--) // exclude unavailable final estimate
+ {
+ const int64_t mdstA = ((int64_t) *(nextA++) - (int64_t) *(mdctA++)) >> 1; // estimate, see also
+ const int64_t mdstB = ((int64_t) *(nextB++) - (int64_t) *(mdctB++)) >> 1; // getMeanAbsValues()
+
+ sumPrdRefRes += (mdstA * mdstB + SA_BW) >> (SA_BW_SHIFT + 1);
+ sumPrdRefRef += (mdstA * mdstA + SA_BW) >> (SA_BW_SHIFT + 1);
+ }
+ if (sfb + 1 < numSwbFrame) // process final sample
+ {
+ const int64_t msSgn = (alterPredDir ? -1 : 1);
+ const int64_t mdstA = ((((int64_t) *nextB + *nextA * msSgn + 1) >> 1) - (int64_t) *mdctA) >> 1;
+ const int64_t mdstB = ((((int64_t) *nextA - *nextB * msSgn + 1) >> 1) - (int64_t) *mdctB) >> 1;
+
+ sumPrdRefRes += (mdstA * mdstB + SA_BW) >> (SA_BW_SHIFT + 1);
+ sumPrdRefRef += (mdstA * mdstA + SA_BW) >> (SA_BW_SHIFT + 1);
+ }
}
else // complex data, both MDCTs and MDSTs available
{
@@ -277,7 +302,7 @@ unsigned StereoProcessor::applyFullFrameMatrix (int32_t* const mdctSpectrum1, in
if (numSfbPredSte <= 1) // discard prediction coefficients and stay with legacy M/S stereo
{
- memset (sfbStereoData, 16, numSwbFrame * grp.numWindowGroups * sizeof (uint8_t));
+ if (applyPredSte) memset (sfbStereoData, 16, numSwbFrame * grp.numWindowGroups * sizeof (uint8_t));
numSfbPredSte = 0;
}
@@ -290,7 +315,7 @@ unsigned StereoProcessor::applyFullFrameMatrix (int32_t* const mdctSpectrum1, in
const uint16_t* grpOff = &grp.sfbOffsets[numSwbFrame * gr];
uint32_t* const grpRms1 = &groupingData1.sfbRmsValues[numSwbFrame * gr];
uint32_t* const grpRms2 = &groupingData2.sfbRmsValues[numSwbFrame * gr];
- int32_t b = 0, prevResi = 0;
+ int32_t prevResi = 0;
if (realOnlyCalc) // preparation of res. magnitude value
{
@@ -316,8 +341,8 @@ unsigned StereoProcessor::applyFullFrameMatrix (int32_t* const mdctSpectrum1, in
if (realOnlyCalc) // real data, only MDCT is available
{
- int32_t* sfbNextD = &sfbMdctD[1];
- int32_t* sfbNextR = &sfbMdctR[1];
+ const int32_t* sfbNextD = &sfbMdctD[1];
+ const int32_t* sfbNextR = &sfbMdctR[1];
for (uint16_t s = sfbWidth - (sfb + 1 == numSwbFrame ? 1 : 0); s > 0; s--)
{
|