aboutsummaryrefslogtreecommitdiffstats
path: root/libFDK
diff options
context:
space:
mode:
Diffstat (limited to 'libFDK')
-rw-r--r--libFDK/include/FDK_qmf_domain.h20
-rw-r--r--libFDK/include/fixpoint_math.h43
-rw-r--r--libFDK/include/mdct.h14
-rw-r--r--libFDK/include/mips/abs_mips.h2
-rw-r--r--libFDK/include/mips/scale_mips.h2
-rw-r--r--libFDK/include/qmf.h105
-rw-r--r--libFDK/include/qmf_pcm.h218
-rw-r--r--libFDK/include/scale.h23
-rw-r--r--libFDK/include/scramble.h2
-rw-r--r--libFDK/src/FDK_bitbuffer.cpp9
-rw-r--r--libFDK/src/FDK_core.cpp6
-rw-r--r--libFDK/src/FDK_decorrelate.cpp80
-rw-r--r--libFDK/src/FDK_hybrid.cpp34
-rw-r--r--libFDK/src/FDK_qmf_domain.cpp49
-rw-r--r--libFDK/src/dct.cpp18
-rw-r--r--libFDK/src/fft_rad2.cpp2
-rw-r--r--libFDK/src/fixpoint_math.cpp8
-rw-r--r--libFDK/src/mdct.cpp6
-rw-r--r--libFDK/src/mips/scale_mips.cpp2
-rw-r--r--libFDK/src/nlc_dec.cpp10
-rw-r--r--libFDK/src/qmf.cpp384
-rw-r--r--libFDK/src/scale.cpp26
22 files changed, 497 insertions, 566 deletions
diff --git a/libFDK/include/FDK_qmf_domain.h b/libFDK/include/FDK_qmf_domain.h
index 5c12682..0e83da3 100644
--- a/libFDK/include/FDK_qmf_domain.h
+++ b/libFDK/include/FDK_qmf_domain.h
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -123,11 +123,10 @@ typedef enum {
#define QMF_WB_SECTION_SIZE (1024 * 2)
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL)
-H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL)
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL)
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL)
-H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL)
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL)
+H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL)
#define QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS (64)
#define QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS (QMF_MAX_SYNTHESIS_BANDS)
@@ -145,15 +144,15 @@ H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL)
#define QMF_DOMAIN_OV_TIMESLOTS_16 (3)
#define QMF_DOMAIN_OV_TIMESLOTS_32 (6)
-H_ALLOC_MEM(AnaQmfStates, FIXP_QAS)
+H_ALLOC_MEM(AnaQmfStates, FIXP_DBL)
H_ALLOC_MEM(SynQmfStates, FIXP_QSS)
H_ALLOC_MEM(QmfSlotsReal, FIXP_DBL *)
H_ALLOC_MEM(QmfSlotsImag, FIXP_DBL *)
H_ALLOC_MEM(QmfOverlapBuffer, FIXP_DBL)
-H_ALLOC_MEM(AnaQmfStates16, FIXP_QAS)
-H_ALLOC_MEM(AnaQmfStates24, FIXP_QAS)
-H_ALLOC_MEM(AnaQmfStates32, FIXP_QAS)
+H_ALLOC_MEM(AnaQmfStates16, FIXP_DBL)
+H_ALLOC_MEM(AnaQmfStates24, FIXP_DBL)
+H_ALLOC_MEM(AnaQmfStates32, FIXP_DBL)
H_ALLOC_MEM(QmfSlotsReal16, FIXP_DBL *)
H_ALLOC_MEM(QmfSlotsReal32, FIXP_DBL *)
H_ALLOC_MEM(QmfSlotsImag16, FIXP_DBL *)
@@ -161,8 +160,6 @@ H_ALLOC_MEM(QmfSlotsImag32, FIXP_DBL *)
H_ALLOC_MEM(QmfOverlapBuffer16, FIXP_DBL)
H_ALLOC_MEM(QmfOverlapBuffer32, FIXP_DBL)
-#define QDOM_PCM INT_PCM
-
/**
* Structure to hold the configuration data which is global whithin a QMF domain
* instance.
@@ -182,9 +179,6 @@ typedef struct {
park a channel if only one processing channel is
available. */
UCHAR parkChannel_requested;
- QDOM_PCM
- *TDinput; /*!< Pointer to time domain data used as input for the QMF
- analysis. */
FIXP_DBL *
pWorkBuffer[QMF_MAX_WB_SECTIONS]; /*!< Pointerarray to volatile memory. */
UINT flags; /*!< Flags to be set on all QMF analysis/synthesis filter
@@ -244,7 +238,7 @@ typedef struct {
(workBuf_nTimeSlots * workBuf_nBands * CMPLX_MOD). */
USHORT workBufferOffset; /*!< Offset within work buffer. */
USHORT workBufferSectSize; /*!< Size of work buffer section. */
- FIXP_QAS *
+ FIXP_DBL *
pAnaQmfStates; /*!< Pointer to QMF analysis states (persistent memory). */
FIXP_DBL
*pOverlapBuffer; /*!< Pointer to QMF overlap/delay memory (persistent
diff --git a/libFDK/include/fixpoint_math.h b/libFDK/include/fixpoint_math.h
index 3805892..51df4d7 100644
--- a/libFDK/include/fixpoint_math.h
+++ b/libFDK/include/fixpoint_math.h
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -171,6 +171,19 @@ extern const FIXP_DBL invSqrtTab[SQRT_VALUES];
* \return non-zero if (a_m*2^a_e) < (b_m*2^b_e), 0 otherwise
*/
FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e) {
+ INT n;
+
+ n = fixnorm_D(a_m);
+ a_m <<= n;
+ a_e -= n;
+
+ n = fixnorm_D(b_m);
+ b_m <<= n;
+ b_e -= n;
+
+ if (a_m == (FIXP_DBL)0) a_e = b_e;
+ if (b_m == (FIXP_DBL)0) b_e = a_e;
+
if (a_e > b_e) {
return ((b_m >> fMin(a_e - b_e, DFRACT_BITS - 1)) > a_m);
} else {
@@ -179,6 +192,19 @@ FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e) {
}
FDK_INLINE INT fIsLessThan(FIXP_SGL a_m, INT a_e, FIXP_SGL b_m, INT b_e) {
+ INT n;
+
+ n = fixnorm_S(a_m);
+ a_m <<= n;
+ a_e -= n;
+
+ n = fixnorm_S(b_m);
+ b_m <<= n;
+ b_e -= n;
+
+ if (a_m == (FIXP_SGL)0) a_e = b_e;
+ if (b_m == (FIXP_SGL)0) b_e = a_e;
+
if (a_e > b_e) {
return ((b_m >> fMin(a_e - b_e, FRACT_BITS - 1)) > a_m);
} else {
@@ -545,15 +571,20 @@ inline INT fMultIceil(FIXP_DBL a, INT b) {
m = fMultNorm(a, (FIXP_DBL)b, &m_e);
if (m_e < (INT)0) {
- if (m_e > (INT)-DFRACT_BITS) {
+ if (m_e > (INT) - (DFRACT_BITS - 1)) {
mi = (m >> (-m_e));
if ((LONG)m & ((1 << (-m_e)) - 1)) {
mi = mi + (FIXP_DBL)1;
}
} else {
- mi = (FIXP_DBL)1;
- if (m < (FIXP_DBL)0) {
- mi = (FIXP_DBL)0;
+ if (m > (FIXP_DBL)0) {
+ mi = (FIXP_DBL)1;
+ } else {
+ if ((m_e == -(DFRACT_BITS - 1)) && (m == (FIXP_DBL)MINVAL_DBL)) {
+ mi = (FIXP_DBL)-1;
+ } else {
+ mi = (FIXP_DBL)0;
+ }
}
}
} else {
@@ -744,7 +775,7 @@ FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
/**
* \brief return (base_m * 2^base_e) ^ N
- * \param base_m mantissa of the base
+ * \param base_m mantissa of the base. Must not be negative.
* \param base_e exponent of the base
* \param N power to be calculated of the base
* \param result_e pointer to a INT where the exponent of the result will be
diff --git a/libFDK/include/mdct.h b/libFDK/include/mdct.h
index 1382374..e7cf3ad 100644
--- a/libFDK/include/mdct.h
+++ b/libFDK/include/mdct.h
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -106,18 +106,16 @@ amm-info@iis.fraunhofer.de
#include "common_fix.h"
#define MDCT_OUT_HEADROOM 2 /* Output additional headroom */
-#define PCM_OUT_BITS SAMPLE_BITS
+
+#define PCM_OUT_BITS DFRACT_BITS
#define PCM_OUT_HEADROOM 8 /* Must have the same values as DMXH_HEADROOM */
-#define MDCT_OUTPUT_SCALE (-MDCT_OUT_HEADROOM + (DFRACT_BITS - SAMPLE_BITS))
+#define MDCT_OUTPUT_SCALE (-MDCT_OUT_HEADROOM + (DFRACT_BITS - PCM_OUT_BITS))
/* Refer to "Output word length" in ISO/IEC 14496-3:2008(E) 23.2.3.6 */
#define MDCT_OUTPUT_GAIN 16
-#if (MDCT_OUTPUT_SCALE >= 0)
-#define IMDCT_SCALE(x) SATURATE_RIGHT_SHIFT(x, MDCT_OUTPUT_SCALE, PCM_OUT_BITS)
-#else
-#define IMDCT_SCALE(x) SATURATE_LEFT_SHIFT(x, -MDCT_OUTPUT_SCALE, PCM_OUT_BITS)
-#endif
+#define IMDCT_SCALE(x, s) \
+ SATURATE_RIGHT_SHIFT((x), ((s) + MDCT_OUTPUT_SCALE), PCM_OUT_BITS)
#define IMDCT_SCALE_DBL(x) (FIXP_DBL)(x)
#define IMDCT_SCALE_DBL_LSH1(x) SATURATE_LEFT_SHIFT_ALT((x), 1, DFRACT_BITS)
diff --git a/libFDK/include/mips/abs_mips.h b/libFDK/include/mips/abs_mips.h
index dbb2063..5644bc0 100644
--- a/libFDK/include/mips/abs_mips.h
+++ b/libFDK/include/mips/abs_mips.h
@@ -107,7 +107,7 @@ amm-info@iis.fraunhofer.de
#if defined(__GNUC__) && defined(__mips__)
-#if defined(__mips_dsp)
+#if defined(__mips_dsp) && !defined(__mips16)
#define FUNCTION_fixabs_D
#define FUNCTION_fixabs_I
#define FUNCTION_fixabs_S
diff --git a/libFDK/include/mips/scale_mips.h b/libFDK/include/mips/scale_mips.h
index 3c141fc..882ef35 100644
--- a/libFDK/include/mips/scale_mips.h
+++ b/libFDK/include/mips/scale_mips.h
@@ -103,7 +103,7 @@ amm-info@iis.fraunhofer.de
#ifndef SCALE_MIPS_H
#define SCALE_MIPS_H
-#if defined(__mips_dsp)
+#if defined(__mips_dsp) && !defined(__mips16)
/*!
*
diff --git a/libFDK/include/qmf.h b/libFDK/include/qmf.h
index 609c6f1..78770b3 100644
--- a/libFDK/include/qmf.h
+++ b/libFDK/include/qmf.h
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -116,6 +116,7 @@ amm-info@iis.fraunhofer.de
#define FIXP_QAS FIXP_PCM
#define QAS_BITS SAMPLE_BITS
+#define INT_PCM_QMFIN INT_PCM
#define FIXP_QSS FIXP_DBL
#define QSS_BITS DFRACT_BITS
@@ -201,66 +202,70 @@ struct QMF_FILTER_BANK {
typedef struct QMF_FILTER_BANK *HANDLE_QMF_FILTER_BANK;
+int qmfInitAnalysisFilterBank(
+ HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
+ FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */
+ int noCols, /*!< Number of time slots */
+ int lsb, /*!< Number of lower bands */
+ int usb, /*!< Number of upper bands */
+ int no_channels, /*!< Number of critically sampled bands */
+ int flags); /*!< Flags */
+#if SAMPLE_BITS == 16
+
+int qmfInitAnalysisFilterBank(
+ HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
+ FIXP_DBL *pFilterStates, /*!< Pointer to filter state buffer */
+ int noCols, /*!< Number of time slots */
+ int lsb, /*!< Number of lower bands */
+ int usb, /*!< Number of upper bands */
+ int no_channels, /*!< Number of critically sampled bands */
+ int flags); /*!< Flags */
+#endif
+
void qmfAnalysisFiltering(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
- const LONG *timeIn, /*!< Time signal */
+ const INT_PCM *timeIn, /*!< Time signal */
const int timeIn_e, /*!< Exponent of audio data */
const int stride, /*!< Stride factor of audio data */
- FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
);
+#if SAMPLE_BITS == 16
void qmfAnalysisFiltering(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
- const INT_PCM *timeIn, /*!< Time signal */
+ const LONG *timeIn, /*!< Time signal */
const int timeIn_e, /*!< Exponent of audio data */
const int stride, /*!< Stride factor of audio data */
- FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
-);
-
-void qmfSynthesisFiltering(
- HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
- FIXP_DBL **QmfBufferReal, /*!< Pointer to real subband slots */
- FIXP_DBL **QmfBufferImag, /*!< Pointer to imag subband slots */
- const QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
- const int ov_len, /*!< Length of band overlap */
- INT_PCM *timeOut, /*!< Time signal */
- const INT stride, /*!< Stride factor of audio data */
- FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer. It must be
- aligned */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
);
-
-int qmfInitAnalysisFilterBank(
- HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
- FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */
- int noCols, /*!< Number of time slots */
- int lsb, /*!< Number of lower bands */
- int usb, /*!< Number of upper bands */
- int no_channels, /*!< Number of critically sampled bands */
- int flags); /*!< Flags */
+#endif
void qmfAnalysisFilteringSlot(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
FIXP_DBL *qmfReal, /*!< Low and High band, real */
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
- const LONG *timeIn, /*!< Pointer to input */
+ const INT_PCM *timeIn, /*!< Pointer to input */
const int stride, /*!< stride factor of input */
- FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
);
+#if SAMPLE_BITS == 16
void qmfAnalysisFilteringSlot(
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
FIXP_DBL *qmfReal, /*!< Low and High band, real */
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
- const INT_PCM *timeIn, /*!< Pointer to input */
+ const LONG *timeIn, /*!< Pointer to input */
const int stride, /*!< stride factor of input */
- FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
);
+#endif
+
int qmfInitSynthesisFilterBank(
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
FIXP_QSS *pFilterStates, /*!< Pointer to filter state buffer */
@@ -270,12 +275,46 @@ int qmfInitSynthesisFilterBank(
int no_channels, /*!< Number of critically sampled bands */
int flags); /*!< Flags */
+void qmfSynthesisFiltering(
+ HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
+ FIXP_DBL **QmfBufferReal, /*!< Pointer to real subband slots */
+ FIXP_DBL **QmfBufferImag, /*!< Pointer to imag subband slots */
+ const QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
+ const int ov_len, /*!< Length of band overlap */
+ INT_PCM *timeOut, /*!< Time signal */
+ const INT stride, /*!< Stride factor of audio data */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer. It must be
+ aligned */
+);
+#if SAMPLE_BITS == 16
+
+void qmfSynthesisFiltering(
+ HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
+ FIXP_DBL **QmfBufferReal, /*!< Pointer to real subband slots */
+ FIXP_DBL **QmfBufferImag, /*!< Pointer to imag subband slots */
+ const QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
+ const int ov_len, /*!< Length of band overlap */
+ LONG *timeOut, /*!< Time signal */
+ const int timeOut_e, /*!< Target exponent for timeOut */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
+);
+#endif
+
void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
const FIXP_DBL *realSlot,
const FIXP_DBL *imagSlot,
const int scaleFactorLowBand,
const int scaleFactorHighBand, INT_PCM *timeOut,
const int timeOut_e, FIXP_DBL *pWorkBuffer);
+#if SAMPLE_BITS == 16
+
+void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
+ const FIXP_DBL *realSlot,
+ const FIXP_DBL *imagSlot,
+ const int scaleFactorLowBand,
+ const int scaleFactorHighBand, LONG *timeOut,
+ const int timeOut_e, FIXP_DBL *pWorkBuffer);
+#endif
void qmfChangeOutScalefactor(
HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
@@ -291,11 +330,5 @@ void qmfChangeOutGain(
FIXP_DBL outputGain, /*!< New gain for output data (mantissa) */
int outputGainScale /*!< New gain for output data (exponent) */
);
-void qmfSynPrototypeFirSlot(
- HANDLE_QMF_FILTER_BANK qmf,
- FIXP_DBL *RESTRICT realSlot, /*!< Input: Pointer to real Slot */
- FIXP_DBL *RESTRICT imagSlot, /*!< Input: Pointer to imag Slot */
- INT_PCM *RESTRICT timeOut, /*!< Time domain data */
- const int timeOut_e);
#endif /*ifndef QMF_H */
diff --git a/libFDK/include/qmf_pcm.h b/libFDK/include/qmf_pcm.h
index f24e0cd..5da53db 100644
--- a/libFDK/include/qmf_pcm.h
+++ b/libFDK/include/qmf_pcm.h
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -402,4 +402,220 @@ void qmfSynthesisFiltering(
timeOut + (i * L * stride), stride, pWorkBuffer);
} /* no_col loop i */
}
+
+/*!
+ *
+ * \brief Create QMF filter bank instance
+ *
+ *
+ * \return 0 if successful
+ *
+ */
+int qmfInitAnalysisFilterBank(
+ HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */
+ FIXP_QAS *pFilterStates, /*!< Handle to filter states */
+ int noCols, /*!< Number of timeslots per frame */
+ int lsb, /*!< lower end of QMF */
+ int usb, /*!< upper end of QMF */
+ int no_channels, /*!< Number of channels (bands) */
+ int flags) /*!< Low Power flag */
+{
+ int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb,
+ no_channels, flags, 0);
+ if (!(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL)) {
+ FDKmemclear(h_Qmf->FilterStates,
+ (2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QAS));
+ }
+
+ FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb);
+
+ return err;
+}
+
+#ifndef FUNCTION_qmfAnaPrototypeFirSlot
+/*!
+ \brief Perform Analysis Prototype Filtering on a single slot of input data.
+*/
+static void qmfAnaPrototypeFirSlot(
+ FIXP_DBL *analysisBuffer,
+ INT no_channels, /*!< Number channels of analysis filter */
+ const FIXP_PFT *p_filter, INT p_stride, /*!< Stride of analysis filter */
+ FIXP_QAS *RESTRICT pFilterStates) {
+ INT k;
+
+ FIXP_DBL accu;
+ const FIXP_PFT *RESTRICT p_flt = p_filter;
+ FIXP_DBL *RESTRICT pData_0 = analysisBuffer + 2 * no_channels - 1;
+ FIXP_DBL *RESTRICT pData_1 = analysisBuffer;
+
+ FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates;
+ FIXP_QAS *RESTRICT sta_1 =
+ (FIXP_QAS *)pFilterStates + (2 * QMF_NO_POLY * no_channels) - 1;
+ INT pfltStep = QMF_NO_POLY * (p_stride);
+ INT staStep1 = no_channels << 1;
+ INT staStep2 = (no_channels << 3) - 1; /* Rewind one less */
+
+ /* FIR filters 127..64 0..63 */
+ for (k = 0; k < no_channels; k++) {
+ accu = fMultDiv2(p_flt[0], *sta_1);
+ sta_1 -= staStep1;
+ accu += fMultDiv2(p_flt[1], *sta_1);
+ sta_1 -= staStep1;
+ accu += fMultDiv2(p_flt[2], *sta_1);
+ sta_1 -= staStep1;
+ accu += fMultDiv2(p_flt[3], *sta_1);
+ sta_1 -= staStep1;
+ accu += fMultDiv2(p_flt[4], *sta_1);
+ *pData_1++ = (accu << 1);
+ sta_1 += staStep2;
+
+ p_flt += pfltStep;
+ accu = fMultDiv2(p_flt[0], *sta_0);
+ sta_0 += staStep1;
+ accu += fMultDiv2(p_flt[1], *sta_0);
+ sta_0 += staStep1;
+ accu += fMultDiv2(p_flt[2], *sta_0);
+ sta_0 += staStep1;
+ accu += fMultDiv2(p_flt[3], *sta_0);
+ sta_0 += staStep1;
+ accu += fMultDiv2(p_flt[4], *sta_0);
+ *pData_0-- = (accu << 1);
+ sta_0 -= staStep2;
+ }
+}
+#endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */
+
+#ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric
+/*!
+ \brief Perform Analysis Prototype Filtering on a single slot of input data.
+*/
+static void qmfAnaPrototypeFirSlot_NonSymmetric(
+ FIXP_DBL *analysisBuffer,
+ int no_channels, /*!< Number channels of analysis filter */
+ const FIXP_PFT *p_filter, int p_stride, /*!< Stride of analysis filter */
+ FIXP_QAS *RESTRICT pFilterStates) {
+ const FIXP_PFT *RESTRICT p_flt = p_filter;
+ int p, k;
+
+ for (k = 0; k < 2 * no_channels; k++) {
+ FIXP_DBL accu = (FIXP_DBL)0;
+
+ p_flt += QMF_NO_POLY * (p_stride - 1);
+
+ /*
+ Perform FIR-Filter
+ */
+ for (p = 0; p < QMF_NO_POLY; p++) {
+ accu += fMultDiv2(*p_flt++, pFilterStates[2 * no_channels * p]);
+ }
+ analysisBuffer[2 * no_channels - 1 - k] = (accu << 1);
+ pFilterStates++;
+ }
+}
+#endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */
+
+/*
+ * \brief Perform one QMF slot analysis of the time domain data of timeIn
+ * with specified stride and stores the real part of the subband
+ * samples in rSubband, and the imaginary part in iSubband
+ *
+ * Note: anaQmf->lsb can be greater than anaQmf->no_channels in case
+ * of implicit resampling (USAC with reduced 3/4 core frame length).
+ */
+void qmfAnalysisFilteringSlot(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
+ FIXP_DBL *qmfReal, /*!< Low and High band, real */
+ FIXP_DBL *qmfImag, /*!< Low and High band, imag */
+ const INT_PCM_QMFIN *RESTRICT timeIn, /*!< Pointer to input */
+ const int stride, /*!< stride factor of input */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
+) {
+ int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1);
+ /*
+ Feed time signal into oldest anaQmf->no_channels states
+ */
+ {
+ FIXP_QAS *FilterStatesAnaTmp = ((FIXP_QAS *)anaQmf->FilterStates) + offset;
+
+ /* Feed and scale actual time in slot */
+ for (int i = anaQmf->no_channels >> 1; i != 0; i--) {
+ /* Place INT_PCM value left aligned in scaledTimeIn */
+ *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
+ timeIn += stride;
+ *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
+ timeIn += stride;
+ }
+ }
+
+ if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
+ qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels,
+ anaQmf->p_filter, anaQmf->p_stride,
+ (FIXP_QAS *)anaQmf->FilterStates);
+ } else {
+ qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter,
+ anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates);
+ }
+
+ if (anaQmf->flags & QMF_FLAG_LP) {
+ if (anaQmf->flags & QMF_FLAG_CLDFB)
+ qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal);
+ else
+ qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal);
+
+ } else {
+ qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag);
+ }
+ /*
+ Shift filter states
+
+ Should be realized with modulo addressing on a DSP instead of a true buffer
+ shift
+ */
+ FDKmemmove(anaQmf->FilterStates,
+ (FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels,
+ offset * sizeof(FIXP_QAS));
+}
+
+/*!
+ *
+ * \brief Perform complex-valued subband filtering of the time domain
+ * data of timeIn and stores the real part of the subband
+ * samples in rAnalysis, and the imaginary part in iAnalysis
+ * The qmf coefficient table is symmetric. The symmetry is expoited by
+ * shrinking the coefficient table to half the size. The addressing mode
+ * takes care of the symmetries.
+ *
+ *
+ * \sa PolyphaseFiltering
+ */
+void qmfAnalysisFiltering(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
+ FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
+ FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
+ QMF_SCALE_FACTOR *scaleFactor,
+ const INT_PCM_QMFIN *timeIn, /*!< Time signal */
+ const int timeIn_e, const int stride,
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
+) {
+ int i;
+ int no_channels = anaQmf->no_channels;
+
+ scaleFactor->lb_scale =
+ -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e;
+ scaleFactor->lb_scale -= anaQmf->filterScale;
+
+ for (i = 0; i < anaQmf->no_col; i++) {
+ FIXP_DBL *qmfImagSlot = NULL;
+
+ if (!(anaQmf->flags & QMF_FLAG_LP)) {
+ qmfImagSlot = qmfImag[i];
+ }
+
+ qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride,
+ pWorkBuffer);
+
+ timeIn += no_channels * stride;
+
+ } /* no_col loop i */
+}
#endif /* QMF_PCM_H */
diff --git a/libFDK/include/scale.h b/libFDK/include/scale.h
index fcfc116..a58614e 100644
--- a/libFDK/include/scale.h
+++ b/libFDK/include/scale.h
@@ -129,15 +129,13 @@ void scaleCplxValues(FIXP_DBL *r_dst, FIXP_DBL *i_dst, const FIXP_DBL *r_src,
void scaleValuesWithFactor(FIXP_DBL *vector, FIXP_DBL factor, INT len,
INT scalefactor);
void scaleValuesSaturate(FIXP_DBL *vector, INT len, INT scalefactor);
-void scaleValuesSaturate(FIXP_DBL *dst, FIXP_DBL *src, INT len,
+void scaleValuesSaturate(FIXP_DBL *dst, const FIXP_DBL *src, INT len,
INT scalefactor);
-void scaleValuesSaturate(FIXP_SGL *dst, FIXP_DBL *src, INT len,
+void scaleValuesSaturate(FIXP_SGL *dst, const FIXP_DBL *src, INT len,
INT scalefactor);
-void scaleValuesSaturate(INT_PCM *dst, FIXP_DBL *src, INT len, INT scalefactor);
void scaleValuesSaturate(FIXP_SGL *vector, INT len, INT scalefactor);
-void scaleValuesSaturate(FIXP_SGL *dst, FIXP_SGL *src, INT len,
+void scaleValuesSaturate(FIXP_SGL *dst, const FIXP_SGL *src, INT len,
INT scalefactor);
-void scaleValuesSaturate(INT_PCM *dst, INT_PCM *src, INT len, INT scalefactor);
INT getScalefactorShort(const SHORT *vector, INT len);
INT getScalefactorPCM(const INT_PCM *vector, INT len, INT stride);
INT getScalefactor(const FIXP_DBL *vector, INT len);
@@ -241,31 +239,20 @@ inline void scaleValueInPlace(FIXP_DBL *value, /*!< Value */
#ifndef SATURATE_RIGHT_SHIFT
#define SATURATE_RIGHT_SHIFT(src, scale, dBits) \
- (((scale) >= 8*sizeof(LONG)) ? (LONG)0 : \
((((LONG)(src) >> (scale)) > (LONG)(((1U) << ((dBits)-1)) - 1)) \
? (LONG)(((1U) << ((dBits)-1)) - 1) \
: (((LONG)(src) >> (scale)) < ~((LONG)(((1U) << ((dBits)-1)) - 1))) \
? ~((LONG)(((1U) << ((dBits)-1)) - 1)) \
- : ((LONG)(src) >> (scale))))
-#endif
-
-#ifndef SATURATE_LEFT_MAX
-#define SATURATE_LEFT_MAX(src, dBits) \
- (((LONG)(src) > 0) \
- ? (LONG)(((1U) << ((dBits)-1)) - 1) \
- : ((LONG)(src) < 0) \
- ? ~((LONG)(((1U) << ((dBits)-1)) - 1)) \
- : (LONG)0)
+ : ((LONG)(src) >> (scale)))
#endif
#ifndef SATURATE_LEFT_SHIFT
#define SATURATE_LEFT_SHIFT(src, scale, dBits) \
- (((scale) >= 8*sizeof(LONG)) ? SATURATE_LEFT_MAX(src, dBits) : \
(((LONG)(src) > ((LONG)(((1U) << ((dBits)-1)) - 1) >> (scale))) \
? (LONG)(((1U) << ((dBits)-1)) - 1) \
: ((LONG)(src) < ~((LONG)(((1U) << ((dBits)-1)) - 1) >> (scale))) \
? ~((LONG)(((1U) << ((dBits)-1)) - 1)) \
- : ((LONG)(src) << (scale))))
+ : ((LONG)(src) << (scale)))
#endif
#ifndef SATURATE_SHIFT
diff --git a/libFDK/include/scramble.h b/libFDK/include/scramble.h
index f07ebed..e7cead9 100644
--- a/libFDK/include/scramble.h
+++ b/libFDK/include/scramble.h
@@ -108,7 +108,7 @@ amm-info@iis.fraunhofer.de
#if defined(__arm__)
#include "arm/scramble_arm.h"
-#elif defined(__mips__) && defined(__mips_dsp)
+#elif defined(__mips__) && defined(__mips_dsp) && !defined(__mips16)
#include "mips/scramble_mips.h"
#endif
diff --git a/libFDK/src/FDK_bitbuffer.cpp b/libFDK/src/FDK_bitbuffer.cpp
index 98905ea..9b7f5b8 100644
--- a/libFDK/src/FDK_bitbuffer.cpp
+++ b/libFDK/src/FDK_bitbuffer.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -368,7 +368,10 @@ void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf, const UCHAR *RESTRICT inputBuffer,
UINT bTotal = 0;
- UINT bToRead = (hBitBuf->bufBits - hBitBuf->ValidBits) >> 3;
+ UINT bToRead =
+ fMin(hBitBuf->bufBits,
+ (UINT)fMax(0, ((INT)hBitBuf->bufBits - (INT)hBitBuf->ValidBits))) >>
+ 3;
UINT noOfBytes =
fMin(bToRead,
*bytesValid); //(bToRead < *bytesValid) ? bToRead : *bytesValid ;
@@ -384,7 +387,7 @@ void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf, const UCHAR *RESTRICT inputBuffer,
bToRead * sizeof(UCHAR));
/* add noOfBits to number of valid bits in buffer */
- hBitBuf->ValidBits += bToRead << 3;
+ hBitBuf->ValidBits = (UINT)((INT)hBitBuf->ValidBits + (INT)(bToRead << 3));
bTotal += bToRead;
inputBuffer += bToRead;
diff --git a/libFDK/src/FDK_core.cpp b/libFDK/src/FDK_core.cpp
index 75ea8a2..48db17e 100644
--- a/libFDK/src/FDK_core.cpp
+++ b/libFDK/src/FDK_core.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -104,10 +104,10 @@ amm-info@iis.fraunhofer.de
/* FDK tools library info */
#define FDK_TOOLS_LIB_VL0 3
-#define FDK_TOOLS_LIB_VL1 0
+#define FDK_TOOLS_LIB_VL1 1
#define FDK_TOOLS_LIB_VL2 0
#define FDK_TOOLS_LIB_TITLE "FDK Tools"
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
#define FDK_TOOLS_LIB_BUILD_DATE ""
#define FDK_TOOLS_LIB_BUILD_TIME ""
#else
diff --git a/libFDK/src/FDK_decorrelate.cpp b/libFDK/src/FDK_decorrelate.cpp
index c5de79a..324983a 100644
--- a/libFDK/src/FDK_decorrelate.cpp
+++ b/libFDK/src/FDK_decorrelate.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -227,7 +227,7 @@ static inline int SpatialDecGetQmfBand(int paramBand, const UCHAR *tab) {
}
#define DUCKER_MAX_NRG_SCALE (24)
-#define DUCKER_HEADROOM_BITS (3)
+#define DUCKER_HEADROOM_BITS (2)
#define FILTER_SF (2)
@@ -606,10 +606,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
dataImagIn += start;
dataRealOut += start;
dataImagOut += start;
-#ifdef FUNCTION_DecorrFilterApplyPASS_func1
- DecorrFilterApplyPASS_func1(i, dataRealIn, dataImagIn, dataRealOut,
- dataImagOut, pDelayBuffer, offset);
-#else
do {
FIXP_DBL delay_re, delay_im, real, imag;
@@ -623,7 +619,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
*dataImagOut++ = delay_im;
pDelayBuffer += offset;
} while (--i != 0);
-#endif
}
}
@@ -1061,24 +1056,15 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
if (maxVal == FL2FXCONST_DBL(-1.0f)) {
-#ifdef FUNCTION_DuckerCalcEnergy_func2
- maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
- maxHybBand, maxHybridBand);
-#else
- FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
- for (qs = startHybBand; qs <= maxHybBand; qs++) {
- localMaxVal |= fAbs(inputReal[qs]);
- localMaxVal |= fAbs(inputImag[qs]);
- }
- for (; qs <= maxHybridBand; qs++) {
- localMaxVal |= fAbs(inputReal[qs]);
- }
- maxVal = localMaxVal;
-#endif
+ clz = fMin(getScalefactor(&inputReal[startHybBand],
+ fMax(0, maxHybridBand - startHybBand + 1)),
+ getScalefactor(&inputImag[startHybBand],
+ fMax(0, maxHybBand - startHybBand + 1)));
+ } else {
+ clz = CntLeadingZeros(maxVal) - 1;
}
- clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
- clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
+ clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
*nrgScale = (SCHAR)clz << 1;
/* Initialize pb since it would stay uninitialized for the case startHybBand
@@ -1086,9 +1072,10 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
pb = SpatialDecGetProcessingBand(maxHybBand, self->mapHybBands2ProcBands);
for (qs = startHybBand; qs <= maxHybBand; qs++) {
pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
- energy[pb] =
- fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
- fPow2Div2(inputImag[qs] << clz));
+ energy[pb] = SATURATE_LEFT_SHIFT(
+ (energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
+ (fPow2Div2(inputImag[qs] << clz) >> 1),
+ 1, DFRACT_BITS);
}
pb++;
@@ -1112,43 +1099,29 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
maxVal = inputMaxVal;
if (maxVal == FL2FXCONST_DBL(-1.0f)) {
-#ifdef FUNCTION_DuckerCalcEnergy_func2
- maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
- maxHybBand, maxHybridBand);
-#else
- FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
- for (qs = startHybBand; qs <= maxHybBand; qs++) {
- localMaxVal |= fAbs(inputReal[qs]);
- localMaxVal |= fAbs(inputImag[qs]);
- }
- for (; qs <= maxHybridBand; qs++) {
- localMaxVal |= fAbs(inputReal[qs]);
- }
- maxVal = localMaxVal;
-#endif
+ clz = fMin(getScalefactor(&inputReal[startHybBand],
+ fMax(0, maxHybridBand - startHybBand + 1)),
+ getScalefactor(&inputImag[startHybBand],
+ fMax(0, maxHybBand - startHybBand + 1)));
+ } else {
+ clz = CntLeadingZeros(maxVal) - 1;
}
- clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
- clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
+ clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
*nrgScale = (SCHAR)clz << 1;
-#ifdef FUNCTION_DuckerCalcEnergy_func4
- DuckerCalcEnergy_func4(inputReal, inputImag, energy,
- self->mapHybBands2ProcBands, clz, startHybBand,
- maxHybBand, maxHybridBand);
-#else
for (qs = startHybBand; qs <= maxHybBand; qs++) {
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
- energy[pb] =
- fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
- fPow2Div2(inputImag[qs] << clz));
+ energy[pb] = SATURATE_LEFT_SHIFT(
+ (energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
+ (fPow2Div2(inputImag[qs] << clz) >> 1),
+ 1, DFRACT_BITS);
}
for (; qs <= maxHybridBand; qs++) {
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
energy[pb] = fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz));
}
-#endif /* FUNCTION_DuckerCalcEnergy_func4 */
}
{
@@ -1295,10 +1268,6 @@ static INT DuckerApply(DUCKER_INSTANCE *const self,
}
}
-#ifdef FUNCTION_DuckerApply_func1
- qs = DuckerApply_func1(qs, hybBands, qs_next, outputReal, outputImag,
- duckGain);
-#else
/* general gain*output section */
if (qs < hybBands) { /* true for about 39% */
for (; qs < qs_next; qs++) { /* runs about 2 times */
@@ -1310,7 +1279,6 @@ static INT DuckerApply(DUCKER_INSTANCE *const self,
outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
}
}
-#endif
} /* pb */
self->headroomSmoothDirRevNrg =
diff --git a/libFDK/src/FDK_hybrid.cpp b/libFDK/src/FDK_hybrid.cpp
index b661f82..08d32a8 100644
--- a/libFDK/src/FDK_hybrid.cpp
+++ b/libFDK/src/FDK_hybrid.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -142,11 +142,12 @@ amm-info@iis.fraunhofer.de
} /* How to arrange the packed values. */
struct FDK_HYBRID_SETUP {
- UCHAR nrQmfBands; /*!< Number of QMF bands to be converted to hybrid. */
- UCHAR nHybBands[3]; /*!< Number of Hybrid bands generated by nrQmfBands. */
- SCHAR kHybrid[3]; /*!< Filter configuration of each QMF band. */
- UCHAR protoLen; /*!< Prototype filter length. */
- UCHAR filterDelay; /*!< Delay caused by hybrid filter. */
+ UCHAR nrQmfBands; /*!< Number of QMF bands to be converted to hybrid. */
+ UCHAR nHybBands[3]; /*!< Number of Hybrid bands generated by nrQmfBands. */
+ UCHAR synHybScale[3]; /*!< Headroom needed in hybrid synthesis filterbank. */
+ SCHAR kHybrid[3]; /*!< Filter configuration of each QMF band. */
+ UCHAR protoLen; /*!< Prototype filter length. */
+ UCHAR filterDelay; /*!< Delay caused by hybrid filter. */
const INT
*pReadIdxTable; /*!< Helper table to access input data ringbuffer. */
};
@@ -156,12 +157,12 @@ static const INT ringbuffIdxTab[2 * 13] = {0, 1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12};
-static const FDK_HYBRID_SETUP setup_3_16 = {3, {8, 4, 4}, {8, 4, 4},
- 13, (13 - 1) / 2, ringbuffIdxTab};
-static const FDK_HYBRID_SETUP setup_3_12 = {3, {8, 2, 2}, {8, 2, 2},
- 13, (13 - 1) / 2, ringbuffIdxTab};
-static const FDK_HYBRID_SETUP setup_3_10 = {3, {6, 2, 2}, {-8, -2, 2},
- 13, (13 - 1) / 2, ringbuffIdxTab};
+static const FDK_HYBRID_SETUP setup_3_16 = {
+ 3, {8, 4, 4}, {4, 3, 3}, {8, 4, 4}, 13, (13 - 1) / 2, ringbuffIdxTab};
+static const FDK_HYBRID_SETUP setup_3_12 = {
+ 3, {8, 2, 2}, {4, 2, 2}, {8, 2, 2}, 13, (13 - 1) / 2, ringbuffIdxTab};
+static const FDK_HYBRID_SETUP setup_3_10 = {
+ 3, {6, 2, 2}, {3, 2, 2}, {-8, -2, 2}, 13, (13 - 1) / 2, ringbuffIdxTab};
static const FIXP_HTP HybFilterCoef8[] = {
HTCP(0x10000000, 0x00000000), HTCP(0x0df26407, 0xfa391882),
@@ -477,17 +478,18 @@ void FDKhybridSynthesisApply(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,
*/
for (k = 0; k < nrQmfBandsLF; k++) {
const int nHybBands = hSynthesisHybFilter->pSetup->nHybBands[k];
+ const int scale = hSynthesisHybFilter->pSetup->synHybScale[k];
FIXP_DBL accu1 = FL2FXCONST_DBL(0.f);
FIXP_DBL accu2 = FL2FXCONST_DBL(0.f);
/* Perform hybrid filtering. */
for (n = 0; n < nHybBands; n++) {
- accu1 += pHybridReal[hybOffset + n];
- accu2 += pHybridImag[hybOffset + n];
+ accu1 += pHybridReal[hybOffset + n] >> scale;
+ accu2 += pHybridImag[hybOffset + n] >> scale;
}
- pQmfReal[k] = accu1;
- pQmfImag[k] = accu2;
+ pQmfReal[k] = SATURATE_LEFT_SHIFT(accu1, scale, DFRACT_BITS);
+ pQmfImag[k] = SATURATE_LEFT_SHIFT(accu2, scale, DFRACT_BITS);
hybOffset += nHybBands;
}
diff --git a/libFDK/src/FDK_qmf_domain.cpp b/libFDK/src/FDK_qmf_domain.cpp
index 3245deb..77c5ca2 100644
--- a/libFDK/src/FDK_qmf_domain.cpp
+++ b/libFDK/src/FDK_qmf_domain.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -106,35 +106,31 @@ amm-info@iis.fraunhofer.de
#include "common_fix.h"
#define WORKBUFFER1_TAG 0
-#define WORKBUFFER2_TAG 1
-
#define WORKBUFFER3_TAG 4
#define WORKBUFFER4_TAG 5
-#define WORKBUFFER5_TAG 6
#define WORKBUFFER6_TAG 7
+#define WORKBUFFER7_TAG 8
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL, QMF_WB_SECTION_SIZE,
SECT_DATA_L1, WORKBUFFER1_TAG)
-C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL, QMF_WB_SECTION_SIZE,
- SECT_DATA_L2, WORKBUFFER2_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL, QMF_WB_SECTION_SIZE,
SECT_DATA_L2, WORKBUFFER3_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL, QMF_WB_SECTION_SIZE,
SECT_DATA_L2, WORKBUFFER4_TAG)
-C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL, QMF_WB_SECTION_SIZE,
- SECT_DATA_L2, WORKBUFFER5_TAG)
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL, QMF_WB_SECTION_SIZE,
SECT_DATA_L2, WORKBUFFER6_TAG)
+C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL, QMF_WB_SECTION_SIZE,
+ SECT_DATA_L2, WORKBUFFER7_TAG)
/*! Analysis states buffer. <br>
Dimension: #((8) + (1)) */
-C_ALLOC_MEM2(AnaQmfStates, FIXP_QAS, 10 * QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS,
- ((8) + (1)))
+C_AALLOC_MEM2(AnaQmfStates, FIXP_DBL, 10 * QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS,
+ ((8) + (1)))
/*! Synthesis states buffer. <br>
Dimension: #((8) + (1)) */
-C_ALLOC_MEM2(SynQmfStates, FIXP_QSS, 9 * QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS,
- ((8) + (1)))
+C_AALLOC_MEM2(SynQmfStates, FIXP_QSS, 9 * QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS,
+ ((8) + (1)))
/*! Pointer to real qmf data for each time slot. <br>
Dimension: #((8) + (1)) */
@@ -156,18 +152,17 @@ C_AALLOC_MEM2(QmfOverlapBuffer, FIXP_DBL,
/*! Analysis states buffer. <br>
Dimension: #((8) + (1)) */
-C_ALLOC_MEM2(AnaQmfStates16, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_16,
- ((8) + (1)))
-
+C_AALLOC_MEM2(AnaQmfStates16, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_16,
+ ((8) + (1)))
/*! Analysis states buffer. <br>
Dimension: #((8) + (1)) */
-C_ALLOC_MEM2(AnaQmfStates24, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24,
- ((8) + (1)))
+C_AALLOC_MEM2(AnaQmfStates24, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24,
+ ((8) + (1)))
/*! Analysis states buffer. <br>
Dimension: #((8) + (1)) */
-C_ALLOC_MEM2(AnaQmfStates32, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32,
- ((8) + (1)))
+C_AALLOC_MEM2(AnaQmfStates32, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32,
+ ((8) + (1)))
/*! Pointer to real qmf data for each time slot. <br>
Dimension: #((8) + (1)) */
@@ -642,10 +637,10 @@ void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
if (pQmfOutImag == NULL) {
for (; b < fMin(lsb, stop_band); b++) {
- pQmfOutReal[b] = scaleValue(real[b], lb_sf);
+ pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf);
}
for (; b < fMin(usb, stop_band); b++) {
- pQmfOutReal[b] = scaleValue(real[b], hb_sf);
+ pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf);
}
for (; b < stop_band; b++) {
pQmfOutReal[b] = (FIXP_DBL)0;
@@ -653,12 +648,12 @@ void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
} else {
FDK_ASSERT(imag != NULL);
for (; b < fMin(lsb, stop_band); b++) {
- pQmfOutReal[b] = scaleValue(real[b], lb_sf);
- pQmfOutImag[b] = scaleValue(imag[b], lb_sf);
+ pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf);
+ pQmfOutImag[b] = scaleValueSaturate(imag[b], lb_sf);
}
for (; b < fMin(usb, stop_band); b++) {
- pQmfOutReal[b] = scaleValue(real[b], hb_sf);
- pQmfOutImag[b] = scaleValue(imag[b], hb_sf);
+ pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf);
+ pQmfOutImag[b] = scaleValueSaturate(imag[b], hb_sf);
}
for (; b < stop_band; b++) {
pQmfOutReal[b] = (FIXP_DBL)0;
@@ -950,7 +945,7 @@ QMF_DOMAIN_ERROR FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd) {
if ((size > 4 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[4] == NULL)) {
/* get work buffer of size QMF_WB_SECTION_SIZE */
- pWorkBuffer[4] = GetQmfWorkBufferCore5();
+ pWorkBuffer[4] = GetQmfWorkBufferCore7();
}
/* 8. distribute workbuffer over processing channels */
@@ -996,7 +991,7 @@ static void FDK_QmfDomain_FreeWorkBuffer(HANDLE_FDK_QMF_DOMAIN hqd) {
if (pWorkBuffer[1]) FreeQmfWorkBufferCore1(&pWorkBuffer[1]);
if (pWorkBuffer[2]) FreeQmfWorkBufferCore3(&pWorkBuffer[2]);
if (pWorkBuffer[3]) FreeQmfWorkBufferCore4(&pWorkBuffer[3]);
- if (pWorkBuffer[4]) FreeQmfWorkBufferCore5(&pWorkBuffer[4]);
+ if (pWorkBuffer[4]) FreeQmfWorkBufferCore7(&pWorkBuffer[4]);
}
void FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd) {
diff --git a/libFDK/src/dct.cpp b/libFDK/src/dct.cpp
index 776493e..bd26736 100644
--- a/libFDK/src/dct.cpp
+++ b/libFDK/src/dct.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -489,18 +489,18 @@ void dst_IV(FIXP_DBL *pDat, int L, int *pDat_e) {
for (i = 0; i < M - 1; i += 2, pDat_0 += 2, pDat_1 -= 2) {
FIXP_DBL accu1, accu2, accu3, accu4;
- accu1 = pDat_1[1];
- accu2 = -pDat_0[0];
- accu3 = pDat_0[1];
- accu4 = -pDat_1[0];
+ accu1 = pDat_1[1] >> 1;
+ accu2 = -(pDat_0[0] >> 1);
+ accu3 = pDat_0[1] >> 1;
+ accu4 = -(pDat_1[0] >> 1);
cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
- pDat_0[0] = accu2 >> 1;
- pDat_0[1] = accu1 >> 1;
- pDat_1[0] = accu4 >> 1;
- pDat_1[1] = -(accu3 >> 1);
+ pDat_0[0] = accu2;
+ pDat_0[1] = accu1;
+ pDat_1[0] = accu4;
+ pDat_1[1] = -accu3;
}
if (M & 1) {
FIXP_DBL accu1, accu2;
diff --git a/libFDK/src/fft_rad2.cpp b/libFDK/src/fft_rad2.cpp
index 27f3aa0..f457f8b 100644
--- a/libFDK/src/fft_rad2.cpp
+++ b/libFDK/src/fft_rad2.cpp
@@ -109,7 +109,7 @@ amm-info@iis.fraunhofer.de
#if defined(__arm__)
#include "arm/fft_rad2_arm.cpp"
-#elif defined(__GNUC__) && defined(__mips__) && defined(__mips_dsp)
+#elif defined(__GNUC__) && defined(__mips__) && defined(__mips_dsp) && !defined(__mips16)
#include "mips/fft_rad2_mips.cpp"
#endif
diff --git a/libFDK/src/fixpoint_math.cpp b/libFDK/src/fixpoint_math.cpp
index 6c656fa..1e26420 100644
--- a/libFDK/src/fixpoint_math.cpp
+++ b/libFDK/src/fixpoint_math.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -650,6 +650,12 @@ FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
INT ans_lg2_e, baselg2_e;
FIXP_DBL base_lg2, ans_lg2, result;
+ if (base_m <= (FIXP_DBL)0) {
+ result = (FIXP_DBL)0;
+ *result_e = 0;
+ return result;
+ }
+
/* Calc log2 of base */
base_lg2 = fLog2(base_m, base_e, &baselg2_e);
diff --git a/libFDK/src/mdct.cpp b/libFDK/src/mdct.cpp
index f5aa284..c864fa1 100644
--- a/libFDK/src/mdct.cpp
+++ b/libFDK/src/mdct.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -572,7 +572,7 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum,
*/
for (i = 0; i < hMdct->prev_nr; i++) {
FIXP_DBL x = -(*pOvl--);
- *pOut0 = IMDCT_SCALE_DBL(x + hMdct->pFacZir[i]);
+ *pOut0 = fAddSaturate(x, IMDCT_SCALE_DBL(hMdct->pFacZir[i]));
pOut0++;
}
hMdct->pFacZir = NULL;
@@ -681,7 +681,7 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum,
FIXP_DBL *pOut = pOut0 - fl / 2;
FDK_ASSERT(fl / 2 <= 128);
for (i = 0; i < fl / 2; i++) {
- pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
+ pOut[i] = fAddSaturate(pOut[i], IMDCT_SCALE_DBL(hMdct->pFacZir[i]));
}
hMdct->pFacZir = NULL;
}
diff --git a/libFDK/src/mips/scale_mips.cpp b/libFDK/src/mips/scale_mips.cpp
index 1a3d33c..ff295d9 100644
--- a/libFDK/src/mips/scale_mips.cpp
+++ b/libFDK/src/mips/scale_mips.cpp
@@ -100,7 +100,7 @@ amm-info@iis.fraunhofer.de
*******************************************************************************/
-#if defined(__mips_dsp)
+#if defined(__mips_dsp) && !defined(__mips16)
#ifndef FUNCTION_getScalefactor_DBL
#define FUNCTION_getScalefactor_DBL
diff --git a/libFDK/src/nlc_dec.cpp b/libFDK/src/nlc_dec.cpp
index 6e98ce0..8b2f97d 100644
--- a/libFDK/src/nlc_dec.cpp
+++ b/libFDK/src/nlc_dec.cpp
@@ -568,7 +568,7 @@ bail:
static ERROR_t huff_decode(HANDLE_FDK_BITSTREAM strm, SCHAR* out_data_1,
SCHAR* out_data_2, DATA_TYPE data_type,
DIFF_TYPE diff_type_1, DIFF_TYPE diff_type_2,
- int num_val, CODING_SCHEME* cdg_scheme, int ldMode) {
+ int num_val, int* cdg_scheme, int ldMode) {
ERROR_t err = HUFFDEC_OK;
DIFF_TYPE diff_type;
@@ -597,14 +597,14 @@ static ERROR_t huff_decode(HANDLE_FDK_BITSTREAM strm, SCHAR* out_data_1,
/* Coding scheme */
data = FDKreadBits(strm, 1);
- *cdg_scheme = (CODING_SCHEME)(data << PAIR_SHIFT);
+ *cdg_scheme = (data << PAIR_SHIFT);
if (*cdg_scheme >> PAIR_SHIFT == HUFF_2D) {
if ((out_data_1 != NULL) && (out_data_2 != NULL) && (ldMode == 0)) {
data = FDKreadBits(strm, 1);
- *cdg_scheme = (CODING_SCHEME)(*cdg_scheme | data);
+ *cdg_scheme = (*cdg_scheme | data);
} else {
- *cdg_scheme = (CODING_SCHEME)(*cdg_scheme | FREQ_PAIR);
+ *cdg_scheme = (*cdg_scheme | FREQ_PAIR);
}
}
@@ -843,7 +843,7 @@ ERROR_t EcDataPairDec(DECODER_TYPE DECODER, HANDLE_FDK_BITSTREAM strm,
SCHAR* pDataVec[2] = {NULL, NULL};
DIFF_TYPE diff_type[2] = {DIFF_FREQ, DIFF_FREQ};
- CODING_SCHEME cdg_scheme = HUFF_1D;
+ int cdg_scheme = HUFF_1D;
DIRECTION direction = BACKWARDS;
switch (data_type) {
diff --git a/libFDK/src/qmf.cpp b/libFDK/src/qmf.cpp
index 6fca043..440bec2 100644
--- a/libFDK/src/qmf.cpp
+++ b/libFDK/src/qmf.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -147,88 +147,6 @@ amm-info@iis.fraunhofer.de
/* moved to qmf_pcm.h: -> qmfSynPrototypeFirSlot_NonSymmetric */
/* moved to qmf_pcm.h: -> qmfSynthesisFilteringSlot */
-#ifndef FUNCTION_qmfAnaPrototypeFirSlot
-/*!
- \brief Perform Analysis Prototype Filtering on a single slot of input data.
-*/
-static void qmfAnaPrototypeFirSlot(
- FIXP_DBL *analysisBuffer,
- INT no_channels, /*!< Number channels of analysis filter */
- const FIXP_PFT *p_filter, INT p_stride, /*!< Stride of analysis filter */
- FIXP_QAS *RESTRICT pFilterStates) {
- INT k;
-
- FIXP_DBL accu;
- const FIXP_PFT *RESTRICT p_flt = p_filter;
- FIXP_DBL *RESTRICT pData_0 = analysisBuffer + 2 * no_channels - 1;
- FIXP_DBL *RESTRICT pData_1 = analysisBuffer;
-
- FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates;
- FIXP_QAS *RESTRICT sta_1 =
- (FIXP_QAS *)pFilterStates + (2 * QMF_NO_POLY * no_channels) - 1;
- INT pfltStep = QMF_NO_POLY * (p_stride);
- INT staStep1 = no_channels << 1;
- INT staStep2 = (no_channels << 3) - 1; /* Rewind one less */
-
- /* FIR filters 127..64 0..63 */
- for (k = 0; k < no_channels; k++) {
- accu = fMultDiv2(p_flt[0], *sta_1);
- sta_1 -= staStep1;
- accu += fMultDiv2(p_flt[1], *sta_1);
- sta_1 -= staStep1;
- accu += fMultDiv2(p_flt[2], *sta_1);
- sta_1 -= staStep1;
- accu += fMultDiv2(p_flt[3], *sta_1);
- sta_1 -= staStep1;
- accu += fMultDiv2(p_flt[4], *sta_1);
- *pData_1++ = (accu << 1);
- sta_1 += staStep2;
-
- p_flt += pfltStep;
- accu = fMultDiv2(p_flt[0], *sta_0);
- sta_0 += staStep1;
- accu += fMultDiv2(p_flt[1], *sta_0);
- sta_0 += staStep1;
- accu += fMultDiv2(p_flt[2], *sta_0);
- sta_0 += staStep1;
- accu += fMultDiv2(p_flt[3], *sta_0);
- sta_0 += staStep1;
- accu += fMultDiv2(p_flt[4], *sta_0);
- *pData_0-- = (accu << 1);
- sta_0 -= staStep2;
- }
-}
-#endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */
-
-#ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric
-/*!
- \brief Perform Analysis Prototype Filtering on a single slot of input data.
-*/
-static void qmfAnaPrototypeFirSlot_NonSymmetric(
- FIXP_DBL *analysisBuffer,
- int no_channels, /*!< Number channels of analysis filter */
- const FIXP_PFT *p_filter, int p_stride, /*!< Stride of analysis filter */
- FIXP_QAS *RESTRICT pFilterStates) {
- const FIXP_PFT *RESTRICT p_flt = p_filter;
- int p, k;
-
- for (k = 0; k < 2 * no_channels; k++) {
- FIXP_DBL accu = (FIXP_DBL)0;
-
- p_flt += QMF_NO_POLY * (p_stride - 1);
-
- /*
- Perform FIR-Filter
- */
- for (p = 0; p < QMF_NO_POLY; p++) {
- accu += fMultDiv2(*p_flt++, pFilterStates[2 * no_channels * p]);
- }
- analysisBuffer[2 * no_channels - 1 - k] = (accu << 1);
- pFilterStates++;
- }
-}
-#endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */
-
/*!
*
* \brief Perform real-valued forward modulation of the time domain
@@ -244,7 +162,7 @@ static void qmfForwardModulationLP_even(
int i;
int L = anaQmf->no_channels;
int M = L >> 1;
- int scale;
+ int scale = 0;
FIXP_DBL accu;
const FIXP_DBL *timeInTmp1 = (FIXP_DBL *)&timeIn[3 * M];
@@ -381,211 +299,6 @@ static void qmfForwardModulationHQ(
}
#endif /* FUNCTION_qmfForwardModulationHQ */
-/*
- * \brief Perform one QMF slot analysis of the time domain data of timeIn
- * with specified stride and stores the real part of the subband
- * samples in rSubband, and the imaginary part in iSubband
- *
- * Note: anaQmf->lsb can be greater than anaQmf->no_channels in case
- * of implicit resampling (USAC with reduced 3/4 core frame length).
- */
-#if (SAMPLE_BITS != DFRACT_BITS) && (QAS_BITS == DFRACT_BITS)
-void qmfAnalysisFilteringSlot(
- HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
- FIXP_DBL *qmfReal, /*!< Low and High band, real */
- FIXP_DBL *qmfImag, /*!< Low and High band, imag */
- const LONG *RESTRICT timeIn, /*!< Pointer to input */
- const int stride, /*!< stride factor of input */
- FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
-) {
- int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1);
- /*
- Feed time signal into oldest anaQmf->no_channels states
- */
- {
- FIXP_DBL *FilterStatesAnaTmp = ((FIXP_DBL *)anaQmf->FilterStates) + offset;
-
- /* Feed and scale actual time in slot */
- for (int i = anaQmf->no_channels >> 1; i != 0; i--) {
- /* Place INT_PCM value left aligned in scaledTimeIn */
-
- *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
- timeIn += stride;
- *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
- timeIn += stride;
- }
- }
-
- if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
- qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels,
- anaQmf->p_filter, anaQmf->p_stride,
- (FIXP_QAS *)anaQmf->FilterStates);
- } else {
- qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter,
- anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates);
- }
-
- if (anaQmf->flags & QMF_FLAG_LP) {
- if (anaQmf->flags & QMF_FLAG_CLDFB)
- qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal);
- else
- qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal);
-
- } else {
- qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag);
- }
- /*
- Shift filter states
-
- Should be realized with modulo adressing on a DSP instead of a true buffer
- shift
- */
- FDKmemmove(anaQmf->FilterStates,
- (FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels,
- offset * sizeof(FIXP_QAS));
-}
-#endif
-
-void qmfAnalysisFilteringSlot(
- HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
- FIXP_DBL *qmfReal, /*!< Low and High band, real */
- FIXP_DBL *qmfImag, /*!< Low and High band, imag */
- const INT_PCM *RESTRICT timeIn, /*!< Pointer to input */
- const int stride, /*!< stride factor of input */
- FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
-) {
- int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1);
- /*
- Feed time signal into oldest anaQmf->no_channels states
- */
- {
- FIXP_QAS *FilterStatesAnaTmp = ((FIXP_QAS *)anaQmf->FilterStates) + offset;
-
- /* Feed and scale actual time in slot */
- for (int i = anaQmf->no_channels >> 1; i != 0; i--) {
- /* Place INT_PCM value left aligned in scaledTimeIn */
-#if (QAS_BITS == SAMPLE_BITS)
- *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
- timeIn += stride;
- *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
- timeIn += stride;
-#elif (QAS_BITS > SAMPLE_BITS)
- *FilterStatesAnaTmp++ = ((FIXP_QAS)*timeIn) << (QAS_BITS - SAMPLE_BITS);
- timeIn += stride;
- *FilterStatesAnaTmp++ = ((FIXP_QAS)*timeIn) << (QAS_BITS - SAMPLE_BITS);
- timeIn += stride;
-#else
- *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn) >> (SAMPLE_BITS - QAS_BITS));
- timeIn += stride;
- *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn) >> (SAMPLE_BITS - QAS_BITS));
- timeIn += stride;
-#endif
- }
- }
-
- if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
- qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels,
- anaQmf->p_filter, anaQmf->p_stride,
- (FIXP_QAS *)anaQmf->FilterStates);
- } else {
- qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter,
- anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates);
- }
-
- if (anaQmf->flags & QMF_FLAG_LP) {
- if (anaQmf->flags & QMF_FLAG_CLDFB)
- qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal);
- else
- qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal);
-
- } else {
- qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag);
- }
- /*
- Shift filter states
-
- Should be realized with modulo adressing on a DSP instead of a true buffer
- shift
- */
- FDKmemmove(anaQmf->FilterStates,
- (FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels,
- offset * sizeof(FIXP_QAS));
-}
-
-/*!
- *
- * \brief Perform complex-valued subband filtering of the time domain
- * data of timeIn and stores the real part of the subband
- * samples in rAnalysis, and the imaginary part in iAnalysis
- * The qmf coefficient table is symmetric. The symmetry is expoited by
- * shrinking the coefficient table to half the size. The addressing mode
- * takes care of the symmetries.
- *
- *
- * \sa PolyphaseFiltering
- */
-#if (SAMPLE_BITS != DFRACT_BITS) && (QAS_BITS == DFRACT_BITS)
-void qmfAnalysisFiltering(
- HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
- FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
- FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
- QMF_SCALE_FACTOR *scaleFactor, const LONG *timeIn, /*!< Time signal */
- const int timeIn_e, const int stride,
- FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
-) {
- int i;
- int no_channels = anaQmf->no_channels;
-
- scaleFactor->lb_scale =
- -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e;
- scaleFactor->lb_scale -= anaQmf->filterScale;
-
- for (i = 0; i < anaQmf->no_col; i++) {
- FIXP_DBL *qmfImagSlot = NULL;
-
- if (!(anaQmf->flags & QMF_FLAG_LP)) {
- qmfImagSlot = qmfImag[i];
- }
-
- qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride,
- pWorkBuffer);
-
- timeIn += no_channels * stride;
-
- } /* no_col loop i */
-}
-#endif
-
-void qmfAnalysisFiltering(
- HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
- FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
- FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
- QMF_SCALE_FACTOR *scaleFactor, const INT_PCM *timeIn, /*!< Time signal */
- const int timeIn_e, const int stride,
- FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
-) {
- int i;
- int no_channels = anaQmf->no_channels;
-
- scaleFactor->lb_scale =
- -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e;
- scaleFactor->lb_scale -= anaQmf->filterScale;
-
- for (i = 0; i < anaQmf->no_col; i++) {
- FIXP_DBL *qmfImagSlot = NULL;
-
- if (!(anaQmf->flags & QMF_FLAG_LP)) {
- qmfImagSlot = qmfImag[i];
- }
-
- qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride,
- pWorkBuffer);
-
- timeIn += no_channels * stride;
-
- } /* no_col loop i */
-}
-
/*!
*
* \brief Perform low power inverse modulation of the subband
@@ -603,15 +316,15 @@ inline static void qmfInverseModulationLP_even(
int i;
int L = synQmf->no_channels;
int M = L >> 1;
- int scale;
+ int scale = 0;
FIXP_DBL tmp;
FIXP_DBL *RESTRICT tReal = pTimeOut;
FIXP_DBL *RESTRICT tImag = pTimeOut + L;
/* Move input to output vector with offset */
- scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand);
- scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
- synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
+ scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb, scaleFactorLowBand);
+ scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
+ synQmf->usb - synQmf->lsb, scaleFactorHighBand);
FDKmemclear(&tReal[0 + synQmf->usb], (L - synQmf->usb) * sizeof(FIXP_DBL));
/* Dct type-2 transform */
@@ -662,9 +375,9 @@ inline static void qmfInverseModulationLP_odd(
int shift = 0;
/* Move input to output vector with offset */
- scaleValues(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
- scaleValues(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
- synQmf->usb - synQmf->lsb, scaleFactorHighBand);
+ scaleValuesSaturate(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
+ scaleValuesSaturate(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
+ synQmf->usb - synQmf->lsb, scaleFactorHighBand);
FDKmemclear(pTimeOut + M + synQmf->usb, (L - synQmf->usb) * sizeof(FIXP_DBL));
dct_IV(pTimeOut + M, L, &shift);
@@ -698,26 +411,27 @@ inline static void qmfInverseModulationHQ(
FIXP_DBL *RESTRICT tImag = pWorkBuffer + L;
if (synQmf->flags & QMF_FLAG_CLDFB) {
- for (i = 0; i < synQmf->lsb; i++) {
- cplxMult(&tImag[i], &tReal[i], scaleValue(qmfImag[i], scaleFactorLowBand),
- scaleValue(qmfReal[i], scaleFactorLowBand), synQmf->t_cos[i],
- synQmf->t_sin[i]);
- }
- for (; i < synQmf->usb; i++) {
- cplxMult(&tImag[i], &tReal[i],
- scaleValue(qmfImag[i], scaleFactorHighBand),
- scaleValue(qmfReal[i], scaleFactorHighBand), synQmf->t_cos[i],
- synQmf->t_sin[i]);
+ for (i = 0; i < synQmf->usb; i++) {
+ cplxMultDiv2(&tImag[i], &tReal[i], qmfImag[i], qmfReal[i],
+ synQmf->t_cos[i], synQmf->t_sin[i]);
}
+ scaleValuesSaturate(&tReal[0], synQmf->lsb, scaleFactorLowBand + 1);
+ scaleValuesSaturate(&tReal[0 + synQmf->lsb], synQmf->usb - synQmf->lsb,
+ scaleFactorHighBand + 1);
+ scaleValuesSaturate(&tImag[0], synQmf->lsb, scaleFactorLowBand + 1);
+ scaleValuesSaturate(&tImag[0 + synQmf->lsb], synQmf->usb - synQmf->lsb,
+ scaleFactorHighBand + 1);
}
if ((synQmf->flags & QMF_FLAG_CLDFB) == 0) {
- scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand);
- scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
- synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
- scaleValues(&tImag[0], &qmfImag[0], synQmf->lsb, (int)scaleFactorLowBand);
- scaleValues(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
- synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
+ scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb,
+ scaleFactorLowBand);
+ scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
+ synQmf->usb - synQmf->lsb, scaleFactorHighBand);
+ scaleValuesSaturate(&tImag[0], &qmfImag[0], synQmf->lsb,
+ scaleFactorLowBand);
+ scaleValuesSaturate(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
+ synQmf->usb - synQmf->lsb, scaleFactorHighBand);
}
FDKmemclear(&tReal[synQmf->usb],
@@ -1004,35 +718,6 @@ static inline void qmfAdaptFilterStates(
* \return 0 if succesful
*
*/
-int qmfInitAnalysisFilterBank(
- HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */
- FIXP_QAS *pFilterStates, /*!< Handle to filter states */
- int noCols, /*!< Number of timeslots per frame */
- int lsb, /*!< lower end of QMF */
- int usb, /*!< upper end of QMF */
- int no_channels, /*!< Number of channels (bands) */
- int flags) /*!< Low Power flag */
-{
- int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb,
- no_channels, flags, 0);
- if (!(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL)) {
- FDKmemclear(h_Qmf->FilterStates,
- (2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QAS));
- }
-
- FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb);
-
- return err;
-}
-
-/*!
- *
- * \brief Create QMF filter bank instance
- *
- *
- * \return 0 if succesful
- *
- */
int qmfInitSynthesisFilterBank(
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */
FIXP_QSS *pFilterStates, /*!< Handle to filter states */
@@ -1128,8 +813,21 @@ void qmfChangeOutGain(
synQmf->outGain_e = outputGainScale;
}
-/* When QMF_16IN_32OUT is set, synthesis functions for 16 and 32 bit parallel
- * output is compiled */
#define INT_PCM_QMFOUT INT_PCM
#define SAMPLE_BITS_QMFOUT SAMPLE_BITS
#include "qmf_pcm.h"
+#if SAMPLE_BITS == 16
+ /* also create a 32 bit output version */
+#undef INT_PCM_QMFOUT
+#undef SAMPLE_BITS_QMFOUT
+#undef QMF_PCM_H
+#undef FIXP_QAS
+#undef QAS_BITS
+#undef INT_PCM_QMFIN
+#define INT_PCM_QMFOUT LONG
+#define SAMPLE_BITS_QMFOUT 32
+#define FIXP_QAS FIXP_DBL
+#define QAS_BITS 32
+#define INT_PCM_QMFIN LONG
+#include "qmf_pcm.h"
+#endif
diff --git a/libFDK/src/scale.cpp b/libFDK/src/scale.cpp
index 24a8a5b..6192170 100644
--- a/libFDK/src/scale.cpp
+++ b/libFDK/src/scale.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -250,10 +250,10 @@ void scaleValuesSaturate(FIXP_DBL *vector, /*!< Vector */
*/
#define FUNCTION_scaleValuesSaturate_DBL_DBL
SCALE_INLINE
-void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
- FIXP_DBL *src, /*!< Input */
- INT len, /*!< Length */
- INT scalefactor /*!< Scalefactor */
+void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
+ const FIXP_DBL *src, /*!< Input */
+ INT len, /*!< Length */
+ INT scalefactor /*!< Scalefactor */
) {
INT i;
@@ -285,10 +285,10 @@ void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
*/
#define FUNCTION_scaleValuesSaturate_SGL_DBL
SCALE_INLINE
-void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
- FIXP_DBL *src, /*!< Input */
- INT len, /*!< Length */
- INT scalefactor) /*!< Scalefactor */
+void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
+ const FIXP_DBL *src, /*!< Input */
+ INT len, /*!< Length */
+ INT scalefactor) /*!< Scalefactor */
{
INT i;
scalefactor = fixmax_I(fixmin_I(scalefactor, (INT)DFRACT_BITS - 1),
@@ -345,10 +345,10 @@ void scaleValuesSaturate(FIXP_SGL *vector, /*!< Vector */
*/
#define FUNCTION_scaleValuesSaturate_SGL_SGL
SCALE_INLINE
-void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
- FIXP_SGL *src, /*!< Input */
- INT len, /*!< Length */
- INT scalefactor /*!< Scalefactor */
+void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
+ const FIXP_SGL *src, /*!< Input */
+ INT len, /*!< Length */
+ INT scalefactor /*!< Scalefactor */
) {
INT i;