mirror of https://github.com/mstorsjo/fdk-aac.git
Avoid decoder internal clipping by converting the whole audio sample data path from 16 to 32 bit data width (FDKdec v3.2.0).
Bug: 149514474 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I8a504ab709e42e27a61fe29840212953742283a5
This commit is contained in:
parent
57c9355de0
commit
e016635f0d
Binary file not shown.
|
@ -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
|
||||
|
@ -113,7 +113,7 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
|
|||
|
||||
if (delay > 0) {
|
||||
data->delay_line =
|
||||
(INT_PCM*)FDKcalloc(num_channels * delay, sizeof(INT_PCM));
|
||||
(PCM_DEC*)FDKcalloc(num_channels * delay, sizeof(PCM_DEC));
|
||||
if (data->delay_line == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -126,36 +126,36 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void FDK_Delay_Apply(FDK_SignalDelay* data, FIXP_PCM* time_buffer,
|
||||
void FDK_Delay_Apply(FDK_SignalDelay* data, PCM_DEC* time_buffer,
|
||||
const UINT frame_length, const UCHAR channel) {
|
||||
FDK_ASSERT(data != NULL);
|
||||
|
||||
if (data->delay > 0) {
|
||||
C_ALLOC_SCRATCH_START(tmp, FIXP_PCM, MAX_FRAME_LENGTH)
|
||||
C_ALLOC_SCRATCH_START(tmp, PCM_DEC, MAX_FRAME_LENGTH)
|
||||
FDK_ASSERT(frame_length <= MAX_FRAME_LENGTH);
|
||||
FDK_ASSERT(channel < data->num_channels);
|
||||
FDK_ASSERT(time_buffer != NULL);
|
||||
if (frame_length >= data->delay) {
|
||||
FDKmemcpy(tmp, &time_buffer[frame_length - data->delay],
|
||||
data->delay * sizeof(FIXP_PCM));
|
||||
data->delay * sizeof(PCM_DEC));
|
||||
FDKmemmove(&time_buffer[data->delay], &time_buffer[0],
|
||||
(frame_length - data->delay) * sizeof(FIXP_PCM));
|
||||
(frame_length - data->delay) * sizeof(PCM_DEC));
|
||||
FDKmemcpy(&time_buffer[0], &data->delay_line[channel * data->delay],
|
||||
data->delay * sizeof(FIXP_PCM));
|
||||
data->delay * sizeof(PCM_DEC));
|
||||
FDKmemcpy(&data->delay_line[channel * data->delay], tmp,
|
||||
data->delay * sizeof(FIXP_PCM));
|
||||
data->delay * sizeof(PCM_DEC));
|
||||
} else {
|
||||
FDKmemcpy(tmp, &time_buffer[0], frame_length * sizeof(FIXP_PCM));
|
||||
FDKmemcpy(tmp, &time_buffer[0], frame_length * sizeof(PCM_DEC));
|
||||
FDKmemcpy(&time_buffer[0], &data->delay_line[channel * data->delay],
|
||||
frame_length * sizeof(FIXP_PCM));
|
||||
frame_length * sizeof(PCM_DEC));
|
||||
FDKmemcpy(&data->delay_line[channel * data->delay],
|
||||
&data->delay_line[channel * data->delay + frame_length],
|
||||
(data->delay - frame_length) * sizeof(FIXP_PCM));
|
||||
(data->delay - frame_length) * sizeof(PCM_DEC));
|
||||
FDKmemcpy(&data->delay_line[channel * data->delay +
|
||||
(data->delay - frame_length)],
|
||||
tmp, frame_length * sizeof(FIXP_PCM));
|
||||
tmp, frame_length * sizeof(PCM_DEC));
|
||||
}
|
||||
C_ALLOC_SCRATCH_END(tmp, FIXP_PCM, MAX_FRAME_LENGTH)
|
||||
C_ALLOC_SCRATCH_END(tmp, PCM_DEC, MAX_FRAME_LENGTH)
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
|
@ -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,7 +109,7 @@ amm-info@iis.fraunhofer.de
|
|||
* Structure representing one delay element for multiple channels.
|
||||
*/
|
||||
typedef struct {
|
||||
INT_PCM* delay_line; /*!< Pointer which stores allocated delay line. */
|
||||
PCM_DEC* delay_line; /*!< Pointer which stores allocated delay line. */
|
||||
USHORT delay; /*!< Delay required in samples (per channel). */
|
||||
UCHAR num_channels; /*!< Number of channels to delay. */
|
||||
} FDK_SignalDelay;
|
||||
|
@ -137,7 +137,7 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
|
|||
*
|
||||
* \return void
|
||||
*/
|
||||
void FDK_Delay_Apply(FDK_SignalDelay* data, FIXP_PCM* time_buffer,
|
||||
void FDK_Delay_Apply(FDK_SignalDelay* data, PCM_DEC* time_buffer,
|
||||
const UINT frame_length, const UCHAR channel);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
@ -108,6 +108,7 @@ amm-info@iis.fraunhofer.de
|
|||
#include "aacdec_hcr_types.h"
|
||||
#include "aacdec_hcrs.h"
|
||||
|
||||
#define PCM_AAC LONG
|
||||
#define PCM_DEC FIXP_DBL
|
||||
#define MAXVAL_PCM_DEC MAXVAL_DBL
|
||||
#define MINVAL_PCM_DEC MINVAL_DBL
|
||||
|
|
|
@ -1281,6 +1281,7 @@ LINKSPEC_CPP HANDLE_AACDECODER CAacDecoder_Open(
|
|||
/* Set default frame delay */
|
||||
aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY,
|
||||
CConcealment_GetDelay(&self->concealCommonData));
|
||||
self->workBufferCore1 = (FIXP_DBL *)GetWorkBufferCore1();
|
||||
|
||||
self->workBufferCore2 = GetWorkBufferCore2();
|
||||
if (self->workBufferCore2 == NULL) goto bail;
|
||||
|
@ -1456,6 +1457,10 @@ LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self) {
|
|||
FreeDrcInfo(&self->hDrcInfo);
|
||||
}
|
||||
|
||||
if (self->workBufferCore1 != NULL) {
|
||||
FreeWorkBufferCore1((CWorkBufferCore1 **)&self->workBufferCore1);
|
||||
}
|
||||
|
||||
/* Free WorkBufferCore2 */
|
||||
if (self->workBufferCore2 != NULL) {
|
||||
FreeWorkBufferCore2(&self->workBufferCore2);
|
||||
|
@ -1493,6 +1498,8 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
|
|||
UCHAR downscaleFactor = self->downscaleFactor;
|
||||
UCHAR downscaleFactorInBS = self->downscaleFactorInBS;
|
||||
|
||||
self->aacOutDataHeadroom = (3);
|
||||
|
||||
// set profile and check for supported aot
|
||||
// leave profile on default (=-1) for all other supported MPEG-4 aot's except
|
||||
// aot=2 (=AAC-LC)
|
||||
|
@ -2394,7 +2401,7 @@ bail:
|
|||
}
|
||||
|
||||
LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
||||
HANDLE_AACDECODER self, const UINT flags, FIXP_PCM *pTimeData,
|
||||
HANDLE_AACDECODER self, const UINT flags, PCM_DEC *pTimeData,
|
||||
const INT timeDataSize, const int timeDataChannelOffset) {
|
||||
AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
|
||||
|
||||
|
@ -3170,10 +3177,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||
FDKmemcpy(drcChMap, self->chMapping, (8) * sizeof(UCHAR));
|
||||
}
|
||||
|
||||
/* Turn on/off DRC modules level normalization in digital domain depending
|
||||
* on the limiter status. */
|
||||
aacDecoder_drcSetParam(self->hDrcInfo, APPLY_NORMALIZATION,
|
||||
(self->limiterEnableCurr) ? 0 : 1);
|
||||
/* Turn off DRC modules level normalization in digital domain. */
|
||||
aacDecoder_drcSetParam(self->hDrcInfo, APPLY_NORMALIZATION, 0);
|
||||
|
||||
/* deactivate legacy DRC in case uniDrc is active, i.e. uniDrc payload is
|
||||
* present and one of DRC or Loudness Normalization is switched on */
|
||||
|
@ -3325,9 +3330,11 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||
&pAacDecoderStaticChannelInfo->drcData);
|
||||
}
|
||||
}
|
||||
|
||||
/* The DRC module demands to be called with the gain field holding the
|
||||
* gain scale. */
|
||||
self->extGain[0] = (FIXP_DBL)TDL_GAIN_SCALING;
|
||||
self->extGain[0] = (FIXP_DBL)AACDEC_DRC_GAIN_SCALING;
|
||||
|
||||
/* DRC processing */
|
||||
aacDecoder_drcApply(
|
||||
self->hDrcInfo, self->hSbrDecoder, pAacDecoderChannelInfo,
|
||||
|
@ -3343,7 +3350,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||
if (self->flushStatus && (self->flushCnt > 0) &&
|
||||
!(flags & AACDEC_CONCEAL)) {
|
||||
FDKmemclear(pTimeData + offset,
|
||||
sizeof(FIXP_PCM) * self->streamInfo.aacSamplesPerFrame);
|
||||
sizeof(PCM_DEC) * self->streamInfo.aacSamplesPerFrame);
|
||||
} else
|
||||
switch (pAacDecoderChannelInfo->renderMode) {
|
||||
case AACDEC_RENDER_IMDCT:
|
||||
|
@ -3355,7 +3362,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||
!frameOk_butConceal),
|
||||
pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1
|
||||
->mdctOutTemp,
|
||||
self->elFlags[el], elCh);
|
||||
self->aacOutDataHeadroom, self->elFlags[el], elCh);
|
||||
|
||||
self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
|
||||
break;
|
||||
|
@ -3376,7 +3383,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||
&self->samplingRateInfo[streamIndex],
|
||||
(self->frameOK && !(flags & AACDEC_CONCEAL) &&
|
||||
!frameOk_butConceal),
|
||||
flags, self->flags[streamIndex]);
|
||||
self->aacOutDataHeadroom, flags, self->flags[streamIndex]);
|
||||
|
||||
self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
|
||||
break;
|
||||
|
@ -3388,7 +3395,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||
if (!CConceal_TDFading_Applied[c]) {
|
||||
CConceal_TDFading_Applied[c] = CConcealment_TDFading(
|
||||
self->streamInfo.aacSamplesPerFrame,
|
||||
&self->pAacDecoderStaticChannelInfo[c], pTimeData + offset, 0);
|
||||
&self->pAacDecoderStaticChannelInfo[c], self->aacOutDataHeadroom,
|
||||
pTimeData + offset, 0);
|
||||
if (c + 1 < (8) && c < aacChannels - 1) {
|
||||
/* update next TDNoise Seed to avoid muting in case of Parametric
|
||||
* Stereo */
|
||||
|
@ -3409,27 +3417,18 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||
* LR) */
|
||||
if ((aacChannels == 2) && bsPseudoLr) {
|
||||
int i, offset2;
|
||||
const FIXP_SGL invSqrt2 =
|
||||
FL2FXCONST_SGL(0.353553390593273f); /* scaled by -1 */
|
||||
FIXP_PCM *pTD = pTimeData;
|
||||
const FIXP_SGL invSqrt2 = FL2FXCONST_SGL(0.707106781186547f);
|
||||
PCM_DEC *pTD = pTimeData;
|
||||
|
||||
offset2 = timeDataChannelOffset;
|
||||
|
||||
for (i = 0; i < self->streamInfo.aacSamplesPerFrame; i++) {
|
||||
FIXP_DBL L = FX_PCM2FX_DBL(pTD[0]);
|
||||
FIXP_DBL R = FX_PCM2FX_DBL(pTD[offset2]);
|
||||
FIXP_DBL L = PCM_DEC2FIXP_DBL(pTD[0]);
|
||||
FIXP_DBL R = PCM_DEC2FIXP_DBL(pTD[offset2]);
|
||||
L = fMult(L, invSqrt2);
|
||||
R = fMult(R, invSqrt2);
|
||||
#if (SAMPLE_BITS == 16)
|
||||
pTD[0] = (FIXP_SGL)SATURATE_RIGHT_SHIFT(L + R + (FIXP_DBL)(1 << 14),
|
||||
15, FRACT_BITS);
|
||||
pTD[offset2] = (FIXP_SGL)SATURATE_RIGHT_SHIFT(
|
||||
L - R + (FIXP_DBL)(1 << 14), 15, FRACT_BITS);
|
||||
#else
|
||||
pTD[0] = SATURATE_LEFT_SHIFT(FX_DBL2FX_PCM(L + R), 1, DFRACT_BITS);
|
||||
pTD[offset2] =
|
||||
SATURATE_LEFT_SHIFT(FX_DBL2FX_PCM(L - R), 1, DFRACT_BITS);
|
||||
#endif
|
||||
pTD[0] = L + R;
|
||||
pTD[offset2] = L - R;
|
||||
pTD++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -191,6 +191,9 @@ struct AAC_DECODER_INSTANCE {
|
|||
INT outputInterleaved; /*!< PCM output format (interleaved/none interleaved).
|
||||
*/
|
||||
|
||||
INT aacOutDataHeadroom; /*!< Headroom of the output time signal to prevent
|
||||
clipping */
|
||||
|
||||
HANDLE_TRANSPORTDEC hInput; /*!< Transport layer handle. */
|
||||
|
||||
SamplingRateInfo
|
||||
|
@ -235,6 +238,7 @@ struct AAC_DECODER_INSTANCE {
|
|||
CAacDecoderStaticChannelInfo
|
||||
*pAacDecoderStaticChannelInfo[(8)]; /*!< Persistent channel memory */
|
||||
|
||||
FIXP_DBL *workBufferCore1;
|
||||
FIXP_DBL *workBufferCore2;
|
||||
PCM_DEC *pTimeData2;
|
||||
INT timeData2Size;
|
||||
|
@ -311,11 +315,10 @@ This structure is allocated once for each CPE. */
|
|||
UCHAR limiterEnableUser; /*!< The limiter configuration requested by the
|
||||
library user */
|
||||
UCHAR limiterEnableCurr; /*!< The current limiter configuration. */
|
||||
|
||||
FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */
|
||||
UINT extGainDelay; /*!< Delay that must be accounted for extGain. */
|
||||
|
||||
INT_PCM pcmOutputBuffer[(8) * (1024 * 2)];
|
||||
|
||||
HANDLE_DRC_DECODER hUniDrcDecoder;
|
||||
UCHAR multibandDrcPresent;
|
||||
UCHAR numTimeSlots;
|
||||
|
@ -427,7 +430,7 @@ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self,
|
|||
\return error status
|
||||
*/
|
||||
LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
||||
HANDLE_AACDECODER self, const UINT flags, FIXP_PCM *pTimeData,
|
||||
HANDLE_AACDECODER self, const UINT flags, PCM_DEC *pTimeData,
|
||||
const INT timeDataSize, const int timeDataChannelOffset);
|
||||
|
||||
/* Free config dependent AAC memory */
|
||||
|
|
|
@ -119,8 +119,8 @@ amm-info@iis.fraunhofer.de
|
|||
|
||||
/* Decoder library info */
|
||||
#define AACDECODER_LIB_VL0 3
|
||||
#define AACDECODER_LIB_VL1 1
|
||||
#define AACDECODER_LIB_VL2 3
|
||||
#define AACDECODER_LIB_VL1 2
|
||||
#define AACDECODER_LIB_VL2 0
|
||||
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
|
||||
#ifdef __ANDROID__
|
||||
#define AACDECODER_LIB_BUILD_DATE ""
|
||||
|
@ -1131,35 +1131,31 @@ static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) {
|
|||
return n;
|
||||
}
|
||||
|
||||
LINKSPEC_CPP AAC_DECODER_ERROR
|
||||
aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
||||
const INT timeDataSize_extern, const UINT flags) {
|
||||
LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
|
||||
INT_PCM *pTimeData,
|
||||
const INT timeDataSize,
|
||||
const UINT flags) {
|
||||
AAC_DECODER_ERROR ErrorStatus;
|
||||
INT layer;
|
||||
INT nBits;
|
||||
INT timeData2Size;
|
||||
INT timeData3Size;
|
||||
INT timeDataHeadroom;
|
||||
HANDLE_FDK_BITSTREAM hBs;
|
||||
int fTpInterruption = 0; /* Transport originated interruption detection. */
|
||||
int fTpConceal = 0; /* Transport originated concealment. */
|
||||
INT_PCM *pTimeData = NULL;
|
||||
INT timeDataSize = 0;
|
||||
UINT accessUnit = 0;
|
||||
UINT numAccessUnits = 1;
|
||||
UINT numPrerollAU = 0;
|
||||
int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */
|
||||
int applyCrossfade = 1; /* flag indicates if flushing was possible */
|
||||
FIXP_PCM *pTimeDataFixpPcm; /* Signal buffer for decoding process before PCM
|
||||
processing */
|
||||
INT timeDataFixpPcmSize;
|
||||
PCM_DEC *pTimeDataPcmPost; /* Signal buffer for PCM post-processing */
|
||||
INT timeDataPcmPostSize;
|
||||
int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */
|
||||
int applyCrossfade = 1; /* flag indicates if flushing was possible */
|
||||
PCM_DEC *pTimeData2;
|
||||
PCM_AAC *pTimeData3;
|
||||
|
||||
if (self == NULL) {
|
||||
return AAC_DEC_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
pTimeData = self->pcmOutputBuffer;
|
||||
timeDataSize = sizeof(self->pcmOutputBuffer) / sizeof(*self->pcmOutputBuffer);
|
||||
|
||||
if (flags & AACDEC_INTR) {
|
||||
self->streamInfo.numLostAccessUnits = 0;
|
||||
}
|
||||
|
@ -1315,19 +1311,23 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
/* Use limiter configuration as requested. */
|
||||
self->limiterEnableCurr = self->limiterEnableUser;
|
||||
}
|
||||
/* reset limiter gain on a per frame basis */
|
||||
self->extGain[0] = FL2FXCONST_DBL(1.0f / (float)(1 << TDL_GAIN_SCALING));
|
||||
|
||||
pTimeDataFixpPcm = pTimeData;
|
||||
timeDataFixpPcmSize = timeDataSize;
|
||||
/* reset DRC level normalization gain on a per frame basis */
|
||||
self->extGain[0] = AACDEC_DRC_GAIN_INIT_VALUE;
|
||||
|
||||
pTimeData2 = self->pTimeData2;
|
||||
timeData2Size = self->timeData2Size / sizeof(PCM_DEC);
|
||||
pTimeData3 = (PCM_AAC *)self->pTimeData2;
|
||||
timeData3Size = self->timeData2Size / sizeof(PCM_AAC);
|
||||
|
||||
ErrorStatus = CAacDecoder_DecodeFrame(
|
||||
self,
|
||||
flags | (fTpConceal ? AACDEC_CONCEAL : 0) |
|
||||
((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
|
||||
: 0),
|
||||
pTimeDataFixpPcm + 0, timeDataFixpPcmSize,
|
||||
self->streamInfo.aacSamplesPerFrame + 0);
|
||||
pTimeData2 + 0, timeData2Size, self->streamInfo.aacSamplesPerFrame + 0);
|
||||
|
||||
timeDataHeadroom = self->aacOutDataHeadroom;
|
||||
|
||||
/* if flushing for USAC DASH IPF was not possible go on with decoding
|
||||
* preroll */
|
||||
|
@ -1352,7 +1352,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
}
|
||||
}
|
||||
|
||||
/* If the current pTimeDataFixpPcm does not contain a valid signal, there
|
||||
/* If the current pTimeData2 does not contain a valid signal, there
|
||||
* nothing else we can do, so bail. */
|
||||
if (!IS_OUTPUT_VALID(ErrorStatus)) {
|
||||
goto bail;
|
||||
|
@ -1366,10 +1366,10 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
self->streamInfo.numChannels = self->streamInfo.aacNumChannels;
|
||||
|
||||
{
|
||||
FDK_Delay_Apply(&self->usacResidualDelay,
|
||||
pTimeDataFixpPcm +
|
||||
1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0,
|
||||
self->streamInfo.frameSize, 0);
|
||||
FDK_Delay_Apply(
|
||||
&self->usacResidualDelay,
|
||||
pTimeData2 + 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0,
|
||||
self->streamInfo.frameSize, 0);
|
||||
}
|
||||
|
||||
/* Setting of internal MPS state; may be reset in CAacDecoder_SyncQmfMode
|
||||
|
@ -1416,8 +1416,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
}
|
||||
}
|
||||
|
||||
self->qmfDomain.globalConf.TDinput = pTimeData;
|
||||
|
||||
switch (FDK_QmfDomain_Configure(&self->qmfDomain)) {
|
||||
default:
|
||||
case QMF_DOMAIN_INIT_ERROR:
|
||||
|
@ -1474,18 +1472,18 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF,
|
||||
(self->mpsEnableCurr) ? 2 : 0);
|
||||
|
||||
INT_PCM *input;
|
||||
input = (INT_PCM *)self->workBufferCore2;
|
||||
FDKmemcpy(input, pTimeData,
|
||||
sizeof(INT_PCM) * (self->streamInfo.numChannels) *
|
||||
PCM_AAC *input;
|
||||
input = (PCM_AAC *)self->workBufferCore2;
|
||||
FDKmemcpy(input, pTimeData3,
|
||||
sizeof(PCM_AAC) * (self->streamInfo.numChannels) *
|
||||
(self->streamInfo.frameSize));
|
||||
|
||||
/* apply SBR processing */
|
||||
sbrError = sbrDecoder_Apply(self->hSbrDecoder, input, pTimeData,
|
||||
timeDataSize, &self->streamInfo.numChannels,
|
||||
&self->streamInfo.sampleRate,
|
||||
&self->mapDescr, self->chMapIndex,
|
||||
self->frameOK, &self->psPossible);
|
||||
sbrError = sbrDecoder_Apply(
|
||||
self->hSbrDecoder, input, pTimeData3, timeData3Size,
|
||||
&self->streamInfo.numChannels, &self->streamInfo.sampleRate,
|
||||
&self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible,
|
||||
self->aacOutDataHeadroom, &timeDataHeadroom);
|
||||
|
||||
if (sbrError == SBRDEC_OK) {
|
||||
/* Update data in streaminfo structure. Assume that the SBR upsampling
|
||||
|
@ -1564,10 +1562,11 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
if (err == 0) {
|
||||
err = mpegSurroundDecoder_Apply(
|
||||
(CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
|
||||
(INT_PCM *)self->workBufferCore2, pTimeData, timeDataSize,
|
||||
(PCM_AAC *)self->workBufferCore2, pTimeData3, timeData3Size,
|
||||
self->streamInfo.aacSamplesPerFrame, &nChannels, &frameSize,
|
||||
self->streamInfo.sampleRate, self->streamInfo.aot,
|
||||
self->channelType, self->channelIndices, &self->mapDescr);
|
||||
self->channelType, self->channelIndices, &self->mapDescr,
|
||||
self->aacOutDataHeadroom, &timeDataHeadroom);
|
||||
}
|
||||
|
||||
if (err == MPS_OUTPUT_BUFFER_TOO_SMALL) {
|
||||
|
@ -1590,8 +1589,8 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
self->streamInfo.frameSize = self->mpsFrameSizeLast;
|
||||
/* ... and clear output buffer so that potentially corrupted data does
|
||||
* not reach the framework. */
|
||||
FDKmemclear(pTimeData, self->mpsOutChannelsLast *
|
||||
self->mpsFrameSizeLast * sizeof(INT_PCM));
|
||||
FDKmemclear(pTimeData3, self->mpsOutChannelsLast *
|
||||
self->mpsFrameSizeLast * sizeof(PCM_AAC));
|
||||
/* Additionally proclaim that this frame had errors during decoding.
|
||||
*/
|
||||
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
|
||||
|
@ -1612,11 +1611,11 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1);
|
||||
|
||||
/* apply SBR processing */
|
||||
sbrError = sbrDecoder_Apply(self->hSbrDecoder, pTimeData, pTimeData,
|
||||
timeDataSize, &self->streamInfo.numChannels,
|
||||
&self->streamInfo.sampleRate,
|
||||
&self->mapDescr, self->chMapIndex,
|
||||
self->frameOK, &self->psPossible);
|
||||
sbrError = sbrDecoder_Apply(
|
||||
self->hSbrDecoder, pTimeData3, pTimeData3, timeData3Size,
|
||||
&self->streamInfo.numChannels, &self->streamInfo.sampleRate,
|
||||
&self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible,
|
||||
self->aacOutDataHeadroom, &timeDataHeadroom);
|
||||
|
||||
if (sbrError == SBRDEC_OK) {
|
||||
/* Update data in streaminfo structure. Assume that the SBR upsampling
|
||||
|
@ -1644,17 +1643,15 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
}
|
||||
}
|
||||
|
||||
/* Use dedicated memory for PCM postprocessing */
|
||||
pTimeDataPcmPost = self->pTimeData2;
|
||||
timeDataPcmPostSize = self->timeData2Size;
|
||||
|
||||
{
|
||||
const int size =
|
||||
self->streamInfo.frameSize * self->streamInfo.numChannels;
|
||||
FDK_ASSERT(timeDataPcmPostSize >= size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
pTimeDataPcmPost[i] =
|
||||
(PCM_DEC)FX_PCM2PCM_DEC(pTimeData[i]) >> PCM_OUT_HEADROOM;
|
||||
if ((INT)PCM_OUT_HEADROOM != timeDataHeadroom) {
|
||||
for (int i = ((self->streamInfo.frameSize *
|
||||
self->streamInfo.numChannels) -
|
||||
1);
|
||||
i >= 0; i--) {
|
||||
pTimeData2[i] =
|
||||
(PCM_DEC)pTimeData3[i] >> (PCM_OUT_HEADROOM - timeDataHeadroom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1709,22 +1706,21 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
if ((self->streamInfo.numChannels > 1) &&
|
||||
(0 || (self->sbrEnabled) || (self->mpsEnableCurr))) {
|
||||
/* interleaving/deinterleaving is performed on upper part of
|
||||
* pTimeDataPcmPost. Check if this buffer is large enough. */
|
||||
if (timeDataPcmPostSize <
|
||||
(INT)(2 * self->streamInfo.numChannels *
|
||||
self->streamInfo.frameSize * sizeof(PCM_DEC))) {
|
||||
* pTimeData2. Check if this buffer is large enough. */
|
||||
if (timeData2Size < (INT)(2 * self->streamInfo.numChannels *
|
||||
self->streamInfo.frameSize)) {
|
||||
ErrorStatus = AAC_DEC_UNKNOWN;
|
||||
goto bail;
|
||||
}
|
||||
needsDeinterleaving = 1;
|
||||
drcWorkBuffer =
|
||||
(FIXP_DBL *)pTimeDataPcmPost +
|
||||
(FIXP_DBL *)pTimeData2 +
|
||||
self->streamInfo.numChannels * self->streamInfo.frameSize;
|
||||
FDK_deinterleave(
|
||||
pTimeDataPcmPost, drcWorkBuffer, self->streamInfo.numChannels,
|
||||
pTimeData2, drcWorkBuffer, self->streamInfo.numChannels,
|
||||
self->streamInfo.frameSize, self->streamInfo.frameSize);
|
||||
} else {
|
||||
drcWorkBuffer = (FIXP_DBL *)pTimeDataPcmPost;
|
||||
drcWorkBuffer = pTimeData2;
|
||||
}
|
||||
|
||||
/* prepare Loudness Normalisation gain */
|
||||
|
@ -1759,7 +1755,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
|
||||
if (needsDeinterleaving) {
|
||||
FDK_interleave(
|
||||
drcWorkBuffer, pTimeDataPcmPost, self->streamInfo.numChannels,
|
||||
drcWorkBuffer, pTimeData2, self->streamInfo.numChannels,
|
||||
self->streamInfo.frameSize, self->streamInfo.frameSize);
|
||||
}
|
||||
}
|
||||
|
@ -1799,6 +1795,9 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
|
||||
if (self->streamInfo.extAot != AOT_AAC_SLS) {
|
||||
INT pcmLimiterScale = 0;
|
||||
INT interleaved = 0;
|
||||
interleaved |= (self->sbrEnabled) ? 1 : 0;
|
||||
interleaved |= (self->mpsEnableCurr) ? 1 : 0;
|
||||
PCMDMX_ERROR dmxErr = PCMDMX_OK;
|
||||
if ((flags & AACDEC_INTR) && (accessUnit == 0)) {
|
||||
/* delete data from the past (e.g. mixdown coeficients) */
|
||||
|
@ -1811,17 +1810,12 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
}
|
||||
}
|
||||
|
||||
INT interleaved = 0;
|
||||
interleaved |= (self->sbrEnabled) ? 1 : 0;
|
||||
interleaved |= (self->mpsEnableCurr) ? 1 : 0;
|
||||
|
||||
/* do PCM post processing */
|
||||
dmxErr = pcmDmx_ApplyFrame(
|
||||
self->hPcmUtils, pTimeDataPcmPost, timeDataFixpPcmSize,
|
||||
self->streamInfo.frameSize, &self->streamInfo.numChannels,
|
||||
interleaved, self->channelType, self->channelIndices,
|
||||
&self->mapDescr,
|
||||
(self->limiterEnableCurr) ? &pcmLimiterScale : NULL);
|
||||
dmxErr = pcmDmx_ApplyFrame(self->hPcmUtils, pTimeData2, timeData2Size,
|
||||
self->streamInfo.frameSize,
|
||||
&self->streamInfo.numChannels, interleaved,
|
||||
self->channelType, self->channelIndices,
|
||||
&self->mapDescr, &pcmLimiterScale);
|
||||
if (dmxErr == PCMDMX_OUTPUT_BUFFER_TOO_SMALL) {
|
||||
ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
|
||||
goto bail;
|
||||
|
@ -1833,13 +1827,35 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
|
||||
}
|
||||
|
||||
pcmLimiterScale += PCM_OUT_HEADROOM;
|
||||
|
||||
if (flags & AACDEC_CLRHIST) {
|
||||
if (!(self->flags[0] & AC_USAC)) {
|
||||
/* Reset DRC data */
|
||||
aacDecoder_drcReset(self->hDrcInfo);
|
||||
/* Delete the delayed signal. */
|
||||
pcmLimiter_Reset(self->hLimiter);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set applyExtGain if DRC processing is enabled and if
|
||||
progRefLevelPresent is present for the first time. Consequences: The
|
||||
headroom of the output signal can be set to AACDEC_DRC_GAIN_SCALING
|
||||
only for audio formats which support legacy DRC Level Normalization.
|
||||
For all other audio formats the headroom of the output
|
||||
signal is set to PCM_OUT_HEADROOM. */
|
||||
if (self->hDrcInfo->enable &&
|
||||
(self->hDrcInfo->progRefLevelPresent == 1)) {
|
||||
self->hDrcInfo->applyExtGain |= 1;
|
||||
}
|
||||
|
||||
/* Check whether time data buffer is large enough. */
|
||||
if (timeDataSize <
|
||||
(self->streamInfo.numChannels * self->streamInfo.frameSize)) {
|
||||
ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (self->limiterEnableCurr) {
|
||||
/* use workBufferCore2 buffer for interleaving */
|
||||
PCM_LIM *pInterleaveBuffer;
|
||||
|
@ -1848,44 +1864,72 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||
/* Set actual signal parameters */
|
||||
pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels);
|
||||
pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate);
|
||||
pcmLimiterScale += PCM_OUT_HEADROOM;
|
||||
|
||||
if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
|
||||
(self->mpsEnableCurr)) {
|
||||
pInterleaveBuffer = (PCM_LIM *)pTimeDataPcmPost;
|
||||
pInterleaveBuffer = (PCM_LIM *)pTimeData2;
|
||||
} else {
|
||||
pInterleaveBuffer = (PCM_LIM *)pTimeData;
|
||||
pInterleaveBuffer = (PCM_LIM *)self->workBufferCore2;
|
||||
|
||||
/* applyLimiter requests for interleaved data */
|
||||
/* Interleave ouput buffer */
|
||||
FDK_interleave(pTimeDataPcmPost, pInterleaveBuffer,
|
||||
FDK_interleave(pTimeData2, pInterleaveBuffer,
|
||||
self->streamInfo.numChannels, blockLength,
|
||||
self->streamInfo.frameSize);
|
||||
}
|
||||
|
||||
FIXP_DBL *pGainPerSample = NULL;
|
||||
|
||||
if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) {
|
||||
pGainPerSample = self->workBufferCore1;
|
||||
|
||||
if ((INT)GetRequiredMemWorkBufferCore1() <
|
||||
(INT)(self->streamInfo.frameSize * sizeof(FIXP_DBL))) {
|
||||
ErrorStatus = AAC_DEC_UNKNOWN;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
pcmLimiterScale = applyDrcLevelNormalization(
|
||||
self->hDrcInfo, (PCM_DEC *)pInterleaveBuffer, self->extGain,
|
||||
pGainPerSample, pcmLimiterScale, self->extGainDelay,
|
||||
self->streamInfo.frameSize, self->streamInfo.numChannels, 1, 1);
|
||||
}
|
||||
|
||||
pcmLimiter_Apply(self->hLimiter, pInterleaveBuffer, pTimeData,
|
||||
self->extGain, &pcmLimiterScale, 1,
|
||||
self->extGainDelay, self->streamInfo.frameSize);
|
||||
pGainPerSample, pcmLimiterScale,
|
||||
self->streamInfo.frameSize);
|
||||
|
||||
{
|
||||
/* Announce the additional limiter output delay */
|
||||
self->streamInfo.outputDelay += pcmLimiter_GetDelay(self->hLimiter);
|
||||
}
|
||||
} else {
|
||||
if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) {
|
||||
pcmLimiterScale = applyDrcLevelNormalization(
|
||||
self->hDrcInfo, pTimeData2, self->extGain, NULL,
|
||||
pcmLimiterScale, self->extGainDelay, self->streamInfo.frameSize,
|
||||
self->streamInfo.numChannels,
|
||||
(interleaved || (self->streamInfo.numChannels == 1))
|
||||
? 1
|
||||
: self->streamInfo.frameSize,
|
||||
0);
|
||||
}
|
||||
|
||||
/* If numChannels = 1 we do not need interleaving. The same applies if
|
||||
SBR or MPS are used, since their output is interleaved already
|
||||
(resampled or not) */
|
||||
if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
|
||||
(self->mpsEnableCurr)) {
|
||||
scaleValuesSaturate(
|
||||
pTimeData, pTimeDataPcmPost,
|
||||
pTimeData, pTimeData2,
|
||||
self->streamInfo.frameSize * self->streamInfo.numChannels,
|
||||
PCM_OUT_HEADROOM);
|
||||
pcmLimiterScale);
|
||||
|
||||
} else {
|
||||
scaleValuesSaturate(
|
||||
(INT_PCM *)self->workBufferCore2, pTimeDataPcmPost,
|
||||
(INT_PCM *)self->workBufferCore2, pTimeData2,
|
||||
self->streamInfo.frameSize * self->streamInfo.numChannels,
|
||||
PCM_OUT_HEADROOM);
|
||||
pcmLimiterScale);
|
||||
/* Interleave ouput buffer */
|
||||
FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData,
|
||||
self->streamInfo.numChannels,
|
||||
|
@ -1981,20 +2025,8 @@ bail:
|
|||
ErrorStatus = AAC_DEC_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Check whether external output buffer is large enough. */
|
||||
if (timeDataSize_extern <
|
||||
self->streamInfo.numChannels * self->streamInfo.frameSize) {
|
||||
ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Update external output buffer. */
|
||||
if (IS_OUTPUT_VALID(ErrorStatus)) {
|
||||
FDKmemcpy(pTimeData_extern, pTimeData,
|
||||
self->streamInfo.numChannels * self->streamInfo.frameSize *
|
||||
sizeof(*pTimeData));
|
||||
} else {
|
||||
FDKmemclear(pTimeData_extern,
|
||||
timeDataSize_extern * sizeof(*pTimeData_extern));
|
||||
if (!IS_OUTPUT_VALID(ErrorStatus)) {
|
||||
FDKmemclear(pTimeData, timeDataSize * sizeof(*pTimeData));
|
||||
}
|
||||
|
||||
return ErrorStatus;
|
||||
|
|
|
@ -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
|
||||
|
@ -1015,9 +1015,9 @@ FIXP_DBL get_gain(const FIXP_DBL *x, const FIXP_DBL *y, int n) {
|
|||
|
||||
void CBlock_FrequencyToTime(
|
||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
|
||||
const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1,
|
||||
UINT elFlags, INT elCh) {
|
||||
const INT aacOutDataHeadroom, UINT elFlags, INT elCh) {
|
||||
int fr, fl, tl, nSpec;
|
||||
|
||||
#if defined(FDK_ASSERT_ENABLE)
|
||||
|
@ -1213,6 +1213,7 @@ void CBlock_FrequencyToTime(
|
|||
bass_pf_1sf_delay(p2_synth, pitch, pit_gain, frameLen,
|
||||
(LpdSfd + 2) * L_SUBFR + BPF_SFD * L_SUBFR,
|
||||
frameLen - (LpdSfd + 4) * L_SUBFR, outSamples,
|
||||
aacOutDataHeadroom,
|
||||
pAacDecoderStaticChannelInfo->mem_bpf);
|
||||
}
|
||||
|
||||
|
@ -1236,7 +1237,8 @@ void CBlock_FrequencyToTime(
|
|||
? MLT_FLAG_CURR_ALIAS_SYMMETRY
|
||||
: 0);
|
||||
|
||||
scaleValuesSaturate(outSamples, tmp, frameLen, MDCT_OUT_HEADROOM);
|
||||
scaleValuesSaturate(outSamples, tmp, frameLen,
|
||||
MDCT_OUT_HEADROOM - aacOutDataHeadroom);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1251,7 +1253,7 @@ void CBlock_FrequencyToTime(
|
|||
#include "ldfiltbank.h"
|
||||
void CBlock_FrequencyToTimeLowDelay(
|
||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
|
||||
const short frameLen) {
|
||||
InvMdctTransformLowDelay_fdk(
|
||||
SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
|
||||
|
|
|
@ -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
|
||||
|
@ -218,16 +218,16 @@ void ApplyTools(CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
|
|||
*/
|
||||
void CBlock_FrequencyToTime(
|
||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
|
||||
const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1,
|
||||
UINT elFlags, INT elCh);
|
||||
const INT aacOutDataHeadroom, UINT elFlags, INT elCh);
|
||||
|
||||
/**
|
||||
* \brief Transform double lapped MDCT (AAC-ELD) spectral data into time domain.
|
||||
*/
|
||||
void CBlock_FrequencyToTimeLowDelay(
|
||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
|
||||
const short frameLen);
|
||||
|
||||
AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(
|
||||
|
|
|
@ -226,7 +226,7 @@ static void CConcealment_ApplyRandomSign(int iRandomPhase, FIXP_DBL *spec,
|
|||
|
||||
/* TimeDomainFading */
|
||||
static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
|
||||
FIXP_DBL fadeStop, FIXP_PCM *pcmdata);
|
||||
FIXP_DBL fadeStop, PCM_DEC *pcmdata);
|
||||
static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
|
||||
int *fadingSteps,
|
||||
FIXP_DBL fadeStop,
|
||||
|
@ -242,7 +242,9 @@ static int CConcealment_ApplyFadeOut(
|
|||
|
||||
static int CConcealment_TDNoise_Random(ULONG *seed);
|
||||
static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
|
||||
const int len, FIXP_PCM *const pcmdata);
|
||||
const int len,
|
||||
const INT aacOutDataHeadroom,
|
||||
PCM_DEC *const pcmdata);
|
||||
|
||||
static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) {
|
||||
BLOCK_TYPE newWinSeq = BLOCK_LONG;
|
||||
|
@ -1844,7 +1846,7 @@ Target fading level is determined by fading index cntFadeFrames.
|
|||
|
||||
INT CConcealment_TDFading(
|
||||
int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
|
||||
FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1) {
|
||||
const INT aacOutDataHeadroom, PCM_DEC *pcmdata, PCM_DEC *pcmdata_1) {
|
||||
/*
|
||||
Do the fading in Time domain based on concealment states and core mode
|
||||
*/
|
||||
|
@ -1957,7 +1959,8 @@ INT CConcealment_TDFading(
|
|||
start += len;
|
||||
}
|
||||
}
|
||||
CConcealment_TDNoise_Apply(pConcealmentInfo, len, pcmdata);
|
||||
CConcealment_TDNoise_Apply(pConcealmentInfo, len, aacOutDataHeadroom,
|
||||
pcmdata);
|
||||
|
||||
/* Save end-of-frame attenuation and fading type */
|
||||
pConcealmentInfo->lastFadingType = fadingType;
|
||||
|
@ -1969,12 +1972,11 @@ INT CConcealment_TDFading(
|
|||
|
||||
/* attenuate pcmdata in Time Domain Fading process */
|
||||
static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
|
||||
FIXP_DBL fadeStop, FIXP_PCM *pcmdata) {
|
||||
FIXP_DBL fadeStop, PCM_DEC *pcmdata) {
|
||||
int i;
|
||||
FIXP_DBL dStep;
|
||||
FIXP_DBL dGain;
|
||||
FIXP_DBL dGain_apply;
|
||||
int bitshift = (DFRACT_BITS - SAMPLE_BITS);
|
||||
|
||||
/* set start energy */
|
||||
dGain = fadeStart;
|
||||
|
@ -1987,7 +1989,7 @@ static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
|
|||
*/
|
||||
dGain_apply = fMax((FIXP_DBL)0, dGain);
|
||||
/* finally, attenuate samples */
|
||||
pcmdata[i] = (FIXP_PCM)((fMult(pcmdata[i], (dGain_apply))) >> bitshift);
|
||||
pcmdata[i] = FIXP_DBL2PCM_DEC(fMult(pcmdata[i], dGain_apply));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2050,9 +2052,11 @@ static int CConcealment_TDNoise_Random(ULONG *seed) {
|
|||
}
|
||||
|
||||
static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
|
||||
const int len, FIXP_PCM *const pcmdata) {
|
||||
FIXP_PCM *states = pConcealmentInfo->TDNoiseStates;
|
||||
FIXP_PCM noiseVal;
|
||||
const int len,
|
||||
const INT aacOutDataHeadroom,
|
||||
PCM_DEC *const pcmdata) {
|
||||
PCM_DEC *states = pConcealmentInfo->TDNoiseStates;
|
||||
PCM_DEC noiseVal;
|
||||
FIXP_DBL noiseValLong;
|
||||
FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef;
|
||||
FIXP_DBL TDNoiseAtt;
|
||||
|
@ -2070,18 +2074,20 @@ static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
|
|||
/* create filtered noise */
|
||||
states[2] = states[1];
|
||||
states[1] = states[0];
|
||||
states[0] = ((FIXP_PCM)CConcealment_TDNoise_Random(&seed));
|
||||
states[0] =
|
||||
FIXP_DBL2PCM_DEC((FIXP_DBL)CConcealment_TDNoise_Random(&seed));
|
||||
noiseValLong = fMult(states[0], coef[0]) + fMult(states[1], coef[1]) +
|
||||
fMult(states[2], coef[2]);
|
||||
noiseVal = FX_DBL2FX_PCM(fMult(noiseValLong, TDNoiseAtt));
|
||||
noiseVal = FIXP_DBL2PCM_DEC(fMult(noiseValLong, TDNoiseAtt) >>
|
||||
aacOutDataHeadroom);
|
||||
|
||||
/* add filtered noise - check for clipping, before */
|
||||
if (noiseVal > (FIXP_PCM)0 &&
|
||||
pcmdata[ii] > (FIXP_PCM)MAXVAL_FIXP_PCM - noiseVal) {
|
||||
noiseVal = noiseVal * (FIXP_PCM)-1;
|
||||
} else if (noiseVal < (FIXP_PCM)0 &&
|
||||
pcmdata[ii] < (FIXP_PCM)MINVAL_FIXP_PCM - noiseVal) {
|
||||
noiseVal = noiseVal * (FIXP_PCM)-1;
|
||||
if (noiseVal > (PCM_DEC)0 &&
|
||||
pcmdata[ii] > (PCM_DEC)MAXVAL_PCM_DEC - noiseVal) {
|
||||
noiseVal = noiseVal * (PCM_DEC)-1;
|
||||
} else if (noiseVal < (PCM_DEC)0 &&
|
||||
pcmdata[ii] < (PCM_DEC)MINVAL_PCM_DEC - noiseVal) {
|
||||
noiseVal = noiseVal * (PCM_DEC)-1;
|
||||
}
|
||||
|
||||
pcmdata[ii] += noiseVal;
|
||||
|
|
|
@ -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,6 +147,6 @@ int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo,
|
|||
|
||||
INT CConcealment_TDFading(
|
||||
int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
|
||||
FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1);
|
||||
const INT aacOutDataHeadroom, PCM_DEC *pcmdata, PCM_DEC *pcmdata_1);
|
||||
|
||||
#endif /* #ifndef CONCEAL_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
|
||||
|
@ -194,7 +194,7 @@ typedef struct {
|
|||
FIXP_DBL last_tcx_gain;
|
||||
INT last_tcx_gain_e;
|
||||
ULONG TDNoiseSeed;
|
||||
FIXP_PCM TDNoiseStates[3];
|
||||
PCM_DEC TDNoiseStates[3];
|
||||
FIXP_SGL TDNoiseCoef[3];
|
||||
FIXP_SGL TDNoiseAtt;
|
||||
|
||||
|
|
|
@ -112,17 +112,20 @@ amm-info@iis.fraunhofer.de
|
|||
#if defined(__arm__)
|
||||
#endif
|
||||
|
||||
static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
|
||||
static void multE2_DinvF_fdk(PCM_DEC *output, FIXP_DBL *x, const FIXP_WTB *fb,
|
||||
FIXP_DBL *z, const int N) {
|
||||
int i;
|
||||
|
||||
/* scale for FIXP_DBL -> INT_PCM conversion. */
|
||||
const int scale = (DFRACT_BITS - SAMPLE_BITS) - LDFB_HEADROOM;
|
||||
#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
|
||||
/* scale for FIXP_DBL -> PCM_DEC conversion: */
|
||||
const int scale = (DFRACT_BITS - PCM_OUT_BITS) - LDFB_HEADROOM + (3);
|
||||
|
||||
#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0)
|
||||
FIXP_DBL rnd_val_wts0 = (FIXP_DBL)0;
|
||||
FIXP_DBL rnd_val_wts1 = (FIXP_DBL)0;
|
||||
#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - WTS0 - 1) > 0)
|
||||
if (-WTS0 - 1 + scale)
|
||||
rnd_val_wts0 = (FIXP_DBL)(1 << (-WTS0 - 1 + scale - 1));
|
||||
#endif
|
||||
if (-WTS1 - 1 + scale)
|
||||
rnd_val_wts1 = (FIXP_DBL)(1 << (-WTS1 - 1 + scale - 1));
|
||||
#endif
|
||||
|
@ -141,16 +144,16 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
|
|||
tmp = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) +
|
||||
fMultDiv2(z[i], fb[N + N / 2 + i]));
|
||||
|
||||
#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
|
||||
#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0)
|
||||
FDK_ASSERT((-WTS1 - 1 + scale) >= 0);
|
||||
FDK_ASSERT(tmp <= ((FIXP_DBL)0x7FFFFFFF -
|
||||
rnd_val_wts1)); /* rounding must not cause overflow */
|
||||
output[(N * 3 / 4 - 1 - i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
|
||||
output[(N * 3 / 4 - 1 - i)] = (PCM_DEC)SATURATE_RIGHT_SHIFT(
|
||||
tmp + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS);
|
||||
#else
|
||||
FDK_ASSERT((WTS1 + 1 - scale) >= 0);
|
||||
output[(N * 3 / 4 - 1 - i)] =
|
||||
(FIXP_PCM)SATURATE_LEFT_SHIFT(tmp, WTS1 + 1 - scale, PCM_OUT_BITS);
|
||||
(PCM_DEC)SATURATE_LEFT_SHIFT(tmp, WTS1 + 1 - scale, PCM_OUT_BITS);
|
||||
#endif
|
||||
|
||||
z[i] = z0;
|
||||
|
@ -173,22 +176,22 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
|
|||
tmp1 = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) +
|
||||
fMultDiv2(z[i], fb[N + N / 2 + i]));
|
||||
|
||||
#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
|
||||
#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0)
|
||||
FDK_ASSERT((-WTS0 - 1 + scale) >= 0);
|
||||
FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF -
|
||||
rnd_val_wts0)); /* rounding must not cause overflow */
|
||||
FDK_ASSERT(tmp1 <= ((FIXP_DBL)0x7FFFFFFF -
|
||||
rnd_val_wts1)); /* rounding must not cause overflow */
|
||||
output[(i - N / 4)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
|
||||
output[(i - N / 4)] = (PCM_DEC)SATURATE_RIGHT_SHIFT(
|
||||
tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS);
|
||||
output[(N * 3 / 4 - 1 - i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
|
||||
output[(N * 3 / 4 - 1 - i)] = (PCM_DEC)SATURATE_RIGHT_SHIFT(
|
||||
tmp1 + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS);
|
||||
#else
|
||||
FDK_ASSERT((WTS0 + 1 - scale) >= 0);
|
||||
output[(i - N / 4)] =
|
||||
(FIXP_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS);
|
||||
(PCM_DEC)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS);
|
||||
output[(N * 3 / 4 - 1 - i)] =
|
||||
(FIXP_PCM)SATURATE_LEFT_SHIFT(tmp1, WTS1 + 1 - scale, PCM_OUT_BITS);
|
||||
(PCM_DEC)SATURATE_LEFT_SHIFT(tmp1, WTS1 + 1 - scale, PCM_OUT_BITS);
|
||||
#endif
|
||||
z[i] = z0;
|
||||
z[N + i] = z2;
|
||||
|
@ -198,22 +201,22 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
|
|||
for (i = 0; i < N / 4; i++) {
|
||||
FIXP_DBL tmp0 = fMultDiv2(z[i], fb[N / 2 + i]);
|
||||
|
||||
#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
|
||||
#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0)
|
||||
FDK_ASSERT((-WTS0 - 1 + scale) >= 0);
|
||||
FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF -
|
||||
rnd_val_wts0)); /* rounding must not cause overflow */
|
||||
output[(N * 3 / 4 + i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
|
||||
output[(N * 3 / 4 + i)] = (PCM_DEC)SATURATE_RIGHT_SHIFT(
|
||||
tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS);
|
||||
#else
|
||||
FDK_ASSERT((WTS0 + 1 - scale) >= 0);
|
||||
output[(N * 3 / 4 + i)] =
|
||||
(FIXP_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS);
|
||||
(PCM_DEC)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctData, const int mdctData_e,
|
||||
FIXP_PCM *output, FIXP_DBL *fs_buffer,
|
||||
PCM_DEC *output, FIXP_DBL *fs_buffer,
|
||||
const int N) {
|
||||
const FIXP_WTB *coef;
|
||||
FIXP_DBL gain = (FIXP_DBL)0;
|
||||
|
|
|
@ -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,9 +104,10 @@ amm-info@iis.fraunhofer.de
|
|||
#define LDFILTBANK_H
|
||||
|
||||
#include "common_fix.h"
|
||||
#include "aac_rom.h"
|
||||
|
||||
int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctdata_m, const int mdctdata_e,
|
||||
FIXP_PCM *mdctOut, FIXP_DBL *fs_buffer,
|
||||
PCM_DEC *mdctOut, FIXP_DBL *fs_buffer,
|
||||
const int frameLength);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -122,18 +122,21 @@ amm-info@iis.fraunhofer.de
|
|||
|
||||
#include "ac_arith_coder.h"
|
||||
|
||||
void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
|
||||
const FIXP_SGL *filt, INT stop, int len) {
|
||||
void filtLP(const FIXP_DBL *syn, PCM_DEC *syn_out, FIXP_DBL *noise,
|
||||
const FIXP_SGL *filt, const INT aacOutDataHeadroom, INT stop,
|
||||
int len) {
|
||||
INT i, j;
|
||||
FIXP_DBL tmp;
|
||||
|
||||
FDK_ASSERT((aacOutDataHeadroom - 1) >= -(MDCT_OUTPUT_SCALE));
|
||||
|
||||
for (i = 0; i < stop; i++) {
|
||||
tmp = fMultDiv2(noise[i], filt[0]); // Filt in Q-1.16
|
||||
for (j = 1; j <= len; j++) {
|
||||
tmp += fMult((noise[i - j] >> 1) + (noise[i + j] >> 1), filt[j]);
|
||||
}
|
||||
syn_out[i] = (FIXP_PCM)(SATURATE_SHIFT(
|
||||
(syn[i] >> 1) - (tmp >> 1), (MDCT_OUTPUT_SCALE - 1), PCM_OUT_BITS));
|
||||
syn_out[i] = (PCM_DEC)(
|
||||
IMDCT_SCALE((syn[i] >> 1) - (tmp >> 1), aacOutDataHeadroom - 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,8 +146,10 @@ void bass_pf_1sf_delay(
|
|||
FIXP_DBL *pit_gain,
|
||||
const int frame_length, /* (i) : frame length (should be 768|1024) */
|
||||
const INT l_frame,
|
||||
const INT l_next, /* (i) : look ahead for symmetric filtering */
|
||||
FIXP_PCM *synth_out, /* (o) : filtered synthesis (with delay of 1 subfr) */
|
||||
const INT l_next, /* (i) : look ahead for symmetric filtering */
|
||||
PCM_DEC *synth_out, /* (o) : filtered synthesis (with delay of 1 subfr) */
|
||||
const INT aacOutDataHeadroom, /* (i) : headroom of the output time signal to
|
||||
prevent clipping */
|
||||
FIXP_DBL mem_bpf[]) /* i/o : memory state [L_FILT+L_SUBFR] */
|
||||
{
|
||||
INT i, sf, i_subfr, T, T2, lg;
|
||||
|
@ -370,7 +375,7 @@ void bass_pf_1sf_delay(
|
|||
|
||||
{
|
||||
filtLP(&syn[i_subfr - L_SUBFR], &synth_out[i_subfr], noise,
|
||||
fdk_dec_filt_lp, L_SUBFR, L_FILT);
|
||||
fdk_dec_filt_lp, aacOutDataHeadroom, L_SUBFR, L_FILT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -383,9 +388,9 @@ void bass_pf_1sf_delay(
|
|||
/* Output scaling of the BPF memory */
|
||||
scaleValues(mem_bpf, (L_FILT + L_SUBFR), -1);
|
||||
/* Copy the rest of the signal (after the fac) */
|
||||
scaleValuesSaturate((FIXP_PCM *)&synth_out[l_frame],
|
||||
(FIXP_DBL *)&syn[l_frame - L_SUBFR],
|
||||
(frame_length - l_frame), MDCT_OUT_HEADROOM);
|
||||
scaleValuesSaturate(
|
||||
(PCM_DEC *)&synth_out[l_frame], (FIXP_DBL *)&syn[l_frame - L_SUBFR],
|
||||
(frame_length - l_frame), MDCT_OUT_HEADROOM - aacOutDataHeadroom);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -1552,9 +1557,9 @@ void CLpdChannelStream_Decode(
|
|||
|
||||
AAC_DECODER_ERROR CLpd_RenderTimeSignal(
|
||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData,
|
||||
INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, UINT flags,
|
||||
UINT strmFlags) {
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC *pTimeData,
|
||||
INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk,
|
||||
const INT aacOutDataHeadroom, UINT flags, UINT strmFlags) {
|
||||
UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
|
||||
AAC_DECODER_ERROR error = AAC_DEC_OK;
|
||||
int k, i_offset;
|
||||
|
@ -2017,7 +2022,8 @@ AAC_DECODER_ERROR CLpd_RenderTimeSignal(
|
|||
{
|
||||
bass_pf_1sf_delay(p2_synth, pitch, pit_gain, lFrame, lFrame / facFB,
|
||||
mod[nbDiv - 1] ? (SynDelay - (lDiv / 2)) : SynDelay,
|
||||
pTimeData, pAacDecoderStaticChannelInfo->mem_bpf);
|
||||
pTimeData, aacOutDataHeadroom,
|
||||
pAacDecoderStaticChannelInfo->mem_bpf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -140,13 +140,14 @@ void CLpdChannelStream_Decode(
|
|||
* \param pTimeData pointer to output buffer
|
||||
* \param samplesPerFrame amount of output samples
|
||||
* \param pSamplingRateInfo holds the sampling rate information
|
||||
* \param pWorkBuffer1 pointer to work buffer for temporal data
|
||||
* \param aacOutDataHeadroom headroom of the output time signal to prevent
|
||||
* clipping
|
||||
*/
|
||||
AAC_DECODER_ERROR CLpd_RenderTimeSignal(
|
||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData,
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC *pTimeData,
|
||||
INT samplesPerFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk,
|
||||
UINT flags, UINT strmFlags);
|
||||
const INT aacOutDataHeadroom, UINT flags, UINT strmFlags);
|
||||
|
||||
static inline INT CLpd_FAC_getLength(int fNotShortBlock, int fac_length_long) {
|
||||
if (fNotShortBlock) {
|
||||
|
@ -156,8 +157,9 @@ static inline INT CLpd_FAC_getLength(int fNotShortBlock, int fac_length_long) {
|
|||
}
|
||||
}
|
||||
|
||||
void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
|
||||
const FIXP_SGL *filt, INT stop, int len);
|
||||
void filtLP(const FIXP_DBL *syn, PCM_DEC *syn_out, FIXP_DBL *noise,
|
||||
const FIXP_SGL *filt, const INT aacOutDataHeadroom, INT stop,
|
||||
int len);
|
||||
|
||||
/**
|
||||
* \brief perform a low-frequency pitch enhancement on time domain signal
|
||||
|
@ -171,13 +173,14 @@ void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
|
|||
* \param[in] l_frame length of filtering, must be multiple of L_SUBFR
|
||||
* \param[in] l_next length of allowed look ahead on syn[i], i < l_frame+l_next
|
||||
* \param[out] synth_out pointer to time domain output signal
|
||||
* \param[in] headroom of the output time signal to prevent clipping
|
||||
* \param[in,out] mem_bpf pointer to filter memory (L_FILT+L_SUBFR)
|
||||
*/
|
||||
|
||||
void bass_pf_1sf_delay(FIXP_DBL syn[], const INT T_sf[], FIXP_DBL *pit_gain,
|
||||
const int frame_length, const INT l_frame,
|
||||
const INT l_next, FIXP_PCM *synth_out,
|
||||
FIXP_DBL mem_bpf[]);
|
||||
const INT l_next, PCM_DEC *synth_out,
|
||||
const INT aacOutDataHeadroom, FIXP_DBL mem_bpf[]);
|
||||
|
||||
/**
|
||||
* \brief random sign generator for FD and TCX noise filling
|
||||
|
|
|
@ -160,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.
|
||||
|
@ -181,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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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,7 +104,7 @@ 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__
|
||||
|
|
|
@ -637,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;
|
||||
|
@ -648,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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
if (pGainPerSample == NULL) {
|
||||
additionalGainAvailable = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < nSamples; i++) {
|
||||
if (gain_delay) {
|
||||
if (i < gain_delay) {
|
||||
additionalGainUnfiltered = limiter->additionalGainPrev;
|
||||
} else {
|
||||
additionalGainUnfiltered = pGain[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];
|
||||
}
|
||||
}
|
||||
/* 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 =
|
||||
(tmp2 == (FIXP_DBL)MINVAL_DBL) ? (FIXP_DBL)MAXVAL_DBL : fAbs(tmp2);
|
||||
tmp1 = fMax(tmp1, 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,
|
||||
|
|
|
@ -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,7 +105,7 @@ 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__
|
||||
|
|
|
@ -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
|
||||
|
@ -252,7 +252,7 @@ typedef enum {
|
|||
scenario. Default parameter value is 3 frames. */
|
||||
} SACDEC_PARAM;
|
||||
|
||||
#define PCM_MPS INT_PCM
|
||||
#define PCM_MPS LONG
|
||||
|
||||
/**
|
||||
* \brief MPEG Surround decoder handle.
|
||||
|
@ -401,17 +401,22 @@ int mpegSurroundDecoder_Parse(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
|||
* for each output audio channel is stored into.
|
||||
* \param mapDescr Channep map descriptor for output channel mapping
|
||||
* to be used (From MPEG PCE ordering to whatever is required).
|
||||
* \param inDataHeadroom Headroom of SAC input time signal to prevent
|
||||
* clipping.
|
||||
* \param outDataHeadroom Pointer to headroom of SAC output time signal to
|
||||
* prevent clipping.
|
||||
*
|
||||
* \return Error code.
|
||||
*/
|
||||
int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
||||
INT_PCM *input, PCM_MPS *pTimeData,
|
||||
PCM_MPS *input, PCM_MPS *pTimeData,
|
||||
const int timeDataSize, int timeDataFrameSize,
|
||||
int *nChannels, int *frameSize, int sampleRate,
|
||||
AUDIO_OBJECT_TYPE coreCodec,
|
||||
AUDIO_CHANNEL_TYPE channelType[],
|
||||
UCHAR channelIndices[],
|
||||
const FDK_channelMapDescr *const mapDescr);
|
||||
const FDK_channelMapDescr *const mapDescr,
|
||||
const INT inDataHeadroom, INT *outDataHeadroom);
|
||||
|
||||
/**
|
||||
* \brief Deallocate a MPEG Surround decoder instance.
|
||||
|
|
|
@ -766,7 +766,7 @@ SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
|
|||
|
||||
/* output scaling */
|
||||
for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) {
|
||||
int outputScale = 0, outputGain_e = 0, scale = 0;
|
||||
int outputScale = 0, outputGain_e = 0, scale = -(8) + (1);
|
||||
FIXP_DBL outputGain_m = getChGain(self, nCh, &outputGain_e);
|
||||
|
||||
if (!isTwoChMode(self->upmixType) && !bypassMode) {
|
||||
|
@ -775,7 +775,7 @@ SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
|
|||
synthesis qmf */
|
||||
}
|
||||
|
||||
scale = outputScale;
|
||||
scale += outputScale;
|
||||
|
||||
qmfChangeOutScalefactor(&self->pQmfDomain->QmfDomainOut[nCh].fb, scale);
|
||||
qmfChangeOutGain(&self->pQmfDomain->QmfDomainOut[nCh].fb, outputGain_m,
|
||||
|
@ -1223,18 +1223,24 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
|
|||
!(self->stereoConfigIndex == 3)) {
|
||||
for (i = 0; i < self->qmfBands; i++) {
|
||||
self_qmfResidualReal__FDK_0_0[i] =
|
||||
fMult(self_qmfResidualReal__FDK_0_0[i] << 1,
|
||||
fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i],
|
||||
1 + self->sacInDataHeadroom - (1)),
|
||||
self->clipProtectGain__FDK);
|
||||
self_qmfResidualImag__FDK_0_0[i] =
|
||||
fMult(self_qmfResidualImag__FDK_0_0[i] << 1,
|
||||
fMult(scaleValueSaturate(self_qmfResidualImag__FDK_0_0[i],
|
||||
1 + self->sacInDataHeadroom - (1)),
|
||||
self->clipProtectGain__FDK);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < self->qmfBands; i++) {
|
||||
self_qmfResidualReal__FDK_0_0[i] = fMult(
|
||||
self_qmfResidualReal__FDK_0_0[i], self->clipProtectGain__FDK);
|
||||
self_qmfResidualImag__FDK_0_0[i] = fMult(
|
||||
self_qmfResidualImag__FDK_0_0[i], self->clipProtectGain__FDK);
|
||||
self_qmfResidualReal__FDK_0_0[i] =
|
||||
fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i],
|
||||
self->sacInDataHeadroom - (1)),
|
||||
self->clipProtectGain__FDK);
|
||||
self_qmfResidualImag__FDK_0_0[i] =
|
||||
fMult(scaleValueSaturate(self_qmfResidualImag__FDK_0_0[i],
|
||||
self->sacInDataHeadroom - (1)),
|
||||
self->clipProtectGain__FDK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1416,6 +1422,7 @@ SACDEC_ERROR SpatialDecApplyFrame(
|
|||
FDK_ASSERT(self != NULL);
|
||||
FDK_ASSERT(pControlFlags != NULL);
|
||||
FDK_ASSERT(pcmOutBuf != NULL);
|
||||
FDK_ASSERT(self->sacInDataHeadroom >= (1));
|
||||
|
||||
self->errInt = err; /* Init internal error */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -523,6 +523,9 @@ struct spatialDec_struct {
|
|||
new frame after SSC change (aka
|
||||
decodeAfterConfigHasChangedFlag). */
|
||||
SpatialDecConcealmentInfo concealInfo;
|
||||
|
||||
INT sacInDataHeadroom; /* Headroom of the SAC input time signal to prevent
|
||||
clipping */
|
||||
};
|
||||
|
||||
#define SACDEC_SYNTAX_MPS 1
|
||||
|
|
|
@ -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
|
||||
|
@ -249,10 +249,10 @@ typedef struct {
|
|||
|
||||
} MEM_REQUIREMENTS;
|
||||
|
||||
#define PCM_MPS INT_PCM
|
||||
#define PCM_MPSF FIXP_PCM
|
||||
#define PCM_MPS LONG
|
||||
#define PCM_MPSF FIXP_DBL
|
||||
|
||||
#define FIXP_DBL2PCM_MPS(x) ((INT_PCM)FX_DBL2FX_PCM(x))
|
||||
#define FIXP_DBL2PCM_MPS(x) ((LONG)(x))
|
||||
|
||||
/* exposed functions (library interface) */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -1507,15 +1507,17 @@ bail:
|
|||
}
|
||||
|
||||
int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
||||
INT_PCM *input, PCM_MPS *pTimeData,
|
||||
PCM_MPS *input, PCM_MPS *pTimeData,
|
||||
const int timeDataSize, int timeDataFrameSize,
|
||||
int *nChannels, int *frameSize, int sampleRate,
|
||||
AUDIO_OBJECT_TYPE coreCodec,
|
||||
AUDIO_CHANNEL_TYPE channelType[],
|
||||
UCHAR channelIndices[],
|
||||
const FDK_channelMapDescr *const mapDescr) {
|
||||
const FDK_channelMapDescr *const mapDescr,
|
||||
const INT inDataHeadroom, INT *outDataHeadroom) {
|
||||
SACDEC_ERROR err = MPS_OK;
|
||||
PCM_MPS *pTimeOut = pTimeData;
|
||||
PCM_MPS *TDinput = NULL;
|
||||
UINT initControlFlags = 0, controlFlags = 0;
|
||||
int timeDataRequiredSize = 0;
|
||||
int newData;
|
||||
|
@ -1534,6 +1536,9 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
|||
return MPS_NOTOK;
|
||||
}
|
||||
|
||||
pMpegSurroundDecoder->pSpatialDec->sacInDataHeadroom = inDataHeadroom;
|
||||
*outDataHeadroom = (INT)(8);
|
||||
|
||||
pMpegSurroundDecoder->pSpatialDec->pConfigCurrent =
|
||||
&pMpegSurroundDecoder
|
||||
->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
|
||||
|
@ -1682,8 +1687,7 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
|||
(timeDataFrameSize *
|
||||
pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsSynthesis) /
|
||||
pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis;
|
||||
pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput =
|
||||
pTimeData + timeDataFrameSizeOut - timeDataFrameSize;
|
||||
TDinput = pTimeData + timeDataFrameSizeOut - timeDataFrameSize;
|
||||
for (int i = *nChannels - 1; i >= 0; i--) {
|
||||
FDKmemmove(pTimeData + (i + 1) * timeDataFrameSizeOut - timeDataFrameSize,
|
||||
pTimeData + timeDataFrameSize * i,
|
||||
|
@ -1694,8 +1698,8 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
|||
} else {
|
||||
if (pMpegSurroundDecoder->mpegSurroundUseTimeInterface) {
|
||||
FDKmemcpy(input, pTimeData,
|
||||
sizeof(INT_PCM) * (*nChannels) * (*frameSize));
|
||||
pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput = input;
|
||||
sizeof(PCM_MPS) * (*nChannels) * (*frameSize));
|
||||
TDinput = input;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1707,8 +1711,8 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
|||
&pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode],
|
||||
pMpegSurroundDecoder->mpegSurroundUseTimeInterface ? INPUTMODE_TIME
|
||||
: INPUTMODE_QMF_SBR,
|
||||
pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput, NULL, NULL,
|
||||
pTimeOut, *frameSize, &controlFlags, *nChannels, mapDescr);
|
||||
TDinput, NULL, NULL, pTimeOut, *frameSize, &controlFlags, *nChannels,
|
||||
mapDescr);
|
||||
*nChannels = pMpegSurroundDecoder->pSpatialDec->numOutputChannelsAT;
|
||||
|
||||
if (err !=
|
||||
|
@ -1781,7 +1785,7 @@ void mpegSurroundDecoder_Close(CMpegSurroundDecoder *pMpegSurroundDecoder) {
|
|||
}
|
||||
|
||||
#define SACDEC_VL0 2
|
||||
#define SACDEC_VL1 0
|
||||
#define SACDEC_VL1 1
|
||||
#define SACDEC_VL2 0
|
||||
|
||||
int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) {
|
||||
|
|
|
@ -187,8 +187,12 @@ SACDEC_ERROR SpatialDecQMFAnalysis(spatialDec *self, const PCM_MPS *inData,
|
|||
if (!isTwoChMode(self->upmixType) && !bypassMode) {
|
||||
int i;
|
||||
for (i = 0; i < self->qmfBands; i++) {
|
||||
qmfReal[ch][i] = fMult(qmfReal[ch][i], self->clipProtectGain__FDK);
|
||||
qmfImag[ch][i] = fMult(qmfImag[ch][i], self->clipProtectGain__FDK);
|
||||
qmfReal[ch][i] = fMult(
|
||||
scaleValueSaturate(qmfReal[ch][i], self->sacInDataHeadroom - (1)),
|
||||
self->clipProtectGain__FDK);
|
||||
qmfImag[ch][i] = fMult(
|
||||
scaleValueSaturate(qmfImag[ch][i], self->sacInDataHeadroom - (1)),
|
||||
self->clipProtectGain__FDK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -216,16 +220,17 @@ SACDEC_ERROR SpatialDecFeedQMF(spatialDec *self, FIXP_DBL **qmfInDataReal,
|
|||
|
||||
/* Write Input data to pQmfRealAnalysis. */
|
||||
if (self->bShareDelayWithSBR) {
|
||||
FDK_QmfDomain_GetSlot(
|
||||
&self->pQmfDomain->QmfDomainIn[ch], ts + HYBRID_FILTER_DELAY, 0,
|
||||
MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis, pQmfImagAnalysis, 15);
|
||||
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch],
|
||||
ts + HYBRID_FILTER_DELAY, 0,
|
||||
MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis,
|
||||
pQmfImagAnalysis, 15 + (1));
|
||||
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts,
|
||||
MAX_QMF_BANDS_TO_HYBRID, self->qmfBands,
|
||||
pQmfRealAnalysis, pQmfImagAnalysis, 15);
|
||||
pQmfRealAnalysis, pQmfImagAnalysis, 15 + (1));
|
||||
} else {
|
||||
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts, 0,
|
||||
self->qmfBands, pQmfRealAnalysis,
|
||||
pQmfImagAnalysis, 15);
|
||||
pQmfImagAnalysis, 15 + (1));
|
||||
}
|
||||
if (ts == self->pQmfDomain->globalConf.nQmfTimeSlots - 1) {
|
||||
/* Is currently also needed in case we dont have any overlap. We need to
|
||||
|
@ -501,8 +506,8 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
|
|||
for (pb = 0, qs = 3; pb < 2; pb++) {
|
||||
INT s;
|
||||
FIXP_DBL maxVal;
|
||||
FIXP_SGL mReal1;
|
||||
FIXP_SGL mReal0, mImag0;
|
||||
FIXP_DBL mReal1;
|
||||
FIXP_DBL mReal0, mImag0;
|
||||
FIXP_DBL iReal0, iImag0, iReal1;
|
||||
|
||||
iReal0 = interpolateParameter(alpha, MReal0[pb], MRealPrev0[pb]);
|
||||
|
@ -515,9 +520,9 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
|
|||
s = fMax(CntLeadingZeros(maxVal) - 1, 0);
|
||||
s = fMin(s, scale_param_m2);
|
||||
|
||||
mReal0 = FX_DBL2FX_SGL(iReal0 << s);
|
||||
mImag0 = FX_DBL2FX_SGL(iImag0 << s);
|
||||
mReal1 = FX_DBL2FX_SGL(iReal1 << s);
|
||||
mReal0 = iReal0 << s;
|
||||
mImag0 = iImag0 << s;
|
||||
mReal1 = iReal1 << s;
|
||||
|
||||
s = scale_param_m2 - s;
|
||||
|
||||
|
@ -934,6 +939,7 @@ SACDEC_ERROR SpatialDecSynthesis(spatialDec *self, const INT ts,
|
|||
self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -=
|
||||
self->clipProtectGainSF__FDK;
|
||||
|
||||
self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -= (1);
|
||||
} else {
|
||||
/* Call the QMF synthesis for dry. */
|
||||
err = CalculateSpaceSynthesisQmf(&self->pQmfDomain->QmfDomainOut[outCh],
|
||||
|
|
|
@ -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
|
||||
|
@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de
|
|||
|
||||
SACDEC_ERROR CalculateSpaceSynthesisQmf(
|
||||
const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr,
|
||||
const FIXP_DBL *Si, const INT stride, INT_PCM *timeSig) {
|
||||
const FIXP_DBL *Si, const INT stride, PCM_MPS *timeSig) {
|
||||
SACDEC_ERROR err = MPS_OK;
|
||||
|
||||
if (hQmfDomainOutCh == NULL) {
|
||||
|
|
|
@ -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
|
||||
|
@ -124,7 +124,7 @@ amm-info@iis.fraunhofer.de
|
|||
*/
|
||||
SACDEC_ERROR CalculateSpaceSynthesisQmf(
|
||||
const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr,
|
||||
const FIXP_DBL *Si, const INT stride, INT_PCM *timeSig);
|
||||
const FIXP_DBL *Si, const INT stride, PCM_MPS *timeSig);
|
||||
|
||||
/**
|
||||
* \brief Convert audio input data to qmf representation.
|
||||
|
|
|
@ -253,17 +253,17 @@ static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry,
|
|||
|
||||
dry = wet = FL2FXCONST_DBL(0.0f);
|
||||
for (qs = 0; qs < cplxBands; qs++) {
|
||||
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]) +
|
||||
fPow2Div2(pHybOutputImagDry[qs]));
|
||||
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]) +
|
||||
fPow2Div2(pHybOutputImagWet[qs]));
|
||||
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)) +
|
||||
fPow2Div2(pHybOutputImagDry[qs] << (1)));
|
||||
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)) +
|
||||
fPow2Div2(pHybOutputImagWet[qs] << (1)));
|
||||
}
|
||||
for (; qs < hybBands; qs++) {
|
||||
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]));
|
||||
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]));
|
||||
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)));
|
||||
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)));
|
||||
}
|
||||
*slotAmp_dry = dry;
|
||||
*slotAmp_wet = wet;
|
||||
*slotAmp_dry = dry >> (2 * (1));
|
||||
*slotAmp_wet = wet >> (2 * (1));
|
||||
}
|
||||
|
||||
#if defined(__aarch64__)
|
||||
|
@ -327,7 +327,7 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
|
|||
|
||||
INT shapeActiv = 1;
|
||||
INT hybBands = fixMin(42, self->hybridBands);
|
||||
INT staticScale = self->staticDecScale;
|
||||
INT staticScale = self->staticDecScale + (1);
|
||||
INT cplxBands;
|
||||
cplxBands = fixMin(42, self->hybridBands);
|
||||
|
||||
|
|
|
@ -111,21 +111,12 @@ amm-info@iis.fraunhofer.de
|
|||
#include "machine_type.h"
|
||||
|
||||
/* Global ROM table data type: */
|
||||
#ifndef ARCH_PREFER_MULT_32x32
|
||||
#define FIXP_CFG FIXP_SGL
|
||||
#define FX_CFG2FX_DBL FX_SGL2FX_DBL
|
||||
#define FX_CFG2FX_SGL
|
||||
#define CFG(a) (FX_DBL2FXCONST_SGL(a))
|
||||
#define FL2FXCONST_CFG FL2FXCONST_SGL
|
||||
#define FX_DBL2FX_CFG(x) FX_DBL2FX_SGL((FIXP_DBL)(x))
|
||||
#else
|
||||
#define FIXP_CFG FIXP_DBL
|
||||
#define FX_CFG2FX_DBL
|
||||
#define FX_CFG2FX_SGL FX_DBL2FX_SGL
|
||||
#define CFG(a) FIXP_DBL(a)
|
||||
#define FL2FXCONST_CFG FL2FXCONST_DBL
|
||||
#define FX_DBL2FX_CFG(x) ((FIXP_DBL)(x))
|
||||
#endif
|
||||
|
||||
/* others */
|
||||
#define SCALE_INV_ICC (2)
|
||||
|
@ -133,15 +124,9 @@ amm-info@iis.fraunhofer.de
|
|||
|
||||
#define QCC_SCALE 1
|
||||
#define M1M2_DATA FIXP_DBL
|
||||
#ifndef ARCH_PREFER_MULT_32x32
|
||||
#define M1M2_CDATA FIXP_SGL
|
||||
#define M1M2_CDATA2FX_DBL(a) FX_SGL2FX_DBL(a)
|
||||
#define FX_DBL2M1M2_CDATA(a) FX_DBL2FX_SGL(a)
|
||||
#else
|
||||
#define M1M2_CDATA FIXP_DBL
|
||||
#define M1M2_CDATA2FX_DBL(a) (a)
|
||||
#define FX_DBL2M1M2_CDATA(a) (a)
|
||||
#endif
|
||||
|
||||
#define CLIP_PROTECT_GAIN_0(x) FL2FXCONST_CFG(((x) / (float)(1 << 0)))
|
||||
#define CLIP_PROTECT_GAIN_1(x) FL2FXCONST_CFG(((x) / (float)(1 << 1)))
|
||||
|
|
|
@ -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
|
||||
|
@ -361,15 +361,20 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
|
|||
* error (0: core decoder found errors, 1: no errors).
|
||||
* \param psDecoded Pointer to a buffer holding a flag. Input: PS is
|
||||
* possible, Output: PS has been rendered.
|
||||
* \param inDataHeadroom Headroom of the SBR input time signal to prevent
|
||||
* clipping.
|
||||
* \param outDataHeadroom Pointer to headroom of the SBR output time signal to
|
||||
* prevent clipping.
|
||||
*
|
||||
* \return Error code.
|
||||
*/
|
||||
SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
|
||||
INT_PCM *timeData, const int timeDataSize,
|
||||
int *numChannels, int *sampleRate,
|
||||
SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, LONG *input, LONG *timeData,
|
||||
const int timeDataSize, int *numChannels,
|
||||
int *sampleRate,
|
||||
const FDK_channelMapDescr *const mapDescr,
|
||||
const int mapIdx, const int coreDecodedOk,
|
||||
UCHAR *psDecoded);
|
||||
UCHAR *psDecoded, const INT inDataHeadroom,
|
||||
INT *outDataHeadroom);
|
||||
|
||||
/**
|
||||
* \brief Close SBR decoder instance and free memory.
|
||||
|
|
|
@ -897,10 +897,10 @@ void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal,
|
|||
for (i = startSample; i < stopSample; i++) {
|
||||
maxVal |=
|
||||
(FIXP_DBL)((LONG)(sourceBufferReal[i][loBand]) ^
|
||||
((LONG)sourceBufferReal[i][loBand] >> (SAMPLE_BITS - 1)));
|
||||
((LONG)sourceBufferReal[i][loBand] >> (DFRACT_BITS - 1)));
|
||||
maxVal |=
|
||||
(FIXP_DBL)((LONG)(sourceBufferImag[i][loBand]) ^
|
||||
((LONG)sourceBufferImag[i][loBand] >> (SAMPLE_BITS - 1)));
|
||||
((LONG)sourceBufferImag[i][loBand] >> (DFRACT_BITS - 1)));
|
||||
}
|
||||
|
||||
if (maxVal != FL2FX_DBL(0.0f)) {
|
||||
|
|
|
@ -957,7 +957,7 @@ QmfTransposerCreate(HANDLE_HBE_TRANSPOSER* hQmfTransposer, const int frameSize,
|
|||
hQmfTran->qmfOutBufSize = 2 * (hQmfTran->noCols / 2 + QMF_WIN_LEN - 1);
|
||||
|
||||
hQmfTran->inBuf_F =
|
||||
(INT_PCM*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(INT_PCM));
|
||||
(LONG*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(LONG));
|
||||
/* buffered time signal needs to be delayed by synthesis_size; max
|
||||
* synthesis_size = 20; */
|
||||
if (hQmfTran->inBuf_F == NULL) {
|
||||
|
|
|
@ -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
|
||||
|
@ -132,6 +132,9 @@ typedef enum {
|
|||
} KEEP_STATES_SYNCED_MODE;
|
||||
|
||||
struct hbeTransposer {
|
||||
FIXP_DBL anaQmfStates[HBE_QMF_FILTER_STATE_ANA_SIZE];
|
||||
FIXP_QSS synQmfStates[HBE_QMF_FILTER_STATE_SYN_SIZE];
|
||||
|
||||
int xOverQmf[MAX_NUM_PATCHES_HBE];
|
||||
|
||||
int maxStretch;
|
||||
|
@ -144,7 +147,7 @@ struct hbeTransposer {
|
|||
int stopBand;
|
||||
int bSbr41;
|
||||
|
||||
INT_PCM *inBuf_F;
|
||||
LONG *inBuf_F;
|
||||
FIXP_DBL **qmfInBufReal_F;
|
||||
FIXP_DBL **qmfInBufImag_F;
|
||||
|
||||
|
@ -156,9 +159,6 @@ struct hbeTransposer {
|
|||
FIXP_DBL const *synthesisQmfPreModCos_F;
|
||||
FIXP_DBL const *synthesisQmfPreModSin_F;
|
||||
|
||||
FIXP_QAS anaQmfStates[HBE_QMF_FILTER_STATE_ANA_SIZE];
|
||||
FIXP_QSS synQmfStates[HBE_QMF_FILTER_STATE_SYN_SIZE];
|
||||
|
||||
FIXP_DBL **qmfHBEBufReal_F;
|
||||
FIXP_DBL **qmfHBEBufImag_F;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -259,17 +259,18 @@ static void copyHarmonicSpectrum(int *xOverQmf, FIXP_DBL **qmfReal,
|
|||
|
||||
void sbr_dec(
|
||||
HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
|
||||
INT_PCM *timeIn, /*!< pointer to input time signal */
|
||||
INT_PCM *timeOut, /*!< pointer to output time signal */
|
||||
LONG *timeIn, /*!< pointer to input time signal */
|
||||
LONG *timeOut, /*!< pointer to output time signal */
|
||||
HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */
|
||||
INT_PCM *timeOutRight, /*!< pointer to output time signal */
|
||||
LONG *timeOutRight, /*!< pointer to output time signal */
|
||||
const int strideOut, /*!< Time data traversal strideOut */
|
||||
HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
|
||||
HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
|
||||
HANDLE_SBR_PREV_FRAME_DATA
|
||||
hPrevFrameData, /*!< Some control data of last frame */
|
||||
const int applyProcessing, /*!< Flag for SBR operation */
|
||||
HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize) {
|
||||
HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize,
|
||||
const INT sbrInDataHeadroom) {
|
||||
int i, slot, reserve;
|
||||
int saveLbScale;
|
||||
int lastSlotOffs;
|
||||
|
@ -278,7 +279,7 @@ void sbr_dec(
|
|||
/* temporary pointer / variable for QMF;
|
||||
required as we want to use temporary buffer
|
||||
creating one frame delay for HBE in LP mode */
|
||||
INT_PCM *pTimeInQmf = timeIn;
|
||||
LONG *pTimeInQmf = timeIn;
|
||||
|
||||
/* Number of QMF timeslots in the overlap buffer: */
|
||||
int ov_len = hSbrDec->LppTrans.pSettings->overlap;
|
||||
|
@ -341,8 +342,8 @@ void sbr_dec(
|
|||
} else {
|
||||
C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * (64));
|
||||
qmfAnalysisFiltering(&hSbrDec->qmfDomainInCh->fb, pReal, pImag,
|
||||
&hSbrDec->qmfDomainInCh->scaling, pTimeInQmf, 0, 1,
|
||||
qmfTemp);
|
||||
&hSbrDec->qmfDomainInCh->scaling, pTimeInQmf,
|
||||
0 + sbrInDataHeadroom, 1, qmfTemp);
|
||||
|
||||
C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * (64));
|
||||
}
|
||||
|
@ -658,7 +659,7 @@ void sbr_dec(
|
|||
|
||||
if (!(flags & SBRDEC_PS_DECODED)) {
|
||||
if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
|
||||
int outScalefactor = 0;
|
||||
int outScalefactor = -(8);
|
||||
|
||||
if (h_ps_d != NULL) {
|
||||
h_ps_d->procFrameBased = 1; /* we here do frame based processing */
|
||||
|
@ -743,6 +744,7 @@ void sbr_dec(
|
|||
*/
|
||||
FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <=
|
||||
QMF_MAX_SYNTHESIS_BANDS);
|
||||
qmfChangeOutScalefactor(synQmfRight, -(8));
|
||||
FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates,
|
||||
9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis *
|
||||
sizeof(FIXP_QSS));
|
||||
|
@ -814,7 +816,8 @@ void sbr_dec(
|
|||
: scaleFactorLowBand_no_ov,
|
||||
scaleFactorHighBand, synQmf->lsb, synQmf->usb);
|
||||
|
||||
outScalefactorL = outScalefactorR = 1; /* psDiffScale! (MPEG-PS) */
|
||||
outScalefactorL = outScalefactorR =
|
||||
1 + sbrInDataHeadroom; /* psDiffScale! (MPEG-PS) */
|
||||
}
|
||||
|
||||
sbrDecoder_drcApplySlot(/* right channel */
|
||||
|
@ -831,6 +834,9 @@ void sbr_dec(
|
|||
outScalefactorL += maxShift;
|
||||
|
||||
if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
|
||||
qmfChangeOutScalefactor(synQmf, -(8));
|
||||
qmfChangeOutScalefactor(synQmfRight, -(8));
|
||||
|
||||
qmfSynthesisFilteringSlot(
|
||||
synQmfRight, rQmfReal, /* QMF real buffer */
|
||||
rQmfImag, /* QMF imag buffer */
|
||||
|
|
|
@ -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
|
||||
|
@ -176,17 +176,18 @@ typedef SBR_CHANNEL *HANDLE_SBR_CHANNEL;
|
|||
|
||||
void sbr_dec(
|
||||
HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
|
||||
INT_PCM *timeIn, /*!< pointer to input time signal */
|
||||
INT_PCM *timeOut, /*!< pointer to output time signal */
|
||||
LONG *timeIn, /*!< pointer to input time signal */
|
||||
LONG *timeOut, /*!< pointer to output time signal */
|
||||
HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */
|
||||
INT_PCM *timeOutRight, /*!< pointer to output time signal */
|
||||
LONG *timeOutRight, /*!< pointer to output time signal */
|
||||
INT strideOut, /*!< Time data traversal strideOut */
|
||||
HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
|
||||
HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
|
||||
HANDLE_SBR_PREV_FRAME_DATA
|
||||
hPrevFrameData, /*!< Some control data of last frame */
|
||||
const int applyProcessing, /*!< Flag for SBR operation */
|
||||
HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize);
|
||||
HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize,
|
||||
const INT sbrInDataHeadroom);
|
||||
|
||||
SBR_ERROR
|
||||
createSbrDec(SBR_CHANNEL *hSbrChannel, HANDLE_SBR_HEADER_DATA hHeaderData,
|
||||
|
|
|
@ -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
|
||||
|
@ -170,6 +170,9 @@ struct SBR_DECODER_INSTANCE {
|
|||
flushed consecutively. */
|
||||
|
||||
UINT flags;
|
||||
|
||||
INT sbrInDataHeadroom; /* Headroom of the SBR input time signal to prevent
|
||||
clipping */
|
||||
};
|
||||
|
||||
H_ALLOC_MEM(Ram_SbrDecElement, SBR_DECODER_ELEMENT)
|
||||
|
|
|
@ -155,7 +155,7 @@ amm-info@iis.fraunhofer.de
|
|||
|
||||
/* Decoder library info */
|
||||
#define SBRDECODER_LIB_VL0 3
|
||||
#define SBRDECODER_LIB_VL1 0
|
||||
#define SBRDECODER_LIB_VL1 1
|
||||
#define SBRDECODER_LIB_VL2 0
|
||||
#define SBRDECODER_LIB_TITLE "SBR Decoder"
|
||||
#ifdef __ANDROID__
|
||||
|
@ -1570,10 +1570,10 @@ bail:
|
|||
* \return SBRDEC_OK if successfull, else error code
|
||||
*/
|
||||
static SBR_ERROR sbrDecoder_DecodeElement(
|
||||
HANDLE_SBRDECODER self, QDOM_PCM *input, INT_PCM *timeData,
|
||||
const int timeDataSize, const FDK_channelMapDescr *const mapDescr,
|
||||
const int mapIdx, int channelIndex, const int elementIndex,
|
||||
const int numInChannels, int *numOutChannels, const int psPossible) {
|
||||
HANDLE_SBRDECODER self, LONG *input, LONG *timeData, const int timeDataSize,
|
||||
const FDK_channelMapDescr *const mapDescr, const int mapIdx,
|
||||
int channelIndex, const int elementIndex, const int numInChannels,
|
||||
int *numOutChannels, const int psPossible) {
|
||||
SBR_DECODER_ELEMENT *hSbrElement = self->pSbrElement[elementIndex];
|
||||
HANDLE_SBR_CHANNEL *pSbrChannel =
|
||||
self->pSbrElement[elementIndex]->pSbrChannel;
|
||||
|
@ -1743,7 +1743,7 @@ static SBR_ERROR sbrDecoder_DecodeElement(
|
|||
timeData + offset1, strideOut, hSbrHeader, hFrameDataLeft,
|
||||
&pSbrChannel[0]->prevFrameData,
|
||||
(hSbrHeader->syncState == SBR_ACTIVE), h_ps_d, self->flags,
|
||||
codecFrameSize);
|
||||
codecFrameSize, self->sbrInDataHeadroom);
|
||||
|
||||
if (stereo) {
|
||||
/* Process right channel */
|
||||
|
@ -1751,7 +1751,7 @@ static SBR_ERROR sbrDecoder_DecodeElement(
|
|||
timeData + offset1, NULL, NULL, strideOut, hSbrHeader,
|
||||
hFrameDataRight, &pSbrChannel[1]->prevFrameData,
|
||||
(hSbrHeader->syncState == SBR_ACTIVE), NULL, self->flags,
|
||||
codecFrameSize);
|
||||
codecFrameSize, self->sbrInDataHeadroom);
|
||||
}
|
||||
|
||||
C_ALLOC_SCRATCH_END(pPsScratch, struct PS_DEC_COEFFICIENTS, 1)
|
||||
|
@ -1771,14 +1771,14 @@ static SBR_ERROR sbrDecoder_DecodeElement(
|
|||
int copyFrameSize =
|
||||
codecFrameSize * self->pQmfDomain->QmfDomainOut->fb.no_channels;
|
||||
copyFrameSize /= self->pQmfDomain->QmfDomainIn->fb.no_channels;
|
||||
INT_PCM *ptr;
|
||||
LONG *ptr;
|
||||
INT i;
|
||||
FDK_ASSERT(strideOut == 2);
|
||||
|
||||
ptr = timeData;
|
||||
for (i = copyFrameSize >> 1; i--;) {
|
||||
INT_PCM tmp; /* This temporal variable is required because some
|
||||
compilers can't do *ptr++ = *ptr++ correctly. */
|
||||
LONG tmp; /* This temporal variable is required because some compilers
|
||||
can't do *ptr++ = *ptr++ correctly. */
|
||||
tmp = *ptr++;
|
||||
*ptr++ = tmp;
|
||||
tmp = *ptr++;
|
||||
|
@ -1791,12 +1791,13 @@ static SBR_ERROR sbrDecoder_DecodeElement(
|
|||
return errorStatus;
|
||||
}
|
||||
|
||||
SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
|
||||
INT_PCM *timeData, const int timeDataSize,
|
||||
int *numChannels, int *sampleRate,
|
||||
SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, LONG *input, LONG *timeData,
|
||||
const int timeDataSize, int *numChannels,
|
||||
int *sampleRate,
|
||||
const FDK_channelMapDescr *const mapDescr,
|
||||
const int mapIdx, const int coreDecodedOk,
|
||||
UCHAR *psDecoded) {
|
||||
UCHAR *psDecoded, const INT inDataHeadroom,
|
||||
INT *outDataHeadroom) {
|
||||
SBR_ERROR errorStatus = SBRDEC_OK;
|
||||
|
||||
int psPossible;
|
||||
|
@ -1833,6 +1834,9 @@ SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
|
|||
psPossible = 0;
|
||||
}
|
||||
|
||||
self->sbrInDataHeadroom = inDataHeadroom;
|
||||
*outDataHeadroom = (INT)(8);
|
||||
|
||||
/* Make sure that even if no SBR data was found/parsed *psDecoded is returned
|
||||
* 1 if psPossible was 0. */
|
||||
if (psPossible == 0) {
|
||||
|
|
Loading…
Reference in New Issue