mirror of
https://github.com/mstorsjo/fdk-aac.git
synced 2025-02-14 18:30:39 +01:00
Merge "Merge Android R"
This commit is contained in:
commit
89b6626d5d
2
PREUPLOAD.cfg
Normal file
2
PREUPLOAD.cfg
Normal file
@ -0,0 +1,2 @@
|
||||
[Hook Scripts]
|
||||
mainline_hook = ${REPO_ROOT}/frameworks/av/tools/mainline_hook_project.sh
|
Binary file not shown.
Binary file not shown.
@ -164,9 +164,6 @@ The contents of each file is described in detail in this document. All header
|
||||
files are provided for usage in specific C/C++ programs. The main AAC decoder
|
||||
library API functions are located in aacdecoder_lib.h header file.
|
||||
|
||||
In binary releases the decoder core resides in statically linkable libraries,
|
||||
for example libAACdec.a.
|
||||
|
||||
|
||||
\section Calling_Sequence Calling Sequence
|
||||
|
||||
@ -174,19 +171,7 @@ The following sequence is necessary for proper decoding of ISO/MPEG-2/4 AAC,
|
||||
HE-AAC v2, or MPEG-D USAC bitstreams. In the following description, input stream
|
||||
read and output write function details are left out, since they may be
|
||||
implemented in a variety of configurations depending on the user's specific
|
||||
requirements. The example implementation uses file-based input/output, and in
|
||||
such case one may call mpegFileRead_Open() to open an input file and to allocate
|
||||
memory for the required structures, and the corresponding mpegFileRead_Close()
|
||||
to close opened files and to de-allocate associated structures.
|
||||
mpegFileRead_Open() will attempt to detect the bitstream format and in case of
|
||||
MPEG-4 file format or Raw Packets file format (a proprietary Fraunhofer IIS file
|
||||
format suitable only for testing) it will read the Audio Specific Config data
|
||||
(ASC). An unsuccessful attempt to recognize the bitstream format requires the
|
||||
user to provide this information manually. For any other bitstream formats that
|
||||
are usually applicable in streaming applications, the decoder itself will try to
|
||||
synchronize and parse the given bitstream fragment using the FDK transport
|
||||
library. Hence, for streaming applications (without file access) this step is
|
||||
not necessary.
|
||||
requirements.
|
||||
|
||||
|
||||
-# Call aacDecoder_Open() to open and retrieve a handle to a new AAC decoder
|
||||
@ -205,19 +190,17 @@ do {
|
||||
working memory (a client-supplied input buffer "inBuffer" in framework). This
|
||||
buffer will be used to load AAC bitstream data to the decoder. Only when all
|
||||
data in this buffer has been processed will the decoder signal an empty buffer.
|
||||
For file-based input, you may invoke mpegFileRead_Read() to acquire new
|
||||
bitstream data.
|
||||
-# Call aacDecoder_Fill() to fill the decoder's internal bitstream input buffer
|
||||
with the client-supplied bitstream input buffer. Note, if the data loaded in to
|
||||
the internal buffer is not sufficient to decode a frame,
|
||||
aacDecoder_DecodeFrame() will return ::AAC_DEC_NOT_ENOUGH_BITS until a
|
||||
sufficient amount of data is loaded in to the internal buffer. For streaming
|
||||
formats (ADTS, LOAS), it is acceptable to load more than one frame to the
|
||||
decoder. However, for RAW file format (Fraunhofer IIS proprietary format), only
|
||||
one frame may be loaded to the decoder per aacDecoder_DecodeFrame() call. For
|
||||
least amount of communication delay, fill and decode should be performed on a
|
||||
frame by frame basis. \code ErrorStatus = aacDecoder_Fill(aacDecoderInfo,
|
||||
inBuffer, bytesRead, bytesValid); \endcode
|
||||
decoder. However, for packed based formats, only one frame may be loaded to the
|
||||
decoder per aacDecoder_DecodeFrame() call. For least amount of communication
|
||||
delay, fill and decode should be performed on a frame by frame basis. \code
|
||||
ErrorStatus = aacDecoder_Fill(aacDecoderInfo, inBuffer, bytesRead,
|
||||
bytesValid); \endcode
|
||||
-# Call aacDecoder_DecodeFrame(). This function decodes one frame and writes
|
||||
decoded PCM audio data to a client-supplied buffer. It is the client's
|
||||
responsibility to allocate a buffer which is large enough to hold the decoded
|
||||
@ -225,12 +208,9 @@ output data. \code ErrorStatus = aacDecoder_DecodeFrame(aacDecoderInfo,
|
||||
TimeData, OUT_BUF_SIZE, flags); \endcode If the bitstream configuration (number
|
||||
of channels, sample rate, frame size) is not known a priori, you may call
|
||||
aacDecoder_GetStreamInfo() to retrieve a structure that contains this
|
||||
information. You may use this data to initialize an audio output device. In the
|
||||
example program, if the number of channels or the sample rate has changed since
|
||||
program start or the previously decoded frame, the audio output device is then
|
||||
re-initialized. If WAVE file output is chosen, a new WAVE file for each new
|
||||
stream configuration is be created. \code p_si =
|
||||
aacDecoder_GetStreamInfo(aacDecoderInfo); \endcode
|
||||
information. You may use this data to initialize an audio output device. \code
|
||||
p_si = aacDecoder_GetStreamInfo(aacDecoderInfo);
|
||||
\endcode
|
||||
-# Repeat steps 5 to 7 until no data is available to decode any more, or in case
|
||||
of error. \code } while (bytesRead[0] > 0 || doFlush || doBsFlush ||
|
||||
forceContinue); \endcode
|
||||
@ -239,7 +219,7 @@ structures. \code aacDecoder_Close(aacDecoderInfo); \endcode
|
||||
|
||||
\image latex decode.png "Decode calling sequence" width=11cm
|
||||
|
||||
\image latex change_source.png "Change data source sequence" width 5cm
|
||||
\image latex change_source.png "Change data source sequence" width=5cm
|
||||
|
||||
\image latex conceal.png "Error concealment sequence" width=14cm
|
||||
|
||||
@ -296,16 +276,14 @@ input buffer, and one to hold the decoded output PCM sample data. In resource
|
||||
limited applications, the output buffer may be reused as an external input
|
||||
buffer prior to the subsequence aacDecoder_Fill() function call.
|
||||
|
||||
The external input buffer is set in the example program and its size is defined
|
||||
by ::IN_BUF_SIZE. You may freely choose different buffer sizes. To feed the data
|
||||
to the decoder-internal input buffer, use the function aacDecoder_Fill(). This
|
||||
function returns important information regarding the number of bytes in the
|
||||
external input buffer that have not yet been copied into the internal input
|
||||
buffer (variable bytesValid). Once the external buffer has been fully copied, it
|
||||
can be completely re-filled again. In case you wish to refill the buffer while
|
||||
there are unprocessed bytes (bytesValid is unequal 0), you should preserve the
|
||||
unconsumed data. However, we recommend to refill the buffer only when bytesValid
|
||||
returns 0.
|
||||
To feed the data to the decoder-internal input buffer, use the
|
||||
function aacDecoder_Fill(). This function returns important information
|
||||
regarding the number of bytes in the external input buffer that have not yet
|
||||
been copied into the internal input buffer (variable bytesValid). Once the
|
||||
external buffer has been fully copied, it can be completely re-filled again. In
|
||||
case you wish to refill the buffer while there are unprocessed bytes (bytesValid
|
||||
is unequal 0), you should preserve the unconsumed data. However, we recommend to
|
||||
refill the buffer only when bytesValid returns 0.
|
||||
|
||||
The bytesValid parameter is an input and output parameter to the FDK decoder. As
|
||||
an input, it signals how many valid bytes are available in the external buffer.
|
||||
@ -340,10 +318,7 @@ explanation, please refer to ISO/IEC 13818-7:2005(E), chapter 8.5.3.2.
|
||||
In case a Program Config is included in the audio configuration, the channel
|
||||
mapping described within it will be adopted.
|
||||
|
||||
In case of MPEG-D Surround the channel mapping will follow the same criteria
|
||||
described in ISO/IEC 13818-7:2005(E), but adding corresponding top channels (if
|
||||
available) to the channel types in order to avoid ambiguity. The examples below
|
||||
explain these aspects in detail.
|
||||
The examples below explain these aspects in detail.
|
||||
|
||||
\section OutputFormatChange Changing the audio output format
|
||||
|
||||
@ -689,9 +664,7 @@ typedef enum {
|
||||
2. If the parameter value is greater than that of
|
||||
::AAC_PCM_MAX_OUTPUT_CHANNELS both will be set to the same
|
||||
value. \n
|
||||
3. This parameter does not affect MPEG Surround processing.
|
||||
\n
|
||||
4. This parameter will be ignored if the number of encoded
|
||||
3. This parameter will be ignored if the number of encoded
|
||||
audio channels is greater than 8. */
|
||||
AAC_PCM_MAX_OUTPUT_CHANNELS =
|
||||
0x0012, /*!< Maximum number of PCM output channels. If lower than the
|
||||
@ -718,11 +691,7 @@ typedef enum {
|
||||
2. If the parameter value is greater than zero but smaller
|
||||
than ::AAC_PCM_MIN_OUTPUT_CHANNELS both will be set to same
|
||||
value. \n
|
||||
3. The operating mode of the MPEG Surround module will be
|
||||
set accordingly. \n
|
||||
4. Setting this parameter with any value will disable the
|
||||
binaural processing of the MPEG Surround module
|
||||
5. This parameter will be ignored if the number of encoded
|
||||
3. This parameter will be ignored if the number of encoded
|
||||
audio channels is greater than 8. */
|
||||
AAC_METADATA_PROFILE =
|
||||
0x0020, /*!< See ::AAC_MD_PROFILE for all available values. */
|
||||
@ -803,11 +772,11 @@ typedef enum {
|
||||
sequences for fading in and out, if provided in the
|
||||
bitstream.\n Enabled album mode makes use of dedicated album
|
||||
loudness information, if provided in the bitstream.\n */
|
||||
AAC_QMF_LOWPOWER = 0x0300, /*!< Quadrature Mirror Filter (QMF) Bank processing
|
||||
mode. \n -1: Use internal default. Implies MPEG
|
||||
Surround partially complex accordingly. \n 0:
|
||||
Use complex QMF data mode. \n 1: Use real (low
|
||||
power) QMF data mode. \n */
|
||||
AAC_QMF_LOWPOWER =
|
||||
0x0300, /*!< Quadrature Mirror Filter (QMF) Bank processing mode. \n
|
||||
-1: Use internal default. \n
|
||||
0: Use complex QMF data mode. \n
|
||||
1: Use real (low power) QMF data mode. \n */
|
||||
AAC_TPDEC_CLEAR_BUFFER =
|
||||
0x0603 /*!< Clear internal bit stream buffer of transport layers. The
|
||||
decoder will start decoding at new data passed after this event
|
||||
@ -901,6 +870,16 @@ typedef struct {
|
||||
metadata found in the bitstream \n 0: DRC presentation
|
||||
mode not indicated \n 1: DRC presentation mode 1 \n 2:
|
||||
DRC presentation mode 2 \n 3: Reserved */
|
||||
INT outputLoudness; /*!< Audio output loudness in steps of -0.25 dB. Range: 0
|
||||
(0 dBFS) to 231 (-57.75 dBFS).\n A value of -1
|
||||
indicates that no loudness metadata is present.\n If
|
||||
loudness normalization is active, the value corresponds
|
||||
to the target loudness value set with
|
||||
::AAC_DRC_REFERENCE_LEVEL.\n If loudness normalization
|
||||
is not active, the output loudness value corresponds to
|
||||
the loudness metadata given in the bitstream.\n
|
||||
Loudness metadata can originate from MPEG-4 DRC or
|
||||
MPEG-D DRC. */
|
||||
|
||||
} CStreamInfo;
|
||||
|
||||
@ -1028,21 +1007,24 @@ LINKSPEC_H AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self,
|
||||
const UINT bufferSize[],
|
||||
UINT *bytesValid);
|
||||
|
||||
#define AACDEC_CONCEAL \
|
||||
1 /*!< Flag for aacDecoder_DecodeFrame(): Trigger the built-in error \
|
||||
concealment module to generate a substitute signal for one lost frame. \
|
||||
New input data will not be considered. */
|
||||
#define AACDEC_FLUSH \
|
||||
2 /*!< Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all \
|
||||
delayed audio without having new input data. Thus new input data will \
|
||||
not be considered.*/
|
||||
#define AACDEC_INTR \
|
||||
4 /*!< Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data \
|
||||
discontinuity. Resync any internals as necessary. */
|
||||
#define AACDEC_CLRHIST \
|
||||
8 /*!< Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and \
|
||||
history buffers. CAUTION: This can cause discontinuities in the output \
|
||||
signal. */
|
||||
/** Flag for aacDecoder_DecodeFrame(): Trigger the built-in error concealment
|
||||
* module to generate a substitute signal for one lost frame. New input data
|
||||
* will not be considered.
|
||||
*/
|
||||
#define AACDEC_CONCEAL 1
|
||||
/** Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all delayed
|
||||
* audio without having new input data. Thus new input data will not be
|
||||
* considered.
|
||||
*/
|
||||
#define AACDEC_FLUSH 2
|
||||
/** Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data
|
||||
* discontinuity. Resync any internals as necessary.
|
||||
*/
|
||||
#define AACDEC_INTR 4
|
||||
/** Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and history
|
||||
* buffers. CAUTION: This can cause discontinuities in the output signal.
|
||||
*/
|
||||
#define AACDEC_CLRHIST 8
|
||||
|
||||
/**
|
||||
* \brief Decode one audio frame
|
||||
|
@ -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
|
||||
@ -105,12 +105,7 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
#define WORKBUFFER1_TAG 0
|
||||
#define WORKBUFFER2_TAG 1
|
||||
|
||||
#define WORKBUFFER3_TAG 4
|
||||
#define WORKBUFFER4_TAG 5
|
||||
|
||||
#define WORKBUFFER5_TAG 6
|
||||
|
||||
#define WORKBUFFER6_TAG 7
|
||||
|
||||
/*! The structure AAC_DECODER_INSTANCE is the top level structure holding all
|
||||
@ -169,9 +164,6 @@ C_ALLOC_MEM2(TimeDataFlush, INT_PCM, TIME_DATA_FLUSH_SIZE, (8))
|
||||
C_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL, ((8) * 1024), SECT_DATA_L2,
|
||||
WORKBUFFER2_TAG)
|
||||
|
||||
C_ALLOC_MEM_OVERLAY(WorkBufferCore3, FIXP_DBL, WB_SECTION_SIZE, SECT_DATA_L2,
|
||||
WORKBUFFER3_TAG)
|
||||
C_AALLOC_MEM(WorkBufferCore4, FIXP_DBL, WB_SECTION_SIZE)
|
||||
C_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR,
|
||||
fMax((INT)(sizeof(FIXP_DBL) * WB_SECTION_SIZE),
|
||||
(INT)sizeof(CAacDecoderCommonData)),
|
||||
|
@ -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
|
||||
@ -136,12 +136,7 @@ H_ALLOC_MEM(TimeDataFlush, INT_PCM)
|
||||
|
||||
H_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1)
|
||||
H_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL)
|
||||
|
||||
H_ALLOC_MEM_OVERLAY(WorkBufferCore3, FIXP_DBL)
|
||||
H_ALLOC_MEM(WorkBufferCore4, FIXP_DBL)
|
||||
|
||||
H_ALLOC_MEM_OVERLAY(WorkBufferCore5, PCM_DEC)
|
||||
|
||||
H_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR)
|
||||
|
||||
#endif /* #ifndef AAC_RAM_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
|
||||
@ -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
|
||||
|
@ -149,6 +149,20 @@ static INT convert_drcParam(FIXP_DBL param_dbl) {
|
||||
return (INT)param_long;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Reset DRC information
|
||||
|
||||
\self Handle of DRC info
|
||||
|
||||
\return none
|
||||
*/
|
||||
void aacDecoder_drcReset(HANDLE_AAC_DRC self) {
|
||||
self->applyExtGain = 0;
|
||||
self->additionalGainPrev = AACDEC_DRC_GAIN_INIT_VALUE;
|
||||
self->additionalGainFilterState = AACDEC_DRC_GAIN_INIT_VALUE;
|
||||
self->additionalGainFilterState1 = AACDEC_DRC_GAIN_INIT_VALUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Initialize DRC information
|
||||
|
||||
@ -176,7 +190,6 @@ void aacDecoder_drcInit(HANDLE_AAC_DRC self) {
|
||||
pParams->usrBoost = FL2FXCONST_DBL(0.0f);
|
||||
pParams->targetRefLevel = 96;
|
||||
pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES;
|
||||
pParams->applyDigitalNorm = ON;
|
||||
pParams->applyHeavyCompression = OFF;
|
||||
pParams->usrApplyHeavyCompression = OFF;
|
||||
|
||||
@ -192,6 +205,8 @@ void aacDecoder_drcInit(HANDLE_AAC_DRC self) {
|
||||
self->progRefLevelPresent = 0;
|
||||
self->presMode = -1;
|
||||
self->uniDrcPrecedence = 0;
|
||||
|
||||
aacDecoder_drcReset(self);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -258,11 +273,8 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self,
|
||||
return AAC_DEC_INVALID_HANDLE;
|
||||
}
|
||||
if (value < 0) {
|
||||
self->params.applyDigitalNorm = OFF;
|
||||
self->params.targetRefLevel = -1;
|
||||
} else {
|
||||
/* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */
|
||||
self->params.applyDigitalNorm = ON;
|
||||
if (self->params.targetRefLevel != (SCHAR)value) {
|
||||
self->params.targetRefLevel = (SCHAR)value;
|
||||
self->progRefLevel = (SCHAR)value; /* Always set the program reference
|
||||
@ -273,16 +285,6 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self,
|
||||
self->update = 1;
|
||||
}
|
||||
break;
|
||||
case APPLY_NORMALIZATION:
|
||||
if ((value != OFF) && (value != ON)) {
|
||||
return AAC_DEC_SET_PARAM_FAIL;
|
||||
}
|
||||
if (self == NULL) {
|
||||
return AAC_DEC_INVALID_HANDLE;
|
||||
}
|
||||
/* Store new parameter value */
|
||||
self->params.applyDigitalNorm = (UCHAR)value;
|
||||
break;
|
||||
case APPLY_HEAVY_COMPRESSION:
|
||||
if ((value != OFF) && (value != ON)) {
|
||||
return AAC_DEC_SET_PARAM_FAIL;
|
||||
@ -910,11 +912,9 @@ void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec,
|
||||
FDK_ASSERT(0);
|
||||
}
|
||||
}
|
||||
if (self->params.applyDigitalNorm == OFF) {
|
||||
/* Reset normalization gain since this module must not apply it */
|
||||
norm_mantissa = FL2FXCONST_DBL(0.5f);
|
||||
norm_exponent = 1;
|
||||
}
|
||||
|
||||
/* calc scale factors */
|
||||
for (band = 0; band < numBands; band++) {
|
||||
@ -1353,3 +1353,152 @@ void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Apply DRC Level Normalization.
|
||||
*
|
||||
* This function prepares/applies the gain values for the DRC Level
|
||||
* Normalization and returns the exponent of the time data. The following two
|
||||
* cases are handled:
|
||||
*
|
||||
* - Limiter enabled:
|
||||
* The input data must be interleaved.
|
||||
* One gain per sample is written to the buffer pGainPerSample.
|
||||
* If necessary the time data is rescaled.
|
||||
*
|
||||
* - Limiter disabled:
|
||||
* The input data can be interleaved or deinterleaved.
|
||||
* The gain values are applied to the time data.
|
||||
* If necessary the time data is rescaled.
|
||||
*
|
||||
* \param hDrcInfo [i/o] handle to drc data structure.
|
||||
* \param samplesIn [i/o] pointer to time data.
|
||||
* \param pGain [i ] pointer to gain to be applied to
|
||||
* the time data.
|
||||
* \param pGainPerSample [o ] pointer to the gain per sample to
|
||||
* be applied to the time data in the limiter.
|
||||
* \param gain_scale [i ] exponent to be applied to the time
|
||||
* data.
|
||||
* \param gain_delay [i ] delay[samples] with which the gains
|
||||
* in pGain shall be applied (gain_delay <= nSamples).
|
||||
* \param nSamples [i ] number of samples per frame.
|
||||
* \param channels [i ] number of channels.
|
||||
* \param stride [i ] channel stride of time data.
|
||||
* \param limiterEnabled [i ] 1 if limiter is enabled, otherwise
|
||||
* 0.
|
||||
*
|
||||
* \return exponent of time data
|
||||
*/
|
||||
INT applyDrcLevelNormalization(HANDLE_AAC_DRC hDrcInfo, PCM_DEC *samplesIn,
|
||||
FIXP_DBL *pGain, FIXP_DBL *pGainPerSample,
|
||||
const INT gain_scale, const UINT gain_delay,
|
||||
const UINT nSamples, const UINT channels,
|
||||
const UINT stride, const UINT limiterEnabled) {
|
||||
UINT i;
|
||||
INT additionalGain_scaling;
|
||||
FIXP_DBL additionalGain;
|
||||
|
||||
FDK_ASSERT(gain_delay <= nSamples);
|
||||
|
||||
FIXP_DBL additionalGainSmoothState = hDrcInfo->additionalGainFilterState;
|
||||
FIXP_DBL additionalGainSmoothState1 = hDrcInfo->additionalGainFilterState1;
|
||||
|
||||
if (!gain_delay) {
|
||||
additionalGain = pGain[0];
|
||||
|
||||
/* Apply the additional scaling gain_scale[0] that has no delay and no
|
||||
* smoothing */
|
||||
additionalGain_scaling =
|
||||
fMin(gain_scale, CntLeadingZeros(additionalGain) - 1);
|
||||
additionalGain = scaleValue(additionalGain, additionalGain_scaling);
|
||||
|
||||
/* if it's not possible to fully apply gain_scale to additionalGain, apply
|
||||
* it to the input signal */
|
||||
additionalGain_scaling -= gain_scale;
|
||||
|
||||
if (additionalGain_scaling) {
|
||||
scaleValuesSaturate(samplesIn, channels * nSamples,
|
||||
-additionalGain_scaling);
|
||||
}
|
||||
|
||||
if (limiterEnabled) {
|
||||
FDK_ASSERT(pGainPerSample != NULL);
|
||||
|
||||
for (i = 0; i < nSamples; i++) {
|
||||
pGainPerSample[i] = additionalGain;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < channels * nSamples; i++) {
|
||||
samplesIn[i] = FIXP_DBL2PCM_DEC(fMult(samplesIn[i], additionalGain));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
UINT inc;
|
||||
FIXP_DBL additionalGainUnfiltered;
|
||||
|
||||
inc = (stride == 1) ? channels : 1;
|
||||
|
||||
for (i = 0; i < nSamples; i++) {
|
||||
if (i < gain_delay) {
|
||||
additionalGainUnfiltered = hDrcInfo->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 gain_scale[0] that has no delay and no
|
||||
* smoothing */
|
||||
additionalGain_scaling =
|
||||
fMin(gain_scale, CntLeadingZeros(additionalGain) - 1);
|
||||
additionalGain = scaleValue(additionalGain, additionalGain_scaling);
|
||||
|
||||
/* if it's not possible to fully apply gain_scale[0] to additionalGain,
|
||||
* apply it to the input signal */
|
||||
additionalGain_scaling -= gain_scale;
|
||||
|
||||
if (limiterEnabled) {
|
||||
FDK_ASSERT(stride == 1);
|
||||
FDK_ASSERT(pGainPerSample != NULL);
|
||||
|
||||
if (additionalGain_scaling) {
|
||||
scaleValuesSaturate(samplesIn, channels, -additionalGain_scaling);
|
||||
}
|
||||
|
||||
pGainPerSample[i] = additionalGain;
|
||||
} else {
|
||||
if (additionalGain_scaling) {
|
||||
for (UINT k = 0; k < channels; k++) {
|
||||
scaleValuesSaturate(&samplesIn[k * stride], 1,
|
||||
-additionalGain_scaling);
|
||||
}
|
||||
}
|
||||
|
||||
for (UINT k = 0; k < channels; k++) {
|
||||
samplesIn[k * stride] =
|
||||
FIXP_DBL2PCM_DEC(fMult(samplesIn[k * stride], additionalGain));
|
||||
}
|
||||
}
|
||||
|
||||
samplesIn += inc;
|
||||
}
|
||||
}
|
||||
|
||||
hDrcInfo->additionalGainPrev = pGain[0];
|
||||
hDrcInfo->additionalGainFilterState = additionalGainSmoothState;
|
||||
hDrcInfo->additionalGainFilterState1 = additionalGainSmoothState1;
|
||||
|
||||
return (AACDEC_DRC_GAIN_SCALING);
|
||||
}
|
||||
|
@ -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,6 +109,11 @@ amm-info@iis.fraunhofer.de
|
||||
#include "channel.h"
|
||||
#include "FDK_bitstream.h"
|
||||
|
||||
#define AACDEC_DRC_GAIN_SCALING (11) /* Scaling of DRC gains */
|
||||
#define AACDEC_DRC_GAIN_INIT_VALUE \
|
||||
(FL2FXCONST_DBL( \
|
||||
1.0f / (1 << AACDEC_DRC_GAIN_SCALING))) /* Init value for DRC gains */
|
||||
|
||||
#define AACDEC_DRC_DFLT_EXPIRY_FRAMES \
|
||||
(0) /* Default DRC data expiry time in AAC frames */
|
||||
|
||||
@ -125,7 +130,6 @@ typedef enum {
|
||||
TARGET_REF_LEVEL,
|
||||
DRC_BS_DELAY,
|
||||
DRC_DATA_EXPIRY_FRAME,
|
||||
APPLY_NORMALIZATION,
|
||||
APPLY_HEAVY_COMPRESSION,
|
||||
DEFAULT_PRESENTATION_MODE,
|
||||
ENCODER_TARGET_LEVEL,
|
||||
@ -136,6 +140,8 @@ typedef enum {
|
||||
/**
|
||||
* \brief DRC module interface functions
|
||||
*/
|
||||
void aacDecoder_drcReset(HANDLE_AAC_DRC self);
|
||||
|
||||
void aacDecoder_drcInit(HANDLE_AAC_DRC self);
|
||||
|
||||
void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChannel);
|
||||
@ -189,4 +195,45 @@ int aacDecoder_drcEpilog(
|
||||
void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
|
||||
SCHAR *pProgRefLevel);
|
||||
|
||||
/**
|
||||
* \brief Apply DRC Level Normalization.
|
||||
*
|
||||
* This function prepares/applies the gain values for the DRC Level
|
||||
* Normalization and returns the exponent of the time data. The following two
|
||||
* cases are handled:
|
||||
*
|
||||
* - Limiter enabled:
|
||||
* The input data must be interleaved.
|
||||
* One gain per sample is written to the buffer pGainPerSample.
|
||||
* If necessary the time data is rescaled.
|
||||
*
|
||||
* - Limiter disabled:
|
||||
* The input data can be interleaved or deinterleaved.
|
||||
* The gain values are applied to the time data.
|
||||
* If necessary the time data is rescaled.
|
||||
*
|
||||
* \param hDrcInfo [i/o] handle to drc data structure.
|
||||
* \param samplesIn [i/o] pointer to time data.
|
||||
* \param pGain [i ] pointer to gain to be applied to
|
||||
* the time data.
|
||||
* \param pGainPerSample [o ] pointer to the gain per sample to
|
||||
* be applied to the time data in the limiter.
|
||||
* \param gain_scale [i ] exponent to be applied to the time
|
||||
* data.
|
||||
* \param gain_delay [i ] delay[samples] with which the gains
|
||||
* in pGain shall be applied (gain_delay <= nSamples).
|
||||
* \param nSamples [i ] number of samples per frame.
|
||||
* \param channels [i ] number of channels.
|
||||
* \param stride [i ] channel stride of time data.
|
||||
* \param limiterEnabled [i ] 1 if limiter is enabled, otherwise
|
||||
* 0.
|
||||
*
|
||||
* \return exponent of time data
|
||||
*/
|
||||
INT applyDrcLevelNormalization(HANDLE_AAC_DRC hDrcInfo, PCM_DEC *samplesIn,
|
||||
FIXP_DBL *pGain, FIXP_DBL *pGainPerSample,
|
||||
const INT gain_scale, const UINT gain_delay,
|
||||
const UINT nSamples, const UINT channels,
|
||||
const UINT stride, const UINT limiterEnabled);
|
||||
|
||||
#endif /* AACDEC_DRC_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
|
||||
@ -168,7 +168,6 @@ typedef struct {
|
||||
|
||||
UINT expiryFrame;
|
||||
UCHAR bsDelayEnable;
|
||||
UCHAR applyDigitalNorm;
|
||||
|
||||
AACDEC_DRC_PARAMETER_HANDLING defaultPresentationMode;
|
||||
UCHAR encoderTargetLevel;
|
||||
@ -213,6 +212,13 @@ typedef struct {
|
||||
uniDrcPrecedence; /* Flag for signalling that uniDrc is active and takes
|
||||
precedence over legacy DRC */
|
||||
|
||||
UCHAR applyExtGain; /* Flag is 1 if extGain has to be applied, otherwise 0. */
|
||||
|
||||
FIXP_DBL additionalGainPrev; /* Gain of previous frame to be applied to the
|
||||
time data */
|
||||
FIXP_DBL additionalGainFilterState; /* Filter state for the gain smoothing */
|
||||
FIXP_DBL additionalGainFilterState1; /* Filter state for the gain smoothing */
|
||||
|
||||
} CDrcInfo;
|
||||
|
||||
typedef CDrcInfo *HANDLE_AAC_DRC;
|
||||
|
@ -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
|
||||
@ -137,7 +137,7 @@ static void DeriveNumberOfExtendedSortedSectionsInSets(
|
||||
static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
||||
INT quantSpecCoef, INT *pLeftStartOfSegment,
|
||||
SCHAR *pRemainingBitsInSegment,
|
||||
int *pNumDecodedBits);
|
||||
int *pNumDecodedBits, UINT *errorWord);
|
||||
|
||||
static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
||||
UINT codebookDim, const SCHAR *pQuantVal,
|
||||
@ -1179,8 +1179,8 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
|
||||
bs, pHcr->decInOut.bitstreamAnchor,
|
||||
pQuantizedSpectralCoefficients
|
||||
[quantizedSpectralCoefficientsIdx],
|
||||
pLeftStartOfSegment, pRemainingBitsInSegment,
|
||||
&numDecodedBits);
|
||||
pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits,
|
||||
&pHcr->decInOut.errorLog);
|
||||
}
|
||||
quantizedSpectralCoefficientsIdx++;
|
||||
if (quantizedSpectralCoefficientsIdx >= 1024) {
|
||||
@ -1195,8 +1195,8 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
|
||||
bs, pHcr->decInOut.bitstreamAnchor,
|
||||
pQuantizedSpectralCoefficients
|
||||
[quantizedSpectralCoefficientsIdx],
|
||||
pLeftStartOfSegment, pRemainingBitsInSegment,
|
||||
&numDecodedBits);
|
||||
pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits,
|
||||
&pHcr->decInOut.errorLog);
|
||||
}
|
||||
quantizedSpectralCoefficientsIdx++;
|
||||
if (quantizedSpectralCoefficientsIdx >= 1024) {
|
||||
@ -1386,7 +1386,7 @@ value == 16, a escapeSequence is decoded in two steps:
|
||||
static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
||||
INT quantSpecCoef, INT *pLeftStartOfSegment,
|
||||
SCHAR *pRemainingBitsInSegment,
|
||||
int *pNumDecodedBits) {
|
||||
int *pNumDecodedBits, UINT *errorWord) {
|
||||
UINT i;
|
||||
INT sign;
|
||||
UINT escapeOnesCounter = 0;
|
||||
@ -1400,6 +1400,9 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
||||
FROM_LEFT_TO_RIGHT);
|
||||
*pRemainingBitsInSegment -= 1;
|
||||
*pNumDecodedBits += 1;
|
||||
if (*pRemainingBitsInSegment < 0) {
|
||||
return Q_VALUE_INVALID;
|
||||
}
|
||||
|
||||
if (carryBit != 0) {
|
||||
escapeOnesCounter += 1;
|
||||
@ -1416,6 +1419,9 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
||||
FROM_LEFT_TO_RIGHT);
|
||||
*pRemainingBitsInSegment -= 1;
|
||||
*pNumDecodedBits += 1;
|
||||
if (*pRemainingBitsInSegment < 0) {
|
||||
return Q_VALUE_INVALID;
|
||||
}
|
||||
|
||||
escape_word <<= 1;
|
||||
escape_word = escape_word | carryBit;
|
||||
@ -1423,8 +1429,12 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
||||
|
||||
sign = (quantSpecCoef >= 0) ? 1 : -1;
|
||||
|
||||
if (escapeOnesCounter < 13) {
|
||||
quantSpecCoef = sign * (((INT)1 << escapeOnesCounter) + escape_word);
|
||||
|
||||
} else {
|
||||
*errorWord |= TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED;
|
||||
quantSpecCoef = Q_VALUE_INVALID;
|
||||
}
|
||||
return quantSpecCoef;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -1324,6 +1324,10 @@ UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM bs, void *ptr) {
|
||||
/* count ones and store sum in escapePrefixUp */
|
||||
if (carryBit == 1) {
|
||||
escapePrefixUp += 1; /* update conter for ones */
|
||||
if (escapePrefixUp > 8) {
|
||||
pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX;
|
||||
return BODY_SIGN_ESC__ESC_PREFIX;
|
||||
}
|
||||
|
||||
/* store updated counter in sideinfo of current codeword */
|
||||
pEscapeSequenceInfo[codewordOffset] &=
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -1225,6 +1225,8 @@ static void CStreamInfoInit(CStreamInfo *pStreamInfo) {
|
||||
pStreamInfo->drcProgRefLev =
|
||||
-1; /* set program reference level to not indicated */
|
||||
pStreamInfo->drcPresMode = -1; /* default: presentation mode not indicated */
|
||||
|
||||
pStreamInfo->outputLoudness = -1; /* default: no loudness metadata present */
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1279,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;
|
||||
@ -1303,7 +1306,8 @@ static void CAacDecoder_DeInit(HANDLE_AACDECODER self,
|
||||
const int subStreamIndex) {
|
||||
int ch;
|
||||
int aacChannelOffset = 0, aacChannels = (8);
|
||||
int numElements = (((8)) + (8)), elementOffset = 0;
|
||||
int numElements = (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1),
|
||||
elementOffset = 0;
|
||||
|
||||
if (self == NULL) return;
|
||||
|
||||
@ -1453,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);
|
||||
@ -1490,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)
|
||||
@ -1847,6 +1857,12 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
|
||||
self->streamInfo.extSamplingRate / self->downscaleFactor;
|
||||
}
|
||||
}
|
||||
if ((asc->m_aot == AOT_AAC_LC) && (asc->m_sbrPresentFlag == 1) &&
|
||||
(asc->m_extensionSamplingFrequency > (2 * asc->m_samplingFrequency))) {
|
||||
return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* Core decoder supports at most a
|
||||
1:2 upsampling for HE-AAC and
|
||||
HE-AACv2 */
|
||||
}
|
||||
|
||||
/* --------- vcb11 ------------ */
|
||||
self->flags[streamIndex] |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0;
|
||||
@ -1928,6 +1944,9 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
|
||||
self->samplingRateInfo[0].samplingRate / self->downscaleFactor;
|
||||
self->streamInfo.aacSamplesPerFrame =
|
||||
asc->m_samplesPerFrame / self->downscaleFactor;
|
||||
if (self->streamInfo.aacSampleRate <= 0) {
|
||||
return AAC_DEC_UNSUPPORTED_SAMPLINGRATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2362,6 +2381,13 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (*configChanged) {
|
||||
if (asc->m_aot == AOT_USAC) {
|
||||
self->hDrcInfo->enable = 0;
|
||||
self->hDrcInfo->progRefLevelPresent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (asc->m_aot == AOT_USAC) {
|
||||
pcmLimiter_SetAttack(self->hLimiter, (5));
|
||||
pcmLimiter_SetThreshold(self->hLimiter, FL2FXCONST_DBL(0.89125094f));
|
||||
@ -2375,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;
|
||||
|
||||
@ -3151,11 +3177,6 @@ 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);
|
||||
|
||||
/* deactivate legacy DRC in case uniDrc is active, i.e. uniDrc payload is
|
||||
* present and one of DRC or Loudness Normalization is switched on */
|
||||
aacDecoder_drcSetParam(
|
||||
@ -3168,9 +3189,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
||||
self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
|
||||
pce->ElementInstanceTag, drcChMap, aacChannels);
|
||||
if (mapped > 0) {
|
||||
/* If at least one DRC thread has been mapped to a channel threre was DRC
|
||||
if (!(self->flags[streamIndex] & (AC_USAC | AC_RSV603DA))) {
|
||||
/* If at least one DRC thread has been mapped to a channel there was DRC
|
||||
* data in the bitstream. */
|
||||
self->flags[streamIndex] |= AC_DRC_PRESENT;
|
||||
} else {
|
||||
self->hDrcInfo->enable = 0;
|
||||
self->hDrcInfo->progRefLevelPresent = 0;
|
||||
ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a reverse mapping table */
|
||||
@ -3300,9 +3327,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,
|
||||
@ -3318,7 +3347,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:
|
||||
@ -3330,7 +3359,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;
|
||||
@ -3351,7 +3380,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;
|
||||
@ -3363,7 +3392,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 */
|
||||
@ -3385,22 +3415,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
||||
if ((aacChannels == 2) && bsPseudoLr) {
|
||||
int i, offset2;
|
||||
const FIXP_SGL invSqrt2 = FL2FXCONST_SGL(0.707106781186547f);
|
||||
FIXP_PCM *pTD = pTimeData;
|
||||
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] = FX_DBL2FX_PCM(fAddSaturate(L + R, (FIXP_DBL)0x8000));
|
||||
pTD[offset2] = FX_DBL2FX_PCM(fAddSaturate(L - R, (FIXP_DBL)0x8000));
|
||||
#else
|
||||
pTD[0] = FX_DBL2FX_PCM(L + R);
|
||||
pTD[offset2] = FX_DBL2FX_PCM(L - R);
|
||||
#endif
|
||||
pTD[0] = L + R;
|
||||
pTD[offset2] = L - R;
|
||||
pTD++;
|
||||
}
|
||||
}
|
||||
@ -3411,9 +3436,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
||||
self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
|
||||
pce->ElementInstanceTag, drcChMap, aacChannels);
|
||||
if (mapped > 0) {
|
||||
/* If at least one DRC thread has been mapped to a channel threre was DRC
|
||||
if (!(self->flags[streamIndex] & (AC_USAC | AC_RSV603DA))) {
|
||||
/* If at least one DRC thread has been mapped to a channel there was DRC
|
||||
* data in the bitstream. */
|
||||
self->flags[streamIndex] |= AC_DRC_PRESENT;
|
||||
} else {
|
||||
self->hDrcInfo->enable = 0;
|
||||
self->hDrcInfo->progRefLevelPresent = 0;
|
||||
ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 2
|
||||
#define AACDECODER_LIB_VL1 2
|
||||
#define AACDECODER_LIB_VL2 0
|
||||
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
|
||||
#ifdef SUPPRESS_BUILD_DATE_INFO
|
||||
#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;
|
||||
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;
|
||||
}
|
||||
@ -1269,9 +1265,9 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
||||
}
|
||||
|
||||
/* Signal bit stream interruption to other modules if required. */
|
||||
if (fTpInterruption || (flags & AACDEC_INTR)) {
|
||||
if (fTpInterruption || ((flags & AACDEC_INTR) && (accessUnit == 0))) {
|
||||
aacDecoder_SignalInterruption(self);
|
||||
if (!(flags & AACDEC_INTR)) {
|
||||
if (!((flags & AACDEC_INTR) && (accessUnit == 0))) {
|
||||
ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR;
|
||||
goto bail;
|
||||
}
|
||||
@ -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,9 +1366,9 @@ 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,
|
||||
FDK_Delay_Apply(
|
||||
&self->usacResidualDelay,
|
||||
pTimeData2 + 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0,
|
||||
self->streamInfo.frameSize, 0);
|
||||
}
|
||||
|
||||
@ -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,16 +1755,51 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) {
|
||||
/* return output loudness information for MPEG-D DRC */
|
||||
LONG outputLoudness =
|
||||
FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_OUTPUT_LOUDNESS);
|
||||
if (outputLoudness == DRC_DEC_LOUDNESS_NOT_PRESENT) {
|
||||
/* no valid MPEG-D DRC loudness value contained */
|
||||
self->streamInfo.outputLoudness = -1;
|
||||
} else {
|
||||
if (outputLoudness > 0) {
|
||||
/* positive output loudness values (very unusual) are limited to 0
|
||||
* dB */
|
||||
self->streamInfo.outputLoudness = 0;
|
||||
} else {
|
||||
self->streamInfo.outputLoudness =
|
||||
-(INT)outputLoudness >>
|
||||
22; /* negate and scale from e = 7 to e = (31-2) */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* return output loudness information for MPEG-4 DRC */
|
||||
if (self->streamInfo.drcProgRefLev <
|
||||
0) { /* no MPEG-4 DRC loudness metadata contained */
|
||||
self->streamInfo.outputLoudness = -1;
|
||||
} else {
|
||||
if (self->defaultTargetLoudness <
|
||||
0) { /* loudness normalization is off */
|
||||
self->streamInfo.outputLoudness = self->streamInfo.drcProgRefLev;
|
||||
} else {
|
||||
self->streamInfo.outputLoudness = self->defaultTargetLoudness;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
if ((flags & AACDEC_INTR) && (accessUnit == 0)) {
|
||||
/* delete data from the past (e.g. mixdown coeficients) */
|
||||
pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
|
||||
}
|
||||
@ -1779,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;
|
||||
@ -1801,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;
|
||||
@ -1816,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,
|
||||
@ -1949,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(
|
||||
|
@ -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
|
||||
@ -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;
|
||||
@ -1228,7 +1230,6 @@ static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
|
||||
int sfb, line = 0;
|
||||
int fac_shift;
|
||||
int fac_mod;
|
||||
FIXP_DBL accu;
|
||||
|
||||
for (sfb = 0; sfb < sfbCnt; sfb++) {
|
||||
fac_shift =
|
||||
@ -1236,15 +1237,11 @@ static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
|
||||
fac_mod = fac_shift & 3;
|
||||
fac_shift = (fac_shift >> 2) + 1;
|
||||
fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct);
|
||||
fac_shift = fMax(fMin(fac_shift, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
|
||||
|
||||
for (; line < pSfbOffset[sfb + 1]; line++) {
|
||||
accu = fMult(*(spectrum + line), facMod4Table[fac_mod]);
|
||||
if (fac_shift < 0) {
|
||||
accu >>= -fac_shift;
|
||||
} else {
|
||||
accu <<= fac_shift;
|
||||
}
|
||||
*(spectrum + line) = accu;
|
||||
FIXP_DBL accu = fMult(*(spectrum + line), facMod4Table[fac_mod]);
|
||||
*(spectrum + line) = scaleValue(accu, fac_shift);
|
||||
}
|
||||
}
|
||||
*pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct);
|
||||
@ -1618,7 +1615,7 @@ static void CConcealment_ApplyRandomSign(int randomPhase, FIXP_DBL *spec,
|
||||
}
|
||||
|
||||
if (packedSign & 0x1) {
|
||||
spec[i] = -spec[i];
|
||||
spec[i] = -fMax(spec[i], (FIXP_DBL)(MINVAL_DBL + 1));
|
||||
}
|
||||
packedSign >>= 1;
|
||||
|
||||
@ -1849,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
|
||||
*/
|
||||
@ -1962,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;
|
||||
@ -1974,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;
|
||||
@ -1992,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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2055,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;
|
||||
@ -2075,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;
|
||||
|
||||
|
@ -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
|
||||
@ -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
|
||||
@ -131,24 +134,26 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
|
||||
FIXP_DBL z0, z2, tmp;
|
||||
|
||||
z2 = x[N / 2 + i];
|
||||
z0 = z2 + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1));
|
||||
z0 = fAddSaturate(z2,
|
||||
(fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1)));
|
||||
|
||||
z[N / 2 + i] = x[N / 2 - 1 - i] +
|
||||
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1));
|
||||
z[N / 2 + i] = fAddSaturate(
|
||||
x[N / 2 - 1 - i],
|
||||
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1)));
|
||||
|
||||
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;
|
||||
@ -159,32 +164,34 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
|
||||
FIXP_DBL z0, z2, tmp0, tmp1;
|
||||
|
||||
z2 = x[N / 2 + i];
|
||||
z0 = z2 + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1));
|
||||
z0 = fAddSaturate(z2,
|
||||
(fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1)));
|
||||
|
||||
z[N / 2 + i] = x[N / 2 - 1 - i] +
|
||||
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1));
|
||||
z[N / 2 + i] = fAddSaturate(
|
||||
x[N / 2 - 1 - i],
|
||||
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1)));
|
||||
|
||||
tmp0 = (fMultDiv2(z[N / 2 + i], fb[N / 2 - 1 - i]) +
|
||||
fMultDiv2(z[i], fb[N / 2 + i]));
|
||||
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;
|
||||
@ -194,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
|
||||
|
@ -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
|
||||
@ -807,19 +807,17 @@ void CJointStereo_ApplyMS(
|
||||
for (int i = 0; i < windowLen; i++) {
|
||||
dmx_re_prev[i] =
|
||||
((staticSpectralCoeffsL[index_offset + i] >>
|
||||
srLeftChan) +
|
||||
fMin(DFRACT_BITS - 1, srLeftChan + 1)) +
|
||||
(staticSpectralCoeffsR[index_offset + i] >>
|
||||
srRightChan)) >>
|
||||
1;
|
||||
fMin(DFRACT_BITS - 1, srRightChan + 1)));
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < windowLen; i++) {
|
||||
dmx_re_prev[i] =
|
||||
((staticSpectralCoeffsL[index_offset + i] >>
|
||||
srLeftChan) -
|
||||
fMin(DFRACT_BITS - 1, srLeftChan + 1)) -
|
||||
(staticSpectralCoeffsR[index_offset + i] >>
|
||||
srRightChan)) >>
|
||||
1;
|
||||
fMin(DFRACT_BITS - 1, srRightChan + 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -854,12 +852,13 @@ void CJointStereo_ApplyMS(
|
||||
if (window == 0) {
|
||||
if (dmx_re_prev_e < frameMaxScale) {
|
||||
if (mainband_flag == 0) {
|
||||
scaleValues(dmx_re_prev, store_dmx_re_prev, windowLen,
|
||||
-(frameMaxScale - dmx_re_prev_e));
|
||||
scaleValues(
|
||||
dmx_re_prev, store_dmx_re_prev, windowLen,
|
||||
-fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e)));
|
||||
} else {
|
||||
for (int i = 0; i < windowLen; i++) {
|
||||
dmx_re_prev[i] >>= (frameMaxScale - dmx_re_prev_e);
|
||||
}
|
||||
scaleValues(
|
||||
dmx_re_prev, windowLen,
|
||||
-fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e)));
|
||||
}
|
||||
} else {
|
||||
if (mainband_flag == 0) {
|
||||
@ -873,10 +872,9 @@ void CJointStereo_ApplyMS(
|
||||
FDK_ASSERT(pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
|
||||
BLOCK_SHORT);
|
||||
if (specScaleL[window - 1] < frameMaxScale) {
|
||||
for (int i = 0; i < windowLen; i++) {
|
||||
dmx_re[windowLen * (window - 1) + i] >>=
|
||||
(frameMaxScale - specScaleL[window - 1]);
|
||||
}
|
||||
scaleValues(&dmx_re[windowLen * (window - 1)], windowLen,
|
||||
-fMin(DFRACT_BITS - 1,
|
||||
(frameMaxScale - specScaleL[window - 1])));
|
||||
} else {
|
||||
specScaleL[window] = specScaleL[window - 1];
|
||||
specScaleR[window] = specScaleR[window - 1];
|
||||
@ -991,7 +989,7 @@ void CJointStereo_ApplyMS(
|
||||
} /* if ( pJointStereoData->complex_coef == 1 ) */
|
||||
|
||||
/* 4. upmix process */
|
||||
INT pred_dir = cplxPredictionData->pred_dir ? -1 : 1;
|
||||
LONG pred_dir = cplxPredictionData->pred_dir ? -1 : 1;
|
||||
/* 0.1 in Q-3.34 */
|
||||
const FIXP_DBL pointOne = 0x66666666; /* 0.8 */
|
||||
/* Shift value for the downmix */
|
||||
@ -1041,34 +1039,24 @@ void CJointStereo_ApplyMS(
|
||||
the downmix. "dmx_re" and "specL" are two different pointers
|
||||
pointing to separate arrays, which may or may not contain the
|
||||
same data (with different scaling).
|
||||
|
||||
specL[i] = + (specL[i] + side);
|
||||
specR[i] = -/+ (specL[i] - side);
|
||||
*/
|
||||
FIXP_DBL side, left, right;
|
||||
|
||||
/* help1: alpha_re[i] * dmx_re[i] */
|
||||
FIXP_DBL help1 = fMultDiv2(alpha_re_tmp, *p2dmxRe++);
|
||||
side = fMultAddDiv2(fMultDiv2(alpha_re_tmp, *p2dmxRe++),
|
||||
alpha_im_tmp, (*p2dmxIm++) << shift_dmx);
|
||||
side = ((*p2CoeffR) >> 2) -
|
||||
(FIXP_DBL)SATURATE_SHIFT(side, -(help3_shift - 2),
|
||||
DFRACT_BITS - 2);
|
||||
|
||||
/* tmp: dmx_im[i] */
|
||||
FIXP_DBL tmp = (*p2dmxIm++) << shift_dmx;
|
||||
left = ((*p2CoeffL) >> 2) + side;
|
||||
right = ((*p2CoeffL) >> 2) - side;
|
||||
right = (FIXP_DBL)((LONG)right * pred_dir);
|
||||
|
||||
/* help2: alpha_im[i] * dmx_im[i] */
|
||||
FIXP_DBL help2 = fMultDiv2(alpha_im_tmp, tmp);
|
||||
|
||||
/* help3: alpha_re[i] * dmx_re[i] + alpha_im[i] * dmx_im[i] */
|
||||
FIXP_DBL help3 = help1 + help2;
|
||||
|
||||
/* side (= help4) = specR[i] - (dmx_re[i] * specL[i] + alpha_im[i]
|
||||
* * dmx_im[i]) */
|
||||
FIXP_DBL help4 = *p2CoeffR - scaleValue(help3, help3_shift);
|
||||
|
||||
/* We calculate the left and right output by using the helper
|
||||
* function */
|
||||
/* specR[i] = -/+ (specL[i] - side); */
|
||||
*p2CoeffR =
|
||||
(FIXP_DBL)((LONG)(*p2CoeffL - help4) * (LONG)pred_dir);
|
||||
p2CoeffR++;
|
||||
|
||||
/* specL[i] = specL[i] + side; */
|
||||
*p2CoeffL = *p2CoeffL + help4;
|
||||
p2CoeffL++;
|
||||
*p2CoeffL++ = SATURATE_LEFT_SHIFT_ALT(left, 2, DFRACT_BITS);
|
||||
*p2CoeffR++ = SATURATE_LEFT_SHIFT_ALT(right, 2, 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
|
||||
@ -131,7 +131,7 @@ void E_UTIL_preemph(const FIXP_DBL *in, FIXP_DBL *out, INT L) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < L; i++) {
|
||||
out[i] = in[i] - fMult(PREEMPH_FAC, in[i - 1]);
|
||||
out[i] = fAddSaturate(in[i], -fMult(PREEMPH_FAC, in[i - 1]));
|
||||
}
|
||||
|
||||
return;
|
||||
@ -465,7 +465,9 @@ void BuildAdaptiveExcitation(
|
||||
/* Note: code[L_SUBFR] and exc2[L_SUBFR] share the same memory!
|
||||
If exc2[i] is written, code[i] will be destroyed!
|
||||
*/
|
||||
#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC)
|
||||
#define SF_HEADROOM (1)
|
||||
#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC - SF_HEADROOM)
|
||||
#define SF_GAIN_P2 (SF_GAIN_P - SF_HEADROOM)
|
||||
|
||||
int i;
|
||||
FIXP_DBL tmp, cpe, code_smooth_prev, code_smooth;
|
||||
@ -477,8 +479,8 @@ void BuildAdaptiveExcitation(
|
||||
cpe = (period_fac >> (2 - SF_PFAC)) + FL2FXCONST_DBL(0.25f);
|
||||
|
||||
/* u'(n) */
|
||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1); /* v(0)*g_p */
|
||||
*exc++ = tmp + (fMultDiv2(code[0], gain_code) << SF);
|
||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1); /* v(0)*g_p */
|
||||
*exc++ = (tmp + (fMultDiv2(code[0], gain_code) << SF)) << SF_HEADROOM;
|
||||
|
||||
/* u(n) */
|
||||
code_smooth_prev = fMultDiv2(*code++, gain_code_smoothed)
|
||||
@ -487,15 +489,15 @@ void BuildAdaptiveExcitation(
|
||||
code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF; /* c(1) * g_sc */
|
||||
tmp += code_smooth_prev; /* tmp = v(0)*g_p + c(0)*g_sc */
|
||||
cpe_code_smooth = fMultDiv2(cpe, code_smooth);
|
||||
*exc2++ = tmp - cpe_code_smooth;
|
||||
*exc2++ = (tmp - cpe_code_smooth) << SF_HEADROOM;
|
||||
cpe_code_smooth_prev = fMultDiv2(cpe, code_smooth_prev);
|
||||
|
||||
i = L_SUBFR - 2;
|
||||
do /* ARM926: 22 cycles per iteration */
|
||||
{
|
||||
/* u'(n) */
|
||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
|
||||
*exc++ = tmp + (fMultDiv2(code_i, gain_code) << SF);
|
||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1);
|
||||
*exc++ = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;
|
||||
/* u(n) */
|
||||
tmp += code_smooth; /* += g_sc * c(i) */
|
||||
tmp -= cpe_code_smooth_prev;
|
||||
@ -503,16 +505,17 @@ void BuildAdaptiveExcitation(
|
||||
code_i = *code++;
|
||||
code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF;
|
||||
cpe_code_smooth = fMultDiv2(cpe, code_smooth);
|
||||
*exc2++ = tmp - cpe_code_smooth; /* tmp - c_pe * g_sc * c(i+1) */
|
||||
*exc2++ = (tmp - cpe_code_smooth)
|
||||
<< SF_HEADROOM; /* tmp - c_pe * g_sc * c(i+1) */
|
||||
} while (--i != 0);
|
||||
|
||||
/* u'(n) */
|
||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
|
||||
*exc = tmp + (fMultDiv2(code_i, gain_code) << SF);
|
||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1);
|
||||
*exc = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;
|
||||
/* u(n) */
|
||||
tmp += code_smooth;
|
||||
tmp -= cpe_code_smooth_prev;
|
||||
*exc2++ = tmp;
|
||||
*exc2++ = tmp << SF_HEADROOM;
|
||||
|
||||
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
|
||||
@ -344,7 +344,7 @@ INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac,
|
||||
/* Overlap Add */
|
||||
x0 = -fMult(*pOvl--, pWindow[i].v.re);
|
||||
|
||||
*pOut0 += IMDCT_SCALE_DBL(x0);
|
||||
*pOut0 = fAddSaturate(*pOut0, IMDCT_SCALE_DBL(x0));
|
||||
pOut0++;
|
||||
}
|
||||
} else {
|
||||
@ -354,7 +354,7 @@ INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac,
|
||||
/* Overlap Add */
|
||||
x0 = fMult(*pOvl--, pWindow[i].v.re);
|
||||
|
||||
*pOut0 += IMDCT_SCALE_DBL(x0);
|
||||
*pOut0 = fAddSaturate(*pOut0, IMDCT_SCALE_DBL(x0));
|
||||
pOut0++;
|
||||
}
|
||||
}
|
||||
@ -362,7 +362,7 @@ INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac,
|
||||
0) { /* this should only happen for ACELP -> TCX20 -> ACELP transition */
|
||||
FIXP_DBL *pOut = pOut0 - fl / 2; /* fl/2 == fac_length */
|
||||
for (i = 0; i < fl / 2; i++) {
|
||||
pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
|
||||
pOut[i] = fAddSaturate(pOut[i], IMDCT_SCALE_DBL(hMdct->pFacZir[i]));
|
||||
}
|
||||
hMdct->pFacZir = NULL;
|
||||
}
|
||||
@ -493,9 +493,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
|
||||
/* Div2 is compensated by table scaling */
|
||||
x = fMultDiv2(pTmp2[i], FacWindowZir[w]);
|
||||
x += fMultDiv2(pTmp1[-i - 1], FacWindowSynth[w]);
|
||||
x += pFAC_and_FAC_ZIR[i];
|
||||
pOut1[i] = x;
|
||||
|
||||
pOut1[i] = fAddSaturate(x, pFAC_and_FAC_ZIR[i]);
|
||||
w++;
|
||||
}
|
||||
}
|
||||
@ -552,7 +550,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
|
||||
FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
|
||||
pOut1 < hMdct->overlap.time + hMdct->ov_size) ||
|
||||
(pOut1 >= output && pOut1 < output + 1024));
|
||||
*pOut1 += IMDCT_SCALE_DBL(-x1);
|
||||
*pOut1 = fAddSaturate(*pOut1, IMDCT_SCALE_DBL(-x1));
|
||||
pOut1--;
|
||||
}
|
||||
|
||||
@ -578,7 +576,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
|
||||
FIXP_DBL x = -(*pCurr--);
|
||||
/* 5) (item 4) Synthesis filter Zir component, FAC ZIR (another one). */
|
||||
if (i < f_len) {
|
||||
x += *pF++;
|
||||
x = fAddSaturate(x, *pF++);
|
||||
}
|
||||
|
||||
FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
|
||||
@ -668,9 +666,9 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
|
||||
for (i = 0; i < fl / 2; i++) {
|
||||
FIXP_DBL x0, x1;
|
||||
|
||||
cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
|
||||
*pOut0 = IMDCT_SCALE_DBL(x0);
|
||||
*pOut1 = IMDCT_SCALE_DBL(-x1);
|
||||
cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
|
||||
*pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
|
||||
*pOut1 = IMDCT_SCALE_DBL_LSH1(-x1);
|
||||
pOut0++;
|
||||
pOut1--;
|
||||
}
|
||||
@ -680,9 +678,9 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
|
||||
for (i = 0; i < fl / 2; i++) {
|
||||
FIXP_DBL x0, x1;
|
||||
|
||||
cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
|
||||
*pOut0 = IMDCT_SCALE_DBL(x0);
|
||||
*pOut1 = IMDCT_SCALE_DBL(x1);
|
||||
cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
|
||||
*pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
|
||||
*pOut1 = IMDCT_SCALE_DBL_LSH1(x1);
|
||||
pOut0++;
|
||||
pOut1--;
|
||||
}
|
||||
@ -691,9 +689,9 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
|
||||
for (i = 0; i < fl / 2; i++) {
|
||||
FIXP_DBL x0, x1;
|
||||
|
||||
cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow_prev[i]);
|
||||
*pOut0 = IMDCT_SCALE_DBL(x0);
|
||||
*pOut1 = IMDCT_SCALE_DBL(x1);
|
||||
cplxMultDiv2(&x1, &x0, *pCurr++, *pOvl--, pWindow_prev[i]);
|
||||
*pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
|
||||
*pOut1 = IMDCT_SCALE_DBL_LSH1(x1);
|
||||
pOut0++;
|
||||
pOut1--;
|
||||
}
|
||||
@ -705,7 +703,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
|
||||
FIXP_DBL *pOut = pOut0 - fl / 2;
|
||||
FDK_ASSERT(fl / 2 <= 128);
|
||||
for (i = 0; i < fl / 2; i++) {
|
||||
pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
|
||||
pOut[i] = fAddSaturate(pOut[i], IMDCT_SCALE_DBL(hMdct->pFacZir[i]));
|
||||
}
|
||||
hMdct->pFacZir = NULL;
|
||||
}
|
||||
|
@ -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
|
||||
@ -231,7 +231,7 @@ void nearest_neighbor_2D8(FIXP_ZF x[8], int y[8]) {
|
||||
void RE8_PPV(FIXP_ZF x[], SHORT y[], int r) {
|
||||
int i, y0[8], y1[8];
|
||||
FIXP_ZF x1[8], tmp;
|
||||
FIXP_DBL e;
|
||||
INT64 e;
|
||||
|
||||
/* find the nearest neighbor y0 of x in 2D8 */
|
||||
nearest_neighbor_2D8(x, y0);
|
||||
@ -245,16 +245,16 @@ void RE8_PPV(FIXP_ZF x[], SHORT y[], int r) {
|
||||
}
|
||||
|
||||
/* compute e0=||x-y0||^2 and e1=||x-y1||^2 */
|
||||
e = (FIXP_DBL)0;
|
||||
e = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
tmp = x[i] - INT2ZF(y0[i], 0);
|
||||
e += fPow2Div2(
|
||||
e += (INT64)fPow2Div2(
|
||||
tmp << r); /* shift left to ensure that no fract part bits get lost. */
|
||||
tmp = x[i] - INT2ZF(y1[i], 0);
|
||||
e -= fPow2Div2(tmp << r);
|
||||
e -= (INT64)fPow2Div2(tmp << r);
|
||||
}
|
||||
/* select best candidate y0 or y1 to minimize distortion */
|
||||
if (e < (FIXP_DBL)0) {
|
||||
if (e < 0) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
y[i] = y0[i];
|
||||
}
|
||||
@ -565,7 +565,8 @@ static void lsf_weight_2st(FIXP_LPC *lsfq, FIXP_DBL *xq, int nk_mode) {
|
||||
/* add non-weighted residual LSF vector to LSF1st */
|
||||
for (i = 0; i < M_LP_FILTER_ORDER; i++) {
|
||||
w = (LONG)fMultDiv2(factor, sqrtFixp(fMult(d[i], d[i + 1])));
|
||||
lsfq[i] = fAddSaturate(lsfq[i], FX_DBL2FX_LPC((FIXP_DBL)(w * (LONG)xq[i])));
|
||||
lsfq[i] = fAddSaturate(lsfq[i],
|
||||
FX_DBL2FX_LPC((FIXP_DBL)((INT64)w * (LONG)xq[i])));
|
||||
}
|
||||
|
||||
return;
|
||||
@ -1138,9 +1139,12 @@ static void get_lsppol(FIXP_LPC lsp[], FIXP_DBL f[], int n, int flag) {
|
||||
for (i = 2; i <= n; i++) {
|
||||
plsp += 2;
|
||||
b = -FX_LPC2FX_DBL(*plsp);
|
||||
f[i] = ((fMultDiv2(b, f[i - 1]) << 1) + (f[i - 2])) << 1;
|
||||
f[i] = SATURATE_LEFT_SHIFT((fMultDiv2(b, f[i - 1]) + (f[i - 2] >> 1)), 2,
|
||||
DFRACT_BITS);
|
||||
for (j = i - 1; j > 1; j--) {
|
||||
f[j] = f[j] + (fMultDiv2(b, f[j - 1]) << 2) + f[j - 2];
|
||||
f[j] = SATURATE_LEFT_SHIFT(
|
||||
((f[j] >> 2) + fMultDiv2(b, f[j - 1]) + (f[j - 2] >> 2)), 2,
|
||||
DFRACT_BITS);
|
||||
}
|
||||
f[1] = f[1] + (b >> (SF_F - 1));
|
||||
}
|
||||
@ -1167,6 +1171,9 @@ void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp) {
|
||||
/*-----------------------------------------------------*
|
||||
* Multiply F1(z) by (1+z^-1) and F2(z) by (1-z^-1) *
|
||||
*-----------------------------------------------------*/
|
||||
scaleValues(f1, NC + 1, -2);
|
||||
scaleValues(f2, NC + 1, -2);
|
||||
|
||||
for (i = NC; i > 0; i--) {
|
||||
f1[i] += f1[i - 1];
|
||||
f2[i] -= f2[i - 1];
|
||||
@ -1175,13 +1182,8 @@ void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp) {
|
||||
FIXP_DBL aDBL[M_LP_FILTER_ORDER];
|
||||
|
||||
for (i = 1, k = M_LP_FILTER_ORDER - 1; i <= NC; i++, k--) {
|
||||
FIXP_DBL tmp1, tmp2;
|
||||
|
||||
tmp1 = f1[i] >> 1;
|
||||
tmp2 = f2[i] >> 1;
|
||||
|
||||
aDBL[i - 1] = (tmp1 + tmp2);
|
||||
aDBL[k] = (tmp1 - tmp2);
|
||||
aDBL[i - 1] = f1[i] + f2[i];
|
||||
aDBL[k] = f1[i] - f2[i];
|
||||
}
|
||||
|
||||
int headroom_a = getScalefactor(aDBL, M_LP_FILTER_ORDER);
|
||||
@ -1190,5 +1192,5 @@ void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp) {
|
||||
a[i] = FX_DBL2FX_LPC(aDBL[i] << headroom_a);
|
||||
}
|
||||
|
||||
*a_exp = 8 - headroom_a;
|
||||
*a_exp = SF_F + (2 - 1) - headroom_a;
|
||||
}
|
||||
|
@ -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
|
||||
@ -122,17 +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 += fMultDiv2((noise[i - j] + noise[i + j]), filt[j]);
|
||||
tmp += fMult((noise[i - j] >> 1) + (noise[i + j] >> 1), filt[j]);
|
||||
}
|
||||
syn_out[i] = (FIXP_PCM)(IMDCT_SCALE(syn[i] - tmp));
|
||||
syn_out[i] = (PCM_DEC)(
|
||||
IMDCT_SCALE((syn[i] >> 1) - (tmp >> 1), aacOutDataHeadroom - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,7 +147,9 @@ void bass_pf_1sf_delay(
|
||||
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) */
|
||||
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;
|
||||
@ -335,17 +341,22 @@ void bass_pf_1sf_delay(
|
||||
|
||||
{
|
||||
for (i = 0; i < lg; i++) {
|
||||
/* scaled with SF_SYNTH + gain_sf + 1 */
|
||||
/* scaled with SF_SYNTH + gain_sf + 1; composition of scalefactor 2:
|
||||
* one additional shift of syn values + fMult => fMultDiv2 */
|
||||
noise_in[i] =
|
||||
(fMult(gainSGL, syn[i + i_subfr] - (syn[i + i_subfr - T] >> 1) -
|
||||
(syn[i + i_subfr + T] >> 1))) >>
|
||||
s1;
|
||||
scaleValue(fMultDiv2(gainSGL, (syn[i + i_subfr] >> 1) -
|
||||
(syn[i + i_subfr - T] >> 2) -
|
||||
(syn[i + i_subfr + T] >> 2)),
|
||||
2 - s1);
|
||||
}
|
||||
|
||||
for (i = lg; i < L_SUBFR; i++) {
|
||||
/* scaled with SF_SYNTH + gain_sf + 1 */
|
||||
/* scaled with SF_SYNTH + gain_sf + 1; composition of scalefactor 2:
|
||||
* one additional shift of syn values + fMult => fMultDiv2 */
|
||||
noise_in[i] =
|
||||
(fMult(gainSGL, syn[i + i_subfr] - syn[i + i_subfr - T])) >> s1;
|
||||
scaleValue(fMultDiv2(gainSGL, (syn[i + i_subfr] >> 1) -
|
||||
(syn[i + i_subfr - T] >> 1)),
|
||||
2 - s1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -364,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -377,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;
|
||||
@ -1222,7 +1233,7 @@ AAC_DECODER_ERROR CLpdChannelStream_Read(
|
||||
(INT)(samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
|
||||
(INT)PIT_MIN_12k8;
|
||||
|
||||
if ((samplingRate < 6000) || (samplingRate > 24000)) {
|
||||
if ((samplingRate < FAC_FSCALE_MIN) || (samplingRate > FAC_FSCALE_MAX)) {
|
||||
error = AAC_DEC_PARSE_ERROR;
|
||||
goto bail;
|
||||
}
|
||||
@ -1546,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;
|
||||
@ -2011,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
|
||||
|
@ -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
|
||||
@ -149,12 +149,6 @@ All API header files are located in the folder /include of the release package.
|
||||
All header files are provided for usage in C/C++ programs. The AAC encoder
|
||||
library API functions are located in aacenc_lib.h.
|
||||
|
||||
In binary releases the encoder core resides in statically linkable libraries
|
||||
called for example libAACenc.a/libFDK.a (LINUX) or FDK_fastaaclib.lib (MS Visual
|
||||
C++) for the plain AAC-LC core encoder and libSBRenc.a (LINUX) or
|
||||
FDK_sbrEncLib.lib (MS Visual C++) for the SBR (Spectral Band Replication) and PS
|
||||
(Parametric Stereo) modules.
|
||||
|
||||
\section CallingSequence Calling Sequence
|
||||
|
||||
For encoding of ISO/MPEG-2/4 AAC bitstreams the following sequence is mandatory.
|
||||
@ -326,18 +320,12 @@ input buffer, simulating a modulo buffer: \code if (outargs.numInSamples>0) {
|
||||
\endcode
|
||||
|
||||
\section writeOutData Output Bitstream Data
|
||||
If any AAC bitstream data is available, write it to output file or device. This
|
||||
can be done once the following condition is true: \code if
|
||||
(outargs.numOutBytes>0) {
|
||||
|
||||
If any AAC bitstream data is available, write it to output file or device as
|
||||
follows. \code if (outargs.numOutBytes>0) { FDKfwrite(outputBuffer,
|
||||
outargs.numOutBytes, 1, pOutFile);
|
||||
}
|
||||
\endcode
|
||||
|
||||
If you use file I/O then for example call mpegFileWrite_Write() from the library
|
||||
libMpegFileWrite \code mpegFileWrite_Write(hMpegFile, outputBuffer,
|
||||
outargs.numOutBytes, aacEncoder_GetParam(hAacEncoder, AACENC_GRANULE_LENGTH));
|
||||
\endcode
|
||||
|
||||
\section cfgMetaData Meta Data Configuration
|
||||
|
||||
If the present library is configured with Metadata support, it is possible to
|
||||
@ -427,7 +415,7 @@ switch (nChannels) {
|
||||
return chMode;
|
||||
\endcode
|
||||
|
||||
\subsection bitreservoir Bitreservoir Configuration
|
||||
\subsection peakbitrate Peak Bitrate Configuration
|
||||
In AAC, the default bitreservoir configuration depends on the chosen bitrate per
|
||||
frame and the number of effective channels. The size can be determined as below.
|
||||
\f[
|
||||
@ -436,17 +424,10 @@ bitreservoir = nEffChannels*6144 - (bitrate*framelength/samplerate)
|
||||
Due to audio quality concerns it is not recommended to change the bitreservoir
|
||||
size to a lower value than the default setting! However, for minimizing the
|
||||
delay for streaming applications or for achieving a constant size of the
|
||||
bitstream packages in each frame, it may be necessaray to change the
|
||||
bitreservoir size. This can be done with the ::AACENC_PEAK_BITRATE parameter.
|
||||
\code
|
||||
bitstream packages in each frame, it may be necessaray to limit the maximum bits
|
||||
per frame size. This can be done with the ::AACENC_PEAK_BITRATE parameter. \code
|
||||
aacEncoder_SetParam(hAacEncoder, AACENC_PEAK_BITRATE, value);
|
||||
\endcode
|
||||
By setting ::AACENC_BITRATEMODE to fixed framing, the bitreservoir is disabled.
|
||||
A disabled bitreservoir results in a constant size for each bitstream package.
|
||||
Please note that especially at lower bitrates a disabled bitreservoir can
|
||||
downgrade the audio quality considerably! The default bitreservoir configuration
|
||||
can be achieved as follows. \code aacEncoder_SetParam(hAacEncoder,
|
||||
AACENC_BITRESERVOIR, -1); \endcode
|
||||
|
||||
To achieve acceptable audio quality with a reduced bitreservoir size setting at
|
||||
least 1000 bits per audio channel is recommended. For a multichannel audio file
|
||||
@ -455,31 +436,32 @@ audio quality.
|
||||
|
||||
|
||||
\subsection vbrmode Variable Bitrate Mode
|
||||
The encoder provides various Variable Bitrate Modes that differ in audio quality
|
||||
and average overall bitrate. The given values are averages over time, different
|
||||
encoder settings and strongly depend on the type of audio signal. The VBR
|
||||
configurations can be adjusted via ::AACENC_BITRATEMODE encoder parameter.
|
||||
The variable bitrate (VBR) mode coding adapts the bit consumption to the
|
||||
psychoacoustic requirements of the signal. The encoder ignores the user-defined
|
||||
bit rate and selects a suitable pre-defined configuration based on the provided
|
||||
AOT. The VBR mode 1 is tuned for HE-AACv2, for VBR mode 2, HE-AACv1 should be
|
||||
used. VBR modes 3-5 should be used with Low-Complexity AAC. When encoding
|
||||
AAC-ELD, the best mode is selected automatically.
|
||||
|
||||
The bitrates given in the table are averages over time and different encoder
|
||||
settings. They strongly depend on the type of audio signal. The VBR
|
||||
configurations can be adjusted with the ::AACENC_BITRATEMODE encoder parameter.
|
||||
\verbatim
|
||||
--------------------------------------------
|
||||
VBR_MODE | Approx. Bitrate in kbps/channel
|
||||
| AAC-LC | AAC-LD/AC_ELD
|
||||
----------+---------------+-----------------
|
||||
VBR_1 | 32 - 48 | 32 - 56
|
||||
VBR_2 | 40 - 56 | 40 - 64
|
||||
VBR_3 | 48 - 64 | 48 - 72
|
||||
VBR_4 | 64 - 80 | 64 - 88
|
||||
VBR_5 | 96 - 120 | 112 - 144
|
||||
-----------------------------------------------
|
||||
VBR_MODE | Approx. Bitrate in kbps for stereo
|
||||
| AAC-LC | AAC-ELD
|
||||
----------+---------------+--------------------
|
||||
VBR_1 | 32 (HE-AACv2) | 48
|
||||
VBR_2 | 72 (HE-AACv1) | 56
|
||||
VBR_3 | 112 | 72
|
||||
VBR_4 | 148 | 148
|
||||
VBR_5 | 228 | 224
|
||||
--------------------------------------------
|
||||
\endverbatim
|
||||
The bitrate ranges apply for individual audio channels. In case of multichannel
|
||||
configurations the average bitrate might be estimated by multiplying with the
|
||||
number of effective channels. This corresponds to all audio input channels
|
||||
exclusively the low frequency channel. At configurations which are making use of
|
||||
downmix modules the AAC core channels respectively downmix channels shall be
|
||||
considered. For ::AACENC_AOT which are using SBR, the average bitrate can be
|
||||
estimated by using the ratio of 0.5 for dualrate SBR and 0.75 for downsampled
|
||||
SBR configurations.
|
||||
|
||||
Note that these figures are valid for stereo encoding only. VBR modes 2-5 will
|
||||
yield much lower bit rates when encoding single-channel input. For
|
||||
configurations which are making use of downmix modules the AAC core channels
|
||||
respectively downmix channels shall be considered.
|
||||
|
||||
\subsection encQual Audio Quality Considerations
|
||||
The default encoder configuration is suggested to be used. Encoder tools such as
|
||||
@ -967,9 +949,7 @@ in this Fraunhofer IIS AAC encoder. AAC has been designed in that way.
|
||||
|
||||
\subsection BEHAVIOUR_ESTIM_AVG_FRAMESIZES Estimating Average Frame Sizes
|
||||
|
||||
A HE-AAC v1 or v2 audio frame contains 2048 PCM samples per channel (there is
|
||||
also one mode with 1920 samples per channel but this is only for special
|
||||
purposes such as DAB+ digital radio).
|
||||
A HE-AAC v1 or v2 audio frame contains 2048 PCM samples per channel.
|
||||
|
||||
The number of HE-AAC frames \f$N\_FRAMES\f$ per second at 44.1 kHz is:
|
||||
|
||||
@ -1082,9 +1062,7 @@ typedef struct AACENCODER *HANDLE_AACENCODER;
|
||||
typedef struct {
|
||||
UINT maxOutBufBytes; /*!< Maximum number of encoder bitstream bytes within one
|
||||
frame. Size depends on maximum number of supported
|
||||
channels in encoder instance. For superframing (as
|
||||
used for example in DAB+), size has to be a multiple
|
||||
accordingly. */
|
||||
channels in encoder instance. */
|
||||
|
||||
UINT maxAncBytes; /*!< Maximum number of ancillary data bytes which can be
|
||||
inserted into bitstream within one frame. */
|
||||
|
@ -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
|
||||
@ -204,5 +204,5 @@ QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel(int n, UCHAR *dynamic_RAM) {
|
||||
* (dynamic_RAM + P_BUF_0 + n*sizeof(QC_OUT_CHANNEL)) is sufficiently aligned,
|
||||
* so the cast is safe */
|
||||
return reinterpret_cast<QC_OUT_CHANNEL *>(reinterpret_cast<void *>(
|
||||
dynamic_RAM + P_BUF_0 + n * sizeof(QC_OUT_CHANNEL)));
|
||||
dynamic_RAM + P_BUF_0 + n * ALIGN_SIZE(sizeof(QC_OUT_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
|
||||
@ -198,7 +198,7 @@ struct AAC_ENC {
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
*/
|
||||
|
||||
#define BUF_SIZE_0 (ALIGN_SIZE(sizeof(QC_OUT_CHANNEL) * (8)))
|
||||
#define BUF_SIZE_0 (ALIGN_SIZE(sizeof(QC_OUT_CHANNEL)) * (8))
|
||||
#define BUF_SIZE_1 \
|
||||
(ALIGN_SIZE(maxSize(maxSize(sizeof(PSY_DYNAMIC), \
|
||||
(BIT_LOOK_UP_SIZE + MERGE_GAIN_LOOK_UP_SIZE)), \
|
||||
|
@ -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
|
||||
@ -114,6 +114,8 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
#include "genericStds.h"
|
||||
|
||||
#define BITRES_MIN \
|
||||
300 /* default threshold for using reduced/disabled bitres mode */
|
||||
#define BITRES_MAX_LD 4000
|
||||
#define BITRES_MIN_LD 500
|
||||
#define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */
|
||||
@ -550,7 +552,8 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(
|
||||
(config->minBitsPerFrame != -1) ? config->minBitsPerFrame : 0;
|
||||
qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7);
|
||||
} else {
|
||||
INT bitreservoir = -1; /* default bitrservoir size*/
|
||||
INT bitreservoir = -1; /* default bitreservoir size*/
|
||||
bitresMin = BITRES_MIN;
|
||||
if (isLowDelay(config->audioObjectType)) {
|
||||
INT brPerChannel = config->bitRate / config->nChannels;
|
||||
brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
|
||||
@ -601,9 +604,9 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(
|
||||
qcInit.nSubFrames = config->nSubFrames;
|
||||
qcInit.padding.paddingRest = config->sampleRate;
|
||||
|
||||
if (qcInit.bitRes >= bitresMin * config->nChannels) {
|
||||
if (qcInit.maxBits - qcInit.averageBits >= bitresMin * config->nChannels) {
|
||||
qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
|
||||
} else if (qcInit.bitRes > 0) {
|
||||
} else if (qcInit.maxBits > qcInit.averageBits) {
|
||||
qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */
|
||||
} else {
|
||||
qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */
|
||||
|
@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de
|
||||
/* Encoder library info */
|
||||
#define AACENCODER_LIB_VL0 4
|
||||
#define AACENCODER_LIB_VL1 0
|
||||
#define AACENCODER_LIB_VL2 0
|
||||
#define AACENCODER_LIB_VL2 1
|
||||
#define AACENCODER_LIB_TITLE "AAC Encoder"
|
||||
#ifdef SUPPRESS_BUILD_DATE_INFO
|
||||
#define AACENCODER_LIB_BUILD_DATE ""
|
||||
@ -446,6 +446,24 @@ static SBR_PS_SIGNALING getSbrSignalingMode(
|
||||
return sbrSignaling;
|
||||
}
|
||||
|
||||
static inline INT getAssociatedChElement(SBR_ELEMENT_INFO *elInfoSbr,
|
||||
CHANNEL_MAPPING *channelMapping) {
|
||||
ELEMENT_INFO *elInfo = channelMapping->elInfo;
|
||||
INT nElements = channelMapping->nElements;
|
||||
INT associatedChElement = -1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nElements; i++) {
|
||||
if (elInfoSbr->elType == elInfo[i].elType &&
|
||||
elInfoSbr->instanceTag == elInfo[i].instanceTag) {
|
||||
associatedChElement = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return associatedChElement;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Allocate Encoder
|
||||
****************************************************************************/
|
||||
@ -1921,7 +1939,15 @@ AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
|
||||
{
|
||||
hAacEncoder->extPayload[nExtensions].dataSize =
|
||||
hAacEncoder->pSbrPayload->dataSize[nPayload][i];
|
||||
hAacEncoder->extPayload[nExtensions].associatedChElement = i;
|
||||
hAacEncoder->extPayload[nExtensions].associatedChElement =
|
||||
getAssociatedChElement(
|
||||
&hAacEncoder->hEnvEnc->sbrElement[i]->elInfo,
|
||||
&hAacEncoder->hAacEnc->channelMapping);
|
||||
if (hAacEncoder->extPayload[nExtensions].associatedChElement ==
|
||||
-1) {
|
||||
err = AACENC_ENCODE_ERROR;
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
hAacEncoder->extPayload[nExtensions].dataType =
|
||||
EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set
|
||||
|
@ -1302,14 +1302,6 @@ static void FDKaacEnc_reduceThresholdsVBR(
|
||||
if (sfbThrReducedLdData < FL2FXCONST_DBL(-0.5f))
|
||||
sfbThrReducedLdData = FL2FXCONST_DBL(-1.f);
|
||||
|
||||
/* minimum of 29 dB Ratio for Thresholds */
|
||||
if ((sfbEnLdData + FL2FXCONST_DBL(1.0f)) >
|
||||
FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)) {
|
||||
sfbThrReducedLdData = fixMax(
|
||||
sfbThrReducedLdData,
|
||||
sfbEnLdData - FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING));
|
||||
}
|
||||
|
||||
sfbThrReducedLdData = fixMax(MIN_LDTHRESH, sfbThrReducedLdData);
|
||||
|
||||
qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData;
|
||||
|
@ -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
|
||||
@ -151,11 +151,11 @@ typedef struct {
|
||||
|
||||
static const BANDWIDTH_TAB_VBR bandWidthTableVBR[] = {
|
||||
{AACENC_BR_MODE_CBR, 0, 0},
|
||||
{AACENC_BR_MODE_VBR_1, 13050, 13050},
|
||||
{AACENC_BR_MODE_VBR_2, 13050, 13050},
|
||||
{AACENC_BR_MODE_VBR_3, 14260, 14260},
|
||||
{AACENC_BR_MODE_VBR_4, 15500, 15500},
|
||||
{AACENC_BR_MODE_VBR_5, 48000, 48000},
|
||||
{AACENC_BR_MODE_VBR_1, 13000, 13000},
|
||||
{AACENC_BR_MODE_VBR_2, 13000, 13000},
|
||||
{AACENC_BR_MODE_VBR_3, 15750, 15750},
|
||||
{AACENC_BR_MODE_VBR_4, 16500, 16500},
|
||||
{AACENC_BR_MODE_VBR_5, 19293, 19293},
|
||||
{AACENC_BR_MODE_SFR, 0, 0},
|
||||
{AACENC_BR_MODE_FF, 0, 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
|
||||
@ -121,20 +121,15 @@ typedef struct {
|
||||
|
||||
static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = {
|
||||
{QCDATA_BR_MODE_VBR_1,
|
||||
FL2FXCONST_DBL(0.160f)}, /* Approx. 32 - 48 (AC-LC), 32 - 56
|
||||
(AAC-LD/ELD) kbps/channel */
|
||||
FL2FXCONST_DBL(0.150f)}, /* Approx. 32 kbps mono AAC-LC + SBR + PS */
|
||||
{QCDATA_BR_MODE_VBR_2,
|
||||
FL2FXCONST_DBL(0.148f)}, /* Approx. 40 - 56 (AC-LC), 40 - 64
|
||||
(AAC-LD/ELD) kbps/channel */
|
||||
FL2FXCONST_DBL(0.162f)}, /* Approx. 64 kbps stereo AAC-LC + SBR */
|
||||
{QCDATA_BR_MODE_VBR_3,
|
||||
FL2FXCONST_DBL(0.135f)}, /* Approx. 48 - 64 (AC-LC), 48 - 72
|
||||
(AAC-LD/ELD) kbps/channel */
|
||||
FL2FXCONST_DBL(0.176f)}, /* Approx. 96 kbps stereo AAC-LC */
|
||||
{QCDATA_BR_MODE_VBR_4,
|
||||
FL2FXCONST_DBL(0.111f)}, /* Approx. 64 - 80 (AC-LC), 64 - 88
|
||||
(AAC-LD/ELD) kbps/channel */
|
||||
FL2FXCONST_DBL(0.120f)}, /* Approx. 128 kbps stereo AAC-LC */
|
||||
{QCDATA_BR_MODE_VBR_5,
|
||||
FL2FXCONST_DBL(0.070f)} /* Approx. 96 - 120 (AC-LC), 112 - 144
|
||||
(AAC-LD/ELD) kbps/channel */
|
||||
FL2FXCONST_DBL(0.070f)} /* Approx. 192 kbps stereo AAC-LC */
|
||||
};
|
||||
|
||||
static INT isConstantBitrateMode(const QCDATA_BR_MODE bitrateMode) {
|
||||
|
@ -114,6 +114,8 @@ amm-info@iis.fraunhofer.de
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DRC_DEC_LOUDNESS_NOT_PRESENT (LONG)0x7FFFFFFE
|
||||
|
||||
typedef struct s_drc_decoder* HANDLE_DRC_DECODER;
|
||||
typedef struct s_uni_drc_interface* HANDLE_UNI_DRC_INTERFACE;
|
||||
typedef struct s_selection_process_output* HANDLE_SEL_PROC_OUTPUT;
|
||||
@ -150,9 +152,12 @@ typedef enum {
|
||||
DRC_DEC_IS_ACTIVE, /**< MPEG-D DRC payload is present and at least one of
|
||||
Dynamic Range Control (DRC) or Loudness Normalization
|
||||
(LN) is activated */
|
||||
DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED /**< number of output channels if
|
||||
appropriate downmixInstruction exists
|
||||
*/
|
||||
DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED, /**< number of output channels if
|
||||
appropriate downmixInstruction
|
||||
exists */
|
||||
DRC_DEC_OUTPUT_LOUDNESS /**< output loudness in dB, with exponent e = 7, or
|
||||
DRC_DEC_LOUDNESS_NOT_PRESENT if no loudness is
|
||||
contained in the bitstream */
|
||||
} DRC_DEC_USERPARAM;
|
||||
|
||||
typedef enum {
|
||||
|
@ -145,6 +145,10 @@ struct s_drc_decoder {
|
||||
SEL_PROC_OUTPUT selProcOutput;
|
||||
} DRC_DECODER;
|
||||
|
||||
static int _getGainStatus(HANDLE_UNI_DRC_GAIN hUniDrcGain) {
|
||||
return hUniDrcGain->status;
|
||||
}
|
||||
|
||||
static int isResetNeeded(HANDLE_DRC_DECODER hDrcDec,
|
||||
const SEL_PROC_OUTPUT oldSelProcOutput) {
|
||||
int i, resetNeeded = 0;
|
||||
@ -515,6 +519,8 @@ LONG FDK_drcDec_GetParam(HANDLE_DRC_DECODER hDrcDec,
|
||||
}
|
||||
case DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED:
|
||||
return (LONG)hDrcDec->selProcOutput.targetChannelCount;
|
||||
case DRC_DEC_OUTPUT_LOUDNESS:
|
||||
return (LONG)hDrcDec->selProcOutput.outputLoudness;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -729,7 +735,9 @@ FDK_drcDec_ReadUniDrcGain(HANDLE_DRC_DECODER hDrcDec,
|
||||
&(hDrcDec->uniDrcGain));
|
||||
if (dErr) return DRC_DEC_NOT_OK;
|
||||
|
||||
if (_getGainStatus(&(hDrcDec->uniDrcGain))) {
|
||||
hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
|
||||
}
|
||||
|
||||
return DRC_DEC_OK;
|
||||
}
|
||||
@ -751,7 +759,9 @@ FDK_drcDec_ReadUniDrc(HANDLE_DRC_DECODER hDrcDec,
|
||||
startSelectionProcess(hDrcDec);
|
||||
if (dErr) return DRC_DEC_NOT_OK;
|
||||
|
||||
if (_getGainStatus(&(hDrcDec->uniDrcGain))) {
|
||||
hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
|
||||
}
|
||||
|
||||
return DRC_DEC_OK;
|
||||
}
|
||||
|
@ -297,9 +297,11 @@ drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec,
|
||||
int seq, gainSequenceCount;
|
||||
DRC_COEFFICIENTS_UNI_DRC* pCoef =
|
||||
selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
|
||||
if (pCoef == NULL) return DE_OK;
|
||||
|
||||
if (pCoef && pCoef->gainSequenceCount) {
|
||||
gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
|
||||
} else {
|
||||
gainSequenceCount = 1;
|
||||
}
|
||||
|
||||
for (seq = 0; seq < gainSequenceCount; seq++) {
|
||||
int lastNodeIndex = 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
|
||||
@ -199,11 +199,8 @@ drcDec_readUniDrc(HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
|
||||
}
|
||||
}
|
||||
|
||||
if (hUniDrcGain != NULL) {
|
||||
err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault,
|
||||
hUniDrcGain);
|
||||
if (err) return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -487,10 +484,13 @@ drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
|
||||
int seq, gainSequenceCount;
|
||||
DRC_COEFFICIENTS_UNI_DRC* pCoef =
|
||||
selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
|
||||
if (pCoef == NULL) return DE_OK;
|
||||
if (hUniDrcGain == NULL) return DE_OK; /* hUniDrcGain not initialized yet */
|
||||
|
||||
if (hUniDrcGain == NULL) return DE_NOT_OK;
|
||||
hUniDrcGain->status = 0;
|
||||
if (pCoef) {
|
||||
gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
|
||||
} else {
|
||||
gainSequenceCount = 0;
|
||||
}
|
||||
|
||||
for (seq = 0; seq < gainSequenceCount; seq++) {
|
||||
UCHAR index = pCoef->gainSetIndexForGainSequence[seq];
|
||||
@ -518,6 +518,9 @@ drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
|
||||
if (err) return err;
|
||||
}
|
||||
|
||||
if (err == DE_OK && gainSequenceCount > 0) {
|
||||
hUniDrcGain->status = 1;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1018,6 +1021,7 @@ static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
|
||||
int additionalDrcSetIdPresent, additionalDrcSetIdCount;
|
||||
int dependsOnEqSetPresent, eqChannelGroupCount, tdFilterCascadePresent,
|
||||
subbandGainsPresent, eqTransitionDurationPresent;
|
||||
UCHAR eqChannelGroupForChannel[8];
|
||||
|
||||
FDKpushFor(hBs, 6); /* eqSetId */
|
||||
FDKpushFor(hBs, 4); /* eqSetComplexityLevel */
|
||||
@ -1067,7 +1071,6 @@ static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
|
||||
|
||||
eqChannelGroupCount = 0;
|
||||
for (c = 0; c < channelCount; c++) {
|
||||
UCHAR eqChannelGroupForChannel[8];
|
||||
int newGroup = 1;
|
||||
if (c >= 8) return DE_MEMORY_ERROR;
|
||||
eqChannelGroupForChannel[c] = FDKreadBits(hBs, 7);
|
||||
|
@ -103,8 +103,6 @@ amm-info@iis.fraunhofer.de
|
||||
#include "drcDec_selectionProcess.h"
|
||||
#include "drcDec_tools.h"
|
||||
|
||||
#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL) MAXVAL_DBL
|
||||
|
||||
typedef enum {
|
||||
DETR_NONE = 0,
|
||||
DETR_NIGHT = 1,
|
||||
@ -753,8 +751,8 @@ static DRCDEC_SELECTION_PROCESS_RETURN _initDefaultParams(
|
||||
hSelProcInput->loudnessNormalizationOn = 1;
|
||||
hSelProcInput->targetLoudness = FL2FXCONST_DBL(-24.0f / (float)(1 << 7));
|
||||
hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
|
||||
hSelProcInput->loudnessMeasurementMethod = MDR_DEFAULT;
|
||||
hSelProcInput->loudnessMeasurementSystem = MSR_DEFAULT;
|
||||
hSelProcInput->loudnessMeasurementMethod = MDR_ANCHOR_LOUDNESS;
|
||||
hSelProcInput->loudnessMeasurementSystem = MSR_EXPERT_PANEL;
|
||||
hSelProcInput->loudnessMeasurementPreProc = LPR_DEFAULT;
|
||||
hSelProcInput->deviceCutOffFrequency = 500;
|
||||
hSelProcInput->loudnessNormalizationGainDbMax =
|
||||
@ -956,17 +954,31 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement4(
|
||||
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
||||
}
|
||||
|
||||
/* #5: The number of DRC bands is supported. */
|
||||
/* #5: The number of DRC bands is supported. Moreover, gainSetIndex and
|
||||
* gainSequenceIndex are within the allowed range. */
|
||||
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5(
|
||||
DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
|
||||
DRC_COEFFICIENTS_UNI_DRC* pCoef, int* pMatchFound) {
|
||||
int i;
|
||||
int b, i;
|
||||
|
||||
*pMatchFound = 1;
|
||||
|
||||
if (pDrcInstructionUniDrc->drcSetId < 0) /* virtual DRC sets are okay */
|
||||
{
|
||||
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
||||
}
|
||||
|
||||
if (pCoef == NULL) /* check for parametricDRC */
|
||||
{
|
||||
*pMatchFound = 1;
|
||||
*pMatchFound = 0; /* parametricDRC not supported */
|
||||
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
||||
}
|
||||
|
||||
if (pCoef->drcLocation !=
|
||||
pDrcInstructionUniDrc
|
||||
->drcLocation) /* drcLocation must be LOCATION_SELECTED */
|
||||
{
|
||||
*pMatchFound = 0;
|
||||
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
||||
}
|
||||
|
||||
@ -974,10 +986,14 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5(
|
||||
int indexDrcCoeff = pDrcInstructionUniDrc->gainSetIndexForChannelGroup[i];
|
||||
int bandCount = 0;
|
||||
|
||||
if (indexDrcCoeff >= 12) {
|
||||
*pMatchFound = 0;
|
||||
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
||||
}
|
||||
|
||||
if (indexDrcCoeff > pCoef->gainSetCount - 1) /* check for parametricDRC */
|
||||
{
|
||||
*pMatchFound = 1;
|
||||
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
||||
continue;
|
||||
}
|
||||
|
||||
GAIN_SET* gainSet = &(pCoef->gainSet[indexDrcCoeff]);
|
||||
@ -986,6 +1002,14 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5(
|
||||
if (bandCount > 4) {
|
||||
*pMatchFound = 0;
|
||||
}
|
||||
|
||||
for (b = 0; b < bandCount; b++) {
|
||||
if ((gainSet->gainSequenceIndex[b] >= 12) ||
|
||||
(gainSet->gainSequenceIndex[b] >= pCoef->gainSequenceCount)) {
|
||||
*pMatchFound = 0;
|
||||
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
||||
@ -1078,6 +1102,19 @@ static int _targetLoudnessInRange(
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static int _drcSetIsUsable(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
|
||||
DRC_INSTRUCTIONS_UNI_DRC* pInst) {
|
||||
int usable = 0;
|
||||
DRC_COEFFICIENTS_UNI_DRC* pCoef =
|
||||
selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
|
||||
|
||||
/* check if ID is unique */
|
||||
if (selectDrcInstructions(hUniDrcConfig, pInst->drcSetId) != pInst) return 0;
|
||||
/* sanity check on drcInstructions */
|
||||
_preSelectionRequirement5(pInst, pCoef, &usable);
|
||||
return usable;
|
||||
}
|
||||
|
||||
/* #8: The range of the target loudness specified for a DRC set has to include
|
||||
* the requested decoder target loudness. */
|
||||
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
|
||||
@ -1097,9 +1134,8 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
|
||||
|
||||
FIXP_DBL loudnessDeviationMax =
|
||||
((FIXP_DBL)hSelProcInput->loudnessDeviationMax) << (DFRACT_BITS - 1 - 7);
|
||||
;
|
||||
|
||||
if (hSelProcInput->loudnessNormalizationOn) {
|
||||
{
|
||||
retVal = _getLoudness(hLoudnessInfoSet, hSelProcInput->albumMode,
|
||||
hSelProcInput->loudnessMeasurementMethod,
|
||||
hSelProcInput->loudnessMeasurementSystem,
|
||||
@ -1108,9 +1144,10 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
|
||||
hSelProcInput->downmixIdRequested[downmixIdIndex],
|
||||
&loudnessNormalizationGainDb, &loudness);
|
||||
if (retVal) return (retVal);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (!hSelProcInput->loudnessNormalizationOn) {
|
||||
loudnessNormalizationGainDb = (FIXP_DBL)0;
|
||||
loudness = UNDEFINED_LOUDNESS_VALUE;
|
||||
}
|
||||
|
||||
retVal = _getSignalPeakLevel(
|
||||
@ -2031,6 +2068,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
|
||||
pSelectionData->loudnessNormalizationGainDbAdjusted +
|
||||
hSelProcInput->loudnessNormalizationGainModificationDb;
|
||||
hSelProcOutput->outputPeakLevelDb = pSelectionData->outputPeakLevel;
|
||||
hSelProcOutput->outputLoudness = pSelectionData->outputLoudness;
|
||||
|
||||
hSelProcOutput->boost = boost;
|
||||
hSelProcOutput->compress = compress;
|
||||
@ -2051,8 +2089,11 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
|
||||
int dependsOnDrcSetID = pSelectionData->pInst->dependsOnDrcSet;
|
||||
|
||||
for (i = 0; i < hUniDrcConfig->drcInstructionsCountInclVirtual; i++) {
|
||||
if (hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId ==
|
||||
dependsOnDrcSetID) {
|
||||
DRC_INSTRUCTIONS_UNI_DRC* pInst =
|
||||
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
|
||||
if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
|
||||
|
||||
if (pInst->drcSetId == dependsOnDrcSetID) {
|
||||
hSelProcOutput->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
|
||||
hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
|
||||
hSelProcOutput->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] =
|
||||
@ -2071,6 +2112,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
|
||||
for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
|
||||
DRC_INSTRUCTIONS_UNI_DRC* pInst =
|
||||
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
|
||||
if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
|
||||
|
||||
if (pInst->drcSetEffect & EB_FADE) {
|
||||
if (pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) {
|
||||
@ -2098,6 +2140,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
|
||||
for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
|
||||
DRC_INSTRUCTIONS_UNI_DRC* pInst =
|
||||
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
|
||||
if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
|
||||
|
||||
if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
|
||||
for (j = 0; j < pInst->downmixIdCount; j++) {
|
||||
@ -2124,6 +2167,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
|
||||
for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
|
||||
DRC_INSTRUCTIONS_UNI_DRC* pInst =
|
||||
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
|
||||
if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
|
||||
|
||||
if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
|
||||
for (j = 0; j < pInst->downmixIdCount; j++) {
|
||||
@ -2231,6 +2275,11 @@ static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelection(
|
||||
for (j = 0; j < hUniDrcConfig->drcInstructionsCountInclVirtual; j++) {
|
||||
DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction =
|
||||
&(hUniDrcConfig->drcInstructionsUniDrc[j]);
|
||||
/* check if ID is unique */
|
||||
if (selectDrcInstructions(hUniDrcConfig, pDrcInstruction->drcSetId) !=
|
||||
pDrcInstruction)
|
||||
continue;
|
||||
|
||||
retVal = _drcSetPreSelectionSingleInstruction(
|
||||
hSelProcInput, i, hUniDrcConfig, hLoudnessInfoSet, pDrcInstruction,
|
||||
*ppCandidatesPotential, *ppCandidatesSelected, codecMode);
|
||||
|
@ -111,6 +111,8 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
typedef struct s_drcdec_selection_process* HANDLE_DRC_SELECTION_PROCESS;
|
||||
|
||||
#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL)(MAXVAL_DBL - 1)
|
||||
|
||||
typedef enum {
|
||||
DRCDEC_SELECTION_PROCESS_NO_ERROR = 0,
|
||||
|
||||
|
@ -130,6 +130,9 @@ typedef struct {
|
||||
|
||||
UCHAR uniDrcGainExtPresent;
|
||||
UNI_DRC_GAIN_EXTENSION uniDrcGainExtension;
|
||||
|
||||
/* derived data */
|
||||
UCHAR status;
|
||||
} UNI_DRC_GAIN, *HANDLE_UNI_DRC_GAIN;
|
||||
|
||||
/****************/
|
||||
|
@ -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
|
||||
@ -285,6 +285,9 @@ static DRC_ERROR _compressorIO_sigmoid_common(
|
||||
&e_tmp2);
|
||||
invExp = fDivNorm(FL2FXCONST_DBL(1.0f / (float)(1 << 1)), exp, &e_invExp);
|
||||
e_invExp += 1 - 5;
|
||||
if (tmp2 < (FIXP_DBL)0) {
|
||||
return DE_NOT_OK;
|
||||
}
|
||||
denom = fPow(tmp2, e_tmp2, invExp, e_invExp, &e_denom);
|
||||
*out = fDivNormSigned(tmp, denom, &e_out);
|
||||
e_out += 7 - e_denom;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -123,11 +123,10 @@ typedef enum {
|
||||
#define QMF_WB_SECTION_SIZE (1024 * 2)
|
||||
|
||||
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL)
|
||||
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL)
|
||||
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL)
|
||||
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL)
|
||||
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL)
|
||||
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL)
|
||||
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL)
|
||||
|
||||
#define QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS (64)
|
||||
#define QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS (QMF_MAX_SYNTHESIS_BANDS)
|
||||
@ -145,15 +144,15 @@ H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL)
|
||||
#define QMF_DOMAIN_OV_TIMESLOTS_16 (3)
|
||||
#define QMF_DOMAIN_OV_TIMESLOTS_32 (6)
|
||||
|
||||
H_ALLOC_MEM(AnaQmfStates, FIXP_QAS)
|
||||
H_ALLOC_MEM(AnaQmfStates, FIXP_DBL)
|
||||
H_ALLOC_MEM(SynQmfStates, FIXP_QSS)
|
||||
H_ALLOC_MEM(QmfSlotsReal, FIXP_DBL *)
|
||||
H_ALLOC_MEM(QmfSlotsImag, FIXP_DBL *)
|
||||
H_ALLOC_MEM(QmfOverlapBuffer, FIXP_DBL)
|
||||
|
||||
H_ALLOC_MEM(AnaQmfStates16, FIXP_QAS)
|
||||
H_ALLOC_MEM(AnaQmfStates24, FIXP_QAS)
|
||||
H_ALLOC_MEM(AnaQmfStates32, FIXP_QAS)
|
||||
H_ALLOC_MEM(AnaQmfStates16, FIXP_DBL)
|
||||
H_ALLOC_MEM(AnaQmfStates24, FIXP_DBL)
|
||||
H_ALLOC_MEM(AnaQmfStates32, FIXP_DBL)
|
||||
H_ALLOC_MEM(QmfSlotsReal16, FIXP_DBL *)
|
||||
H_ALLOC_MEM(QmfSlotsReal32, FIXP_DBL *)
|
||||
H_ALLOC_MEM(QmfSlotsImag16, FIXP_DBL *)
|
||||
@ -161,8 +160,6 @@ H_ALLOC_MEM(QmfSlotsImag32, FIXP_DBL *)
|
||||
H_ALLOC_MEM(QmfOverlapBuffer16, FIXP_DBL)
|
||||
H_ALLOC_MEM(QmfOverlapBuffer32, FIXP_DBL)
|
||||
|
||||
#define QDOM_PCM INT_PCM
|
||||
|
||||
/**
|
||||
* Structure to hold the configuration data which is global whithin a QMF domain
|
||||
* instance.
|
||||
@ -182,9 +179,6 @@ typedef struct {
|
||||
park a channel if only one processing channel is
|
||||
available. */
|
||||
UCHAR parkChannel_requested;
|
||||
QDOM_PCM
|
||||
*TDinput; /*!< Pointer to time domain data used as input for the QMF
|
||||
analysis. */
|
||||
FIXP_DBL *
|
||||
pWorkBuffer[QMF_MAX_WB_SECTIONS]; /*!< Pointerarray to volatile memory. */
|
||||
UINT flags; /*!< Flags to be set on all QMF analysis/synthesis filter
|
||||
@ -244,7 +238,7 @@ typedef struct {
|
||||
(workBuf_nTimeSlots * workBuf_nBands * CMPLX_MOD). */
|
||||
USHORT workBufferOffset; /*!< Offset within work buffer. */
|
||||
USHORT workBufferSectSize; /*!< Size of work buffer section. */
|
||||
FIXP_QAS *
|
||||
FIXP_DBL *
|
||||
pAnaQmfStates; /*!< Pointer to QMF analysis states (persistent memory). */
|
||||
FIXP_DBL
|
||||
*pOverlapBuffer; /*!< Pointer to QMF overlap/delay memory (persistent
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -171,6 +171,19 @@ extern const FIXP_DBL invSqrtTab[SQRT_VALUES];
|
||||
* \return non-zero if (a_m*2^a_e) < (b_m*2^b_e), 0 otherwise
|
||||
*/
|
||||
FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e) {
|
||||
INT n;
|
||||
|
||||
n = fixnorm_D(a_m);
|
||||
a_m <<= n;
|
||||
a_e -= n;
|
||||
|
||||
n = fixnorm_D(b_m);
|
||||
b_m <<= n;
|
||||
b_e -= n;
|
||||
|
||||
if (a_m == (FIXP_DBL)0) a_e = b_e;
|
||||
if (b_m == (FIXP_DBL)0) b_e = a_e;
|
||||
|
||||
if (a_e > b_e) {
|
||||
return ((b_m >> fMin(a_e - b_e, DFRACT_BITS - 1)) > a_m);
|
||||
} else {
|
||||
@ -179,6 +192,19 @@ FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e) {
|
||||
}
|
||||
|
||||
FDK_INLINE INT fIsLessThan(FIXP_SGL a_m, INT a_e, FIXP_SGL b_m, INT b_e) {
|
||||
INT n;
|
||||
|
||||
n = fixnorm_S(a_m);
|
||||
a_m <<= n;
|
||||
a_e -= n;
|
||||
|
||||
n = fixnorm_S(b_m);
|
||||
b_m <<= n;
|
||||
b_e -= n;
|
||||
|
||||
if (a_m == (FIXP_SGL)0) a_e = b_e;
|
||||
if (b_m == (FIXP_SGL)0) b_e = a_e;
|
||||
|
||||
if (a_e > b_e) {
|
||||
return ((b_m >> fMin(a_e - b_e, FRACT_BITS - 1)) > a_m);
|
||||
} else {
|
||||
@ -545,17 +571,22 @@ inline INT fMultIceil(FIXP_DBL a, INT b) {
|
||||
m = fMultNorm(a, (FIXP_DBL)b, &m_e);
|
||||
|
||||
if (m_e < (INT)0) {
|
||||
if (m_e > (INT)-DFRACT_BITS) {
|
||||
if (m_e > (INT) - (DFRACT_BITS - 1)) {
|
||||
mi = (m >> (-m_e));
|
||||
if ((LONG)m & ((1 << (-m_e)) - 1)) {
|
||||
mi = mi + (FIXP_DBL)1;
|
||||
}
|
||||
} else {
|
||||
if (m > (FIXP_DBL)0) {
|
||||
mi = (FIXP_DBL)1;
|
||||
if (m < (FIXP_DBL)0) {
|
||||
} else {
|
||||
if ((m_e == -(DFRACT_BITS - 1)) && (m == (FIXP_DBL)MINVAL_DBL)) {
|
||||
mi = (FIXP_DBL)-1;
|
||||
} else {
|
||||
mi = (FIXP_DBL)0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mi = scaleValueSaturate(m, m_e);
|
||||
}
|
||||
@ -744,7 +775,7 @@ FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
|
||||
|
||||
/**
|
||||
* \brief return (base_m * 2^base_e) ^ N
|
||||
* \param base_m mantissa of the base
|
||||
* \param base_m mantissa of the base. Must not be negative.
|
||||
* \param base_e exponent of the base
|
||||
* \param N power to be calculated of the base
|
||||
* \param result_e pointer to a INT where the exponent of the result will be
|
||||
|
@ -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
|
||||
@ -116,6 +116,7 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
#define FIXP_QAS FIXP_PCM
|
||||
#define QAS_BITS SAMPLE_BITS
|
||||
#define INT_PCM_QMFIN INT_PCM
|
||||
|
||||
#define FIXP_QSS FIXP_DBL
|
||||
#define QSS_BITS DFRACT_BITS
|
||||
@ -201,16 +202,25 @@ struct QMF_FILTER_BANK {
|
||||
|
||||
typedef struct QMF_FILTER_BANK *HANDLE_QMF_FILTER_BANK;
|
||||
|
||||
void qmfAnalysisFiltering(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
|
||||
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
|
||||
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
|
||||
QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
|
||||
const LONG *timeIn, /*!< Time signal */
|
||||
const int timeIn_e, /*!< Exponent of audio data */
|
||||
const int stride, /*!< Stride factor of audio data */
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
|
||||
);
|
||||
int qmfInitAnalysisFilterBank(
|
||||
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
|
||||
FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */
|
||||
int noCols, /*!< Number of time slots */
|
||||
int lsb, /*!< Number of lower bands */
|
||||
int usb, /*!< Number of upper bands */
|
||||
int no_channels, /*!< Number of critically sampled bands */
|
||||
int flags); /*!< Flags */
|
||||
#if SAMPLE_BITS == 16
|
||||
|
||||
int qmfInitAnalysisFilterBank(
|
||||
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
|
||||
FIXP_DBL *pFilterStates, /*!< Pointer to filter state buffer */
|
||||
int noCols, /*!< Number of time slots */
|
||||
int lsb, /*!< Number of lower bands */
|
||||
int usb, /*!< Number of upper bands */
|
||||
int no_channels, /*!< Number of critically sampled bands */
|
||||
int flags); /*!< Flags */
|
||||
#endif
|
||||
|
||||
void qmfAnalysisFiltering(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
|
||||
@ -222,6 +232,48 @@ void qmfAnalysisFiltering(
|
||||
const int stride, /*!< Stride factor of audio data */
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
|
||||
);
|
||||
#if SAMPLE_BITS == 16
|
||||
|
||||
void qmfAnalysisFiltering(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
|
||||
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
|
||||
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
|
||||
QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
|
||||
const LONG *timeIn, /*!< Time signal */
|
||||
const int timeIn_e, /*!< Exponent of audio data */
|
||||
const int stride, /*!< Stride factor of audio data */
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
|
||||
);
|
||||
#endif
|
||||
|
||||
void qmfAnalysisFilteringSlot(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
|
||||
FIXP_DBL *qmfReal, /*!< Low and High band, real */
|
||||
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
|
||||
const INT_PCM *timeIn, /*!< Pointer to input */
|
||||
const int stride, /*!< stride factor of input */
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
|
||||
);
|
||||
#if SAMPLE_BITS == 16
|
||||
|
||||
void qmfAnalysisFilteringSlot(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
|
||||
FIXP_DBL *qmfReal, /*!< Low and High band, real */
|
||||
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
|
||||
const LONG *timeIn, /*!< Pointer to input */
|
||||
const int stride, /*!< stride factor of input */
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
|
||||
);
|
||||
#endif
|
||||
|
||||
int qmfInitSynthesisFilterBank(
|
||||
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
|
||||
FIXP_QSS *pFilterStates, /*!< Pointer to filter state buffer */
|
||||
int noCols, /*!< Number of time slots */
|
||||
int lsb, /*!< Number of lower bands */
|
||||
int usb, /*!< Number of upper bands */
|
||||
int no_channels, /*!< Number of critically sampled bands */
|
||||
int flags); /*!< Flags */
|
||||
|
||||
void qmfSynthesisFiltering(
|
||||
HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
|
||||
@ -234,41 +286,19 @@ void qmfSynthesisFiltering(
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer. It must be
|
||||
aligned */
|
||||
);
|
||||
#if SAMPLE_BITS == 16
|
||||
|
||||
int qmfInitAnalysisFilterBank(
|
||||
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
|
||||
FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */
|
||||
int noCols, /*!< Number of time slots */
|
||||
int lsb, /*!< Number of lower bands */
|
||||
int usb, /*!< Number of upper bands */
|
||||
int no_channels, /*!< Number of critically sampled bands */
|
||||
int flags); /*!< Flags */
|
||||
|
||||
void qmfAnalysisFilteringSlot(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
|
||||
FIXP_DBL *qmfReal, /*!< Low and High band, real */
|
||||
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
|
||||
const LONG *timeIn, /*!< Pointer to input */
|
||||
const int stride, /*!< stride factor of input */
|
||||
void qmfSynthesisFiltering(
|
||||
HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
|
||||
FIXP_DBL **QmfBufferReal, /*!< Pointer to real subband slots */
|
||||
FIXP_DBL **QmfBufferImag, /*!< Pointer to imag subband slots */
|
||||
const QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
|
||||
const int ov_len, /*!< Length of band overlap */
|
||||
LONG *timeOut, /*!< Time signal */
|
||||
const int timeOut_e, /*!< Target exponent for timeOut */
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
|
||||
);
|
||||
|
||||
void qmfAnalysisFilteringSlot(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
|
||||
FIXP_DBL *qmfReal, /*!< Low and High band, real */
|
||||
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
|
||||
const INT_PCM *timeIn, /*!< Pointer to input */
|
||||
const int stride, /*!< stride factor of input */
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
|
||||
);
|
||||
int qmfInitSynthesisFilterBank(
|
||||
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
|
||||
FIXP_QSS *pFilterStates, /*!< Pointer to filter state buffer */
|
||||
int noCols, /*!< Number of time slots */
|
||||
int lsb, /*!< Number of lower bands */
|
||||
int usb, /*!< Number of upper bands */
|
||||
int no_channels, /*!< Number of critically sampled bands */
|
||||
int flags); /*!< Flags */
|
||||
#endif
|
||||
|
||||
void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
|
||||
const FIXP_DBL *realSlot,
|
||||
@ -276,6 +306,15 @@ void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
|
||||
const int scaleFactorLowBand,
|
||||
const int scaleFactorHighBand, INT_PCM *timeOut,
|
||||
const int timeOut_e, FIXP_DBL *pWorkBuffer);
|
||||
#if SAMPLE_BITS == 16
|
||||
|
||||
void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
|
||||
const FIXP_DBL *realSlot,
|
||||
const FIXP_DBL *imagSlot,
|
||||
const int scaleFactorLowBand,
|
||||
const int scaleFactorHighBand, LONG *timeOut,
|
||||
const int timeOut_e, FIXP_DBL *pWorkBuffer);
|
||||
#endif
|
||||
|
||||
void qmfChangeOutScalefactor(
|
||||
HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
|
||||
@ -291,11 +330,5 @@ void qmfChangeOutGain(
|
||||
FIXP_DBL outputGain, /*!< New gain for output data (mantissa) */
|
||||
int outputGainScale /*!< New gain for output data (exponent) */
|
||||
);
|
||||
void qmfSynPrototypeFirSlot(
|
||||
HANDLE_QMF_FILTER_BANK qmf,
|
||||
FIXP_DBL *RESTRICT realSlot, /*!< Input: Pointer to real Slot */
|
||||
FIXP_DBL *RESTRICT imagSlot, /*!< Input: Pointer to imag Slot */
|
||||
INT_PCM *RESTRICT timeOut, /*!< Time domain data */
|
||||
const int timeOut_e);
|
||||
|
||||
#endif /*ifndef QMF_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -402,4 +402,220 @@ void qmfSynthesisFiltering(
|
||||
timeOut + (i * L * stride), stride, pWorkBuffer);
|
||||
} /* no_col loop i */
|
||||
}
|
||||
|
||||
/*!
|
||||
*
|
||||
* \brief Create QMF filter bank instance
|
||||
*
|
||||
*
|
||||
* \return 0 if successful
|
||||
*
|
||||
*/
|
||||
int qmfInitAnalysisFilterBank(
|
||||
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */
|
||||
FIXP_QAS *pFilterStates, /*!< Handle to filter states */
|
||||
int noCols, /*!< Number of timeslots per frame */
|
||||
int lsb, /*!< lower end of QMF */
|
||||
int usb, /*!< upper end of QMF */
|
||||
int no_channels, /*!< Number of channels (bands) */
|
||||
int flags) /*!< Low Power flag */
|
||||
{
|
||||
int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb,
|
||||
no_channels, flags, 0);
|
||||
if (!(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL)) {
|
||||
FDKmemclear(h_Qmf->FilterStates,
|
||||
(2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QAS));
|
||||
}
|
||||
|
||||
FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifndef FUNCTION_qmfAnaPrototypeFirSlot
|
||||
/*!
|
||||
\brief Perform Analysis Prototype Filtering on a single slot of input data.
|
||||
*/
|
||||
static void qmfAnaPrototypeFirSlot(
|
||||
FIXP_DBL *analysisBuffer,
|
||||
INT no_channels, /*!< Number channels of analysis filter */
|
||||
const FIXP_PFT *p_filter, INT p_stride, /*!< Stride of analysis filter */
|
||||
FIXP_QAS *RESTRICT pFilterStates) {
|
||||
INT k;
|
||||
|
||||
FIXP_DBL accu;
|
||||
const FIXP_PFT *RESTRICT p_flt = p_filter;
|
||||
FIXP_DBL *RESTRICT pData_0 = analysisBuffer + 2 * no_channels - 1;
|
||||
FIXP_DBL *RESTRICT pData_1 = analysisBuffer;
|
||||
|
||||
FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates;
|
||||
FIXP_QAS *RESTRICT sta_1 =
|
||||
(FIXP_QAS *)pFilterStates + (2 * QMF_NO_POLY * no_channels) - 1;
|
||||
INT pfltStep = QMF_NO_POLY * (p_stride);
|
||||
INT staStep1 = no_channels << 1;
|
||||
INT staStep2 = (no_channels << 3) - 1; /* Rewind one less */
|
||||
|
||||
/* FIR filters 127..64 0..63 */
|
||||
for (k = 0; k < no_channels; k++) {
|
||||
accu = fMultDiv2(p_flt[0], *sta_1);
|
||||
sta_1 -= staStep1;
|
||||
accu += fMultDiv2(p_flt[1], *sta_1);
|
||||
sta_1 -= staStep1;
|
||||
accu += fMultDiv2(p_flt[2], *sta_1);
|
||||
sta_1 -= staStep1;
|
||||
accu += fMultDiv2(p_flt[3], *sta_1);
|
||||
sta_1 -= staStep1;
|
||||
accu += fMultDiv2(p_flt[4], *sta_1);
|
||||
*pData_1++ = (accu << 1);
|
||||
sta_1 += staStep2;
|
||||
|
||||
p_flt += pfltStep;
|
||||
accu = fMultDiv2(p_flt[0], *sta_0);
|
||||
sta_0 += staStep1;
|
||||
accu += fMultDiv2(p_flt[1], *sta_0);
|
||||
sta_0 += staStep1;
|
||||
accu += fMultDiv2(p_flt[2], *sta_0);
|
||||
sta_0 += staStep1;
|
||||
accu += fMultDiv2(p_flt[3], *sta_0);
|
||||
sta_0 += staStep1;
|
||||
accu += fMultDiv2(p_flt[4], *sta_0);
|
||||
*pData_0-- = (accu << 1);
|
||||
sta_0 -= staStep2;
|
||||
}
|
||||
}
|
||||
#endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */
|
||||
|
||||
#ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric
|
||||
/*!
|
||||
\brief Perform Analysis Prototype Filtering on a single slot of input data.
|
||||
*/
|
||||
static void qmfAnaPrototypeFirSlot_NonSymmetric(
|
||||
FIXP_DBL *analysisBuffer,
|
||||
int no_channels, /*!< Number channels of analysis filter */
|
||||
const FIXP_PFT *p_filter, int p_stride, /*!< Stride of analysis filter */
|
||||
FIXP_QAS *RESTRICT pFilterStates) {
|
||||
const FIXP_PFT *RESTRICT p_flt = p_filter;
|
||||
int p, k;
|
||||
|
||||
for (k = 0; k < 2 * no_channels; k++) {
|
||||
FIXP_DBL accu = (FIXP_DBL)0;
|
||||
|
||||
p_flt += QMF_NO_POLY * (p_stride - 1);
|
||||
|
||||
/*
|
||||
Perform FIR-Filter
|
||||
*/
|
||||
for (p = 0; p < QMF_NO_POLY; p++) {
|
||||
accu += fMultDiv2(*p_flt++, pFilterStates[2 * no_channels * p]);
|
||||
}
|
||||
analysisBuffer[2 * no_channels - 1 - k] = (accu << 1);
|
||||
pFilterStates++;
|
||||
}
|
||||
}
|
||||
#endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */
|
||||
|
||||
/*
|
||||
* \brief Perform one QMF slot analysis of the time domain data of timeIn
|
||||
* with specified stride and stores the real part of the subband
|
||||
* samples in rSubband, and the imaginary part in iSubband
|
||||
*
|
||||
* Note: anaQmf->lsb can be greater than anaQmf->no_channels in case
|
||||
* of implicit resampling (USAC with reduced 3/4 core frame length).
|
||||
*/
|
||||
void qmfAnalysisFilteringSlot(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
|
||||
FIXP_DBL *qmfReal, /*!< Low and High band, real */
|
||||
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
|
||||
const INT_PCM_QMFIN *RESTRICT timeIn, /*!< Pointer to input */
|
||||
const int stride, /*!< stride factor of input */
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
|
||||
) {
|
||||
int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1);
|
||||
/*
|
||||
Feed time signal into oldest anaQmf->no_channels states
|
||||
*/
|
||||
{
|
||||
FIXP_QAS *FilterStatesAnaTmp = ((FIXP_QAS *)anaQmf->FilterStates) + offset;
|
||||
|
||||
/* Feed and scale actual time in slot */
|
||||
for (int i = anaQmf->no_channels >> 1; i != 0; i--) {
|
||||
/* Place INT_PCM value left aligned in scaledTimeIn */
|
||||
*FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
|
||||
timeIn += stride;
|
||||
*FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
|
||||
timeIn += stride;
|
||||
}
|
||||
}
|
||||
|
||||
if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
|
||||
qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels,
|
||||
anaQmf->p_filter, anaQmf->p_stride,
|
||||
(FIXP_QAS *)anaQmf->FilterStates);
|
||||
} else {
|
||||
qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter,
|
||||
anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates);
|
||||
}
|
||||
|
||||
if (anaQmf->flags & QMF_FLAG_LP) {
|
||||
if (anaQmf->flags & QMF_FLAG_CLDFB)
|
||||
qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal);
|
||||
else
|
||||
qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal);
|
||||
|
||||
} else {
|
||||
qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag);
|
||||
}
|
||||
/*
|
||||
Shift filter states
|
||||
|
||||
Should be realized with modulo addressing on a DSP instead of a true buffer
|
||||
shift
|
||||
*/
|
||||
FDKmemmove(anaQmf->FilterStates,
|
||||
(FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels,
|
||||
offset * sizeof(FIXP_QAS));
|
||||
}
|
||||
|
||||
/*!
|
||||
*
|
||||
* \brief Perform complex-valued subband filtering of the time domain
|
||||
* data of timeIn and stores the real part of the subband
|
||||
* samples in rAnalysis, and the imaginary part in iAnalysis
|
||||
* The qmf coefficient table is symmetric. The symmetry is expoited by
|
||||
* shrinking the coefficient table to half the size. The addressing mode
|
||||
* takes care of the symmetries.
|
||||
*
|
||||
*
|
||||
* \sa PolyphaseFiltering
|
||||
*/
|
||||
void qmfAnalysisFiltering(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
|
||||
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
|
||||
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
|
||||
QMF_SCALE_FACTOR *scaleFactor,
|
||||
const INT_PCM_QMFIN *timeIn, /*!< Time signal */
|
||||
const int timeIn_e, const int stride,
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
|
||||
) {
|
||||
int i;
|
||||
int no_channels = anaQmf->no_channels;
|
||||
|
||||
scaleFactor->lb_scale =
|
||||
-ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e;
|
||||
scaleFactor->lb_scale -= anaQmf->filterScale;
|
||||
|
||||
for (i = 0; i < anaQmf->no_col; i++) {
|
||||
FIXP_DBL *qmfImagSlot = NULL;
|
||||
|
||||
if (!(anaQmf->flags & QMF_FLAG_LP)) {
|
||||
qmfImagSlot = qmfImag[i];
|
||||
}
|
||||
|
||||
qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride,
|
||||
pWorkBuffer);
|
||||
|
||||
timeIn += no_channels * stride;
|
||||
|
||||
} /* no_col loop i */
|
||||
}
|
||||
#endif /* QMF_PCM_H */
|
||||
|
@ -129,15 +129,13 @@ void scaleCplxValues(FIXP_DBL *r_dst, FIXP_DBL *i_dst, const FIXP_DBL *r_src,
|
||||
void scaleValuesWithFactor(FIXP_DBL *vector, FIXP_DBL factor, INT len,
|
||||
INT scalefactor);
|
||||
void scaleValuesSaturate(FIXP_DBL *vector, INT len, INT scalefactor);
|
||||
void scaleValuesSaturate(FIXP_DBL *dst, FIXP_DBL *src, INT len,
|
||||
void scaleValuesSaturate(FIXP_DBL *dst, const FIXP_DBL *src, INT len,
|
||||
INT scalefactor);
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, FIXP_DBL *src, INT len,
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, const FIXP_DBL *src, INT len,
|
||||
INT scalefactor);
|
||||
void scaleValuesSaturate(INT_PCM *dst, FIXP_DBL *src, INT len, INT scalefactor);
|
||||
void scaleValuesSaturate(FIXP_SGL *vector, INT len, INT scalefactor);
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, FIXP_SGL *src, INT len,
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, const FIXP_SGL *src, INT len,
|
||||
INT scalefactor);
|
||||
void scaleValuesSaturate(INT_PCM *dst, INT_PCM *src, INT len, INT scalefactor);
|
||||
INT getScalefactorShort(const SHORT *vector, INT len);
|
||||
INT getScalefactorPCM(const INT_PCM *vector, INT len, INT stride);
|
||||
INT getScalefactor(const FIXP_DBL *vector, INT len);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -368,7 +368,10 @@ void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf, const UCHAR *RESTRICT inputBuffer,
|
||||
|
||||
UINT bTotal = 0;
|
||||
|
||||
UINT bToRead = (hBitBuf->bufBits - hBitBuf->ValidBits) >> 3;
|
||||
UINT bToRead =
|
||||
fMin(hBitBuf->bufBits,
|
||||
(UINT)fMax(0, ((INT)hBitBuf->bufBits - (INT)hBitBuf->ValidBits))) >>
|
||||
3;
|
||||
UINT noOfBytes =
|
||||
fMin(bToRead,
|
||||
*bytesValid); //(bToRead < *bytesValid) ? bToRead : *bytesValid ;
|
||||
@ -384,7 +387,7 @@ void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf, const UCHAR *RESTRICT inputBuffer,
|
||||
bToRead * sizeof(UCHAR));
|
||||
|
||||
/* add noOfBits to number of valid bits in buffer */
|
||||
hBitBuf->ValidBits += bToRead << 3;
|
||||
hBitBuf->ValidBits = (UINT)((INT)hBitBuf->ValidBits + (INT)(bToRead << 3));
|
||||
bTotal += bToRead;
|
||||
inputBuffer += bToRead;
|
||||
|
||||
|
@ -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 SUPPRESS_BUILD_DATE_INFO
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -227,7 +227,7 @@ static inline int SpatialDecGetQmfBand(int paramBand, const UCHAR *tab) {
|
||||
}
|
||||
|
||||
#define DUCKER_MAX_NRG_SCALE (24)
|
||||
#define DUCKER_HEADROOM_BITS (3)
|
||||
#define DUCKER_HEADROOM_BITS (2)
|
||||
|
||||
#define FILTER_SF (2)
|
||||
|
||||
@ -606,10 +606,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
|
||||
dataImagIn += start;
|
||||
dataRealOut += start;
|
||||
dataImagOut += start;
|
||||
#ifdef FUNCTION_DecorrFilterApplyPASS_func1
|
||||
DecorrFilterApplyPASS_func1(i, dataRealIn, dataImagIn, dataRealOut,
|
||||
dataImagOut, pDelayBuffer, offset);
|
||||
#else
|
||||
do {
|
||||
FIXP_DBL delay_re, delay_im, real, imag;
|
||||
|
||||
@ -623,7 +619,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
|
||||
*dataImagOut++ = delay_im;
|
||||
pDelayBuffer += offset;
|
||||
} while (--i != 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1061,24 +1056,15 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
|
||||
FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
|
||||
|
||||
if (maxVal == FL2FXCONST_DBL(-1.0f)) {
|
||||
#ifdef FUNCTION_DuckerCalcEnergy_func2
|
||||
maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
|
||||
maxHybBand, maxHybridBand);
|
||||
#else
|
||||
FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
|
||||
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
||||
localMaxVal |= fAbs(inputReal[qs]);
|
||||
localMaxVal |= fAbs(inputImag[qs]);
|
||||
}
|
||||
for (; qs <= maxHybridBand; qs++) {
|
||||
localMaxVal |= fAbs(inputReal[qs]);
|
||||
}
|
||||
maxVal = localMaxVal;
|
||||
#endif
|
||||
clz = fMin(getScalefactor(&inputReal[startHybBand],
|
||||
fMax(0, maxHybridBand - startHybBand + 1)),
|
||||
getScalefactor(&inputImag[startHybBand],
|
||||
fMax(0, maxHybBand - startHybBand + 1)));
|
||||
} else {
|
||||
clz = CntLeadingZeros(maxVal) - 1;
|
||||
}
|
||||
|
||||
clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
|
||||
clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
|
||||
clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
|
||||
*nrgScale = (SCHAR)clz << 1;
|
||||
|
||||
/* Initialize pb since it would stay uninitialized for the case startHybBand
|
||||
@ -1086,9 +1072,10 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
|
||||
pb = SpatialDecGetProcessingBand(maxHybBand, self->mapHybBands2ProcBands);
|
||||
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
||||
pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
|
||||
energy[pb] =
|
||||
fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
|
||||
fPow2Div2(inputImag[qs] << clz));
|
||||
energy[pb] = SATURATE_LEFT_SHIFT(
|
||||
(energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
|
||||
(fPow2Div2(inputImag[qs] << clz) >> 1),
|
||||
1, DFRACT_BITS);
|
||||
}
|
||||
pb++;
|
||||
|
||||
@ -1112,43 +1099,29 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
|
||||
maxVal = inputMaxVal;
|
||||
|
||||
if (maxVal == FL2FXCONST_DBL(-1.0f)) {
|
||||
#ifdef FUNCTION_DuckerCalcEnergy_func2
|
||||
maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
|
||||
maxHybBand, maxHybridBand);
|
||||
#else
|
||||
FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
|
||||
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
||||
localMaxVal |= fAbs(inputReal[qs]);
|
||||
localMaxVal |= fAbs(inputImag[qs]);
|
||||
}
|
||||
for (; qs <= maxHybridBand; qs++) {
|
||||
localMaxVal |= fAbs(inputReal[qs]);
|
||||
}
|
||||
maxVal = localMaxVal;
|
||||
#endif
|
||||
clz = fMin(getScalefactor(&inputReal[startHybBand],
|
||||
fMax(0, maxHybridBand - startHybBand + 1)),
|
||||
getScalefactor(&inputImag[startHybBand],
|
||||
fMax(0, maxHybBand - startHybBand + 1)));
|
||||
} else {
|
||||
clz = CntLeadingZeros(maxVal) - 1;
|
||||
}
|
||||
|
||||
clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
|
||||
clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
|
||||
clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
|
||||
*nrgScale = (SCHAR)clz << 1;
|
||||
|
||||
#ifdef FUNCTION_DuckerCalcEnergy_func4
|
||||
DuckerCalcEnergy_func4(inputReal, inputImag, energy,
|
||||
self->mapHybBands2ProcBands, clz, startHybBand,
|
||||
maxHybBand, maxHybridBand);
|
||||
#else
|
||||
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
||||
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
|
||||
energy[pb] =
|
||||
fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
|
||||
fPow2Div2(inputImag[qs] << clz));
|
||||
energy[pb] = SATURATE_LEFT_SHIFT(
|
||||
(energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
|
||||
(fPow2Div2(inputImag[qs] << clz) >> 1),
|
||||
1, DFRACT_BITS);
|
||||
}
|
||||
|
||||
for (; qs <= maxHybridBand; qs++) {
|
||||
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
|
||||
energy[pb] = fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz));
|
||||
}
|
||||
#endif /* FUNCTION_DuckerCalcEnergy_func4 */
|
||||
}
|
||||
|
||||
{
|
||||
@ -1295,10 +1268,6 @@ static INT DuckerApply(DUCKER_INSTANCE *const self,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FUNCTION_DuckerApply_func1
|
||||
qs = DuckerApply_func1(qs, hybBands, qs_next, outputReal, outputImag,
|
||||
duckGain);
|
||||
#else
|
||||
/* general gain*output section */
|
||||
if (qs < hybBands) { /* true for about 39% */
|
||||
for (; qs < qs_next; qs++) { /* runs about 2 times */
|
||||
@ -1310,7 +1279,6 @@ static INT DuckerApply(DUCKER_INSTANCE *const self,
|
||||
outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} /* pb */
|
||||
|
||||
self->headroomSmoothDirRevNrg =
|
||||
|
@ -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
|
||||
@ -144,6 +144,7 @@ amm-info@iis.fraunhofer.de
|
||||
struct FDK_HYBRID_SETUP {
|
||||
UCHAR nrQmfBands; /*!< Number of QMF bands to be converted to hybrid. */
|
||||
UCHAR nHybBands[3]; /*!< Number of Hybrid bands generated by nrQmfBands. */
|
||||
UCHAR synHybScale[3]; /*!< Headroom needed in hybrid synthesis filterbank. */
|
||||
SCHAR kHybrid[3]; /*!< Filter configuration of each QMF band. */
|
||||
UCHAR protoLen; /*!< Prototype filter length. */
|
||||
UCHAR filterDelay; /*!< Delay caused by hybrid filter. */
|
||||
@ -156,12 +157,12 @@ static const INT ringbuffIdxTab[2 * 13] = {0, 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
9, 10, 11, 12, 0, 1, 2, 3, 4,
|
||||
5, 6, 7, 8, 9, 10, 11, 12};
|
||||
|
||||
static const FDK_HYBRID_SETUP setup_3_16 = {3, {8, 4, 4}, {8, 4, 4},
|
||||
13, (13 - 1) / 2, ringbuffIdxTab};
|
||||
static const FDK_HYBRID_SETUP setup_3_12 = {3, {8, 2, 2}, {8, 2, 2},
|
||||
13, (13 - 1) / 2, ringbuffIdxTab};
|
||||
static const FDK_HYBRID_SETUP setup_3_10 = {3, {6, 2, 2}, {-8, -2, 2},
|
||||
13, (13 - 1) / 2, ringbuffIdxTab};
|
||||
static const FDK_HYBRID_SETUP setup_3_16 = {
|
||||
3, {8, 4, 4}, {4, 3, 3}, {8, 4, 4}, 13, (13 - 1) / 2, ringbuffIdxTab};
|
||||
static const FDK_HYBRID_SETUP setup_3_12 = {
|
||||
3, {8, 2, 2}, {4, 2, 2}, {8, 2, 2}, 13, (13 - 1) / 2, ringbuffIdxTab};
|
||||
static const FDK_HYBRID_SETUP setup_3_10 = {
|
||||
3, {6, 2, 2}, {3, 2, 2}, {-8, -2, 2}, 13, (13 - 1) / 2, ringbuffIdxTab};
|
||||
|
||||
static const FIXP_HTP HybFilterCoef8[] = {
|
||||
HTCP(0x10000000, 0x00000000), HTCP(0x0df26407, 0xfa391882),
|
||||
@ -477,17 +478,18 @@ void FDKhybridSynthesisApply(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,
|
||||
*/
|
||||
for (k = 0; k < nrQmfBandsLF; k++) {
|
||||
const int nHybBands = hSynthesisHybFilter->pSetup->nHybBands[k];
|
||||
const int scale = hSynthesisHybFilter->pSetup->synHybScale[k];
|
||||
|
||||
FIXP_DBL accu1 = FL2FXCONST_DBL(0.f);
|
||||
FIXP_DBL accu2 = FL2FXCONST_DBL(0.f);
|
||||
|
||||
/* Perform hybrid filtering. */
|
||||
for (n = 0; n < nHybBands; n++) {
|
||||
accu1 += pHybridReal[hybOffset + n];
|
||||
accu2 += pHybridImag[hybOffset + n];
|
||||
accu1 += pHybridReal[hybOffset + n] >> scale;
|
||||
accu2 += pHybridImag[hybOffset + n] >> scale;
|
||||
}
|
||||
pQmfReal[k] = accu1;
|
||||
pQmfImag[k] = accu2;
|
||||
pQmfReal[k] = SATURATE_LEFT_SHIFT(accu1, scale, DFRACT_BITS);
|
||||
pQmfImag[k] = SATURATE_LEFT_SHIFT(accu2, scale, DFRACT_BITS);
|
||||
|
||||
hybOffset += nHybBands;
|
||||
}
|
||||
|
@ -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,34 +106,30 @@ amm-info@iis.fraunhofer.de
|
||||
#include "common_fix.h"
|
||||
|
||||
#define WORKBUFFER1_TAG 0
|
||||
#define WORKBUFFER2_TAG 1
|
||||
|
||||
#define WORKBUFFER3_TAG 4
|
||||
#define WORKBUFFER4_TAG 5
|
||||
#define WORKBUFFER5_TAG 6
|
||||
#define WORKBUFFER6_TAG 7
|
||||
#define WORKBUFFER7_TAG 8
|
||||
|
||||
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
||||
SECT_DATA_L1, WORKBUFFER1_TAG)
|
||||
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
||||
SECT_DATA_L2, WORKBUFFER2_TAG)
|
||||
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
||||
SECT_DATA_L2, WORKBUFFER3_TAG)
|
||||
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
||||
SECT_DATA_L2, WORKBUFFER4_TAG)
|
||||
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
||||
SECT_DATA_L2, WORKBUFFER5_TAG)
|
||||
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
||||
SECT_DATA_L2, WORKBUFFER6_TAG)
|
||||
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
||||
SECT_DATA_L2, WORKBUFFER7_TAG)
|
||||
|
||||
/*! Analysis states buffer. <br>
|
||||
Dimension: #((8) + (1)) */
|
||||
C_ALLOC_MEM2(AnaQmfStates, FIXP_QAS, 10 * QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS,
|
||||
C_AALLOC_MEM2(AnaQmfStates, FIXP_DBL, 10 * QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS,
|
||||
((8) + (1)))
|
||||
|
||||
/*! Synthesis states buffer. <br>
|
||||
Dimension: #((8) + (1)) */
|
||||
C_ALLOC_MEM2(SynQmfStates, FIXP_QSS, 9 * QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS,
|
||||
C_AALLOC_MEM2(SynQmfStates, FIXP_QSS, 9 * QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS,
|
||||
((8) + (1)))
|
||||
|
||||
/*! Pointer to real qmf data for each time slot. <br>
|
||||
@ -156,17 +152,16 @@ C_AALLOC_MEM2(QmfOverlapBuffer, FIXP_DBL,
|
||||
|
||||
/*! Analysis states buffer. <br>
|
||||
Dimension: #((8) + (1)) */
|
||||
C_ALLOC_MEM2(AnaQmfStates16, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_16,
|
||||
C_AALLOC_MEM2(AnaQmfStates16, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_16,
|
||||
((8) + (1)))
|
||||
/*! Analysis states buffer. <br>
|
||||
Dimension: #((8) + (1)) */
|
||||
C_AALLOC_MEM2(AnaQmfStates24, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24,
|
||||
((8) + (1)))
|
||||
|
||||
/*! Analysis states buffer. <br>
|
||||
Dimension: #((8) + (1)) */
|
||||
C_ALLOC_MEM2(AnaQmfStates24, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24,
|
||||
((8) + (1)))
|
||||
|
||||
/*! Analysis states buffer. <br>
|
||||
Dimension: #((8) + (1)) */
|
||||
C_ALLOC_MEM2(AnaQmfStates32, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32,
|
||||
C_AALLOC_MEM2(AnaQmfStates32, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32,
|
||||
((8) + (1)))
|
||||
|
||||
/*! Pointer to real qmf data for each time slot. <br>
|
||||
@ -642,10 +637,10 @@ void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
|
||||
|
||||
if (pQmfOutImag == NULL) {
|
||||
for (; b < fMin(lsb, stop_band); b++) {
|
||||
pQmfOutReal[b] = scaleValue(real[b], lb_sf);
|
||||
pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf);
|
||||
}
|
||||
for (; b < fMin(usb, stop_band); b++) {
|
||||
pQmfOutReal[b] = scaleValue(real[b], hb_sf);
|
||||
pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf);
|
||||
}
|
||||
for (; b < stop_band; b++) {
|
||||
pQmfOutReal[b] = (FIXP_DBL)0;
|
||||
@ -653,12 +648,12 @@ void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
|
||||
} else {
|
||||
FDK_ASSERT(imag != NULL);
|
||||
for (; b < fMin(lsb, stop_band); b++) {
|
||||
pQmfOutReal[b] = scaleValue(real[b], lb_sf);
|
||||
pQmfOutImag[b] = scaleValue(imag[b], lb_sf);
|
||||
pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf);
|
||||
pQmfOutImag[b] = scaleValueSaturate(imag[b], lb_sf);
|
||||
}
|
||||
for (; b < fMin(usb, stop_band); b++) {
|
||||
pQmfOutReal[b] = scaleValue(real[b], hb_sf);
|
||||
pQmfOutImag[b] = scaleValue(imag[b], hb_sf);
|
||||
pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf);
|
||||
pQmfOutImag[b] = scaleValueSaturate(imag[b], hb_sf);
|
||||
}
|
||||
for (; b < stop_band; b++) {
|
||||
pQmfOutReal[b] = (FIXP_DBL)0;
|
||||
@ -950,7 +945,7 @@ QMF_DOMAIN_ERROR FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd) {
|
||||
|
||||
if ((size > 4 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[4] == NULL)) {
|
||||
/* get work buffer of size QMF_WB_SECTION_SIZE */
|
||||
pWorkBuffer[4] = GetQmfWorkBufferCore5();
|
||||
pWorkBuffer[4] = GetQmfWorkBufferCore7();
|
||||
}
|
||||
|
||||
/* 8. distribute workbuffer over processing channels */
|
||||
@ -996,7 +991,7 @@ static void FDK_QmfDomain_FreeWorkBuffer(HANDLE_FDK_QMF_DOMAIN hqd) {
|
||||
if (pWorkBuffer[1]) FreeQmfWorkBufferCore1(&pWorkBuffer[1]);
|
||||
if (pWorkBuffer[2]) FreeQmfWorkBufferCore3(&pWorkBuffer[2]);
|
||||
if (pWorkBuffer[3]) FreeQmfWorkBufferCore4(&pWorkBuffer[3]);
|
||||
if (pWorkBuffer[4]) FreeQmfWorkBufferCore5(&pWorkBuffer[4]);
|
||||
if (pWorkBuffer[4]) FreeQmfWorkBufferCore7(&pWorkBuffer[4]);
|
||||
}
|
||||
|
||||
void FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -489,18 +489,18 @@ void dst_IV(FIXP_DBL *pDat, int L, int *pDat_e) {
|
||||
for (i = 0; i < M - 1; i += 2, pDat_0 += 2, pDat_1 -= 2) {
|
||||
FIXP_DBL accu1, accu2, accu3, accu4;
|
||||
|
||||
accu1 = pDat_1[1];
|
||||
accu2 = -pDat_0[0];
|
||||
accu3 = pDat_0[1];
|
||||
accu4 = -pDat_1[0];
|
||||
accu1 = pDat_1[1] >> 1;
|
||||
accu2 = -(pDat_0[0] >> 1);
|
||||
accu3 = pDat_0[1] >> 1;
|
||||
accu4 = -(pDat_1[0] >> 1);
|
||||
|
||||
cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
|
||||
cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
|
||||
|
||||
pDat_0[0] = accu2 >> 1;
|
||||
pDat_0[1] = accu1 >> 1;
|
||||
pDat_1[0] = accu4 >> 1;
|
||||
pDat_1[1] = -(accu3 >> 1);
|
||||
pDat_0[0] = accu2;
|
||||
pDat_0[1] = accu1;
|
||||
pDat_1[0] = accu4;
|
||||
pDat_1[1] = -accu3;
|
||||
}
|
||||
if (M & 1) {
|
||||
FIXP_DBL accu1, accu2;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -650,6 +650,12 @@ FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
|
||||
INT ans_lg2_e, baselg2_e;
|
||||
FIXP_DBL base_lg2, ans_lg2, result;
|
||||
|
||||
if (base_m <= (FIXP_DBL)0) {
|
||||
result = (FIXP_DBL)0;
|
||||
*result_e = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Calc log2 of base */
|
||||
base_lg2 = fLog2(base_m, base_e, &baselg2_e);
|
||||
|
||||
|
@ -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
|
||||
@ -569,7 +569,7 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum,
|
||||
*/
|
||||
for (i = 0; i < hMdct->prev_nr; i++) {
|
||||
FIXP_DBL x = -(*pOvl--);
|
||||
*pOut0 = IMDCT_SCALE_DBL(x + hMdct->pFacZir[i]);
|
||||
*pOut0 = fAddSaturate(x, IMDCT_SCALE_DBL(hMdct->pFacZir[i]));
|
||||
pOut0++;
|
||||
}
|
||||
hMdct->pFacZir = NULL;
|
||||
@ -678,7 +678,7 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum,
|
||||
FIXP_DBL *pOut = pOut0 - fl / 2;
|
||||
FDK_ASSERT(fl / 2 <= 128);
|
||||
for (i = 0; i < fl / 2; i++) {
|
||||
pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
|
||||
pOut[i] = fAddSaturate(pOut[i], IMDCT_SCALE_DBL(hMdct->pFacZir[i]));
|
||||
}
|
||||
hMdct->pFacZir = NULL;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -147,88 +147,6 @@ amm-info@iis.fraunhofer.de
|
||||
/* moved to qmf_pcm.h: -> qmfSynPrototypeFirSlot_NonSymmetric */
|
||||
/* moved to qmf_pcm.h: -> qmfSynthesisFilteringSlot */
|
||||
|
||||
#ifndef FUNCTION_qmfAnaPrototypeFirSlot
|
||||
/*!
|
||||
\brief Perform Analysis Prototype Filtering on a single slot of input data.
|
||||
*/
|
||||
static void qmfAnaPrototypeFirSlot(
|
||||
FIXP_DBL *analysisBuffer,
|
||||
INT no_channels, /*!< Number channels of analysis filter */
|
||||
const FIXP_PFT *p_filter, INT p_stride, /*!< Stride of analysis filter */
|
||||
FIXP_QAS *RESTRICT pFilterStates) {
|
||||
INT k;
|
||||
|
||||
FIXP_DBL accu;
|
||||
const FIXP_PFT *RESTRICT p_flt = p_filter;
|
||||
FIXP_DBL *RESTRICT pData_0 = analysisBuffer + 2 * no_channels - 1;
|
||||
FIXP_DBL *RESTRICT pData_1 = analysisBuffer;
|
||||
|
||||
FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates;
|
||||
FIXP_QAS *RESTRICT sta_1 =
|
||||
(FIXP_QAS *)pFilterStates + (2 * QMF_NO_POLY * no_channels) - 1;
|
||||
INT pfltStep = QMF_NO_POLY * (p_stride);
|
||||
INT staStep1 = no_channels << 1;
|
||||
INT staStep2 = (no_channels << 3) - 1; /* Rewind one less */
|
||||
|
||||
/* FIR filters 127..64 0..63 */
|
||||
for (k = 0; k < no_channels; k++) {
|
||||
accu = fMultDiv2(p_flt[0], *sta_1);
|
||||
sta_1 -= staStep1;
|
||||
accu += fMultDiv2(p_flt[1], *sta_1);
|
||||
sta_1 -= staStep1;
|
||||
accu += fMultDiv2(p_flt[2], *sta_1);
|
||||
sta_1 -= staStep1;
|
||||
accu += fMultDiv2(p_flt[3], *sta_1);
|
||||
sta_1 -= staStep1;
|
||||
accu += fMultDiv2(p_flt[4], *sta_1);
|
||||
*pData_1++ = (accu << 1);
|
||||
sta_1 += staStep2;
|
||||
|
||||
p_flt += pfltStep;
|
||||
accu = fMultDiv2(p_flt[0], *sta_0);
|
||||
sta_0 += staStep1;
|
||||
accu += fMultDiv2(p_flt[1], *sta_0);
|
||||
sta_0 += staStep1;
|
||||
accu += fMultDiv2(p_flt[2], *sta_0);
|
||||
sta_0 += staStep1;
|
||||
accu += fMultDiv2(p_flt[3], *sta_0);
|
||||
sta_0 += staStep1;
|
||||
accu += fMultDiv2(p_flt[4], *sta_0);
|
||||
*pData_0-- = (accu << 1);
|
||||
sta_0 -= staStep2;
|
||||
}
|
||||
}
|
||||
#endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */
|
||||
|
||||
#ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric
|
||||
/*!
|
||||
\brief Perform Analysis Prototype Filtering on a single slot of input data.
|
||||
*/
|
||||
static void qmfAnaPrototypeFirSlot_NonSymmetric(
|
||||
FIXP_DBL *analysisBuffer,
|
||||
int no_channels, /*!< Number channels of analysis filter */
|
||||
const FIXP_PFT *p_filter, int p_stride, /*!< Stride of analysis filter */
|
||||
FIXP_QAS *RESTRICT pFilterStates) {
|
||||
const FIXP_PFT *RESTRICT p_flt = p_filter;
|
||||
int p, k;
|
||||
|
||||
for (k = 0; k < 2 * no_channels; k++) {
|
||||
FIXP_DBL accu = (FIXP_DBL)0;
|
||||
|
||||
p_flt += QMF_NO_POLY * (p_stride - 1);
|
||||
|
||||
/*
|
||||
Perform FIR-Filter
|
||||
*/
|
||||
for (p = 0; p < QMF_NO_POLY; p++) {
|
||||
accu += fMultDiv2(*p_flt++, pFilterStates[2 * no_channels * p]);
|
||||
}
|
||||
analysisBuffer[2 * no_channels - 1 - k] = (accu << 1);
|
||||
pFilterStates++;
|
||||
}
|
||||
}
|
||||
#endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */
|
||||
|
||||
/*!
|
||||
*
|
||||
* \brief Perform real-valued forward modulation of the time domain
|
||||
@ -244,7 +162,7 @@ static void qmfForwardModulationLP_even(
|
||||
int i;
|
||||
int L = anaQmf->no_channels;
|
||||
int M = L >> 1;
|
||||
int scale;
|
||||
int scale = 0;
|
||||
FIXP_DBL accu;
|
||||
|
||||
const FIXP_DBL *timeInTmp1 = (FIXP_DBL *)&timeIn[3 * M];
|
||||
@ -381,211 +299,6 @@ static void qmfForwardModulationHQ(
|
||||
}
|
||||
#endif /* FUNCTION_qmfForwardModulationHQ */
|
||||
|
||||
/*
|
||||
* \brief Perform one QMF slot analysis of the time domain data of timeIn
|
||||
* with specified stride and stores the real part of the subband
|
||||
* samples in rSubband, and the imaginary part in iSubband
|
||||
*
|
||||
* Note: anaQmf->lsb can be greater than anaQmf->no_channels in case
|
||||
* of implicit resampling (USAC with reduced 3/4 core frame length).
|
||||
*/
|
||||
#if (SAMPLE_BITS != DFRACT_BITS) && (QAS_BITS == DFRACT_BITS)
|
||||
void qmfAnalysisFilteringSlot(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
|
||||
FIXP_DBL *qmfReal, /*!< Low and High band, real */
|
||||
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
|
||||
const LONG *RESTRICT timeIn, /*!< Pointer to input */
|
||||
const int stride, /*!< stride factor of input */
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
|
||||
) {
|
||||
int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1);
|
||||
/*
|
||||
Feed time signal into oldest anaQmf->no_channels states
|
||||
*/
|
||||
{
|
||||
FIXP_DBL *FilterStatesAnaTmp = ((FIXP_DBL *)anaQmf->FilterStates) + offset;
|
||||
|
||||
/* Feed and scale actual time in slot */
|
||||
for (int i = anaQmf->no_channels >> 1; i != 0; i--) {
|
||||
/* Place INT_PCM value left aligned in scaledTimeIn */
|
||||
|
||||
*FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
|
||||
timeIn += stride;
|
||||
*FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
|
||||
timeIn += stride;
|
||||
}
|
||||
}
|
||||
|
||||
if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
|
||||
qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels,
|
||||
anaQmf->p_filter, anaQmf->p_stride,
|
||||
(FIXP_QAS *)anaQmf->FilterStates);
|
||||
} else {
|
||||
qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter,
|
||||
anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates);
|
||||
}
|
||||
|
||||
if (anaQmf->flags & QMF_FLAG_LP) {
|
||||
if (anaQmf->flags & QMF_FLAG_CLDFB)
|
||||
qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal);
|
||||
else
|
||||
qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal);
|
||||
|
||||
} else {
|
||||
qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag);
|
||||
}
|
||||
/*
|
||||
Shift filter states
|
||||
|
||||
Should be realized with modulo adressing on a DSP instead of a true buffer
|
||||
shift
|
||||
*/
|
||||
FDKmemmove(anaQmf->FilterStates,
|
||||
(FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels,
|
||||
offset * sizeof(FIXP_QAS));
|
||||
}
|
||||
#endif
|
||||
|
||||
void qmfAnalysisFilteringSlot(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
|
||||
FIXP_DBL *qmfReal, /*!< Low and High band, real */
|
||||
FIXP_DBL *qmfImag, /*!< Low and High band, imag */
|
||||
const INT_PCM *RESTRICT timeIn, /*!< Pointer to input */
|
||||
const int stride, /*!< stride factor of input */
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
|
||||
) {
|
||||
int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1);
|
||||
/*
|
||||
Feed time signal into oldest anaQmf->no_channels states
|
||||
*/
|
||||
{
|
||||
FIXP_QAS *FilterStatesAnaTmp = ((FIXP_QAS *)anaQmf->FilterStates) + offset;
|
||||
|
||||
/* Feed and scale actual time in slot */
|
||||
for (int i = anaQmf->no_channels >> 1; i != 0; i--) {
|
||||
/* Place INT_PCM value left aligned in scaledTimeIn */
|
||||
#if (QAS_BITS == SAMPLE_BITS)
|
||||
*FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
|
||||
timeIn += stride;
|
||||
*FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
|
||||
timeIn += stride;
|
||||
#elif (QAS_BITS > SAMPLE_BITS)
|
||||
*FilterStatesAnaTmp++ = ((FIXP_QAS)*timeIn) << (QAS_BITS - SAMPLE_BITS);
|
||||
timeIn += stride;
|
||||
*FilterStatesAnaTmp++ = ((FIXP_QAS)*timeIn) << (QAS_BITS - SAMPLE_BITS);
|
||||
timeIn += stride;
|
||||
#else
|
||||
*FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn) >> (SAMPLE_BITS - QAS_BITS));
|
||||
timeIn += stride;
|
||||
*FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn) >> (SAMPLE_BITS - QAS_BITS));
|
||||
timeIn += stride;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
|
||||
qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels,
|
||||
anaQmf->p_filter, anaQmf->p_stride,
|
||||
(FIXP_QAS *)anaQmf->FilterStates);
|
||||
} else {
|
||||
qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter,
|
||||
anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates);
|
||||
}
|
||||
|
||||
if (anaQmf->flags & QMF_FLAG_LP) {
|
||||
if (anaQmf->flags & QMF_FLAG_CLDFB)
|
||||
qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal);
|
||||
else
|
||||
qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal);
|
||||
|
||||
} else {
|
||||
qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag);
|
||||
}
|
||||
/*
|
||||
Shift filter states
|
||||
|
||||
Should be realized with modulo adressing on a DSP instead of a true buffer
|
||||
shift
|
||||
*/
|
||||
FDKmemmove(anaQmf->FilterStates,
|
||||
(FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels,
|
||||
offset * sizeof(FIXP_QAS));
|
||||
}
|
||||
|
||||
/*!
|
||||
*
|
||||
* \brief Perform complex-valued subband filtering of the time domain
|
||||
* data of timeIn and stores the real part of the subband
|
||||
* samples in rAnalysis, and the imaginary part in iAnalysis
|
||||
* The qmf coefficient table is symmetric. The symmetry is expoited by
|
||||
* shrinking the coefficient table to half the size. The addressing mode
|
||||
* takes care of the symmetries.
|
||||
*
|
||||
*
|
||||
* \sa PolyphaseFiltering
|
||||
*/
|
||||
#if (SAMPLE_BITS != DFRACT_BITS) && (QAS_BITS == DFRACT_BITS)
|
||||
void qmfAnalysisFiltering(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
|
||||
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
|
||||
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
|
||||
QMF_SCALE_FACTOR *scaleFactor, const LONG *timeIn, /*!< Time signal */
|
||||
const int timeIn_e, const int stride,
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
|
||||
) {
|
||||
int i;
|
||||
int no_channels = anaQmf->no_channels;
|
||||
|
||||
scaleFactor->lb_scale =
|
||||
-ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e;
|
||||
scaleFactor->lb_scale -= anaQmf->filterScale;
|
||||
|
||||
for (i = 0; i < anaQmf->no_col; i++) {
|
||||
FIXP_DBL *qmfImagSlot = NULL;
|
||||
|
||||
if (!(anaQmf->flags & QMF_FLAG_LP)) {
|
||||
qmfImagSlot = qmfImag[i];
|
||||
}
|
||||
|
||||
qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride,
|
||||
pWorkBuffer);
|
||||
|
||||
timeIn += no_channels * stride;
|
||||
|
||||
} /* no_col loop i */
|
||||
}
|
||||
#endif
|
||||
|
||||
void qmfAnalysisFiltering(
|
||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
|
||||
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
|
||||
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
|
||||
QMF_SCALE_FACTOR *scaleFactor, const INT_PCM *timeIn, /*!< Time signal */
|
||||
const int timeIn_e, const int stride,
|
||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
|
||||
) {
|
||||
int i;
|
||||
int no_channels = anaQmf->no_channels;
|
||||
|
||||
scaleFactor->lb_scale =
|
||||
-ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e;
|
||||
scaleFactor->lb_scale -= anaQmf->filterScale;
|
||||
|
||||
for (i = 0; i < anaQmf->no_col; i++) {
|
||||
FIXP_DBL *qmfImagSlot = NULL;
|
||||
|
||||
if (!(anaQmf->flags & QMF_FLAG_LP)) {
|
||||
qmfImagSlot = qmfImag[i];
|
||||
}
|
||||
|
||||
qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride,
|
||||
pWorkBuffer);
|
||||
|
||||
timeIn += no_channels * stride;
|
||||
|
||||
} /* no_col loop i */
|
||||
}
|
||||
|
||||
/*!
|
||||
*
|
||||
* \brief Perform low power inverse modulation of the subband
|
||||
@ -603,15 +316,15 @@ inline static void qmfInverseModulationLP_even(
|
||||
int i;
|
||||
int L = synQmf->no_channels;
|
||||
int M = L >> 1;
|
||||
int scale;
|
||||
int scale = 0;
|
||||
FIXP_DBL tmp;
|
||||
FIXP_DBL *RESTRICT tReal = pTimeOut;
|
||||
FIXP_DBL *RESTRICT tImag = pTimeOut + L;
|
||||
|
||||
/* Move input to output vector with offset */
|
||||
scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand);
|
||||
scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
|
||||
synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
|
||||
scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb, scaleFactorLowBand);
|
||||
scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
|
||||
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||
FDKmemclear(&tReal[0 + synQmf->usb], (L - synQmf->usb) * sizeof(FIXP_DBL));
|
||||
|
||||
/* Dct type-2 transform */
|
||||
@ -662,8 +375,8 @@ inline static void qmfInverseModulationLP_odd(
|
||||
int shift = 0;
|
||||
|
||||
/* Move input to output vector with offset */
|
||||
scaleValues(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
|
||||
scaleValues(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
|
||||
scaleValuesSaturate(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
|
||||
scaleValuesSaturate(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
|
||||
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||
FDKmemclear(pTimeOut + M + synQmf->usb, (L - synQmf->usb) * sizeof(FIXP_DBL));
|
||||
|
||||
@ -698,26 +411,27 @@ inline static void qmfInverseModulationHQ(
|
||||
FIXP_DBL *RESTRICT tImag = pWorkBuffer + L;
|
||||
|
||||
if (synQmf->flags & QMF_FLAG_CLDFB) {
|
||||
for (i = 0; i < synQmf->lsb; i++) {
|
||||
cplxMult(&tImag[i], &tReal[i], scaleValue(qmfImag[i], scaleFactorLowBand),
|
||||
scaleValue(qmfReal[i], scaleFactorLowBand), synQmf->t_cos[i],
|
||||
synQmf->t_sin[i]);
|
||||
}
|
||||
for (; i < synQmf->usb; i++) {
|
||||
cplxMult(&tImag[i], &tReal[i],
|
||||
scaleValue(qmfImag[i], scaleFactorHighBand),
|
||||
scaleValue(qmfReal[i], scaleFactorHighBand), synQmf->t_cos[i],
|
||||
synQmf->t_sin[i]);
|
||||
for (i = 0; i < synQmf->usb; i++) {
|
||||
cplxMultDiv2(&tImag[i], &tReal[i], qmfImag[i], qmfReal[i],
|
||||
synQmf->t_cos[i], synQmf->t_sin[i]);
|
||||
}
|
||||
scaleValuesSaturate(&tReal[0], synQmf->lsb, scaleFactorLowBand + 1);
|
||||
scaleValuesSaturate(&tReal[0 + synQmf->lsb], synQmf->usb - synQmf->lsb,
|
||||
scaleFactorHighBand + 1);
|
||||
scaleValuesSaturate(&tImag[0], synQmf->lsb, scaleFactorLowBand + 1);
|
||||
scaleValuesSaturate(&tImag[0 + synQmf->lsb], synQmf->usb - synQmf->lsb,
|
||||
scaleFactorHighBand + 1);
|
||||
}
|
||||
|
||||
if ((synQmf->flags & QMF_FLAG_CLDFB) == 0) {
|
||||
scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand);
|
||||
scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
|
||||
synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
|
||||
scaleValues(&tImag[0], &qmfImag[0], synQmf->lsb, (int)scaleFactorLowBand);
|
||||
scaleValues(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
|
||||
synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
|
||||
scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb,
|
||||
scaleFactorLowBand);
|
||||
scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
|
||||
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||
scaleValuesSaturate(&tImag[0], &qmfImag[0], synQmf->lsb,
|
||||
scaleFactorLowBand);
|
||||
scaleValuesSaturate(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
|
||||
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||
}
|
||||
|
||||
FDKmemclear(&tReal[synQmf->usb],
|
||||
@ -996,35 +710,6 @@ static inline void qmfAdaptFilterStates(
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
*
|
||||
* \brief Create QMF filter bank instance
|
||||
*
|
||||
*
|
||||
* \return 0 if succesful
|
||||
*
|
||||
*/
|
||||
int qmfInitAnalysisFilterBank(
|
||||
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */
|
||||
FIXP_QAS *pFilterStates, /*!< Handle to filter states */
|
||||
int noCols, /*!< Number of timeslots per frame */
|
||||
int lsb, /*!< lower end of QMF */
|
||||
int usb, /*!< upper end of QMF */
|
||||
int no_channels, /*!< Number of channels (bands) */
|
||||
int flags) /*!< Low Power flag */
|
||||
{
|
||||
int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb,
|
||||
no_channels, flags, 0);
|
||||
if (!(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL)) {
|
||||
FDKmemclear(h_Qmf->FilterStates,
|
||||
(2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QAS));
|
||||
}
|
||||
|
||||
FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*!
|
||||
*
|
||||
* \brief Create QMF filter bank instance
|
||||
@ -1128,8 +813,21 @@ void qmfChangeOutGain(
|
||||
synQmf->outGain_e = outputGainScale;
|
||||
}
|
||||
|
||||
/* When QMF_16IN_32OUT is set, synthesis functions for 16 and 32 bit parallel
|
||||
* output is compiled */
|
||||
#define INT_PCM_QMFOUT INT_PCM
|
||||
#define SAMPLE_BITS_QMFOUT SAMPLE_BITS
|
||||
#include "qmf_pcm.h"
|
||||
#if SAMPLE_BITS == 16
|
||||
/* also create a 32 bit output version */
|
||||
#undef INT_PCM_QMFOUT
|
||||
#undef SAMPLE_BITS_QMFOUT
|
||||
#undef QMF_PCM_H
|
||||
#undef FIXP_QAS
|
||||
#undef QAS_BITS
|
||||
#undef INT_PCM_QMFIN
|
||||
#define INT_PCM_QMFOUT LONG
|
||||
#define SAMPLE_BITS_QMFOUT 32
|
||||
#define FIXP_QAS FIXP_DBL
|
||||
#define QAS_BITS 32
|
||||
#define INT_PCM_QMFIN LONG
|
||||
#include "qmf_pcm.h"
|
||||
#endif
|
||||
|
@ -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
|
||||
@ -251,7 +251,7 @@ void scaleValuesSaturate(FIXP_DBL *vector, /*!< Vector */
|
||||
#define FUNCTION_scaleValuesSaturate_DBL_DBL
|
||||
SCALE_INLINE
|
||||
void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
|
||||
FIXP_DBL *src, /*!< Input */
|
||||
const FIXP_DBL *src, /*!< Input */
|
||||
INT len, /*!< Length */
|
||||
INT scalefactor /*!< Scalefactor */
|
||||
) {
|
||||
@ -286,7 +286,7 @@ void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
|
||||
#define FUNCTION_scaleValuesSaturate_SGL_DBL
|
||||
SCALE_INLINE
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
|
||||
FIXP_DBL *src, /*!< Input */
|
||||
const FIXP_DBL *src, /*!< Input */
|
||||
INT len, /*!< Length */
|
||||
INT scalefactor) /*!< Scalefactor */
|
||||
{
|
||||
@ -346,7 +346,7 @@ void scaleValuesSaturate(FIXP_SGL *vector, /*!< Vector */
|
||||
#define FUNCTION_scaleValuesSaturate_SGL_SGL
|
||||
SCALE_INLINE
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
|
||||
FIXP_SGL *src, /*!< Input */
|
||||
const FIXP_SGL *src, /*!< Input */
|
||||
INT len, /*!< Length */
|
||||
INT scalefactor /*!< Scalefactor */
|
||||
) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -213,8 +213,8 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts,
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (!bs.protection_absent) {
|
||||
FDKcrcReset(&pAdts->crcInfo);
|
||||
if (!bs.protection_absent) {
|
||||
FDKpushBack(hBs, 56); /* complete fixed and variable header! */
|
||||
crcReg = FDKcrcStartReg(&pAdts->crcInfo, hBs, 0);
|
||||
FDKpushFor(hBs, 56);
|
||||
@ -314,15 +314,55 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts,
|
||||
if (bs.channel_config == 0) {
|
||||
int pceBits = 0;
|
||||
UINT alignAnchor = FDKgetValidBits(hBs);
|
||||
CProgramConfig tmpPce;
|
||||
|
||||
if (FDKreadBits(hBs, 3) == ID_PCE) {
|
||||
/* Got luck! Parse the PCE */
|
||||
crcReg = adtsRead_CrcStartReg(pAdts, hBs, 0);
|
||||
|
||||
CProgramConfig_Read(&pAsc->m_progrConfigElement, hBs, alignAnchor);
|
||||
CProgramConfig_Init(&tmpPce);
|
||||
CProgramConfig_Read(&tmpPce, hBs, alignAnchor);
|
||||
|
||||
if (CProgramConfig_IsValid(&tmpPce)) {
|
||||
if (CProgramConfig_IsValid(&oldPce)) {
|
||||
/* Compare the new and the old PCE (tags ignored) */
|
||||
switch (CProgramConfig_Compare(&tmpPce, &oldPce)) {
|
||||
case 0: /* Nothing to do because PCE matches the old one exactly. */
|
||||
case 1: /* Channel configuration not changed. Just new metadata. */
|
||||
FDKmemcpy(&pAsc->m_progrConfigElement, &tmpPce,
|
||||
sizeof(CProgramConfig));
|
||||
break;
|
||||
case 2: /* The number of channels are identical but not the config
|
||||
*/
|
||||
case -1: /* The channel configuration is completely different */
|
||||
default:
|
||||
FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce,
|
||||
sizeof(CProgramConfig));
|
||||
FDKpushBack(hBs, adtsHeaderLength);
|
||||
return TRANSPORTDEC_PARSE_ERROR;
|
||||
}
|
||||
} else {
|
||||
FDKmemcpy(&pAsc->m_progrConfigElement, &tmpPce,
|
||||
sizeof(CProgramConfig));
|
||||
}
|
||||
} else {
|
||||
if (CProgramConfig_IsValid(&oldPce)) {
|
||||
FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce,
|
||||
sizeof(CProgramConfig));
|
||||
} else {
|
||||
FDKpushBack(hBs, adtsHeaderLength);
|
||||
return TRANSPORTDEC_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
adtsRead_CrcEndReg(pAdts, hBs, crcReg);
|
||||
pceBits = alignAnchor - FDKgetValidBits(hBs);
|
||||
pceBits = (INT)alignAnchor - (INT)FDKgetValidBits(hBs);
|
||||
adtsHeaderLength += pceBits;
|
||||
|
||||
if (pceBits > (INT)alignAnchor) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* store the number of PCE bits */
|
||||
bs.num_pce_bits = pceBits;
|
||||
} else {
|
||||
|
@ -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
|
||||
@ -1325,9 +1325,9 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
|
||||
CSTpCallBacks *cb) {
|
||||
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
|
||||
CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig;
|
||||
ASC_ELD_EXT_TYPE eldExtType;
|
||||
UINT eldExtType;
|
||||
int eldExtLen, len, cnt, ldSbrLen = 0, eldExtLenSum, numSbrHeader = 0,
|
||||
sbrIndex;
|
||||
sbrIndex, eldExtCnt = 0;
|
||||
|
||||
unsigned char downscale_fill_nibble;
|
||||
|
||||
@ -1394,9 +1394,8 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
|
||||
eldExtLenSum = FDKgetValidBits(hBs);
|
||||
esc->m_downscaledSamplingFrequency = asc->m_samplingFrequency;
|
||||
/* parse ExtTypeConfigData */
|
||||
while (
|
||||
((eldExtType = (ASC_ELD_EXT_TYPE)FDKreadBits(hBs, 4)) != ELDEXT_TERM) &&
|
||||
((INT)FDKgetValidBits(hBs) >= 0)) {
|
||||
while (((eldExtType = FDKreadBits(hBs, 4)) != ELDEXT_TERM) &&
|
||||
((INT)FDKgetValidBits(hBs) >= 0) && (eldExtCnt++ < 15)) {
|
||||
eldExtLen = len = FDKreadBits(hBs, 4);
|
||||
if (len == 0xf) {
|
||||
len = FDKreadBits(hBs, 8);
|
||||
@ -1440,7 +1439,8 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
|
||||
UCHAR tmpDownscaleFreqIdx;
|
||||
esc->m_downscaledSamplingFrequency =
|
||||
getSampleRate(hBs, &tmpDownscaleFreqIdx, 4);
|
||||
if (esc->m_downscaledSamplingFrequency == 0) {
|
||||
if (esc->m_downscaledSamplingFrequency == 0 ||
|
||||
esc->m_downscaledSamplingFrequency > 96000) {
|
||||
return TRANSPORTDEC_PARSE_ERROR;
|
||||
}
|
||||
downscale_fill_nibble = FDKreadBits(hBs, 4);
|
||||
@ -1454,6 +1454,9 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (eldExtType != ELDEXT_TERM) {
|
||||
return TRANSPORTDEC_PARSE_ERROR;
|
||||
}
|
||||
|
||||
if ((INT)FDKgetValidBits(hBs) < 0) {
|
||||
return TRANSPORTDEC_PARSE_ERROR;
|
||||
@ -1948,6 +1951,9 @@ static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc,
|
||||
INT nbits = (INT)FDKgetValidBits(hBs);
|
||||
|
||||
usacSamplingFrequency = getSampleRate(hBs, &asc->m_samplingFrequencyIndex, 5);
|
||||
if (usacSamplingFrequency == 0 || usacSamplingFrequency > 96000) {
|
||||
return TRANSPORTDEC_PARSE_ERROR;
|
||||
}
|
||||
asc->m_samplingFrequency = (UINT)usacSamplingFrequency;
|
||||
|
||||
coreSbrFrameLengthIndex = FDKreadBits(hBs, 3);
|
||||
@ -2027,7 +2033,8 @@ static TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(
|
||||
self->m_extensionSamplingFrequency = getSampleRate(
|
||||
bs, &self->m_extensionSamplingFrequencyIndex, 4);
|
||||
|
||||
if ((INT)self->m_extensionSamplingFrequency <= 0) {
|
||||
if (self->m_extensionSamplingFrequency == 0 ||
|
||||
self->m_extensionSamplingFrequency > 96000) {
|
||||
return TRANSPORTDEC_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
@ -2139,6 +2146,24 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
|
||||
|
||||
self->m_channelConfiguration = FDKreadBits(bs, 4);
|
||||
|
||||
/* MPEG-04 standard ISO/IEC 14496-3: channelConfiguration == 0 is reserved
|
||||
in er_raw_data_block (table 4.19) and er_raw_data_block_eld (table 4.75)
|
||||
MPEG-04 conformance ISO/IEC 14496-4: channelConfiguration == 0 is not
|
||||
permitted for AOT_ER_AAC_LC, AOT_ER_AAC_LTP, AOT_ER_AAC_LD,
|
||||
AOT_ER_AAC_SCAL (chapter 6.6.4.1.2.1.1) */
|
||||
if ((self->m_channelConfiguration == 0) &&
|
||||
((self->m_aot == AOT_ER_AAC_LC) || (self->m_aot == AOT_ER_AAC_LTP) ||
|
||||
(self->m_aot == AOT_ER_AAC_LD) || (self->m_aot == AOT_ER_AAC_SCAL) ||
|
||||
(self->m_aot == AOT_ER_AAC_ELD))) {
|
||||
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
|
||||
}
|
||||
/* MPEG-04 conformance ISO/IEC 14496-4: channelConfiguration > 2 is not
|
||||
* permitted for AOT_AAC_SCAL and AOT_ER_AAC_SCAL (chapter 6.6.4.1.2.1.1) */
|
||||
if ((self->m_channelConfiguration > 2) &&
|
||||
((self->m_aot == AOT_AAC_SCAL) || (self->m_aot == AOT_ER_AAC_SCAL))) {
|
||||
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
|
||||
}
|
||||
|
||||
/* SBR extension ( explicit non-backwards compatible mode ) */
|
||||
self->m_sbrPresentFlag = 0;
|
||||
self->m_psPresentFlag = 0;
|
||||
@ -2153,6 +2178,10 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
|
||||
|
||||
self->m_extensionSamplingFrequency =
|
||||
getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
|
||||
if (self->m_extensionSamplingFrequency == 0 ||
|
||||
self->m_extensionSamplingFrequency > 96000) {
|
||||
return TRANSPORTDEC_PARSE_ERROR;
|
||||
}
|
||||
self->m_aot = getAOT(bs);
|
||||
|
||||
switch (self->m_aot) {
|
||||
|
@ -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
|
||||
@ -367,10 +367,10 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig(
|
||||
}
|
||||
if (pLatmDemux->m_AudioMuxVersion == 1) {
|
||||
FDK_BITSTREAM tmpBs;
|
||||
UINT ascLen = 0;
|
||||
INT ascLen = 0;
|
||||
ascLen = CLatmDemux_GetValue(bs);
|
||||
/* The ascLen could be wrong, so check if validBits<=bufBits*/
|
||||
if (ascLen > FDKgetValidBits(bs)) {
|
||||
if (ascLen < 0 || ascLen > (INT)FDKgetValidBits(bs)) {
|
||||
ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
|
||||
goto bail;
|
||||
}
|
||||
|
@ -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
|
||||
@ -482,7 +482,8 @@ TRANSPORTDEC_ERROR transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (i > 0) {
|
||||
FDKpushBack(hBs, newConfigLength * 8 - FDKgetValidBits(hBs));
|
||||
FDKpushBack(hBs,
|
||||
(INT)newConfigLength * 8 - (INT)FDKgetValidBits(hBs));
|
||||
configMode = AC_CM_ALLOC_MEM;
|
||||
}
|
||||
/* config transport decoder */
|
||||
@ -663,10 +664,14 @@ TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
|
||||
if (*pBytesValid == 0) {
|
||||
/* nothing to do */
|
||||
return TRANSPORTDEC_OK;
|
||||
}
|
||||
|
||||
if (hTp->numberOfRawDataBlocks <= 0) {
|
||||
} else {
|
||||
const int bytesValid = *pBytesValid;
|
||||
FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
|
||||
|
||||
if (hTp->numberOfRawDataBlocks > 0) {
|
||||
hTp->globalFramePos += (bytesValid - *pBytesValid) * 8;
|
||||
hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -924,6 +929,11 @@ static TRANSPORTDEC_ERROR transportDec_readHeader(
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if an error is detected terminate config parsing to avoid that an
|
||||
* invalid config is accepted in the second pass */
|
||||
if (err != TRANSPORTDEC_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Reset CRC because the next bits are the beginning of a
|
||||
@ -976,6 +986,9 @@ static TRANSPORTDEC_ERROR transportDec_readHeader(
|
||||
CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
|
||||
if (hTp->transportFmt == TT_MP4_LOAS) {
|
||||
syncLayerFrameBits -= startPos - (INT)FDKgetValidBits(hBs) - (13);
|
||||
if (syncLayerFrameBits <= 0) {
|
||||
err = TRANSPORTDEC_SYNC_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1151,6 +1164,11 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
|
||||
&rawDataBlockLength, &fTraverseMoreFrames,
|
||||
&syncLayerFrameBits, &fConfigFound,
|
||||
&headerBits);
|
||||
if (headerBits > bitsAvail) {
|
||||
err = (headerBits < (INT)hBs->hBitBuf.bufBits)
|
||||
? TRANSPORTDEC_NOT_ENOUGH_BITS
|
||||
: TRANSPORTDEC_SYNC_ERROR;
|
||||
}
|
||||
if (TPDEC_IS_FATAL_ERROR(err)) {
|
||||
/* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
|
||||
* next time. Ensure that the bit amount lands at a multiple of
|
||||
@ -1181,8 +1199,6 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
|
||||
}
|
||||
|
||||
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
|
||||
/* Enforce reading of new data */
|
||||
hTp->numberOfRawDataBlocks = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1263,8 +1279,9 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
|
||||
if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS |
|
||||
TPDEC_SYNCOK)) &&
|
||||
err == TRANSPORTDEC_OK) {
|
||||
err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
|
||||
FDKgetValidBits(hBs) - syncLayerFrameBits);
|
||||
err =
|
||||
additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
|
||||
(INT)FDKgetValidBits(hBs) - syncLayerFrameBits);
|
||||
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
|
||||
hTp->holdOffFrames++;
|
||||
}
|
||||
@ -1273,7 +1290,9 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
|
||||
/* Rewind for retry because of not enough bits */
|
||||
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
|
||||
FDKpushBack(hBs, headerBits);
|
||||
hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
|
||||
headerBits = 0;
|
||||
rawDataBlockLength = rawDataBlockLengthPrevious;
|
||||
} else {
|
||||
/* reset hold off frame counter */
|
||||
hTp->holdOffFrames = 0;
|
||||
@ -1460,7 +1479,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (i > 0) {
|
||||
FDKpushBack(hBs, bsStart - FDKgetValidBits(hBs));
|
||||
FDKpushBack(hBs, bsStart - (INT)FDKgetValidBits(hBs));
|
||||
configMode = AC_CM_ALLOC_MEM;
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
@ -256,26 +251,15 @@ 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 *
|
||||
* 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 */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -152,7 +152,7 @@ TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs,
|
||||
limiter->attack = attack;
|
||||
limiter->attackConst = attackConst;
|
||||
limiter->releaseConst = releaseConst;
|
||||
limiter->threshold = threshold >> TDL_GAIN_SCALING;
|
||||
limiter->threshold = threshold;
|
||||
limiter->channels = maxChannels;
|
||||
limiter->maxChannels = maxChannels;
|
||||
limiter->sampleRate = maxSampleRate;
|
||||
@ -165,18 +165,13 @@ TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs,
|
||||
|
||||
/* apply limiter */
|
||||
TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
|
||||
INT_PCM* samplesOut, FIXP_DBL* RESTRICT pGain,
|
||||
const INT* RESTRICT gain_scale,
|
||||
const UINT gain_size, const UINT gain_delay,
|
||||
const UINT nSamples) {
|
||||
INT_PCM* samplesOut, FIXP_DBL* pGainPerSample,
|
||||
const INT scaling, const UINT nSamples) {
|
||||
unsigned int i, j;
|
||||
FIXP_DBL tmp1;
|
||||
FIXP_DBL tmp2;
|
||||
FIXP_DBL tmp, old, gain, additionalGain = 0, additionalGainUnfiltered;
|
||||
FIXP_DBL tmp, old, gain, additionalGain = 0;
|
||||
FIXP_DBL minGain = FL2FXCONST_DBL(1.0f / (1 << 1));
|
||||
|
||||
FDK_ASSERT(gain_size == 1);
|
||||
FDK_ASSERT(gain_delay <= nSamples);
|
||||
UINT additionalGainAvailable = 1;
|
||||
|
||||
if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
|
||||
|
||||
@ -185,7 +180,7 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
|
||||
unsigned int attack = limiter->attack;
|
||||
FIXP_DBL attackConst = limiter->attackConst;
|
||||
FIXP_DBL releaseConst = limiter->releaseConst;
|
||||
FIXP_DBL threshold = limiter->threshold;
|
||||
FIXP_DBL threshold = limiter->threshold >> scaling;
|
||||
|
||||
FIXP_DBL max = limiter->max;
|
||||
FIXP_DBL* maxBuf = limiter->maxBuf;
|
||||
@ -195,55 +190,34 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
|
||||
unsigned int delayBufIdx = limiter->delayBufIdx;
|
||||
|
||||
FIXP_DBL smoothState0 = limiter->smoothState0;
|
||||
FIXP_DBL additionalGainSmoothState = limiter->additionalGainFilterState;
|
||||
FIXP_DBL additionalGainSmoothState1 = limiter->additionalGainFilterState1;
|
||||
|
||||
if (!gain_delay) {
|
||||
additionalGain = pGain[0];
|
||||
if (gain_scale[0] > 0) {
|
||||
additionalGain <<= gain_scale[0];
|
||||
} else {
|
||||
additionalGain >>= -gain_scale[0];
|
||||
if (limiter->scaling != scaling) {
|
||||
scaleValuesSaturate(delayBuf, attack * channels,
|
||||
limiter->scaling - scaling);
|
||||
scaleValuesSaturate(maxBuf, attack + 1, limiter->scaling - scaling);
|
||||
max = scaleValueSaturate(max, limiter->scaling - scaling);
|
||||
limiter->scaling = scaling;
|
||||
}
|
||||
|
||||
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 = fAbs(tmp2);
|
||||
tmp2 = FIXP_DBL(INT(tmp2) ^ INT((tmp2 >> (SAMPLE_BITS_LIM - 1))));
|
||||
tmp1 = fMax(tmp1, tmp2);
|
||||
tmp2 =
|
||||
(tmp2 == (FIXP_DBL)MINVAL_DBL) ? (FIXP_DBL)MAXVAL_DBL : fAbs(tmp2);
|
||||
tmp = fMax(tmp, tmp2);
|
||||
}
|
||||
|
||||
if (additionalGainAvailable) {
|
||||
additionalGain = pGainPerSample[i];
|
||||
tmp = fMult(tmp, additionalGain);
|
||||
}
|
||||
tmp = fMult(tmp1, additionalGain);
|
||||
|
||||
/* set threshold as lower border to save calculations in running maximum
|
||||
* algorithm */
|
||||
@ -314,22 +288,42 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
|
||||
/* lookahead delay, apply gain */
|
||||
for (j = 0; j < channels; j++) {
|
||||
tmp = p_delayBuf[j];
|
||||
|
||||
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];
|
||||
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 SUPPRESS_BUILD_DATE_INFO
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
@ -1554,22 +1554,20 @@ static SACDEC_ERROR mapIndexData(
|
||||
/* Interpolate */
|
||||
i1 = 0;
|
||||
for (i = 0; i < numParameterSets; i++) {
|
||||
int xi, i2, x1, x2;
|
||||
|
||||
if (aInterpolate[i] != 1) {
|
||||
i1 = i;
|
||||
} else {
|
||||
int xi, i2, x1, x2;
|
||||
|
||||
for (i2 = i; i2 < numParameterSets; i2++) {
|
||||
if (aInterpolate[i2] != 1) break;
|
||||
}
|
||||
i2 = i;
|
||||
while (aInterpolate[i2] == 1) {
|
||||
i2++;
|
||||
if (i2 >= MAX_PARAMETER_SETS) return MPS_WRONG_PARAMETERSETS;
|
||||
}
|
||||
if (i2 >= numParameterSets) return MPS_WRONG_PARAMETERSETS;
|
||||
|
||||
x1 = paramSlot[i1];
|
||||
xi = paramSlot[i];
|
||||
x2 = paramSlot[i2];
|
||||
|
||||
if (aInterpolate[i] == 1) {
|
||||
if (i2 >= numParameterSets) return MPS_WRONG_PARAMETERSETS;
|
||||
for (band = startBand; band < stopBand; band++) {
|
||||
int yi, y1, y2;
|
||||
y1 = outputIdxData[xttIdx][i1][band];
|
||||
@ -1588,9 +1586,9 @@ static SACDEC_ERROR mapIndexData(
|
||||
for (ps = 0; ps < numParameterSets; ps++) {
|
||||
if (quantMode && (paramType == t_CLD)) {
|
||||
if (pOttVsTotDbIn == 0) return MPS_WRONG_OTT;
|
||||
if ((pOttVsTotDb1 == 0) && (ottVsTotDbMode == ottVsTotDb1Activ))
|
||||
if ((pOttVsTotDb1 == 0) && (ottVsTotDbMode & ottVsTotDb1Activ))
|
||||
return MPS_WRONG_OTT;
|
||||
if ((pOttVsTotDb2 == 0) && (ottVsTotDbMode == ottVsTotDb2Activ))
|
||||
if ((pOttVsTotDb2 == 0) && (ottVsTotDbMode & ottVsTotDb2Activ))
|
||||
return MPS_WRONG_OTT;
|
||||
|
||||
for (pb = startBand; pb < stopBand; pb++) {
|
||||
@ -1612,6 +1610,10 @@ static SACDEC_ERROR mapIndexData(
|
||||
} /* for( i = 0 ; i < numParameterSets; i++ ) */
|
||||
|
||||
if (extendFrame) {
|
||||
if (paramType == t_IPD) {
|
||||
llData->bsQuantCoarseXXX[numParameterSets] =
|
||||
llData->bsQuantCoarseXXX[numParameterSets - 1];
|
||||
}
|
||||
for (band = startBand; band < stopBand; band++) {
|
||||
outputDataIdx[xttIdx][numParameterSets][band] =
|
||||
outputDataIdx[xttIdx][numParameterSets - 1][band];
|
||||
|
@ -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
|
||||
@ -117,6 +117,9 @@ amm-info@iis.fraunhofer.de
|
||||
/* Scaling of spectral data after applying M2 matrix, but only for binaural
|
||||
upmix type Scaling is compensated later in synthesis qmf filterbank */
|
||||
#define SCALE_DATA_APPLY_M2 (1)
|
||||
/* Applying M2 parameter in combination with phase coding needs 2 bits headroom
|
||||
* because up to a maximum of 4 spectral values can be added for USAC */
|
||||
#define SCALE_DATA_APPLY_M2_PC (2)
|
||||
|
||||
SACDEC_ERROR initM1andM2(spatialDec* self, int initStatesFlag,
|
||||
int configChanged);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1317,10 +1323,12 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
|
||||
if ((self->tempShapeConfig == 1) && (!isTwoChMode(self->upmixType))) {
|
||||
for (ch = 0; ch < self->numOutputChannels; ch++) {
|
||||
for (hyb = 0; hyb < self->tp_hybBandBorder; hyb++) {
|
||||
self->hybOutputRealDry__FDK[ch][hyb] +=
|
||||
self->hybOutputRealWet__FDK[ch][hyb];
|
||||
self->hybOutputImagDry__FDK[ch][hyb] +=
|
||||
self->hybOutputImagWet__FDK[ch][hyb];
|
||||
self->hybOutputRealDry__FDK[ch][hyb] =
|
||||
fAddSaturate(self->hybOutputRealDry__FDK[ch][hyb],
|
||||
self->hybOutputRealWet__FDK[ch][hyb]);
|
||||
self->hybOutputImagDry__FDK[ch][hyb] =
|
||||
fAddSaturate(self->hybOutputImagDry__FDK[ch][hyb],
|
||||
self->hybOutputImagWet__FDK[ch][hyb]);
|
||||
} /* loop hyb */
|
||||
} /* loop ch */
|
||||
err = subbandTPApply(
|
||||
@ -1341,11 +1349,11 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
|
||||
FIXP_DBL *RESTRICT pRealWet = self->hybOutputRealWet__FDK[ch];
|
||||
FIXP_DBL *RESTRICT pImagWet = self->hybOutputImagWet__FDK[ch];
|
||||
for (hyb = 0; hyb < nHybBands; hyb++) {
|
||||
pRealDry[hyb] += pRealWet[hyb];
|
||||
pImagDry[hyb] += pImagWet[hyb];
|
||||
pRealDry[hyb] = fAddSaturate(pRealDry[hyb], pRealWet[hyb]);
|
||||
pImagDry[hyb] = fAddSaturate(pImagDry[hyb], pImagWet[hyb]);
|
||||
} /* loop hyb */
|
||||
for (; hyb < self->hybridBands; hyb++) {
|
||||
pRealDry[hyb] += pRealWet[hyb];
|
||||
pRealDry[hyb] = fAddSaturate(pRealDry[hyb], pRealWet[hyb]);
|
||||
} /* loop hyb */
|
||||
} /* loop ch */
|
||||
} /* ( self->tempShapeConfig == 1 ) || ( self->tempShapeConfig == 2 ) */
|
||||
@ -1414,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) {
|
||||
|
@ -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,6 +113,8 @@ amm-info@iis.fraunhofer.de
|
||||
#include "FDK_trigFcts.h"
|
||||
#include "FDK_decorrelate.h"
|
||||
|
||||
#define SAC_DEC_APPLY_M2_SCALE(spec, s) ((spec) >> (-(s)))
|
||||
|
||||
/**
|
||||
* \brief Linear interpolation between two parameter values.
|
||||
* a*alpha + b*(1-alpha)
|
||||
@ -185,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -214,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
|
||||
@ -499,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]);
|
||||
@ -513,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;
|
||||
|
||||
@ -634,8 +641,7 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
|
||||
}
|
||||
|
||||
if (self->phaseCoding == 3) {
|
||||
/* + SCALE_DATA_APPLY_M2 to compensate for Div2 below ?! */
|
||||
scale_param_m2 = SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2;
|
||||
scale_param_m2 = -(SCALE_DATA_APPLY_M2_PC - 1);
|
||||
}
|
||||
|
||||
for (row = 0; row < self->numM2rows; row++) {
|
||||
@ -686,10 +692,10 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
|
||||
} else { /* isBinauralMode(self->upmixType) */
|
||||
|
||||
for (qs = 0; qs < complexHybBands; qs++) {
|
||||
pHybOutRealDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImagDry[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
|
||||
<< (scale_param_m2);
|
||||
pHybOutRealDry[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
|
||||
pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
|
||||
}
|
||||
|
||||
M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col],
|
||||
@ -697,27 +703,27 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
|
||||
self->kernels_width, alpha, complexParBands);
|
||||
|
||||
/* direct signals sign is -1 for qs = 0,2 */
|
||||
pHybOutRealDry[0] += fMultDiv2(pWImag[0], pKernel[0])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImagDry[0] -= fMultDiv2(pWReal[0], pKernel[0])
|
||||
<< (scale_param_m2);
|
||||
pHybOutRealDry[0] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
|
||||
pHybOutImagDry[0] -= SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
|
||||
|
||||
pHybOutRealDry[2] += fMultDiv2(pWImag[2], pKernel[2])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImagDry[2] -= fMultDiv2(pWReal[2], pKernel[2])
|
||||
<< (scale_param_m2);
|
||||
pHybOutRealDry[2] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
|
||||
pHybOutImagDry[2] -= SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
|
||||
|
||||
/* direct signals sign is +1 for qs = 1,3,4,5,...,complexHybBands */
|
||||
pHybOutRealDry[1] -= fMultDiv2(pWImag[1], pKernel[1])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImagDry[1] += fMultDiv2(pWReal[1], pKernel[1])
|
||||
<< (scale_param_m2);
|
||||
pHybOutRealDry[1] -= SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
|
||||
pHybOutImagDry[1] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
|
||||
|
||||
for (qs = 3; qs < complexHybBands; qs++) {
|
||||
pHybOutRealDry[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImagDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
|
||||
<< (scale_param_m2);
|
||||
pHybOutRealDry[qs] -= SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
|
||||
pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
|
||||
}
|
||||
} /* self->upmixType */
|
||||
} /* if (activParamBands) */
|
||||
@ -770,17 +776,17 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
|
||||
FIXP_DBL *RESTRICT pHybOutImag;
|
||||
|
||||
for (qs = 0; qs < resHybIndex; qs++) {
|
||||
pHybOutRealDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImagDry[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
|
||||
<< (scale_param_m2);
|
||||
pHybOutRealDry[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
|
||||
pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
|
||||
}
|
||||
/* decor signals */
|
||||
for (; qs < complexHybBands; qs++) {
|
||||
pHybOutRealWet[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImagWet[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
|
||||
<< (scale_param_m2);
|
||||
pHybOutRealWet[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
|
||||
pHybOutImagWet[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
|
||||
}
|
||||
|
||||
M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col],
|
||||
@ -790,20 +796,20 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
|
||||
/* direct signals sign is -1 for qs = 0,2 */
|
||||
/* direct signals sign is +1 for qs = 1,3.. */
|
||||
if (toolsDisabled) {
|
||||
pHybOutRealDry[0] += fMultDiv2(pWImag[0], pKernel[0])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImagDry[0] -= fMultDiv2(pWReal[0], pKernel[0])
|
||||
<< (scale_param_m2);
|
||||
pHybOutRealDry[0] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
|
||||
pHybOutImagDry[0] -= SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
|
||||
|
||||
pHybOutRealDry[1] -= fMultDiv2(pWImag[1], pKernel[1])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImagDry[1] += fMultDiv2(pWReal[1], pKernel[1])
|
||||
<< (scale_param_m2);
|
||||
pHybOutRealDry[1] -= SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
|
||||
pHybOutImagDry[1] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
|
||||
|
||||
pHybOutRealDry[2] += fMultDiv2(pWImag[2], pKernel[2])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImagDry[2] -= fMultDiv2(pWReal[2], pKernel[2])
|
||||
<< (scale_param_m2);
|
||||
pHybOutRealDry[2] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
|
||||
pHybOutImagDry[2] -= SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
|
||||
} else {
|
||||
pHybOutReal = &pHybOutRealDry[0];
|
||||
pHybOutImag = &pHybOutImagDry[0];
|
||||
@ -811,46 +817,60 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
|
||||
pHybOutReal = &pHybOutRealWet[0];
|
||||
pHybOutImag = &pHybOutImagWet[0];
|
||||
}
|
||||
pHybOutReal[0] += fMultDiv2(pWImag[0], pKernel[0])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImag[0] -= fMultDiv2(pWReal[0], pKernel[0])
|
||||
<< (scale_param_m2);
|
||||
pHybOutReal[0] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
|
||||
pHybOutImag[0] -= SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
|
||||
|
||||
if (1 == resHybIndex) {
|
||||
pHybOutReal = &pHybOutRealWet[0];
|
||||
pHybOutImag = &pHybOutImagWet[0];
|
||||
}
|
||||
pHybOutReal[1] -= fMultDiv2(pWImag[1], pKernel[1])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImag[1] += fMultDiv2(pWReal[1], pKernel[1])
|
||||
<< (scale_param_m2);
|
||||
pHybOutReal[1] -= SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
|
||||
pHybOutImag[1] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
|
||||
|
||||
if (2 == resHybIndex) {
|
||||
pHybOutReal = &pHybOutRealWet[0];
|
||||
pHybOutImag = &pHybOutImagWet[0];
|
||||
}
|
||||
pHybOutReal[2] += fMultDiv2(pWImag[2], pKernel[2])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImag[2] -= fMultDiv2(pWReal[2], pKernel[2])
|
||||
<< (scale_param_m2);
|
||||
pHybOutReal[2] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
|
||||
pHybOutImag[2] -= SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
|
||||
}
|
||||
|
||||
for (qs = 3; qs < resHybIndex; qs++) {
|
||||
pHybOutRealDry[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImagDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
|
||||
<< (scale_param_m2);
|
||||
pHybOutRealDry[qs] -= SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
|
||||
pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
|
||||
}
|
||||
/* decor signals */
|
||||
for (; qs < complexHybBands; qs++) {
|
||||
pHybOutRealWet[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
|
||||
<< (scale_param_m2);
|
||||
pHybOutImagWet[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
|
||||
<< (scale_param_m2);
|
||||
pHybOutRealWet[qs] -= SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
|
||||
pHybOutImagWet[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
|
||||
}
|
||||
} /* self->upmixType */
|
||||
} /* if (activParamBands) { */
|
||||
} /* self->numVChannels */
|
||||
|
||||
if (self->phaseCoding == 3) {
|
||||
scaleValuesSaturate(pHybOutRealDry, complexHybBands,
|
||||
SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
|
||||
scaleValuesSaturate(pHybOutImagDry, complexHybBands,
|
||||
SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
|
||||
|
||||
if (!toolsDisabled) {
|
||||
scaleValuesSaturate(pHybOutRealWet, complexHybBands,
|
||||
SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
|
||||
scaleValuesSaturate(pHybOutImagWet, complexHybBands,
|
||||
SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
C_ALLOC_SCRATCH_END(pKernel, FIXP_SGL, MAX_HYBRID_BANDS);
|
||||
@ -919,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.
|
||||
|
@ -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
|
||||
@ -162,75 +162,59 @@ static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
|
||||
FIXP_DBL nrg;
|
||||
|
||||
/* qs = 12, 13, 14 */
|
||||
slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
/* qs = 15 */
|
||||
slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
/* qs = 16, 17 */
|
||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
slotNrg[4] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
slotNrg[4] =
|
||||
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
/* qs = 18, 19, 20 */
|
||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
slotNrg[5] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
slotNrg[5] =
|
||||
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
/* qs = 21, 22 */
|
||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
slotNrg[6] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
slotNrg[6] =
|
||||
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
/* qs = 23, 24 */
|
||||
if (hybBands > 23) {
|
||||
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
/* qs = 25, 26, 29, 28, 29 */
|
||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
slotNrg[7] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
slotNrg[7] =
|
||||
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
/* qs = 30 ... min(41,hybBands-1) */
|
||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
for (qs = 31; qs < hybBands; qs++) {
|
||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
||||
(SF_FACTOR_SLOT - 1));
|
||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||
}
|
||||
slotNrg[8] = nrg;
|
||||
} else {
|
||||
@ -239,49 +223,22 @@ static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
|
||||
}
|
||||
}
|
||||
|
||||
static inline INT getMaxValDmx(FIXP_DBL *RESTRICT pReal,
|
||||
FIXP_DBL *RESTRICT pImag, INT cplxBands,
|
||||
INT hybBands) {
|
||||
INT qs, clz;
|
||||
FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
|
||||
|
||||
for (qs = 12; qs < cplxBands; qs++) {
|
||||
maxVal |= fAbs(pReal[qs]);
|
||||
maxVal |= fAbs(pImag[qs]);
|
||||
}
|
||||
for (; qs < hybBands; qs++) {
|
||||
maxVal |= fAbs(pReal[qs]);
|
||||
}
|
||||
|
||||
clz = fixMax(0, CntLeadingZeros(maxVal) - 1);
|
||||
|
||||
return (clz);
|
||||
}
|
||||
|
||||
static inline INT getMaxValDryWet(FIXP_DBL *RESTRICT pReal,
|
||||
static inline void combineDryWet(FIXP_DBL *RESTRICT pReal,
|
||||
FIXP_DBL *RESTRICT pImag,
|
||||
FIXP_DBL *RESTRICT pHybOutputRealDry,
|
||||
FIXP_DBL *RESTRICT pHybOutputImagDry,
|
||||
FIXP_DBL *RESTRICT pHybOutputRealWet,
|
||||
FIXP_DBL *RESTRICT pHybOutputImagWet,
|
||||
INT cplxBands, INT hybBands) {
|
||||
INT qs, clz;
|
||||
FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
|
||||
INT qs;
|
||||
|
||||
for (qs = 12; qs < cplxBands; qs++) {
|
||||
pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs];
|
||||
maxVal |= fAbs(pReal[qs]);
|
||||
pImag[qs] = pHybOutputImagDry[qs] + pHybOutputImagWet[qs];
|
||||
maxVal |= fAbs(pImag[qs]);
|
||||
pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
|
||||
pImag[qs] = (pHybOutputImagDry[qs] >> 1) + (pHybOutputImagWet[qs] >> 1);
|
||||
}
|
||||
for (; qs < hybBands; qs++) {
|
||||
pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs];
|
||||
maxVal |= fAbs(pReal[qs]);
|
||||
pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
|
||||
}
|
||||
|
||||
clz = fixMax(0, CntLeadingZeros(maxVal) - 1);
|
||||
|
||||
return (clz);
|
||||
}
|
||||
|
||||
static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry,
|
||||
@ -296,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,11 +284,14 @@ shapeBBEnv(FIXP_DBL *pHybOutputRealDry, FIXP_DBL *pHybOutputImagDry,
|
||||
}
|
||||
} else {
|
||||
for (qs = 0; qs < cplxBands; qs++) {
|
||||
pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale;
|
||||
pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac) << scale;
|
||||
pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
|
||||
fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
|
||||
pHybOutputImagDry[qs] = SATURATE_LEFT_SHIFT(
|
||||
fMultDiv2(pHybOutputImagDry[qs], dryFac), scale, DFRACT_BITS);
|
||||
}
|
||||
for (; qs < hybBands; qs++) {
|
||||
pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale;
|
||||
pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
|
||||
fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -367,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);
|
||||
|
||||
@ -386,15 +346,18 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
|
||||
prevChOffs = ch;
|
||||
pReal = pScratchBuffer;
|
||||
pImag = pScratchBuffer + 42;
|
||||
clz = getMaxValDryWet(
|
||||
pReal, pImag, self->hybOutputRealDry__FDK[ch],
|
||||
self->hybOutputImagDry__FDK[ch], self->hybOutputRealWet__FDK[ch],
|
||||
combineDryWet(pReal, pImag, self->hybOutputRealDry__FDK[ch],
|
||||
self->hybOutputImagDry__FDK[ch],
|
||||
self->hybOutputRealWet__FDK[ch],
|
||||
self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
|
||||
clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
|
||||
getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
|
||||
} else {
|
||||
prevChOffs = ch + self->numOutputChannels;
|
||||
pReal = self->hybInputReal__FDK[ch];
|
||||
pImag = self->hybInputImag__FDK[ch];
|
||||
clz = getMaxValDmx(pReal, pImag, cplxBands, hybBands);
|
||||
clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
|
||||
getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
|
||||
}
|
||||
|
||||
partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs];
|
||||
@ -411,8 +374,10 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
|
||||
SF_FACTOR_SLOT */
|
||||
}
|
||||
|
||||
slotNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT;
|
||||
frameNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT;
|
||||
slotNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
|
||||
SF_FACTOR_SLOT;
|
||||
frameNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
|
||||
SF_FACTOR_SLOT;
|
||||
|
||||
partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
|
||||
pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1);
|
||||
@ -652,14 +617,16 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
|
||||
fixMax(3, fixMax(dryFacSF, slotAmpSF)); /* scale is at least with 3
|
||||
bits to avoid overflows
|
||||
when calculating dryFac */
|
||||
dryFac = dryFac >> (scale - dryFacSF);
|
||||
slotAmp_ratio = slotAmp_ratio >> (scale - slotAmpSF);
|
||||
dryFac = dryFac >> fixMin(scale - dryFacSF, DFRACT_BITS - 1);
|
||||
slotAmp_ratio =
|
||||
slotAmp_ratio >> fixMin(scale - slotAmpSF, DFRACT_BITS - 1);
|
||||
|
||||
/* limit dryFac */
|
||||
dryFac = fixMax(
|
||||
FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1),
|
||||
fMult(dryFac, slotAmp_ratio) - (slotAmp_ratio >> scale) +
|
||||
(dryFac >> scale));
|
||||
fMult(dryFac, slotAmp_ratio) -
|
||||
(slotAmp_ratio >> fixMin(scale, DFRACT_BITS - 1)) +
|
||||
(dryFac >> fixMin(scale, DFRACT_BITS - 1)));
|
||||
dryFac = fixMin(
|
||||
FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1),
|
||||
dryFac); /* reduce shift bits by 3, because upper
|
||||
@ -673,8 +640,8 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
|
||||
|
||||
/* shaping */
|
||||
shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6],
|
||||
&self->hybOutputImagDry__FDK[ch][6], dryFac, scale, cplxBands,
|
||||
hybBands);
|
||||
&self->hybOutputImagDry__FDK[ch][6], dryFac,
|
||||
fixMin(scale, DFRACT_BITS - 1), cplxBands, hybBands);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -106,6 +106,8 @@ amm-info@iis.fraunhofer.de
|
||||
#include "FDK_matrixCalloc.h"
|
||||
#include "sac_rom.h"
|
||||
|
||||
#define SF_FREQ_DOMAIN_HEADROOM (2 * (1))
|
||||
|
||||
#define BP_GF_START 6
|
||||
#define BP_GF_SIZE 25
|
||||
#define HP_SIZE 9
|
||||
@ -114,6 +116,16 @@ amm-info@iis.fraunhofer.de
|
||||
#define SF_WET 5
|
||||
#define SF_DRY \
|
||||
3 /* SF_DRY == 2 would produce good conformance test results as well */
|
||||
#define SF_DRY_NRG \
|
||||
(4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
|
||||
i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
|
||||
calculation needs 4 bits headroom, headroom can be reduced by 1 \
|
||||
bit due to fPow2Div2() usage */
|
||||
#define SF_WET_NRG \
|
||||
(4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
|
||||
i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
|
||||
calculation needs 4 bits headroom, headroom can be reduced by 1 \
|
||||
bit due to fPow2Div2() usage */
|
||||
#define SF_PRODUCT_BP_GF 13
|
||||
#define SF_PRODUCT_BP_GF_GF 26
|
||||
#define SF_SCALE 2
|
||||
@ -172,18 +184,6 @@ amm-info@iis.fraunhofer.de
|
||||
STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO)
|
||||
*/
|
||||
|
||||
#define DRY_ENER_WEIGHT(DryEner) DryEner = DryEner >> dry_scale_dmx
|
||||
|
||||
#define WET_ENER_WEIGHT(WetEner) WetEner = WetEner << wet_scale_dmx
|
||||
|
||||
#define DRY_ENER_SUM_REAL(DryEner, dmxReal, n) \
|
||||
DryEner += \
|
||||
fMultDiv2(fPow2Div2(dmxReal << SF_DRY), pBP[n]) >> ((2 * SF_DRY) - 2)
|
||||
|
||||
#define DRY_ENER_SUM_CPLX(DryEner, dmxReal, dmxImag, n) \
|
||||
DryEner += fMultDiv2( \
|
||||
fPow2Div2(dmxReal << SF_DRY) + fPow2Div2(dmxImag << SF_DRY), pBP[n])
|
||||
|
||||
#define CALC_WET_SCALE(dryIdx, wetIdx) \
|
||||
if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \
|
||||
scale[wetIdx] = STP_SCALE_LIMIT_HI; \
|
||||
@ -206,29 +206,6 @@ struct STP_DEC {
|
||||
int update_old_ener;
|
||||
};
|
||||
|
||||
inline void combineSignalReal(FIXP_DBL *hybOutputRealDry,
|
||||
FIXP_DBL *hybOutputRealWet, int bands) {
|
||||
int n;
|
||||
|
||||
for (n = bands - 1; n >= 0; n--) {
|
||||
*hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet;
|
||||
hybOutputRealDry++, hybOutputRealWet++;
|
||||
}
|
||||
}
|
||||
|
||||
inline void combineSignalRealScale1(FIXP_DBL *hybOutputRealDry,
|
||||
FIXP_DBL *hybOutputRealWet, FIXP_DBL scaleX,
|
||||
int bands) {
|
||||
int n;
|
||||
|
||||
for (n = bands - 1; n >= 0; n--) {
|
||||
*hybOutputRealDry =
|
||||
*hybOutputRealDry +
|
||||
(fMultDiv2(*hybOutputRealWet, scaleX) << (SF_SCALE + 1));
|
||||
hybOutputRealDry++, hybOutputRealWet++;
|
||||
}
|
||||
}
|
||||
|
||||
inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
|
||||
FIXP_DBL *hybOutputImagDry,
|
||||
FIXP_DBL *hybOutputRealWet,
|
||||
@ -236,8 +213,8 @@ inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
|
||||
int n;
|
||||
|
||||
for (n = bands - 1; n >= 0; n--) {
|
||||
*hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet;
|
||||
*hybOutputImagDry = *hybOutputImagDry + *hybOutputImagWet;
|
||||
*hybOutputRealDry = fAddSaturate(*hybOutputRealDry, *hybOutputRealWet);
|
||||
*hybOutputImagDry = fAddSaturate(*hybOutputImagDry, *hybOutputImagWet);
|
||||
hybOutputRealDry++, hybOutputRealWet++;
|
||||
hybOutputImagDry++, hybOutputImagWet++;
|
||||
}
|
||||
@ -253,12 +230,14 @@ inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry,
|
||||
FIXP_DBL scaleY;
|
||||
for (n = bands - 1; n >= 0; n--) {
|
||||
scaleY = fMultDiv2(scaleX, *pBP);
|
||||
*hybOutputRealDry =
|
||||
*hybOutputRealDry +
|
||||
(fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 2));
|
||||
*hybOutputImagDry =
|
||||
*hybOutputImagDry +
|
||||
(fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 2));
|
||||
*hybOutputRealDry = SATURATE_LEFT_SHIFT(
|
||||
(*hybOutputRealDry >> 1) +
|
||||
(fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 1)),
|
||||
1, DFRACT_BITS);
|
||||
*hybOutputImagDry = SATURATE_LEFT_SHIFT(
|
||||
(*hybOutputImagDry >> 1) +
|
||||
(fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 1)),
|
||||
1, DFRACT_BITS);
|
||||
hybOutputRealDry++, hybOutputRealWet++;
|
||||
hybOutputImagDry++, hybOutputImagWet++;
|
||||
pBP++;
|
||||
@ -305,12 +284,10 @@ SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) {
|
||||
|
||||
for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
|
||||
self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE));
|
||||
self->oldWetEnerLD64[ch] =
|
||||
FL2FXCONST_DBL(0.34375f); /* 32768.0*32768.0/2^(44-26-10) */
|
||||
self->oldWetEnerLD64[ch] = FL2FXCONST_DBL(0.0);
|
||||
}
|
||||
for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) {
|
||||
self->oldDryEnerLD64[ch] =
|
||||
FL2FXCONST_DBL(0.1875f); /* 32768.0*32768.0/2^(44-26) */
|
||||
self->oldDryEnerLD64[ch] = FL2FXCONST_DBL(0.0);
|
||||
}
|
||||
|
||||
self->BP = BP__FDK;
|
||||
@ -364,7 +341,12 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
||||
{
|
||||
cplxBands = BP_GF_SIZE;
|
||||
cplxHybBands = self->hybridBands;
|
||||
if (self->treeConfig == TREE_212) {
|
||||
dry_scale_dmx = 2; /* 2 bits to compensate fMultDiv2() and fPow2Div2()
|
||||
used in energy calculation */
|
||||
} else {
|
||||
dry_scale_dmx = (2 * SF_DRY) - 2;
|
||||
}
|
||||
wet_scale_dmx = 2;
|
||||
}
|
||||
|
||||
@ -390,6 +372,10 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
||||
CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK);
|
||||
}
|
||||
for (ch = 0; ch < self->numOutputChannels; ch++) {
|
||||
if (self->treeConfig == TREE_212)
|
||||
hStpDec->oldWetEnerLD64[ch] =
|
||||
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR__FDK);
|
||||
else
|
||||
hStpDec->oldWetEnerLD64[ch] =
|
||||
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK);
|
||||
}
|
||||
@ -411,12 +397,33 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
||||
pBP = hStpDec->BP_GF - BP_GF_START;
|
||||
switch (self->treeConfig) {
|
||||
case TREE_212:
|
||||
INT sMin, sNorm, sReal, sImag;
|
||||
|
||||
sReal = fMin(getScalefactor(&qmfOutputRealDry[i_LF][BP_GF_START],
|
||||
cplxBands - BP_GF_START),
|
||||
getScalefactor(&qmfOutputRealDry[i_RF][BP_GF_START],
|
||||
cplxBands - BP_GF_START));
|
||||
sImag = fMin(getScalefactor(&qmfOutputImagDry[i_LF][BP_GF_START],
|
||||
cplxBands - BP_GF_START),
|
||||
getScalefactor(&qmfOutputImagDry[i_RF][BP_GF_START],
|
||||
cplxBands - BP_GF_START));
|
||||
sMin = fMin(sReal, sImag) - 1;
|
||||
|
||||
for (n = BP_GF_START; n < cplxBands; n++) {
|
||||
dmxReal0 = qmfOutputRealDry[i_LF][n] + qmfOutputRealDry[i_RF][n];
|
||||
dmxImag0 = qmfOutputImagDry[i_LF][n] + qmfOutputImagDry[i_RF][n];
|
||||
DRY_ENER_SUM_CPLX(DryEner0, dmxReal0, dmxImag0, n);
|
||||
dmxReal0 = scaleValue(qmfOutputRealDry[i_LF][n], sMin) +
|
||||
scaleValue(qmfOutputRealDry[i_RF][n], sMin);
|
||||
dmxImag0 = scaleValue(qmfOutputImagDry[i_LF][n], sMin) +
|
||||
scaleValue(qmfOutputImagDry[i_RF][n], sMin);
|
||||
|
||||
DryEner0 += (fMultDiv2(fPow2Div2(dmxReal0), pBP[n]) +
|
||||
fMultDiv2(fPow2Div2(dmxImag0), pBP[n])) >>
|
||||
SF_DRY_NRG;
|
||||
}
|
||||
DRY_ENER_WEIGHT(DryEner0);
|
||||
|
||||
sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_DRY_NRG + dry_scale_dmx -
|
||||
(2 * sMin) + nrgScale;
|
||||
DryEner0 = scaleValueSaturate(
|
||||
DryEner0, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
@ -424,7 +431,7 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
||||
|
||||
/* normalise the 'direct' signals */
|
||||
for (ch = 0; ch < self->numInputChannels; ch++) {
|
||||
DryEner[ch] = DryEner[ch] << (nrgScale);
|
||||
if (self->treeConfig != TREE_212) DryEner[ch] = DryEner[ch] << nrgScale;
|
||||
hStpDec->runDryEner[ch] =
|
||||
fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
|
||||
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
|
||||
@ -436,11 +443,9 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
||||
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
|
||||
}
|
||||
}
|
||||
if (self->treeConfig == TREE_212) {
|
||||
for (; ch < MAX_INPUT_CHANNELS; ch++) {
|
||||
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
|
||||
}
|
||||
}
|
||||
|
||||
/* normalise the 'diffuse' signals */
|
||||
pBP = hStpDec->BP_GF - BP_GF_START;
|
||||
@ -450,14 +455,30 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
||||
}
|
||||
|
||||
WetEnerX = FL2FXCONST_DBL(0.0f);
|
||||
for (n = BP_GF_START; n < cplxBands; n++) {
|
||||
tmp = fPow2Div2(qmfOutputRealWet[ch][n] << SF_WET);
|
||||
tmp += fPow2Div2(qmfOutputImagWet[ch][n] << SF_WET);
|
||||
WetEnerX += fMultDiv2(tmp, pBP[n]);
|
||||
}
|
||||
WET_ENER_WEIGHT(WetEnerX);
|
||||
|
||||
WetEnerX = WetEnerX << (nrgScale);
|
||||
if (self->treeConfig == TREE_212) {
|
||||
INT sMin, sNorm;
|
||||
|
||||
sMin = fMin(getScalefactor(&qmfOutputRealWet[ch][BP_GF_START],
|
||||
cplxBands - BP_GF_START),
|
||||
getScalefactor(&qmfOutputImagWet[ch][BP_GF_START],
|
||||
cplxBands - BP_GF_START));
|
||||
|
||||
for (n = BP_GF_START; n < cplxBands; n++) {
|
||||
WetEnerX +=
|
||||
(fMultDiv2(fPow2Div2(scaleValue(qmfOutputRealWet[ch][n], sMin)),
|
||||
pBP[n]) +
|
||||
fMultDiv2(fPow2Div2(scaleValue(qmfOutputImagWet[ch][n], sMin)),
|
||||
pBP[n])) >>
|
||||
SF_WET_NRG;
|
||||
}
|
||||
sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_WET_NRG + wet_scale_dmx -
|
||||
(2 * sMin) + nrgScale;
|
||||
WetEnerX = scaleValueSaturate(
|
||||
WetEnerX, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
|
||||
} else
|
||||
FDK_ASSERT(self->treeConfig == TREE_212);
|
||||
|
||||
hStpDec->runWetEner[ch] =
|
||||
fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) +
|
||||
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -123,12 +123,15 @@ static const UCHAR nBitsTsdCW_64slots[64] = {
|
||||
|
||||
RAM_ALIGN
|
||||
LNK_SECTION_CONSTDATA
|
||||
static const FIXP_STP phiTsd[8] = {
|
||||
STCP(0x7fffffff, 0x00000000), STCP(0x5a82799a, 0x5a82799a),
|
||||
STCP(0x00000000, 0x7fffffff), STCP(0xa57d8666, 0x5a82799a),
|
||||
STCP(0x80000000, 0x00000000), STCP(0xa57d8666, 0xa57d8666),
|
||||
STCP(0x00000000, 0x80000000), STCP(0x5a82799a, 0xa57d8666),
|
||||
};
|
||||
static const FIXP_DPK phiTsd[8] = {
|
||||
{{(FIXP_DBL)0x7fffffff, (FIXP_DBL)0x00000000}},
|
||||
{{(FIXP_DBL)0x5a82799a, (FIXP_DBL)0x5a82799a}},
|
||||
{{(FIXP_DBL)0x00000000, (FIXP_DBL)0x7fffffff}},
|
||||
{{(FIXP_DBL)0xa57d8666, (FIXP_DBL)0x5a82799a}},
|
||||
{{(FIXP_DBL)0x80000000, (FIXP_DBL)0x00000000}},
|
||||
{{(FIXP_DBL)0xa57d8666, (FIXP_DBL)0xa57d8666}},
|
||||
{{(FIXP_DBL)0x00000000, (FIXP_DBL)0x80000000}},
|
||||
{{(FIXP_DBL)0x5a82799a, (FIXP_DBL)0xa57d8666}}};
|
||||
|
||||
/*** Static Functions ***/
|
||||
static void longmult1(USHORT a[], USHORT b, USHORT d[], int len) {
|
||||
@ -333,16 +336,19 @@ void TsdApply(const int numHybridBands, const TSD_DATA *pTsdData, int *pTsdTs,
|
||||
|
||||
if (isTrSlot(pTsdData, ts)) {
|
||||
int k;
|
||||
const FIXP_STP *phi = &phiTsd[pTsdData->bsTsdTrPhaseData[ts]];
|
||||
const FIXP_DPK *phi = &phiTsd[pTsdData->bsTsdTrPhaseData[ts]];
|
||||
FDK_ASSERT((pTsdData->bsTsdTrPhaseData[ts] >= 0) &&
|
||||
(pTsdData->bsTsdTrPhaseData[ts] < 8));
|
||||
|
||||
/* d = d_nonTr + v_direct * exp(j * bsTsdTrPhaseData[ts]/4 * pi ) */
|
||||
for (k = TSD_START_BAND; k < numHybridBands; k++) {
|
||||
FIXP_DBL tempReal, tempImag;
|
||||
cplxMult(&tempReal, &tempImag, pVdirectReal[k], pVdirectImag[k], *phi);
|
||||
pDnonTrReal[k] += tempReal;
|
||||
pDnonTrImag[k] += tempImag;
|
||||
cplxMultDiv2(&tempReal, &tempImag, pVdirectReal[k], pVdirectImag[k],
|
||||
*phi);
|
||||
pDnonTrReal[k] = SATURATE_LEFT_SHIFT(
|
||||
(pDnonTrReal[k] >> 2) + (tempReal >> 1), 2, DFRACT_BITS);
|
||||
pDnonTrImag[k] = SATURATE_LEFT_SHIFT(
|
||||
(pDnonTrImag[k] >> 2) + (tempImag >> 1), 2, 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
|
||||
@ -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.
|
||||
|
@ -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
|
||||
@ -897,21 +897,22 @@ 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)) {
|
||||
reserve = fixMax(0, CntLeadingZeros(maxVal) - 2);
|
||||
reserve = CntLeadingZeros(maxVal) - 2;
|
||||
}
|
||||
|
||||
nrg_ov = nrg = (FIXP_DBL)0;
|
||||
if (scale_nrg_ov > -31) {
|
||||
for (i = startSample; i < overlap; i++) {
|
||||
nrg_ov += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) +
|
||||
fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >>
|
||||
nrg_ov +=
|
||||
(fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) +
|
||||
fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >>
|
||||
sum_scale_ov;
|
||||
}
|
||||
} else {
|
||||
@ -919,8 +920,8 @@ void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal,
|
||||
}
|
||||
if (scale_nrg > -31) {
|
||||
for (i = overlap; i < stopSample; i++) {
|
||||
nrg += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) +
|
||||
fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >>
|
||||
nrg += (fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) +
|
||||
fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >>
|
||||
sum_scale;
|
||||
}
|
||||
} else {
|
||||
|
@ -151,6 +151,9 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
#include "genericStds.h" /* need FDKpow() for debug outputs */
|
||||
|
||||
#define MAX_SFB_NRG_HEADROOM (1)
|
||||
#define MAX_VAL_NRG_HEADROOM ((((FIXP_DBL)MAXVAL_DBL) >> MAX_SFB_NRG_HEADROOM))
|
||||
|
||||
typedef struct {
|
||||
FIXP_DBL nrgRef[MAX_FREQ_COEFFS];
|
||||
FIXP_DBL nrgEst[MAX_FREQ_COEFFS];
|
||||
@ -699,20 +702,11 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
|
||||
gain_sf[i] += gamma_sf + 1; /* +1 because of fMultDiv2() */
|
||||
|
||||
/* set gain to at least 0.2f */
|
||||
FIXP_DBL point_two = FL2FXCONST_DBL(0.8f); /* scaled up by 2 */
|
||||
int point_two_sf = -2;
|
||||
|
||||
FIXP_DBL tmp = gain[i];
|
||||
if (point_two_sf < gain_sf[i]) {
|
||||
point_two >>= gain_sf[i] - point_two_sf;
|
||||
} else {
|
||||
tmp >>= point_two_sf - gain_sf[i];
|
||||
}
|
||||
|
||||
/* limit and calculate gain[i]^2 too */
|
||||
FIXP_DBL gain_pow2;
|
||||
int gain_pow2_sf;
|
||||
if (tmp < point_two) {
|
||||
|
||||
if (fIsLessThan(gain[i], gain_sf[i], FL2FXCONST_DBL(0.2f), 0)) {
|
||||
gain[i] = FL2FXCONST_DBL(0.8f);
|
||||
gain_sf[i] = -2;
|
||||
gain_pow2 = FL2FXCONST_DBL(0.64f);
|
||||
@ -739,7 +733,8 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
|
||||
fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf);
|
||||
total_power_high_after_sf = new_summand_sf;
|
||||
} else if (new_summand_sf < total_power_high_after_sf) {
|
||||
subsample_power_high[i] >>= total_power_high_after_sf - new_summand_sf;
|
||||
subsample_power_high[i] >>=
|
||||
fMin(DFRACT_BITS - 1, total_power_high_after_sf - new_summand_sf);
|
||||
}
|
||||
total_power_high_after += subsample_power_high[i] >> preShift2;
|
||||
}
|
||||
@ -985,7 +980,8 @@ void calculateSbrEnvelope(
|
||||
*/
|
||||
if (!useLP)
|
||||
adj_e = h_sbr_cal_env->filtBufferNoise_e -
|
||||
getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands);
|
||||
getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands) +
|
||||
(INT)MAX_SFB_NRG_HEADROOM;
|
||||
|
||||
/*
|
||||
Scan for maximum reference energy to be able
|
||||
@ -1005,7 +1001,7 @@ void calculateSbrEnvelope(
|
||||
- Smoothing can smear high gains of the previous envelope into the
|
||||
current
|
||||
*/
|
||||
maxSfbNrg_e += 6;
|
||||
maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
|
||||
|
||||
adj_e = maxSfbNrg_e;
|
||||
// final_e should not exist for PVC fixfix framing
|
||||
@ -1031,7 +1027,7 @@ void calculateSbrEnvelope(
|
||||
- Smoothing can smear high gains of the previous envelope into the
|
||||
current
|
||||
*/
|
||||
maxSfbNrg_e += 6;
|
||||
maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
|
||||
|
||||
if (borders[i] < hHeaderData->numberTimeSlots)
|
||||
/* This envelope affects timeslots that belong to the output frame */
|
||||
@ -1477,7 +1473,7 @@ void calculateSbrEnvelope(
|
||||
|
||||
for (k = 0; k < noSubbands; k++) {
|
||||
int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1);
|
||||
pNrgs->nrgGain[k] >>= sc;
|
||||
pNrgs->nrgGain[k] >>= fixMin(sc, DFRACT_BITS - 1);
|
||||
pNrgs->nrgGain_e[k] += sc;
|
||||
}
|
||||
|
||||
@ -1485,7 +1481,7 @@ void calculateSbrEnvelope(
|
||||
for (k = 0; k < noSubbands; k++) {
|
||||
int sc =
|
||||
scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1);
|
||||
h_sbr_cal_env->filtBuffer[k] >>= sc;
|
||||
h_sbr_cal_env->filtBuffer[k] >>= fixMin(sc, DFRACT_BITS - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1576,12 +1572,13 @@ void calculateSbrEnvelope(
|
||||
FDK_ASSERT(!iTES_enable); /* not supported */
|
||||
if (flags & SBRDEC_ELD_GRID) {
|
||||
/* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */
|
||||
adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband], pNrgs,
|
||||
&h_sbr_cal_env->harmIndex, lowSubband,
|
||||
noSubbands,
|
||||
fMin(scale_change, DFRACT_BITS - 1),
|
||||
noNoiseFlag, &h_sbr_cal_env->phaseIndex,
|
||||
EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale);
|
||||
adjustTimeSlot_EldGrid(
|
||||
&analysBufferReal[j][lowSubband], pNrgs,
|
||||
&h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
|
||||
fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
|
||||
&h_sbr_cal_env->phaseIndex,
|
||||
fMax(EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale,
|
||||
-(DFRACT_BITS - 1)));
|
||||
} else {
|
||||
adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs,
|
||||
&h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
|
||||
@ -1830,7 +1827,8 @@ static void equalizeFiltBufferExp(
|
||||
diff = (int)(nrgGain_e[band] - filtBuffer_e[band]);
|
||||
if (diff > 0) {
|
||||
filtBuffer[band] >>=
|
||||
diff; /* Compensate for the scale change by shifting the mantissa. */
|
||||
fMin(diff, DFRACT_BITS - 1); /* Compensate for the scale change by
|
||||
shifting the mantissa. */
|
||||
filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */
|
||||
} else if (diff < 0) {
|
||||
/* The buffered gains seem to be larger, but maybe there
|
||||
@ -1850,8 +1848,8 @@ static void equalizeFiltBufferExp(
|
||||
filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */
|
||||
|
||||
/* For the remaining difference, change the new gain value */
|
||||
diff = fixMin(-(reserve + diff), DFRACT_BITS - 1);
|
||||
nrgGain[band] >>= diff;
|
||||
diff = -(reserve + diff);
|
||||
nrgGain[band] >>= fMin(diff, DFRACT_BITS - 1);
|
||||
nrgGain_e[band] += diff;
|
||||
}
|
||||
}
|
||||
@ -2423,6 +2421,9 @@ static void adjustTimeSlot_EldGrid(
|
||||
const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0];
|
||||
const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0];
|
||||
|
||||
const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
|
||||
const FIXP_DBL min_val = -max_val;
|
||||
|
||||
*(ptrReal - 1) = fAddSaturate(
|
||||
*(ptrReal - 1),
|
||||
SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]),
|
||||
@ -2435,7 +2436,8 @@ static void adjustTimeSlot_EldGrid(
|
||||
FIXP_DBL sineLevel_curr = *pSineLevel++;
|
||||
phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
|
||||
|
||||
signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
|
||||
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
|
||||
<< scale_change;
|
||||
sbNoise = *pNoiseLevel++;
|
||||
if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
|
||||
signalReal +=
|
||||
@ -2469,7 +2471,8 @@ static void adjustTimeSlot_EldGrid(
|
||||
FIXP_DBL sineLevel_curr = *pSineLevel++;
|
||||
phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
|
||||
|
||||
signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
|
||||
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
|
||||
<< scale_change;
|
||||
sbNoise = *pNoiseLevel++;
|
||||
if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
|
||||
signalReal +=
|
||||
@ -2509,6 +2512,8 @@ static void adjustTimeSlotLC(
|
||||
FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
|
||||
int tone_count = 0;
|
||||
int sineSign = 1;
|
||||
const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
|
||||
const FIXP_DBL min_val = -max_val;
|
||||
|
||||
#define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f))
|
||||
#define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.16773f))
|
||||
@ -2524,7 +2529,8 @@ static void adjustTimeSlotLC(
|
||||
of the signal and should be carried out with full accuracy
|
||||
(supplying #FRACT_BITS valid bits).
|
||||
*/
|
||||
signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
|
||||
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
|
||||
<< scale_change;
|
||||
sineLevel = *pSineLevel++;
|
||||
sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
|
||||
|
||||
@ -2552,10 +2558,10 @@ static void adjustTimeSlotLC(
|
||||
|
||||
/* save switch and compare operations and reduce to XOR statement */
|
||||
if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) {
|
||||
*(ptrReal - 1) += tmp1;
|
||||
*(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), tmp1);
|
||||
signalReal -= tmp2;
|
||||
} else {
|
||||
*(ptrReal - 1) -= tmp1;
|
||||
*(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), -tmp1);
|
||||
signalReal += tmp2;
|
||||
}
|
||||
*ptrReal++ = signalReal;
|
||||
@ -2586,7 +2592,9 @@ static void adjustTimeSlotLC(
|
||||
|
||||
/* The next multiplication constitutes the actual envelope adjustment of
|
||||
* the signal. */
|
||||
signalReal += fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
|
||||
signalReal +=
|
||||
fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
|
||||
<< scale_change;
|
||||
|
||||
pNoiseLevel++;
|
||||
*ptrReal++ = signalReal;
|
||||
@ -2599,7 +2607,8 @@ static void adjustTimeSlotLC(
|
||||
index++;
|
||||
/* The next multiplication constitutes the actual envelope adjustment of
|
||||
* the signal. */
|
||||
signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
|
||||
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
|
||||
<< scale_change;
|
||||
|
||||
if (*pSineLevel++ != FL2FXCONST_DBL(0.0f))
|
||||
tone_count++;
|
||||
@ -2627,7 +2636,8 @@ static void adjustTimeSlotLC(
|
||||
index++;
|
||||
/* The next multiplication constitutes the actual envelope adjustment of the
|
||||
* signal. */
|
||||
signalReal = fMultDiv2(*ptrReal, *pGain) << ((int)scale_change);
|
||||
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f));
|
||||
sineLevel = pSineLevel[0];
|
||||
|
||||
@ -2696,6 +2706,9 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
||||
/*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
|
||||
int index = *ptrPhaseIndex;
|
||||
int shift;
|
||||
FIXP_DBL max_val_noise = 0, min_val_noise = 0;
|
||||
const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
|
||||
const FIXP_DBL min_val = -max_val;
|
||||
|
||||
*ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
|
||||
|
||||
@ -2705,6 +2718,8 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
||||
shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
|
||||
} else {
|
||||
shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
|
||||
max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
|
||||
min_val_noise = -max_val_noise;
|
||||
}
|
||||
|
||||
if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
|
||||
@ -2720,7 +2735,9 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
||||
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
|
||||
fMult(direct_ratio, noiseLevel[k]);
|
||||
} else {
|
||||
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) +
|
||||
smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
|
||||
smoothedNoise =
|
||||
(fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
|
||||
fMult(direct_ratio, noiseLevel[k]);
|
||||
}
|
||||
|
||||
@ -2729,8 +2746,12 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
||||
of the signal and should be carried out with full accuracy
|
||||
(supplying #DFRACT_BITS valid bits).
|
||||
*/
|
||||
signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change);
|
||||
signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change);
|
||||
signalReal =
|
||||
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
signalImag =
|
||||
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
|
||||
index++;
|
||||
|
||||
@ -2752,8 +2773,12 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
||||
} else {
|
||||
for (k = 0; k < noSubbands; k++) {
|
||||
smoothedGain = gain[k];
|
||||
signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
|
||||
signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
|
||||
signalReal =
|
||||
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
signalImag =
|
||||
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
|
||||
index++;
|
||||
|
||||
@ -2859,6 +2884,9 @@ static void adjustTimeSlotHQ(
|
||||
int freqInvFlag = (lowSubband & 1);
|
||||
FIXP_DBL sineLevel;
|
||||
int shift;
|
||||
FIXP_DBL max_val_noise = 0, min_val_noise = 0;
|
||||
const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
|
||||
const FIXP_DBL min_val = -max_val;
|
||||
|
||||
*ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
|
||||
*ptrHarmIndex = (harmIndex + 1) & 3;
|
||||
@ -2874,10 +2902,13 @@ static void adjustTimeSlotHQ(
|
||||
|
||||
filtBufferNoiseShift +=
|
||||
1; /* due to later use of fMultDiv2 instead of fMult */
|
||||
if (filtBufferNoiseShift < 0)
|
||||
if (filtBufferNoiseShift < 0) {
|
||||
shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
|
||||
else
|
||||
} else {
|
||||
shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
|
||||
max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
|
||||
min_val_noise = -max_val_noise;
|
||||
}
|
||||
|
||||
if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
|
||||
for (k = 0; k < noSubbands; k++) {
|
||||
@ -2893,7 +2924,9 @@ static void adjustTimeSlotHQ(
|
||||
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
|
||||
fMult(direct_ratio, noiseLevel[k]);
|
||||
} else {
|
||||
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) +
|
||||
smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
|
||||
smoothedNoise =
|
||||
(fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
|
||||
fMult(direct_ratio, noiseLevel[k]);
|
||||
}
|
||||
|
||||
@ -2902,8 +2935,12 @@ static void adjustTimeSlotHQ(
|
||||
of the signal and should be carried out with full accuracy
|
||||
(supplying #DFRACT_BITS valid bits).
|
||||
*/
|
||||
signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change);
|
||||
signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change);
|
||||
signalReal =
|
||||
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
signalImag =
|
||||
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
|
||||
index++;
|
||||
|
||||
@ -2956,8 +2993,12 @@ static void adjustTimeSlotHQ(
|
||||
} else {
|
||||
for (k = 0; k < noSubbands; k++) {
|
||||
smoothedGain = gain[k];
|
||||
signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
|
||||
signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
|
||||
signalReal =
|
||||
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
signalImag =
|
||||
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
|
||||
index++;
|
||||
|
||||
@ -3141,6 +3182,11 @@ ResetLimiterBands(
|
||||
return SBRDEC_UNSUPPORTED_CONFIG;
|
||||
}
|
||||
|
||||
/* Restrict maximum value of limiter band table */
|
||||
if (workLimiterBandTable[tempNoLim] > highSubband) {
|
||||
return SBRDEC_UNSUPPORTED_CONFIG;
|
||||
}
|
||||
|
||||
/* Copy limiterbands from working buffer into final destination */
|
||||
for (k = 0; k <= nBands; k++) {
|
||||
limiterBandTable[k] = workLimiterBandTable[k];
|
||||
|
@ -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
|
||||
@ -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) {
|
||||
@ -1339,7 +1339,7 @@ static void addHighBandPart(FIXP_DBL g_r_m, FIXP_DBL g_i_m, INT g_e,
|
||||
g_r_m = fMultDiv2(tmp_r, factor_m) << shift;
|
||||
g_i_m = fMultDiv2(tmp_i, factor_m) << shift;
|
||||
g_e = scale_factor_hbe - (g_e + factor_e + gammaCenter_e + add);
|
||||
fMax((INT)0, g_e);
|
||||
g_e = fMax((INT)0, g_e);
|
||||
*qmfHBEBufReal_F += g_r_m >> g_e;
|
||||
*qmfHBEBufImag_F += g_i_m >> g_e;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1014,8 +1014,8 @@ void lppTransposerHBE(
|
||||
pSettings->nCols) +
|
||||
lowBandShift);
|
||||
|
||||
dynamicScale = fixMax(
|
||||
0, dynamicScale - 1); /* one additional bit headroom to prevent -1.0 */
|
||||
dynamicScale =
|
||||
dynamicScale - 1; /* one additional bit headroom to prevent -1.0 */
|
||||
|
||||
/*
|
||||
Scale temporal QMF buffer.
|
||||
@ -1194,6 +1194,9 @@ void lppTransposerHBE(
|
||||
} else { /* bw <= 0 */
|
||||
|
||||
int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
|
||||
dynamicScale +=
|
||||
1; /* prevent negativ scale factor due to 'one additional bit
|
||||
headroom' */
|
||||
|
||||
for (i = startSample; i < stopSample; i++) {
|
||||
FIXP_DBL accu1, accu2;
|
||||
@ -1210,9 +1213,9 @@ void lppTransposerHBE(
|
||||
dynamicScale;
|
||||
|
||||
qmfBufferReal[i][loBand] =
|
||||
(lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << 1);
|
||||
(lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << (1 + 1));
|
||||
qmfBufferImag[i][loBand] =
|
||||
(lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << 1);
|
||||
(lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << (1 + 1));
|
||||
}
|
||||
} /* bw <= 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
|
||||
@ -534,7 +534,8 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
|
||||
for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
|
||||
for (band = sg_borders[ksg]; band < sg_borders[ksg + 1]; band++) {
|
||||
/* The division by 8 == (RATE*lbw) is required algorithmically */
|
||||
E[ksg] += (fPow2Div2(qmfR[band]) + fPow2Div2(qmfI[band])) >> 2;
|
||||
E[ksg] +=
|
||||
((fPow2Div2(qmfR[band]) >> 1) + (fPow2Div2(qmfI[band]) >> 1)) >> 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -542,7 +543,7 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
|
||||
if (E[ksg] > (FIXP_DBL)0) {
|
||||
/* 10/log2(10) = 0.752574989159953 * 2^2 */
|
||||
int exp_log;
|
||||
FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent, &exp_log);
|
||||
FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent + 2, &exp_log);
|
||||
nrg = fMult(nrg, FL2FXCONST_SGL(LOG10FAC));
|
||||
nrg = scaleValue(nrg, exp_log - PVC_ESG_EXP + 2);
|
||||
pEsg[ksg] = fMax(nrg, FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)));
|
||||
@ -603,22 +604,22 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
|
||||
E_high_exp[ksg] = 0;
|
||||
|
||||
/* residual part */
|
||||
accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP +
|
||||
accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP - 2 +
|
||||
pPvcDynamicData->pScalingCoef[3]);
|
||||
|
||||
/* linear combination of lower grouped energies part */
|
||||
for (kb = 0; kb < PVC_NBLOW; kb++) {
|
||||
predCoeff = (FIXP_SGL)(
|
||||
(SHORT)(SCHAR)pTab1[kb * pPvcDynamicData->nbHigh + ksg] << 8);
|
||||
predCoeff_exp = pPvcDynamicData->pScalingCoef[kb] +
|
||||
1; /* +1 to compensate for Div2 */
|
||||
accu += fMultDiv2(E[kb], predCoeff) << predCoeff_exp;
|
||||
predCoeff_exp = -(pPvcDynamicData->pScalingCoef[kb] + 1 -
|
||||
2); /* +1 to compensate for Div2; -2 for accu */
|
||||
accu += fMultDiv2(E[kb], predCoeff) >> predCoeff_exp;
|
||||
}
|
||||
/* convert back to linear domain */
|
||||
accu = fMult(accu, FL2FXCONST_SGL(LOG10FAC_INV));
|
||||
accu = f2Pow(
|
||||
accu, PVC_ESG_EXP - 1,
|
||||
&predCoeff_exp); /* -1 compensates for exponent of LOG10FAC_INV */
|
||||
accu = f2Pow(accu, PVC_ESG_EXP - 1 + 2,
|
||||
&predCoeff_exp); /* -1 compensates for exponent of
|
||||
LOG10FAC_INV; +2 for accu */
|
||||
predictedEsgSlot[ksg] = accu;
|
||||
E_high_exp[ksg] = predCoeff_exp;
|
||||
if (predCoeff_exp > E_high_exp_max) {
|
||||
@ -628,8 +629,8 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
|
||||
|
||||
/* rescale output vector according to largest exponent */
|
||||
for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
|
||||
int scale = E_high_exp[ksg] - E_high_exp_max;
|
||||
predictedEsgSlot[ksg] = scaleValue(predictedEsgSlot[ksg], scale);
|
||||
int scale = fMin(E_high_exp_max - E_high_exp[ksg], DFRACT_BITS - 1);
|
||||
predictedEsgSlot[ksg] = predictedEsgSlot[ksg] >> scale;
|
||||
}
|
||||
*predictedEsg_exp = E_high_exp_max;
|
||||
}
|
||||
|
@ -1,192 +0,0 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
|
||||
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
|
||||
scheme for digital audio. This FDK AAC Codec software is intended to be used on
|
||||
a wide variety of Android devices.
|
||||
|
||||
AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
|
||||
general perceptual audio codecs. AAC-ELD is considered the best-performing
|
||||
full-bandwidth communications codec by independent studies and is widely
|
||||
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
|
||||
specifications.
|
||||
|
||||
Patent licenses for necessary patent claims for the FDK AAC Codec (including
|
||||
those of Fraunhofer) may be obtained through Via Licensing
|
||||
(www.vialicensing.com) or through the respective patent owners individually for
|
||||
the purpose of encoding or decoding bit streams in products that are compliant
|
||||
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
|
||||
Android devices already license these patent claims through Via Licensing or
|
||||
directly from the patent owners, and therefore FDK AAC Codec software may
|
||||
already be covered under those patent licenses when it is used for those
|
||||
licensed purposes only.
|
||||
|
||||
Commercially-licensed AAC software libraries, including floating-point versions
|
||||
with enhanced sound quality, are also available from Fraunhofer. Users are
|
||||
encouraged to check the Fraunhofer website for additional applications
|
||||
information and documentation.
|
||||
|
||||
2. COPYRIGHT LICENSE
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted without payment of copyright license fees provided that you
|
||||
satisfy the following conditions:
|
||||
|
||||
You must retain the complete text of this software license in redistributions of
|
||||
the FDK AAC Codec or your modifications thereto in source code form.
|
||||
|
||||
You must retain the complete text of this software license in the documentation
|
||||
and/or other materials provided with redistributions of the FDK AAC Codec or
|
||||
your modifications thereto in binary form. You must make available free of
|
||||
charge copies of the complete source code of the FDK AAC Codec and your
|
||||
modifications thereto to recipients of copies in binary form.
|
||||
|
||||
The name of Fraunhofer may not be used to endorse or promote products derived
|
||||
from this library without prior written permission.
|
||||
|
||||
You may not charge copyright license fees for anyone to use, copy or distribute
|
||||
the FDK AAC Codec software or your modifications thereto.
|
||||
|
||||
Your modified versions of the FDK AAC Codec must carry prominent notices stating
|
||||
that you changed the software and the date of any change. For modified versions
|
||||
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
|
||||
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
|
||||
AAC Codec Library for Android."
|
||||
|
||||
3. NO PATENT LICENSE
|
||||
|
||||
NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
|
||||
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
|
||||
Fraunhofer provides no warranty of patent non-infringement with respect to this
|
||||
software.
|
||||
|
||||
You may use this FDK AAC Codec software or modifications thereto only for
|
||||
purposes that are authorized by appropriate patent licenses.
|
||||
|
||||
4. DISCLAIMER
|
||||
|
||||
This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
|
||||
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
including but not limited to the implied warranties of merchantability and
|
||||
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
|
||||
or consequential damages, including but not limited to procurement of substitute
|
||||
goods or services; loss of use, data, or profits, or business interruption,
|
||||
however caused and on any theory of liability, whether in contract, strict
|
||||
liability, or tort (including negligence), arising in any way out of the use of
|
||||
this software, even if advised of the possibility of such damage.
|
||||
|
||||
5. CONTACT INFORMATION
|
||||
|
||||
Fraunhofer Institute for Integrated Circuits IIS
|
||||
Attention: Audio and Multimedia Departments - FDK AAC LL
|
||||
Am Wolfsmantel 33
|
||||
91058 Erlangen, Germany
|
||||
|
||||
www.iis.fraunhofer.de/amm
|
||||
amm-info@iis.fraunhofer.de
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
/**************************** SBR decoder library ******************************
|
||||
|
||||
Author(s):
|
||||
|
||||
Description:
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
/*!
|
||||
\file
|
||||
\brief CRC check coutines
|
||||
*/
|
||||
|
||||
#include "sbr_crc.h"
|
||||
|
||||
#include "FDK_bitstream.h"
|
||||
#include "transcendent.h"
|
||||
|
||||
#define MAXCRCSTEP 16
|
||||
#define MAXCRCSTEP_LD 4
|
||||
|
||||
/*!
|
||||
\brief crc calculation
|
||||
*/
|
||||
static ULONG calcCRC(HANDLE_CRC hCrcBuf, ULONG bValue, int nBits) {
|
||||
int i;
|
||||
ULONG bMask = (1UL << (nBits - 1));
|
||||
|
||||
for (i = 0; i < nBits; i++, bMask >>= 1) {
|
||||
USHORT flag = (hCrcBuf->crcState & hCrcBuf->crcMask) ? 1 : 0;
|
||||
USHORT flag1 = (bMask & bValue) ? 1 : 0;
|
||||
|
||||
flag ^= flag1;
|
||||
hCrcBuf->crcState <<= 1;
|
||||
if (flag) hCrcBuf->crcState ^= hCrcBuf->crcPoly;
|
||||
}
|
||||
|
||||
return (hCrcBuf->crcState);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief crc
|
||||
*/
|
||||
static int getCrc(HANDLE_FDK_BITSTREAM hBs, ULONG NrBits) {
|
||||
int i;
|
||||
CRC_BUFFER CrcBuf;
|
||||
|
||||
CrcBuf.crcState = SBR_CRC_START;
|
||||
CrcBuf.crcPoly = SBR_CRC_POLY;
|
||||
CrcBuf.crcMask = SBR_CRC_MASK;
|
||||
|
||||
int CrcStep = NrBits >> MAXCRCSTEP_LD;
|
||||
|
||||
int CrcNrBitsRest = (NrBits - CrcStep * MAXCRCSTEP);
|
||||
ULONG bValue;
|
||||
|
||||
for (i = 0; i < CrcStep; i++) {
|
||||
bValue = FDKreadBits(hBs, MAXCRCSTEP);
|
||||
calcCRC(&CrcBuf, bValue, MAXCRCSTEP);
|
||||
}
|
||||
|
||||
bValue = FDKreadBits(hBs, CrcNrBitsRest);
|
||||
calcCRC(&CrcBuf, bValue, CrcNrBitsRest);
|
||||
|
||||
return (CrcBuf.crcState & SBR_CRC_RANGE);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief crc interface
|
||||
\return 1: CRC OK, 0: CRC check failure
|
||||
*/
|
||||
int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBs, /*!< handle to bit-buffer */
|
||||
LONG NrBits) /*!< max. CRC length */
|
||||
{
|
||||
int crcResult = 1;
|
||||
ULONG NrCrcBits;
|
||||
ULONG crcCheckResult;
|
||||
LONG NrBitsAvailable;
|
||||
ULONG crcCheckSum;
|
||||
|
||||
crcCheckSum = FDKreadBits(hBs, 10);
|
||||
|
||||
NrBitsAvailable = FDKgetValidBits(hBs);
|
||||
if (NrBitsAvailable <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
NrCrcBits = fixMin((INT)NrBits, (INT)NrBitsAvailable);
|
||||
|
||||
crcCheckResult = getCrc(hBs, NrCrcBits);
|
||||
FDKpushBack(hBs, (NrBitsAvailable - FDKgetValidBits(hBs)));
|
||||
|
||||
if (crcCheckResult != crcCheckSum) {
|
||||
crcResult = 0;
|
||||
}
|
||||
|
||||
return (crcResult);
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
|
||||
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
|
||||
scheme for digital audio. This FDK AAC Codec software is intended to be used on
|
||||
a wide variety of Android devices.
|
||||
|
||||
AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
|
||||
general perceptual audio codecs. AAC-ELD is considered the best-performing
|
||||
full-bandwidth communications codec by independent studies and is widely
|
||||
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
|
||||
specifications.
|
||||
|
||||
Patent licenses for necessary patent claims for the FDK AAC Codec (including
|
||||
those of Fraunhofer) may be obtained through Via Licensing
|
||||
(www.vialicensing.com) or through the respective patent owners individually for
|
||||
the purpose of encoding or decoding bit streams in products that are compliant
|
||||
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
|
||||
Android devices already license these patent claims through Via Licensing or
|
||||
directly from the patent owners, and therefore FDK AAC Codec software may
|
||||
already be covered under those patent licenses when it is used for those
|
||||
licensed purposes only.
|
||||
|
||||
Commercially-licensed AAC software libraries, including floating-point versions
|
||||
with enhanced sound quality, are also available from Fraunhofer. Users are
|
||||
encouraged to check the Fraunhofer website for additional applications
|
||||
information and documentation.
|
||||
|
||||
2. COPYRIGHT LICENSE
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted without payment of copyright license fees provided that you
|
||||
satisfy the following conditions:
|
||||
|
||||
You must retain the complete text of this software license in redistributions of
|
||||
the FDK AAC Codec or your modifications thereto in source code form.
|
||||
|
||||
You must retain the complete text of this software license in the documentation
|
||||
and/or other materials provided with redistributions of the FDK AAC Codec or
|
||||
your modifications thereto in binary form. You must make available free of
|
||||
charge copies of the complete source code of the FDK AAC Codec and your
|
||||
modifications thereto to recipients of copies in binary form.
|
||||
|
||||
The name of Fraunhofer may not be used to endorse or promote products derived
|
||||
from this library without prior written permission.
|
||||
|
||||
You may not charge copyright license fees for anyone to use, copy or distribute
|
||||
the FDK AAC Codec software or your modifications thereto.
|
||||
|
||||
Your modified versions of the FDK AAC Codec must carry prominent notices stating
|
||||
that you changed the software and the date of any change. For modified versions
|
||||
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
|
||||
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
|
||||
AAC Codec Library for Android."
|
||||
|
||||
3. NO PATENT LICENSE
|
||||
|
||||
NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
|
||||
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
|
||||
Fraunhofer provides no warranty of patent non-infringement with respect to this
|
||||
software.
|
||||
|
||||
You may use this FDK AAC Codec software or modifications thereto only for
|
||||
purposes that are authorized by appropriate patent licenses.
|
||||
|
||||
4. DISCLAIMER
|
||||
|
||||
This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
|
||||
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
including but not limited to the implied warranties of merchantability and
|
||||
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
|
||||
or consequential damages, including but not limited to procurement of substitute
|
||||
goods or services; loss of use, data, or profits, or business interruption,
|
||||
however caused and on any theory of liability, whether in contract, strict
|
||||
liability, or tort (including negligence), arising in any way out of the use of
|
||||
this software, even if advised of the possibility of such damage.
|
||||
|
||||
5. CONTACT INFORMATION
|
||||
|
||||
Fraunhofer Institute for Integrated Circuits IIS
|
||||
Attention: Audio and Multimedia Departments - FDK AAC LL
|
||||
Am Wolfsmantel 33
|
||||
91058 Erlangen, Germany
|
||||
|
||||
www.iis.fraunhofer.de/amm
|
||||
amm-info@iis.fraunhofer.de
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
/**************************** SBR decoder library ******************************
|
||||
|
||||
Author(s):
|
||||
|
||||
Description:
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
/*!
|
||||
\file
|
||||
\brief CRC checking routines
|
||||
*/
|
||||
#ifndef SBR_CRC_H
|
||||
#define SBR_CRC_H
|
||||
|
||||
#include "sbrdecoder.h"
|
||||
|
||||
#include "FDK_bitstream.h"
|
||||
|
||||
/* some useful crc polynoms:
|
||||
|
||||
crc5: x^5+x^4+x^2+x^1+1
|
||||
crc6: x^6+x^5+x^3+x^2+x+1
|
||||
crc7: x^7+x^6+x^2+1
|
||||
crc8: x^8+x^2+x+x+1
|
||||
*/
|
||||
|
||||
/* default SBR CRC */ /* G(x) = x^10 + x^9 + x^5 + x^4 + x + 1 */
|
||||
#define SBR_CRC_POLY 0x0233
|
||||
#define SBR_CRC_MASK 0x0200
|
||||
#define SBR_CRC_START 0x0000
|
||||
#define SBR_CRC_RANGE 0x03FF
|
||||
|
||||
typedef struct {
|
||||
USHORT crcState;
|
||||
USHORT crcMask;
|
||||
USHORT crcPoly;
|
||||
} CRC_BUFFER;
|
||||
|
||||
typedef CRC_BUFFER *HANDLE_CRC;
|
||||
|
||||
int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBitBuf, LONG NrCrcBits);
|
||||
|
||||
#endif
|
@ -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
|
||||
@ -109,9 +109,6 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
#include "sbr_ram.h"
|
||||
|
||||
#define WORKBUFFER1_TAG 2
|
||||
#define WORKBUFFER2_TAG 3
|
||||
|
||||
/*!
|
||||
\name StaticSbrData
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
@ -230,6 +230,8 @@ static UCHAR getStopBand(
|
||||
}
|
||||
}
|
||||
|
||||
stopMin = fMin(stopMin, 64);
|
||||
|
||||
/*
|
||||
Choose a stop band between k1 and 64 depending on stopFreq (0..13),
|
||||
based on a logarithmic scale.
|
||||
@ -523,7 +525,8 @@ static FIXP_SGL calcFactorPerBand(int k_start, int k_stop, int num_bands) {
|
||||
step = FL2FXCONST_DBL(0.0f);
|
||||
}
|
||||
}
|
||||
return FX_DBL2FX_SGL(bandfactor << 1);
|
||||
return (bandfactor >= FL2FXCONST_DBL(0.5)) ? (FIXP_SGL)MAXVAL_SGL
|
||||
: FX_DBL2FX_SGL(bandfactor << 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -143,21 +143,19 @@ amm-info@iis.fraunhofer.de
|
||||
#include "env_extr.h"
|
||||
#include "sbr_dec.h"
|
||||
#include "env_dec.h"
|
||||
#include "sbr_crc.h"
|
||||
#include "FDK_crc.h"
|
||||
#include "sbr_ram.h"
|
||||
#include "sbr_rom.h"
|
||||
#include "lpp_tran.h"
|
||||
#include "transcendent.h"
|
||||
|
||||
#include "FDK_crc.h"
|
||||
|
||||
#include "sbrdec_drc.h"
|
||||
|
||||
#include "psbitdec.h"
|
||||
|
||||
/* 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 SUPPRESS_BUILD_DATE_INFO
|
||||
@ -1134,18 +1132,22 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
|
||||
SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT;
|
||||
|
||||
INT startPos = FDKgetValidBits(hBs);
|
||||
INT CRCLen = 0;
|
||||
FDK_CRCINFO crcInfo;
|
||||
INT crcReg = 0;
|
||||
USHORT sbrCrc = 0;
|
||||
UINT crcPoly;
|
||||
UINT crcStartValue = 0;
|
||||
UINT crcLen;
|
||||
|
||||
HANDLE_FDK_BITSTREAM hBsOriginal = hBs;
|
||||
FDK_BITSTREAM bsBwd;
|
||||
|
||||
FDK_CRCINFO crcInfo;
|
||||
INT crcReg = 0;
|
||||
USHORT drmSbrCrc = 0;
|
||||
const int fGlobalIndependencyFlag = acFlags & AC_INDEP;
|
||||
const int bs_pvc = acElFlags[elementIndex] & AC_EL_USAC_PVC;
|
||||
const int bs_interTes = acElFlags[elementIndex] & AC_EL_USAC_ITES;
|
||||
int stereo;
|
||||
int fDoDecodeSbrData = 1;
|
||||
int alignBits = 0;
|
||||
|
||||
int lastSlot, lastHdrSlot = 0, thisHdrSlot = 0;
|
||||
|
||||
@ -1277,27 +1279,23 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
|
||||
if (fDoDecodeSbrData) {
|
||||
if (crcFlag) {
|
||||
switch (self->coreCodec) {
|
||||
case AOT_ER_AAC_ELD:
|
||||
FDKpushFor(hBs, 10);
|
||||
/* check sbrcrc later: we don't know the payload length now */
|
||||
break;
|
||||
case AOT_DRM_AAC:
|
||||
case AOT_DRM_SURROUND:
|
||||
drmSbrCrc = (USHORT)FDKreadBits(hBs, 8);
|
||||
/* Setup CRC decoder */
|
||||
FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8);
|
||||
/* Start CRC region */
|
||||
crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
|
||||
crcPoly = 0x001d;
|
||||
crcLen = 8;
|
||||
crcStartValue = 0x000000ff;
|
||||
break;
|
||||
default:
|
||||
CRCLen = bsPayLen - 10; /* change: 0 => i */
|
||||
if (CRCLen < 0) {
|
||||
fDoDecodeSbrData = 0;
|
||||
} else {
|
||||
fDoDecodeSbrData = SbrCrcCheck(hBs, CRCLen);
|
||||
}
|
||||
crcPoly = 0x0633;
|
||||
crcLen = 10;
|
||||
crcStartValue = 0x00000000;
|
||||
break;
|
||||
}
|
||||
sbrCrc = (USHORT)FDKreadBits(hBs, crcLen);
|
||||
/* Setup CRC decoder */
|
||||
FDKcrcInit(&crcInfo, crcPoly, crcStartValue, crcLen);
|
||||
/* Start CRC region */
|
||||
crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
|
||||
}
|
||||
} /* if (fDoDecodeSbrData) */
|
||||
|
||||
@ -1450,35 +1448,6 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
|
||||
valBits = (INT)FDKgetValidBits(hBs);
|
||||
}
|
||||
|
||||
if (crcFlag) {
|
||||
switch (self->coreCodec) {
|
||||
case AOT_ER_AAC_ELD: {
|
||||
/* late crc check for eld */
|
||||
INT payloadbits =
|
||||
(INT)startPos - (INT)FDKgetValidBits(hBs) - startPos;
|
||||
INT crcLen = payloadbits - 10;
|
||||
FDKpushBack(hBs, payloadbits);
|
||||
fDoDecodeSbrData = SbrCrcCheck(hBs, crcLen);
|
||||
FDKpushFor(hBs, crcLen);
|
||||
} break;
|
||||
case AOT_DRM_AAC:
|
||||
case AOT_DRM_SURROUND:
|
||||
/* End CRC region */
|
||||
FDKcrcEndReg(&crcInfo, hBs, crcReg);
|
||||
/* Check CRC */
|
||||
if ((FDKcrcGetCRC(&crcInfo) ^ 0xFF) != drmSbrCrc) {
|
||||
fDoDecodeSbrData = 0;
|
||||
if (headerStatus != HEADER_NOT_PRESENT) {
|
||||
headerStatus = HEADER_ERROR;
|
||||
hSbrHeader->syncState = SBR_NOT_INITIALIZED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* sanity check of remaining bits */
|
||||
if (valBits < 0) {
|
||||
fDoDecodeSbrData = 0;
|
||||
@ -1489,7 +1458,7 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
|
||||
case AOT_AAC_LC: {
|
||||
/* This sanity check is only meaningful with General Audio
|
||||
* bitstreams */
|
||||
int alignBits = valBits & 0x7;
|
||||
alignBits = valBits & 0x7;
|
||||
|
||||
if (valBits > alignBits) {
|
||||
fDoDecodeSbrData = 0;
|
||||
@ -1508,6 +1477,20 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
|
||||
errorStatus = SBRDEC_PARSE_ERROR;
|
||||
}
|
||||
|
||||
if (crcFlag && (hSbrHeader->syncState >= SBR_HEADER) && fDoDecodeSbrData) {
|
||||
FDKpushFor(hBs, alignBits);
|
||||
FDKcrcEndReg(&crcInfo, hBs, crcReg); /* End CRC region */
|
||||
FDKpushBack(hBs, alignBits);
|
||||
/* Check CRC */
|
||||
if ((FDKcrcGetCRC(&crcInfo) ^ crcStartValue) != sbrCrc) {
|
||||
fDoDecodeSbrData = 0;
|
||||
if (headerStatus != HEADER_NOT_PRESENT) {
|
||||
headerStatus = HEADER_ERROR;
|
||||
hSbrHeader->syncState = SBR_NOT_INITIALIZED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!fDoDecodeSbrData) {
|
||||
/* Set error flag for this slot to trigger concealment */
|
||||
setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR);
|
||||
@ -1587,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;
|
||||
@ -1760,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 */
|
||||
@ -1768,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)
|
||||
@ -1788,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++;
|
||||
@ -1808,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;
|
||||
@ -1850,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…
x
Reference in New Issue
Block a user