editorial changes

This commit is contained in:
Christian R. Helmrich 2020-01-02 03:01:24 +01:00
parent 2e1a6c97b3
commit cde6178540
9 changed files with 148 additions and 148 deletions

View File

@ -1,11 +1,11 @@
## makefile - master user make-file for compiling exhale on Linux and MacOS platforms ## makefile - master user make-file for compiling exhale on Linux and MacOS platforms
# written by C. R. Helmrich, last modified 2019 - see License.txt for legal notices # written by C. R. Helmrich, last modified in 2020 - see License.htm for legal notices
# #
# The copyright in this software is being made available under a Modified BSD License # The copyright in this software is being made available under a Modified BSD-Style 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-2019 Christian R. Helmrich, project ecodis. All rights reserved. # Copyright (c) 2018-2020 Christian R. Helmrich, project ecodis. All rights reserved.
## ##
## BUILD32=1: compile for 32-bit platforms, BUILD32=0: compile for 64-bit platforms ## BUILD32=1: compile for 32-bit platforms, BUILD32=0: compile for 64-bit platforms

View File

@ -1,11 +1,11 @@
## makefile - application make-file for compiling exhale on Linux and MacOS platforms ## makefile - application make-file for compiling exhale on Linux and MacOS platforms
# written by C. R. Helmrich, last modified 2019 - see License.txt for legal notices # written by C. R. Helmrich, last modified in 2020 - see License.htm for legal notices
# #
# The copyright in this software is being made available under a Modified BSD License # The copyright in this software is being made available under a Modified BSD-Style 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-2019 Christian R. Helmrich, project ecodis. All rights reserved. # Copyright (c) 2018-2020 Christian R. Helmrich, project ecodis. All rights reserved.
## ##
# define as console application # define as console application
@ -22,7 +22,7 @@ DIR_SRC = ../../src/app
DEFS = -DMSYS_LINUX -DMSYS_UNIX_LARGEFILE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 DEFS = -DMSYS_LINUX -DMSYS_UNIX_LARGEFILE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
# name of product / binary file # name of product / binary file
PRD_NAME = Exhale PRD_NAME = exhale
# name of temporary object file # name of temporary object file
OBJS = \ OBJS = \
@ -36,15 +36,15 @@ LIBS = -ldl
DYN_LIBS = DYN_LIBS =
STAT_LIBS = -lpthread STAT_LIBS = -lpthread
DYN_DEBUG_LIBS = -lExhaleDynd DYN_DEBUG_LIBS = -l$(PRD_NAME)Dynd
DYN_DEBUG_PREREQS = $(DIR_LIB)/libExhaleDynd.a DYN_DEBUG_PREREQS = $(DIR_LIB)/lib$(PRD_NAME)Dynd.a
STAT_DEBUG_LIBS = -lExhaled STAT_DEBUG_LIBS = -l$(PRD_NAME)d
STAT_DEBUG_PREREQS = $(DIR_LIB)/libExhaled.a STAT_DEBUG_PREREQS = $(DIR_LIB)/lib$(PRD_NAME)d.a
DYN_RELEASE_LIBS = -lExhale DYN_RELEASE_LIBS = -l$(PRD_NAME)
DYN_RELEASE_PREREQS = $(DIR_LIB)/libExhale.a DYN_RELEASE_PREREQS = $(DIR_LIB)/lib$(PRD_NAME).a
STAT_RELEASE_LIBS = -lExhale STAT_RELEASE_LIBS = -l$(PRD_NAME)
STAT_RELEASE_PREREQS = $(DIR_LIB)/libExhale.a STAT_RELEASE_PREREQS = $(DIR_LIB)/lib$(PRD_NAME).a
# include common makefile.base # include common makefile.base
include ../makefile.base include ../makefile.base

View File

