mirror of
https://gitlab.com/ecodis/exhale.git
synced 2025-03-12 17:20:25 +01:00
editorial changes
This commit is contained in:
parent
2e1a6c97b3
commit
cde6178540
6
makefile
6
makefile
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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];
|
||||||
|
|
||||||
|
@ -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];
|
||||||
|
@ -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 = \
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
##
|
##
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
|
Loading…
x
Reference in New Issue
Block a user