aboutsummaryrefslogtreecommitdiffstats
path: root/libPCMutils
diff options
context:
space:
mode:
authorMartin Storsjo <martin@martin.st>2020-11-17 12:38:51 +0200
committerMartin Storsjo <martin@martin.st>2020-11-17 12:38:51 +0200
commitc7a3808a2fd18bb4dad24d281cbb862b241806a9 (patch)
tree2cea66fef9961cd71efc817fed7e857ef27099b0 /libPCMutils
parentd23a21ab427da642c8f32bb0659ae63a86f98e96 (diff)
parentf4adff7fbb0968a13fd5077ea3df734870aef3cf (diff)
downloadfdk-aac-c7a3808a2fd18bb4dad24d281cbb862b241806a9.tar.gz
fdk-aac-c7a3808a2fd18bb4dad24d281cbb862b241806a9.tar.bz2
fdk-aac-c7a3808a2fd18bb4dad24d281cbb862b241806a9.zip
Merge remote-tracking branch 'aosp/master'
Diffstat (limited to 'libPCMutils')
-rw-r--r--libPCMutils/include/limiter.h36
-rw-r--r--libPCMutils/src/limiter.cpp122
-rw-r--r--libPCMutils/src/version.h6
3 files changed, 66 insertions, 98 deletions
diff --git a/libPCMutils/include/limiter.h b/libPCMutils/include/limiter.h
index fab7226..419e891 100644
--- a/libPCMutils/include/limiter.h
+++ b/libPCMutils/include/limiter.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
@@ -109,8 +109,6 @@ amm-info@iis.fraunhofer.de
#define TDL_ATTACK_DEFAULT_MS (15) /* default attack time in ms */
#define TDL_RELEASE_DEFAULT_MS (50) /* default release time in ms */
-#define TDL_GAIN_SCALING (15) /* scaling of gain value. */
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -128,10 +126,7 @@ struct TDLimiter {
unsigned int maxBufIdx, delayBufIdx;
FIXP_DBL smoothState0;
FIXP_DBL minGain;
-
- FIXP_DBL additionalGainPrev;
- FIXP_DBL additionalGainFilterState;
- FIXP_DBL additionalGainFilterState1;
+ INT scaling;
};
typedef enum {
@@ -255,27 +250,16 @@ TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter,
/******************************************************************************
* pcmLimiter_Apply *
- * limiter: limiter handle *
- * pGain : pointer to gains to be applied to the signal before limiting, *
- * which are downscaled by TDL_GAIN_SCALING bit. *
- * These gains are delayed by gain_delay, and smoothed. *
- * Smoothing is done by a butterworth lowpass filter with a cutoff *
- * frequency which is fixed with respect to the sampling rate. *
- * It is a substitute for the smoothing due to windowing and *
- * overlap/add, if a gain is applied in frequency domain. *
- * gain_scale: pointer to scaling exponents to be applied to the signal before *
- * limiting, without delay and without smoothing *
- * gain_size: number of elements in pGain, currently restricted to 1 *
- * gain_delay: delay [samples] with which the gains in pGain shall be applied *
- * gain_delay <= nSamples *
- * samples: input/output buffer containing interleaved samples *
- * precision of output will be DFRACT_BITS-TDL_GAIN_SCALING bits *
- * nSamples: number of samples per channel *
+ * limiter: limiter handle *
+ * samplesIn: pointer to input buffer containing interleaved samples *
+ * samplesOut: pointer to output buffer containing interleaved samples *
+ * pGainPerSample: pointer to gains for each sample *
+ * scaling: scaling of output samples *
+ * nSamples: number of samples per channel *
* returns: error code *
******************************************************************************/
TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
- INT_PCM* samplesOut, FIXP_DBL* pGain,
- const INT* gain_scale, const UINT gain_size,
- const UINT gain_delay, const UINT nSamples);
+ INT_PCM* samplesOut, FIXP_DBL* pGainPerSample,
+ const INT scaling, const UINT nSamples);
#endif /* #ifndef LIMITER_H */
diff --git a/libPCMutils/src/limiter.cpp b/libPCMutils/src/limiter.cpp
index a799a51..598dc0c 100644
--- a/libPCMutils/src/limiter.cpp
+++ b/libPCMutils/src/limiter.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
@@ -152,7 +152,7 @@ TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs,
limiter->attack = attack;
limiter->attackConst = attackConst;
limiter->releaseConst = releaseConst;
- limiter->threshold = threshold >> TDL_GAIN_SCALING;
+ limiter->threshold = threshold;
limiter->channels = maxChannels;
limiter->maxChannels = maxChannels;
limiter->sampleRate = maxSampleRate;
@@ -165,18 +165,13 @@ TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs,
/* apply limiter */
TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
- INT_PCM* samplesOut, FIXP_DBL* RESTRICT pGain,
- const INT* RESTRICT gain_scale,
- const UINT gain_size, const UINT gain_delay,
- const UINT nSamples) {
+ INT_PCM* samplesOut, FIXP_DBL* pGainPerSample,
+ const INT scaling, const UINT nSamples) {
unsigned int i, j;
- FIXP_DBL tmp1;
FIXP_DBL tmp2;
- FIXP_DBL tmp, old, gain, additionalGain = 0, additionalGainUnfiltered;
+ FIXP_DBL tmp, old, gain, additionalGain = 0;
FIXP_DBL minGain = FL2FXCONST_DBL(1.0f / (1 << 1));
-
- FDK_ASSERT(gain_size == 1);
- FDK_ASSERT(gain_delay <= nSamples);
+ UINT additionalGainAvailable = 1;
if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
@@ -185,7 +180,7 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
unsigned int attack = limiter->attack;
FIXP_DBL attackConst = limiter->attackConst;
FIXP_DBL releaseConst = limiter->releaseConst;
- FIXP_DBL threshold = limiter->threshold;
+ FIXP_DBL threshold = limiter->threshold >> scaling;
FIXP_DBL max = limiter->max;
FIXP_DBL* maxBuf = limiter->maxBuf;
@@ -195,55 +190,34 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
unsigned int delayBufIdx = limiter->delayBufIdx;
FIXP_DBL smoothState0 = limiter->smoothState0;
- FIXP_DBL additionalGainSmoothState = limiter->additionalGainFilterState;
- FIXP_DBL additionalGainSmoothState1 = limiter->additionalGainFilterState1;
- if (!gain_delay) {
- additionalGain = pGain[0];
- if (gain_scale[0] > 0) {
- additionalGain <<= gain_scale[0];
- } else {
- additionalGain >>= -gain_scale[0];
- }
+ if (limiter->scaling != scaling) {
+ scaleValuesSaturate(delayBuf, attack * channels,
+ limiter->scaling - scaling);
+ scaleValuesSaturate(maxBuf, attack + 1, limiter->scaling - scaling);
+ max = scaleValueSaturate(max, limiter->scaling - scaling);
+ limiter->scaling = scaling;
}
- for (i = 0; i < nSamples; i++) {
- if (gain_delay) {
- if (i < gain_delay) {
- additionalGainUnfiltered = limiter->additionalGainPrev;
- } else {
- additionalGainUnfiltered = pGain[0];
- }
+ if (pGainPerSample == NULL) {
+ additionalGainAvailable = 0;
+ }
- /* Smooth additionalGain */
- /* [b,a] = butter(1, 0.01) */
- static const FIXP_SGL b[] = {FL2FXCONST_SGL(0.015466 * 2.0),
- FL2FXCONST_SGL(0.015466 * 2.0)};
- static const FIXP_SGL a[] = {(FIXP_SGL)MAXVAL_SGL,
- FL2FXCONST_SGL(-0.96907)};
- additionalGain = -fMult(additionalGainSmoothState, a[1]) +
- fMultDiv2(additionalGainUnfiltered, b[0]) +
- fMultDiv2(additionalGainSmoothState1, b[1]);
- additionalGainSmoothState1 = additionalGainUnfiltered;
- additionalGainSmoothState = additionalGain;
-
- /* Apply the additional scaling that has no delay and no smoothing */
- if (gain_scale[0] > 0) {
- additionalGain <<= gain_scale[0];
- } else {
- additionalGain >>= -gain_scale[0];
- }
- }
+ for (i = 0; i < nSamples; i++) {
/* get maximum absolute sample value of all channels, including the
* additional gain. */
- tmp1 = (FIXP_DBL)0;
+ tmp = (FIXP_DBL)0;
for (j = 0; j < channels; j++) {
tmp2 = PCM_LIM2FIXP_DBL(samplesIn[j]);
- tmp2 = fAbs(tmp2);
- tmp2 = FIXP_DBL(INT(tmp2) ^ INT((tmp2 >> (SAMPLE_BITS_LIM - 1))));
- tmp1 = fMax(tmp1, tmp2);
+ tmp2 =
+ (tmp2 == (FIXP_DBL)MINVAL_DBL) ? (FIXP_DBL)MAXVAL_DBL : fAbs(tmp2);
+ tmp = fMax(tmp, tmp2);
+ }
+
+ if (additionalGainAvailable) {
+ additionalGain = pGainPerSample[i];
+ tmp = fMult(tmp, additionalGain);
}
- tmp = fMult(tmp1, additionalGain);
/* set threshold as lower border to save calculations in running maximum
* algorithm */
@@ -314,22 +288,42 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
/* lookahead delay, apply gain */
for (j = 0; j < channels; j++) {
tmp = p_delayBuf[j];
- p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
+
+ if (additionalGainAvailable) {
+ p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
+ } else {
+ p_delayBuf[j] = PCM_LIM2FIXP_DBL(samplesIn[j]);
+ }
/* Apply gain to delayed signal */
tmp = fMultDiv2(tmp, gain);
-
+#if (SAMPLE_BITS == DFRACT_BITS)
+ samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM(
+ (FIXP_DBL)SATURATE_LEFT_SHIFT(tmp, scaling + 1, DFRACT_BITS));
+#else
samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT(
- tmp, TDL_GAIN_SCALING + 1, DFRACT_BITS));
+ tmp + ((FIXP_DBL)0x8000 >> (scaling + 1)), scaling + 1,
+ DFRACT_BITS));
+#endif
}
gain >>= 1;
} else {
/* lookahead delay, apply gain=1.0f */
for (j = 0; j < channels; j++) {
tmp = p_delayBuf[j];
- p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
+ if (additionalGainAvailable) {
+ p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
+ } else {
+ p_delayBuf[j] = PCM_LIM2FIXP_DBL(samplesIn[j]);
+ }
+
+#if (SAMPLE_BITS == DFRACT_BITS)
+ samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM(
+ (FIXP_DBL)SATURATE_LEFT_SHIFT(tmp, scaling, DFRACT_BITS));
+#else
samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT(
- tmp, TDL_GAIN_SCALING, DFRACT_BITS));
+ tmp + ((FIXP_DBL)0x8000 >> scaling), scaling, DFRACT_BITS));
+#endif
}
}
@@ -354,13 +348,9 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
limiter->delayBufIdx = delayBufIdx;
limiter->smoothState0 = smoothState0;
- limiter->additionalGainFilterState = additionalGainSmoothState;
- limiter->additionalGainFilterState1 = additionalGainSmoothState1;
limiter->minGain = minGain;
- limiter->additionalGainPrev = pGain[0];
-
return TDLIMIT_OK;
}
}
@@ -370,7 +360,7 @@ TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter,
FIXP_DBL threshold) {
if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
- limiter->threshold = threshold >> TDL_GAIN_SCALING;
+ limiter->threshold = threshold;
return TDLIMIT_OK;
}
@@ -384,13 +374,7 @@ TDLIMITER_ERROR pcmLimiter_Reset(TDLimiterPtr limiter) {
limiter->cor = FL2FXCONST_DBL(1.0f / (1 << 1));
limiter->smoothState0 = FL2FXCONST_DBL(1.0f / (1 << 1));
limiter->minGain = FL2FXCONST_DBL(1.0f / (1 << 1));
-
- limiter->additionalGainPrev =
- FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING));
- limiter->additionalGainFilterState =
- FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING));
- limiter->additionalGainFilterState1 =
- FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING));
+ limiter->scaling = 0;
FDKmemset(limiter->maxBuf, 0, (limiter->attack + 1) * sizeof(FIXP_DBL));
FDKmemset(limiter->delayBuf, 0,
diff --git a/libPCMutils/src/version.h b/libPCMutils/src/version.h
index fa31af1..871aa90 100644
--- a/libPCMutils/src/version.h
+++ b/libPCMutils/src/version.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
@@ -105,10 +105,10 @@ amm-info@iis.fraunhofer.de
/* library info */
#define PCMUTIL_LIB_VL0 3
-#define PCMUTIL_LIB_VL1 0
+#define PCMUTIL_LIB_VL1 1
#define PCMUTIL_LIB_VL2 0
#define PCMUTIL_LIB_TITLE "PCM Utility Lib"
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
#define PCMUTIL_LIB_BUILD_DATE ""
#define PCMUTIL_LIB_BUILD_TIME ""
#else