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
|
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.
|
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
|
\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
|
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
|
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
|
implemented in a variety of configurations depending on the user's specific
|
||||||
requirements. The example implementation uses file-based input/output, and in
|
requirements.
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
-# Call aacDecoder_Open() to open and retrieve a handle to a new AAC decoder
|
-# 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
|
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
|
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.
|
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
|
-# 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
|
with the client-supplied bitstream input buffer. Note, if the data loaded in to
|
||||||
the internal buffer is not sufficient to decode a frame,
|
the internal buffer is not sufficient to decode a frame,
|
||||||
aacDecoder_DecodeFrame() will return ::AAC_DEC_NOT_ENOUGH_BITS until a
|
aacDecoder_DecodeFrame() will return ::AAC_DEC_NOT_ENOUGH_BITS until a
|
||||||
sufficient amount of data is loaded in to the internal buffer. For streaming
|
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
|
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
|
decoder. However, for packed based formats, only one frame may be loaded to the
|
||||||
one frame may be loaded to the decoder per aacDecoder_DecodeFrame() call. For
|
decoder per aacDecoder_DecodeFrame() call. For least amount of communication
|
||||||
least amount of communication delay, fill and decode should be performed on a
|
delay, fill and decode should be performed on a frame by frame basis. \code
|
||||||
frame by frame basis. \code ErrorStatus = aacDecoder_Fill(aacDecoderInfo,
|
ErrorStatus = aacDecoder_Fill(aacDecoderInfo, inBuffer, bytesRead,
|
||||||
inBuffer, bytesRead, bytesValid); \endcode
|
bytesValid); \endcode
|
||||||
-# Call aacDecoder_DecodeFrame(). This function decodes one frame and writes
|
-# Call aacDecoder_DecodeFrame(). This function decodes one frame and writes
|
||||||
decoded PCM audio data to a client-supplied buffer. It is the client's
|
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
|
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
|
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
|
of channels, sample rate, frame size) is not known a priori, you may call
|
||||||
aacDecoder_GetStreamInfo() to retrieve a structure that contains this
|
aacDecoder_GetStreamInfo() to retrieve a structure that contains this
|
||||||
information. You may use this data to initialize an audio output device. In the
|
information. You may use this data to initialize an audio output device. \code
|
||||||
example program, if the number of channels or the sample rate has changed since
|
p_si = aacDecoder_GetStreamInfo(aacDecoderInfo);
|
||||||
program start or the previously decoded frame, the audio output device is then
|
\endcode
|
||||||
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
|
|
||||||
-# Repeat steps 5 to 7 until no data is available to decode any more, or in case
|
-# 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 ||
|
of error. \code } while (bytesRead[0] > 0 || doFlush || doBsFlush ||
|
||||||
forceContinue); \endcode
|
forceContinue); \endcode
|
||||||
@ -239,7 +219,7 @@ structures. \code aacDecoder_Close(aacDecoderInfo); \endcode
|
|||||||
|
|
||||||
\image latex decode.png "Decode calling sequence" width=11cm
|
\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
|
\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
|
limited applications, the output buffer may be reused as an external input
|
||||||
buffer prior to the subsequence aacDecoder_Fill() function call.
|
buffer prior to the subsequence aacDecoder_Fill() function call.
|
||||||
|
|
||||||
The external input buffer is set in the example program and its size is defined
|
To feed the data to the decoder-internal input buffer, use the
|
||||||
by ::IN_BUF_SIZE. You may freely choose different buffer sizes. To feed the data
|
function aacDecoder_Fill(). This function returns important information
|
||||||
to the decoder-internal input buffer, use the function aacDecoder_Fill(). This
|
regarding the number of bytes in the external input buffer that have not yet
|
||||||
function returns important information regarding the number of bytes in the
|
been copied into the internal input buffer (variable bytesValid). Once the
|
||||||
external input buffer that have not yet been copied into the internal input
|
external buffer has been fully copied, it can be completely re-filled again. In
|
||||||
buffer (variable bytesValid). Once the external buffer has been fully copied, it
|
case you wish to refill the buffer while there are unprocessed bytes (bytesValid
|
||||||
can be completely re-filled again. In case you wish to refill the buffer while
|
is unequal 0), you should preserve the unconsumed data. However, we recommend to
|
||||||
there are unprocessed bytes (bytesValid is unequal 0), you should preserve the
|
refill the buffer only when bytesValid returns 0.
|
||||||
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
|
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.
|
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
|
In case a Program Config is included in the audio configuration, the channel
|
||||||
mapping described within it will be adopted.
|
mapping described within it will be adopted.
|
||||||
|
|
||||||
In case of MPEG-D Surround the channel mapping will follow the same criteria
|
The examples below explain these aspects in detail.
|
||||||
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.
|
|
||||||
|
|
||||||
\section OutputFormatChange Changing the audio output format
|
\section OutputFormatChange Changing the audio output format
|
||||||
|
|
||||||
@ -689,9 +664,7 @@ typedef enum {
|
|||||||
2. If the parameter value is greater than that of
|
2. If the parameter value is greater than that of
|
||||||
::AAC_PCM_MAX_OUTPUT_CHANNELS both will be set to the same
|
::AAC_PCM_MAX_OUTPUT_CHANNELS both will be set to the same
|
||||||
value. \n
|
value. \n
|
||||||
3. This parameter does not affect MPEG Surround processing.
|
3. This parameter will be ignored if the number of encoded
|
||||||
\n
|
|
||||||
4. This parameter will be ignored if the number of encoded
|
|
||||||
audio channels is greater than 8. */
|
audio channels is greater than 8. */
|
||||||
AAC_PCM_MAX_OUTPUT_CHANNELS =
|
AAC_PCM_MAX_OUTPUT_CHANNELS =
|
||||||
0x0012, /*!< Maximum number of PCM output channels. If lower than the
|
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
|
2. If the parameter value is greater than zero but smaller
|
||||||
than ::AAC_PCM_MIN_OUTPUT_CHANNELS both will be set to same
|
than ::AAC_PCM_MIN_OUTPUT_CHANNELS both will be set to same
|
||||||
value. \n
|
value. \n
|
||||||
3. The operating mode of the MPEG Surround module will be
|
3. This parameter will be ignored if the number of encoded
|
||||||
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
|
|
||||||
audio channels is greater than 8. */
|
audio channels is greater than 8. */
|
||||||
AAC_METADATA_PROFILE =
|
AAC_METADATA_PROFILE =
|
||||||
0x0020, /*!< See ::AAC_MD_PROFILE for all available values. */
|
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
|
sequences for fading in and out, if provided in the
|
||||||
bitstream.\n Enabled album mode makes use of dedicated album
|
bitstream.\n Enabled album mode makes use of dedicated album
|
||||||
loudness information, if provided in the bitstream.\n */
|
loudness information, if provided in the bitstream.\n */
|
||||||
AAC_QMF_LOWPOWER = 0x0300, /*!< Quadrature Mirror Filter (QMF) Bank processing
|
AAC_QMF_LOWPOWER =
|
||||||
mode. \n -1: Use internal default. Implies MPEG
|
0x0300, /*!< Quadrature Mirror Filter (QMF) Bank processing mode. \n
|
||||||
Surround partially complex accordingly. \n 0:
|
-1: Use internal default. \n
|
||||||
Use complex QMF data mode. \n 1: Use real (low
|
0: Use complex QMF data mode. \n
|
||||||
power) QMF data mode. \n */
|
1: Use real (low power) QMF data mode. \n */
|
||||||
AAC_TPDEC_CLEAR_BUFFER =
|
AAC_TPDEC_CLEAR_BUFFER =
|
||||||
0x0603 /*!< Clear internal bit stream buffer of transport layers. The
|
0x0603 /*!< Clear internal bit stream buffer of transport layers. The
|
||||||
decoder will start decoding at new data passed after this event
|
decoder will start decoding at new data passed after this event
|
||||||
@ -892,15 +861,25 @@ typedef struct {
|
|||||||
1770. If no level has been found in the bitstream the
|
1770. If no level has been found in the bitstream the
|
||||||
value is -1. */
|
value is -1. */
|
||||||
SCHAR
|
SCHAR
|
||||||
drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154,
|
drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154,
|
||||||
this field indicates whether light (MPEG-4 Dynamic Range
|
this field indicates whether light (MPEG-4 Dynamic Range
|
||||||
Control tool) or heavy compression (DVB heavy
|
Control tool) or heavy compression (DVB heavy
|
||||||
compression) dynamic range control shall take priority
|
compression) dynamic range control shall take priority
|
||||||
on the outputs. For details, see ETSI TS 101 154, table
|
on the outputs. For details, see ETSI TS 101 154, table
|
||||||
C.33. Possible values are: \n -1: No corresponding
|
C.33. Possible values are: \n -1: No corresponding
|
||||||
metadata found in the bitstream \n 0: DRC presentation
|
metadata found in the bitstream \n 0: DRC presentation
|
||||||
mode not indicated \n 1: DRC presentation mode 1 \n 2:
|
mode not indicated \n 1: DRC presentation mode 1 \n 2:
|
||||||
DRC presentation mode 2 \n 3: Reserved */
|
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;
|
} CStreamInfo;
|
||||||
|
|
||||||
@ -1028,21 +1007,24 @@ LINKSPEC_H AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self,
|
|||||||
const UINT bufferSize[],
|
const UINT bufferSize[],
|
||||||
UINT *bytesValid);
|
UINT *bytesValid);
|
||||||
|
|
||||||
#define AACDEC_CONCEAL \
|
/** Flag for aacDecoder_DecodeFrame(): Trigger the built-in error concealment
|
||||||
1 /*!< Flag for aacDecoder_DecodeFrame(): Trigger the built-in error \
|
* module to generate a substitute signal for one lost frame. New input data
|
||||||
concealment module to generate a substitute signal for one lost frame. \
|
* will not be considered.
|
||||||
New input data will not be considered. */
|
*/
|
||||||
#define AACDEC_FLUSH \
|
#define AACDEC_CONCEAL 1
|
||||||
2 /*!< Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all \
|
/** Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all delayed
|
||||||
delayed audio without having new input data. Thus new input data will \
|
* audio without having new input data. Thus new input data will not be
|
||||||
not be considered.*/
|
* considered.
|
||||||
#define AACDEC_INTR \
|
*/
|
||||||
4 /*!< Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data \
|
#define AACDEC_FLUSH 2
|
||||||
discontinuity. Resync any internals as necessary. */
|
/** Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data
|
||||||
#define AACDEC_CLRHIST \
|
* discontinuity. Resync any internals as necessary.
|
||||||
8 /*!< Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and \
|
*/
|
||||||
history buffers. CAUTION: This can cause discontinuities in the output \
|
#define AACDEC_INTR 4
|
||||||
signal. */
|
/** 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
|
* \brief Decode one audio frame
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -113,7 +113,7 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
|
|||||||
|
|
||||||
if (delay > 0) {
|
if (delay > 0) {
|
||||||
data->delay_line =
|
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) {
|
if (data->delay_line == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -126,36 +126,36 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
|
|||||||
return 0;
|
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) {
|
const UINT frame_length, const UCHAR channel) {
|
||||||
FDK_ASSERT(data != NULL);
|
FDK_ASSERT(data != NULL);
|
||||||
|
|
||||||
if (data->delay > 0) {
|
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(frame_length <= MAX_FRAME_LENGTH);
|
||||||
FDK_ASSERT(channel < data->num_channels);
|
FDK_ASSERT(channel < data->num_channels);
|
||||||
FDK_ASSERT(time_buffer != NULL);
|
FDK_ASSERT(time_buffer != NULL);
|
||||||
if (frame_length >= data->delay) {
|
if (frame_length >= data->delay) {
|
||||||
FDKmemcpy(tmp, &time_buffer[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],
|
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],
|
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,
|
FDKmemcpy(&data->delay_line[channel * data->delay], tmp,
|
||||||
data->delay * sizeof(FIXP_PCM));
|
data->delay * sizeof(PCM_DEC));
|
||||||
} else {
|
} 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],
|
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],
|
FDKmemcpy(&data->delay_line[channel * data->delay],
|
||||||
&data->delay_line[channel * data->delay + frame_length],
|
&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 +
|
FDKmemcpy(&data->delay_line[channel * data->delay +
|
||||||
(data->delay - frame_length)],
|
(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;
|
return;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -109,7 +109,7 @@ amm-info@iis.fraunhofer.de
|
|||||||
* Structure representing one delay element for multiple channels.
|
* Structure representing one delay element for multiple channels.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
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). */
|
USHORT delay; /*!< Delay required in samples (per channel). */
|
||||||
UCHAR num_channels; /*!< Number of channels to delay. */
|
UCHAR num_channels; /*!< Number of channels to delay. */
|
||||||
} FDK_SignalDelay;
|
} FDK_SignalDelay;
|
||||||
@ -137,7 +137,7 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
|
|||||||
*
|
*
|
||||||
* \return void
|
* \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);
|
const UINT frame_length, const UCHAR channel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -105,12 +105,7 @@ amm-info@iis.fraunhofer.de
|
|||||||
|
|
||||||
#define WORKBUFFER1_TAG 0
|
#define WORKBUFFER1_TAG 0
|
||||||
#define WORKBUFFER2_TAG 1
|
#define WORKBUFFER2_TAG 1
|
||||||
|
|
||||||
#define WORKBUFFER3_TAG 4
|
|
||||||
#define WORKBUFFER4_TAG 5
|
|
||||||
|
|
||||||
#define WORKBUFFER5_TAG 6
|
#define WORKBUFFER5_TAG 6
|
||||||
|
|
||||||
#define WORKBUFFER6_TAG 7
|
#define WORKBUFFER6_TAG 7
|
||||||
|
|
||||||
/*! The structure AAC_DECODER_INSTANCE is the top level structure holding all
|
/*! 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,
|
C_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL, ((8) * 1024), SECT_DATA_L2,
|
||||||
WORKBUFFER2_TAG)
|
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,
|
C_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR,
|
||||||
fMax((INT)(sizeof(FIXP_DBL) * WB_SECTION_SIZE),
|
fMax((INT)(sizeof(FIXP_DBL) * WB_SECTION_SIZE),
|
||||||
(INT)sizeof(CAacDecoderCommonData)),
|
(INT)sizeof(CAacDecoderCommonData)),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -136,12 +136,7 @@ H_ALLOC_MEM(TimeDataFlush, INT_PCM)
|
|||||||
|
|
||||||
H_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1)
|
H_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1)
|
||||||
H_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL)
|
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(WorkBufferCore5, PCM_DEC)
|
||||||
|
|
||||||
H_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR)
|
H_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR)
|
||||||
|
|
||||||
#endif /* #ifndef AAC_RAM_H */
|
#endif /* #ifndef AAC_RAM_H */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -108,6 +108,7 @@ amm-info@iis.fraunhofer.de
|
|||||||
#include "aacdec_hcr_types.h"
|
#include "aacdec_hcr_types.h"
|
||||||
#include "aacdec_hcrs.h"
|
#include "aacdec_hcrs.h"
|
||||||
|
|
||||||
|
#define PCM_AAC LONG
|
||||||
#define PCM_DEC FIXP_DBL
|
#define PCM_DEC FIXP_DBL
|
||||||
#define MAXVAL_PCM_DEC MAXVAL_DBL
|
#define MAXVAL_PCM_DEC MAXVAL_DBL
|
||||||
#define MINVAL_PCM_DEC MINVAL_DBL
|
#define MINVAL_PCM_DEC MINVAL_DBL
|
||||||
|
@ -149,6 +149,20 @@ static INT convert_drcParam(FIXP_DBL param_dbl) {
|
|||||||
return (INT)param_long;
|
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
|
\brief Initialize DRC information
|
||||||
|
|
||||||
@ -176,7 +190,6 @@ void aacDecoder_drcInit(HANDLE_AAC_DRC self) {
|
|||||||
pParams->usrBoost = FL2FXCONST_DBL(0.0f);
|
pParams->usrBoost = FL2FXCONST_DBL(0.0f);
|
||||||
pParams->targetRefLevel = 96;
|
pParams->targetRefLevel = 96;
|
||||||
pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES;
|
pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES;
|
||||||
pParams->applyDigitalNorm = ON;
|
|
||||||
pParams->applyHeavyCompression = OFF;
|
pParams->applyHeavyCompression = OFF;
|
||||||
pParams->usrApplyHeavyCompression = OFF;
|
pParams->usrApplyHeavyCompression = OFF;
|
||||||
|
|
||||||
@ -192,6 +205,8 @@ void aacDecoder_drcInit(HANDLE_AAC_DRC self) {
|
|||||||
self->progRefLevelPresent = 0;
|
self->progRefLevelPresent = 0;
|
||||||
self->presMode = -1;
|
self->presMode = -1;
|
||||||
self->uniDrcPrecedence = 0;
|
self->uniDrcPrecedence = 0;
|
||||||
|
|
||||||
|
aacDecoder_drcReset(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -258,11 +273,8 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self,
|
|||||||
return AAC_DEC_INVALID_HANDLE;
|
return AAC_DEC_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
self->params.applyDigitalNorm = OFF;
|
|
||||||
self->params.targetRefLevel = -1;
|
self->params.targetRefLevel = -1;
|
||||||
} else {
|
} else {
|
||||||
/* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */
|
|
||||||
self->params.applyDigitalNorm = ON;
|
|
||||||
if (self->params.targetRefLevel != (SCHAR)value) {
|
if (self->params.targetRefLevel != (SCHAR)value) {
|
||||||
self->params.targetRefLevel = (SCHAR)value;
|
self->params.targetRefLevel = (SCHAR)value;
|
||||||
self->progRefLevel = (SCHAR)value; /* Always set the program reference
|
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;
|
self->update = 1;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case APPLY_HEAVY_COMPRESSION:
|
||||||
if ((value != OFF) && (value != ON)) {
|
if ((value != OFF) && (value != ON)) {
|
||||||
return AAC_DEC_SET_PARAM_FAIL;
|
return AAC_DEC_SET_PARAM_FAIL;
|
||||||
@ -910,11 +912,9 @@ void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec,
|
|||||||
FDK_ASSERT(0);
|
FDK_ASSERT(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (self->params.applyDigitalNorm == OFF) {
|
/* Reset normalization gain since this module must not apply it */
|
||||||
/* Reset normalization gain since this module must not apply it */
|
norm_mantissa = FL2FXCONST_DBL(0.5f);
|
||||||
norm_mantissa = FL2FXCONST_DBL(0.5f);
|
norm_exponent = 1;
|
||||||
norm_exponent = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calc scale factors */
|
/* calc scale factors */
|
||||||
for (band = 0; band < numBands; band++) {
|
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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -109,6 +109,11 @@ amm-info@iis.fraunhofer.de
|
|||||||
#include "channel.h"
|
#include "channel.h"
|
||||||
#include "FDK_bitstream.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 \
|
#define AACDEC_DRC_DFLT_EXPIRY_FRAMES \
|
||||||
(0) /* Default DRC data expiry time in AAC frames */
|
(0) /* Default DRC data expiry time in AAC frames */
|
||||||
|
|
||||||
@ -125,7 +130,6 @@ typedef enum {
|
|||||||
TARGET_REF_LEVEL,
|
TARGET_REF_LEVEL,
|
||||||
DRC_BS_DELAY,
|
DRC_BS_DELAY,
|
||||||
DRC_DATA_EXPIRY_FRAME,
|
DRC_DATA_EXPIRY_FRAME,
|
||||||
APPLY_NORMALIZATION,
|
|
||||||
APPLY_HEAVY_COMPRESSION,
|
APPLY_HEAVY_COMPRESSION,
|
||||||
DEFAULT_PRESENTATION_MODE,
|
DEFAULT_PRESENTATION_MODE,
|
||||||
ENCODER_TARGET_LEVEL,
|
ENCODER_TARGET_LEVEL,
|
||||||
@ -136,6 +140,8 @@ typedef enum {
|
|||||||
/**
|
/**
|
||||||
* \brief DRC module interface functions
|
* \brief DRC module interface functions
|
||||||
*/
|
*/
|
||||||
|
void aacDecoder_drcReset(HANDLE_AAC_DRC self);
|
||||||
|
|
||||||
void aacDecoder_drcInit(HANDLE_AAC_DRC self);
|
void aacDecoder_drcInit(HANDLE_AAC_DRC self);
|
||||||
|
|
||||||
void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChannel);
|
void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChannel);
|
||||||
@ -189,4 +195,45 @@ int aacDecoder_drcEpilog(
|
|||||||
void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
|
void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
|
||||||
SCHAR *pProgRefLevel);
|
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 */
|
#endif /* AACDEC_DRC_H */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -168,7 +168,6 @@ typedef struct {
|
|||||||
|
|
||||||
UINT expiryFrame;
|
UINT expiryFrame;
|
||||||
UCHAR bsDelayEnable;
|
UCHAR bsDelayEnable;
|
||||||
UCHAR applyDigitalNorm;
|
|
||||||
|
|
||||||
AACDEC_DRC_PARAMETER_HANDLING defaultPresentationMode;
|
AACDEC_DRC_PARAMETER_HANDLING defaultPresentationMode;
|
||||||
UCHAR encoderTargetLevel;
|
UCHAR encoderTargetLevel;
|
||||||
@ -213,6 +212,13 @@ typedef struct {
|
|||||||
uniDrcPrecedence; /* Flag for signalling that uniDrc is active and takes
|
uniDrcPrecedence; /* Flag for signalling that uniDrc is active and takes
|
||||||
precedence over legacy DRC */
|
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;
|
} CDrcInfo;
|
||||||
|
|
||||||
typedef CDrcInfo *HANDLE_AAC_DRC;
|
typedef CDrcInfo *HANDLE_AAC_DRC;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -137,7 +137,7 @@ static void DeriveNumberOfExtendedSortedSectionsInSets(
|
|||||||
static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
||||||
INT quantSpecCoef, INT *pLeftStartOfSegment,
|
INT quantSpecCoef, INT *pLeftStartOfSegment,
|
||||||
SCHAR *pRemainingBitsInSegment,
|
SCHAR *pRemainingBitsInSegment,
|
||||||
int *pNumDecodedBits);
|
int *pNumDecodedBits, UINT *errorWord);
|
||||||
|
|
||||||
static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
||||||
UINT codebookDim, const SCHAR *pQuantVal,
|
UINT codebookDim, const SCHAR *pQuantVal,
|
||||||
@ -1179,8 +1179,8 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
|
|||||||
bs, pHcr->decInOut.bitstreamAnchor,
|
bs, pHcr->decInOut.bitstreamAnchor,
|
||||||
pQuantizedSpectralCoefficients
|
pQuantizedSpectralCoefficients
|
||||||
[quantizedSpectralCoefficientsIdx],
|
[quantizedSpectralCoefficientsIdx],
|
||||||
pLeftStartOfSegment, pRemainingBitsInSegment,
|
pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits,
|
||||||
&numDecodedBits);
|
&pHcr->decInOut.errorLog);
|
||||||
}
|
}
|
||||||
quantizedSpectralCoefficientsIdx++;
|
quantizedSpectralCoefficientsIdx++;
|
||||||
if (quantizedSpectralCoefficientsIdx >= 1024) {
|
if (quantizedSpectralCoefficientsIdx >= 1024) {
|
||||||
@ -1195,8 +1195,8 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
|
|||||||
bs, pHcr->decInOut.bitstreamAnchor,
|
bs, pHcr->decInOut.bitstreamAnchor,
|
||||||
pQuantizedSpectralCoefficients
|
pQuantizedSpectralCoefficients
|
||||||
[quantizedSpectralCoefficientsIdx],
|
[quantizedSpectralCoefficientsIdx],
|
||||||
pLeftStartOfSegment, pRemainingBitsInSegment,
|
pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits,
|
||||||
&numDecodedBits);
|
&pHcr->decInOut.errorLog);
|
||||||
}
|
}
|
||||||
quantizedSpectralCoefficientsIdx++;
|
quantizedSpectralCoefficientsIdx++;
|
||||||
if (quantizedSpectralCoefficientsIdx >= 1024) {
|
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,
|
static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
||||||
INT quantSpecCoef, INT *pLeftStartOfSegment,
|
INT quantSpecCoef, INT *pLeftStartOfSegment,
|
||||||
SCHAR *pRemainingBitsInSegment,
|
SCHAR *pRemainingBitsInSegment,
|
||||||
int *pNumDecodedBits) {
|
int *pNumDecodedBits, UINT *errorWord) {
|
||||||
UINT i;
|
UINT i;
|
||||||
INT sign;
|
INT sign;
|
||||||
UINT escapeOnesCounter = 0;
|
UINT escapeOnesCounter = 0;
|
||||||
@ -1400,6 +1400,9 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|||||||
FROM_LEFT_TO_RIGHT);
|
FROM_LEFT_TO_RIGHT);
|
||||||
*pRemainingBitsInSegment -= 1;
|
*pRemainingBitsInSegment -= 1;
|
||||||
*pNumDecodedBits += 1;
|
*pNumDecodedBits += 1;
|
||||||
|
if (*pRemainingBitsInSegment < 0) {
|
||||||
|
return Q_VALUE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
if (carryBit != 0) {
|
if (carryBit != 0) {
|
||||||
escapeOnesCounter += 1;
|
escapeOnesCounter += 1;
|
||||||
@ -1416,6 +1419,9 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|||||||
FROM_LEFT_TO_RIGHT);
|
FROM_LEFT_TO_RIGHT);
|
||||||
*pRemainingBitsInSegment -= 1;
|
*pRemainingBitsInSegment -= 1;
|
||||||
*pNumDecodedBits += 1;
|
*pNumDecodedBits += 1;
|
||||||
|
if (*pRemainingBitsInSegment < 0) {
|
||||||
|
return Q_VALUE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
escape_word <<= 1;
|
escape_word <<= 1;
|
||||||
escape_word = escape_word | carryBit;
|
escape_word = escape_word | carryBit;
|
||||||
@ -1423,8 +1429,12 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
|
|||||||
|
|
||||||
sign = (quantSpecCoef >= 0) ? 1 : -1;
|
sign = (quantSpecCoef >= 0) ? 1 : -1;
|
||||||
|
|
||||||
quantSpecCoef = sign * (((INT)1 << escapeOnesCounter) + escape_word);
|
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;
|
return quantSpecCoef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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 */
|
/* count ones and store sum in escapePrefixUp */
|
||||||
if (carryBit == 1) {
|
if (carryBit == 1) {
|
||||||
escapePrefixUp += 1; /* update conter for ones */
|
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 */
|
/* store updated counter in sideinfo of current codeword */
|
||||||
pEscapeSequenceInfo[codewordOffset] &=
|
pEscapeSequenceInfo[codewordOffset] &=
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -1225,6 +1225,8 @@ static void CStreamInfoInit(CStreamInfo *pStreamInfo) {
|
|||||||
pStreamInfo->drcProgRefLev =
|
pStreamInfo->drcProgRefLev =
|
||||||
-1; /* set program reference level to not indicated */
|
-1; /* set program reference level to not indicated */
|
||||||
pStreamInfo->drcPresMode = -1; /* default: presentation mode 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 */
|
/* Set default frame delay */
|
||||||
aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY,
|
aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY,
|
||||||
CConcealment_GetDelay(&self->concealCommonData));
|
CConcealment_GetDelay(&self->concealCommonData));
|
||||||
|
self->workBufferCore1 = (FIXP_DBL *)GetWorkBufferCore1();
|
||||||
|
|
||||||
self->workBufferCore2 = GetWorkBufferCore2();
|
self->workBufferCore2 = GetWorkBufferCore2();
|
||||||
if (self->workBufferCore2 == NULL) goto bail;
|
if (self->workBufferCore2 == NULL) goto bail;
|
||||||
@ -1303,7 +1306,8 @@ static void CAacDecoder_DeInit(HANDLE_AACDECODER self,
|
|||||||
const int subStreamIndex) {
|
const int subStreamIndex) {
|
||||||
int ch;
|
int ch;
|
||||||
int aacChannelOffset = 0, aacChannels = (8);
|
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;
|
if (self == NULL) return;
|
||||||
|
|
||||||
@ -1453,6 +1457,10 @@ LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self) {
|
|||||||
FreeDrcInfo(&self->hDrcInfo);
|
FreeDrcInfo(&self->hDrcInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self->workBufferCore1 != NULL) {
|
||||||
|
FreeWorkBufferCore1((CWorkBufferCore1 **)&self->workBufferCore1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Free WorkBufferCore2 */
|
/* Free WorkBufferCore2 */
|
||||||
if (self->workBufferCore2 != NULL) {
|
if (self->workBufferCore2 != NULL) {
|
||||||
FreeWorkBufferCore2(&self->workBufferCore2);
|
FreeWorkBufferCore2(&self->workBufferCore2);
|
||||||
@ -1490,6 +1498,8 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
|
|||||||
UCHAR downscaleFactor = self->downscaleFactor;
|
UCHAR downscaleFactor = self->downscaleFactor;
|
||||||
UCHAR downscaleFactorInBS = self->downscaleFactorInBS;
|
UCHAR downscaleFactorInBS = self->downscaleFactorInBS;
|
||||||
|
|
||||||
|
self->aacOutDataHeadroom = (3);
|
||||||
|
|
||||||
// set profile and check for supported aot
|
// set profile and check for supported aot
|
||||||
// leave profile on default (=-1) for all other supported MPEG-4 aot's except
|
// leave profile on default (=-1) for all other supported MPEG-4 aot's except
|
||||||
// aot=2 (=AAC-LC)
|
// aot=2 (=AAC-LC)
|
||||||
@ -1847,6 +1857,12 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
|
|||||||
self->streamInfo.extSamplingRate / self->downscaleFactor;
|
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 ------------ */
|
/* --------- vcb11 ------------ */
|
||||||
self->flags[streamIndex] |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0;
|
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->samplingRateInfo[0].samplingRate / self->downscaleFactor;
|
||||||
self->streamInfo.aacSamplesPerFrame =
|
self->streamInfo.aacSamplesPerFrame =
|
||||||
asc->m_samplesPerFrame / self->downscaleFactor;
|
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;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*configChanged) {
|
||||||
|
if (asc->m_aot == AOT_USAC) {
|
||||||
|
self->hDrcInfo->enable = 0;
|
||||||
|
self->hDrcInfo->progRefLevelPresent = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (asc->m_aot == AOT_USAC) {
|
if (asc->m_aot == AOT_USAC) {
|
||||||
pcmLimiter_SetAttack(self->hLimiter, (5));
|
pcmLimiter_SetAttack(self->hLimiter, (5));
|
||||||
pcmLimiter_SetThreshold(self->hLimiter, FL2FXCONST_DBL(0.89125094f));
|
pcmLimiter_SetThreshold(self->hLimiter, FL2FXCONST_DBL(0.89125094f));
|
||||||
@ -2375,7 +2401,7 @@ bail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
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) {
|
const INT timeDataSize, const int timeDataChannelOffset) {
|
||||||
AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
|
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));
|
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
|
/* deactivate legacy DRC in case uniDrc is active, i.e. uniDrc payload is
|
||||||
* present and one of DRC or Loudness Normalization is switched on */
|
* present and one of DRC or Loudness Normalization is switched on */
|
||||||
aacDecoder_drcSetParam(
|
aacDecoder_drcSetParam(
|
||||||
@ -3168,9 +3189,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
|
self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
|
||||||
pce->ElementInstanceTag, drcChMap, aacChannels);
|
pce->ElementInstanceTag, drcChMap, aacChannels);
|
||||||
if (mapped > 0) {
|
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))) {
|
||||||
* data in the bitstream. */
|
/* If at least one DRC thread has been mapped to a channel there was DRC
|
||||||
self->flags[streamIndex] |= AC_DRC_PRESENT;
|
* 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 */
|
/* Create a reverse mapping table */
|
||||||
@ -3300,9 +3327,11 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
&pAacDecoderStaticChannelInfo->drcData);
|
&pAacDecoderStaticChannelInfo->drcData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The DRC module demands to be called with the gain field holding the
|
/* The DRC module demands to be called with the gain field holding the
|
||||||
* gain scale. */
|
* gain scale. */
|
||||||
self->extGain[0] = (FIXP_DBL)TDL_GAIN_SCALING;
|
self->extGain[0] = (FIXP_DBL)AACDEC_DRC_GAIN_SCALING;
|
||||||
|
|
||||||
/* DRC processing */
|
/* DRC processing */
|
||||||
aacDecoder_drcApply(
|
aacDecoder_drcApply(
|
||||||
self->hDrcInfo, self->hSbrDecoder, pAacDecoderChannelInfo,
|
self->hDrcInfo, self->hSbrDecoder, pAacDecoderChannelInfo,
|
||||||
@ -3318,7 +3347,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
if (self->flushStatus && (self->flushCnt > 0) &&
|
if (self->flushStatus && (self->flushCnt > 0) &&
|
||||||
!(flags & AACDEC_CONCEAL)) {
|
!(flags & AACDEC_CONCEAL)) {
|
||||||
FDKmemclear(pTimeData + offset,
|
FDKmemclear(pTimeData + offset,
|
||||||
sizeof(FIXP_PCM) * self->streamInfo.aacSamplesPerFrame);
|
sizeof(PCM_DEC) * self->streamInfo.aacSamplesPerFrame);
|
||||||
} else
|
} else
|
||||||
switch (pAacDecoderChannelInfo->renderMode) {
|
switch (pAacDecoderChannelInfo->renderMode) {
|
||||||
case AACDEC_RENDER_IMDCT:
|
case AACDEC_RENDER_IMDCT:
|
||||||
@ -3330,7 +3359,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
!frameOk_butConceal),
|
!frameOk_butConceal),
|
||||||
pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1
|
pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1
|
||||||
->mdctOutTemp,
|
->mdctOutTemp,
|
||||||
self->elFlags[el], elCh);
|
self->aacOutDataHeadroom, self->elFlags[el], elCh);
|
||||||
|
|
||||||
self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
|
self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
|
||||||
break;
|
break;
|
||||||
@ -3351,7 +3380,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
&self->samplingRateInfo[streamIndex],
|
&self->samplingRateInfo[streamIndex],
|
||||||
(self->frameOK && !(flags & AACDEC_CONCEAL) &&
|
(self->frameOK && !(flags & AACDEC_CONCEAL) &&
|
||||||
!frameOk_butConceal),
|
!frameOk_butConceal),
|
||||||
flags, self->flags[streamIndex]);
|
self->aacOutDataHeadroom, flags, self->flags[streamIndex]);
|
||||||
|
|
||||||
self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
|
self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
|
||||||
break;
|
break;
|
||||||
@ -3363,7 +3392,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
if (!CConceal_TDFading_Applied[c]) {
|
if (!CConceal_TDFading_Applied[c]) {
|
||||||
CConceal_TDFading_Applied[c] = CConcealment_TDFading(
|
CConceal_TDFading_Applied[c] = CConcealment_TDFading(
|
||||||
self->streamInfo.aacSamplesPerFrame,
|
self->streamInfo.aacSamplesPerFrame,
|
||||||
&self->pAacDecoderStaticChannelInfo[c], pTimeData + offset, 0);
|
&self->pAacDecoderStaticChannelInfo[c], self->aacOutDataHeadroom,
|
||||||
|
pTimeData + offset, 0);
|
||||||
if (c + 1 < (8) && c < aacChannels - 1) {
|
if (c + 1 < (8) && c < aacChannels - 1) {
|
||||||
/* update next TDNoise Seed to avoid muting in case of Parametric
|
/* update next TDNoise Seed to avoid muting in case of Parametric
|
||||||
* Stereo */
|
* Stereo */
|
||||||
@ -3385,22 +3415,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
if ((aacChannels == 2) && bsPseudoLr) {
|
if ((aacChannels == 2) && bsPseudoLr) {
|
||||||
int i, offset2;
|
int i, offset2;
|
||||||
const FIXP_SGL invSqrt2 = FL2FXCONST_SGL(0.707106781186547f);
|
const FIXP_SGL invSqrt2 = FL2FXCONST_SGL(0.707106781186547f);
|
||||||
FIXP_PCM *pTD = pTimeData;
|
PCM_DEC *pTD = pTimeData;
|
||||||
|
|
||||||
offset2 = timeDataChannelOffset;
|
offset2 = timeDataChannelOffset;
|
||||||
|
|
||||||
for (i = 0; i < self->streamInfo.aacSamplesPerFrame; i++) {
|
for (i = 0; i < self->streamInfo.aacSamplesPerFrame; i++) {
|
||||||
FIXP_DBL L = FX_PCM2FX_DBL(pTD[0]);
|
FIXP_DBL L = PCM_DEC2FIXP_DBL(pTD[0]);
|
||||||
FIXP_DBL R = FX_PCM2FX_DBL(pTD[offset2]);
|
FIXP_DBL R = PCM_DEC2FIXP_DBL(pTD[offset2]);
|
||||||
L = fMult(L, invSqrt2);
|
L = fMult(L, invSqrt2);
|
||||||
R = fMult(R, invSqrt2);
|
R = fMult(R, invSqrt2);
|
||||||
#if (SAMPLE_BITS == 16)
|
pTD[0] = L + R;
|
||||||
pTD[0] = FX_DBL2FX_PCM(fAddSaturate(L + R, (FIXP_DBL)0x8000));
|
pTD[offset2] = L - R;
|
||||||
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++;
|
pTD++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3411,9 +3436,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
|
self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
|
||||||
pce->ElementInstanceTag, drcChMap, aacChannels);
|
pce->ElementInstanceTag, drcChMap, aacChannels);
|
||||||
if (mapped > 0) {
|
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))) {
|
||||||
* data in the bitstream. */
|
/* If at least one DRC thread has been mapped to a channel there was DRC
|
||||||
self->flags[streamIndex] |= AC_DRC_PRESENT;
|
* 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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -191,6 +191,9 @@ struct AAC_DECODER_INSTANCE {
|
|||||||
INT outputInterleaved; /*!< PCM output format (interleaved/none interleaved).
|
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. */
|
HANDLE_TRANSPORTDEC hInput; /*!< Transport layer handle. */
|
||||||
|
|
||||||
SamplingRateInfo
|
SamplingRateInfo
|
||||||
@ -235,6 +238,7 @@ struct AAC_DECODER_INSTANCE {
|
|||||||
CAacDecoderStaticChannelInfo
|
CAacDecoderStaticChannelInfo
|
||||||
*pAacDecoderStaticChannelInfo[(8)]; /*!< Persistent channel memory */
|
*pAacDecoderStaticChannelInfo[(8)]; /*!< Persistent channel memory */
|
||||||
|
|
||||||
|
FIXP_DBL *workBufferCore1;
|
||||||
FIXP_DBL *workBufferCore2;
|
FIXP_DBL *workBufferCore2;
|
||||||
PCM_DEC *pTimeData2;
|
PCM_DEC *pTimeData2;
|
||||||
INT timeData2Size;
|
INT timeData2Size;
|
||||||
@ -311,11 +315,10 @@ This structure is allocated once for each CPE. */
|
|||||||
UCHAR limiterEnableUser; /*!< The limiter configuration requested by the
|
UCHAR limiterEnableUser; /*!< The limiter configuration requested by the
|
||||||
library user */
|
library user */
|
||||||
UCHAR limiterEnableCurr; /*!< The current limiter configuration. */
|
UCHAR limiterEnableCurr; /*!< The current limiter configuration. */
|
||||||
|
|
||||||
FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */
|
FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */
|
||||||
UINT extGainDelay; /*!< Delay that must be accounted for extGain. */
|
UINT extGainDelay; /*!< Delay that must be accounted for extGain. */
|
||||||
|
|
||||||
INT_PCM pcmOutputBuffer[(8) * (1024 * 2)];
|
|
||||||
|
|
||||||
HANDLE_DRC_DECODER hUniDrcDecoder;
|
HANDLE_DRC_DECODER hUniDrcDecoder;
|
||||||
UCHAR multibandDrcPresent;
|
UCHAR multibandDrcPresent;
|
||||||
UCHAR numTimeSlots;
|
UCHAR numTimeSlots;
|
||||||
@ -427,7 +430,7 @@ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self,
|
|||||||
\return error status
|
\return error status
|
||||||
*/
|
*/
|
||||||
LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
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);
|
const INT timeDataSize, const int timeDataChannelOffset);
|
||||||
|
|
||||||
/* Free config dependent AAC memory */
|
/* Free config dependent AAC memory */
|
||||||
|
@ -119,8 +119,8 @@ amm-info@iis.fraunhofer.de
|
|||||||
|
|
||||||
/* Decoder library info */
|
/* Decoder library info */
|
||||||
#define AACDECODER_LIB_VL0 3
|
#define AACDECODER_LIB_VL0 3
|
||||||
#define AACDECODER_LIB_VL1 1
|
#define AACDECODER_LIB_VL1 2
|
||||||
#define AACDECODER_LIB_VL2 2
|
#define AACDECODER_LIB_VL2 0
|
||||||
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
|
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
|
||||||
#ifdef SUPPRESS_BUILD_DATE_INFO
|
#ifdef SUPPRESS_BUILD_DATE_INFO
|
||||||
#define AACDECODER_LIB_BUILD_DATE ""
|
#define AACDECODER_LIB_BUILD_DATE ""
|
||||||
@ -1131,35 +1131,31 @@ static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
LINKSPEC_CPP AAC_DECODER_ERROR
|
LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
|
||||||
aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
INT_PCM *pTimeData,
|
||||||
const INT timeDataSize_extern, const UINT flags) {
|
const INT timeDataSize,
|
||||||
|
const UINT flags) {
|
||||||
AAC_DECODER_ERROR ErrorStatus;
|
AAC_DECODER_ERROR ErrorStatus;
|
||||||
INT layer;
|
INT layer;
|
||||||
INT nBits;
|
INT nBits;
|
||||||
|
INT timeData2Size;
|
||||||
|
INT timeData3Size;
|
||||||
|
INT timeDataHeadroom;
|
||||||
HANDLE_FDK_BITSTREAM hBs;
|
HANDLE_FDK_BITSTREAM hBs;
|
||||||
int fTpInterruption = 0; /* Transport originated interruption detection. */
|
int fTpInterruption = 0; /* Transport originated interruption detection. */
|
||||||
int fTpConceal = 0; /* Transport originated concealment. */
|
int fTpConceal = 0; /* Transport originated concealment. */
|
||||||
INT_PCM *pTimeData = NULL;
|
|
||||||
INT timeDataSize = 0;
|
|
||||||
UINT accessUnit = 0;
|
UINT accessUnit = 0;
|
||||||
UINT numAccessUnits = 1;
|
UINT numAccessUnits = 1;
|
||||||
UINT numPrerollAU = 0;
|
UINT numPrerollAU = 0;
|
||||||
int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */
|
int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */
|
||||||
int applyCrossfade = 1; /* flag indicates if flushing was possible */
|
int applyCrossfade = 1; /* flag indicates if flushing was possible */
|
||||||
FIXP_PCM *pTimeDataFixpPcm; /* Signal buffer for decoding process before PCM
|
PCM_DEC *pTimeData2;
|
||||||
processing */
|
PCM_AAC *pTimeData3;
|
||||||
INT timeDataFixpPcmSize;
|
|
||||||
PCM_DEC *pTimeDataPcmPost; /* Signal buffer for PCM post-processing */
|
|
||||||
INT timeDataPcmPostSize;
|
|
||||||
|
|
||||||
if (self == NULL) {
|
if (self == NULL) {
|
||||||
return AAC_DEC_INVALID_HANDLE;
|
return AAC_DEC_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pTimeData = self->pcmOutputBuffer;
|
|
||||||
timeDataSize = sizeof(self->pcmOutputBuffer) / sizeof(*self->pcmOutputBuffer);
|
|
||||||
|
|
||||||
if (flags & AACDEC_INTR) {
|
if (flags & AACDEC_INTR) {
|
||||||
self->streamInfo.numLostAccessUnits = 0;
|
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. */
|
/* Signal bit stream interruption to other modules if required. */
|
||||||
if (fTpInterruption || (flags & AACDEC_INTR)) {
|
if (fTpInterruption || ((flags & AACDEC_INTR) && (accessUnit == 0))) {
|
||||||
aacDecoder_SignalInterruption(self);
|
aacDecoder_SignalInterruption(self);
|
||||||
if (!(flags & AACDEC_INTR)) {
|
if (!((flags & AACDEC_INTR) && (accessUnit == 0))) {
|
||||||
ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR;
|
ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
@ -1315,19 +1311,23 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||||||
/* Use limiter configuration as requested. */
|
/* Use limiter configuration as requested. */
|
||||||
self->limiterEnableCurr = self->limiterEnableUser;
|
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;
|
/* reset DRC level normalization gain on a per frame basis */
|
||||||
timeDataFixpPcmSize = timeDataSize;
|
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(
|
ErrorStatus = CAacDecoder_DecodeFrame(
|
||||||
self,
|
self,
|
||||||
flags | (fTpConceal ? AACDEC_CONCEAL : 0) |
|
flags | (fTpConceal ? AACDEC_CONCEAL : 0) |
|
||||||
((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
|
((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
|
||||||
: 0),
|
: 0),
|
||||||
pTimeDataFixpPcm + 0, timeDataFixpPcmSize,
|
pTimeData2 + 0, timeData2Size, self->streamInfo.aacSamplesPerFrame + 0);
|
||||||
self->streamInfo.aacSamplesPerFrame + 0);
|
|
||||||
|
timeDataHeadroom = self->aacOutDataHeadroom;
|
||||||
|
|
||||||
/* if flushing for USAC DASH IPF was not possible go on with decoding
|
/* if flushing for USAC DASH IPF was not possible go on with decoding
|
||||||
* preroll */
|
* 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. */
|
* nothing else we can do, so bail. */
|
||||||
if (!IS_OUTPUT_VALID(ErrorStatus)) {
|
if (!IS_OUTPUT_VALID(ErrorStatus)) {
|
||||||
goto bail;
|
goto bail;
|
||||||
@ -1366,10 +1366,10 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||||||
self->streamInfo.numChannels = self->streamInfo.aacNumChannels;
|
self->streamInfo.numChannels = self->streamInfo.aacNumChannels;
|
||||||
|
|
||||||
{
|
{
|
||||||
FDK_Delay_Apply(&self->usacResidualDelay,
|
FDK_Delay_Apply(
|
||||||
pTimeDataFixpPcm +
|
&self->usacResidualDelay,
|
||||||
1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0,
|
pTimeData2 + 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0,
|
||||||
self->streamInfo.frameSize, 0);
|
self->streamInfo.frameSize, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setting of internal MPS state; may be reset in CAacDecoder_SyncQmfMode
|
/* Setting of internal MPS state; may be reset in CAacDecoder_SyncQmfMode
|
||||||
@ -1416,8 +1416,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self->qmfDomain.globalConf.TDinput = pTimeData;
|
|
||||||
|
|
||||||
switch (FDK_QmfDomain_Configure(&self->qmfDomain)) {
|
switch (FDK_QmfDomain_Configure(&self->qmfDomain)) {
|
||||||
default:
|
default:
|
||||||
case QMF_DOMAIN_INIT_ERROR:
|
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,
|
sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF,
|
||||||
(self->mpsEnableCurr) ? 2 : 0);
|
(self->mpsEnableCurr) ? 2 : 0);
|
||||||
|
|
||||||
INT_PCM *input;
|
PCM_AAC *input;
|
||||||
input = (INT_PCM *)self->workBufferCore2;
|
input = (PCM_AAC *)self->workBufferCore2;
|
||||||
FDKmemcpy(input, pTimeData,
|
FDKmemcpy(input, pTimeData3,
|
||||||
sizeof(INT_PCM) * (self->streamInfo.numChannels) *
|
sizeof(PCM_AAC) * (self->streamInfo.numChannels) *
|
||||||
(self->streamInfo.frameSize));
|
(self->streamInfo.frameSize));
|
||||||
|
|
||||||
/* apply SBR processing */
|
/* apply SBR processing */
|
||||||
sbrError = sbrDecoder_Apply(self->hSbrDecoder, input, pTimeData,
|
sbrError = sbrDecoder_Apply(
|
||||||
timeDataSize, &self->streamInfo.numChannels,
|
self->hSbrDecoder, input, pTimeData3, timeData3Size,
|
||||||
&self->streamInfo.sampleRate,
|
&self->streamInfo.numChannels, &self->streamInfo.sampleRate,
|
||||||
&self->mapDescr, self->chMapIndex,
|
&self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible,
|
||||||
self->frameOK, &self->psPossible);
|
self->aacOutDataHeadroom, &timeDataHeadroom);
|
||||||
|
|
||||||
if (sbrError == SBRDEC_OK) {
|
if (sbrError == SBRDEC_OK) {
|
||||||
/* Update data in streaminfo structure. Assume that the SBR upsampling
|
/* 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) {
|
if (err == 0) {
|
||||||
err = mpegSurroundDecoder_Apply(
|
err = mpegSurroundDecoder_Apply(
|
||||||
(CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
|
(CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
|
||||||
(INT_PCM *)self->workBufferCore2, pTimeData, timeDataSize,
|
(PCM_AAC *)self->workBufferCore2, pTimeData3, timeData3Size,
|
||||||
self->streamInfo.aacSamplesPerFrame, &nChannels, &frameSize,
|
self->streamInfo.aacSamplesPerFrame, &nChannels, &frameSize,
|
||||||
self->streamInfo.sampleRate, self->streamInfo.aot,
|
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) {
|
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;
|
self->streamInfo.frameSize = self->mpsFrameSizeLast;
|
||||||
/* ... and clear output buffer so that potentially corrupted data does
|
/* ... and clear output buffer so that potentially corrupted data does
|
||||||
* not reach the framework. */
|
* not reach the framework. */
|
||||||
FDKmemclear(pTimeData, self->mpsOutChannelsLast *
|
FDKmemclear(pTimeData3, self->mpsOutChannelsLast *
|
||||||
self->mpsFrameSizeLast * sizeof(INT_PCM));
|
self->mpsFrameSizeLast * sizeof(PCM_AAC));
|
||||||
/* Additionally proclaim that this frame had errors during decoding.
|
/* Additionally proclaim that this frame had errors during decoding.
|
||||||
*/
|
*/
|
||||||
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
|
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);
|
sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1);
|
||||||
|
|
||||||
/* apply SBR processing */
|
/* apply SBR processing */
|
||||||
sbrError = sbrDecoder_Apply(self->hSbrDecoder, pTimeData, pTimeData,
|
sbrError = sbrDecoder_Apply(
|
||||||
timeDataSize, &self->streamInfo.numChannels,
|
self->hSbrDecoder, pTimeData3, pTimeData3, timeData3Size,
|
||||||
&self->streamInfo.sampleRate,
|
&self->streamInfo.numChannels, &self->streamInfo.sampleRate,
|
||||||
&self->mapDescr, self->chMapIndex,
|
&self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible,
|
||||||
self->frameOK, &self->psPossible);
|
self->aacOutDataHeadroom, &timeDataHeadroom);
|
||||||
|
|
||||||
if (sbrError == SBRDEC_OK) {
|
if (sbrError == SBRDEC_OK) {
|
||||||
/* Update data in streaminfo structure. Assume that the SBR upsampling
|
/* 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 =
|
if ((INT)PCM_OUT_HEADROOM != timeDataHeadroom) {
|
||||||
self->streamInfo.frameSize * self->streamInfo.numChannels;
|
for (int i = ((self->streamInfo.frameSize *
|
||||||
FDK_ASSERT(timeDataPcmPostSize >= size);
|
self->streamInfo.numChannels) -
|
||||||
for (int i = 0; i < size; i++) {
|
1);
|
||||||
pTimeDataPcmPost[i] =
|
i >= 0; i--) {
|
||||||
(PCM_DEC)FX_PCM2PCM_DEC(pTimeData[i]) >> PCM_OUT_HEADROOM;
|
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) &&
|
if ((self->streamInfo.numChannels > 1) &&
|
||||||
(0 || (self->sbrEnabled) || (self->mpsEnableCurr))) {
|
(0 || (self->sbrEnabled) || (self->mpsEnableCurr))) {
|
||||||
/* interleaving/deinterleaving is performed on upper part of
|
/* interleaving/deinterleaving is performed on upper part of
|
||||||
* pTimeDataPcmPost. Check if this buffer is large enough. */
|
* pTimeData2. Check if this buffer is large enough. */
|
||||||
if (timeDataPcmPostSize <
|
if (timeData2Size < (INT)(2 * self->streamInfo.numChannels *
|
||||||
(INT)(2 * self->streamInfo.numChannels *
|
self->streamInfo.frameSize)) {
|
||||||
self->streamInfo.frameSize * sizeof(PCM_DEC))) {
|
|
||||||
ErrorStatus = AAC_DEC_UNKNOWN;
|
ErrorStatus = AAC_DEC_UNKNOWN;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
needsDeinterleaving = 1;
|
needsDeinterleaving = 1;
|
||||||
drcWorkBuffer =
|
drcWorkBuffer =
|
||||||
(FIXP_DBL *)pTimeDataPcmPost +
|
(FIXP_DBL *)pTimeData2 +
|
||||||
self->streamInfo.numChannels * self->streamInfo.frameSize;
|
self->streamInfo.numChannels * self->streamInfo.frameSize;
|
||||||
FDK_deinterleave(
|
FDK_deinterleave(
|
||||||
pTimeDataPcmPost, drcWorkBuffer, self->streamInfo.numChannels,
|
pTimeData2, drcWorkBuffer, self->streamInfo.numChannels,
|
||||||
self->streamInfo.frameSize, self->streamInfo.frameSize);
|
self->streamInfo.frameSize, self->streamInfo.frameSize);
|
||||||
} else {
|
} else {
|
||||||
drcWorkBuffer = (FIXP_DBL *)pTimeDataPcmPost;
|
drcWorkBuffer = pTimeData2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare Loudness Normalisation gain */
|
/* prepare Loudness Normalisation gain */
|
||||||
@ -1759,16 +1755,51 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||||||
|
|
||||||
if (needsDeinterleaving) {
|
if (needsDeinterleaving) {
|
||||||
FDK_interleave(
|
FDK_interleave(
|
||||||
drcWorkBuffer, pTimeDataPcmPost, self->streamInfo.numChannels,
|
drcWorkBuffer, pTimeData2, self->streamInfo.numChannels,
|
||||||
self->streamInfo.frameSize, self->streamInfo.frameSize);
|
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) {
|
if (self->streamInfo.extAot != AOT_AAC_SLS) {
|
||||||
INT pcmLimiterScale = 0;
|
INT pcmLimiterScale = 0;
|
||||||
|
INT interleaved = 0;
|
||||||
|
interleaved |= (self->sbrEnabled) ? 1 : 0;
|
||||||
|
interleaved |= (self->mpsEnableCurr) ? 1 : 0;
|
||||||
PCMDMX_ERROR dmxErr = PCMDMX_OK;
|
PCMDMX_ERROR dmxErr = PCMDMX_OK;
|
||||||
if (flags & (AACDEC_INTR)) {
|
if ((flags & AACDEC_INTR) && (accessUnit == 0)) {
|
||||||
/* delete data from the past (e.g. mixdown coeficients) */
|
/* delete data from the past (e.g. mixdown coeficients) */
|
||||||
pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
|
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 */
|
/* do PCM post processing */
|
||||||
dmxErr = pcmDmx_ApplyFrame(
|
dmxErr = pcmDmx_ApplyFrame(self->hPcmUtils, pTimeData2, timeData2Size,
|
||||||
self->hPcmUtils, pTimeDataPcmPost, timeDataFixpPcmSize,
|
self->streamInfo.frameSize,
|
||||||
self->streamInfo.frameSize, &self->streamInfo.numChannels,
|
&self->streamInfo.numChannels, interleaved,
|
||||||
interleaved, self->channelType, self->channelIndices,
|
self->channelType, self->channelIndices,
|
||||||
&self->mapDescr,
|
&self->mapDescr, &pcmLimiterScale);
|
||||||
(self->limiterEnableCurr) ? &pcmLimiterScale : NULL);
|
|
||||||
if (dmxErr == PCMDMX_OUTPUT_BUFFER_TOO_SMALL) {
|
if (dmxErr == PCMDMX_OUTPUT_BUFFER_TOO_SMALL) {
|
||||||
ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
|
ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
goto bail;
|
goto bail;
|
||||||
@ -1801,13 +1827,35 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||||||
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
|
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pcmLimiterScale += PCM_OUT_HEADROOM;
|
||||||
|
|
||||||
if (flags & AACDEC_CLRHIST) {
|
if (flags & AACDEC_CLRHIST) {
|
||||||
if (!(self->flags[0] & AC_USAC)) {
|
if (!(self->flags[0] & AC_USAC)) {
|
||||||
|
/* Reset DRC data */
|
||||||
|
aacDecoder_drcReset(self->hDrcInfo);
|
||||||
/* Delete the delayed signal. */
|
/* Delete the delayed signal. */
|
||||||
pcmLimiter_Reset(self->hLimiter);
|
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) {
|
if (self->limiterEnableCurr) {
|
||||||
/* use workBufferCore2 buffer for interleaving */
|
/* use workBufferCore2 buffer for interleaving */
|
||||||
PCM_LIM *pInterleaveBuffer;
|
PCM_LIM *pInterleaveBuffer;
|
||||||
@ -1816,44 +1864,72 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
|
|||||||
/* Set actual signal parameters */
|
/* Set actual signal parameters */
|
||||||
pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels);
|
pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels);
|
||||||
pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate);
|
pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate);
|
||||||
pcmLimiterScale += PCM_OUT_HEADROOM;
|
|
||||||
|
|
||||||
if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
|
if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
|
||||||
(self->mpsEnableCurr)) {
|
(self->mpsEnableCurr)) {
|
||||||
pInterleaveBuffer = (PCM_LIM *)pTimeDataPcmPost;
|
pInterleaveBuffer = (PCM_LIM *)pTimeData2;
|
||||||
} else {
|
} else {
|
||||||
pInterleaveBuffer = (PCM_LIM *)pTimeData;
|
pInterleaveBuffer = (PCM_LIM *)self->workBufferCore2;
|
||||||
|
|
||||||
/* applyLimiter requests for interleaved data */
|
/* applyLimiter requests for interleaved data */
|
||||||
/* Interleave ouput buffer */
|
/* Interleave ouput buffer */
|
||||||
FDK_interleave(pTimeDataPcmPost, pInterleaveBuffer,
|
FDK_interleave(pTimeData2, pInterleaveBuffer,
|
||||||
self->streamInfo.numChannels, blockLength,
|
self->streamInfo.numChannels, blockLength,
|
||||||
self->streamInfo.frameSize);
|
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,
|
pcmLimiter_Apply(self->hLimiter, pInterleaveBuffer, pTimeData,
|
||||||
self->extGain, &pcmLimiterScale, 1,
|
pGainPerSample, pcmLimiterScale,
|
||||||
self->extGainDelay, self->streamInfo.frameSize);
|
self->streamInfo.frameSize);
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Announce the additional limiter output delay */
|
/* Announce the additional limiter output delay */
|
||||||
self->streamInfo.outputDelay += pcmLimiter_GetDelay(self->hLimiter);
|
self->streamInfo.outputDelay += pcmLimiter_GetDelay(self->hLimiter);
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
/* If numChannels = 1 we do not need interleaving. The same applies if
|
||||||
SBR or MPS are used, since their output is interleaved already
|
SBR or MPS are used, since their output is interleaved already
|
||||||
(resampled or not) */
|
(resampled or not) */
|
||||||
if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
|
if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
|
||||||
(self->mpsEnableCurr)) {
|
(self->mpsEnableCurr)) {
|
||||||
scaleValuesSaturate(
|
scaleValuesSaturate(
|
||||||
pTimeData, pTimeDataPcmPost,
|
pTimeData, pTimeData2,
|
||||||
self->streamInfo.frameSize * self->streamInfo.numChannels,
|
self->streamInfo.frameSize * self->streamInfo.numChannels,
|
||||||
PCM_OUT_HEADROOM);
|
pcmLimiterScale);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
scaleValuesSaturate(
|
scaleValuesSaturate(
|
||||||
(INT_PCM *)self->workBufferCore2, pTimeDataPcmPost,
|
(INT_PCM *)self->workBufferCore2, pTimeData2,
|
||||||
self->streamInfo.frameSize * self->streamInfo.numChannels,
|
self->streamInfo.frameSize * self->streamInfo.numChannels,
|
||||||
PCM_OUT_HEADROOM);
|
pcmLimiterScale);
|
||||||
/* Interleave ouput buffer */
|
/* Interleave ouput buffer */
|
||||||
FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData,
|
FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData,
|
||||||
self->streamInfo.numChannels,
|
self->streamInfo.numChannels,
|
||||||
@ -1949,20 +2025,8 @@ bail:
|
|||||||
ErrorStatus = AAC_DEC_UNKNOWN;
|
ErrorStatus = AAC_DEC_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether external output buffer is large enough. */
|
if (!IS_OUTPUT_VALID(ErrorStatus)) {
|
||||||
if (timeDataSize_extern <
|
FDKmemclear(pTimeData, timeDataSize * sizeof(*pTimeData));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrorStatus;
|
return ErrorStatus;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -1015,9 +1015,9 @@ FIXP_DBL get_gain(const FIXP_DBL *x, const FIXP_DBL *y, int n) {
|
|||||||
|
|
||||||
void CBlock_FrequencyToTime(
|
void CBlock_FrequencyToTime(
|
||||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
||||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
|
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
|
||||||
const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1,
|
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;
|
int fr, fl, tl, nSpec;
|
||||||
|
|
||||||
#if defined(FDK_ASSERT_ENABLE)
|
#if defined(FDK_ASSERT_ENABLE)
|
||||||
@ -1213,6 +1213,7 @@ void CBlock_FrequencyToTime(
|
|||||||
bass_pf_1sf_delay(p2_synth, pitch, pit_gain, frameLen,
|
bass_pf_1sf_delay(p2_synth, pitch, pit_gain, frameLen,
|
||||||
(LpdSfd + 2) * L_SUBFR + BPF_SFD * L_SUBFR,
|
(LpdSfd + 2) * L_SUBFR + BPF_SFD * L_SUBFR,
|
||||||
frameLen - (LpdSfd + 4) * L_SUBFR, outSamples,
|
frameLen - (LpdSfd + 4) * L_SUBFR, outSamples,
|
||||||
|
aacOutDataHeadroom,
|
||||||
pAacDecoderStaticChannelInfo->mem_bpf);
|
pAacDecoderStaticChannelInfo->mem_bpf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1236,7 +1237,8 @@ void CBlock_FrequencyToTime(
|
|||||||
? MLT_FLAG_CURR_ALIAS_SYMMETRY
|
? MLT_FLAG_CURR_ALIAS_SYMMETRY
|
||||||
: 0);
|
: 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"
|
#include "ldfiltbank.h"
|
||||||
void CBlock_FrequencyToTimeLowDelay(
|
void CBlock_FrequencyToTimeLowDelay(
|
||||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
||||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
|
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
|
||||||
const short frameLen) {
|
const short frameLen) {
|
||||||
InvMdctTransformLowDelay_fdk(
|
InvMdctTransformLowDelay_fdk(
|
||||||
SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
|
SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -218,16 +218,16 @@ void ApplyTools(CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
|
|||||||
*/
|
*/
|
||||||
void CBlock_FrequencyToTime(
|
void CBlock_FrequencyToTime(
|
||||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
||||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
|
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
|
||||||
const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1,
|
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.
|
* \brief Transform double lapped MDCT (AAC-ELD) spectral data into time domain.
|
||||||
*/
|
*/
|
||||||
void CBlock_FrequencyToTimeLowDelay(
|
void CBlock_FrequencyToTimeLowDelay(
|
||||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
||||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
|
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
|
||||||
const short frameLen);
|
const short frameLen);
|
||||||
|
|
||||||
AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(
|
AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -226,7 +226,7 @@ static void CConcealment_ApplyRandomSign(int iRandomPhase, FIXP_DBL *spec,
|
|||||||
|
|
||||||
/* TimeDomainFading */
|
/* TimeDomainFading */
|
||||||
static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
|
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,
|
static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
|
||||||
int *fadingSteps,
|
int *fadingSteps,
|
||||||
FIXP_DBL fadeStop,
|
FIXP_DBL fadeStop,
|
||||||
@ -242,7 +242,9 @@ static int CConcealment_ApplyFadeOut(
|
|||||||
|
|
||||||
static int CConcealment_TDNoise_Random(ULONG *seed);
|
static int CConcealment_TDNoise_Random(ULONG *seed);
|
||||||
static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
|
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) {
|
static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) {
|
||||||
BLOCK_TYPE newWinSeq = BLOCK_LONG;
|
BLOCK_TYPE newWinSeq = BLOCK_LONG;
|
||||||
@ -1228,7 +1230,6 @@ static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
|
|||||||
int sfb, line = 0;
|
int sfb, line = 0;
|
||||||
int fac_shift;
|
int fac_shift;
|
||||||
int fac_mod;
|
int fac_mod;
|
||||||
FIXP_DBL accu;
|
|
||||||
|
|
||||||
for (sfb = 0; sfb < sfbCnt; sfb++) {
|
for (sfb = 0; sfb < sfbCnt; sfb++) {
|
||||||
fac_shift =
|
fac_shift =
|
||||||
@ -1236,15 +1237,11 @@ static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
|
|||||||
fac_mod = fac_shift & 3;
|
fac_mod = fac_shift & 3;
|
||||||
fac_shift = (fac_shift >> 2) + 1;
|
fac_shift = (fac_shift >> 2) + 1;
|
||||||
fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct);
|
fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct);
|
||||||
|
fac_shift = fMax(fMin(fac_shift, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
|
||||||
|
|
||||||
for (; line < pSfbOffset[sfb + 1]; line++) {
|
for (; line < pSfbOffset[sfb + 1]; line++) {
|
||||||
accu = fMult(*(spectrum + line), facMod4Table[fac_mod]);
|
FIXP_DBL accu = fMult(*(spectrum + line), facMod4Table[fac_mod]);
|
||||||
if (fac_shift < 0) {
|
*(spectrum + line) = scaleValue(accu, fac_shift);
|
||||||
accu >>= -fac_shift;
|
|
||||||
} else {
|
|
||||||
accu <<= fac_shift;
|
|
||||||
}
|
|
||||||
*(spectrum + line) = accu;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct);
|
*pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct);
|
||||||
@ -1618,7 +1615,7 @@ static void CConcealment_ApplyRandomSign(int randomPhase, FIXP_DBL *spec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (packedSign & 0x1) {
|
if (packedSign & 0x1) {
|
||||||
spec[i] = -spec[i];
|
spec[i] = -fMax(spec[i], (FIXP_DBL)(MINVAL_DBL + 1));
|
||||||
}
|
}
|
||||||
packedSign >>= 1;
|
packedSign >>= 1;
|
||||||
|
|
||||||
@ -1849,7 +1846,7 @@ Target fading level is determined by fading index cntFadeFrames.
|
|||||||
|
|
||||||
INT CConcealment_TDFading(
|
INT CConcealment_TDFading(
|
||||||
int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
|
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
|
Do the fading in Time domain based on concealment states and core mode
|
||||||
*/
|
*/
|
||||||
@ -1962,7 +1959,8 @@ INT CConcealment_TDFading(
|
|||||||
start += len;
|
start += len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CConcealment_TDNoise_Apply(pConcealmentInfo, len, pcmdata);
|
CConcealment_TDNoise_Apply(pConcealmentInfo, len, aacOutDataHeadroom,
|
||||||
|
pcmdata);
|
||||||
|
|
||||||
/* Save end-of-frame attenuation and fading type */
|
/* Save end-of-frame attenuation and fading type */
|
||||||
pConcealmentInfo->lastFadingType = fadingType;
|
pConcealmentInfo->lastFadingType = fadingType;
|
||||||
@ -1974,12 +1972,11 @@ INT CConcealment_TDFading(
|
|||||||
|
|
||||||
/* attenuate pcmdata in Time Domain Fading process */
|
/* attenuate pcmdata in Time Domain Fading process */
|
||||||
static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
|
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;
|
int i;
|
||||||
FIXP_DBL dStep;
|
FIXP_DBL dStep;
|
||||||
FIXP_DBL dGain;
|
FIXP_DBL dGain;
|
||||||
FIXP_DBL dGain_apply;
|
FIXP_DBL dGain_apply;
|
||||||
int bitshift = (DFRACT_BITS - SAMPLE_BITS);
|
|
||||||
|
|
||||||
/* set start energy */
|
/* set start energy */
|
||||||
dGain = fadeStart;
|
dGain = fadeStart;
|
||||||
@ -1992,7 +1989,7 @@ static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
|
|||||||
*/
|
*/
|
||||||
dGain_apply = fMax((FIXP_DBL)0, dGain);
|
dGain_apply = fMax((FIXP_DBL)0, dGain);
|
||||||
/* finally, attenuate samples */
|
/* 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,
|
static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
|
||||||
const int len, FIXP_PCM *const pcmdata) {
|
const int len,
|
||||||
FIXP_PCM *states = pConcealmentInfo->TDNoiseStates;
|
const INT aacOutDataHeadroom,
|
||||||
FIXP_PCM noiseVal;
|
PCM_DEC *const pcmdata) {
|
||||||
|
PCM_DEC *states = pConcealmentInfo->TDNoiseStates;
|
||||||
|
PCM_DEC noiseVal;
|
||||||
FIXP_DBL noiseValLong;
|
FIXP_DBL noiseValLong;
|
||||||
FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef;
|
FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef;
|
||||||
FIXP_DBL TDNoiseAtt;
|
FIXP_DBL TDNoiseAtt;
|
||||||
@ -2075,18 +2074,20 @@ static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
|
|||||||
/* create filtered noise */
|
/* create filtered noise */
|
||||||
states[2] = states[1];
|
states[2] = states[1];
|
||||||
states[1] = states[0];
|
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]) +
|
noiseValLong = fMult(states[0], coef[0]) + fMult(states[1], coef[1]) +
|
||||||
fMult(states[2], coef[2]);
|
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 */
|
/* add filtered noise - check for clipping, before */
|
||||||
if (noiseVal > (FIXP_PCM)0 &&
|
if (noiseVal > (PCM_DEC)0 &&
|
||||||
pcmdata[ii] > (FIXP_PCM)MAXVAL_FIXP_PCM - noiseVal) {
|
pcmdata[ii] > (PCM_DEC)MAXVAL_PCM_DEC - noiseVal) {
|
||||||
noiseVal = noiseVal * (FIXP_PCM)-1;
|
noiseVal = noiseVal * (PCM_DEC)-1;
|
||||||
} else if (noiseVal < (FIXP_PCM)0 &&
|
} else if (noiseVal < (PCM_DEC)0 &&
|
||||||
pcmdata[ii] < (FIXP_PCM)MINVAL_FIXP_PCM - noiseVal) {
|
pcmdata[ii] < (PCM_DEC)MINVAL_PCM_DEC - noiseVal) {
|
||||||
noiseVal = noiseVal * (FIXP_PCM)-1;
|
noiseVal = noiseVal * (PCM_DEC)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcmdata[ii] += noiseVal;
|
pcmdata[ii] += noiseVal;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -147,6 +147,6 @@ int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo,
|
|||||||
|
|
||||||
INT CConcealment_TDFading(
|
INT CConcealment_TDFading(
|
||||||
int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
|
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 */
|
#endif /* #ifndef CONCEAL_H */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -194,7 +194,7 @@ typedef struct {
|
|||||||
FIXP_DBL last_tcx_gain;
|
FIXP_DBL last_tcx_gain;
|
||||||
INT last_tcx_gain_e;
|
INT last_tcx_gain_e;
|
||||||
ULONG TDNoiseSeed;
|
ULONG TDNoiseSeed;
|
||||||
FIXP_PCM TDNoiseStates[3];
|
PCM_DEC TDNoiseStates[3];
|
||||||
FIXP_SGL TDNoiseCoef[3];
|
FIXP_SGL TDNoiseCoef[3];
|
||||||
FIXP_SGL TDNoiseAtt;
|
FIXP_SGL TDNoiseAtt;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -112,17 +112,20 @@ amm-info@iis.fraunhofer.de
|
|||||||
#if defined(__arm__)
|
#if defined(__arm__)
|
||||||
#endif
|
#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) {
|
FIXP_DBL *z, const int N) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* scale for FIXP_DBL -> INT_PCM conversion. */
|
/* scale for FIXP_DBL -> PCM_DEC conversion: */
|
||||||
const int scale = (DFRACT_BITS - SAMPLE_BITS) - LDFB_HEADROOM;
|
const int scale = (DFRACT_BITS - PCM_OUT_BITS) - LDFB_HEADROOM + (3);
|
||||||
#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
|
|
||||||
|
#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0)
|
||||||
FIXP_DBL rnd_val_wts0 = (FIXP_DBL)0;
|
FIXP_DBL rnd_val_wts0 = (FIXP_DBL)0;
|
||||||
FIXP_DBL rnd_val_wts1 = (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)
|
if (-WTS0 - 1 + scale)
|
||||||
rnd_val_wts0 = (FIXP_DBL)(1 << (-WTS0 - 1 + scale - 1));
|
rnd_val_wts0 = (FIXP_DBL)(1 << (-WTS0 - 1 + scale - 1));
|
||||||
|
#endif
|
||||||
if (-WTS1 - 1 + scale)
|
if (-WTS1 - 1 + scale)
|
||||||
rnd_val_wts1 = (FIXP_DBL)(1 << (-WTS1 - 1 + scale - 1));
|
rnd_val_wts1 = (FIXP_DBL)(1 << (-WTS1 - 1 + scale - 1));
|
||||||
#endif
|
#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;
|
FIXP_DBL z0, z2, tmp;
|
||||||
|
|
||||||
z2 = x[N / 2 + i];
|
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] +
|
z[N / 2 + i] = fAddSaturate(
|
||||||
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1));
|
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]) +
|
tmp = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) +
|
||||||
fMultDiv2(z[i], fb[N + N / 2 + 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((-WTS1 - 1 + scale) >= 0);
|
||||||
FDK_ASSERT(tmp <= ((FIXP_DBL)0x7FFFFFFF -
|
FDK_ASSERT(tmp <= ((FIXP_DBL)0x7FFFFFFF -
|
||||||
rnd_val_wts1)); /* rounding must not cause overflow */
|
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);
|
tmp + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS);
|
||||||
#else
|
#else
|
||||||
FDK_ASSERT((WTS1 + 1 - scale) >= 0);
|
FDK_ASSERT((WTS1 + 1 - scale) >= 0);
|
||||||
output[(N * 3 / 4 - 1 - i)] =
|
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
|
#endif
|
||||||
|
|
||||||
z[i] = z0;
|
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;
|
FIXP_DBL z0, z2, tmp0, tmp1;
|
||||||
|
|
||||||
z2 = x[N / 2 + i];
|
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] +
|
z[N / 2 + i] = fAddSaturate(
|
||||||
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1));
|
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]) +
|
tmp0 = (fMultDiv2(z[N / 2 + i], fb[N / 2 - 1 - i]) +
|
||||||
fMultDiv2(z[i], fb[N / 2 + i]));
|
fMultDiv2(z[i], fb[N / 2 + i]));
|
||||||
tmp1 = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) +
|
tmp1 = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) +
|
||||||
fMultDiv2(z[i], fb[N + N / 2 + 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((-WTS0 - 1 + scale) >= 0);
|
||||||
FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF -
|
FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF -
|
||||||
rnd_val_wts0)); /* rounding must not cause overflow */
|
rnd_val_wts0)); /* rounding must not cause overflow */
|
||||||
FDK_ASSERT(tmp1 <= ((FIXP_DBL)0x7FFFFFFF -
|
FDK_ASSERT(tmp1 <= ((FIXP_DBL)0x7FFFFFFF -
|
||||||
rnd_val_wts1)); /* rounding must not cause overflow */
|
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);
|
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);
|
tmp1 + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS);
|
||||||
#else
|
#else
|
||||||
FDK_ASSERT((WTS0 + 1 - scale) >= 0);
|
FDK_ASSERT((WTS0 + 1 - scale) >= 0);
|
||||||
output[(i - N / 4)] =
|
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)] =
|
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
|
#endif
|
||||||
z[i] = z0;
|
z[i] = z0;
|
||||||
z[N + i] = z2;
|
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++) {
|
for (i = 0; i < N / 4; i++) {
|
||||||
FIXP_DBL tmp0 = fMultDiv2(z[i], fb[N / 2 + 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((-WTS0 - 1 + scale) >= 0);
|
||||||
FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF -
|
FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF -
|
||||||
rnd_val_wts0)); /* rounding must not cause overflow */
|
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);
|
tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS);
|
||||||
#else
|
#else
|
||||||
FDK_ASSERT((WTS0 + 1 - scale) >= 0);
|
FDK_ASSERT((WTS0 + 1 - scale) >= 0);
|
||||||
output[(N * 3 / 4 + i)] =
|
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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctData, const int mdctData_e,
|
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 int N) {
|
||||||
const FIXP_WTB *coef;
|
const FIXP_WTB *coef;
|
||||||
FIXP_DBL gain = (FIXP_DBL)0;
|
FIXP_DBL gain = (FIXP_DBL)0;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -104,9 +104,10 @@ amm-info@iis.fraunhofer.de
|
|||||||
#define LDFILTBANK_H
|
#define LDFILTBANK_H
|
||||||
|
|
||||||
#include "common_fix.h"
|
#include "common_fix.h"
|
||||||
|
#include "aac_rom.h"
|
||||||
|
|
||||||
int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctdata_m, const int mdctdata_e,
|
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);
|
const int frameLength);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -807,19 +807,17 @@ void CJointStereo_ApplyMS(
|
|||||||
for (int i = 0; i < windowLen; i++) {
|
for (int i = 0; i < windowLen; i++) {
|
||||||
dmx_re_prev[i] =
|
dmx_re_prev[i] =
|
||||||
((staticSpectralCoeffsL[index_offset + i] >>
|
((staticSpectralCoeffsL[index_offset + i] >>
|
||||||
srLeftChan) +
|
fMin(DFRACT_BITS - 1, srLeftChan + 1)) +
|
||||||
(staticSpectralCoeffsR[index_offset + i] >>
|
(staticSpectralCoeffsR[index_offset + i] >>
|
||||||
srRightChan)) >>
|
fMin(DFRACT_BITS - 1, srRightChan + 1)));
|
||||||
1;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < windowLen; i++) {
|
for (int i = 0; i < windowLen; i++) {
|
||||||
dmx_re_prev[i] =
|
dmx_re_prev[i] =
|
||||||
((staticSpectralCoeffsL[index_offset + i] >>
|
((staticSpectralCoeffsL[index_offset + i] >>
|
||||||
srLeftChan) -
|
fMin(DFRACT_BITS - 1, srLeftChan + 1)) -
|
||||||
(staticSpectralCoeffsR[index_offset + i] >>
|
(staticSpectralCoeffsR[index_offset + i] >>
|
||||||
srRightChan)) >>
|
fMin(DFRACT_BITS - 1, srRightChan + 1)));
|
||||||
1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -854,12 +852,13 @@ void CJointStereo_ApplyMS(
|
|||||||
if (window == 0) {
|
if (window == 0) {
|
||||||
if (dmx_re_prev_e < frameMaxScale) {
|
if (dmx_re_prev_e < frameMaxScale) {
|
||||||
if (mainband_flag == 0) {
|
if (mainband_flag == 0) {
|
||||||
scaleValues(dmx_re_prev, store_dmx_re_prev, windowLen,
|
scaleValues(
|
||||||
-(frameMaxScale - dmx_re_prev_e));
|
dmx_re_prev, store_dmx_re_prev, windowLen,
|
||||||
|
-fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e)));
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < windowLen; i++) {
|
scaleValues(
|
||||||
dmx_re_prev[i] >>= (frameMaxScale - dmx_re_prev_e);
|
dmx_re_prev, windowLen,
|
||||||
}
|
-fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mainband_flag == 0) {
|
if (mainband_flag == 0) {
|
||||||
@ -873,10 +872,9 @@ void CJointStereo_ApplyMS(
|
|||||||
FDK_ASSERT(pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
|
FDK_ASSERT(pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
|
||||||
BLOCK_SHORT);
|
BLOCK_SHORT);
|
||||||
if (specScaleL[window - 1] < frameMaxScale) {
|
if (specScaleL[window - 1] < frameMaxScale) {
|
||||||
for (int i = 0; i < windowLen; i++) {
|
scaleValues(&dmx_re[windowLen * (window - 1)], windowLen,
|
||||||
dmx_re[windowLen * (window - 1) + i] >>=
|
-fMin(DFRACT_BITS - 1,
|
||||||
(frameMaxScale - specScaleL[window - 1]);
|
(frameMaxScale - specScaleL[window - 1])));
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
specScaleL[window] = specScaleL[window - 1];
|
specScaleL[window] = specScaleL[window - 1];
|
||||||
specScaleR[window] = specScaleR[window - 1];
|
specScaleR[window] = specScaleR[window - 1];
|
||||||
@ -991,7 +989,7 @@ void CJointStereo_ApplyMS(
|
|||||||
} /* if ( pJointStereoData->complex_coef == 1 ) */
|
} /* if ( pJointStereoData->complex_coef == 1 ) */
|
||||||
|
|
||||||
/* 4. upmix process */
|
/* 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 */
|
/* 0.1 in Q-3.34 */
|
||||||
const FIXP_DBL pointOne = 0x66666666; /* 0.8 */
|
const FIXP_DBL pointOne = 0x66666666; /* 0.8 */
|
||||||
/* Shift value for the downmix */
|
/* Shift value for the downmix */
|
||||||
@ -1041,34 +1039,24 @@ void CJointStereo_ApplyMS(
|
|||||||
the downmix. "dmx_re" and "specL" are two different pointers
|
the downmix. "dmx_re" and "specL" are two different pointers
|
||||||
pointing to separate arrays, which may or may not contain the
|
pointing to separate arrays, which may or may not contain the
|
||||||
same data (with different scaling).
|
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] */
|
side = fMultAddDiv2(fMultDiv2(alpha_re_tmp, *p2dmxRe++),
|
||||||
FIXP_DBL help1 = 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] */
|
left = ((*p2CoeffL) >> 2) + side;
|
||||||
FIXP_DBL tmp = (*p2dmxIm++) << shift_dmx;
|
right = ((*p2CoeffL) >> 2) - side;
|
||||||
|
right = (FIXP_DBL)((LONG)right * pred_dir);
|
||||||
|
|
||||||
/* help2: alpha_im[i] * dmx_im[i] */
|
*p2CoeffL++ = SATURATE_LEFT_SHIFT_ALT(left, 2, DFRACT_BITS);
|
||||||
FIXP_DBL help2 = fMultDiv2(alpha_im_tmp, tmp);
|
*p2CoeffR++ = SATURATE_LEFT_SHIFT_ALT(right, 2, DFRACT_BITS);
|
||||||
|
|
||||||
/* 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++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -131,7 +131,7 @@ void E_UTIL_preemph(const FIXP_DBL *in, FIXP_DBL *out, INT L) {
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < L; 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;
|
return;
|
||||||
@ -465,7 +465,9 @@ void BuildAdaptiveExcitation(
|
|||||||
/* Note: code[L_SUBFR] and exc2[L_SUBFR] share the same memory!
|
/* Note: code[L_SUBFR] and exc2[L_SUBFR] share the same memory!
|
||||||
If exc2[i] is written, code[i] will be destroyed!
|
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;
|
int i;
|
||||||
FIXP_DBL tmp, cpe, code_smooth_prev, code_smooth;
|
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);
|
cpe = (period_fac >> (2 - SF_PFAC)) + FL2FXCONST_DBL(0.25f);
|
||||||
|
|
||||||
/* u'(n) */
|
/* u'(n) */
|
||||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1); /* v(0)*g_p */
|
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1); /* v(0)*g_p */
|
||||||
*exc++ = tmp + (fMultDiv2(code[0], gain_code) << SF);
|
*exc++ = (tmp + (fMultDiv2(code[0], gain_code) << SF)) << SF_HEADROOM;
|
||||||
|
|
||||||
/* u(n) */
|
/* u(n) */
|
||||||
code_smooth_prev = fMultDiv2(*code++, gain_code_smoothed)
|
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 */
|
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 */
|
tmp += code_smooth_prev; /* tmp = v(0)*g_p + c(0)*g_sc */
|
||||||
cpe_code_smooth = fMultDiv2(cpe, code_smooth);
|
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);
|
cpe_code_smooth_prev = fMultDiv2(cpe, code_smooth_prev);
|
||||||
|
|
||||||
i = L_SUBFR - 2;
|
i = L_SUBFR - 2;
|
||||||
do /* ARM926: 22 cycles per iteration */
|
do /* ARM926: 22 cycles per iteration */
|
||||||
{
|
{
|
||||||
/* u'(n) */
|
/* u'(n) */
|
||||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
|
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1);
|
||||||
*exc++ = tmp + (fMultDiv2(code_i, gain_code) << SF);
|
*exc++ = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;
|
||||||
/* u(n) */
|
/* u(n) */
|
||||||
tmp += code_smooth; /* += g_sc * c(i) */
|
tmp += code_smooth; /* += g_sc * c(i) */
|
||||||
tmp -= cpe_code_smooth_prev;
|
tmp -= cpe_code_smooth_prev;
|
||||||
@ -503,16 +505,17 @@ void BuildAdaptiveExcitation(
|
|||||||
code_i = *code++;
|
code_i = *code++;
|
||||||
code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF;
|
code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF;
|
||||||
cpe_code_smooth = fMultDiv2(cpe, code_smooth);
|
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);
|
} while (--i != 0);
|
||||||
|
|
||||||
/* u'(n) */
|
/* u'(n) */
|
||||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
|
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1);
|
||||||
*exc = tmp + (fMultDiv2(code_i, gain_code) << SF);
|
*exc = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;
|
||||||
/* u(n) */
|
/* u(n) */
|
||||||
tmp += code_smooth;
|
tmp += code_smooth;
|
||||||
tmp -= cpe_code_smooth_prev;
|
tmp -= cpe_code_smooth_prev;
|
||||||
*exc2++ = tmp;
|
*exc2++ = tmp << SF_HEADROOM;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -344,7 +344,7 @@ INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac,
|
|||||||
/* Overlap Add */
|
/* Overlap Add */
|
||||||
x0 = -fMult(*pOvl--, pWindow[i].v.re);
|
x0 = -fMult(*pOvl--, pWindow[i].v.re);
|
||||||
|
|
||||||
*pOut0 += IMDCT_SCALE_DBL(x0);
|
*pOut0 = fAddSaturate(*pOut0, IMDCT_SCALE_DBL(x0));
|
||||||
pOut0++;
|
pOut0++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -354,7 +354,7 @@ INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac,
|
|||||||
/* Overlap Add */
|
/* Overlap Add */
|
||||||
x0 = fMult(*pOvl--, pWindow[i].v.re);
|
x0 = fMult(*pOvl--, pWindow[i].v.re);
|
||||||
|
|
||||||
*pOut0 += IMDCT_SCALE_DBL(x0);
|
*pOut0 = fAddSaturate(*pOut0, IMDCT_SCALE_DBL(x0));
|
||||||
pOut0++;
|
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 */
|
0) { /* this should only happen for ACELP -> TCX20 -> ACELP transition */
|
||||||
FIXP_DBL *pOut = pOut0 - fl / 2; /* fl/2 == fac_length */
|
FIXP_DBL *pOut = pOut0 - fl / 2; /* fl/2 == fac_length */
|
||||||
for (i = 0; i < fl / 2; i++) {
|
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;
|
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 */
|
/* Div2 is compensated by table scaling */
|
||||||
x = fMultDiv2(pTmp2[i], FacWindowZir[w]);
|
x = fMultDiv2(pTmp2[i], FacWindowZir[w]);
|
||||||
x += fMultDiv2(pTmp1[-i - 1], FacWindowSynth[w]);
|
x += fMultDiv2(pTmp1[-i - 1], FacWindowSynth[w]);
|
||||||
x += pFAC_and_FAC_ZIR[i];
|
pOut1[i] = fAddSaturate(x, pFAC_and_FAC_ZIR[i]);
|
||||||
pOut1[i] = x;
|
|
||||||
|
|
||||||
w++;
|
w++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -552,7 +550,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
|
|||||||
FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
|
FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
|
||||||
pOut1 < hMdct->overlap.time + hMdct->ov_size) ||
|
pOut1 < hMdct->overlap.time + hMdct->ov_size) ||
|
||||||
(pOut1 >= output && pOut1 < output + 1024));
|
(pOut1 >= output && pOut1 < output + 1024));
|
||||||
*pOut1 += IMDCT_SCALE_DBL(-x1);
|
*pOut1 = fAddSaturate(*pOut1, IMDCT_SCALE_DBL(-x1));
|
||||||
pOut1--;
|
pOut1--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,7 +576,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
|
|||||||
FIXP_DBL x = -(*pCurr--);
|
FIXP_DBL x = -(*pCurr--);
|
||||||
/* 5) (item 4) Synthesis filter Zir component, FAC ZIR (another one). */
|
/* 5) (item 4) Synthesis filter Zir component, FAC ZIR (another one). */
|
||||||
if (i < f_len) {
|
if (i < f_len) {
|
||||||
x += *pF++;
|
x = fAddSaturate(x, *pF++);
|
||||||
}
|
}
|
||||||
|
|
||||||
FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
|
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++) {
|
for (i = 0; i < fl / 2; i++) {
|
||||||
FIXP_DBL x0, x1;
|
FIXP_DBL x0, x1;
|
||||||
|
|
||||||
cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
|
cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
|
||||||
*pOut0 = IMDCT_SCALE_DBL(x0);
|
*pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
|
||||||
*pOut1 = IMDCT_SCALE_DBL(-x1);
|
*pOut1 = IMDCT_SCALE_DBL_LSH1(-x1);
|
||||||
pOut0++;
|
pOut0++;
|
||||||
pOut1--;
|
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++) {
|
for (i = 0; i < fl / 2; i++) {
|
||||||
FIXP_DBL x0, x1;
|
FIXP_DBL x0, x1;
|
||||||
|
|
||||||
cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
|
cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
|
||||||
*pOut0 = IMDCT_SCALE_DBL(x0);
|
*pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
|
||||||
*pOut1 = IMDCT_SCALE_DBL(x1);
|
*pOut1 = IMDCT_SCALE_DBL_LSH1(x1);
|
||||||
pOut0++;
|
pOut0++;
|
||||||
pOut1--;
|
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++) {
|
for (i = 0; i < fl / 2; i++) {
|
||||||
FIXP_DBL x0, x1;
|
FIXP_DBL x0, x1;
|
||||||
|
|
||||||
cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow_prev[i]);
|
cplxMultDiv2(&x1, &x0, *pCurr++, *pOvl--, pWindow_prev[i]);
|
||||||
*pOut0 = IMDCT_SCALE_DBL(x0);
|
*pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
|
||||||
*pOut1 = IMDCT_SCALE_DBL(x1);
|
*pOut1 = IMDCT_SCALE_DBL_LSH1(x1);
|
||||||
pOut0++;
|
pOut0++;
|
||||||
pOut1--;
|
pOut1--;
|
||||||
}
|
}
|
||||||
@ -705,7 +703,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
|
|||||||
FIXP_DBL *pOut = pOut0 - fl / 2;
|
FIXP_DBL *pOut = pOut0 - fl / 2;
|
||||||
FDK_ASSERT(fl / 2 <= 128);
|
FDK_ASSERT(fl / 2 <= 128);
|
||||||
for (i = 0; i < fl / 2; i++) {
|
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;
|
hMdct->pFacZir = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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) {
|
void RE8_PPV(FIXP_ZF x[], SHORT y[], int r) {
|
||||||
int i, y0[8], y1[8];
|
int i, y0[8], y1[8];
|
||||||
FIXP_ZF x1[8], tmp;
|
FIXP_ZF x1[8], tmp;
|
||||||
FIXP_DBL e;
|
INT64 e;
|
||||||
|
|
||||||
/* find the nearest neighbor y0 of x in 2D8 */
|
/* find the nearest neighbor y0 of x in 2D8 */
|
||||||
nearest_neighbor_2D8(x, y0);
|
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 */
|
/* compute e0=||x-y0||^2 and e1=||x-y1||^2 */
|
||||||
e = (FIXP_DBL)0;
|
e = 0;
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
tmp = x[i] - INT2ZF(y0[i], 0);
|
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 << r); /* shift left to ensure that no fract part bits get lost. */
|
||||||
tmp = x[i] - INT2ZF(y1[i], 0);
|
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 */
|
/* select best candidate y0 or y1 to minimize distortion */
|
||||||
if (e < (FIXP_DBL)0) {
|
if (e < 0) {
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
y[i] = y0[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 */
|
/* add non-weighted residual LSF vector to LSF1st */
|
||||||
for (i = 0; i < M_LP_FILTER_ORDER; i++) {
|
for (i = 0; i < M_LP_FILTER_ORDER; i++) {
|
||||||
w = (LONG)fMultDiv2(factor, sqrtFixp(fMult(d[i], d[i + 1])));
|
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;
|
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++) {
|
for (i = 2; i <= n; i++) {
|
||||||
plsp += 2;
|
plsp += 2;
|
||||||
b = -FX_LPC2FX_DBL(*plsp);
|
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--) {
|
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));
|
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) *
|
* 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--) {
|
for (i = NC; i > 0; i--) {
|
||||||
f1[i] += f1[i - 1];
|
f1[i] += f1[i - 1];
|
||||||
f2[i] -= f2[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];
|
FIXP_DBL aDBL[M_LP_FILTER_ORDER];
|
||||||
|
|
||||||
for (i = 1, k = M_LP_FILTER_ORDER - 1; i <= NC; i++, k--) {
|
for (i = 1, k = M_LP_FILTER_ORDER - 1; i <= NC; i++, k--) {
|
||||||
FIXP_DBL tmp1, tmp2;
|
aDBL[i - 1] = f1[i] + f2[i];
|
||||||
|
aDBL[k] = f1[i] - f2[i];
|
||||||
tmp1 = f1[i] >> 1;
|
|
||||||
tmp2 = f2[i] >> 1;
|
|
||||||
|
|
||||||
aDBL[i - 1] = (tmp1 + tmp2);
|
|
||||||
aDBL[k] = (tmp1 - tmp2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int headroom_a = getScalefactor(aDBL, M_LP_FILTER_ORDER);
|
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[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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -122,17 +122,21 @@ amm-info@iis.fraunhofer.de
|
|||||||
|
|
||||||
#include "ac_arith_coder.h"
|
#include "ac_arith_coder.h"
|
||||||
|
|
||||||
void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
|
void filtLP(const FIXP_DBL *syn, PCM_DEC *syn_out, FIXP_DBL *noise,
|
||||||
const FIXP_SGL *filt, INT stop, int len) {
|
const FIXP_SGL *filt, const INT aacOutDataHeadroom, INT stop,
|
||||||
|
int len) {
|
||||||
INT i, j;
|
INT i, j;
|
||||||
FIXP_DBL tmp;
|
FIXP_DBL tmp;
|
||||||
|
|
||||||
|
FDK_ASSERT((aacOutDataHeadroom - 1) >= -(MDCT_OUTPUT_SCALE));
|
||||||
|
|
||||||
for (i = 0; i < stop; i++) {
|
for (i = 0; i < stop; i++) {
|
||||||
tmp = fMultDiv2(noise[i], filt[0]); // Filt in Q-1.16
|
tmp = fMultDiv2(noise[i], filt[0]); // Filt in Q-1.16
|
||||||
for (j = 1; j <= len; j++) {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,8 +146,10 @@ void bass_pf_1sf_delay(
|
|||||||
FIXP_DBL *pit_gain,
|
FIXP_DBL *pit_gain,
|
||||||
const int frame_length, /* (i) : frame length (should be 768|1024) */
|
const int frame_length, /* (i) : frame length (should be 768|1024) */
|
||||||
const INT l_frame,
|
const INT l_frame,
|
||||||
const INT l_next, /* (i) : look ahead for symmetric filtering */
|
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] */
|
FIXP_DBL mem_bpf[]) /* i/o : memory state [L_FILT+L_SUBFR] */
|
||||||
{
|
{
|
||||||
INT i, sf, i_subfr, T, T2, lg;
|
INT i, sf, i_subfr, T, T2, lg;
|
||||||
@ -335,17 +341,22 @@ void bass_pf_1sf_delay(
|
|||||||
|
|
||||||
{
|
{
|
||||||
for (i = 0; i < lg; i++) {
|
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] =
|
noise_in[i] =
|
||||||
(fMult(gainSGL, syn[i + i_subfr] - (syn[i + i_subfr - T] >> 1) -
|
scaleValue(fMultDiv2(gainSGL, (syn[i + i_subfr] >> 1) -
|
||||||
(syn[i + i_subfr + T] >> 1))) >>
|
(syn[i + i_subfr - T] >> 2) -
|
||||||
s1;
|
(syn[i + i_subfr + T] >> 2)),
|
||||||
|
2 - s1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = lg; i < L_SUBFR; i++) {
|
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] =
|
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 {
|
} else {
|
||||||
@ -364,7 +375,7 @@ void bass_pf_1sf_delay(
|
|||||||
|
|
||||||
{
|
{
|
||||||
filtLP(&syn[i_subfr - L_SUBFR], &synth_out[i_subfr], noise,
|
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 */
|
/* Output scaling of the BPF memory */
|
||||||
scaleValues(mem_bpf, (L_FILT + L_SUBFR), -1);
|
scaleValues(mem_bpf, (L_FILT + L_SUBFR), -1);
|
||||||
/* Copy the rest of the signal (after the fac) */
|
/* Copy the rest of the signal (after the fac) */
|
||||||
scaleValuesSaturate((FIXP_PCM *)&synth_out[l_frame],
|
scaleValuesSaturate(
|
||||||
(FIXP_DBL *)&syn[l_frame - L_SUBFR],
|
(PCM_DEC *)&synth_out[l_frame], (FIXP_DBL *)&syn[l_frame - L_SUBFR],
|
||||||
(frame_length - l_frame), MDCT_OUT_HEADROOM);
|
(frame_length - l_frame), MDCT_OUT_HEADROOM - aacOutDataHeadroom);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -1222,7 +1233,7 @@ AAC_DECODER_ERROR CLpdChannelStream_Read(
|
|||||||
(INT)(samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
|
(INT)(samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
|
||||||
(INT)PIT_MIN_12k8;
|
(INT)PIT_MIN_12k8;
|
||||||
|
|
||||||
if ((samplingRate < 6000) || (samplingRate > 24000)) {
|
if ((samplingRate < FAC_FSCALE_MIN) || (samplingRate > FAC_FSCALE_MAX)) {
|
||||||
error = AAC_DEC_PARSE_ERROR;
|
error = AAC_DEC_PARSE_ERROR;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
@ -1546,9 +1557,9 @@ void CLpdChannelStream_Decode(
|
|||||||
|
|
||||||
AAC_DECODER_ERROR CLpd_RenderTimeSignal(
|
AAC_DECODER_ERROR CLpd_RenderTimeSignal(
|
||||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
||||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData,
|
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC *pTimeData,
|
||||||
INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, UINT flags,
|
INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk,
|
||||||
UINT strmFlags) {
|
const INT aacOutDataHeadroom, UINT flags, UINT strmFlags) {
|
||||||
UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
|
UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
|
||||||
AAC_DECODER_ERROR error = AAC_DEC_OK;
|
AAC_DECODER_ERROR error = AAC_DEC_OK;
|
||||||
int k, i_offset;
|
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,
|
bass_pf_1sf_delay(p2_synth, pitch, pit_gain, lFrame, lFrame / facFB,
|
||||||
mod[nbDiv - 1] ? (SynDelay - (lDiv / 2)) : SynDelay,
|
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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -140,13 +140,14 @@ void CLpdChannelStream_Decode(
|
|||||||
* \param pTimeData pointer to output buffer
|
* \param pTimeData pointer to output buffer
|
||||||
* \param samplesPerFrame amount of output samples
|
* \param samplesPerFrame amount of output samples
|
||||||
* \param pSamplingRateInfo holds the sampling rate information
|
* \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(
|
AAC_DECODER_ERROR CLpd_RenderTimeSignal(
|
||||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
|
||||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData,
|
CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC *pTimeData,
|
||||||
INT samplesPerFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk,
|
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) {
|
static inline INT CLpd_FAC_getLength(int fNotShortBlock, int fac_length_long) {
|
||||||
if (fNotShortBlock) {
|
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,
|
void filtLP(const FIXP_DBL *syn, PCM_DEC *syn_out, FIXP_DBL *noise,
|
||||||
const FIXP_SGL *filt, INT stop, int len);
|
const FIXP_SGL *filt, const INT aacOutDataHeadroom, INT stop,
|
||||||
|
int len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief perform a low-frequency pitch enhancement on time domain signal
|
* \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_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[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[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)
|
* \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,
|
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 frame_length, const INT l_frame,
|
||||||
const INT l_next, FIXP_PCM *synth_out,
|
const INT l_next, PCM_DEC *synth_out,
|
||||||
FIXP_DBL mem_bpf[]);
|
const INT aacOutDataHeadroom, FIXP_DBL mem_bpf[]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief random sign generator for FD and TCX noise filling
|
* \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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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
|
All header files are provided for usage in C/C++ programs. The AAC encoder
|
||||||
library API functions are located in aacenc_lib.h.
|
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
|
\section CallingSequence Calling Sequence
|
||||||
|
|
||||||
For encoding of ISO/MPEG-2/4 AAC bitstreams the following sequence is mandatory.
|
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
|
\endcode
|
||||||
|
|
||||||
\section writeOutData Output Bitstream Data
|
\section writeOutData Output Bitstream Data
|
||||||
If any AAC bitstream data is available, write it to output file or device. This
|
If any AAC bitstream data is available, write it to output file or device as
|
||||||
can be done once the following condition is true: \code if
|
follows. \code if (outargs.numOutBytes>0) { FDKfwrite(outputBuffer,
|
||||||
(outargs.numOutBytes>0) {
|
outargs.numOutBytes, 1, pOutFile);
|
||||||
|
|
||||||
}
|
}
|
||||||
\endcode
|
\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
|
\section cfgMetaData Meta Data Configuration
|
||||||
|
|
||||||
If the present library is configured with Metadata support, it is possible to
|
If the present library is configured with Metadata support, it is possible to
|
||||||
@ -427,7 +415,7 @@ switch (nChannels) {
|
|||||||
return chMode;
|
return chMode;
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
\subsection bitreservoir Bitreservoir Configuration
|
\subsection peakbitrate Peak Bitrate Configuration
|
||||||
In AAC, the default bitreservoir configuration depends on the chosen bitrate per
|
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.
|
frame and the number of effective channels. The size can be determined as below.
|
||||||
\f[
|
\f[
|
||||||
@ -436,17 +424,10 @@ bitreservoir = nEffChannels*6144 - (bitrate*framelength/samplerate)
|
|||||||
Due to audio quality concerns it is not recommended to change the bitreservoir
|
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
|
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
|
delay for streaming applications or for achieving a constant size of the
|
||||||
bitstream packages in each frame, it may be necessaray to change the
|
bitstream packages in each frame, it may be necessaray to limit the maximum bits
|
||||||
bitreservoir size. This can be done with the ::AACENC_PEAK_BITRATE parameter.
|
per frame size. This can be done with the ::AACENC_PEAK_BITRATE parameter. \code
|
||||||
\code
|
|
||||||
aacEncoder_SetParam(hAacEncoder, AACENC_PEAK_BITRATE, value);
|
aacEncoder_SetParam(hAacEncoder, AACENC_PEAK_BITRATE, value);
|
||||||
\endcode
|
\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
|
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
|
least 1000 bits per audio channel is recommended. For a multichannel audio file
|
||||||
@ -455,31 +436,32 @@ audio quality.
|
|||||||
|
|
||||||
|
|
||||||
\subsection vbrmode Variable Bitrate Mode
|
\subsection vbrmode Variable Bitrate Mode
|
||||||
The encoder provides various Variable Bitrate Modes that differ in audio quality
|
The variable bitrate (VBR) mode coding adapts the bit consumption to the
|
||||||
and average overall bitrate. The given values are averages over time, different
|
psychoacoustic requirements of the signal. The encoder ignores the user-defined
|
||||||
encoder settings and strongly depend on the type of audio signal. The VBR
|
bit rate and selects a suitable pre-defined configuration based on the provided
|
||||||
configurations can be adjusted via ::AACENC_BITRATEMODE encoder parameter.
|
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
|
\verbatim
|
||||||
--------------------------------------------
|
-----------------------------------------------
|
||||||
VBR_MODE | Approx. Bitrate in kbps/channel
|
VBR_MODE | Approx. Bitrate in kbps for stereo
|
||||||
| AAC-LC | AAC-LD/AC_ELD
|
| AAC-LC | AAC-ELD
|
||||||
----------+---------------+-----------------
|
----------+---------------+--------------------
|
||||||
VBR_1 | 32 - 48 | 32 - 56
|
VBR_1 | 32 (HE-AACv2) | 48
|
||||||
VBR_2 | 40 - 56 | 40 - 64
|
VBR_2 | 72 (HE-AACv1) | 56
|
||||||
VBR_3 | 48 - 64 | 48 - 72
|
VBR_3 | 112 | 72
|
||||||
VBR_4 | 64 - 80 | 64 - 88
|
VBR_4 | 148 | 148
|
||||||
VBR_5 | 96 - 120 | 112 - 144
|
VBR_5 | 228 | 224
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
\endverbatim
|
\endverbatim
|
||||||
The bitrate ranges apply for individual audio channels. In case of multichannel
|
Note that these figures are valid for stereo encoding only. VBR modes 2-5 will
|
||||||
configurations the average bitrate might be estimated by multiplying with the
|
yield much lower bit rates when encoding single-channel input. For
|
||||||
number of effective channels. This corresponds to all audio input channels
|
configurations which are making use of downmix modules the AAC core channels
|
||||||
exclusively the low frequency channel. At configurations which are making use of
|
respectively downmix channels shall be considered.
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
\subsection encQual Audio Quality Considerations
|
\subsection encQual Audio Quality Considerations
|
||||||
The default encoder configuration is suggested to be used. Encoder tools such as
|
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
|
\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
|
A HE-AAC v1 or v2 audio frame contains 2048 PCM samples per channel.
|
||||||
also one mode with 1920 samples per channel but this is only for special
|
|
||||||
purposes such as DAB+ digital radio).
|
|
||||||
|
|
||||||
The number of HE-AAC frames \f$N\_FRAMES\f$ per second at 44.1 kHz is:
|
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 {
|
typedef struct {
|
||||||
UINT maxOutBufBytes; /*!< Maximum number of encoder bitstream bytes within one
|
UINT maxOutBufBytes; /*!< Maximum number of encoder bitstream bytes within one
|
||||||
frame. Size depends on maximum number of supported
|
frame. Size depends on maximum number of supported
|
||||||
channels in encoder instance. For superframing (as
|
channels in encoder instance. */
|
||||||
used for example in DAB+), size has to be a multiple
|
|
||||||
accordingly. */
|
|
||||||
|
|
||||||
UINT maxAncBytes; /*!< Maximum number of ancillary data bytes which can be
|
UINT maxAncBytes; /*!< Maximum number of ancillary data bytes which can be
|
||||||
inserted into bitstream within one frame. */
|
inserted into bitstream within one frame. */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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,
|
* (dynamic_RAM + P_BUF_0 + n*sizeof(QC_OUT_CHANNEL)) is sufficiently aligned,
|
||||||
* so the cast is safe */
|
* so the cast is safe */
|
||||||
return reinterpret_cast<QC_OUT_CHANNEL *>(reinterpret_cast<void *>(
|
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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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 \
|
#define BUF_SIZE_1 \
|
||||||
(ALIGN_SIZE(maxSize(maxSize(sizeof(PSY_DYNAMIC), \
|
(ALIGN_SIZE(maxSize(maxSize(sizeof(PSY_DYNAMIC), \
|
||||||
(BIT_LOOK_UP_SIZE + MERGE_GAIN_LOOK_UP_SIZE)), \
|
(BIT_LOOK_UP_SIZE + MERGE_GAIN_LOOK_UP_SIZE)), \
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -114,6 +114,8 @@ amm-info@iis.fraunhofer.de
|
|||||||
|
|
||||||
#include "genericStds.h"
|
#include "genericStds.h"
|
||||||
|
|
||||||
|
#define BITRES_MIN \
|
||||||
|
300 /* default threshold for using reduced/disabled bitres mode */
|
||||||
#define BITRES_MAX_LD 4000
|
#define BITRES_MAX_LD 4000
|
||||||
#define BITRES_MIN_LD 500
|
#define BITRES_MIN_LD 500
|
||||||
#define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */
|
#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;
|
(config->minBitsPerFrame != -1) ? config->minBitsPerFrame : 0;
|
||||||
qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7);
|
qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7);
|
||||||
} else {
|
} else {
|
||||||
INT bitreservoir = -1; /* default bitrservoir size*/
|
INT bitreservoir = -1; /* default bitreservoir size*/
|
||||||
|
bitresMin = BITRES_MIN;
|
||||||
if (isLowDelay(config->audioObjectType)) {
|
if (isLowDelay(config->audioObjectType)) {
|
||||||
INT brPerChannel = config->bitRate / config->nChannels;
|
INT brPerChannel = config->bitRate / config->nChannels;
|
||||||
brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
|
brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
|
||||||
@ -601,9 +604,9 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(
|
|||||||
qcInit.nSubFrames = config->nSubFrames;
|
qcInit.nSubFrames = config->nSubFrames;
|
||||||
qcInit.padding.paddingRest = config->sampleRate;
|
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 */
|
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 */
|
qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */
|
||||||
} else {
|
} else {
|
||||||
qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */
|
qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */
|
||||||
|
@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de
|
|||||||
/* Encoder library info */
|
/* Encoder library info */
|
||||||
#define AACENCODER_LIB_VL0 4
|
#define AACENCODER_LIB_VL0 4
|
||||||
#define AACENCODER_LIB_VL1 0
|
#define AACENCODER_LIB_VL1 0
|
||||||
#define AACENCODER_LIB_VL2 0
|
#define AACENCODER_LIB_VL2 1
|
||||||
#define AACENCODER_LIB_TITLE "AAC Encoder"
|
#define AACENCODER_LIB_TITLE "AAC Encoder"
|
||||||
#ifdef SUPPRESS_BUILD_DATE_INFO
|
#ifdef SUPPRESS_BUILD_DATE_INFO
|
||||||
#define AACENCODER_LIB_BUILD_DATE ""
|
#define AACENCODER_LIB_BUILD_DATE ""
|
||||||
@ -446,6 +446,24 @@ static SBR_PS_SIGNALING getSbrSignalingMode(
|
|||||||
return sbrSignaling;
|
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
|
Allocate Encoder
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -1921,7 +1939,15 @@ AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
|
|||||||
{
|
{
|
||||||
hAacEncoder->extPayload[nExtensions].dataSize =
|
hAacEncoder->extPayload[nExtensions].dataSize =
|
||||||
hAacEncoder->pSbrPayload->dataSize[nPayload][i];
|
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 =
|
hAacEncoder->extPayload[nExtensions].dataType =
|
||||||
EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set
|
EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set
|
||||||
|
@ -1302,14 +1302,6 @@ static void FDKaacEnc_reduceThresholdsVBR(
|
|||||||
if (sfbThrReducedLdData < FL2FXCONST_DBL(-0.5f))
|
if (sfbThrReducedLdData < FL2FXCONST_DBL(-0.5f))
|
||||||
sfbThrReducedLdData = FL2FXCONST_DBL(-1.f);
|
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);
|
sfbThrReducedLdData = fixMax(MIN_LDTHRESH, sfbThrReducedLdData);
|
||||||
|
|
||||||
qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData;
|
qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -151,11 +151,11 @@ typedef struct {
|
|||||||
|
|
||||||
static const BANDWIDTH_TAB_VBR bandWidthTableVBR[] = {
|
static const BANDWIDTH_TAB_VBR bandWidthTableVBR[] = {
|
||||||
{AACENC_BR_MODE_CBR, 0, 0},
|
{AACENC_BR_MODE_CBR, 0, 0},
|
||||||
{AACENC_BR_MODE_VBR_1, 13050, 13050},
|
{AACENC_BR_MODE_VBR_1, 13000, 13000},
|
||||||
{AACENC_BR_MODE_VBR_2, 13050, 13050},
|
{AACENC_BR_MODE_VBR_2, 13000, 13000},
|
||||||
{AACENC_BR_MODE_VBR_3, 14260, 14260},
|
{AACENC_BR_MODE_VBR_3, 15750, 15750},
|
||||||
{AACENC_BR_MODE_VBR_4, 15500, 15500},
|
{AACENC_BR_MODE_VBR_4, 16500, 16500},
|
||||||
{AACENC_BR_MODE_VBR_5, 48000, 48000},
|
{AACENC_BR_MODE_VBR_5, 19293, 19293},
|
||||||
{AACENC_BR_MODE_SFR, 0, 0},
|
{AACENC_BR_MODE_SFR, 0, 0},
|
||||||
{AACENC_BR_MODE_FF, 0, 0}
|
{AACENC_BR_MODE_FF, 0, 0}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -121,20 +121,15 @@ typedef struct {
|
|||||||
|
|
||||||
static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = {
|
static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = {
|
||||||
{QCDATA_BR_MODE_VBR_1,
|
{QCDATA_BR_MODE_VBR_1,
|
||||||
FL2FXCONST_DBL(0.160f)}, /* Approx. 32 - 48 (AC-LC), 32 - 56
|
FL2FXCONST_DBL(0.150f)}, /* Approx. 32 kbps mono AAC-LC + SBR + PS */
|
||||||
(AAC-LD/ELD) kbps/channel */
|
|
||||||
{QCDATA_BR_MODE_VBR_2,
|
{QCDATA_BR_MODE_VBR_2,
|
||||||
FL2FXCONST_DBL(0.148f)}, /* Approx. 40 - 56 (AC-LC), 40 - 64
|
FL2FXCONST_DBL(0.162f)}, /* Approx. 64 kbps stereo AAC-LC + SBR */
|
||||||
(AAC-LD/ELD) kbps/channel */
|
|
||||||
{QCDATA_BR_MODE_VBR_3,
|
{QCDATA_BR_MODE_VBR_3,
|
||||||
FL2FXCONST_DBL(0.135f)}, /* Approx. 48 - 64 (AC-LC), 48 - 72
|
FL2FXCONST_DBL(0.176f)}, /* Approx. 96 kbps stereo AAC-LC */
|
||||||
(AAC-LD/ELD) kbps/channel */
|
|
||||||
{QCDATA_BR_MODE_VBR_4,
|
{QCDATA_BR_MODE_VBR_4,
|
||||||
FL2FXCONST_DBL(0.111f)}, /* Approx. 64 - 80 (AC-LC), 64 - 88
|
FL2FXCONST_DBL(0.120f)}, /* Approx. 128 kbps stereo AAC-LC */
|
||||||
(AAC-LD/ELD) kbps/channel */
|
|
||||||
{QCDATA_BR_MODE_VBR_5,
|
{QCDATA_BR_MODE_VBR_5,
|
||||||
FL2FXCONST_DBL(0.070f)} /* Approx. 96 - 120 (AC-LC), 112 - 144
|
FL2FXCONST_DBL(0.070f)} /* Approx. 192 kbps stereo AAC-LC */
|
||||||
(AAC-LD/ELD) kbps/channel */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static INT isConstantBitrateMode(const QCDATA_BR_MODE bitrateMode) {
|
static INT isConstantBitrateMode(const QCDATA_BR_MODE bitrateMode) {
|
||||||
|
@ -114,6 +114,8 @@ amm-info@iis.fraunhofer.de
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DRC_DEC_LOUDNESS_NOT_PRESENT (LONG)0x7FFFFFFE
|
||||||
|
|
||||||
typedef struct s_drc_decoder* HANDLE_DRC_DECODER;
|
typedef struct s_drc_decoder* HANDLE_DRC_DECODER;
|
||||||
typedef struct s_uni_drc_interface* HANDLE_UNI_DRC_INTERFACE;
|
typedef struct s_uni_drc_interface* HANDLE_UNI_DRC_INTERFACE;
|
||||||
typedef struct s_selection_process_output* HANDLE_SEL_PROC_OUTPUT;
|
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
|
DRC_DEC_IS_ACTIVE, /**< MPEG-D DRC payload is present and at least one of
|
||||||
Dynamic Range Control (DRC) or Loudness Normalization
|
Dynamic Range Control (DRC) or Loudness Normalization
|
||||||
(LN) is activated */
|
(LN) is activated */
|
||||||
DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED /**< number of output channels if
|
DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED, /**< number of output channels if
|
||||||
appropriate downmixInstruction exists
|
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;
|
} DRC_DEC_USERPARAM;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -145,6 +145,10 @@ struct s_drc_decoder {
|
|||||||
SEL_PROC_OUTPUT selProcOutput;
|
SEL_PROC_OUTPUT selProcOutput;
|
||||||
} DRC_DECODER;
|
} DRC_DECODER;
|
||||||
|
|
||||||
|
static int _getGainStatus(HANDLE_UNI_DRC_GAIN hUniDrcGain) {
|
||||||
|
return hUniDrcGain->status;
|
||||||
|
}
|
||||||
|
|
||||||
static int isResetNeeded(HANDLE_DRC_DECODER hDrcDec,
|
static int isResetNeeded(HANDLE_DRC_DECODER hDrcDec,
|
||||||
const SEL_PROC_OUTPUT oldSelProcOutput) {
|
const SEL_PROC_OUTPUT oldSelProcOutput) {
|
||||||
int i, resetNeeded = 0;
|
int i, resetNeeded = 0;
|
||||||
@ -515,6 +519,8 @@ LONG FDK_drcDec_GetParam(HANDLE_DRC_DECODER hDrcDec,
|
|||||||
}
|
}
|
||||||
case DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED:
|
case DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED:
|
||||||
return (LONG)hDrcDec->selProcOutput.targetChannelCount;
|
return (LONG)hDrcDec->selProcOutput.targetChannelCount;
|
||||||
|
case DRC_DEC_OUTPUT_LOUDNESS:
|
||||||
|
return (LONG)hDrcDec->selProcOutput.outputLoudness;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -729,7 +735,9 @@ FDK_drcDec_ReadUniDrcGain(HANDLE_DRC_DECODER hDrcDec,
|
|||||||
&(hDrcDec->uniDrcGain));
|
&(hDrcDec->uniDrcGain));
|
||||||
if (dErr) return DRC_DEC_NOT_OK;
|
if (dErr) return DRC_DEC_NOT_OK;
|
||||||
|
|
||||||
hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
|
if (_getGainStatus(&(hDrcDec->uniDrcGain))) {
|
||||||
|
hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
|
||||||
|
}
|
||||||
|
|
||||||
return DRC_DEC_OK;
|
return DRC_DEC_OK;
|
||||||
}
|
}
|
||||||
@ -751,7 +759,9 @@ FDK_drcDec_ReadUniDrc(HANDLE_DRC_DECODER hDrcDec,
|
|||||||
startSelectionProcess(hDrcDec);
|
startSelectionProcess(hDrcDec);
|
||||||
if (dErr) return DRC_DEC_NOT_OK;
|
if (dErr) return DRC_DEC_NOT_OK;
|
||||||
|
|
||||||
hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
|
if (_getGainStatus(&(hDrcDec->uniDrcGain))) {
|
||||||
|
hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
|
||||||
|
}
|
||||||
|
|
||||||
return DRC_DEC_OK;
|
return DRC_DEC_OK;
|
||||||
}
|
}
|
||||||
|
@ -297,9 +297,11 @@ drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec,
|
|||||||
int seq, gainSequenceCount;
|
int seq, gainSequenceCount;
|
||||||
DRC_COEFFICIENTS_UNI_DRC* pCoef =
|
DRC_COEFFICIENTS_UNI_DRC* pCoef =
|
||||||
selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
|
selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
|
||||||
if (pCoef == NULL) return DE_OK;
|
if (pCoef && pCoef->gainSequenceCount) {
|
||||||
|
gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
|
||||||
gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
|
} else {
|
||||||
|
gainSequenceCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (seq = 0; seq < gainSequenceCount; seq++) {
|
for (seq = 0; seq < gainSequenceCount; seq++) {
|
||||||
int lastNodeIndex = 0;
|
int lastNodeIndex = 0;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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,
|
||||||
err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault,
|
hUniDrcGain);
|
||||||
hUniDrcGain);
|
|
||||||
if (err) return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -487,10 +484,13 @@ drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
|
|||||||
int seq, gainSequenceCount;
|
int seq, gainSequenceCount;
|
||||||
DRC_COEFFICIENTS_UNI_DRC* pCoef =
|
DRC_COEFFICIENTS_UNI_DRC* pCoef =
|
||||||
selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
|
selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
|
||||||
if (pCoef == NULL) return DE_OK;
|
if (hUniDrcGain == NULL) return DE_NOT_OK;
|
||||||
if (hUniDrcGain == NULL) return DE_OK; /* hUniDrcGain not initialized yet */
|
hUniDrcGain->status = 0;
|
||||||
|
if (pCoef) {
|
||||||
gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
|
gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
|
||||||
|
} else {
|
||||||
|
gainSequenceCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (seq = 0; seq < gainSequenceCount; seq++) {
|
for (seq = 0; seq < gainSequenceCount; seq++) {
|
||||||
UCHAR index = pCoef->gainSetIndexForGainSequence[seq];
|
UCHAR index = pCoef->gainSetIndexForGainSequence[seq];
|
||||||
@ -518,6 +518,9 @@ drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
|
|||||||
if (err) return err;
|
if (err) return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (err == DE_OK && gainSequenceCount > 0) {
|
||||||
|
hUniDrcGain->status = 1;
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1018,6 +1021,7 @@ static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
|
|||||||
int additionalDrcSetIdPresent, additionalDrcSetIdCount;
|
int additionalDrcSetIdPresent, additionalDrcSetIdCount;
|
||||||
int dependsOnEqSetPresent, eqChannelGroupCount, tdFilterCascadePresent,
|
int dependsOnEqSetPresent, eqChannelGroupCount, tdFilterCascadePresent,
|
||||||
subbandGainsPresent, eqTransitionDurationPresent;
|
subbandGainsPresent, eqTransitionDurationPresent;
|
||||||
|
UCHAR eqChannelGroupForChannel[8];
|
||||||
|
|
||||||
FDKpushFor(hBs, 6); /* eqSetId */
|
FDKpushFor(hBs, 6); /* eqSetId */
|
||||||
FDKpushFor(hBs, 4); /* eqSetComplexityLevel */
|
FDKpushFor(hBs, 4); /* eqSetComplexityLevel */
|
||||||
@ -1067,7 +1071,6 @@ static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
|
|||||||
|
|
||||||
eqChannelGroupCount = 0;
|
eqChannelGroupCount = 0;
|
||||||
for (c = 0; c < channelCount; c++) {
|
for (c = 0; c < channelCount; c++) {
|
||||||
UCHAR eqChannelGroupForChannel[8];
|
|
||||||
int newGroup = 1;
|
int newGroup = 1;
|
||||||
if (c >= 8) return DE_MEMORY_ERROR;
|
if (c >= 8) return DE_MEMORY_ERROR;
|
||||||
eqChannelGroupForChannel[c] = FDKreadBits(hBs, 7);
|
eqChannelGroupForChannel[c] = FDKreadBits(hBs, 7);
|
||||||
|
@ -103,8 +103,6 @@ amm-info@iis.fraunhofer.de
|
|||||||
#include "drcDec_selectionProcess.h"
|
#include "drcDec_selectionProcess.h"
|
||||||
#include "drcDec_tools.h"
|
#include "drcDec_tools.h"
|
||||||
|
|
||||||
#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL) MAXVAL_DBL
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DETR_NONE = 0,
|
DETR_NONE = 0,
|
||||||
DETR_NIGHT = 1,
|
DETR_NIGHT = 1,
|
||||||
@ -753,8 +751,8 @@ static DRCDEC_SELECTION_PROCESS_RETURN _initDefaultParams(
|
|||||||
hSelProcInput->loudnessNormalizationOn = 1;
|
hSelProcInput->loudnessNormalizationOn = 1;
|
||||||
hSelProcInput->targetLoudness = FL2FXCONST_DBL(-24.0f / (float)(1 << 7));
|
hSelProcInput->targetLoudness = FL2FXCONST_DBL(-24.0f / (float)(1 << 7));
|
||||||
hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
|
hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
|
||||||
hSelProcInput->loudnessMeasurementMethod = MDR_DEFAULT;
|
hSelProcInput->loudnessMeasurementMethod = MDR_ANCHOR_LOUDNESS;
|
||||||
hSelProcInput->loudnessMeasurementSystem = MSR_DEFAULT;
|
hSelProcInput->loudnessMeasurementSystem = MSR_EXPERT_PANEL;
|
||||||
hSelProcInput->loudnessMeasurementPreProc = LPR_DEFAULT;
|
hSelProcInput->loudnessMeasurementPreProc = LPR_DEFAULT;
|
||||||
hSelProcInput->deviceCutOffFrequency = 500;
|
hSelProcInput->deviceCutOffFrequency = 500;
|
||||||
hSelProcInput->loudnessNormalizationGainDbMax =
|
hSelProcInput->loudnessNormalizationGainDbMax =
|
||||||
@ -956,17 +954,31 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement4(
|
|||||||
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
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(
|
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5(
|
||||||
DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
|
DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
|
||||||
DRC_COEFFICIENTS_UNI_DRC* pCoef, int* pMatchFound) {
|
DRC_COEFFICIENTS_UNI_DRC* pCoef, int* pMatchFound) {
|
||||||
int i;
|
int b, i;
|
||||||
|
|
||||||
*pMatchFound = 1;
|
*pMatchFound = 1;
|
||||||
|
|
||||||
|
if (pDrcInstructionUniDrc->drcSetId < 0) /* virtual DRC sets are okay */
|
||||||
|
{
|
||||||
|
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (pCoef == NULL) /* check for parametricDRC */
|
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;
|
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -974,10 +986,14 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5(
|
|||||||
int indexDrcCoeff = pDrcInstructionUniDrc->gainSetIndexForChannelGroup[i];
|
int indexDrcCoeff = pDrcInstructionUniDrc->gainSetIndexForChannelGroup[i];
|
||||||
int bandCount = 0;
|
int bandCount = 0;
|
||||||
|
|
||||||
|
if (indexDrcCoeff >= 12) {
|
||||||
|
*pMatchFound = 0;
|
||||||
|
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (indexDrcCoeff > pCoef->gainSetCount - 1) /* check for parametricDRC */
|
if (indexDrcCoeff > pCoef->gainSetCount - 1) /* check for parametricDRC */
|
||||||
{
|
{
|
||||||
*pMatchFound = 1;
|
continue;
|
||||||
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GAIN_SET* gainSet = &(pCoef->gainSet[indexDrcCoeff]);
|
GAIN_SET* gainSet = &(pCoef->gainSet[indexDrcCoeff]);
|
||||||
@ -986,6 +1002,14 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5(
|
|||||||
if (bandCount > 4) {
|
if (bandCount > 4) {
|
||||||
*pMatchFound = 0;
|
*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;
|
return DRCDEC_SELECTION_PROCESS_NO_ERROR;
|
||||||
@ -1078,6 +1102,19 @@ static int _targetLoudnessInRange(
|
|||||||
return retVal;
|
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
|
/* #8: The range of the target loudness specified for a DRC set has to include
|
||||||
* the requested decoder target loudness. */
|
* the requested decoder target loudness. */
|
||||||
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
|
static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
|
||||||
@ -1097,9 +1134,8 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
|
|||||||
|
|
||||||
FIXP_DBL loudnessDeviationMax =
|
FIXP_DBL loudnessDeviationMax =
|
||||||
((FIXP_DBL)hSelProcInput->loudnessDeviationMax) << (DFRACT_BITS - 1 - 7);
|
((FIXP_DBL)hSelProcInput->loudnessDeviationMax) << (DFRACT_BITS - 1 - 7);
|
||||||
;
|
|
||||||
|
|
||||||
if (hSelProcInput->loudnessNormalizationOn) {
|
{
|
||||||
retVal = _getLoudness(hLoudnessInfoSet, hSelProcInput->albumMode,
|
retVal = _getLoudness(hLoudnessInfoSet, hSelProcInput->albumMode,
|
||||||
hSelProcInput->loudnessMeasurementMethod,
|
hSelProcInput->loudnessMeasurementMethod,
|
||||||
hSelProcInput->loudnessMeasurementSystem,
|
hSelProcInput->loudnessMeasurementSystem,
|
||||||
@ -1108,9 +1144,10 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
|
|||||||
hSelProcInput->downmixIdRequested[downmixIdIndex],
|
hSelProcInput->downmixIdRequested[downmixIdIndex],
|
||||||
&loudnessNormalizationGainDb, &loudness);
|
&loudnessNormalizationGainDb, &loudness);
|
||||||
if (retVal) return (retVal);
|
if (retVal) return (retVal);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if (!hSelProcInput->loudnessNormalizationOn) {
|
||||||
loudnessNormalizationGainDb = (FIXP_DBL)0;
|
loudnessNormalizationGainDb = (FIXP_DBL)0;
|
||||||
loudness = UNDEFINED_LOUDNESS_VALUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
retVal = _getSignalPeakLevel(
|
retVal = _getSignalPeakLevel(
|
||||||
@ -2031,6 +2068,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
|
|||||||
pSelectionData->loudnessNormalizationGainDbAdjusted +
|
pSelectionData->loudnessNormalizationGainDbAdjusted +
|
||||||
hSelProcInput->loudnessNormalizationGainModificationDb;
|
hSelProcInput->loudnessNormalizationGainModificationDb;
|
||||||
hSelProcOutput->outputPeakLevelDb = pSelectionData->outputPeakLevel;
|
hSelProcOutput->outputPeakLevelDb = pSelectionData->outputPeakLevel;
|
||||||
|
hSelProcOutput->outputLoudness = pSelectionData->outputLoudness;
|
||||||
|
|
||||||
hSelProcOutput->boost = boost;
|
hSelProcOutput->boost = boost;
|
||||||
hSelProcOutput->compress = compress;
|
hSelProcOutput->compress = compress;
|
||||||
@ -2051,8 +2089,11 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
|
|||||||
int dependsOnDrcSetID = pSelectionData->pInst->dependsOnDrcSet;
|
int dependsOnDrcSetID = pSelectionData->pInst->dependsOnDrcSet;
|
||||||
|
|
||||||
for (i = 0; i < hUniDrcConfig->drcInstructionsCountInclVirtual; i++) {
|
for (i = 0; i < hUniDrcConfig->drcInstructionsCountInclVirtual; i++) {
|
||||||
if (hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId ==
|
DRC_INSTRUCTIONS_UNI_DRC* pInst =
|
||||||
dependsOnDrcSetID) {
|
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
|
||||||
|
if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
|
||||||
|
|
||||||
|
if (pInst->drcSetId == dependsOnDrcSetID) {
|
||||||
hSelProcOutput->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
|
hSelProcOutput->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
|
||||||
hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
|
hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
|
||||||
hSelProcOutput->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] =
|
hSelProcOutput->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] =
|
||||||
@ -2071,6 +2112,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
|
|||||||
for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
|
for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
|
||||||
DRC_INSTRUCTIONS_UNI_DRC* pInst =
|
DRC_INSTRUCTIONS_UNI_DRC* pInst =
|
||||||
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
|
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
|
||||||
|
if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
|
||||||
|
|
||||||
if (pInst->drcSetEffect & EB_FADE) {
|
if (pInst->drcSetEffect & EB_FADE) {
|
||||||
if (pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) {
|
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++) {
|
for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
|
||||||
DRC_INSTRUCTIONS_UNI_DRC* pInst =
|
DRC_INSTRUCTIONS_UNI_DRC* pInst =
|
||||||
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
|
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
|
||||||
|
if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
|
||||||
|
|
||||||
if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
|
if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
|
||||||
for (j = 0; j < pInst->downmixIdCount; j++) {
|
for (j = 0; j < pInst->downmixIdCount; j++) {
|
||||||
@ -2124,6 +2167,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
|
|||||||
for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
|
for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
|
||||||
DRC_INSTRUCTIONS_UNI_DRC* pInst =
|
DRC_INSTRUCTIONS_UNI_DRC* pInst =
|
||||||
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
|
&(hUniDrcConfig->drcInstructionsUniDrc[i]);
|
||||||
|
if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
|
||||||
|
|
||||||
if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
|
if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
|
||||||
for (j = 0; j < pInst->downmixIdCount; j++) {
|
for (j = 0; j < pInst->downmixIdCount; j++) {
|
||||||
@ -2231,6 +2275,11 @@ static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelection(
|
|||||||
for (j = 0; j < hUniDrcConfig->drcInstructionsCountInclVirtual; j++) {
|
for (j = 0; j < hUniDrcConfig->drcInstructionsCountInclVirtual; j++) {
|
||||||
DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction =
|
DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction =
|
||||||
&(hUniDrcConfig->drcInstructionsUniDrc[j]);
|
&(hUniDrcConfig->drcInstructionsUniDrc[j]);
|
||||||
|
/* check if ID is unique */
|
||||||
|
if (selectDrcInstructions(hUniDrcConfig, pDrcInstruction->drcSetId) !=
|
||||||
|
pDrcInstruction)
|
||||||
|
continue;
|
||||||
|
|
||||||
retVal = _drcSetPreSelectionSingleInstruction(
|
retVal = _drcSetPreSelectionSingleInstruction(
|
||||||
hSelProcInput, i, hUniDrcConfig, hLoudnessInfoSet, pDrcInstruction,
|
hSelProcInput, i, hUniDrcConfig, hLoudnessInfoSet, pDrcInstruction,
|
||||||
*ppCandidatesPotential, *ppCandidatesSelected, codecMode);
|
*ppCandidatesPotential, *ppCandidatesSelected, codecMode);
|
||||||
|
@ -111,6 +111,8 @@ amm-info@iis.fraunhofer.de
|
|||||||
|
|
||||||
typedef struct s_drcdec_selection_process* HANDLE_DRC_SELECTION_PROCESS;
|
typedef struct s_drcdec_selection_process* HANDLE_DRC_SELECTION_PROCESS;
|
||||||
|
|
||||||
|
#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL)(MAXVAL_DBL - 1)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DRCDEC_SELECTION_PROCESS_NO_ERROR = 0,
|
DRCDEC_SELECTION_PROCESS_NO_ERROR = 0,
|
||||||
|
|
||||||
|
@ -130,6 +130,9 @@ typedef struct {
|
|||||||
|
|
||||||
UCHAR uniDrcGainExtPresent;
|
UCHAR uniDrcGainExtPresent;
|
||||||
UNI_DRC_GAIN_EXTENSION uniDrcGainExtension;
|
UNI_DRC_GAIN_EXTENSION uniDrcGainExtension;
|
||||||
|
|
||||||
|
/* derived data */
|
||||||
|
UCHAR status;
|
||||||
} UNI_DRC_GAIN, *HANDLE_UNI_DRC_GAIN;
|
} UNI_DRC_GAIN, *HANDLE_UNI_DRC_GAIN;
|
||||||
|
|
||||||
/****************/
|
/****************/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -285,6 +285,9 @@ static DRC_ERROR _compressorIO_sigmoid_common(
|
|||||||
&e_tmp2);
|
&e_tmp2);
|
||||||
invExp = fDivNorm(FL2FXCONST_DBL(1.0f / (float)(1 << 1)), exp, &e_invExp);
|
invExp = fDivNorm(FL2FXCONST_DBL(1.0f / (float)(1 << 1)), exp, &e_invExp);
|
||||||
e_invExp += 1 - 5;
|
e_invExp += 1 - 5;
|
||||||
|
if (tmp2 < (FIXP_DBL)0) {
|
||||||
|
return DE_NOT_OK;
|
||||||
|
}
|
||||||
denom = fPow(tmp2, e_tmp2, invExp, e_invExp, &e_denom);
|
denom = fPow(tmp2, e_tmp2, invExp, e_invExp, &e_denom);
|
||||||
*out = fDivNormSigned(tmp, denom, &e_out);
|
*out = fDivNormSigned(tmp, denom, &e_out);
|
||||||
e_out += 7 - e_denom;
|
e_out += 7 - e_denom;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -123,11 +123,10 @@ typedef enum {
|
|||||||
#define QMF_WB_SECTION_SIZE (1024 * 2)
|
#define QMF_WB_SECTION_SIZE (1024 * 2)
|
||||||
|
|
||||||
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL)
|
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(QmfWorkBufferCore3, FIXP_DBL)
|
||||||
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, 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(QmfWorkBufferCore6, FIXP_DBL)
|
||||||
|
H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL)
|
||||||
|
|
||||||
#define QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS (64)
|
#define QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS (64)
|
||||||
#define QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS (QMF_MAX_SYNTHESIS_BANDS)
|
#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_16 (3)
|
||||||
#define QMF_DOMAIN_OV_TIMESLOTS_32 (6)
|
#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(SynQmfStates, FIXP_QSS)
|
||||||
H_ALLOC_MEM(QmfSlotsReal, FIXP_DBL *)
|
H_ALLOC_MEM(QmfSlotsReal, FIXP_DBL *)
|
||||||
H_ALLOC_MEM(QmfSlotsImag, FIXP_DBL *)
|
H_ALLOC_MEM(QmfSlotsImag, FIXP_DBL *)
|
||||||
H_ALLOC_MEM(QmfOverlapBuffer, FIXP_DBL)
|
H_ALLOC_MEM(QmfOverlapBuffer, FIXP_DBL)
|
||||||
|
|
||||||
H_ALLOC_MEM(AnaQmfStates16, FIXP_QAS)
|
H_ALLOC_MEM(AnaQmfStates16, FIXP_DBL)
|
||||||
H_ALLOC_MEM(AnaQmfStates24, FIXP_QAS)
|
H_ALLOC_MEM(AnaQmfStates24, FIXP_DBL)
|
||||||
H_ALLOC_MEM(AnaQmfStates32, FIXP_QAS)
|
H_ALLOC_MEM(AnaQmfStates32, FIXP_DBL)
|
||||||
H_ALLOC_MEM(QmfSlotsReal16, FIXP_DBL *)
|
H_ALLOC_MEM(QmfSlotsReal16, FIXP_DBL *)
|
||||||
H_ALLOC_MEM(QmfSlotsReal32, FIXP_DBL *)
|
H_ALLOC_MEM(QmfSlotsReal32, FIXP_DBL *)
|
||||||
H_ALLOC_MEM(QmfSlotsImag16, 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(QmfOverlapBuffer16, FIXP_DBL)
|
||||||
H_ALLOC_MEM(QmfOverlapBuffer32, 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
|
* Structure to hold the configuration data which is global whithin a QMF domain
|
||||||
* instance.
|
* instance.
|
||||||
@ -182,9 +179,6 @@ typedef struct {
|
|||||||
park a channel if only one processing channel is
|
park a channel if only one processing channel is
|
||||||
available. */
|
available. */
|
||||||
UCHAR parkChannel_requested;
|
UCHAR parkChannel_requested;
|
||||||
QDOM_PCM
|
|
||||||
*TDinput; /*!< Pointer to time domain data used as input for the QMF
|
|
||||||
analysis. */
|
|
||||||
FIXP_DBL *
|
FIXP_DBL *
|
||||||
pWorkBuffer[QMF_MAX_WB_SECTIONS]; /*!< Pointerarray to volatile memory. */
|
pWorkBuffer[QMF_MAX_WB_SECTIONS]; /*!< Pointerarray to volatile memory. */
|
||||||
UINT flags; /*!< Flags to be set on all QMF analysis/synthesis filter
|
UINT flags; /*!< Flags to be set on all QMF analysis/synthesis filter
|
||||||
@ -244,7 +238,7 @@ typedef struct {
|
|||||||
(workBuf_nTimeSlots * workBuf_nBands * CMPLX_MOD). */
|
(workBuf_nTimeSlots * workBuf_nBands * CMPLX_MOD). */
|
||||||
USHORT workBufferOffset; /*!< Offset within work buffer. */
|
USHORT workBufferOffset; /*!< Offset within work buffer. */
|
||||||
USHORT workBufferSectSize; /*!< Size of work buffer section. */
|
USHORT workBufferSectSize; /*!< Size of work buffer section. */
|
||||||
FIXP_QAS *
|
FIXP_DBL *
|
||||||
pAnaQmfStates; /*!< Pointer to QMF analysis states (persistent memory). */
|
pAnaQmfStates; /*!< Pointer to QMF analysis states (persistent memory). */
|
||||||
FIXP_DBL
|
FIXP_DBL
|
||||||
*pOverlapBuffer; /*!< Pointer to QMF overlap/delay memory (persistent
|
*pOverlapBuffer; /*!< Pointer to QMF overlap/delay memory (persistent
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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
|
* \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) {
|
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) {
|
if (a_e > b_e) {
|
||||||
return ((b_m >> fMin(a_e - b_e, DFRACT_BITS - 1)) > a_m);
|
return ((b_m >> fMin(a_e - b_e, DFRACT_BITS - 1)) > a_m);
|
||||||
} else {
|
} 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) {
|
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) {
|
if (a_e > b_e) {
|
||||||
return ((b_m >> fMin(a_e - b_e, FRACT_BITS - 1)) > a_m);
|
return ((b_m >> fMin(a_e - b_e, FRACT_BITS - 1)) > a_m);
|
||||||
} else {
|
} else {
|
||||||
@ -545,15 +571,20 @@ inline INT fMultIceil(FIXP_DBL a, INT b) {
|
|||||||
m = fMultNorm(a, (FIXP_DBL)b, &m_e);
|
m = fMultNorm(a, (FIXP_DBL)b, &m_e);
|
||||||
|
|
||||||
if (m_e < (INT)0) {
|
if (m_e < (INT)0) {
|
||||||
if (m_e > (INT)-DFRACT_BITS) {
|
if (m_e > (INT) - (DFRACT_BITS - 1)) {
|
||||||
mi = (m >> (-m_e));
|
mi = (m >> (-m_e));
|
||||||
if ((LONG)m & ((1 << (-m_e)) - 1)) {
|
if ((LONG)m & ((1 << (-m_e)) - 1)) {
|
||||||
mi = mi + (FIXP_DBL)1;
|
mi = mi + (FIXP_DBL)1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mi = (FIXP_DBL)1;
|
if (m > (FIXP_DBL)0) {
|
||||||
if (m < (FIXP_DBL)0) {
|
mi = (FIXP_DBL)1;
|
||||||
mi = (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 {
|
} else {
|
||||||
@ -744,7 +775,7 @@ FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief return (base_m * 2^base_e) ^ N
|
* \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 base_e exponent of the base
|
||||||
* \param N power to be calculated 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
|
* \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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -106,18 +106,16 @@ amm-info@iis.fraunhofer.de
|
|||||||
#include "common_fix.h"
|
#include "common_fix.h"
|
||||||
|
|
||||||
#define MDCT_OUT_HEADROOM 2 /* Output additional headroom */
|
#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 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 */
|
/* Refer to "Output word length" in ISO/IEC 14496-3:2008(E) 23.2.3.6 */
|
||||||
#define MDCT_OUTPUT_GAIN 16
|
#define MDCT_OUTPUT_GAIN 16
|
||||||
|
|
||||||
#if (MDCT_OUTPUT_SCALE >= 0)
|
#define IMDCT_SCALE(x, s) \
|
||||||
#define IMDCT_SCALE(x) SATURATE_RIGHT_SHIFT(x, MDCT_OUTPUT_SCALE, PCM_OUT_BITS)
|
SATURATE_RIGHT_SHIFT((x), ((s) + 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_DBL(x) (FIXP_DBL)(x)
|
#define IMDCT_SCALE_DBL(x) (FIXP_DBL)(x)
|
||||||
#define IMDCT_SCALE_DBL_LSH1(x) SATURATE_LEFT_SHIFT_ALT((x), 1, DFRACT_BITS)
|
#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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -116,6 +116,7 @@ amm-info@iis.fraunhofer.de
|
|||||||
|
|
||||||
#define FIXP_QAS FIXP_PCM
|
#define FIXP_QAS FIXP_PCM
|
||||||
#define QAS_BITS SAMPLE_BITS
|
#define QAS_BITS SAMPLE_BITS
|
||||||
|
#define INT_PCM_QMFIN INT_PCM
|
||||||
|
|
||||||
#define FIXP_QSS FIXP_DBL
|
#define FIXP_QSS FIXP_DBL
|
||||||
#define QSS_BITS DFRACT_BITS
|
#define QSS_BITS DFRACT_BITS
|
||||||
@ -201,16 +202,25 @@ struct QMF_FILTER_BANK {
|
|||||||
|
|
||||||
typedef struct QMF_FILTER_BANK *HANDLE_QMF_FILTER_BANK;
|
typedef struct QMF_FILTER_BANK *HANDLE_QMF_FILTER_BANK;
|
||||||
|
|
||||||
void qmfAnalysisFiltering(
|
int qmfInitAnalysisFilterBank(
|
||||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
|
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
|
||||||
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
|
FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */
|
||||||
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
|
int noCols, /*!< Number of time slots */
|
||||||
QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
|
int lsb, /*!< Number of lower bands */
|
||||||
const LONG *timeIn, /*!< Time signal */
|
int usb, /*!< Number of upper bands */
|
||||||
const int timeIn_e, /*!< Exponent of audio data */
|
int no_channels, /*!< Number of critically sampled bands */
|
||||||
const int stride, /*!< Stride factor of audio data */
|
int flags); /*!< Flags */
|
||||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
|
#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(
|
void qmfAnalysisFiltering(
|
||||||
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
|
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
|
||||||
@ -222,6 +232,48 @@ void qmfAnalysisFiltering(
|
|||||||
const int stride, /*!< Stride factor of audio data */
|
const int stride, /*!< Stride factor of audio data */
|
||||||
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
|
FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
|
||||||
);
|
);
|
||||||
|
#if SAMPLE_BITS == 16
|
||||||
|
|
||||||
|
void qmfAnalysisFiltering(
|
||||||
|
HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
|
||||||
|
FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
|
||||||
|
FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
|
||||||
|
QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
|
||||||
|
const 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(
|
void qmfSynthesisFiltering(
|
||||||
HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
|
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
|
FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer. It must be
|
||||||
aligned */
|
aligned */
|
||||||
);
|
);
|
||||||
|
#if SAMPLE_BITS == 16
|
||||||
|
|
||||||
int qmfInitAnalysisFilterBank(
|
void qmfSynthesisFiltering(
|
||||||
HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
|
HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
|
||||||
FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */
|
FIXP_DBL **QmfBufferReal, /*!< Pointer to real subband slots */
|
||||||
int noCols, /*!< Number of time slots */
|
FIXP_DBL **QmfBufferImag, /*!< Pointer to imag subband slots */
|
||||||
int lsb, /*!< Number of lower bands */
|
const QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
|
||||||
int usb, /*!< Number of upper bands */
|
const int ov_len, /*!< Length of band overlap */
|
||||||
int no_channels, /*!< Number of critically sampled bands */
|
LONG *timeOut, /*!< Time signal */
|
||||||
int flags); /*!< Flags */
|
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 LONG *timeIn, /*!< Pointer to input */
|
|
||||||
const int stride, /*!< stride factor of input */
|
|
||||||
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 */
|
|
||||||
);
|
|
||||||
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 qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
|
void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
|
||||||
const FIXP_DBL *realSlot,
|
const FIXP_DBL *realSlot,
|
||||||
@ -276,6 +306,15 @@ void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
|
|||||||
const int scaleFactorLowBand,
|
const int scaleFactorLowBand,
|
||||||
const int scaleFactorHighBand, INT_PCM *timeOut,
|
const int scaleFactorHighBand, INT_PCM *timeOut,
|
||||||
const int timeOut_e, FIXP_DBL *pWorkBuffer);
|
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(
|
void qmfChangeOutScalefactor(
|
||||||
HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
|
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) */
|
FIXP_DBL outputGain, /*!< New gain for output data (mantissa) */
|
||||||
int outputGainScale /*!< New gain for output data (exponent) */
|
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 */
|
#endif /*ifndef QMF_H */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -402,4 +402,220 @@ void qmfSynthesisFiltering(
|
|||||||
timeOut + (i * L * stride), stride, pWorkBuffer);
|
timeOut + (i * L * stride), stride, pWorkBuffer);
|
||||||
} /* no_col loop i */
|
} /* 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 */
|
#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,
|
void scaleValuesWithFactor(FIXP_DBL *vector, FIXP_DBL factor, INT len,
|
||||||
INT scalefactor);
|
INT scalefactor);
|
||||||
void scaleValuesSaturate(FIXP_DBL *vector, 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);
|
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);
|
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 *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);
|
INT scalefactor);
|
||||||
void scaleValuesSaturate(INT_PCM *dst, INT_PCM *src, INT len, INT scalefactor);
|
|
||||||
INT getScalefactorShort(const SHORT *vector, INT len);
|
INT getScalefactorShort(const SHORT *vector, INT len);
|
||||||
INT getScalefactorPCM(const INT_PCM *vector, INT len, INT stride);
|
INT getScalefactorPCM(const INT_PCM *vector, INT len, INT stride);
|
||||||
INT getScalefactor(const FIXP_DBL *vector, INT len);
|
INT getScalefactor(const FIXP_DBL *vector, INT len);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -368,7 +368,10 @@ void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf, const UCHAR *RESTRICT inputBuffer,
|
|||||||
|
|
||||||
UINT bTotal = 0;
|
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 =
|
UINT noOfBytes =
|
||||||
fMin(bToRead,
|
fMin(bToRead,
|
||||||
*bytesValid); //(bToRead < *bytesValid) ? bToRead : *bytesValid ;
|
*bytesValid); //(bToRead < *bytesValid) ? bToRead : *bytesValid ;
|
||||||
@ -384,7 +387,7 @@ void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf, const UCHAR *RESTRICT inputBuffer,
|
|||||||
bToRead * sizeof(UCHAR));
|
bToRead * sizeof(UCHAR));
|
||||||
|
|
||||||
/* add noOfBits to number of valid bits in buffer */
|
/* add noOfBits to number of valid bits in buffer */
|
||||||
hBitBuf->ValidBits += bToRead << 3;
|
hBitBuf->ValidBits = (UINT)((INT)hBitBuf->ValidBits + (INT)(bToRead << 3));
|
||||||
bTotal += bToRead;
|
bTotal += bToRead;
|
||||||
inputBuffer += bToRead;
|
inputBuffer += bToRead;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -104,7 +104,7 @@ amm-info@iis.fraunhofer.de
|
|||||||
|
|
||||||
/* FDK tools library info */
|
/* FDK tools library info */
|
||||||
#define FDK_TOOLS_LIB_VL0 3
|
#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_VL2 0
|
||||||
#define FDK_TOOLS_LIB_TITLE "FDK Tools"
|
#define FDK_TOOLS_LIB_TITLE "FDK Tools"
|
||||||
#ifdef SUPPRESS_BUILD_DATE_INFO
|
#ifdef SUPPRESS_BUILD_DATE_INFO
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -227,7 +227,7 @@ static inline int SpatialDecGetQmfBand(int paramBand, const UCHAR *tab) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define DUCKER_MAX_NRG_SCALE (24)
|
#define DUCKER_MAX_NRG_SCALE (24)
|
||||||
#define DUCKER_HEADROOM_BITS (3)
|
#define DUCKER_HEADROOM_BITS (2)
|
||||||
|
|
||||||
#define FILTER_SF (2)
|
#define FILTER_SF (2)
|
||||||
|
|
||||||
@ -606,10 +606,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
|
|||||||
dataImagIn += start;
|
dataImagIn += start;
|
||||||
dataRealOut += start;
|
dataRealOut += start;
|
||||||
dataImagOut += start;
|
dataImagOut += start;
|
||||||
#ifdef FUNCTION_DecorrFilterApplyPASS_func1
|
|
||||||
DecorrFilterApplyPASS_func1(i, dataRealIn, dataImagIn, dataRealOut,
|
|
||||||
dataImagOut, pDelayBuffer, offset);
|
|
||||||
#else
|
|
||||||
do {
|
do {
|
||||||
FIXP_DBL delay_re, delay_im, real, imag;
|
FIXP_DBL delay_re, delay_im, real, imag;
|
||||||
|
|
||||||
@ -623,7 +619,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
|
|||||||
*dataImagOut++ = delay_im;
|
*dataImagOut++ = delay_im;
|
||||||
pDelayBuffer += offset;
|
pDelayBuffer += offset;
|
||||||
} while (--i != 0);
|
} while (--i != 0);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1061,24 +1056,15 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
|
|||||||
FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
|
FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
|
||||||
|
|
||||||
if (maxVal == FL2FXCONST_DBL(-1.0f)) {
|
if (maxVal == FL2FXCONST_DBL(-1.0f)) {
|
||||||
#ifdef FUNCTION_DuckerCalcEnergy_func2
|
clz = fMin(getScalefactor(&inputReal[startHybBand],
|
||||||
maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
|
fMax(0, maxHybridBand - startHybBand + 1)),
|
||||||
maxHybBand, maxHybridBand);
|
getScalefactor(&inputImag[startHybBand],
|
||||||
#else
|
fMax(0, maxHybBand - startHybBand + 1)));
|
||||||
FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
|
} else {
|
||||||
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
clz = CntLeadingZeros(maxVal) - 1;
|
||||||
localMaxVal |= fAbs(inputReal[qs]);
|
|
||||||
localMaxVal |= fAbs(inputImag[qs]);
|
|
||||||
}
|
|
||||||
for (; qs <= maxHybridBand; qs++) {
|
|
||||||
localMaxVal |= fAbs(inputReal[qs]);
|
|
||||||
}
|
|
||||||
maxVal = localMaxVal;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
|
clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
|
||||||
clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
|
|
||||||
*nrgScale = (SCHAR)clz << 1;
|
*nrgScale = (SCHAR)clz << 1;
|
||||||
|
|
||||||
/* Initialize pb since it would stay uninitialized for the case startHybBand
|
/* 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);
|
pb = SpatialDecGetProcessingBand(maxHybBand, self->mapHybBands2ProcBands);
|
||||||
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
||||||
pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
|
pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
|
||||||
energy[pb] =
|
energy[pb] = SATURATE_LEFT_SHIFT(
|
||||||
fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
|
(energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
|
||||||
fPow2Div2(inputImag[qs] << clz));
|
(fPow2Div2(inputImag[qs] << clz) >> 1),
|
||||||
|
1, DFRACT_BITS);
|
||||||
}
|
}
|
||||||
pb++;
|
pb++;
|
||||||
|
|
||||||
@ -1112,43 +1099,29 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
|
|||||||
maxVal = inputMaxVal;
|
maxVal = inputMaxVal;
|
||||||
|
|
||||||
if (maxVal == FL2FXCONST_DBL(-1.0f)) {
|
if (maxVal == FL2FXCONST_DBL(-1.0f)) {
|
||||||
#ifdef FUNCTION_DuckerCalcEnergy_func2
|
clz = fMin(getScalefactor(&inputReal[startHybBand],
|
||||||
maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
|
fMax(0, maxHybridBand - startHybBand + 1)),
|
||||||
maxHybBand, maxHybridBand);
|
getScalefactor(&inputImag[startHybBand],
|
||||||
#else
|
fMax(0, maxHybBand - startHybBand + 1)));
|
||||||
FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
|
} else {
|
||||||
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
clz = CntLeadingZeros(maxVal) - 1;
|
||||||
localMaxVal |= fAbs(inputReal[qs]);
|
|
||||||
localMaxVal |= fAbs(inputImag[qs]);
|
|
||||||
}
|
|
||||||
for (; qs <= maxHybridBand; qs++) {
|
|
||||||
localMaxVal |= fAbs(inputReal[qs]);
|
|
||||||
}
|
|
||||||
maxVal = localMaxVal;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
|
clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
|
||||||
clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
|
|
||||||
*nrgScale = (SCHAR)clz << 1;
|
*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++) {
|
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
||||||
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
|
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
|
||||||
energy[pb] =
|
energy[pb] = SATURATE_LEFT_SHIFT(
|
||||||
fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
|
(energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
|
||||||
fPow2Div2(inputImag[qs] << clz));
|
(fPow2Div2(inputImag[qs] << clz) >> 1),
|
||||||
|
1, DFRACT_BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; qs <= maxHybridBand; qs++) {
|
for (; qs <= maxHybridBand; qs++) {
|
||||||
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
|
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
|
||||||
energy[pb] = fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz));
|
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 */
|
/* general gain*output section */
|
||||||
if (qs < hybBands) { /* true for about 39% */
|
if (qs < hybBands) { /* true for about 39% */
|
||||||
for (; qs < qs_next; qs++) { /* runs about 2 times */
|
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;
|
outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} /* pb */
|
} /* pb */
|
||||||
|
|
||||||
self->headroomSmoothDirRevNrg =
|
self->headroomSmoothDirRevNrg =
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -142,11 +142,12 @@ amm-info@iis.fraunhofer.de
|
|||||||
} /* How to arrange the packed values. */
|
} /* How to arrange the packed values. */
|
||||||
|
|
||||||
struct FDK_HYBRID_SETUP {
|
struct FDK_HYBRID_SETUP {
|
||||||
UCHAR nrQmfBands; /*!< Number of QMF bands to be converted to hybrid. */
|
UCHAR nrQmfBands; /*!< Number of QMF bands to be converted to hybrid. */
|
||||||
UCHAR nHybBands[3]; /*!< Number of Hybrid bands generated by nrQmfBands. */
|
UCHAR nHybBands[3]; /*!< Number of Hybrid bands generated by nrQmfBands. */
|
||||||
SCHAR kHybrid[3]; /*!< Filter configuration of each QMF band. */
|
UCHAR synHybScale[3]; /*!< Headroom needed in hybrid synthesis filterbank. */
|
||||||
UCHAR protoLen; /*!< Prototype filter length. */
|
SCHAR kHybrid[3]; /*!< Filter configuration of each QMF band. */
|
||||||
UCHAR filterDelay; /*!< Delay caused by hybrid filter. */
|
UCHAR protoLen; /*!< Prototype filter length. */
|
||||||
|
UCHAR filterDelay; /*!< Delay caused by hybrid filter. */
|
||||||
const INT
|
const INT
|
||||||
*pReadIdxTable; /*!< Helper table to access input data ringbuffer. */
|
*pReadIdxTable; /*!< Helper table to access input data ringbuffer. */
|
||||||
};
|
};
|
||||||
@ -156,12 +157,12 @@ static const INT ringbuffIdxTab[2 * 13] = {0, 1, 2, 3, 4, 5, 6, 7, 8,
|
|||||||
9, 10, 11, 12, 0, 1, 2, 3, 4,
|
9, 10, 11, 12, 0, 1, 2, 3, 4,
|
||||||
5, 6, 7, 8, 9, 10, 11, 12};
|
5, 6, 7, 8, 9, 10, 11, 12};
|
||||||
|
|
||||||
static const FDK_HYBRID_SETUP setup_3_16 = {3, {8, 4, 4}, {8, 4, 4},
|
static const FDK_HYBRID_SETUP setup_3_16 = {
|
||||||
13, (13 - 1) / 2, ringbuffIdxTab};
|
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}, {8, 2, 2},
|
static const FDK_HYBRID_SETUP setup_3_12 = {
|
||||||
13, (13 - 1) / 2, ringbuffIdxTab};
|
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}, {-8, -2, 2},
|
static const FDK_HYBRID_SETUP setup_3_10 = {
|
||||||
13, (13 - 1) / 2, ringbuffIdxTab};
|
3, {6, 2, 2}, {3, 2, 2}, {-8, -2, 2}, 13, (13 - 1) / 2, ringbuffIdxTab};
|
||||||
|
|
||||||
static const FIXP_HTP HybFilterCoef8[] = {
|
static const FIXP_HTP HybFilterCoef8[] = {
|
||||||
HTCP(0x10000000, 0x00000000), HTCP(0x0df26407, 0xfa391882),
|
HTCP(0x10000000, 0x00000000), HTCP(0x0df26407, 0xfa391882),
|
||||||
@ -477,17 +478,18 @@ void FDKhybridSynthesisApply(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,
|
|||||||
*/
|
*/
|
||||||
for (k = 0; k < nrQmfBandsLF; k++) {
|
for (k = 0; k < nrQmfBandsLF; k++) {
|
||||||
const int nHybBands = hSynthesisHybFilter->pSetup->nHybBands[k];
|
const int nHybBands = hSynthesisHybFilter->pSetup->nHybBands[k];
|
||||||
|
const int scale = hSynthesisHybFilter->pSetup->synHybScale[k];
|
||||||
|
|
||||||
FIXP_DBL accu1 = FL2FXCONST_DBL(0.f);
|
FIXP_DBL accu1 = FL2FXCONST_DBL(0.f);
|
||||||
FIXP_DBL accu2 = FL2FXCONST_DBL(0.f);
|
FIXP_DBL accu2 = FL2FXCONST_DBL(0.f);
|
||||||
|
|
||||||
/* Perform hybrid filtering. */
|
/* Perform hybrid filtering. */
|
||||||
for (n = 0; n < nHybBands; n++) {
|
for (n = 0; n < nHybBands; n++) {
|
||||||
accu1 += pHybridReal[hybOffset + n];
|
accu1 += pHybridReal[hybOffset + n] >> scale;
|
||||||
accu2 += pHybridImag[hybOffset + n];
|
accu2 += pHybridImag[hybOffset + n] >> scale;
|
||||||
}
|
}
|
||||||
pQmfReal[k] = accu1;
|
pQmfReal[k] = SATURATE_LEFT_SHIFT(accu1, scale, DFRACT_BITS);
|
||||||
pQmfImag[k] = accu2;
|
pQmfImag[k] = SATURATE_LEFT_SHIFT(accu2, scale, DFRACT_BITS);
|
||||||
|
|
||||||
hybOffset += nHybBands;
|
hybOffset += nHybBands;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -106,35 +106,31 @@ amm-info@iis.fraunhofer.de
|
|||||||
#include "common_fix.h"
|
#include "common_fix.h"
|
||||||
|
|
||||||
#define WORKBUFFER1_TAG 0
|
#define WORKBUFFER1_TAG 0
|
||||||
#define WORKBUFFER2_TAG 1
|
|
||||||
|
|
||||||
#define WORKBUFFER3_TAG 4
|
#define WORKBUFFER3_TAG 4
|
||||||
#define WORKBUFFER4_TAG 5
|
#define WORKBUFFER4_TAG 5
|
||||||
#define WORKBUFFER5_TAG 6
|
|
||||||
#define WORKBUFFER6_TAG 7
|
#define WORKBUFFER6_TAG 7
|
||||||
|
#define WORKBUFFER7_TAG 8
|
||||||
|
|
||||||
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
||||||
SECT_DATA_L1, WORKBUFFER1_TAG)
|
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,
|
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
||||||
SECT_DATA_L2, WORKBUFFER3_TAG)
|
SECT_DATA_L2, WORKBUFFER3_TAG)
|
||||||
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
||||||
SECT_DATA_L2, WORKBUFFER4_TAG)
|
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,
|
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL, QMF_WB_SECTION_SIZE,
|
||||||
SECT_DATA_L2, WORKBUFFER6_TAG)
|
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>
|
/*! Analysis states buffer. <br>
|
||||||
Dimension: #((8) + (1)) */
|
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)))
|
((8) + (1)))
|
||||||
|
|
||||||
/*! Synthesis states buffer. <br>
|
/*! Synthesis states buffer. <br>
|
||||||
Dimension: #((8) + (1)) */
|
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)))
|
((8) + (1)))
|
||||||
|
|
||||||
/*! Pointer to real qmf data for each time slot. <br>
|
/*! Pointer to real qmf data for each time slot. <br>
|
||||||
Dimension: #((8) + (1)) */
|
Dimension: #((8) + (1)) */
|
||||||
@ -156,18 +152,17 @@ C_AALLOC_MEM2(QmfOverlapBuffer, FIXP_DBL,
|
|||||||
|
|
||||||
/*! Analysis states buffer. <br>
|
/*! Analysis states buffer. <br>
|
||||||
Dimension: #((8) + (1)) */
|
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)))
|
((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>
|
/*! Analysis states buffer. <br>
|
||||||
Dimension: #((8) + (1)) */
|
Dimension: #((8) + (1)) */
|
||||||
C_ALLOC_MEM2(AnaQmfStates24, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24,
|
C_AALLOC_MEM2(AnaQmfStates32, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32,
|
||||||
((8) + (1)))
|
((8) + (1)))
|
||||||
|
|
||||||
/*! Analysis states buffer. <br>
|
|
||||||
Dimension: #((8) + (1)) */
|
|
||||||
C_ALLOC_MEM2(AnaQmfStates32, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32,
|
|
||||||
((8) + (1)))
|
|
||||||
|
|
||||||
/*! Pointer to real qmf data for each time slot. <br>
|
/*! Pointer to real qmf data for each time slot. <br>
|
||||||
Dimension: #((8) + (1)) */
|
Dimension: #((8) + (1)) */
|
||||||
@ -642,10 +637,10 @@ void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
|
|||||||
|
|
||||||
if (pQmfOutImag == NULL) {
|
if (pQmfOutImag == NULL) {
|
||||||
for (; b < fMin(lsb, stop_band); b++) {
|
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++) {
|
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++) {
|
for (; b < stop_band; b++) {
|
||||||
pQmfOutReal[b] = (FIXP_DBL)0;
|
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 {
|
} else {
|
||||||
FDK_ASSERT(imag != NULL);
|
FDK_ASSERT(imag != NULL);
|
||||||
for (; b < fMin(lsb, stop_band); b++) {
|
for (; b < fMin(lsb, stop_band); b++) {
|
||||||
pQmfOutReal[b] = scaleValue(real[b], lb_sf);
|
pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf);
|
||||||
pQmfOutImag[b] = scaleValue(imag[b], lb_sf);
|
pQmfOutImag[b] = scaleValueSaturate(imag[b], lb_sf);
|
||||||
}
|
}
|
||||||
for (; b < fMin(usb, stop_band); b++) {
|
for (; b < fMin(usb, stop_band); b++) {
|
||||||
pQmfOutReal[b] = scaleValue(real[b], hb_sf);
|
pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf);
|
||||||
pQmfOutImag[b] = scaleValue(imag[b], hb_sf);
|
pQmfOutImag[b] = scaleValueSaturate(imag[b], hb_sf);
|
||||||
}
|
}
|
||||||
for (; b < stop_band; b++) {
|
for (; b < stop_band; b++) {
|
||||||
pQmfOutReal[b] = (FIXP_DBL)0;
|
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)) {
|
if ((size > 4 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[4] == NULL)) {
|
||||||
/* get work buffer of size QMF_WB_SECTION_SIZE */
|
/* get work buffer of size QMF_WB_SECTION_SIZE */
|
||||||
pWorkBuffer[4] = GetQmfWorkBufferCore5();
|
pWorkBuffer[4] = GetQmfWorkBufferCore7();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 8. distribute workbuffer over processing channels */
|
/* 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[1]) FreeQmfWorkBufferCore1(&pWorkBuffer[1]);
|
||||||
if (pWorkBuffer[2]) FreeQmfWorkBufferCore3(&pWorkBuffer[2]);
|
if (pWorkBuffer[2]) FreeQmfWorkBufferCore3(&pWorkBuffer[2]);
|
||||||
if (pWorkBuffer[3]) FreeQmfWorkBufferCore4(&pWorkBuffer[3]);
|
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) {
|
void FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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) {
|
for (i = 0; i < M - 1; i += 2, pDat_0 += 2, pDat_1 -= 2) {
|
||||||
FIXP_DBL accu1, accu2, accu3, accu4;
|
FIXP_DBL accu1, accu2, accu3, accu4;
|
||||||
|
|
||||||
accu1 = pDat_1[1];
|
accu1 = pDat_1[1] >> 1;
|
||||||
accu2 = -pDat_0[0];
|
accu2 = -(pDat_0[0] >> 1);
|
||||||
accu3 = pDat_0[1];
|
accu3 = pDat_0[1] >> 1;
|
||||||
accu4 = -pDat_1[0];
|
accu4 = -(pDat_1[0] >> 1);
|
||||||
|
|
||||||
cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
|
cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
|
||||||
cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
|
cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
|
||||||
|
|
||||||
pDat_0[0] = accu2 >> 1;
|
pDat_0[0] = accu2;
|
||||||
pDat_0[1] = accu1 >> 1;
|
pDat_0[1] = accu1;
|
||||||
pDat_1[0] = accu4 >> 1;
|
pDat_1[0] = accu4;
|
||||||
pDat_1[1] = -(accu3 >> 1);
|
pDat_1[1] = -accu3;
|
||||||
}
|
}
|
||||||
if (M & 1) {
|
if (M & 1) {
|
||||||
FIXP_DBL accu1, accu2;
|
FIXP_DBL accu1, accu2;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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;
|
INT ans_lg2_e, baselg2_e;
|
||||||
FIXP_DBL base_lg2, ans_lg2, result;
|
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 */
|
/* Calc log2 of base */
|
||||||
base_lg2 = fLog2(base_m, base_e, &baselg2_e);
|
base_lg2 = fLog2(base_m, base_e, &baselg2_e);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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++) {
|
for (i = 0; i < hMdct->prev_nr; i++) {
|
||||||
FIXP_DBL x = -(*pOvl--);
|
FIXP_DBL x = -(*pOvl--);
|
||||||
*pOut0 = IMDCT_SCALE_DBL(x + hMdct->pFacZir[i]);
|
*pOut0 = fAddSaturate(x, IMDCT_SCALE_DBL(hMdct->pFacZir[i]));
|
||||||
pOut0++;
|
pOut0++;
|
||||||
}
|
}
|
||||||
hMdct->pFacZir = NULL;
|
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;
|
FIXP_DBL *pOut = pOut0 - fl / 2;
|
||||||
FDK_ASSERT(fl / 2 <= 128);
|
FDK_ASSERT(fl / 2 <= 128);
|
||||||
for (i = 0; i < fl / 2; i++) {
|
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;
|
hMdct->pFacZir = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -147,88 +147,6 @@ amm-info@iis.fraunhofer.de
|
|||||||
/* moved to qmf_pcm.h: -> qmfSynPrototypeFirSlot_NonSymmetric */
|
/* moved to qmf_pcm.h: -> qmfSynPrototypeFirSlot_NonSymmetric */
|
||||||
/* moved to qmf_pcm.h: -> qmfSynthesisFilteringSlot */
|
/* 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
|
* \brief Perform real-valued forward modulation of the time domain
|
||||||
@ -244,7 +162,7 @@ static void qmfForwardModulationLP_even(
|
|||||||
int i;
|
int i;
|
||||||
int L = anaQmf->no_channels;
|
int L = anaQmf->no_channels;
|
||||||
int M = L >> 1;
|
int M = L >> 1;
|
||||||
int scale;
|
int scale = 0;
|
||||||
FIXP_DBL accu;
|
FIXP_DBL accu;
|
||||||
|
|
||||||
const FIXP_DBL *timeInTmp1 = (FIXP_DBL *)&timeIn[3 * M];
|
const FIXP_DBL *timeInTmp1 = (FIXP_DBL *)&timeIn[3 * M];
|
||||||
@ -381,211 +299,6 @@ static void qmfForwardModulationHQ(
|
|||||||
}
|
}
|
||||||
#endif /* FUNCTION_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
|
* \brief Perform low power inverse modulation of the subband
|
||||||
@ -603,15 +316,15 @@ inline static void qmfInverseModulationLP_even(
|
|||||||
int i;
|
int i;
|
||||||
int L = synQmf->no_channels;
|
int L = synQmf->no_channels;
|
||||||
int M = L >> 1;
|
int M = L >> 1;
|
||||||
int scale;
|
int scale = 0;
|
||||||
FIXP_DBL tmp;
|
FIXP_DBL tmp;
|
||||||
FIXP_DBL *RESTRICT tReal = pTimeOut;
|
FIXP_DBL *RESTRICT tReal = pTimeOut;
|
||||||
FIXP_DBL *RESTRICT tImag = pTimeOut + L;
|
FIXP_DBL *RESTRICT tImag = pTimeOut + L;
|
||||||
|
|
||||||
/* Move input to output vector with offset */
|
/* Move input to output vector with offset */
|
||||||
scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand);
|
scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb, scaleFactorLowBand);
|
||||||
scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
|
scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
|
||||||
synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
|
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||||
FDKmemclear(&tReal[0 + synQmf->usb], (L - synQmf->usb) * sizeof(FIXP_DBL));
|
FDKmemclear(&tReal[0 + synQmf->usb], (L - synQmf->usb) * sizeof(FIXP_DBL));
|
||||||
|
|
||||||
/* Dct type-2 transform */
|
/* Dct type-2 transform */
|
||||||
@ -662,9 +375,9 @@ inline static void qmfInverseModulationLP_odd(
|
|||||||
int shift = 0;
|
int shift = 0;
|
||||||
|
|
||||||
/* Move input to output vector with offset */
|
/* Move input to output vector with offset */
|
||||||
scaleValues(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
|
scaleValuesSaturate(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
|
||||||
scaleValues(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
|
scaleValuesSaturate(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
|
||||||
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||||
FDKmemclear(pTimeOut + M + synQmf->usb, (L - synQmf->usb) * sizeof(FIXP_DBL));
|
FDKmemclear(pTimeOut + M + synQmf->usb, (L - synQmf->usb) * sizeof(FIXP_DBL));
|
||||||
|
|
||||||
dct_IV(pTimeOut + M, L, &shift);
|
dct_IV(pTimeOut + M, L, &shift);
|
||||||
@ -698,26 +411,27 @@ inline static void qmfInverseModulationHQ(
|
|||||||
FIXP_DBL *RESTRICT tImag = pWorkBuffer + L;
|
FIXP_DBL *RESTRICT tImag = pWorkBuffer + L;
|
||||||
|
|
||||||
if (synQmf->flags & QMF_FLAG_CLDFB) {
|
if (synQmf->flags & QMF_FLAG_CLDFB) {
|
||||||
for (i = 0; i < synQmf->lsb; i++) {
|
for (i = 0; i < synQmf->usb; i++) {
|
||||||
cplxMult(&tImag[i], &tReal[i], scaleValue(qmfImag[i], scaleFactorLowBand),
|
cplxMultDiv2(&tImag[i], &tReal[i], qmfImag[i], qmfReal[i],
|
||||||
scaleValue(qmfReal[i], scaleFactorLowBand), synQmf->t_cos[i],
|
synQmf->t_cos[i], synQmf->t_sin[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]);
|
|
||||||
}
|
}
|
||||||
|
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) {
|
if ((synQmf->flags & QMF_FLAG_CLDFB) == 0) {
|
||||||
scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand);
|
scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb,
|
||||||
scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
|
scaleFactorLowBand);
|
||||||
synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
|
scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
|
||||||
scaleValues(&tImag[0], &qmfImag[0], synQmf->lsb, (int)scaleFactorLowBand);
|
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||||
scaleValues(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
|
scaleValuesSaturate(&tImag[0], &qmfImag[0], synQmf->lsb,
|
||||||
synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
|
scaleFactorLowBand);
|
||||||
|
scaleValuesSaturate(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
|
||||||
|
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||||
}
|
}
|
||||||
|
|
||||||
FDKmemclear(&tReal[synQmf->usb],
|
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
|
* \brief Create QMF filter bank instance
|
||||||
@ -1128,8 +813,21 @@ void qmfChangeOutGain(
|
|||||||
synQmf->outGain_e = outputGainScale;
|
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 INT_PCM_QMFOUT INT_PCM
|
||||||
#define SAMPLE_BITS_QMFOUT SAMPLE_BITS
|
#define SAMPLE_BITS_QMFOUT SAMPLE_BITS
|
||||||
#include "qmf_pcm.h"
|
#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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -250,10 +250,10 @@ void scaleValuesSaturate(FIXP_DBL *vector, /*!< Vector */
|
|||||||
*/
|
*/
|
||||||
#define FUNCTION_scaleValuesSaturate_DBL_DBL
|
#define FUNCTION_scaleValuesSaturate_DBL_DBL
|
||||||
SCALE_INLINE
|
SCALE_INLINE
|
||||||
void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
|
void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
|
||||||
FIXP_DBL *src, /*!< Input */
|
const FIXP_DBL *src, /*!< Input */
|
||||||
INT len, /*!< Length */
|
INT len, /*!< Length */
|
||||||
INT scalefactor /*!< Scalefactor */
|
INT scalefactor /*!< Scalefactor */
|
||||||
) {
|
) {
|
||||||
INT i;
|
INT i;
|
||||||
|
|
||||||
@ -285,10 +285,10 @@ void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
|
|||||||
*/
|
*/
|
||||||
#define FUNCTION_scaleValuesSaturate_SGL_DBL
|
#define FUNCTION_scaleValuesSaturate_SGL_DBL
|
||||||
SCALE_INLINE
|
SCALE_INLINE
|
||||||
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
|
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
|
||||||
FIXP_DBL *src, /*!< Input */
|
const FIXP_DBL *src, /*!< Input */
|
||||||
INT len, /*!< Length */
|
INT len, /*!< Length */
|
||||||
INT scalefactor) /*!< Scalefactor */
|
INT scalefactor) /*!< Scalefactor */
|
||||||
{
|
{
|
||||||
INT i;
|
INT i;
|
||||||
scalefactor = fixmax_I(fixmin_I(scalefactor, (INT)DFRACT_BITS - 1),
|
scalefactor = fixmax_I(fixmin_I(scalefactor, (INT)DFRACT_BITS - 1),
|
||||||
@ -345,10 +345,10 @@ void scaleValuesSaturate(FIXP_SGL *vector, /*!< Vector */
|
|||||||
*/
|
*/
|
||||||
#define FUNCTION_scaleValuesSaturate_SGL_SGL
|
#define FUNCTION_scaleValuesSaturate_SGL_SGL
|
||||||
SCALE_INLINE
|
SCALE_INLINE
|
||||||
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
|
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
|
||||||
FIXP_SGL *src, /*!< Input */
|
const FIXP_SGL *src, /*!< Input */
|
||||||
INT len, /*!< Length */
|
INT len, /*!< Length */
|
||||||
INT scalefactor /*!< Scalefactor */
|
INT scalefactor /*!< Scalefactor */
|
||||||
) {
|
) {
|
||||||
INT i;
|
INT i;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -213,8 +213,8 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts,
|
|||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FDKcrcReset(&pAdts->crcInfo);
|
||||||
if (!bs.protection_absent) {
|
if (!bs.protection_absent) {
|
||||||
FDKcrcReset(&pAdts->crcInfo);
|
|
||||||
FDKpushBack(hBs, 56); /* complete fixed and variable header! */
|
FDKpushBack(hBs, 56); /* complete fixed and variable header! */
|
||||||
crcReg = FDKcrcStartReg(&pAdts->crcInfo, hBs, 0);
|
crcReg = FDKcrcStartReg(&pAdts->crcInfo, hBs, 0);
|
||||||
FDKpushFor(hBs, 56);
|
FDKpushFor(hBs, 56);
|
||||||
@ -314,15 +314,55 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts,
|
|||||||
if (bs.channel_config == 0) {
|
if (bs.channel_config == 0) {
|
||||||
int pceBits = 0;
|
int pceBits = 0;
|
||||||
UINT alignAnchor = FDKgetValidBits(hBs);
|
UINT alignAnchor = FDKgetValidBits(hBs);
|
||||||
|
CProgramConfig tmpPce;
|
||||||
|
|
||||||
if (FDKreadBits(hBs, 3) == ID_PCE) {
|
if (FDKreadBits(hBs, 3) == ID_PCE) {
|
||||||
/* Got luck! Parse the PCE */
|
/* Got luck! Parse the PCE */
|
||||||
crcReg = adtsRead_CrcStartReg(pAdts, hBs, 0);
|
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);
|
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 */
|
/* store the number of PCE bits */
|
||||||
bs.num_pce_bits = pceBits;
|
bs.num_pce_bits = pceBits;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -1325,9 +1325,9 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
|
|||||||
CSTpCallBacks *cb) {
|
CSTpCallBacks *cb) {
|
||||||
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
|
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
|
||||||
CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig;
|
CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig;
|
||||||
ASC_ELD_EXT_TYPE eldExtType;
|
UINT eldExtType;
|
||||||
int eldExtLen, len, cnt, ldSbrLen = 0, eldExtLenSum, numSbrHeader = 0,
|
int eldExtLen, len, cnt, ldSbrLen = 0, eldExtLenSum, numSbrHeader = 0,
|
||||||
sbrIndex;
|
sbrIndex, eldExtCnt = 0;
|
||||||
|
|
||||||
unsigned char downscale_fill_nibble;
|
unsigned char downscale_fill_nibble;
|
||||||
|
|
||||||
@ -1394,9 +1394,8 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
|
|||||||
eldExtLenSum = FDKgetValidBits(hBs);
|
eldExtLenSum = FDKgetValidBits(hBs);
|
||||||
esc->m_downscaledSamplingFrequency = asc->m_samplingFrequency;
|
esc->m_downscaledSamplingFrequency = asc->m_samplingFrequency;
|
||||||
/* parse ExtTypeConfigData */
|
/* parse ExtTypeConfigData */
|
||||||
while (
|
while (((eldExtType = FDKreadBits(hBs, 4)) != ELDEXT_TERM) &&
|
||||||
((eldExtType = (ASC_ELD_EXT_TYPE)FDKreadBits(hBs, 4)) != ELDEXT_TERM) &&
|
((INT)FDKgetValidBits(hBs) >= 0) && (eldExtCnt++ < 15)) {
|
||||||
((INT)FDKgetValidBits(hBs) >= 0)) {
|
|
||||||
eldExtLen = len = FDKreadBits(hBs, 4);
|
eldExtLen = len = FDKreadBits(hBs, 4);
|
||||||
if (len == 0xf) {
|
if (len == 0xf) {
|
||||||
len = FDKreadBits(hBs, 8);
|
len = FDKreadBits(hBs, 8);
|
||||||
@ -1440,7 +1439,8 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
|
|||||||
UCHAR tmpDownscaleFreqIdx;
|
UCHAR tmpDownscaleFreqIdx;
|
||||||
esc->m_downscaledSamplingFrequency =
|
esc->m_downscaledSamplingFrequency =
|
||||||
getSampleRate(hBs, &tmpDownscaleFreqIdx, 4);
|
getSampleRate(hBs, &tmpDownscaleFreqIdx, 4);
|
||||||
if (esc->m_downscaledSamplingFrequency == 0) {
|
if (esc->m_downscaledSamplingFrequency == 0 ||
|
||||||
|
esc->m_downscaledSamplingFrequency > 96000) {
|
||||||
return TRANSPORTDEC_PARSE_ERROR;
|
return TRANSPORTDEC_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
downscale_fill_nibble = FDKreadBits(hBs, 4);
|
downscale_fill_nibble = FDKreadBits(hBs, 4);
|
||||||
@ -1454,6 +1454,9 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (eldExtType != ELDEXT_TERM) {
|
||||||
|
return TRANSPORTDEC_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if ((INT)FDKgetValidBits(hBs) < 0) {
|
if ((INT)FDKgetValidBits(hBs) < 0) {
|
||||||
return TRANSPORTDEC_PARSE_ERROR;
|
return TRANSPORTDEC_PARSE_ERROR;
|
||||||
@ -1948,6 +1951,9 @@ static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc,
|
|||||||
INT nbits = (INT)FDKgetValidBits(hBs);
|
INT nbits = (INT)FDKgetValidBits(hBs);
|
||||||
|
|
||||||
usacSamplingFrequency = getSampleRate(hBs, &asc->m_samplingFrequencyIndex, 5);
|
usacSamplingFrequency = getSampleRate(hBs, &asc->m_samplingFrequencyIndex, 5);
|
||||||
|
if (usacSamplingFrequency == 0 || usacSamplingFrequency > 96000) {
|
||||||
|
return TRANSPORTDEC_PARSE_ERROR;
|
||||||
|
}
|
||||||
asc->m_samplingFrequency = (UINT)usacSamplingFrequency;
|
asc->m_samplingFrequency = (UINT)usacSamplingFrequency;
|
||||||
|
|
||||||
coreSbrFrameLengthIndex = FDKreadBits(hBs, 3);
|
coreSbrFrameLengthIndex = FDKreadBits(hBs, 3);
|
||||||
@ -2027,7 +2033,8 @@ static TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(
|
|||||||
self->m_extensionSamplingFrequency = getSampleRate(
|
self->m_extensionSamplingFrequency = getSampleRate(
|
||||||
bs, &self->m_extensionSamplingFrequencyIndex, 4);
|
bs, &self->m_extensionSamplingFrequencyIndex, 4);
|
||||||
|
|
||||||
if ((INT)self->m_extensionSamplingFrequency <= 0) {
|
if (self->m_extensionSamplingFrequency == 0 ||
|
||||||
|
self->m_extensionSamplingFrequency > 96000) {
|
||||||
return TRANSPORTDEC_PARSE_ERROR;
|
return TRANSPORTDEC_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2139,6 +2146,24 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
|
|||||||
|
|
||||||
self->m_channelConfiguration = FDKreadBits(bs, 4);
|
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 ) */
|
/* SBR extension ( explicit non-backwards compatible mode ) */
|
||||||
self->m_sbrPresentFlag = 0;
|
self->m_sbrPresentFlag = 0;
|
||||||
self->m_psPresentFlag = 0;
|
self->m_psPresentFlag = 0;
|
||||||
@ -2153,6 +2178,10 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
|
|||||||
|
|
||||||
self->m_extensionSamplingFrequency =
|
self->m_extensionSamplingFrequency =
|
||||||
getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
|
getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
|
||||||
|
if (self->m_extensionSamplingFrequency == 0 ||
|
||||||
|
self->m_extensionSamplingFrequency > 96000) {
|
||||||
|
return TRANSPORTDEC_PARSE_ERROR;
|
||||||
|
}
|
||||||
self->m_aot = getAOT(bs);
|
self->m_aot = getAOT(bs);
|
||||||
|
|
||||||
switch (self->m_aot) {
|
switch (self->m_aot) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -367,10 +367,10 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig(
|
|||||||
}
|
}
|
||||||
if (pLatmDemux->m_AudioMuxVersion == 1) {
|
if (pLatmDemux->m_AudioMuxVersion == 1) {
|
||||||
FDK_BITSTREAM tmpBs;
|
FDK_BITSTREAM tmpBs;
|
||||||
UINT ascLen = 0;
|
INT ascLen = 0;
|
||||||
ascLen = CLatmDemux_GetValue(bs);
|
ascLen = CLatmDemux_GetValue(bs);
|
||||||
/* The ascLen could be wrong, so check if validBits<=bufBits*/
|
/* 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;
|
ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -482,7 +482,8 @@ TRANSPORTDEC_ERROR transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,
|
|||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
FDKpushBack(hBs, newConfigLength * 8 - FDKgetValidBits(hBs));
|
FDKpushBack(hBs,
|
||||||
|
(INT)newConfigLength * 8 - (INT)FDKgetValidBits(hBs));
|
||||||
configMode = AC_CM_ALLOC_MEM;
|
configMode = AC_CM_ALLOC_MEM;
|
||||||
}
|
}
|
||||||
/* config transport decoder */
|
/* config transport decoder */
|
||||||
@ -663,10 +664,14 @@ TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
|
|||||||
if (*pBytesValid == 0) {
|
if (*pBytesValid == 0) {
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
return TRANSPORTDEC_OK;
|
return TRANSPORTDEC_OK;
|
||||||
}
|
} else {
|
||||||
|
const int bytesValid = *pBytesValid;
|
||||||
if (hTp->numberOfRawDataBlocks <= 0) {
|
|
||||||
FDKfeedBuffer(hBs, pBuffer, bufferSize, 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 {
|
} else {
|
||||||
/* Reset CRC because the next bits are the beginning of a
|
/* 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);
|
CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
|
||||||
if (hTp->transportFmt == TT_MP4_LOAS) {
|
if (hTp->transportFmt == TT_MP4_LOAS) {
|
||||||
syncLayerFrameBits -= startPos - (INT)FDKgetValidBits(hBs) - (13);
|
syncLayerFrameBits -= startPos - (INT)FDKgetValidBits(hBs) - (13);
|
||||||
|
if (syncLayerFrameBits <= 0) {
|
||||||
|
err = TRANSPORTDEC_SYNC_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1151,6 +1164,11 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
|
|||||||
&rawDataBlockLength, &fTraverseMoreFrames,
|
&rawDataBlockLength, &fTraverseMoreFrames,
|
||||||
&syncLayerFrameBits, &fConfigFound,
|
&syncLayerFrameBits, &fConfigFound,
|
||||||
&headerBits);
|
&headerBits);
|
||||||
|
if (headerBits > bitsAvail) {
|
||||||
|
err = (headerBits < (INT)hBs->hBitBuf.bufBits)
|
||||||
|
? TRANSPORTDEC_NOT_ENOUGH_BITS
|
||||||
|
: TRANSPORTDEC_SYNC_ERROR;
|
||||||
|
}
|
||||||
if (TPDEC_IS_FATAL_ERROR(err)) {
|
if (TPDEC_IS_FATAL_ERROR(err)) {
|
||||||
/* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
|
/* 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
|
* 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) {
|
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
|
||||||
/* Enforce reading of new data */
|
|
||||||
hTp->numberOfRawDataBlocks = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1263,8 +1279,9 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
|
|||||||
if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS |
|
if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS |
|
||||||
TPDEC_SYNCOK)) &&
|
TPDEC_SYNCOK)) &&
|
||||||
err == TRANSPORTDEC_OK) {
|
err == TRANSPORTDEC_OK) {
|
||||||
err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
|
err =
|
||||||
FDKgetValidBits(hBs) - syncLayerFrameBits);
|
additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
|
||||||
|
(INT)FDKgetValidBits(hBs) - syncLayerFrameBits);
|
||||||
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
|
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
|
||||||
hTp->holdOffFrames++;
|
hTp->holdOffFrames++;
|
||||||
}
|
}
|
||||||
@ -1273,7 +1290,9 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
|
|||||||
/* Rewind for retry because of not enough bits */
|
/* Rewind for retry because of not enough bits */
|
||||||
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
|
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
|
||||||
FDKpushBack(hBs, headerBits);
|
FDKpushBack(hBs, headerBits);
|
||||||
|
hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
|
||||||
headerBits = 0;
|
headerBits = 0;
|
||||||
|
rawDataBlockLength = rawDataBlockLengthPrevious;
|
||||||
} else {
|
} else {
|
||||||
/* reset hold off frame counter */
|
/* reset hold off frame counter */
|
||||||
hTp->holdOffFrames = 0;
|
hTp->holdOffFrames = 0;
|
||||||
@ -1460,7 +1479,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
|
|||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
FDKpushBack(hBs, bsStart - FDKgetValidBits(hBs));
|
FDKpushBack(hBs, bsStart - (INT)FDKgetValidBits(hBs));
|
||||||
configMode = AC_CM_ALLOC_MEM;
|
configMode = AC_CM_ALLOC_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -109,8 +109,6 @@ amm-info@iis.fraunhofer.de
|
|||||||
#define TDL_ATTACK_DEFAULT_MS (15) /* default attack time in ms */
|
#define TDL_ATTACK_DEFAULT_MS (15) /* default attack time in ms */
|
||||||
#define TDL_RELEASE_DEFAULT_MS (50) /* default release 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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -128,10 +126,7 @@ struct TDLimiter {
|
|||||||
unsigned int maxBufIdx, delayBufIdx;
|
unsigned int maxBufIdx, delayBufIdx;
|
||||||
FIXP_DBL smoothState0;
|
FIXP_DBL smoothState0;
|
||||||
FIXP_DBL minGain;
|
FIXP_DBL minGain;
|
||||||
|
INT scaling;
|
||||||
FIXP_DBL additionalGainPrev;
|
|
||||||
FIXP_DBL additionalGainFilterState;
|
|
||||||
FIXP_DBL additionalGainFilterState1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -255,27 +250,16 @@ TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter,
|
|||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* pcmLimiter_Apply *
|
* pcmLimiter_Apply *
|
||||||
* limiter: limiter handle *
|
* limiter: limiter handle *
|
||||||
* pGain : pointer to gains to be applied to the signal before limiting, *
|
* samplesIn: pointer to input buffer containing interleaved samples *
|
||||||
* which are downscaled by TDL_GAIN_SCALING bit. *
|
* samplesOut: pointer to output buffer containing interleaved samples *
|
||||||
* These gains are delayed by gain_delay, and smoothed. *
|
* pGainPerSample: pointer to gains for each sample *
|
||||||
* Smoothing is done by a butterworth lowpass filter with a cutoff *
|
* scaling: scaling of output samples *
|
||||||
* frequency which is fixed with respect to the sampling rate. *
|
* nSamples: number of samples per channel *
|
||||||
* It is a substitute for the smoothing due to windowing and *
|
|
||||||
* overlap/add, if a gain is applied in frequency domain. *
|
|
||||||
* gain_scale: pointer to scaling exponents to be applied to the signal before *
|
|
||||||
* limiting, without delay and without smoothing *
|
|
||||||
* gain_size: number of elements in pGain, currently restricted to 1 *
|
|
||||||
* gain_delay: delay [samples] with which the gains in pGain shall be applied *
|
|
||||||
* gain_delay <= nSamples *
|
|
||||||
* samples: input/output buffer containing interleaved samples *
|
|
||||||
* precision of output will be DFRACT_BITS-TDL_GAIN_SCALING bits *
|
|
||||||
* nSamples: number of samples per channel *
|
|
||||||
* returns: error code *
|
* returns: error code *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
|
TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
|
||||||
INT_PCM* samplesOut, FIXP_DBL* pGain,
|
INT_PCM* samplesOut, FIXP_DBL* pGainPerSample,
|
||||||
const INT* gain_scale, const UINT gain_size,
|
const INT scaling, const UINT nSamples);
|
||||||
const UINT gain_delay, const UINT nSamples);
|
|
||||||
|
|
||||||
#endif /* #ifndef LIMITER_H */
|
#endif /* #ifndef LIMITER_H */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -152,7 +152,7 @@ TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs,
|
|||||||
limiter->attack = attack;
|
limiter->attack = attack;
|
||||||
limiter->attackConst = attackConst;
|
limiter->attackConst = attackConst;
|
||||||
limiter->releaseConst = releaseConst;
|
limiter->releaseConst = releaseConst;
|
||||||
limiter->threshold = threshold >> TDL_GAIN_SCALING;
|
limiter->threshold = threshold;
|
||||||
limiter->channels = maxChannels;
|
limiter->channels = maxChannels;
|
||||||
limiter->maxChannels = maxChannels;
|
limiter->maxChannels = maxChannels;
|
||||||
limiter->sampleRate = maxSampleRate;
|
limiter->sampleRate = maxSampleRate;
|
||||||
@ -165,18 +165,13 @@ TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs,
|
|||||||
|
|
||||||
/* apply limiter */
|
/* apply limiter */
|
||||||
TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
|
TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
|
||||||
INT_PCM* samplesOut, FIXP_DBL* RESTRICT pGain,
|
INT_PCM* samplesOut, FIXP_DBL* pGainPerSample,
|
||||||
const INT* RESTRICT gain_scale,
|
const INT scaling, const UINT nSamples) {
|
||||||
const UINT gain_size, const UINT gain_delay,
|
|
||||||
const UINT nSamples) {
|
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
FIXP_DBL tmp1;
|
|
||||||
FIXP_DBL tmp2;
|
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));
|
FIXP_DBL minGain = FL2FXCONST_DBL(1.0f / (1 << 1));
|
||||||
|
UINT additionalGainAvailable = 1;
|
||||||
FDK_ASSERT(gain_size == 1);
|
|
||||||
FDK_ASSERT(gain_delay <= nSamples);
|
|
||||||
|
|
||||||
if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
|
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;
|
unsigned int attack = limiter->attack;
|
||||||
FIXP_DBL attackConst = limiter->attackConst;
|
FIXP_DBL attackConst = limiter->attackConst;
|
||||||
FIXP_DBL releaseConst = limiter->releaseConst;
|
FIXP_DBL releaseConst = limiter->releaseConst;
|
||||||
FIXP_DBL threshold = limiter->threshold;
|
FIXP_DBL threshold = limiter->threshold >> scaling;
|
||||||
|
|
||||||
FIXP_DBL max = limiter->max;
|
FIXP_DBL max = limiter->max;
|
||||||
FIXP_DBL* maxBuf = limiter->maxBuf;
|
FIXP_DBL* maxBuf = limiter->maxBuf;
|
||||||
@ -195,55 +190,34 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
|
|||||||
unsigned int delayBufIdx = limiter->delayBufIdx;
|
unsigned int delayBufIdx = limiter->delayBufIdx;
|
||||||
|
|
||||||
FIXP_DBL smoothState0 = limiter->smoothState0;
|
FIXP_DBL smoothState0 = limiter->smoothState0;
|
||||||
FIXP_DBL additionalGainSmoothState = limiter->additionalGainFilterState;
|
|
||||||
FIXP_DBL additionalGainSmoothState1 = limiter->additionalGainFilterState1;
|
|
||||||
|
|
||||||
if (!gain_delay) {
|
if (limiter->scaling != scaling) {
|
||||||
additionalGain = pGain[0];
|
scaleValuesSaturate(delayBuf, attack * channels,
|
||||||
if (gain_scale[0] > 0) {
|
limiter->scaling - scaling);
|
||||||
additionalGain <<= gain_scale[0];
|
scaleValuesSaturate(maxBuf, attack + 1, limiter->scaling - scaling);
|
||||||
} else {
|
max = scaleValueSaturate(max, limiter->scaling - scaling);
|
||||||
additionalGain >>= -gain_scale[0];
|
limiter->scaling = scaling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pGainPerSample == NULL) {
|
||||||
|
additionalGainAvailable = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < nSamples; i++) {
|
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
|
/* get maximum absolute sample value of all channels, including the
|
||||||
* additional gain. */
|
* additional gain. */
|
||||||
tmp1 = (FIXP_DBL)0;
|
tmp = (FIXP_DBL)0;
|
||||||
for (j = 0; j < channels; j++) {
|
for (j = 0; j < channels; j++) {
|
||||||
tmp2 = PCM_LIM2FIXP_DBL(samplesIn[j]);
|
tmp2 = PCM_LIM2FIXP_DBL(samplesIn[j]);
|
||||||
tmp2 = fAbs(tmp2);
|
tmp2 =
|
||||||
tmp2 = FIXP_DBL(INT(tmp2) ^ INT((tmp2 >> (SAMPLE_BITS_LIM - 1))));
|
(tmp2 == (FIXP_DBL)MINVAL_DBL) ? (FIXP_DBL)MAXVAL_DBL : fAbs(tmp2);
|
||||||
tmp1 = fMax(tmp1, tmp2);
|
tmp = fMax(tmp, tmp2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalGainAvailable) {
|
||||||
|
additionalGain = pGainPerSample[i];
|
||||||
|
tmp = fMult(tmp, additionalGain);
|
||||||
}
|
}
|
||||||
tmp = fMult(tmp1, additionalGain);
|
|
||||||
|
|
||||||
/* set threshold as lower border to save calculations in running maximum
|
/* set threshold as lower border to save calculations in running maximum
|
||||||
* algorithm */
|
* algorithm */
|
||||||
@ -314,22 +288,42 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
|
|||||||
/* lookahead delay, apply gain */
|
/* lookahead delay, apply gain */
|
||||||
for (j = 0; j < channels; j++) {
|
for (j = 0; j < channels; j++) {
|
||||||
tmp = p_delayBuf[j];
|
tmp = p_delayBuf[j];
|
||||||
p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
|
|
||||||
|
if (additionalGainAvailable) {
|
||||||
|
p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
|
||||||
|
} else {
|
||||||
|
p_delayBuf[j] = PCM_LIM2FIXP_DBL(samplesIn[j]);
|
||||||
|
}
|
||||||
|
|
||||||
/* Apply gain to delayed signal */
|
/* Apply gain to delayed signal */
|
||||||
tmp = fMultDiv2(tmp, gain);
|
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(
|
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;
|
gain >>= 1;
|
||||||
} else {
|
} else {
|
||||||
/* lookahead delay, apply gain=1.0f */
|
/* lookahead delay, apply gain=1.0f */
|
||||||
for (j = 0; j < channels; j++) {
|
for (j = 0; j < channels; j++) {
|
||||||
tmp = p_delayBuf[j];
|
tmp = p_delayBuf[j];
|
||||||
p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
|
if (additionalGainAvailable) {
|
||||||
|
p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
|
||||||
|
} else {
|
||||||
|
p_delayBuf[j] = PCM_LIM2FIXP_DBL(samplesIn[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (SAMPLE_BITS == DFRACT_BITS)
|
||||||
|
samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM(
|
||||||
|
(FIXP_DBL)SATURATE_LEFT_SHIFT(tmp, scaling, DFRACT_BITS));
|
||||||
|
#else
|
||||||
samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT(
|
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->delayBufIdx = delayBufIdx;
|
||||||
|
|
||||||
limiter->smoothState0 = smoothState0;
|
limiter->smoothState0 = smoothState0;
|
||||||
limiter->additionalGainFilterState = additionalGainSmoothState;
|
|
||||||
limiter->additionalGainFilterState1 = additionalGainSmoothState1;
|
|
||||||
|
|
||||||
limiter->minGain = minGain;
|
limiter->minGain = minGain;
|
||||||
|
|
||||||
limiter->additionalGainPrev = pGain[0];
|
|
||||||
|
|
||||||
return TDLIMIT_OK;
|
return TDLIMIT_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,7 +360,7 @@ TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter,
|
|||||||
FIXP_DBL threshold) {
|
FIXP_DBL threshold) {
|
||||||
if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
|
if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
|
||||||
|
|
||||||
limiter->threshold = threshold >> TDL_GAIN_SCALING;
|
limiter->threshold = threshold;
|
||||||
|
|
||||||
return TDLIMIT_OK;
|
return TDLIMIT_OK;
|
||||||
}
|
}
|
||||||
@ -384,13 +374,7 @@ TDLIMITER_ERROR pcmLimiter_Reset(TDLimiterPtr limiter) {
|
|||||||
limiter->cor = FL2FXCONST_DBL(1.0f / (1 << 1));
|
limiter->cor = FL2FXCONST_DBL(1.0f / (1 << 1));
|
||||||
limiter->smoothState0 = FL2FXCONST_DBL(1.0f / (1 << 1));
|
limiter->smoothState0 = FL2FXCONST_DBL(1.0f / (1 << 1));
|
||||||
limiter->minGain = FL2FXCONST_DBL(1.0f / (1 << 1));
|
limiter->minGain = FL2FXCONST_DBL(1.0f / (1 << 1));
|
||||||
|
limiter->scaling = 0;
|
||||||
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));
|
|
||||||
|
|
||||||
FDKmemset(limiter->maxBuf, 0, (limiter->attack + 1) * sizeof(FIXP_DBL));
|
FDKmemset(limiter->maxBuf, 0, (limiter->attack + 1) * sizeof(FIXP_DBL));
|
||||||
FDKmemset(limiter->delayBuf, 0,
|
FDKmemset(limiter->delayBuf, 0,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -105,7 +105,7 @@ amm-info@iis.fraunhofer.de
|
|||||||
|
|
||||||
/* library info */
|
/* library info */
|
||||||
#define PCMUTIL_LIB_VL0 3
|
#define PCMUTIL_LIB_VL0 3
|
||||||
#define PCMUTIL_LIB_VL1 0
|
#define PCMUTIL_LIB_VL1 1
|
||||||
#define PCMUTIL_LIB_VL2 0
|
#define PCMUTIL_LIB_VL2 0
|
||||||
#define PCMUTIL_LIB_TITLE "PCM Utility Lib"
|
#define PCMUTIL_LIB_TITLE "PCM Utility Lib"
|
||||||
#ifdef SUPPRESS_BUILD_DATE_INFO
|
#ifdef SUPPRESS_BUILD_DATE_INFO
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -252,7 +252,7 @@ typedef enum {
|
|||||||
scenario. Default parameter value is 3 frames. */
|
scenario. Default parameter value is 3 frames. */
|
||||||
} SACDEC_PARAM;
|
} SACDEC_PARAM;
|
||||||
|
|
||||||
#define PCM_MPS INT_PCM
|
#define PCM_MPS LONG
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief MPEG Surround decoder handle.
|
* \brief MPEG Surround decoder handle.
|
||||||
@ -401,17 +401,22 @@ int mpegSurroundDecoder_Parse(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
|||||||
* for each output audio channel is stored into.
|
* for each output audio channel is stored into.
|
||||||
* \param mapDescr Channep map descriptor for output channel mapping
|
* \param mapDescr Channep map descriptor for output channel mapping
|
||||||
* to be used (From MPEG PCE ordering to whatever is required).
|
* 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.
|
* \return Error code.
|
||||||
*/
|
*/
|
||||||
int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
||||||
INT_PCM *input, PCM_MPS *pTimeData,
|
PCM_MPS *input, PCM_MPS *pTimeData,
|
||||||
const int timeDataSize, int timeDataFrameSize,
|
const int timeDataSize, int timeDataFrameSize,
|
||||||
int *nChannels, int *frameSize, int sampleRate,
|
int *nChannels, int *frameSize, int sampleRate,
|
||||||
AUDIO_OBJECT_TYPE coreCodec,
|
AUDIO_OBJECT_TYPE coreCodec,
|
||||||
AUDIO_CHANNEL_TYPE channelType[],
|
AUDIO_CHANNEL_TYPE channelType[],
|
||||||
UCHAR channelIndices[],
|
UCHAR channelIndices[],
|
||||||
const FDK_channelMapDescr *const mapDescr);
|
const FDK_channelMapDescr *const mapDescr,
|
||||||
|
const INT inDataHeadroom, INT *outDataHeadroom);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Deallocate a MPEG Surround decoder instance.
|
* \brief Deallocate a MPEG Surround decoder instance.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -1554,22 +1554,20 @@ static SACDEC_ERROR mapIndexData(
|
|||||||
/* Interpolate */
|
/* Interpolate */
|
||||||
i1 = 0;
|
i1 = 0;
|
||||||
for (i = 0; i < numParameterSets; i++) {
|
for (i = 0; i < numParameterSets; i++) {
|
||||||
int xi, i2, x1, x2;
|
|
||||||
|
|
||||||
if (aInterpolate[i] != 1) {
|
if (aInterpolate[i] != 1) {
|
||||||
i1 = i;
|
i1 = i;
|
||||||
}
|
} else {
|
||||||
i2 = i;
|
int xi, i2, x1, x2;
|
||||||
while (aInterpolate[i2] == 1) {
|
|
||||||
i2++;
|
|
||||||
if (i2 >= MAX_PARAMETER_SETS) return MPS_WRONG_PARAMETERSETS;
|
|
||||||
}
|
|
||||||
x1 = paramSlot[i1];
|
|
||||||
xi = paramSlot[i];
|
|
||||||
x2 = paramSlot[i2];
|
|
||||||
|
|
||||||
if (aInterpolate[i] == 1) {
|
for (i2 = i; i2 < numParameterSets; i2++) {
|
||||||
|
if (aInterpolate[i2] != 1) break;
|
||||||
|
}
|
||||||
if (i2 >= numParameterSets) return MPS_WRONG_PARAMETERSETS;
|
if (i2 >= numParameterSets) return MPS_WRONG_PARAMETERSETS;
|
||||||
|
|
||||||
|
x1 = paramSlot[i1];
|
||||||
|
xi = paramSlot[i];
|
||||||
|
x2 = paramSlot[i2];
|
||||||
|
|
||||||
for (band = startBand; band < stopBand; band++) {
|
for (band = startBand; band < stopBand; band++) {
|
||||||
int yi, y1, y2;
|
int yi, y1, y2;
|
||||||
y1 = outputIdxData[xttIdx][i1][band];
|
y1 = outputIdxData[xttIdx][i1][band];
|
||||||
@ -1588,9 +1586,9 @@ static SACDEC_ERROR mapIndexData(
|
|||||||
for (ps = 0; ps < numParameterSets; ps++) {
|
for (ps = 0; ps < numParameterSets; ps++) {
|
||||||
if (quantMode && (paramType == t_CLD)) {
|
if (quantMode && (paramType == t_CLD)) {
|
||||||
if (pOttVsTotDbIn == 0) return MPS_WRONG_OTT;
|
if (pOttVsTotDbIn == 0) return MPS_WRONG_OTT;
|
||||||
if ((pOttVsTotDb1 == 0) && (ottVsTotDbMode == ottVsTotDb1Activ))
|
if ((pOttVsTotDb1 == 0) && (ottVsTotDbMode & ottVsTotDb1Activ))
|
||||||
return MPS_WRONG_OTT;
|
return MPS_WRONG_OTT;
|
||||||
if ((pOttVsTotDb2 == 0) && (ottVsTotDbMode == ottVsTotDb2Activ))
|
if ((pOttVsTotDb2 == 0) && (ottVsTotDbMode & ottVsTotDb2Activ))
|
||||||
return MPS_WRONG_OTT;
|
return MPS_WRONG_OTT;
|
||||||
|
|
||||||
for (pb = startBand; pb < stopBand; pb++) {
|
for (pb = startBand; pb < stopBand; pb++) {
|
||||||
@ -1612,6 +1610,10 @@ static SACDEC_ERROR mapIndexData(
|
|||||||
} /* for( i = 0 ; i < numParameterSets; i++ ) */
|
} /* for( i = 0 ; i < numParameterSets; i++ ) */
|
||||||
|
|
||||||
if (extendFrame) {
|
if (extendFrame) {
|
||||||
|
if (paramType == t_IPD) {
|
||||||
|
llData->bsQuantCoarseXXX[numParameterSets] =
|
||||||
|
llData->bsQuantCoarseXXX[numParameterSets - 1];
|
||||||
|
}
|
||||||
for (band = startBand; band < stopBand; band++) {
|
for (band = startBand; band < stopBand; band++) {
|
||||||
outputDataIdx[xttIdx][numParameterSets][band] =
|
outputDataIdx[xttIdx][numParameterSets][band] =
|
||||||
outputDataIdx[xttIdx][numParameterSets - 1][band];
|
outputDataIdx[xttIdx][numParameterSets - 1][band];
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -117,6 +117,9 @@ amm-info@iis.fraunhofer.de
|
|||||||
/* Scaling of spectral data after applying M2 matrix, but only for binaural
|
/* Scaling of spectral data after applying M2 matrix, but only for binaural
|
||||||
upmix type Scaling is compensated later in synthesis qmf filterbank */
|
upmix type Scaling is compensated later in synthesis qmf filterbank */
|
||||||
#define SCALE_DATA_APPLY_M2 (1)
|
#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,
|
SACDEC_ERROR initM1andM2(spatialDec* self, int initStatesFlag,
|
||||||
int configChanged);
|
int configChanged);
|
||||||
|
@ -766,7 +766,7 @@ SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
|
|||||||
|
|
||||||
/* output scaling */
|
/* output scaling */
|
||||||
for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) {
|
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);
|
FIXP_DBL outputGain_m = getChGain(self, nCh, &outputGain_e);
|
||||||
|
|
||||||
if (!isTwoChMode(self->upmixType) && !bypassMode) {
|
if (!isTwoChMode(self->upmixType) && !bypassMode) {
|
||||||
@ -775,7 +775,7 @@ SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
|
|||||||
synthesis qmf */
|
synthesis qmf */
|
||||||
}
|
}
|
||||||
|
|
||||||
scale = outputScale;
|
scale += outputScale;
|
||||||
|
|
||||||
qmfChangeOutScalefactor(&self->pQmfDomain->QmfDomainOut[nCh].fb, scale);
|
qmfChangeOutScalefactor(&self->pQmfDomain->QmfDomainOut[nCh].fb, scale);
|
||||||
qmfChangeOutGain(&self->pQmfDomain->QmfDomainOut[nCh].fb, outputGain_m,
|
qmfChangeOutGain(&self->pQmfDomain->QmfDomainOut[nCh].fb, outputGain_m,
|
||||||
@ -1223,18 +1223,24 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
|
|||||||
!(self->stereoConfigIndex == 3)) {
|
!(self->stereoConfigIndex == 3)) {
|
||||||
for (i = 0; i < self->qmfBands; i++) {
|
for (i = 0; i < self->qmfBands; i++) {
|
||||||
self_qmfResidualReal__FDK_0_0[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->clipProtectGain__FDK);
|
||||||
self_qmfResidualImag__FDK_0_0[i] =
|
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);
|
self->clipProtectGain__FDK);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < self->qmfBands; i++) {
|
for (i = 0; i < self->qmfBands; i++) {
|
||||||
self_qmfResidualReal__FDK_0_0[i] = fMult(
|
self_qmfResidualReal__FDK_0_0[i] =
|
||||||
self_qmfResidualReal__FDK_0_0[i], self->clipProtectGain__FDK);
|
fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i],
|
||||||
self_qmfResidualImag__FDK_0_0[i] = fMult(
|
self->sacInDataHeadroom - (1)),
|
||||||
self_qmfResidualImag__FDK_0_0[i], self->clipProtectGain__FDK);
|
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))) {
|
if ((self->tempShapeConfig == 1) && (!isTwoChMode(self->upmixType))) {
|
||||||
for (ch = 0; ch < self->numOutputChannels; ch++) {
|
for (ch = 0; ch < self->numOutputChannels; ch++) {
|
||||||
for (hyb = 0; hyb < self->tp_hybBandBorder; hyb++) {
|
for (hyb = 0; hyb < self->tp_hybBandBorder; hyb++) {
|
||||||
self->hybOutputRealDry__FDK[ch][hyb] +=
|
self->hybOutputRealDry__FDK[ch][hyb] =
|
||||||
self->hybOutputRealWet__FDK[ch][hyb];
|
fAddSaturate(self->hybOutputRealDry__FDK[ch][hyb],
|
||||||
self->hybOutputImagDry__FDK[ch][hyb] +=
|
self->hybOutputRealWet__FDK[ch][hyb]);
|
||||||
self->hybOutputImagWet__FDK[ch][hyb];
|
self->hybOutputImagDry__FDK[ch][hyb] =
|
||||||
|
fAddSaturate(self->hybOutputImagDry__FDK[ch][hyb],
|
||||||
|
self->hybOutputImagWet__FDK[ch][hyb]);
|
||||||
} /* loop hyb */
|
} /* loop hyb */
|
||||||
} /* loop ch */
|
} /* loop ch */
|
||||||
err = subbandTPApply(
|
err = subbandTPApply(
|
||||||
@ -1341,11 +1349,11 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
|
|||||||
FIXP_DBL *RESTRICT pRealWet = self->hybOutputRealWet__FDK[ch];
|
FIXP_DBL *RESTRICT pRealWet = self->hybOutputRealWet__FDK[ch];
|
||||||
FIXP_DBL *RESTRICT pImagWet = self->hybOutputImagWet__FDK[ch];
|
FIXP_DBL *RESTRICT pImagWet = self->hybOutputImagWet__FDK[ch];
|
||||||
for (hyb = 0; hyb < nHybBands; hyb++) {
|
for (hyb = 0; hyb < nHybBands; hyb++) {
|
||||||
pRealDry[hyb] += pRealWet[hyb];
|
pRealDry[hyb] = fAddSaturate(pRealDry[hyb], pRealWet[hyb]);
|
||||||
pImagDry[hyb] += pImagWet[hyb];
|
pImagDry[hyb] = fAddSaturate(pImagDry[hyb], pImagWet[hyb]);
|
||||||
} /* loop hyb */
|
} /* loop hyb */
|
||||||
for (; hyb < self->hybridBands; hyb++) {
|
for (; hyb < self->hybridBands; hyb++) {
|
||||||
pRealDry[hyb] += pRealWet[hyb];
|
pRealDry[hyb] = fAddSaturate(pRealDry[hyb], pRealWet[hyb]);
|
||||||
} /* loop hyb */
|
} /* loop hyb */
|
||||||
} /* loop ch */
|
} /* loop ch */
|
||||||
} /* ( self->tempShapeConfig == 1 ) || ( self->tempShapeConfig == 2 ) */
|
} /* ( self->tempShapeConfig == 1 ) || ( self->tempShapeConfig == 2 ) */
|
||||||
@ -1414,6 +1422,7 @@ SACDEC_ERROR SpatialDecApplyFrame(
|
|||||||
FDK_ASSERT(self != NULL);
|
FDK_ASSERT(self != NULL);
|
||||||
FDK_ASSERT(pControlFlags != NULL);
|
FDK_ASSERT(pControlFlags != NULL);
|
||||||
FDK_ASSERT(pcmOutBuf != NULL);
|
FDK_ASSERT(pcmOutBuf != NULL);
|
||||||
|
FDK_ASSERT(self->sacInDataHeadroom >= (1));
|
||||||
|
|
||||||
self->errInt = err; /* Init internal error */
|
self->errInt = err; /* Init internal error */
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -523,6 +523,9 @@ struct spatialDec_struct {
|
|||||||
new frame after SSC change (aka
|
new frame after SSC change (aka
|
||||||
decodeAfterConfigHasChangedFlag). */
|
decodeAfterConfigHasChangedFlag). */
|
||||||
SpatialDecConcealmentInfo concealInfo;
|
SpatialDecConcealmentInfo concealInfo;
|
||||||
|
|
||||||
|
INT sacInDataHeadroom; /* Headroom of the SAC input time signal to prevent
|
||||||
|
clipping */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SACDEC_SYNTAX_MPS 1
|
#define SACDEC_SYNTAX_MPS 1
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -249,10 +249,10 @@ typedef struct {
|
|||||||
|
|
||||||
} MEM_REQUIREMENTS;
|
} MEM_REQUIREMENTS;
|
||||||
|
|
||||||
#define PCM_MPS INT_PCM
|
#define PCM_MPS LONG
|
||||||
#define PCM_MPSF FIXP_PCM
|
#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) */
|
/* exposed functions (library interface) */
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -1507,15 +1507,17 @@ bail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
||||||
INT_PCM *input, PCM_MPS *pTimeData,
|
PCM_MPS *input, PCM_MPS *pTimeData,
|
||||||
const int timeDataSize, int timeDataFrameSize,
|
const int timeDataSize, int timeDataFrameSize,
|
||||||
int *nChannels, int *frameSize, int sampleRate,
|
int *nChannels, int *frameSize, int sampleRate,
|
||||||
AUDIO_OBJECT_TYPE coreCodec,
|
AUDIO_OBJECT_TYPE coreCodec,
|
||||||
AUDIO_CHANNEL_TYPE channelType[],
|
AUDIO_CHANNEL_TYPE channelType[],
|
||||||
UCHAR channelIndices[],
|
UCHAR channelIndices[],
|
||||||
const FDK_channelMapDescr *const mapDescr) {
|
const FDK_channelMapDescr *const mapDescr,
|
||||||
|
const INT inDataHeadroom, INT *outDataHeadroom) {
|
||||||
SACDEC_ERROR err = MPS_OK;
|
SACDEC_ERROR err = MPS_OK;
|
||||||
PCM_MPS *pTimeOut = pTimeData;
|
PCM_MPS *pTimeOut = pTimeData;
|
||||||
|
PCM_MPS *TDinput = NULL;
|
||||||
UINT initControlFlags = 0, controlFlags = 0;
|
UINT initControlFlags = 0, controlFlags = 0;
|
||||||
int timeDataRequiredSize = 0;
|
int timeDataRequiredSize = 0;
|
||||||
int newData;
|
int newData;
|
||||||
@ -1534,6 +1536,9 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
|||||||
return MPS_NOTOK;
|
return MPS_NOTOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pMpegSurroundDecoder->pSpatialDec->sacInDataHeadroom = inDataHeadroom;
|
||||||
|
*outDataHeadroom = (INT)(8);
|
||||||
|
|
||||||
pMpegSurroundDecoder->pSpatialDec->pConfigCurrent =
|
pMpegSurroundDecoder->pSpatialDec->pConfigCurrent =
|
||||||
&pMpegSurroundDecoder
|
&pMpegSurroundDecoder
|
||||||
->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
|
->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
|
||||||
@ -1682,8 +1687,7 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
|||||||
(timeDataFrameSize *
|
(timeDataFrameSize *
|
||||||
pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsSynthesis) /
|
pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsSynthesis) /
|
||||||
pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis;
|
pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis;
|
||||||
pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput =
|
TDinput = pTimeData + timeDataFrameSizeOut - timeDataFrameSize;
|
||||||
pTimeData + timeDataFrameSizeOut - timeDataFrameSize;
|
|
||||||
for (int i = *nChannels - 1; i >= 0; i--) {
|
for (int i = *nChannels - 1; i >= 0; i--) {
|
||||||
FDKmemmove(pTimeData + (i + 1) * timeDataFrameSizeOut - timeDataFrameSize,
|
FDKmemmove(pTimeData + (i + 1) * timeDataFrameSizeOut - timeDataFrameSize,
|
||||||
pTimeData + timeDataFrameSize * i,
|
pTimeData + timeDataFrameSize * i,
|
||||||
@ -1694,8 +1698,8 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
|||||||
} else {
|
} else {
|
||||||
if (pMpegSurroundDecoder->mpegSurroundUseTimeInterface) {
|
if (pMpegSurroundDecoder->mpegSurroundUseTimeInterface) {
|
||||||
FDKmemcpy(input, pTimeData,
|
FDKmemcpy(input, pTimeData,
|
||||||
sizeof(INT_PCM) * (*nChannels) * (*frameSize));
|
sizeof(PCM_MPS) * (*nChannels) * (*frameSize));
|
||||||
pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput = input;
|
TDinput = input;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1707,8 +1711,8 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
|
|||||||
&pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode],
|
&pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode],
|
||||||
pMpegSurroundDecoder->mpegSurroundUseTimeInterface ? INPUTMODE_TIME
|
pMpegSurroundDecoder->mpegSurroundUseTimeInterface ? INPUTMODE_TIME
|
||||||
: INPUTMODE_QMF_SBR,
|
: INPUTMODE_QMF_SBR,
|
||||||
pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput, NULL, NULL,
|
TDinput, NULL, NULL, pTimeOut, *frameSize, &controlFlags, *nChannels,
|
||||||
pTimeOut, *frameSize, &controlFlags, *nChannels, mapDescr);
|
mapDescr);
|
||||||
*nChannels = pMpegSurroundDecoder->pSpatialDec->numOutputChannelsAT;
|
*nChannels = pMpegSurroundDecoder->pSpatialDec->numOutputChannelsAT;
|
||||||
|
|
||||||
if (err !=
|
if (err !=
|
||||||
@ -1781,7 +1785,7 @@ void mpegSurroundDecoder_Close(CMpegSurroundDecoder *pMpegSurroundDecoder) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define SACDEC_VL0 2
|
#define SACDEC_VL0 2
|
||||||
#define SACDEC_VL1 0
|
#define SACDEC_VL1 1
|
||||||
#define SACDEC_VL2 0
|
#define SACDEC_VL2 0
|
||||||
|
|
||||||
int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) {
|
int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -113,6 +113,8 @@ amm-info@iis.fraunhofer.de
|
|||||||
#include "FDK_trigFcts.h"
|
#include "FDK_trigFcts.h"
|
||||||
#include "FDK_decorrelate.h"
|
#include "FDK_decorrelate.h"
|
||||||
|
|
||||||
|
#define SAC_DEC_APPLY_M2_SCALE(spec, s) ((spec) >> (-(s)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Linear interpolation between two parameter values.
|
* \brief Linear interpolation between two parameter values.
|
||||||
* a*alpha + b*(1-alpha)
|
* a*alpha + b*(1-alpha)
|
||||||
@ -185,8 +187,12 @@ SACDEC_ERROR SpatialDecQMFAnalysis(spatialDec *self, const PCM_MPS *inData,
|
|||||||
if (!isTwoChMode(self->upmixType) && !bypassMode) {
|
if (!isTwoChMode(self->upmixType) && !bypassMode) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < self->qmfBands; i++) {
|
for (i = 0; i < self->qmfBands; i++) {
|
||||||
qmfReal[ch][i] = fMult(qmfReal[ch][i], self->clipProtectGain__FDK);
|
qmfReal[ch][i] = fMult(
|
||||||
qmfImag[ch][i] = fMult(qmfImag[ch][i], self->clipProtectGain__FDK);
|
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. */
|
/* Write Input data to pQmfRealAnalysis. */
|
||||||
if (self->bShareDelayWithSBR) {
|
if (self->bShareDelayWithSBR) {
|
||||||
FDK_QmfDomain_GetSlot(
|
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch],
|
||||||
&self->pQmfDomain->QmfDomainIn[ch], ts + HYBRID_FILTER_DELAY, 0,
|
ts + HYBRID_FILTER_DELAY, 0,
|
||||||
MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis, pQmfImagAnalysis, 15);
|
MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis,
|
||||||
|
pQmfImagAnalysis, 15 + (1));
|
||||||
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts,
|
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts,
|
||||||
MAX_QMF_BANDS_TO_HYBRID, self->qmfBands,
|
MAX_QMF_BANDS_TO_HYBRID, self->qmfBands,
|
||||||
pQmfRealAnalysis, pQmfImagAnalysis, 15);
|
pQmfRealAnalysis, pQmfImagAnalysis, 15 + (1));
|
||||||
} else {
|
} else {
|
||||||
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts, 0,
|
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts, 0,
|
||||||
self->qmfBands, pQmfRealAnalysis,
|
self->qmfBands, pQmfRealAnalysis,
|
||||||
pQmfImagAnalysis, 15);
|
pQmfImagAnalysis, 15 + (1));
|
||||||
}
|
}
|
||||||
if (ts == self->pQmfDomain->globalConf.nQmfTimeSlots - 1) {
|
if (ts == self->pQmfDomain->globalConf.nQmfTimeSlots - 1) {
|
||||||
/* Is currently also needed in case we dont have any overlap. We need to
|
/* 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++) {
|
for (pb = 0, qs = 3; pb < 2; pb++) {
|
||||||
INT s;
|
INT s;
|
||||||
FIXP_DBL maxVal;
|
FIXP_DBL maxVal;
|
||||||
FIXP_SGL mReal1;
|
FIXP_DBL mReal1;
|
||||||
FIXP_SGL mReal0, mImag0;
|
FIXP_DBL mReal0, mImag0;
|
||||||
FIXP_DBL iReal0, iImag0, iReal1;
|
FIXP_DBL iReal0, iImag0, iReal1;
|
||||||
|
|
||||||
iReal0 = interpolateParameter(alpha, MReal0[pb], MRealPrev0[pb]);
|
iReal0 = interpolateParameter(alpha, MReal0[pb], MRealPrev0[pb]);
|
||||||
@ -513,9 +520,9 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
|
|||||||
s = fMax(CntLeadingZeros(maxVal) - 1, 0);
|
s = fMax(CntLeadingZeros(maxVal) - 1, 0);
|
||||||
s = fMin(s, scale_param_m2);
|
s = fMin(s, scale_param_m2);
|
||||||
|
|
||||||
mReal0 = FX_DBL2FX_SGL(iReal0 << s);
|
mReal0 = iReal0 << s;
|
||||||
mImag0 = FX_DBL2FX_SGL(iImag0 << s);
|
mImag0 = iImag0 << s;
|
||||||
mReal1 = FX_DBL2FX_SGL(iReal1 << s);
|
mReal1 = iReal1 << s;
|
||||||
|
|
||||||
s = scale_param_m2 - 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) {
|
if (self->phaseCoding == 3) {
|
||||||
/* + SCALE_DATA_APPLY_M2 to compensate for Div2 below ?! */
|
scale_param_m2 = -(SCALE_DATA_APPLY_M2_PC - 1);
|
||||||
scale_param_m2 = SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (row = 0; row < self->numM2rows; row++) {
|
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) */
|
} else { /* isBinauralMode(self->upmixType) */
|
||||||
|
|
||||||
for (qs = 0; qs < complexHybBands; qs++) {
|
for (qs = 0; qs < complexHybBands; qs++) {
|
||||||
pHybOutRealDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
|
pHybOutRealDry[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
|
||||||
pHybOutImagDry[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
|
pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
|
||||||
}
|
}
|
||||||
|
|
||||||
M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col],
|
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);
|
self->kernels_width, alpha, complexParBands);
|
||||||
|
|
||||||
/* direct signals sign is -1 for qs = 0,2 */
|
/* direct signals sign is -1 for qs = 0,2 */
|
||||||
pHybOutRealDry[0] += fMultDiv2(pWImag[0], pKernel[0])
|
pHybOutRealDry[0] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
|
||||||
pHybOutImagDry[0] -= fMultDiv2(pWReal[0], pKernel[0])
|
pHybOutImagDry[0] -= SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
|
||||||
|
|
||||||
pHybOutRealDry[2] += fMultDiv2(pWImag[2], pKernel[2])
|
pHybOutRealDry[2] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
|
||||||
pHybOutImagDry[2] -= fMultDiv2(pWReal[2], pKernel[2])
|
pHybOutImagDry[2] -= SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
|
||||||
|
|
||||||
/* direct signals sign is +1 for qs = 1,3,4,5,...,complexHybBands */
|
/* direct signals sign is +1 for qs = 1,3,4,5,...,complexHybBands */
|
||||||
pHybOutRealDry[1] -= fMultDiv2(pWImag[1], pKernel[1])
|
pHybOutRealDry[1] -= SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
|
||||||
pHybOutImagDry[1] += fMultDiv2(pWReal[1], pKernel[1])
|
pHybOutImagDry[1] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
|
||||||
|
|
||||||
for (qs = 3; qs < complexHybBands; qs++) {
|
for (qs = 3; qs < complexHybBands; qs++) {
|
||||||
pHybOutRealDry[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
|
pHybOutRealDry[qs] -= SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
|
||||||
pHybOutImagDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
|
pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
|
||||||
}
|
}
|
||||||
} /* self->upmixType */
|
} /* self->upmixType */
|
||||||
} /* if (activParamBands) */
|
} /* if (activParamBands) */
|
||||||
@ -770,17 +776,17 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
|
|||||||
FIXP_DBL *RESTRICT pHybOutImag;
|
FIXP_DBL *RESTRICT pHybOutImag;
|
||||||
|
|
||||||
for (qs = 0; qs < resHybIndex; qs++) {
|
for (qs = 0; qs < resHybIndex; qs++) {
|
||||||
pHybOutRealDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
|
pHybOutRealDry[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
|
||||||
pHybOutImagDry[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
|
pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
|
||||||
}
|
}
|
||||||
/* decor signals */
|
/* decor signals */
|
||||||
for (; qs < complexHybBands; qs++) {
|
for (; qs < complexHybBands; qs++) {
|
||||||
pHybOutRealWet[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
|
pHybOutRealWet[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
|
||||||
pHybOutImagWet[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
|
pHybOutImagWet[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
|
||||||
}
|
}
|
||||||
|
|
||||||
M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col],
|
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 = 0,2 */
|
||||||
/* direct signals sign is +1 for qs = 1,3.. */
|
/* direct signals sign is +1 for qs = 1,3.. */
|
||||||
if (toolsDisabled) {
|
if (toolsDisabled) {
|
||||||
pHybOutRealDry[0] += fMultDiv2(pWImag[0], pKernel[0])
|
pHybOutRealDry[0] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
|
||||||
pHybOutImagDry[0] -= fMultDiv2(pWReal[0], pKernel[0])
|
pHybOutImagDry[0] -= SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
|
||||||
|
|
||||||
pHybOutRealDry[1] -= fMultDiv2(pWImag[1], pKernel[1])
|
pHybOutRealDry[1] -= SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
|
||||||
pHybOutImagDry[1] += fMultDiv2(pWReal[1], pKernel[1])
|
pHybOutImagDry[1] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
|
||||||
|
|
||||||
pHybOutRealDry[2] += fMultDiv2(pWImag[2], pKernel[2])
|
pHybOutRealDry[2] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
|
||||||
pHybOutImagDry[2] -= fMultDiv2(pWReal[2], pKernel[2])
|
pHybOutImagDry[2] -= SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
|
||||||
} else {
|
} else {
|
||||||
pHybOutReal = &pHybOutRealDry[0];
|
pHybOutReal = &pHybOutRealDry[0];
|
||||||
pHybOutImag = &pHybOutImagDry[0];
|
pHybOutImag = &pHybOutImagDry[0];
|
||||||
@ -811,46 +817,60 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
|
|||||||
pHybOutReal = &pHybOutRealWet[0];
|
pHybOutReal = &pHybOutRealWet[0];
|
||||||
pHybOutImag = &pHybOutImagWet[0];
|
pHybOutImag = &pHybOutImagWet[0];
|
||||||
}
|
}
|
||||||
pHybOutReal[0] += fMultDiv2(pWImag[0], pKernel[0])
|
pHybOutReal[0] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
|
||||||
pHybOutImag[0] -= fMultDiv2(pWReal[0], pKernel[0])
|
pHybOutImag[0] -= SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
|
||||||
|
|
||||||
if (1 == resHybIndex) {
|
if (1 == resHybIndex) {
|
||||||
pHybOutReal = &pHybOutRealWet[0];
|
pHybOutReal = &pHybOutRealWet[0];
|
||||||
pHybOutImag = &pHybOutImagWet[0];
|
pHybOutImag = &pHybOutImagWet[0];
|
||||||
}
|
}
|
||||||
pHybOutReal[1] -= fMultDiv2(pWImag[1], pKernel[1])
|
pHybOutReal[1] -= SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
|
||||||
pHybOutImag[1] += fMultDiv2(pWReal[1], pKernel[1])
|
pHybOutImag[1] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
|
||||||
|
|
||||||
if (2 == resHybIndex) {
|
if (2 == resHybIndex) {
|
||||||
pHybOutReal = &pHybOutRealWet[0];
|
pHybOutReal = &pHybOutRealWet[0];
|
||||||
pHybOutImag = &pHybOutImagWet[0];
|
pHybOutImag = &pHybOutImagWet[0];
|
||||||
}
|
}
|
||||||
pHybOutReal[2] += fMultDiv2(pWImag[2], pKernel[2])
|
pHybOutReal[2] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
|
||||||
pHybOutImag[2] -= fMultDiv2(pWReal[2], pKernel[2])
|
pHybOutImag[2] -= SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (qs = 3; qs < resHybIndex; qs++) {
|
for (qs = 3; qs < resHybIndex; qs++) {
|
||||||
pHybOutRealDry[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
|
pHybOutRealDry[qs] -= SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
|
||||||
pHybOutImagDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
|
pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
|
||||||
}
|
}
|
||||||
/* decor signals */
|
/* decor signals */
|
||||||
for (; qs < complexHybBands; qs++) {
|
for (; qs < complexHybBands; qs++) {
|
||||||
pHybOutRealWet[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
|
pHybOutRealWet[qs] -= SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
|
||||||
pHybOutImagWet[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
|
pHybOutImagWet[qs] += SAC_DEC_APPLY_M2_SCALE(
|
||||||
<< (scale_param_m2);
|
fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
|
||||||
}
|
}
|
||||||
} /* self->upmixType */
|
} /* self->upmixType */
|
||||||
} /* if (activParamBands) { */
|
} /* if (activParamBands) { */
|
||||||
} /* self->numVChannels */
|
} /* 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);
|
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->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -=
|
||||||
self->clipProtectGainSF__FDK;
|
self->clipProtectGainSF__FDK;
|
||||||
|
|
||||||
|
self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -= (1);
|
||||||
} else {
|
} else {
|
||||||
/* Call the QMF synthesis for dry. */
|
/* Call the QMF synthesis for dry. */
|
||||||
err = CalculateSpaceSynthesisQmf(&self->pQmfDomain->QmfDomainOut[outCh],
|
err = CalculateSpaceSynthesisQmf(&self->pQmfDomain->QmfDomainOut[outCh],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de
|
|||||||
|
|
||||||
SACDEC_ERROR CalculateSpaceSynthesisQmf(
|
SACDEC_ERROR CalculateSpaceSynthesisQmf(
|
||||||
const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr,
|
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;
|
SACDEC_ERROR err = MPS_OK;
|
||||||
|
|
||||||
if (hQmfDomainOutCh == NULL) {
|
if (hQmfDomainOutCh == NULL) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -124,7 +124,7 @@ amm-info@iis.fraunhofer.de
|
|||||||
*/
|
*/
|
||||||
SACDEC_ERROR CalculateSpaceSynthesisQmf(
|
SACDEC_ERROR CalculateSpaceSynthesisQmf(
|
||||||
const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr,
|
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.
|
* \brief Convert audio input data to qmf representation.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -162,75 +162,59 @@ static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
|
|||||||
FIXP_DBL nrg;
|
FIXP_DBL nrg;
|
||||||
|
|
||||||
/* qs = 12, 13, 14 */
|
/* qs = 12, 13, 14 */
|
||||||
slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) +
|
slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) +
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
(SF_FACTOR_SLOT - 1));
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) +
|
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 15 */
|
/* qs = 15 */
|
||||||
slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) +
|
slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 16, 17 */
|
/* qs = 16, 17 */
|
||||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
slotNrg[4] =
|
||||||
slotNrg[4] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 18, 19, 20 */
|
/* qs = 18, 19, 20 */
|
||||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
slotNrg[5] =
|
||||||
(SF_FACTOR_SLOT - 1));
|
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
slotNrg[5] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 21, 22 */
|
/* qs = 21, 22 */
|
||||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
slotNrg[6] =
|
||||||
slotNrg[6] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 23, 24 */
|
/* qs = 23, 24 */
|
||||||
if (hybBands > 23) {
|
if (hybBands > 23) {
|
||||||
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) +
|
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) +
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 25, 26, 29, 28, 29 */
|
/* qs = 25, 26, 29, 28, 29 */
|
||||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
(SF_FACTOR_SLOT - 1));
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
slotNrg[7] =
|
||||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
slotNrg[7] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
|
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 30 ... min(41,hybBands-1) */
|
/* qs = 30 ... min(41,hybBands-1) */
|
||||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
for (qs = 31; qs < hybBands; qs++) {
|
for (qs = 31; qs < hybBands; qs++) {
|
||||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
}
|
}
|
||||||
slotNrg[8] = nrg;
|
slotNrg[8] = nrg;
|
||||||
} else {
|
} else {
|
||||||
@ -239,49 +223,22 @@ static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline INT getMaxValDmx(FIXP_DBL *RESTRICT pReal,
|
static inline void combineDryWet(FIXP_DBL *RESTRICT pReal,
|
||||||
FIXP_DBL *RESTRICT pImag, INT cplxBands,
|
FIXP_DBL *RESTRICT pImag,
|
||||||
INT hybBands) {
|
FIXP_DBL *RESTRICT pHybOutputRealDry,
|
||||||
INT qs, clz;
|
FIXP_DBL *RESTRICT pHybOutputImagDry,
|
||||||
FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
|
FIXP_DBL *RESTRICT pHybOutputRealWet,
|
||||||
|
FIXP_DBL *RESTRICT pHybOutputImagWet,
|
||||||
|
INT cplxBands, INT hybBands) {
|
||||||
|
INT qs;
|
||||||
|
|
||||||
for (qs = 12; qs < cplxBands; qs++) {
|
for (qs = 12; qs < cplxBands; qs++) {
|
||||||
maxVal |= fAbs(pReal[qs]);
|
pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
|
||||||
maxVal |= fAbs(pImag[qs]);
|
pImag[qs] = (pHybOutputImagDry[qs] >> 1) + (pHybOutputImagWet[qs] >> 1);
|
||||||
}
|
}
|
||||||
for (; qs < hybBands; qs++) {
|
for (; qs < hybBands; qs++) {
|
||||||
maxVal |= fAbs(pReal[qs]);
|
pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
clz = fixMax(0, CntLeadingZeros(maxVal) - 1);
|
|
||||||
|
|
||||||
return (clz);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline INT getMaxValDryWet(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);
|
|
||||||
|
|
||||||
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]);
|
|
||||||
}
|
|
||||||
for (; qs < hybBands; qs++) {
|
|
||||||
pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs];
|
|
||||||
maxVal |= fAbs(pReal[qs]);
|
|
||||||
}
|
|
||||||
|
|
||||||
clz = fixMax(0, CntLeadingZeros(maxVal) - 1);
|
|
||||||
|
|
||||||
return (clz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry,
|
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);
|
dry = wet = FL2FXCONST_DBL(0.0f);
|
||||||
for (qs = 0; qs < cplxBands; qs++) {
|
for (qs = 0; qs < cplxBands; qs++) {
|
||||||
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]) +
|
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)) +
|
||||||
fPow2Div2(pHybOutputImagDry[qs]));
|
fPow2Div2(pHybOutputImagDry[qs] << (1)));
|
||||||
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]) +
|
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)) +
|
||||||
fPow2Div2(pHybOutputImagWet[qs]));
|
fPow2Div2(pHybOutputImagWet[qs] << (1)));
|
||||||
}
|
}
|
||||||
for (; qs < hybBands; qs++) {
|
for (; qs < hybBands; qs++) {
|
||||||
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]));
|
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)));
|
||||||
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]));
|
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)));
|
||||||
}
|
}
|
||||||
*slotAmp_dry = dry;
|
*slotAmp_dry = dry >> (2 * (1));
|
||||||
*slotAmp_wet = wet;
|
*slotAmp_wet = wet >> (2 * (1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__aarch64__)
|
#if defined(__aarch64__)
|
||||||
@ -327,11 +284,14 @@ shapeBBEnv(FIXP_DBL *pHybOutputRealDry, FIXP_DBL *pHybOutputImagDry,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (qs = 0; qs < cplxBands; qs++) {
|
for (qs = 0; qs < cplxBands; qs++) {
|
||||||
pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale;
|
pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
|
||||||
pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac) << scale;
|
fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
|
||||||
|
pHybOutputImagDry[qs] = SATURATE_LEFT_SHIFT(
|
||||||
|
fMultDiv2(pHybOutputImagDry[qs], dryFac), scale, DFRACT_BITS);
|
||||||
}
|
}
|
||||||
for (; qs < hybBands; qs++) {
|
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 shapeActiv = 1;
|
||||||
INT hybBands = fixMin(42, self->hybridBands);
|
INT hybBands = fixMin(42, self->hybridBands);
|
||||||
INT staticScale = self->staticDecScale;
|
INT staticScale = self->staticDecScale + (1);
|
||||||
INT cplxBands;
|
INT cplxBands;
|
||||||
cplxBands = fixMin(42, self->hybridBands);
|
cplxBands = fixMin(42, self->hybridBands);
|
||||||
|
|
||||||
@ -386,15 +346,18 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
|
|||||||
prevChOffs = ch;
|
prevChOffs = ch;
|
||||||
pReal = pScratchBuffer;
|
pReal = pScratchBuffer;
|
||||||
pImag = pScratchBuffer + 42;
|
pImag = pScratchBuffer + 42;
|
||||||
clz = getMaxValDryWet(
|
combineDryWet(pReal, pImag, self->hybOutputRealDry__FDK[ch],
|
||||||
pReal, pImag, self->hybOutputRealDry__FDK[ch],
|
self->hybOutputImagDry__FDK[ch],
|
||||||
self->hybOutputImagDry__FDK[ch], self->hybOutputRealWet__FDK[ch],
|
self->hybOutputRealWet__FDK[ch],
|
||||||
self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
|
self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
|
||||||
|
clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
|
||||||
|
getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
|
||||||
} else {
|
} else {
|
||||||
prevChOffs = ch + self->numOutputChannels;
|
prevChOffs = ch + self->numOutputChannels;
|
||||||
pReal = self->hybInputReal__FDK[ch];
|
pReal = self->hybInputReal__FDK[ch];
|
||||||
pImag = self->hybInputImag__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];
|
partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs];
|
||||||
@ -411,8 +374,10 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
|
|||||||
SF_FACTOR_SLOT */
|
SF_FACTOR_SLOT */
|
||||||
}
|
}
|
||||||
|
|
||||||
slotNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT;
|
slotNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
|
||||||
frameNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT;
|
SF_FACTOR_SLOT;
|
||||||
|
frameNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
|
||||||
|
SF_FACTOR_SLOT;
|
||||||
|
|
||||||
partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
|
partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
|
||||||
pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 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
|
fixMax(3, fixMax(dryFacSF, slotAmpSF)); /* scale is at least with 3
|
||||||
bits to avoid overflows
|
bits to avoid overflows
|
||||||
when calculating dryFac */
|
when calculating dryFac */
|
||||||
dryFac = dryFac >> (scale - dryFacSF);
|
dryFac = dryFac >> fixMin(scale - dryFacSF, DFRACT_BITS - 1);
|
||||||
slotAmp_ratio = slotAmp_ratio >> (scale - slotAmpSF);
|
slotAmp_ratio =
|
||||||
|
slotAmp_ratio >> fixMin(scale - slotAmpSF, DFRACT_BITS - 1);
|
||||||
|
|
||||||
/* limit dryFac */
|
/* limit dryFac */
|
||||||
dryFac = fixMax(
|
dryFac = fixMax(
|
||||||
FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1),
|
FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1),
|
||||||
fMult(dryFac, slotAmp_ratio) - (slotAmp_ratio >> scale) +
|
fMult(dryFac, slotAmp_ratio) -
|
||||||
(dryFac >> scale));
|
(slotAmp_ratio >> fixMin(scale, DFRACT_BITS - 1)) +
|
||||||
|
(dryFac >> fixMin(scale, DFRACT_BITS - 1)));
|
||||||
dryFac = fixMin(
|
dryFac = fixMin(
|
||||||
FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1),
|
FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1),
|
||||||
dryFac); /* reduce shift bits by 3, because upper
|
dryFac); /* reduce shift bits by 3, because upper
|
||||||
@ -673,8 +640,8 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
|
|||||||
|
|
||||||
/* shaping */
|
/* shaping */
|
||||||
shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6],
|
shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6],
|
||||||
&self->hybOutputImagDry__FDK[ch][6], dryFac, scale, cplxBands,
|
&self->hybOutputImagDry__FDK[ch][6], dryFac,
|
||||||
hybBands);
|
fixMin(scale, DFRACT_BITS - 1), cplxBands, hybBands);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,21 +111,12 @@ amm-info@iis.fraunhofer.de
|
|||||||
#include "machine_type.h"
|
#include "machine_type.h"
|
||||||
|
|
||||||
/* Global ROM table data type: */
|
/* 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 FIXP_CFG FIXP_DBL
|
||||||
#define FX_CFG2FX_DBL
|
#define FX_CFG2FX_DBL
|
||||||
#define FX_CFG2FX_SGL FX_DBL2FX_SGL
|
#define FX_CFG2FX_SGL FX_DBL2FX_SGL
|
||||||
#define CFG(a) FIXP_DBL(a)
|
#define CFG(a) FIXP_DBL(a)
|
||||||
#define FL2FXCONST_CFG FL2FXCONST_DBL
|
#define FL2FXCONST_CFG FL2FXCONST_DBL
|
||||||
#define FX_DBL2FX_CFG(x) ((FIXP_DBL)(x))
|
#define FX_DBL2FX_CFG(x) ((FIXP_DBL)(x))
|
||||||
#endif
|
|
||||||
|
|
||||||
/* others */
|
/* others */
|
||||||
#define SCALE_INV_ICC (2)
|
#define SCALE_INV_ICC (2)
|
||||||
@ -133,15 +124,9 @@ amm-info@iis.fraunhofer.de
|
|||||||
|
|
||||||
#define QCC_SCALE 1
|
#define QCC_SCALE 1
|
||||||
#define M1M2_DATA FIXP_DBL
|
#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_CDATA FIXP_DBL
|
||||||
#define M1M2_CDATA2FX_DBL(a) (a)
|
#define M1M2_CDATA2FX_DBL(a) (a)
|
||||||
#define FX_DBL2M1M2_CDATA(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_0(x) FL2FXCONST_CFG(((x) / (float)(1 << 0)))
|
||||||
#define CLIP_PROTECT_GAIN_1(x) FL2FXCONST_CFG(((x) / (float)(1 << 1)))
|
#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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -106,6 +106,8 @@ amm-info@iis.fraunhofer.de
|
|||||||
#include "FDK_matrixCalloc.h"
|
#include "FDK_matrixCalloc.h"
|
||||||
#include "sac_rom.h"
|
#include "sac_rom.h"
|
||||||
|
|
||||||
|
#define SF_FREQ_DOMAIN_HEADROOM (2 * (1))
|
||||||
|
|
||||||
#define BP_GF_START 6
|
#define BP_GF_START 6
|
||||||
#define BP_GF_SIZE 25
|
#define BP_GF_SIZE 25
|
||||||
#define HP_SIZE 9
|
#define HP_SIZE 9
|
||||||
@ -114,6 +116,16 @@ amm-info@iis.fraunhofer.de
|
|||||||
#define SF_WET 5
|
#define SF_WET 5
|
||||||
#define SF_DRY \
|
#define SF_DRY \
|
||||||
3 /* SF_DRY == 2 would produce good conformance test results as well */
|
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 13
|
||||||
#define SF_PRODUCT_BP_GF_GF 26
|
#define SF_PRODUCT_BP_GF_GF 26
|
||||||
#define SF_SCALE 2
|
#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)
|
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) \
|
#define CALC_WET_SCALE(dryIdx, wetIdx) \
|
||||||
if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \
|
if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \
|
||||||
scale[wetIdx] = STP_SCALE_LIMIT_HI; \
|
scale[wetIdx] = STP_SCALE_LIMIT_HI; \
|
||||||
@ -206,29 +206,6 @@ struct STP_DEC {
|
|||||||
int update_old_ener;
|
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,
|
inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
|
||||||
FIXP_DBL *hybOutputImagDry,
|
FIXP_DBL *hybOutputImagDry,
|
||||||
FIXP_DBL *hybOutputRealWet,
|
FIXP_DBL *hybOutputRealWet,
|
||||||
@ -236,8 +213,8 @@ inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
|
|||||||
int n;
|
int n;
|
||||||
|
|
||||||
for (n = bands - 1; n >= 0; n--) {
|
for (n = bands - 1; n >= 0; n--) {
|
||||||
*hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet;
|
*hybOutputRealDry = fAddSaturate(*hybOutputRealDry, *hybOutputRealWet);
|
||||||
*hybOutputImagDry = *hybOutputImagDry + *hybOutputImagWet;
|
*hybOutputImagDry = fAddSaturate(*hybOutputImagDry, *hybOutputImagWet);
|
||||||
hybOutputRealDry++, hybOutputRealWet++;
|
hybOutputRealDry++, hybOutputRealWet++;
|
||||||
hybOutputImagDry++, hybOutputImagWet++;
|
hybOutputImagDry++, hybOutputImagWet++;
|
||||||
}
|
}
|
||||||
@ -253,12 +230,14 @@ inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry,
|
|||||||
FIXP_DBL scaleY;
|
FIXP_DBL scaleY;
|
||||||
for (n = bands - 1; n >= 0; n--) {
|
for (n = bands - 1; n >= 0; n--) {
|
||||||
scaleY = fMultDiv2(scaleX, *pBP);
|
scaleY = fMultDiv2(scaleX, *pBP);
|
||||||
*hybOutputRealDry =
|
*hybOutputRealDry = SATURATE_LEFT_SHIFT(
|
||||||
*hybOutputRealDry +
|
(*hybOutputRealDry >> 1) +
|
||||||
(fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 2));
|
(fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 1)),
|
||||||
*hybOutputImagDry =
|
1, DFRACT_BITS);
|
||||||
*hybOutputImagDry +
|
*hybOutputImagDry = SATURATE_LEFT_SHIFT(
|
||||||
(fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 2));
|
(*hybOutputImagDry >> 1) +
|
||||||
|
(fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 1)),
|
||||||
|
1, DFRACT_BITS);
|
||||||
hybOutputRealDry++, hybOutputRealWet++;
|
hybOutputRealDry++, hybOutputRealWet++;
|
||||||
hybOutputImagDry++, hybOutputImagWet++;
|
hybOutputImagDry++, hybOutputImagWet++;
|
||||||
pBP++;
|
pBP++;
|
||||||
@ -305,12 +284,10 @@ SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) {
|
|||||||
|
|
||||||
for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
|
for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
|
||||||
self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE));
|
self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE));
|
||||||
self->oldWetEnerLD64[ch] =
|
self->oldWetEnerLD64[ch] = FL2FXCONST_DBL(0.0);
|
||||||
FL2FXCONST_DBL(0.34375f); /* 32768.0*32768.0/2^(44-26-10) */
|
|
||||||
}
|
}
|
||||||
for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) {
|
for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) {
|
||||||
self->oldDryEnerLD64[ch] =
|
self->oldDryEnerLD64[ch] = FL2FXCONST_DBL(0.0);
|
||||||
FL2FXCONST_DBL(0.1875f); /* 32768.0*32768.0/2^(44-26) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self->BP = BP__FDK;
|
self->BP = BP__FDK;
|
||||||
@ -364,7 +341,12 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
|||||||
{
|
{
|
||||||
cplxBands = BP_GF_SIZE;
|
cplxBands = BP_GF_SIZE;
|
||||||
cplxHybBands = self->hybridBands;
|
cplxHybBands = self->hybridBands;
|
||||||
dry_scale_dmx = (2 * SF_DRY) - 2;
|
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;
|
wet_scale_dmx = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,8 +372,12 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
|||||||
CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK);
|
CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK);
|
||||||
}
|
}
|
||||||
for (ch = 0; ch < self->numOutputChannels; ch++) {
|
for (ch = 0; ch < self->numOutputChannels; ch++) {
|
||||||
hStpDec->oldWetEnerLD64[ch] =
|
if (self->treeConfig == TREE_212)
|
||||||
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK);
|
hStpDec->oldWetEnerLD64[ch] =
|
||||||
|
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR__FDK);
|
||||||
|
else
|
||||||
|
hStpDec->oldWetEnerLD64[ch] =
|
||||||
|
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hStpDec->update_old_ener++;
|
hStpDec->update_old_ener++;
|
||||||
@ -411,12 +397,33 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
|||||||
pBP = hStpDec->BP_GF - BP_GF_START;
|
pBP = hStpDec->BP_GF - BP_GF_START;
|
||||||
switch (self->treeConfig) {
|
switch (self->treeConfig) {
|
||||||
case TREE_212:
|
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++) {
|
for (n = BP_GF_START; n < cplxBands; n++) {
|
||||||
dmxReal0 = qmfOutputRealDry[i_LF][n] + qmfOutputRealDry[i_RF][n];
|
dmxReal0 = scaleValue(qmfOutputRealDry[i_LF][n], sMin) +
|
||||||
dmxImag0 = qmfOutputImagDry[i_LF][n] + qmfOutputImagDry[i_RF][n];
|
scaleValue(qmfOutputRealDry[i_RF][n], sMin);
|
||||||
DRY_ENER_SUM_CPLX(DryEner0, dmxReal0, dmxImag0, n);
|
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;
|
break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
@ -424,7 +431,7 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
|||||||
|
|
||||||
/* normalise the 'direct' signals */
|
/* normalise the 'direct' signals */
|
||||||
for (ch = 0; ch < self->numInputChannels; ch++) {
|
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] =
|
hStpDec->runDryEner[ch] =
|
||||||
fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
|
fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
|
||||||
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
|
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
|
||||||
@ -436,10 +443,8 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
|||||||
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
|
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (self->treeConfig == TREE_212) {
|
for (; ch < MAX_INPUT_CHANNELS; ch++) {
|
||||||
for (; ch < MAX_INPUT_CHANNELS; ch++) {
|
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
|
||||||
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* normalise the 'diffuse' signals */
|
/* normalise the 'diffuse' signals */
|
||||||
@ -450,14 +455,30 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
WetEnerX = FL2FXCONST_DBL(0.0f);
|
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] =
|
hStpDec->runWetEner[ch] =
|
||||||
fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) +
|
fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) +
|
||||||
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX);
|
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -123,12 +123,15 @@ static const UCHAR nBitsTsdCW_64slots[64] = {
|
|||||||
|
|
||||||
RAM_ALIGN
|
RAM_ALIGN
|
||||||
LNK_SECTION_CONSTDATA
|
LNK_SECTION_CONSTDATA
|
||||||
static const FIXP_STP phiTsd[8] = {
|
static const FIXP_DPK phiTsd[8] = {
|
||||||
STCP(0x7fffffff, 0x00000000), STCP(0x5a82799a, 0x5a82799a),
|
{{(FIXP_DBL)0x7fffffff, (FIXP_DBL)0x00000000}},
|
||||||
STCP(0x00000000, 0x7fffffff), STCP(0xa57d8666, 0x5a82799a),
|
{{(FIXP_DBL)0x5a82799a, (FIXP_DBL)0x5a82799a}},
|
||||||
STCP(0x80000000, 0x00000000), STCP(0xa57d8666, 0xa57d8666),
|
{{(FIXP_DBL)0x00000000, (FIXP_DBL)0x7fffffff}},
|
||||||
STCP(0x00000000, 0x80000000), STCP(0x5a82799a, 0xa57d8666),
|
{{(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 Functions ***/
|
||||||
static void longmult1(USHORT a[], USHORT b, USHORT d[], int len) {
|
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)) {
|
if (isTrSlot(pTsdData, ts)) {
|
||||||
int k;
|
int k;
|
||||||
const FIXP_STP *phi = &phiTsd[pTsdData->bsTsdTrPhaseData[ts]];
|
const FIXP_DPK *phi = &phiTsd[pTsdData->bsTsdTrPhaseData[ts]];
|
||||||
FDK_ASSERT((pTsdData->bsTsdTrPhaseData[ts] >= 0) &&
|
FDK_ASSERT((pTsdData->bsTsdTrPhaseData[ts] >= 0) &&
|
||||||
(pTsdData->bsTsdTrPhaseData[ts] < 8));
|
(pTsdData->bsTsdTrPhaseData[ts] < 8));
|
||||||
|
|
||||||
/* d = d_nonTr + v_direct * exp(j * bsTsdTrPhaseData[ts]/4 * pi ) */
|
/* d = d_nonTr + v_direct * exp(j * bsTsdTrPhaseData[ts]/4 * pi ) */
|
||||||
for (k = TSD_START_BAND; k < numHybridBands; k++) {
|
for (k = TSD_START_BAND; k < numHybridBands; k++) {
|
||||||
FIXP_DBL tempReal, tempImag;
|
FIXP_DBL tempReal, tempImag;
|
||||||
cplxMult(&tempReal, &tempImag, pVdirectReal[k], pVdirectImag[k], *phi);
|
cplxMultDiv2(&tempReal, &tempImag, pVdirectReal[k], pVdirectImag[k],
|
||||||
pDnonTrReal[k] += tempReal;
|
*phi);
|
||||||
pDnonTrImag[k] += tempImag;
|
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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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).
|
* error (0: core decoder found errors, 1: no errors).
|
||||||
* \param psDecoded Pointer to a buffer holding a flag. Input: PS is
|
* \param psDecoded Pointer to a buffer holding a flag. Input: PS is
|
||||||
* possible, Output: PS has been rendered.
|
* 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.
|
* \return Error code.
|
||||||
*/
|
*/
|
||||||
SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
|
SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, LONG *input, LONG *timeData,
|
||||||
INT_PCM *timeData, const int timeDataSize,
|
const int timeDataSize, int *numChannels,
|
||||||
int *numChannels, int *sampleRate,
|
int *sampleRate,
|
||||||
const FDK_channelMapDescr *const mapDescr,
|
const FDK_channelMapDescr *const mapDescr,
|
||||||
const int mapIdx, const int coreDecodedOk,
|
const int mapIdx, const int coreDecodedOk,
|
||||||
UCHAR *psDecoded);
|
UCHAR *psDecoded, const INT inDataHeadroom,
|
||||||
|
INT *outDataHeadroom);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Close SBR decoder instance and free memory.
|
* \brief Close SBR decoder instance and free memory.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -897,30 +897,31 @@ void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal,
|
|||||||
for (i = startSample; i < stopSample; i++) {
|
for (i = startSample; i < stopSample; i++) {
|
||||||
maxVal |=
|
maxVal |=
|
||||||
(FIXP_DBL)((LONG)(sourceBufferReal[i][loBand]) ^
|
(FIXP_DBL)((LONG)(sourceBufferReal[i][loBand]) ^
|
||||||
((LONG)sourceBufferReal[i][loBand] >> (SAMPLE_BITS - 1)));
|
((LONG)sourceBufferReal[i][loBand] >> (DFRACT_BITS - 1)));
|
||||||
maxVal |=
|
maxVal |=
|
||||||
(FIXP_DBL)((LONG)(sourceBufferImag[i][loBand]) ^
|
(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)) {
|
if (maxVal != FL2FX_DBL(0.0f)) {
|
||||||
reserve = fixMax(0, CntLeadingZeros(maxVal) - 2);
|
reserve = CntLeadingZeros(maxVal) - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
nrg_ov = nrg = (FIXP_DBL)0;
|
nrg_ov = nrg = (FIXP_DBL)0;
|
||||||
if (scale_nrg_ov > -31) {
|
if (scale_nrg_ov > -31) {
|
||||||
for (i = startSample; i < overlap; i++) {
|
for (i = startSample; i < overlap; i++) {
|
||||||
nrg_ov += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) +
|
nrg_ov +=
|
||||||
fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >>
|
(fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) +
|
||||||
sum_scale_ov;
|
fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >>
|
||||||
|
sum_scale_ov;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
scale_nrg_ov = 0;
|
scale_nrg_ov = 0;
|
||||||
}
|
}
|
||||||
if (scale_nrg > -31) {
|
if (scale_nrg > -31) {
|
||||||
for (i = overlap; i < stopSample; i++) {
|
for (i = overlap; i < stopSample; i++) {
|
||||||
nrg += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) +
|
nrg += (fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) +
|
||||||
fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >>
|
fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >>
|
||||||
sum_scale;
|
sum_scale;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -151,6 +151,9 @@ amm-info@iis.fraunhofer.de
|
|||||||
|
|
||||||
#include "genericStds.h" /* need FDKpow() for debug outputs */
|
#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 {
|
typedef struct {
|
||||||
FIXP_DBL nrgRef[MAX_FREQ_COEFFS];
|
FIXP_DBL nrgRef[MAX_FREQ_COEFFS];
|
||||||
FIXP_DBL nrgEst[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() */
|
gain_sf[i] += gamma_sf + 1; /* +1 because of fMultDiv2() */
|
||||||
|
|
||||||
/* set gain to at least 0.2f */
|
/* 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 */
|
/* limit and calculate gain[i]^2 too */
|
||||||
FIXP_DBL gain_pow2;
|
FIXP_DBL gain_pow2;
|
||||||
int gain_pow2_sf;
|
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[i] = FL2FXCONST_DBL(0.8f);
|
||||||
gain_sf[i] = -2;
|
gain_sf[i] = -2;
|
||||||
gain_pow2 = FL2FXCONST_DBL(0.64f);
|
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);
|
fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf);
|
||||||
total_power_high_after_sf = new_summand_sf;
|
total_power_high_after_sf = new_summand_sf;
|
||||||
} else if (new_summand_sf < total_power_high_after_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;
|
total_power_high_after += subsample_power_high[i] >> preShift2;
|
||||||
}
|
}
|
||||||
@ -985,7 +980,8 @@ void calculateSbrEnvelope(
|
|||||||
*/
|
*/
|
||||||
if (!useLP)
|
if (!useLP)
|
||||||
adj_e = h_sbr_cal_env->filtBufferNoise_e -
|
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
|
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
|
- Smoothing can smear high gains of the previous envelope into the
|
||||||
current
|
current
|
||||||
*/
|
*/
|
||||||
maxSfbNrg_e += 6;
|
maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
|
||||||
|
|
||||||
adj_e = maxSfbNrg_e;
|
adj_e = maxSfbNrg_e;
|
||||||
// final_e should not exist for PVC fixfix framing
|
// 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
|
- Smoothing can smear high gains of the previous envelope into the
|
||||||
current
|
current
|
||||||
*/
|
*/
|
||||||
maxSfbNrg_e += 6;
|
maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
|
||||||
|
|
||||||
if (borders[i] < hHeaderData->numberTimeSlots)
|
if (borders[i] < hHeaderData->numberTimeSlots)
|
||||||
/* This envelope affects timeslots that belong to the output frame */
|
/* This envelope affects timeslots that belong to the output frame */
|
||||||
@ -1477,7 +1473,7 @@ void calculateSbrEnvelope(
|
|||||||
|
|
||||||
for (k = 0; k < noSubbands; k++) {
|
for (k = 0; k < noSubbands; k++) {
|
||||||
int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1);
|
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;
|
pNrgs->nrgGain_e[k] += sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1485,7 +1481,7 @@ void calculateSbrEnvelope(
|
|||||||
for (k = 0; k < noSubbands; k++) {
|
for (k = 0; k < noSubbands; k++) {
|
||||||
int sc =
|
int sc =
|
||||||
scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1);
|
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 */
|
FDK_ASSERT(!iTES_enable); /* not supported */
|
||||||
if (flags & SBRDEC_ELD_GRID) {
|
if (flags & SBRDEC_ELD_GRID) {
|
||||||
/* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */
|
/* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */
|
||||||
adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband], pNrgs,
|
adjustTimeSlot_EldGrid(
|
||||||
&h_sbr_cal_env->harmIndex, lowSubband,
|
&analysBufferReal[j][lowSubband], pNrgs,
|
||||||
noSubbands,
|
&h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
|
||||||
fMin(scale_change, DFRACT_BITS - 1),
|
fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
|
||||||
noNoiseFlag, &h_sbr_cal_env->phaseIndex,
|
&h_sbr_cal_env->phaseIndex,
|
||||||
EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale);
|
fMax(EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale,
|
||||||
|
-(DFRACT_BITS - 1)));
|
||||||
} else {
|
} else {
|
||||||
adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs,
|
adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs,
|
||||||
&h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
|
&h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
|
||||||
@ -1830,7 +1827,8 @@ static void equalizeFiltBufferExp(
|
|||||||
diff = (int)(nrgGain_e[band] - filtBuffer_e[band]);
|
diff = (int)(nrgGain_e[band] - filtBuffer_e[band]);
|
||||||
if (diff > 0) {
|
if (diff > 0) {
|
||||||
filtBuffer[band] >>=
|
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 */
|
filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */
|
||||||
} else if (diff < 0) {
|
} else if (diff < 0) {
|
||||||
/* The buffered gains seem to be larger, but maybe there
|
/* 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: */
|
filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */
|
||||||
|
|
||||||
/* For the remaining difference, change the new gain value */
|
/* For the remaining difference, change the new gain value */
|
||||||
diff = fixMin(-(reserve + diff), DFRACT_BITS - 1);
|
diff = -(reserve + diff);
|
||||||
nrgGain[band] >>= diff;
|
nrgGain[band] >>= fMin(diff, DFRACT_BITS - 1);
|
||||||
nrgGain_e[band] += diff;
|
nrgGain_e[band] += diff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2423,6 +2421,9 @@ static void adjustTimeSlot_EldGrid(
|
|||||||
const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0];
|
const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0];
|
||||||
const INT *p_harmonicPhase = &harmonicPhase[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) = fAddSaturate(
|
||||||
*(ptrReal - 1),
|
*(ptrReal - 1),
|
||||||
SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]),
|
SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]),
|
||||||
@ -2435,7 +2436,8 @@ static void adjustTimeSlot_EldGrid(
|
|||||||
FIXP_DBL sineLevel_curr = *pSineLevel++;
|
FIXP_DBL sineLevel_curr = *pSineLevel++;
|
||||||
phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
|
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++;
|
sbNoise = *pNoiseLevel++;
|
||||||
if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
|
if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
|
||||||
signalReal +=
|
signalReal +=
|
||||||
@ -2469,7 +2471,8 @@ static void adjustTimeSlot_EldGrid(
|
|||||||
FIXP_DBL sineLevel_curr = *pSineLevel++;
|
FIXP_DBL sineLevel_curr = *pSineLevel++;
|
||||||
phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
|
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++;
|
sbNoise = *pNoiseLevel++;
|
||||||
if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
|
if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
|
||||||
signalReal +=
|
signalReal +=
|
||||||
@ -2509,6 +2512,8 @@ static void adjustTimeSlotLC(
|
|||||||
FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
|
FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
|
||||||
int tone_count = 0;
|
int tone_count = 0;
|
||||||
int sineSign = 1;
|
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 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f))
|
||||||
#define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.16773f))
|
#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
|
of the signal and should be carried out with full accuracy
|
||||||
(supplying #FRACT_BITS valid bits).
|
(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++;
|
sineLevel = *pSineLevel++;
|
||||||
sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
|
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 */
|
/* save switch and compare operations and reduce to XOR statement */
|
||||||
if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) {
|
if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) {
|
||||||
*(ptrReal - 1) += tmp1;
|
*(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), tmp1);
|
||||||
signalReal -= tmp2;
|
signalReal -= tmp2;
|
||||||
} else {
|
} else {
|
||||||
*(ptrReal - 1) -= tmp1;
|
*(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), -tmp1);
|
||||||
signalReal += tmp2;
|
signalReal += tmp2;
|
||||||
}
|
}
|
||||||
*ptrReal++ = signalReal;
|
*ptrReal++ = signalReal;
|
||||||
@ -2586,7 +2592,9 @@ static void adjustTimeSlotLC(
|
|||||||
|
|
||||||
/* The next multiplication constitutes the actual envelope adjustment of
|
/* The next multiplication constitutes the actual envelope adjustment of
|
||||||
* the signal. */
|
* the signal. */
|
||||||
signalReal += fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
|
signalReal +=
|
||||||
|
fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
|
||||||
|
<< scale_change;
|
||||||
|
|
||||||
pNoiseLevel++;
|
pNoiseLevel++;
|
||||||
*ptrReal++ = signalReal;
|
*ptrReal++ = signalReal;
|
||||||
@ -2599,7 +2607,8 @@ static void adjustTimeSlotLC(
|
|||||||
index++;
|
index++;
|
||||||
/* The next multiplication constitutes the actual envelope adjustment of
|
/* The next multiplication constitutes the actual envelope adjustment of
|
||||||
* the signal. */
|
* 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))
|
if (*pSineLevel++ != FL2FXCONST_DBL(0.0f))
|
||||||
tone_count++;
|
tone_count++;
|
||||||
@ -2627,7 +2636,8 @@ static void adjustTimeSlotLC(
|
|||||||
index++;
|
index++;
|
||||||
/* The next multiplication constitutes the actual envelope adjustment of the
|
/* The next multiplication constitutes the actual envelope adjustment of the
|
||||||
* signal. */
|
* 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));
|
sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f));
|
||||||
sineLevel = pSineLevel[0];
|
sineLevel = pSineLevel[0];
|
||||||
|
|
||||||
@ -2696,6 +2706,9 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
|||||||
/*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
|
/*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
|
||||||
int index = *ptrPhaseIndex;
|
int index = *ptrPhaseIndex;
|
||||||
int shift;
|
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);
|
*ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
|
||||||
|
|
||||||
@ -2705,6 +2718,8 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
|||||||
shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
|
shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
|
||||||
} else {
|
} else {
|
||||||
shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
|
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)) {
|
if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
|
||||||
@ -2720,8 +2735,10 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
|||||||
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
|
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
|
||||||
fMult(direct_ratio, noiseLevel[k]);
|
fMult(direct_ratio, noiseLevel[k]);
|
||||||
} else {
|
} else {
|
||||||
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) +
|
smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
|
||||||
fMult(direct_ratio, noiseLevel[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
|
of the signal and should be carried out with full accuracy
|
||||||
(supplying #DFRACT_BITS valid bits).
|
(supplying #DFRACT_BITS valid bits).
|
||||||
*/
|
*/
|
||||||
signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change);
|
signalReal =
|
||||||
signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change);
|
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
|
||||||
|
<< scale_change;
|
||||||
|
signalImag =
|
||||||
|
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
|
||||||
|
<< scale_change;
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
@ -2752,8 +2773,12 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
|||||||
} else {
|
} else {
|
||||||
for (k = 0; k < noSubbands; k++) {
|
for (k = 0; k < noSubbands; k++) {
|
||||||
smoothedGain = gain[k];
|
smoothedGain = gain[k];
|
||||||
signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
|
signalReal =
|
||||||
signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
|
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
|
||||||
|
<< scale_change;
|
||||||
|
signalImag =
|
||||||
|
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
|
||||||
|
<< scale_change;
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
@ -2859,6 +2884,9 @@ static void adjustTimeSlotHQ(
|
|||||||
int freqInvFlag = (lowSubband & 1);
|
int freqInvFlag = (lowSubband & 1);
|
||||||
FIXP_DBL sineLevel;
|
FIXP_DBL sineLevel;
|
||||||
int shift;
|
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);
|
*ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
|
||||||
*ptrHarmIndex = (harmIndex + 1) & 3;
|
*ptrHarmIndex = (harmIndex + 1) & 3;
|
||||||
@ -2874,10 +2902,13 @@ static void adjustTimeSlotHQ(
|
|||||||
|
|
||||||
filtBufferNoiseShift +=
|
filtBufferNoiseShift +=
|
||||||
1; /* due to later use of fMultDiv2 instead of fMult */
|
1; /* due to later use of fMultDiv2 instead of fMult */
|
||||||
if (filtBufferNoiseShift < 0)
|
if (filtBufferNoiseShift < 0) {
|
||||||
shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
|
shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
|
||||||
else
|
} else {
|
||||||
shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
|
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)) {
|
if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
|
||||||
for (k = 0; k < noSubbands; k++) {
|
for (k = 0; k < noSubbands; k++) {
|
||||||
@ -2893,8 +2924,10 @@ static void adjustTimeSlotHQ(
|
|||||||
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
|
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
|
||||||
fMult(direct_ratio, noiseLevel[k]);
|
fMult(direct_ratio, noiseLevel[k]);
|
||||||
} else {
|
} else {
|
||||||
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) +
|
smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
|
||||||
fMult(direct_ratio, noiseLevel[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
|
of the signal and should be carried out with full accuracy
|
||||||
(supplying #DFRACT_BITS valid bits).
|
(supplying #DFRACT_BITS valid bits).
|
||||||
*/
|
*/
|
||||||
signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change);
|
signalReal =
|
||||||
signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change);
|
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
|
||||||
|
<< scale_change;
|
||||||
|
signalImag =
|
||||||
|
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
|
||||||
|
<< scale_change;
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
@ -2956,8 +2993,12 @@ static void adjustTimeSlotHQ(
|
|||||||
} else {
|
} else {
|
||||||
for (k = 0; k < noSubbands; k++) {
|
for (k = 0; k < noSubbands; k++) {
|
||||||
smoothedGain = gain[k];
|
smoothedGain = gain[k];
|
||||||
signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
|
signalReal =
|
||||||
signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
|
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
|
||||||
|
<< scale_change;
|
||||||
|
signalImag =
|
||||||
|
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
|
||||||
|
<< scale_change;
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
@ -3141,6 +3182,11 @@ ResetLimiterBands(
|
|||||||
return SBRDEC_UNSUPPORTED_CONFIG;
|
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 */
|
/* Copy limiterbands from working buffer into final destination */
|
||||||
for (k = 0; k <= nBands; k++) {
|
for (k = 0; k <= nBands; k++) {
|
||||||
limiterBandTable[k] = workLimiterBandTable[k];
|
limiterBandTable[k] = workLimiterBandTable[k];
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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->qmfOutBufSize = 2 * (hQmfTran->noCols / 2 + QMF_WIN_LEN - 1);
|
||||||
|
|
||||||
hQmfTran->inBuf_F =
|
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
|
/* buffered time signal needs to be delayed by synthesis_size; max
|
||||||
* synthesis_size = 20; */
|
* synthesis_size = 20; */
|
||||||
if (hQmfTran->inBuf_F == NULL) {
|
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_r_m = fMultDiv2(tmp_r, factor_m) << shift;
|
||||||
g_i_m = fMultDiv2(tmp_i, factor_m) << shift;
|
g_i_m = fMultDiv2(tmp_i, factor_m) << shift;
|
||||||
g_e = scale_factor_hbe - (g_e + factor_e + gammaCenter_e + add);
|
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;
|
*qmfHBEBufReal_F += g_r_m >> g_e;
|
||||||
*qmfHBEBufImag_F += g_i_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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -132,6 +132,9 @@ typedef enum {
|
|||||||
} KEEP_STATES_SYNCED_MODE;
|
} KEEP_STATES_SYNCED_MODE;
|
||||||
|
|
||||||
struct hbeTransposer {
|
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 xOverQmf[MAX_NUM_PATCHES_HBE];
|
||||||
|
|
||||||
int maxStretch;
|
int maxStretch;
|
||||||
@ -144,7 +147,7 @@ struct hbeTransposer {
|
|||||||
int stopBand;
|
int stopBand;
|
||||||
int bSbr41;
|
int bSbr41;
|
||||||
|
|
||||||
INT_PCM *inBuf_F;
|
LONG *inBuf_F;
|
||||||
FIXP_DBL **qmfInBufReal_F;
|
FIXP_DBL **qmfInBufReal_F;
|
||||||
FIXP_DBL **qmfInBufImag_F;
|
FIXP_DBL **qmfInBufImag_F;
|
||||||
|
|
||||||
@ -156,9 +159,6 @@ struct hbeTransposer {
|
|||||||
FIXP_DBL const *synthesisQmfPreModCos_F;
|
FIXP_DBL const *synthesisQmfPreModCos_F;
|
||||||
FIXP_DBL const *synthesisQmfPreModSin_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 **qmfHBEBufReal_F;
|
||||||
FIXP_DBL **qmfHBEBufImag_F;
|
FIXP_DBL **qmfHBEBufImag_F;
|
||||||
|
|
||||||
|
@ -1014,8 +1014,8 @@ void lppTransposerHBE(
|
|||||||
pSettings->nCols) +
|
pSettings->nCols) +
|
||||||
lowBandShift);
|
lowBandShift);
|
||||||
|
|
||||||
dynamicScale = fixMax(
|
dynamicScale =
|
||||||
0, dynamicScale - 1); /* one additional bit headroom to prevent -1.0 */
|
dynamicScale - 1; /* one additional bit headroom to prevent -1.0 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Scale temporal QMF buffer.
|
Scale temporal QMF buffer.
|
||||||
@ -1194,6 +1194,9 @@ void lppTransposerHBE(
|
|||||||
} else { /* bw <= 0 */
|
} else { /* bw <= 0 */
|
||||||
|
|
||||||
int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
|
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++) {
|
for (i = startSample; i < stopSample; i++) {
|
||||||
FIXP_DBL accu1, accu2;
|
FIXP_DBL accu1, accu2;
|
||||||
@ -1210,9 +1213,9 @@ void lppTransposerHBE(
|
|||||||
dynamicScale;
|
dynamicScale;
|
||||||
|
|
||||||
qmfBufferReal[i][loBand] =
|
qmfBufferReal[i][loBand] =
|
||||||
(lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << 1);
|
(lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << (1 + 1));
|
||||||
qmfBufferImag[i][loBand] =
|
qmfBufferImag[i][loBand] =
|
||||||
(lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << 1);
|
(lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << (1 + 1));
|
||||||
}
|
}
|
||||||
} /* bw <= 0 */
|
} /* bw <= 0 */
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -534,7 +534,8 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
|
|||||||
for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
|
for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
|
||||||
for (band = sg_borders[ksg]; band < sg_borders[ksg + 1]; band++) {
|
for (band = sg_borders[ksg]; band < sg_borders[ksg + 1]; band++) {
|
||||||
/* The division by 8 == (RATE*lbw) is required algorithmically */
|
/* 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) {
|
if (E[ksg] > (FIXP_DBL)0) {
|
||||||
/* 10/log2(10) = 0.752574989159953 * 2^2 */
|
/* 10/log2(10) = 0.752574989159953 * 2^2 */
|
||||||
int exp_log;
|
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 = fMult(nrg, FL2FXCONST_SGL(LOG10FAC));
|
||||||
nrg = scaleValue(nrg, exp_log - PVC_ESG_EXP + 2);
|
nrg = scaleValue(nrg, exp_log - PVC_ESG_EXP + 2);
|
||||||
pEsg[ksg] = fMax(nrg, FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)));
|
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;
|
E_high_exp[ksg] = 0;
|
||||||
|
|
||||||
/* residual part */
|
/* 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]);
|
pPvcDynamicData->pScalingCoef[3]);
|
||||||
|
|
||||||
/* linear combination of lower grouped energies part */
|
/* linear combination of lower grouped energies part */
|
||||||
for (kb = 0; kb < PVC_NBLOW; kb++) {
|
for (kb = 0; kb < PVC_NBLOW; kb++) {
|
||||||
predCoeff = (FIXP_SGL)(
|
predCoeff = (FIXP_SGL)(
|
||||||
(SHORT)(SCHAR)pTab1[kb * pPvcDynamicData->nbHigh + ksg] << 8);
|
(SHORT)(SCHAR)pTab1[kb * pPvcDynamicData->nbHigh + ksg] << 8);
|
||||||
predCoeff_exp = pPvcDynamicData->pScalingCoef[kb] +
|
predCoeff_exp = -(pPvcDynamicData->pScalingCoef[kb] + 1 -
|
||||||
1; /* +1 to compensate for Div2 */
|
2); /* +1 to compensate for Div2; -2 for accu */
|
||||||
accu += fMultDiv2(E[kb], predCoeff) << predCoeff_exp;
|
accu += fMultDiv2(E[kb], predCoeff) >> predCoeff_exp;
|
||||||
}
|
}
|
||||||
/* convert back to linear domain */
|
/* convert back to linear domain */
|
||||||
accu = fMult(accu, FL2FXCONST_SGL(LOG10FAC_INV));
|
accu = fMult(accu, FL2FXCONST_SGL(LOG10FAC_INV));
|
||||||
accu = f2Pow(
|
accu = f2Pow(accu, PVC_ESG_EXP - 1 + 2,
|
||||||
accu, PVC_ESG_EXP - 1,
|
&predCoeff_exp); /* -1 compensates for exponent of
|
||||||
&predCoeff_exp); /* -1 compensates for exponent of LOG10FAC_INV */
|
LOG10FAC_INV; +2 for accu */
|
||||||
predictedEsgSlot[ksg] = accu;
|
predictedEsgSlot[ksg] = accu;
|
||||||
E_high_exp[ksg] = predCoeff_exp;
|
E_high_exp[ksg] = predCoeff_exp;
|
||||||
if (predCoeff_exp > E_high_exp_max) {
|
if (predCoeff_exp > E_high_exp_max) {
|
||||||
@ -628,8 +629,8 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
|
|||||||
|
|
||||||
/* rescale output vector according to largest exponent */
|
/* rescale output vector according to largest exponent */
|
||||||
for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
|
for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
|
||||||
int scale = E_high_exp[ksg] - E_high_exp_max;
|
int scale = fMin(E_high_exp_max - E_high_exp[ksg], DFRACT_BITS - 1);
|
||||||
predictedEsgSlot[ksg] = scaleValue(predictedEsgSlot[ksg], scale);
|
predictedEsgSlot[ksg] = predictedEsgSlot[ksg] >> scale;
|
||||||
}
|
}
|
||||||
*predictedEsg_exp = E_high_exp_max;
|
*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
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -259,17 +259,18 @@ static void copyHarmonicSpectrum(int *xOverQmf, FIXP_DBL **qmfReal,
|
|||||||
|
|
||||||
void sbr_dec(
|
void sbr_dec(
|
||||||
HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
|
HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
|
||||||
INT_PCM *timeIn, /*!< pointer to input time signal */
|
LONG *timeIn, /*!< pointer to input time signal */
|
||||||
INT_PCM *timeOut, /*!< pointer to output time signal */
|
LONG *timeOut, /*!< pointer to output time signal */
|
||||||
HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */
|
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 */
|
const int strideOut, /*!< Time data traversal strideOut */
|
||||||
HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
|
HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
|
||||||
HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
|
HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
|
||||||
HANDLE_SBR_PREV_FRAME_DATA
|
HANDLE_SBR_PREV_FRAME_DATA
|
||||||
hPrevFrameData, /*!< Some control data of last frame */
|
hPrevFrameData, /*!< Some control data of last frame */
|
||||||
const int applyProcessing, /*!< Flag for SBR operation */
|
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 i, slot, reserve;
|
||||||
int saveLbScale;
|
int saveLbScale;
|
||||||
int lastSlotOffs;
|
int lastSlotOffs;
|
||||||
@ -278,7 +279,7 @@ void sbr_dec(
|
|||||||
/* temporary pointer / variable for QMF;
|
/* temporary pointer / variable for QMF;
|
||||||
required as we want to use temporary buffer
|
required as we want to use temporary buffer
|
||||||
creating one frame delay for HBE in LP mode */
|
creating one frame delay for HBE in LP mode */
|
||||||
INT_PCM *pTimeInQmf = timeIn;
|
LONG *pTimeInQmf = timeIn;
|
||||||
|
|
||||||
/* Number of QMF timeslots in the overlap buffer: */
|
/* Number of QMF timeslots in the overlap buffer: */
|
||||||
int ov_len = hSbrDec->LppTrans.pSettings->overlap;
|
int ov_len = hSbrDec->LppTrans.pSettings->overlap;
|
||||||
@ -341,8 +342,8 @@ void sbr_dec(
|
|||||||
} else {
|
} else {
|
||||||
C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * (64));
|
C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * (64));
|
||||||
qmfAnalysisFiltering(&hSbrDec->qmfDomainInCh->fb, pReal, pImag,
|
qmfAnalysisFiltering(&hSbrDec->qmfDomainInCh->fb, pReal, pImag,
|
||||||
&hSbrDec->qmfDomainInCh->scaling, pTimeInQmf, 0, 1,
|
&hSbrDec->qmfDomainInCh->scaling, pTimeInQmf,
|
||||||
qmfTemp);
|
0 + sbrInDataHeadroom, 1, qmfTemp);
|
||||||
|
|
||||||
C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * (64));
|
C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * (64));
|
||||||
}
|
}
|
||||||
@ -658,7 +659,7 @@ void sbr_dec(
|
|||||||
|
|
||||||
if (!(flags & SBRDEC_PS_DECODED)) {
|
if (!(flags & SBRDEC_PS_DECODED)) {
|
||||||
if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
|
if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
|
||||||
int outScalefactor = 0;
|
int outScalefactor = -(8);
|
||||||
|
|
||||||
if (h_ps_d != NULL) {
|
if (h_ps_d != NULL) {
|
||||||
h_ps_d->procFrameBased = 1; /* we here do frame based processing */
|
h_ps_d->procFrameBased = 1; /* we here do frame based processing */
|
||||||
@ -743,6 +744,7 @@ void sbr_dec(
|
|||||||
*/
|
*/
|
||||||
FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <=
|
FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <=
|
||||||
QMF_MAX_SYNTHESIS_BANDS);
|
QMF_MAX_SYNTHESIS_BANDS);
|
||||||
|
qmfChangeOutScalefactor(synQmfRight, -(8));
|
||||||
FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates,
|
FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates,
|
||||||
9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis *
|
9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis *
|
||||||
sizeof(FIXP_QSS));
|
sizeof(FIXP_QSS));
|
||||||
@ -814,7 +816,8 @@ void sbr_dec(
|
|||||||
: scaleFactorLowBand_no_ov,
|
: scaleFactorLowBand_no_ov,
|
||||||
scaleFactorHighBand, synQmf->lsb, synQmf->usb);
|
scaleFactorHighBand, synQmf->lsb, synQmf->usb);
|
||||||
|
|
||||||
outScalefactorL = outScalefactorR = 1; /* psDiffScale! (MPEG-PS) */
|
outScalefactorL = outScalefactorR =
|
||||||
|
1 + sbrInDataHeadroom; /* psDiffScale! (MPEG-PS) */
|
||||||
}
|
}
|
||||||
|
|
||||||
sbrDecoder_drcApplySlot(/* right channel */
|
sbrDecoder_drcApplySlot(/* right channel */
|
||||||
@ -831,6 +834,9 @@ void sbr_dec(
|
|||||||
outScalefactorL += maxShift;
|
outScalefactorL += maxShift;
|
||||||
|
|
||||||
if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
|
if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
|
||||||
|
qmfChangeOutScalefactor(synQmf, -(8));
|
||||||
|
qmfChangeOutScalefactor(synQmfRight, -(8));
|
||||||
|
|
||||||
qmfSynthesisFilteringSlot(
|
qmfSynthesisFilteringSlot(
|
||||||
synQmfRight, rQmfReal, /* QMF real buffer */
|
synQmfRight, rQmfReal, /* QMF real buffer */
|
||||||
rQmfImag, /* QMF imag buffer */
|
rQmfImag, /* QMF imag buffer */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -176,17 +176,18 @@ typedef SBR_CHANNEL *HANDLE_SBR_CHANNEL;
|
|||||||
|
|
||||||
void sbr_dec(
|
void sbr_dec(
|
||||||
HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
|
HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
|
||||||
INT_PCM *timeIn, /*!< pointer to input time signal */
|
LONG *timeIn, /*!< pointer to input time signal */
|
||||||
INT_PCM *timeOut, /*!< pointer to output time signal */
|
LONG *timeOut, /*!< pointer to output time signal */
|
||||||
HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */
|
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 */
|
INT strideOut, /*!< Time data traversal strideOut */
|
||||||
HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
|
HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
|
||||||
HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
|
HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
|
||||||
HANDLE_SBR_PREV_FRAME_DATA
|
HANDLE_SBR_PREV_FRAME_DATA
|
||||||
hPrevFrameData, /*!< Some control data of last frame */
|
hPrevFrameData, /*!< Some control data of last frame */
|
||||||
const int applyProcessing, /*!< Flag for SBR operation */
|
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
|
SBR_ERROR
|
||||||
createSbrDec(SBR_CHANNEL *hSbrChannel, HANDLE_SBR_HEADER_DATA hHeaderData,
|
createSbrDec(SBR_CHANNEL *hSbrChannel, HANDLE_SBR_HEADER_DATA hHeaderData,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -109,9 +109,6 @@ amm-info@iis.fraunhofer.de
|
|||||||
|
|
||||||
#include "sbr_ram.h"
|
#include "sbr_ram.h"
|
||||||
|
|
||||||
#define WORKBUFFER1_TAG 2
|
|
||||||
#define WORKBUFFER2_TAG 3
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\name StaticSbrData
|
\name StaticSbrData
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
@ -170,6 +170,9 @@ struct SBR_DECODER_INSTANCE {
|
|||||||
flushed consecutively. */
|
flushed consecutively. */
|
||||||
|
|
||||||
UINT flags;
|
UINT flags;
|
||||||
|
|
||||||
|
INT sbrInDataHeadroom; /* Headroom of the SBR input time signal to prevent
|
||||||
|
clipping */
|
||||||
};
|
};
|
||||||
|
|
||||||
H_ALLOC_MEM(Ram_SbrDecElement, SBR_DECODER_ELEMENT)
|
H_ALLOC_MEM(Ram_SbrDecElement, SBR_DECODER_ELEMENT)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
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.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
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),
|
Choose a stop band between k1 and 64 depending on stopFreq (0..13),
|
||||||
based on a logarithmic scale.
|
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);
|
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 "env_extr.h"
|
||||||
#include "sbr_dec.h"
|
#include "sbr_dec.h"
|
||||||
#include "env_dec.h"
|
#include "env_dec.h"
|
||||||
#include "sbr_crc.h"
|
#include "FDK_crc.h"
|
||||||
#include "sbr_ram.h"
|
#include "sbr_ram.h"
|
||||||
#include "sbr_rom.h"
|
#include "sbr_rom.h"
|
||||||
#include "lpp_tran.h"
|
#include "lpp_tran.h"
|
||||||
#include "transcendent.h"
|
#include "transcendent.h"
|
||||||
|
|
||||||
#include "FDK_crc.h"
|
|
||||||
|
|
||||||
#include "sbrdec_drc.h"
|
#include "sbrdec_drc.h"
|
||||||
|
|
||||||
#include "psbitdec.h"
|
#include "psbitdec.h"
|
||||||
|
|
||||||
/* Decoder library info */
|
/* Decoder library info */
|
||||||
#define SBRDECODER_LIB_VL0 3
|
#define SBRDECODER_LIB_VL0 3
|
||||||
#define SBRDECODER_LIB_VL1 0
|
#define SBRDECODER_LIB_VL1 1
|
||||||
#define SBRDECODER_LIB_VL2 0
|
#define SBRDECODER_LIB_VL2 0
|
||||||
#define SBRDECODER_LIB_TITLE "SBR Decoder"
|
#define SBRDECODER_LIB_TITLE "SBR Decoder"
|
||||||
#ifdef SUPPRESS_BUILD_DATE_INFO
|
#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;
|
SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT;
|
||||||
|
|
||||||
INT startPos = FDKgetValidBits(hBs);
|
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;
|
HANDLE_FDK_BITSTREAM hBsOriginal = hBs;
|
||||||
FDK_BITSTREAM bsBwd;
|
FDK_BITSTREAM bsBwd;
|
||||||
|
|
||||||
FDK_CRCINFO crcInfo;
|
|
||||||
INT crcReg = 0;
|
|
||||||
USHORT drmSbrCrc = 0;
|
|
||||||
const int fGlobalIndependencyFlag = acFlags & AC_INDEP;
|
const int fGlobalIndependencyFlag = acFlags & AC_INDEP;
|
||||||
const int bs_pvc = acElFlags[elementIndex] & AC_EL_USAC_PVC;
|
const int bs_pvc = acElFlags[elementIndex] & AC_EL_USAC_PVC;
|
||||||
const int bs_interTes = acElFlags[elementIndex] & AC_EL_USAC_ITES;
|
const int bs_interTes = acElFlags[elementIndex] & AC_EL_USAC_ITES;
|
||||||
int stereo;
|
int stereo;
|
||||||
int fDoDecodeSbrData = 1;
|
int fDoDecodeSbrData = 1;
|
||||||
|
int alignBits = 0;
|
||||||
|
|
||||||
int lastSlot, lastHdrSlot = 0, thisHdrSlot = 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 (fDoDecodeSbrData) {
|
||||||
if (crcFlag) {
|
if (crcFlag) {
|
||||||
switch (self->coreCodec) {
|
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_AAC:
|
||||||
case AOT_DRM_SURROUND:
|
case AOT_DRM_SURROUND:
|
||||||
drmSbrCrc = (USHORT)FDKreadBits(hBs, 8);
|
crcPoly = 0x001d;
|
||||||
/* Setup CRC decoder */
|
crcLen = 8;
|
||||||
FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8);
|
crcStartValue = 0x000000ff;
|
||||||
/* Start CRC region */
|
|
||||||
crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CRCLen = bsPayLen - 10; /* change: 0 => i */
|
crcPoly = 0x0633;
|
||||||
if (CRCLen < 0) {
|
crcLen = 10;
|
||||||
fDoDecodeSbrData = 0;
|
crcStartValue = 0x00000000;
|
||||||
} else {
|
|
||||||
fDoDecodeSbrData = SbrCrcCheck(hBs, CRCLen);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
sbrCrc = (USHORT)FDKreadBits(hBs, crcLen);
|
||||||
|
/* Setup CRC decoder */
|
||||||
|
FDKcrcInit(&crcInfo, crcPoly, crcStartValue, crcLen);
|
||||||
|
/* Start CRC region */
|
||||||
|
crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
|
||||||
}
|
}
|
||||||
} /* if (fDoDecodeSbrData) */
|
} /* if (fDoDecodeSbrData) */
|
||||||
|
|
||||||
@ -1450,35 +1448,6 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
|
|||||||
valBits = (INT)FDKgetValidBits(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 */
|
/* sanity check of remaining bits */
|
||||||
if (valBits < 0) {
|
if (valBits < 0) {
|
||||||
fDoDecodeSbrData = 0;
|
fDoDecodeSbrData = 0;
|
||||||
@ -1489,7 +1458,7 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
|
|||||||
case AOT_AAC_LC: {
|
case AOT_AAC_LC: {
|
||||||
/* This sanity check is only meaningful with General Audio
|
/* This sanity check is only meaningful with General Audio
|
||||||
* bitstreams */
|
* bitstreams */
|
||||||
int alignBits = valBits & 0x7;
|
alignBits = valBits & 0x7;
|
||||||
|
|
||||||
if (valBits > alignBits) {
|
if (valBits > alignBits) {
|
||||||
fDoDecodeSbrData = 0;
|
fDoDecodeSbrData = 0;
|
||||||
@ -1508,6 +1477,20 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
|
|||||||
errorStatus = SBRDEC_PARSE_ERROR;
|
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) {
|
if (!fDoDecodeSbrData) {
|
||||||
/* Set error flag for this slot to trigger concealment */
|
/* Set error flag for this slot to trigger concealment */
|
||||||
setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR);
|
setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR);
|
||||||
@ -1587,10 +1570,10 @@ bail:
|
|||||||
* \return SBRDEC_OK if successfull, else error code
|
* \return SBRDEC_OK if successfull, else error code
|
||||||
*/
|
*/
|
||||||
static SBR_ERROR sbrDecoder_DecodeElement(
|
static SBR_ERROR sbrDecoder_DecodeElement(
|
||||||
HANDLE_SBRDECODER self, QDOM_PCM *input, INT_PCM *timeData,
|
HANDLE_SBRDECODER self, LONG *input, LONG *timeData, const int timeDataSize,
|
||||||
const int timeDataSize, const FDK_channelMapDescr *const mapDescr,
|
const FDK_channelMapDescr *const mapDescr, const int mapIdx,
|
||||||
const int mapIdx, int channelIndex, const int elementIndex,
|
int channelIndex, const int elementIndex, const int numInChannels,
|
||||||
const int numInChannels, int *numOutChannels, const int psPossible) {
|
int *numOutChannels, const int psPossible) {
|
||||||
SBR_DECODER_ELEMENT *hSbrElement = self->pSbrElement[elementIndex];
|
SBR_DECODER_ELEMENT *hSbrElement = self->pSbrElement[elementIndex];
|
||||||
HANDLE_SBR_CHANNEL *pSbrChannel =
|
HANDLE_SBR_CHANNEL *pSbrChannel =
|
||||||
self->pSbrElement[elementIndex]->pSbrChannel;
|
self->pSbrElement[elementIndex]->pSbrChannel;
|
||||||
@ -1760,7 +1743,7 @@ static SBR_ERROR sbrDecoder_DecodeElement(
|
|||||||
timeData + offset1, strideOut, hSbrHeader, hFrameDataLeft,
|
timeData + offset1, strideOut, hSbrHeader, hFrameDataLeft,
|
||||||
&pSbrChannel[0]->prevFrameData,
|
&pSbrChannel[0]->prevFrameData,
|
||||||
(hSbrHeader->syncState == SBR_ACTIVE), h_ps_d, self->flags,
|
(hSbrHeader->syncState == SBR_ACTIVE), h_ps_d, self->flags,
|
||||||
codecFrameSize);
|
codecFrameSize, self->sbrInDataHeadroom);
|
||||||
|
|
||||||
if (stereo) {
|
if (stereo) {
|
||||||
/* Process right channel */
|
/* Process right channel */
|
||||||
@ -1768,7 +1751,7 @@ static SBR_ERROR sbrDecoder_DecodeElement(
|
|||||||
timeData + offset1, NULL, NULL, strideOut, hSbrHeader,
|
timeData + offset1, NULL, NULL, strideOut, hSbrHeader,
|
||||||
hFrameDataRight, &pSbrChannel[1]->prevFrameData,
|
hFrameDataRight, &pSbrChannel[1]->prevFrameData,
|
||||||
(hSbrHeader->syncState == SBR_ACTIVE), NULL, self->flags,
|
(hSbrHeader->syncState == SBR_ACTIVE), NULL, self->flags,
|
||||||
codecFrameSize);
|
codecFrameSize, self->sbrInDataHeadroom);
|
||||||
}
|
}
|
||||||
|
|
||||||
C_ALLOC_SCRATCH_END(pPsScratch, struct PS_DEC_COEFFICIENTS, 1)
|
C_ALLOC_SCRATCH_END(pPsScratch, struct PS_DEC_COEFFICIENTS, 1)
|
||||||
@ -1788,14 +1771,14 @@ static SBR_ERROR sbrDecoder_DecodeElement(
|
|||||||
int copyFrameSize =
|
int copyFrameSize =
|
||||||
codecFrameSize * self->pQmfDomain->QmfDomainOut->fb.no_channels;
|
codecFrameSize * self->pQmfDomain->QmfDomainOut->fb.no_channels;
|
||||||
copyFrameSize /= self->pQmfDomain->QmfDomainIn->fb.no_channels;
|
copyFrameSize /= self->pQmfDomain->QmfDomainIn->fb.no_channels;
|
||||||
INT_PCM *ptr;
|
LONG *ptr;
|
||||||
INT i;
|
INT i;
|
||||||
FDK_ASSERT(strideOut == 2);
|
FDK_ASSERT(strideOut == 2);
|
||||||
|
|
||||||
ptr = timeData;
|
ptr = timeData;
|
||||||
for (i = copyFrameSize >> 1; i--;) {
|
for (i = copyFrameSize >> 1; i--;) {
|
||||||
INT_PCM tmp; /* This temporal variable is required because some
|
LONG tmp; /* This temporal variable is required because some compilers
|
||||||
compilers can't do *ptr++ = *ptr++ correctly. */
|
can't do *ptr++ = *ptr++ correctly. */
|
||||||
tmp = *ptr++;
|
tmp = *ptr++;
|
||||||
*ptr++ = tmp;
|
*ptr++ = tmp;
|
||||||
tmp = *ptr++;
|
tmp = *ptr++;
|
||||||
@ -1808,12 +1791,13 @@ static SBR_ERROR sbrDecoder_DecodeElement(
|
|||||||
return errorStatus;
|
return errorStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
|
SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, LONG *input, LONG *timeData,
|
||||||
INT_PCM *timeData, const int timeDataSize,
|
const int timeDataSize, int *numChannels,
|
||||||
int *numChannels, int *sampleRate,
|
int *sampleRate,
|
||||||
const FDK_channelMapDescr *const mapDescr,
|
const FDK_channelMapDescr *const mapDescr,
|
||||||
const int mapIdx, const int coreDecodedOk,
|
const int mapIdx, const int coreDecodedOk,
|
||||||
UCHAR *psDecoded) {
|
UCHAR *psDecoded, const INT inDataHeadroom,
|
||||||
|
INT *outDataHeadroom) {
|
||||||
SBR_ERROR errorStatus = SBRDEC_OK;
|
SBR_ERROR errorStatus = SBRDEC_OK;
|
||||||
|
|
||||||
int psPossible;
|
int psPossible;
|
||||||
@ -1850,6 +1834,9 @@ SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
|
|||||||
psPossible = 0;
|
psPossible = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->sbrInDataHeadroom = inDataHeadroom;
|
||||||
|
*outDataHeadroom = (INT)(8);
|
||||||
|
|
||||||
/* Make sure that even if no SBR data was found/parsed *psDecoded is returned
|
/* Make sure that even if no SBR data was found/parsed *psDecoded is returned
|
||||||
* 1 if psPossible was 0. */
|
* 1 if psPossible was 0. */
|
||||||
if (psPossible == 0) {
|
if (psPossible == 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user