mirror of
https://gitlab.com/ecodis/exhale.git
synced 2025-03-12 01:00:11 +01:00
ARM, API, other fixes
This commit is contained in:
parent
fd32557d3e
commit
12bb57155a
15
README.md
15
README.md
@ -94,17 +94,17 @@ to exhale's standard input pipe (stdin), such as foobar2000.
|
|||||||
|
|
||||||
In a terminal, change to exhale's `bin` subdirectory and then enter
|
In a terminal, change to exhale's `bin` subdirectory and then enter
|
||||||
|
|
||||||
`./exhale` (on Linux and MacOS) or `exhaleApp.exe` (on Windows)
|
`./exhale` (on Linux and MacOS) or `exhale.exe` (on Windows)
|
||||||
|
|
||||||
to print out usage information. As an example, the following command
|
to print out usage information. As an example, the following command
|
||||||
|
|
||||||
`exhaleApp.exe 5 C:\Music\Input.wav C:\Music\Output.m4a`
|
`exhale.exe 5 C:\Music\Input.wav C:\Music\Output.m4a`
|
||||||
|
|
||||||
converts file Input.wav to file Output.m4a at roughly 128 kbit/s (if
|
converts file Input.wav to file Output.m4a at roughly 128 kbit/s (if
|
||||||
the input signal is two-channel stereo) and in xHE-AAC audio format.
|
the input signal is two-channel stereo) and in xHE-AAC audio format.
|
||||||
Note that, when calling the exhale application with a path (such as,
|
Note that, when calling the exhale application with a path (such as,
|
||||||
e.g., `bin/exhale` or `bin\exhaleApp.exe`), but specifying the input
|
e.g., `bin/exhale` or `bin\exhale.exe`), but specifying the input or
|
||||||
or output file without any path (e.g., `Input.wav`), those files are
|
output file without a file path (e.g., `Input.wav`), those files are
|
||||||
assumed to be located in the application path (here, `bin`). Use the
|
assumed to be located in the application path (here, `bin`). Use the
|
||||||
"dot prefix" to indicate files in the *current* directory instead of
|
"dot prefix" to indicate files in the *current* directory instead of
|
||||||
the application directory (here, `./Input.wav` or `.\Input.wav`).
|
the application directory (here, `./Input.wav` or `.\Input.wav`).
|
||||||
@ -119,9 +119,9 @@ to be converted, rightclick on one of them, and select `Convert` ->
|
|||||||
the window content changed, on `Add New`. Then select `Custom` under
|
the window content changed, on `Add New`. Then select `Custom` under
|
||||||
"Encoder" and enter the following information:
|
"Encoder" and enter the following information:
|
||||||
|
|
||||||
- *Encoder file:* exhaleApp.exe (possibly including path to it)
|
- *Encoder file:* exhale.exe (including path to the executable)
|
||||||
- *Extension:* m4a
|
- *Extension:* m4a
|
||||||
- *Parameters:* # %d (where number is the bit-rate mode, 1...9)
|
- *Parameters:* # %d (where # is the bit-rate mode, i.e. 1...9)
|
||||||
- *Format is:* lossy
|
- *Format is:* lossy
|
||||||
- *Highest BPS mode supported:* 24 (or 32, doesn't matter much)
|
- *Highest BPS mode supported:* 24 (or 32, doesn't matter much)
|
||||||
- *Encoder name:* xHE-AAC (exhale)
|
- *Encoder name:* xHE-AAC (exhale)
|
||||||
@ -129,7 +129,8 @@ the window content changed, on `Add New`. Then select `Custom` under
|
|||||||
- *Settings:* CVBR mode # (where # equals that in *Parameters*)
|
- *Settings:* CVBR mode # (where # equals that in *Parameters*)
|
||||||
|
|
||||||
Then click on `OK` and on `Back` and, in the first "Converter Setup"
|
Then click on `OK` and on `Back` and, in the first "Converter Setup"
|
||||||
window, on `Other` and ensure all "Transfer..." boxes are unchecked.
|
window, on `Other` and ensure the "Transfer..." box for the class of
|
||||||
|
input metadata that you wish to copy to the output files is checked.
|
||||||
Now set the destination settings as desired and click on `Convert`.
|
Now set the destination settings as desired and click on `Convert`.
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef _EXHALE_DECL_H_
|
#ifndef _EXHALE_DECL_H_
|
||||||
#define _EXHALE_DECL_H_
|
#define _EXHALE_DECL_H_
|
||||||
|
|
||||||
#include <stdint.h> // for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t
|
#include <stdint.h> /* for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t */
|
||||||
|
|
||||||
#if defined (_WIN32) || defined (WIN32) || defined (_WIN64) || defined (WIN64)
|
#if defined (_WIN32) || defined (WIN32) || defined (_WIN64) || defined (WIN64)
|
||||||
# ifdef EXHALE_DYN_LINK
|
# ifdef EXHALE_DYN_LINK
|
||||||
@ -23,31 +23,43 @@
|
|||||||
# define EXHALE_DECL
|
# define EXHALE_DECL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
struct ExhaleEncAPI
|
struct ExhaleEncAPI
|
||||||
{
|
{
|
||||||
// initializer
|
/* initializer */
|
||||||
virtual unsigned initEncoder (unsigned char* const audioConfigBuffer, uint32_t* const audioConfigBytes = nullptr) = 0;
|
virtual unsigned initEncoder (unsigned char* const audioConfigBuffer, uint32_t* const audioConfigBytes = nullptr) = 0;
|
||||||
// lookahead encoder
|
/* lookahead encoder */
|
||||||
virtual unsigned encodeLookahead () = 0;
|
virtual unsigned encodeLookahead () = 0;
|
||||||
// frame encoder
|
/* frame encoder */
|
||||||
virtual unsigned encodeFrame () = 0;
|
virtual unsigned encodeFrame () = 0;
|
||||||
// destructor
|
/* destructor */
|
||||||
virtual ~ExhaleEncAPI () { }
|
virtual ~ExhaleEncAPI () { }
|
||||||
};
|
};
|
||||||
|
|
||||||
// C constructor
|
extern "C"
|
||||||
extern "C" EXHALE_DECL ExhaleEncAPI* exhaleCreate (int32_t* const, unsigned char* const, const unsigned, const unsigned,
|
{
|
||||||
const unsigned, const unsigned, const unsigned, const bool, const bool);
|
#else /* C, not C++ */
|
||||||
// C destructor
|
struct ExhaleEncAPI; /* opaque type */
|
||||||
extern "C" EXHALE_DECL unsigned exhaleDelete (ExhaleEncAPI*);
|
typedef struct ExhaleEncAPI ExhaleEncAPI;
|
||||||
|
#endif
|
||||||
|
|
||||||
// C initializer
|
/* C constructor */
|
||||||
extern "C" EXHALE_DECL unsigned exhaleInitEncoder (ExhaleEncAPI*, unsigned char* const, uint32_t* const);
|
EXHALE_DECL ExhaleEncAPI* exhaleCreate (int32_t* const, unsigned char* const, const unsigned, const unsigned,
|
||||||
|
const unsigned, const unsigned, const unsigned, const bool, const bool);
|
||||||
|
/* C destructor */
|
||||||
|
EXHALE_DECL unsigned exhaleDelete (ExhaleEncAPI*);
|
||||||
|
|
||||||
// C lookahead encoder
|
/* C initializer */
|
||||||
extern "C" EXHALE_DECL unsigned exhaleEncodeLookahead (ExhaleEncAPI*);
|
EXHALE_DECL unsigned exhaleInitEncoder (ExhaleEncAPI*, unsigned char* const, uint32_t* const);
|
||||||
|
|
||||||
// C frame encoder
|
/* C lookahead encoder */
|
||||||
extern "C" EXHALE_DECL unsigned exhaleEncodeFrame (ExhaleEncAPI*);
|
EXHALE_DECL unsigned exhaleEncodeLookahead (ExhaleEncAPI*);
|
||||||
|
|
||||||
#endif // _EXHALE_DECL_H_
|
/* C frame encoder */
|
||||||
|
EXHALE_DECL unsigned exhaleEncodeFrame (ExhaleEncAPI*);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _EXHALE_DECL_H_ */
|
||||||
|
@ -145,7 +145,7 @@ unsigned BitStreamWriter::writeChannelWiseTnsData (const TnsData& tnsData, const
|
|||||||
{
|
{
|
||||||
const int8_t* coeff = tnsData.coeff[n + f];
|
const int8_t* coeff = tnsData.coeff[n + f];
|
||||||
unsigned coefBits = (tnsData.coeffResLow[n] ? 3 : 4);
|
unsigned coefBits = (tnsData.coeffResLow[n] ? 3 : 4);
|
||||||
char coefMaxValue = (tnsData.coeffResLow[n] ? 2 : 4);
|
int8_t coefMaxValue = (tnsData.coeffResLow[n] ? 2 : 4);
|
||||||
bool dontCompress = false;
|
bool dontCompress = false;
|
||||||
|
|
||||||
m_auBitStream.write (tnsData.filterDownward[n + f] ? 1 : 0, 1);
|
m_auBitStream.write (tnsData.filterDownward[n + f] ? 1 : 0, 1);
|
||||||
|
@ -340,7 +340,7 @@ static const uint8_t numberOfChannels[USAC_MAX_NUM_ELCONFIGS] = {0, 1, 2, 3, 4,
|
|||||||
|
|
||||||
static inline unsigned toNumChannels (const USAC_CCI chConfigurationIndex)
|
static inline unsigned toNumChannels (const USAC_CCI chConfigurationIndex)
|
||||||
{
|
{
|
||||||
return numberOfChannels[__max (0, (char) chConfigurationIndex)];
|
return numberOfChannels[__max (0, (signed char) chConfigurationIndex)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// ISO/IEC 23003-3, Table 68
|
// ISO/IEC 23003-3, Table 68
|
||||||
@ -918,7 +918,9 @@ unsigned ExhaleEncoder::psychBitAllocation () // perceptual bit-allocation via s
|
|||||||
const bool eightShorts = (coreConfig.icsInfoCurr[ch].windowSequence == EIGHT_SHORT);
|
const bool eightShorts = (coreConfig.icsInfoCurr[ch].windowSequence == EIGHT_SHORT);
|
||||||
const bool saveBitRate = (meanSpecFlat[ci] > SCHAR_MAX && samplingRate >= 32000 + (unsigned) m_bitRateMode * 12000);
|
const bool saveBitRate = (meanSpecFlat[ci] > SCHAR_MAX && samplingRate >= 32000 + (unsigned) m_bitRateMode * 12000);
|
||||||
const uint8_t maxSfbCh = grpData.sfbsPerGroup;
|
const uint8_t maxSfbCh = grpData.sfbsPerGroup;
|
||||||
|
#if !RESTRICT_TO_AAC
|
||||||
const uint8_t numSwbCh = (eightShorts ? m_numSwbShort : m_numSwbLong);
|
const uint8_t numSwbCh = (eightShorts ? m_numSwbShort : m_numSwbLong);
|
||||||
|
#endif
|
||||||
const uint16_t mSfmFac = UCHAR_MAX - ((9u * meanSpecFlat[ci]) >> 4);
|
const uint16_t mSfmFac = UCHAR_MAX - ((9u * meanSpecFlat[ci]) >> 4);
|
||||||
uint32_t* stepSizes = &sfbStepSizes[ci * m_numSwbShort * NUM_WINDOW_GROUPS];
|
uint32_t* stepSizes = &sfbStepSizes[ci * m_numSwbShort * NUM_WINDOW_GROUPS];
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#define WIN_SCALE double (1 << 23)
|
#define WIN_SCALE double (1 << 23)
|
||||||
|
|
||||||
// channelConfigurationIndex setup
|
// channelConfigurationIndex setup
|
||||||
typedef enum USAC_CCI : char
|
typedef enum USAC_CCI : signed char
|
||||||
{
|
{
|
||||||
CCI_UNDEF = -1,
|
CCI_UNDEF = -1,
|
||||||
CCI_CONF = 0, // channel-to-speaker mapping defined in UsacChannelConfig() (not to be used here!)
|
CCI_CONF = 0, // channel-to-speaker mapping defined in UsacChannelConfig() (not to be used here!)
|
||||||
@ -71,7 +71,7 @@ private:
|
|||||||
EntropyCoder m_entropyCoder[USAC_MAX_NUM_CHANNELS];
|
EntropyCoder m_entropyCoder[USAC_MAX_NUM_CHANNELS];
|
||||||
uint32_t m_frameCount;
|
uint32_t m_frameCount;
|
||||||
USAC_CCFL m_frameLength;
|
USAC_CCFL m_frameLength;
|
||||||
char m_frequencyIdx;
|
int8_t m_frequencyIdx;
|
||||||
bool m_indepFlag; // usacIndependencyFlag bit
|
bool m_indepFlag; // usacIndependencyFlag bit
|
||||||
uint32_t m_indepPeriod;
|
uint32_t m_indepPeriod;
|
||||||
LinearPredictor m_linPredictor; // for pre-roll est, TNS
|
LinearPredictor m_linPredictor; // for pre-roll est, TNS
|
||||||
@ -153,52 +153,56 @@ public:
|
|||||||
}; // ExhaleEncoder
|
}; // ExhaleEncoder
|
||||||
|
|
||||||
#ifdef EXHALE_DYN_LINK
|
#ifdef EXHALE_DYN_LINK
|
||||||
// C constructor
|
extern "C"
|
||||||
extern "C" EXHALE_DECL ExhaleEncAPI* exhaleCreate (int32_t* const inputPcmData, unsigned char* const outputAuData,
|
|
||||||
const unsigned sampleRate = 44100, const unsigned numChannels = 2,
|
|
||||||
const unsigned frameLength = 1024, const unsigned indepPeriod = 45,
|
|
||||||
const unsigned varBitRateMode = 3, const bool useNoiseFilling = true,
|
|
||||||
const bool useEcodisExt = false)
|
|
||||||
{
|
{
|
||||||
return new ExhaleEncoder (inputPcmData, outputAuData, sampleRate, numChannels, frameLength, indepPeriod, varBitRateMode
|
// C constructor
|
||||||
|
EXHALE_DECL ExhaleEncAPI* exhaleCreate (int32_t* const inputPcmData, unsigned char* const outputAuData,
|
||||||
|
const unsigned sampleRate = 44100, const unsigned numChannels = 2,
|
||||||
|
const unsigned frameLength = 1024, const unsigned indepPeriod = 45,
|
||||||
|
const unsigned varBitRateMode = 3, const bool useNoiseFilling = true,
|
||||||
|
const bool useEcodisExt = false)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<ExhaleEncAPI*> (new ExhaleEncoder (inputPcmData, outputAuData, sampleRate, numChannels, frameLength, indepPeriod, varBitRateMode
|
||||||
#if !RESTRICT_TO_AAC
|
#if !RESTRICT_TO_AAC
|
||||||
, useNoiseFilling, useEcodisExt
|
, useNoiseFilling, useEcodisExt
|
||||||
#endif
|
#endif
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// C destructor
|
// C destructor
|
||||||
extern "C" EXHALE_DECL unsigned exhaleDelete (ExhaleEncAPI* exhaleEnc)
|
EXHALE_DECL unsigned exhaleDelete (ExhaleEncAPI* exhaleEnc)
|
||||||
{
|
{
|
||||||
if (exhaleEnc != NULL) { delete exhaleEnc; return 0; }
|
if (exhaleEnc != NULL) { delete reinterpret_cast<ExhaleEncoder*> (exhaleEnc); return 0; }
|
||||||
|
|
||||||
return USHRT_MAX; // error
|
return USHRT_MAX; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
// C initializer
|
// C initializer
|
||||||
extern "C" EXHALE_DECL unsigned exhaleInitEncoder (ExhaleEncAPI* exhaleEnc, unsigned char* const audioConfigBuffer,
|
EXHALE_DECL unsigned exhaleInitEncoder (ExhaleEncAPI* exhaleEnc, unsigned char* const audioConfigBuffer,
|
||||||
uint32_t* const audioConfigBytes = nullptr)
|
uint32_t* const audioConfigBytes = nullptr)
|
||||||
{
|
{
|
||||||
if (exhaleEnc != NULL) return exhaleEnc->initEncoder (audioConfigBuffer, audioConfigBytes);
|
if (exhaleEnc != NULL) return reinterpret_cast<ExhaleEncoder*> (exhaleEnc)->initEncoder (audioConfigBuffer, audioConfigBytes);
|
||||||
|
|
||||||
return USHRT_MAX; // error
|
return USHRT_MAX; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
// C lookahead encoder
|
// C lookahead encoder
|
||||||
extern "C" EXHALE_DECL unsigned exhaleEncodeLookahead (ExhaleEncAPI* exhaleEnc)
|
EXHALE_DECL unsigned exhaleEncodeLookahead (ExhaleEncAPI* exhaleEnc)
|
||||||
{
|
{
|
||||||
if (exhaleEnc != NULL) return exhaleEnc->encodeLookahead ();
|
if (exhaleEnc != NULL) return reinterpret_cast<ExhaleEncoder*> (exhaleEnc)->encodeLookahead ();
|
||||||
|
|
||||||
return USHRT_MAX; // error
|
return USHRT_MAX; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
// C frame encoder
|
// C frame encoder
|
||||||
extern "C" EXHALE_DECL unsigned exhaleEncodeFrame (ExhaleEncAPI* exhaleEnc)
|
EXHALE_DECL unsigned exhaleEncodeFrame (ExhaleEncAPI* exhaleEnc)
|
||||||
{
|
{
|
||||||
if (exhaleEnc != NULL) return exhaleEnc->encodeFrame ();
|
if (exhaleEnc != NULL) return reinterpret_cast<ExhaleEncoder*> (exhaleEnc)->encodeFrame ();
|
||||||
|
|
||||||
return USHRT_MAX; // error
|
return USHRT_MAX; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
#endif // EXHALE_DYN_LINK
|
#endif // EXHALE_DYN_LINK
|
||||||
|
|
||||||
#endif // _EXHALE_ENC_H_
|
#endif // _EXHALE_ENC_H_
|
||||||
|
@ -53,11 +53,11 @@ static const unsigned allowedSamplingRates[USAC_NUM_SAMPLE_RATES] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// public sampling rate functions
|
// public sampling rate functions
|
||||||
char toSamplingFrequencyIndex (const unsigned samplingRate)
|
int8_t toSamplingFrequencyIndex (const unsigned samplingRate)
|
||||||
{
|
{
|
||||||
for (char i = 0; i < AAC_NUM_SAMPLE_RATES; i++)
|
for (int8_t i = 0; i < AAC_NUM_SAMPLE_RATES; i++)
|
||||||
{
|
{
|
||||||
if (samplingRate == allowedSamplingRates[(int) i]) // AAC rate
|
if (samplingRate == allowedSamplingRates[i]) // (HE-)AAC rate
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ char toSamplingFrequencyIndex (const unsigned samplingRate)
|
|||||||
return -1; // no index found
|
return -1; // no index found
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned toSamplingRate (const char samplingFrequencyIndex)
|
unsigned toSamplingRate (const int8_t samplingFrequencyIndex)
|
||||||
{
|
{
|
||||||
#if RESTRICT_TO_AAC
|
#if RESTRICT_TO_AAC
|
||||||
if ((samplingFrequencyIndex < 0) || (samplingFrequencyIndex >= AAC_NUM_SAMPLE_RATES))
|
if ((samplingFrequencyIndex < 0) || (samplingFrequencyIndex >= AAC_NUM_SAMPLE_RATES))
|
||||||
|
@ -172,7 +172,7 @@ const uint8_t eightTimesSqrt256Minus[256] = {
|
|||||||
const uint8_t oneTwentyEightOver[14] = {0, 128, 64, 43, 32, 26, 22, 19, 16, 15, 13, 12, 11, 10};
|
const uint8_t oneTwentyEightOver[14] = {0, 128, 64, 43, 32, 26, 22, 19, 16, 15, 13, 12, 11, 10};
|
||||||
|
|
||||||
// public sampling rate functions
|
// public sampling rate functions
|
||||||
char toSamplingFrequencyIndex (const unsigned samplingRate);
|
int8_t toSamplingFrequencyIndex (const unsigned samplingRate);
|
||||||
unsigned toSamplingRate (const char samplingFrequencyIndex);
|
unsigned toSamplingRate (const int8_t samplingFrequencyIndex);
|
||||||
|
|
||||||
#endif // _EXHALE_LIB_PCH_H_
|
#endif // _EXHALE_LIB_PCH_H_
|
||||||
|
@ -24,7 +24,7 @@ static const short tnsQuantCoeff4[17/*2^4+1*/] = { // = round (2^11 * sin (x * p
|
|||||||
static const short* tnsQuantCoeff[2/*coefRes*/] = {tnsQuantCoeff3, tnsQuantCoeff4};
|
static const short* tnsQuantCoeff[2/*coefRes*/] = {tnsQuantCoeff3, tnsQuantCoeff4};
|
||||||
|
|
||||||
// ISO/IEC 14496-3, Sec. 4.6.9.3, 3-bit
|
// ISO/IEC 14496-3, Sec. 4.6.9.3, 3-bit
|
||||||
static const char tnsQuantIndex3[SCHAR_MAX + 1] = { // = round (asin (x / 64) * (x < 0 ? 9 : 7) / pi)
|
static const int8_t tnsQuantIndex3[SCHAR_MAX + 1] = { // = round (asin (x / 64) * (x < 0 ? 9 : 7) / pi)
|
||||||
-4, -4, -4, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
|
-4, -4, -4, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
@ -32,31 +32,31 @@ static const char tnsQuantIndex3[SCHAR_MAX + 1] = { // = round (asin (x / 64) *
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ISO/IEC 14496-3, Sec. 4.6.9.3, 4-bit
|
// ISO/IEC 14496-3, Sec. 4.6.9.3, 4-bit
|
||||||
static const char tnsQuantIndex4[SCHAR_MAX + 1] = { // = round (asin (x / 64) * (x < 0 ? 17 : 15) / pi)
|
static const int8_t tnsQuantIndex4[SCHAR_MAX + 1] = { // = round (asin (x / 64) * (x < 0 ? 17 : 15) / pi)
|
||||||
-8, -7, -7, -7, -6, -6, -6, -6, -6, -5, -5, -5, -5, -5, -5, -5, -4, -4, -4, -4, -4, -4, -4, -4, -4, -3, -3, -3, -3, -3, -3, -3,
|
-8, -7, -7, -7, -6, -6, -6, -6, -6, -5, -5, -5, -5, -5, -5, -5, -4, -4, -4, -4, -4, -4, -4, -4, -4, -3, -3, -3, -3, -3, -3, -3,
|
||||||
-3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0,
|
-3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
|
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
|
||||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* tnsQuantIndex[2/*coefRes*/] = {tnsQuantIndex3, tnsQuantIndex4};
|
static const int8_t* tnsQuantIndex[2/*coefRes*/] = {tnsQuantIndex3, tnsQuantIndex4};
|
||||||
|
|
||||||
// static helper functions
|
// static helper functions
|
||||||
static int quantizeParCorCoeffs (const short* const parCorCoeffs, const uint16_t nCoeffs, const short bitDepth, int8_t* const quantCoeffs,
|
static int quantizeParCorCoeffs (const short* const parCorCoeffs, const uint16_t nCoeffs, const short bitDepth, int8_t* const quantCoeffs,
|
||||||
const bool lowRes)
|
const bool lowRes)
|
||||||
{
|
{
|
||||||
const short bitShift = bitDepth - 7;
|
const short bitShift = bitDepth - 7;
|
||||||
const unsigned tabIdx = (lowRes ? 0 : 1);
|
const unsigned tabIdx = (lowRes ? 0 : 1);
|
||||||
const char tabOffset = 4 << tabIdx;
|
const int8_t tabOffset = 4 << tabIdx;
|
||||||
const short* coeffTab = tnsQuantCoeff[tabIdx];
|
const short* coeffTab = tnsQuantCoeff[tabIdx];
|
||||||
const char* indexTab = tnsQuantIndex[tabIdx];
|
const int8_t* indexTab = tnsQuantIndex[tabIdx];
|
||||||
int dist0, dist1, distTotal = 0;
|
int dist0, dist1, distTotal = 0;
|
||||||
|
|
||||||
for (uint16_t s = 0; s < nCoeffs; s++)
|
for (uint16_t s = 0; s < nCoeffs; s++)
|
||||||
{
|
{
|
||||||
const short coeff = (bitShift < 0 ? parCorCoeffs[s] << -bitShift : parCorCoeffs[s] >> bitShift);
|
const short coeff = (bitShift < 0 ? parCorCoeffs[s] << -bitShift : parCorCoeffs[s] >> bitShift);
|
||||||
const char coeff1 = indexTab[coeff + 1 + (SCHAR_MAX >> 1)];
|
const int8_t coeff1 = indexTab[coeff + 1 + (SCHAR_MAX >> 1)];
|
||||||
const char coeff0 = (coeff1 <= -tabOffset ? coeff1 : coeff1 - 1);
|
const int8_t coeff0 = (coeff1 <= -tabOffset ? coeff1 : coeff1 - 1);
|
||||||
|
|
||||||
dist0 = (int) coeffTab[coeff0 + tabOffset] - parCorCoeffs[s];
|
dist0 = (int) coeffTab[coeff0 + tabOffset] - parCorCoeffs[s];
|
||||||
dist0 *= dist0;
|
dist0 *= dist0;
|
||||||
@ -249,7 +249,7 @@ uint8_t LinearPredictor::calcOptTnsCoeffs (short* const parCorCoeffs, int8_t* co
|
|||||||
|
|
||||||
if ((parCorCoeffs == nullptr) || (quantCoeffs == nullptr) || (maxOrder == 0) || (maxOrder > MAX_PREDICTION_ORDER) || (parCorCoeffBitDepth < 2) || (bitShift < 0))
|
if ((parCorCoeffs == nullptr) || (quantCoeffs == nullptr) || (maxOrder == 0) || (maxOrder > MAX_PREDICTION_ORDER) || (parCorCoeffBitDepth < 2) || (bitShift < 0))
|
||||||
{
|
{
|
||||||
if (quantCoeffs) memset (quantCoeffs, 0, order * sizeof (char));
|
if (quantCoeffs) memset (quantCoeffs, 0, order * sizeof (int8_t));
|
||||||
|
|
||||||
return 0; // invalid input arguments error
|
return 0; // invalid input arguments error
|
||||||
}
|
}
|
||||||
@ -269,7 +269,7 @@ uint8_t LinearPredictor::calcOptTnsCoeffs (short* const parCorCoeffs, int8_t* co
|
|||||||
|
|
||||||
if (predGain < 41 + (tonality >> 3)) // 1.5 dB
|
if (predGain < 41 + (tonality >> 3)) // 1.5 dB
|
||||||
{
|
{
|
||||||
memset (quantCoeffs, 0, order * sizeof (char));
|
memset (quantCoeffs, 0, order * sizeof (int8_t));
|
||||||
|
|
||||||
return 0; // LPC prediction gain is too low
|
return 0; // LPC prediction gain is too low
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ uint8_t LinearPredictor::calcOptTnsCoeffs (short* const parCorCoeffs, int8_t* co
|
|||||||
{
|
{
|
||||||
// low-res quantizer yields lower distortion
|
// low-res quantizer yields lower distortion
|
||||||
*lowCoeffRes = true;
|
*lowCoeffRes = true;
|
||||||
memcpy (quantCoeffs, m_tempBuf, order * sizeof (char));
|
memcpy (quantCoeffs, m_tempBuf, order * sizeof (int8_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; order > 0; order--) // return opt order
|
for (; order > 0; order--) // return opt order
|
||||||
@ -385,9 +385,9 @@ unsigned LinearPredictor::parCorToLpCoeffs (const short* const parCorCoeffs, con
|
|||||||
unsigned LinearPredictor::quantTnsToLpCoeffs (const int8_t* const quantTnsCoeffs, const uint16_t nCoeffs, const bool lowCoeffRes,
|
unsigned LinearPredictor::quantTnsToLpCoeffs (const int8_t* const quantTnsCoeffs, const uint16_t nCoeffs, const bool lowCoeffRes,
|
||||||
short* const parCorCoeffs, short* const lpCoeffs)
|
short* const parCorCoeffs, short* const lpCoeffs)
|
||||||
{
|
{
|
||||||
const unsigned tabIdx = (lowCoeffRes ? 0 : 1);
|
const unsigned tabIdx = (lowCoeffRes ? 0 : 1);
|
||||||
const char tabOffset = 4 << tabIdx;
|
const int8_t tabOffset = 4 << tabIdx;
|
||||||
const short* coeffTab = tnsQuantCoeff[tabIdx];
|
const short* coeffTab = tnsQuantCoeff[tabIdx];
|
||||||
|
|
||||||
if ((quantTnsCoeffs == nullptr) || (parCorCoeffs == nullptr) || (lpCoeffs == nullptr) || (nCoeffs == 0) || (nCoeffs > MAX_PREDICTION_ORDER))
|
if ((quantTnsCoeffs == nullptr) || (parCorCoeffs == nullptr) || (lpCoeffs == nullptr) || (nCoeffs == 0) || (nCoeffs > MAX_PREDICTION_ORDER))
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user