aboutsummaryrefslogtreecommitdiffstats
path: root/libFDK/include
diff options
context:
space:
mode:
Diffstat (limited to 'libFDK/include')
-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
9 files changed, 344 insertions, 85 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