@ -1,11 +1,11 @@
/* exhaleEnc.cpp - source file for class providing Extended HE-AAC encoding capability /* exhaleEnc.cpp - source file for class providing Extended HE-AAC encoding capability
* written by C. R. Helmrich, last modified 2019 - see License.txt for legal notices * written by C. R. Helmrich, last modified in 2019 - see License.htm for legal notices
* *
* The copyright in this software is being made available under a Modified BSD License * The copyright in this software is being made available under a Modified BSD-Style 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-2019 Christian R. Helmrich, project ecodis. All rights reserved. * Copyright (c) 2018-2020 Christian R. Helmrich, project ecodis. All rights reserved.
*/ */
#include "exhaleLibPch.h" #include "exhaleLibPch.h"
@ -82,12 +82,12 @@ static uint32_t quantizeSfbWithMinSnr (const unsigned* const coeffMagn, const ui
const unsigned char groupLength, unsigned char* const quantMagn, char* const arithTuples, const unsigned char groupLength, unsigned char* const quantMagn, char* const arithTuples,
const bool nonZeroSnr = false) const bool nonZeroSnr = false)
{ {
const unsigned short sfbStart = sfbOffset[b]; const uint16_t sfbStart = sfbOffset[b];
const unsigned short sfbWidth = sfbOffset[b + 1] - sfbStart; const uint16_t sfbWidth = sfbOffset[b + 1] - sfbStart;
const unsigned* const sfbMagn = &coeffMagn[sfbStart]; const unsigned* const sfbMagn = &coeffMagn[sfbStart];
uint32_t maxIndex = 0, maxLevel = sfbMagn[0]; uint32_t maxIndex = 0, maxLevel = sfbMagn[0];
for (unsigned short s = sfbWidth - 1; s > 0; s--) for (uint16_t s = sfbWidth - 1; s > 0; s--)
{ {
if (maxLevel < sfbMagn[s]) // find largest-level magn. in SFB if (maxLevel < sfbMagn[s]) // find largest-level magn. in SFB
{ {
@ -104,7 +104,7 @@ static uint32_t quantizeSfbWithMinSnr (const unsigned* const coeffMagn, const ui
if (arithTuples != nullptr) // update entropy coding two-tuples if (arithTuples != nullptr) // update entropy coding two-tuples
{ {
const unsigned short swbStart = ((sfbStart - sfbOffset[0]) * oneTwentyEightOver[groupLength]) >> 7; const uint16_t swbStart = ((sfbStart - sfbOffset[0]) * oneTwentyEightOver[groupLength]) >> 7;
memset (&arithTuples[swbStart >> 1], 1, ((sfbWidth * oneTwentyEightOver[groupLength]) >> 8) * sizeof (char)); memset (&arithTuples[swbStart >> 1], 1, ((sfbWidth * oneTwentyEightOver[groupLength]) >> 8) * sizeof (char));
@ -172,73 +172,73 @@ static const ELEM_TYPE elementTypeConfig[USAC_MAX_NUM_ELCONFIGS][USAC_MAX_N
}; };
// ISO/IEC 14496-3, Table 4.140 // ISO/IEC 14496-3, Table 4.140
static const unsigned short sfbOffsetL0[42] = { // 88.2 and 96 kHz static const uint16_t sfbOffsetL0[42] = { // 88.2 and 96 kHz
0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 108, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 108,
120, 132, 144, 156, 172, 188, 212, 240, 276, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024 120, 132, 144, 156, 172, 188, 212, 240, 276, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024
}; };
// ISO/IEC 14496-3, Table 4.141 // ISO/IEC 14496-3, Table 4.141
static const unsigned short sfbOffsetS0[13] = { static const uint16_t sfbOffsetS0[13] = {
0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128
}; };
// ISO/IEC 14496-3, Table 4.138 // ISO/IEC 14496-3, Table 4.138
static const unsigned short sfbOffsetL1[48] = { // 64 kHz static const uint16_t sfbOffsetL1[48] = { // 64 kHz
0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 100, 112, 124, 140, 156, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 100, 112, 124, 140, 156,
172, 192, 216, 240, 268, 304, 344, 384, 424, 464, 504, 544, 584, 624, 664, 704, 744, 784, 824, 864, 904, 944, 984, 1024 172, 192, 216, 240, 268, 304, 344, 384, 424, 464, 504, 544, 584, 624, 664, 704, 744, 784, 824, 864, 904, 944, 984, 1024
}; };
// ISO/IEC 14496-3, Table 4.139 // ISO/IEC 14496-3, Table 4.139
static const unsigned short sfbOffsetS1[13] = { static const uint16_t sfbOffsetS1[13] = {
0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128
}; };
// ISO/IEC 14496-3, Table 4.131 // ISO/IEC 14496-3, Table 4.131
static const unsigned short sfbOffsetL2[52] = { // 32, 44.1, and 48 kHz static const uint16_t sfbOffsetL2[52] = { // 32, 44.1, and 48 kHz
0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176, 196, 216, 240, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176, 196, 216, 240,
264, 292, 320, 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960/*!*/, 992/*!*/, 1024 264, 292, 320, 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960/*!*/, 992/*!*/, 1024
}; };
// ISO/IEC 14496-3, Table 4.130 // ISO/IEC 14496-3, Table 4.130
static const unsigned short sfbOffsetS2[15] = { static const uint16_t sfbOffsetS2[15] = {
0, 4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 128 0, 4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 128
}; };
// ISO/IEC 14496-3, Table 4.136 // ISO/IEC 14496-3, Table 4.136
static const unsigned short sfbOffsetL3[48] = { // 22.05 and 24 kHz static const uint16_t sfbOffsetL3[48] = { // 22.05 and 24 kHz
0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 136, 148, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 136, 148,
160, 172, 188, 204, 220, 240, 260, 284, 308, 336, 364, 396, 432, 468, 508, 552, 600, 652, 704, 768, 832, 896, 960, 1024 160, 172, 188, 204, 220, 240, 260, 284, 308, 336, 364, 396, 432, 468, 508, 552, 600, 652, 704, 768, 832, 896, 960, 1024
}; };
// ISO/IEC 14496-3, Table 4.137 // ISO/IEC 14496-3, Table 4.137
static const unsigned short sfbOffsetS3[16] = { static const uint16_t sfbOffsetS3[16] = {
0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 128 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 128
}; };
// ISO/IEC 14496-3, Table 4.134 // ISO/IEC 14496-3, Table 4.134
static const unsigned short sfbOffsetL4[44] = { // 11.025, 12, and 16 kHz static const uint16_t sfbOffsetL4[44] = { // 11.025, 12, and 16 kHz
0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 100, 112, 124, 136, 148, 160, 172, 184, 196, 212, 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 100, 112, 124, 136, 148, 160, 172, 184, 196, 212,
228, 244, 260, 280, 300, 320, 344, 368, 396, 424, 456, 492, 532, 572, 616, 664, 716, 772, 832, 896, 960, 1024 228, 244, 260, 280, 300, 320, 344, 368, 396, 424, 456, 492, 532, 572, 616, 664, 716, 772, 832, 896, 960, 1024
}; };
// ISO/IEC 14496-3, Table 4.135 // ISO/IEC 14496-3, Table 4.135
static const unsigned short sfbOffsetS4[16] = { static const uint16_t sfbOffsetS4[16] = {
0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 108, 128 0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 108, 128
}; };
// ISO/IEC 14496-3, Table 4.132 // ISO/IEC 14496-3, Table 4.132
static const unsigned short sfbOffsetL5[41] = { // 8 kHz static const uint16_t sfbOffsetL5[41] = { // 8 kHz
0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 172, 188, 204, 220, 236, 252, 268, 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 172, 188, 204, 220, 236, 252, 268,
288, 308, 328, 348, 372, 396, 420, 448, 476, 508, 544, 580, 620, 664, 712, 764, 820, 880, 944, 1024 288, 308, 328, 348, 372, 396, 420, 448, 476, 508, 544, 580, 620, 664, 712, 764, 820, 880, 944, 1024
}; };
// ISO/IEC 14496-3, Table 4.133 // ISO/IEC 14496-3, Table 4.133
static const unsigned short sfbOffsetS5[16] = { static const uint16_t sfbOffsetS5[16] = {
0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 108, 128 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 108, 128
}; };
// long-window SFB offset tables // long-window SFB offset tables
static const unsigned short* swbOffsetsL[USAC_NUM_FREQ_TABLES] = { static const uint16_t* swbOffsetsL[USAC_NUM_FREQ_TABLES] = {
sfbOffsetL0, sfbOffsetL1, sfbOffsetL2, sfbOffsetL3, sfbOffsetL4, sfbOffsetL5 sfbOffsetL0, sfbOffsetL1, sfbOffsetL2, sfbOffsetL3, sfbOffsetL4, sfbOffsetL5
}; };
static const unsigned char numSwbOffsetL[USAC_NUM_FREQ_TABLES] = {42, 48, 52, 48, 44, 41}; static const unsigned char numSwbOffsetL[USAC_NUM_FREQ_TABLES] = {42, 48, 52, 48, 44, 41};
// short-window SFB offset tables // short-window SFB offset tables
static const unsigned short* swbOffsetsS[USAC_NUM_FREQ_TABLES] = { static const uint16_t* swbOffsetsS[USAC_NUM_FREQ_TABLES] = {
sfbOffsetS0, sfbOffsetS1, sfbOffsetS2, sfbOffsetS3, sfbOffsetS4, sfbOffsetS5 sfbOffsetS0, sfbOffsetS1, sfbOffsetS2, sfbOffsetS3, sfbOffsetS4, sfbOffsetS5
}; };
static const unsigned char numSwbOffsetS[USAC_NUM_FREQ_TABLES] = {13, 13, 15, 16, 16, 16}; static const unsigned char numSwbOffsetS[USAC_NUM_FREQ_TABLES] = {13, 13, 15, 16, 16, 16};
@ -293,7 +293,7 @@ static const USAC_WSEQ windowSequenceSynch[5][5] = { // first: chan. index 0, s
unsigned ExhaleEncoder::applyTnsToWinGroup (TnsData& tnsData, SfbGroupData& grpData, const bool eightShorts, const unsigned char maxSfb, unsigned ExhaleEncoder::applyTnsToWinGroup (TnsData& tnsData, SfbGroupData& grpData, const bool eightShorts, const unsigned char maxSfb,
const unsigned channelIndex) const unsigned channelIndex)
{ {
const unsigned short filtOrder = tnsData.filterOrder[0]; const uint16_t filtOrder = tnsData.filterOrder[0];
const uint16_t* grpSO = &grpData.sfbOffsets[m_numSwbShort * tnsData.filteredWindow]; const uint16_t* grpSO = &grpData.sfbOffsets[m_numSwbShort * tnsData.filteredWindow];
const unsigned nSamplesInFrame = toFrameLength (m_frameLength); const unsigned nSamplesInFrame = toFrameLength (m_frameLength);
unsigned errorValue = 0; // no error unsigned errorValue = 0; // no error
@ -333,7 +333,7 @@ unsigned ExhaleEncoder::applyTnsToWinGroup (TnsData& tnsData, SfbGroupData& grpD
{ {
int32_t* const mdctSignal = m_mdctSignals[channelIndex]; int32_t* const mdctSignal = m_mdctSignals[channelIndex];
const short offs = grpSO[tnsStartSfb]; const short offs = grpSO[tnsStartSfb];
unsigned short s = grpSO[tnsMaxBands] - offs; uint16_t s = grpSO[tnsMaxBands] - offs;
short filterC[MAX_PREDICTION_ORDER] = {0, 0, 0, 0}; short filterC[MAX_PREDICTION_ORDER] = {0, 0, 0, 0};
int32_t* predSig = &mdctSignal[grpSO[tnsMaxBands]]; // end of spectrum to be predicted int32_t* predSig = &mdctSignal[grpSO[tnsMaxBands]]; // end of spectrum to be predicted
@ -401,7 +401,7 @@ unsigned ExhaleEncoder::eightShortGrouping (SfbGroupData& grpData, uint16_t* con
uint16_t* grpOffset = &grpOffsets[m_numSwbShort * gr]; uint16_t* grpOffset = &grpOffsets[m_numSwbShort * gr];
int32_t* const grpMdctSig = &mdctSignal[grpStartLine -= nSamplesInShort * grpLength]; int32_t* const grpMdctSig = &mdctSignal[grpStartLine -= nSamplesInShort * grpLength];
for (unsigned short b = 0; b < m_numSwbShort; b++) for (uint16_t b = 0; b < m_numSwbShort; b++)
{ {
const unsigned swbOffset = grpOffsets[b]; const unsigned swbOffset = grpOffsets[b];
const unsigned numCoeffs = __min (grpOffsets[b + 1], nSamplesInShort) - swbOffset; const unsigned numCoeffs = __min (grpOffsets[b + 1], nSamplesInShort) - swbOffset;
@ -409,7 +409,7 @@ unsigned ExhaleEncoder::eightShortGrouping (SfbGroupData& grpData, uint16_t* con
// adjust scale factor band offsets // adjust scale factor band offsets
grpOffset[b] = uint16_t (grpStartLine + swbOffset * grpLength); grpOffset[b] = uint16_t (grpStartLine + swbOffset * grpLength);
// interleave spectral coefficients // interleave spectral coefficients
for (unsigned short w = 0; w < grpLength; w++) for (uint16_t w = 0; w < grpLength; w++)
{ {
memcpy (&m_tempIntBuf[grpOffset[b] + w * numCoeffs], &grpMdctSig[swbOffset + w * nSamplesInShort], numCoeffs * sizeof (int32_t)); memcpy (&m_tempIntBuf[grpOffset[b] + w * numCoeffs], &grpMdctSig[swbOffset + w * nSamplesInShort], numCoeffs * sizeof (int32_t));
} }
@ -445,8 +445,8 @@ unsigned ExhaleEncoder::getOptParCorCoeffs (const int32_t* const mdctSignal, con
#if EE_OPT_TNS_SPEC_RANGE #if EE_OPT_TNS_SPEC_RANGE
if (tnsData.filterOrder[0] > 0) // try to reduce TNS start band as long as SNR increases if (tnsData.filterOrder[0] > 0) // try to reduce TNS start band as long as SNR increases
{ {
const unsigned short filtOrder = tnsData.filterOrder[0]; const uint16_t filtOrder = tnsData.filterOrder[0];
unsigned short b = __min (m_specAnaCurr[channelIndex] & 31, (nSamplesInFrame - filtOrder) >> SA_BW_SHIFT); uint16_t b = __min (m_specAnaCurr[channelIndex] & 31, (nSamplesInFrame - filtOrder) >> SA_BW_SHIFT);
short filterC[MAX_PREDICTION_ORDER] = {0, 0, 0, 0}; short filterC[MAX_PREDICTION_ORDER] = {0, 0, 0, 0};
int32_t* predSig = &m_mdctSignals[channelIndex][b << SA_BW_SHIFT]; // TNS start offset int32_t* predSig = &m_mdctSignals[channelIndex][b << SA_BW_SHIFT]; // TNS start offset
@ -458,7 +458,7 @@ unsigned ExhaleEncoder::getOptParCorCoeffs (const int32_t* const mdctSignal, con
if (filtOrder >= 4) // max. order 4 if (filtOrder >= 4) // max. order 4
{ {
for (unsigned short s = 1 << SA_BW_SHIFT; s > 0; s--) // generate the TNS residual for (uint16_t s = 1 << SA_BW_SHIFT; s > 0; s--) // produce the TNS filter residual
{ {
const int64_t predSample = *(predSig - 1) * (int64_t) filterC[0] + *(predSig - 2) * (int64_t) filterC[1] + const int64_t predSample = *(predSig - 1) * (int64_t) filterC[0] + *(predSig - 2) * (int64_t) filterC[1] +
*(predSig - 3) * (int64_t) filterC[2] + *(predSig - 4) * (int64_t) filterC[3]; *(predSig - 3) * (int64_t) filterC[2] + *(predSig - 4) * (int64_t) filterC[3];
@ -470,7 +470,7 @@ unsigned ExhaleEncoder::getOptParCorCoeffs (const int32_t* const mdctSignal, con
} }
else if (filtOrder == 3) // order 3 else if (filtOrder == 3) // order 3
{ {
for (unsigned short s = 1 << SA_BW_SHIFT; s > 0; s--) // generate the TNS residual for (uint16_t s = 1 << SA_BW_SHIFT; s > 0; s--) // produce the TNS filter residual
{ {
const int64_t predSample = *(predSig - 1) * (int64_t) filterC[0] + *(predSig - 2) * (int64_t) filterC[1] + const int64_t predSample = *(predSig - 1) * (int64_t) filterC[0] + *(predSig - 2) * (int64_t) filterC[1] +
*(predSig - 3) * (int64_t) filterC[2]; *(predSig - 3) * (int64_t) filterC[2];
@ -482,7 +482,7 @@ unsigned ExhaleEncoder::getOptParCorCoeffs (const int32_t* const mdctSignal, con
} }
else // save 1-2 MACs, order 2 or 1 else // save 1-2 MACs, order 2 or 1
{ {
for (unsigned short s = 1 << SA_BW_SHIFT; s > 0; s--) // generate the TNS residual for (uint16_t s = 1 << SA_BW_SHIFT; s > 0; s--) // produce the TNS filter residual
{ {
const int64_t predSample = *(predSig - 1) * (int64_t) filterC[0] + *(predSig - 2) * (int64_t) filterC[1]; const int64_t predSample = *(predSig - 1) * (int64_t) filterC[0] + *(predSig - 2) * (int64_t) filterC[1];
const int64_t mdctSample = *(predSig--); const int64_t mdctSample = *(predSig--);
@ -569,7 +569,7 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
const uint32_t* rms = grpData.sfbRmsValues; const uint32_t* rms = grpData.sfbRmsValues;
unsigned char* scaleFactors = grpData.scaleFactors; unsigned char* scaleFactors = grpData.scaleFactors;
for (unsigned short b = 0; b < grpData.sfbsPerGroup; b++) for (uint16_t b = 0; b < grpData.sfbsPerGroup; b++)
{ {
const unsigned char sfbWidth = off[b + 1] - off[b]; const unsigned char sfbWidth = off[b + 1] - off[b];
const unsigned highPassAtten = 4 + b * 2; // LF SNR increase, my M.Sc. thesis, p. 54 const unsigned highPassAtten = 4 + b * 2; // LF SNR increase, my M.Sc. thesis, p. 54
@ -598,7 +598,7 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
} }
memset (grpData.scaleFactors, 0, (MAX_NUM_SWB_SHORT * NUM_WINDOW_GROUPS) * sizeof (unsigned char)); memset (grpData.scaleFactors, 0, (MAX_NUM_SWB_SHORT * NUM_WINDOW_GROUPS) * sizeof (unsigned char));
for (unsigned short gr = 0; gr < grpData.numWindowGroups; gr++) for (uint16_t gr = 0; gr < grpData.numWindowGroups; gr++)
{ {
const uint16_t* grpOff = &grpData.sfbOffsets[m_numSwbShort * gr]; const uint16_t* grpOff = &grpData.sfbOffsets[m_numSwbShort * gr];
const uint32_t* grpRms = &grpData.sfbRmsValues[m_numSwbShort * gr]; const uint32_t* grpRms = &grpData.sfbRmsValues[m_numSwbShort * gr];
@ -672,7 +672,7 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
if (tnsData.numFilters > 0) // convert TNS group index to window index for write-out if (tnsData.numFilters > 0) // convert TNS group index to window index for write-out
{ {
s = 0; s = 0;
for (unsigned short gr = 0; gr < grpData.numWindowGroups; gr++) for (uint16_t gr = 0; gr < grpData.numWindowGroups; gr++)
{ {
if (gr == tnsData.filteredWindow) if (gr == tnsData.filteredWindow)
{ {
@ -722,7 +722,7 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en
memset (m_mdctQuantMag[ci], 0, nSamplesInFrame * sizeof (unsigned char)); // zero out memset (m_mdctQuantMag[ci], 0, nSamplesInFrame * sizeof (unsigned char)); // zero out
for (unsigned short gr = 0; gr < grpData.numWindowGroups; gr++) for (uint16_t gr = 0; gr < grpData.numWindowGroups; gr++)
{ {
const unsigned char grpLength = grpData.windowGroupLength[gr]; const unsigned char grpLength = grpData.windowGroupLength[gr];
const uint16_t* grpOff = &grpData.sfbOffsets[m_numSwbShort * gr]; const uint16_t* grpOff = &grpData.sfbOffsets[m_numSwbShort * gr];
@ -734,11 +734,11 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en
errorValue |= entrCoder.initWindowCoding (m_indepFlag && (gr == 0), shortWinCurr); errorValue |= entrCoder.initWindowCoding (m_indepFlag && (gr == 0), shortWinCurr);
s = 0; s = 0;
for (unsigned short b = 0; b < grpData.sfbsPerGroup; b++) for (uint16_t b = 0; b < grpData.sfbsPerGroup; b++)
{ {
// partial SFB ungrouping for entropy coding setup below // partial SFB ungrouping for entropy coding setup below
const unsigned short swbSize = ((grpOff[b + 1] - grpOff[b]) * oneTwentyEightOver[grpLength]) >> 7; // sfbWidth / grpLength const uint16_t swbSize = ((grpOff[b + 1] - grpOff[b]) * oneTwentyEightOver[grpLength]) >> 7; // sfbWidth / grpLength
unsigned char* const swbMagn = &m_mdctQuantMag[ci][grpOff[b + 1] - swbSize]; uint8_t* const swbMagn = &m_mdctQuantMag[ci][grpOff[b + 1] - swbSize];
grpScaleFactors[b] = m_sfbQuantizer.quantizeSpecSfb (entrCoder, m_mdctSignals[ci], grpLength, grpOff, grpRms, grpScaleFactors[b] = m_sfbQuantizer.quantizeSpecSfb (entrCoder, m_mdctSignals[ci], grpLength, grpOff, grpRms,
b, grpScaleFactors[b], sfIdxPred, m_mdctQuantMag[ci]); b, grpScaleFactors[b], sfIdxPred, m_mdctQuantMag[ci]);
@ -752,9 +752,9 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en
// correct previous scale factor if the delta exceeds 60 // correct previous scale factor if the delta exceeds 60
if ((b > 0) && (grpScaleFactors[b] > grpScaleFactors[b - 1] + INDEX_OFFSET)) if ((b > 0) && (grpScaleFactors[b] > grpScaleFactors[b - 1] + INDEX_OFFSET))
{ {
const unsigned short sfbM1Start = grpOff[b - 1]; const uint16_t sfbM1Start = grpOff[b - 1];
const unsigned short sfbM1Width = grpOff[b] - sfbM1Start; const uint16_t sfbM1Width = grpOff[b] - sfbM1Start;
const unsigned short swbM1Size = (sfbM1Width * oneTwentyEightOver[grpLength]) >> 7; // sfbM1Width / grpLength const uint16_t swbM1Size = (sfbM1Width * oneTwentyEightOver[grpLength]) >> 7; // sfbM1Width / grpLength
grpScaleFactors[b - 1] = grpScaleFactors[b] - INDEX_OFFSET; // reset SFB to zero grpScaleFactors[b - 1] = grpScaleFactors[b] - INDEX_OFFSET; // reset SFB to zero
memset (&m_mdctQuantMag[ci][sfbM1Start], 0, sfbM1Width * sizeof (unsigned char)); memset (&m_mdctQuantMag[ci][sfbM1Start], 0, sfbM1Width * sizeof (unsigned char));
@ -772,7 +772,7 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en
} }
// set up entropy coding 2-tuples for next SFB or window // set up entropy coding 2-tuples for next SFB or window
lastSOff = s; lastSOff = s;
for (unsigned short c = 0; c < swbSize; c += 2) for (uint16_t c = 0; c < swbSize; c += 2)
{ {
arithTuples[s++] = __min (0xF, swbMagn[c] + swbMagn[c + 1] + 1); // 23003-3, 7.4 arithTuples[s++] = __min (0xF, swbMagn[c] + swbMagn[c + 1] + 1); // 23003-3, 7.4
} }
@ -782,7 +782,7 @@ unsigned ExhaleEncoder::quantizationCoding () // apply MDCT quantization and en
{ {
const unsigned char maxSfbLong = (samplingRate < 37566 ? 51 /*32 kHz*/ : brModeAndFsToMaxSfbLong (m_bitRateMode, samplingRate)); const unsigned char maxSfbLong = (samplingRate < 37566 ? 51 /*32 kHz*/ : brModeAndFsToMaxSfbLong (m_bitRateMode, samplingRate));
const unsigned char maxSfbShort = (samplingRate < 37566 ? 14 /*32 kHz*/ : brModeAndFsToMaxSfbShort(m_bitRateMode, samplingRate)); const unsigned char maxSfbShort = (samplingRate < 37566 ? 14 /*32 kHz*/ : brModeAndFsToMaxSfbShort(m_bitRateMode, samplingRate));
const unsigned short peakIndex = (shortWinCurr ? 0 : (m_specAnaCurr[ci] >> 5) & 2047); const uint16_t peakIndex = (shortWinCurr ? 0 : (m_specAnaCurr[ci] >> 5) & 2047);
#if RESTRICT_TO_AAC #if RESTRICT_TO_AAC
const unsigned sfmBasedSfbStart = (shortWinCurr ? maxSfbShort : maxSfbLong) - 6 + (m_bitRateMode >> 1) + ((m_specAnaCurr[ci] >> 21) & 7); const unsigned sfmBasedSfbStart = (shortWinCurr ? maxSfbShort : maxSfbLong) - 6 + (m_bitRateMode >> 1) + ((m_specAnaCurr[ci] >> 21) & 7);
#else #else
@ -1041,7 +1041,7 @@ unsigned ExhaleEncoder::spectralProcessing () // complete ics_info(), calc TNS
(abs (specFlat[0] - specFlat[1]) <= (UCHAR_MAX >> 3)) && (abs (specFlat[0] - specFlat[1]) <= (UCHAR_MAX >> 3)) &&
(abs (tnsStart[0] - tnsStart[1]) <= (UCHAR_MAX >> 5))) // TNS synchronization (abs (tnsStart[0] - tnsStart[1]) <= (UCHAR_MAX >> 5))) // TNS synchronization
{ {
const unsigned short maxTnsOrder = __max (coreConfig.tnsData[0].filterOrder[0], coreConfig.tnsData[1].filterOrder[0]); const uint16_t maxTnsOrder = __max (coreConfig.tnsData[0].filterOrder[0], coreConfig.tnsData[1].filterOrder[0]);
TnsData& tnsData0 = coreConfig.tnsData[0]; TnsData& tnsData0 = coreConfig.tnsData[0];
TnsData& tnsData1 = coreConfig.tnsData[1]; TnsData& tnsData1 = coreConfig.tnsData[1];
@ -1095,7 +1095,7 @@ unsigned ExhaleEncoder::spectralProcessing () // complete ics_info(), calc TNS
coreConfig.icsInfoCurr[ch].windowGrouping = scaleFactorGrouping[icsCurr.windowGrouping]; coreConfig.icsInfoCurr[ch].windowGrouping = scaleFactorGrouping[icsCurr.windowGrouping];
} }
for (unsigned short gr = 0; gr < grpData.numWindowGroups; gr++) for (uint16_t gr = 0; gr < grpData.numWindowGroups; gr++)
{ {
const unsigned grpSOStart = grpSO[grpData.sfbsPerGroup + m_numSwbShort * gr]; const unsigned grpSOStart = grpSO[grpData.sfbsPerGroup + m_numSwbShort * gr];

View File

@ -83,7 +83,7 @@ private:
#endif #endif
uint8_t m_numElements; uint8_t m_numElements;
uint8_t m_numSwbShort; uint8_t m_numSwbShort;
uint8_t* m_outAuData; unsigned char* m_outAuData;
BitStreamWriter m_outStream; // for access unit creation BitStreamWriter m_outStream; // for access unit creation
int32_t* m_pcm24Data; int32_t* m_pcm24Data;
SfbGroupData* m_scaleFacData[USAC_MAX_NUM_CHANNELS]; SfbGroupData* m_scaleFacData[USAC_MAX_NUM_CHANNELS];

View File

@ -1,11 +1,11 @@
## makefile - code library make-file for compiling exhale on Linux and MacOS platforms ## makefile - code library make-file for compiling exhale on Linux and MacOS platforms
# written by C. R. Helmrich, last modified 2019 - see License.txt for legal notices # written by C. R. Helmrich, last modified in 2020 - see License.htm for legal notices
# #
# The copyright in this software is being made available under a Modified BSD License # The copyright in this software is being made available under a Modified BSD-Style 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-2019 Christian R. Helmrich, project ecodis. All rights reserved. # Copyright (c) 2018-2020 Christian R. Helmrich, project ecodis. All rights reserved.
## ##
# define as source code library # define as source code library
@ -22,7 +22,7 @@ DIR_SRC = ../../src/lib
DEFS = -DMSYS_LINUX -DMSYS_UNIX_LARGEFILE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 DEFS = -DMSYS_LINUX -DMSYS_UNIX_LARGEFILE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
# name of product / binary file # name of product / binary file
PRD_NAME = Exhale PRD_NAME = exhale
# name of temporary object file # name of temporary object file
OBJS = \ OBJS = \

View File

@ -13,7 +13,7 @@
// static helper function // static helper function
static inline short getBitCount (EntropyCoder& entrCoder, const int sfIndex, const int sfIndexPred, static inline short getBitCount (EntropyCoder& entrCoder, const int sfIndex, const int sfIndexPred,
const unsigned char groupLength, const unsigned char* coeffQuant, const uint8_t groupLength, const uint8_t* coeffQuant,
const uint16_t coeffOffset, const uint16_t numCoeffs) const uint16_t coeffOffset, const uint16_t numCoeffs)
{ {
unsigned bitCount = (sfIndex != UCHAR_MAX && sfIndexPred == UCHAR_MAX ? 8 : entrCoder.indexGetBitCount (sfIndex - sfIndexPred)); unsigned bitCount = (sfIndex != UCHAR_MAX && sfIndexPred == UCHAR_MAX ? 8 : entrCoder.indexGetBitCount (sfIndex - sfIndexPred));
@ -27,8 +27,8 @@ static inline short getBitCount (EntropyCoder& entrCoder, const int sfIndex, con
} }
// private helper functions // private helper functions
double SfbQuantizer::getQuantDist (const unsigned* const coeffMagn, const unsigned char scaleFactor, double SfbQuantizer::getQuantDist (const unsigned* const coeffMagn, const uint8_t scaleFactor,
const unsigned char* coeffQuant, const uint16_t numCoeffs) const uint8_t* coeffQuant, const uint16_t numCoeffs)
{ {
const double stepSizeDiv = m_lutSfNorm[scaleFactor]; const double stepSizeDiv = m_lutSfNorm[scaleFactor];
double dDist = 0.0; double dDist = 0.0;
@ -44,8 +44,8 @@ double SfbQuantizer::getQuantDist (const unsigned* const coeffMagn, const unsign
return dDist * m_lut2ExpX4[scaleFactor] * m_lut2ExpX4[scaleFactor]; return dDist * m_lut2ExpX4[scaleFactor] * m_lut2ExpX4[scaleFactor];
} }
unsigned char SfbQuantizer::quantizeMagn (const unsigned* const coeffMagn, const unsigned char scaleFactor, uint8_t SfbQuantizer::quantizeMagn (const unsigned* const coeffMagn, const uint8_t scaleFactor,
unsigned char* const coeffQuant, const uint16_t numCoeffs, /*mod*/uint8_t* const coeffQuant, const uint16_t numCoeffs,
short* const sigMaxQ /*= NULL*/, short* const sigNumQ /*= NULL*/) short* const sigMaxQ /*= NULL*/, short* const sigNumQ /*= NULL*/)
{ {
const double stepSizeDiv = m_lutSfNorm[scaleFactor]; const double stepSizeDiv = m_lutSfNorm[scaleFactor];
@ -112,7 +112,7 @@ unsigned char SfbQuantizer::quantizeMagn (const unsigned* const coeffMagn, const
dDen += normalizedMagn * normalizedMagn; dDen += normalizedMagn * normalizedMagn;
} }
#endif #endif
coeffQuant[i] = (unsigned char) q; coeffQuant[i] = (uint8_t) q;
} }
if (sigMaxQ) *sigMaxQ = maxQ; // max. quantized value magnitude if (sigMaxQ) *sigMaxQ = maxQ; // max. quantized value magnitude
@ -121,7 +121,7 @@ unsigned char SfbQuantizer::quantizeMagn (const unsigned* const coeffMagn, const
// compute least-squares optimal gain multiplied onto step-size // compute least-squares optimal gain multiplied onto step-size
numQ = scaleFactor + short (SF_QUANT_OFFSET + FOUR_LOG102 * log10 (dNum <= 0.0 ? 1.0 : dNum / dDen) - (dNum < dDen ? 1.0 : 0.0)); numQ = scaleFactor + short (SF_QUANT_OFFSET + FOUR_LOG102 * log10 (dNum <= 0.0 ? 1.0 : dNum / dDen) - (dNum < dDen ? 1.0 : 0.0));
return (unsigned char) __max (0, numQ); // optimal scale factor return (uint8_t) __max (0, numQ); // optimal scale factor index
} }
// constructor // constructor
@ -168,14 +168,14 @@ SfbQuantizer::~SfbQuantizer ()
// public functions // public functions
unsigned SfbQuantizer::initQuantMemory (const unsigned maxTransfLength, unsigned SfbQuantizer::initQuantMemory (const unsigned maxTransfLength,
#if EC_TRELLIS_OPT_CODING #if EC_TRELLIS_OPT_CODING
const unsigned char numSwb, const unsigned char bitRateMode, const uint8_t numSwb, const uint8_t bitRateMode,
#endif #endif
const unsigned char maxScaleFacIndex /*= SCHAR_MAX*/) const uint8_t maxScaleFacIndex /*= SCHAR_MAX*/)
{ {
const unsigned numScaleFactors = (unsigned) maxScaleFacIndex + 1; const unsigned numScaleFactors = (unsigned) maxScaleFacIndex + 1;
#if EC_TRELLIS_OPT_CODING #if EC_TRELLIS_OPT_CODING
const unsigned char numIStates = 8 - __min (5, (bitRateMode + 2) >> 2); // states per SFB const uint8_t numTrellisStates = 8 - __min (5, (bitRateMode + 2) >> 2); // states per SFB
const unsigned char numDStates = numIStates * numIStates; // interdependent states per SFB const uint8_t numSquaredStates = numTrellisStates * numTrellisStates;
#endif #endif
unsigned x; unsigned x;
@ -194,13 +194,13 @@ unsigned SfbQuantizer::initQuantMemory (const unsigned maxTransfLength,
return 2; // memory allocation error return 2; // memory allocation error
} }
#if EC_TRELLIS_OPT_CODING #if EC_TRELLIS_OPT_CODING
m_numCStates = numIStates; m_numCStates = numTrellisStates;
for (x = 0; x < __min (52u, numSwb); x++) for (x = 0; x < __min (52u, numSwb); x++)
{ {
if ((m_quantDist[x] = (double* ) malloc (numIStates * sizeof (double ))) == nullptr || if ((m_quantDist[x] = (double* ) malloc (numTrellisStates * sizeof (double ))) == nullptr ||
(m_quantInSf[x] = (uint8_t* ) malloc (numIStates * sizeof (uint8_t ))) == nullptr || (m_quantInSf[x] = (uint8_t* ) malloc (numTrellisStates * sizeof (uint8_t ))) == nullptr ||
(m_quantRate[x] = (uint16_t*) malloc (numDStates * sizeof (uint16_t))) == nullptr) (m_quantRate[x] = (uint16_t*) malloc (numSquaredStates * sizeof (uint16_t))) == nullptr)
{ {
return 2; return 2;
} }
@ -223,12 +223,12 @@ unsigned SfbQuantizer::initQuantMemory (const unsigned maxTransfLength,
return 0; // no error return 0; // no error
} }
uint8_t SfbQuantizer::quantizeSpecSfb (EntropyCoder& entropyCoder, const int32_t* const inputCoeffs, const unsigned char grpLength, uint8_t SfbQuantizer::quantizeSpecSfb (EntropyCoder& entropyCoder, const int32_t* const inputCoeffs, const uint8_t grpLength,
const uint16_t* const grpOffsets, uint32_t* const grpStats, // quant./coding statistics const uint16_t* const grpOffsets, uint32_t* const grpStats, // quant./coding statistics
const unsigned sfb, const unsigned char sfIndex, const unsigned char sfIndexPred /*= UCHAR_MAX*/, const unsigned sfb, const uint8_t sfIndex, const uint8_t sfIndexPred /*= UCHAR_MAX*/,
unsigned char* const quantCoeffs /*= nullptr*/) // returns the RD optimized scale factor index uint8_t* const quantCoeffs /*= nullptr*/) // returns the RD optimized scale factor index
{ {
unsigned char sfBest = sfIndex; uint8_t sfBest = sfIndex;
if ((inputCoeffs == nullptr) || (grpOffsets == nullptr) || (sfb >= 52) || (sfIndex > m_maxSfIndex)) if ((inputCoeffs == nullptr) || (grpOffsets == nullptr) || (sfb >= 52) || (sfIndex > m_maxSfIndex))
{ {
@ -258,7 +258,7 @@ uint8_t SfbQuantizer::quantizeSpecSfb (EntropyCoder& entropyCoder, const int32_t
if (quantCoeffs) if (quantCoeffs)
{ {
memset (&quantCoeffs[sfbStart], 0, sfbWidth * sizeof (unsigned char)); // zero output memset (&quantCoeffs[sfbStart], 0, sfbWidth * sizeof (uint8_t)); // SFB output zeroing
if (grpStats) // approximate bit count if (grpStats) // approximate bit count
{ {
grpStats[sfb] = getBitCount (entropyCoder, 0, 0, grpLength, &quantCoeffs[grpStart], sfbStart - grpStart, sfbWidth); grpStats[sfb] = getBitCount (entropyCoder, 0, 0, grpLength, &quantCoeffs[grpStart], sfbStart - grpStart, sfbWidth);
@ -271,7 +271,7 @@ uint8_t SfbQuantizer::quantizeSpecSfb (EntropyCoder& entropyCoder, const int32_t
const uint16_t grpStart = grpOffsets[0]; const uint16_t grpStart = grpOffsets[0];
const uint16_t sfbStart = grpOffsets[sfb]; const uint16_t sfbStart = grpOffsets[sfb];
const uint16_t sfbWidth = grpOffsets[sfb + 1] - sfbStart; const uint16_t sfbWidth = grpOffsets[sfb + 1] - sfbStart;
const uint16_t cpyWidth = sfbWidth * sizeof (unsigned char); const uint16_t cpyWidth = sfbWidth * sizeof (uint8_t);
uint32_t* const coeffMagn = &m_coeffMagn[sfbStart]; uint32_t* const coeffMagn = &m_coeffMagn[sfbStart];
unsigned codStart = 0, ctxStart = 0; unsigned codStart = 0, ctxStart = 0;
unsigned codFinal = 0, ctxFinal = 0; unsigned codFinal = 0, ctxFinal = 0;
@ -283,9 +283,9 @@ uint8_t SfbQuantizer::quantizeSpecSfb (EntropyCoder& entropyCoder, const int32_t
#else #else
bool rdOptimQuant = true; bool rdOptimQuant = true;
#endif #endif
unsigned char* ptrBest = &m_coeffTemp[0]; uint8_t* ptrBest = &m_coeffTemp[0];
unsigned char* ptrCurr = &m_coeffTemp[100]; uint8_t* ptrCurr = &m_coeffTemp[100];
unsigned char sfCurr = sfIndex; uint8_t sfCurr = sfIndex;
for (int i = sfbWidth - 1; i >= 0; i--) // back up magnitudes. TODO: use SIMD for speed? for (int i = sfbWidth - 1; i >= 0; i--) // back up magnitudes. TODO: use SIMD for speed?
{ {
@ -297,7 +297,7 @@ uint8_t SfbQuantizer::quantizeSpecSfb (EntropyCoder& entropyCoder, const int32_t
if (maxQBest > SCHAR_MAX) // limit SNR via scale factor index if (maxQBest > SCHAR_MAX) // limit SNR via scale factor index
{ {
for (unsigned char c = 0; (c < 2) && (maxQBest > SCHAR_MAX); c++) // rarely done twice for (uint8_t c = 0; (c < 2) && (maxQBest > SCHAR_MAX); c++) // very rarely done twice
{ {
sfCurr += getScaleFacOffset (pow ((double) maxQBest, 4.0 / 3.0) / m_lutXExp43[SCHAR_MAX]) + c; sfCurr += getScaleFacOffset (pow ((double) maxQBest, 4.0 / 3.0) / m_lutXExp43[SCHAR_MAX]) + c;
sfBest = quantizeMagn (coeffMagn, sfCurr, ptrBest, sfbWidth, &maxQBest, &numQBest); sfBest = quantizeMagn (coeffMagn, sfCurr, ptrBest, sfbWidth, &maxQBest, &numQBest);
@ -373,7 +373,7 @@ uint8_t SfbQuantizer::quantizeSpecSfb (EntropyCoder& entropyCoder, const int32_t
// rate-distortion decision with empirical rate threshold // rate-distortion decision with empirical rate threshold
if ((numQCurr <= numQBest + (distCurr >= distBest ? -1 : short (0.5 + distBest / __max (1.0, distCurr))))) if ((numQCurr <= numQBest + (distCurr >= distBest ? -1 : short (0.5 + distBest / __max (1.0, distCurr)))))
{ {
unsigned char* ptrTemp = ptrBest; uint8_t* ptrTemp = ptrBest;
ptrBest = ptrCurr; ptrBest = ptrCurr;
ptrCurr = ptrTemp; ptrCurr = ptrTemp;
@ -397,7 +397,7 @@ uint8_t SfbQuantizer::quantizeSpecSfb (EntropyCoder& entropyCoder, const int32_t
if ((sfCurr != sfIndexPred) && (sfBest != sfIndexPred) && rdOptimQuant && (sfIndexPred > 0) && (sfIndexPred < m_maxSfIndex)) if ((sfCurr != sfIndexPred) && (sfBest != sfIndexPred) && rdOptimQuant && (sfIndexPred > 0) && (sfIndexPred < m_maxSfIndex))
{ {
unsigned char sf; uint8_t sf;
// try quantization with repeated scale factor to save bits // try quantization with repeated scale factor to save bits
for (sf = (sfCurr = sfIndexPred + 1); (sf >= sfIndexPred) && (sfCurr > sfIndexPred); sf--) for (sf = (sfCurr = sfIndexPred + 1); (sf >= sfIndexPred) && (sfCurr > sfIndexPred); sf--)
@ -506,9 +506,9 @@ uint8_t SfbQuantizer::quantizeSpecSfb (EntropyCoder& entropyCoder, const int32_t
#if EC_TRELLIS_OPT_CODING #if EC_TRELLIS_OPT_CODING
# define EC_TRAIN 0 # define EC_TRAIN 0
unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned char* const optimalSf, const unsigned targetBitCount, unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, uint8_t* const optimalSf, const unsigned targetBitCount,
const uint16_t* const grpOffsets, uint32_t* const grpStats, // quant./coding statistics const uint16_t* const grpOffsets, uint32_t* const grpStats, // quant./coding statistics
const unsigned numSfb, unsigned char* const quantCoeffs) // returns RD optimization bit count const unsigned numSfb, uint8_t* const quantCoeffs) // returns RD optimization bit count
{ {
// numSfb: number of trellis stages. Based on: A. Aggarwal, S. L. Regunathan, and K. Rose, // numSfb: number of trellis stages. Based on: A. Aggarwal, S. L. Regunathan, and K. Rose,
// "Trellis-Based Optimization of MPEG-4 Advanced Audio Coding," in Proc. IEEE Workshop on // "Trellis-Based Optimization of MPEG-4 Advanced Audio Coding," in Proc. IEEE Workshop on
@ -518,14 +518,14 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
const uint32_t codFinal = entropyCoder.arithGetCodState (); const uint32_t codFinal = entropyCoder.arithGetCodState ();
const uint32_t ctxFinal = entropyCoder.arithGetCtxState (); // after quantizeSfb() const uint32_t ctxFinal = entropyCoder.arithGetCtxState (); // after quantizeSfb()
const uint16_t grpStart = grpOffsets[0]; const uint16_t grpStart = grpOffsets[0];
unsigned char* const inScaleFac = &m_coeffTemp[716]; uint8_t* const inScaleFac = &m_coeffTemp[716];
uint32_t prevCodState[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t prevCodState[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint32_t prevCtxState[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t prevCtxState[8] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned char prevScaleFac[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t prevScaleFac[8] = {0, 0, 0, 0, 0, 0, 0, 0};
double prevVtrbCost[8] = {0, 0, 0, 0, 0, 0, 0, 0}; double prevVtrbCost[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint32_t tempCodState[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t tempCodState[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint32_t tempCtxState[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t tempCtxState[8] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned char tempScaleFac[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t tempScaleFac[8] = {0, 0, 0, 0, 0, 0, 0, 0};
double tempVtrbCost[8] = {0, 0, 0, 0, 0, 0, 0, 0}; double tempVtrbCost[8] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned tempBitCount, sfb, is; unsigned tempBitCount, sfb, is;
int ds; int ds;
@ -542,17 +542,17 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
for (sfb = 0; sfb < numSfb; sfb++) // SFB-wise scale factor, weighted distortion, and rate for (sfb = 0; sfb < numSfb; sfb++) // SFB-wise scale factor, weighted distortion, and rate
{ {
const unsigned char refSf = m_quantInSf[sfb][1]; const uint8_t refSf = m_quantInSf[sfb][1];
const uint16_t refNumQ = m_quantRate[sfb][1]; const uint16_t refNumQ = m_quantRate[sfb][1];
const double refQuantDist = m_quantDist[sfb][1]; const double refQuantDist = m_quantDist[sfb][1];
const double refQuantNorm = m_lutSfNorm[refSf] * m_lutSfNorm[refSf]; const double refQuantNorm = m_lutSfNorm[refSf] * m_lutSfNorm[refSf];
const uint16_t sfbStart = grpOffsets[sfb]; const uint16_t sfbStart = grpOffsets[sfb];
const uint16_t sfbWidth = grpOffsets[sfb + 1] - sfbStart; const uint16_t sfbWidth = grpOffsets[sfb + 1] - sfbStart;
uint32_t* const coeffMagn = &m_coeffMagn[sfbStart]; uint32_t* const coeffMagn = &m_coeffMagn[sfbStart];
unsigned char* const tempMagn = &m_coeffTemp[sfbStart]; uint8_t* const tempMagn = &m_coeffTemp[sfbStart];
bool maxSnrReached = false; bool maxSnrReached = false;
if (refQuantDist < 0.0) memset (tempMagn, 0, sfbWidth * sizeof (unsigned char)); if (refQuantDist < 0.0) memset (tempMagn, 0, sfbWidth * sizeof (uint8_t));
#if EC_TRAIN #if EC_TRAIN
else refGrpDist += refQuantDist; else refGrpDist += refQuantDist;
#endif #endif
@ -563,10 +563,10 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
for (is = 0; is < m_numCStates; is++) // populate the trellis for (is = 0; is < m_numCStates; is++) // populate the trellis
{ {
unsigned char* const mag = (is != 1 || quantCoeffs == nullptr ? &m_coeffTemp[grpStart] : &quantCoeffs[grpStart]); uint8_t* const mag = (is != 1 || quantCoeffs == nullptr ? &m_coeffTemp[grpStart] : &quantCoeffs[grpStart]);
double* const currDist = &m_quantDist[sfb][is]; double* currDist = &m_quantDist[sfb][is];
uint16_t* currRate = &m_quantRate[sfb][is * m_numCStates]; uint16_t* currRate = &m_quantRate[sfb][is * m_numCStates];
unsigned char sfBest = optimalSf[sfb]; // optimal refSf uint8_t sfBest = optimalSf[sfb]; // optimal refSf
short maxQCurr = 0, numQCurr = 0; // for sign bits counting short maxQCurr = 0, numQCurr = 0; // for sign bits counting
if (refQuantDist < 0.0) // -1.0 means SFB is zero-quantized if (refQuantDist < 0.0) // -1.0 means SFB is zero-quantized
@ -576,7 +576,7 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
} }
else if (is != 1) // quantization & distortion not computed else if (is != 1) // quantization & distortion not computed
{ {
const unsigned char sfCurr = __max (0, __min (m_maxSfIndex, refSf + 1 - (int) is)); const uint8_t sfCurr = __max (0, __min (m_maxSfIndex, refSf + 1 - (int) is));
*currDist = -1.0; *currDist = -1.0;
if ((sfCurr == 0) || maxSnrReached) if ((sfCurr == 0) || maxSnrReached)
@ -596,7 +596,7 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
*currDist = getQuantDist (coeffMagn, sfBest, tempMagn, sfbWidth) * refQuantNorm; *currDist = getQuantDist (coeffMagn, sfBest, tempMagn, sfbWidth) * refQuantNorm;
} }
} }
if (*currDist < 0.0) memset (tempMagn, 0, sfbWidth * sizeof (unsigned char)); if (*currDist < 0.0) memset (tempMagn, 0, sfbWidth * sizeof (uint8_t));
m_quantInSf[sfb][is] = sfCurr; // store initial scale fac m_quantInSf[sfb][is] = sfCurr; // store initial scale fac
} }
else // is == 1, quant. & dist. computed with quantizeSfb() else // is == 1, quant. & dist. computed with quantizeSfb()
@ -645,7 +645,7 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
memcpy (prevCodState, tempCodState, m_numCStates * sizeof (uint32_t)); memcpy (prevCodState, tempCodState, m_numCStates * sizeof (uint32_t));
memcpy (prevCtxState, tempCtxState, m_numCStates * sizeof (uint32_t)); memcpy (prevCtxState, tempCtxState, m_numCStates * sizeof (uint32_t));
memcpy (prevScaleFac, tempScaleFac, m_numCStates * sizeof (unsigned char)); memcpy (prevScaleFac, tempScaleFac, m_numCStates * sizeof (uint8_t ));
} // for sfb } // for sfb
entropyCoder.arithSetCodState (codFinal); // back to last state entropyCoder.arithSetCodState (codFinal); // back to last state
@ -657,7 +657,7 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
#endif #endif
{ {
double* const prevCost = prevVtrbCost; double* const prevCost = prevVtrbCost;
unsigned char* const prevPath = m_coeffTemp; // for backtrack uint8_t* const prevPath = m_coeffTemp; // trellis backtracker
double costMinIs = (double) UINT_MAX; double costMinIs = (double) UINT_MAX;
#if EC_TRAIN #if EC_TRAIN
double tempGrpDist = 0.0; double tempGrpDist = 0.0;
@ -675,13 +675,13 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
for (sfb = 1; sfb < numSfb; sfb++) // search for minimum path for (sfb = 1; sfb < numSfb; sfb++) // search for minimum path
{ {
double* const currCost = tempVtrbCost; double* const currCost = tempVtrbCost;
unsigned char* const currPath = &prevPath[sfb * m_numCStates]; uint8_t* const currPath = &prevPath[sfb * m_numCStates];
for (is = 0; is < m_numCStates; is++) // SFB's minimum path for (is = 0; is < m_numCStates; is++) // SFB's minimum path
{ {
uint16_t* currRate = &m_quantRate[sfb][is * m_numCStates]; uint16_t* currRate = &m_quantRate[sfb][is * m_numCStates];
double costMinDs = (double) UINT_MAX; double costMinDs = (double) UINT_MAX;
unsigned char pathMinDs = 1; uint8_t pathMinDs = 1;
for (ds = m_numCStates - 1; ds >= 0; ds--) // transitions for (ds = m_numCStates - 1; ds >= 0; ds--) // transitions
{ {
@ -690,7 +690,7 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
if (costMinDs > costCurr) if (costMinDs > costCurr)
{ {
costMinDs = costCurr; costMinDs = costCurr;
pathMinDs = (unsigned char) ds; pathMinDs = (uint8_t) ds;
} }
} }
if (costMinDs < UINT_MAX) costMinDs += __max (0.0, m_quantDist[sfb][is]); if (costMinDs < UINT_MAX) costMinDs += __max (0.0, m_quantDist[sfb][is]);
@ -713,8 +713,8 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
for (tempBitCount = 0; sfb > 0; sfb--) // min-cost group rate for (tempBitCount = 0; sfb > 0; sfb--) // min-cost group rate
{ {
const unsigned char* currPath = &prevPath[sfb * m_numCStates]; const uint8_t* currPath = &prevPath[sfb * m_numCStates];
const unsigned char pathMinDs = currPath[pathMinIs]; const uint8_t pathMinDs = currPath[pathMinIs];
inScaleFac[sfb] = (m_quantDist[sfb][pathMinIs] < 0.0 ? UCHAR_MAX : m_quantInSf[sfb][pathMinIs]); inScaleFac[sfb] = (m_quantDist[sfb][pathMinIs] < 0.0 ? UCHAR_MAX : m_quantInSf[sfb][pathMinIs]);
tempBitCount += m_quantRate[sfb][pathMinDs + pathMinIs * m_numCStates]; tempBitCount += m_quantRate[sfb][pathMinDs + pathMinIs * m_numCStates];
@ -736,7 +736,7 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
if (quantCoeffs != nullptr) if (quantCoeffs != nullptr)
#endif #endif
{ {
unsigned char sfIndexPred = UCHAR_MAX; uint8_t sfIndexPred = UCHAR_MAX;
if (grpStats) if (grpStats)
{ {
@ -753,7 +753,7 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
if (inScaleFac[sfb] == UCHAR_MAX) // forced zero-quantized if (inScaleFac[sfb] == UCHAR_MAX) // forced zero-quantized
{ {
optimalSf[sfb] = sfIndexPred; optimalSf[sfb] = sfIndexPred;
memset (&quantCoeffs[sfbStart], 0, sfbWidth * sizeof (unsigned char)); memset (&quantCoeffs[sfbStart], 0, sfbWidth * sizeof (uint8_t));
} }
else if (inScaleFac[sfb] != m_quantInSf[sfb][1]) // speedup else if (inScaleFac[sfb] != m_quantInSf[sfb][1]) // speedup
{ {
@ -775,7 +775,7 @@ unsigned SfbQuantizer::quantizeSpecRDOC (EntropyCoder& entropyCoder, unsigned ch
if ((sfb > 0) && (optimalSf[sfb] < UCHAR_MAX) && (sfIndexPred == UCHAR_MAX)) if ((sfb > 0) && (optimalSf[sfb] < UCHAR_MAX) && (sfIndexPred == UCHAR_MAX))
{ {
memset (optimalSf, optimalSf[sfb], sfb * sizeof (unsigned char)); // back-propagate memset (optimalSf, optimalSf[sfb], sfb * sizeof (uint8_t)); // back-propagate factor
} }
sfIndexPred = optimalSf[sfb]; sfIndexPred = optimalSf[sfb];
} // for sfb } // for sfb

View File

@ -13,7 +13,7 @@
// static helper function // static helper function
static inline uint32_t packAvgSpecAnalysisStats (const uint64_t sumAvgBand, const uint64_t sumMaxBand, static inline uint32_t packAvgSpecAnalysisStats (const uint64_t sumAvgBand, const uint64_t sumMaxBand,
const unsigned char predGain, const uint8_t predGain,
const uint16_t idxMaxSpec, const uint16_t idxLpStart) const uint16_t idxMaxSpec, const uint16_t idxLpStart)
{ {
// temporal flatness, normalized for a value of 256 for a linear prediction gain of 1 (0 dB) // temporal flatness, normalized for a value of 256 for a linear prediction gain of 1 (0 dB)

View File

@ -22,15 +22,15 @@ SpecGapFiller::SpecGapFiller ()
} }
// public functions // public functions
unsigned char SpecGapFiller::getSpecGapFillParams (const SfbQuantizer& sfbQuantizer, const unsigned char* const quantMagn, uint8_t SpecGapFiller::getSpecGapFillParams (const SfbQuantizer& sfbQuantizer, const uint8_t* const quantMagn,
const unsigned char numSwbShort, SfbGroupData& grpData /*modified*/, const uint8_t numSwbShort, SfbGroupData& grpData /*modified*/,
const unsigned nSamplesInFrame /*= 1024*/) const unsigned nSamplesInFrame /*= 1024*/)
{ {
const unsigned* const coeffMagn = sfbQuantizer.getCoeffMagnPtr (); const unsigned* const coeffMagn = sfbQuantizer.getCoeffMagnPtr ();
const double* const sfNormFacs = sfbQuantizer.getSfNormTabPtr (); const double* const sfNormFacs = sfbQuantizer.getSfNormTabPtr ();
const uint16_t sfbsPerGrp = grpData.sfbsPerGroup; const uint16_t sfbsPerGrp = grpData.sfbsPerGroup;
const uint16_t windowNfso = noiseFillingStartOffset[grpData.numWindowGroups == 1 ? 0 : 1][nSamplesInFrame >> 10]; const uint16_t windowNfso = noiseFillingStartOffset[grpData.numWindowGroups == 1 ? 0 : 1][nSamplesInFrame >> 10];
unsigned char scaleFactorLimit = 0; uint8_t scaleFactorLimit = 0;
uint16_t u = 0; uint16_t u = 0;
short diff = 0, s = 0; short diff = 0, s = 0;
double magnSum = 0.0; double magnSum = 0.0;
@ -48,8 +48,8 @@ unsigned char SpecGapFiller::getSpecGapFillParams (const SfbQuantizer& sfbQuanti
for (uint16_t gr = 0; gr < grpData.numWindowGroups; gr++) for (uint16_t gr = 0; gr < grpData.numWindowGroups; gr++)
{ {
const uint16_t* grpOff = &grpData.sfbOffsets[numSwbShort * gr]; const uint16_t* grpOff = &grpData.sfbOffsets[numSwbShort * gr];
const uint32_t* grpRms = &grpData.sfbRmsValues[numSwbShort * gr]; // quant./coding stats const uint32_t* grpRms = &grpData.sfbRmsValues[numSwbShort * gr]; // quant/coder stats
const unsigned char* grpScFacs = &grpData.scaleFactors[numSwbShort * gr]; const uint8_t* grpScFacs = &grpData.scaleFactors[numSwbShort * gr];
const uint16_t grpLength = grpData.windowGroupLength[gr]; const uint16_t grpLength = grpData.windowGroupLength[gr];
const uint16_t grpNfso = grpOff[0] + grpLength * windowNfso; const uint16_t grpNfso = grpOff[0] + grpLength * windowNfso;
const uint16_t sfbLimit = (grpData.numWindowGroups == 1 ? sfbsPerGrp - (grpOff[sfbsPerGrp] >= nSamplesInFrame ? 1 : 0) const uint16_t sfbLimit = (grpData.numWindowGroups == 1 ? sfbsPerGrp - (grpOff[sfbsPerGrp] >= nSamplesInFrame ? 1 : 0)
@ -59,8 +59,8 @@ unsigned char SpecGapFiller::getSpecGapFillParams (const SfbQuantizer& sfbQuanti
const uint16_t sfbStart = grpOff[b]; const uint16_t sfbStart = grpOff[b];
const uint16_t sfbWidth = grpOff[b + 1] - sfbStart; const uint16_t sfbWidth = grpOff[b + 1] - sfbStart;
const unsigned* const sfbMagn = &coeffMagn[sfbStart]; const unsigned* const sfbMagn = &coeffMagn[sfbStart];
const unsigned char* sfbQuant = &quantMagn[sfbStart]; const uint8_t* sfbQuant = &quantMagn[sfbStart];
const unsigned char sFac = grpScFacs[b]; const uint8_t sFac = grpScFacs[b];
if (sfbStart < grpNfso) // SFBs below noiseFillingStartOffset if (sfbStart < grpNfso) // SFBs below noiseFillingStartOffset
{ {
@ -84,7 +84,7 @@ unsigned char SpecGapFiller::getSpecGapFillParams (const SfbQuantizer& sfbQuanti
if (grpLength > 1) // eight-short windows: SFB ungrouping if (grpLength > 1) // eight-short windows: SFB ungrouping
{ {
const uint32_t* sfbMagnPtr = sfbMagn; const uint32_t* sfbMagnPtr = sfbMagn;
const unsigned char* sfbQuantPtr = sfbQuant; const uint8_t* sfbQuantPtr = sfbQuant;
const int swbLength = (sfbWidth * oneTwentyEightOver[grpLength]) >> 7; // sfbWidth / grpLength const int swbLength = (sfbWidth * oneTwentyEightOver[grpLength]) >> 7; // sfbWidth / grpLength
unsigned sfbMagnMin = USHRT_MAX; unsigned sfbMagnMin = USHRT_MAX;
uint16_t uMin = 0; uint16_t uMin = 0;
@ -149,8 +149,8 @@ unsigned char SpecGapFiller::getSpecGapFillParams (const SfbQuantizer& sfbQuanti
for (uint16_t gr = 0; gr < grpData.numWindowGroups; gr++) for (uint16_t gr = 0; gr < grpData.numWindowGroups; gr++)
{ {
const uint16_t* grpOff = &grpData.sfbOffsets[numSwbShort * gr]; const uint16_t* grpOff = &grpData.sfbOffsets[numSwbShort * gr];
const uint32_t* grpRms = &grpData.sfbRmsValues[numSwbShort * gr]; // quant./coding stats const uint32_t* grpRms = &grpData.sfbRmsValues[numSwbShort * gr]; // quant/coder stats
unsigned char* const grpScFacs = &grpData.scaleFactors[numSwbShort * gr]; uint8_t* const grpScFacs = &grpData.scaleFactors[numSwbShort * gr];
for (uint16_t b = m_1stGapFillSfb; b < sfbsPerGrp; b++) // calculate scale factors for (uint16_t b = m_1stGapFillSfb; b < sfbsPerGrp; b++) // calculate scale factors
{ {
@ -202,21 +202,21 @@ unsigned char SpecGapFiller::getSpecGapFillParams (const SfbQuantizer& sfbQuanti
for (uint16_t gr = 0; gr < grpData.numWindowGroups; gr++) for (uint16_t gr = 0; gr < grpData.numWindowGroups; gr++)
{ {
const uint32_t* grpRms = &grpData.sfbRmsValues[numSwbShort * gr]; // quant./coding stats const uint32_t* grpRms = &grpData.sfbRmsValues[numSwbShort * gr]; // quant/coder stats
unsigned char* const grpScFacs = &grpData.scaleFactors[numSwbShort * gr]; uint8_t* const grpScFacs = &grpData.scaleFactors[numSwbShort * gr];
for (uint16_t b = m_1stGapFillSfb; b < sfbsPerGrp; b++) // account f. noise_offset for (uint16_t b = m_1stGapFillSfb; b < sfbsPerGrp; b++) // account f. noise_offset
{ {
if ((grpRms[b] >> 16) == 0) // the SFB is all-zero quantized if ((grpRms[b] >> 16) == 0) // the SFB is all-zero quantized
{ {
grpScFacs[b] = (unsigned char) __max (s, grpScFacs[b] - diff); grpScFacs[b] = (uint8_t) __max (s, grpScFacs[b] - diff);
if (grpScFacs[b] > scaleFactorLimit) grpScFacs[b] = scaleFactorLimit; if (grpScFacs[b] > scaleFactorLimit) grpScFacs[b] = scaleFactorLimit;
} }
} // for b } // for b
// repeat first significant scale factor downwards to save bits // repeat first significant scale factor downwards to save bits
memset (grpScFacs, grpScFacs[m_1stNonZeroSfb[gr]], m_1stNonZeroSfb[gr] * sizeof (unsigned char)); memset (grpScFacs, grpScFacs[m_1stNonZeroSfb[gr]], m_1stNonZeroSfb[gr] * sizeof (uint8_t));
} // for gr } // for gr
return CLIP_UCHAR (u | (diff + 16)); // combined level and offset return CLIP_UCHAR (u | (diff + 16)); // combined level and offset

View File

@ -1,11 +1,11 @@
## makefile.base - common make-file for compiling exhale on Linux and MacOS platforms ## makefile.base - common make-file for compiling exhale on Linux and MacOS platforms
# written by C. R. Helmrich, last modified 2019 - see License.txt for legal notices # written by C. R. Helmrich, last modified in 2020 - see License.htm for legal notices
# #
# The copyright in this software is being made available under a Modified BSD License # The copyright in this software is being made available under a Modified BSD-Style 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-2019 Christian R. Helmrich, project ecodis. All rights reserved. # Copyright (c) 2018-2020 Christian R. Helmrich, project ecodis. All rights reserved.
## ##
######################################################### #########################################################